Kernel/IPStack - (minor) TODO retransmit timer
[tpg/acess2.git] / UDI / drivers / uart_16c550 / uart16c550_pio.h
1 #define PIO_op_RI(op, reg, sz, val)     {UDI_PIO_##op+UDI_PIO_DIRECT+UDI_PIO_##reg, UDI_PIO_##sz##BYTE, val}
2 #define PIO_MOV_RI2(reg, val)   PIO_op_RI(LOAD_IMM, reg, 2, val)
3 #define PIO_MOV_RI1(reg, val)   PIO_op_RI(LOAD_IMM, reg, 2, val)        // Load IMM has to be 2 bytes
4 #define PIO_OUT_RI1(reg, ofs)   PIO_op_RI(OUT, reg, 1, ofs)
5 #define PIO_IN_RI1(reg, ofs)    PIO_op_RI(IN, reg, 1, ofs)
6
7 //
8 // Reset
9 // 
10 udi_pio_trans_t uart_pio_reset[] = {
11         // TODO: Programmable baud rate
12         PIO_MOV_RI1(R0, 0x00),
13         PIO_OUT_RI1(R0, 1),     // +1 = 0x00 - Disable interrupts
14         PIO_MOV_RI1(R0, 0x80),
15         PIO_OUT_RI1(R0, 3),     // +3 = 0x80 - Enable DLAB
16         PIO_MOV_RI1(R0, 0x01),
17         PIO_OUT_RI1(R0, 0),     // +0 = 0x01 - Divisor low      (115200 baud)
18         PIO_MOV_RI1(R0, 0x00),
19         PIO_OUT_RI1(R0, 1),     // +1 = 0x00 - Divisor high
20         PIO_MOV_RI1(R0, 0x03),
21         PIO_OUT_RI1(R0, 3),     // +3 = 0x03 - 8n1
22         PIO_MOV_RI1(R0, 0xC7),
23         PIO_OUT_RI1(R0, 2),     // +2 = 0xC7 - Clear FIFO, 14-byte threshold
24         PIO_MOV_RI1(R0, 0x0B),
25         PIO_OUT_RI1(R0, 4),     // +4 = 0x0B - IRQs enabled, RTS/DSR set
26         {UDI_PIO_END, UDI_PIO_2BYTE, 0}
27 };
28 //
29 // Transmit
30 //
31 udi_pio_trans_t uart_pio_tx[] = {
32         // while( (inb(SERIAL_PORT + 5) & 0x20) == 0 );
33         // outb(SERIAL_PORT, ch);
34         
35         // R0: Temp
36         // R1: Byte to write
37         // R2: Buffer size
38         // R3: Position
39         {UDI_PIO_LOAD_IMM+UDI_PIO_DIRECT+UDI_PIO_R3, UDI_PIO_2BYTE, 0},
40         {UDI_PIO_LOAD_IMM+UDI_PIO_DIRECT+UDI_PIO_R0, UDI_PIO_2BYTE, 0},
41         {UDI_PIO_LOAD+UDI_PIO_MEM+UDI_PIO_R0, UDI_PIO_4BYTE, UDI_PIO_R2},
42         
43         {UDI_PIO_LABEL, 0, 1},  // Loop top
44
45         {UDI_PIO_STORE+UDI_PIO_DIRECT+UDI_PIO_R0, UDI_PIO_2BYTE, UDI_PIO_R3},
46         //PIO_op_RI(LOAD, R0, 2, UDI_PIO_R3),
47         PIO_op_RI(SUB, R0, 2, UDI_PIO_R2),
48         {UDI_PIO_CSKIP+UDI_PIO_R0, UDI_PIO_1BYTE, UDI_PIO_NZ},
49         {UDI_PIO_BRANCH, 0, 3},
50         
51         // Load byte into R1 (and increment R3)
52         {UDI_PIO_LOAD+UDI_PIO_BUF+UDI_PIO_R3, UDI_PIO_1BYTE, UDI_PIO_R1},
53         PIO_op_RI(ADD_IMM, R3, 2, 1),
54         
55         // TX single byte from R1
56         // - Wait for FIFO to clear
57         // while( (inb(SERIAL_PORT + 5) & 0x20) == 0 );
58         {UDI_PIO_LABEL, 0, 2},
59         PIO_IN_RI1(R0, 5),
60         PIO_op_RI(AND_IMM, R0, 1, 0x20),
61         {UDI_PIO_CSKIP+UDI_PIO_R0, UDI_PIO_1BYTE, UDI_PIO_NZ},
62         {UDI_PIO_BRANCH, 0, 2},
63         // - TX
64         // outb(SERIAL_PORT, ch);
65         PIO_OUT_RI1(R1, 0),
66         {UDI_PIO_BRANCH, 0, 1},
67         
68         // Done
69         {UDI_PIO_LABEL, 0, 3},
70         {UDI_PIO_END, UDI_PIO_2BYTE, 0}
71 };
72 //
73 // Recieve (interrupt)
74 //
75 udi_pio_trans_t uart_pio_intr[] = {
76         // 0: Enable interrupts 
77         PIO_MOV_RI1(R0, 0x09),
78         PIO_OUT_RI1(R0, 1),     // +1 = EDSSI (Delta Line status), ELSI (Line Status), ERBFI (Rx Full)
79         {UDI_PIO_END, UDI_PIO_2BYTE, 0},
80         // 1: Interrupt
81         // - Check if the interrupt was for this device,
82         //   if so rx into buffer and return byte count
83         // return inb(SERIAL_PORT); 
84         {UDI_PIO_LABEL, 0, 1},
85         // if( (inb(SERIAL_PORT+5) & 0x01) == 0 ) {
86         PIO_IN_RI1(R0, 5),
87         PIO_op_RI(AND_IMM, R0, 1, 0x01),
88         {UDI_PIO_CSKIP+UDI_PIO_R0, UDI_PIO_1BYTE, UDI_PIO_Z},
89         {UDI_PIO_BRANCH, 0, 3},
90         //      SetUnclaimed()
91         PIO_MOV_RI1(R2, 0),
92         PIO_MOV_RI1(R1, UDI_INTR_UNCLAIMED),
93         {UDI_PIO_STORE+UDI_PIO_SCRATCH+UDI_PIO_R2, UDI_PIO_1BYTE, UDI_PIO_R1},
94         //      return 0;
95         {UDI_PIO_END_IMM, UDI_PIO_2BYTE, 0},
96         // }
97         // else {
98         {UDI_PIO_LABEL, 0, 3},
99         //      buf_ofs = 0;
100         PIO_MOV_RI2(R2, 0),     // Buffer offset
101         //      do {
102         {UDI_PIO_LABEL, 0, 4},
103         //              buffer[buf_ofs] = inb(SERIAL_PORT+0);
104         PIO_IN_RI1(R0, 0),
105         {UDI_PIO_STORE+UDI_PIO_BUF+UDI_PIO_R2, UDI_PIO_1BYTE, UDI_PIO_R0},
106         //              buf_ofs ++;
107         PIO_op_RI(ADD_IMM, R2, 1, 0x01),
108         //      } while( inb(SERIAL_PORT+5) & 0x01 );
109         PIO_IN_RI1(R0, 5),
110         PIO_op_RI(AND_IMM, R0, 1, 0x01),
111         {UDI_PIO_CSKIP+UDI_PIO_R0, UDI_PIO_1BYTE, UDI_PIO_Z},
112         {UDI_PIO_BRANCH, 0, 4},
113         //      return 0;
114         {UDI_PIO_END, UDI_PIO_1BYTE, UDI_PIO_R2},
115         // }
116         
117         // 2: Interrupt Overrun
118         {UDI_PIO_LABEL, 0, 2},
119         PIO_MOV_RI1(R0, 0x08),  // EDSSI only
120         PIO_OUT_RI1(R0, 1),
121         {UDI_PIO_END_IMM, UDI_PIO_2BYTE, 0}
122 };
123
124 #define ARRAY_SIZEOF(arr)       (sizeof(arr)/sizeof(arr[0]))
125
126 struct {
127         udi_pio_trans_t *trans_list;
128         udi_ubit16_t    list_length;
129         udi_ubit16_t    pio_attributes;
130 } uart_pio_ops[] = {
131         [PIO_RESET]  = {uart_pio_reset, ARRAY_SIZEOF(uart_pio_reset), 0},
132         [PIO_TX]     = {uart_pio_tx, ARRAY_SIZEOF(uart_pio_tx), 0},
133         [PIO_INTR]   = {uart_pio_intr, ARRAY_SIZEOF(uart_pio_intr), 0},
134 };
135 //const int UART_NUM_PIO_OPS = ARRAY_SIZEOF(uart_pio_ops);
136

UCC git Repository :: git.ucc.asn.au