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.