v0.1 board believed to be reading Vbat, Pressure, and X/Y/Z correctly now,
[fw/openalt] / i2c / i2cPolled.c
1 #include "FreeRTOS.h"
2
3 #include <stdio.h>
4 #include <sys/times.h>
5
6 #include "i2c.h"
7
8 //
9 //  Default timeout, in milliseconds for generic read/write
10 //
11 #define I2C_DEFAULT_TIMEOUT 100
12
13 //
14 //
15 //
16 typedef enum
17 {
18   I2CFLAGS_START         = 0x0001,
19   I2CFLAGS_REPEATEDSTART = 0x0002,
20   I2CFLAGS_STOP          = 0x0004,
21   I2CFLAGS_ADDRESS       = 0x0008,
22   I2CFLAGS_WRITEDATA     = 0x0010,
23   I2CFLAGS_READDATA      = 0x0020,
24 }
25 i2cFlags_e;
26
27 typedef enum
28 {
29   I2CMODE_ACK = 0,
30   I2CMODE_NACK,
31   I2CMODE_READ
32 }
33 i2cMode_e;
34
35 //
36 //
37 //
38 static unsigned int i2cTimeoutInTicks = I2C_DEFAULT_TIMEOUT / portTICK_RATE_MS;
39
40 //
41 //  Our PCLK is 48Mhz (12Mhz Xtal, PLL x 4, VBPDIV = /1), we want 100Khz SCLK
42 //
43 void i2cInit (void)
44 {
45   SCB_PCONP |= SCB_PCONP_PCI2C0;
46
47   PCB_PINSEL0 = (PCB_PINSEL0 & ~(PCB_PINSEL0_P02_MASK | PCB_PINSEL0_P03_MASK)) | (PCB_PINSEL0_P02_SCL0 | PCB_PINSEL0_P03_SDA0);
48
49   I2C0_CONCLR = I2C_CONCLR_MASK;
50   I2C0_CONSET = I2C_CONSET_I2EN;
51   I2C0_SCLL   = 480;
52   I2C0_SCLH   = 480;
53 }
54
55 //
56 //
57 //
58 static i2cErr_e i2cStatus (void)
59 {
60   i2cErr_e status;
61
62   while (!(I2C0_CONSET & I2C_CONSET_SI))
63     ;
64
65   if ((status = I2C0_STAT) == I2CERR_BUSERRORx)
66     return I2CERR_BUSERROR;
67
68   return status;
69 }
70
71 //
72 //
73 //
74 static i2cErr_e i2cStop (void)
75 {
76   I2C0_CONCLR = I2C_CONCLR_SIC;
77   I2C0_CONSET = I2C_CONSET_STO;
78
79   while (I2C0_CONSET & I2C_CONSET_STO)
80     ;
81
82   return I2CERR_NONE;
83 }
84
85 //
86 //
87 //
88 static i2cErr_e i2cStart (void)
89 {
90   I2C0_CONCLR = I2C_CONCLR_SIC;
91   I2C0_CONSET = I2C_CONSET_STA;
92
93   while (1)
94   {
95     i2cErr_e status;
96
97     if (((status = i2cStatus ()) == I2CERR_STARTTX) || (status == I2CERR_REPEATEDSTARTTX))
98     {
99       I2C0_CONCLR = I2C_CONCLR_STAC;
100       return I2CERR_NONE;
101     }
102     else if (status != I2CERR_NOINFO)
103     {
104       I2C0_CONCLR = I2C_CONCLR_STAC;
105       return status;
106     }
107     else
108       I2C0_CONCLR = I2C_CONCLR_SIC;
109   }
110 }
111
112 //
113 //
114 //
115 static i2cErr_e i2cRepeatedStart (void)
116 {
117   while (!(I2C0_CONSET & I2C_CONSET_SI))
118     ;
119
120   I2C0_CONCLR = I2C_CONCLR_SIC;
121   I2C0_CONSET = I2C_CONSET_STA;
122
123   while (1)
124   {
125     i2cErr_e status;
126
127     if (((status = i2cStatus ()) == I2CERR_STARTTX) || (status == I2CERR_REPEATEDSTARTTX))
128     {
129       I2C0_CONCLR = I2C_CONCLR_STAC;
130       return I2CERR_NONE;
131     }
132     else if (status != I2CERR_NOINFO)
133     {
134       I2C0_CONCLR = I2C_CONCLR_STAC;
135       return status;
136     }
137     else
138       I2C0_CONCLR = I2C_CONCLR_SIC;
139   }
140 }
141
142 //
143 //
144 //
145 static i2cErr_e i2cPutByte (U8 data)
146 {
147   if (!(I2C0_CONSET & I2C_CONSET_SI))
148     return I2CERR_BUSY;
149
150   I2C0_DAT = data;
151   I2C0_CONCLR = I2C_CONCLR_SIC;
152
153   return I2CERR_NONE;
154 }
155
156 //
157 //
158 //
159 static i2cErr_e i2cGetByte (i2cMode_e mode, U8 *pData)
160 {
161   switch (mode)
162   {
163     case I2CMODE_ACK :
164       I2C0_CONCLR = I2C_CONCLR_SIC;
165       I2C0_CONSET = I2C_CONSET_AA;
166       break;
167
168     case I2CMODE_NACK :
169       I2C0_CONCLR = (I2C_CONCLR_AAC | I2C_CONCLR_SIC);
170       break;
171
172     case I2CMODE_READ :
173       {
174         if (!(I2C0_CONSET & I2C_CONSET_SI))
175           return I2CERR_EMPTY;
176
177         *pData = (U8) I2C0_DAT;
178       }
179       break;
180   }
181
182   return I2CERR_NONE;
183
184
185 //
186 //
187 //
188 static i2cErr_e i2cWriteBufferEx (U8 address, U8 *buffer, U32 bufferLength, i2cFlags_e flags)
189 {
190   U32 i;
191   i2cErr_e status;
192
193   if (flags & I2CFLAGS_START)
194   {
195     if ((status = i2cStart ()) != I2CERR_NONE)
196     {
197       i2cStop ();
198       return status;
199     }
200   }
201   else if (flags & I2CFLAGS_REPEATEDSTART)
202   {
203     if ((status = i2cRepeatedStart ()) != I2CERR_NONE)
204     {
205       i2cStop ();
206       return status;
207     }
208   }
209
210   if (flags & I2CFLAGS_ADDRESS)
211   {
212     do
213       if (((status = i2cPutByte (address & ~0x01)) != I2CERR_NONE) && (status != I2CERR_BUSY))
214         return status;
215     while (status == I2CERR_BUSY);
216   }
217
218   if (flags & I2CFLAGS_WRITEDATA)
219   {
220     for (i = 0; i < bufferLength; i++, buffer++)
221     {
222       while (1)
223       {
224         if (((status = i2cStatus ()) == I2CERR_SLAWTX_ACKRX) || (status == I2CERR_DATTX_ACKRX))
225         {
226           do
227             if (((status = i2cPutByte (*buffer)) != I2CERR_NONE) && (status != I2CERR_BUSY))
228               return status;
229           while (status == I2CERR_BUSY);
230
231           break;
232         }
233         else if (status != I2CERR_NOINFO)
234         {
235           i2cStop ();
236           return status;
237         }
238       }
239     }
240   }
241
242   if (flags & I2CFLAGS_STOP)
243   {
244     while (1)
245     {
246       if (((status = i2cStatus ()) == I2CERR_SLAWTX_ACKRX) || (status == I2CERR_DATTX_ACKRX))
247       {
248         i2cStop ();
249         return I2CERR_NONE;
250       }
251       else if (status != I2CERR_NOINFO)
252       {
253         i2cStop ();
254         return status;
255       }
256     }
257   }
258
259   return I2CERR_NONE;
260 }
261
262 //
263 //
264 //
265 static i2cErr_e i2cReadBufferEx (U8 address, U8 *buffer, U32 bufferLength, i2cFlags_e flags)
266 {
267   U32 i;
268   i2cErr_e status;
269
270   if (flags & I2CFLAGS_START)
271   {
272     if ((status = i2cStart ()) != I2CERR_NONE)
273     {
274       i2cStop ();
275       return status;
276     }
277   }
278   else if (flags & I2CFLAGS_REPEATEDSTART)
279   {
280     if ((status = i2cRepeatedStart ()) != I2CERR_NONE)
281     {
282       i2cStop ();
283       return status;
284     }
285   }
286
287   if (flags & I2CFLAGS_ADDRESS)
288   {
289     do
290       if (((status = i2cPutByte (address | 0x01)) != I2CERR_NONE) && (status != I2CERR_BUSY))
291         return status;
292     while (status == I2CERR_BUSY);
293   }
294
295   if (flags & I2CFLAGS_READDATA)
296   {
297     for (i = 0; i < bufferLength; i++, buffer++)
298     {
299       while (1)
300       {
301         if (((status = i2cStatus ()) == I2CERR_SLARTX_ACKRX) || (status == I2CERR_SLARTX_NACKRX) || (status == I2CERR_DATRX_ACKTX))
302         {
303           i2cGetByte ((i != bufferLength - 1) ? I2CMODE_ACK : I2CMODE_NACK, NULL);
304
305           do
306             status = i2cGetByte (I2CMODE_READ, buffer);
307           while (status == I2CERR_EMPTY);
308
309           break;
310         }
311         else if (status != I2CERR_NOINFO)
312         {
313           i2cStop ();
314           return status;
315         }
316       }
317     }
318   }
319
320   if (flags & I2CFLAGS_STOP)
321     i2cStop ();
322
323   return I2CERR_NONE;
324 }
325
326 //
327 //
328 //
329 static int i2cPoll (U8 address)
330 {
331   clock_t theFuture = times (NULL) + i2cTimeoutInTicks;
332
333   while (times (NULL) < theFuture)
334   {
335     if ((i2cErrno = i2cStart ()) != I2CERR_NONE)
336       break;
337     if ((i2cErrno = i2cPutByte (address & ~0x01)) != I2CERR_NONE)
338       break;
339     if ((i2cErrno = i2cStatus ()) == I2CERR_SLAWTX_ACKRX)
340       break;
341   }
342
343   if (i2cErrno != I2CERR_SLAWTX_ACKRX)
344     i2cErrno = I2CERR_TIMEOUTACKPOLL;
345
346   i2cStop ();
347
348   return (i2cErrno == I2CERR_SLAWTX_ACKRX) ? 0 : -1;
349 }
350
351 //
352 //
353 //
354 void i2cSetTimeout (unsigned int timeoutInMilliseconds)
355 {
356   if (timeoutInMilliseconds < portTICK_RATE_MS)
357     timeoutInMilliseconds = portTICK_RATE_MS;
358
359   i2cTimeoutInTicks = timeoutInMilliseconds / portTICK_RATE_MS;
360 }
361
362 void i2cDump (void)
363 {
364   printf ("i2cDump not implemented for polled mode\n");
365 }
366
367 int i2cWriteBuffer (U8 address, U8 *buffer, U32 bufferLength)
368 {
369   if ((i2cErrno = i2cWriteBufferEx (address, buffer, bufferLength, I2CFLAGS_START | I2CFLAGS_ADDRESS | I2CFLAGS_WRITEDATA | I2CFLAGS_STOP)) != I2CERR_NONE)
370     return -1;
371
372   return 0;
373 }
374
375 int i2cReadBuffer (U8 address, U8 *buffer, U32 bufferLength)
376 {
377   if ((i2cErrno = i2cReadBufferEx (address, buffer, bufferLength, I2CFLAGS_START | I2CFLAGS_ADDRESS | I2CFLAGS_READDATA | I2CFLAGS_STOP)) != I2CERR_NONE)
378     return -1;
379
380   return 0;
381 }
382
383 int i2cWriteReadBuffer (U8 address, U8 *buffer, U32 putLength, U32 getLength)
384 {
385   if ((i2cErrno = i2cWriteBufferEx (address, buffer, putLength, I2CFLAGS_START | I2CFLAGS_ADDRESS | I2CFLAGS_WRITEDATA)) != I2CERR_NONE)
386     return -1;
387
388   if ((i2cErrno = i2cReadBufferEx (address, buffer, getLength, I2CFLAGS_REPEATEDSTART | I2CFLAGS_ADDRESS | I2CFLAGS_READDATA | I2CFLAGS_STOP)) != I2CERR_NONE)
389     return -1;
390
391   return 0;
392 }
393
394 int i2cWriteBufferPoll (U8 address, U8 *buffer, U32 bufferLength)
395 {
396   int r;
397
398   if (!(r = i2cWriteBuffer (address, buffer, bufferLength)))
399     r = i2cPoll (address);
400
401   return r;
402 }
403
404 int i2cWriteReadBufferPoll (U8 address, U8 *buffer, U32 putLength, U32 getLength)
405 {
406   int r;
407
408   if (!(r = i2cWriteReadBuffer (address, buffer, putLength, getLength)))
409     r = i2cPoll (address);
410
411   return r;
412 }