2 * bcm2835 mini uart (UART1)
6 #include "../port/lib.h"
7 #include "../port/error.h"
13 #define GPIOREGS (VIRTIO+0x200000)
14 #define AUXREGS (VIRTIO+0x215000)
70 extern PhysUart miniphysuart;
72 static Uart miniuart = {
73 .regs = (u32int*)AUXREGS,
76 .phys = &miniphysuart,
80 gpiosel(uint pin, int func)
85 gp = (u32int*)GPIOREGS;
86 fsel = &gp[Fsel0 + pin/10];
88 *fsel = (*fsel & ~(FuncMask << off)) | func << off;
97 gp = (u32int*)GPIOREGS;
98 reg = &gp[PUDclk0 + pin/32];
99 mask = 1 << (pin % 32);
108 gpioout(uint pin, int set)
113 gp = (u32int*)GPIOREGS;
115 gp[v + pin/32] = 1 << (pin % 32);
123 gp = (u32int*)GPIOREGS;
124 return (gp[Lev0 + pin/32] & (1 << (pin % 32))) != 0;
128 interrupt(Ureg*, void *arg)
134 ap = (u32int*)uart->regs;
137 if(0 && (ap[Irq] & UartIrq) == 0)
139 if(ap[MuLsr] & TxRdy)
141 if(ap[MuLsr] & RxRdy){
143 uartrecv(uart, ap[MuIo] & 0xFF);
144 }while(ap[MuLsr] & RxRdy);
156 enable(Uart *uart, int ie)
160 ap = (u32int*)uart->regs;
162 gpiosel(TxPin, Alt5);
163 gpiosel(RxPin, Alt5);
166 ap[Enables] |= UartEn;
169 ap[MuCntl] = TxEn|RxEn;
170 ap[MuBaud] = 250000000 / (115200 * 8) - 1;
172 intrenable(IRQaux, interrupt, uart, 0, "uart");
173 ap[MuIer] = RxIen|TxIen;
183 ap = (u32int*)uart->regs;
193 ap = (u32int*)uart->regs;
197 while(ap[MuLsr] & TxRdy){
198 if(uart->op >= uart->oe && uartstageoutput(uart) == 0)
200 ap[MuIo] = *(uart->op++);
202 if(ap[MuLsr] & TxDone)
211 dobreak(Uart *uart, int ms)
217 baud(Uart *uart, int n)
221 ap = (u32int*)uart->regs;
222 if(uart->freq == 0 || n <= 0)
224 ap[MuBaud] = (uart->freq + 4*n - 1) / (8 * n) - 1;
230 bits(Uart *uart, int n)
235 ap = (u32int*)uart->regs;
246 ap[MuLcr] = (ap[MuLcr] & ~Bitsmask) | set;
252 stop(Uart *uart, int n)
261 parity(Uart *uart, int n)
270 * cts/rts flow control
271 * need to bring signals to gpio pins before enabling this
275 modemctl(Uart *uart, int on)
279 ap = (u32int*)uart->regs;
281 ap[MuCntl] |= CtsFlow;
283 ap[MuCntl] &= ~CtsFlow;
288 rts(Uart *uart, int on)
292 ap = (u32int*)uart->regs;
300 status(Uart *uart, void *buf, long n, long offset)
309 "dev(%d) type(%d) framing(%d) overruns(%d) "
310 "berr(%d) serr(%d)\n",
320 n = readstr(offset, buf, n, p);
327 donothing(Uart*, int)
336 ap = (u32int*)AUXREGS;
337 while((ap[MuLsr] & TxRdy) == 0)
340 while((ap[MuLsr] & TxRdy) == 0)
349 ap = (u32int*)AUXREGS;
350 while((ap[MuLsr] & RxRdy) == 0)
352 return ap[MuIo] & 0xFF;
362 if((p = getconf("console")) == nil)
364 n = strtoul(p, &cmd, 0);
376 (*uart->phys->enable)(uart, 0);
377 uartctl(uart, "b9600 l8 pn s1");
385 PhysUart miniphysuart = {
396 .modemctl = donothing,
411 gpiosel(OkLed, Output);