Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

UART: setting baudrate, stopbits, and parity on runtime #5899

Closed
wants to merge 17 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
102 changes: 102 additions & 0 deletions cpu/cc2538/periph/uart.c
Original file line number Diff line number Diff line change
Expand Up @@ -348,3 +348,105 @@ void uart_poweroff(uart_t uart)
{
(void) uart;
}

int uart_mode(uart_t uart, uint8_t databits,
uint8_t stopbits, uart_parity_t parity)
{
cc2538_uart_t *u;

switch (uart) {
#if UART_0_EN
case UART_0:
u = UART_0_DEV;
break;
#endif
#if UART_1_EN
case UART_1:
u = UART_1_DEV;
break;
#endif
default:
return -1;
}

/* flush TX buffer before mode switch */
uart_txflush(uart);

/* disable RX during mode switch */

u->cc2538_uart_ctl.CTLbits.RXE = 0;

switch(databits){
case 5:
u->cc2538_uart_lcrh.LCRHbits.WLEN = WLEN_5_BITS;
break;
case 6:
u->cc2538_uart_lcrh.LCRHbits.WLEN = WLEN_6_BITS;
break;
case 7:
u->cc2538_uart_lcrh.LCRHbits.WLEN = WLEN_7_BITS;
break;
case 8:
u->cc2538_uart_lcrh.LCRHbits.WLEN = WLEN_8_BITS;
break;
default:
u->cc2538_uart_ctl.CTLbits.RXE = 1;
return -2;
}

switch(stopbits){
case 1:
u->cc2538_uart_lcrh.LCRHbits.STP2 = 0;
break;
case 2:
u->cc2538_uart_lcrh.LCRHbits.STP2 = 1;
break;
default:
u->cc2538_uart_ctl.CTLbits.RXE = 1;
return -2;
}

switch(parity){
case UART_NONE:
u->cc2538_uart_lcrh.LCRHbits.EPS = 0;
u->cc2538_uart_lcrh.LCRHbits.PEN = 0;
break;
case UART_EVEN:
u->cc2538_uart_lcrh.LCRHbits.EPS = 1;
u->cc2538_uart_lcrh.LCRHbits.PEN = 1;
break;
case UART_ODD:
u->cc2538_uart_lcrh.LCRHbits.EPS = 0;
u->cc2538_uart_lcrh.LCRHbits.PEN = 1;
break;
default:
u->cc2538_uart_ctl.CTLbits.RXE = 1;
return -2;
}

u->cc2538_uart_ctl.CTLbits.RXE = 1;
return 0;
}

void uart_txflush(uart_t uart)
{
cc2538_uart_t *u;

switch (uart) {
#if UART_0_EN
case UART_0:
u = UART_0_DEV;
break;
#endif
#if UART_1_EN
case UART_1:
u = UART_1_DEV;
break;
#endif
default:
return;
}

/* stupid busy waiting, could be improved... */
while(u->cc2538_uart_fr.FRbits.TXFE == 0);
}
48 changes: 46 additions & 2 deletions drivers/include/periph/uart.h
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,17 @@ typedef unsigned int uart_t;
#endif
/** @} */

/**
* @brief Parity modes
* @{
*/
typedef enum {
UART_NONE,
UART_EVEN,
UART_ODD,
} uart_parity_t;
/** @} */

/**
* @brief Signature for receive interrupt callback
*
Expand Down Expand Up @@ -124,6 +135,8 @@ enum {
* - no parity
* - 1 stop bit
* - baudrate as given
* If needed, data bits, stop bits, and parity can be changed with
* uart_mode() afterwards.
*
* If no callback parameter is given (rx_cb := NULL), the UART will be
* initialized in TX only mode.
Expand All @@ -146,8 +159,11 @@ int uart_init(uart_t uart, uint32_t baudrate, uart_rx_cb_t rx_cb, void *arg);
* @brief Write data from the given buffer to the specified UART device
*
* This function is blocking, as it will only return after @p len bytes from the
* given buffer have been send. The way this data is send is up to the
* implementation: active waiting, interrupt driven, DMA, etc.
* given buffer have been written into the UARTs TX FIFO. It does not guarantee,
* that all data have already been sent by the UART when the function returns.
* If necessary, use uart_txflush() afterwards to wait until this is done. The
* way this data is send to the UART is up to the implementation: active
* waiting, interrupt driven, DMA, etc.
*
* @param[in] uart UART device to use for transmission
* @param[in] data data buffer to send
Expand All @@ -170,6 +186,34 @@ void uart_poweron(uart_t uart);
*/
void uart_poweroff(uart_t uart);

/**
* @brief Configure UART mode
*
* This function reconfigures the UART mode (data bits, stop bits, parity).
* Before doing this, it waits until all data in the UART TX buffer have been
* sent out. During the mode change, the UART receive is disabled.
*
* @param[in] uart the UART device to set parity mode
* @param[in] databits number of databits
* @param[in] stopbits number of stopbits
* @param[in] parity parity mode
*
* @return 0 on success
* @return -1 on invalid UART device
* @return -2 on inapplicable parity
*/
int uart_mode(uart_t uart, uint8_t databits,
uint8_t stopbits, uart_parity_t parity);

/**
* @brief Flush UART TX buffer
*
* Block until TX buffer is empty and all bytes have been shifted out
*
* @param[in] uart the UART device to flush
*/
void uart_txflush(uart_t uart);

#ifdef __cplusplus
}
#endif
Expand Down