Merge pull request #1471 from thomaseichinger/impl_uart0

cpu: make stm32f{0,1,3,4} comply to UART0 module
This commit is contained in:
Thomas Eichinger 2014-09-26 14:20:36 +02:00
commit c4f3b88490
14 changed files with 192 additions and 48 deletions

View File

@ -38,7 +38,8 @@
* @{ * @{
*/ */
#define STDIO UART_0 #define STDIO UART_0
#define STDIO_BAUDRATE (115200) #define STDIO_BAUDRATE (115200U)
#define STDIO_RX_BUFSIZE (64U)
/** @} */ /** @} */
/** /**

View File

@ -40,6 +40,7 @@
*/ */
#define STDIO UART_0 #define STDIO UART_0
#define STDIO_BAUDRATE (115200U) #define STDIO_BAUDRATE (115200U)
#define STDIO_RX_BUFSIZE (64U)
/** @} */ /** @} */
/** /**

View File

@ -38,6 +38,8 @@
* @name Assign the UART interface to be used for stdio * @name Assign the UART interface to be used for stdio
*/ */
#define STDIO UART_0 #define STDIO UART_0
#define STDIO_BAUDRATE (115200U)
#define STDIO_RX_BUFSIZE (64U)
/** /**
* @name LED pin definitions * @name LED pin definitions

View File

@ -39,7 +39,7 @@
*/ */
#define STDIO UART_0 #define STDIO UART_0
#define STDIO_BAUDRATE (115200U) #define STDIO_BAUDRATE (115200U)
#define STDIO_BUFSIZE (64U) #define STDIO_RX_BUFSIZE (64U)
/** @} */ /** @} */
/** /**

View File

@ -40,6 +40,7 @@
*/ */
#define STDIO UART_0 #define STDIO UART_0
#define STDIO_BAUDRATE (115200U) #define STDIO_BAUDRATE (115200U)
#define STDIO_RX_BUFSIZE (64U)
/** @} */ /** @} */
/** /**

View File

@ -7,6 +7,9 @@ export USEMODULE += cortex-m0_common
# define path to cortex-m common module, which is needed for this CPU # define path to cortex-m common module, which is needed for this CPU
export CORTEX_COMMON = $(RIOTCPU)/cortex-m0_common/ export CORTEX_COMMON = $(RIOTCPU)/cortex-m0_common/
# this CPU implementation makes use of the ringbuffer, so include the lib module
export USEMODULE += lib
# define the linker script to use for this CPU. The CPU_MODEL variable is defined in the # define the linker script to use for this CPU. The CPU_MODEL variable is defined in the
# board's Makefile.include. This enables multiple STMF0 controllers with different memory to # board's Makefile.include. This enables multiple STMF0 controllers with different memory to
# use the same code-base. # use the same code-base.

View File

@ -30,10 +30,15 @@
#include "thread.h" #include "thread.h"
#include "kernel.h" #include "kernel.h"
#include "mutex.h"
#include "ringbuffer.h"
#include "irq.h" #include "irq.h"
#include "board.h" #include "board.h"
#include "periph/uart.h" #include "periph/uart.h"
#ifdef MODULE_UART0
#include "board_uart0.h"
#endif
/** /**
* manage the heap * manage the heap
@ -41,12 +46,44 @@
extern uint32_t _end; /* address of last used memory cell */ extern uint32_t _end; /* address of last used memory cell */
caddr_t heap_top = (caddr_t)&_end + 4; caddr_t heap_top = (caddr_t)&_end + 4;
#ifndef MODULE_UART0
/**
* @brief use mutex for waiting on incoming UART chars
*/
static mutex_t uart_rx_mutex;
static char rx_buf_mem[STDIO_RX_BUFSIZE];
static ringbuffer_t rx_buf;
#endif
/**
* @brief Receive a new character from the UART and put it into the receive buffer
*/
void rx_cb(void *arg, char data)
{
#ifndef MODULE_UART0
(void)arg;
ringbuffer_add_one(&rx_buf, data);
mutex_unlock(&uart_rx_mutex);
#else
if (uart0_handler_pid) {
uart0_handle_incoming(data);
uart0_notify_thread();
}
#endif
}
/** /**
* @brief Initialize NewLib, called by __libc_init_array() from the startup script * @brief Initialize NewLib, called by __libc_init_array() from the startup script
*/ */
void _init(void) void _init(void)
{ {
uart_init_blocking(STDIO, 115200); #ifndef MODULE_UART0
mutex_init(&uart_rx_mutex);
ringbuffer_init(&rx_buf, rx_buf_mem, STDIO_RX_BUFSIZE);
#endif
uart_init(STDIO, STDIO_BAUDRATE, rx_cb, 0, 0);
} }
/** /**
@ -152,11 +189,16 @@ int _open_r(struct _reent *r, const char *name, int mode)
*/ */
int _read_r(struct _reent *r, int fd, void *buffer, unsigned int count) int _read_r(struct _reent *r, int fd, void *buffer, unsigned int count)
{ {
char c; #ifndef MODULE_UART0
char *buff = (char*)buffer; while (rx_buf.avail == 0) {
uart_read_blocking(STDIO, &c); mutex_lock(&uart_rx_mutex);
buff[0] = c; }
return ringbuffer_get(&rx_buf, (char*)buffer, rx_buf.avail);
#else
char *res = (char*)buffer;
res[0] = (char)uart0_readc();
return 1; return 1;
#endif
} }
/** /**

View File

@ -4,6 +4,9 @@ export CFLAGS += -DCOREIF_NG=1
# tell the build system that the CPU depends on the Cortex-M common files # tell the build system that the CPU depends on the Cortex-M common files
export USEMODULE += cortex-m3_common export USEMODULE += cortex-m3_common
# this CPU implementation makes use of the ringbuffer, so include the lib module
export USEMODULE += lib
# define path to cortex-m common module, which is needed for this CPU # define path to cortex-m common module, which is needed for this CPU
export CORTEXM_COMMON = $(RIOTCPU)/cortex-m3_common/ export CORTEXM_COMMON = $(RIOTCPU)/cortex-m3_common/

View File

@ -29,11 +29,6 @@
#include "sched.h" #include "sched.h"
#include "thread.h" #include "thread.h"
#ifdef MODULE_UART0
#include "board_uart0.h"
#endif
/** /**
* @brief Each UART device has to store two callbacks. * @brief Each UART device has to store two callbacks.
*/ */
@ -296,28 +291,17 @@ static inline void irq_handler(uint8_t uartnum, USART_TypeDef *dev)
{ {
if (dev->SR & USART_SR_RXNE) { if (dev->SR & USART_SR_RXNE) {
char data = (char)dev->DR; char data = (char)dev->DR;
#ifdef MODULE_UART0
if (uart0_handler_pid) {
uart0_handle_incoming(data);
uart0_notify_thread();
}
#else
config[uartnum].rx_cb(config[uartnum].arg, data); config[uartnum].rx_cb(config[uartnum].arg, data);
#endif
} }
else if (dev->SR & USART_SR_ORE) { else if (dev->SR & USART_SR_ORE) {
/* ORE is cleared by reading SR and DR sequentially */ /* ORE is cleared by reading SR and DR sequentially */
dev->DR; dev->DR;
} }
else if (dev->SR & USART_SR_TXE) { else if (dev->SR & USART_SR_TXE) {
#ifdef MODULE_UART0 if (config[uartnum].tx_cb(config[uartnum].arg) == 0) {
dev->SR &= ~(USART_SR_TXE); dev->CR1 &= ~(USART_CR1_TXEIE);
#else }
config[uartnum].tx_cb(config[uartnum].arg);
#endif
} }
if (sched_context_switch_request) { if (sched_context_switch_request) {
thread_yield(); thread_yield();
} }

View File

@ -28,28 +28,62 @@
#include <sys/unistd.h> #include <sys/unistd.h>
#include <stdint.h> #include <stdint.h>
#include "board.h"
#include "thread.h" #include "thread.h"
#include "kernel.h" #include "kernel.h"
#include "mutex.h"
#include "ringbuffer.h"
#include "irq.h" #include "irq.h"
#include "periph/uart.h" #include "periph/uart.h"
#ifdef MODULE_UART0
#include "board_uart0.h"
#endif
/** /**
* manage the heap * manage the heap
*/ */
extern uint32_t _end; /* address of last used memory cell */ extern uint32_t _end; /* address of last used memory cell */
caddr_t heap_top = (caddr_t)&_end + 4; caddr_t heap_top = (caddr_t)&_end + 4;
#ifndef MODULE_UART0
/**
* @brief use mutex for waiting on incoming UART chars
*/
static mutex_t uart_rx_mutex;
static char rx_buf_mem[STDIO_RX_BUFSIZE];
static ringbuffer_t rx_buf;
#endif
/**
* @brief Receive a new character from the UART and put it into the receive buffer
*/
void rx_cb(void *arg, char data)
{
#ifndef MODULE_UART0
(void)arg;
ringbuffer_add_one(&rx_buf, data);
mutex_unlock(&uart_rx_mutex);
#else
if (uart0_handler_pid) {
uart0_handle_incoming(data);
uart0_notify_thread();
}
#endif
}
/** /**
* @brief Initialize NewLib, called by __libc_init_array() from the startup script * @brief Initialize NewLib, called by __libc_init_array() from the startup script
*/ */
void _init(void) void _init(void)
{ {
#ifdef MODULE_UART0 #ifndef MODULE_UART0
uart_init(UART_0, 115200, NULL, NULL, NULL); mutex_init(&uart_rx_mutex);
#else ringbuffer_init(&rx_buf, rx_buf_mem, STDIO_RX_BUFSIZE);
uart_init_blocking(UART_0, 115200);
#endif #endif
uart_init(STDIO, STDIO_BAUDRATE, rx_cb, 0, 0);
} }
/** /**
@ -155,11 +189,16 @@ int _open_r(struct _reent *r, const char *name, int mode)
*/ */
int _read_r(struct _reent *r, int fd, void *buffer, unsigned int count) int _read_r(struct _reent *r, int fd, void *buffer, unsigned int count)
{ {
char c; #ifndef MODULE_UART0
char *buff = (char*)buffer; while (rx_buf.avail == 0) {
uart_read_blocking(UART_0, &c); mutex_lock(&uart_rx_mutex);
buff[0] = c; }
return ringbuffer_get(&rx_buf, (char*)buffer, rx_buf.avail);
#else
char *res = (char*)buffer;
res[0] = (char)uart0_readc();
return 1; return 1;
#endif
} }
/** /**

View File

@ -37,28 +37,42 @@
#include "irq.h" #include "irq.h"
#include "periph/uart.h" #include "periph/uart.h"
#ifdef MODULE_UART0
#include "board_uart0.h"
#endif
/** /**
* @brief manage the heap * @brief manage the heap
*/ */
extern uint32_t _end; /* address of last used memory cell */ extern uint32_t _end; /* address of last used memory cell */
caddr_t heap_top = (caddr_t)&_end + 4; caddr_t heap_top = (caddr_t)&_end + 4;
#ifndef MODULE_UART0
/** /**
* @brief use mutex for waiting on incoming UART chars * @brief use mutex for waiting on incoming UART chars
*/ */
static mutex_t uart_rx_mutex; static mutex_t uart_rx_mutex;
static char rx_buf_mem[STDIO_BUFSIZE]; static char rx_buf_mem[STDIO_RX_BUFSIZE];
static ringbuffer_t rx_buf; static ringbuffer_t rx_buf;
#endif
/** /**
* @brief Receive a new character from the UART and put it into the receive buffer * @brief Receive a new character from the UART and put it into the receive buffer
*/ */
void rx_cb(void *arg, char data) void rx_cb(void *arg, char data)
{ {
#ifndef MODULE_UART0
(void)arg; (void)arg;
ringbuffer_add_one(&rx_buf, data); ringbuffer_add_one(&rx_buf, data);
mutex_unlock(&uart_rx_mutex); mutex_unlock(&uart_rx_mutex);
#else
if (uart0_handler_pid) {
uart0_handle_incoming(data);
uart0_notify_thread();
}
#endif
} }
/** /**
@ -66,10 +80,11 @@ void rx_cb(void *arg, char data)
*/ */
void _init(void) void _init(void)
{ {
#ifndef MODULE_UART0
mutex_init(&uart_rx_mutex); mutex_init(&uart_rx_mutex);
ringbuffer_init(&rx_buf, rx_buf_mem, STDIO_BUFSIZE); ringbuffer_init(&rx_buf, rx_buf_mem, STDIO_RX_BUFSIZE);
uart_init(STDIO, STDIO_BAUDRATE, rx_cb, 0, 0); #endif
} uart_init(STDIO, STDIO_BAUDRATE, rx_cb, 0, 0);}
/** /**
* @brief Free resources on NewLib de-initialization, not used for RIOT * @brief Free resources on NewLib de-initialization, not used for RIOT
@ -174,10 +189,16 @@ int _open_r(struct _reent *r, const char *name, int mode)
*/ */
int _read_r(struct _reent *r, int fd, void *buffer, unsigned int count) int _read_r(struct _reent *r, int fd, void *buffer, unsigned int count)
{ {
#ifndef MODULE_UART0
while (rx_buf.avail == 0) { while (rx_buf.avail == 0) {
mutex_lock(&uart_rx_mutex); mutex_lock(&uart_rx_mutex);
} }
return ringbuffer_get(&rx_buf, (char*)buffer, rx_buf.avail); return ringbuffer_get(&rx_buf, (char*)buffer, rx_buf.avail);
#else
char *res = (char*)buffer;
res[0] = (char)uart0_readc();
return 1;
#endif
} }
/** /**

View File

@ -4,6 +4,9 @@ export CFLAGS += -DCOREIF_NG=1
# export the peripheral drivers to be linked into the final binary # export the peripheral drivers to be linked into the final binary
export USEMODULE += periph export USEMODULE += periph
# this CPU implementation makes use of the ringbuffer, so include the lib module
export USEMODULE += lib
# tell the build system that the CPU depends on the Cortex-M common files # tell the build system that the CPU depends on the Cortex-M common files
export USEMODULE += cortex-m4_common export USEMODULE += cortex-m4_common

View File

@ -27,7 +27,6 @@
/* guard file in case no UART device was specified */ /* guard file in case no UART device was specified */
#if UART_NUMOF #if UART_NUMOF
/** /**
* @brief Each UART device has to store two callbacks. * @brief Each UART device has to store two callbacks.
*/ */

View File

@ -31,21 +31,59 @@
#include "board.h" #include "board.h"
#include "thread.h" #include "thread.h"
#include "kernel.h" #include "kernel.h"
#include "mutex.h"
#include "ringbuffer.h"
#include "irq.h" #include "irq.h"
#include "periph/uart.h" #include "periph/uart.h"
#ifdef MODULE_UART0
#include "board_uart0.h"
#endif
/** /**
* manage the heap * manage the heap
*/ */
extern uint32_t _end; /* address of last used memory cell */ extern uint32_t _end; /* address of last used memory cell */
caddr_t heap_top = (caddr_t)&_end + 4; caddr_t heap_top = (caddr_t)&_end + 4;
#ifndef MODULE_UART0
/**
* @brief use mutex for waiting on incoming UART chars
*/
static mutex_t uart_rx_mutex;
static char rx_buf_mem[STDIO_RX_BUFSIZE];
static ringbuffer_t rx_buf;
#endif
/**
* @brief Receive a new character from the UART and put it into the receive buffer
*/
void rx_cb(void *arg, char data)
{
#ifndef MODULE_UART0
(void)arg;
ringbuffer_add_one(&rx_buf, data);
mutex_unlock(&uart_rx_mutex);
#else
if (uart0_handler_pid) {
uart0_handle_incoming(data);
uart0_notify_thread();
}
#endif
}
/** /**
* @brief Initialize NewLib, called by __libc_init_array() from the startup script * @brief Initialize NewLib, called by __libc_init_array() from the startup script
*/ */
void _init(void) void _init(void)
{ {
uart_init_blocking(STDIO, STDIO_BAUDRATE); #ifndef MODULE_UART0
mutex_init(&uart_rx_mutex);
ringbuffer_init(&rx_buf, rx_buf_mem, STDIO_RX_BUFSIZE);
#endif
uart_init(STDIO, STDIO_BAUDRATE, rx_cb, 0, 0);
} }
/** /**
@ -151,11 +189,16 @@ int _open_r(struct _reent *r, const char *name, int mode)
*/ */
int _read_r(struct _reent *r, int fd, void *buffer, unsigned int count) int _read_r(struct _reent *r, int fd, void *buffer, unsigned int count)
{ {
char c; #ifndef MODULE_UART0
char *buff = (char*)buffer; while (rx_buf.avail == 0) {
uart_read_blocking(STDIO, &c); mutex_lock(&uart_rx_mutex);
buff[0] = c; }
return ringbuffer_get(&rx_buf, (char*)buffer, rx_buf.avail);
#else
char *res = (char*)buffer;
res[0] = (char)uart0_readc();
return 1; return 1;
#endif
} }
/** /**
@ -175,11 +218,13 @@ int _read_r(struct _reent *r, int fd, void *buffer, unsigned int count)
*/ */
int _write_r(struct _reent *r, int fd, const void *data, unsigned int count) int _write_r(struct _reent *r, int fd, const void *data, unsigned int count)
{ {
char *c = (char*)data; int i = 0;
for (int i = 0; i < count; i++) {
uart_write_blocking(STDIO, c[i]); while (i < count) {
uart_write_blocking(STDIO, ((char*)data)[i++]);
} }
return count;
return i;
} }
/** /**