diff --git a/boards/iot-lab_M3/include/board.h b/boards/iot-lab_M3/include/board.h index d913d7c4af6d69ced6004d9bfd438cb95a1a574d..8e35ded673973b3420c1df3256a03d69c099b477 100644 --- a/boards/iot-lab_M3/include/board.h +++ b/boards/iot-lab_M3/include/board.h @@ -38,7 +38,8 @@ * @{ */ #define STDIO UART_0 -#define STDIO_BAUDRATE (115200) +#define STDIO_BAUDRATE (115200U) +#define STDIO_RX_BUFSIZE (64U) /** @} */ /** diff --git a/boards/msbiot/include/board.h b/boards/msbiot/include/board.h index 18931c63b60f5baafbdf77c46f43a3b63471349d..0b6034a9f9510d152aa24fcd444281a883f1de63 100644 --- a/boards/msbiot/include/board.h +++ b/boards/msbiot/include/board.h @@ -40,6 +40,7 @@ */ #define STDIO UART_0 #define STDIO_BAUDRATE (115200U) +#define STDIO_RX_BUFSIZE (64U) /** @} */ /** diff --git a/boards/stm32f0discovery/include/board.h b/boards/stm32f0discovery/include/board.h index 13b8451979c2102ab053a94884c0a62990805c1b..355776edf4e413e62feaa4108dabaa3d17d1deda 100644 --- a/boards/stm32f0discovery/include/board.h +++ b/boards/stm32f0discovery/include/board.h @@ -38,6 +38,8 @@ * @name Assign the UART interface to be used for stdio */ #define STDIO UART_0 +#define STDIO_BAUDRATE (115200U) +#define STDIO_RX_BUFSIZE (64U) /** * @name LED pin definitions diff --git a/boards/stm32f3discovery/include/board.h b/boards/stm32f3discovery/include/board.h index 7918d0f393c43aefd389bbbbc81e7ec468598b91..0f071217be8ff15fe8c9309cb513b2e88a716fa5 100644 --- a/boards/stm32f3discovery/include/board.h +++ b/boards/stm32f3discovery/include/board.h @@ -39,7 +39,7 @@ */ #define STDIO UART_0 #define STDIO_BAUDRATE (115200U) -#define STDIO_BUFSIZE (64U) +#define STDIO_RX_BUFSIZE (64U) /** @} */ /** diff --git a/boards/stm32f4discovery/include/board.h b/boards/stm32f4discovery/include/board.h index e40813bc2e48a0ba4aff170f6a6f0c9039123b96..0b0195b0a49f82796d763b8e10a8b54c7570e98f 100644 --- a/boards/stm32f4discovery/include/board.h +++ b/boards/stm32f4discovery/include/board.h @@ -40,6 +40,7 @@ */ #define STDIO UART_0 #define STDIO_BAUDRATE (115200U) +#define STDIO_RX_BUFSIZE (64U) /** @} */ /** diff --git a/cpu/stm32f0/Makefile.include b/cpu/stm32f0/Makefile.include index c2bd10a42374fbb4b87845d7ae723a3cd356ad97..27d71f5cf2f1f737fbaa5079e267a66400759481 100644 --- a/cpu/stm32f0/Makefile.include +++ b/cpu/stm32f0/Makefile.include @@ -7,6 +7,9 @@ export USEMODULE += cortex-m0_common # define path to cortex-m common module, which is needed for this CPU 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 # board's Makefile.include. This enables multiple STMF0 controllers with different memory to # use the same code-base. diff --git a/cpu/stm32f0/syscalls.c b/cpu/stm32f0/syscalls.c index f8dcdc78e95c852bdcc4d3734bbd1ccb806463cc..1f0787e8ebc40b326229aae2b722fbde03865214 100644 --- a/cpu/stm32f0/syscalls.c +++ b/cpu/stm32f0/syscalls.c @@ -30,10 +30,15 @@ #include "thread.h" #include "kernel.h" +#include "mutex.h" +#include "ringbuffer.h" #include "irq.h" #include "board.h" #include "periph/uart.h" +#ifdef MODULE_UART0 +#include "board_uart0.h" +#endif /** * manage the heap @@ -41,12 +46,44 @@ extern uint32_t _end; /* address of last used memory cell */ 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 */ 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) { - char c; - char *buff = (char*)buffer; - uart_read_blocking(STDIO, &c); - buff[0] = c; +#ifndef MODULE_UART0 + while (rx_buf.avail == 0) { + mutex_lock(&uart_rx_mutex); + } + return ringbuffer_get(&rx_buf, (char*)buffer, rx_buf.avail); +#else + char *res = (char*)buffer; + res[0] = (char)uart0_readc(); return 1; +#endif } /** diff --git a/cpu/stm32f1/Makefile.include b/cpu/stm32f1/Makefile.include index 87dd950e2b507048f096c83bba4ba182ed993429..7370ae77acdcb271f3934d5eda17eed80b81624d 100644 --- a/cpu/stm32f1/Makefile.include +++ b/cpu/stm32f1/Makefile.include @@ -4,6 +4,9 @@ export CFLAGS += -DCOREIF_NG=1 # tell the build system that the CPU depends on the Cortex-M common files 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 export CORTEXM_COMMON = $(RIOTCPU)/cortex-m3_common/ diff --git a/cpu/stm32f1/periph/uart.c b/cpu/stm32f1/periph/uart.c index 5b4c397b29b595a3fb7216af4cae9fcff3df1a2b..bfd847741173fdcc5f4069906b5f3b631f113a5d 100644 --- a/cpu/stm32f1/periph/uart.c +++ b/cpu/stm32f1/periph/uart.c @@ -29,11 +29,6 @@ #include "sched.h" #include "thread.h" -#ifdef MODULE_UART0 -#include "board_uart0.h" -#endif - - /** * @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) { 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); -#endif } else if (dev->SR & USART_SR_ORE) { /* ORE is cleared by reading SR and DR sequentially */ dev->DR; } else if (dev->SR & USART_SR_TXE) { -#ifdef MODULE_UART0 - dev->SR &= ~(USART_SR_TXE); -#else - config[uartnum].tx_cb(config[uartnum].arg); -#endif + if (config[uartnum].tx_cb(config[uartnum].arg) == 0) { + dev->CR1 &= ~(USART_CR1_TXEIE); + } } - if (sched_context_switch_request) { thread_yield(); } diff --git a/cpu/stm32f1/syscalls.c b/cpu/stm32f1/syscalls.c index c7962b99e29e1849291b508fdf3de3738e117a8b..247caa4bb5bbb5836569d4414f666fc9d9aa5e21 100644 --- a/cpu/stm32f1/syscalls.c +++ b/cpu/stm32f1/syscalls.c @@ -28,28 +28,62 @@ #include <sys/unistd.h> #include <stdint.h> +#include "board.h" #include "thread.h" #include "kernel.h" +#include "mutex.h" +#include "ringbuffer.h" #include "irq.h" #include "periph/uart.h" +#ifdef MODULE_UART0 +#include "board_uart0.h" +#endif + /** * manage the heap */ extern uint32_t _end; /* address of last used memory cell */ 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 */ void _init(void) { -#ifdef MODULE_UART0 - uart_init(UART_0, 115200, NULL, NULL, NULL); -#else - uart_init_blocking(UART_0, 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); } /** @@ -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) { - char c; - char *buff = (char*)buffer; - uart_read_blocking(UART_0, &c); - buff[0] = c; +#ifndef MODULE_UART0 + while (rx_buf.avail == 0) { + mutex_lock(&uart_rx_mutex); + } + return ringbuffer_get(&rx_buf, (char*)buffer, rx_buf.avail); +#else + char *res = (char*)buffer; + res[0] = (char)uart0_readc(); return 1; +#endif } /** diff --git a/cpu/stm32f3/syscalls.c b/cpu/stm32f3/syscalls.c index e2747d46da2c7ae7c9ca38f6fe10df1cb05b16f7..4f89a0e7e35337f32f77eee71028dced84f4a9aa 100644 --- a/cpu/stm32f3/syscalls.c +++ b/cpu/stm32f3/syscalls.c @@ -37,28 +37,42 @@ #include "irq.h" #include "periph/uart.h" +#ifdef MODULE_UART0 +#include "board_uart0.h" +#endif + /** * @brief manage the heap */ extern uint32_t _end; /* address of last used memory cell */ 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_BUFSIZE]; +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 } /** @@ -66,10 +80,11 @@ void rx_cb(void *arg, char data) */ void _init(void) { +#ifndef MODULE_UART0 mutex_init(&uart_rx_mutex); - ringbuffer_init(&rx_buf, rx_buf_mem, STDIO_BUFSIZE); - uart_init(STDIO, STDIO_BAUDRATE, rx_cb, 0, 0); -} + ringbuffer_init(&rx_buf, rx_buf_mem, STDIO_RX_BUFSIZE); +#endif + uart_init(STDIO, STDIO_BAUDRATE, rx_cb, 0, 0);} /** * @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) { +#ifndef MODULE_UART0 while (rx_buf.avail == 0) { mutex_lock(&uart_rx_mutex); } return ringbuffer_get(&rx_buf, (char*)buffer, rx_buf.avail); +#else + char *res = (char*)buffer; + res[0] = (char)uart0_readc(); + return 1; +#endif } /** diff --git a/cpu/stm32f4/Makefile.include b/cpu/stm32f4/Makefile.include index 511a37959b503b470162bd818e443663954f1120..bb97cdfef0b421fa00053c6941be098711673e35 100644 --- a/cpu/stm32f4/Makefile.include +++ b/cpu/stm32f4/Makefile.include @@ -4,6 +4,9 @@ export CFLAGS += -DCOREIF_NG=1 # export the peripheral drivers to be linked into the final binary 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 export USEMODULE += cortex-m4_common diff --git a/cpu/stm32f4/periph/uart.c b/cpu/stm32f4/periph/uart.c index 93bddb01f7dad1ab5f9080b122123dfd6c80982d..891ffd30325712ef0c0a978188219e4a9d4eb1b8 100644 --- a/cpu/stm32f4/periph/uart.c +++ b/cpu/stm32f4/periph/uart.c @@ -27,7 +27,6 @@ /* guard file in case no UART device was specified */ #if UART_NUMOF - /** * @brief Each UART device has to store two callbacks. */ diff --git a/cpu/stm32f4/syscalls.c b/cpu/stm32f4/syscalls.c index fa915f7b608e1ed7846ca93f6d8ef8657ae4b7e6..2d4508ca3fd41ebffadd608ea804801d572bab46 100644 --- a/cpu/stm32f4/syscalls.c +++ b/cpu/stm32f4/syscalls.c @@ -31,21 +31,59 @@ #include "board.h" #include "thread.h" #include "kernel.h" +#include "mutex.h" +#include "ringbuffer.h" #include "irq.h" #include "periph/uart.h" +#ifdef MODULE_UART0 +#include "board_uart0.h" +#endif + /** * manage the heap */ extern uint32_t _end; /* address of last used memory cell */ 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 */ 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) { - char c; - char *buff = (char*)buffer; - uart_read_blocking(STDIO, &c); - buff[0] = c; +#ifndef MODULE_UART0 + while (rx_buf.avail == 0) { + mutex_lock(&uart_rx_mutex); + } + return ringbuffer_get(&rx_buf, (char*)buffer, rx_buf.avail); +#else + char *res = (char*)buffer; + res[0] = (char)uart0_readc(); 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) { - char *c = (char*)data; - for (int i = 0; i < count; i++) { - uart_write_blocking(STDIO, c[i]); + int i = 0; + + while (i < count) { + uart_write_blocking(STDIO, ((char*)data)[i++]); } - return count; + + return i; } /**