1#define USE_HW_I2C
2#ifdef USE_HW_I2C
3#include "ddk750_help.h"
4#include "ddk750_reg.h"
5#include "ddk750_hwi2c.h"
6#include "ddk750_power.h"
7
8#define MAX_HWI2C_FIFO                  16
9#define HWI2C_WAIT_TIMEOUT              0xF0000
10
11
12int hwI2CInit(
13    unsigned char busSpeedMode
14)
15{
16    unsigned int value;
17
18    /* Enable GPIO 30 & 31 as IIC clock & data */
19	value = PEEK32(GPIO_MUX);
20
21    value = FIELD_SET(value, GPIO_MUX, 30, I2C) |
22			FIELD_SET(0, GPIO_MUX, 31, I2C);
23	POKE32(GPIO_MUX, value);
24
25    /* Enable Hardware I2C power.
26       TODO: Check if we need to enable GPIO power?
27     */
28    enableI2C(1);
29
30    /* Enable the I2C Controller and set the bus speed mode */
31    value = PEEK32(I2C_CTRL);
32    if (busSpeedMode == 0)
33        value = FIELD_SET(value, I2C_CTRL, MODE, STANDARD);
34    else
35        value = FIELD_SET(value, I2C_CTRL, MODE, FAST);
36    value = FIELD_SET(value, I2C_CTRL, EN, ENABLE);
37    POKE32(I2C_CTRL, value);
38
39    return 0;
40}
41
42
43void hwI2CClose(void)
44{
45    unsigned int value;
46
47    /* Disable I2C controller */
48    value = PEEK32(I2C_CTRL);
49    value = FIELD_SET(value, I2C_CTRL, EN, DISABLE);
50    POKE32(I2C_CTRL, value);
51
52    /* Disable I2C Power */
53    enableI2C(0);
54
55    /* Set GPIO 30 & 31 back as GPIO pins */
56    value = PEEK32(GPIO_MUX);
57    value = FIELD_SET(value, GPIO_MUX, 30, GPIO);
58    value = FIELD_SET(value, GPIO_MUX, 31, GPIO);
59    POKE32(GPIO_MUX, value);
60}
61
62
63static long hwI2CWaitTXDone(void)
64{
65    unsigned int timeout;
66
67    /* Wait until the transfer is completed. */
68    timeout = HWI2C_WAIT_TIMEOUT;
69	while ((FIELD_GET(PEEK32(I2C_STATUS), I2C_STATUS, TX) != I2C_STATUS_TX_COMPLETED) &&
70           (timeout != 0))
71		timeout--;
72
73	if (timeout == 0)
74	    return (-1);
75
76    return 0;
77}
78
79
80
81/*
82 *  This function writes data to the i2c slave device registers.
83 *
84 *  Parameters:
85 *      deviceAddress   - i2c Slave device address
86 *      length          - Total number of bytes to be written to the device
87 *      pBuffer         - The buffer that contains the data to be written to the
88 *                     i2c device.
89 *
90 *  Return Value:
91 *      Total number of bytes those are actually written.
92 */
93static unsigned int hwI2CWriteData(
94    unsigned char deviceAddress,
95    unsigned int length,
96    unsigned char *pBuffer
97)
98{
99    unsigned char count, i;
100    unsigned int totalBytes = 0;
101
102    /* Set the Device Address */
103    POKE32(I2C_SLAVE_ADDRESS, deviceAddress & ~0x01);
104
105    /* Write data.
106     * Note:
107     *      Only 16 byte can be accessed per i2c start instruction.
108     */
109    do
110    {
111        /* Reset I2C by writing 0 to I2C_RESET register to clear the previous status. */
112        POKE32(I2C_RESET, 0);
113
114        /* Set the number of bytes to be written */
115        if (length < MAX_HWI2C_FIFO)
116            count = length - 1;
117        else
118            count = MAX_HWI2C_FIFO - 1;
119        POKE32(I2C_BYTE_COUNT, count);
120
121        /* Move the data to the I2C data register */
122	    for (i = 0; i <= count; i++)
123            POKE32(I2C_DATA0 + i, *pBuffer++);
124
125        /* Start the I2C */
126        POKE32(I2C_CTRL, FIELD_SET(PEEK32(I2C_CTRL), I2C_CTRL, CTRL, START));
127
128        /* Wait until the transfer is completed. */
129        if (hwI2CWaitTXDone() != 0)
130            break;
131
132        /* Substract length */
133        length -= (count + 1);
134
135        /* Total byte written */
136        totalBytes += (count + 1);
137
138    } while (length > 0);
139
140    return totalBytes;
141}
142
143
144
145
146/*
147 *  This function reads data from the slave device and stores them
148 *  in the given buffer
149 *
150 *  Parameters:
151 *      deviceAddress   - i2c Slave device address
152 *      length          - Total number of bytes to be read
153 *      pBuffer         - Pointer to a buffer to be filled with the data read
154 *                     from the slave device. It has to be the same size as the
155 *                     length to make sure that it can keep all the data read.
156 *
157 *  Return Value:
158 *      Total number of actual bytes read from the slave device
159 */
160static unsigned int hwI2CReadData(
161    unsigned char deviceAddress,
162    unsigned int length,
163    unsigned char *pBuffer
164)
165{
166    unsigned char count, i;
167    unsigned int totalBytes = 0;
168
169    /* Set the Device Address */
170    POKE32(I2C_SLAVE_ADDRESS, deviceAddress | 0x01);
171
172    /* Read data and save them to the buffer.
173     * Note:
174     *      Only 16 byte can be accessed per i2c start instruction.
175     */
176    do
177    {
178        /* Reset I2C by writing 0 to I2C_RESET register to clear all the status. */
179        POKE32(I2C_RESET, 0);
180
181        /* Set the number of bytes to be read */
182        if (length <= MAX_HWI2C_FIFO)
183            count = length - 1;
184        else
185            count = MAX_HWI2C_FIFO - 1;
186        POKE32(I2C_BYTE_COUNT, count);
187
188        /* Start the I2C */
189        POKE32(I2C_CTRL, FIELD_SET(PEEK32(I2C_CTRL), I2C_CTRL, CTRL, START));
190
191        /* Wait until transaction done. */
192        if (hwI2CWaitTXDone() != 0)
193            break;
194
195        /* Save the data to the given buffer */
196        for (i = 0; i <= count; i++)
197		    *pBuffer++ = PEEK32(I2C_DATA0 + i);
198
199        /* Substract length by 16 */
200        length -= (count + 1);
201
202        /* Number of bytes read. */
203        totalBytes += (count + 1);
204
205    } while (length > 0);
206
207    return totalBytes;
208}
209
210
211
212
213/*
214 *  This function reads the slave device's register
215 *
216 *  Parameters:
217 *      deviceAddress   - i2c Slave device address which register
218 *                        to be read from
219 *      registerIndex   - Slave device's register to be read
220 *
221 *  Return Value:
222 *      Register value
223 */
224unsigned char hwI2CReadReg(
225    unsigned char deviceAddress,
226    unsigned char registerIndex
227)
228{
229    unsigned char value = (0xFF);
230
231    if (hwI2CWriteData(deviceAddress, 1, &registerIndex) == 1)
232        hwI2CReadData(deviceAddress, 1, &value);
233
234    return value;
235}
236
237
238
239
240
241/*
242 *  This function writes a value to the slave device's register
243 *
244 *  Parameters:
245 *      deviceAddress   - i2c Slave device address which register
246 *                        to be written
247 *      registerIndex   - Slave device's register to be written
248 *      data            - Data to be written to the register
249 *
250 *  Result:
251 *          0   - Success
252 *         -1   - Fail
253 */
254int hwI2CWriteReg(
255    unsigned char deviceAddress,
256    unsigned char registerIndex,
257    unsigned char data
258)
259{
260    unsigned char value[2];
261
262    value[0] = registerIndex;
263    value[1] = data;
264    if (hwI2CWriteData(deviceAddress, 2, value) == 2)
265        return 0;
266
267    return (-1);
268}
269
270
271#endif
272