f3d93e09edcf2d1aef6016e054f910db1d6556d1
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 }
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);
102 }
105 void main (void)
106 {
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);
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");
155 }