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.

[参考译文] TMS320F280025C:使用与 DMA 集成的 SPI 外设无法读取 SD 卡

Guru**** 2524550 points
Other Parts Discussed in Thread: C2000WARE

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

https://e2e.ti.com/support/microcontrollers/c2000-microcontrollers-group/c2000/f/c2000-microcontrollers-forum/959084/tms320f280025c-not-able-to-read-the-sd-card-using-spi-peripheral-integrated-with-dma

器件型号:TMS320F280025C
主题中讨论的其他器件:C2000WARE

您好!

美好的夜晚!!!

我使用 SPI 模块通过阻止 TMS320F28002x 的非 FIFO API 测试了 SD 卡的读取和写入操作、并且工作正常(使用了 c2000ware 中提供的 SD 卡库)。

但是、当我使用 DMA 模块进行尝试时、我将面临两个主要问题、如下所述。

1.当我发送数据块时,我将收到一个额外的字节,我必须通过一个额外的读取函数"SPI_readDataBlockingFIFO( SPIB_BASE );"来处理该字节。

2.当我必须从 SD 卡读取数据块时,我没有收到预期的数据。

观察结果:

在这两种情况下、我都获得了 DMA 的 RX 和 TX 中断

请找到以下用于测试的 SPI、DMA 和代码配置。 请尽快告诉我出错的地方。

/*数据传输函数*/

静态 BOOL xmit_datablock (
const 字节*缓冲区、/*要传输的512字节数据块*/
字节令牌/*数据/停止令牌*/
)

字节 RESP、wc;

如果(WAIT_READY()!= 0xFF)
返回 false;

Xmit_spi (token);/* Xmit data token */
如果(token!= 0xFD)/*是数据令牌*/

uint16_t I_U16 = 0;
TrnsmTRY_ove_Flag = 0;

for (I_U16 = 0;I_U16 < 512;I_U16++)

sData[ I_U16 ]=(buff [ I_U16 ]<<8);

/*通过 DMA 将512字节数据块发送到 SDMMC */
// memcpy (sData,buff << 8,512);

dma_startChannel( dma_ch6_BASE );
dma_startChannel( dma_ch5_base );

/*通过 DMA 传输数据块*/

while (!Trnsmitue_over_Flag );

Xmit_SPI (0xFF);/* CRC (虚拟)*/
Xmit_SPI( 0xFF );
RESP = RCVR_SPI ();/*接收数据响应*/

RESP = SPI_readDataBlockingFIFO (SPIB_BASE);

如果(RESP & 0x1F)!= 0x05)/*如果不接受,则返回错误*/
返回 false;

返回 true;

/*读取数据块*/

静态 BOOL RCVR_datablock (
用于存储接收到的数据的字节*缓冲区、//
UINT BTR /*字节计数(必须为偶数)*/
)

字节令牌;

Timer1 = 10U;
Do /* Wait for data packet in timeout of 100ms */

令牌= RCVR_SPI ();

while ((token ==0xFFU)&& Timer1);

if (token!= 0xFE)
返回 false;//如果数据令牌无效,返回时出错*/

TrnsmTRY_ove_Flag = 0;

/*虚拟写入 DMA 寄存器*/
memset( sData,0xFF00,BTR );

dma_startChannel( dma_ch6_BASE );
dma_startChannel( dma_ch5_base );

/*从 RX 缓冲区读取数据*/

uint16_t temp = 0;
temp = SPI_readDataBlockingFIFO( SPIB_BASE );

while (! Trnsmyne_over_Flag );
memcpy( buff、RDATA、BTR );

buff [ BTR ]= temp;

RCVR_SPI();/*丢弃 CRC */
RCVR_SPI();

返回 true;/*成功返回*/

/* SPI 初始化*/

空 InitSpiBFifo(空)

/*配置 SPI 相关 GPIO 的*/
InitSpiBGpio();

/*在配置 SPI 模块之前将其复位。 *
SPI_disableModule( SPIB_BASE );

/* SPI 配置。 使用500kHz SPICLK 和8位字大小
*模式0操作 SD 卡
*
SPI_setConfig (SPIB_BASE、DEVICE_LSPCLK_FREQ、SPI_PROT_POL0PHA0、
SPI_MODE_MASTER、00000、SPI_DATA_WIDTH_8_Bits);

/*禁用环回模式*/
SPI_disableLoopback ( SPIB_BASE );

/*设置仿真时 SPI 操作的行为
*挂起发生
*
SPI_setEmulationMode( SPIB_BASE,SPI_emulation_free_run );


/* FIFO 和中断配置*/
SPI_enableFIFO( SPIB_BASE );
SPI_clearInterruptStatus (SPIB_BASE、SPI_INT_TXFF | SPI_INT_RXFF);
SPI_setFIFOInterruptLevel (SPIB_BASE、SPI_FIFO_TX1、SPI_FIFO_RX1);
SPI_enableInterrupt (SPIB_BASE、SPI_INT_RXFF | SPI_INT_TXFF);

/*启用模块。 *
SPI_enableModule( SPIB_BASE );

/* DMA 配置*/

空 InitDma(空)

/*此文件中使用的中断被重新映射到 ISR 函数*/
interrupt_register (INT_DMA_CH5、&DmaCh5TxIsr);
interrupt_register (INT_DMA_CH6、&DmaCh6RxIsr);

/*设置用于 SPI 的 DMA、初始化用于 FIFO 模式的 SPI */
/*初始化 DMA */
dma_initController();


/*为 TX 配置 DMA 通道5。 当 FIFO 中有足够的空间时、即数据
将从 sData 缓冲器传输到 SPI 模块的发送
缓冲寄存器。
*

dma_configAddresses (dma_ch5_base、(uint16_t *)(SPIB_BASE + SPI_O_TXBUF)、
sData);
dma_configBurst (dma_ch5_base,1、1、0);
dma_configTransfer( dma_ch5_base,512,1,0 );
DMA_configMode (DMA_CH5_base、DMA_TRIGGER_SPIBTX、DMA_CFG_OneShot_disable |
DMA_CFG_Continuous_disable | DMA_CFG_Size_16BIT );

/*配置 DMA Ch5中断*/
dma_setInterruptMode (dma_ch5_base、dma_int_at_end);
dma_enableInterrupt (dma_ch5_base);
dma_enableTrigger (dma_ch5_base);


/*为 RX 配置 DMA 通道6。 当 FIFO 至少包含8个字到时
读取时、数据将从 SPI 模块的接收缓冲器传输
RDATA 缓冲区。
*

DMA_configAddresses (DMA_CH6_BASE、RDATA、
(uint16_t *)(SPIB_BASE + SPI_O_RXBUF);
dma_configBurst (dma_ch6_BASE,1、0、1);
dma_configTransfer( dma_ch6_BASE,512,0,1 );
DMA_configMode (DMA_CH6_BASE、DMA_TRIGGER_SPIBRX、DMA_CFG_OneShot_disable |
DMA_CFG_Continuous_disable | DMA_CFG_Size_16BIT );

/*配置 DMA 通道6中断*/
dma_setInterruptMode (dma_ch6_BASE、dma_INT_at_end);
DMA_enableInterrupt (DMA_CH6_BASE);
dma_enableTrigger (dma_ch6_BASE);

/*启用 DMA 所需的中断*/
interrupt_enable (INT_DMA_CH5);
interrupt_enable (INT_DMA_CH6);

/*启用全局中断(INTM)和实时中断(DBGM)*/
EINT;
ERTM;

/* DMA 通道5 ISR */
_interrupt void DmaCh5TxIsr( void )

dma_stopChannel( dma_ch5_base );
interrupt_clearACKGroup( interrupt_ack_group7 );
返回;

/* DMA 通道6 ISR */
_interrupt void DmaCh6RxIsr( void )

dma_stopChannel( dma_ch6_BASE );
interrupt_clearACKGroup( interrupt_ack_group7 );

Trnsmyne_over_Flag = 1;

谢谢、此致、

Amol  

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

    Amol、

    [报价]/* SPI 配置。 使用500kHz SPICLK 和8位字大小
    *模式0操作 SD 卡
    *
    SPI_setConfig (SPIB_BASE、DEVICE_LSPCLK_FREQ、SPI_PROT_POL0PHA0、
    SPI_MODE_MASTER、00000、SPI_DATA_WIDTH_8_Bits);

    [/报价]

    为什么将 SPI 波特率设置为00000?

    [引述] 1. 当我发送一个数据块时,我将收到一个额外的字节,我必须通过一个额外的读取函数"SPI_readDataBlockingFIFO( SPIB_BASE );"来处理它

    我相信您每次只发送1个字、如果是、您应该将 TXFFIL 设置为0。

    原因:只有当 TX FIFO 为空时才需要触发 SPITXDMA。

    我不确定 xmit_spi()函数和 RCVR_spi()函数的内容。 因此、我无法对此进行评论。 但是、您的 DMA 配置看起来不错。 在发送/接收时、您是否使用 SPI 逻辑分析仪来读取总线的内容。

    此致、

    曼诺伊

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

    您好、Manoj、

    感谢您的即时响应。

    以下是我的观点。

    SPI 模块的波特率为500kHz。 复制粘贴错误

    2. xmit_spi()函数和 RCVR_spi()函数的内容是  

    静态字节 RCVR_SPI (空)

    volatile DWORD rcvdat;

    /*写入虚拟数据*/
    SPI_writeDataBlockingFIFO (SPIB_BASE、0xFF00U);

    /*从 RX 缓冲区读取数据*/
    rcvdat = SPI_readDataBlockingFIFO( SPIB_BASE );

    rcvdat = rcvdat & 0xFF;

    return (byte) rcvdat;

    静态空 xmit_SPI (字节 dat)/*由 ADJ 更改*/


    //包含的文件,如 integer.h,用于 DWORD 定义
    volatile DWORD rcvdat;

    /*将数据写入 TX 缓冲区*/
    spi_writeDataBlockingFIFO( SPIB_BASE,(uint16_t)( dat <<8U )));

    /*写入期间读取的清除数据*/
    rcvdat = SPI_readDataBlockingFIFO( SPIB_BASE );

    3.对于基本测试、我使用 TXFFIL 作为1、但在将来我将提高 TX 级别。

    -我将 尝试将 TXFFIL 设为0,将捕获逻辑分析仪上的波形,并在明天分享结果。

    4.我在 之前的查询中附加了用于 接收数据的代码片段。  请告诉我为何未收到预期数据。 我是否错过了任何内容?

    谢谢、此致、

    Amol

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

    Amol、

    如果您已将 DMA 配置为发送和接收、为什么要使用 xmit_SPI 和 RCVR_SPI 函数。 此函数使用您尝试使用 DMA 写入/读取的 CPU 直接写入 SPITXBUF 并从 SPIRXBUF 读取。

    我建议查看以下项目路径中可用的 SPI_ex3_loopback_DMA 项目:

    \driverlib\f28004x\examples\spi\

    此致、

    曼诺伊

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

    此问题是否已解决? 我可以关闭此主题吗?