From e706902ac4ce17370277cd25af347758b61b4a35 Mon Sep 17 00:00:00 2001 From: Joachim Naulet Date: Fri, 14 Jul 2023 08:09:37 +0200 Subject: [PATCH] uart: fix all drivers according to issue #60 --- drivers/uart/uart-arm_pl011.c | 48 +++++++--- drivers/uart/uart-atmel_sercom.c | 44 ++++++--- drivers/uart/uart-avr.c | 143 +++++++++++++++++++++--------- drivers/uart/uart-avr.h | 3 + drivers/uart/uart-gd32vf103.c | 46 +++++++--- drivers/uart/uart-pic32mx.c | 36 +++++--- drivers/uart/uart-sam3x.c | 25 ++++-- drivers/uart/uart-tinyavr_usart.c | 79 +++++++++++++---- drivers/uart/uart-tinyavr_usart.h | 3 + 9 files changed, 315 insertions(+), 112 deletions(-) diff --git a/drivers/uart/uart-arm_pl011.c b/drivers/uart/uart-arm_pl011.c index 583e8e26..694bbdb9 100644 --- a/drivers/uart/uart-arm_pl011.c +++ b/drivers/uart/uart-arm_pl011.c @@ -155,23 +155,31 @@ static int set_cs(struct uart *ctx, size_t cs) return 0; } -static int set_parity(struct uart *ctx, bool parenb, bool parodd) +static int set_parity(struct uart *ctx, uart_par_t par) { - if (parenb) { - ctx->base->UARTLCR_H |= UARTLCR_H_PEN; + if (!picoRTOS_assert(par != UART_PAR_IGNORE)) return -EINVAL; + if (!picoRTOS_assert(par < UART_PAR_COUNT)) return -EINVAL; - if (parodd) ctx->base->UARTLCR_H &= ~UARTLCR_H_EPS; - else ctx->base->UARTLCR_H |= UARTLCR_H_EPS; - - }else + /* no parity */ + if (par == UART_PAR_NONE) { ctx->base->UARTLCR_H &= ~UARTLCR_H_PEN; + return 0; + } + + /* parity */ + ctx->base->UARTLCR_H |= UARTLCR_H_PEN; + if (par == UART_PAR_ODD) ctx->base->UARTLCR_H &= ~UARTLCR_H_EPS; + else ctx->base->UARTLCR_H |= UARTLCR_H_EPS; return 0; } -static int set_stopb(struct uart *ctx, bool cstopb) +static int set_cstopb(struct uart *ctx, uart_cstopb_t cstopb) { - if (cstopb) ctx->base->UARTLCR_H |= UARTLCR_H_STP2; + if (!picoRTOS_assert(cstopb != UART_CSTOPB_IGNORE)) return -EINVAL; + if (!picoRTOS_assert(cstopb < UART_CSTOPB_COUNT)) return -EINVAL; + + if (cstopb == UART_CSTOPB_2BIT) ctx->base->UARTLCR_H |= UARTLCR_H_STP2; else ctx->base->UARTLCR_H &= ~UARTLCR_H_STP2; return 0; @@ -181,10 +189,24 @@ int uart_setup(struct uart *ctx, const struct uart_settings *settings) { int res; - if ((res = set_baudrate(ctx, settings->baudrate)) < 0 || - (res = set_cs(ctx, settings->cs)) < 0 || - (res = set_parity(ctx, settings->parenb, settings->parodd)) < 0 || - (res = set_stopb(ctx, settings->cstopb)) < 0) + /* baudrate */ + if (settings->baudrate != 0 && + (res = set_baudrate(ctx, settings->baudrate)) < 0) + return res; + + /* cs */ + if (settings->cs != 0 && + (res = set_cs(ctx, settings->cs)) < 0) + return res; + + /* parity */ + if (settings->par != UART_PAR_IGNORE && + (res = set_parity(ctx, settings->par)) < 0) + return res; + + /* cstopb */ + if (settings->cstopb != UART_CSTOPB_IGNORE && + (res = set_cstopb(ctx, settings->cstopb)) < 0) return res; return 0; diff --git a/drivers/uart/uart-atmel_sercom.c b/drivers/uart/uart-atmel_sercom.c index 19dc1446..075d7d20 100644 --- a/drivers/uart/uart-atmel_sercom.c +++ b/drivers/uart/uart-atmel_sercom.c @@ -175,22 +175,28 @@ static int set_cs(struct uart *ctx, size_t cs) return 0; } -static int set_parity(struct uart *ctx, bool parenb, bool parodd) +static int set_parity(struct uart *ctx, uart_par_t par) { + if (!picoRTOS_assert(par != UART_PAR_IGNORE)) return -EINVAL; + if (!picoRTOS_assert(par < UART_PAR_COUNT)) return -EINVAL; + ctx->base->CTRLA &= ~CTRLA_FORM(CTRLA_FORM_M); + if (par == UART_PAR_NONE) + return 0; - if (parenb) { - ctx->base->CTRLA |= CTRLA_FORM(0x1); - if (parodd) ctx->base->CTRLB |= CTRLB_PMODE; - else ctx->base->CTRLB &= ~CTRLB_PMODE; - } + ctx->base->CTRLA |= CTRLA_FORM(0x1); + if (par == UART_PAR_ODD) ctx->base->CTRLB |= CTRLB_PMODE; + else ctx->base->CTRLB &= ~CTRLB_PMODE; return 0; } -static int set_stopb(struct uart *ctx, bool cstopb) +static int set_cstopb(struct uart *ctx, uart_cstopb_t cstopb) { - if (cstopb) ctx->base->CTRLB |= CTRLB_SBMODE; + if (!picoRTOS_assert(cstopb != UART_CSTOPB_IGNORE)) return -EINVAL; + if (!picoRTOS_assert(cstopb < UART_CSTOPB_COUNT)) return -EINVAL; + + if (cstopb == UART_CSTOPB_2BIT) ctx->base->CTRLB |= CTRLB_SBMODE; else ctx->base->CTRLB &= ~CTRLB_SBMODE; return 0; @@ -202,10 +208,24 @@ int uart_setup(struct uart *ctx, const struct uart_settings *settings) ctx->base->CTRLA &= ~CTRLA_ENABLE; - if ((res = set_baudrate(ctx, settings->baudrate)) < 0 || - (res = set_cs(ctx, settings->cs)) < 0 || - (res = set_parity(ctx, settings->parenb, settings->parodd)) < 0 || - (res = set_stopb(ctx, settings->cstopb)) < 0) + /* baudrate */ + if (settings->baudrate != 0 && + (res = set_baudrate(ctx, settings->baudrate)) < 0) + return res; + + /* cs */ + if (settings->cs != 0 && + (res = set_cs(ctx, settings->cs)) < 0) + return res; + + /* parity */ + if (settings->par != UART_PAR_IGNORE && + (res = set_parity(ctx, settings->par)) < 0) + return res; + + /* cstopb */ + if (settings->cstopb != UART_CSTOPB_IGNORE && + (res = set_cstopb(ctx, settings->cstopb)) < 0) return res; ctx->base->CTRLA |= CTRLA_ENABLE; diff --git a/drivers/uart/uart-avr.c b/drivers/uart/uart-avr.c index 2d70b8d1..5f6253ac 100644 --- a/drivers/uart/uart-avr.c +++ b/drivers/uart/uart-avr.c @@ -15,14 +15,51 @@ struct USART_AVR { #define UCSRnA_RXC (1 << 7) #define UCSRnA_TXC (1 << 6) #define UCSRnA_UDRE (1 << 5) +#define UCSRnA_FE (1 << 4) +#define UCSRnA_DOR (1 << 3) +#define UCSRnA_UPE (1 << 2) #define UCSRnA_U2X (1 << 1) +#define UCSRnA_MPCM (1 << 0) + +#define UCSRnB_RXCIE (1 << 7) +#define UCSRnB_TXCIE (1 << 6) +#define UCSRnB_UDRIE (1 << 5) +#define UCSRnB_RXEN (1 << 4) +#define UCSRnB_TXEN (1 << 3) +#define UCSRnB_UCSZ2 (1 << 2) +#define UCSRnB_RXD8 (1 << 1) +#define UCSRnB_TXD8 (1 << 0) + +#define UCSRnC_UMSEL_M 0x3u +#define UCSRnC_UMSEL(x) (((x) & UCSRnC_UMSEL_M) << 6) +#define UCSRnC_UPM_M 0x3u +#define UCSRnC_UPM(x) (((x) & UCSRnC_UPM_M) << 4) +#define UCSRnC_USBS (1 << 3) +#define UCSRnC_UCSZ_M 0x3u +#define UCSRnC_UCSZ(x) (((x) & UCSRnC_UCSZ_M) << 1) +#define UCSRnC_UCPOL (1 << 0) -#define UCSRnB_RXEN (1 << 4) -#define UCSRnB_TXEN (1 << 3) +/* Function: uart_avr_init + * Initializes an UART + * + * Parameters: + * ctx - The UART to init + * base - The UART base address + * clkid - The UART clock ID + * + * Returns: + * Always 0 + */ +int uart_avr_init(struct uart *ctx, int base, clock_id_t clkid) +{ + ctx->base = (struct USART_AVR*)base; + ctx->clkid = clkid; -#define UCSRnC_UPM1 (1 << 5) -#define UCSRnC_UPM0 (1 << 4) -#define UCSRnC_USBS (1 << 3) + /* turn on */ + ctx->base->UCSRnA = (uint8_t)UCSRnA_U2X; + ctx->base->UCSRnB = (uint8_t)(UCSRnB_TXEN | UCSRnB_RXEN); + return 0; +} static int set_baudrate(struct uart *ctx, unsigned long baud) { @@ -40,27 +77,53 @@ static int set_baudrate(struct uart *ctx, unsigned long baud) return 0; } -/* public */ +static int set_cs(struct uart *ctx, size_t cs) +{ + if (!picoRTOS_assert(cs >= (size_t)UART_AVR_CS_MIN)) return -EINVAL; + if (!picoRTOS_assert(cs <= (size_t)UART_AVR_CS_MAX)) return -EINVAL; -/* Function: uart_avr_init - * Initializes an UART - * - * Parameters: - * ctx - The UART to init - * base - The UART base address - * clkid - The UART clock ID - * - * Returns: - * Always 0 - */ -int uart_avr_init(struct uart *ctx, int base, clock_id_t clkid) + /* no support for 9bit yet */ + ctx->base->UCSRnB &= ~UCSRnB_UCSZ2; + ctx->base->UCSRnC &= ~UCSRnC_UCSZ(UCSRnC_UCSZ_M); + + switch (cs) { + case 5: break; + case 6: ctx->base->UCSRnC |= UCSRnC_UCSZ(1); break; + case 7: ctx->base->UCSRnC |= UCSRnC_UCSZ(2); break; + case 8: ctx->base->UCSRnC |= UCSRnC_UCSZ(3); break; + default: + picoRTOS_break(); + /*@notreached@*/ + return -EIO; + } + + return 0; +} + +static int set_parity(struct uart *ctx, uart_par_t par) { - ctx->base = (struct USART_AVR*)base; - ctx->clkid = clkid; + if (!picoRTOS_assert(par != UART_PAR_IGNORE)) return -EINVAL; + if (!picoRTOS_assert(par < UART_PAR_COUNT)) return -EINVAL; + + /* disable */ + ctx->base->UCSRnC &= ~UCSRnC_UPM(UCSRnC_UPM_M); + if (par == UART_PAR_NONE) + return 0; + + if (par == UART_PAR_ODD) ctx->base->UCSRnC |= UCSRnC_UPM(3); + else ctx->base->UCSRnC |= UCSRnC_UPM(2); + + return 0; +} + +static int set_cstopb(struct uart *ctx, uart_cstopb_t cstopb) +{ + if (!picoRTOS_assert(cstopb != UART_CSTOPB_IGNORE)) return -EINVAL; + if (!picoRTOS_assert(cstopb < UART_CSTOPB_COUNT)) return -EINVAL; + + if (cstopb == UART_CSTOPB_2BIT) ctx->base->UCSRnC |= UCSRnC_USBS; + else ctx->base->UCSRnC &= ~UCSRnC_USBS; - /* turn on */ - ctx->base->UCSRnA = (uint8_t)UCSRnA_U2X; - ctx->base->UCSRnB = (uint8_t)(UCSRnB_TXEN | UCSRnB_RXEN); return 0; } @@ -69,29 +132,27 @@ int uart_avr_init(struct uart *ctx, int base, clock_id_t clkid) int uart_setup(struct uart *ctx, const struct uart_settings *settings) { int res; - uint8_t ucsrxc = (uint8_t)0; - if ((res = set_baudrate(ctx, settings->baudrate)) < 0) + /* baudrate */ + if (settings->baudrate != 0 && + (res = set_baudrate(ctx, settings->baudrate)) < 0) return res; - if (settings->cstopb) ucsrxc |= UCSRnC_USBS; - if (settings->parenb) { - ucsrxc = (uint8_t)UCSRnC_UPM0; - if (settings->parodd) ucsrxc |= UCSRnC_UPM0; - } + /* cs */ + if (settings->cs != 0 && + (res = set_cs(ctx, settings->cs)) < 0) + return res; - switch (settings->cs) { - case 5: break; - case 6: ucsrxc |= 0x2; break; - case 7: ucsrxc |= 0x4; break; - case 8: ucsrxc |= 0X6; break; - default: - picoRTOS_break(); - /*@notreached@*/ - return -EIO; - } + /* parity */ + if (settings->par != UART_PAR_IGNORE && + (res = set_parity(ctx, settings->par)) < 0) + return res; + + /* cstopb */ + if (settings->cstopb != UART_CSTOPB_IGNORE && + (res = set_cstopb(ctx, settings->cstopb)) < 0) + return res; - ctx->base->UCSRnC = ucsrxc; return 0; } diff --git a/drivers/uart/uart-avr.h b/drivers/uart/uart-avr.h index 3159ada3..d9e8cbca 100644 --- a/drivers/uart/uart-avr.h +++ b/drivers/uart/uart-avr.h @@ -4,6 +4,9 @@ #include "uart.h" #include "clock.h" +#define UART_AVR_CS_MIN 5 +#define UART_AVR_CS_MAX 8 + struct USART_AVR; struct uart { diff --git a/drivers/uart/uart-gd32vf103.c b/drivers/uart/uart-gd32vf103.c index c6c0bb13..5157e5a1 100644 --- a/drivers/uart/uart-gd32vf103.c +++ b/drivers/uart/uart-gd32vf103.c @@ -127,24 +127,32 @@ static int set_cs(struct uart *ctx, size_t cs) return 0; } -static int set_parity(struct uart *ctx, bool parenb, bool parodd) +static int set_parity(struct uart *ctx, uart_par_t par) { - ctx->base->USART_CTL0 &= ~USART_CTL0_PCEN; + if (!picoRTOS_assert(par != UART_PAR_IGNORE)) return -EINVAL; + if (!picoRTOS_assert(par < UART_PAR_COUNT)) return -EINVAL; - if (parenb) { - ctx->base->USART_CTL0 |= USART_CTL0_PCEN; - if (parodd) ctx->base->USART_CTL0 |= USART_CTL0_PM; - else ctx->base->USART_CTL0 &= ~USART_CTL0_PM; + /* no parity */ + if (par == UART_PAR_NONE) { + ctx->base->USART_CTL0 &= ~USART_CTL0_PCEN; + return 0; } + ctx->base->USART_CTL0 |= USART_CTL0_PCEN; + if (par == UART_PAR_ODD) ctx->base->USART_CTL0 |= USART_CTL0_PM; + else ctx->base->USART_CTL0 &= ~USART_CTL0_PM; + return 0; } -static int set_stopb(struct uart *ctx, bool cstopb) +static int set_cstopb(struct uart *ctx, uart_cstopb_t cstopb) { + if (!picoRTOS_assert(cstopb != UART_CSTOPB_IGNORE)) return -EINVAL; + if (!picoRTOS_assert(cstopb < UART_CSTOPB_COUNT)) return -EINVAL; + ctx->base->USART_CTL1 &= ~USART_CTL1_STB(USART_CTL1_STB_M); - if (cstopb) + if (cstopb == UART_CSTOPB_2BIT) ctx->base->USART_CTL1 |= USART_CTL1_STB(2); return 0; @@ -154,10 +162,24 @@ int uart_setup(struct uart *ctx, const struct uart_settings *settings) { int res; - if ((res = set_baudrate(ctx, settings->baudrate)) < 0 || - (res = set_cs(ctx, settings->cs)) < 0 || - (res = set_parity(ctx, settings->parenb, settings->parodd)) < 0 || - (res = set_stopb(ctx, settings->cstopb)) < 0) + /* baudrate */ + if (settings->baudrate != 0 && + (res = set_baudrate(ctx, settings->baudrate)) < 0) + return res; + + /* cs */ + if (settings->cs != 0 && + (res = set_cs(ctx, settings->cs)) < 0) + return res; + + /* parity */ + if (settings->par != UART_PAR_IGNORE && + (res = set_parity(ctx, settings->par)) < 0) + return res; + + /* cstopb */ + if (settings->cstopb != UART_CSTOPB_IGNORE && + (res = set_cstopb(ctx, settings->cstopb)) < 0) return res; return 0; diff --git a/drivers/uart/uart-pic32mx.c b/drivers/uart/uart-pic32mx.c index 58390a77..13de5220 100644 --- a/drivers/uart/uart-pic32mx.c +++ b/drivers/uart/uart-pic32mx.c @@ -89,21 +89,27 @@ static int set_baudrate(struct uart *ctx, unsigned long baudrate) return 0; } -static int set_parity(struct uart *ctx, bool parenb, bool parodd) +static int set_parity(struct uart *ctx, uart_par_t par) { + if (!picoRTOS_assert(par != UART_PAR_IGNORE)) return -EINVAL; + if (!picoRTOS_assert(par < UART_PAR_COUNT)) return -EINVAL; + ctx->base->UxMODE.CLR = (uint32_t)UxMODE_PDSEL(UxMODE_PDSEL_M); + if (par == UART_PAR_NONE) + return 0; - if (parenb) { - if (parodd) ctx->base->UxMODE.SET = (uint32_t)UxMODE_PDSEL(0x2); - else ctx->base->UxMODE.SET = (uint32_t)UxMODE_PDSEL(0x1); - } + if (par == UART_PAR_ODD) ctx->base->UxMODE.SET = (uint32_t)UxMODE_PDSEL(0x2); + else ctx->base->UxMODE.SET = (uint32_t)UxMODE_PDSEL(0x1); return 0; } -static int set_stopb(struct uart *ctx, bool cstopb) +static int set_cstopb(struct uart *ctx, uart_cstopb_t cstopb) { - if (cstopb) ctx->base->UxMODE.SET = (uint32_t)UxMODE_STSEL; + if (!picoRTOS_assert(cstopb != UART_CSTOPB_IGNORE)) return -EINVAL; + if (!picoRTOS_assert(cstopb < UART_CSTOPB_COUNT)) return -EINVAL; + + if (cstopb == UART_CSTOPB_2BIT) ctx->base->UxMODE.SET = (uint32_t)UxMODE_STSEL; else ctx->base->UxMODE.CLR = (uint32_t)UxMODE_STSEL; return 0; @@ -113,9 +119,19 @@ int uart_setup(struct uart *ctx, const struct uart_settings *settings) { int res; - if ((res = set_baudrate(ctx, settings->baudrate)) < 0 || - (res = set_parity(ctx, settings->parenb, settings->parodd)) < 0 || - (res = set_stopb(ctx, settings->cstopb)) < 0) + /* baudrate */ + if (settings->baudrate != 0 && + (res = set_baudrate(ctx, settings->baudrate)) < 0) + return res; + + /* parity */ + if (settings->par != UART_PAR_IGNORE && + (res = set_parity(ctx, settings->par)) < 0) + return res; + + /* cstopb */ + if (settings->cstopb != UART_CSTOPB_IGNORE && + (res = set_cstopb(ctx, settings->cstopb)) < 0) return res; /* ignore cs */ diff --git a/drivers/uart/uart-sam3x.c b/drivers/uart/uart-sam3x.c index 665356b9..4257bc64 100644 --- a/drivers/uart/uart-sam3x.c +++ b/drivers/uart/uart-sam3x.c @@ -84,15 +84,20 @@ static int set_baudrate(struct uart *ctx, unsigned long baudrate) return 0; } -static int set_parity(struct uart *ctx, bool parenb, bool parodd) +static int set_parity(struct uart *ctx, uart_par_t par) { + if (!picoRTOS_assert(par != UART_PAR_IGNORE)) return -EINVAL; + if (!picoRTOS_assert(par < UART_PAR_COUNT)) return -EINVAL; + ctx->base->UART_MR &= ~UART_MR_PAR(UART_MR_PAR_M); - if (parenb) { - if (parodd) ctx->base->UART_MR |= UART_MR_PAR(1); - else ctx->base->UART_MR |= UART_MR_PAR(0); - }else + if (par == UART_PAR_NONE) { ctx->base->UART_MR |= UART_MR_PAR(4); + return 0; + } + + if (par == UART_PAR_ODD) ctx->base->UART_MR |= UART_MR_PAR(1); + else ctx->base->UART_MR |= UART_MR_PAR(0); return 0; } @@ -101,8 +106,14 @@ int uart_setup(struct uart *ctx, const struct uart_settings *settings) { int res; - if ((res = set_baudrate(ctx, settings->baudrate)) < 0 || - (res = set_parity(ctx, settings->parenb, settings->parodd)) < 0) + /* baudrate */ + if (settings->baudrate != 0 && + (res = set_baudrate(ctx, settings->baudrate)) < 0) + return res; + + /* parity */ + if (settings->par != UART_PAR_IGNORE && + (res = set_parity(ctx, settings->par)) < 0) return res; /* ignore cs and stopb */ diff --git a/drivers/uart/uart-tinyavr_usart.c b/drivers/uart/uart-tinyavr_usart.c index 8846c01e..b256dd83 100644 --- a/drivers/uart/uart-tinyavr_usart.c +++ b/drivers/uart/uart-tinyavr_usart.c @@ -100,25 +100,18 @@ static int set_baudrate(struct uart *ctx, unsigned long baud) return 0; } -int uart_setup(struct uart *ctx, const struct uart_settings *settings) +static int set_cs(struct uart *ctx, size_t cs) { - int res; - uint8_t ctrlc = (uint8_t)0; + if (!picoRTOS_assert(cs >= (size_t)USART_TINYAVR_CS_MIN)) return -EINVAL; + if (!picoRTOS_assert(cs <= (size_t)USART_TINYAVR_CS_MAX)) return -EINVAL; - if ((res = set_baudrate(ctx, settings->baudrate)) < 0) - return res; - - if (settings->cstopb) ctrlc |= CTRLC_SBMODE; - if (settings->parenb) { - if (settings->parodd) ctrlc |= CTRLC_PMODE(0x3); - else ctrlc |= CTRLC_PMODE(0x2); - } + ctx->base->CTRLC &= ~CTRLC_CHSIZE(CTRLC_CHSIZE_M); - switch (settings->cs) { - case 5: ctrlc |= CTRLC_CHSIZE(0); break; - case 6: ctrlc |= CTRLC_CHSIZE(1); break; - case 7: ctrlc |= CTRLC_CHSIZE(2); break; - case 8: ctrlc |= CTRLC_CHSIZE(3); break; + switch (cs) { + case 5: ctx->base->CTRLC |= CTRLC_CHSIZE(0); break; + case 6: ctx->base->CTRLC |= CTRLC_CHSIZE(1); break; + case 7: ctx->base->CTRLC |= CTRLC_CHSIZE(2); break; + case 8: ctx->base->CTRLC |= CTRLC_CHSIZE(3); break; // case 9: ctrlc |= CTRLC_CHSIZE(6); break; default: picoRTOS_break(); @@ -126,7 +119,59 @@ int uart_setup(struct uart *ctx, const struct uart_settings *settings) return -EIO; } - ctx->base->CTRLC = ctrlc; + return 0; +} + +static int set_parity(struct uart *ctx, uart_par_t par) +{ + if (!picoRTOS_assert(par != UART_PAR_IGNORE)) return -EINVAL; + if (!picoRTOS_assert(par < UART_PAR_COUNT)) return -EINVAL; + + ctx->base->CTRLC &= ~CTRLC_PMODE(CTRLC_PMODE_M); + if (par == UART_PAR_NONE) + return 0; + + if (par == UART_PAR_ODD) ctx->base->CTRLC |= CTRLC_PMODE(0x3); + else ctx->base->CTRLC |= CTRLC_PMODE(0x2); + + return 0; +} + +static int set_cstopb(struct uart *ctx, uart_cstopb_t cstopb) +{ + if (!picoRTOS_assert(cstopb != UART_CSTOPB_IGNORE)) return -EINVAL; + if (!picoRTOS_assert(cstopb < UART_CSTOPB_COUNT)) return -EINVAL; + + if (cstopb == UART_CSTOPB_2BIT) ctx->base->CTRLC |= CTRLC_SBMODE; + else ctx->base->CTRLC &= ~CTRLC_SBMODE; + + return 0; +} + +int uart_setup(struct uart *ctx, const struct uart_settings *settings) +{ + int res; + + /* baudrate */ + if (settings->baudrate != 0 && + (res = set_baudrate(ctx, settings->baudrate)) < 0) + return res; + + /* cs */ + if (settings->cs != 0 && + (res = set_cs(ctx, settings->cs)) < 0) + return res; + + /* parity */ + if (settings->par != UART_PAR_IGNORE && + (res = set_parity(ctx, settings->par)) < 0) + return res; + + /* cstopb */ + if (settings->cstopb != UART_CSTOPB_IGNORE && + (res = set_cstopb(ctx, settings->cstopb)) < 0) + return res; + return 0; } diff --git a/drivers/uart/uart-tinyavr_usart.h b/drivers/uart/uart-tinyavr_usart.h index 504cd228..7d09d370 100644 --- a/drivers/uart/uart-tinyavr_usart.h +++ b/drivers/uart/uart-tinyavr_usart.h @@ -4,6 +4,9 @@ #include "uart.h" #include "clock.h" +#define USART_TINYAVR_CS_MIN 5 +#define USART_TINYAVR_CS_MAX 8 + struct USART_TINYAVR_UART; struct uart {