1
0
mirror of git://projects.qi-hardware.com/ben-blinkenlights.git synced 2024-07-01 02:25:27 +03:00

swuart/: half-duplex software UART for UBB (WIP)

This commit is contained in:
Werner Almesberger 2012-12-17 00:45:21 -03:00
parent 2c52dac4ca
commit 4689882497
2 changed files with 120 additions and 0 deletions

19
swuart/Makefile Normal file
View File

@ -0,0 +1,19 @@
CC = mipsel-openwrt-linux-gcc
CFLAGS = -g -Wall -I../libubb/include
LDFLAGS = -static
LDLIBS = -L../libubb -lubb
MAIN = swuart
OBJS = swuart.o
.PHONY: all clean spotless
all: $(MAIN)
$(MAIN): $(OBJS)
clean:
rm -f $(OBJS)
spotless: clean
rm -f $(MAIN)

101
swuart/swuart.c Normal file
View File

@ -0,0 +1,101 @@
/*
* 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 <stdlib.h>
#include <unistd.h>
#include <ubb/ubb.h>
#include <ubb/regs4740.h>
#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);
}