/* * stm32f4_uart.c * * Created on: Jul 24, 2016 * Author: tkl */ #include #include #include "stm32f4xx.h" #include "stm32f4xx_isr.h" #include "stm32f4_uart.h" struct stm32f4_uart_obj { const void *callback; //!< Interrupt callback. const void *parameter; //!< argument for the callback. }; static volatile struct stm32f4_uart_obj uart1_obj; int stm32f4_uart_open(const void *this) { struct stm32f4_uart *uart = (struct stm32f4_uart *)this; uint8_t gpio_af = 0; uint32_t rcc_apb_uart = 0, rcc_apb_gpio = 0; if(uart->usart_port == USART1) { gpio_af = GPIO_AF_USART1; rcc_apb_uart = RCC_APB2Periph_USART1; } if(uart->gpio_port == GPIOA) { rcc_apb_gpio = RCC_AHB1Periph_GPIOA; } else if(uart->gpio_port == GPIOB) { rcc_apb_gpio = RCC_AHB1Periph_GPIOB; } RCC_APB2PeriphClockCmd(rcc_apb_uart, ENABLE); RCC_AHB1PeriphClockCmd(rcc_apb_gpio, ENABLE); GPIO_Init(uart->gpio_port, (GPIO_InitTypeDef *)uart->gpio_init); GPIO_PinAFConfig(uart->gpio_port, uart->pin_src_rx, gpio_af); GPIO_PinAFConfig(uart->gpio_port, uart->pin_src_tx, gpio_af); USART_Init(uart->usart_port, (USART_InitTypeDef *)uart->usart_init); USART_ITConfig(uart->usart_port, uart->usart_it_select, ENABLE); NVIC_Init((NVIC_InitTypeDef *)uart->nvic_init); USART_Cmd(uart->usart_port, ENABLE); return (0); } int stm32f4_uart_close(const void *this) { struct stm32f4_uart *uart = (struct stm32f4_uart *)this; USART_Cmd(uart->usart_port, DISABLE); return (0); } int stm32f4_uart_read(const void *this, char *buffer, int len) { struct stm32f4_uart *uart = (struct stm32f4_uart *)this; *buffer = uart->usart_port->DR; return (1); } int stm32f4_uart_write(const void *this, const char *buffer, int len) { struct stm32f4_uart *uart = (struct stm32f4_uart *)this; int i; for(i = 0; i < len; i++) { // wait until data register is empty while(!(uart->usart_port->SR & 0x00000040)); USART_SendData(uart->usart_port, buffer[i]); } return (i); } int stm32f4_uart_set_cb(const void *this, const void *callback, const void *param) { struct stm32f4_uart *uart = (struct stm32f4_uart *)this; if(uart->usart_port == USART1) { uart1_obj.callback = callback; uart1_obj.parameter = param; } return (0); } // this is the interrupt request handler (IRQ) for ALL USART1 interrupts void USART1_IRQHandler(void) { enter_isr(); // check if the USART1 receive interrupt flag was set if(USART_GetITStatus(USART1, USART_IT_RXNE)) { if(uart1_obj.callback) { void (*cb)(const void *) = uart1_obj.callback; cb(uart1_obj.parameter); } } exit_isr(); }