From 0f3c33dc4f008a1fc404de1d2a6ee756801219eb Mon Sep 17 00:00:00 2001 From: Harald Welte Date: Sun, 15 Jan 2017 22:35:45 +0100 Subject: firmware: Introduce sercomm_change_speed() to change baudrate The function will wait until the Tx queue is drained and then proceed to change the UARt baud rate. --- src/target/firmware/comm/sercomm.c | 33 ++++++++++++++++++++++++++++++ src/target/firmware/include/comm/sercomm.h | 2 ++ 2 files changed, 35 insertions(+) diff --git a/src/target/firmware/comm/sercomm.c b/src/target/firmware/comm/sercomm.c index 490e2254..810d661c 100644 --- a/src/target/firmware/comm/sercomm.c +++ b/src/target/firmware/comm/sercomm.c @@ -157,6 +157,39 @@ unsigned int sercomm_tx_queue_depth(uint8_t dlci) return num; } +#ifndef HOST_BUILD +/* wait until everything has been transmitted, then grab the lock and + * change the baud rate as requested */ +void sercomm_change_speed(enum uart_baudrate bdrt) +{ + unsigned int i, count; + unsigned long flags; + + while (1) { + /* count the number of pending messages */ + count = 0; + for (i = 0; i < ARRAY_SIZE(sercomm.tx.dlci_queues); i++) + count += sercomm_tx_queue_depth(i); + /* if we still have any in the queue, restart */ + if (count == 0) + break; + } + + while (1) { + /* no messages in the queue, grab the lock to ensure it + * stays that way */ + sercomm_lock(&flags); + if (!sercomm.tx.msg && !sercomm.tx.next_char) { + /* change speed */ + uart_baudrate(sercomm.uart_id, bdrt); + sercomm_unlock(&flags); + break; + } + sercomm_unlock(&flags); + } +} +#endif + /* fetch one octet of to-be-transmitted serial data */ int sercomm_drv_pull(uint8_t *ch) { diff --git a/src/target/firmware/include/comm/sercomm.h b/src/target/firmware/include/comm/sercomm.h index a474c61a..21f715ba 100644 --- a/src/target/firmware/include/comm/sercomm.h +++ b/src/target/firmware/include/comm/sercomm.h @@ -22,9 +22,11 @@ enum sercomm_dlci { }; #ifndef HOST_BUILD +#include /* helper functions for target */ void sercomm_bind_uart(int uart); int sercomm_get_uart(void); +void sercomm_change_speed(enum uart_baudrate bdrt); #endif void sercomm_init(void); -- cgit v1.2.3