voron

experimental ARM OS
git clone git://git.2f30.org/voron
Log | Files | Refs | README | LICENSE

rs232.c (2505B)


      1 #include <kernel.h>
      2 #include <irq.h>
      3 #include <rs232.h>
      4 
      5 /* TRM p.4459 */
      6 #define TX_FIFO_FULL	(1<<0)
      7 #define TX_FIFO_E	(1<<5)
      8 #define RX_FIFO_E	(1<<0)
      9 #define RHR_IT		(1<<0)
     10 #define IT_PENDING	(1<<0)
     11 #define IT_TYPE_RHR	(2<<1)
     12 
     13 /* TRM p.4444 */
     14 struct uart {
     15 	union {			/* 0x00 */
     16 		u32 thr;
     17 		u32 rhr;
     18 		u32 dll;
     19 	};
     20 	union {			/* 0x04 */
     21 		u32 ier;
     22 		u32 dlh;
     23 	};
     24 	union {			/* 0x08 */
     25 		u32 iir;
     26 		u32 fcr;
     27 		u32 efr;
     28 	};
     29 	u32 lcr;		/* 0x0c */
     30 	union {			/* 0x10 */
     31 		u32 mcr;
     32 		u32 xon1_addr1;
     33 	};
     34 	union {			/* 0x14 */
     35 		u32 lsr;
     36 		u32 xon2_addr2;
     37 	};
     38 	union {			/* 0x18 */
     39 		u32 tcr;
     40 		u32 msr;
     41 		u32 xoff1;
     42 	};
     43 	union {			/* 0x1c */
     44 		u32 spr;
     45 		u32 tlr;
     46 		u32 xoff2;
     47 	};
     48 	u32 mdr1;		/* 0x20 */
     49 	u32 mdr2;		/* 0x24 */
     50 	union {			/* 0x28 */
     51 		u32 sflsr;
     52 		u32 txfll;
     53 	};
     54 	union {			/* 0x2c */
     55 		u32 resume;
     56 		u32 txflh;
     57 	};
     58 	union {			/* 0x30 */
     59 		u32 sfregl;
     60 		u32 rxfll;
     61 	};
     62 	union {			/* 0x34 */
     63 		u32 sfregh;
     64 		u32 rxflh;
     65 	};
     66 	union {			/* 0x38 */
     67 		u32 blr;
     68 		u32 uasr;
     69 	};
     70 	u32 acreg;		/* 0x3c */
     71 	u32 scr;		/* 0x40 */
     72 	u32 ssr;		/* 0x44 */
     73 	u32 eblr;		/* 0x48 */
     74 	u32 __pad;		/* 0x4c */
     75 	u32 mvr;		/* 0x50 */
     76 	u32 sysc;		/* 0x54 */
     77 	u32 syss;		/* 0x58 */
     78 	u32 wer;		/* 0x5c */
     79 	u32 cfps;		/* 0x60 */
     80 	u32 rxfifo_lvl;		/* 0x64 */
     81 	u32 txfifo_lvl;		/* 0x68 */
     82 	u32 ier2;		/* 0x6c */
     83 	u32 isr2;		/* 0x70 */
     84 	u32 freq_sel;		/* 0x74 */
     85 	u32 __pad2[2];		/* 0x78 */
     86 	u32 mdr3;		/* 0x80 */
     87 	u32 tx_dma_threshold;	/* 0x84 */
     88 };
     89 
     90 /* UART3 */
     91 #define UART_IRQ_NUM	(HW_IRQ(74))
     92 static struct uart *uart = (struct uart*)0x48020000;
     93 
     94 int
     95 rs232_puts(const char *s)
     96 {
     97 	int ret = 0;
     98 
     99 	while (s[ret]) {
    100 		rs232_putchar(s[ret]);
    101 		ret++;
    102 	}
    103 
    104 	return ret;
    105 }
    106 
    107 int
    108 rs232_putchar(int c)
    109 {
    110 	if (c == '\n') {
    111 		if (readl(&uart->ssr) & TX_FIFO_FULL) {
    112 			while ((readl(&uart->lsr) & TX_FIFO_E) == 0)
    113 				;
    114 		}
    115 		writel('\r', &uart->thr);
    116 	}
    117 	/* if UART TX FIFO is full */
    118 	if (readl(&uart->ssr) & TX_FIFO_FULL) {
    119 		/* while UART TX FIFO is not empty */
    120 		while ((readl(&uart->lsr) & TX_FIFO_E) == 0)
    121 			;
    122 	}
    123 	/* write the character */
    124 	writel(c, &uart->thr);
    125 	return c;
    126 }
    127 
    128 int
    129 rs232_getchar(void)
    130 {
    131 	while ((readl(&uart->lsr) & RX_FIFO_E) == 0)
    132 		;
    133 	return readl(&uart->rhr);
    134 }
    135 
    136 static void
    137 rs232_irq_handler(__unused u32 irq_num, __unused struct regs *regs)
    138 {
    139 	while(!(readl(&uart->iir) & IT_PENDING)) {
    140 		if (readl(&uart->iir) & IT_TYPE_RHR)
    141 			rs232_putchar(rs232_getchar());
    142 	}
    143 }
    144 
    145 __attribute__((constructor))
    146 void
    147 rs232_init(void)
    148 {
    149 	irq_register(UART_IRQ_NUM, rs232_irq_handler);
    150 	writel(RHR_IT, &uart->ier);
    151 }