This is the mail archive of the ecos-patches@sourceware.org mailing list for the eCos project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

AT91 DCC driver


Hi Folks

A couple of weekends ago i could not find the serial cable for my AT91
device. So i set too and wrote a DCC driver. DCC, or Debug
Communications Channel is part of the JTAG core of most ARM
processors. It allows the CPU to exchange bytes with the host over the
JTAG interface. Some JTAG devices make these bytes available via a TCP
socket which you can telnet to. So you end up with a virtual "serial"
port over the JTAG connector. This is useful when all your serial
ports are being used for connecting to peripherals, or as in my case,
you have lost the serial cable.

The code provides a HAL diag driver. It is not possible to use DCC as
a full interrupt driver serial device because there is no interrupt to
indicate a byte is available. You have to poll. But this fits the HAL
driver model well. The code has been tested on an AT91SAM7S but i
expect it to wok on all AT91SAM devices. I only tested output, ie
diag_printf(). There is code to also read from DCC, but i've not
tested.

The code is pretty generic. It should be very easy to port it to other
ARM devices which support DCC.

    Andrew
Index: hal/arm/at91/var/current/ChangeLog
===================================================================
RCS file: /cvs/ecos/ecos/packages/hal/arm/at91/var/current/ChangeLog,v
retrieving revision 1.40
diff -u -r1.40 ChangeLog
--- hal/arm/at91/var/current/ChangeLog	5 Mar 2007 17:04:02 -0000	1.40
+++ hal/arm/at91/var/current/ChangeLog	12 Jul 2008 13:07:54 -0000
@@ -1,3 +1,15 @@
+2008-07-12  Andrew Lunn  <andrew.lunn@ascom.ch>
+
+	* src/hal_diag_dcc.{ch}
+	* src/hal_diag.c
+	* src/hal_diag_dbg.c
+	* cdl/hal_arm_at91.cdl: Add support for DCC, ie the Debug
+	Communications Channel, which is part of JTAG core of AT91 and
+	most ARM processors. JTAG devices often make this available via a
+	TCP port which can be accessed via telnet. NOTE: Only output to
+	DCC has been tested via diag_printf. Code exists for input, but it
+	has not been tested.
+	
 2007-03-05  Andrew Lunn <andrew.lunn@ascom.ch>
 
 	* include/var_io.h: Fix a few typos pointed out by
Index: hal/arm/at91/var/current/cdl/hal_arm_at91.cdl
===================================================================
RCS file: /cvs/ecos/ecos/packages/hal/arm/at91/var/current/cdl/hal_arm_at91.cdl,v
retrieving revision 1.10
diff -u -r1.10 hal_arm_at91.cdl
--- hal/arm/at91/var/current/cdl/hal_arm_at91.cdl	19 Feb 2006 19:08:28 -0000	1.10
+++ hal/arm/at91/var/current/cdl/hal_arm_at91.cdl	12 Jul 2008 13:07:54 -0000
@@ -169,4 +169,27 @@
             The driver for using the UARTS will be compiled in the
             varient HAL when this option is enabled."
     }
-}
+
+    cdl_component CYGBLD_HAL_ARM_AT91_DCC {
+        display       "Enable the use of the DCC for debug output"
+        flavor        bool
+        default_value 0
+        compile       hal_diag_dcc.c
+        description   "
+            A <serial> driver will be compiled and inserted into the
+            vector table which does I/O via the DCC. The DCC is part of
+            the JTAG interface and some JTAG devices made this interface
+            available via telnet etc."
+        
+        cdl_option CYGBLD_HAL_ARM_AT91_DCC_CHANNEL {   
+            display       "Channel the DCC port should use in the VV table"
+            flavor        data
+            default_value 2
+            description   "
+                The DCC driver has to be registered in the VV table of
+                drivers. This option determines which entry in the
+                table it will take. The default value will overwride
+                the first serial port. "
+        }
+    }
+}
\ No newline at end of file
Index: hal/arm/at91/var/current/src/hal_diag.c
===================================================================
RCS file: /cvs/ecos/ecos/packages/hal/arm/at91/var/current/src/hal_diag.c,v
retrieving revision 1.6
diff -u -r1.6 hal_diag.c
--- hal/arm/at91/var/current/src/hal_diag.c	13 Mar 2006 07:47:23 -0000	1.6
+++ hal/arm/at91/var/current/src/hal_diag.c	12 Jul 2008 13:07:54 -0000
@@ -65,6 +65,7 @@
 
 #include <cyg/hal/var_io.h>             // USART registers
 
+#include "hal_diag_dcc.h"               // DCC initialization file
 //-----------------------------------------------------------------------------
 typedef struct {
     cyg_uint8* base;
@@ -357,6 +358,10 @@
     initialized = 1;
 
     cyg_hal_plf_serial_init();
+
+#ifdef CYGBLD_HAL_ARM_AT91_DCC
+    cyg_hal_plf_dcc_init(CYGBLD_HAL_ARM_AT91_DCC_CHANNEL);
+#endif
 }
 
 void
Index: hal/arm/at91/var/current/src/hal_diag_dbg.c
===================================================================
RCS file: /cvs/ecos/ecos/packages/hal/arm/at91/var/current/src/hal_diag_dbg.c,v
retrieving revision 1.1
diff -u -r1.1 hal_diag_dbg.c
--- hal/arm/at91/var/current/src/hal_diag_dbg.c	19 Feb 2006 19:08:28 -0000	1.1
+++ hal/arm/at91/var/current/src/hal_diag_dbg.c	12 Jul 2008 13:07:55 -0000
@@ -66,6 +66,7 @@
 
 #include <cyg/hal/var_io.h>             // Device registers
 
+#include "hal_diag_dcc.h"               // DCC initialization file
 //-----------------------------------------------------------------------------
 typedef struct {
     cyg_uint8* base;
@@ -331,6 +332,10 @@
     initialized = 1;
 
     cyg_hal_plf_serial_init();
+
+#ifdef CYGBLD_HAL_ARM_AT91_DCC
+    cyg_hal_plf_dcc_init(CYGBLD_HAL_ARM_AT91_DCC_CHANNEL);
+#endif
 }
 
 void
Index: hal/arm/at91/var/current/src/hal_diag_dcc.c
===================================================================
RCS file: hal/arm/at91/var/current/src/hal_diag_dcc.c
diff -N hal/arm/at91/var/current/src/hal_diag_dcc.c
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ hal/arm/at91/var/current/src/hal_diag_dcc.c	12 Jul 2008 13:07:55 -0000
@@ -0,0 +1,211 @@
+/*=============================================================================
+//
+//      hal_diag_dcc.c
+//
+//      HAL diagnostic output via the DCC interface.
+//
+//=============================================================================
+//####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
+// Copyright (C) 2008 FSF
+//
+// 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####
+//
+// Author(s):   Andrew Lunn
+// Contributors:jskov, gthomas
+// Date:        2008-06-15
+// Purpose:     HAL diagnostic output via DCC.
+// Description: Implementations of HAL diagnostic output support.
+//
+//####DESCRIPTIONEND####
+//
+//===========================================================================*/
+
+#include <pkgconf/hal.h>
+#include CYGBLD_HAL_PLATFORM_H
+
+#include <cyg/infra/cyg_type.h>         // base types
+
+#include <cyg/hal/hal_arch.h>           // SAVE/RESTORE GP macros
+#include <cyg/hal/hal_io.h>             // IO macros
+#include <cyg/hal/hal_if.h>             // interface API
+#include <cyg/hal/hal_intr.h>           // HAL_ENABLE/MASK/UNMASK_INTERRUPTS
+#include <cyg/hal/hal_misc.h>           // Helper functions
+#include <cyg/hal/hal_diag.h>
+
+#define DCC_TX_BUSY 2
+#define DCC_RX_READY 1
+
+//-----------------------------------------------------------------------------
+
+static void
+cyg_hal_plf_dcc_putc(void * __ch_data, char ch)
+{
+  unsigned int status;
+  CYG_UNUSED_PARAM(void *, __ch_data);
+
+  CYGARC_HAL_SAVE_GP();
+  
+  do {
+    __asm__ volatile ( "mrc p14,0, %0, c0, c0\n" : "=r" (status));
+  } while ( status & DCC_TX_BUSY );
+  __asm__( "mcr p14,0, %0, c1, c0\n" : : "r" (ch));
+  
+  CYGARC_HAL_RESTORE_GP();
+}
+
+static cyg_bool
+cyg_hal_plf_dcc_getc_nonblock(cyg_uint8* ch)
+{
+  cyg_uint32 status;
+  cyg_uint32 c;
+  
+  __asm__( "mrc p14,0, %0, c0, c0\n" : "=r" (status));
+  
+  if (status & DCC_RX_READY) {
+    __asm__( "mrc p14,0, %0, c1, c0\n" : "=r" (c));
+    *ch = (char )c;
+    return true;
+  } else 
+    return false;
+}
+
+static cyg_uint8
+cyg_hal_plf_dcc_getc(void* __ch_data)
+{
+  cyg_uint8 ch;
+  CYG_UNUSED_PARAM(void *, __ch_data);
+  CYGARC_HAL_SAVE_GP();
+  
+  while(!cyg_hal_plf_dcc_getc_nonblock(&ch));
+  
+  CYGARC_HAL_RESTORE_GP();
+  return ch;
+}
+
+static void
+cyg_hal_plf_dcc_write(void* __ch_data, const cyg_uint8* __buf, 
+                      cyg_uint32 __len)
+{
+  CYG_UNUSED_PARAM(void *, __ch_data);
+  CYGARC_HAL_SAVE_GP();
+  
+  while(__len-- > 0)
+    cyg_hal_plf_dcc_putc(NULL, *__buf++);
+  
+  CYGARC_HAL_RESTORE_GP();
+}
+
+static void
+cyg_hal_plf_dcc_read(void* __ch_data, cyg_uint8* __buf, cyg_uint32 __len)
+{
+  CYG_UNUSED_PARAM(void *, __ch_data);
+  CYGARC_HAL_SAVE_GP();
+  
+  while(__len-- > 0)
+    *__buf++ = cyg_hal_plf_dcc_getc(NULL);
+  
+  CYGARC_HAL_RESTORE_GP();
+}
+
+static cyg_bool
+cyg_hal_plf_dcc_getc_timeout(void* __ch_data, cyg_uint8* ch)
+{
+  int delay_count;
+  cyg_bool res;
+  CYG_UNUSED_PARAM(void *, __ch_data);
+
+  CYGARC_HAL_SAVE_GP();
+
+  delay_count = 100010; // delay in .1 ms steps
+
+  for(;;) {
+    res = cyg_hal_plf_dcc_getc_nonblock(ch);
+    if (res || 0 == delay_count--)
+      break;
+    
+    CYGACC_CALL_IF_DELAY_US(100);
+  }
+  
+  CYGARC_HAL_RESTORE_GP();
+  return res;
+}
+
+static int
+cyg_hal_plf_dcc_control(void *__ch_data, __comm_control_cmd_t __func, ...)
+{
+  CYG_UNUSED_PARAM(void *, __ch_data);
+  CYG_UNUSED_PARAM(__comm_control_cmd_t, __func);
+  
+  return 0;
+}
+
+static void
+cyg_hal_plf_dcc_register(const int channel)
+{
+  hal_virtual_comm_table_t* comm;
+  int cur;
+  
+  cur = CYGACC_CALL_IF_SET_CONSOLE_COMM(CYGNUM_CALL_IF_SET_COMM_ID_QUERY_CURRENT);
+  // Setup procs in the vector table
+  
+  CYGACC_CALL_IF_SET_CONSOLE_COMM(channel);
+  comm = CYGACC_CALL_IF_CONSOLE_PROCS();
+  CYGACC_COMM_IF_CH_DATA_SET(*comm, NULL);
+  CYGACC_COMM_IF_WRITE_SET(*comm, cyg_hal_plf_dcc_write);
+  CYGACC_COMM_IF_READ_SET(*comm, cyg_hal_plf_dcc_read);
+  CYGACC_COMM_IF_PUTC_SET(*comm, cyg_hal_plf_dcc_putc);
+  CYGACC_COMM_IF_GETC_SET(*comm, cyg_hal_plf_dcc_getc);
+  CYGACC_COMM_IF_CONTROL_SET(*comm, cyg_hal_plf_dcc_control);
+  CYGACC_COMM_IF_DBG_ISR_SET(*comm, NULL);
+  CYGACC_COMM_IF_GETC_TIMEOUT_SET(*comm, cyg_hal_plf_dcc_getc_timeout);
+
+  // Restore to original console.
+  CYGACC_CALL_IF_SET_CONSOLE_COMM(cur);
+}
+
+void
+cyg_hal_plf_dcc_init(const int channel)
+{
+  static int initialized = 0;
+  
+  if (initialized)
+    return;
+  
+  initialized = 1;
+  
+  cyg_hal_plf_dcc_register(channel);
+}
+
+//-----------------------------------------------------------------------------
+// End of hal_diag_dcc.c
Index: hal/arm/at91/var/current/src/hal_diag_dcc.h
===================================================================
RCS file: hal/arm/at91/var/current/src/hal_diag_dcc.h
diff -N hal/arm/at91/var/current/src/hal_diag_dcc.h
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ hal/arm/at91/var/current/src/hal_diag_dcc.h	12 Jul 2008 13:07:55 -0000
@@ -0,0 +1,60 @@
+#ifndef CYGONCE_HAL_DIAG_DCC_H
+#define CYGONCE_HAL_DIAG_DCC_H
+
+//=============================================================================
+//
+//      hal_diag_dcc.h
+//
+//      HAL Support for Kernel Diagnostic Routines via DCC
+//
+//=============================================================================
+//####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 2008 FSF.
+//
+// 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####
+//
+// Author(s):   asl
+// Contributors:
+// Date:        2008-06-15
+// Purpose:     HAL Support for Kernel Diagnostic Routines via DCC.
+// Description: Diagnostic routines for use during kernel development.
+// Usage:       #include "hal_diag_dcc.h"
+//
+//####DESCRIPTIONEND####
+//
+//=============================================================================
+
+externC void cyg_hal_plf_dcc_init(const int channel);
+
+#endif
+

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]