1 | #include <i2c.h>
|
2 | #include <libpic30.h>
|
3 | #include "i2c_func.h"
|
4 | //function initiates I2C1 module to baud rate BRG
|
5 | void i2c_init(int BRG)
|
6 | {
|
7 | int temp;
|
8 |
|
9 | // I2CBRG = 194 for 10Mhz OSCI with PPL with 100kHz I2C clock
|
10 | I2C2BRG = BRG;
|
11 | I2C2CONbits.I2CEN = 0; // Disable I2C Mode
|
12 | I2C2CONbits.DISSLW = 1; // Disable slew rate control
|
13 | IFS3bits.MI2C2IF = 0; // Clear Interrupt
|
14 | I2C2CONbits.I2CEN = 1; // Enable I2C Mode
|
15 | temp = I2C2RCV; // read buffer to clear buffer full
|
16 | reset_i2c_bus(); // set bus to idle
|
17 | }
|
18 |
|
19 |
|
20 | //function iniates a start condition on bus
|
21 | void i2c_start(void)
|
22 | {
|
23 | int x = 0;
|
24 | I2C2CONbits.ACKDT = 0; //Reset any previous Ack
|
25 | __delay32(36);
|
26 | I2C2CONbits.SEN = 1; //Initiate Start condition
|
27 | Nop();
|
28 |
|
29 | //the hardware will automatically clear Start Bit
|
30 | //wait for automatic clear before proceding
|
31 | while (I2C2CONbits.SEN)
|
32 | {
|
33 | __delay32(12);
|
34 | x++;
|
35 | if (x > 20)
|
36 | break;
|
37 | }
|
38 | __delay32(24);
|
39 | }
|
40 |
|
41 |
|
42 | void i2c_restart(void)
|
43 | {
|
44 | int x = 0;
|
45 |
|
46 | I2C2CONbits.RSEN = 1; //Initiate restart condition
|
47 | Nop();
|
48 |
|
49 | //the hardware will automatically clear restart bit
|
50 | //wait for automatic clear before proceding
|
51 | while (I2C2CONbits.RSEN)
|
52 | {
|
53 | __delay32(12);
|
54 | x++;
|
55 | if (x > 20) break;
|
56 | }
|
57 |
|
58 | __delay32(24);
|
59 | }
|
60 |
|
61 |
|
62 | //Resets the I2C bus to Idle
|
63 | void reset_i2c_bus(void)
|
64 | {
|
65 | int x = 0;
|
66 |
|
67 | //initiate stop bit
|
68 | I2C2CONbits.PEN = 1;
|
69 |
|
70 | //wait for hardware clear of stop bit
|
71 | while (I2C2CONbits.PEN)
|
72 | {
|
73 | __delay32(12);
|
74 | x ++;
|
75 | if (x > 20) break;
|
76 | }
|
77 | I2C2CONbits.RCEN = 0;
|
78 | //IFS1bits.MI2C1IF = 0; // Clear Interrupt
|
79 | IFS3bits.MI2C2IF = 0;
|
80 | I2C2STATbits.IWCOL = 0;
|
81 | I2C2STATbits.BCL = 0;
|
82 | __delay32(120);
|
83 | }
|
84 |
|
85 |
|
86 | //basic I2C byte send
|
87 | char send_i2c_byte(int data)
|
88 | {
|
89 | int i;
|
90 |
|
91 | while (I2C2STATbits.TBF) { }
|
92 | // IFS1bits.MI2C1IF = 0; // Clear Interrupt
|
93 | IFS3bits.MI2C2IF = 0;
|
94 | I2C2TRN = data; // load the outgoing data byte
|
95 |
|
96 | // wait for transmission
|
97 | for (i=0; i<500; i++)
|
98 | {
|
99 | if (!I2C2STATbits.TRSTAT) break;
|
100 | __delay32(12);
|
101 |
|
102 | }
|
103 | if (i == 500) {
|
104 | return(1);
|
105 | }
|
106 |
|
107 | // Check for NO_ACK from slave, abort if not found
|
108 | if (I2C2STATbits.ACKSTAT == 1)
|
109 | {
|
110 | reset_i2c_bus();
|
111 | return(1);
|
112 | }
|
113 |
|
114 | __delay32(24);
|
115 | return(0);
|
116 | }
|
117 |
|
118 | //function reads data, returns the read data, no ack
|
119 | char i2c_read(void)
|
120 | {
|
121 | int i = 0;
|
122 | char data = 0;
|
123 |
|
124 | //set I2C module to receive
|
125 | I2C2CONbits.RCEN = 1;
|
126 |
|
127 | //if no response, break
|
128 | while (!I2C2STATbits.RBF)
|
129 | {
|
130 | i ++;
|
131 | if (i > 2000) break;
|
132 | }
|
133 |
|
134 | //get data from I2CRCV register
|
135 | data = I2C2RCV;
|
136 | //set nack
|
137 | I2C2CONbits.ACKEN = 0;
|
138 |
|
139 | //wait before exiting
|
140 | __delay32(120);
|
141 |
|
142 |
|
143 | //return data
|
144 | return data;
|
145 | }
|
146 |
|
147 |
|
148 |
|
149 | //function reads data, returns the read data, with ack
|
150 | char i2c_read_ack(void) //does not reset bus!!!
|
151 | {
|
152 | int i = 0;
|
153 | char data = 0;
|
154 |
|
155 | //set I2C module to receive
|
156 | I2C2CONbits.RCEN = 1;
|
157 |
|
158 | //if no response, break
|
159 | while (!I2C2STATbits.RBF)
|
160 | {
|
161 | i++;
|
162 | if (i > 2000) break;
|
163 | }
|
164 |
|
165 | //get data from I2CRCV register
|
166 | data = I2C2RCV;
|
167 |
|
168 | //set ACK to high
|
169 | I2C2CONbits.ACKEN = 1;
|
170 |
|
171 | //wait before exiting
|
172 | __delay32(120);
|
173 |
|
174 | //return data
|
175 | return data;
|
176 | }
|
177 |
|
178 |
|
179 | void I2Cwrite(char addr, char subaddr, char value)
|
180 | {
|
181 | i2c_start();
|
182 | send_i2c_byte(addr);
|
183 | send_i2c_byte(subaddr);
|
184 | send_i2c_byte(value);
|
185 | reset_i2c_bus();
|
186 | }
|
187 |
|
188 | char I2Cread(char addr, char subaddr)
|
189 | {
|
190 | char temp;
|
191 |
|
192 | i2c_start();
|
193 | send_i2c_byte(addr);
|
194 | send_i2c_byte(subaddr);
|
195 | __delay32(120);
|
196 |
|
197 | i2c_restart();
|
198 | send_i2c_byte(addr | 0x01);
|
199 | temp = i2c_read();
|
200 |
|
201 | reset_i2c_bus();
|
202 | return temp;
|
203 | }
|
204 |
|
205 | unsigned char I2Cpoll(char addr)
|
206 | {
|
207 | unsigned char temp = 0;
|
208 |
|
209 | i2c_start();
|
210 | temp = send_i2c_byte(addr);
|
211 | reset_i2c_bus();
|
212 |
|
213 | return temp;
|
214 | }
|