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:不能使用 SPI1 和 DMA

Guru**** 2885260 points
请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

https://e2e.ti.com/support/microcontrollers/arm-based-microcontrollers-group/arm-based-microcontrollers/f/arm-based-microcontrollers-forum/1638839/tms570ls3137-tms570ls3137-not-able-to-use-spi1-and-dma

器件型号: TMS570LS3137

我将 MibSPI1 用作“标准 SPI“、以便与 FRAM 和闪存存储器通信。

与 FRAM 和闪存的通信在池和中断模式下可以正常工作、但我无法将其用于 DMA。

 

下面是一个额外代码、用于演示如何尝试使用 SPI1 设置 DMA 传输

#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 在 SCI 下工作正常、但对 SPI1 不起作用。 我的代码中有什么问题?

由于闪存的 SPI 传输很长(每次传输高达 580 字节)、我希望将 DMA 与 SPI1 配合使用以减少 CPU 负载。

 

感谢您的帮助

此致

Fabrice Mousset