#include "drv_dma.h" #include "drv_clk.h" #include "drv_misc.h" #include "kit_time.h" #include "kit_debug.h" #define DMA_IT_TC ((uint32_t)0x00000002) #define DMA_IT_HT ((uint32_t)0x00000004) #define DMA_IT_TE ((uint32_t)0x00000008) #define DMA_CCR_EN ((uint32_t)0x00000001) #define DMA1_IT_TE2 ((uint32_t)0x00000080) #define DMA1_IT_TC2 ((uint32_t)0x00000020) #define DMA_Mode_Normal ((uint32_t)0x00000000) #define DMA_Mode_Circular ((uint32_t)0x00000020) #define DMA_DIR_PeripheralDST ((uint32_t)0x00000010) #define DMA_DIR_PeripheralSRC ((uint32_t)0x00000000) #define DMA_MemoryDataSize_Byte ((uint32_t)0x00000000) #define DMA_MemoryDataSize_HalfWord ((uint32_t)0x00000400) #define DMA_MemoryDataSize_Word ((uint32_t)0x00000800) #define DMA_PeripheralDataSize_Byte ((uint32_t)0x00000000) #define DMA_PeripheralDataSize_HalfWord ((uint32_t)0x00000100) #define DMA_PeripheralDataSize_Word ((uint32_t)0x00000200) #define DMA_STREAM3_IT_ERR ((uint32_t)0x03400000) #define DMA_STREAM3_IT_FLAG ((uint32_t)0x0F400000) typedef enum { kDmaIdx_0, kDmaIdx_1, kDmaIdx_End, }DmaIdx; typedef struct { uint8_t irq; uint8_t ch_id; //通道实际编号,如通道5编号为4 DmaIdx dma_idx; DMA_Stream_TypeDef *channel_reg; }Stm32DmaProp; static KitIrqCall dma_irq_call[kDmaStream_End]; const DMA_TypeDef * dma_array[kDmaIdx_End] = {DMA1, DMA2}; static const Stm32DmaProp stm32_dma[kDmaStream_End] = { {DMA1_Stream0_IRQn, 0, kDmaIdx_0, DMA1_Stream0}, {DMA1_Stream1_IRQn, 1, kDmaIdx_0, DMA1_Stream1}, {DMA1_Stream2_IRQn, 2, kDmaIdx_0, DMA1_Stream2}, {DMA1_Stream3_IRQn, 3, kDmaIdx_0, DMA1_Stream3}, {DMA1_Stream4_IRQn, 4, kDmaIdx_0, DMA1_Stream4}, {DMA1_Stream5_IRQn, 5, kDmaIdx_0, DMA1_Stream5}, {DMA1_Stream6_IRQn, 6, kDmaIdx_0, DMA1_Stream6}, {DMA1_Stream7_IRQn, 7, kDmaIdx_0, DMA1_Stream7}, {DMA2_Stream0_IRQn, 0, kDmaIdx_1, DMA2_Stream0}, {DMA2_Stream1_IRQn, 1, kDmaIdx_1, DMA2_Stream1}, {DMA2_Stream2_IRQn, 2, kDmaIdx_1, DMA2_Stream2}, {DMA2_Stream3_IRQn, 3, kDmaIdx_1, DMA2_Stream3}, {DMA2_Stream4_IRQn, 4, kDmaIdx_1, DMA2_Stream4}, {DMA2_Stream5_IRQn, 5, kDmaIdx_1, DMA2_Stream5}, {DMA2_Stream6_IRQn, 6, kDmaIdx_1, DMA2_Stream6}, {DMA2_Stream7_IRQn, 6, kDmaIdx_1, DMA2_Stream7}, }; #define DMA1_Channel1_IT_Mask ((uint32_t)(DMA_ISR_GIF1 | DMA_ISR_TCIF1 | DMA_ISR_HTIF1 | DMA_ISR_TEIF1)) void dma_reset(DmaStream stream_idx) { DMA_Stream_TypeDef* DMAy_Streamx = stm32_dma[stream_idx].channel_reg; DMAy_Streamx->CR &= (uint16_t)(~DMA_SxCR_EN); /* Reset DMAy Channelx control register */ DMAy_Streamx->CR = 0; /* Reset DMAy Channelx remaining bytes register */ DMAy_Streamx->NDTR = 0; /* Reset DMAy Channelx peripheral address register */ DMAy_Streamx->PAR = 0; /* Reset DMAy Channelx memory address register */ DMAy_Streamx->M0AR = 0; DMAy_Streamx->M1AR = 0; DMAy_Streamx->FCR = (uint32_t)0x00000021; } const uint32_t dma_clk_en[kDmaIdx_End] = {RCC_AHB1ENR_DMA1EN, RCC_AHB1ENR_DMA2EN}; KitResult drv_dma_init(DmaStream stream_idx, DmaChannel channel, uint32_t dma_config, uint32_t addr) { uint32_t reg = 0; KitResult res = kKitResult_Ok; KIT_ASSERT_PARAM((stream_idx < kDmaStream_End) && (addr != NULL)); if((stream_idx < kDmaStream_End) && (addr != NULL)) { RCC->AHB1ENR |= dma_clk_en[stm32_dma[stream_idx].dma_idx]; //开启时钟 //dma初始化 dma_reset(stream_idx); if((dma_config & DMA_CFG_DATA_DIR_M2P) == DMA_CFG_DATA_DIR_M2P) { reg |= KIT_CREAT_BIT(6); } else if((dma_config & DMA_CFG_DATA_DIR_M2M) == DMA_CFG_DATA_DIR_M2P) { reg |= KIT_CREAT_BIT(7); } if((dma_config & DMA_CFG_CYCLE_EXE) == DMA_CFG_CYCLE_EXE) { reg |= KIT_CREAT_BIT(8); } if((dma_config & DMA_CFG_DATA_P_I) == DMA_CFG_DATA_P_I) { reg |= KIT_CREAT_BIT(9); } if((dma_config & DMA_CFG_DATA_M_I) == DMA_CFG_DATA_M_I) { reg |= KIT_CREAT_BIT(10); } if((dma_config & DMA_CFG_DATA_LEN_2B) == DMA_CFG_DATA_LEN_2B) { reg |= (KIT_CREAT_BIT(11) | KIT_CREAT_BIT(13)); } else if((dma_config & DMA_CFG_DATA_LEN_4B) == DMA_CFG_DATA_LEN_4B) { reg |= (KIT_CREAT_BIT(12) | KIT_CREAT_BIT(14)); } reg |= ((uint32_t)channel) << 25; stm32_dma[stream_idx].channel_reg->CR |= reg; stm32_dma[stream_idx].channel_reg->PAR = addr; } else { res = kKitResult_ParamErr; } return res; } void drv_dma_set_interrupt(DmaStream stream_idx, uint8_t priority, KitIrqCall call) { KIT_ASSERT_PARAM(stream_idx < kDmaStream_End); stm32_dma[stream_idx].channel_reg->CR |= (DMA_SxCR_TCIE | DMA_SxCR_TEIE); drv_misc_set_nvic(stm32_dma[stream_idx].irq, priority); dma_irq_call[stream_idx] = call; } __IO uint32_t * dma_ifcr[4] = {&DMA1->LIFCR, &DMA1->HIFCR, &DMA2->LIFCR, &DMA2->HIFCR}; const uint32_t dma_ifcr_clr_bit[4] = {0x0000003D, 0x00000F40, 0x003D0000, 0x0F400000}; //传输错误或者结束标志位 __IO uint32_t * dma_isr[4] = {&DMA1->LISR, &DMA1->HISR, &DMA2->LISR, &DMA2->HISR}; const uint32_t dma_isr_transfer_end_bit[4] = {0x0000002C, 0x00000B00, 0x002C0000, 0x0B000000}; void drv_dma_set_buf(DmaStream stream_idx,uint8_t* buf, uint16_t len) { DMA_Stream_TypeDef * stream_reg; KIT_ASSERT_PARAM((buf != NULL) && (len > 0)); KIT_ASSERT_PARAM(stream_idx < kDmaStream_End); if((stream_idx < kDmaStream_End) && (buf != NULL)) { stream_reg = stm32_dma[stream_idx].channel_reg; //清除标志位 *dma_ifcr[stream_idx / 4] |= dma_ifcr_clr_bit[stream_idx % 4]; stream_reg->NDTR = len; stream_reg->M0AR = (uint32_t)buf; stream_reg->CR |= DMA_CCR_EN; } } KitResult drv_dma_send(DmaStream dma_tx_ch, uint8_t *tx_buf, uint16_t tx_len) { uint32_t dly = 0; KitResult res = kKitResult_Ok; KIT_ASSERT_PARAM((tx_buf != NULL) && (tx_len > 0)); drv_dma_set_buf(dma_tx_ch, tx_buf, tx_len); //等待接收完成 while((*dma_isr[dma_tx_ch >> 2] & dma_isr_transfer_end_bit[dma_tx_ch % 4]) == 0) { kit_time_dly_ms(1); if(++dly > 500) { res = kKitResult_TimeOut; break; } } stm32_dma[dma_tx_ch].channel_reg->CR &= ~DMA_CCR_EN ; //关闭DMA通道2 return res; } KitResult drv_dma_receive(DmaStream dma_rx_ch, DmaStream dma_tx_ch, uint8_t *rx_buf, uint16_t rx_len) { uint32_t dly = 0; KitResult res = kKitResult_Ok; KIT_ASSERT_PARAM(timeout > 0); KIT_ASSERT_PARAM(((tx_buf != NULL) && (tx_len > 0)) || ((tx_buf == NULL) && (tx_len == 0))); KIT_ASSERT_PARAM(((rx_buf != NULL) && (rx_len > 0)) || ((rx_buf == NULL) && (rx_len == 0))); drv_dma_set_buf(dma_rx_ch, rx_buf, rx_len); drv_dma_set_buf(dma_tx_ch, rx_buf, rx_len); //等待接收完成 while((*dma_isr[dma_rx_ch >> 2] & dma_isr_transfer_end_bit[dma_rx_ch % 4]) == 0) { kit_time_dly_ms(1); if(++dly > 200) { res = kKitResult_TimeOut; break; } } stm32_dma[dma_tx_ch].channel_reg->CR &= ~DMA_CCR_EN ; //关闭DMA通道3 stm32_dma[dma_tx_ch].channel_reg->CR &= ~DMA_CCR_EN ; //关闭DMA通道2 return res; } void DMA1_Stream0_IRQHandler(void) { } void DMA1_Stream1_IRQHandler(void) { } void DMA1_Stream2_IRQHandler(void) { } void DMA1_Stream3_IRQHandler(void) { KitResult res = kKitResult_Ok; DMA1_Stream3->CR &= ~DMA_CCR_EN ; //关闭DMA通道2 DMA1_Stream4->CR &= ~DMA_CCR_EN ; //关闭DMA通道3 if((DMA1->LISR & DMA_STREAM3_IT_ERR) != 0) { KIT_ASSERT_RES(0, kKitResult_Error); res = kKitResult_Error; } DMA1->LIFCR = DMA_STREAM3_IT_FLAG; //清楚标志位 if(dma_irq_call[kDma1Stream_3] != NULL) dma_irq_call[kDma1Stream_3](res, NULL); } void DMA1_Stream4_IRQHandler(void) { } void DMA1_Stream5_IRQHandler(void) { } void DMA1_Channel6_IRQHandler(void) { } void DMA2_Stream0_IRQHandler(void) { } void DMA2_Stream1_IRQHandler(void) { } void DMA2_Stream2_IRQHandler(void) { } void DMA2_Stream3_IRQHandler(void) { } void DMA2_Stream4_IRQHandler(void) { } void DMA2_Stream5_IRQHandler(void) { } void DMA2_Stream6_IRQHandler(void) { } void DMA2_Stream7_IRQHandler(void) { }