i2c writer utility
authorMike Line <m-line1@ti.com>
Tue, 19 Oct 2010 18:53:43 +0000 (14:53 -0400)
committerMike Line <m-line1@ti.com>
Tue, 19 Oct 2010 18:53:43 +0000 (14:53 -0400)
src/util/i2cWrite/i2cWrite.c [new file with mode: 0644]

diff --git a/src/util/i2cWrite/i2cWrite.c b/src/util/i2cWrite/i2cWrite.c
new file mode 100644 (file)
index 0000000..d145002
--- /dev/null
@@ -0,0 +1,161 @@
+/****************************************************************************************************
+ * FILE PURPOSE: Write an I2C eeprom
+ ****************************************************************************************************
+ * @file i2cWrite.c
+ *
+ * @brief
+ *   Writes bytes to an i2c eeprom. The bytes are stored in word format, and written out
+ *   in big endian format, regardless of the endianness of the device.
+ *
+ ****************************************************************************************************/
+
+#include "types.h"
+#include "i2c.h"
+#include "target.h"
+#include <stdio.h>
+
+#define I2C_SIZE_BYTES  0x10000
+
+/* Run time configuration */
+unsigned int   deviceFreqMhz = 1000;
+unsigned short busAddress    = 0x50;
+unsigned int   nbytes        = I2C_SIZE_BYTES;
+unsigned int   dataAddress   = 0;
+
+
+#pragma DATA_SECTION(i2cData, ".i2cData")
+unsigned int i2cData[I2C_SIZE_BYTES >> 2];
+
+#define I2C_BLOCK_SIZE_BYTES    64
+unsigned char i2cBlock[I2C_BLOCK_SIZE_BYTES+4];  /* need 2 bytes for the address */
+
+/** 
+ *  @brief
+ *      Form a block of data to write to the i2c. The block is 
+ *      created as a byte stream from the 4 byte stream in which
+ *      the MSB is always sent first.
+ */
+int formBlock (unsigned int addr, int byteIndex, int n)
+{
+    int p;
+    int i;
+
+    /* Must start on a word aligned boundary */
+    if ((n & 0x3) != 0)  {
+        printf ("Error: Invalid block base offset specified\n");
+        return (-1);
+    }
+
+    /* The 1st two bytes are the address */
+    i2cBlock[0] = (addr >> 8) & 0xff;
+    i2cBlock[1] = (addr >> 0) & 0xff;
+
+    p = byteIndex >> 2;
+
+
+    for (i = 0; i < I2C_BLOCK_SIZE_BYTES; i += 4, p++)  {
+
+        i2cBlock[i+2+0] = (i2cData[p] >> 24) & 0xff;
+        i2cBlock[i+2+1] = (i2cData[p] >> 16) & 0xff;
+        i2cBlock[i+2+2] = (i2cData[p] >>  8) & 0xff;
+        i2cBlock[i+2+3] = (i2cData[p] >>  0) & 0xff;
+
+    }
+
+    return (n+2);
+
+}
+    
+
+/**
+ *  @brief
+ *     Display the error returned by the i2c driver 
+ */
+void showI2cError (I2C_RET iret)
+{
+    char *ecode;
+
+    switch (iret)  {
+        case I2C_RET_LOST_ARB:        ecode = "I2C master lost an arbitration battle";
+                                      break;
+
+        case I2C_RET_NO_ACK:          ecode = "I2C master detected no ack from slave";
+                                      break;
+
+        case I2C_RET_IDLE_TIMEOUT:    ecode = "I2C timed out";
+                                      break;
+
+        case I2C_RET_BAD_REQUEST:     ecode = "I2C driver detected a bad data request";
+                                      break;
+
+        case I2C_RET_CLOCK_STUCK_LOW: ecode = "I2C driver found the bus stuck low";
+                                      break;
+
+        case I2C_RET_GEN_ERROR:       ecode = "I2C driver reported a general error";
+                                      break;
+
+    }
+
+    printf ("I2C reported error: %s\n", ecode);
+
+}
+
+
+void main (void)
+{
+    I2C_RET i2cRet;
+    int     n;
+    int     remain;
+    int     progBytes;
+
+    volatile int i;
+
+    hwI2Cinit (deviceFreqMhz,
+               DEVICE_I2C_MODULE_DIVISOR,
+               25,                              /* Run the bus at 25 kHz */
+               10);
+
+
+
+    for (n = 0; n < nbytes; n += I2C_BLOCK_SIZE_BYTES)  {
+
+        remain = nbytes - n;
+        if (remain > I2C_BLOCK_SIZE_BYTES)
+            remain = I2C_BLOCK_SIZE_BYTES;
+
+        /* formBlock sets up the address as well as the data */
+        progBytes = formBlock (dataAddress + n, n, remain);
+
+        if (progBytes < 0)
+            return;
+
+        /* Write the block */
+        i2cRet = hwI2cMasterWrite (busAddress,
+                                   i2cBlock,
+                                   progBytes,
+                                   I2C_RELEASE_BUS,
+                                   FALSE);
+        
+
+        if (i2cRet != I2C_RET_OK)  {
+            showI2cError (i2cRet);
+            return;
+        }
+
+
+
+        /* Some delay */
+        for (i = 0; i < 600000; i++);
+
+    }
+
+
+    printf ("I2C write complete\n");
+}
+        
+
+
+
+
+
+