public inbox for ecos-patches@sourceware.org
 help / color / mirror / Atom feed
* AT91 ADC support
@ 2010-05-22  9:40 Christophe Coutand
  2010-05-27 13:42 ` John Dallaway
  0 siblings, 1 reply; 18+ messages in thread
From: Christophe Coutand @ 2010-05-22  9:40 UTC (permalink / raw)
  To: ecos-patches

[-- Attachment #1: Type: text/plain, Size: 71 bytes --]

Includes a possible ADC driver for the AT91 processors.

Christophe

[-- Attachment #2: at91 ADC driver --]
[-- Type: application/octet-stream, Size: 43165 bytes --]

# HG changeset patch
# Parent 88dcd2e87bb3d402997a851d2b5454418dc5d331
# User ccoutand
# Date 1274520665 -7200

diff --git a/packages/devs/adc/arm/at91/current/ChangeLog b/packages/devs/adc/arm/at91/current/ChangeLog
new file mode 100644
--- /dev/null
+++ b/packages/devs/adc/arm/at91/current/ChangeLog
@@ -0,0 +1,30 @@
+2010-05-18  ccoutand  <ccoutand@stmi.com>
+
+	* AT91 ADC driver package created
+	* cdl/adc_at91.cdl
+	* src/adc_at91.c
+	* tests/at91_adc_test.c
+
+//===========================================================================
+// ####GPLCOPYRIGHTBEGIN####                                                
+// -------------------------------------------                              
+// This file is part of eCos, the Embedded Configurable Operating System.   
+// Copyright (C) 2010 Free Software Foundation, Inc.                        
+//
+// This program 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.                                                           
+//
+// This program 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 this program; if not, write to the                            
+// Free Software Foundation, Inc., 51 Franklin Street,                      
+// Fifth Floor, Boston, MA  02110-1301, USA.                                
+// -------------------------------------------                              
+// ####GPLCOPYRIGHTEND####                                                  
+//===========================================================================
diff --git a/packages/devs/adc/arm/at91/current/cdl/adc_at91.cdl b/packages/devs/adc/arm/at91/current/cdl/adc_at91.cdl
new file mode 100644
--- /dev/null
+++ b/packages/devs/adc/arm/at91/current/cdl/adc_at91.cdl
@@ -0,0 +1,198 @@
+# ====================================================================
+#
+#      adc_at91.cdl
+#
+#      eCos AT91 ADC configuration data
+#
+# ====================================================================
+## ####ECOSGPLCOPYRIGHTBEGIN####                                            
+## -------------------------------------------                              
+## This file is part of eCos, the Embedded Configurable Operating System.   
+## Copyright (C) 2008 Free Software Foundation, 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.,    
+## 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, 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 v2.                                               
+##
+## This exception does not invalidate any other reasons why a work based    
+## on this file might be covered by the GNU General Public License.         
+## -------------------------------------------                              
+## ####ECOSGPLCOPYRIGHTEND####                                              
+# ====================================================================
+######DESCRIPTIONBEGIN####
+#
+# Author(s):      ccoutand@stmi.com
+# Contributors:   
+# Date:           2010-02-12
+#
+#####DESCRIPTIONEND####
+#
+# ====================================================================
+
+
+cdl_package CYGPKG_DEVS_ADC_ARM_AT91 {
+    display     "ADC hardware device driver for AT91 family of ARM controllers"
+    
+    parent      CYGPKG_IO_ADC_DEVICES
+    active_if   CYGPKG_IO_ADC_DEVICES
+    active_if   CYGPKG_HAL_ARM_AT91
+    requires    {CYGNUM_IO_ADC_SAMPLE_SIZE <= 12}
+    requires    {CYGNUM_IO_ADC_SAMPLE_SIZE >= 10}
+    description " 
+           This package provides a generic ADC device driver for the on-chip
+           ADC peripherals in AT91 processors."
+           
+    include_dir cyg/io
+    compile     -library=libextras.a adc_at91.c
+    
+    cdl_interface CYGINT_DEVS_ADC_ARM_AT91_CHANNELS {
+        display "Number of ADC channels"
+    }  
+   
+    cdl_option CYGPKG_DEVS_ADC_ARM_AT91_DEBUG_LEVEL {
+         display "Driver debug output level"
+         flavor  data
+         legal_values {0 1 2}
+         default_value 0
+         description   "
+             This option specifies the level of debug data output by
+             the AT91 ADC device driver. A value of 0 signifies
+             no debug data output; 1 signifies normal debug data
+             output. If an overrun occurred then this can only be
+             detected by debug output messages."         
+    }
+    
+    cdl_option CYGNUM_DEVS_ADC_ARM_AT91_SELECT_TIMER {
+        display       "Interrupt priority"
+        flavor        data
+        legal_values {0 1 2}
+        default_value 1
+        description   "
+            This option selects the timer channel to be used for generating the 
+            sampling interval. Timer channel 0 can be assigned as Real Time Kernel clock 
+            so timer channel 1 is set to be the default value."
+    }
+
+    cdl_option CYGNUM_DEVS_ADC_ARM_AT91_PRESCAL {
+        display       "ADC clock setting"
+        flavor        data
+        legal_values  0 to 255
+        default_value 128
+        description   "
+            This option sets the AT91 ADC PRESCAL value. ADCClock = MCK / ((PRESCAL + 1) * 2)"
+    }
+
+    cdl_option CYGNUM_DEVS_ADC_ARM_AT91_STARTUP_TIME {
+        display       "ADC start up time"
+        flavor        data
+        legal_values  0 to 255
+        default_value 128
+        description   "
+            This option sets the AT91 ADC Startup value. ADC Start Up Time = (STARTUP+1) * 8 / ADCClock"
+    }
+
+    cdl_option CYGNUM_DEVS_ADC_ARM_AT91_SHTIM {
+        display       "ADC start up time"
+        flavor        data
+        legal_values  0 to 15
+        default_value 7
+        description   "
+            This option sets the AT91 ADC Sample and Hold Time. Sample and Hold Time = SHTIM / ADCClock"
+    }
+
+    cdl_option CYGNUM_DEVS_ADC_ARM_AT91_INTPRIO {
+        display       "Interrupt priority"
+        flavor        data
+        legal_values  0 to 15
+        default_value 15
+        description   "
+            This option selects the interrupt priority for the ADC
+            interrupts.  Timer x is used for generating the sample
+            clock. So this option configures the interrupt priority
+            for timer x. There are 16 priority levels corresponding to
+            the values 0 through 15 decimal, of which 15 is the lowest
+            priority. The reset value of these registers defaults all
+            interrupts to the lowest priority, allowing a single write
+            to elevate the priority of an individual interrupt."
+    }
+
+      
+    cdl_option CYGNUM_DEVS_ADC_ARM_AT91_DEFAULT_RATE {
+        display "Default sample rate"
+        flavor   data
+        legal_values 1 to 10000
+        default_value 100
+        description "
+            The driver will be initialized with the default sample rate.
+            If you raise the default sample rate you might need to increase
+            the buffer size for each channel."
+    }
+                
+    # Support up to 8 ADC channels
+    for { set ::channel 0 } { $::channel < 8 } { incr ::channel } {  
+    
+        cdl_component CYGPKG_DEVS_ADC_ARM_AT91_CHANNEL[set ::channel] {
+            display        "Access ADC channel [set ::channel]"
+            flavor          bool
+            default_value   [set ::channel] == 0
+            implements      CYGINT_DEVS_ADC_ARM_AT91_CHANNELS
+            description "
+                If the application needs to access the on-chip ADC
+                channel [set ::channel] via an eCos ADC driver then
+                this option should be enabled."
+     
+            cdl_option CYGDAT_DEVS_ADC_ARM_AT91_CHANNEL[set ::channel]_NAME {
+                display "Device name"
+                flavor      data
+                default_value   [format {"\"/dev/adc0%d\""} $::channel]
+                description "
+                    This option controls the name that an eCos application
+                    should use to access this device via cyg_io_lookup(),
+                    open(), or similar calls."
+            }
+        
+            cdl_option CYGDAT_DEVS_ADC_ARM_AT91_CHANNEL[set ::channel]_BUFSIZE {
+                display "Size of data buffer"
+                flavor  data
+                legal_values  0x01 to 0x2000000
+                default_value 512
+                description "
+                    This option controls the number of samples the
+                    buffer can store. The required RAM depends on the
+                    sample size and on the number of samples. If the
+                    sample size is <= 8 bit the the required RAM =
+                    size of data buffer. If the sample size is 9 or 10
+                    bit then required RAM = size of data buffer * 2."
+            } 
+        } 
+    }
+    
+    cdl_option CYGPKG_DEVS_ADC_ARM_AT91_TESTS {
+        display "Tests for AT91 ADC driver"
+        flavor  data
+        no_define
+        calculated { "tests/at91_adc_test" }
+        description   "
+            This option specifies the set of tests for the AT91
+            ADC device driver."
+    }
+
+}
diff --git a/packages/devs/adc/arm/at91/current/src/adc_at91.c b/packages/devs/adc/arm/at91/current/src/adc_at91.c
new file mode 100644
--- /dev/null
+++ b/packages/devs/adc/arm/at91/current/src/adc_at91.c
@@ -0,0 +1,524 @@
+//==========================================================================
+//
+//      adc_at91.c
+//
+//      ADC driver for AT91 on chip ADC
+//
+//==========================================================================
+// ####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 2008 Free Software Foundation, 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.,
+// 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, 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 v2.
+//
+// This exception does not invalidate any other reasons why a work based
+// on this file might be covered by the GNU General Public License.
+// -------------------------------------------
+// ####ECOSGPLCOPYRIGHTEND####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s):   Original lpc24xx driver from Uwe Kindler
+//              Updated for Atmel AT91 device, ccoutand <ccoutand@stmi.com>
+// Contributors:
+// Date:         2010-02-15
+// Purpose:
+// Description:
+//
+//####DESCRIPTIONEND####
+//
+//==========================================================================
+
+
+//==========================================================================
+//                                 INCLUDES
+//==========================================================================
+#include <pkgconf/system.h>
+#include <pkgconf/devs_adc_arm_at91.h>
+
+#include <cyg/infra/cyg_type.h>
+#include <cyg/infra/cyg_ass.h>
+#include <cyg/infra/diag.h>
+#include <cyg/io/adc.h>
+#include <cyg/hal/hal_arch.h>
+#include <cyg/hal/hal_io.h>
+#include <cyg/hal/hal_intr.h>
+#include <cyg/hal/drv_api.h>
+
+#if CYGPKG_DEVS_ADC_ARM_AT91_DEBUG_LEVEL > 0
+   #define at91_adc_printf(args...) diag_printf(args)
+#else
+   #define at91_adc_printf(args...)
+#endif
+
+#define AT91_MAX_ADC_CHAN 8 // maximum number of channels for AT91 device
+
+#define AT91_ADC_CHER_CHx(_ch_)  (0x1 << _ch_)
+#define AT91_ADC_CHER_CDRx(_ch_) (_ch_ << 2)
+
+//==========================================================================
+//                                  DATA TYPES
+//==========================================================================
+typedef struct at91_adc_info
+{
+    cyg_uint32              adc_base;          // base address of ADC peripheral
+    cyg_vector_t            adc_vector;        // interrupt vector number
+    cyg_uint32              timer_base;        // base address of Timer peripheral
+    cyg_uint32              tc_base;           // base address of Timer channel
+    cyg_vector_t            timer_vector;      // interrupt vector number
+    int                     timer_intprio;     // interrupt priority of ADC interrupt
+    cyg_uint8               prescal;           // ADC prescal value
+    cyg_uint32              timer_cnt;         // Timer value
+    cyg_uint8               timer_clk;	       // Timer clock setting
+    cyg_uint32              resolution;
+    cyg_handle_t            int_handle;        // For initializing the interrupt
+    cyg_interrupt           int_data;
+    struct cyg_adc_channel* channel[AT91_MAX_ADC_CHAN]; // stores references to channel objects
+    cyg_uint8               chan_mask;         // mask that indicates channels used
+                                               // by ADC driver
+} at91_adc_info;
+
+
+//==========================================================================
+//                               DECLARATIONS
+//==========================================================================
+static bool at91_adc_init(struct cyg_devtab_entry *tab);
+static Cyg_ErrNo at91_adc_lookup(struct cyg_devtab_entry **tab,
+                                    struct cyg_devtab_entry  *sub_tab,
+                                    const char               *name);
+static void at91_adc_enable( cyg_adc_channel *chan );
+static void at91_adc_disable( cyg_adc_channel *chan );
+static void at91_adc_set_rate( cyg_adc_channel *chan, cyg_uint32 rate );
+static cyg_uint32 at91_adc_isr(cyg_vector_t vector, cyg_addrword_t data);
+static void at91_adc_dsr(cyg_vector_t vector,
+                            cyg_ucount32 count,
+                            cyg_addrword_t data);
+
+// -------------------------------------------------------------------------
+// Driver functions:
+CYG_ADC_FUNCTIONS( at91_adc_funs,
+                   at91_adc_enable,
+                   at91_adc_disable,
+                   at91_adc_set_rate );
+
+// -------------------------------------------------------------------------
+// Device instance:
+static at91_adc_info at91_adc_info0 =
+{
+    .adc_base       = AT91_ADC,
+    .adc_vector     = CYGNUM_HAL_INTERRUPT_ADC,
+    .timer_base     = AT91_TC,
+    .tc_base        = AT91_TC + (AT91_TC_TC_SIZE * CYGNUM_DEVS_ADC_ARM_AT91_SELECT_TIMER),
+    .timer_vector   = CYGNUM_HAL_INTERRUPT_TC0 + CYGNUM_DEVS_ADC_ARM_AT91_SELECT_TIMER,
+    .timer_intprio  = CYGNUM_DEVS_ADC_ARM_AT91_INTPRIO,
+    .int_handle     = 0,
+#if CYGNUM_IO_ADC_SAMPLE_SIZE > 8
+     .resolution    = AT91_ADC_MR_LOWREC_10BITS,
+#else
+     .resolution    = AT91_ADC_MR_LOWREC_8BITS,
+#endif
+    .chan_mask      = 0
+};
+
+CYG_ADC_DEVICE( at91_adc_device,
+                &at91_adc_funs,
+                &at91_adc_info0,
+                CYGNUM_DEVS_ADC_ARM_AT91_DEFAULT_RATE);
+
+// -------------------------------------------------------------------------
+// Channel instances:
+
+#define AT91_ADC_CHANNEL( __chan )                                    \
+CYG_ADC_CHANNEL( at91_adc_channel##__chan,                            \
+                 __chan,                                                 \
+                 CYGDAT_DEVS_ADC_ARM_AT91_CHANNEL##__chan##_BUFSIZE,  \
+                 &at91_adc_device );                                  \
+                                                                         \
+DEVTAB_ENTRY( at91_adc_channel##__chan##_device,                      \
+              CYGDAT_DEVS_ADC_ARM_AT91_CHANNEL##__chan##_NAME,        \
+              0,                                                         \
+              &cyg_io_adc_devio,                                         \
+              at91_adc_init,                                          \
+              at91_adc_lookup,                                        \
+              &at91_adc_channel##__chan );
+
+#ifdef CYGPKG_DEVS_ADC_ARM_AT91_CHANNEL0
+AT91_ADC_CHANNEL(0);
+#endif
+#ifdef CYGPKG_DEVS_ADC_ARM_AT91_CHANNEL1
+AT91_ADC_CHANNEL(1);
+#endif
+#ifdef CYGPKG_DEVS_ADC_ARM_AT91_CHANNEL2
+AT91_ADC_CHANNEL(2);
+#endif
+#ifdef CYGPKG_DEVS_ADC_ARM_AT91_CHANNEL3
+AT91_ADC_CHANNEL(3);
+#endif
+#ifdef CYGPKG_DEVS_ADC_ARM_AT91_CHANNEL4
+AT91_ADC_CHANNEL(4);
+#endif
+#ifdef CYGPKG_DEVS_ADC_ARM_AT91_CHANNEL5
+AT91_ADC_CHANNEL(5);
+#endif
+#ifdef CYGPKG_DEVS_ADC_ARM_AT91_CHANNEL6
+AT91_ADC_CHANNEL(6);
+#endif
+#ifdef CYGPKG_DEVS_ADC_ARM_AT91_CHANNEL7
+AT91_ADC_CHANNEL(7);
+#endif
+
+
+//==========================================================================
+// This function is called from the device IO infrastructure to initialize
+// the device. It should perform any work needed to start up the device,
+// short of actually starting the generation of samples. This function will
+// be called for each channel, so if there is initialization that only needs
+// to be done once, such as creating and interrupt object, then care should
+// be taken to do this. This function should also call cyg_adc_device_init()
+// to initialize the generic parts of the driver.
+//==========================================================================
+static bool at91_adc_init(struct cyg_devtab_entry *tab)
+{
+    cyg_adc_channel *chan   = (cyg_adc_channel *)tab->priv;
+    cyg_adc_device *device  = chan->device;
+    at91_adc_info *info     = device->dev_priv;
+    cyg_uint32 regval;
+
+    if (!info->int_handle)
+    {
+       cyg_drv_interrupt_create(info->timer_vector,
+                                 info->timer_intprio,
+                                (cyg_addrword_t)device,
+                                &at91_adc_isr,
+                                &at91_adc_dsr,
+                                &(info->int_handle),
+                                &(info->int_data));
+       cyg_drv_interrupt_attach(info->int_handle);
+       cyg_drv_interrupt_mask(info->timer_vector);
+
+       // Reset ADC
+       HAL_WRITE_UINT32((info->adc_base + AT91_ADC_CR), AT91_ADC_CR_SWRST);
+
+       // Disable counter interrupts
+       HAL_WRITE_UINT32(info->tc_base+AT91_TC_CCR, AT91_TC_CCR_CLKDIS);
+       HAL_WRITE_UINT32(info->tc_base+AT91_TC_IDR, 0xffffffff);
+
+       // Clear status bit
+       HAL_READ_UINT32(info->tc_base + AT91_TC_SR, regval);
+
+       // Enable peripheral clocks for TC
+       HAL_WRITE_UINT32(AT91_PMC+AT91_PMC_PCER,  \
+    		  ((AT91_PMC_PCER_TC0) << CYGNUM_DEVS_ADC_ARM_AT91_SELECT_TIMER));
+
+       //
+       // Disable all interrupts, all channels
+       //
+       HAL_WRITE_UINT32((info->adc_base + AT91_ADC_CHDR), \
+                     AT91_ADC_CHER_CH0  |\
+                     AT91_ADC_CHER_CH1  |\
+                     AT91_ADC_CHER_CH2  |\
+                     AT91_ADC_CHER_CH3  |\
+                     AT91_ADC_CHER_CH4  |\
+                     AT91_ADC_CHER_CH5  |\
+                     AT91_ADC_CHER_CH6  |\
+                     AT91_ADC_CHER_CH7);
+       HAL_WRITE_UINT32((info->adc_base + AT91_ADC_IDR), \
+                     AT91_ADC_CHER_CH0  |\
+                     AT91_ADC_CHER_CH1  |\
+                     AT91_ADC_CHER_CH2  |\
+                     AT91_ADC_CHER_CH3  |\
+                     AT91_ADC_CHER_CH4  |\
+                     AT91_ADC_CHER_CH5  |\
+                     AT91_ADC_CHER_CH6  |\
+                     AT91_ADC_CHER_CH7);
+
+       //
+       // setup the default sample rate
+       //
+       at91_adc_set_rate(chan, chan->device->config.rate);
+
+       // setup ADC mode
+       HAL_WRITE_UINT32((info->adc_base + AT91_ADC_MR), \
+	   	    ( ( CYGNUM_DEVS_ADC_ARM_AT91_PRESCAL << AT91_ADC_MR_PRESCAL_SHIFT ) & \
+	   	    		AT91_ADC_MR_PRESCAL_MASK ) | \
+	   	    ( ( CYGNUM_DEVS_ADC_ARM_AT91_STARTUP_TIME  << AT91_ADC_MR_STARTUP_SHIFT ) & \
+	   		   	    AT91_ADC_MR_STARTUP_MASK ) | \
+	   	    ( ( CYGNUM_DEVS_ADC_ARM_AT91_SHTIM << AT91_ADC_MR_SHTIM_SHIFT ) & \
+	   		   		AT91_ADC_MR_SHTIM_MASK ) | \
+	   	    AT91_ADC_MR_TRGSEL_TIOA0  | \
+	   	    info->resolution);
+
+
+    } // if (!info->int_handle)
+
+    cyg_adc_device_init(device); // initialize generic parts of driver
+
+    return true;
+}
+
+
+//==========================================================================
+// This function is called when a client looks up or opens a channel. It
+// should call cyg_adc_channel_init() to initialize the generic part of
+// the channel. It should also perform any operations needed to start the
+// channel generating samples.
+//==========================================================================
+static Cyg_ErrNo at91_adc_lookup(struct cyg_devtab_entry **tab,
+                                    struct cyg_devtab_entry  *sub_tab,
+                                    const char               *name)
+{
+    cyg_adc_channel  *chan     = (cyg_adc_channel *)(*tab)->priv;
+    at91_adc_info *info     = chan->device->dev_priv;
+
+    info->channel[chan->channel] = chan;
+    cyg_adc_channel_init(chan); // initialize generic parts of channel
+
+    //
+    // The generic ADC manual says: When a channel is first looked up or
+    // opened, then it is automatically enabled and samples start to
+    // accumulate - so we start the channel now
+    //
+    chan->enabled = true;
+    at91_adc_enable(chan);
+
+    return ENOERR;
+}
+
+
+//==========================================================================
+// This function is called from the generic ADC package to enable the
+// channel in response to a CYG_IO_SET_CONFIG_ADC_ENABLE config operation.
+// It should take any steps needed to start the channel generating samples
+//==========================================================================
+static void at91_adc_enable(cyg_adc_channel *chan)
+{
+    at91_adc_info *info      = chan->device->dev_priv;
+
+    // Enable the channel
+    HAL_WRITE_UINT32((info->adc_base + AT91_ADC_CHER), \
+                      AT91_ADC_CHER_CHx(chan->channel));
+
+    //
+    // Unmask interrupt as soon as 1 channel is enable
+    //
+    if (!info->chan_mask)
+    {
+       cyg_drv_interrupt_unmask(info->timer_vector);
+
+       // Enable timer interrupt
+       HAL_WRITE_UINT32(info->tc_base+AT91_TC_IER, AT91_TC_IER_CPC);
+
+       // Enable the clock
+       HAL_WRITE_UINT32(info->tc_base+AT91_TC_CCR, AT91_TC_CCR_TRIG | AT91_TC_CCR_CLKEN);
+
+       // Start timer
+       HAL_WRITE_UINT32(info->tc_base+AT91_TC_CCR,  AT91_TC_CCR_TRIG);
+
+       // Start ADC sampling
+       HAL_WRITE_UINT32((info->adc_base + AT91_ADC_CR), AT91_ADC_CR_START);
+
+#if CYGPKG_DEVS_ADC_ARM_AT91_DEBUG_LEVEL > 0
+        info->zero_time = cyg_current_time() * 10;
+#endif
+    }
+
+    info->chan_mask |= AT91_ADC_CHER_CHx(chan->channel);
+
+}
+
+
+//==========================================================================
+// This function is called from the generic ADC package to enable the
+// channel in response to a CYG_IO_SET_CONFIG_ADC_DISABLE config operation.
+// It should take any steps needed to stop the channel generating samples.
+//==========================================================================
+static void at91_adc_disable(cyg_adc_channel *chan)
+{
+    at91_adc_info *info  = chan->device->dev_priv;
+    cyg_uint32 sr;
+
+    info->chan_mask &= ~ AT91_ADC_CHER_CHx(chan->channel);
+
+    // Disable the channel
+    HAL_WRITE_UINT32((info->adc_base + AT91_ADC_CHDR), \
+                      AT91_ADC_CHER_CHx(chan->channel));
+
+    //
+    // If no channel is enabled the we disable interrupts now
+    //
+    if (!info->chan_mask)
+    {
+       cyg_drv_interrupt_mask(info->timer_vector);
+
+       // Clear interrupt
+       HAL_READ_UINT32(info->tc_base+AT91_TC_SR, sr);
+
+       // Disable  timer interrupt
+       HAL_WRITE_UINT32(info->tc_base+AT91_TC_IDR, AT91_TC_IER_CPC);
+
+       // Disable the clock
+       HAL_WRITE_UINT32(info->tc_base+AT91_TC_CCR, AT91_TC_CCR_CLKDIS);
+
+    }
+}
+
+
+//==========================================================================
+// This function is called from the generic ADC package to enable the
+// channel in response to a CYG_IO_SET_CONFIG_ADC_RATE config operation.
+// It should take any steps needed to change the sample rate of the channel,
+// or of the entire device.
+// We use a timer channel to generate the interrupts for sampling the
+// analog channels
+//==========================================================================
+static void at91_adc_set_rate( cyg_adc_channel *chan, cyg_uint32 rate)
+{
+    cyg_adc_device   *device = chan->device;
+    at91_adc_info *info   = (at91_adc_info *)device->dev_priv;
+    cyg_uint8 timer_clk   = AT91_TC_CMR_CLKS_MCK2;
+    cyg_uint32 tmr_period = CYGNUM_HAL_ARM_AT91_CLOCK_SPEED / ( rate << 1);
+
+    if( tmr_period > 0xffff )
+    {
+    	tmr_period = CYGNUM_HAL_ARM_AT91_CLOCK_SPEED / ( rate << 5);
+        timer_clk  = AT91_TC_CMR_CLKS_MCK32;
+    }
+
+    if( tmr_period > 0xffff )
+    {
+    	tmr_period = CYGNUM_HAL_ARM_AT91_CLOCK_SPEED / ( rate << 7);
+    	timer_clk  = AT91_TC_CMR_CLKS_MCK128;
+    }
+
+    if( tmr_period > 0xffff )
+    {
+    	tmr_period = CYGNUM_HAL_ARM_AT91_CLOCK_SPEED / ( rate << 10);
+    	timer_clk  = AT91_TC_CMR_CLKS_MCK1024;
+    }
+
+    if( tmr_period > 0xffff )
+    {
+    	tmr_period = 0xffff;
+    	timer_clk  = AT91_TC_CMR_CLKS_MCK1024;
+    	at91_adc_printf("AT91 ADC timer, rate too high!");
+    }
+
+    device->config.rate = rate;
+    info->timer_clk = timer_clk;
+    info->timer_cnt = tmr_period;
+
+    // Set timer values
+    HAL_WRITE_UINT32(info->tc_base+AT91_TC_CMR,  AT91_TC_CMR_CPCTRG | info->timer_clk);
+    HAL_WRITE_UINT32(info->tc_base+AT91_TC_RC,  info->timer_cnt);
+
+    at91_adc_printf("AT91 ADC Timer settings %d, %d", info->timer_clk, info->timer_cnt);
+
+    return;
+}
+
+
+//==========================================================================
+// This function is the ISR attached to the ADC device's interrupt vector.
+// It is responsible for reading samples from the channels and passing them
+// on to the generic layer. It needs to check each channel for data, and call
+// cyg_adc_receive_sample() for each new sample available, and then ready the
+// device for the next interrupt.
+//==========================================================================
+static cyg_uint32 at91_adc_isr(cyg_vector_t vector, cyg_addrword_t data)
+{
+    cyg_adc_device   *device = (cyg_adc_device *) data;
+    at91_adc_info *info   = (at91_adc_info *)device->dev_priv;
+    cyg_uint32        regval,  adc_status;
+    cyg_uint32        res = 0;
+    cyg_adc_sample_t  adcdata;
+    cyg_uint32 sr;
+
+    cyg_uint8 active_channels = info->chan_mask;
+    cyg_uint8 channel_no = 0;
+
+    // Clear timer interrupt
+    HAL_READ_UINT32(info->tc_base+AT91_TC_SR, sr);
+
+    // Check on channel conversion done
+    HAL_READ_UINT32(info->adc_base + AT91_ADC_SR, adc_status);
+
+    while (active_channels)
+    {
+        if (active_channels & 0x01)
+        {
+            // If ADC conversion done, save sample
+            if(adc_status & AT91_ADC_CHER_CHx(channel_no))
+            {
+              HAL_READ_UINT32((info->adc_base + AT91_ADC_CDR0 + AT91_ADC_CHER_CDRx(channel_no)), regval);
+              adcdata = regval & 0x3FF;
+              res |= CYG_ISR_HANDLED
+                |  cyg_adc_receive_sample(info->channel[channel_no],
+                                          adcdata);
+            }
+        } // if (active_channels & 0x01)
+        active_channels >>= 1;
+        channel_no++;
+    } // while (active_channels)
+
+    // Restart sampling
+    HAL_WRITE_UINT32((info->adc_base + AT91_ADC_CR), AT91_ADC_CR_START);
+
+    cyg_drv_interrupt_acknowledge(info->timer_vector);
+
+    return res;
+}
+
+
+//==========================================================================
+// This function is the DSR attached to the ADC device's interrupt vector.
+// It is called by the kernel if the ISR return value contains the
+// CYG_ISR_HANDLED bit. It needs to call cyg_adc_wakeup() for each channel
+// that has its wakeup field set.
+//==========================================================================
+static void at91_adc_dsr(cyg_vector_t vector,
+                            cyg_ucount32 count,
+                            cyg_addrword_t data)
+{
+    cyg_adc_device   *device          = (cyg_adc_device *) data;
+    at91_adc_info *info            = device->dev_priv;
+    cyg_uint8         active_channels = info->chan_mask;
+    cyg_uint8         chan_no         = 0;
+
+    while (active_channels)
+    {
+        if (active_channels & 0x01)
+        {
+            if(info->channel[chan_no]->wakeup)
+            {
+                cyg_adc_wakeup(info->channel[chan_no]);
+            }
+        }
+        chan_no++;
+        active_channels >>= 1;
+    }
+}
+
+
+//---------------------------------------------------------------------------
+// eof adc_at91.c
diff --git a/packages/devs/adc/arm/at91/current/tests/at91_adc_test.c b/packages/devs/adc/arm/at91/current/tests/at91_adc_test.c
new file mode 100644
--- /dev/null
+++ b/packages/devs/adc/arm/at91/current/tests/at91_adc_test.c
@@ -0,0 +1,290 @@
+//==========================================================================
+//
+//      at91_adc_test.c
+//
+//      ADC driver for AT91 on chip ADC
+//
+//==========================================================================
+// ####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 2008 Free Software Foundation, 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.,
+// 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, 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 v2.
+//
+// This exception does not invalidate any other reasons why a work based
+// on this file might be covered by the GNU General Public License.
+// -------------------------------------------
+// ####ECOSGPLCOPYRIGHTEND####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s):  Original lpc24xx driver from Uwe Kindler
+//             Updated for Atmel AT91 device, ccoutand <ccoutand@stmi.com>
+// Contributors:
+// Date:         2010-02-15
+// Purpose:
+// Description:
+//
+//####DESCRIPTIONEND####
+//
+//==========================================================================
+
+#include <pkgconf/system.h>
+
+#include <cyg/infra/testcase.h>         // test macros
+#include <cyg/infra/cyg_ass.h>          // assertion macros
+#include <cyg/infra/diag.h>
+#include <cyg/hal/hal_diag.h>
+#include <cyg/hal/hal_arch.h>           // CYGNUM_HAL_STACK_SIZE_TYPICAL
+
+// Package requirements
+#if defined(CYGPKG_IO_ADC) && defined(CYGPKG_KERNEL)
+
+#include <pkgconf/kernel.h>
+#include <cyg/io/io.h>
+#include <cyg/io/adc.h>
+#include <pkgconf/devs_adc_arm_at91.h>
+
+// Package option requirements
+#if defined(CYGFUN_KERNEL_API_C)
+
+#include <cyg/kernel/kapi.h>
+
+#if CYGINT_DEVS_ADC_ARM_AT91_CHANNELS > 0
+
+#define MAX_ADC_CHANNEL_TO_TEST 4
+
+//===========================================================================
+//                               DATA TYPES
+//===========================================================================
+typedef struct st_thread_data
+{
+    cyg_thread   obj;
+    long         stack[CYGNUM_HAL_STACK_SIZE_TYPICAL];
+    cyg_handle_t hdl;
+} thread_data_t;
+
+
+//===========================================================================
+//                              LOCAL DATA
+//===========================================================================
+cyg_thread_entry_t adc_thread;
+thread_data_t      adc_thread_data;
+
+
+//===========================================================================
+//                             ADC THREAD
+//===========================================================================
+void adc_thread(cyg_addrword_t data)
+{
+    int             res;
+    cyg_io_handle_t handle[8]     = {0, 0, 0, 0, 0, 0, 0, 0};
+    cyg_uint32      sample_cnt[8] = {0, 0, 0, 0, 0, 0, 0, 0};
+    cyg_uint32      cfg_data;
+    cyg_uint32      len;
+    cyg_uint32      start_time;
+    cyg_uint32      end_time;
+    int             i;
+    cyg_uint8       seconds = 0;
+    float           final_seconds;
+    cyg_uint32      samples_expected;
+
+
+    diag_printf("This test reads samples from all enabled ADC channels.\n"
+                "Each second the number of already acquired samples\n"
+                "will be printed. After 10 seconds all ADC channels\n"
+                "will be stopped and each ADC buffer will be read until\n"
+                "it is empty. If the number of acquired samples is much\n"
+                "smaller than the number of expected samples, then you\n"
+                "should lower the sample rate.\n\n");
+
+    // Get a handle for ADC device 0 channel 0 - 3 (lookup also trigger a channel enable)
+    res = cyg_io_lookup( "/dev/adc00", &handle[0]);
+    res = cyg_io_lookup( "/dev/adc01", &handle[1]);
+    res = cyg_io_lookup( "/dev/adc02", &handle[2]);
+    res = cyg_io_lookup( "/dev/adc03", &handle[3]);
+
+    //
+    // switch all channels to non blocking
+    //
+    for (i = 0; i < MAX_ADC_CHANNEL_TO_TEST; ++i)
+    {
+        if (handle[i])
+        {
+            cfg_data = 0;
+            len = sizeof(cfg_data);
+            res = cyg_io_set_config(handle[i],
+                                    CYG_IO_SET_CONFIG_READ_BLOCKING,
+                                    &cfg_data,
+                                    &len);
+            if (ENOERR != res)
+            {
+                CYG_TEST_FAIL_FINISH("Error switching ADC channel to non blocking");
+            }
+            sample_cnt[i] = 0;
+        }
+    }
+
+    start_time = cyg_current_time();
+    do
+    {
+        for (i = 0; i < MAX_ADC_CHANNEL_TO_TEST; ++i)
+        {
+            if (handle[i])
+            {
+                cyg_adc_sample_t sample;
+
+                // read a sample from the channel
+                do
+                {
+                    cyg_uint32 len = sizeof(sample);
+                    res = cyg_io_read( handle[i], &sample, &len );
+                }
+                while (-EAGAIN == res);
+                if (ENOERR == res)
+                {
+                    sample_cnt[i]++;
+                }
+            } // if (handle[i])
+        }
+        //
+        // print number of acquired samples - if one second is expired.
+        // we expect that the number of acquired samples is nearly the
+        // sample rate
+        //
+        end_time = cyg_current_time();
+        if ((end_time - start_time) >= 100)
+        {
+            start_time = end_time;
+            diag_printf("%d\t %d\t %d\t %d\n",
+                        sample_cnt[0],
+                        sample_cnt[1],
+                        sample_cnt[2],
+                        sample_cnt[3]);
+            seconds++;
+        } // if ((end_time - start_time) >= 100)
+    } while (seconds < 10);
+
+    //
+    // Now stop all channels
+    //
+    for (i = 0; i < MAX_ADC_CHANNEL_TO_TEST; ++i)
+    {
+        if (handle[i])
+        {
+            res = cyg_io_set_config(handle[i],
+                                    CYG_IO_SET_CONFIG_ADC_DISABLE,
+                                    0,
+                                    0);
+            if (ENOERR != res)
+            {
+                CYG_TEST_FAIL_FINISH("Error disabling ADC channel");
+            }
+        } // if (handle[i])
+    }
+    end_time = cyg_current_time();
+    end_time = seconds * 1000 + (end_time - start_time) * 10;
+    final_seconds = end_time / 1000.0;
+
+    //
+    // Now read all remaining samples from buffer
+    //
+    for (i = 0; i < MAX_ADC_CHANNEL_TO_TEST; ++i)
+    {
+        if (handle[i])
+        {
+            do
+            {
+                cyg_adc_sample_t sample;
+                cyg_uint32 len = sizeof(sample);
+                res = cyg_io_read( handle[i], &sample, &len );
+                if (ENOERR == res)
+                {
+                    sample_cnt[i]++;
+                }
+            } while (ENOERR == res);
+        } // if (handle[i])
+    }
+
+    diag_printf("\n\n----------------------------------------\n");
+    samples_expected = final_seconds * CYGNUM_DEVS_ADC_ARM_AT91_DEFAULT_RATE;
+    diag_printf("Samples expected after %d milliseconds: %d\n",
+                end_time, samples_expected);
+    diag_printf("Samples read (per channel):\n");
+    diag_printf("%d\t %d\t %d\t %d\n",
+                sample_cnt[0],
+                sample_cnt[1],
+                sample_cnt[2],
+                sample_cnt[3]);
+
+    CYG_TEST_PASS_FINISH("ADC test OK");
+}
+
+
+void
+cyg_start(void)
+{
+    CYG_TEST_INIT();
+
+    //
+    // create the main ADC test thread
+    //
+    cyg_thread_create(4, adc_thread,
+                      (cyg_addrword_t) 0,
+                      "at91_adc_thread",
+                      (void *) adc_thread_data.stack,
+                      1024 * sizeof(long),
+                      &adc_thread_data.hdl,
+                      &adc_thread_data.obj);
+
+    cyg_thread_resume(adc_thread_data.hdl);
+
+    cyg_scheduler_start();
+}
+#else // CYGINT_DEVS_ADC_ARM_AT91_CHANNELS > 0
+#define N_A_MSG "Needs at least one enabled ADC channel"
+#endif
+
+#else // CYGFUN_KERNEL_API_C
+#define N_A_MSG "Needs kernel C API"
+#endif
+
+#else // CYGPKG_IO_ADC && CYGPKG_KERNEL
+#define N_A_MSG "Needs Kernel and ADC support"
+#endif
+
+#ifdef N_A_MSG
+void
+cyg_start( void )
+{
+    CYG_TEST_INIT();
+    CYG_TEST_NA(N_A_MSG);
+}
+#endif // N_A_MSG
+
+
+// EOF can_tx.c
+
+//---------------------------------------------------------------------------
+// eof at91_adc_test.c
diff --git a/packages/ecos.db b/packages/ecos.db
--- a/packages/ecos.db
+++ b/packages/ecos.db
@@ -2421,6 +2421,15 @@
             ADC provided by the LPC24xx processor family."
 }
 
+package CYGPKG_DEVS_ADC_ARM_AT91 {
+    alias           { "AT91 ADC driver" }
+    hardware
+    directory       devs/adc/arm/at91
+    script          adc_at91.cdl
+    description "
+            This packages provides an ADC driver for the on-chip
+            ADC provided by the Atmel AT91 processor family."
+}
 package CYGPKG_DEVS_ADC_SYNTH {
     alias         { "Synthethic ADC driver" adc_synth }
     hardware

^ permalink raw reply	[flat|nested] 18+ messages in thread

* Re: AT91 ADC support
  2010-05-22  9:40 AT91 ADC support Christophe Coutand
@ 2010-05-27 13:42 ` John Dallaway
  2010-05-27 13:52   ` Sergei Gavrikov
  0 siblings, 1 reply; 18+ messages in thread
From: John Dallaway @ 2010-05-27 13:42 UTC (permalink / raw)
  To: Christophe Coutand, Sergei Gavrikov; +Cc: ecos-patches

Hi Christophe and Sergei

Christophe, is your ADC driver applicable to all AT91 parts with on-chip
ADC in theory?

Sergei, if so, we should add the new package to all the relevant target
records in ecos.db: at91sam7sek, at91sam7xek, sam7ex256, eb55, phycore

John Dallaway
eCos maintainer

^ permalink raw reply	[flat|nested] 18+ messages in thread

* Re: AT91 ADC support
  2010-05-27 13:42 ` John Dallaway
@ 2010-05-27 13:52   ` Sergei Gavrikov
  2010-05-27 14:16     ` Christophe Coutand
  0 siblings, 1 reply; 18+ messages in thread
From: Sergei Gavrikov @ 2010-05-27 13:52 UTC (permalink / raw)
  To: John Dallaway; +Cc: Christophe Coutand, Sergei Gavrikov, ecos-patches

On Thu, 27 May 2010, John Dallaway wrote:

> Hi Christophe and Sergei
>
> Christophe, is your ADC driver applicable to all AT91 parts with on-chip
> ADC in theory?
>
> Sergei, if so, we should add the new package to all the relevant target
> records in ecos.db: at91sam7sek, at91sam7xek, sam7ex256, eb55, phycore

Hi John,

First I tried to build the driver for AT91 'phycore' target and it was
not possible to build it because in AT91 var_io.h some ADC defines
included by a condition:

...
#elif defined (CYGHWR_HAL_ARM_AT91SAM7)
#include <pkgconf/hal_arm_at91sam7.h>
...

So, it seemed for me that's AT91SAM7 related driver. I have no
experience with AT91 CPU set. May be Christophe enlighten us?

Thanks for your point. It seems I must dive in AT91 datasheets.

Sergei

> John Dallaway
> eCos maintainer
>

^ permalink raw reply	[flat|nested] 18+ messages in thread

* RE: AT91 ADC support
  2010-05-27 13:52   ` Sergei Gavrikov
@ 2010-05-27 14:16     ` Christophe Coutand
  2010-05-27 14:47       ` John Dallaway
  0 siblings, 1 reply; 18+ messages in thread
From: Christophe Coutand @ 2010-05-27 14:16 UTC (permalink / raw)
  To: Sergei Gavrikov, John Dallaway; +Cc: ecos-patches

Hi,

I originally made it for AT91SAM7S and AT91SAM7X but at the last minute
I saw that Atmel was using the same ADC for AT91M55800A, AT91SAM9X etc..
so I renamed it to AT91. I thought this would be more future proof.

It remains true that I have not compiled / tested it for anything else
than AT91SAM7S / AT91SAM7X.

I can specify which AT91 supports it and update the var_io.h when
definition are missing.

Regards,
Christophe


-----Original Message-----
From: Sergei Gavrikov [mailto:sergei.gavrikov@gmail.com] 
Sent: 27. mai 2010 15:52
To: John Dallaway
Cc: Christophe Coutand; Sergei Gavrikov;
ecos-patches@ecos.sourceware.org
Subject: Re: AT91 ADC support

On Thu, 27 May 2010, John Dallaway wrote:

> Hi Christophe and Sergei
>
> Christophe, is your ADC driver applicable to all AT91 parts with
on-chip
> ADC in theory?
>
> Sergei, if so, we should add the new package to all the relevant
target
> records in ecos.db: at91sam7sek, at91sam7xek, sam7ex256, eb55, phycore

Hi John,

First I tried to build the driver for AT91 'phycore' target and it was
not possible to build it because in AT91 var_io.h some ADC defines
included by a condition:

...
#elif defined (CYGHWR_HAL_ARM_AT91SAM7)
#include <pkgconf/hal_arm_at91sam7.h>
...

So, it seemed for me that's AT91SAM7 related driver. I have no
experience with AT91 CPU set. May be Christophe enlighten us?

Thanks for your point. It seems I must dive in AT91 datasheets.

Sergei

> John Dallaway
> eCos maintainer
>

^ permalink raw reply	[flat|nested] 18+ messages in thread

* Re: AT91 ADC support
  2010-05-27 14:16     ` Christophe Coutand
@ 2010-05-27 14:47       ` John Dallaway
  2010-05-27 15:44         ` Christophe Coutand
  0 siblings, 1 reply; 18+ messages in thread
From: John Dallaway @ 2010-05-27 14:47 UTC (permalink / raw)
  To: Christophe Coutand; +Cc: Sergei Gavrikov, ecos-patches

Hi Christophe

Christophe Coutand wrote:

> I originally made it for AT91SAM7S and AT91SAM7X but at the last minute
> I saw that Atmel was using the same ADC for AT91M55800A, AT91SAM9X etc..
> so I renamed it to AT91. I thought this would be more future proof.

It's definitely a good idea to keep the package name more generic.

> It remains true that I have not compiled / tested it for anything else
> than AT91SAM7S / AT91SAM7X.
> 
> I can specify which AT91 supports it and update the var_io.h when
> definition are missing.

If it's easy to get the package building for the AT91M55800A targets
(eb55, phycore) then that would be preferable. If not, we can add the
package to the AT91SAM7 targets only (at91sam7sek, at91sam7xek,
sam7ex256) for now.

John Dallaway
eCos maintainer

^ permalink raw reply	[flat|nested] 18+ messages in thread

* RE: AT91 ADC support
  2010-05-27 14:47       ` John Dallaway
@ 2010-05-27 15:44         ` Christophe Coutand
  2010-05-27 16:08           ` John Dallaway
  2010-05-27 16:37           ` Sergei Gavrikov
  0 siblings, 2 replies; 18+ messages in thread
From: Christophe Coutand @ 2010-05-27 15:44 UTC (permalink / raw)
  To: John Dallaway; +Cc: Sergei Gavrikov, ecos-patches

Hi John,

It's pretty easy to add the required definition for the AT91M55800A
targets. The only thing I see now is that this device contains 2 ADCs
which I have not considered before. I guess there are several ways out
of this:

1- Update the actual AT91 ADC driver to make full use of the AT91M55800A
targets. I guess should be done by loading a second ADC instance (one
for each ADC. I have not been through all the thinking here...).

2- or limit the AT91 driver to use only ADC0 of the AT91M55800A target
for the time being.

3- or exclude AT91M55800A targets for the time being.

IMO #1 is best but I cannot give any time frame for completing it.

One additional weakness of the driver is that it is made for up to 8
channels. It is defined nowhere what the targeted CPU can actually
handle, this is left to the user when configuring eCos. I believe this
is pretty fine since the user must anyway know which signal he wants to
sample but you might disagree on that one.

Regards,
Christophe


-----Original Message-----
From: John Dallaway [mailto:john@dallaway.org.uk] 
Sent: 27. mai 2010 16:48
To: Christophe Coutand
Cc: Sergei Gavrikov; ecos-patches@ecos.sourceware.org
Subject: Re: AT91 ADC support

Hi Christophe

Christophe Coutand wrote:

> I originally made it for AT91SAM7S and AT91SAM7X but at the last
minute
> I saw that Atmel was using the same ADC for AT91M55800A, AT91SAM9X
etc..
> so I renamed it to AT91. I thought this would be more future proof.

It's definitely a good idea to keep the package name more generic.

> It remains true that I have not compiled / tested it for anything else
> than AT91SAM7S / AT91SAM7X.
> 
> I can specify which AT91 supports it and update the var_io.h when
> definition are missing.

If it's easy to get the package building for the AT91M55800A targets
(eb55, phycore) then that would be preferable. If not, we can add the
package to the AT91SAM7 targets only (at91sam7sek, at91sam7xek,
sam7ex256) for now.

John Dallaway
eCos maintainer

^ permalink raw reply	[flat|nested] 18+ messages in thread

* Re: AT91 ADC support
  2010-05-27 15:44         ` Christophe Coutand
@ 2010-05-27 16:08           ` John Dallaway
  2010-05-27 16:37             ` Kurt Siedenburg
  2010-05-27 16:37           ` Sergei Gavrikov
  1 sibling, 1 reply; 18+ messages in thread
From: John Dallaway @ 2010-05-27 16:08 UTC (permalink / raw)
  To: Christophe Coutand; +Cc: Sergei Gavrikov, ecos-patches

Hi Christophe

Christophe Coutand wrote:

> It's pretty easy to add the required definition for the AT91M55800A
> targets. The only thing I see now is that this device contains 2 ADCs
> which I have not considered before. I guess there are several ways out
> of this:
> 
> 1- Update the actual AT91 ADC driver to make full use of the AT91M55800A
> targets. I guess should be done by loading a second ADC instance (one
> for each ADC. I have not been through all the thinking here...).
> 
> 2- or limit the AT91 driver to use only ADC0 of the AT91M55800A target
> for the time being.
> 
> 3- or exclude AT91M55800A targets for the time being.
> 
> IMO #1 is best but I cannot give any time frame for completing it.

In that case, I would suggest option #2 for now. Someone else (who has
an AT91M55800A on their desk) may be interested in adding support for
the second ADC.

John Dallaway
eCos maintainer

^ permalink raw reply	[flat|nested] 18+ messages in thread

* RE: AT91 ADC support
  2010-05-27 16:08           ` John Dallaway
@ 2010-05-27 16:37             ` Kurt Siedenburg
  0 siblings, 0 replies; 18+ messages in thread
From: Kurt Siedenburg @ 2010-05-27 16:37 UTC (permalink / raw)
  To: ecos-patches

Whenever I encounter a situation like this the most generic way to deal
with it is:

- extend the driver to support more than 1 ADC device
- make it a configuration (CDL?) parameter how many channels an ADC
device supports

This way the footprint is minimized:
The same code is shared for more than 1 channel - as opposed to
duplicating the code for a 2nd ADC.

If you need/want to quench the last byte out of the footprint you could
even conceive an additional config CDL param:  single device support vs.
multi device support.

Not sure if you want to entertain this idea in this case - it's too far
off wrt. my ecos usage and experience.  And if the driver footprint is
small anyway - it might not be worth the effort.


Just my 3 cents (or is it only 2 ;-) )
  Kurt

P.S.:  Yes - I do use ecos.  But I inherited an ecos 1.3 which I keep
alive for the time being.  And which I have adapted to our latest HW -
with a 2-level cache architecture (Xscale 1 ==> Xscale 3).  Unfortunatly
(for ecos) my constraints are such that I can't contribute back much to
ecos - I'm too busy otherwise.

-----Original Message-----
From: ecos-patches-owner@ecos.sourceware.org
[mailto:ecos-patches-owner@ecos.sourceware.org] On Behalf Of John
Dallaway
Sent: Thursday, May 27, 2010 9:08 AM
To: Christophe Coutand
Cc: Sergei Gavrikov; ecos-patches@ecos.sourceware.org
Subject: Re: AT91 ADC support

Hi Christophe

Christophe Coutand wrote:

> It's pretty easy to add the required definition for the AT91M55800A
> targets. The only thing I see now is that this device contains 2 ADCs
> which I have not considered before. I guess there are several ways out
> of this:
> 
> 1- Update the actual AT91 ADC driver to make full use of the
AT91M55800A
> targets. I guess should be done by loading a second ADC instance (one
> for each ADC. I have not been through all the thinking here...).
> 
> 2- or limit the AT91 driver to use only ADC0 of the AT91M55800A target
> for the time being.
> 
> 3- or exclude AT91M55800A targets for the time being.
> 
> IMO #1 is best but I cannot give any time frame for completing it.

In that case, I would suggest option #2 for now. Someone else (who has
an AT91M55800A on their desk) may be interested in adding support for
the second ADC.

John Dallaway
eCos maintainer

^ permalink raw reply	[flat|nested] 18+ messages in thread

* RE: AT91 ADC support
  2010-05-27 15:44         ` Christophe Coutand
  2010-05-27 16:08           ` John Dallaway
@ 2010-05-27 16:37           ` Sergei Gavrikov
  2010-05-27 19:49             ` Christophe Coutand
  2010-05-27 21:37             ` Christophe Coutand
  1 sibling, 2 replies; 18+ messages in thread
From: Sergei Gavrikov @ 2010-05-27 16:37 UTC (permalink / raw)
  To: Christophe Coutand; +Cc: John Dallaway, eCos Patches

On Thu, 27 May 2010, Christophe Coutand wrote:
> Hi John,
>
> It's pretty easy to add the required definition for the AT91M55800A
> targets. The only thing I see now is that this device contains 2 ADCs
> which I have not considered before. I guess there are several ways out
> of this:
>
> 1- Update the actual AT91 ADC driver to make full use of the
> AT91M55800A targets. I guess should be done by loading a second ADC
> instance (one for each ADC. I have not been through all the thinking
> here...).
>
> 2- or limit the AT91 driver to use only ADC0 of the AT91M55800A target
> for the time being.
>
> 3- or exclude AT91M55800A targets for the time being.
>
> IMO #1 is best but I cannot give any time frame for completing it.

Hi Christophe, John

I would prefer #1, if you want I can add that in AT91/ADC CDL/sources.
One thing: I won't be able to test it on real hardware (only build
process can be tested me).

John, what do you think: Can we add the second ADC instance without a
testing?

> One additional weakness of the driver is that it is made for up to 8
> channels. It is defined nowhere what the targeted CPU can actually
> handle, this is left to the user when configuring eCos. I believe this
> is pretty fine since the user must anyway know which signal he wants to
> sample but you might disagree on that one.

I know only one target which would use all 8 channels :-) That's eCos
i386/Linux synthetic target.

Thanks for collaboration.

Sergei

> Regards,
> Christophe

^ permalink raw reply	[flat|nested] 18+ messages in thread

* RE: AT91 ADC support
  2010-05-27 16:37           ` Sergei Gavrikov
@ 2010-05-27 19:49             ` Christophe Coutand
  2010-05-27 21:44               ` Sergei Gavrikov
  2010-05-27 21:37             ` Christophe Coutand
  1 sibling, 1 reply; 18+ messages in thread
From: Christophe Coutand @ 2010-05-27 19:49 UTC (permalink / raw)
  To: Sergei Gavrikov; +Cc: John Dallaway, eCos Patches

[-- Attachment #1: Type: text/plain, Size: 2233 bytes --]

Hi Sergei,

I have attached an updated var_io.h that includes ADC support for the
AT91M55800A. I took the opportunity to define the number of channels per
ADC in this file. It can be overwritten per platform basis since
AT91SAM7L64 for instance has 4 channels only.

The definition of AT91_MAX_ADC_CHAN must be removed from
devs/adc/arm/at91/current/src/adc_at91.c. I have not joined any patch
for it since I will hopefully submit a new driver that support both
ADCs.

Christophe

-----Original Message-----
From: Sergei Gavrikov [mailto:sergei.gavrikov@gmail.com] 
Sent: 27. mai 2010 18:38
To: Christophe Coutand
Cc: John Dallaway; eCos Patches
Subject: RE: AT91 ADC support

On Thu, 27 May 2010, Christophe Coutand wrote:
> Hi John,
>
> It's pretty easy to add the required definition for the AT91M55800A
> targets. The only thing I see now is that this device contains 2 ADCs
> which I have not considered before. I guess there are several ways out
> of this:
>
> 1- Update the actual AT91 ADC driver to make full use of the
> AT91M55800A targets. I guess should be done by loading a second ADC
> instance (one for each ADC. I have not been through all the thinking
> here...).
>
> 2- or limit the AT91 driver to use only ADC0 of the AT91M55800A target
> for the time being.
>
> 3- or exclude AT91M55800A targets for the time being.
>
> IMO #1 is best but I cannot give any time frame for completing it.

Hi Christophe, John

I would prefer #1, if you want I can add that in AT91/ADC CDL/sources.
One thing: I won't be able to test it on real hardware (only build
process can be tested me).

John, what do you think: Can we add the second ADC instance without a
testing?

> One additional weakness of the driver is that it is made for up to 8
> channels. It is defined nowhere what the targeted CPU can actually
> handle, this is left to the user when configuring eCos. I believe this
> is pretty fine since the user must anyway know which signal he wants
to
> sample but you might disagree on that one.

I know only one target which would use all 8 channels :-) That's eCos
i386/Linux synthetic target.

Thanks for collaboration.

Sergei

> Regards,
> Christophe

[-- Attachment #2: at91_M55800A_var_io --]
[-- Type: application/octet-stream, Size: 1512 bytes --]

diff -r ae816c83f082 packages/hal/arm/at91/var/current/include/var_io.h
--- a/packages/hal/arm/at91/var/current/include/var_io.h	Tue May 11 16:26:19 2010 +0000
+++ b/packages/hal/arm/at91/var/current/include/var_io.h	Thu May 27 21:29:45 2010 +0200
@@ -2671,10 +2671,33 @@
 //=============================================================================
 // Analog to Digital Convertor (ADC)
 
+#if defined(CYGHWR_HAL_ARM_AT91SAM7) || \
+	            defined (CYGHWR_HAL_ARM_AT91_M55800A)
+
+// AT91SAM7 specifics
 #if defined(CYGHWR_HAL_ARM_AT91SAM7)
+#if !defined(AT91_ADC)
+#define AT91_ADC 0xFFFD8000
+#endif
 
-#ifndef AT91_ADC
-#define AT91_ADC 0xFFFD8000
+#if !defined(AT91_MAX_ADC_CHAN)
+#define AT91_MAX_ADC_CHAN 8
+#endif
+#endif
+
+// AT91_M55800A specifics
+#if defined(CYGHWR_HAL_ARM_AT91_M55800A)
+#if !defined(AT91_ADC)
+#define AT91_ADC 0xFFFB0000
+#endif
+
+#if !defined(AT91_ADC1)
+#define AT91_ADC1 0xFFFB4000
+#endif
+
+#if !defined(AT91_MAX_ADC_CHAN)
+#define AT91_MAX_ADC_CHAN 4
+#endif
 #endif
 
 #define AT91_ADC_CR    0x00 // Control
diff -r ae816c83f082 packages/hal/arm/at91/var/current/ChangeLog
--- a/packages/hal/arm/at91/var/current/ChangeLog	Tue May 11 16:26:19 2010 +0000
+++ b/packages/hal/arm/at91/var/current/ChangeLog	Thu May 27 21:32:38 2010 +0200
@@ -1,3 +1,6 @@
+2010-05-27 ccoutand <ccoutand@stmi.com>
+        * include/var_io.h: Added ADC defines for AT91_M55800A CPU
+
 2009-06-03 Oliver Munz <oli@snr.ch>
 
  	* Fix the a problem in the kernel delay_us, if the PIT is

^ permalink raw reply	[flat|nested] 18+ messages in thread

* RE: AT91 ADC support
  2010-05-27 16:37           ` Sergei Gavrikov
  2010-05-27 19:49             ` Christophe Coutand
@ 2010-05-27 21:37             ` Christophe Coutand
  1 sibling, 0 replies; 18+ messages in thread
From: Christophe Coutand @ 2010-05-27 21:37 UTC (permalink / raw)
  To: Sergei Gavrikov; +Cc: John Dallaway, eCos Patches

[-- Attachment #1: Type: text/plain, Size: 1870 bytes --]

Hi Sergei,

Here is the updated driver for supporting dual ADC. Let me know if this
is the way to go.

Regards,
Christophe

-----Original Message-----
From: Sergei Gavrikov [mailto:sergei.gavrikov@gmail.com] 
Sent: 27. mai 2010 18:38
To: Christophe Coutand
Cc: John Dallaway; eCos Patches
Subject: RE: AT91 ADC support

On Thu, 27 May 2010, Christophe Coutand wrote:
> Hi John,
>
> It's pretty easy to add the required definition for the AT91M55800A
> targets. The only thing I see now is that this device contains 2 ADCs
> which I have not considered before. I guess there are several ways out
> of this:
>
> 1- Update the actual AT91 ADC driver to make full use of the
> AT91M55800A targets. I guess should be done by loading a second ADC
> instance (one for each ADC. I have not been through all the thinking
> here...).
>
> 2- or limit the AT91 driver to use only ADC0 of the AT91M55800A target
> for the time being.
>
> 3- or exclude AT91M55800A targets for the time being.
>
> IMO #1 is best but I cannot give any time frame for completing it.

Hi Christophe, John

I would prefer #1, if you want I can add that in AT91/ADC CDL/sources.
One thing: I won't be able to test it on real hardware (only build
process can be tested me).

John, what do you think: Can we add the second ADC instance without a
testing?

> One additional weakness of the driver is that it is made for up to 8
> channels. It is defined nowhere what the targeted CPU can actually
> handle, this is left to the user when configuring eCos. I believe this
> is pretty fine since the user must anyway know which signal he wants
to
> sample but you might disagree on that one.

I know only one target which would use all 8 channels :-) That's eCos
i386/Linux synthetic target.

Thanks for collaboration.

Sergei

> Regards,
> Christophe

[-- Attachment #2: at91_adc_v3 --]
[-- Type: application/octet-stream, Size: 53760 bytes --]

diff -r ae816c83f082 packages/devs/adc/arm/at91/current/ChangeLog
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/packages/devs/adc/arm/at91/current/ChangeLog	Thu May 27 23:24:52 2010 +0200
@@ -0,0 +1,31 @@
+2010-05-18  ccoutand  <ccoutand@stmi.com>
+
+        * AT91 ADC driver package created
+        * cdl/adc_at91.cdl
+        * src/adc_at91.c
+        * include/adc_at91.inl
+        * tests/at91_adc_test.c
+
+//===========================================================================
+// ####GPLCOPYRIGHTBEGIN####                                                
+// -------------------------------------------                              
+// This file is part of eCos, the Embedded Configurable Operating System.   
+// Copyright (C) 2010 Free Software Foundation, Inc.                        
+//
+// This program 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.                                                           
+//
+// This program 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 this program; if not, write to the                            
+// Free Software Foundation, Inc., 51 Franklin Street,                      
+// Fifth Floor, Boston, MA  02110-1301, USA.                                
+// -------------------------------------------                              
+// ####GPLCOPYRIGHTEND####                                                  
+//===========================================================================
diff -r ae816c83f082 packages/devs/adc/arm/at91/current/cdl/adc_at91.cdl
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/packages/devs/adc/arm/at91/current/cdl/adc_at91.cdl	Thu May 27 23:24:59 2010 +0200
@@ -0,0 +1,354 @@
+# ====================================================================
+#
+#      adc_at91.cdl
+#
+#      eCos AT91 ADC configuration data
+#
+# ====================================================================
+## ####ECOSGPLCOPYRIGHTBEGIN####                                            
+## -------------------------------------------                              
+## This file is part of eCos, the Embedded Configurable Operating System.   
+## Copyright (C) 2008 Free Software Foundation, 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.,    
+## 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, 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 v2.                                               
+##
+## This exception does not invalidate any other reasons why a work based    
+## on this file might be covered by the GNU General Public License.         
+## -------------------------------------------                              
+## ####ECOSGPLCOPYRIGHTEND####                                              
+# ====================================================================
+######DESCRIPTIONBEGIN####
+#
+# Author(s):      ccoutand@stmi.com
+# Contributors:   
+# Date:           2010-02-12
+#
+#####DESCRIPTIONEND####
+#
+# ====================================================================
+
+
+cdl_package CYGPKG_DEVS_ADC_ARM_AT91 {
+    display     "ADC hardware device driver for AT91 family of ARM controllers"
+    
+    parent      CYGPKG_IO_ADC_DEVICES
+    active_if   CYGPKG_IO_ADC_DEVICES
+    active_if   CYGPKG_HAL_ARM_AT91
+    description " 
+           This package provides a generic ADC device driver for the on-chip
+           ADC peripherals in AT91 processors."
+           
+    include_dir cyg/io
+    compile     -library=libextras.a adc_at91.c
+    
+    define_proc {
+      puts $::cdl_system_header "#define CYGDAT_DEVS_ADC_ARM_AT91_INL <cyg/io/adc_at91.inl>"
+    }
+    
+    # 
+    # Primary ADC ( ADC0 )
+    #
+    cdl_component CYGPKG_DEVS_ADC_ARM_AT91_ADC0 {
+       display       "Atmel AT91 ADC port 0 driver"
+       flavor        bool
+       default_value 1
+       description "
+           This option includes the device driver for the on-chip ADC 0 of the
+           AT91 processors"
+    
+    
+       cdl_interface CYGINT_DEVS_ADC_ARM_AT91_ADC0_CHANNELS {
+          display "Number of ADC0 channels"
+       }  
+   
+       cdl_option CYGNUM_DEVS_ADC_ARM_AT91_ADC0_SELECT_TIMER {
+          display       "Interrupt priority"
+          flavor        data
+          legal_values {0 1 2}
+          default_value 1
+          description   "
+              This option selects the timer channel to be used for 
+              generating the sampling interval. Timer channel 0 can 
+              be assigned as Real Time Kernel clock so timer channel 
+              1 is set to be the default value."
+       }
+
+       cdl_option CYGNUM_DEVS_ADC_ARM_AT91_ADC0_PRESCAL {
+           display       "ADC clock setting"
+           flavor        data
+           legal_values  0 to 255
+           default_value 128
+           description   "
+               This option sets the AT91 ADC PRESCAL value. 
+               ADCClock = MCK / ((PRESCAL + 1) * 2)"
+       }
+
+       cdl_option CYGNUM_DEVS_ADC_ARM_AT91_ADC0_STARTUP_TIME {
+           display       "ADC start-up time"
+           flavor        data
+           legal_values  0 to 255
+           default_value 128
+           description   "
+               This option sets the AT91 ADC start-up time value. 
+               ADC start-up time = (STARTUP+1) * 8 / ADCClock"
+       }
+
+       cdl_option CYGNUM_DEVS_ADC_ARM_AT91_ADC0_SHTIM {
+           display       "ADC start up time"
+           flavor        data
+           legal_values  0 to 15
+           default_value 7
+           description   "
+               This option sets the AT91 ADC Sample and Hold Time. 
+               Sample and Hold Time = SHTIM / ADCClock"
+       }
+
+       cdl_option CYGNUM_DEVS_ADC_ARM_AT91_ADC0_INTPRIO {
+           display       "Interrupt priority"
+           flavor        data
+           legal_values  0 to 15
+           default_value 15
+           description   "
+               This option selects the interrupt priority for the ADC
+               interrupts.  Timer x is used for generating the sample
+               clock. So this option configures the interrupt priority
+               for timer x. There are 16 priority levels corresponding to
+               the values 0 through 15 decimal, of which 15 is the lowest
+               priority. The reset value of these registers defaults all
+               interrupts to the lowest priority, allowing a single write
+               to elevate the priority of an individual interrupt."
+       }
+
+       cdl_option CYGNUM_DEVS_ADC_ARM_AT91_ADC0_DEFAULT_RATE {
+           display "Default sample rate"
+           flavor   data
+           legal_values 1 to 10000
+           default_value 100
+           description "
+               The driver will be initialized with the default sample rate.
+               If you raise the default sample rate you might need to increase
+               the buffer size for each channel."
+       }
+                
+       # Support up to 8 ADC channels
+       for { set ::channel 0 } { $::channel < 8 } { incr ::channel } {  
+    
+           cdl_component CYGPKG_DEVS_ADC_ARM_AT91_ADC0_CHANNEL[set ::channel] {
+               display        "Access ADC channel [set ::channel]"
+               flavor          bool
+               default_value   [set ::channel] == 0
+               implements      CYGINT_DEVS_ADC_ARM_AT91_ADC0_CHANNELS
+               description "
+                   If the application needs to access the on-chip ADC
+                   channel [set ::channel] via an eCos ADC driver then
+                   this option should be enabled."
+     
+               cdl_option CYGDAT_DEVS_ADC_ARM_AT91_ADC0_CHANNEL[set ::channel]_NAME {
+                   display "Device name"
+                   flavor      data
+                   default_value   [format {"\"/dev/adc0%d\""} $::channel]
+                   description "
+                       This option controls the name that an eCos application
+                       should use to access this device via cyg_io_lookup(),
+                       open(), or similar calls."
+               }
+        
+               cdl_option CYGDAT_DEVS_ADC_ARM_AT91_ADC0_CHANNEL[set ::channel]_BUFSIZE {
+                   display "Size of data buffer"
+                   flavor  data
+                   legal_values  0x01 to 0x2000000
+                   default_value 512
+                   description "
+                       This option controls the number of samples the
+                       buffer can store. The required RAM depends on the
+                       sample size and on the number of samples. If the
+                       sample size is <= 8 bit the the required RAM =
+                       size of data buffer. If the sample size is 9 or 10
+                       bit then required RAM = size of data buffer * 2."
+               } 
+           } 
+        }
+     }
+     
+    # 
+    # ADC1
+    #
+    cdl_component CYGPKG_DEVS_ADC_ARM_AT91_ADC1 {
+       display       "Atmel AT91 ADC port 1 driver"
+       flavor        bool
+       default_value 0
+       
+       requires      { CYGHWR_HAL_ARM_AT91 == "M55800A" }
+       
+       description "
+           This option includes the device driver for the on-chip ADC 1 of the
+           AT91 processors"
+    
+    
+       cdl_interface CYGINT_DEVS_ADC_ARM_AT91_ADC1_CHANNELS {
+          display "Number of ADC1 channels"
+       }  
+   
+       cdl_option CYGNUM_DEVS_ADC_ARM_AT91_ADC1_SELECT_TIMER {
+          display       "Interrupt priority"
+          flavor        data
+          legal_values {0 1 2}
+          default_value 2
+          description   "
+              This option selects the timer channel to be used for 
+              generating the sampling interval. Timer channel 0 can 
+              be assigned as Real Time Kernel clock so timer channel 
+              1 is set to be the default value."
+       }
+
+       cdl_option CYGNUM_DEVS_ADC_ARM_AT91_ADC1_PRESCAL {
+           display       "ADC clock setting"
+           flavor        data
+           legal_values  0 to 255
+           default_value 128
+           description   "
+               This option sets the AT91 ADC PRESCAL value. 
+               ADCClock = MCK / ((PRESCAL + 1) * 2)"
+       }
+
+       cdl_option CYGNUM_DEVS_ADC_ARM_AT91_ADC1_STARTUP_TIME {
+           display       "ADC start-up time"
+           flavor        data
+           legal_values  0 to 255
+           default_value 128
+           description   "
+               This option sets the AT91 ADC start-up time value. 
+               ADC start-up time = (STARTUP+1) * 8 / ADCClock"
+       }
+
+       cdl_option CYGNUM_DEVS_ADC_ARM_AT91_ADC1_SHTIM {
+           display       "ADC start up time"
+           flavor        data
+           legal_values  0 to 15
+           default_value 7
+           description   "
+               This option sets the AT91 ADC Sample and Hold Time. 
+               Sample and Hold Time = SHTIM / ADCClock"
+       }
+
+       cdl_option CYGNUM_DEVS_ADC_ARM_AT91_ADC1_INTPRIO {
+           display       "Interrupt priority"
+           flavor        data
+           legal_values  0 to 15
+           default_value 15
+           description   "
+               This option selects the interrupt priority for the ADC
+               interrupts.  Timer x is used for generating the sample
+               clock. So this option configures the interrupt priority
+               for timer x. There are 16 priority levels corresponding to
+               the values 0 through 15 decimal, of which 15 is the lowest
+               priority. The reset value of these registers defaults all
+               interrupts to the lowest priority, allowing a single write
+               to elevate the priority of an individual interrupt."
+       }
+
+       cdl_option CYGNUM_DEVS_ADC_ARM_AT91_ADC1_DEFAULT_RATE {
+           display "Default sample rate"
+           flavor   data
+           legal_values 1 to 10000
+           default_value 100
+           description "
+               The driver will be initialized with the default sample rate.
+               If you raise the default sample rate you might need to increase
+               the buffer size for each channel."
+       }
+                
+       # Support up to 8 ADC channels
+       for { set ::channel 0 } { $::channel < 8 } { incr ::channel } {  
+    
+           cdl_component CYGPKG_DEVS_ADC_ARM_AT91_ADC1_CHANNEL[set ::channel] {
+               display        "Access ADC channel [set ::channel]"
+               flavor          bool
+               default_value   [set ::channel] == 0
+               implements      CYGINT_DEVS_ADC_ARM_AT91_ADC1_CHANNELS
+               description "
+                   If the application needs to access the on-chip ADC
+                   channel [set ::channel] via an eCos ADC driver then
+                   this option should be enabled."
+     
+               cdl_option CYGDAT_DEVS_ADC_ARM_AT91_ADC1_CHANNEL[set ::channel]_NAME {
+                   display "Device name"
+                   flavor      data
+                   default_value   [format {"\"/dev/adc1%d\""} $::channel]
+                   description "
+                       This option controls the name that an eCos application
+                       should use to access this device via cyg_io_lookup(),
+                       open(), or similar calls."
+               }
+        
+               cdl_option CYGDAT_DEVS_ADC_ARM_AT91_ADC1_CHANNEL[set ::channel]_BUFSIZE {
+                   display "Size of data buffer"
+                   flavor  data
+                   legal_values  0x01 to 0x2000000
+                   default_value 512
+                   description "
+                       This option controls the number of samples the
+                       buffer can store. The required RAM depends on the
+                       sample size and on the number of samples. If the
+                       sample size is <= 8 bit the the required RAM =
+                       size of data buffer. If the sample size is 9 or 10
+                       bit then required RAM = size of data buffer * 2."
+               } 
+           } 
+        }
+     }     
+     
+     cdl_option CYGPKG_DEVS_ADC_ARM_AT91_DEBUG_LEVEL {
+         display "Driver debug output level"
+         flavor  data
+         legal_values {0 1}
+         default_value 0
+         description   "
+              This option specifies the level of debug data output by
+              the AT91 ADC device driver. A value of 0 signifies
+              no debug data output; 1 signifies normal debug data
+              output. If an overrun occurred then this can only be
+              detected by debug output messages."         
+     }     
+
+     cdl_component CYGSEM_DEVS_ADC_ARM_AT91_SAMPLE_SIZE_LIMIT {
+         display       "Sample size limit"
+         flavor          bool
+         calculated    1
+         requires      { ( CYGNUM_IO_ADC_SAMPLE_SIZE == 8 )
+                            || ( CYGNUM_IO_ADC_SAMPLE_SIZE == 10 ) }
+         description   "
+             Tell user about AT91 ADC sample size limitation."
+     }
+
+    cdl_option CYGPKG_DEVS_ADC_ARM_AT91_TESTS {
+        display "Tests for AT91 ADC driver"
+        flavor  data
+        no_define
+        calculated { "tests/at91_adc_test" }
+        description   "
+            This option specifies the set of tests for the AT91
+            ADC device driver."
+    }
+
+}
diff -r ae816c83f082 packages/devs/adc/arm/at91/current/include/adc_at91.inl
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/packages/devs/adc/arm/at91/current/include/adc_at91.inl	Thu May 27 23:25:09 2010 +0200
@@ -0,0 +1,200 @@
+//==========================================================================
+//
+//      adc_at91.inl
+//
+//      ADC driver for AT91 on chip ADC
+//
+//==========================================================================
+// ####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 2008 Free Software Foundation, 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.,
+// 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, 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 v2.
+//
+// This exception does not invalidate any other reasons why a work based
+// on this file might be covered by the GNU General Public License.
+// -------------------------------------------
+// ####ECOSGPLCOPYRIGHTEND####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s):    Atmel AT91 on-chip ADC device driver, ccoutand
+//              
+// Contributors:
+// Date:         2010-05-27
+// Purpose:
+// Description:
+//
+//####DESCRIPTIONEND####
+//
+//==========================================================================
+
+#ifndef CYGONCE_DEVS_ADC_ARM_AT91_INL
+#define CYGONCE_DEVS_ADC_ARM_AT91_INL
+
+// Some AT91 HAL are defining the timer 0 vector as TC0 and other as TIMER0
+#ifndef CYGNUM_HAL_INTERRUPT_TC0
+#define CYGNUM_HAL_INTERRUPT_TC0 CYGNUM_HAL_INTERRUPT_TIMER0
+#endif
+
+// Declare ADC0
+#ifdef CYGPKG_DEVS_ADC_ARM_AT91_ADC0
+
+static at91_adc_info at91_adc0_info =
+{
+    .adc_base         = AT91_ADC,
+    .timer_base       = AT91_TC,
+    .tc_base          = AT91_TC + (AT91_TC_TC_SIZE * CYGNUM_DEVS_ADC_ARM_AT91_ADC0_SELECT_TIMER),
+    .timer_vector     = CYGNUM_HAL_INTERRUPT_TC0 + CYGNUM_DEVS_ADC_ARM_AT91_ADC0_SELECT_TIMER,
+    .timer_intprio    = CYGNUM_DEVS_ADC_ARM_AT91_ADC0_INTPRIO,
+    .timer_id         = CYGNUM_DEVS_ADC_ARM_AT91_ADC0_SELECT_TIMER,
+    .int_handle       = 0,
+    .adc_prescal      = CYGNUM_DEVS_ADC_ARM_AT91_ADC0_PRESCAL,
+    .adc_startup_time = CYGNUM_DEVS_ADC_ARM_AT91_ADC0_STARTUP_TIME,
+    .adc_shtim        = CYGNUM_DEVS_ADC_ARM_AT91_ADC0_SHTIM,
+#if CYGNUM_IO_ADC_SAMPLE_SIZE > 8
+     .resolution      = AT91_ADC_MR_LOWREC_10BITS,
+#else
+     .resolution      = AT91_ADC_MR_LOWRES_8BITS,
+#endif
+    .chan_mask        = 0
+};
+
+CYG_ADC_DEVICE( at91_adc0_device,
+                &at91_adc_funs,
+                &at91_adc0_info,
+                CYGNUM_DEVS_ADC_ARM_AT91_ADC0_DEFAULT_RATE);
+
+#define AT91_ADC0_CHANNEL( __chan )                                        \
+CYG_ADC_CHANNEL( at91_adc0_channel##__chan,                                \
+                 __chan,                                                   \
+                 CYGDAT_DEVS_ADC_ARM_AT91_ADC0_CHANNEL##__chan##_BUFSIZE,  \
+                 &at91_adc0_device );                                       \
+                                                                           \
+DEVTAB_ENTRY( at91_adc0_channel##__chan##_device,                          \
+              CYGDAT_DEVS_ADC_ARM_AT91_ADC0_CHANNEL##__chan##_NAME,        \
+              0,                                                           \
+              &cyg_io_adc_devio,                                           \
+              at91_adc_init,                                               \
+              at91_adc_lookup,                                             \
+              &at91_adc0_channel##__chan );
+
+#ifdef CYGPKG_DEVS_ADC_ARM_AT91_ADC0_CHANNEL0
+AT91_ADC0_CHANNEL(0);
+#endif
+#ifdef CYGPKG_DEVS_ADC_ARM_AT91_ADC0_CHANNEL1
+AT91_ADC0_CHANNEL(1);
+#endif
+#ifdef CYGPKG_DEVS_ADC_ARM_AT91_ADC0_CHANNEL2
+AT91_ADC0_CHANNEL(2);
+#endif
+#ifdef CYGPKG_DEVS_ADC_ARM_AT91_ADC0_CHANNEL3
+AT91_ADC0_CHANNEL(3);
+#endif
+#ifdef CYGPKG_DEVS_ADC_ARM_AT91_ADC0_CHANNEL4
+AT91_ADC0_CHANNEL(4);
+#endif
+#ifdef CYGPKG_DEVS_ADC_ARM_AT91_ADC0_CHANNEL5
+AT91_ADC0_CHANNEL(5);
+#endif
+#ifdef CYGPKG_DEVS_ADC_ARM_AT91_ADC0_CHANNEL6
+AT91_ADC0_CHANNEL(6);
+#endif
+#ifdef CYGPKG_DEVS_ADC_ARM_AT91_ADC0_CHANNEL7
+AT91_ADC0_CHANNEL(7);
+#endif
+
+#endif // CYGPKG_DEVS_ADC_ARM_AT91_ADC0
+
+
+
+// Declare ADC1
+#ifdef CYGPKG_DEVS_ADC_ARM_AT91_ADC1
+
+static at91_adc_info at91_adc1_info =
+{
+    .adc_base         = AT91_ADC1,
+    .timer_base       = AT91_TC,
+    .tc_base          = AT91_TC + (AT91_TC_TC_SIZE * CYGNUM_DEVS_ADC_ARM_AT91_ADC1_SELECT_TIMER),
+    .timer_vector     = CYGNUM_HAL_INTERRUPT_TC0 + CYGNUM_DEVS_ADC_ARM_AT91_ADC1_SELECT_TIMER,
+    .timer_intprio    = CYGNUM_DEVS_ADC_ARM_AT91_ADC1_INTPRIO,
+    .timer_id         = CYGNUM_DEVS_ADC_ARM_AT91_ADC1_SELECT_TIMER,
+    .int_handle       = 0,
+    .adc_prescal      = CYGNUM_DEVS_ADC_ARM_AT91_ADC1_PRESCAL,
+    .adc_startup_time = CYGNUM_DEVS_ADC_ARM_AT91_ADC1_STARTUP_TIME,
+    .adc_shtim        = CYGNUM_DEVS_ADC_ARM_AT91_ADC1_SHTIM,
+#if CYGNUM_IO_ADC_SAMPLE_SIZE > 8
+     .resolution      = AT91_ADC_MR_LOWREC_10BITS,
+#else
+     .resolution      = AT91_ADC_MR_LOWRES_8BITS,
+#endif
+    .chan_mask        = 0
+};
+CYG_ADC_DEVICE( at91_adc1_device,
+                &at91_adc_funs,
+                &at91_adc1_info,
+                CYGNUM_DEVS_ADC_ARM_AT91_ADC1_DEFAULT_RATE);
+
+#define AT91_ADC1_CHANNEL( __chan )                                        \
+CYG_ADC_CHANNEL( at91_adc1_channel##__chan,                                \
+                 __chan,                                                   \
+                 CYGDAT_DEVS_ADC_ARM_AT91_ADC1_CHANNEL##__chan##_BUFSIZE,  \
+                 &at91_adc1_device );                                       \
+                                                                           \
+DEVTAB_ENTRY( at91_adc1_channel##__chan##_device,                          \
+              CYGDAT_DEVS_ADC_ARM_AT91_ADC1_CHANNEL##__chan##_NAME,        \
+              0,                                                           \
+              &cyg_io_adc_devio,                                           \
+              at91_adc_init,                                               \
+              at91_adc_lookup,                                             \
+              &at91_adc1_channel##__chan );
+
+#ifdef CYGPKG_DEVS_ADC_ARM_AT91_ADC1_CHANNEL0
+AT91_ADC1_CHANNEL(0);
+#endif
+#ifdef CYGPKG_DEVS_ADC_ARM_AT91_ADC1_CHANNEL1
+AT91_ADC1_CHANNEL(1);
+#endif
+#ifdef CYGPKG_DEVS_ADC_ARM_AT91_ADC1_CHANNEL2
+AT91_ADC1_CHANNEL(2);
+#endif
+#ifdef CYGPKG_DEVS_ADC_ARM_AT91_ADC1_CHANNEL3
+AT91_ADC1_CHANNEL(3);
+#endif
+#ifdef CYGPKG_DEVS_ADC_ARM_AT91_ADC1_CHANNEL4
+AT91_ADC1_CHANNEL(4);
+#endif
+#ifdef CYGPKG_DEVS_ADC_ARM_AT91_ADC1_CHANNEL5
+AT91_ADC1_CHANNEL(5);
+#endif
+#ifdef CYGPKG_DEVS_ADC_ARM_AT91_ADC1_CHANNEL6
+AT91_ADC1_CHANNEL(6);
+#endif
+#ifdef CYGPKG_DEVS_ADC_ARM_AT91_ADC1_CHANNEL7
+AT91_ADC1_CHANNEL(7);
+#endif
+
+#endif // CYGPKG_DEVS_ADC_ARM_AT91_ADC1
+
+#endif // CYGONCE_DEVS_ADC_ARM_AT91_INL
diff -r ae816c83f082 packages/devs/adc/arm/at91/current/src/adc_at91.c
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/packages/devs/adc/arm/at91/current/src/adc_at91.c	Thu May 27 23:25:14 2010 +0200
@@ -0,0 +1,457 @@
+//==========================================================================
+//
+//      adc_at91.c
+//
+//      ADC driver for AT91 on chip ADC
+//
+//==========================================================================
+// ####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 2008 Free Software Foundation, 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.,
+// 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, 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 v2.
+//
+// This exception does not invalidate any other reasons why a work based
+// on this file might be covered by the GNU General Public License.
+// -------------------------------------------
+// ####ECOSGPLCOPYRIGHTEND####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s):   Uwe Kindler <uwe_kindler@web.de>
+//              Updated for Atmel AT91 device, ccoutand <ccoutand@stmi.com>
+// Contributors:
+// Date:         2010-02-15
+// Purpose:
+// Description:
+//
+//####DESCRIPTIONEND####
+//
+//==========================================================================
+
+
+//==========================================================================
+//                                 INCLUDES
+//==========================================================================
+#include <pkgconf/system.h>
+#include <pkgconf/devs_adc_arm_at91.h>
+
+#include <cyg/infra/cyg_type.h>
+#include <cyg/infra/cyg_ass.h>
+#include <cyg/infra/diag.h>
+#include <cyg/io/adc.h>
+#include <cyg/hal/hal_arch.h>
+#include <cyg/hal/hal_io.h>
+#include <cyg/hal/hal_intr.h>
+#include <cyg/hal/drv_api.h>
+
+#if CYGPKG_DEVS_ADC_ARM_AT91_DEBUG_LEVEL > 0
+   #define at91_adc_printf(args...) diag_printf(args)
+#else
+   #define at91_adc_printf(args...)
+#endif
+
+#define AT91_ADC_CHER_CHx(_ch_)  (0x1 << _ch_)
+#define AT91_ADC_CHER_CDRx(_ch_) (_ch_ << 2)
+
+//==========================================================================
+//                                  DATA TYPES
+//==========================================================================
+typedef struct at91_adc_info
+{
+    cyg_uint32              adc_base;          // base address of ADC peripheral
+    cyg_uint8               adc_prescal;       // ADC prescal value
+    cyg_uint8               adc_startup_time;  // ADC Startup Time value
+    cyg_uint8               adc_shtim;         // ADC SHTIM value
+    cyg_uint8               timer_id;          // select timer
+    cyg_uint32              timer_base;        // base address of Timer peripheral
+    cyg_uint32              tc_base;           // base address of Timer channel
+    cyg_vector_t            timer_vector;      // interrupt vector number
+    int                     timer_intprio;     // interrupt priority of ADC interrupt
+    cyg_uint32              timer_cnt;         // Timer value
+    cyg_uint8               timer_clk;         // Timer clock setting
+    cyg_uint32              resolution;
+    cyg_handle_t            int_handle;        // For initializing the interrupt
+    cyg_interrupt           int_data;
+    struct cyg_adc_channel *channel[AT91_MAX_ADC_CHAN]; // stores references to channel objects
+    cyg_uint8               chan_mask;         // mask that indicates channels used
+                                               // by ADC driver
+} at91_adc_info;
+
+
+//==========================================================================
+//                               DECLARATIONS
+//==========================================================================
+static bool at91_adc_init(struct cyg_devtab_entry *tab);
+static Cyg_ErrNo at91_adc_lookup(struct cyg_devtab_entry **tab,
+                                    struct cyg_devtab_entry  *sub_tab,
+                                    const char               *name);
+static void at91_adc_enable( cyg_adc_channel *chan );
+static void at91_adc_disable( cyg_adc_channel *chan );
+static void at91_adc_set_rate( cyg_adc_channel *chan, cyg_uint32 rate );
+static cyg_uint32 at91_adc_isr(cyg_vector_t vector, cyg_addrword_t data);
+static void at91_adc_dsr(cyg_vector_t vector,
+                            cyg_ucount32 count,
+                            cyg_addrword_t data);
+
+// -------------------------------------------------------------------------
+// Driver functions:
+CYG_ADC_FUNCTIONS( at91_adc_funs,
+                   at91_adc_enable,
+                   at91_adc_disable,
+                   at91_adc_set_rate );
+
+
+#include CYGDAT_DEVS_ADC_ARM_AT91_INL // Instantiate ADCs
+
+//==========================================================================
+// This function is called from the device IO infrastructure to initialize
+// the device. It should perform any work needed to start up the device,
+// short of actually starting the generation of samples. This function will
+// be called for each channel, so if there is initialization that only needs
+// to be done once, such as creating and interrupt object, then care should
+// be taken to do this. This function should also call cyg_adc_device_init()
+// to initialize the generic parts of the driver.
+//==========================================================================
+static bool at91_adc_init(struct cyg_devtab_entry *tab)
+{
+    cyg_adc_channel *chan   = (cyg_adc_channel *)tab->priv;
+    cyg_adc_device *device  = chan->device;
+    at91_adc_info *info     = device->dev_priv;
+    cyg_uint32 regval;
+
+    if (!info->int_handle)
+    {
+       cyg_drv_interrupt_create(info->timer_vector,
+                                 info->timer_intprio,
+                                (cyg_addrword_t)device,
+                                &at91_adc_isr,
+                                &at91_adc_dsr,
+                                &(info->int_handle),
+                                &(info->int_data));
+       cyg_drv_interrupt_attach(info->int_handle);
+       cyg_drv_interrupt_mask(info->timer_vector);
+
+       // Reset ADC
+       HAL_WRITE_UINT32((info->adc_base + AT91_ADC_CR), AT91_ADC_CR_SWRST);
+
+       // Disable counter interrupts
+       HAL_WRITE_UINT32(info->tc_base+AT91_TC_CCR, AT91_TC_CCR_CLKDIS);
+       HAL_WRITE_UINT32(info->tc_base+AT91_TC_IDR, 0xffffffff);
+
+       // Clear status bit
+       HAL_READ_UINT32(info->tc_base + AT91_TC_SR, regval);
+
+       // Enable peripheral clocks for TC
+       HAL_WRITE_UINT32(AT91_PMC+AT91_PMC_PCER,  \
+             ((AT91_PMC_PCER_TC0) << info->timer_id));
+
+       //
+       // Disable all interrupts, all channels
+       //
+       HAL_WRITE_UINT32((info->adc_base + AT91_ADC_CHDR), \
+                     AT91_ADC_CHER_CH0  |\
+                     AT91_ADC_CHER_CH1  |\
+                     AT91_ADC_CHER_CH2  |\
+                     AT91_ADC_CHER_CH3  |\
+                     AT91_ADC_CHER_CH4  |\
+                     AT91_ADC_CHER_CH5  |\
+                     AT91_ADC_CHER_CH6  |\
+                     AT91_ADC_CHER_CH7);
+       HAL_WRITE_UINT32((info->adc_base + AT91_ADC_IDR), \
+                     AT91_ADC_CHER_CH0  |\
+                     AT91_ADC_CHER_CH1  |\
+                     AT91_ADC_CHER_CH2  |\
+                     AT91_ADC_CHER_CH3  |\
+                     AT91_ADC_CHER_CH4  |\
+                     AT91_ADC_CHER_CH5  |\
+                     AT91_ADC_CHER_CH6  |\
+                     AT91_ADC_CHER_CH7);
+
+       //
+       // setup the default sample rate
+       //
+       at91_adc_set_rate(chan, chan->device->config.rate);
+
+       // setup ADC mode
+       HAL_WRITE_UINT32((info->adc_base + AT91_ADC_MR), \
+                    ( ( info->adc_prescal  << AT91_ADC_MR_PRESCAL_SHIFT ) & \
+                        AT91_ADC_MR_PRESCAL_MASK ) | \
+                    ( ( info->adc_startup_time   << AT91_ADC_MR_STARTUP_SHIFT ) & \
+                        AT91_ADC_MR_STARTUP_MASK ) | \
+                    ( (  info->adc_shtim << AT91_ADC_MR_SHTIM_SHIFT ) & \
+                        AT91_ADC_MR_SHTIM_MASK ) | \
+                        AT91_ADC_MR_TRGSEL_TIOA0  | \
+                        info->resolution);
+
+
+    } // if (!info->int_handle)
+
+    cyg_adc_device_init(device); // initialize generic parts of driver
+
+    return true;
+}
+
+
+//==========================================================================
+// This function is called when a client looks up or opens a channel. It
+// should call cyg_adc_channel_init() to initialize the generic part of
+// the channel. It should also perform any operations needed to start the
+// channel generating samples.
+//==========================================================================
+static Cyg_ErrNo at91_adc_lookup(struct cyg_devtab_entry **tab,
+                                    struct cyg_devtab_entry  *sub_tab,
+                                    const char               *name)
+{
+    cyg_adc_channel  *chan     = (cyg_adc_channel *)(*tab)->priv;
+    at91_adc_info *info     = chan->device->dev_priv;
+
+    info->channel[chan->channel] = chan;
+    cyg_adc_channel_init(chan); // initialize generic parts of channel
+
+    //
+    // The generic ADC manual says: When a channel is first looked up or
+    // opened, then it is automatically enabled and samples start to
+    // accumulate - so we start the channel now
+    //
+    chan->enabled = true;
+    at91_adc_enable(chan);
+
+    return ENOERR;
+}
+
+
+//==========================================================================
+// This function is called from the generic ADC package to enable the
+// channel in response to a CYG_IO_SET_CONFIG_ADC_ENABLE config operation.
+// It should take any steps needed to start the channel generating samples
+//==========================================================================
+static void at91_adc_enable(cyg_adc_channel *chan)
+{
+    at91_adc_info *info      = chan->device->dev_priv;
+
+    // Enable the channel
+    HAL_WRITE_UINT32((info->adc_base + AT91_ADC_CHER), \
+                      AT91_ADC_CHER_CHx(chan->channel));
+
+    //
+    // Unmask interrupt as soon as 1 channel is enable
+    //
+    if (!info->chan_mask)
+    {
+       cyg_drv_interrupt_unmask(info->timer_vector);
+
+       // Enable timer interrupt
+       HAL_WRITE_UINT32(info->tc_base+AT91_TC_IER, AT91_TC_IER_CPC);
+
+       // Enable the clock
+       HAL_WRITE_UINT32(info->tc_base+AT91_TC_CCR, AT91_TC_CCR_TRIG | AT91_TC_CCR_CLKEN);
+
+       // Start timer
+       HAL_WRITE_UINT32(info->tc_base+AT91_TC_CCR,  AT91_TC_CCR_TRIG);
+
+       // Start ADC sampling
+       HAL_WRITE_UINT32((info->adc_base + AT91_ADC_CR), AT91_ADC_CR_START);
+
+    }
+
+    info->chan_mask |= AT91_ADC_CHER_CHx(chan->channel);
+
+}
+
+
+//==========================================================================
+// This function is called from the generic ADC package to enable the
+// channel in response to a CYG_IO_SET_CONFIG_ADC_DISABLE config operation.
+// It should take any steps needed to stop the channel generating samples.
+//==========================================================================
+static void at91_adc_disable(cyg_adc_channel *chan)
+{
+    at91_adc_info *info  = chan->device->dev_priv;
+    cyg_uint32 sr;
+
+    info->chan_mask &= ~ AT91_ADC_CHER_CHx(chan->channel);
+
+    // Disable the channel
+    HAL_WRITE_UINT32((info->adc_base + AT91_ADC_CHDR), \
+                      AT91_ADC_CHER_CHx(chan->channel));
+
+    //
+    // If no channel is enabled the we disable interrupts now
+    //
+    if (!info->chan_mask)
+    {
+       cyg_drv_interrupt_mask(info->timer_vector);
+
+       // Clear interrupt
+       HAL_READ_UINT32(info->tc_base+AT91_TC_SR, sr);
+
+       // Disable  timer interrupt
+       HAL_WRITE_UINT32(info->tc_base+AT91_TC_IDR, AT91_TC_IER_CPC);
+
+       // Disable the clock
+       HAL_WRITE_UINT32(info->tc_base+AT91_TC_CCR, AT91_TC_CCR_CLKDIS);
+
+    }
+}
+
+
+//==========================================================================
+// This function is called from the generic ADC package to enable the
+// channel in response to a CYG_IO_SET_CONFIG_ADC_RATE config operation.
+// It should take any steps needed to change the sample rate of the channel,
+// or of the entire device.
+// We use a timer channel to generate the interrupts for sampling the
+// analog channels
+//==========================================================================
+static void at91_adc_set_rate( cyg_adc_channel *chan, cyg_uint32 rate)
+{
+    cyg_adc_device   *device = chan->device;
+    at91_adc_info *info   = (at91_adc_info *)device->dev_priv;
+    cyg_uint8 timer_clk   = AT91_TC_CMR_CLKS_MCK2;
+    cyg_uint32 tmr_period = CYGNUM_HAL_ARM_AT91_CLOCK_SPEED / ( rate << 1);
+
+    if( tmr_period > 0xffff )
+    {
+       tmr_period = CYGNUM_HAL_ARM_AT91_CLOCK_SPEED / ( rate << 5);
+       timer_clk  = AT91_TC_CMR_CLKS_MCK32;
+    }
+
+    if( tmr_period > 0xffff )
+    {
+       tmr_period = CYGNUM_HAL_ARM_AT91_CLOCK_SPEED / ( rate << 7);
+       timer_clk  = AT91_TC_CMR_CLKS_MCK128;
+    }
+
+    if( tmr_period > 0xffff )
+    {
+       tmr_period = CYGNUM_HAL_ARM_AT91_CLOCK_SPEED / ( rate << 10);
+       timer_clk  = AT91_TC_CMR_CLKS_MCK1024;
+    }
+
+    if( tmr_period > 0xffff )
+    {
+       tmr_period = 0xffff;
+       timer_clk  = AT91_TC_CMR_CLKS_MCK1024;
+       at91_adc_printf("AT91 ADC timer, rate too high!");
+    }
+
+    device->config.rate = rate;
+    info->timer_clk = timer_clk;
+    info->timer_cnt = tmr_period;
+
+    // Set timer values
+    HAL_WRITE_UINT32(info->tc_base+AT91_TC_CMR,  AT91_TC_CMR_CPCTRG | info->timer_clk);
+    HAL_WRITE_UINT32(info->tc_base+AT91_TC_RC,  info->timer_cnt);
+
+    at91_adc_printf("AT91 ADC Timer settings %d, %d", info->timer_clk, info->timer_cnt);
+
+    return;
+}
+
+
+//==========================================================================
+// This function is the ISR attached to the ADC device's interrupt vector.
+// It is responsible for reading samples from the channels and passing them
+// on to the generic layer. It needs to check each channel for data, and call
+// cyg_adc_receive_sample() for each new sample available, and then ready the
+// device for the next interrupt.
+//==========================================================================
+static cyg_uint32 at91_adc_isr(cyg_vector_t vector, cyg_addrword_t data)
+{
+    cyg_adc_device   *device = (cyg_adc_device *) data;
+    at91_adc_info *info   = (at91_adc_info *)device->dev_priv;
+    cyg_uint32        regval,  adc_status;
+    cyg_uint32        res = 0;
+    cyg_adc_sample_t  adcdata;
+    cyg_uint32 sr;
+
+    cyg_uint8 active_channels = info->chan_mask;
+    cyg_uint8 channel_no = 0;
+
+    // Clear timer interrupt
+    HAL_READ_UINT32(info->tc_base+AT91_TC_SR, sr);
+
+    // Check on channel conversion done
+    HAL_READ_UINT32(info->adc_base + AT91_ADC_SR, adc_status);
+
+    while (active_channels)
+    {
+        if (active_channels & 0x01)
+        {
+            // If ADC conversion done, save sample
+            if(adc_status & AT91_ADC_CHER_CHx(channel_no))
+            {
+              HAL_READ_UINT32((info->adc_base + AT91_ADC_CDR0 + AT91_ADC_CHER_CDRx(channel_no)), regval);
+              adcdata = regval & 0x3FF;
+              res |= CYG_ISR_HANDLED
+                |  cyg_adc_receive_sample(info->channel[channel_no],
+                                          adcdata);
+            }
+        } // if (active_channels & 0x01)
+        active_channels >>= 1;
+        channel_no++;
+    } // while (active_channels)
+
+    // Restart sampling
+    HAL_WRITE_UINT32((info->adc_base + AT91_ADC_CR), AT91_ADC_CR_START);
+
+    cyg_drv_interrupt_acknowledge(info->timer_vector);
+
+    return res;
+}
+
+
+//==========================================================================
+// This function is the DSR attached to the ADC device's interrupt vector.
+// It is called by the kernel if the ISR return value contains the
+// CYG_ISR_HANDLED bit. It needs to call cyg_adc_wakeup() for each channel
+// that has its wakeup field set.
+//==========================================================================
+static void at91_adc_dsr(cyg_vector_t vector,
+                            cyg_ucount32 count,
+                            cyg_addrword_t data)
+{
+    cyg_adc_device   *device          = (cyg_adc_device *) data;
+    at91_adc_info *info            = device->dev_priv;
+    cyg_uint8         active_channels = info->chan_mask;
+    cyg_uint8         chan_no         = 0;
+
+    while (active_channels)
+    {
+        if (active_channels & 0x01)
+        {
+            if(info->channel[chan_no]->wakeup)
+            {
+                cyg_adc_wakeup(info->channel[chan_no]);
+            }
+        }
+        chan_no++;
+        active_channels >>= 1;
+    }
+}
+
+
+//---------------------------------------------------------------------------
+// eof adc_at91.c
diff -r ae816c83f082 packages/devs/adc/arm/at91/current/tests/at91_adc_test.c
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/packages/devs/adc/arm/at91/current/tests/at91_adc_test.c	Thu May 27 23:25:19 2010 +0200
@@ -0,0 +1,290 @@
+//==========================================================================
+//
+//      at91_adc_test.c
+//
+//      ADC driver for AT91 on chip ADC
+//
+//==========================================================================
+// ####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 2008 Free Software Foundation, 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.,
+// 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, 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 v2.
+//
+// This exception does not invalidate any other reasons why a work based
+// on this file might be covered by the GNU General Public License.
+// -------------------------------------------
+// ####ECOSGPLCOPYRIGHTEND####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s):  Uwe Kindler <uwe_kindler@web.de>
+//             Updated for Atmel AT91 device, ccoutand <ccoutand@stmi.com>
+// Contributors:
+// Date:         2010-02-15
+// Purpose:
+// Description:
+//
+//####DESCRIPTIONEND####
+//
+//==========================================================================
+
+#include <pkgconf/system.h>
+
+#include <cyg/infra/testcase.h>         // test macros
+#include <cyg/infra/cyg_ass.h>          // assertion macros
+#include <cyg/infra/diag.h>
+#include <cyg/hal/hal_diag.h>
+#include <cyg/hal/hal_arch.h>           // CYGNUM_HAL_STACK_SIZE_TYPICAL
+
+// Package requirements
+#if defined(CYGPKG_IO_ADC) && defined(CYGPKG_KERNEL)
+
+#include <pkgconf/kernel.h>
+#include <cyg/io/io.h>
+#include <cyg/io/adc.h>
+#include <pkgconf/devs_adc_arm_at91.h>
+
+// Package option requirements
+#if defined(CYGFUN_KERNEL_API_C)
+
+#include <cyg/kernel/kapi.h>
+
+#if CYGINT_DEVS_ADC_ARM_AT91_ADC0_CHANNELS > 0
+
+#define MAX_ADC_CHANNEL_TO_TEST 4
+
+//===========================================================================
+//                               DATA TYPES
+//===========================================================================
+typedef struct st_thread_data
+{
+    cyg_thread   obj;
+    long         stack[CYGNUM_HAL_STACK_SIZE_TYPICAL];
+    cyg_handle_t hdl;
+} thread_data_t;
+
+
+//===========================================================================
+//                              LOCAL DATA
+//===========================================================================
+cyg_thread_entry_t adc_thread;
+thread_data_t      adc_thread_data;
+
+
+//===========================================================================
+//                             ADC THREAD
+//===========================================================================
+void adc_thread(cyg_addrword_t data)
+{
+    int             res;
+    cyg_io_handle_t handle[8]     = {0, 0, 0, 0, 0, 0, 0, 0};
+    cyg_uint32      sample_cnt[8] = {0, 0, 0, 0, 0, 0, 0, 0};
+    cyg_uint32      cfg_data;
+    cyg_uint32      len;
+    cyg_uint32      start_time;
+    cyg_uint32      end_time;
+    int             i;
+    cyg_uint8       seconds = 0;
+    float           final_seconds;
+    cyg_uint32      samples_expected;
+
+
+    diag_printf("This test reads samples from all enabled ADC channels.\n"
+                "Each second the number of already acquired samples\n"
+                "will be printed. After 10 seconds all ADC channels\n"
+                "will be stopped and each ADC buffer will be read until\n"
+                "it is empty. If the number of acquired samples is much\n"
+                "smaller than the number of expected samples, then you\n"
+                "should lower the sample rate.\n\n");
+
+    // Get a handle for ADC device 0 channel 0 - 3 (lookup also trigger a channel enable)
+    res = cyg_io_lookup( "/dev/adc00", &handle[0]);
+    res = cyg_io_lookup( "/dev/adc01", &handle[1]);
+    res = cyg_io_lookup( "/dev/adc02", &handle[2]);
+    res = cyg_io_lookup( "/dev/adc03", &handle[3]);
+
+    //
+    // switch all channels to non blocking
+    //
+    for (i = 0; i < MAX_ADC_CHANNEL_TO_TEST; ++i)
+    {
+        if (handle[i])
+        {
+            cfg_data = 0;
+            len = sizeof(cfg_data);
+            res = cyg_io_set_config(handle[i],
+                                    CYG_IO_SET_CONFIG_READ_BLOCKING,
+                                    &cfg_data,
+                                    &len);
+            if (ENOERR != res)
+            {
+                CYG_TEST_FAIL_FINISH("Error switching ADC channel to non blocking");
+            }
+            sample_cnt[i] = 0;
+        }
+    }
+
+    start_time = cyg_current_time();
+    do
+    {
+        for (i = 0; i < MAX_ADC_CHANNEL_TO_TEST; ++i)
+        {
+            if (handle[i])
+            {
+                cyg_adc_sample_t sample;
+
+                // read a sample from the channel
+                do
+                {
+                    cyg_uint32 len = sizeof(sample);
+                    res = cyg_io_read( handle[i], &sample, &len );
+                }
+                while (-EAGAIN == res);
+                if (ENOERR == res)
+                {
+                    sample_cnt[i]++;
+                }
+            } // if (handle[i])
+        }
+        //
+        // print number of acquired samples - if one second is expired.
+        // we expect that the number of acquired samples is nearly the
+        // sample rate
+        //
+        end_time = cyg_current_time();
+        if ((end_time - start_time) >= 100)
+        {
+            start_time = end_time;
+            diag_printf("%d\t %d\t %d\t %d\n",
+                        sample_cnt[0],
+                        sample_cnt[1],
+                        sample_cnt[2],
+                        sample_cnt[3]);
+            seconds++;
+        } // if ((end_time - start_time) >= 100)
+    } while (seconds < 10);
+
+    //
+    // Now stop all channels
+    //
+    for (i = 0; i < MAX_ADC_CHANNEL_TO_TEST; ++i)
+    {
+        if (handle[i])
+        {
+            res = cyg_io_set_config(handle[i],
+                                    CYG_IO_SET_CONFIG_ADC_DISABLE,
+                                    0,
+                                    0);
+            if (ENOERR != res)
+            {
+                CYG_TEST_FAIL_FINISH("Error disabling ADC channel");
+            }
+        } // if (handle[i])
+    }
+    end_time = cyg_current_time();
+    end_time = seconds * 1000 + (end_time - start_time) * 10;
+    final_seconds = end_time / 1000.0;
+
+    //
+    // Now read all remaining samples from buffer
+    //
+    for (i = 0; i < MAX_ADC_CHANNEL_TO_TEST; ++i)
+    {
+        if (handle[i])
+        {
+            do
+            {
+                cyg_adc_sample_t sample;
+                cyg_uint32 len = sizeof(sample);
+                res = cyg_io_read( handle[i], &sample, &len );
+                if (ENOERR == res)
+                {
+                    sample_cnt[i]++;
+                }
+            } while (ENOERR == res);
+        } // if (handle[i])
+    }
+
+    diag_printf("\n\n----------------------------------------\n");
+    samples_expected = final_seconds * CYGNUM_DEVS_ADC_ARM_AT91_ADC0_DEFAULT_RATE;
+    diag_printf("Samples expected after %d milliseconds: %d\n",
+                end_time, samples_expected);
+    diag_printf("Samples read (per channel):\n");
+    diag_printf("%d\t %d\t %d\t %d\n",
+                sample_cnt[0],
+                sample_cnt[1],
+                sample_cnt[2],
+                sample_cnt[3]);
+
+    CYG_TEST_PASS_FINISH("ADC test OK");
+}
+
+
+void
+cyg_start(void)
+{
+    CYG_TEST_INIT();
+
+    //
+    // create the main ADC test thread
+    //
+    cyg_thread_create(4, adc_thread,
+                      (cyg_addrword_t) 0,
+                      "at91_adc_thread",
+                      (void *) adc_thread_data.stack,
+                      1024 * sizeof(long),
+                      &adc_thread_data.hdl,
+                      &adc_thread_data.obj);
+
+    cyg_thread_resume(adc_thread_data.hdl);
+
+    cyg_scheduler_start();
+}
+#else // CYGINT_DEVS_ADC_ARM_AT91_CHANNELS > 0
+#define N_A_MSG "Needs at least one enabled ADC channel"
+#endif
+
+#else // CYGFUN_KERNEL_API_C
+#define N_A_MSG "Needs kernel C API"
+#endif
+
+#else // CYGPKG_IO_ADC && CYGPKG_KERNEL
+#define N_A_MSG "Needs Kernel and ADC support"
+#endif
+
+#ifdef N_A_MSG
+void
+cyg_start( void )
+{
+    CYG_TEST_INIT();
+    CYG_TEST_NA(N_A_MSG);
+}
+#endif // N_A_MSG
+
+
+// EOF can_tx.c
+
+//---------------------------------------------------------------------------
+// eof at91_adc_test.c

^ permalink raw reply	[flat|nested] 18+ messages in thread

* RE: AT91 ADC support
  2010-05-27 19:49             ` Christophe Coutand
@ 2010-05-27 21:44               ` Sergei Gavrikov
  2010-05-29 10:24                 ` Sergei Gavrikov
  0 siblings, 1 reply; 18+ messages in thread
From: Sergei Gavrikov @ 2010-05-27 21:44 UTC (permalink / raw)
  To: Christophe Coutand; +Cc: John Dallaway, eCos Patches

On Thu, 27 May 2010, Christophe Coutand wrote:
> Hi Sergei,
>
> I have attached an updated var_io.h that includes ADC support for the
> AT91M55800A. I took the opportunity to define the number of channels
> per ADC in this file. It can be overwritten per platform basis since
> AT91SAM7L64 for instance has 4 channels only.

Hi Christophe,

Thanks for your time. I will take a look this morning.

> The definition of AT91_MAX_ADC_CHAN must be removed from
> devs/adc/arm/at91/current/src/adc_at91.c. I have not joined any patch
> for it since I will hopefully submit a new driver that support both
> ADCs.

Excellent! I did want to ask you about and it seems fetchamil is
retrieving it just now.

Sergei

> Christophe
>
> -----Original Message-----
> From: Sergei Gavrikov [mailto:sergei.gavrikov@gmail.com]
> Sent: 27. mai 2010 18:38
> To: Christophe Coutand
> Cc: John Dallaway; eCos Patches
> Subject: RE: AT91 ADC support
>
> On Thu, 27 May 2010, Christophe Coutand wrote:
>> Hi John,
>>
>> It's pretty easy to add the required definition for the AT91M55800A
>> targets. The only thing I see now is that this device contains 2 ADCs
>> which I have not considered before. I guess there are several ways out
>> of this:
>>
>> 1- Update the actual AT91 ADC driver to make full use of the
>> AT91M55800A targets. I guess should be done by loading a second ADC
>> instance (one for each ADC. I have not been through all the thinking
>> here...).
>>
>> 2- or limit the AT91 driver to use only ADC0 of the AT91M55800A target
>> for the time being.
>>
>> 3- or exclude AT91M55800A targets for the time being.
>>
>> IMO #1 is best but I cannot give any time frame for completing it.
>
> Hi Christophe, John
>
> I would prefer #1, if you want I can add that in AT91/ADC CDL/sources.
> One thing: I won't be able to test it on real hardware (only build
> process can be tested me).
>
> John, what do you think: Can we add the second ADC instance without a
> testing?
>
>> One additional weakness of the driver is that it is made for up to 8
>> channels. It is defined nowhere what the targeted CPU can actually
>> handle, this is left to the user when configuring eCos. I believe this
>> is pretty fine since the user must anyway know which signal he wants
> to
>> sample but you might disagree on that one.
>
> I know only one target which would use all 8 channels :-) That's eCos
> i386/Linux synthetic target.
>
> Thanks for collaboration.
>
> Sergei
>
>> Regards,
>> Christophe
>

^ permalink raw reply	[flat|nested] 18+ messages in thread

* RE: AT91 ADC support
  2010-05-27 21:44               ` Sergei Gavrikov
@ 2010-05-29 10:24                 ` Sergei Gavrikov
  2010-05-29 13:10                   ` John Dallaway
  2011-02-22 11:33                   ` John Dallaway
  0 siblings, 2 replies; 18+ messages in thread
From: Sergei Gavrikov @ 2010-05-29 10:24 UTC (permalink / raw)
  To: eCos Patches; +Cc: Christophe Coutand, John Dallaway

On Fri, 28 May 2010, Sergei Gavrikov wrote:

> On Thu, 27 May 2010, Christophe Coutand wrote:
>> Hi Sergei,
>> 
>> I have attached an updated var_io.h that includes ADC support for the
>> AT91M55800A. I took the opportunity to define the number of channels
>> per ADC in this file. It can be overwritten per platform basis since
>> AT91SAM7L64 for instance has 4 channels only.
>
> Hi Christophe,
>
> Thanks for your time. I will take a look this morning.

[snip]

>> The definition of AT91_MAX_ADC_CHAN must be removed from
>> devs/adc/arm/at91/current/src/adc_at91.c. I have not joined any patch
>> for it since I will hopefully submit a new driver that support both
>> ADCs.

Hi Christophe, John

Excuse, that took a bit more time for testing. So, with the latest sent
stuff, it's possible to build ADC driver and ADC tests for the next AT91
targets

   at91sam7sek: SUCCESS
   at91sam7xek: SUCCESS
   sam7ex256: SUCCESS
   eb55: SUCCESS
   phycore: SUCCESS

I'm personally do not see any pit stops which would block a check-in the
latest version of the driver. Christophe, thank you for your time and
contribution. John?

Sergei

>> -----Original Message-----
>> From: Sergei Gavrikov [mailto:sergei.gavrikov@gmail.com]
>> Sent: 27. mai 2010 18:38
>> To: Christophe Coutand
>> Cc: John Dallaway; eCos Patches
>> Subject: RE: AT91 ADC support
>> 
>> On Thu, 27 May 2010, Christophe Coutand wrote:
>>> Hi John,
>>> 
>>> It's pretty easy to add the required definition for the AT91M55800A
>>> targets. The only thing I see now is that this device contains 2 ADCs
>>> which I have not considered before. I guess there are several ways out
>>> of this:
>>> 
>>> 1- Update the actual AT91 ADC driver to make full use of the
>>> AT91M55800A targets. I guess should be done by loading a second ADC
>>> instance (one for each ADC. I have not been through all the thinking
>>> here...).
>>> 
>>> 2- or limit the AT91 driver to use only ADC0 of the AT91M55800A target
>>> for the time being.
>>> 
>>> 3- or exclude AT91M55800A targets for the time being.
>>> 
>>> IMO #1 is best but I cannot give any time frame for completing it.
>> 
>> Hi Christophe, John
>> 
>> I would prefer #1, if you want I can add that in AT91/ADC CDL/sources.
>> One thing: I won't be able to test it on real hardware (only build
>> process can be tested me).
>> 
>> John, what do you think: Can we add the second ADC instance without a
>> testing?
>> 
>>> One additional weakness of the driver is that it is made for up to 8
>>> channels. It is defined nowhere what the targeted CPU can actually
>>> handle, this is left to the user when configuring eCos. I believe this
>>> is pretty fine since the user must anyway know which signal he wants
>> to
>>> sample but you might disagree on that one.
>> 
>> I know only one target which would use all 8 channels :-) That's eCos
>> i386/Linux synthetic target.
>> 
>> Thanks for collaboration.
>> 
>> Sergei
>> 
>>> Regards,
>>> Christophe

^ permalink raw reply	[flat|nested] 18+ messages in thread

* Re: AT91 ADC support
  2010-05-29 10:24                 ` Sergei Gavrikov
@ 2010-05-29 13:10                   ` John Dallaway
  2010-05-30 10:34                     ` Sergei Gavrikov
  2011-02-22 11:33                   ` John Dallaway
  1 sibling, 1 reply; 18+ messages in thread
From: John Dallaway @ 2010-05-29 13:10 UTC (permalink / raw)
  To: Sergei Gavrikov; +Cc: eCos Patches, Christophe Coutand

Hi Sergei

Sergei Gavrikov wrote:

> Excuse, that took a bit more time for testing. So, with the latest sent
> stuff, it's possible to build ADC driver and ADC tests for the next AT91
> targets
> 
>   at91sam7sek: SUCCESS
>   at91sam7xek: SUCCESS
>   sam7ex256: SUCCESS
>   eb55: SUCCESS
>   phycore: SUCCESS
> 
> I'm personally do not see any pit stops which would block a check-in the
> latest version of the driver. Christophe, thank you for your time and
> contribution. John?

I have no objections. My concern was that we avoid an unquantified delay
in checking-in Christophe's contribution.

Thank you for sorting this out...

John Dallaway
eCos maintainer

^ permalink raw reply	[flat|nested] 18+ messages in thread

* Re: AT91 ADC support
  2010-05-29 13:10                   ` John Dallaway
@ 2010-05-30 10:34                     ` Sergei Gavrikov
  2010-05-30 12:40                       ` Christophe Coutand
  0 siblings, 1 reply; 18+ messages in thread
From: Sergei Gavrikov @ 2010-05-30 10:34 UTC (permalink / raw)
  To: John Dallaway; +Cc: Christophe Coutand, eCos Patches

Hi

Now checked-in. Christophe, thank you for your contribution! John - for 
your assistance! And your patience (well, you know ;-)

Sergei

On Sat, 29 May 2010, John Dallaway wrote:
> Hi Sergei
>
> Sergei Gavrikov wrote:
>
>> Excuse, that took a bit more time for testing. So, with the latest sent
>> stuff, it's possible to build ADC driver and ADC tests for the next AT91
>> targets
>>
>>   at91sam7sek: SUCCESS
>>   at91sam7xek: SUCCESS
>>   sam7ex256: SUCCESS
>>   eb55: SUCCESS
>>   phycore: SUCCESS
>>
>> I'm personally do not see any pit stops which would block a check-in the
>> latest version of the driver. Christophe, thank you for your time and
>> contribution. John?
>
> I have no objections. My concern was that we avoid an unquantified delay
> in checking-in Christophe's contribution.
>
> Thank you for sorting this out...
>
> John Dallaway
> eCos maintainer

^ permalink raw reply	[flat|nested] 18+ messages in thread

* RE: AT91 ADC support
  2010-05-30 10:34                     ` Sergei Gavrikov
@ 2010-05-30 12:40                       ` Christophe Coutand
  2010-05-30 13:46                         ` Sergei Gavrikov
  0 siblings, 1 reply; 18+ messages in thread
From: Christophe Coutand @ 2010-05-30 12:40 UTC (permalink / raw)
  To: Sergei Gavrikov, John Dallaway; +Cc: eCos Patches

Hi Sergei,

Thanks. Additionally, can you clarify something for me. When updating
the eCos documentation, are the SGML files part of the source code
repository used to generate the HTML version of the documentation? Or
should both be updated separately?

Regards,
Christophe  

-----Original Message-----
From: Sergei Gavrikov [mailto:sergei.gavrikov@gmail.com] 
Sent: 30. mai 2010 12:34
To: John Dallaway
Cc: Christophe Coutand; eCos Patches
Subject: Re: AT91 ADC support

Hi

Now checked-in. Christophe, thank you for your contribution! John - for 
your assistance! And your patience (well, you know ;-)

Sergei

On Sat, 29 May 2010, John Dallaway wrote:
> Hi Sergei
>
> Sergei Gavrikov wrote:
>
>> Excuse, that took a bit more time for testing. So, with the latest
sent
>> stuff, it's possible to build ADC driver and ADC tests for the next
AT91
>> targets
>>
>>   at91sam7sek: SUCCESS
>>   at91sam7xek: SUCCESS
>>   sam7ex256: SUCCESS
>>   eb55: SUCCESS
>>   phycore: SUCCESS
>>
>> I'm personally do not see any pit stops which would block a check-in
the
>> latest version of the driver. Christophe, thank you for your time and
>> contribution. John?
>
> I have no objections. My concern was that we avoid an unquantified
delay
> in checking-in Christophe's contribution.
>
> Thank you for sorting this out...
>
> John Dallaway
> eCos maintainer

^ permalink raw reply	[flat|nested] 18+ messages in thread

* RE: AT91 ADC support
  2010-05-30 12:40                       ` Christophe Coutand
@ 2010-05-30 13:46                         ` Sergei Gavrikov
  0 siblings, 0 replies; 18+ messages in thread
From: Sergei Gavrikov @ 2010-05-30 13:46 UTC (permalink / raw)
  To: Christophe Coutand; +Cc: eCos Patches

On Sun, 30 May 2010, Christophe Coutand wrote:
> Hi Sergei,
>
> Thanks. Additionally, can you clarify something for me. When updating
> the eCos documentation, are the SGML files part of the source code
> repository used to generate the HTML version of the documentation? Or
> should both be updated separately?

Hi Christophe,

You will need to create a per-package `docs' directory, write own doc
entry in SGML Then it's needed to update ecos/doc/sgml/doclist to point
on new entry.

Sergei

^ permalink raw reply	[flat|nested] 18+ messages in thread

* Re: AT91 ADC support
  2010-05-29 10:24                 ` Sergei Gavrikov
  2010-05-29 13:10                   ` John Dallaway
@ 2011-02-22 11:33                   ` John Dallaway
  1 sibling, 0 replies; 18+ messages in thread
From: John Dallaway @ 2011-02-22 11:33 UTC (permalink / raw)
  To: eCos Patches; +Cc: Sergei Gavrikov, Christophe Coutand

[-- Attachment #1: Type: text/plain, Size: 451 bytes --]

Sergei Gavrikov wrote:

> Excuse, that took a bit more time for testing. So, with the latest sent
> stuff, it's possible to build ADC driver and ADC tests for the next AT91
> targets
> 
>   at91sam7sek: SUCCESS
>   at91sam7xek: SUCCESS
>   sam7ex256: SUCCESS
>   eb55: SUCCESS
>   phycore: SUCCESS

I've added CYGPKG_DEVS_ADC_ARM_AT91 to the target records for these
targets. Checked-in.

John Dallaway
eCos maintainer
http://www.dallaway.org.uk/john

[-- Attachment #2: at91-adc-targets-110222.patch --]
[-- Type: text/x-patch, Size: 3258 bytes --]

Index: ChangeLog
===================================================================
RCS file: /cvs/ecos/ecos/packages/ChangeLog,v
retrieving revision 1.217
diff -U5 -r1.217 ChangeLog
--- ChangeLog	18 Feb 2011 15:20:59 -0000	1.217
+++ ChangeLog	22 Feb 2011 11:21:49 -0000
@@ -1,5 +1,11 @@
+2011-02-22  John Dallaway  <john@dallaway.org.uk>
+
+	* ecos.db: Add hardware package CYGPKG_DEVS_ADC_ARM_AT91 to
+	applicable target records: at91sam7sek, at91sam7xek, sam7ex256,
+	eb55, phycore
+
 2011-02-18  John Dallaway  <john@dallaway.org.uk>
 
 	* ecos.db: Remove non-hardware package CYGPKG_IO_ADC from the
 	ek-lm3s811 target definition and eliminate leading space in alias
 	string for correct sorting of targets by name.
Index: ecos.db
===================================================================
RCS file: /cvs/ecos/ecos/packages/ecos.db,v
retrieving revision 1.203
diff -U5 -r1.203 ecos.db
--- ecos.db	18 Feb 2011 15:20:59 -0000	1.203
+++ ecos.db	22 Feb 2011 11:21:50 -0000
@@ -4755,10 +4755,11 @@
                    CYGPKG_DEVS_SPI_ARM_AT91
                    CYGPKG_DEVICES_WATCHDOG_ARM_AT91WDTC
                    CYGPKG_IO_USB
                    CYGPKG_IO_USB_SLAVE
                    CYGPKG_DEVS_USB_AT91
+                   CYGPKG_DEVS_ADC_ARM_AT91
         }
         description "
         The at91sam7sek target provides the packages needed to run eCos on an 
         Atmel AT91SAM7S-EK evaluation board."
 }
@@ -4778,10 +4779,11 @@
                    CYGPKG_IO_USB_SLAVE
                    CYGPKG_DEVS_USB_AT91
                    CYGPKG_DEVS_ETH_PHY
                    CYGPKG_DEVS_ETH_ARM_AT91
                    CYGPKG_DEVS_CAN_AT91SAM7
+                   CYGPKG_DEVS_ADC_ARM_AT91
         }
         description "
         The at91sam7xek target provides the packages needed to run eCos on an 
         Atmel AT91SAM7X-EK evaluation board."
 }
@@ -4801,10 +4803,11 @@
                    CYGPKG_IO_USB_SLAVE
                    CYGPKG_DEVS_USB_AT91
                    CYGPKG_DEVS_ETH_PHY
                    CYGPKG_DEVS_ETH_ARM_AT91
                    CYGPKG_DEVS_CAN_AT91SAM7
+                   CYGPKG_DEVS_ADC_ARM_AT91
         }
         description "
         The SAM7EX256 target provides the packages needed to run eCos on an 
         Olimex SAM7-EX256 evaluation board."
 }
@@ -4849,10 +4852,11 @@
                    CYGPKG_IO_SERIAL_ARM_AT91
                    CYGPKG_IO_SPI
                    CYGPKG_DEVS_SPI_ARM_EB55
                    CYGPKG_DEVS_SPI_ARM_AT91
                    CYGPKG_DEVICES_WATCHDOG_ARM_AT91
+                   CYGPKG_DEVS_ADC_ARM_AT91
         }
         description "
 	The eb55 target provides the packages needed to run eCos on an Atmel
 	evaluation board (EB55)."
 }
@@ -4864,10 +4868,11 @@
                    CYGPKG_HAL_ARM_AT91_PHYCORE
                    CYGPKG_DEVS_FLASH_PHYCORE
                    CYGPKG_DEVS_FLASH_AMD_AM29XXXXX
                    CYGPKG_IO_SERIAL_ARM_AT91
                    CYGPKG_DEVICES_WATCHDOG_ARM_AT91
+                   CYGPKG_DEVS_ADC_ARM_AT91
         }
         description "
 	The phyCORE AT91M55800A target provides the packages needed to 
         run eCos on an PHYTEC evaluation board (phycore AT91M55800A based 
         on HD200)."

^ permalink raw reply	[flat|nested] 18+ messages in thread

end of thread, other threads:[~2011-02-22 11:33 UTC | newest]

Thread overview: 18+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2010-05-22  9:40 AT91 ADC support Christophe Coutand
2010-05-27 13:42 ` John Dallaway
2010-05-27 13:52   ` Sergei Gavrikov
2010-05-27 14:16     ` Christophe Coutand
2010-05-27 14:47       ` John Dallaway
2010-05-27 15:44         ` Christophe Coutand
2010-05-27 16:08           ` John Dallaway
2010-05-27 16:37             ` Kurt Siedenburg
2010-05-27 16:37           ` Sergei Gavrikov
2010-05-27 19:49             ` Christophe Coutand
2010-05-27 21:44               ` Sergei Gavrikov
2010-05-29 10:24                 ` Sergei Gavrikov
2010-05-29 13:10                   ` John Dallaway
2010-05-30 10:34                     ` Sergei Gavrikov
2010-05-30 12:40                       ` Christophe Coutand
2010-05-30 13:46                         ` Sergei Gavrikov
2011-02-22 11:33                   ` John Dallaway
2010-05-27 21:37             ` Christophe Coutand

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).