Root/
| 1 | libubb: SWUART - a software-implemented UART |
| 2 | ============================================ |
| 3 | |
| 4 | libubb also provides a UART implemented in software. This UART uses |
| 5 | signals of UBB and runs in user space. |
| 6 | |
| 7 | To comply with the relatively tight bit timing requirements of the |
| 8 | serial protocol, the UART's transfer function disables interrupts |
| 9 | while sending or receiving data, and it uses hardware timer 7. |
| 10 | |
| 11 | The format is always 8 data bits, no parity, one stop bit. |
| 12 | |
| 13 | |
| 14 | Installation, compiling, and linking |
| 15 | ------------------------------------ |
| 16 | |
| 17 | Compiler and linker settings are the same as for general use of |
| 18 | UBB. |
| 19 | |
| 20 | |
| 21 | Skeleton program |
| 22 | ---------------- |
| 23 | |
| 24 | This program fragment illustrates the key elements the SWUART: |
| 25 | |
| 26 | 1 #include <ubb/ubb.h> |
| 27 | 2 #include <ubb/swuart.h> |
| 28 | 3 |
| 29 | 4 ... |
| 30 | 5 #define TX UBB_DAT0 |
| 31 | 6 #define RX UBB_DAT1 |
| 32 | 7 ... |
| 33 | 8 |
| 34 | 9 char buf[200]; |
| 35 | 10 int got; |
| 36 | 11 |
| 37 | 12 if (ubb_open(0) < 0) { |
| 38 | 13 perror("ubb_open"); |
| 39 | 14 exit(1); |
| 40 | 15 } |
| 41 | 16 |
| 42 | 17 if (swuart_open(TX, RX, 38400) < 0) { |
| 43 | 18 perror("swuart_open"); |
| 44 | 19 exit(1); |
| 45 | 20 } |
| 46 | 21 |
| 47 | 22 got = swuart_trx("hello\n", 6, buf, sizeof(buf), 40000, 20000); |
| 48 | 23 fwrite(buf, 1, got, stdout); |
| 49 | 24 |
| 50 | 25 swuart_close(); |
| 51 | 26 ubb_close(0); |
| 52 | |
| 53 | Until line 15 we have the usual UBB setup, with the difference that |
| 54 | we also include ubb/swuart.h |
| 55 | |
| 56 | Note that we don't call ubb_power in this example. If power has to |
| 57 | be supplied to the device connected to UBB, such a call would have |
| 58 | to be made. |
| 59 | |
| 60 | Lines 17 to 19 prepare the UART. TX and RX are the bits used to send |
| 61 | or receive, respectively. If sending or receiving is not needed, set |
| 62 | the respective value to zero. The bit rate should be in the range |
| 63 | from 110 to 115200. |
| 64 | |
| 65 | swuart_open return 0 on success. In case of an error, it returns a |
| 66 | negative value and sets "errno". |
| 67 | |
| 68 | The call to swuart_trx in line 22 is the heart of SWUART: it first |
| 69 | sends the six bytes of "hello\n" and then wait for up to 40000 bit |
| 70 | times (i.e., about one second) for a response. The response is assume |
| 71 | to have ended once 20000 bit times (about half a second) have passed |
| 72 | since the last time a byte has been successfully received and stored. |
| 73 | |
| 74 | swuart_trx returns the number of bytes that have been received. If |
| 75 | there was no response, it returns 0. |
| 76 | |
| 77 | Line 23 writes anything that has been received to standard output. |
| 78 | |
| 79 | Lines 25 and 26 shut down everything. It is not necessary to call |
| 80 | swuart_close if the process simply exits. |
| 81 | |
| 82 | |
| 83 | Errors |
| 84 | ------ |
| 85 | |
| 86 | The functions swuart_get_errors and swuart_clear_errors access the |
| 87 | receiver error counters. See include/ubb/swuart.h for details. |
| 88 | |
| 89 | The following error conditions are detected: |
| 90 | |
| 91 | - glitch: any falling edges that look like a start bit but where |
| 92 | the signal returns to "1" in the middle of the bit. The receiver |
| 93 | does not try to receive the rest of such a byte. |
| 94 | |
| 95 | - framing: bytes with a stop bit that is not "1". Such bytes are |
| 96 | discarded. |
| 97 | |
| 98 | - overflow: bytes received when the buffer is already full. |
| 99 | Reception of data when the buffer is full will not restart the |
| 100 | idle timeout but swuart_trx will still wait for the specified |
| 101 | amount of time to pass. |
| 102 | |
| 103 | |
| 104 | Duplex limitations |
| 105 | ------------------ |
| 106 | |
| 107 | While a reception can start while swuart_trx is still sending and |
| 108 | the bit boundaries of sender and receiver do not need to coincide, |
| 109 | this still isn't entirely full-duplex. |
| 110 | |
| 111 | For example, data arriving before the first call to swuart_trx or |
| 112 | between calls to swuart_trx is lost. If swuart_trx is invoked |
| 113 | while data is arriving, it may misinterpret data bits as start |
| 114 | bits and thus receive garbage. |
| 115 | |
| 116 | Furthermore, swuart_trx disables interrupts while running. This |
| 117 | means that the entire Ben will be unresponsive during that time. |
| 118 | Therefore, the idle intervals should be as short as possible. |
| 119 |
Branches:
master
