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 }