主题中讨论的其他器件: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