15d9de2d3SDavid du Colombier /*
25d9de2d3SDavid du Colombier * bcm2835 mini uart (UART1)
35d9de2d3SDavid du Colombier */
45d9de2d3SDavid du Colombier
55d9de2d3SDavid du Colombier #include "u.h"
65d9de2d3SDavid du Colombier #include "../port/lib.h"
75d9de2d3SDavid du Colombier #include "../port/error.h"
85d9de2d3SDavid du Colombier #include "mem.h"
95d9de2d3SDavid du Colombier #include "dat.h"
105d9de2d3SDavid du Colombier #include "fns.h"
115d9de2d3SDavid du Colombier #include "io.h"
125d9de2d3SDavid du Colombier
135d9de2d3SDavid du Colombier #define GPIOREGS (VIRTIO+0x200000)
145d9de2d3SDavid du Colombier #define AUXREGS (VIRTIO+0x215000)
155d9de2d3SDavid du Colombier #define OkLed 16
165d9de2d3SDavid du Colombier #define TxPin 14
175d9de2d3SDavid du Colombier #define RxPin 15
185d9de2d3SDavid du Colombier
195d9de2d3SDavid du Colombier /* GPIO regs */
205d9de2d3SDavid du Colombier enum {
215d9de2d3SDavid du Colombier Fsel0 = 0x00>>2,
225d9de2d3SDavid du Colombier FuncMask= 0x7,
235d9de2d3SDavid du Colombier Input = 0x0,
245d9de2d3SDavid du Colombier Output = 0x1,
255d9de2d3SDavid du Colombier Alt0 = 0x4,
265d9de2d3SDavid du Colombier Alt1 = 0x5,
275d9de2d3SDavid du Colombier Alt2 = 0x6,
285d9de2d3SDavid du Colombier Alt3 = 0x7,
295d9de2d3SDavid du Colombier Alt4 = 0x3,
305d9de2d3SDavid du Colombier Alt5 = 0x2,
315d9de2d3SDavid du Colombier Set0 = 0x1c>>2,
325d9de2d3SDavid du Colombier Clr0 = 0x28>>2,
335d9de2d3SDavid du Colombier Lev0 = 0x34>>2,
345d9de2d3SDavid du Colombier PUD = 0x94>>2,
355d9de2d3SDavid du Colombier Off = 0x0,
365d9de2d3SDavid du Colombier Pulldown= 0x1,
375d9de2d3SDavid du Colombier Pullup = 0x2,
385d9de2d3SDavid du Colombier PUDclk0 = 0x98>>2,
395d9de2d3SDavid du Colombier PUDclk1 = 0x9c>>2,
405d9de2d3SDavid du Colombier };
415d9de2d3SDavid du Colombier
425d9de2d3SDavid du Colombier /* AUX regs */
435d9de2d3SDavid du Colombier enum {
445d9de2d3SDavid du Colombier Irq = 0x00>>2,
455d9de2d3SDavid du Colombier UartIrq = 1<<0,
465d9de2d3SDavid du Colombier Enables = 0x04>>2,
475d9de2d3SDavid du Colombier UartEn = 1<<0,
485d9de2d3SDavid du Colombier MuIo = 0x40>>2,
495d9de2d3SDavid du Colombier MuIer = 0x44>>2,
505d9de2d3SDavid du Colombier RxIen = 1<<0,
515d9de2d3SDavid du Colombier TxIen = 1<<1,
525d9de2d3SDavid du Colombier MuIir = 0x48>>2,
535d9de2d3SDavid du Colombier MuLcr = 0x4c>>2,
545d9de2d3SDavid du Colombier Bitsmask= 3<<0,
555d9de2d3SDavid du Colombier Bits7 = 2<<0,
565d9de2d3SDavid du Colombier Bits8 = 3<<0,
575d9de2d3SDavid du Colombier MuMcr = 0x50>>2,
585d9de2d3SDavid du Colombier RtsN = 1<<1,
595d9de2d3SDavid du Colombier MuLsr = 0x54>>2,
605d9de2d3SDavid du Colombier TxDone = 1<<6,
615d9de2d3SDavid du Colombier TxRdy = 1<<5,
625d9de2d3SDavid du Colombier RxRdy = 1<<0,
635d9de2d3SDavid du Colombier MuCntl = 0x60>>2,
645d9de2d3SDavid du Colombier CtsFlow = 1<<3,
655d9de2d3SDavid du Colombier TxEn = 1<<1,
665d9de2d3SDavid du Colombier RxEn = 1<<0,
675d9de2d3SDavid du Colombier MuBaud = 0x68>>2,
685d9de2d3SDavid du Colombier };
695d9de2d3SDavid du Colombier
705d9de2d3SDavid du Colombier extern PhysUart miniphysuart;
715d9de2d3SDavid du Colombier
725d9de2d3SDavid du Colombier static Uart miniuart = {
735d9de2d3SDavid du Colombier .regs = (u32int*)AUXREGS,
745d9de2d3SDavid du Colombier .name = "uart0",
755d9de2d3SDavid du Colombier .freq = 250000000,
765d9de2d3SDavid du Colombier .phys = &miniphysuart,
775d9de2d3SDavid du Colombier };
785d9de2d3SDavid du Colombier
795d9de2d3SDavid du Colombier void
gpiosel(uint pin,int func)805d9de2d3SDavid du Colombier gpiosel(uint pin, int func)
815d9de2d3SDavid du Colombier {
825d9de2d3SDavid du Colombier u32int *gp, *fsel;
835d9de2d3SDavid du Colombier int off;
845d9de2d3SDavid du Colombier
855d9de2d3SDavid du Colombier gp = (u32int*)GPIOREGS;
865d9de2d3SDavid du Colombier fsel = &gp[Fsel0 + pin/10];
875d9de2d3SDavid du Colombier off = (pin % 10) * 3;
885d9de2d3SDavid du Colombier *fsel = (*fsel & ~(FuncMask<<off)) | func<<off;
895d9de2d3SDavid du Colombier }
905d9de2d3SDavid du Colombier
915d9de2d3SDavid du Colombier void
gpiopulloff(uint pin)925d9de2d3SDavid du Colombier gpiopulloff(uint pin)
935d9de2d3SDavid du Colombier {
945d9de2d3SDavid du Colombier u32int *gp, *reg;
955d9de2d3SDavid du Colombier u32int mask;
965d9de2d3SDavid du Colombier
975d9de2d3SDavid du Colombier gp = (u32int*)GPIOREGS;
985d9de2d3SDavid du Colombier reg = &gp[PUDclk0 + pin/32];
995d9de2d3SDavid du Colombier mask = 1 << (pin % 32);
1005d9de2d3SDavid du Colombier gp[PUD] = Off;
1015d9de2d3SDavid du Colombier microdelay(1);
1025d9de2d3SDavid du Colombier *reg = mask;
1035d9de2d3SDavid du Colombier microdelay(1);
1045d9de2d3SDavid du Colombier *reg = 0;
1055d9de2d3SDavid du Colombier }
1065d9de2d3SDavid du Colombier
1075d9de2d3SDavid du Colombier void
gpioout(uint pin,int set)1085d9de2d3SDavid du Colombier gpioout(uint pin, int set)
1095d9de2d3SDavid du Colombier {
1105d9de2d3SDavid du Colombier u32int *gp;
1115d9de2d3SDavid du Colombier int v;
1125d9de2d3SDavid du Colombier
1135d9de2d3SDavid du Colombier gp = (u32int*)GPIOREGS;
1145d9de2d3SDavid du Colombier v = set? Set0 : Clr0;
1155d9de2d3SDavid du Colombier gp[v + pin/32] = 1 << (pin % 32);
1165d9de2d3SDavid du Colombier }
1175d9de2d3SDavid du Colombier
1185d9de2d3SDavid du Colombier int
gpioin(uint pin)1195d9de2d3SDavid du Colombier gpioin(uint pin)
1205d9de2d3SDavid du Colombier {
1215d9de2d3SDavid du Colombier u32int *gp;
1225d9de2d3SDavid du Colombier
1235d9de2d3SDavid du Colombier gp = (u32int*)GPIOREGS;
1245d9de2d3SDavid du Colombier return (gp[Lev0 + pin/32] & (1 << (pin % 32))) != 0;
1255d9de2d3SDavid du Colombier }
1265d9de2d3SDavid du Colombier
1275d9de2d3SDavid du Colombier static void
interrupt(Ureg *,void * arg)1285d9de2d3SDavid du Colombier interrupt(Ureg*, void *arg)
1295d9de2d3SDavid du Colombier {
1305d9de2d3SDavid du Colombier Uart *uart;
1315d9de2d3SDavid du Colombier u32int *ap;
1325d9de2d3SDavid du Colombier
1335d9de2d3SDavid du Colombier uart = arg;
1345d9de2d3SDavid du Colombier ap = (u32int*)uart->regs;
1355d9de2d3SDavid du Colombier
1365d9de2d3SDavid du Colombier coherence();
1375d9de2d3SDavid du Colombier if(0 && (ap[Irq] & UartIrq) == 0)
1385d9de2d3SDavid du Colombier return;
1395d9de2d3SDavid du Colombier if(ap[MuLsr] & TxRdy)
1405d9de2d3SDavid du Colombier uartkick(uart);
1415d9de2d3SDavid du Colombier if(ap[MuLsr] & RxRdy){
142*b4d1cf41SDavid du Colombier if(uart->console){
1435d9de2d3SDavid du Colombier if(uart->opens == 1)
1445d9de2d3SDavid du Colombier uart->putc = kbdcr2nl;
1455d9de2d3SDavid du Colombier else
1465d9de2d3SDavid du Colombier uart->putc = nil;
147*b4d1cf41SDavid du Colombier }
1485d9de2d3SDavid du Colombier do{
1495d9de2d3SDavid du Colombier uartrecv(uart, ap[MuIo] & 0xFF);
1505d9de2d3SDavid du Colombier }while(ap[MuLsr] & RxRdy);
1515d9de2d3SDavid du Colombier }
1525d9de2d3SDavid du Colombier coherence();
1535d9de2d3SDavid du Colombier }
1545d9de2d3SDavid du Colombier
1555d9de2d3SDavid du Colombier static Uart*
pnp(void)1565d9de2d3SDavid du Colombier pnp(void)
1575d9de2d3SDavid du Colombier {
1585d9de2d3SDavid du Colombier Uart *uart;
1595d9de2d3SDavid du Colombier
1605d9de2d3SDavid du Colombier uart = &miniuart;
1615d9de2d3SDavid du Colombier if(uart->console == 0)
1625d9de2d3SDavid du Colombier kbdq = qopen(8*1024, 0, nil, nil);
1635d9de2d3SDavid du Colombier return uart;
1645d9de2d3SDavid du Colombier }
1655d9de2d3SDavid du Colombier
1665d9de2d3SDavid du Colombier static void
enable(Uart * uart,int ie)1675d9de2d3SDavid du Colombier enable(Uart *uart, int ie)
1685d9de2d3SDavid du Colombier {
1695d9de2d3SDavid du Colombier u32int *ap;
1705d9de2d3SDavid du Colombier
1715d9de2d3SDavid du Colombier ap = (u32int*)uart->regs;
1725d9de2d3SDavid du Colombier delay(10);
1735d9de2d3SDavid du Colombier gpiosel(TxPin, Alt5);
1745d9de2d3SDavid du Colombier gpiosel(RxPin, Alt5);
1755d9de2d3SDavid du Colombier gpiopulloff(TxPin);
1765d9de2d3SDavid du Colombier gpiopulloff(RxPin);
1775d9de2d3SDavid du Colombier ap[Enables] |= UartEn;
1785d9de2d3SDavid du Colombier ap[MuIir] = 6;
1795d9de2d3SDavid du Colombier ap[MuLcr] = Bits8;
1805d9de2d3SDavid du Colombier ap[MuCntl] = TxEn|RxEn;
1815d9de2d3SDavid du Colombier ap[MuBaud] = 250000000/(115200*8) - 1;
1825d9de2d3SDavid du Colombier if(ie){
1835d9de2d3SDavid du Colombier intrenable(IRQaux, interrupt, uart, 0, "uart");
1845d9de2d3SDavid du Colombier ap[MuIer] = RxIen|TxIen;
1855d9de2d3SDavid du Colombier }else
1865d9de2d3SDavid du Colombier ap[MuIer] = 0;
1875d9de2d3SDavid du Colombier }
1885d9de2d3SDavid du Colombier
1895d9de2d3SDavid du Colombier static void
disable(Uart * uart)1905d9de2d3SDavid du Colombier disable(Uart *uart)
1915d9de2d3SDavid du Colombier {
1925d9de2d3SDavid du Colombier u32int *ap;
1935d9de2d3SDavid du Colombier
1945d9de2d3SDavid du Colombier ap = (u32int*)uart->regs;
1955d9de2d3SDavid du Colombier ap[MuCntl] = 0;
1965d9de2d3SDavid du Colombier ap[MuIer] = 0;
1975d9de2d3SDavid du Colombier }
1985d9de2d3SDavid du Colombier
1995d9de2d3SDavid du Colombier static void
kick(Uart * uart)2005d9de2d3SDavid du Colombier kick(Uart *uart)
2015d9de2d3SDavid du Colombier {
2025d9de2d3SDavid du Colombier u32int *ap;
2035d9de2d3SDavid du Colombier
2045d9de2d3SDavid du Colombier ap = (u32int*)uart->regs;
2055d9de2d3SDavid du Colombier if(uart->blocked)
2065d9de2d3SDavid du Colombier return;
2075d9de2d3SDavid du Colombier coherence();
2085d9de2d3SDavid du Colombier while(ap[MuLsr] & TxRdy){
2095d9de2d3SDavid du Colombier if(uart->op >= uart->oe && uartstageoutput(uart) == 0)
2105d9de2d3SDavid du Colombier break;
2115d9de2d3SDavid du Colombier ap[MuIo] = *(uart->op++);
2125d9de2d3SDavid du Colombier }
2135d9de2d3SDavid du Colombier if(ap[MuLsr] & TxDone)
2145d9de2d3SDavid du Colombier ap[MuIer] &= ~TxIen;
2155d9de2d3SDavid du Colombier else
2165d9de2d3SDavid du Colombier ap[MuIer] |= TxIen;
2175d9de2d3SDavid du Colombier coherence();
2185d9de2d3SDavid du Colombier }
2195d9de2d3SDavid du Colombier
2205d9de2d3SDavid du Colombier /* TODO */
2215d9de2d3SDavid du Colombier static void
dobreak(Uart * uart,int ms)2225d9de2d3SDavid du Colombier dobreak(Uart *uart, int ms)
2235d9de2d3SDavid du Colombier {
2245d9de2d3SDavid du Colombier USED(uart, ms);
2255d9de2d3SDavid du Colombier }
2265d9de2d3SDavid du Colombier
2275d9de2d3SDavid du Colombier static int
baud(Uart * uart,int n)2285d9de2d3SDavid du Colombier baud(Uart *uart, int n)
2295d9de2d3SDavid du Colombier {
2305d9de2d3SDavid du Colombier u32int *ap;
2315d9de2d3SDavid du Colombier
2325d9de2d3SDavid du Colombier ap = (u32int*)uart->regs;
2335d9de2d3SDavid du Colombier if(uart->freq == 0 || n <= 0)
2345d9de2d3SDavid du Colombier return -1;
2355d9de2d3SDavid du Colombier ap[MuBaud] = (uart->freq + 4*n - 1) / (8 * n) - 1;
2365d9de2d3SDavid du Colombier uart->baud = n;
2375d9de2d3SDavid du Colombier return 0;
2385d9de2d3SDavid du Colombier }
2395d9de2d3SDavid du Colombier
2405d9de2d3SDavid du Colombier static int
bits(Uart * uart,int n)2415d9de2d3SDavid du Colombier bits(Uart *uart, int n)
2425d9de2d3SDavid du Colombier {
2435d9de2d3SDavid du Colombier u32int *ap;
2445d9de2d3SDavid du Colombier int set;
2455d9de2d3SDavid du Colombier
2465d9de2d3SDavid du Colombier ap = (u32int*)uart->regs;
2475d9de2d3SDavid du Colombier switch(n){
2485d9de2d3SDavid du Colombier case 7:
2495d9de2d3SDavid du Colombier set = Bits7;
2505d9de2d3SDavid du Colombier break;
2515d9de2d3SDavid du Colombier case 8:
2525d9de2d3SDavid du Colombier set = Bits8;
2535d9de2d3SDavid du Colombier break;
2545d9de2d3SDavid du Colombier default:
2555d9de2d3SDavid du Colombier return -1;
2565d9de2d3SDavid du Colombier }
2575d9de2d3SDavid du Colombier ap[MuLcr] = (ap[MuLcr] & ~Bitsmask) | set;
2585d9de2d3SDavid du Colombier uart->bits = n;
2595d9de2d3SDavid du Colombier return 0;
2605d9de2d3SDavid du Colombier }
2615d9de2d3SDavid du Colombier
2625d9de2d3SDavid du Colombier static int
stop(Uart * uart,int n)2635d9de2d3SDavid du Colombier stop(Uart *uart, int n)
2645d9de2d3SDavid du Colombier {
2655d9de2d3SDavid du Colombier if(n != 1)
2665d9de2d3SDavid du Colombier return -1;
2675d9de2d3SDavid du Colombier uart->stop = n;
2685d9de2d3SDavid du Colombier return 0;
2695d9de2d3SDavid du Colombier }
2705d9de2d3SDavid du Colombier
2715d9de2d3SDavid du Colombier static int
parity(Uart * uart,int n)2725d9de2d3SDavid du Colombier parity(Uart *uart, int n)
2735d9de2d3SDavid du Colombier {
2745d9de2d3SDavid du Colombier if(n != 'n')
2755d9de2d3SDavid du Colombier return -1;
2765d9de2d3SDavid du Colombier uart->parity = n;
2775d9de2d3SDavid du Colombier return 0;
2785d9de2d3SDavid du Colombier }
2795d9de2d3SDavid du Colombier
2805d9de2d3SDavid du Colombier /*
2815d9de2d3SDavid du Colombier * cts/rts flow control
2825d9de2d3SDavid du Colombier * need to bring signals to gpio pins before enabling this
2835d9de2d3SDavid du Colombier */
2845d9de2d3SDavid du Colombier
2855d9de2d3SDavid du Colombier static void
modemctl(Uart * uart,int on)2865d9de2d3SDavid du Colombier modemctl(Uart *uart, int on)
2875d9de2d3SDavid du Colombier {
2885d9de2d3SDavid du Colombier u32int *ap;
2895d9de2d3SDavid du Colombier
2905d9de2d3SDavid du Colombier ap = (u32int*)uart->regs;
2915d9de2d3SDavid du Colombier if(on)
2925d9de2d3SDavid du Colombier ap[MuCntl] |= CtsFlow;
2935d9de2d3SDavid du Colombier else
2945d9de2d3SDavid du Colombier ap[MuCntl] &= ~CtsFlow;
2955d9de2d3SDavid du Colombier uart->modem = on;
2965d9de2d3SDavid du Colombier }
2975d9de2d3SDavid du Colombier
2985d9de2d3SDavid du Colombier static void
rts(Uart * uart,int on)2995d9de2d3SDavid du Colombier rts(Uart *uart, int on)
3005d9de2d3SDavid du Colombier {
3015d9de2d3SDavid du Colombier u32int *ap;
3025d9de2d3SDavid du Colombier
3035d9de2d3SDavid du Colombier ap = (u32int*)uart->regs;
3045d9de2d3SDavid du Colombier if(on)
3055d9de2d3SDavid du Colombier ap[MuMcr] &= ~RtsN;
3065d9de2d3SDavid du Colombier else
3075d9de2d3SDavid du Colombier ap[MuMcr] |= RtsN;
3085d9de2d3SDavid du Colombier }
3095d9de2d3SDavid du Colombier
3105d9de2d3SDavid du Colombier static long
status(Uart * uart,void * buf,long n,long offset)3115d9de2d3SDavid du Colombier status(Uart *uart, void *buf, long n, long offset)
3125d9de2d3SDavid du Colombier {
3135d9de2d3SDavid du Colombier char *p;
3145d9de2d3SDavid du Colombier
3155d9de2d3SDavid du Colombier p = malloc(READSTR);
3165d9de2d3SDavid du Colombier if(p == nil)
3175d9de2d3SDavid du Colombier error(Enomem);
3185d9de2d3SDavid du Colombier snprint(p, READSTR,
3195d9de2d3SDavid du Colombier "b%d\n"
3205d9de2d3SDavid du Colombier "dev(%d) type(%d) framing(%d) overruns(%d) "
3215d9de2d3SDavid du Colombier "berr(%d) serr(%d)\n",
3225d9de2d3SDavid du Colombier
3235d9de2d3SDavid du Colombier uart->baud,
3245d9de2d3SDavid du Colombier uart->dev,
3255d9de2d3SDavid du Colombier uart->type,
3265d9de2d3SDavid du Colombier uart->ferr,
3275d9de2d3SDavid du Colombier uart->oerr,
3285d9de2d3SDavid du Colombier uart->berr,
3295d9de2d3SDavid du Colombier uart->serr
3305d9de2d3SDavid du Colombier );
3315d9de2d3SDavid du Colombier n = readstr(offset, buf, n, p);
3325d9de2d3SDavid du Colombier free(p);
3335d9de2d3SDavid du Colombier
3345d9de2d3SDavid du Colombier return n;
3355d9de2d3SDavid du Colombier }
3365d9de2d3SDavid du Colombier
3375d9de2d3SDavid du Colombier static void
donothing(Uart *,int)3385d9de2d3SDavid du Colombier donothing(Uart*, int)
3395d9de2d3SDavid du Colombier {
3405d9de2d3SDavid du Colombier }
3415d9de2d3SDavid du Colombier
3425d9de2d3SDavid du Colombier void
putc(Uart *,int c)3435d9de2d3SDavid du Colombier putc(Uart*, int c)
3445d9de2d3SDavid du Colombier {
3455d9de2d3SDavid du Colombier u32int *ap;
3465d9de2d3SDavid du Colombier
3475d9de2d3SDavid du Colombier ap = (u32int*)AUXREGS;
3485d9de2d3SDavid du Colombier while((ap[MuLsr] & TxRdy) == 0)
3495d9de2d3SDavid du Colombier ;
3505d9de2d3SDavid du Colombier ap[MuIo] = c;
3515d9de2d3SDavid du Colombier while((ap[MuLsr] & TxRdy) == 0)
3525d9de2d3SDavid du Colombier ;
3535d9de2d3SDavid du Colombier }
3545d9de2d3SDavid du Colombier
3555d9de2d3SDavid du Colombier int
getc(Uart *)3565d9de2d3SDavid du Colombier getc(Uart*)
3575d9de2d3SDavid du Colombier {
3585d9de2d3SDavid du Colombier u32int *ap;
3595d9de2d3SDavid du Colombier
3605d9de2d3SDavid du Colombier ap = (u32int*)AUXREGS;
3615d9de2d3SDavid du Colombier while((ap[MuLsr] & RxRdy) == 0)
3625d9de2d3SDavid du Colombier ;
3635d9de2d3SDavid du Colombier return ap[MuIo] & 0xFF;
3645d9de2d3SDavid du Colombier }
3655d9de2d3SDavid du Colombier
3665d9de2d3SDavid du Colombier void
uartconsinit(void)3675d9de2d3SDavid du Colombier uartconsinit(void)
3685d9de2d3SDavid du Colombier {
3695d9de2d3SDavid du Colombier Uart *uart;
3705d9de2d3SDavid du Colombier int n;
3715d9de2d3SDavid du Colombier char *p, *cmd;
3725d9de2d3SDavid du Colombier
3735d9de2d3SDavid du Colombier if((p = getconf("console")) == nil)
3745d9de2d3SDavid du Colombier return;
3755d9de2d3SDavid du Colombier n = strtoul(p, &cmd, 0);
3765d9de2d3SDavid du Colombier if(p == cmd)
3775d9de2d3SDavid du Colombier return;
3785d9de2d3SDavid du Colombier switch(n){
3795d9de2d3SDavid du Colombier default:
3805d9de2d3SDavid du Colombier return;
3815d9de2d3SDavid du Colombier case 0:
3825d9de2d3SDavid du Colombier uart = &miniuart;
3835d9de2d3SDavid du Colombier break;
3845d9de2d3SDavid du Colombier }
3855d9de2d3SDavid du Colombier
3865d9de2d3SDavid du Colombier if(!uart->enabled)
3875d9de2d3SDavid du Colombier (*uart->phys->enable)(uart, 0);
3885d9de2d3SDavid du Colombier uartctl(uart, "b9600 l8 pn s1");
3895d9de2d3SDavid du Colombier if(*cmd != '\0')
3905d9de2d3SDavid du Colombier uartctl(uart, cmd);
3915d9de2d3SDavid du Colombier
3925d9de2d3SDavid du Colombier consuart = uart;
3935d9de2d3SDavid du Colombier uart->console = 1;
3945d9de2d3SDavid du Colombier }
3955d9de2d3SDavid du Colombier
3965d9de2d3SDavid du Colombier PhysUart miniphysuart = {
3975d9de2d3SDavid du Colombier .name = "miniuart",
3985d9de2d3SDavid du Colombier .pnp = pnp,
3995d9de2d3SDavid du Colombier .enable = enable,
4005d9de2d3SDavid du Colombier .disable = disable,
4015d9de2d3SDavid du Colombier .kick = kick,
4025d9de2d3SDavid du Colombier .dobreak = dobreak,
4035d9de2d3SDavid du Colombier .baud = baud,
4045d9de2d3SDavid du Colombier .bits = bits,
4055d9de2d3SDavid du Colombier .stop = stop,
4065d9de2d3SDavid du Colombier .parity = parity,
4075d9de2d3SDavid du Colombier .modemctl = donothing,
4085d9de2d3SDavid du Colombier .rts = rts,
4095d9de2d3SDavid du Colombier .dtr = donothing,
4105d9de2d3SDavid du Colombier .status = status,
4115d9de2d3SDavid du Colombier .fifo = donothing,
4125d9de2d3SDavid du Colombier .getc = getc,
4135d9de2d3SDavid du Colombier .putc = putc,
4145d9de2d3SDavid du Colombier };
4155d9de2d3SDavid du Colombier
4165d9de2d3SDavid du Colombier void
okay(int on)4175d9de2d3SDavid du Colombier okay(int on)
4185d9de2d3SDavid du Colombier {
4195d9de2d3SDavid du Colombier static int first;
4205d9de2d3SDavid du Colombier
4215d9de2d3SDavid du Colombier if(!first++)
4225d9de2d3SDavid du Colombier gpiosel(OkLed, Output);
4235d9de2d3SDavid du Colombier gpioout(OkLed, !on);
4245d9de2d3SDavid du Colombier }
425