From 5c18d42c8d2a18dacb985cd8aca04a39b49add1e Mon Sep 17 00:00:00 2001 From: tkremeyer Date: Tue, 13 Mar 2018 14:31:19 +0100 Subject: [PATCH] UART: Add ability to configure stopbits and parity bit (#590) --- core/include/esp/uart.h | 36 +++++++++++ core/include/esp/uart_regs.h | 14 ++++- examples/uart_config/Makefile | 3 + examples/uart_config/uart_config.c | 96 ++++++++++++++++++++++++++++++ 4 files changed, 148 insertions(+), 1 deletion(-) create mode 100755 examples/uart_config/Makefile create mode 100755 examples/uart_config/uart_config.c diff --git a/core/include/esp/uart.h b/core/include/esp/uart.h index 9d72dc3..5104f80 100644 --- a/core/include/esp/uart.h +++ b/core/include/esp/uart.h @@ -124,4 +124,40 @@ static inline int uart_get_baud(int uart_num) return APB_CLK_FREQ / FIELD2VAL(UART_CLOCK_DIVIDER_VALUE, UART(uart_num).CLOCK_DIVIDER); } +/* Set uart stop bit count to the desired value */ +static inline void uart_set_stopbits(int uart_num, UART_StopBits stop_bits) { + UART(uart_num).CONF0 = SET_FIELD(UART(uart_num).CONF0, UART_CONF0_STOP_BITS, stop_bits); +} + +/* Returns the current stopbit count for the UART */ +static inline UART_StopBits uart_get_stopbits(int uart_num) { + return (UART_StopBits)(FIELD2VAL(UART_CONF0_STOP_BITS, UART(uart_num).CONF0)); +} + +/* Set if uart parity bit should be enabled */ +static inline void uart_set_parity_enabled(int uart_num, bool enable) { + if(enable) + UART(uart_num).CONF0 = SET_MASK_BITS(UART(uart_num).CONF0, UART_CONF0_PARITY_ENABLE); + else + UART(uart_num).CONF0 = CLEAR_MASK_BITS(UART(uart_num).CONF0, UART_CONF0_PARITY_ENABLE); +} + +/* Set uart parity bit type */ +static inline void uart_set_parity(int uart_num, UART_Parity parity) { + if(parity == UART_PARITY_EVEN) + UART(uart_num).CONF0 = CLEAR_MASK_BITS(UART(uart_num).CONF0, UART_CONF0_PARITY); + else + UART(uart_num).CONF0 = SET_MASK_BITS(UART(uart_num).CONF0, UART_CONF0_PARITY); +} + +/* Returns if parity bit is currently enabled for UART uart_num */ +static inline bool uart_get_parity_enabled(int uart_num) { + return ((UART(uart_num).CONF0 & UART_CONF0_PARITY_ENABLE) != 0); +} + +/* Returns the current parity bit type for UART uart_num (also if parity bit is not enabled) */ +static inline UART_Parity uart_get_parity(int uart_num) { + return (UART_Parity)((UART(uart_num).CONF0 & UART_CONF0_PARITY) != 0); +} + #endif /* _ESP_UART_H */ diff --git a/core/include/esp/uart_regs.h b/core/include/esp/uart_regs.h index 671754d..9f50245 100644 --- a/core/include/esp/uart_regs.h +++ b/core/include/esp/uart_regs.h @@ -50,6 +50,18 @@ struct UART_REGS { _Static_assert(sizeof(struct UART_REGS) == 0x80, "UART_REGS is the wrong size"); +typedef enum { + UART_STOPBITS_0 = 0b00, + UART_STOPBITS_1 = 0b01, + UART_STOPBITS_1_5 = 0b10, + UART_STOPBITS_2 = 0b11 +} UART_StopBits; + +typedef enum { + UART_PARITY_EVEN = 0b0, + UART_PARITY_ODD = 0b1 +} UART_Parity; + /* Details for FIFO register */ #define UART_FIFO_DATA_M 0x000000ff @@ -153,7 +165,7 @@ _Static_assert(sizeof(struct UART_REGS) == 0x80, "UART_REGS is the wrong size"); #define UART_CONF0_BYTE_LEN_M 0x00000003 #define UART_CONF0_BYTE_LEN_S 2 #define UART_CONF0_PARITY_ENABLE BIT(1) -#define UART_CONF0_PARITY BIT(0) //FIXME: does this indicate odd or even? +#define UART_CONF0_PARITY BIT(0) //where 0 means even /* Details for CONF1 register */ diff --git a/examples/uart_config/Makefile b/examples/uart_config/Makefile new file mode 100755 index 0000000..f414a7d --- /dev/null +++ b/examples/uart_config/Makefile @@ -0,0 +1,3 @@ +PROGRAM=uart_config + +include ../../common.mk diff --git a/examples/uart_config/uart_config.c b/examples/uart_config/uart_config.c new file mode 100755 index 0000000..573b9a4 --- /dev/null +++ b/examples/uart_config/uart_config.c @@ -0,0 +1,96 @@ +/* A basic example that demonstrates how UART can be configured. + Outputs some test data with 100baud, 1.5 stopbits, even parity bit to UART1 + (GPIO2; D4 for NodeMCU boards) + + This sample code is in the public domain. + */ + +#include +#include +#include +#include + +#include +#include + +void uart_send_data(void *pvParameters){ + /* Activate UART for GPIO2 */ + gpio_set_iomux_function(2, IOMUX_GPIO2_FUNC_UART1_TXD); + + /* Set baud rate of UART1 to 100 (so it's easier to measure) */ + uart_set_baud(1, 100); + + /* Set to 1.5 stopbits */ + uart_set_stopbits(1, UART_STOPBITS_1_5); + + /* Enable parity bit */ + uart_set_parity_enabled(1, true); + + /* Set parity bit to even */ + uart_set_parity(1, UART_PARITY_EVEN); + + /* Repeatedly send some example packets */ + for(;;) + { + uart_putc(1, 0B00000000); + uart_putc(1, 0B00000001); + uart_putc(1, 0B10101010); + uart_flush_txfifo(1); + } +} + +void uart_print_config(void *pvParameters){ + for(;;) + { + /* Get data */ + int baud = uart_get_baud(1); + UART_StopBits stopbits = uart_get_stopbits(1); + bool parity_enabled = uart_get_parity_enabled(1); + UART_Parity parity = uart_get_parity(1); + + /* Print to UART0 */ + printf("Baud: %d ", baud); + + switch(stopbits){ + case UART_STOPBITS_0: + printf("Stopbits: 0 "); + break; + case UART_STOPBITS_1: + printf("Stopbits: 1 "); + break; + case UART_STOPBITS_1_5: + printf("Stopbits: 1.5 "); + break; + case UART_STOPBITS_2: + printf("Stopbits: 2"); + break; + default: + printf("Stopbits: Error"); + } + + printf("Parity bit enabled: %d ", parity_enabled); + + switch(parity){ + case UART_PARITY_EVEN: + printf("Parity: Even"); + break; + case UART_PARITY_ODD: + printf("Parity: Odd"); + break; + default: + printf("Parity: Error"); + } + + printf("\n"); + + vTaskDelay(1000.0 / portTICK_PERIOD_MS); + } +} + +void user_init(void){ + uart_set_baud(0, 115200); + printf("SDK version:%s\n", sdk_system_get_sdk_version()); + + xTaskCreate(uart_send_data, "tsk1", 256, NULL, 2, NULL); + xTaskCreate(uart_print_config, "tsk2", 256, NULL, 3, NULL); +}