HWA
Bare metal programming with style
Class _swuarta: software-emulated UART

Detailed Description

This class implements a software-emulated UART with the following features:

Note
Currently, this is only supported by Devices.
Performances

Tested on ATtiny24/44/84 with internal oscillator (rc_8MHz):

Note
The make rule swuarta-perfs defined in hwa/atmel/avr/examples/make/Makefile.cc displays the number of CPU cycles spent in different sections of the _swuarta code and in critical sections according to the configuration. These figures determine the performances that can be achieved.
Pins

If the same pin is used for rxd and txd signals, the UART automatically reverts to RX mode after a transmission is completed and transmissions are delayed one a reception is started, i.e. hw(write,UART,data) blocks until a reception is completed once it has started.

Start detection

By default, the pin-change controller associated to the RXD pin is used as the interrupt provider for detecting the start bit. This implies that the same pin-change controller should not be used by the application.

Counting unit

The counting unit is configured in up-loop mode, counting from 0 to the maximum it can reach. The user application can use the count value and the overflow interrupt, for example to make a RTC counter.

Automatic baudrate detection

If defined, autosync a method to automatically detect the baudrate:

Note
It is advised to disable the sleep instruction and all interrupts except the UART starter for a better accuracy of the baudrate detection. Once the UART is synchronized, interrupts can be re-enabled.
Do not forget that the software UART is interrupt-driven and that too long delays before the UART IRQs are serviced will lead to loss of data.
Currently, baudrate detection is started when the UART receives a character and it is not synced. The processing is blocking. Non blocking alternatives are provided but not yet useable.
Bus collision detection

If check_tx is defined, the status of the bus is compared with the last bit sent before sending a new one. If there is a mismatch (collision), the UART releases the TXD pin and sets the stop status flag to 0. The UART continues virtually to send until the end of the frame when it sets the txc bit as usual. That way, the application remains synchronized with the bus and can decide whether to retry the transmission or to listen to what is happening on the bus.

Note
Currently, check_tx can not be set by the constructor.

Implementation

Header file:



HW_SWUARTA(...) declares an object. You must provide:

HW_SWUARTA( txd, ..., // Pin TXD
[ rxd, ..., // Pin RXD
startirq, ..., ] // IRQ used for RX start bit
counter, ..., // Counter unit used
compare, ..., // Compare unit used
clkdiv, ..., // Counter prescaler value
[ autosync, ..., ] // Autosync method (51,91,101)
[ fastreg, ... ] ); // Address of a fast access register for status
#define UART HW_SWUARTA( txd, (portb,0),
rxd, (portb,1),
startirq, ((portb,1),port,pcic,irq),
counter, counter0,
compare, compare0,
clkdiv, 2,
autosync, 51,
fastreg, (shared,gpior0) );



HW_DECLARE( UART ) declares the functions that implement the device. You can put it in your header files:

HW_DECLARE( UART );

Currently, class _swuarta does not support HW_IMPLEMENT(). You must include the assembly file hwa/ext/swuarta.sx in one of your source files after having defined a UART symbol, once per object:

;; -*- asm -*-
#undef UART
#define UART UART0
#include <hwa/ext/swuarta.sx> // Implement UART0
#undef UART
#define UART UART1
#include <hwa/ext/swuarta.sx> // Implement UART1

Actions



Both hw( configure, UART, ... ) and hwa( configure, UART, ... ) configure the object but they differ slightly in what they do:

Optionnal arguments are used for consistency with the class _uarta.

hwa( configure, UART,
[ bps, BPS, ] // Baudrate in bits per second
[ cpb, N, ] // Baudrate in CPU clock pulses per bit
[ databits, 8, ] // Number of data bits in frame. Must be `8`.
[ parity, none, ] // Parity. Must be `none`.
[ stopbits, 1, ] // Number of stop bits in frame. Must be `1`.
[ receiver, enabled // Whether the UART can receive. Default is `enabled`.
| disabled, ]
[ transmitter, enabled ] ); // Whether the UART can transmit. Must be `enabled`.
hw( configure, UART,
bps, 100000 ); // Baudrate in bits per second



hw( read, UART ) clears the rxc flag, and returns the last byte received.

while ( hw(stat,UART).rxc == 0 );
uint8_t byte = hw( read, UART );



hw( write, UART, byte ) places a byte into the shift register, clears the txc flag and starts the transmission.

This instruction returns before the byte is actually transmitted. You need to check the txc flag to know when the transmission is complete.

while ( hw(stat,UART).txc == 0 );
hw( write, UART, '#' );



hw( stat, UART ) returns the status with the following flags:

uint8_t byte ;
hw_stat_t(UART) st ; // Structure of UART status
st = hw( stat, UART ); // Read the status
if ( st.rxc==1 && st.stop==1 ) // Reception complete with valid stop bit
byte = hw( read, UART );



hw( clear, UART ) clears the rxc and txc status flags.

hw( clear, UART );



hw( reset, UART ) aborts any transmission or reception. If the UART has automatic baudrate detection, the UART will first resynchronize.

hw( reset, UART );



hw( wait_idle, UART, n ) wait n idle bits:

hw( wait_idle, UART, 25 );

Registers

Macros

#define HW_SWUARTA(...)
 
hwa
#define hwa(...)
hwa( action, object [,...] ) stores an action for an object into a HWA context.
Definition: hwa_macros.h:552
HW_DECLARE
#define HW_DECLARE(...)
Declares the functions that implement an object.
Definition: hwa_1.h:526
swuarta.h
Software-emulated UART.
hw
#define hw(...)
hw( action, object [,...] ) executes an action immediately on an object.
Definition: hwa_macros.h:523
hw_stat_t
#define hw_stat_t(object)
Declares the appropriate structure that holds the status of an object.
Definition: hwa_macros.h:711
HW_SWUARTA
#define HW_SWUARTA(...)
Constructor for SWUARTA.
Definition: swuarta.h:153