board/cpu: adjusted uart driver implementations
for - sam3x8e - stm32f0 - stm32f4 - sam3x8e - nrf51822
This commit is contained in:
parent
8a80b2add8
commit
037820d6a6
@ -33,6 +33,14 @@
|
||||
*/
|
||||
#define HW_TIMER TIMER_0
|
||||
|
||||
/**
|
||||
* @name Define UART device and baudrate for stdio
|
||||
* @{
|
||||
*/
|
||||
#define STDIO UART_0
|
||||
#define STDIO_BAUDRATE (115200U)
|
||||
/** @} */
|
||||
|
||||
/**
|
||||
* @name LED pin definitions
|
||||
* @{
|
||||
|
||||
@ -73,6 +73,7 @@
|
||||
/* UART 0 device configuration */
|
||||
#define UART_0_DEV USART1
|
||||
#define UART_0_CLKEN() (RCC->APB2ENR |= RCC_APB2ENR_USART1EN)
|
||||
#define UART_0_CLKDIS() (RCC->APB2ENR &= (~RCC_APB2ENR_USART1EN))
|
||||
#define UART_0_IRQ USART1_IRQn
|
||||
#define UART_0_ISR isr_usart1
|
||||
/* UART 0 pin configuration */
|
||||
@ -85,6 +86,7 @@
|
||||
/* UART 1 device configuration */
|
||||
#define UART_1_DEV USART2
|
||||
#define UART_1_CLKEN() (RCC->APB1ENR |= RCC_APB1ENR_USART2EN)
|
||||
#define UART_1_CLKDIS() (RCC->APB1ENR &= (~RCC_APB1ENR_USART2EN))
|
||||
#define UART_1_IRQ USART2_IRQn
|
||||
#define UART_1_ISR isr_usart2
|
||||
/* UART 1 pin configuration */
|
||||
|
||||
@ -80,6 +80,7 @@
|
||||
/* UART 0 device configuration */
|
||||
#define UART_0_DEV USART2
|
||||
#define UART_0_CLKEN() (RCC->APB1ENR |= RCC_APB1ENR_USART2EN)
|
||||
#define UART_0_CLKDIS() (RCC->APB1ENR &= ~(RCC_APB1ENR_USART2EN))
|
||||
#define UART_0_CLK (42000000) /* UART clock runs with 42MHz (F_CPU / 4) */
|
||||
#define UART_0_IRQ_CHAN USART2_IRQn
|
||||
#define UART_0_ISR isr_usart2
|
||||
@ -93,6 +94,7 @@
|
||||
/* UART 1 device configuration */
|
||||
#define UART_1_DEV USART3
|
||||
#define UART_1_CLKEN() (RCC->APB1ENR |= RCC_APB1ENR_USART3EN)
|
||||
#define UART_1_CLKDIS() (RCC->APB1ENR &= ~(RCC_APB1ENR_USART3EN))
|
||||
#define UART_1_CLK (42000000) /* UART clock runs with 42MHz (F_CPU / 4) */
|
||||
#define UART_1_IRQ_CHAN USART3_IRQn
|
||||
#define UART_1_ISR isr_usart3
|
||||
|
||||
@ -35,6 +35,14 @@
|
||||
*/
|
||||
#define HW_TIMER TIMER_0
|
||||
|
||||
/**
|
||||
* @name Define UART device and baudrate for stdio
|
||||
* @{
|
||||
*/
|
||||
#define STDIO UART_0
|
||||
#define STDIO_BAUDRATE (115200U)
|
||||
/** @} */
|
||||
|
||||
/**
|
||||
* @name LED pin definitions
|
||||
* @{
|
||||
|
||||
@ -29,12 +29,16 @@
|
||||
#define ENABLE_DEBUG (0)
|
||||
#include "debug.h"
|
||||
|
||||
/* guard file in case no UART device was specified */
|
||||
#if UART_NUMOF
|
||||
|
||||
/**
|
||||
* @brief Each UART device has to store two callbacks.
|
||||
*/
|
||||
typedef struct {
|
||||
void (*rx_cb)(char);
|
||||
void (*tx_cb)(void);
|
||||
uart_rx_cb_t rx_cb;
|
||||
uart_tx_cb_t tx_cb;
|
||||
void *arg;
|
||||
} uart_conf_t;
|
||||
|
||||
/**
|
||||
@ -42,7 +46,7 @@ typedef struct {
|
||||
*
|
||||
* TODO: this function needs to be implemented
|
||||
*/
|
||||
int uart_init(uart_t uart, uint32_t baudrate, void (*rx_cb)(char), void (*tx_cb)(void))
|
||||
int uart_init(uart_t uart, uint32_t baudrate, uart_rx_cb_t rx_cb, uart_tx_cb_t tx_cb, void *arg)
|
||||
{
|
||||
|
||||
int res;
|
||||
@ -141,9 +145,6 @@ int uart_init_blocking(uart_t uart, uint32_t baudrate)
|
||||
UART_0_DEV->TASKS_STARTRX = 1;
|
||||
break;
|
||||
#endif
|
||||
case UART_UNDEFINED:
|
||||
return -2;
|
||||
break;
|
||||
}
|
||||
|
||||
DEBUG("UART INITIALIZATION complete\n");
|
||||
@ -167,8 +168,6 @@ int uart_write(uart_t uart, char data)
|
||||
case UART_0:
|
||||
UART_0_DEV->TXD = (uint8_t)data;
|
||||
break;
|
||||
case UART_UNDEFINED:
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 1;
|
||||
@ -188,8 +187,6 @@ int uart_read_blocking(uart_t uart, char *data)
|
||||
DEBUG("Reading data\n");
|
||||
*data = (char)(UART_0_DEV->RXD & 0xff);
|
||||
break;
|
||||
case UART_UNDEFINED:
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 1;
|
||||
@ -206,9 +203,9 @@ int uart_write_blocking(uart_t uart, char data)
|
||||
/* reset ready flag */
|
||||
UART_0_DEV->EVENTS_TXDRDY = 0;
|
||||
break;
|
||||
case UART_UNDEFINED:
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
#endif /* UART_NUMOF */
|
||||
|
||||
@ -24,25 +24,25 @@
|
||||
#include "periph/uart.h"
|
||||
#include "periph_conf.h"
|
||||
|
||||
/* guard file in case no UART device was specified */
|
||||
#if UART_NUMOF
|
||||
|
||||
/**
|
||||
* @brief Each UART device has to store two callbacks.
|
||||
*/
|
||||
typedef struct {
|
||||
void (*rx_cb)(char);
|
||||
void (*tx_cb)(void);
|
||||
uart_rx_cb_t rx_cb;
|
||||
uart_tx_cb_t tx_cb;
|
||||
void *arg;
|
||||
} uart_conf_t;
|
||||
|
||||
/**
|
||||
* @brief Allocate memory to store the callback functions.
|
||||
*/
|
||||
static uart_conf_t config[UART_NUMOF];
|
||||
static uart_conf_t uart_config[UART_NUMOF];
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
int uart_init(uart_t uart, uint32_t baudrate, void (*rx_cb)(char), void (*tx_cb)(void))
|
||||
int uart_init(uart_t uart, uint32_t baudrate, uart_rx_cb_t rx_cb, uart_tx_cb_t tx_cb, void *arg)
|
||||
{
|
||||
/* initialize basic functionality */
|
||||
int res = uart_init_blocking(uart, baudrate);
|
||||
@ -51,16 +51,15 @@ int uart_init(uart_t uart, uint32_t baudrate, void (*rx_cb)(char), void (*tx_cb)
|
||||
}
|
||||
|
||||
/* register callbacks */
|
||||
config[uart].rx_cb = rx_cb;
|
||||
config[uart].tx_cb = tx_cb;
|
||||
uart_config[uart].rx_cb = rx_cb;
|
||||
uart_config[uart].tx_cb = tx_cb;
|
||||
uart_config[uart].arg = arg;
|
||||
|
||||
/* configure interrupts and enable RX interrupt */
|
||||
switch (uart) {
|
||||
case UART_0:
|
||||
UART_0_DEV->UART_IER = UART_IER_RXRDY;
|
||||
break;
|
||||
case UART_UNDEFINED:
|
||||
return -2;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
@ -83,9 +82,6 @@ int uart_init_blocking(uart_t uart, uint32_t baudrate)
|
||||
UART_0_DEV->UART_CR = UART_CR_RXEN | UART_CR_TXEN | UART_CR_RSTSTA;
|
||||
break;
|
||||
#endif
|
||||
case UART_UNDEFINED:
|
||||
return -2;
|
||||
break;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
@ -106,8 +102,6 @@ int uart_write(uart_t uart, char data)
|
||||
case UART_0:
|
||||
UART_0_DEV->UART_THR = data;
|
||||
break;
|
||||
case UART_UNDEFINED:
|
||||
return -1;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
@ -119,8 +113,6 @@ int uart_read_blocking(uart_t uart, char *data)
|
||||
while (!(UART_0_DEV->UART_SR & UART_SR_RXRDY));
|
||||
*data = (char)UART_0_DEV->UART_RHR;
|
||||
break;
|
||||
case UART_UNDEFINED:
|
||||
return -1;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
@ -132,8 +124,18 @@ int uart_write_blocking(uart_t uart, char data)
|
||||
while (!(UART_0_DEV->UART_SR & UART_SR_TXRDY));
|
||||
UART_0_DEV->UART_THR = data;
|
||||
break;
|
||||
case UART_UNDEFINED:
|
||||
return -1;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
void uart_poweron(uart_t uart)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void uart_poweroff(uart_t uart)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
#endif /* UART_NUMOF */
|
||||
|
||||
@ -28,6 +28,7 @@
|
||||
#include <sys/unistd.h>
|
||||
#include <stdint.h>
|
||||
|
||||
#include "board.h"
|
||||
#include "thread.h"
|
||||
#include "kernel.h"
|
||||
#include "irq.h"
|
||||
@ -45,7 +46,7 @@ caddr_t heap_top = (caddr_t)&_end + 4;
|
||||
*/
|
||||
void _init(void)
|
||||
{
|
||||
uart_init_blocking(UART_0, 115200);
|
||||
uart_init_blocking(STDIO, STDIO_BAUDRATE);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@ -22,19 +22,23 @@
|
||||
|
||||
#include "cpu.h"
|
||||
#include "board.h"
|
||||
#include "sched.h"
|
||||
#include "thread.h"
|
||||
#include "periph_conf.h"
|
||||
#include "periph/uart.h"
|
||||
|
||||
/* guard file in case no UART device was specified */
|
||||
#if UART_NUMOF
|
||||
|
||||
/**
|
||||
* @brief Each UART device has to store two callbacks.
|
||||
*/
|
||||
typedef struct {
|
||||
void (*rx_cb)(char);
|
||||
void (*tx_cb)(void);
|
||||
uart_rx_cb_t rx_cb;
|
||||
uart_tx_cb_t tx_cb;
|
||||
void *arg;
|
||||
} uart_conf_t;
|
||||
|
||||
|
||||
/**
|
||||
* @brief Unified interrupt handler for all UART devices
|
||||
*
|
||||
@ -43,14 +47,13 @@ typedef struct {
|
||||
*/
|
||||
static inline void irq_handler(uart_t uartnum, USART_TypeDef *uart);
|
||||
|
||||
|
||||
/**
|
||||
* @brief Allocate memory to store the callback functions.
|
||||
*/
|
||||
static uart_conf_t config[UART_NUMOF];
|
||||
static uart_conf_t uart_config[UART_NUMOF];
|
||||
|
||||
|
||||
int uart_init(uart_t uart, uint32_t baudrate, void (*rx_cb)(char), void (*tx_cb)(void))
|
||||
int uart_init(uart_t uart, uint32_t baudrate, uart_rx_cb_t rx_cb, uart_tx_cb_t tx_cb, void *arg)
|
||||
{
|
||||
int res;
|
||||
|
||||
@ -76,24 +79,23 @@ int uart_init(uart_t uart, uint32_t baudrate, void (*rx_cb)(char), void (*tx_cb)
|
||||
UART_1_DEV->CR1 |= USART_CR1_RXNEIE;
|
||||
break;
|
||||
#endif
|
||||
case UART_UNDEFINED:
|
||||
default:
|
||||
return -2;
|
||||
}
|
||||
|
||||
/* register callbacks */
|
||||
config[uart].rx_cb = rx_cb;
|
||||
config[uart].tx_cb = tx_cb;
|
||||
uart_config[uart].rx_cb = rx_cb;
|
||||
uart_config[uart].tx_cb = tx_cb;
|
||||
uart_config[uart].arg = arg;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int uart_init_blocking(uart_t uart, uint32_t baudrate)
|
||||
{
|
||||
USART_TypeDef *dev;
|
||||
GPIO_TypeDef *port;
|
||||
uint32_t rx_pin, tx_pin;
|
||||
uint8_t af;
|
||||
USART_TypeDef *dev = 0;
|
||||
GPIO_TypeDef *port = 0;
|
||||
uint32_t rx_pin = 0;
|
||||
uint32_t tx_pin = 0;
|
||||
uint8_t af = 0;
|
||||
float divider;
|
||||
uint16_t mantissa;
|
||||
uint8_t fraction;
|
||||
@ -124,9 +126,6 @@ int uart_init_blocking(uart_t uart, uint32_t baudrate)
|
||||
UART_1_PORT_CLKEN();
|
||||
break;
|
||||
#endif
|
||||
case UART_UNDEFINED:
|
||||
default:
|
||||
return -2;
|
||||
}
|
||||
|
||||
/* configure RX and TX pins, set pin to use alternative function mode */
|
||||
@ -176,33 +175,12 @@ void uart_tx_begin(uart_t uart)
|
||||
UART_1_DEV->CR1 |= USART_CR1_TXEIE;
|
||||
break;
|
||||
#endif
|
||||
case UART_UNDEFINED:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
#include <stdio.h>
|
||||
void uart_tx_end(uart_t uart)
|
||||
{
|
||||
switch (uart) {
|
||||
#if UART_0_EN
|
||||
case UART_0:
|
||||
UART_0_DEV->CR1 &= ~USART_CR1_TXEIE;
|
||||
break;
|
||||
#endif
|
||||
#if UART_1_EN
|
||||
case UART_1:
|
||||
UART_1_DEV->CR1 &= ~USART_CR1_TXEIE;
|
||||
break;
|
||||
#endif
|
||||
case UART_UNDEFINED:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
int uart_write(uart_t uart, char data)
|
||||
{
|
||||
USART_TypeDef *dev;
|
||||
USART_TypeDef *dev = 0;
|
||||
|
||||
switch (uart) {
|
||||
#if UART_0_EN
|
||||
@ -215,9 +193,6 @@ int uart_write(uart_t uart, char data)
|
||||
dev = UART_1_DEV;
|
||||
break;
|
||||
#endif
|
||||
case UART_UNDEFINED:
|
||||
default:
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (dev->ISR & USART_ISR_TXE) {
|
||||
@ -229,7 +204,7 @@ int uart_write(uart_t uart, char data)
|
||||
|
||||
int uart_read_blocking(uart_t uart, char *data)
|
||||
{
|
||||
USART_TypeDef *dev;
|
||||
USART_TypeDef *dev = 0;
|
||||
|
||||
switch (uart) {
|
||||
#if UART_0_EN
|
||||
@ -242,9 +217,6 @@ int uart_read_blocking(uart_t uart, char *data)
|
||||
dev = UART_1_DEV;
|
||||
break;
|
||||
#endif
|
||||
case UART_UNDEFINED:
|
||||
default:
|
||||
return -1;
|
||||
}
|
||||
|
||||
while (!(dev->ISR & USART_ISR_RXNE));
|
||||
@ -255,7 +227,7 @@ int uart_read_blocking(uart_t uart, char *data)
|
||||
|
||||
int uart_write_blocking(uart_t uart, char data)
|
||||
{
|
||||
USART_TypeDef *dev;
|
||||
USART_TypeDef *dev = 0;
|
||||
|
||||
switch (uart) {
|
||||
#if UART_0_EN
|
||||
@ -268,9 +240,6 @@ int uart_write_blocking(uart_t uart, char data)
|
||||
dev = UART_1_DEV;
|
||||
break;
|
||||
#endif
|
||||
case UART_UNDEFINED:
|
||||
default:
|
||||
return -1;
|
||||
}
|
||||
|
||||
while (!(dev->ISR & USART_ISR_TXE));
|
||||
@ -279,31 +248,74 @@ int uart_write_blocking(uart_t uart, char data)
|
||||
return 1;
|
||||
}
|
||||
|
||||
void uart_poweron(uart_t uart)
|
||||
{
|
||||
switch (uart) {
|
||||
#if UART_0_EN
|
||||
case UART_0:
|
||||
UART_0_CLKEN();
|
||||
break;
|
||||
#endif
|
||||
#if UART_1_EN
|
||||
case UART_1:
|
||||
UART_1_CLKEN();
|
||||
break;
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
void uart_poweroff(uart_t uart)
|
||||
{
|
||||
switch (uart) {
|
||||
#if UART_0_EN
|
||||
case UART_0:
|
||||
UART_0_CLKDIS();
|
||||
break;
|
||||
#endif
|
||||
#if UART_1_EN
|
||||
case UART_1:
|
||||
UART_1_CLKDIS();
|
||||
break;
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
#if UART_0_EN
|
||||
__attribute__((naked)) void UART_0_ISR(void)
|
||||
{
|
||||
ISR_ENTER();
|
||||
irq_handler(UART_0, UART_0_DEV);
|
||||
ISR_EXIT();
|
||||
}
|
||||
#endif
|
||||
|
||||
#if UART_1_EN
|
||||
__attribute__((naked)) void UART_1_ISR(void)
|
||||
{
|
||||
ISR_ENTER();
|
||||
irq_handler(UART_1, UART_1_DEV);
|
||||
ISR_EXIT();
|
||||
}
|
||||
#endif
|
||||
|
||||
static inline void irq_handler(uint8_t uartnum, USART_TypeDef *dev)
|
||||
{
|
||||
if (dev->ISR & USART_ISR_RXNE) {
|
||||
char data = (char)dev->RDR;
|
||||
config[uartnum].rx_cb(data);
|
||||
uart_config[uartnum].rx_cb(uart_config[uartnum].arg, data);
|
||||
}
|
||||
else if (dev->ISR & USART_ISR_ORE) {
|
||||
/* do nothing on overrun */
|
||||
dev->ICR |= USART_ICR_ORECF;
|
||||
}
|
||||
else if (dev->ISR & USART_ISR_TXE) {
|
||||
config[uartnum].tx_cb();
|
||||
if (uart_config[uartnum].tx_cb(uart_config[uartnum].arg) == 0) {
|
||||
dev->CR1 &= ~USART_CR1_TXEIE;
|
||||
}
|
||||
}
|
||||
if (sched_context_switch_request) {
|
||||
thread_yield();
|
||||
}
|
||||
}
|
||||
|
||||
#endif /* UART_NUMOF */
|
||||
|
||||
@ -24,13 +24,16 @@
|
||||
#include "periph_conf.h"
|
||||
#include "periph/uart.h"
|
||||
|
||||
/* guard file in case no UART device was specified */
|
||||
#if UART_NUMOF
|
||||
|
||||
/**
|
||||
* @brief Each UART device has to store two callbacks.
|
||||
*/
|
||||
typedef struct {
|
||||
void (*rx_cb)(char);
|
||||
void (*tx_cb)(void);
|
||||
uart_rx_cb_t rx_cb;
|
||||
uart_tx_cb_t tx_cb;
|
||||
void *arg;
|
||||
} uart_conf_t;
|
||||
|
||||
/**
|
||||
@ -44,9 +47,9 @@ static inline void irq_handler(uart_t uartnum, USART_TypeDef *uart);
|
||||
/**
|
||||
* @brief Allocate memory to store the callback functions.
|
||||
*/
|
||||
static uart_conf_t config[UART_NUMOF];
|
||||
static uart_conf_t uart_config[UART_NUMOF];
|
||||
|
||||
int uart_init(uart_t uart, uint32_t baudrate, void (*rx_cb)(char), void (*tx_cb)(void))
|
||||
int uart_init(uart_t uart, uint32_t baudrate, uart_rx_cb_t rx_cb, uart_tx_cb_t tx_cb, void *arg)
|
||||
{
|
||||
/* do basic initialization */
|
||||
int res = uart_init_blocking(uart, baudrate);
|
||||
@ -55,8 +58,10 @@ int uart_init(uart_t uart, uint32_t baudrate, void (*rx_cb)(char), void (*tx_cb)
|
||||
}
|
||||
|
||||
/* remember callback addresses */
|
||||
config[uart].rx_cb = rx_cb;
|
||||
config[uart].tx_cb = tx_cb;
|
||||
uart_config[uart].rx_cb = rx_cb;
|
||||
uart_config[uart].tx_cb = tx_cb;
|
||||
uart_config[uart].arg = arg;
|
||||
|
||||
|
||||
/* enable receive interrupt */
|
||||
switch (uart) {
|
||||
@ -81,10 +86,6 @@ int uart_init(uart_t uart, uint32_t baudrate, void (*rx_cb)(char), void (*tx_cb)
|
||||
UART_2_DEV->CR1 |= USART_CR1_RXNEIE;
|
||||
break;
|
||||
#endif
|
||||
case UART_UNDEFINED:
|
||||
default:
|
||||
return -2;
|
||||
break;
|
||||
}
|
||||
|
||||
return 0;
|
||||
@ -92,12 +93,12 @@ int uart_init(uart_t uart, uint32_t baudrate, void (*rx_cb)(char), void (*tx_cb)
|
||||
|
||||
int uart_init_blocking(uart_t uart, uint32_t baudrate)
|
||||
{
|
||||
USART_TypeDef *dev;
|
||||
GPIO_TypeDef *port;
|
||||
uint32_t tx_pin;
|
||||
uint32_t rx_pin;
|
||||
uint8_t af;
|
||||
float clk;
|
||||
USART_TypeDef *dev = 0;
|
||||
GPIO_TypeDef *port = 0;
|
||||
uint32_t tx_pin = 0;
|
||||
uint32_t rx_pin = 0;
|
||||
uint8_t af = 0;
|
||||
float clk = 0;
|
||||
float divider;
|
||||
uint16_t mantissa;
|
||||
uint8_t fraction;
|
||||
@ -139,12 +140,9 @@ int uart_init_blocking(uart_t uart, uint32_t baudrate)
|
||||
UART_2_PORT_CLKEN();
|
||||
break;
|
||||
#endif
|
||||
case UART_UNDEFINED:
|
||||
default:
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* configure RX and TX pins, set pin to use alternative function mode */
|
||||
/* uart_configure RX and TX pins, set pin to use alternative function mode */
|
||||
port->MODER &= ~(3 << (rx_pin * 2) | 3 << (tx_pin * 2));
|
||||
port->MODER |= 2 << (rx_pin * 2) | 2 << (tx_pin * 2);
|
||||
/* and assign alternative function */
|
||||
@ -165,7 +163,7 @@ int uart_init_blocking(uart_t uart, uint32_t baudrate)
|
||||
port->AFR[1] |= af << ((tx_pin - 8) * 4);
|
||||
}
|
||||
|
||||
/* configure UART to mode 8N1 with given baudrate */
|
||||
/* uart_configure UART to mode 8N1 with given baudrate */
|
||||
divider = clk / (16 * baudrate);
|
||||
mantissa = (uint16_t)divider;
|
||||
fraction = (uint8_t)((divider - mantissa) * 16);
|
||||
@ -198,39 +196,12 @@ void uart_tx_begin(uart_t uart)
|
||||
UART_2_DEV->CR1 |= USART_CR1_TXEIE;
|
||||
break;
|
||||
#endif
|
||||
case UART_UNDEFINED:
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void uart_tx_end(uart_t uart)
|
||||
{
|
||||
switch (uart) {
|
||||
#if UART_0_EN
|
||||
case UART_0:
|
||||
UART_0_DEV->CR1 &= ~USART_CR1_TXEIE;
|
||||
break;
|
||||
#endif
|
||||
#if UART_1_EN
|
||||
case UART_1:
|
||||
UART_1_DEV->CR1 &= ~USART_CR1_TXEIE;
|
||||
break;
|
||||
#endif
|
||||
#if UART_2_EN
|
||||
case UART_2:
|
||||
UART_2_DEV->CR1 &= ~USART_CR1_TXEIE;
|
||||
break;
|
||||
#endif
|
||||
case UART_UNDEFINED:
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
int uart_write(uart_t uart, char data)
|
||||
{
|
||||
USART_TypeDef *dev;
|
||||
USART_TypeDef *dev = 0;
|
||||
|
||||
switch (uart) {
|
||||
#if UART_0_EN
|
||||
@ -248,10 +219,6 @@ int uart_write(uart_t uart, char data)
|
||||
dev = UART_2_DEV;
|
||||
break;
|
||||
#endif
|
||||
case UART_UNDEFINED:
|
||||
default:
|
||||
return -2;
|
||||
break;
|
||||
}
|
||||
|
||||
if (dev->ISR & USART_ISR_TXE) {
|
||||
@ -263,7 +230,7 @@ int uart_write(uart_t uart, char data)
|
||||
|
||||
int uart_read_blocking(uart_t uart, char *data)
|
||||
{
|
||||
USART_TypeDef *dev;
|
||||
USART_TypeDef *dev = 0;
|
||||
|
||||
switch (uart) {
|
||||
#if UART_0_EN
|
||||
@ -281,10 +248,6 @@ int uart_read_blocking(uart_t uart, char *data)
|
||||
dev = UART_2_DEV;
|
||||
break;
|
||||
#endif
|
||||
case UART_UNDEFINED:
|
||||
default:
|
||||
return -2;
|
||||
break;
|
||||
}
|
||||
|
||||
while (!(dev->ISR & USART_ISR_RXNE));
|
||||
@ -295,7 +258,7 @@ int uart_read_blocking(uart_t uart, char *data)
|
||||
|
||||
int uart_write_blocking(uart_t uart, char data)
|
||||
{
|
||||
USART_TypeDef *dev;
|
||||
USART_TypeDef *dev = 0;
|
||||
|
||||
switch (uart) {
|
||||
#if UART_0_EN
|
||||
@ -313,10 +276,6 @@ int uart_write_blocking(uart_t uart, char data)
|
||||
dev = UART_2_DEV;
|
||||
break;
|
||||
#endif
|
||||
case UART_UNDEFINED:
|
||||
default:
|
||||
return -2;
|
||||
break;
|
||||
}
|
||||
|
||||
while (!(dev->ISR & USART_ISR_TXE));
|
||||
@ -356,12 +315,16 @@ static inline void irq_handler(uint8_t uartnum, USART_TypeDef *dev)
|
||||
{
|
||||
if (dev->ISR & USART_ISR_RXNE) {
|
||||
char data = (char)dev->RDR;
|
||||
config[uartnum].rx_cb(data);
|
||||
uart_config[uartnum].rx_cb(uart_config[uartnum].arg, data);
|
||||
}
|
||||
else if (dev->ISR & USART_ISR_TXE) {
|
||||
config[uartnum].tx_cb();
|
||||
if (uart_config[uartnum].tx_cb(uart_config[uartnum].arg) == 0) {
|
||||
dev->CR1 &= ~(USART_CR1_TXEIE);
|
||||
}
|
||||
}
|
||||
if (sched_context_switch_request) {
|
||||
thread_yield();
|
||||
}
|
||||
}
|
||||
|
||||
#endif /* UART_NUMOF */
|
||||
|
||||
@ -53,8 +53,10 @@ static ringbuffer_t rx_buf;
|
||||
/**
|
||||
* @brief Receive a new character from the UART and put it into the receive buffer
|
||||
*/
|
||||
void rx_cb(char data)
|
||||
void rx_cb(void *arg, char data)
|
||||
{
|
||||
(void)arg;
|
||||
|
||||
ringbuffer_add_one(&rx_buf, data);
|
||||
mutex_unlock(&uart_rx_mutex);
|
||||
}
|
||||
@ -66,7 +68,7 @@ void _init(void)
|
||||
{
|
||||
mutex_init(&uart_rx_mutex);
|
||||
ringbuffer_init(&rx_buf, rx_buf_mem, STDIO_BUFSIZE);
|
||||
uart_init(STDIO, STDIO_BAUDRATE, rx_cb, 0);
|
||||
uart_init(STDIO, STDIO_BAUDRATE, rx_cb, 0, 0);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@ -18,21 +18,22 @@
|
||||
* @}
|
||||
*/
|
||||
|
||||
#include <math.h>
|
||||
|
||||
#include "cpu.h"
|
||||
#include "thread.h"
|
||||
#include "sched.h"
|
||||
#include "periph_conf.h"
|
||||
#include "periph/uart.h"
|
||||
|
||||
/* guard file in case no UART device was specified */
|
||||
#if UART_NUMOF
|
||||
|
||||
/**
|
||||
* @brief Each UART device has to store two callbacks.
|
||||
*/
|
||||
typedef struct {
|
||||
void (*rx_cb)(char);
|
||||
void (*tx_cb)(void);
|
||||
uart_rx_cb_t rx_cb;
|
||||
uart_tx_cb_t tx_cb;
|
||||
void *arg;
|
||||
} uart_conf_t;
|
||||
|
||||
/**
|
||||
@ -46,9 +47,9 @@ static inline void irq_handler(uart_t uartnum, USART_TypeDef *uart);
|
||||
/**
|
||||
* @brief Allocate memory to store the callback functions.
|
||||
*/
|
||||
static uart_conf_t config[UART_NUMOF];
|
||||
static uart_conf_t uart_config[UART_NUMOF];
|
||||
|
||||
int uart_init(uart_t uart, uint32_t baudrate, void (*rx_cb)(char), void (*tx_cb)(void))
|
||||
int uart_init(uart_t uart, uint32_t baudrate, uart_rx_cb_t rx_cb, uart_tx_cb_t tx_cb, void *arg)
|
||||
{
|
||||
/* do basic initialization */
|
||||
int res = uart_init_blocking(uart, baudrate);
|
||||
@ -57,8 +58,9 @@ int uart_init(uart_t uart, uint32_t baudrate, void (*rx_cb)(char), void (*tx_cb)
|
||||
}
|
||||
|
||||
/* remember callback addresses */
|
||||
config[uart].rx_cb = rx_cb;
|
||||
config[uart].tx_cb = tx_cb;
|
||||
uart_config[uart].rx_cb = rx_cb;
|
||||
uart_config[uart].tx_cb = tx_cb;
|
||||
uart_config[uart].arg = arg;
|
||||
|
||||
/* enable receive interrupt */
|
||||
switch (uart) {
|
||||
@ -76,10 +78,6 @@ int uart_init(uart_t uart, uint32_t baudrate, void (*rx_cb)(char), void (*tx_cb)
|
||||
UART_1_DEV->CR1 |= USART_CR1_RXNEIE;
|
||||
break;
|
||||
#endif
|
||||
case UART_UNDEFINED:
|
||||
default:
|
||||
return -2;
|
||||
break;
|
||||
}
|
||||
|
||||
return 0;
|
||||
@ -87,12 +85,12 @@ int uart_init(uart_t uart, uint32_t baudrate, void (*rx_cb)(char), void (*tx_cb)
|
||||
|
||||
int uart_init_blocking(uart_t uart, uint32_t baudrate)
|
||||
{
|
||||
USART_TypeDef *dev;
|
||||
GPIO_TypeDef *port;
|
||||
uint32_t tx_pin;
|
||||
uint32_t rx_pin;
|
||||
uint8_t af;
|
||||
float clk;
|
||||
USART_TypeDef *dev = 0;
|
||||
GPIO_TypeDef *port = 0;
|
||||
uint32_t tx_pin = 0;
|
||||
uint32_t rx_pin = 0;
|
||||
uint8_t af = 0;
|
||||
float clk = 0.0;
|
||||
float divider;
|
||||
uint16_t mantissa;
|
||||
uint8_t fraction;
|
||||
@ -122,9 +120,6 @@ int uart_init_blocking(uart_t uart, uint32_t baudrate)
|
||||
UART_1_PORT_CLKEN();
|
||||
break;
|
||||
#endif
|
||||
case UART_UNDEFINED:
|
||||
default:
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* configure RX and TX pins, set pin to use alternative function mode */
|
||||
@ -175,34 +170,12 @@ void uart_tx_begin(uart_t uart)
|
||||
UART_1_DEV->CR1 |= USART_CR1_TXEIE;
|
||||
break;
|
||||
#endif
|
||||
case UART_UNDEFINED:
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void uart_tx_end(uart_t uart)
|
||||
{
|
||||
switch (uart) {
|
||||
#if UART_0_EN
|
||||
case UART_0:
|
||||
UART_0_DEV->CR1 &= ~USART_CR1_TXEIE;
|
||||
break;
|
||||
#endif
|
||||
#if UART_1_EN
|
||||
case UART_1:
|
||||
UART_1_DEV->CR1 &= ~USART_CR1_TXEIE;
|
||||
break;
|
||||
#endif
|
||||
case UART_UNDEFINED:
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
int uart_write(uart_t uart, char data)
|
||||
{
|
||||
USART_TypeDef *dev;
|
||||
USART_TypeDef *dev = 0;
|
||||
|
||||
switch (uart) {
|
||||
#if UART_0_EN
|
||||
@ -215,10 +188,6 @@ int uart_write(uart_t uart, char data)
|
||||
dev = UART_1_DEV;
|
||||
break;
|
||||
#endif
|
||||
case UART_UNDEFINED:
|
||||
default:
|
||||
return -2;
|
||||
break;
|
||||
}
|
||||
|
||||
if (dev->SR & USART_SR_TXE) {
|
||||
@ -230,7 +199,7 @@ int uart_write(uart_t uart, char data)
|
||||
|
||||
int uart_read_blocking(uart_t uart, char *data)
|
||||
{
|
||||
USART_TypeDef *dev;
|
||||
USART_TypeDef *dev = 0;
|
||||
|
||||
switch (uart) {
|
||||
#if UART_0_EN
|
||||
@ -243,10 +212,6 @@ int uart_read_blocking(uart_t uart, char *data)
|
||||
dev = UART_1_DEV;
|
||||
break;
|
||||
#endif
|
||||
case UART_UNDEFINED:
|
||||
default:
|
||||
return -2;
|
||||
break;
|
||||
}
|
||||
|
||||
while (!(dev->SR & USART_SR_RXNE));
|
||||
@ -257,7 +222,7 @@ int uart_read_blocking(uart_t uart, char *data)
|
||||
|
||||
int uart_write_blocking(uart_t uart, char data)
|
||||
{
|
||||
USART_TypeDef *dev;
|
||||
USART_TypeDef *dev = 0;
|
||||
|
||||
switch (uart) {
|
||||
#if UART_0_EN
|
||||
@ -270,10 +235,6 @@ int uart_write_blocking(uart_t uart, char data)
|
||||
dev = UART_1_DEV;
|
||||
break;
|
||||
#endif
|
||||
case UART_UNDEFINED:
|
||||
default:
|
||||
return -2;
|
||||
break;
|
||||
}
|
||||
|
||||
while (!(dev->SR & USART_SR_TXE));
|
||||
@ -282,32 +243,70 @@ int uart_write_blocking(uart_t uart, char data)
|
||||
return 1;
|
||||
}
|
||||
|
||||
__attribute__((naked))
|
||||
void UART_0_ISR(void)
|
||||
void uart_poweron(uart_t uart)
|
||||
{
|
||||
switch (uart) {
|
||||
#if UART_0_EN
|
||||
case UART_0:
|
||||
UART_0_CLKEN();
|
||||
break;
|
||||
#endif
|
||||
#if UART_1_EN
|
||||
case UART_1:
|
||||
UART_1_CLKEN();
|
||||
break;
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
void uart_poweroff(uart_t uart)
|
||||
{
|
||||
switch (uart) {
|
||||
#if UART_0_EN
|
||||
case UART_0:
|
||||
UART_0_CLKDIS();
|
||||
break;
|
||||
#endif
|
||||
#if UART_1_EN
|
||||
case UART_1:
|
||||
UART_1_CLKDIS();
|
||||
break;
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
#if UART_0_EN
|
||||
__attribute__((naked)) void UART_0_ISR(void)
|
||||
{
|
||||
ISR_ENTER();
|
||||
irq_handler(UART_0, UART_0_DEV);
|
||||
ISR_EXIT();
|
||||
}
|
||||
#endif
|
||||
|
||||
__attribute__((naked))
|
||||
void UART_1_ISR(void)
|
||||
#if UART_1_EN
|
||||
__attribute__((naked)) void UART_1_ISR(void)
|
||||
{
|
||||
ISR_ENTER();
|
||||
irq_handler(UART_1, UART_1_DEV);
|
||||
ISR_EXIT();
|
||||
}
|
||||
#endif
|
||||
|
||||
static inline void irq_handler(uint8_t uartnum, USART_TypeDef *dev)
|
||||
{
|
||||
if (dev->SR & USART_SR_RXNE) {
|
||||
char data = (char)dev->DR;
|
||||
config[uartnum].rx_cb(data);
|
||||
uart_config[uartnum].rx_cb(uart_config[uartnum].arg, data);
|
||||
}
|
||||
else if (dev->SR & USART_SR_TXE) {
|
||||
config[uartnum].tx_cb();
|
||||
if (uart_config[uartnum].tx_cb(uart_config[uartnum].arg) == 0) {
|
||||
dev->CR1 &= ~(USART_CR1_TXEIE);
|
||||
}
|
||||
}
|
||||
if (sched_context_switch_request) {
|
||||
thread_yield();
|
||||
}
|
||||
}
|
||||
|
||||
#endif /* UART_NUMOF */
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user