From 9ddc3779692ccb1bb33d90484d3523ea61cf73ae Mon Sep 17 00:00:00 2001 From: Werner Almesberger Date: Mon, 31 Dec 2012 19:30:18 -0300 Subject: [PATCH] libubb/README.SWUART: document the software-implemented UART --- libubb/README.SWUART | 118 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 118 insertions(+) create mode 100644 libubb/README.SWUART diff --git a/libubb/README.SWUART b/libubb/README.SWUART new file mode 100644 index 0000000..5e6f6b0 --- /dev/null +++ b/libubb/README.SWUART @@ -0,0 +1,118 @@ +libubb: SWUART - a software-implemented UART +============================================ + +libubb also provides a UART implemented in software. This UART uses +signals of UBB and runs in user space. + +To comply with the relatively tight bit timing requirements of the +serial protocol, the UART's transfer function disables interrupts +while sending or receiving data, and it uses hardware timer 7. + +The format is always 8 data bits, no parity, one stop bit. + + +Installation, compiling, and linking +------------------------------------ + +Compiler and linker settings are the same as for general use of +UBB. + + +Skeleton program +---------------- + +This program fragment illustrates the key elements the SWUART: + + 1 #include + 2 #include + 3 + 4 ... + 5 #define TX UBB_DAT0 + 6 #define RX UBB_DAT1 + 7 ... + 8 + 9 char buf[200]; + 10 int got; + 11 + 12 if (ubb_open(0) < 0) { + 13 perror("ubb_open"); + 14 exit(1); + 15 } + 16 + 17 if (swuart_open(TX, RX, 38400) < 0) { + 18 perror("swuart_open"); + 19 exit(1); + 20 } + 21 + 22 got = swuart_trx("hello\n", 6, buf, sizeof(buf), 40000, 20000); + 23 fwrite(buf, 1, got, stdout); + 24 + 25 swuart_close(); + 26 ubb_close(0); + +Until line 15 we have the usual UBB setup, with the difference that +we also include ubb/swuart.h + +Note that we don't call ubb_power in this example. If power has to +be supplied to the device connected to UBB, such a call would have +to be made. + +Lines 17 to 19 prepare the UART. TX and RX are the bits used to send +or receive, respectively. If sending or receiving is not needed, set +the respective value to zero. The bit rate should be in the range +from 110 to 115200. + +swuart_open return 0 on success. In case of an error, it returns a +negative value and sets "errno". + +The call to swuart_trx in line 22 is the heart of SWUART: it first +sends the six bytes of "hello\n" and then wait for up to 40000 bit +times (i.e., about one second) for a response. The response is assume +to have ended once 20000 bit times (about half a second) have passed +since the last time a byte has been successfully received and stored. + +swuart_trx returns the number of bytes that have been received. If +there was no response, it returns 0. + +Line 23 writes anything that has been received to standard output. + +Lines 25 and 26 shut down everything. It is not necessary to call +swuart_close if the process simply exits. + + +Errors +------ + +The functions swuart_get_errors and swuart_clear_errors access the +receiver error counters. See include/ubb/swuart.h for details. + +The following error conditions are detected: + +- glitch: any falling edges that look like a start bit but where + the signal returns to "1" in the middle of the bit. The receiver + does not try to receive the rest of such a byte. + +- framing: bytes with a stop bit that is not "1". Such bytes are + discarded. + +- overflow: bytes received when the buffer is already full. + Reception of data when the buffer is full will not restart the + idle timeout but swuart_trx will still wait for the specified + amount of time to pass. + + +Duplex limitations +------------------ + +While a reception can start while swuart_trx is still sending and +the bit boundaries of sender and receiver do not need to coincide, +this still isn't entirely full-duplex. + +For example, data arriving before the first call to swuart_trx or +between calls to swuart_trx is lost. If swuart_trx is invoked +while data is arriving, it may misinterpret data bits as start +bits and thus receive garbage. + +Furthermore, swuart_trx disables interrupts while running. This +means that the entire Ben will be unresponsive during that time. +Therefore, the idle intervals should be as short as possible.