#include "rtthread.h" #include "stm32f4xx.h" #include "board.h" #include "if_uart.h" #ifndef RT_THREAD #define rt_interrupt_enter() #define rt_interrupt_leave() #define rt_mutex_create(...) 0 #define rt_mutex_delete(...) #define rt_mutex_take(...) #define rt_mutex_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} typedef struct{ char *name; USART_TypeDef *uart; void (*uart_clock_fun)(uint32_t,FunctionalState); uint32_t uart_rcc; int baudrate; 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; int irq_channel; }uart_dtb; static const uart_dtb g_uartdtb[]={ { .name="uart1", .uart=USART1, .uart_clock_fun=RCC_APB2PeriphClockCmd, .uart_rcc=RCC_APB2Periph_USART1, .baudrate=57600, .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, .irq_channel=USART1_IRQn, }, { .name="uart2", .uart=USART2, .uart_clock_fun=RCC_APB1PeriphClockCmd, .uart_rcc=RCC_APB1Periph_USART2, .baudrate=57600, .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, .irq_channel=USART2_IRQn, }, { .name="uart3", .uart=USART3, .uart_clock_fun=RCC_APB1PeriphClockCmd, .uart_rcc=RCC_APB1Periph_USART3, .baudrate=57600, .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, .irq_channel=USART3_IRQn, }, { .name="uart4", .uart=UART4, .uart_clock_fun=RCC_APB1PeriphClockCmd, .uart_rcc=RCC_APB1Periph_UART4, .baudrate=115200, .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, .irq_channel=UART4_IRQn, }, { .name="uart5", .uart=UART5, .uart_clock_fun=RCC_APB1PeriphClockCmd, .uart_rcc=RCC_APB1Periph_UART5, .baudrate=57600, .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, .irq_channel=UART5_IRQn, }, { .name="uart6", .uart=USART6, .uart_clock_fun=RCC_APB2PeriphClockCmd, .uart_rcc=RCC_APB2Periph_USART6, .baudrate=57600, .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, .irq_channel=USART6_IRQn, }, }; typedef struct{ const uart_dtb *dtb; void (*irq_fun)(void *t,uint8_t d); void *t; void *mutex; }self_data; static self_data g_self[LENGTH(g_uartdtb)]; def_find_fun(uart_dtb,g_uartdtb) static int init(uart_def *u) { 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->mutex=rt_mutex_create(u->name,RT_IPC_FLAG_FIFO); { u->private_data=self; dtb->uart_clock_fun(dtb->uart_rcc,ENABLE); init2.USART_BaudRate = dtb->baudrate; 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<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<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_RXNE, 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_mutex_delete(((self_data *)u->private_data)->mutex); 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 read(uart_def *u,uint8_t *b,int len) { param_check(u); param_check(u->private_data); return 0; } 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; rt_mutex_take(self->mutex,RT_WAITING_FOREVER); for(int i=0;iDR=b[i]; } rt_mutex_release(self->mutex); return len; } static inline void self_irq(self_data *self) { rt_interrupt_enter(); if(USART_GetFlagStatus(self->dtb->uart,USART_FLAG_RXNE)) { if(self->irq_fun){ self->irq_fun(self->t,self->dtb->uart->DR); } } else if(USART_GetFlagStatus(self->dtb->uart,USART_FLAG_TC)) { USART_ClearFlag(self->dtb->uart,USART_FLAG_TC); } 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); } uart_init_export(uart1,init,deinit,set_irq,0,read,write,0) uart_init_export(uart2,init,deinit,set_irq,0,read,write,0) uart_init_export(uart3,init,deinit,set_irq,0,read,write,0) uart_init_export(uart4,init,deinit,set_irq,0,read,write,0) uart_init_export(uart5,init,deinit,set_irq,0,read,write,0) uart_init_export(uart6,init,deinit,set_irq,0,read,write,0)