diff packages/hal/arm/ebsa285/current/src/hal_diag.c @ 110:84e4bde58b26 ecos-sw-2000-07-14

Merge from eCos master repository on 2000-07-14-22:00:02-BST
author jlarmour
date Mon, 17 Jul 2000 14:42:27 +0000
parents 435cced73e2f
children 02ea4320376c
line wrap: on
line diff
--- a/packages/hal/arm/ebsa285/current/src/hal_diag.c
+++ b/packages/hal/arm/ebsa285/current/src/hal_diag.c
@@ -52,12 +52,273 @@
 #include <cyg/hal/hal_arch.h>           // basic machine info
 #include <cyg/hal/hal_intr.h>           // interrupt macros
 #include <cyg/hal/hal_io.h>             // IO macros
+#include <cyg/hal/hal_if.h>             // calling interface API
+#include <cyg/hal/hal_misc.h>           // helper functions
 #include <cyg/hal/hal_diag.h>
+#include <cyg/hal/hal_ebsa285.h>        // Hardware definitions
+#include <cyg/hal/drv_api.h>            // cyg_drv_interrupt_acknowledge
+
+/*---------------------------------------------------------------------------*/
+
+struct ebsa_serial {
+  volatile cyg_uint32 data_register;
+  volatile cyg_uint32 rxstat;
+  volatile cyg_uint32 h_baud_control;
+  volatile cyg_uint32 m_baud_control;
+  volatile cyg_uint32 l_baud_control;
+  volatile cyg_uint32 control_register;
+  volatile cyg_uint32 flag_register;
+};
+
+/*---------------------------------------------------------------------------*/
+
+static void
+init_channel(void* __ch_data)
+{
+    volatile struct ebsa_serial* base = (struct ebsa_serial*)__ch_data;
+
+    int dummy;
+    /*
+     * Make sure everything is off
+     */
+    base->control_register = SA110_UART_DISABLED | SA110_SIR_DISABLED;
+    
+    /*
+     * Read the RXStat to drain the fifo
+     */
+    dummy = base->rxstat;
+
+    /*
+     * Set the baud rate - this also turns the uart on.
+     *
+     * Note that the ordering of these writes is critical,
+     * and the writes to the H_BAUD_CONTROL and CONTROL_REGISTER
+     * are necessary to force the UART to update its register
+     * contents.
+     */
+    base->l_baud_control   = 0x13; // bp->divisor_low;
+    base->m_baud_control   = 0x00; // bp->divisor_high;
+    base->h_baud_control = SA110_UART_BREAK_DISABLED    |
+        SA110_UART_PARITY_DISABLED   |
+        SA110_UART_STOP_BITS_ONE     |
+        SA110_UART_FIFO_ENABLED      |
+        SA110_UART_DATA_LENGTH_8_BITS;
+    base->control_register = SA110_UART_ENABLED | SA110_SIR_DISABLED;
+    // All done
+}
+
+void
+cyg_hal_plf_serial_putc(void *__ch_data, char c)
+{
+    volatile struct ebsa_serial* base = (struct ebsa_serial*)__ch_data;
+    CYGARC_HAL_SAVE_GP();
+
+    // Wait for Tx FIFO not full
+    while ((base->flag_register & SA110_TX_FIFO_STATUS_MASK) == SA110_TX_FIFO_BUSY)
+        ;
+    base->data_register = c;
+
+    CYGARC_HAL_RESTORE_GP();
+}
+
+
+static cyg_bool
+cyg_hal_plf_serial_getc_nonblock(void* __ch_data, cyg_uint8* ch)
+{
+    volatile struct ebsa_serial* base = (struct ebsa_serial*)__ch_data;
+
+
+    if ((base->flag_register & SA110_RX_FIFO_STATUS_MASK) == SA110_RX_FIFO_EMPTY)
+        return false;
+
+    *ch = (char)(base->data_register & 0xFF);
+
+    return true;
+}
+
+
+cyg_uint8
+cyg_hal_plf_serial_getc(void* __ch_data)
+{
+    cyg_uint8 ch;
+    CYGARC_HAL_SAVE_GP();
+
+    while(!cyg_hal_plf_serial_getc_nonblock(__ch_data, &ch));
+
+    CYGARC_HAL_RESTORE_GP();
+    return ch;
+}
+
+#if defined(CYGSEM_HAL_VIRTUAL_VECTOR_DIAG) \
+    || defined(CYGPRI_HAL_IMPLEMENTS_IF_SERVICES)
+
+static cyg_int32 msec_timeout;
+
+static void
+cyg_hal_plf_serial_write(void* __ch_data, const cyg_uint8* __buf, 
+                         cyg_uint32 __len)
+{
+    CYGARC_HAL_SAVE_GP();
+
+    while(__len-- > 0)
+        cyg_hal_plf_serial_putc(__ch_data, *__buf++);
+
+    CYGARC_HAL_RESTORE_GP();
+}
+
+static void
+cyg_hal_plf_serial_read(void* __ch_data, cyg_uint8* __buf, cyg_uint32 __len)
+{
+    CYGARC_HAL_SAVE_GP();
+
+    while(__len-- > 0)
+        *__buf++ = cyg_hal_plf_serial_getc(__ch_data);
+
+    CYGARC_HAL_RESTORE_GP();
+}
+
+cyg_bool
+cyg_hal_plf_serial_getc_timeout(void* __ch_data, cyg_uint8* ch)
+{
+    int delay_count;
+    cyg_bool res;
+    CYGARC_HAL_SAVE_GP();
+
+    delay_count = msec_timeout * 10; // delay in .1 ms steps
+
+    for(;;) {
+        res = cyg_hal_plf_serial_getc_nonblock(__ch_data, ch);
+        if (res || 0 == delay_count--)
+            break;
+        
+        CYGACC_CALL_IF_DELAY_US(100);
+    }
+
+    CYGARC_HAL_RESTORE_GP();
+    return res;
+}
+
+static int
+cyg_hal_plf_serial_control(void *__ch_data, __comm_control_cmd_t __func, ...)
+{
+    static int irq_state = 0;
+    int ret = 0;
+    CYGARC_HAL_SAVE_GP();
+
+    switch (__func) {
+    case __COMMCTL_IRQ_ENABLE:
+        irq_state = 1;
+
+        HAL_INTERRUPT_UNMASK(CYGNUM_HAL_INTERRUPT_SERIAL_RX);
+        break;
+    case __COMMCTL_IRQ_DISABLE:
+        ret = irq_state;
+        irq_state = 0;
+
+        HAL_INTERRUPT_MASK(CYGNUM_HAL_INTERRUPT_SERIAL_RX);
+        break;
+    case __COMMCTL_DBG_ISR_VECTOR:
+        ret = CYGNUM_HAL_INTERRUPT_SERIAL_RX;
+        break;
+    case __COMMCTL_SET_TIMEOUT:
+    {
+        va_list ap;
+
+        va_start(ap, __func);
+
+        ret = msec_timeout;
+        msec_timeout = va_arg(ap, cyg_uint32);
+
+        va_end(ap);
+    }        
+    default:
+        break;
+    }
+    CYGARC_HAL_RESTORE_GP();
+    return ret;
+}
+
+static int
+cyg_hal_plf_serial_isr(void *__ch_data, int* __ctrlc, 
+                       CYG_ADDRWORD __vector, CYG_ADDRWORD __data)
+{
+    int reg, res = 0;
+    volatile struct ebsa_serial* base = (struct ebsa_serial*)__ch_data;
+    char c;
+    CYGARC_HAL_SAVE_GP();
+
+    if ( CYGNUM_HAL_INTERRUPT_SERIAL_RX == __vector ) {
+      reg = base->flag_register;
+      // read it anyway just in case - no harm done and we might
+      // prevent an interrup loop
+      c = (char)(base->data_register & 0xFF);
+
+      cyg_drv_interrupt_acknowledge(CYGNUM_HAL_INTERRUPT_SERIAL_RX);
+      *__ctrlc = 0;
+      if ( (reg & SA110_RX_FIFO_STATUS_MASK) != SA110_RX_FIFO_EMPTY ) {
+        if( cyg_hal_is_break( &c , 1 ) )
+          *__ctrlc = 1;
+
+        res = CYG_ISR_HANDLED;
+      }
+    }
+
+    CYGARC_HAL_RESTORE_GP();
+    return res;
+}
+
+static void
+cyg_hal_plf_serial_init(void)
+{
+    hal_virtual_comm_table_t* comm;
+    int cur = CYGACC_CALL_IF_SET_CONSOLE_COMM(CYGNUM_CALL_IF_SET_COMM_ID_QUERY_CURRENT);
+
+    // Init channels
+    init_channel((void*)UART_BASE_0);
+
+    // Setup procs in the vector table
+
+    // Set channel 0
+    CYGACC_CALL_IF_SET_CONSOLE_COMM(0);
+    comm = CYGACC_CALL_IF_CONSOLE_PROCS();
+    CYGACC_COMM_IF_CH_DATA_SET(*comm, UART_BASE_0);
+    CYGACC_COMM_IF_WRITE_SET(*comm, cyg_hal_plf_serial_write);
+    CYGACC_COMM_IF_READ_SET(*comm, cyg_hal_plf_serial_read);
+    CYGACC_COMM_IF_PUTC_SET(*comm, cyg_hal_plf_serial_putc);
+    CYGACC_COMM_IF_GETC_SET(*comm, cyg_hal_plf_serial_getc);
+    CYGACC_COMM_IF_CONTROL_SET(*comm, cyg_hal_plf_serial_control);
+    CYGACC_COMM_IF_DBG_ISR_SET(*comm, cyg_hal_plf_serial_isr);
+    CYGACC_COMM_IF_GETC_TIMEOUT_SET(*comm, cyg_hal_plf_serial_getc_timeout);
+
+    // Restore original console
+    CYGACC_CALL_IF_SET_CONSOLE_COMM(cur);
+}
+
+void
+cyg_hal_plf_comms_init(void)
+{
+    static int initialized = 0;
+
+    if (initialized)
+        return;
+
+    initialized = 1;
+
+    cyg_hal_plf_serial_init();
+}
+#endif // CYGSEM_HAL_VIRTUAL_VECTOR_DIAG || CYGPRI_HAL_IMPLEMENTS_IF_SERVICES
+
+
+
+//=============================================================================
+// Compatibility with older stubs
+//=============================================================================
+
+#ifndef CYGSEM_HAL_VIRTUAL_VECTOR_DIAG
+
 #ifdef CYGDBG_HAL_DEBUG_GDB_INCLUDE_STUBS
-#include <cyg/hal/drv_api.h>            // cyg_drv_interrupt_acknowledge
 #include <cyg/hal/hal_stub.h>           // cyg_hal_gdb_interrupt
 #endif
-#include <cyg/hal/hal_ebsa285.h>        // Hardware definitions
 
 #ifdef CYGSEM_HAL_ROM_MONITOR
 #define CYG_HAL_STARTUP_ROM
@@ -71,24 +332,26 @@
 /*---------------------------------------------------------------------------*/
 // EBSA285 Serial Port (UARTx) for Debug
 
+void hal_diag_init(void)
+{
+  init_channel((void*)UART_BASE_0);
+}
+
+
 // Actually send character down the wire
 static void
 hal_diag_write_char_serial(char c)
 {
-    // Wait for Tx FIFO not full
-    while ((*SA110_UART_FLAG_REGISTER & SA110_TX_FIFO_STATUS_MASK) == SA110_TX_FIFO_BUSY)
-        ;
-    *SA110_UART_DATA_REGISTER = c;
+    cyg_hal_plf_serial_putc((void*)UART_BASE_0, c);
 }
 
 static bool
 hal_diag_read_serial(char *c)
 {
     long timeout = 1000000000;  // A long time...
-    while ((*SA110_UART_FLAG_REGISTER & SA110_RX_FIFO_STATUS_MASK) == SA110_RX_FIFO_EMPTY)
-        if ( --timeout == 0 )
-            return false;
-    *c = (char)(*SA110_UART_DATA_REGISTER & 0xFF);
+    while (! cyg_hal_plf_serial_getc_nonblock((void*)UART_BASE_0, c) )
+        if ( --timeout == 0 ) return false;
+
     return true;
 }
 
@@ -124,39 +387,6 @@ const static struct _baud bauds[] = {
 };
 #endif
 
-void hal_diag_init(void)
-{
-    int dummy;
-    /*
-     * Make sure everything is off
-     */
-    *SA110_UART_CONTROL_REGISTER = SA110_UART_DISABLED | SA110_SIR_DISABLED;
-    
-    /*
-     * Read the RXStat to drain the fifo
-     */
-    dummy = *SA110_UART_RXSTAT;
-
-    /*
-     * Set the baud rate - this also turns the uart on.
-     *
-     * Note that the ordering of these writes is critical,
-     * and the writes to the H_BAUD_CONTROL and CONTROL_REGISTER
-     * are necessary to force the UART to update its register
-     * contents.
-     */
-    *SA110_UART_L_BAUD_CONTROL   = 0x13; // bp->divisor_low;
-    *SA110_UART_M_BAUD_CONTROL   = 0x00; // bp->divisor_high;
-    *SA110_UART_H_BAUD_CONTROL = SA110_UART_BREAK_DISABLED    |
-        SA110_UART_PARITY_DISABLED   |
-        SA110_UART_STOP_BITS_ONE     |
-        SA110_UART_FIFO_ENABLED      |
-        SA110_UART_DATA_LENGTH_8_BITS;
-    *SA110_UART_CONTROL_REGISTER = SA110_UART_ENABLED | 
-        SA110_SIR_DISABLED;
-    // All done
-}
-
 #ifdef HAL_DIAG_USES_HARDWARE
 
 #ifdef DEBUG_DIAG
@@ -270,7 +500,7 @@ hal_diag_write_char(char c)
                 break;              // a good acknowledge
 
 #ifdef CYGDBG_HAL_DEBUG_GDB_BREAK_SUPPORT
-            cyg_drv_interrupt_acknowledge(CYG_DIAG_DEV_INT);
+            cyg_drv_interrupt_acknowledge(CYGNUM_HAL_INTERRUPT_SERIAL_RX);
             if( c1 == 3 ) {
                 // Ctrl-C: breakpoint.
                 cyg_hal_gdb_interrupt(
@@ -297,31 +527,7 @@ hal_diag_write_char(char c)
 }
 #endif
 
-/*---------------------------------------------------------------------------*/
-#ifndef CYGDBG_HAL_DEBUG_GDB_INCLUDE_STUBS
-#ifdef CYGDBG_HAL_DEBUG_GDB_CTRLC_SUPPORT
-// This routine is polled from the default ISR - the assumption is that any
-// other ISR installed knows what it's going and can handle a ^C correctly.
-int hal_ctrlc_isr( CYG_ADDRWORD vector, CYG_ADDRWORD data)
-{
-    char c;
-    int reg;
-    if ( CYG_DIAG_DEV_INT != vector )
-        return 0; // not for us
-
-    reg = *SA110_UART_FLAG_REGISTER;
-    // read it anyway just in case - no harm done and we might prevent an
-    // interrup loop
-    c = (char)(*SA110_UART_DATA_REGISTER & 0xFF);
-    if ( (reg & SA110_RX_FIFO_STATUS_MASK) != SA110_RX_FIFO_EMPTY ) {
-        if ( 3 == c ) {
-            HAL_BREAKPOINT( hal_ctrlc_isr_breakinst );
-        }
-    }
-    return 1;
-}
-#endif
-#endif
+#endif // !CYGSEM_HAL_VIRTUAL_VECTOR_DIAG
 
 /*---------------------------------------------------------------------------*/
 /* End of hal_diag.c */