1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19#include <stdio.h>
20#include <stdlib.h>
21#include <string.h>
22#include <vxWorks.h>
23#include <sysLib.h>
24#include <iosLib.h>
25#include <logLib.h>
26#include <tickLib.h>
27
28
29#include "config.h"
30#include "mpc8220.h"
31#include "i2cCore.h"
32
33#ifdef DEBUG_I2CCORE
34int I2CCDbg = 0;
35#endif
36
37#define ABS(x) ((x < 0)? -x : x)
38
39char *I2CERR[16] = {
40 "Transfer in Progress\n",
41 "Transfer complete\n",
42 "Not Addressed\n",
43 "Addressed as a slave\n",
44 "Bus is Idle\n",
45 "Bus is busy\n",
46 "Arbitration Lost\n",
47 "Arbitration on Track\n",
48 "Slave receive, master writing to slave\n",
49 "Slave transmit, master reading from slave\n",
50 "Interrupt is pending\n",
51 "Interrupt complete\n",
52 "Acknowledge received\n",
53 "No acknowledge received\n",
54 "Unknown status\n",
55 "\n"
56};
57
58
59
60
61
62
63
64
65
66STATUS chk_status (PSI2C pi2c, UINT8 sta_bit, UINT8 truefalse)
67{
68 int i, status = 0;
69
70 for (i = 0; i < I2C_POLL_COUNT; i++) {
71 if ((pi2c->sr & sta_bit) == (truefalse ? sta_bit : 0))
72 return (OK);
73 }
74
75 I2CCDBG (L2, ("--- sr %x stabit %x truefalse %d\n",
76 pi2c->sr, sta_bit, truefalse, 0, 0, 0));
77
78 if (i == I2C_POLL_COUNT) {
79 switch (sta_bit) {
80 case I2C_STA_CF:
81 status = 0;
82 break;
83 case I2C_STA_AAS:
84 status = 2;
85 break;
86 case I2C_STA_BB:
87 status = 4;
88 break;
89 case I2C_STA_AL:
90 status = 6;
91 break;
92 case I2C_STA_SRW:
93 status = 8;
94 break;
95 case I2C_STA_IF:
96 status = 10;
97 break;
98 case I2C_STA_RXAK:
99 status = 12;
100 break;
101 default:
102 status = 14;
103 break;
104 }
105
106 if (!truefalse)
107 status++;
108
109 I2CCDBG (NO, ("--- status %d\n", status, 0, 0, 0, 0, 0));
110 I2CCDBG (NO, (I2CERR[status], 0, 0, 0, 0, 0, 0));
111 }
112
113 return (ERROR);
114}
115
116
117
118
119
120
121STATUS i2c_enable (SI2C * pi2c, PI2CSET pi2cSet)
122{
123 int fdr = pi2cSet->bit_rate;
124 UINT8 adr = pi2cSet->i2c_adr;
125
126 I2CCDBG (L2, ("i2c_enable fdr %d adr %x\n", fdr, adr, 0, 0, 0, 0));
127
128 i2c_clear (pi2c);
129
130 SetI2cFDR (pi2c, fdr);
131 pi2c->adr = adr;
132
133 pi2c->cr = I2C_CTL_EN;
134
135
136
137
138
139 if (chk_status (pi2c, I2C_STA_BB, 0) != OK) {
140 if ((pi2c->cr & I2C_CTL_STA) == I2C_CTL_STA)
141 pi2c->cr &= ~I2C_CTL_STA;
142
143
144 if (chk_status (pi2c, I2C_STA_BB, 1) == OK)
145 return ERROR;
146 }
147
148 return (OK);
149}
150
151
152
153
154
155
156STATUS i2c_disable (PSI2C pi2c)
157{
158 i2c_clear (pi2c);
159
160 pi2c->cr &= I2C_CTL_EN;
161
162 if ((pi2c->cr & I2C_CTL_STA) == I2C_CTL_STA)
163 pi2c->cr &= ~I2C_CTL_STA;
164
165 if (chk_status (pi2c, I2C_STA_BB, 0) != OK)
166 return ERROR;
167
168 return (OK);
169}
170
171
172
173
174
175
176STATUS i2c_clear (PSI2C pi2c)
177{
178 pi2c->adr = 0;
179 pi2c->fdr = 0;
180 pi2c->cr = 0;
181 pi2c->sr = 0;
182
183 return (OK);
184}
185
186
187STATUS i2c_start (PSI2C pi2c, PI2CSET pi2cSet)
188{
189#ifdef TWOBYTES
190 UINT16 ByteOffset = pi2cSet->str_adr;
191#else
192 UINT8 ByteOffset = pi2cSet->str_adr;
193#endif
194#if 1
195 UINT8 tmp = 0;
196#endif
197 UINT8 Addr = pi2cSet->slv_adr;
198
199 pi2c->cr |= I2C_CTL_STA;
200
201 if (chk_status (pi2c, I2C_STA_BB, 1) != OK)
202 return ERROR;
203
204
205 if (i2c_writebyte (pi2c, &Addr) != OK) {
206 i2c_stop (pi2c);
207 return ERROR;
208 }
209#ifdef TWOBYTES
210# if 0
211
212 if (i2c_write2byte (pi2c, &ByteOffset) != OK) {
213 i2c_stop (pi2c);
214 return ERROR;
215 }
216#endif
217 tmp = (ByteOffset >> 8) & 0xff;
218 if (i2c_writebyte (pi2c, &tmp) != OK) {
219 i2c_stop (pi2c);
220 return ERROR;
221 }
222 tmp = ByteOffset & 0xff;
223 if (i2c_writebyte (pi2c, &tmp) != OK) {
224 i2c_stop (pi2c);
225 return ERROR;
226 }
227#else
228 if (i2c_writebyte (pi2c, &ByteOffset) != OK) {
229 i2c_stop (pi2c);
230 return ERROR;
231 }
232#endif
233
234 return (OK);
235}
236
237STATUS i2c_stop (PSI2C pi2c)
238{
239 pi2c->cr &= ~I2C_CTL_STA;
240 if (chk_status (pi2c, I2C_STA_BB, 0) != OK)
241 return ERROR;
242
243 return (OK);
244}
245
246
247
248
249
250
251int i2c_readblock (SI2C * pi2c, PI2CSET pi2cSet, UINT8 * Data)
252{
253 int i = 0;
254 UINT8 Tmp;
255
256
257 UINT8 Addr = pi2cSet->slv_adr;
258 int Length = pi2cSet->xfer_size;
259
260 I2CCDBG (L1, ("i2c_readblock addr %x data 0x%08x len %d offset %d\n",
261 Addr, (int) Data, Length, ByteOffset, 0, 0));
262
263 if (pi2c->sr & I2C_STA_AL) {
264 I2CCDBG (FN, ("Arbitration lost\n", 0, 0, 0, 0, 0, 0));
265 pi2c->sr &= ~I2C_STA_AL;
266 return ERROR;
267 }
268
269 pi2c->cr |= I2C_CTL_TX;
270
271 if (i2c_start (pi2c, pi2cSet) == ERROR)
272 return ERROR;
273
274 pi2c->cr |= I2C_CTL_RSTA;
275
276 Tmp = Addr | 1;
277
278 if (i2c_writebyte (pi2c, &Tmp) != OK) {
279 i2c_stop (pi2c);
280 return ERROR;
281 }
282
283 if (((pi2c->sr & 0x07) == 0x07) || (pi2c->sr & 0x01))
284 return ERROR;
285
286 pi2c->cr &= ~I2C_CTL_TX;
287
288 if (((pi2c->sr & 0x07) == 0x07) || (pi2c->sr & 0x01))
289 return ERROR;
290
291
292 if (i2c_readbyte (pi2c, &Tmp, &i) != OK) {
293 i2c_stop (pi2c);
294 return ERROR;
295 }
296
297 i = 0;
298 while (Length) {
299 if (Length == 2)
300 pi2c->cr |= I2C_CTL_TXAK;
301
302 if (Length == 1)
303 pi2c->cr &= ~I2C_CTL_STA;
304
305 if (i2c_readbyte (pi2c, Data, &Length) != OK) {
306 return i2c_stop (pi2c);
307 }
308 i++;
309 Length--;
310 Data++;
311 }
312
313 if (i2c_stop (pi2c) == ERROR)
314 return ERROR;
315
316 return i;
317}
318
319STATUS i2c_writeblock (SI2C * pi2c, PI2CSET pi2cSet, UINT8 * Data)
320{
321 int Length = pi2cSet->xfer_size;
322
323#ifdef TWOBYTES
324 UINT16 ByteOffset = pi2cSet->str_adr;
325#else
326 UINT8 ByteOffset = pi2cSet->str_adr;
327#endif
328 int j, k;
329
330 I2CCDBG (L2, ("i2c_writeblock\n", 0, 0, 0, 0, 0, 0));
331
332 if (pi2c->sr & I2C_STA_AL) {
333
334 I2CCDBG (L2, ("Arbitration lost\n", 0, 0, 0, 0, 0, 0));
335 pi2c->sr &= ~I2C_STA_AL;
336 return ERROR;
337 }
338
339 pi2c->cr |= I2C_CTL_TX;
340
341
342 if ((ByteOffset % 8) != 0) {
343 int remain;
344
345 if (Length > 8) {
346 remain = 8 - (ByteOffset % 8);
347 Length -= remain;
348
349 pi2cSet->str_adr = ByteOffset;
350
351 if (i2c_start (pi2c, pi2cSet) == ERROR)
352 return ERROR;
353
354 for (j = ByteOffset; j < remain; j++) {
355 if (i2c_writebyte (pi2c, Data++) != OK)
356 return ERROR;
357 }
358
359 if (i2c_stop (pi2c) == ERROR)
360 return ERROR;
361
362 sysMsDelay (32);
363
364
365 ByteOffset += remain;
366 }
367 }
368
369 for (j = ByteOffset, k = 0; j < (Length + ByteOffset); j++) {
370 if ((j % 8) == 0) {
371 pi2cSet->str_adr = j;
372 if (i2c_start (pi2c, pi2cSet) == ERROR)
373 return ERROR;
374 }
375
376 k++;
377
378 if (i2c_writebyte (pi2c, Data++) != OK)
379 return ERROR;
380
381 if ((j == (Length - 1)) || ((k % 8) == 0)) {
382 if (i2c_stop (pi2c) == ERROR)
383 return ERROR;
384
385 sysMsDelay (50);
386 }
387
388 }
389
390 return k;
391}
392
393STATUS i2c_readbyte (SI2C * pi2c, UINT8 * readb, int *index)
394{
395 pi2c->sr &= ~I2C_STA_IF;
396 *readb = pi2c->dr;
397
398
399
400
401
402 if (*index != 2) {
403 if (chk_status (pi2c, I2C_STA_CF, 1) != OK)
404 return ERROR;
405 }
406
407 if (*index != 1) {
408 if (chk_status (pi2c, I2C_STA_IF, 1) != OK)
409 return ERROR;
410 }
411
412 return (OK);
413}
414
415
416STATUS i2c_writebyte (SI2C * pi2c, UINT8 * writeb)
417{
418 pi2c->sr &= ~I2C_STA_IF;
419 pi2c->dr = *writeb;
420
421 if (chk_status (pi2c, I2C_STA_CF, 1) != OK)
422 return ERROR;
423
424 if (chk_status (pi2c, I2C_STA_IF, 1) != OK)
425 return ERROR;
426
427 return OK;
428}
429
430STATUS i2c_write2byte (SI2C * pi2c, UINT16 * writeb)
431{
432 UINT8 data;
433
434 data = (UINT8) ((*writeb >> 8) & 0xff);
435 if (i2c_writebyte (pi2c, &data) != OK)
436 return ERROR;
437 data = (UINT8) (*writeb & 0xff);
438 if (i2c_writebyte (pi2c, &data) != OK)
439 return ERROR;
440 return OK;
441}
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511STATUS SetI2cFDR (PSI2C pi2cRegs, int bitrate)
512{
513
514 const UINT8 div_hold[8][3] = { {9, 3}, {10, 3},
515 {12, 4}, {15, 4},
516 {5, 1}, {6, 1},
517 {7, 2}, {8, 2}
518 };
519
520 const UINT8 scl_tap[8][2] = { {4, 1}, {4, 2},
521 {6, 4}, {6, 8},
522 {14, 16}, {30, 32},
523 {62, 64}, {126, 128}
524 };
525
526 UINT8 mfdr_bits;
527
528 int i = 0;
529 int j = 0;
530
531 int Diff, min;
532 int WhichFreq, iRec, jRec;
533 int SCL_Period;
534 int SCL_Hold;
535 int I2C_Freq;
536
537 I2CCDBG (L2, ("Entering getBitRate: bitrate %d pi2cRegs 0x%08x\n",
538 bitrate, (int) pi2cRegs, 0, 0, 0, 0));
539
540 if (bitrate < 0) {
541 I2CCDBG (NO, ("Invalid bitrate\n", 0, 0, 0, 0, 0, 0));
542 return ERROR;
543 }
544
545
546 mfdr_bits = 0;
547 min = 0x7fffffff;
548 WhichFreq = iRec = jRec = 0;
549
550 for (i = 0; i < 8; i++) {
551 for (j = 0; j < 8; j++) {
552
553
554
555
556 SCL_Period =
557 2 * (scl_tap[i][0] +
558 ((div_hold[j][0] - 1) * scl_tap[i][1]) +
559 2);
560
561
562 I2C_Freq = DEV_CLOCK_FREQ / SCL_Period;
563
564
565 if (I2C_Freq > bitrate)
566 continue;
567
568
569 Diff = I2C_Freq - bitrate;
570
571 Diff = ABS (Diff);
572
573
574 if (Diff < min) {
575 min = Diff;
576 WhichFreq = I2C_Freq;
577 iRec = i;
578 jRec = j;
579 }
580
581 I2CCDBG (L2,
582 ("--- (%d,%d) I2C_Freq %d minDiff %d min %d\n",
583 i, j, I2C_Freq, Diff, min, 0));
584 }
585 }
586
587 SCL_Period =
588 2 * (scl_tap[iRec][0] +
589 ((div_hold[jRec][0] - 1) * scl_tap[iRec][1]) + 2);
590
591 I2CCDBG (L2, ("\nmin %d WhichFreq %d iRec %d jRec %d\n",
592 min, WhichFreq, iRec, jRec, 0, 0));
593 I2CCDBG (L2, ("--- scl2tap %d SCL_Tap %d tap2tap %d\n",
594 scl_tap[iRec][0], div_hold[jRec][0], scl_tap[iRec][1],
595 0, 0, 0));
596
597
598 SCL_Hold =
599 scl_tap[iRec][0] +
600 ((div_hold[jRec][1] - 1) * scl_tap[iRec][1]) + 3;
601 I2CCDBG (L2,
602 ("--- SCL_Period %d SCL_Hold %d\n", SCL_Period, SCL_Hold, 0,
603 0, 0, 0));
604
605 I2CCDBG (L2, ("--- mfdr_bits %x\n", mfdr_bits, 0, 0, 0, 0, 0));
606
607
608 if ((iRec & 1) == 1)
609 mfdr_bits |= 0x04;
610 if ((iRec & 2) == 2)
611 mfdr_bits |= 0x08;
612 if ((iRec & 4) == 4)
613 mfdr_bits |= 0x10;
614
615 if ((jRec & 1) == 1)
616 mfdr_bits |= 0x01;
617 if ((jRec & 2) == 2)
618 mfdr_bits |= 0x02;
619 if ((jRec & 4) == 4)
620 mfdr_bits |= 0x20;
621
622 I2CCDBG (L2, ("--- mfdr_bits %x\n", mfdr_bits, 0, 0, 0, 0, 0));
623
624 pi2cRegs->fdr = mfdr_bits;
625
626 return OK;
627}
628