From: John Hodge Date: Mon, 3 Feb 2014 02:23:27 +0000 (+0800) Subject: UDI/16c550 - TX working, RX in progress X-Git-Url: https://git.ucc.asn.au/?a=commitdiff_plain;h=5b80adc9ea328e519329ba299fcf8ffe0daf2704;p=tpg%2Facess2.git UDI/16c550 - TX working, RX in progress --- diff --git a/UDI/drivers/uart_16c550/uart16c550.c b/UDI/drivers/uart_16c550/uart16c550.c index 62b3de80..c67c8833 100644 --- a/UDI/drivers/uart_16c550/uart16c550.c +++ b/UDI/drivers/uart_16c550/uart16c550.c @@ -141,8 +141,8 @@ void uart_bus_dev_bind__pio_map(udi_cb_t *gcb, udi_pio_handle_t new_pio_handle) } udi_intr_attach_cb_t *intr_cb = UDI_MCB(new_cb, udi_intr_attach_cb_t); intr_cb->interrupt_idx = 0; - intr_cb->min_event_pend = 2; - intr_cb->preprocessing_handle = rdata->pio_handles[PIO_RX]; + intr_cb->min_event_pend = 1; + intr_cb->preprocessing_handle = rdata->pio_handles[PIO_INTR]; // Attach interrupt udi_intr_attach_req(intr_cb); @@ -153,6 +153,20 @@ void uart_bus_dev_bus_unbind_ack(udi_bus_bind_cb_t *cb) } void uart_bus_dev_intr_attach_ack(udi_intr_attach_cb_t *intr_attach_cb, udi_status_t status) { + udi_cb_t *gcb = UDI_GCB(intr_attach_cb); + rdata_t *rdata = gcb->context; + + // TODO: Allocate interrupt cbs + CONTIN(uart_bus_dev_intr_attach_ack, udi_cb_alloc, (UART_CB_INTR_EVENT, rdata->interrupt_channel), + (udi_cb_t *new_cb)) + + udi_intr_event_cb_t *cb = UDI_MCB(new_cb, udi_intr_event_cb_t); + udi_intr_event_rdy(cb); + + udi_channel_event_cb_t *channel_cb = UDI_MCB(rdata->active_cb, udi_channel_event_cb_t); + + udi_channel_event_complete(channel_cb, UDI_OK); + // = = = = = } void uart_bus_dev_intr_detach_ack(udi_intr_detach_cb_t *intr_detach_cb) { diff --git a/UDI/drivers/uart_16c550/uart16c550_common.h b/UDI/drivers/uart_16c550/uart16c550_common.h index 5b91bf5c..864f461b 100644 --- a/UDI/drivers/uart_16c550/uart16c550_common.h +++ b/UDI/drivers/uart_16c550/uart16c550_common.h @@ -16,13 +16,15 @@ enum { enum { PIO_RESET, PIO_TX, - PIO_RX, + PIO_INTR, N_PIO }; #define RX_BUFFER_SIZE 32 typedef struct { + udi_init_context_t init_context; + udi_cb_t *active_cb; struct { udi_index_t pio_index; diff --git a/UDI/drivers/uart_16c550/uart16c550_pio.h b/UDI/drivers/uart_16c550/uart16c550_pio.h index db9998d1..850cb81d 100644 --- a/UDI/drivers/uart_16c550/uart16c550_pio.h +++ b/UDI/drivers/uart_16c550/uart16c550_pio.h @@ -1,6 +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_RI2(reg, val) PIO_op_RI(LOAD_IMM, reg, 2, val) -#define PIO_MOV_RI1(reg, val) PIO_op_RI(LOAD_IMM, reg, 1, 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) @@ -38,14 +38,16 @@ udi_pio_trans_t uart_pio_tx[] = { // 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 - - PIO_op_RI(LOAD, R0, 2, UDI_PIO_R3), + + {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_Z}, + {UDI_PIO_CSKIP+UDI_PIO_R0, UDI_PIO_1BYTE, UDI_PIO_NZ}, {UDI_PIO_BRANCH, 0, 3}, // Load byte into R1 (and increment R3) @@ -54,14 +56,16 @@ udi_pio_trans_t uart_pio_tx[] = { // 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), - {UDI_PIO_AND_IMM+UDI_PIO_DIRECT+UDI_PIO_DIRECT, UDI_PIO_1BYTE, 0x20}, - {UDI_PIO_CSKIP+UDI_PIO_R0, UDI_PIO_1BYTE, UDI_PIO_Z}, - {UDI_PIO_BRANCH, 0, 1}, + 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, 2}, + {UDI_PIO_BRANCH, 0, 1}, // Done {UDI_PIO_LABEL, 0, 3}, @@ -70,10 +74,25 @@ udi_pio_trans_t uart_pio_tx[] = { // // Recieve (interrupt) // -udi_pio_trans_t uart_pio_rx[] = { +udi_pio_trans_t uart_pio_intr[] = { + // 0: Enable interrupts + {UDI_PIO_END, UDI_PIO_2BYTE, 0}, + // 1: Interrupt // if( (inb(SERIAL_PORT+5) & 0x01) == 0 ) // return -1; // return inb(SERIAL_PORT); + {UDI_PIO_LABEL, 0, 1}, + 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_END, UDI_PIO_2BYTE, 0}, + 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}, + {UDI_PIO_END, UDI_PIO_2BYTE, 0}, + + // 2: Interrupt Overrun + {UDI_PIO_LABEL, 0, 2}, {UDI_PIO_END, UDI_PIO_2BYTE, 0} }; @@ -86,7 +105,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); diff --git a/UDI/drivers/uart_16c550/udiprops.txt b/UDI/drivers/uart_16c550/udiprops.txt index 714977c0..7fb8577b 100644 --- a/UDI/drivers/uart_16c550/udiprops.txt +++ b/UDI/drivers/uart_16c550/udiprops.txt @@ -18,7 +18,8 @@ meta 1 udi_bridge meta 2 udi_gio parent_bind_ops 1 0 1 1 # bridge metalang, rgn 0, ops 1, cb 1 -child_bind_ops 2 0 2 # GIO metalang, rgn 0, ops 2 +# Ops 2 is interrupt handler +child_bind_ops 2 0 3 # GIO metalang, rgn 0, ops 3 # PC Serial Port device 101 1 bus_type string system sysbus_io_addr_lo ubit32 0x3F8 sysbus_io_size ubit32 16 sysbus_intr0 ubit32 4 @@ -26,9 +27,13 @@ message 101 PC Serial (COM1) device 102 1 bus_type string system sysbus_io_addr_lo ubit32 0x2F8 sysbus_io_size ubit32 16 sysbus_intr0 ubit32 3 message 102 PC Serial (COM2) +# Generic XT-Compatible Serial Controller +device 103 1 bus_type string pci pci_baseclass ubit32 0x07 pci_sub_class ubit32 0x00 pci_prog_if ubit32 0x00 +message 103 Generic XT-Compatible Serial Controller + # PCI 16550 compatibles -device 103 1 bus_type string pci pci_baseclass ubit32 0x07 pci_sub_class ubit32 0x00 pci_prog_if ubit32 0x02 -message 103 PCI 16550 Compatible +device 104 1 bus_type string pci pci_baseclass ubit32 0x07 pci_sub_class ubit32 0x00 pci_prog_if ubit32 0x02 +message 104 PCI 16550 Compatible module uart16c550 region 0