UDI/16c550 - TX working, RX in progress
authorJohn Hodge <[email protected]>
Mon, 3 Feb 2014 02:23:27 +0000 (10:23 +0800)
committerJohn Hodge <[email protected]>
Mon, 3 Feb 2014 02:23:27 +0000 (10:23 +0800)
UDI/drivers/uart_16c550/uart16c550.c
UDI/drivers/uart_16c550/uart16c550_common.h
UDI/drivers/uart_16c550/uart16c550_pio.h
UDI/drivers/uart_16c550/udiprops.txt

index 62b3de8..c67c883 100644 (file)
@@ -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)
 {
index 5b91bf5..864f461 100644 (file)
@@ -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;
index db9998d..850cb81 100644 (file)
@@ -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);
 
index 714977c..7fb8577 100644 (file)
@@ -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

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