2 #include "../port/lib.h"
7 #include "../port/error.h"
9 #include "../port/netif.h"
11 /* this isn't strictly an sa1110 driver. The rts/cts stuff is h3650 specific */
13 static void sa1110_uartpower(Uart *, int);
22 SCE= 1<<4, /* synchronous clock enable */
23 RCE= 1<<5, /* rx on falling edge of clock */
24 TCE= 1<<6, /* tx on falling edge of clock */
27 Rena= 1<<0, /* receiver enable */
28 Tena= 1<<1, /* transmitter enable */
29 Break= 1<<2, /* force TXD3 low */
30 Rintena= 1<<3, /* enable receive interrupt */
31 Tintena= 1<<4, /* enable transmitter interrupt */
32 Loopback= 1<<5, /* loop back data */
35 DEparity= 1<<8, /* parity error */
36 DEframe= 1<<9, /* framing error */
37 DEoverrun= 1<<10, /* overrun error */
40 Tint= 1<<0, /* transmit fifo half full interrupt */
41 Rint0= 1<<1, /* receiver fifo 1/3-2/3 full */
42 Rint1= 1<<2, /* receiver fifo not empty and receiver idle */
45 Fifoerror= 1<<5, /* fifo error */
48 Tbusy= 1<<0, /* transmitting */
49 Rnotempty= 1<<1, /* receive fifo not empty */
50 Tnotfull= 1<<2, /* transmit fifo not full */
56 extern PhysUart sa1110physuart;
59 Uart sa1110uart[2] = {
60 { .regs = (void*)UART3REGS,
61 .name = "serialport3",
67 .phys = &sa1110physuart,
69 .next = &sa1110uart[1], },
71 { .regs = (void*)UART1REGS,
72 .name = "serialport1",
78 .phys = &sa1110physuart,
85 #define R(p) ((Uartregs*)((p)->regs))
86 #define SR(p) ((Uartregs*)((p)->saveregs))
89 * enable a port's interrupts. set DTR and RTS
92 sa1110_uartenable(Uart *p, int intena)
96 s = R(p)->ctl[3] & ~(Rintena|Tintena|Rena|Tena);
98 R(p)->ctl[3] = s |Rintena|Tintena|Rena|Tena;
100 R(p)->ctl[3] = s | Rena|Tena;
104 * disable interrupts. clear DTR, and RTS
107 sa1110_uartdisable(Uart *p)
109 R(p)->ctl[3] &= ~(Rintena|Tintena|Rena|Tena);
113 sa1110_uartstatus(Uart *p, void *buf, long n, long offset)
119 snprint(str, sizeof(str),
120 "b%d c%d d%d e%d l%d m%d p%c r%d s%d i%d\n"
121 "dev(%d) type(%d) framing(%d) overruns(%d)%s%s%s%s\n",
127 (ctl0 & Bits8) ? 8 : 7,
129 (ctl0 & Parity) ? ((ctl0 & Even) ? 'e' : 'o') : 'n',
131 (ctl0 & Stop2) ? 2 : 1,
142 return readstr(offset, buf, n, str);
149 sa1110_uartbaud(Uart *p, int rate)
161 brconst = p->freq/(16*rate) - 1;
162 R(p)->ctl[1] = (brconst>>8) & 0xf;
163 R(p)->ctl[2] = brconst & 0xff;
176 sa1110_uartbreak(Uart *p, int ms)
181 R(p)->ctl[3] |= Break;
182 tsleep(&up->sleep, return0, 0, ms);
183 R(p)->ctl[3] &= ~Break;
190 sa1110_uartbits(Uart *p, int n)
223 sa1110_uartstop(Uart *p, int n)
256 sa1110_uartrts(Uart*, int)
264 sa1110_uartdtr(Uart*, int)
269 * turn on/off modem flow control on/off (rts/cts)
272 sa1110_uartmodemctl(Uart *p, int on)
284 sa1110_uartparity(Uart *p, int type)
297 ctl0 &= ~(Parity|Even);
314 * restart output if not blocked and OK to send
317 sa1110_uartkick(Uart *p)
321 R(p)->ctl[3] &= ~Tintena;
323 if(p->cts == 0 || p->blocked)
326 for(i = 0; i < 1024; i++){
327 if(!(R(p)->status[1] & Tnotfull)){
328 R(p)->ctl[3] |= Tintena;
331 if(p->op >= p->oe && uartstageoutput(p) == 0)
333 R(p)->data = *p->op++;
341 sa1110_uartintr(Ureg*, void *x)
350 /* receiver interrupt, snarf bytes */
351 while(regs->status[1] & Rnotempty)
352 uartrecv(p, regs->data);
354 /* remember and reset interrupt causes */
356 regs->status[0] |= s;
359 /* transmitter interrupt, restart */
363 if(s & (ParityError|FrameError|Overrun)){
372 /* receiver interrupt, snarf bytes */
373 while(regs->status[1] & Rnotempty)
374 uartrecv(p, regs->data);
384 sa1110_getc(Uart *uart)
389 while((ur->status[1] & Rnotempty) == 0)
395 sa1110_putc(Uart *uart, int c)
400 /* wait for output ready */
401 while((ur->status[1] & Tnotfull) == 0)
404 while((ur->status[1] & Tbusy))
408 PhysUart sa1110physuart = {
411 .enable= sa1110_uartenable,
412 .disable= sa1110_uartdisable,
413 .bits= sa1110_uartbits,
414 .kick= sa1110_uartkick,
415 .modemctl= sa1110_uartmodemctl,
416 .baud= sa1110_uartbaud,
417 .stop= sa1110_uartstop,
418 .parity= sa1110_uartparity,
419 .dobreak= sa1110_uartbreak,
420 .rts= sa1110_uartrts,
421 .dtr= sa1110_uartdtr,
422 .status= sa1110_uartstatus,
423 .power= sa1110_uartpower,
429 * for iprint, just write it
432 serialµcputs(uchar *str, int n)
440 /* wait for output ready */
441 while((ur->status[1] & Tnotfull) == 0)
445 while((ur->status[1] & Tbusy))
451 /* gpclk register 0 */
452 Gpclk_sus= 1<<0, /* set uart mode */
455 Gpclkregs *gpclkregs;
458 * setup all uarts (called early by main() to allow debugging output to
462 sa1110_uartsetup(int console)
466 /* external serial port (eia0) */
468 p->regs = mapspecial(UART3REGS, sizeof(Uartregs));
469 p->saveregs = xalloc(sizeof(Uartregs));
470 /* set eia0 up as a console */
472 uartctl(p, "b115200 l8 pn s1");
473 (*p->phys->enable)(p, 0);
477 intrenable(IRQ, IRQuart3, sa1110_uartintr, p, p->name);
479 /* port for talking to microcontroller (eia1) */
480 gpclkregs = mapspecial(GPCLKREGS, sizeof(Gpclkregs));
481 gpclkregs->r0 = Gpclk_sus; /* set uart mode */
484 p->regs = mapspecial(UART1REGS, sizeof(Uartregs));
485 p->saveregs = xalloc(sizeof(Uartregs));
486 uartctl(p, "b115200 l8 pn s1");
489 (*p->phys->enable)(p, 0);
490 intrenable(IRQ, IRQuart1b, sa1110_uartintr, p, p->name);
494 uartcpy(Uartregs *to, Uartregs *from)
496 to->ctl[0] = from->ctl[0];
497 // to->ctl[1] = from->ctl[1];
498 // to->ctl[2] = from->ctl[2];
499 to->ctl[3] = from->ctl[3];
504 sa1110_uartpower(Uart *p, int powerup)
507 /* power up, restore the registers */
508 uartcpy(R(p), SR(p));
509 R(p)->status[0] = R(p)->status[0];
511 /* power down, save the registers */
512 uartcpy(SR(p), R(p));