103 lines
2.5 KiB
C
103 lines
2.5 KiB
C
/*
|
|
* stm32f4_uart.c
|
|
*
|
|
* Created on: Jul 24, 2016
|
|
* Author: tkl
|
|
*/
|
|
|
|
#include <stddef.h>
|
|
#include <stdint.h>
|
|
|
|
#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();
|
|
}
|