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.

TMS570LS3137: Transmitting Data via DMA in between two SPIs (only for transmitting, receiving will be held as it is)

Part Number: TMS570LS3137


Hello, I am trying to transmit a data via DMA, but for receving I don't want to use DMA for now.

In debugging, I just see the first block of the data is sent but rest of them seem as zero in the expression of RX_Data.

Here the codes,

/* USER CODE BEGIN (0) */
/* USER CODE END */

/* Include Files */

/* USER CODE BEGIN (1) */

#include "sys_common.h"
#include "spi.h"
#include "sys_dma.h"
#include "rti.h"
#include <stdio.h>
#include <string.h>

#define SPI3_TX_ADDR ((uint32_t)(&(spiREG3->DAT1)) +2)
#define SPI1_RX_ADDR ((uint32_t)(&(spiREG1->BUF)) + 2)

unsigned int FrameCnt = 16;

/* USER CODE END */

/* USER CODE BEGIN (2) */

uint16_t TX_Data[16] = { 0x02, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, 0x10 };
uint16_t RX_Data[16] = { 0 };

g_dmaCTRL g_dmaCTRLPKT_TX;

void dmaConfigCtrlTxPacket(uint32 sadd, uint32 dadd, uint16 ElmntCnt, uint16 FrameCnt)
{

g_dmaCTRLPKT_TX.SADD = (uint32_t)TX_Data;

g_dmaCTRLPKT_TX.DADD = (uint32_t)RX_Data;

g_dmaCTRLPKT_TX.CHCTRL = 0;

g_dmaCTRLPKT_TX.ELCNT = ElmntCnt;

g_dmaCTRLPKT_TX.FRCNT = FrameCnt;

g_dmaCTRLPKT_TX.ELDOFFSET = 0;

g_dmaCTRLPKT_TX.ELSOFFSET = 0; // sizeof(uint16_t);

g_dmaCTRLPKT_TX.FRDOFFSET = 0;

g_dmaCTRLPKT_TX.FRSOFFSET = sizeof(uint16_t) ;

g_dmaCTRLPKT_TX.PORTASGN = 4;

g_dmaCTRLPKT_TX.RDSIZE = ACCESS_16_BIT;

g_dmaCTRLPKT_TX.WRSIZE = ACCESS_16_BIT;

g_dmaCTRLPKT_TX.TTYPE = FRAME_TRANSFER;

g_dmaCTRLPKT_TX.ADDMODERD = ADDR_OFFSET;
g_dmaCTRLPKT_TX.ADDMODEWR = ADDR_OFFSET;

g_dmaCTRLPKT_TX.AUTOINIT = AUTOINIT_ON;
}


/* USER CODE END */
int main(void) {

spiDAT1_t dataconfig1_t;

dataconfig1_t.CS_HOLD = FALSE;
dataconfig1_t.WDEL = TRUE;
dataconfig1_t.DFSEL = SPI_FMT_0;
dataconfig1_t.CSNR = 0xFD;

/* Enable IRQ - Clear I flag in CPS register */
_enable_IRQ();

/* - initializing spi*/
spiInit();

/* - enabling dma module */
dmaEnable();

/* - configuring dma TX control packets */
dmaConfigCtrlTxPacket((uint32_t)&TX_Data, SPI3_TX_ADDR, 16, FrameCnt);
dmaSetCtrlPacket(DMA_CH1, g_dmaCTRLPKT_TX);

dmaReqAssign(DMA_CH1, 15); //SPI3 TX

dmaSetPriority(DMA_CH1, HIGHPRIORITY);

spiREG3->INT0 = (0x1 << 16);

dmaSetChEnable(DMA_CH1, DMA_HW); //SPI3 TX, hardware triggering


spiSendAndGetData(spiREG1, &dataconfig1_t, 16, TX_Data, RX_Data);

while(1);

/* USER CODE END */

}


/* USER CODE BEGIN (4) */
/* USER CODE END */

How can I send the whole data written in TX_Data? Thanks for your help in advance.

Caner

  • I have re-organised the codes as,

    int main(void) {


    /* - initializing spi*/
    spiInit();

    /* - enabling dma module */
    dmaEnable();

    spiREG3->DAT1 |= (uint32_t)TX_Data;


    /* - configuring dma TX control packets */
    dmaConfigCtrlTxPacket((uint32_t)&TX_Data, (uint32_t)&RX_Data, 16, FrameCnt);

    //(uint32_t)(&(spiREG1->SPI1_RX_ADDR))

    dmaSetCtrlPacket(DMA_CH1, g_dmaCTRLPKT_TX);

    dmaReqAssign(DMA_CH1, 15); //SPI3 TX

    dmaSetPriority(DMA_CH1, HIGHPRIORITY);

    spiREG3->INT0 = (0x1 << 16); 

    dmaSetChEnable(DMA_CH1, DMA_HW); //SPI3 TX, hardware triggering


    while(1);

    I can see the data written on the DAT1 register of SPI3. However, I can't transmit this data to RxBuf of SPI1. 

  • Hi,

    The DMA is used to transfer data from one memory location to other memory location.

    In DMA channel control packet configuration, the destination addr should be SPI DAT1 register rather than your RX_Data array. 

    Please refer to DMA chapter in TRM about how to use the DMA.

  • Hi QJ Wang, thanks for your reply. I have seen that mistake later and rewritten the codes.

    This time, it only sends the first data of the TX_Data array but not the rest. 

    .....

    void dmaConfigCtrlTxPacket(uint32 sadd, uint32 dadd, uint16 ElmntCnt, uint16 FrameCnt)
    {

    g_dmaCTRLPKT_TX.SADD = sadd;

    g_dmaCTRLPKT_TX.DADD = dadd;

    g_dmaCTRLPKT_TX.CHCTRL = 0;

    g_dmaCTRLPKT_TX.ELCNT = ElmntCnt; //1;

    g_dmaCTRLPKT_TX.FRCNT = FrameCnt; //1;

    g_dmaCTRLPKT_TX.ELDOFFSET = 0;

    g_dmaCTRLPKT_TX.ELSOFFSET = sizeof(uint16_t); 

    g_dmaCTRLPKT_TX.FRDOFFSET = 0;

    g_dmaCTRLPKT_TX.FRSOFFSET = sizeof(uint16_t); 

    g_dmaCTRLPKT_TX.PORTASGN = 4;

    g_dmaCTRLPKT_TX.RDSIZE = ACCESS_16_BIT;

    g_dmaCTRLPKT_TX.WRSIZE = ACCESS_16_BIT;

    g_dmaCTRLPKT_TX.TTYPE = FRAME_TRANSFER;

    g_dmaCTRLPKT_TX.ADDMODERD = ADDR_OFFSET;
    g_dmaCTRLPKT_TX.ADDMODEWR = ADDR_FIXED;

    g_dmaCTRLPKT_TX.AUTOINIT = AUTOINIT_ON;
    }


    /* USER CODE END */
    /* USER CODE BEGIN (3) */
    int main(void)
    {
    spiDAT1_t dataconfig1_t;

    dataconfig1_t.CS_HOLD = FALSE;
    dataconfig1_t.WDEL = TRUE;
    dataconfig1_t.DFSEL = SPI_FMT_0;
    dataconfig1_t.CSNR = 0xFD;


    spiInit();


    dmaEnable();


    dmaConfigCtrlTxPacket((uint32_t)&TX_Data, SPI3_TX_ADDR, 16, 1);

    dmaSetCtrlPacket(DMA_CH1, g_dmaCTRLPKT_TX);

    dmaReqAssign(DMA_CH1, 15); //SPI3 TX

    dmaSetPriority(DMA_CH1, HIGHPRIORITY);

    dmaSetChEnable(DMA_CH1, DMA_HW);

    spiREG3->INT0 = (0x1 << 16);

    while(1)
    {

    spiReceiveData(spiREG1, &dataconfig1_t, 16, RX_Data);
    }


    /* USER CODE END */

    }


    /* USER CODE BEGIN (4) */

    /* USER CODE END */

  • Why do you use sizeof(uint16_t) for source frame index and source element index?

  • For frame source offset, actually I wanted to increase the source address by 1 bit much after each frame transfer, but I couldn't get a satisfying result. After these configurations, I could see each data is sent to SPI3 DAT1 one by one but I did not get the direct effect of using it for this purpose, truly.

    but then I thought that if I can send the data properly, I should keep them just about later examining and focused on receiving the data. Now, I have set elsoffset as 0 but if I do the same thing for frsoffset, it doesn't send any data. 

    Now I am also wondering if I can send data via DMA and receive as normal by using SPI loopback? I am also aware, the concept you have mentioned has to be understood very well but will it be wrong to keep them as they are set, and look for receiving the data Sir? This is because, I can send the data to SPIREG3 DAT1. Now I want to receive them.

  • Did the example project (SPI+DMA) work on your setup? 

    The TX DMA is triggered by the HW request. the TX DMA request is generated only after the data in SPIDAT1 is copied to the TX shift register. The SPIEN must be set to 1 before SPIDAT1 is written.

    To enable SPI3:

    spiREG3->GCR1 = (spiREG3->GCR1 & 0xFFFFFFFFU) | (0x1 << 24);  //Enable SPI

    For the receiver side, it's better to use interrupt mode and read the data in the ISR.

  • Hello again Sir, sorry for late reply. I can send and receive data as requested, and thanks a lot for suggestion about using interrupt mode for the receiver side.