Make the TWI driver more generic to work with devices other than EEPROMS.
authorbernie <bernie@38d2e660-2303-0410-9eaa-f027e97ec537>
Mon, 20 Mar 2006 17:49:50 +0000 (17:49 +0000)
committerbernie <bernie@38d2e660-2303-0410-9eaa-f027e97ec537>
Mon, 20 Mar 2006 17:49:50 +0000 (17:49 +0000)
git-svn-id: https://src.develer.com/svnoss/bertos/trunk@569 38d2e660-2303-0410-9eaa-f027e97ec537

drv/eeprom.c
drv/twi.c
drv/twi.h

index 8280ef2c75d558ee6ebf5bdf864d0f821d1474be..9eeb011a96110813474f051e3318d0ee93f33ad1 100755 (executable)
@@ -16,6 +16,9 @@
 
 /*#*
  *#* $Log$
+ *#* Revision 1.19  2006/03/20 17:49:50  bernie
+ *#* Make the TWI driver more generic to work with devices other than EEPROMS.
+ *#*
  *#* Revision 1.18  2005/11/27 23:33:40  bernie
  *#* Use appconfig.h instead of cfg/config.h.
  *#*
        #error CONFIG_EEPROM_VERIFY must be defined to either 0 or 1
 #endif
 
+/**
+ * EEPROM ID code
+ */
+#define EEPROM_ID  0xA0
+
+/**
+ * This macros form the correct slave address for EEPROMs
+ */
+#define EEPROM_ADDR(x) (EEPROM_ID | (((uint8_t)(x)) << 1))
+
+
+
 
 /*!
  * Copy \c count bytes from buffer \c buf to
@@ -80,7 +95,7 @@ static bool eeprom_writeRaw(e2addr_t addr, const void *buf, size_t count)
                uint8_t blk_offs = (uint8_t)addr;
 
                result =
-                       twi_start_w(blk_addr)
+                       twi_start_w(EEPROM_ADDR(blk_addr))
                        && twi_send(&blk_offs, sizeof blk_offs)
                        && twi_send(buf, size);
 
@@ -90,7 +105,7 @@ static bool eeprom_writeRaw(e2addr_t addr, const void *buf, size_t count)
                uint16_t addr_be = cpu_to_be16(addr);
 
                result =
-                       twi_start_w(0)
+                       twi_start_w(EEPROM_ID)
                        && twi_send((uint8_t *)&addr_be, sizeof addr_be)
                        && twi_send(buf, size);
 
@@ -198,9 +213,9 @@ bool eeprom_read(e2addr_t addr, void *buf, size_t count)
        uint8_t blk_offs = (uint8_t)addr;
 
        bool res =
-               twi_start_w(blk_addr)
+               twi_start_w(EEPROM_ADDR(blk_addr))
                && twi_send(&blk_offs, sizeof blk_offs)
-               && twi_start_r(blk_addr)
+               && twi_start_r(EEPROM_ADDR(blk_addr))
                && twi_recv(buf, count);
 
 #elif CONFIG_EEPROM_TYPE == EEPROM_24XX256
@@ -209,9 +224,9 @@ bool eeprom_read(e2addr_t addr, void *buf, size_t count)
        addr = cpu_to_be16(addr);
 
        bool res =
-               twi_start_w(0)
+               twi_start_w(EEPROM_ID)
                && twi_send((uint8_t *)&addr, sizeof(addr))
-               && twi_start_r(0)
+               && twi_start_r(EEPROM_ID)
                && twi_recv(buf, count);
 #else
        #error Unknown device type
index 76d4a82f463c28c305c23913d6e45ef9c6922ac4..f2c73f94d760ea05e767bf1d014c33311fb71fd0 100755 (executable)
--- a/drv/twi.c
+++ b/drv/twi.c
@@ -15,6 +15,9 @@
 
 /*#*
  *#* $Log$
+ *#* Revision 1.6  2006/03/20 17:49:50  bernie
+ *#* Make the TWI driver more generic to work with devices other than EEPROMS.
+ *#*
  *#* Revision 1.5  2005/11/27 23:33:40  bernie
  *#* Use appconfig.h instead of cfg/config.h.
  *#*
 /* Wait for TWINT flag set: bus is ready */
 #define WAIT_TWI_READY  do {} while (!(TWCR & BV(TWINT)))
 
-/*! \name EEPROM control codes */
-/*@{*/
-#define SLA_W  0xA0
-#define SLA_R  0xA1
-/*@}*/
+#define READ_BIT BV(0)
 
 
 /*!
@@ -73,13 +72,13 @@ static bool twi_start(void)
 
 /*!
  * Send START condition and select slave for write.
+ * \c id is the device id comprehensive of address left shifted by 1.
+ * The LSB of \c id is ignored and reset to 0 for write operation.
  *
  * \return true on success, false otherwise.
  */
-bool twi_start_w(uint8_t slave_addr)
+bool twi_start_w(uint8_t id)
 {
-       ASSERT(slave_addr < 8);
-
        /*
         * Loop on the select write sequence: when the eeprom is busy
         * writing previously sent data it will reply to the SLA_W
@@ -88,7 +87,7 @@ bool twi_start_w(uint8_t slave_addr)
         */
        while (twi_start())
        {
-               TWDR = SLA_W | (slave_addr << 1);
+               TWDR = id & ~READ_BIT;
                TWCR = BV(TWINT) | BV(TWEN);
                WAIT_TWI_READY;
 
@@ -107,16 +106,16 @@ bool twi_start_w(uint8_t slave_addr)
 
 /*!
  * Send START condition and select slave for read.
+ * \c id is the device id comprehensive of address left shifted by 1.
+ * The LSB of \c id is ignored and set to 1 for read operation.
  *
  * \return true on success, false otherwise.
  */
-bool twi_start_r(uint8_t slave_addr)
+bool twi_start_r(uint8_t id)
 {
-       ASSERT(slave_addr < 8);
-
        if (twi_start())
        {
-               TWDR = SLA_R | (slave_addr << 1);
+               TWDR = id | READ_BIT;
                TWCR = BV(TWINT) | BV(TWEN);
                WAIT_TWI_READY;
 
@@ -135,7 +134,27 @@ bool twi_start_r(uint8_t slave_addr)
  */
 void twi_stop(void)
 {
-       TWCR = BV(TWINT) | BV(TWEN) | BV(TWSTO);
+        TWCR = BV(TWINT) | BV(TWEN) | BV(TWSTO);
+}
+
+
+/*!
+ * Put a single byte in master transmitter mode
+ * to the selected slave device through the TWI bus.
+ *
+ * \return true on success, false on error.
+ */
+bool twi_put(const uint8_t data)
+{
+       TWDR = data;
+       TWCR = BV(TWINT) | BV(TWEN);
+       WAIT_TWI_READY;
+       if (TW_STATUS != TW_MT_DATA_ACK)
+       {
+               kprintf("!TW_MT_DATA_ACK: %x\n", TWSR);
+               return false;
+       }
+       return true;
 }
 
 
@@ -151,16 +170,9 @@ bool twi_send(const void *_buf, size_t count)
 
        while (count--)
        {
-               TWDR = *buf++;
-               TWCR = BV(TWINT) | BV(TWEN);
-               WAIT_TWI_READY;
-               if (TW_STATUS != TW_MT_DATA_ACK)
-               {
-                       kprintf("!TW_MT_DATA_ACK: %x\n", TWSR);
+               if (!twi_put(*buf++))
                        return false;
-               }
        }
-
        return true;
 }
 
index ac8c46f20f2eff8f03aa30d03c2a1e740e51aa99..20671a463f91522b352d3a04536df69db489b22f 100755 (executable)
--- a/drv/twi.h
+++ b/drv/twi.h
@@ -15,6 +15,9 @@
 
 /*#*
  *#* $Log$
+ *#* Revision 1.4  2006/03/20 17:49:49  bernie
+ *#* Make the TWI driver more generic to work with devices other than EEPROMS.
+ *#*
  *#* Revision 1.3  2005/04/11 19:10:28  bernie
  *#* Include top-level headers from cfg/ subdir.
  *#*
 
 #include <cfg/compiler.h>
 
-bool twi_start_w(uint8_t slave_addr);
-bool twi_start_r(uint8_t slave_addr);
+bool twi_start_w(uint8_t id);
+bool twi_start_r(uint8_t id);
 void twi_stop(void);
+bool twi_put(const uint8_t data);
 bool twi_send(const void *_buf, size_t count);
 bool twi_recv(void *_buf, size_t count);
 void twi_init(void);