f3d93e09edcf2d1aef6016e054f910db1d6556d1
[keystone-rtos/ibl.git] / src / util / i2cWrite / i2cWrite.c
1 /****************************************************************************************************
2  * FILE PURPOSE: Write an I2C eeprom
3  ****************************************************************************************************
4  * @file i2cWrite.c
5  *
6  * @brief
7  *   Writes bytes to an i2c eeprom. The bytes are stored in word format, and written out
8  *   in big endian format, regardless of the endianness of the device.
9  *
10  ****************************************************************************************************/
12 #include "types.h"
13 #include "i2c.h"
14 #include "target.h"
15 #include <stdio.h>
17 #define I2C_SIZE_BYTES  0x10000
19 /* Run time configuration */
20 unsigned int   deviceFreqMhz = 1000;
21 unsigned short busAddress    = 0x50;
22 unsigned int   i2cBlockSize  = 64;
23 unsigned int   nbytes        = I2C_SIZE_BYTES;
24 unsigned int   dataAddress   = 0;
27 #pragma DATA_SECTION(i2cData, ".i2cData")
28 unsigned int i2cData[I2C_SIZE_BYTES >> 2];
30 #define I2C_MAX_BLOCK_SIZE_BYTES    256
31 unsigned char i2cBlock[I2C_MAX_BLOCK_SIZE_BYTES+4];  /* need 2 bytes for the address */
33 /** 
34  *  @brief
35  *      Form a block of data to write to the i2c. The block is 
36  *      created as a byte stream from the 4 byte stream in which
37  *      the MSB is always sent first.
38  */
39 int formBlock (unsigned int addr, int byteIndex, int n)
40 {
41     int p;
42     int i;
44     /* Must start on a word aligned boundary */
45     if ((n & 0x3) != 0)  {
46         printf ("Error: Invalid block base offset specified\n");
47         return (-1);
48     }
50     /* The 1st two bytes are the address */
51     i2cBlock[0] = (addr >> 8) & 0xff;
52     i2cBlock[1] = (addr >> 0) & 0xff;
54     p = byteIndex >> 2;
57     for (i = 0; i < i2cBlockSize; i += 4, p++)  {
59         i2cBlock[i+2+0] = (i2cData[p] >> 24) & 0xff;
60         i2cBlock[i+2+1] = (i2cData[p] >> 16) & 0xff;
61         i2cBlock[i+2+2] = (i2cData[p] >>  8) & 0xff;
62         i2cBlock[i+2+3] = (i2cData[p] >>  0) & 0xff;
64     }
66     return (n+2);
68 }
69     
71 /**
72  *  @brief
73  *     Display the error returned by the i2c driver 
74  */
75 void showI2cError (I2C_RET iret)
76 {
77     char *ecode;
79     switch (iret)  {
80         case I2C_RET_LOST_ARB:        ecode = "I2C master lost an arbitration battle";
81                                       break;
83         case I2C_RET_NO_ACK:          ecode = "I2C master detected no ack from slave";
84                                       break;
86         case I2C_RET_IDLE_TIMEOUT:    ecode = "I2C timed out";
87                                       break;
89         case I2C_RET_BAD_REQUEST:     ecode = "I2C driver detected a bad data request";
90                                       break;
92         case I2C_RET_CLOCK_STUCK_LOW: ecode = "I2C driver found the bus stuck low";
93                                       break;
95         case I2C_RET_GEN_ERROR:       ecode = "I2C driver reported a general error";
96                                       break;
98     }
100     printf ("I2C reported error: %s\n", ecode);
105 void main (void)
107     I2C_RET i2cRet;
108     int     n;
109     int     remain;
110     int     progBytes;
112     volatile int i;
114     hwI2Cinit (deviceFreqMhz,
115                DEVICE_I2C_MODULE_DIVISOR,
116                25,                              /* Run the bus at 25 kHz */
117                10);
121     for (n = 0; n < nbytes; n += i2cBlockSize)  {
123         remain = nbytes - n;
124         if (remain > i2cBlockSize)
125             remain = i2cBlockSize;
127         /* formBlock sets up the address as well as the data */
128         progBytes = formBlock (dataAddress + n, n, remain);
130         if (progBytes < 0)
131             return;
133         /* Write the block */
134         i2cRet = hwI2cMasterWrite (busAddress,
135                                    i2cBlock,
136                                    progBytes,
137                                    I2C_RELEASE_BUS,
138                                    FALSE);
139         
141         if (i2cRet != I2C_RET_OK)  {
142             showI2cError (i2cRet);
143             return;
144         }
148         /* Some delay */
149         for (i = 0; i < 600000; i++);
151     }
154     printf ("I2C write complete\n");
156