653 lines
		
	
	
		
			16 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
			
		
		
	
	
			653 lines
		
	
	
		
			16 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
| 
 | |
| #include "rtthread.h"
 | |
| #include "stm32f4xx.h"
 | |
| #include "board.h"
 | |
| #include "if_uart_dma.h"
 | |
| 
 | |
| 
 | |
| #ifndef RT_THREAD
 | |
| 
 | |
| #define rt_interrupt_enter()
 | |
| #define rt_interrupt_leave()
 | |
| #define rt_sem_create(...) 0
 | |
| #define rt_sem_delete(...)
 | |
| #define rt_sem_take(...)
 | |
| #define rt_sem_release(...)
 | |
| 
 | |
| #endif
 | |
| 
 | |
| 
 | |
| 
 | |
| 
 | |
| 
 | |
| 
 | |
| #define GPIO_Initer() {.GPIO_Mode=GPIO_Mode_AF,\
 | |
|   .GPIO_Speed=GPIO_Speed_50MHz,\
 | |
|   .GPIO_OType=GPIO_OType_PP,\
 | |
|   .GPIO_PuPd=GPIO_PuPd_UP \
 | |
| }
 | |
| 
 | |
| 
 | |
| #define UART_Initer() {.USART_WordLength=USART_WordLength_8b,\
 | |
|   .USART_StopBits=USART_StopBits_1,\
 | |
|   .USART_Parity=USART_Parity_No,\
 | |
|   .USART_HardwareFlowControl=USART_HardwareFlowControl_None,\
 | |
|   .USART_Mode=USART_Mode_Rx | USART_Mode_Tx,\
 | |
| }
 | |
| 
 | |
| #define NVIC_Initer() {0}
 | |
| 
 | |
| 
 | |
| #define DMA_RX_Initer() {\
 | |
|   .DMA_DIR = DMA_DIR_PeripheralToMemory,\
 | |
|   .DMA_PeripheralInc = DMA_PeripheralInc_Disable,\
 | |
|   .DMA_MemoryInc = DMA_MemoryInc_Enable,\
 | |
|   .DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte,\
 | |
|   .DMA_MemoryDataSize = DMA_MemoryDataSize_Byte,\
 | |
|   .DMA_Mode = DMA_Mode_Circular,\
 | |
|   .DMA_Priority = DMA_Priority_High,\
 | |
|   .DMA_FIFOMode = DMA_FIFOMode_Disable,\
 | |
|   .DMA_FIFOThreshold = DMA_FIFOThreshold_Full,\
 | |
|   .DMA_MemoryBurst = DMA_MemoryBurst_Single,\
 | |
|   .DMA_PeripheralBurst = DMA_PeripheralBurst_Single,\
 | |
| }
 | |
| 
 | |
| 
 | |
| #define DMA_TX_Initer() {\
 | |
| 	.DMA_DIR = DMA_DIR_MemoryToPeripheral,\
 | |
| 	.DMA_PeripheralInc = DMA_PeripheralInc_Disable,\
 | |
| 	.DMA_MemoryInc = DMA_MemoryInc_Enable,\
 | |
| 	.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte,\
 | |
| 	.DMA_MemoryDataSize = DMA_MemoryDataSize_Byte,\
 | |
| 	.DMA_Mode = DMA_Mode_Normal,\
 | |
| 	.DMA_Priority = DMA_Priority_Medium,\
 | |
| 	.DMA_FIFOMode = DMA_FIFOMode_Disable,\
 | |
| 	.DMA_FIFOThreshold = DMA_FIFOThreshold_Full,\
 | |
| 	.DMA_MemoryBurst = DMA_MemoryBurst_Single,\
 | |
| 	.DMA_PeripheralBurst = DMA_PeripheralBurst_Single,\
 | |
| }
 | |
| 
 | |
| 
 | |
| 
 | |
| 
 | |
| typedef struct{
 | |
|   char *name;
 | |
|   USART_TypeDef *uart;
 | |
|   void (*uart_clock_fun)(uint32_t,FunctionalState);
 | |
|   uint32_t uart_rcc;
 | |
|   int baudrate;
 | |
|   int irq_channel;
 | |
|   
 | |
|   void (*gpio_tx_clock_fun)(uint32_t,FunctionalState);
 | |
|   uint32_t gpio_tx_rcc;
 | |
|   GPIO_TypeDef *gpio_tx_base;
 | |
|   uint16_t gpio_tx_pin;
 | |
|   uint8_t gpio_tx_af;
 | |
|   void (*gpio_rx_clock_fun)(uint32_t,FunctionalState);
 | |
|   uint32_t gpio_rx_rcc;
 | |
|   GPIO_TypeDef *gpio_rx_base;
 | |
|   uint16_t gpio_rx_pin;
 | |
|   uint8_t gpio_rx_af;
 | |
|   
 | |
|   DMA_Stream_TypeDef *dma_rx_stream;
 | |
|   void (*dma_rx_clock_fun)(uint32_t,FunctionalState);
 | |
|   uint32_t dma_rx_rcc;
 | |
|   uint32_t dma_rx_channel;
 | |
|   
 | |
|   DMA_Stream_TypeDef *dma_tx_stream;
 | |
|   void (*dma_tx_clock_fun)(uint32_t,FunctionalState);
 | |
|   uint32_t dma_tx_rcc;
 | |
|   uint32_t dma_tx_channel;
 | |
|   int dma_tx_irq_channel;
 | |
|   uint32_t dma_tx_tc_flag;
 | |
|   
 | |
| }uart_dtb;
 | |
| 
 | |
| 
 | |
| 
 | |
| static const uart_dtb g_uartdtb[]={
 | |
|   {
 | |
|     .name="uart1",
 | |
|     .uart=USART1,
 | |
|     .uart_clock_fun=RCC_APB2PeriphClockCmd,
 | |
|     .uart_rcc=RCC_APB2Periph_USART1,
 | |
|     .baudrate=57600,
 | |
|     .irq_channel=USART1_IRQn,
 | |
|     
 | |
|     .gpio_tx_clock_fun=RCC_AHB1PeriphClockCmd,
 | |
|     .gpio_tx_rcc=RCC_AHB1Periph_GPIOA,
 | |
|     .gpio_tx_base=GPIOA,
 | |
|     .gpio_tx_pin=9,
 | |
|     .gpio_tx_af=GPIO_AF_USART1,
 | |
|     .gpio_rx_clock_fun=RCC_AHB1PeriphClockCmd,
 | |
|     .gpio_rx_rcc=RCC_AHB1Periph_GPIOA,
 | |
|     .gpio_rx_base=GPIOA,
 | |
|     .gpio_rx_pin=10,
 | |
|     .gpio_rx_af=GPIO_AF_USART1,
 | |
|     
 | |
|     .dma_rx_stream=DMA2_Stream5,
 | |
|     .dma_rx_clock_fun=RCC_AHB1PeriphClockCmd,
 | |
|     .dma_rx_rcc=RCC_AHB1Periph_DMA2,
 | |
|     .dma_rx_channel=DMA_Channel_4,
 | |
|     
 | |
|     .dma_tx_stream=DMA2_Stream7,
 | |
|     .dma_tx_clock_fun=RCC_AHB1PeriphClockCmd,
 | |
|     .dma_tx_rcc=RCC_AHB1Periph_DMA2,
 | |
|     .dma_tx_channel=DMA_Channel_4,
 | |
|     .dma_tx_irq_channel=DMA2_Stream7_IRQn,
 | |
|     .dma_tx_tc_flag=DMA_FLAG_TCIF7,
 | |
|   },
 | |
|   {
 | |
|     .name="uart2",
 | |
|     .uart=USART2,
 | |
|     .uart_clock_fun=RCC_APB1PeriphClockCmd,
 | |
|     .uart_rcc=RCC_APB1Periph_USART2,
 | |
|     .baudrate=57600,
 | |
|     .irq_channel=USART2_IRQn,
 | |
|     
 | |
|     .gpio_tx_clock_fun=RCC_AHB1PeriphClockCmd,
 | |
|     .gpio_tx_rcc=RCC_AHB1Periph_GPIOD,
 | |
|     .gpio_tx_base=GPIOD,
 | |
|     .gpio_tx_pin=5,
 | |
|     .gpio_tx_af=GPIO_AF_USART2,
 | |
|     .gpio_rx_clock_fun=RCC_AHB1PeriphClockCmd,
 | |
|     .gpio_rx_rcc=RCC_AHB1Periph_GPIOD,
 | |
|     .gpio_rx_base=GPIOD,
 | |
|     .gpio_rx_pin=6,
 | |
|     .gpio_rx_af=GPIO_AF_USART2,
 | |
|     
 | |
|     .dma_rx_stream=DMA1_Stream5,
 | |
|     .dma_rx_clock_fun=RCC_AHB1PeriphClockCmd,
 | |
|     .dma_rx_rcc=RCC_AHB1Periph_DMA1,
 | |
|     .dma_rx_channel=DMA_Channel_4,
 | |
|     
 | |
|     .dma_tx_stream=DMA1_Stream6,
 | |
|     .dma_tx_clock_fun=RCC_AHB1PeriphClockCmd,
 | |
|     .dma_tx_rcc=RCC_AHB1Periph_DMA1,
 | |
|     .dma_tx_channel=DMA_Channel_4,
 | |
|     .dma_tx_irq_channel=DMA1_Stream6_IRQn,
 | |
|     .dma_tx_tc_flag=DMA_FLAG_TCIF6,
 | |
|   },
 | |
|   {
 | |
|     .name="uart3",
 | |
|     .uart=USART3,
 | |
|     .uart_clock_fun=RCC_APB1PeriphClockCmd,
 | |
|     .uart_rcc=RCC_APB1Periph_USART3,
 | |
|     .baudrate=57600,
 | |
|     .irq_channel=USART3_IRQn,
 | |
|     
 | |
|     .gpio_tx_clock_fun=RCC_AHB1PeriphClockCmd,
 | |
|     .gpio_tx_rcc=RCC_AHB1Periph_GPIOD,
 | |
|     .gpio_tx_base=GPIOD,
 | |
|     .gpio_tx_pin=8,
 | |
|     .gpio_tx_af=GPIO_AF_USART3,
 | |
|     .gpio_rx_clock_fun=RCC_AHB1PeriphClockCmd,
 | |
|     .gpio_rx_rcc=RCC_AHB1Periph_GPIOD,
 | |
|     .gpio_rx_base=GPIOD,
 | |
|     .gpio_rx_pin=9,
 | |
|     .gpio_rx_af=GPIO_AF_USART3,
 | |
|     
 | |
|     .dma_rx_stream=DMA1_Stream1,
 | |
|     .dma_rx_clock_fun=RCC_AHB1PeriphClockCmd,
 | |
|     .dma_rx_rcc=RCC_AHB1Periph_DMA1,
 | |
|     .dma_rx_channel=DMA_Channel_4,
 | |
|     
 | |
|     .dma_tx_stream=DMA1_Stream3,
 | |
|     .dma_tx_clock_fun=RCC_AHB1PeriphClockCmd,
 | |
|     .dma_tx_rcc=RCC_AHB1Periph_DMA1,
 | |
|     .dma_tx_channel=DMA_Channel_4,
 | |
|     .dma_tx_irq_channel=DMA1_Stream3_IRQn,
 | |
|     .dma_tx_tc_flag=DMA_FLAG_TCIF3,
 | |
|   },
 | |
|   {
 | |
|     .name="uart4",
 | |
|     .uart=UART4,
 | |
|     .uart_clock_fun=RCC_APB1PeriphClockCmd,
 | |
|     .uart_rcc=RCC_APB1Periph_UART4,
 | |
|     .baudrate=115200,
 | |
|     .irq_channel=UART4_IRQn,
 | |
|     
 | |
|     .gpio_tx_clock_fun=RCC_AHB1PeriphClockCmd,
 | |
|     .gpio_tx_rcc=RCC_AHB1Periph_GPIOC,
 | |
|     .gpio_tx_base=GPIOC,
 | |
|     .gpio_tx_pin=10,
 | |
|     .gpio_tx_af=GPIO_AF_UART4,
 | |
|     .gpio_rx_clock_fun=RCC_AHB1PeriphClockCmd,
 | |
|     .gpio_rx_rcc=RCC_AHB1Periph_GPIOC,
 | |
|     .gpio_rx_base=GPIOC,
 | |
|     .gpio_rx_pin=11,
 | |
|     .gpio_rx_af=GPIO_AF_UART4,
 | |
|     
 | |
|     .dma_rx_stream=DMA1_Stream2,
 | |
|     .dma_rx_clock_fun=RCC_AHB1PeriphClockCmd,
 | |
|     .dma_rx_rcc=RCC_AHB1Periph_DMA1,
 | |
|     .dma_rx_channel=DMA_Channel_4,
 | |
|     
 | |
|     .dma_tx_stream=DMA1_Stream4,
 | |
|     .dma_tx_clock_fun=RCC_AHB1PeriphClockCmd,
 | |
|     .dma_tx_rcc=RCC_AHB1Periph_DMA1,
 | |
|     .dma_tx_channel=DMA_Channel_4,
 | |
|     .dma_tx_irq_channel=DMA1_Stream4_IRQn,
 | |
|     .dma_tx_tc_flag=DMA_FLAG_TCIF4,
 | |
|   },
 | |
|   {
 | |
|     .name="uart5",
 | |
|     .uart=UART5,
 | |
|     .uart_clock_fun=RCC_APB1PeriphClockCmd,
 | |
|     .uart_rcc=RCC_APB1Periph_UART5,
 | |
|     .baudrate=57600,
 | |
|     .irq_channel=UART5_IRQn,
 | |
|     
 | |
|     .gpio_tx_clock_fun=RCC_AHB1PeriphClockCmd,
 | |
|     .gpio_tx_rcc=RCC_AHB1Periph_GPIOC,
 | |
|     .gpio_tx_base=GPIOC,
 | |
|     .gpio_tx_pin=12,
 | |
|     .gpio_tx_af=GPIO_AF_UART5,
 | |
|     .gpio_rx_clock_fun=RCC_AHB1PeriphClockCmd,
 | |
|     .gpio_rx_rcc=RCC_AHB1Periph_GPIOD,
 | |
|     .gpio_rx_base=GPIOD,
 | |
|     .gpio_rx_pin=2,
 | |
|     .gpio_rx_af=GPIO_AF_UART5,
 | |
|     
 | |
|     .dma_rx_stream=DMA1_Stream0,
 | |
|     .dma_rx_clock_fun=RCC_AHB1PeriphClockCmd,
 | |
|     .dma_rx_rcc=RCC_AHB1Periph_DMA1,
 | |
|     .dma_rx_channel=DMA_Channel_4,
 | |
|     
 | |
|     .dma_tx_stream=DMA1_Stream7,
 | |
|     .dma_tx_clock_fun=RCC_AHB1PeriphClockCmd,
 | |
|     .dma_tx_rcc=RCC_AHB1Periph_DMA1,
 | |
|     .dma_tx_channel=DMA_Channel_4,
 | |
|     .dma_tx_irq_channel=DMA1_Stream7_IRQn,
 | |
|     .dma_tx_tc_flag=DMA_FLAG_TCIF7,
 | |
|   },
 | |
|   {
 | |
|     .name="uart6",
 | |
|     .uart=USART6,
 | |
|     .uart_clock_fun=RCC_APB2PeriphClockCmd,
 | |
|     .uart_rcc=RCC_APB2Periph_USART6,
 | |
|     .baudrate=57600,
 | |
|     .irq_channel=USART6_IRQn,
 | |
|     
 | |
|     .gpio_tx_clock_fun=RCC_AHB1PeriphClockCmd,
 | |
|     .gpio_tx_rcc=RCC_AHB1Periph_GPIOC,
 | |
|     .gpio_tx_base=GPIOC,
 | |
|     .gpio_tx_pin=6,
 | |
|     .gpio_tx_af=GPIO_AF_USART6,
 | |
|     .gpio_rx_clock_fun=RCC_AHB1PeriphClockCmd,
 | |
|     .gpio_rx_rcc=RCC_AHB1Periph_GPIOC,
 | |
|     .gpio_rx_base=GPIOC,
 | |
|     .gpio_rx_pin=7,
 | |
|     .gpio_rx_af=GPIO_AF_USART6,
 | |
|     
 | |
|     .dma_rx_stream=DMA2_Stream2,
 | |
|     .dma_rx_clock_fun=RCC_AHB1PeriphClockCmd,
 | |
|     .dma_rx_rcc=RCC_AHB1Periph_DMA2,
 | |
|     .dma_rx_channel=DMA_Channel_5,
 | |
|     
 | |
|     .dma_tx_stream=DMA2_Stream6,
 | |
|     .dma_tx_clock_fun=RCC_AHB1PeriphClockCmd,
 | |
|     .dma_tx_rcc=RCC_AHB1Periph_DMA2,
 | |
|     .dma_tx_channel=DMA_Channel_5,
 | |
|     .dma_tx_irq_channel=DMA2_Stream6_IRQn,
 | |
|     .dma_tx_tc_flag=DMA_FLAG_TCIF6,
 | |
|   },
 | |
| };
 | |
| 
 | |
| 
 | |
| 
 | |
| typedef struct{
 | |
|   const uart_dtb *dtb;
 | |
|   void (*irq_fun)(void *t,uint8_t d);
 | |
|   void (*irq_fun_end)(void *t,uint32_t len);
 | |
|   void *t;
 | |
|   uint8_t *rx_buff;
 | |
|   uint32_t rx_buff_size;
 | |
|   void *sem;
 | |
|   int in_send;
 | |
| }self_data;
 | |
| 
 | |
| 
 | |
| static self_data g_self[LENGTH(g_uartdtb)];
 | |
| 
 | |
| 
 | |
| def_find_fun(uart_dtb,g_uartdtb)
 | |
| 
 | |
| 
 | |
| 
 | |
| static int init(uart_def *u,int bsp)
 | |
| {
 | |
|   param_check(u);
 | |
|   if(u->private_data) return 0;
 | |
|   GPIO_InitTypeDef init=GPIO_Initer();
 | |
| 	USART_InitTypeDef init2=UART_Initer(); 
 | |
|   NVIC_InitTypeDef init3=NVIC_Initer();
 | |
|   int index;
 | |
|   const uart_dtb *dtb=find(u->name,&index);
 | |
|   self_data *self=&g_self[index];
 | |
|   self->dtb=dtb;
 | |
|   self->irq_fun=0;
 | |
|   self->t=0;
 | |
|   self->sem=rt_sem_create(u->name,1,RT_IPC_FLAG_FIFO);
 | |
|   self->in_send=0;
 | |
|   {
 | |
|     u->private_data=self;
 | |
|     dtb->uart_clock_fun(dtb->uart_rcc,ENABLE);
 | |
|     if(bsp==0) bsp=dtb->baudrate;
 | |
|     init2.USART_BaudRate = bsp;
 | |
|     USART_Init(dtb->uart, &init2);	
 | |
|     USART_Cmd(dtb->uart, ENABLE);	
 | |
|     
 | |
|     dtb->gpio_tx_clock_fun(dtb->gpio_tx_rcc,ENABLE);
 | |
|     GPIO_PinAFConfig(dtb->gpio_tx_base,dtb->gpio_tx_pin,dtb->gpio_tx_af);
 | |
|     init.GPIO_Pin=1<<dtb->gpio_tx_pin;
 | |
|     GPIO_Init(dtb->gpio_tx_base,&init); 
 | |
| 
 | |
|     dtb->gpio_rx_clock_fun(dtb->gpio_rx_rcc,ENABLE);
 | |
|     GPIO_PinAFConfig(dtb->gpio_rx_base,dtb->gpio_rx_pin,dtb->gpio_rx_af);
 | |
|     init.GPIO_Pin=1<<dtb->gpio_rx_pin;
 | |
|     GPIO_Init(dtb->gpio_rx_base,&init); 
 | |
| 
 | |
|     init3.NVIC_IRQChannel = dtb->irq_channel;
 | |
|     init3.NVIC_IRQChannelPreemptionPriority=3;
 | |
|     init3.NVIC_IRQChannelSubPriority =3;
 | |
|     init3.NVIC_IRQChannelCmd = ENABLE;
 | |
|     NVIC_Init(&init3);
 | |
|     USART_ITConfig(dtb->uart, USART_IT_IDLE, ENABLE);	
 | |
|     
 | |
|     init3.NVIC_IRQChannel = dtb->dma_tx_irq_channel;
 | |
|     init3.NVIC_IRQChannelPreemptionPriority=3;
 | |
|     init3.NVIC_IRQChannelSubPriority =3;
 | |
|     init3.NVIC_IRQChannelCmd = ENABLE;
 | |
|     NVIC_Init(&init3);
 | |
|   }
 | |
|   return 0;
 | |
| }
 | |
| 
 | |
| 
 | |
| 
 | |
| static int dma_rx_init(self_data *self,uint8_t *rx_buff,uint32_t rx_buff_size)
 | |
| {
 | |
|   const uart_dtb *dtb=self->dtb;
 | |
| 	DMA_InitTypeDef init=DMA_RX_Initer();	
 | |
|   
 | |
|   USART_DMACmd(dtb->uart,USART_DMAReq_Rx,ENABLE);
 | |
|   DMA_DeInit(dtb->dma_rx_stream);
 | |
|   while (DMA_GetCmdStatus(dtb->dma_rx_stream) != DISABLE);
 | |
|   RCC_AHB1PeriphClockCmd(dtb->dma_rx_rcc,ENABLE);
 | |
|   init.DMA_Channel = dtb->dma_rx_channel;
 | |
|   init.DMA_PeripheralBaseAddr = (u32)(&(dtb->uart->DR));
 | |
|   init.DMA_Memory0BaseAddr = (u32)rx_buff;
 | |
|   DMA_Init(dtb->dma_rx_stream, &init);
 | |
|   DMA_Cmd(dtb->dma_rx_stream, DISABLE);
 | |
|   return 0;
 | |
| }
 | |
| 
 | |
| static int dma_rx_reset(self_data *self)
 | |
| {
 | |
|   const uart_dtb *dtb=self->dtb;
 | |
|   
 | |
|   DMA_Cmd(dtb->dma_rx_stream, DISABLE);
 | |
|   while(DMA_GetCmdStatus(dtb->dma_rx_stream)!=DISABLE);
 | |
|   DMA_SetCurrDataCounter(dtb->dma_rx_stream, self->rx_buff_size);  
 | |
|   DMA_Cmd(dtb->dma_rx_stream, ENABLE);
 | |
|   
 | |
|   return 0;
 | |
| }
 | |
| 
 | |
| 
 | |
| 
 | |
| 
 | |
| static int dma_tx_init(self_data *self,const uint8_t *tx_buff,uint32_t tx_buff_size)
 | |
| {
 | |
|   const uart_dtb *dtb=self->dtb;
 | |
| 	DMA_InitTypeDef init=DMA_TX_Initer();	
 | |
|   
 | |
|   USART_DMACmd(dtb->uart,USART_DMAReq_Tx,ENABLE);
 | |
|   DMA_DeInit(dtb->dma_tx_stream);
 | |
|   while (DMA_GetCmdStatus(dtb->dma_tx_stream) != DISABLE);
 | |
|   RCC_AHB1PeriphClockCmd(dtb->dma_tx_rcc,ENABLE);
 | |
|   init.DMA_Channel = dtb->dma_tx_channel;
 | |
|   init.DMA_PeripheralBaseAddr = (u32)(&(dtb->uart->DR));
 | |
|   init.DMA_Memory0BaseAddr = (u32)tx_buff;
 | |
|   init.DMA_BufferSize=tx_buff_size;
 | |
|   DMA_Init(dtb->dma_tx_stream, &init);
 | |
|   DMA_Cmd(dtb->dma_tx_stream, ENABLE);
 | |
|   DMA_ITConfig(dtb->dma_tx_stream,DMA_IT_TC,ENABLE);
 | |
|   return 0;
 | |
| }
 | |
| 
 | |
| 
 | |
| static int dma_tx_reset(self_data *self,uint8_t *tx_buff,uint32_t tx_buff_size)
 | |
| {
 | |
|   const uart_dtb *dtb=self->dtb;
 | |
|   
 | |
|   USART_DMACmd(dtb->uart,USART_DMAReq_Tx,ENABLE);
 | |
|   DMA_Cmd(dtb->dma_tx_stream, DISABLE);
 | |
|   while(DMA_GetCmdStatus(dtb->dma_tx_stream)!=DISABLE);
 | |
|   DMA_ClearFlag(dtb->dma_tx_stream,dtb->dma_tx_tc_flag);
 | |
|   DMA_SetCurrDataCounter(dtb->dma_tx_stream, tx_buff_size);
 | |
|   dtb->dma_rx_stream->M0AR=(uint32_t)tx_buff;
 | |
|   DMA_Cmd(dtb->dma_tx_stream, ENABLE);
 | |
|   return 0;
 | |
| }
 | |
| 
 | |
| 
 | |
| 
 | |
| 
 | |
| 
 | |
| 
 | |
| 
 | |
| static int deinit(uart_def *u)
 | |
| {
 | |
|   param_check(u);
 | |
|   if(u->private_data==0) return 0;
 | |
|   NVIC_InitTypeDef init3=NVIC_Initer();
 | |
|   const uart_dtb *dtb=find(u->name,0);
 | |
|   {
 | |
|     USART_Cmd(dtb->uart, DISABLE);	
 | |
|     dtb->uart_clock_fun(dtb->uart_rcc,DISABLE);
 | |
|     dtb->gpio_tx_clock_fun(dtb->gpio_tx_rcc,DISABLE);
 | |
|     dtb->gpio_rx_clock_fun(dtb->gpio_rx_rcc,DISABLE);
 | |
|     init3.NVIC_IRQChannelCmd = DISABLE;
 | |
|     NVIC_Init(&init3);
 | |
|     USART_ITConfig(dtb->uart, USART_IT_RXNE, DISABLE);
 | |
|     rt_sem_delete(((self_data *)u->private_data)->sem);
 | |
|     u->private_data=0;
 | |
|   }
 | |
|   return 0;
 | |
| }
 | |
| 
 | |
| 
 | |
| 
 | |
| static int set_irq(uart_def *u,void (*irq)(void *t,uint8_t d),void *t)
 | |
| {
 | |
|   param_check(u);
 | |
|   param_check(u->private_data);
 | |
|   self_data *self=u->private_data;
 | |
|   irq_disable();
 | |
|   self->irq_fun=irq;
 | |
|   self->t=t;
 | |
|   irq_enable();
 | |
|   return 0;
 | |
| }
 | |
| 
 | |
| static int set_end_irq(uart_def *u,uint8_t *rx_buff,int rx_buff_size,
 | |
|   void (*irq)(void *t,uint32_t len),void *t)
 | |
| {
 | |
|   param_check(u);
 | |
|   param_check(u->private_data);
 | |
|   self_data *self=u->private_data;
 | |
|   dma_rx_init(self,rx_buff,rx_buff_size);
 | |
|   self->rx_buff=rx_buff;
 | |
|   self->rx_buff_size=rx_buff_size;
 | |
|   dma_rx_reset(self);
 | |
|   irq_disable();
 | |
|   self->irq_fun_end=irq;
 | |
|   self->t=t;
 | |
|   irq_enable();
 | |
|   return 0;
 | |
| }
 | |
| 
 | |
| 
 | |
| static int read(uart_def *u,uint8_t *b,int len)
 | |
| {
 | |
|   param_check(u);
 | |
|   param_check(u->private_data);
 | |
|   return 0;
 | |
| }
 | |
| 
 | |
| 
 | |
| // dma后台发送需要保证数据在发送期间有效
 | |
| static int write(uart_def *u,const uint8_t *b,int len)
 | |
| {
 | |
|   param_check(u);
 | |
|   param_check(u->private_data);
 | |
|   self_data *self=u->private_data;
 | |
|   USART_TypeDef *uart=self->dtb->uart;
 | |
|   if(1){
 | |
|     dma_tx_init(self,b,len);
 | |
|   }else{
 | |
|     for(int i=0;i<len;i++)
 | |
|     {
 | |
|       while(!USART_GetFlagStatus(uart,USART_FLAG_TXE));
 | |
|       uart->DR=b[i];
 | |
|     }
 | |
|   }
 | |
|   return len;
 | |
| }
 | |
| 
 | |
| // 阻塞发送,此函数结束即可释放内存
 | |
| static int write_block(uart_def *u,const uint8_t *b,int len)
 | |
| {
 | |
|   param_check(u);
 | |
|   param_check(u->private_data);
 | |
|   self_data *self=u->private_data;
 | |
|   USART_TypeDef *uart=self->dtb->uart;
 | |
|   self->in_send=1;
 | |
|   if(1){
 | |
|     dma_tx_init(self,b,len);
 | |
|   }else{
 | |
|     for(int i=0;i<len;i++)
 | |
|     {
 | |
|       while(!USART_GetFlagStatus(uart,USART_FLAG_TXE));
 | |
|       uart->DR=b[i];
 | |
|     }
 | |
|     self->in_send=0;
 | |
|   }
 | |
|   while(self->in_send){}
 | |
|   return len;
 | |
| }
 | |
| 
 | |
| 
 | |
| 
 | |
| static inline void self_irq(self_data *self)
 | |
| {
 | |
| 	rt_interrupt_enter();
 | |
|   const uart_dtb *dtb=self->dtb;
 | |
|   
 | |
|   if(USART_GetFlagStatus(dtb->uart,USART_FLAG_RXNE))
 | |
|   {
 | |
|     if(self->irq_fun){
 | |
|       self->irq_fun(self->t,dtb->uart->DR);
 | |
|     }
 | |
|   }
 | |
|   else if(USART_GetFlagStatus(dtb->uart,USART_FLAG_TC))
 | |
|   {
 | |
|     USART_ClearFlag(dtb->uart,USART_FLAG_TC);
 | |
|   }
 | |
|   else if(USART_GetFlagStatus(dtb->uart,USART_FLAG_IDLE))
 | |
|   {
 | |
|     USART_ReceiveData(dtb->uart);
 | |
|     if(self->irq_fun_end){
 | |
|       self->irq_fun_end(self->t,self->rx_buff_size-DMA_GetCurrDataCounter(dtb->dma_rx_stream));
 | |
|     }
 | |
|     dma_rx_reset(self);
 | |
|   }
 | |
| 	rt_interrupt_leave();
 | |
| }
 | |
| static inline void self_dma_irq(self_data *self)
 | |
| {
 | |
| 	rt_interrupt_enter();
 | |
|   const uart_dtb *dtb=self->dtb;
 | |
|   if(DMA_GetFlagStatus(dtb->dma_tx_stream,dtb->dma_tx_tc_flag))
 | |
|   {
 | |
|     DMA_ClearFlag(dtb->dma_tx_stream,dtb->dma_tx_tc_flag);
 | |
|     DMA_Cmd(dtb->dma_tx_stream, DISABLE);
 | |
|     self->in_send=0;
 | |
|   }
 | |
| 	rt_interrupt_leave();
 | |
| }
 | |
| 
 | |
| void USART1_IRQHandler(void)
 | |
| {
 | |
|   self_data *self=&g_self[0];
 | |
|   self_irq(self);
 | |
| }
 | |
| void USART2_IRQHandler(void)
 | |
| {
 | |
|   self_data *self=&g_self[1];
 | |
|   self_irq(self);
 | |
| }
 | |
| void USART3_IRQHandler(void)
 | |
| {
 | |
|   self_data *self=&g_self[2];
 | |
|   self_irq(self);
 | |
| }
 | |
| void UART4_IRQHandler(void)
 | |
| {
 | |
|   self_data *self=&g_self[3];
 | |
|   self_irq(self);
 | |
| }
 | |
| void UART5_IRQHandler(void)
 | |
| {
 | |
|   self_data *self=&g_self[4];
 | |
|   self_irq(self);
 | |
| }
 | |
| void USART6_IRQHandler(void)
 | |
| {
 | |
|   self_data *self=&g_self[5];
 | |
|   self_irq(self);
 | |
| }
 | |
| 
 | |
| void DMA2_Stream7_IRQHandler(void)
 | |
| {
 | |
|   self_data *self=&g_self[0];
 | |
|   self_dma_irq(self);
 | |
| }
 | |
| void DMA1_Stream6_IRQHandler(void)
 | |
| {
 | |
|   self_data *self=&g_self[1];
 | |
|   self_dma_irq(self);
 | |
| }
 | |
| void DMA1_Stream3_IRQHandler(void)
 | |
| {
 | |
|   self_data *self=&g_self[2];
 | |
|   self_dma_irq(self);
 | |
| }
 | |
| void DMA1_Stream4_IRQHandler(void)
 | |
| {
 | |
|   self_data *self=&g_self[3];
 | |
|   self_dma_irq(self);
 | |
| }
 | |
| void DMA1_Stream7_IRQHandler(void)
 | |
| {
 | |
|   self_data *self=&g_self[4];
 | |
|   self_dma_irq(self);
 | |
| }
 | |
| void DMA2_Stream6_IRQHandler(void)
 | |
| {
 | |
|   self_data *self=&g_self[5];
 | |
|   self_dma_irq(self);
 | |
| }
 | |
| 
 | |
| 
 | |
| uart_init_export(uart1,init,deinit,set_irq,set_end_irq,read,write,0)
 | |
| uart_init_export(uart2,init,deinit,set_irq,set_end_irq,read,write,0)
 | |
| uart_init_export(uart3,init,deinit,set_irq,set_end_irq,read,write,0)
 | |
| uart_init_export(uart5,init,deinit,set_irq,set_end_irq,read,write,0)
 | |
| uart_init_export(uart6,init,deinit,set_irq,set_end_irq,read,write,0)
 | |
| uart_init_export(uart4,init,deinit,set_irq,set_end_irq,read,write_block,0)
 | |
| 
 | |
| 
 | 
