/* * swuart/swuart.c - Software-implemented half-duplex UART for UBB * * Written 2012 by Werner Almesberger * Copyright 2012 Werner Almesberger * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. */ #include #include #include #include #define TX UBB_DAT2 static uint32_t tx_mask, rx_mask; static int loops; /* * TX bit timing: * * bps loops nominal estimated measured error * 1152200 202 8.696 us 8.673 us 8.67 us -0.3% * 38400 619 26.042 us 26.062 us 26.04 us n/a * 9600 2494 104.167 us 104.250 us 104.16 us n/a * * Estimated loop timing: 0.25+0.0417*loops */ int swuart_open(uint32_t tx, uint32_t rx, int bps) { if (ubb_open(0)) return -1; loops = 24000000/bps-6; tx_mask = tx; rx_mask = rx; ubb_power(1); OUT(tx); CLR(tx); IN(rx); return 0; } static void send(uint8_t *out, int out_size) { const uint8_t *end = out+out_size; unsigned pattern; int i, j; while (out != end) { pattern = 0x200 | (*out++ << 1); for (i = 0; i != 10; i++) { if (pattern & 1) SET(tx_mask); else CLR(tx_mask); pattern >>= 1; for (j = 0; j != loops; j++); } } } int swuart_trx(void *out, int out_size, void *in, int in_size, int bit_wait) { uint32_t icmr; icmr = ICMR; ICMSR = 0xffffffff; send(out, out_size); ICMCR = ~icmr; return 0; } int main(int argc, char **argv) { swuart_open(TX, 0, atoi(argv[1])); while (1) { swuart_trx("U ", 2, NULL, 0, 0); usleep(100); } ubb_close(0); }