- Dual software UART
Echo what is received from one software UART to both. The first UART that synchronizes sets the other up.
This is totally reversible, the LED shows when one UART resynchronizes.
Notes:
- Do not leave an RX pin floating!
- Choose a moderate baudrate so that the CPU has the time to service interrupts in a relatively reasonable time (115200 bps seems OK for
counter1
with internal 8 MHz RC oscilltor and OSCCAL=0xFF or the 16 MHz Nanodccduino).
- CH340 USB/Serial adapter does not send parity bits under Linux (though no error is triggered). Then, the software UART never resynchronizes (it works in a Windows XP VirtualBoxed under Linux, so there must be a bug in the Linux driver).
- Test application
./main.py -b BAUDRATE
- config.h
#ifndef CONFIG_H
#define CONFIG_H
#include BOARD_H
#define UART0 HW_SWUARTA( txd, DIABOLO_PIN_TX, \
rxd, DIABOLO_PIN_RX, \
startirq, (DIABOLO_PIN_RX,port,pcic,irq), \
counter, counter1, \
compare, compare0, \
clkdiv, 1, \
autosync, 51, \
fastreg, (shared,gpior0) )
#define UART1 HW_SWUARTA( txd, PIN_TX2, \
rxd, PIN_RX2, \
startirq, (PIN_RX2,port,pcic,irq), \
counter, counter1, \
compare, compare1, \
clkdiv, 1, \
autosync, 51, \
fastreg, (shared,gpior1) )
#endif
- main.c
#include "config.h"
#if defined HW_DEVICE_ATTINYX5
# error ATtinyX5 devices are not supported because the same pin-change interrupt controller can not be used for 2 different software UARTS
#endif
void uart0_putbyte ( uint8_t byte )
{
while ( !
hw(stat,UART0).txc ) {}
hw( write, UART0,
byte );
}
void uart1_putbyte ( uint8_t byte )
{
while ( !
hw(stat,UART1).txc ) {}
hw( write, UART1,
byte );
}
int
main ( )
{
hw( write, (core0, osccal), 0xFF );
hwa( configure, PIN_LED, mode, digital_output );
sleep, enabled,
sleep_mode, idle );
hw( enable, interrupts );
for(;;) {
for(;;) {
if (
hw(stat,UART0).sync ) {
uart0_putbyte( '$' );
hw( write, (UART1,dt0),
hw( read, (UART0,dt0) ) );
hw( write, (UART1,dtn),
hw( read, (UART0,dtn) ) );
hw( write, (UART1,sync), 1 );
uart1_putbyte( '$' );
break ;
}
if (
hw(stat,UART1).sync ) {
uart1_putbyte( '$' );
hw( write, (UART0,dt0),
hw( read, (UART1,dt0) ) );
hw( write, (UART0,dtn),
hw( read, (UART1,dtn) ) );
hw( write, (UART0,sync), 1 );
uart0_putbyte( '$' );
break ;
}
}
for(;;) {
if (
hw(stat,UART0).rxc ) {
if (
hw(stat,UART0).stop == 0 )
break ;
uint8_t
byte =
hw( read, UART0 );
uart0_putbyte( byte );
uart1_putbyte( byte );
}
if (
hw(stat,UART1).rxc ) {
if (
hw(stat,UART1).stop == 0 )
break ;
uint8_t
byte =
hw( read, UART1 );
uart1_putbyte( byte );
uart0_putbyte( byte );
}
}
}
}