1 | //////////////////////////////////////////////////////////////////////////
|
2 | void init_i2c (void)
|
3 | {
|
4 | // I2C Disable
|
5 | I2C1CONCLR_bit.I2ENC = 1;
|
6 |
|
7 |
|
8 | // CPU Taktteiler fuer I2C1
|
9 | // PCLKSEL1_bit.PCLK_I2C1 = 0; // CCLK/4
|
10 | PCLKSEL1_bit.PCLK_I2C1 = 1; // CCLK/1
|
11 | // PCLKSEL1_bit.PCLK_I2C1 = 2; // CCLK/2
|
12 | // PCLKSEL1_bit.PCLK_I2C1 = 3; // CCLK/8
|
13 |
|
14 |
|
15 | // I2C Takt
|
16 | // I2C Frequenz = PCLK_I2C / (I2C_I2SCLH + I2C_I2SCLL)
|
17 | // Register Wert ist Anzahl von Taktzyklen fuer high- oder low-Time
|
18 | I2C1SCLH = 70; // High-Time
|
19 | I2C1SCLL = 70; // Low-Time
|
20 |
|
21 | // Werte muessen groesser gleich 4 sein
|
22 | // if (I2C1SCLH < 4 || I2C1SCLL < 4) return;
|
23 |
|
24 |
|
25 | // I2C Configuration Register
|
26 | I2C1CONCLR_bit.AAC = 1; // ACK Flag Clear
|
27 | I2C1CONCLR_bit.SIC = 1; // Interrupt Flag Clear
|
28 | I2C1CONCLR_bit.STAC = 1; // Start Flag Clear
|
29 | I2C1CONSET_bit.I2EN = 1; // I2C Enable
|
30 | }
|
31 | ///////////////////////////////////////////////////////////////////////////
|
32 |
|
33 | ///////////////////////////////////////////////////////////////////////////
|
34 | unsigned char write_i2c (unsigned char addr, unsigned char *data, unsigned char data_cnt)
|
35 | {
|
36 | unsigned char i;
|
37 |
|
38 |
|
39 | // Start ausgeben
|
40 | I2C1CONSET_bit.STA = 1;
|
41 |
|
42 | // Auf Interrupt warten (Start fertig)
|
43 | while (!I2C1CONSET_bit.SI);
|
44 | if (I2C1STAT_bit.STATUS != 0x08) return 11;//FALSE;
|
45 |
|
46 | // Adresse ausgeben
|
47 | I2C1DAT = addr<<1; // Write = 8. Bit low
|
48 | // Start ruecksetzen
|
49 | //I2C1CONCLR_bit.STAC = 1; // Start ruecksetzen
|
50 | //I2C1CONCLR_bit.SIC = 1; // Interrupt ruecksetzen
|
51 | I2C1CONCLR = 0x20;
|
52 | I2C1CONCLR = 0x08;
|
53 |
|
54 |
|
55 | // Auf Interrupt warten (ACK Adresse + Write)
|
56 | while (!I2C1CONSET_bit.SI);
|
57 | if (I2C1STAT_bit.STATUS != 0x18) return 22;//FALSE;
|
58 |
|
59 |
|
60 | for (i = 0; i < data_cnt; i++)
|
61 | {
|
62 | // Daten ausgeben
|
63 | I2C1DAT = data[i];
|
64 | //I2C1CONCLR_bit.SIC = 1; // Interrupt ruecksetzen
|
65 | I2C1CONCLR = 0x08;
|
66 |
|
67 | // Auf Interrupt warten (TX fertig + ACK)
|
68 | while (!I2C1CONSET_bit.SI);
|
69 | if (I2C1STAT_bit.STATUS != 0x28) return 33;//FALSE;
|
70 | }
|
71 |
|
72 | //I2C1CONCLR_bit.SIC = 1; // Interrupt ruecksetzen
|
73 | I2C1CONCLR = 0x08;
|
74 |
|
75 | // Stop ausgeben
|
76 | I2C1CONSET_bit.STO = 1;
|
77 |
|
78 |
|
79 | return TRUE;
|
80 | }
|
81 | ///////////////////////////////////////////////////////////////////////////
|
82 |
|
83 | ///////////////////////////////////////////////////////////////////////////
|
84 | unsigned char read_i2c (unsigned char addr, unsigned char *data, unsigned char data_cnt)
|
85 | {
|
86 | unsigned char i;
|
87 |
|
88 |
|
89 | // Start ausgeben
|
90 | I2C1CONSET_bit.STA = 1;
|
91 |
|
92 | // Auf Interrupt warten (Start fertig)
|
93 | while (!I2C1CONSET_bit.SI);
|
94 | if (I2C1STAT_bit.STATUS != 0x08) return 11;//FALSE;
|
95 |
|
96 | // Adresse ausgeben
|
97 | I2C1DAT = (addr<<1) + 1; // Read = 8. Bit high
|
98 | // Start ruecksetzen
|
99 | //I2C1CONCLR_bit.STAC = 1; // Start ruecksetzen
|
100 | //I2C1CONCLR_bit.SIC = 1; // Interrupt ruecksetzen
|
101 | I2C1CONCLR = 0x20;
|
102 | I2C1CONCLR = 0x08;
|
103 |
|
104 |
|
105 | // Auf Interrupt warten (ACK Adresse + Read)
|
106 | while (!I2C1CONSET_bit.SI);
|
107 | if (I2C1STAT_bit.STATUS != 0x40) return 22;//FALSE;
|
108 | //I2C1CONCLR_bit.SIC = 1; // Interrupt ruecksetzen
|
109 | //I2C1CONCLR = 0x08;
|
110 |
|
111 |
|
112 | for (i = 0; i < data_cnt; i++)
|
113 | {
|
114 | // Immer ACK bis auf letztes Byte
|
115 | if (i+1 < data_cnt)
|
116 | {
|
117 | // ACK ausgeben
|
118 | I2C1CONSET_bit.AA = 1;
|
119 | //I2C1CONCLR_bit.SIC = 1; // Interrupt ruecksetzen
|
120 | I2C1CONCLR = 0x08;
|
121 |
|
122 | // Auf Interrupt warten (RX & ACK fertig)
|
123 | while (!I2C1CONSET_bit.SI);
|
124 | if (I2C1STAT_bit.STATUS != 0x50) return (33+i);//FALSE;
|
125 | }
|
126 | else
|
127 | {
|
128 | // NACK ausgeben
|
129 | //I2C1CONCLR_bit.AAC = 1;
|
130 | I2C1CONCLR = 0x04;
|
131 | //I2C1CONCLR_bit.SIC = 1; // Interrupt ruecksetzen
|
132 | I2C1CONCLR = 0x08;
|
133 |
|
134 | // Auf Interrupt warten (RX & NACK fertig)
|
135 | while (!I2C1CONSET_bit.SI);
|
136 | if (I2C1STAT_bit.STATUS != 0x58) return (33+i);//FALSE;
|
137 | }
|
138 |
|
139 |
|
140 | // Daten einlesen
|
141 | data[i] = I2C1DAT;
|
142 | }
|
143 |
|
144 | //I2C1CONCLR_bit.SIC = 1; // Interrupt ruecksetzen
|
145 | I2C1CONCLR = 0x08;
|
146 |
|
147 | // Stop ausgeben
|
148 | I2C1CONSET_bit.STO = 1;
|
149 |
|
150 |
|
151 | return TRUE;
|
152 | }
|
153 | ///////////////////////////////////////////////////////////////////////////
|