1 /*
2 *
3 * Copyright (C) 2010 Texas Instruments Incorporated - http://www.ti.com/
4 *
5 *
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
8 * are met:
9 *
10 * Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 *
13 * Redistributions in binary form must reproduce the above copyright
14 * notice, this list of conditions and the following disclaimer in the
15 * documentation and/or other materials provided with the
16 * distribution.
17 *
18 * Neither the name of Texas Instruments Incorporated nor the names of
19 * its contributors may be used to endorse or promote products derived
20 * from this software without specific prior written permission.
21 *
22 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
23 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
24 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
25 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
26 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
27 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
28 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
29 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
30 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
31 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
32 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
33 *
34 */
38 /****************************************************************************
39 * FILE PURPOSE: An i2c driver for the rom boot loader
40 ****************************************************************************
41 * FILE NAME: i2c.c
42 *
43 * DESCRIPTION: Provides an i2c driver for the rom boot loader. The driver
44 * is adapted from the csl polling driver in the 64x csl.
45 *
46 ****************************************************************************/
47 #include "types.h"
48 #include "i2c.h"
49 #include "i2cloc.h"
50 #include "target.h"
52 #define DEVICE_REG32_W(x,y) *(volatile unsigned int *)(x)=(y)
53 #define DEVICE_REG32_R(x) (*(volatile unsigned int *)(x))
55 /**************************************************************************
56 * Global variables
57 *************************************************************************/
58 UINT32 i2cCoreFreqMhz;
59 UINT32 i2cBitPeriodCycles;
62 /***********************************************************************************
63 * FUNCTION PURPOSE: Provide an approximate delay
64 ***********************************************************************************
65 * DESCRIPTION: A delay in units of CPU cycles is executed
66 ***********************************************************************************/
67 static void chipDelay32 (uint32 del)
68 {
69 volatile unsigned int i;
71 for (i = 0; i < del/8; i++);
73 }
76 /***************************************************************************
77 * FUNCTION PURPOSE: Generate a delay
78 ***************************************************************************
79 * DESCRIPTION: Creates a delay specified in usec
80 ***************************************************************************/
81 void hw_i2c_delay_usec (UINT32 usec)
82 {
83 UINT32 delayCycles;
85 delayCycles = usec * i2cCoreFreqMhz;
87 chipDelay32 (delayCycles);
89 } /* hw_i2c_delay_usec */
92 /***************************************************************************
93 * FUNCTION PURPOSE: Initialize the I2C.
94 ***************************************************************************
95 * DESCRIPTION: Puts the I2C into reset, sets up the device and takes
96 * the device out of reset in slave receiver mode.
97 **************************************************************************/
98 void hwI2Cinit (UINT16 coreFreqMhz, UINT16 moduleDivisor, UINT16 clkFreqKhz, UINT16 ownAddr)
99 {
100 UINT32 psc;
101 UINT32 clkx;
102 UINT32 tmp;
103 UINT32 moduleFreqMhzQ1;
104 UINT32 trueModFreqHz;
105 UINT32 trueModFreqkHz;
107 /* Put the i2c peripheral into reset */
108 DEVICE_REG32_W (DEVICE_I2C_BASE + I2C_REG_MDR, I2C_VAL_REG_MDR_RESET);
110 /* To determine the module prescaler Q31.1 format will be used. This is just
111 * handled simply since the input module frequency is an integer it will just
112 * be multiplied by two. Dividing two Q31.1 result in a Q30.0, or the divider *
113 * Calculate module prescalars to get as close to target frequencies as possible */
114 moduleFreqMhzQ1 = (coreFreqMhz << 1) / moduleDivisor;
115 psc = moduleFreqMhzQ1 / I2C_TARGET_MODULE_FREQ_MHZ_Q1;
116 if (psc > 0)
117 psc = psc - 1;
118 trueModFreqHz = ((UINT32)coreFreqMhz * (UINT32)1000000) / (moduleDivisor * (psc+1));
120 tmp = trueModFreqHz / (clkFreqKhz * 1000);
121 if (tmp > 12)
122 clkx = (tmp - 12) >> 1;
123 else
124 clkx = 0;
126 /* Store the core frequency for use in generating delay */
127 i2cCoreFreqMhz = coreFreqMhz;
129 /* Calculate the number of micro seconds for each bit. */
130 trueModFreqkHz = trueModFreqHz / 1000; /* Prevent 32 bit integer overlflow */
131 i2cBitPeriodCycles = (UINT32)coreFreqMhz * 1000 * (2 * clkx + 12) / trueModFreqkHz;
133 /* Initialize the registers */
134 DEVICE_REG32_W(DEVICE_I2C_BASE + I2C_REG_PSC, (UINT32)psc);
135 DEVICE_REG32_W(DEVICE_I2C_BASE + I2C_REG_OAR, (UINT32)ownAddr);
136 DEVICE_REG32_W(DEVICE_I2C_BASE + I2C_REG_IER, (UINT32)0);
137 DEVICE_REG32_W(DEVICE_I2C_BASE + I2C_REG_STR, I2C_VAL_REG_STR_RESET);
138 DEVICE_REG32_W(DEVICE_I2C_BASE + I2C_REG_CLKL, clkx);
139 DEVICE_REG32_W(DEVICE_I2C_BASE + I2C_REG_CLKH, clkx);
140 DEVICE_REG32_W(DEVICE_I2C_BASE + I2C_REG_CNT, (UINT32)0);
141 DEVICE_REG32_W(DEVICE_I2C_BASE + I2C_REG_SAR, (UINT32)0x3ff);
142 DEVICE_REG32_W(DEVICE_I2C_BASE + I2C_REG_DXR, (UINT32)0);
143 DEVICE_REG32_W(DEVICE_I2C_BASE + I2C_REG_PFUNC, (UINT32)0);
145 /* Take the I2C out of reset in the slave receiver mode */
146 DEVICE_REG32_W(DEVICE_I2C_BASE + I2C_REG_MDR, I2C_VAL_REG_MDR_SLVRCV);
148 /* Read the receive register to clear it */
149 tmp = DEVICE_REG32_R(DEVICE_I2C_BASE + I2C_REG_DRR);
152 } /* hwI2Cinit */
155 /****************************************************************************
156 * FUNCTION PURPOSE: Perform a master write
157 ****************************************************************************
158 * DESCRIPTION: Enters master transmitter mode, writes a specified number
159 * of bytes. The byte stream arrives packed in the 16 bit
160 * data stream, and are sent most significant byte first.
161 ****************************************************************************/
162 I2C_RET hwI2cMasterWrite (UINT16 eeprom_i2c_id, UINT8 *eData, UINT16 nbytes, UINT16 endBusState, BOOL busIsMine)
163 {
164 UINT32 timeoutCount;
165 UINT32 polling;
166 UINT32 value;
167 UINT32 str;
168 UINT16 i;
170 /* If the byte length is 0 there is nothing to do */
171 if (nbytes == 0)
172 return (I2C_RET_OK);
174 /* Check for the bus busy signal */
175 if (busIsMine == FALSE) {
176 timeoutCount = 0;
177 do {
178 polling = I2C_REG_STR_FIELD_BB(DEVICE_REG32_R (DEVICE_I2C_BASE + I2C_REG_STR));
180 if (polling != 0) {
181 hw_i2c_delay_usec (I2C_MASTER_TRANSMITTER_BUS_ACCESS_DELAY_US);
183 timeoutCount += 1;
184 if (timeoutCount >= I2C_MAX_MASTER_TRANSMITTER_BUS_ACCESS_TIMEOUT) {
186 /* Return to slave receiver, clear nack and bus busy */
187 DEVICE_REG32_W (DEVICE_I2C_BASE + I2C_REG_MDR, I2C_VAL_REG_MDR_SLVRCV);
188 DEVICE_REG32_W (DEVICE_I2C_BASE + I2C_REG_STR, I2C_VAL_REG_STR_ON_FAIL);
189 return (I2C_RET_IDLE_TIMEOUT);
190 }
191 } else { /* The bus is free */
192 timeoutCount = 0;
193 }
194 }
195 while (timeoutCount != 0);
197 }
199 /* Enter master transmitter mode, set the slave address register */
200 DEVICE_REG32_W (DEVICE_I2C_BASE + I2C_REG_MDR, I2C_VAL_REG_MDR_MSTXMT);
201 DEVICE_REG32_W (DEVICE_I2C_BASE + I2C_REG_SAR, (UINT32)eeprom_i2c_id);
203 /* Put the first byte into the transmit register, set the start bit */
204 value = *eData & 0x00ff;
205 eData = eData + 1;
206 DEVICE_REG32_W (DEVICE_I2C_BASE + I2C_REG_DXR, value);
209 /* Some delay required */
210 chipDelay32 (i2cBitPeriodCycles);
212 /* Set the start bit */
213 DEVICE_REG32_W (DEVICE_I2C_BASE + I2C_REG_MDR, I2C_VAL_REG_MDR_MSTXMTSTRT);
215 for (i = 1; i < nbytes; i++) {
216 timeoutCount = 0;
218 do {
219 /* Read status */
220 str = DEVICE_REG32_R (DEVICE_I2C_BASE + I2C_REG_STR);
222 /* On Nack return failure */
223 if (I2C_REG_STR_FIELD_NACK(str) != 0) {
225 /* Return to slave receiver, clear nack and bus busy */
226 DEVICE_REG32_W (DEVICE_I2C_BASE + I2C_REG_MDR, I2C_VAL_REG_MDR_SLVRCV);
227 DEVICE_REG32_W (DEVICE_I2C_BASE + I2C_REG_STR, I2C_VAL_REG_STR_ON_FAIL);
228 return (I2C_RET_NO_ACK);
229 }
231 /* Check for transmit ready */
232 if (I2C_REG_STR_FIELD_XRDY(str) != 0) {
233 timeoutCount = 0;
235 value = *eData & 0x00ff;
236 eData = eData + 1;
238 DEVICE_REG32_W (DEVICE_I2C_BASE + I2C_REG_DXR, value);
241 } else { /* XRDY bit not set */
242 chipDelay32 (i2cBitPeriodCycles);
243 timeoutCount += 1;
244 if (timeoutCount >= I2C_MAX_MASTER_TRANSMITTER_TIMEOUT) {
245 /* Return to slave receiver, clear nack and bus busy */
246 DEVICE_REG32_W (DEVICE_I2C_BASE + I2C_REG_MDR, I2C_VAL_REG_MDR_SLVRCV);
247 DEVICE_REG32_W (DEVICE_I2C_BASE + I2C_REG_STR, I2C_VAL_REG_STR_ON_FAIL);
248 return (I2C_RET_IDLE_TIMEOUT);
249 }
250 }
252 } while (timeoutCount != 0);
254 } /* end for loop */
257 /* If releasing the bus, send a stop bit */
258 if (endBusState == I2C_RELEASE_BUS) {
260 /* Wait for the ardy bit to go high */
261 timeoutCount = 0;
262 do {
263 str = DEVICE_REG32_R (DEVICE_I2C_BASE + I2C_REG_STR);
264 if (I2C_REG_STR_FIELD_ARDY(str) != 0) {
265 DEVICE_REG32_W (DEVICE_I2C_BASE + I2C_REG_MDR, I2C_VAL_REG_MDR_MSTXMTSTOP);
266 DEVICE_REG32_W (DEVICE_I2C_BASE + I2C_REG_STR, I2C_VAL_REG_STR_CLR_BUSY);
267 hw_i2c_delay_usec (10000);
268 timeoutCount = 0;
270 } else { /* Registers not ready for access */
271 timeoutCount += 1;
273 if (timeoutCount >= I2C_MAX_MASTER_TRANSMITTER_ARDY_TIMEOUT) {
274 /* On timeout put the peripheral into reset, wait, then
275 * take it out of reset */
276 DEVICE_REG32_W (DEVICE_I2C_BASE + I2C_REG_MDR, I2C_VAL_REG_MDR_RESET);
277 hw_i2c_delay_usec (10000);
278 DEVICE_REG32_W (DEVICE_I2C_BASE + I2C_REG_MDR, I2C_VAL_REG_MDR_SLVRCV);
279 return (I2C_RET_IDLE_TIMEOUT);
280 }
281 chipDelay32 (i2cBitPeriodCycles);
282 }
283 } while (timeoutCount != 0);
285 } /* end bus release */
287 return (I2C_RET_OK);
289 } /* hwI2cMasterWrite */
293 /**************************************************************************
294 * FUNCTION PURPOSE: Perform a master read from an I2C prom
295 **************************************************************************
296 * DESCRIPTION: Reads a fixed number of bytes from an I2C prom. The read
297 * consists of a master write of 2 bytes (forming a 16 bit address,
298 * msb transmitted first), followed by a master read of the
299 * input number of bytes. The bytes that are read are placed
300 * in p_packed_bytes in big endian format.
301 **************************************************************************/
302 I2C_RET hwI2cMasterRead (
303 UINT32 byte_addr,
304 UINT32 byte_len,
305 UINT8 *p_packed_bytes,
306 UINT16 eeprom_i2c_id,
307 UINT16 address_delay)
308 {
310 UINT32 str;
311 UINT32 timeoutCount;
312 UINT32 i;
313 UINT8 eAddr[2];
314 I2C_RET ret;
316 /* If the byte length is 0, there is nothing to do */
317 if (byte_len == 0)
318 return (I2C_RET_OK);
320 /* Write the byte address to the eeprom. Do not send a stop */
321 eAddr[0] = (byte_addr >> 8) & 0xff;
322 eAddr[1] = byte_addr & 0xff;
324 ret = hwI2cMasterWrite (eeprom_i2c_id, eAddr, 2, I2C_DO_NOT_RELEASE_BUS, FALSE);
325 if (ret != I2C_RET_OK)
326 return (ret);
328 /* Give the I2C prom some time to process the read command */
329 chipDelay32 (((UINT32)address_delay)<<8);
331 /* Set the start bit, begin the master read */
332 DEVICE_REG32_W (DEVICE_I2C_BASE + I2C_REG_MDR, I2C_VAL_REG_MDR_MSTRCV);
334 /* Read the requested number of bytes */
335 for (i = 0; i < byte_len; i++) {
336 timeoutCount = 0;
338 do {
339 /* Read status */
340 str = DEVICE_REG32_R (DEVICE_I2C_BASE + I2C_REG_STR);
342 /* On Nack return failure */
343 if (I2C_REG_STR_FIELD_NACK(str) != 0) {
345 /* Return to slave receiver, clear nack and bus busy */
346 DEVICE_REG32_W (DEVICE_I2C_BASE + I2C_REG_MDR, I2C_VAL_REG_MDR_SLVRCV);
347 DEVICE_REG32_W (DEVICE_I2C_BASE + I2C_REG_STR, I2C_VAL_REG_STR_ON_FAIL);
348 return (I2C_RET_NO_ACK);
349 }
351 /* Check for receive byte ready */
352 if (I2C_REG_STR_FIELD_RRDY(str) != 0) {
353 *p_packed_bytes = (UINT16) (DEVICE_REG32_R (DEVICE_I2C_BASE + I2C_REG_DRR) & 0x00ff);
354 timeoutCount = 0;
355 p_packed_bytes = p_packed_bytes + 1;
358 } else { /* RRDY bit not set */
359 chipDelay32 (i2cBitPeriodCycles);
360 timeoutCount += 1;
361 if (timeoutCount >= I2C_MAX_MASTER_RECEIVE_TIMEOUT) {
362 /* Return to slave receiver, clear nack and bus busy */
363 DEVICE_REG32_W (DEVICE_I2C_BASE + I2C_REG_MDR, I2C_VAL_REG_MDR_SLVRCV);
364 DEVICE_REG32_W (DEVICE_I2C_BASE + I2C_REG_STR, I2C_VAL_REG_STR_ON_FAIL);
365 return (I2C_RET_IDLE_TIMEOUT);
366 }
367 }
369 } while (timeoutCount != 0);
371 } /* end for loop */
373 /* The data block has been read. Send the stop bit */
374 DEVICE_REG32_W (DEVICE_I2C_BASE + I2C_REG_MDR, I2C_VAL_REG_MDR_MSTRCVSTOP);
377 /* Wait for the rrdy and read the dummy byte */
378 timeoutCount = 0;
379 do {
381 str = DEVICE_REG32_R (DEVICE_I2C_BASE + I2C_REG_STR);
383 /* Check for receive byte ready */
384 if (I2C_REG_STR_FIELD_RRDY(str) != 0) {
385 eAddr[0] = (UINT16) (DEVICE_REG32_R (DEVICE_I2C_BASE + I2C_REG_DRR) & 0x00ff);
386 timeoutCount = 0;
388 } else { /* rrdy not set */
390 chipDelay32 (i2cBitPeriodCycles);
391 timeoutCount += 1;
392 if (timeoutCount >= I2C_MAX_MASTER_RECEIVE_TIMEOUT) {
393 /* Return to slave receiver, clear nack and bus busy */
394 DEVICE_REG32_W (DEVICE_I2C_BASE + I2C_REG_MDR, I2C_VAL_REG_MDR_SLVRCV);
395 DEVICE_REG32_W (DEVICE_I2C_BASE + I2C_REG_STR, I2C_VAL_REG_STR_ON_FAIL);
396 return (I2C_RET_IDLE_TIMEOUT);
397 }
398 }
400 } while (timeoutCount != 0);
402 return (I2C_RET_OK);
404 } /* hwI2cMasterRead */