This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

TMS570LC4357: SPI1 cannot use DMA for first data

Part Number: TMS570LC4357

Hi team,

SPI dual machine communication test on TMS570LC4357. SPI3 is the master and SPI1 is the slave. The slave receives and transmits data through the DMA.

During the test, the scope shows that the master can normally generate the CS, SCK, and MOSI signals. Miso reads as 0. The hardware connection is confirmed to be correct, but the slave SPI1 is unable to receive or transmit data (transmitted data is the default value of 0x00). The following are the DMA configurations: 

uint16 SPI1_TX_Data[D_SIZE];
uint16 SPI1_RX_Data[D_SIZE];

g_dmaCTRL g_dmaCTRLPKT1; 
g_dmaCTRL g_dmaCTRLPKT2;

void DMA_Config(void)
{
dmaEnable();
//DMA transmit channel 0
g_dmaCTRLPKT1.SADD = (uint32)&SPI1_TX_Data[0]; // source address
g_dmaCTRLPKT1.DADD = (uint32)(&(spiREG1->DAT1)); // destination address
g_dmaCTRLPKT1.CHCTRL = 0; // channel control
g_dmaCTRLPKT1.FRCNT = 1; // frame count
g_dmaCTRLPKT1.ELCNT = D_SIZE; // element count
g_dmaCTRLPKT1.ELDOFFSET = 0; // element destination offset
g_dmaCTRLPKT1.ELSOFFSET = 0; // element source offset
g_dmaCTRLPKT1.FRDOFFSET = 0; // frame destination offset
g_dmaCTRLPKT1.FRSOFFSET = 0; // frame source offset
g_dmaCTRLPKT1.PORTASGN = PORTA_READ_PORTB_WRITE;
g_dmaCTRLPKT1.RDSIZE = ACCESS_16_BIT; // read size
g_dmaCTRLPKT1.WRSIZE = ACCESS_16_BIT; // write size
g_dmaCTRLPKT1.TTYPE = FRAME_TRANSFER; // transfer type
g_dmaCTRLPKT1.ADDMODERD = ADDR_INC1; // address mode read
g_dmaCTRLPKT1.ADDMODEWR = ADDR_FIXED; // address mode write
g_dmaCTRLPKT1.AUTOINIT = AUTOINIT_ON; // autoinit

//DMA receive channel 1
g_dmaCTRLPKT2.SADD = (uint32)(&(spiREG1->BUF)); // source address
g_dmaCTRLPKT2.DADD = (uint32)&SPI1_RX_Data[0]; // destination address
g_dmaCTRLPKT2.CHCTRL = 0; // channel control
g_dmaCTRLPKT2.FRCNT = 1; // frame count
g_dmaCTRLPKT2.ELCNT = D_SIZE; // element count
g_dmaCTRLPKT2.ELDOFFSET = 0; // element destination offset
g_dmaCTRLPKT2.ELSOFFSET = 0; // element destination offset
g_dmaCTRLPKT2.FRDOFFSET = 0; // frame destination offset
g_dmaCTRLPKT2.FRSOFFSET = 0; // frame destination offset
g_dmaCTRLPKT2.PORTASGN = PORTB_READ_PORTA_WRITE; 
g_dmaCTRLPKT2.RDSIZE = ACCESS_16_BIT; // read size
g_dmaCTRLPKT2.WRSIZE = ACCESS_16_BIT; // write size
g_dmaCTRLPKT2.TTYPE = FRAME_TRANSFER; // transfer type
g_dmaCTRLPKT2.ADDMODERD = ADDR_FIXED; // address mode read
g_dmaCTRLPKT2.ADDMODEWR = ADDR_INC1; // address mode write
g_dmaCTRLPKT2.AUTOINIT = AUTOINIT_ON; // autoinit


/* - setting dma control packets */
dmaSetCtrlPacket(DMA_CH0,g_dmaCTRLPKT1); // CH0--transmit
dmaSetCtrlPacket(DMA_CH1,g_dmaCTRLPKT2); // CH1--receive

dmaSetPriority(DMA_CH0, LOWPRIORITY);
dmaSetPriority(DMA_CH1, HIGHPRIORITY);

spiREG1->INT0 = (spiREG1->GCR1 & 0xFFFEFFFFU) | 0x00010000U; //Enable DMA request for SPI1 
dmaReqAssign(DMA_CH0, DMA_REQ1); //Request line 1:SPI1 TX
dmaReqAssign(DMA_CH1, DMA_REQ0); //Request line 0:SPI1 RX

/* - setting the dma channel to trigger on h/w request */
dmaSetChEnable(DMA_CH0,DMA_HW); // Enable channel 0 on hardware event
dmaSetChEnable(DMA_CH1,DMA_HW); // Enable channel 1 on hardware event

dmaEnableInterrupt(DMA_CH1,FTC,DMA_INTA); //Frame transfer complete entry interrupt, where DMA reception is interrupted, meaning that a frame has completed a frame transfer from the peripheral to memory 
}

int main(void)
{
/* USER CODE BEGIN (3) */
spiDAT1_t dataconfig1_t;
dataconfig1_t.CS_HOLD = TRUE;
dataconfig1_t.WDEL = TRUE;
dataconfig1_t.DFSEL = SPI_FMT_0;
dataconfig1_t.CSNR = 0xFE;

loadDataPattern2(D_SIZE,SPI1_TX_Data); //F....0
loadDataPattern1(D_SIZE,SPI3_TX_Data); //0....F

rtiInit();
gioInit();
sciInit();
spiInit();

sciEnableNotification(sciREG1,SCI_RX_INT);
rtiEnableNotification(rtiREG1,rtiNOTIFICATION_COMPARE0);
rtiStartCounter(rtiREG1,rtiCOUNTER_BLOCK0);

DMA_Config(); //Configure the DMA channel and enable its frame transmission complete interrupt 
spiREG1->GCR1 = (spiREG1->GCR1 & 0xFEFFFFFFU) | 0x01000000U;
spiREG3->GCR1 = (spiREG3->GCR1 & 0xFEFFFFFFU) | 0x01000000U;
_enable_IRQ_interrupt_();

while(1)
{
if(RTI_FLAG==1)
{
TX_DATA[10]+=0x01;
gioToggleBit(gioPORTB,6);
gioToggleBit(gioPORTB,7);
printf("hahaha\r\n");
spiTransmitAndReceiveData(spiREG3, &dataconfig1_t, D_SIZE, SPI3_TX_Data, SPI3_RX_Data);
memset(SPI3_RX_Data,0,D_SIZE);
RTI_FLAG=0;
}
}

/* USER CODE END */

return 0;
}

Could you help check is there anything need to be modified? Thanks.

Best Regards,

Cherry