diff options
author | Harald Welte <laforge@gnumonks.org> | 2017-01-15 22:35:45 +0100 |
---|---|---|
committer | Harald Welte <laforge@gnumonks.org> | 2017-01-15 22:35:45 +0100 |
commit | 0f3c33dc4f008a1fc404de1d2a6ee756801219eb (patch) | |
tree | b1537641de77ad0ebbcbbe750641a0928cff77c1 /src | |
parent | 36b5c8c3004644d75797deb8a438df38545455b6 (diff) |
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.
Diffstat (limited to 'src')
-rw-r--r-- | src/target/firmware/comm/sercomm.c | 33 | ||||
-rw-r--r-- | src/target/firmware/include/comm/sercomm.h | 2 |
2 files changed, 35 insertions, 0 deletions
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 <uart.h> /* 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); |