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


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

PATCH::polling mode i2c driver for at91sam7x


Polling mode TWI driver for at91sam7x

Thanks & Regards
vibi
Index: packages/ecos.db
===================================================================
RCS file: /media/nfs/ecos-exp/cvsserver/packages/ecos.db,v
retrieving revision 1.1.1.1
diff -u -5 -p -r1.1.1.1 ecos.db
--- packages/ecos.db	5 Apr 2009 09:50:30 -0000	1.1.1.1
+++ packages/ecos.db	5 Apr 2009 11:02:37 -0000
@@ -2419,10 +2419,19 @@ package CYGPKG_DEVS_ADC_ARM_LPC24XX {
     description "
             This packages provides an ADC driver for the on-chip
             ADC provided by the LPC24xx processor family."
 }
 
+package CYGPKG_DEVS_I2C_ARM_AT91 {
+    alias           { "AT91sam7x I2C driver" }
+    hardware
+    directory       devs/i2c/arm/at91
+    script          i2c_at91.cdl
+    description "This package provides a driver for the I2C unit of the AT91sam7x
+                 controller family."
+}
+
 package CYGPKG_DEVS_ADC_SYNTH {
     alias         { "Synthethic ADC driver" adc_synth }
     hardware
     directory     devs/adc/synth
     script        adc_synth.cdl
@@ -4712,10 +4721,12 @@ target at91sam7xek {
                    CYGPKG_HAL_ARM_AT91SAM7XEK
                    CYGPKG_IO_SERIAL_ARM_AT91
                    CYGPKG_DEVS_FLASH_AT91
                    CYGPKG_IO_SPI
                    CYGPKG_DEVS_SPI_ARM_AT91
+                   CYGPKG_IO_I2C
+                   CYGPKG_DEVS_I2C_ARM_AT91
                    CYGPKG_DEVICES_WATCHDOG_ARM_AT91WDTC
                    CYGPKG_DEVS_USB_AT91
                    CYGPKG_DEVS_ETH_PHY
                    CYGPKG_DEVS_ETH_ARM_AT91
         }
Index: packages/devs/i2c/arm/at91/current/cdl/i2c_at91.cdl
===================================================================
RCS file: /media/nfs/ecos-exp/cvsserver/packages/devs/i2c/arm/at91/current/cdl/i2c_at91.cdl,v
retrieving revision 1.1
diff -u -5 -p -r1.1 i2c_at91.cdl
--- packages/devs/i2c/arm/at91/current/cdl/i2c_at91.cdl	5 Apr 2009 10:50:28 -0000	1.1
+++ packages/devs/i2c/arm/at91/current/cdl/i2c_at91.cdl	1 Apr 2009 19:36:19 -0000
@@ -0,0 +1,58 @@
+# ====================================================================
+#
+#      i2c_at91.cdl
+#
+#      I2C driver for AT91SAM7x
+#
+# ====================================================================
+#####ECOSGPLCOPYRIGHTBEGIN####
+## -------------------------------------------
+## This file is part of eCos, the Embedded Configurable Operating System.
+## Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
+##
+## eCos is free software; you can redistribute it and/or modify it under
+## the terms of the GNU General Public License as published by the Free
+## Software Foundation; either version 2 or (at your option) any later version.
+##
+## eCos is distributed in the hope that it will be useful, but WITHOUT ANY
+## WARRANTY; without even the implied warranty of MERCHANTABILITY or
+## FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+## for more details.
+##
+## You should have received a copy of the GNU General Public License along
+## with eCos; if not, write to the Free Software Foundation, Inc.,
+## 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+##
+## As a special exception, if other files instantiate templates or use macros
+## or inline functions from this file, or you compile this file and link it
+## with other works to produce a work based on this file, this file does not
+## by itself cause the resulting work to be covered by the GNU General Public
+## License. However the source code for this file must still be made available
+## in accordance with section (3) of the GNU General Public License.
+##
+## This exception does not invalidate any other reasons why a work based on
+## this file might be covered by the GNU General Public License.
+## -------------------------------------------
+#####ECOSGPLCOPYRIGHTEND####
+# ====================================================================
+######DESCRIPTIONBEGIN####
+#
+# Author(s):      vibi sreenivasan <vibi_sreenivasan@cms.com>
+# Contributors:   
+# Date:           2007-07-12
+#
+#####DESCRIPTIONEND####
+#
+# ====================================================================
+
+cdl_package CYGPKG_DEVS_I2C_ARM_AT91 {
+    display     "I2C driver for AT91 family of ARM controllers"
+    parent      CYGPKG_IO_I2C
+    active_if   CYGPKG_IO_I2C
+    active_if   CYGPKG_HAL_ARM_AT91SAM7XEK
+    description "This package provides a driver for the I2C module found in
+                 Atmel AT91SAM7X controllers."
+    hardware
+    include_dir   cyg/io
+    compile     i2c_at91.c
+}
\ No newline at end of file
Index: packages/devs/i2c/arm/at91/current/include/i2c_at91.h
===================================================================
RCS file: /media/nfs/ecos-exp/cvsserver/packages/devs/i2c/arm/at91/current/include/i2c_at91.h,v
retrieving revision 1.1
diff -u -5 -p -r1.1 i2c_at91.h
--- packages/devs/i2c/arm/at91/current/include/i2c_at91.h	5 Apr 2009 10:50:45 -0000	1.1
+++ packages/devs/i2c/arm/at91/current/include/i2c_at91.h	5 Apr 2009 11:30:36 -0000
@@ -0,0 +1,85 @@
+#ifndef CYGONCE_DEVS_I2C_ARM_AT91_H
+#define CYGONCE_DEVS_I2C_ARM_AT91_H
+//==========================================================================
+//
+//      i2c_at91.h
+//
+//      Atmel AT91 (ARM) I2C driver defines
+//
+//==========================================================================
+//####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
+//
+// eCos is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 2 or (at your option) any later version.
+//
+// eCos is distributed in the hope that it will be useful, but WITHOUT ANY
+// WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with eCos; if not, write to the Free Software Foundation, Inc.,
+// 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+//
+// As a special exception, if other files instantiate templates or use macros
+// or inline functions from this file, or you compile this file and link it
+// with other works to produce a work based on this file, this file does not
+// by itself cause the resulting work to be covered by the GNU General Public
+// License. However the source code for this file must still be made available
+// in accordance with section (3) of the GNU General Public License.
+//
+// This exception does not invalidate any other reasons why a work based on
+// this file might be covered by the GNU General Public License.
+//
+// Alternative licenses for eCos may be arranged by contacting Red Hat, Inc.
+// at http://sources.redhat.com/ecos/ecos-license/
+// -------------------------------------------
+//####ECOSGPLCOPYRIGHTEND####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s):     vibi sreenivasan <vibi_sreenivasan@cms.com> 
+// Date:          10-11-2008
+//
+//####DESCRIPTIONEND####
+//
+//==========================================================================
+
+#include <pkgconf/hal.h>
+#include <cyg/infra/cyg_type.h>
+#include <cyg/hal/drv_api.h>
+#include <cyg/io/i2c.h>
+
+#define I2C_AT91_TXR_START    (1 << 7)
+#define I2C_AT91_TXR_END      (1 << 6)
+#define I2C_AT91_RXR_START    (1 << 5)
+#define I2C_AT91_RXR_END      (1 << 4)
+
+
+typedef struct cyg_i2c_at91_dev_s
+{
+    // upper layer data (upper layer i2c device structure)
+    cyg_i2c_device i2c_device;
+    // lower layer data
+    cyg_uint8 int_addr_sz;    // most chips do have internal address size
+} cyg_i2c_at91_dev_t;
+
+#define CYG_I2C_AT91_DEVICE(_name_, _bus_, _address_, _flags_, _delay_, _int_adr_sz_)     \
+    cyg_i2c_at91_dev_t _name_ = {                                                                               \
+        .i2c_device = {                                                                                         \
+            .i2c_bus = _bus_,                                                                                   \
+            .i2c_address = _address_,                                                                           \
+            .i2c_flags = _flags_,                                                                               \
+            .i2c_delay = _delay_,                                                                               \
+        },                                                                                                      \
+        .int_addr_sz = _int_adr_sz_,                                                                            \
+    }
+    
+#define HAL_I2C_EXPORTED_DEVICES \
+    externC cyg_i2c_bus cyg_i2c_at91_bus; \
+#endif // CYGONCE_DEVS_I2C_ARM_AT91_H 
+
Index: packages/devs/i2c/arm/at91/current/src/i2c_at91.c
===================================================================
RCS file: /media/nfs/ecos-exp/cvsserver/packages/devs/i2c/arm/at91/current/src/i2c_at91.c,v
retrieving revision 1.1
diff -u -5 -p -r1.1 i2c_at91.c
--- packages/devs/i2c/arm/at91/current/src/i2c_at91.c	5 Apr 2009 10:50:54 -0000	1.1
+++ packages/devs/i2c/arm/at91/current/src/i2c_at91.c	5 Apr 2009 11:32:14 -0000
@@ -0,0 +1,239 @@
+//==========================================================================
+//
+//      i2c_at91.c
+//
+//      I2C driver for AT91SAM7x
+//
+//==========================================================================
+//####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
+//
+// eCos is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 2 or (at your option) any later version.
+//
+// eCos is distributed in the hope that it will be useful, but WITHOUT ANY
+// WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with eCos; if not, write to the Free Software Foundation, Inc.,
+// 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+//
+// As a special exception, if other files instantiate templates or use macros
+// or inline functions from this file, or you compile this file and link it
+// with other works to produce a work based on this file, this file does not
+// by itself cause the resulting work to be covered by the GNU General Public
+// License. However the source code for this file must still be made available
+// in accordance with section (3) of the GNU General Public License.
+//
+// This exception does not invalidate any other reasons why a work based on
+// this file might be covered by the GNU General Public License.
+//
+// Alternative licenses for eCos may be arranged by contacting Red Hat, Inc.
+// at http://sources.redhat.com/ecos/ecos-license/
+// -------------------------------------------
+//####ECOSGPLCOPYRIGHTEND####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s):    vibi sreenivasan <vibi_sreenivasan@cms.com>
+// Contributors: 
+// Date:         2009-3-25
+// Purpose:      
+// Description:  
+//              
+//####DESCRIPTIONEND####
+//
+//==========================================================================
+
+#include <pkgconf/system.h>
+#include <pkgconf/devs_i2c_arm_at91.h>
+#include <cyg/infra/cyg_type.h>
+#include <cyg/infra/diag.h>
+#include <cyg/io/i2c.h>
+#include <cyg/io/i2c_at91.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>
+
+#define I2C_BASE        AT91_TWI
+#define I2C_TXCOMP      AT91_TWI_SR_TXCOMP
+#define I2C_RXRDY       AT91_TWI_SR_RXRDY
+#define I2C_TXRDY       AT91_TWI_SR_TXRDY
+#define I2C_NACK        AT91_TWI_SR_NACK
+
+#define I2C_W8(r,x)     HAL_WRITE_UINT8(I2C_BASE + (r), (x))
+#define I2C_R8(r,x)     HAL_READ_UINT8(I2C_BASE + (r), (x))
+#define I2C_W32(r, x)   HAL_WRITE_UINT32(I2C_BASE + (r), (x))
+#define I2C_R32(r, x)   HAL_READ_UINT32(I2C_BASE + (r), (x))
+
+#define TIMEOUT 1200
+static cyg_uint32       i2c_delay;
+
+// set up I2C bus timing
+static void
+i2c_at91_delay(cyg_uint32 delay)
+{
+    cyg_uint32 cdiv,ckdiv = 0;
+
+    if(delay == i2c_delay)
+        return;
+    // (delay / 10^9) for converting delay nsec to sec
+    // formula from datasheet => Tlow = ((CLDIV * 2^CKDIV) + 3) * Tmck
+    // CLDIV = CHDIV = CDIV
+    cdiv =  (delay / 1000) * (CYGNUM_HAL_ARM_AT91_CLOCK_SPEED / (2 * 1000000));
+    cdiv -= 3;
+    while (cdiv > 255) {
+        ckdiv++;
+        cdiv >>= 1;
+    }
+    I2C_W32(AT91_TWI_CWGR,ckdiv << AT91_TWI_CWGR_CKDIV_SHIFT | 
+        cdiv << AT91_TWI_CWGR_CHDIV_SHIFT | cdiv << AT91_TWI_CWGR_CLDIV_SHIFT);
+    i2c_delay = delay;
+}
+
+// Initialize driver & hardware state
+static void
+i2c_at91_init(struct cyg_i2c_bus *bus)
+{
+    // enable multi-drain
+    HAL_WRITE_UINT32((AT91_PIOA + AT91_PIO_MDER),(AT91_PIO_PSR_TWD
+        |AT91_PIO_PSR_TWCK));
+    HAL_ARM_AT91_GPIO_CFG_PULLUP(AT91_GPIO_PA10,AT91_PIN_PULLUP_DISABLE);
+    HAL_ARM_AT91_GPIO_CFG_PULLUP(AT91_GPIO_PA11,AT91_PIN_PULLUP_DISABLE);
+    HAL_ARM_AT91_PIO_CFG(AT91_TWI_TWD);
+    HAL_ARM_AT91_PIO_CFG(AT91_TWI_TWCK);
+    // enable TWI clock
+    HAL_WRITE_UINT32((AT91_PMC + AT91_PMC_PCER), AT91_PMC_PCER_TWI);
+    // S/W reset
+    I2C_W32(AT91_TWI_CR, AT91_TWI_CR_SWRST);
+    // Works only as master
+    I2C_W32(AT91_TWI_CR, AT91_TWI_CR_MSEN);
+
+}
+
+
+// transmit a buffer to a device
+static cyg_uint32
+i2c_at91_tx(const cyg_i2c_device *dev, 
+               cyg_bool send_start, 
+               const cyg_uint8 *tx_data, 
+               cyg_uint32 count, 
+               cyg_bool send_stop)
+{
+    cyg_i2c_at91_dev_t *at91_i2c_dev = (cyg_i2c_at91_dev_t*)dev;
+    cyg_uint32 tmp = 0,timeout,i2c_count = count;
+    cyg_uint8 i = at91_i2c_dev->int_addr_sz;
+    volatile cyg_uint32 stat_reg;
+    const cyg_uint8 *i2c_txbuf = &tx_data[i];
+    if (!count)
+        return 0;
+    // set device specific speed
+    i2c_at91_delay(dev->i2c_delay);    
+    // calculate internal address
+    while (i--)
+        tmp |= *tx_data++ << (i << 3);
+    // Load device address, direction & internal address size
+    I2C_W32(AT91_TWI_MMR,AT91_TWI_MMR_MWRITE | 
+        ((dev->i2c_address << AT91_TWI_MMR_DADR_SHIFT) | 
+                ((at91_i2c_dev->int_addr_sz << AT91_TWI_MMR_IADRZ_SHIFT) &
+                                                    AT91_TWI_MMR_IADRZ_MASK)));
+    // Load internal address
+    I2C_W32(AT91_TWI_IADR,tmp);
+    // Load START condition if requested
+    if (send_start)
+        I2C_W32(AT91_TWI_CR, AT91_TWI_CR_START);
+    // use tmp to store flags to check
+    tmp = AT91_TWI_SR_TXRDY;
+    do
+    {   
+        // Load STOP condition with the last transfer if requested
+        if (send_stop && i2c_count == 1) {
+            I2C_W32(AT91_TWI_CR, AT91_TWI_CR_STOP);
+            tmp = AT91_TWI_SR_TXCOMP;
+        }
+        // Load DATA to txmit
+        I2C_W8(AT91_TWI_THR,*i2c_txbuf++);
+        // Wait for txr completion flag || timeout
+        for ( timeout = TIMEOUT,stat_reg = 0;
+            timeout && !(stat_reg & tmp); timeout-- )
+               I2C_R32 (AT91_TWI_SR,stat_reg);
+        // error condition , return howmuch data was transferred 
+        if (!timeout)
+            return (count - i2c_count);
+    } while (--i2c_count);
+    return (count - i2c_count);
+}
+
+
+// receive into a buffer from a device
+// there is no h/w specific way to send NACK
+static cyg_uint32
+i2c_at91_rx(const cyg_i2c_device *dev,
+               cyg_bool send_start,
+               cyg_uint8 *rx_data,
+               cyg_uint32 count,
+               cyg_bool send_nak,
+               cyg_bool send_stop)
+{
+    cyg_i2c_at91_dev_t *at91_i2c_dev = (cyg_i2c_at91_dev_t*)dev;
+    cyg_uint32 tmp = 0,timeout,i2c_count = count;
+    volatile cyg_uint32 stat_reg;
+    cyg_uint8 i = at91_i2c_dev->int_addr_sz;
+    if (!count)
+        return 0;
+    // set device specific speed
+    i2c_at91_delay(dev->i2c_delay);
+    // calculate internal address
+    while (i--)
+        tmp |= *rx_data++ << (i << 3);
+    // Load device address , direction & internal address size
+    I2C_W32(AT91_TWI_MMR,AT91_TWI_MMR_MREAD | 
+        ((dev->i2c_address << AT91_TWI_MMR_DADR_SHIFT) | 
+            ((at91_i2c_dev->int_addr_sz << AT91_TWI_MMR_IADRZ_SHIFT) &
+                                                 AT91_TWI_MMR_IADRZ_MASK)));
+    I2C_W32(AT91_TWI_IADR,tmp);
+    I2C_W32(AT91_TWI_CR, AT91_TWI_CR_START);
+    // use tmp to store flags to check
+    tmp = AT91_TWI_SR_RXRDY;
+    do
+    {
+        // Load STOP condition with the last transfer if requested
+        if (send_stop && i2c_count == 1) {
+            I2C_W32(AT91_TWI_CR, AT91_TWI_CR_STOP);
+            tmp = AT91_TWI_SR_TXCOMP;
+        }
+        // Wait for txr completion flag || timeout
+        for ( timeout = TIMEOUT,stat_reg = 0;
+            timeout && !(stat_reg & tmp); timeout-- )
+               I2C_R32 (AT91_TWI_SR,stat_reg);
+        // error condition , return howmuch data was transferred 
+        if (!timeout)
+            return (count - i2c_count);
+        // Read recived data
+        I2C_R8(AT91_TWI_RHR,*rx_data++);
+    } while (--i2c_count);
+    return (count - i2c_count);
+}
+
+
+
+// generate a STOP
+static void
+i2c_at91_stop(const cyg_i2c_device *dev)
+{
+    I2C_W32(AT91_TWI_CR, AT91_TWI_CR_STOP);
+}
+
+CYG_I2C_BUS(cyg_i2c_at91_bus,
+            &i2c_at91_init,
+            &i2c_at91_tx,
+            &i2c_at91_rx,
+            &i2c_at91_stop,
+            (void *) 0);
+
Index: packages/hal/arm/at91/var/current/include/var_io.h
===================================================================
RCS file: /media/nfs/ecos-exp/cvsserver/packages/hal/arm/at91/var/current/include/var_io.h,v
retrieving revision 1.1.1.1
diff -u -5 -p -r1.1.1.1 var_io.h
--- packages/hal/arm/at91/var/current/include/var_io.h	5 Apr 2009 09:50:34 -0000	1.1.1.1
+++ packages/hal/arm/at91/var/current/include/var_io.h	5 Apr 2009 10:59:49 -0000
@@ -2625,10 +2625,12 @@
 #define AT91_TWI_CR_MSDIS (1 << 3) // Master Transfer Disable
 #define AT91_TWI_CR_SVEN  (1 << 4) // Slave Transfer Enable
 #define AT91_TWI_CR_SDIS  (1 << 5) // Slave Transfer Disable
 #define AT91_TWI_CR_SWRST (1 << 7) // Software Reset
 #define AT91_TWI_MMR  0x04 // Master Mode
+#define AT91_TWI_MMR_IADRZ_MASK  (3 <<  8) // Internal Device Address Size Mask
+#define AT91_TWI_MMR_IADRZ_SHIFT  (8)   // Internal Device Address Size Shift
 #define AT91_TWI_MMR_IADRZ_NO (0 <<  8) // Internal Device Address size 0Bytes
 #define AT91_TWI_MMR_IADRZ_1  (1 <<  8) // Internal Device Address size 1Byte
 #define AT91_TWI_MMR_IADRZ_2  (2 <<  8) // Internal Device Address size 2Bytes
 #define AT91_TWI_MMR_IADRZ_3  (3 <<  8) // Internal Device Address size 3Bytes
 #define AT91_TWI_MMR_MWRITE   (0 << 12) // Master Write

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