diff packages/hal/common/current/src/hal_if.c @ 208:e0c0827131d1 ecos

Merge from eCos master repository on 2002-05-20-20:11:54-BST
author jlarmour
date Mon, 20 May 2002 22:19:26 +0000
parents 678094f34118
children d2c90368aeef
line wrap: on
line diff
--- a/packages/hal/common/current/src/hal_if.c
+++ b/packages/hal/common/current/src/hal_if.c
@@ -5,29 +5,38 @@
 //      ROM/RAM interfacing functions
 //
 //=============================================================================
-//####COPYRIGHTBEGIN####
-//                                                                          
-// -------------------------------------------                              
-// The contents of this file are subject to the Red Hat eCos Public License 
-// Version 1.1 (the "License"); you may not use this file except in         
-// compliance with the License.  You may obtain a copy of the License at    
-// http://www.redhat.com/                                                   
-//                                                                          
-// Software distributed under the License is distributed on an "AS IS"      
-// basis, WITHOUT WARRANTY OF ANY KIND, either express or implied.  See the 
-// License for the specific language governing rights and limitations under 
-// the License.                                                             
-//                                                                          
-// The Original Code is eCos - Embedded Configurable Operating System,      
-// released September 30, 1998.                                             
-//                                                                          
-// The Initial Developer of the Original Code is Red Hat.                   
-// Portions created by Red Hat are                                          
-// Copyright (C) 1998, 1999, 2000, 2001 Red Hat, Inc.
-// All Rights Reserved.                                                     
-// -------------------------------------------                              
-//                                                                          
-//####COPYRIGHTEND####
+//####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
+//
+// eCos is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 2 or (at your option) any later version.
+//
+// eCos is distributed in the hope that it will be useful, but WITHOUT ANY
+// WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with eCos; if not, write to the Free Software Foundation, Inc.,
+// 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+//
+// As a special exception, if other files instantiate templates or use macros
+// or inline functions from this file, or you compile this file and link it
+// with other works to produce a work based on this file, this file does not
+// by itself cause the resulting work to be covered by the GNU General Public
+// License. However the source code for this file must still be made available
+// in accordance with section (3) of the GNU General Public License.
+//
+// This exception does not invalidate any other reasons why a work based on
+// this file might be covered by the GNU General Public License.
+//
+// Alternative licenses for eCos may be arranged by contacting Red Hat, Inc.
+// at http://sources.redhat.com/ecos/ecos-license
+// -------------------------------------------
+//####ECOSGPLCOPYRIGHTEND####
 //=============================================================================
 //#####DESCRIPTIONBEGIN####
 //
@@ -393,11 +402,91 @@ cyg_hal_diag_mangler_gdb_getc(void* __ch
     return __ch;
 }
 
+static char __mangler_line[100];
+static int  __mangler_pos = 0;
+
+static void
+cyg_hal_diag_mangler_gdb_flush(void* __ch_data)
+{
+    CYG_INTERRUPT_STATE old;
+    hal_virtual_comm_table_t* __chan = CYGACC_CALL_IF_DEBUG_PROCS();
+
+    // Nothing to do if mangler buffer is empty.
+    if (__mangler_pos == 0)
+        return;
+
+    // Disable interrupts. This prevents GDB trying to interrupt us
+    // while we are in the middle of sending a packet. The serial
+    // receive interrupt will be seen when we re-enable interrupts
+    // later.
+#if defined(CYG_HAL_STARTUP_ROM) \
+    || !defined(CYG_HAL_GDB_ENTER_CRITICAL_IO_REGION)
+    HAL_DISABLE_INTERRUPTS(old);
+#else
+    CYG_HAL_GDB_ENTER_CRITICAL_IO_REGION(old);
+#endif
+        
+#if CYGNUM_HAL_DEBUG_GDB_PROTOCOL_RETRIES != 0
+    // Only wait 500ms for data to arrive - avoid "stuck" connections
+    CYGACC_COMM_IF_CONTROL(*__chan, __COMMCTL_SET_TIMEOUT, CYGNUM_HAL_DEBUG_GDB_PROTOCOL_TIMEOUT);
+#endif
+
+    while(1)
+    {
+	static const char hex[] = "0123456789ABCDEF";
+	cyg_uint8 csum = 0, c1;
+	int i;
+        
+	CYGACC_COMM_IF_PUTC(*__chan, '$');
+	CYGACC_COMM_IF_PUTC(*__chan, 'O');
+	csum += 'O';
+	for( i = 0; i < __mangler_pos; i++ )
+        {
+	    char ch = __mangler_line[i];
+	    char h = hex[(ch>>4)&0xF];
+	    char l = hex[ch&0xF];
+	    CYGACC_COMM_IF_PUTC(*__chan, h);
+	    CYGACC_COMM_IF_PUTC(*__chan, l);
+	    csum += h;
+	    csum += l;
+	}
+	CYGACC_COMM_IF_PUTC(*__chan, '#');
+	CYGACC_COMM_IF_PUTC(*__chan, hex[(csum>>4)&0xF]);
+	CYGACC_COMM_IF_PUTC(*__chan, hex[csum&0xF]);
+
+    nak:
+#if CYGNUM_HAL_DEBUG_GDB_PROTOCOL_RETRIES != 0
+	if (CYGACC_COMM_IF_GETC_TIMEOUT(*__chan, &c1) == 0) {
+	    c1 = '-';
+	    if (tries && (--tries == 0)) c1 = '+';
+	}
+#else
+	c1 = CYGACC_COMM_IF_GETC(*__chan);
+#endif
+
+	if( c1 == '+' ) break;
+
+	if( cyg_hal_is_break( &c1 , 1 ) ) {
+	    // Caller's responsibility to react on this.
+	    CYGACC_CALL_IF_CONSOLE_INTERRUPT_FLAG_SET(1);
+	    break;
+	}
+	if( c1 != '-' ) goto nak;
+    }
+
+    __mangler_pos = 0;
+    // And re-enable interrupts
+#if defined(CYG_HAL_STARTUP_ROM) \
+    || !defined(CYG_HAL_GDB_ENTER_CRITICAL_IO_REGION)
+    HAL_RESTORE_INTERRUPTS(old);
+#else
+    CYG_HAL_GDB_LEAVE_CRITICAL_IO_REGION(old);
+#endif
+}
+
 static void
 cyg_hal_diag_mangler_gdb_putc(void* __ch_data, cyg_uint8 c)
 {
-    static char line[100];
-    static int pos = 0;
 #if CYGNUM_HAL_DEBUG_GDB_PROTOCOL_RETRIES != 0
     int tries = CYGNUM_HAL_DEBUG_GDB_PROTOCOL_RETRIES;
 #endif
@@ -407,81 +496,10 @@ cyg_hal_diag_mangler_gdb_putc(void* __ch
 
     CYGARC_HAL_SAVE_GP();
 
-    line[pos++] = c;
-
-    if( c == '\n' || pos == sizeof(line) )
-    {
-        CYG_INTERRUPT_STATE old;
-        hal_virtual_comm_table_t* __chan = CYGACC_CALL_IF_DEBUG_PROCS();
-
-        // Disable interrupts. This prevents GDB trying to interrupt us
-        // while we are in the middle of sending a packet. The serial
-        // receive interrupt will be seen when we re-enable interrupts
-        // later.
-#if defined(CYG_HAL_STARTUP_ROM) \
-    || !defined(CYG_HAL_GDB_ENTER_CRITICAL_IO_REGION)
-        HAL_DISABLE_INTERRUPTS(old);
-#else
-        CYG_HAL_GDB_ENTER_CRITICAL_IO_REGION(old);
-#endif
-        
-#if CYGNUM_HAL_DEBUG_GDB_PROTOCOL_RETRIES != 0
-        // Only wait 500ms for data to arrive - avoid "stuck" connections
-        CYGACC_COMM_IF_CONTROL(*__chan, __COMMCTL_SET_TIMEOUT, CYGNUM_HAL_DEBUG_GDB_PROTOCOL_TIMEOUT);
-#endif
+    __mangler_line[__mangler_pos++] = c;
 
-        while(1)
-        {
-            static const char hex[] = "0123456789ABCDEF";
-            cyg_uint8 csum = 0, c1;
-            int i;
-        
-            CYGACC_COMM_IF_PUTC(*__chan, '$');
-            CYGACC_COMM_IF_PUTC(*__chan, 'O');
-            csum += 'O';
-            for( i = 0; i < pos; i++ )
-            {
-                char ch = line[i];
-                char h = hex[(ch>>4)&0xF];
-                char l = hex[ch&0xF];
-                CYGACC_COMM_IF_PUTC(*__chan, h);
-                CYGACC_COMM_IF_PUTC(*__chan, l);
-                csum += h;
-                csum += l;
-            }
-            CYGACC_COMM_IF_PUTC(*__chan, '#');
-            CYGACC_COMM_IF_PUTC(*__chan, hex[(csum>>4)&0xF]);
-            CYGACC_COMM_IF_PUTC(*__chan, hex[csum&0xF]);
-
-        nak:
-#if CYGNUM_HAL_DEBUG_GDB_PROTOCOL_RETRIES != 0
-            if (CYGACC_COMM_IF_GETC_TIMEOUT(*__chan, &c1) == 0) {
-                c1 = '-';
-                if (tries && (--tries == 0)) c1 = '+';
-            }
-#else
-            c1 = CYGACC_COMM_IF_GETC(*__chan);
-#endif
-
-            if( c1 == '+' ) break;
-
-            if( cyg_hal_is_break( &c1 , 1 ) ) {
-                // Caller's responsibility to react on this.
-                CYGACC_CALL_IF_CONSOLE_INTERRUPT_FLAG_SET(1);
-                break;
-            }
-            if( c1 != '-' ) goto nak;
-        }
-
-        pos = 0;
-        // And re-enable interrupts
-#if defined(CYG_HAL_STARTUP_ROM) \
-    || !defined(CYG_HAL_GDB_ENTER_CRITICAL_IO_REGION)
-        HAL_RESTORE_INTERRUPTS(old);
-#else
-        CYG_HAL_GDB_LEAVE_CRITICAL_IO_REGION(old);
-#endif
-    }
+    if( c == '\n' || __mangler_pos == sizeof(__mangler_line) )
+	cyg_hal_diag_mangler_gdb_flush(__ch_data);
 
     CYGARC_HAL_RESTORE_GP();
 }
@@ -514,7 +532,12 @@ static int
 cyg_hal_diag_mangler_gdb_control(void *__ch_data, 
                                  __comm_control_cmd_t __func, ...)
 {
-    // Do nothing (yet).
+    CYGARC_HAL_SAVE_GP();
+
+    if (__func == __COMMCTL_FLUSH_OUTPUT)
+	cyg_hal_diag_mangler_gdb_flush(__ch_data);
+
+    CYGARC_HAL_RESTORE_GP();
     return 0;
 }