Part Number: TMS570LS1227
Other Parts Discussed in Thread: ADS125H02, HALCOGEN
I've configured SPI2 as slave and MIBSPI1 as master and both use DMA. When MIBSPI1 isn't in use, SPI2 works fine but when MIBSPI1 starts data transfer, SPI2 communication fails. As far as I could see, the data in the DMA buffer is shifted a few bits.
There are 3 ADC chips connected to the MIBSPI port and the MCU reads data at 7.2K sample rate from each ADC chips. SPI2 and MIBSPI1 use BTC and FTC DMA interrupts respectively. I also changed dmaFTCAInterrupt function in sys_dma.c and it calls another function when FTC interrupt is triggered.
Another thing is that data size of the SPI2 isn't fixed. It first receives 3 16-bits words as header. This header contains the package size and then the MCU changes DMA buffer size to send/receive number of bytes defined in the header.
When the SPI2 is configured in ISR mode, it works without problem up to 4MHz.
#define CONFIG_SPI_TX_DMA_CH DMA_CH13
#define CONFIG_SPI_RX_DMA_CH DMA_CH12
#define CONFIG_SPI_TX_DMA_REQ 3ul
#define CONFIG_SPI_RX_DMA_REQ 2ul
#define CONFIG_SPI_HEADER_SIZE 3
#define CONFIG_SPI_PORT spiREG2
#define CONFIG_SPI_TX_ADDR ((uint32_t)(&(CONFIG_SPI_PORT->DAT1)) + 2)
#define CONFIG_SPI_RX_ADDR ((uint32_t)(&(CONFIG_SPI_PORT->BUF)) + 2)
void dmaConfigSPICtrlTxPacket(g_dmaCTRL * g_dmaCTRLPKT_TX, uint32 sadd, uint32 dadd, uint16 FrameCnt)
{
g_dmaCTRLPKT_TX->SADD = sadd; /* source address */
g_dmaCTRLPKT_TX->DADD = dadd; /* destination address */
g_dmaCTRLPKT_TX->CHCTRL = 0; /* channel control */
g_dmaCTRLPKT_TX->FRCNT = FrameCnt; /* frame count */
g_dmaCTRLPKT_TX->ELCNT = 1; /* element count */
g_dmaCTRLPKT_TX->ELDOFFSET = 0; /* element destination offset */
g_dmaCTRLPKT_TX->ELSOFFSET = 0; /* element source offset */
g_dmaCTRLPKT_TX->FRDOFFSET = 0; /* frame destination offset */
g_dmaCTRLPKT_TX->FRSOFFSET = 0; /* frame source offset */
g_dmaCTRLPKT_TX->PORTASGN = 4; /* port b */
g_dmaCTRLPKT_TX->RDSIZE = ACCESS_16_BIT; /* read size */
g_dmaCTRLPKT_TX->WRSIZE = ACCESS_16_BIT; /* write size */
g_dmaCTRLPKT_TX->TTYPE = FRAME_TRANSFER; /* transfer type */
g_dmaCTRLPKT_TX->ADDMODERD = ADDR_INC1; /* address mode read */
g_dmaCTRLPKT_TX->ADDMODEWR = ADDR_FIXED; /* address mode write */
g_dmaCTRLPKT_TX->AUTOINIT = AUTOINIT_ON; /* autoinit */
}
void dmaConfigSPICtrlRxPacket(g_dmaCTRL * g_dmaCTRLPKT_RX, uint32 sadd, uint32 dadd, uint16 FrameCnt)
{
g_dmaCTRLPKT_RX->SADD = sadd; /* source address */
g_dmaCTRLPKT_RX->DADD = dadd; /* destination address */
g_dmaCTRLPKT_RX->CHCTRL = 0; /* channel control */
g_dmaCTRLPKT_RX->FRCNT = FrameCnt; /* frame count */
g_dmaCTRLPKT_RX->ELCNT = 1; /* element count */
g_dmaCTRLPKT_RX->ELDOFFSET = 0; /* element destination offset */
g_dmaCTRLPKT_RX->ELSOFFSET = 0; /* element source offset */
g_dmaCTRLPKT_RX->FRDOFFSET = 0; /* frame destination offset */
g_dmaCTRLPKT_RX->FRSOFFSET = 0; /* frame source offset */
g_dmaCTRLPKT_RX->PORTASGN = 4; /* port b */
g_dmaCTRLPKT_RX->RDSIZE = ACCESS_16_BIT; /* read size */
g_dmaCTRLPKT_RX->WRSIZE = ACCESS_16_BIT; /* write size */
g_dmaCTRLPKT_RX->TTYPE = FRAME_TRANSFER; /* transfer type */
g_dmaCTRLPKT_RX->ADDMODERD = ADDR_FIXED; /* address mode read */
g_dmaCTRLPKT_RX->ADDMODEWR = ADDR_INC1; /* address mode write */
g_dmaCTRLPKT_RX->AUTOINIT = AUTOINIT_ON; /* autoinit */
}
void setConfigSPIDMA(void)
{
g_dmaCTRL g_dmaCTRLPKT;
dmaEnableInterrupt(CONFIG_SPI_RX_DMA_CH, BTC); //Block transfer complete
dmaReqAssign(CONFIG_SPI_RX_DMA_CH, CONFIG_SPI_RX_DMA_REQ); //SPI2 RX
dmaReqAssign(CONFIG_SPI_TX_DMA_CH, CONFIG_SPI_TX_DMA_REQ); //SPI2 TX
dmaConfigSPICtrlTxPacket(&g_dmaCTRLPKT, (uint32_t)&ResponseData, CONFIG_SPI_TX_ADDR, CONFIG_SPI_HEADER_SIZE);
dmaSetCtrlPacket(CONFIG_SPI_TX_DMA_CH, g_dmaCTRLPKT);
dmaConfigSPICtrlRxPacket(&g_dmaCTRLPKT, CONFIG_SPI_RX_ADDR, (uint32_t)&RX_Data.PacketArray, CONFIG_SPI_HEADER_SIZE);
dmaSetCtrlPacket(CONFIG_SPI_RX_DMA_CH, g_dmaCTRLPKT);
dmaSetChEnable(CONFIG_SPI_RX_DMA_CH, DMA_HW); //SPI2 RX, hardware triggering
dmaSetChEnable(CONFIG_SPI_TX_DMA_CH, DMA_HW); //SPI2 TX, hardware triggering
dmaSetPriority(CONFIG_SPI_RX_DMA_CH, HIGHPRIORITY);
dmaSetPriority(CONFIG_SPI_TX_DMA_CH, HIGHPRIORITY);
CONFIG_SPI_PORT->GCR1 = (CONFIG_SPI_PORT->GCR1 & 0xFFFFFFFFU) | (0x1 << 24); //Enable SPI
CONFIG_SPI_PORT->INT0 = (0x1 << 16); //SPI_DMAREQ; Enable DMA REQ only after setting the SPIEN bit to 1.
}
void sendAndGetSPIData(uint32_t outputBuffer, uint32_t inputBuffer, uint32_t ucDataLength)
{
dmaRAMREG->PCP[CONFIG_SPI_TX_DMA_CH].ISADDR = outputBuffer;
dmaRAMREG->PCP[CONFIG_SPI_TX_DMA_CH].IDADDR = CONFIG_SPI_TX_ADDR;
dmaRAMREG->PCP[CONFIG_SPI_TX_DMA_CH].ITCOUNT = (ucDataLength << 16U) | 1;
dmaRAMREG->PCP[CONFIG_SPI_RX_DMA_CH].IDADDR = inputBuffer;
dmaRAMREG->PCP[CONFIG_SPI_RX_DMA_CH].ISADDR = CONFIG_SPI_RX_ADDR;
dmaRAMREG->PCP[CONFIG_SPI_RX_DMA_CH].ITCOUNT = (ucDataLength << 16U) | 1;
dmaSetChEnable(CONFIG_SPI_RX_DMA_CH, DMA_HW); //SPI2 RX, hardware triggering
dmaSetChEnable(CONFIG_SPI_TX_DMA_CH, DMA_HW); //SPI2 TX, hardware triggering
CONFIG_SPI_PORT->GCR1 = (CONFIG_SPI_PORT->GCR1 & 0xFFFFFFFFU) | (0x1 << 24); //Enable SPI
CONFIG_SPI_PORT->INT0 = (0x1 << 16); //SPI_DMAREQ; Enable DMA REQ only after setting the SPIEN bit to 1.
while((dmaREG->PEND & (1ul << 0)) != 0ul);
}
void getConfigSPIData(uint32_t buffer, uint32_t ucDataLength)
{
dmaRAMREG->PCP[CONFIG_SPI_RX_DMA_CH].IDADDR = buffer;
dmaRAMREG->PCP[CONFIG_SPI_RX_DMA_CH].ISADDR = CONFIG_SPI_RX_ADDR;
dmaRAMREG->PCP[CONFIG_SPI_RX_DMA_CH].ITCOUNT = (ucDataLength << 16U) | 1;
dmaSetChEnable(CONFIG_SPI_RX_DMA_CH, DMA_HW); //SPI2 RX, hardware triggering
dmaSetChEnable(CONFIG_SPI_TX_DMA_CH, DMA_HW); //SPI2 TX, hardware triggering
CONFIG_SPI_PORT->GCR1 = (CONFIG_SPI_PORT->GCR1 & 0xFFFFFFFFU) | (0x1 << 24); //Enable SPI
CONFIG_SPI_PORT->INT0 = (0x1 << 16); //SPI_DMAREQ; Enable DMA REQ only after setting the SPIEN bit to 1.
while((dmaREG->PEND & (1ul << 0)) != 0ul);
}
void dmaGroupANotification(dmaInterrupt_t inttype, uint32 channel)
{
CONFIG_SPI_PORT->INT0 &= ~(1ul << 16);
CONFIG_SPI_PORT->GCR1 &= ~(0x1 << 24);
ProcessSPI2();
}
void dmaFTCAInterrupt(void)
{
uint32 offset = dmaREG->FTCAOFFSET;
if (offset != 0U)
{
dmaGroupANotificationFTC(FTC, offset - 1U);
}
}
void dmaBTCAInterrupt(void)
{
uint32 offset = dmaREG->BTCAOFFSET;
if (offset != 0U)
{
dmaGroupANotification(BTC, offset - 1U);
}
}


