summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorHarald Welte <laforge@gnumonks.org>2017-01-15 22:35:45 +0100
committerHarald Welte <laforge@gnumonks.org>2017-01-15 22:35:45 +0100
commit0f3c33dc4f008a1fc404de1d2a6ee756801219eb (patch)
treeb1537641de77ad0ebbcbbe750641a0928cff77c1 /src
parent36b5c8c3004644d75797deb8a438df38545455b6 (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.c33
-rw-r--r--src/target/firmware/include/comm/sercomm.h2
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);