]> Gitweb @ Texas Instruments - Open Source Git Repositories - git.TI.com/gitweb - keystone-rtos/ibl.git/blob - src/hw/i2c/i2c.c
Bug fix - added endian swap for MDIO parameters
[keystone-rtos/ibl.git] / src / hw / i2c / i2c.c
1 /****************************************************************************
2  * FILE PURPOSE: An i2c driver for the rom boot loader
3  ****************************************************************************
4  * FILE NAME: i2c.c
5  *
6  * DESCRIPTION: Provides an i2c driver for the rom boot loader. The driver
7  *              is adapted from the csl polling driver in the 64x csl.
8  *
9  ****************************************************************************/ 
10 #include "types.h"
11 #include "i2c.h"
12 #include "i2cloc.h"
13 #include "target.h"
15 #define DEVICE_REG32_W(x,y)   *(volatile unsigned int *)(x)=(y)
16 #define DEVICE_REG32_R(x)    (*(volatile unsigned int *)(x))
18  /**************************************************************************
19   * Global variables
20   *************************************************************************/
21  UINT32 i2cCoreFreqMhz;
22  UINT32 i2cBitPeriodCycles; 
25 /***********************************************************************************
26  * FUNCTION PURPOSE: Provide an approximate delay
27  ***********************************************************************************
28  * DESCRIPTION: A delay in units of CPU cycles is executed
29  ***********************************************************************************/
30 static void chipDelay32 (uint32 del)
31 {
32     volatile unsigned int i;
34     for (i = 0; i < del/8; i++);
36 }
39 /***************************************************************************
40  * FUNCTION PURPOSE: Generate a delay
41  ***************************************************************************
42  * DESCRIPTION: Creates a delay specified in usec
43  ***************************************************************************/
44 void hw_i2c_delay_usec (UINT32 usec)
45 {
46   UINT32 delayCycles;
48   delayCycles = usec * i2cCoreFreqMhz;
50   chipDelay32 (delayCycles);
52 } /* hw_i2c_delay_usec */
53  
54  
55  /***************************************************************************
56   * FUNCTION PURPOSE: Initialize the I2C.
57   ***************************************************************************
58   * DESCRIPTION: Puts the I2C into reset, sets up the device and takes
59   *              the device out of reset in slave receiver mode.
60   **************************************************************************/
61 void hwI2Cinit (UINT16 coreFreqMhz, UINT16 moduleDivisor, UINT16 clkFreqKhz, UINT16 ownAddr)
62  {
63    UINT32 psc;
64    UINT32 clkx;
65    UINT32 tmp;
66    UINT32 moduleFreqMhzQ1;
67    UINT32 trueModFreqHz;
68    UINT32 trueModFreqkHz;
69  
70    /* Put the i2c peripheral into reset */
71    DEVICE_REG32_W (DEVICE_I2C_BASE + I2C_REG_MDR, I2C_VAL_REG_MDR_RESET);
72    
73    /* To determine the module prescaler Q31.1 format will be used. This is just
74     * handled simply since the input module frequency is an integer it will just
75     * be multiplied by two. Dividing two Q31.1 result in a Q30.0, or the divider *
76     * Calculate module prescalars to get as close to target frequencies as possible */
77    moduleFreqMhzQ1 = (coreFreqMhz << 1) / moduleDivisor;
78    psc = moduleFreqMhzQ1 / I2C_TARGET_MODULE_FREQ_MHZ_Q1;
79    if (psc > 0)
80      psc = psc - 1;
81    trueModFreqHz = ((UINT32)coreFreqMhz * (UINT32)1000000) / (moduleDivisor * (psc+1));
82    
83    tmp = trueModFreqHz / (clkFreqKhz * 1000);
84    if (tmp > 12) 
85      clkx = (tmp - 12) >> 1;
86    else
87      clkx = 0;
88      
89    /* Store the core frequency for use in generating delay */
90    i2cCoreFreqMhz = coreFreqMhz;
91    
92    /* Calculate the number of micro seconds for each bit. */
93    trueModFreqkHz = trueModFreqHz / 1000;  /* Prevent 32 bit integer overlflow */
94    i2cBitPeriodCycles = (UINT32)coreFreqMhz * 1000 * (2 * clkx + 12) / trueModFreqkHz;
95    
96    /* Initialize the registers */
97    DEVICE_REG32_W(DEVICE_I2C_BASE + I2C_REG_PSC, (UINT32)psc); 
98    DEVICE_REG32_W(DEVICE_I2C_BASE + I2C_REG_OAR, (UINT32)ownAddr);
99    DEVICE_REG32_W(DEVICE_I2C_BASE + I2C_REG_IER, (UINT32)0);
100    DEVICE_REG32_W(DEVICE_I2C_BASE + I2C_REG_STR, I2C_VAL_REG_STR_RESET);
101    DEVICE_REG32_W(DEVICE_I2C_BASE + I2C_REG_CLKL, clkx);
102    DEVICE_REG32_W(DEVICE_I2C_BASE + I2C_REG_CLKH, clkx); 
103    DEVICE_REG32_W(DEVICE_I2C_BASE + I2C_REG_CNT, (UINT32)0);
104    DEVICE_REG32_W(DEVICE_I2C_BASE + I2C_REG_SAR, (UINT32)0x3ff);
105    DEVICE_REG32_W(DEVICE_I2C_BASE + I2C_REG_DXR, (UINT32)0);
106    DEVICE_REG32_W(DEVICE_I2C_BASE + I2C_REG_PFUNC, (UINT32)0);
107    
108    /* Take the I2C out of reset in the slave receiver mode */
109    DEVICE_REG32_W(DEVICE_I2C_BASE + I2C_REG_MDR, I2C_VAL_REG_MDR_SLVRCV);
110    
111    /* Read the receive register to clear it */
112    tmp = DEVICE_REG32_R(DEVICE_I2C_BASE + I2C_REG_DRR);
115 } /* hwI2Cinit */
118 /****************************************************************************
119  * FUNCTION PURPOSE: Perform a master write 
120  ****************************************************************************
121  * DESCRIPTION: Enters master transmitter mode, writes a specified number
122  *              of bytes. The byte stream arrives packed in the 16 bit
123  *              data stream, and are sent most significant byte first.
124  ****************************************************************************/
125 I2C_RET hwI2cMasterWrite (UINT16 eeprom_i2c_id, UINT8 *eData, UINT16 nbytes, UINT16 endBusState, BOOL busIsMine)
127   UINT32 timeoutCount;
128   UINT32 polling;
129   UINT32 value;
130   UINT32 str;
131   UINT16 i;
133   /* If the byte length is 0 there is nothing to do */
134   if (nbytes == 0)
135     return (I2C_RET_OK);
136    
137   /* Check for the bus busy signal */
138   if (busIsMine == FALSE)  {
139     timeoutCount = 0;
140     do  { 
141       polling = I2C_REG_STR_FIELD_BB(DEVICE_REG32_R (DEVICE_I2C_BASE + I2C_REG_STR));
142     
143       if (polling != 0)  {
144         hw_i2c_delay_usec (I2C_MASTER_TRANSMITTER_BUS_ACCESS_DELAY_US);
145       
146         timeoutCount += 1;
147         if (timeoutCount >= I2C_MAX_MASTER_TRANSMITTER_BUS_ACCESS_TIMEOUT)  {
148       
149           /* Return to slave receiver, clear nack and bus busy */
150           DEVICE_REG32_W (DEVICE_I2C_BASE + I2C_REG_MDR, I2C_VAL_REG_MDR_SLVRCV);
151           DEVICE_REG32_W (DEVICE_I2C_BASE + I2C_REG_STR, I2C_VAL_REG_STR_ON_FAIL);
152           return (I2C_RET_IDLE_TIMEOUT);
153         }
154       } else  { /* The bus is free */
155         timeoutCount = 0;
156       }
157     }
158     while (timeoutCount != 0);
160   }
161       
162   /* Enter master transmitter mode, set the slave address register */
163   DEVICE_REG32_W (DEVICE_I2C_BASE + I2C_REG_MDR, I2C_VAL_REG_MDR_MSTXMT);
164   DEVICE_REG32_W (DEVICE_I2C_BASE + I2C_REG_SAR, (UINT32)eeprom_i2c_id);
165   
166   /* Put the first byte into the transmit register, set the start bit */
167   value = *eData & 0x00ff;
168   eData = eData + 1;
169   DEVICE_REG32_W (DEVICE_I2C_BASE + I2C_REG_DXR, value);
170   
172   /* Some delay required */
173   chipDelay32 (i2cBitPeriodCycles);
175   /* Set the start bit */
176   DEVICE_REG32_W (DEVICE_I2C_BASE + I2C_REG_MDR, I2C_VAL_REG_MDR_MSTXMTSTRT);
177   
178   for (i = 1; i < nbytes; i++)  {
179     timeoutCount = 0;
180   
181     do  {
182       /* Read status */
183       str = DEVICE_REG32_R (DEVICE_I2C_BASE + I2C_REG_STR);
184     
185       /* On Nack return failure */
186       if (I2C_REG_STR_FIELD_NACK(str) != 0)  {
187       
188         /* Return to slave receiver, clear nack and bus busy */
189         DEVICE_REG32_W (DEVICE_I2C_BASE + I2C_REG_MDR, I2C_VAL_REG_MDR_SLVRCV);
190         DEVICE_REG32_W (DEVICE_I2C_BASE + I2C_REG_STR, I2C_VAL_REG_STR_ON_FAIL);
191         return (I2C_RET_NO_ACK);
192       }
193         
194       /* Check for transmit ready */
195       if (I2C_REG_STR_FIELD_XRDY(str) != 0)  {
196         timeoutCount = 0;
197         
198         value = *eData & 0x00ff;
199         eData =  eData + 1;
200         
201         DEVICE_REG32_W (DEVICE_I2C_BASE + I2C_REG_DXR, value);
203         
204       }  else  {   /* XRDY bit not set */
205         chipDelay32 (i2cBitPeriodCycles);
206         timeoutCount += 1;
207         if (timeoutCount >= I2C_MAX_MASTER_TRANSMITTER_TIMEOUT)  {
208           /* Return to slave receiver, clear nack and bus busy */
209           DEVICE_REG32_W (DEVICE_I2C_BASE + I2C_REG_MDR, I2C_VAL_REG_MDR_SLVRCV);
210           DEVICE_REG32_W (DEVICE_I2C_BASE + I2C_REG_STR, I2C_VAL_REG_STR_ON_FAIL);
211           return (I2C_RET_IDLE_TIMEOUT);
212         }
213       }
214           
215     } while (timeoutCount != 0);
217   } /* end for loop */
219   
220   /* If releasing the bus, send a stop bit */
221   if (endBusState == I2C_RELEASE_BUS)  {
222   
223     /* Wait for the ardy bit to go high */
224     timeoutCount = 0;
225     do  {
226       str = DEVICE_REG32_R (DEVICE_I2C_BASE + I2C_REG_STR);
227       if (I2C_REG_STR_FIELD_ARDY(str) != 0)  {
228         DEVICE_REG32_W (DEVICE_I2C_BASE + I2C_REG_MDR, I2C_VAL_REG_MDR_MSTXMTSTOP);
229         DEVICE_REG32_W (DEVICE_I2C_BASE + I2C_REG_STR, I2C_VAL_REG_STR_CLR_BUSY);
230         hw_i2c_delay_usec (10000);
231         timeoutCount = 0;
232         
233       } else  { /* Registers not ready for access */
234         timeoutCount += 1;
235         
236         if (timeoutCount >= I2C_MAX_MASTER_TRANSMITTER_ARDY_TIMEOUT)  {
237            /* On timeout put the peripheral into reset, wait, then
238             * take it out of reset */
239            DEVICE_REG32_W (DEVICE_I2C_BASE + I2C_REG_MDR, I2C_VAL_REG_MDR_RESET);
240            hw_i2c_delay_usec (10000);
241            DEVICE_REG32_W (DEVICE_I2C_BASE + I2C_REG_MDR, I2C_VAL_REG_MDR_SLVRCV);
242            return (I2C_RET_IDLE_TIMEOUT);
243          }
244         chipDelay32 (i2cBitPeriodCycles); 
245       }
246     } while (timeoutCount != 0);
247     
248   } /* end bus release */
249   
250   return (I2C_RET_OK);
251   
252 } /* hwI2cMasterWrite */
253    
254   
256 /**************************************************************************
257  * FUNCTION PURPOSE: Perform a master read from an I2C prom
258  **************************************************************************
259  * DESCRIPTION: Reads a fixed number of bytes from an I2C prom. The read
260  *              consists of a master write of 2 bytes (forming a 16 bit address,
261  *              msb transmitted first), followed by a master read of the
262  *              input number of bytes. The bytes that are read are placed
263  *              in p_packed_bytes in big endian format.
264  **************************************************************************/
265 I2C_RET hwI2cMasterRead (
266   UINT32           byte_addr,
267   UINT32           byte_len,
268   UINT8           *p_packed_bytes,
269   UINT16           eeprom_i2c_id,
270   UINT16           address_delay)
273   UINT32  str;  
274   UINT32  timeoutCount;
275   UINT32  i;
276   UINT8   eAddr[2];
277   I2C_RET ret;
279   /* If the byte length is 0, there is nothing to do */
280   if (byte_len == 0)
281     return (I2C_RET_OK);
282     
283   /* Write the byte address to the eeprom. Do not send a stop */
284   eAddr[0] = (byte_addr >> 8) & 0xff;
285   eAddr[1] = byte_addr & 0xff;
287   ret = hwI2cMasterWrite (eeprom_i2c_id, eAddr, 2, I2C_DO_NOT_RELEASE_BUS, FALSE);
288   if (ret != I2C_RET_OK)
289     return (ret);
290     
291   /* Give the I2C prom some time to process the read command */
292   chipDelay32 (((UINT32)address_delay)<<8);
294   /* Set the start bit, begin the master read */
295   DEVICE_REG32_W (DEVICE_I2C_BASE + I2C_REG_MDR, I2C_VAL_REG_MDR_MSTRCV);
297   /* Read the requested number of bytes */
298   for (i = 0; i < byte_len; i++)  {
299     timeoutCount = 0;
300   
301     do  {
302       /* Read status */
303       str = DEVICE_REG32_R (DEVICE_I2C_BASE + I2C_REG_STR);
304     
305       /* On Nack return failure */
306       if (I2C_REG_STR_FIELD_NACK(str) != 0)  {
307       
308         /* Return to slave receiver, clear nack and bus busy */
309         DEVICE_REG32_W (DEVICE_I2C_BASE + I2C_REG_MDR, I2C_VAL_REG_MDR_SLVRCV);
310         DEVICE_REG32_W (DEVICE_I2C_BASE + I2C_REG_STR, I2C_VAL_REG_STR_ON_FAIL);
311         return (I2C_RET_NO_ACK);
312       }
313         
314       /* Check for receive byte ready */
315       if (I2C_REG_STR_FIELD_RRDY(str) != 0)  {
316         *p_packed_bytes = (UINT16) (DEVICE_REG32_R (DEVICE_I2C_BASE + I2C_REG_DRR) & 0x00ff);
317         timeoutCount = 0;
318         p_packed_bytes = p_packed_bytes + 1;
319         
320         
321       }  else  {   /* RRDY bit not set */
322         chipDelay32 (i2cBitPeriodCycles);
323         timeoutCount += 1;
324         if (timeoutCount >= I2C_MAX_MASTER_RECEIVE_TIMEOUT)  {
325           /* Return to slave receiver, clear nack and bus busy */
326           DEVICE_REG32_W (DEVICE_I2C_BASE + I2C_REG_MDR, I2C_VAL_REG_MDR_SLVRCV);
327           DEVICE_REG32_W (DEVICE_I2C_BASE + I2C_REG_STR, I2C_VAL_REG_STR_ON_FAIL);
328           return (I2C_RET_IDLE_TIMEOUT);
329         }
330       }
331           
332     } while (timeoutCount != 0);
334   } /* end for loop */
336   /* The data block has been read. Send the stop bit */
337   DEVICE_REG32_W (DEVICE_I2C_BASE + I2C_REG_MDR, I2C_VAL_REG_MDR_MSTRCVSTOP);
338         
340   /* Wait for the rrdy and read the dummy byte */
341   timeoutCount = 0;
342   do  {
344     str = DEVICE_REG32_R (DEVICE_I2C_BASE + I2C_REG_STR);
346     /* Check for receive byte ready */
347     if (I2C_REG_STR_FIELD_RRDY(str) != 0)  {
348       eAddr[0] = (UINT16) (DEVICE_REG32_R (DEVICE_I2C_BASE + I2C_REG_DRR) & 0x00ff);
349       timeoutCount = 0;
351     }  else  {  /* rrdy not set */
353       chipDelay32 (i2cBitPeriodCycles);
354       timeoutCount += 1;
355       if (timeoutCount >= I2C_MAX_MASTER_RECEIVE_TIMEOUT)  {
356         /* Return to slave receiver, clear nack and bus busy */
357         DEVICE_REG32_W (DEVICE_I2C_BASE + I2C_REG_MDR, I2C_VAL_REG_MDR_SLVRCV);
358         DEVICE_REG32_W (DEVICE_I2C_BASE + I2C_REG_STR, I2C_VAL_REG_STR_ON_FAIL);
359         return (I2C_RET_IDLE_TIMEOUT);
360       }
361     }
363   } while (timeoutCount != 0);
364   
365   return (I2C_RET_OK);
366   
367 } /* hwI2cMasterRead */
368