现在有点眉目,我的代码给你看看,看一下有什么问题。
1. 改了一下寄存器的定义,不使用库的bit写法
typedef struct {
__IO uint32_t CHANNELx_STATUS;
__IO uint32_t CHANNELx_INTEN;
__IO uint32_t CHANNELx_RST;
__IO uint32_t CHANNELx_STOP;
__IO uint32_t CHANNELx_CONFIG;
__IO uint32_t CHANNELx_CHAN_LENGTH;
__IO uint32_t CHANNELx_MEM_START_ADDR;
__IO uint32_t CHANNELx_MEM_END_ADDR;
__IO uint32_t CHANNELx_PERIPH_ADDR;
__IO uint32_t CHANNELx_CHAN_ENABLE;
__IO uint32_t CHANNELx_DATA_TRANS_NUM;
__IO uint32_t CHANNELx_INTER_FIFO_DATA_LEFT_NUM;
} DMA_Type_B;
2. DMA初始化:DMA_Type_B *dmaChannel[] =
{
(DMA_Type_B *)DMA2, (DMA_Type_B *)DMA3,
(DMA_Type_B *)DMA4, (DMA_Type_B *)DMA5,
};
CKGEN_Enable(CLK_DMA_AHB,1); /* Enable DMA AHB clock */
CKGEN_Enable(CLK_DMA_APB,1); /* Enable DMA APB clock */
CKGEN_SoftReset(SRST_DMA_AHB,1); /* Inactive DMA_AHB reset */
CKGEN_SoftReset(SRST_DMA_APB,1); /* Inactive DMA_APB reset */
dmaChannel[2 * port]->CHANNELx_RST = 1 << 1; //HARD_RST
dmaChannel[2 * port]->CHANNELx_RST = 0;
dmaChannel[2 * port + 1]->CHANNELx_RST = 1 << 1; //HARD_RST
dmaChannel[2 * port + 1]->CHANNELx_RST = 0;
3. SPI双工接口函数:
void spimTransferBytes(uint8_t port, uint8_t* wrBuf, uint8_t* rdBuf, uint16_t len)
{
SPI_Type* SPIx;
uint32_t spiBuf;
//uint8_t spiBuf[] = {0xaa, 0x55};
uint8_t dmaIndex = 0;
DMA_Type_B *dmaChannel[] =
{
(DMA_Type_B *)DMA2, (DMA_Type_B *)DMA3,
(DMA_Type_B *)DMA4, (DMA_Type_B *)DMA5,
};
if(len == 0 || port > 1)
return;
SPIx = spimGroup[port];
if(SPIx == SPI2)
dmaIndex = 2;
SPI_Disable(SPIx);
dmaChannel[dmaIndex]->CHANNELx_STATUS = 0;
dmaChannel[dmaIndex]->CHANNELx_INTEN = 0;
dmaChannel[dmaIndex]->CHANNELx_CONFIG =
(0 << 0) | //MEM2MEM 1bit
(3 << 1) | //CHAN_PRIORITY 2bit
(0 << 3) | //MEM_SIZE 2bit
(0 << 5) | //PERIPH_SIZE 2bit
(1 << 7) | //MEM_INCREAMENT 1bit
(0 << 8) | //PERIPH_INCREAMENT 1bit
(0 << 9) | //CHAN_CIRCULAR 1bit
(0 << 10) | //CH_DIR 1bit
(0 << 11); //MEM_BYTE_MODE 2bit
dmaChannel[dmaIndex]->CHANNELx_CHAN_LENGTH = len;
if(rdBuf == NULL)
{
dmaChannel[dmaIndex]->CHANNELx_MEM_START_ADDR = (uint32_t)(&spiBuf);
dmaChannel[dmaIndex]->CHANNELx_MEM_END_ADDR = (uint32_t)(&spiBuf);
}
else
{
dmaChannel[dmaIndex]->CHANNELx_MEM_START_ADDR = (uint32_t)(rdBuf);
dmaChannel[dmaIndex]->CHANNELx_MEM_END_ADDR = (uint32_t)rdBuf + len;
}
dmaChannel[dmaIndex]->CHANNELx_PERIPH_ADDR = (uint32_t)&(SPIx->DATA);
dmaChannel[dmaIndex]->CHANNELx_CHAN_ENABLE = 1;
dmaChannel[dmaIndex + 1]->CHANNELx_STATUS = 0;
dmaChannel[dmaIndex + 1]->CHANNELx_INTEN = 0;
dmaChannel[dmaIndex + 1]->CHANNELx_CONFIG =
(0 << 0) | //MEM2MEM 1bit
(3 << 1) | //CHAN_PRIORITY 2bit
(0 << 3) | //MEM_SIZE 2bit
(0 << 5) | //PERIPH_SIZE 2bit
(1 << 7) | //MEM_INCREAMENT 1bit
(0 << 8) | //PERIPH_INCREAMENT 1bit
(0 << 9) | //CHAN_CIRCULAR 1bit
(1 << 10) | //CH_DIR 1bit
(0 << 11); //MEM_BYTE_MODE 2bit
dmaChannel[dmaIndex + 1]->CHANNELx_CHAN_LENGTH = len;
if(wrBuf == NULL)
{
dmaChannel[dmaIndex + 1]->CHANNELx_MEM_START_ADDR = (uint32_t)(&spiBuf);
dmaChannel[dmaIndex + 1]->CHANNELx_MEM_END_ADDR = (uint32_t)(&spiBuf);
}
else
{
dmaChannel[dmaIndex + 1]->CHANNELx_MEM_START_ADDR = (uint32_t)(wrBuf);
dmaChannel[dmaIndex + 1]->CHANNELx_MEM_END_ADDR = (uint32_t)wrBuf + len;
}
dmaChannel[dmaIndex + 1]->CHANNELx_PERIPH_ADDR = (uint32_t)&(SPIx->DATA);
dmaChannel[dmaIndex + 1]->CHANNELx_CHAN_ENABLE = 1;
//Printf("DMA RX Config: %x\n", dmaChannel[dmaIndex]->CHANNELx_CONFIG);
//Printf("DMA TX Config: %x\n", dmaChannel[dmaIndex + 1]->CHANNELx_CONFIG);
SPI_Enable(SPIx);
//wait for finish
while((dmaChannel[dmaIndex + 1]->CHANNELx_STATUS & 0x01) == 0);
//disable DMA
dmaChannel[dmaIndex]->CHANNELx_CHAN_ENABLE = 0;
dmaChannel[dmaIndex + 1]->CHANNELx_CHAN_ENABLE = 0;
}
如果CHANNELx_CONFIG是上面的配置,SPI通信不通,如果改成MEM_SIZE = 2,MEM_BYTE_MODE = 3,前面的SPI通信正常,但是写入数据的顺序似乎有错误,因为我这边接的SPI设备是彩屏驱动,我刷全屏为绿色,显示是另外的颜色。
|