例如,用全双工DMA模式读SPI Flash芯片的数据,首先要发送2个命令字节,然后再读回3个数据字节。
但是,你必须读5个字节才行,前面2个字节是无用数据,因为发送前面2个字节时,SPI的接收电路也在工作。
处理的方法也比较简单,去掉前面2个字节,只保留后面3个字节就行了。
但是这样很不通用,每次读取时,前面的命令字节数是不定长的,后面的接收缓冲区也可能指向不同的数组,总不能为每个接收数组预留几个空字节吧。
但是ST的HAL库函数HAL_SPI_Receive_DMA就没有这个烦恼,直接指定接收缓冲区的地址就行,用不着手工去掉前面的无用字节
不知道AT32里面该怎么实现?
我的代码大概如此:
void spi_read(uint8_t *addr, uint32_t len)
{
//1. 配置RX DMA
//禁用DMA通道,否则不能改参数
dma_channel_enable(DMA2_CHANNEL1, FALSE);
//改参数后打开DMA
DMA2_CHANNEL1->dtcnt = len;
DMA2_CHANNEL1->maddr = (uint32_t)addr;
dma_channel_enable(DMA2_CHANNEL1, TRUE);
//2. 配置TX DMA,输出dummy数据,否则没有CLK
//禁用DMA通道,否则不能改参数
dma_channel_enable(DMA2_CHANNEL2, FALSE);
//改参数后打开DMA
DMA2_CHANNEL2->dtcnt = len;
DMA2_CHANNEL2->maddr = (uint32_t)addr;
dma_channel_enable(DMA2_CHANNEL2, TRUE);
//3. 等到传输完成标志=1
while (dma_flag_get(DMA2_FDT1_FLAG)==RESET){};
}
上面只是SPI DMA读取的代码。该代码执行前,先用spi_send发送N个字节,器件会返回M个字节,而spi_read的len必须等于N+M。
我希望,器件返回M个字节,那么spi_read的len就设置为M,不要再费劲从*addr指向的缓冲区里抠掉N个字节。
|