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;
168 ap[MuCntl] = TxEn|RxEn;
170 intrenable(IRQaux, interrupt, uart, 0, "uart");
171 ap[MuIer] = RxIen|TxIen;
181 ap = (u32int*)uart->regs;
191 ap = (u32int*)uart->regs;
195 while(ap[MuLsr] & TxRdy){
196 if(uart->op >= uart->oe && uartstageoutput(uart) == 0)
198 ap[MuIo] = *(uart->op++);
200 if(ap[MuLsr] & TxDone)
209 dobreak(Uart *uart, int ms)
215 baud(Uart *uart, int n)
219 ap = (u32int*)uart->regs;
220 if(uart->freq == 0 || n <= 0)
222 ap[MuBaud] = (uart->freq + 4*n - 1) / (8 * n) - 1;
228 bits(Uart *uart, int n)
233 ap = (u32int*)uart->regs;
244 ap[MuLcr] = (ap[MuLcr] & ~Bitsmask) | set;
250 stop(Uart *uart, int n)
259 parity(Uart *uart, int n)
268 * cts/rts flow control
269 * need to bring signals to gpio pins before enabling this
273 modemctl(Uart *uart, int on)
277 ap = (u32int*)uart->regs;
279 ap[MuCntl] |= CtsFlow;
281 ap[MuCntl] &= ~CtsFlow;
286 rts(Uart *uart, int on)
290 ap = (u32int*)uart->regs;
298 status(Uart *uart, void *buf, long n, long offset)
307 "dev(%d) type(%d) framing(%d) overruns(%d) "
308 "berr(%d) serr(%d)\n",
318 n = readstr(offset, buf, n, p);
325 donothing(Uart*, int)
334 ap = (u32int*)AUXREGS;
335 while((ap[MuLsr] & TxRdy) == 0)
338 while((ap[MuLsr] & TxRdy) == 0)
347 ap = (u32int*)AUXREGS;
348 while((ap[MuLsr] & RxRdy) == 0)
350 return ap[MuIo] & 0xFF;
360 if((p = getconf("console")) == nil)
362 n = strtoul(p, &cmd, 0);
373 uartctl(uart, "b9600 l8 pn s1");
378 (*uart->phys->enable)(uart, 0);
384 PhysUart miniphysuart = {
395 .modemctl = donothing,
410 gpiosel(OkLed, Output);