X-Git-Url: https://git.ucc.asn.au/?a=blobdiff_plain;f=UDI%2Fdrivers%2Fuart_16c550%2Fuart16c550_pio.h;h=f02d8f056e04ba9e0db02db5a71e0b90d29d5b10;hb=d7dcea0e5a8df0f479e99f168a10b9a9535c7ad6;hp=7a4e22767c2f708b0174556d897f45dde615032e;hpb=ad8ed64b7916f20a97d573b29642f567f9e43331;p=tpg%2Facess2.git diff --git a/UDI/drivers/uart_16c550/uart16c550_pio.h b/UDI/drivers/uart_16c550/uart16c550_pio.h index 7a4e2276..f02d8f05 100644 --- a/UDI/drivers/uart_16c550/uart16c550_pio.h +++ b/UDI/drivers/uart_16c550/uart16c550_pio.h @@ -1,5 +1,6 @@ #define PIO_op_RI(op, reg, sz, val) {UDI_PIO_##op+UDI_PIO_DIRECT+UDI_PIO_##reg, UDI_PIO_##sz##BYTE, val} -#define PIO_MOV_RI1(reg, val) PIO_op_RI(LOAD_IMM, reg, 2, val) +#define PIO_MOV_RI2(reg, val) PIO_op_RI(LOAD_IMM, reg, 2, val) +#define PIO_MOV_RI1(reg, val) PIO_op_RI(LOAD_IMM, reg, 2, val) // Load IMM has to be 2 bytes #define PIO_OUT_RI1(reg, ofs) PIO_op_RI(OUT, reg, 1, ofs) #define PIO_IN_RI1(reg, ofs) PIO_op_RI(IN, reg, 1, ofs) @@ -7,19 +8,117 @@ // Reset // udi_pio_trans_t uart_pio_reset[] = { + // TODO: Programmable baud rate + PIO_MOV_RI1(R0, 0x00), + PIO_OUT_RI1(R0, 1), // +1 = 0x00 - Disable interrupts + PIO_MOV_RI1(R0, 0x80), + PIO_OUT_RI1(R0, 3), // +3 = 0x80 - Enable DLAB + PIO_MOV_RI1(R0, 0x01), + PIO_OUT_RI1(R0, 0), // +0 = 0x01 - Divisor low (115200 baud) + PIO_MOV_RI1(R0, 0x00), + PIO_OUT_RI1(R0, 1), // +1 = 0x00 - Divisor high + PIO_MOV_RI1(R0, 0x03), + PIO_OUT_RI1(R0, 3), // +3 = 0x03 - 8n1 + PIO_MOV_RI1(R0, 0xC7), + PIO_OUT_RI1(R0, 2), // +2 = 0xC7 - Clear FIFO, 14-byte threshold + PIO_MOV_RI1(R0, 0x0B), + PIO_OUT_RI1(R0, 4), // +4 = 0x0B - IRQs enabled, RTS/DSR set {UDI_PIO_END, UDI_PIO_2BYTE, 0} }; // // Transmit // udi_pio_trans_t uart_pio_tx[] = { + // while( (inb(SERIAL_PORT + 5) & 0x20) == 0 ); + // outb(SERIAL_PORT, ch); + + // R0: Temp + // R1: Byte to write + // R2: Buffer size + // R3: Position + {UDI_PIO_LOAD_IMM+UDI_PIO_DIRECT+UDI_PIO_R3, UDI_PIO_2BYTE, 0}, + {UDI_PIO_LOAD_IMM+UDI_PIO_DIRECT+UDI_PIO_R0, UDI_PIO_2BYTE, 0}, + {UDI_PIO_LOAD+UDI_PIO_MEM+UDI_PIO_R0, UDI_PIO_4BYTE, UDI_PIO_R2}, + + {UDI_PIO_LABEL, 0, 1}, // Loop top + + {UDI_PIO_STORE+UDI_PIO_DIRECT+UDI_PIO_R0, UDI_PIO_2BYTE, UDI_PIO_R3}, + //PIO_op_RI(LOAD, R0, 2, UDI_PIO_R3), + PIO_op_RI(SUB, R0, 2, UDI_PIO_R2), + {UDI_PIO_CSKIP+UDI_PIO_R0, UDI_PIO_1BYTE, UDI_PIO_NZ}, + {UDI_PIO_BRANCH, 0, 3}, + + // Load byte into R1 (and increment R3) + {UDI_PIO_LOAD+UDI_PIO_BUF+UDI_PIO_R3, UDI_PIO_1BYTE, UDI_PIO_R1}, + PIO_op_RI(ADD_IMM, R3, 2, 1), + + // TX single byte from R1 + // - Wait for FIFO to clear + // while( (inb(SERIAL_PORT + 5) & 0x20) == 0 ); + {UDI_PIO_LABEL, 0, 2}, + PIO_IN_RI1(R0, 5), + PIO_op_RI(AND_IMM, R0, 1, 0x20), + {UDI_PIO_CSKIP+UDI_PIO_R0, UDI_PIO_1BYTE, UDI_PIO_NZ}, + {UDI_PIO_BRANCH, 0, 2}, + // - TX + // outb(SERIAL_PORT, ch); + PIO_OUT_RI1(R1, 0), + {UDI_PIO_BRANCH, 0, 1}, + + // Done + {UDI_PIO_LABEL, 0, 3}, {UDI_PIO_END, UDI_PIO_2BYTE, 0} }; // // Recieve (interrupt) // -udi_pio_trans_t uart_pio_rx[] = { - {UDI_PIO_END, UDI_PIO_2BYTE, 0} +udi_pio_trans_t uart_pio_intr[] = { + // 0: Enable interrupts + PIO_MOV_RI1(R0, 0x09), + PIO_OUT_RI1(R0, 1), // +1 = EDSSI (Delta Line status), ELSI (Line Status), ERBFI (Rx Full) + {UDI_PIO_END, UDI_PIO_2BYTE, 0}, + // 1: Interrupt + // - Check if the interrupt was for this device, + // if so rx into buffer and return byte count + // return inb(SERIAL_PORT); + {UDI_PIO_LABEL, 0, 1}, + // if( (inb(SERIAL_PORT+5) & 0x01) == 0 ) { + PIO_IN_RI1(R0, 5), + PIO_op_RI(AND_IMM, R0, 1, 0x01), + {UDI_PIO_CSKIP+UDI_PIO_R0, UDI_PIO_1BYTE, UDI_PIO_Z}, + {UDI_PIO_BRANCH, 0, 3}, + // SetUnclaimed() + PIO_MOV_RI1(R2, 0), + PIO_MOV_RI1(R1, UDI_INTR_UNCLAIMED), + {UDI_PIO_STORE+UDI_PIO_SCRATCH+UDI_PIO_R2, UDI_PIO_1BYTE, UDI_PIO_R1}, + // return 0; + {UDI_PIO_END_IMM, UDI_PIO_2BYTE, 0}, + // } + // else { + {UDI_PIO_LABEL, 0, 3}, + // buf_ofs = 0; + PIO_MOV_RI2(R2, 0), // Buffer offset + // do { + {UDI_PIO_LABEL, 0, 4}, + // buffer[buf_ofs] = inb(SERIAL_PORT+0); + PIO_IN_RI1(R0, 0), + {UDI_PIO_STORE+UDI_PIO_BUF+UDI_PIO_R2, UDI_PIO_1BYTE, UDI_PIO_R0}, + // buf_ofs ++; + PIO_op_RI(ADD_IMM, R2, 1, 0x01), + // } while( inb(SERIAL_PORT+5) & 0x01 ); + PIO_IN_RI1(R0, 5), + PIO_op_RI(AND_IMM, R0, 1, 0x01), + {UDI_PIO_CSKIP+UDI_PIO_R0, UDI_PIO_1BYTE, UDI_PIO_Z}, + {UDI_PIO_BRANCH, 0, 4}, + // return 0; + {UDI_PIO_END, UDI_PIO_1BYTE, UDI_PIO_R2}, + // } + + // 2: Interrupt Overrun + {UDI_PIO_LABEL, 0, 2}, + PIO_MOV_RI1(R0, 0x08), // EDSSI only + PIO_OUT_RI1(R0, 1), + {UDI_PIO_END_IMM, UDI_PIO_2BYTE, 0} }; #define ARRAY_SIZEOF(arr) (sizeof(arr)/sizeof(arr[0])) @@ -31,7 +130,7 @@ struct { } uart_pio_ops[] = { [PIO_RESET] = {uart_pio_reset, ARRAY_SIZEOF(uart_pio_reset), 0}, [PIO_TX] = {uart_pio_tx, ARRAY_SIZEOF(uart_pio_tx), 0}, - [PIO_RX] = {uart_pio_rx, ARRAY_SIZEOF(uart_pio_rx), 0}, + [PIO_INTR] = {uart_pio_intr, ARRAY_SIZEOF(uart_pio_intr), 0}, }; //const int UART_NUM_PIO_OPS = ARRAY_SIZEOF(uart_pio_ops);