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: TMS570LS3137: Not able to use SPI1 and DMA

Part Number: TMS570LS3137

I use MibSPI1 as "Standard SPI" to communicate with a FRAM and a FLASH memory.

Communication with FRAM and FLASH works in pooling and interrupt mode, but I am not able to use it with DMA.

 

Here a code extra to show how I try to setup DMA transfer with SPI1

#define SPI1_TX_ADDR    ((uint32_t)(&(spiREG1->DAT1)) + 3)
#define SPI1_RX_ADDR    ((uint32_t)(&(spiREG1->BUF)) + 3)

#define DMA_SPI1_RX             (0u)
#define DMA_SPI1_TX             (1u)

#define DMA_SPI1_RX_CH     DMA_CH0
#define DMA_SPI1_TX_CH     DMA_CH1

g_dmaCTRL dmaCTRLPKT_spi1_rx = {
    .SADD      = SPI1_RX_ADDR,  // source address
    .DADD      = 0,   // destination address
    .CHCTRL    = 0,             // is last channel
    .FRCNT     = 1,             // frame count
    .ELCNT     = 1,             // element count
    .ELDOFFSET = 0,             // element destination offset
    .ELSOFFSET = 0,             // element destination offset
    .FRDOFFSET = 0,             // frame destination offset
    .FRSOFFSET = 0,             // frame destination offset
    .PORTASGN  = 4,             // port b
    .RDSIZE    = ACCESS_8_BIT,  // read size
    .WRSIZE    = ACCESS_8_BIT,  // write size
    .TTYPE     = FRAME_TRANSFER,// transfer type
    .ADDMODERD = ADDR_FIXED,    // reads from a fixed register
    .ADDMODEWR = ADDR_FIXED,    // each channel writes a fixed address
    .AUTOINIT  = AUTOINIT_OFF   // no automatic restart
};

g_dmaCTRL dmaCTRLPKT_spi1_tx = {
    .SADD      = 0,   // source address
    .DADD      = SPI1_TX_ADDR,  // destination address
    .CHCTRL    = 0,             // is last channel
    .FRCNT     = 1,             // frame count
    .ELCNT     = 1,             // element count
    .ELDOFFSET = 0,             // element destination offset
    .ELSOFFSET = 0,             // element destination offset
    .FRDOFFSET = 0,             // frame destination offset
    .FRSOFFSET = 0,             // frame destination offset
    .PORTASGN  = 4,             // port b
    .RDSIZE    = ACCESS_8_BIT,  // read size
    .WRSIZE    = ACCESS_8_BIT,  // write size
    .TTYPE     = FRAME_TRANSFER,// transfer type
    .ADDMODERD = ADDR_FIXED,    // reads from a fixed address
    .ADDMODEWR = ADDR_FIXED,    // writes a fixed register
    .AUTOINIT  = AUTOINIT_OFF   // no automatic restart
};

void start_spi1_dma_transfer(uint32_t msg_size, uint8_t * pTxdata, uint8_t * pRxdata)
{
    if (pTxdata)
    {
        dmaCTRLPKT_spi1_tx.SADD = (uint32_t)pTxdata;
        dmaCTRLPKT_spi1_tx.ADDMODERD = ADDR_INC1; // auto increment read pointer
    }
    else
    {
        dmaCTRLPKT_spi1_tx.SADD = (uint32_t)&dummy_byte;   // dummy data
        dmaCTRLPKT_spi1_tx.ADDMODERD = ADDR_FIXED; // fixed read pointer
    }

    if (pRxdata)
    {
        dmaCTRLPKT_spi1_rx.DADD = (uint32_t)pRxdata;
        dmaCTRLPKT_spi1_rx.ADDMODEWR = ADDR_INC1; // auto increment write pointer
    }
    else
    {
        dmaCTRLPKT_spi1_rx.DADD = (uint32_t)&dummy_byte; // dummy destination
        dmaCTRLPKT_spi1_rx.ADDMODEWR = ADDR_FIXED; // fixed write pointer
    }

    dmaCTRLPKT_spi1_tx.ELCNT = msg_size;
    dmaCTRLPKT_spi1_rx.ELCNT = msg_size;

    dmaSetCtrlPacket(DMA_SPI1_TX_CH, &dmaCTRLPKT_spi1_tx);
    dmaSetCtrlPacket(DMA_SPI1_RX_CH, &dmaCTRLPKT_spi1_rx);

    // enable dma/spi1 transmission/reception
    dmaSetChEnable(DMA_SPI1_RX_CH, DMA_HW); // SPI1 RX, hardware triggering
    dmaSetChEnable(DMA_SPI1_TX_CH, DMA_HW); // SPI1 TX, hardware triggering


    spiREG1->INT0 = (1<<16);
}

uint8 buffer_spi[8]= {1, 2, 3, 4, 5, 6, 7, 8};
void test(void)
{
    spiInit();
    
    /* setup DMA channel SPI1 reception */
    dmaReqAssign(DMA_SPI1_RX_CH, DMA_SPI1_RX);
    dmaEnableInterrupt(DMA_SPI1_RX_CH, BTC);   // enabled Block Transfer Complete interrupt

    /* setup DMA channel SPI1 transmission */
    dmaReqAssign(DMA_SPI1_TX_CH, DMA_SPI1_TX);
    dmaEnableInterrupt(DMA_SPI1_TX_CH, BTC);   // enabled Block Transfer Complete interrupt

    /* setup transfer configuration */
    spiREG1->DAT1 = ((uint32)SPI_FMT_1<< 24U) |
                    (0U << 16U) |   /* chip select */
                    (0U << 26)   |  /* no write delay */
                    (1U << 28) |  /* chip select hold */
                    (0x00000000U);

    /* start SPI transfer */
    start_spi1_dma_transfer(8, buffer_spi, buffer_spi);
}

DMA works fine with SCI, but not with the SPI1. What is wrong in my code?

I want to use DMA with SPI1 to reduce CPU load, as SPI transfer with FLASH are long (up to 580 bytes per transfer).

 

Thanks for any help

Regards

Fabrice Mousset