]> git.tdb.fi Git - model-railway-devices.git/commitdiff
Add function to change serial port baud rate on the fly
authorMikko Rasa <tdb@tdb.fi>
Tue, 12 Nov 2013 14:01:36 +0000 (16:01 +0200)
committerMikko Rasa <tdb@tdb.fi>
Tue, 12 Nov 2013 14:01:36 +0000 (16:01 +0200)
common/serial.c
common/serial.h

index 8874c3e07545f1d4b52cd1e60df6c003b6da1d64..6bf730c8c7a4640fbac5f4730a79f578b2da3da8 100644 (file)
@@ -1,5 +1,6 @@
 #include <avr/interrupt.h>
 #include <avr/io.h>
+#include "delay.h"
 #include "ringbuffer.h"
 #include "serial.h"
 
@@ -18,19 +19,37 @@ static uint8_t rx_overrun;
 #define INTERRUPTS 0
 #endif
 
+static inline void set_baud(uint16_t baud)
+{
+       baud = (F_CPU/16+baud/2)/baud-1;
+       UBRR0H = baud>>8;
+       UBRR0L = baud;
+}
+
 void serial_init(uint16_t baud)
 {
        DDRD = (DDRD&~0x03) | 0x02;
        PORTD &= ~0x03;
 
-       baud = (F_CPU/16+baud/2)/baud-1;
-       UBRR0H = baud>>8;
-       UBRR0L = baud;
+       set_baud(baud);
        UCSR0A = 0;
        UCSR0C = BIT(UCSZ00) | BIT(UCSZ01);  // 8N1
        UCSR0B = BIT(RXEN0) | BIT(TXEN0) | INTERRUPTS;
 }
 
+void serial_set_baud(uint16_t baud)
+{
+#ifdef SERIAL_ASYNC
+       while(!(UCSR0A&BIT(UDRE0))) ;
+#endif
+       /* It's impossible to reliably find out when transmission has finished.
+       Wait for one character duration to be safe. */
+       uint16_t delay = (UBRR0H<<8)|UBRR0L;
+       for(uint8_t i=0; i<40; ++i)
+               delay_loop16(delay);
+       set_baud(baud);
+}
+
 uint8_t serial_read()
 {
 #ifdef SERIAL_ASYNC
index f5d59876114c29d01876e3cdedd96b4a83184452..9e48a6eb1352dde48890a4c9d47bcc899660e0d8 100644 (file)
@@ -4,6 +4,7 @@
 #include <stdint.h>
 
 void serial_init(uint16_t);
+void serial_set_baud(uint16_t);
 uint8_t serial_read();
 uint8_t serial_read_available();
 uint8_t serial_read_overrun();