1  | /**
  | 
2  |   I2C2 Generated Driver File
  | 
3  | 
  | 
4  |   @Company
  | 
5  |     Microchip Technology Inc.
  | 
6  | 
  | 
7  |   @File Name
  | 
8  |     i2c2_master.c
  | 
9  | 
  | 
10  |   @Summary
  | 
11  |     This is the generated driver implementation file for the I2C2 driver using PIC10 / PIC12 / PIC16 / PIC18 MCUs
  | 
12  | 
  | 
13  |   @Description
  | 
14  |     This header file provides implementations for driver APIs for I2C2.
  | 
15  |     Generation Information :
  | 
16  |        ac Product Revision  :  PIC10 / PIC12 / PIC16 / PIC18 MCUs - 1.81.8
  | 
17  |         Device            :  PIC18F45K42
  | 
18  |         Driver Version    :  1.0.2
  | 
19  |     The generated drivers are tested against the following:
  | 
20  |         Compiler          :  XC8 2.36 and above or later
  | 
21  |         MPLAB             :  MPLAB X 6.00
  | 
22  | */
  | 
23  | 
  | 
24  | /*
  | 
25  |     (c) 2018 Microchip Technology Inc. and its subsidiaries. 
  | 
26  |     
  | 
27  |     Subject to your compliance with these terms, you may use Microchip software and any 
  | 
28  |     derivatives exclusively with Microchip products. It is your responsibility to comply with third party 
  | 
29  |     license terms applicable to your use of third party software (including open source software) that 
  | 
30  |     may accompany Microchip software.
  | 
31  |     
  | 
32  |     THIS SOFTWARE IS SUPPLIED BY MICROCHIP "AS IS". NO WARRANTIES, WHETHER 
  | 
33  |     EXPRESS, IMPLIED OR STATUTORY, APPLY TO THIS SOFTWARE, INCLUDING ANY 
  | 
34  |     IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY, AND FITNESS 
  | 
35  |     FOR A PARTICULAR PURPOSE.
  | 
36  |     
  | 
37  |     IN NO EVENT WILL MICROCHIP BE LIABLE FOR ANY INDIRECT, SPECIAL, PUNITIVE, 
  | 
38  |     INCIDENTAL OR CONSEQUENTIAL LOSS, DAMAGE, COST OR EXPENSE OF ANY KIND 
  | 
39  |     WHATSOEVER RELATED TO THE SOFTWARE, HOWEVER CAUSED, EVEN IF MICROCHIP 
  | 
40  |     HAS BEEN ADVISED OF THE POSSIBILITY OR THE DAMAGES ARE FORESEEABLE. TO 
  | 
41  |     THE FULLEST EXTENT ALLOWED BY LAW, MICROCHIP'S TOTAL LIABILITY ON ALL 
  | 
42  |     CLAIMS IN ANY WAY RELATED TO THIS SOFTWARE WILL NOT EXCEED THE AMOUNT 
  | 
43  |     OF FEES, IF ANY, THAT YOU HAVE PAID DIRECTLY TO MICROCHIP FOR THIS 
  | 
44  |     SOFTWARE.
  | 
45  | */
  | 
46  | 
  | 
47  | #include "i2c2_master.h"
  | 
48  | #include <xc.h>
  | 
49  | 
  | 
50  | // I2C2 STATES
  | 
51  | typedef enum {
 | 
52  |     I2C2_IDLE = 0,
  | 
53  |     I2C2_SEND_ADR_READ,
  | 
54  |     I2C2_SEND_ADR_WRITE,
  | 
55  |     I2C2_TX,
  | 
56  |     I2C2_RX,
  | 
57  |     I2C2_TX_EMPTY,
  | 
58  |     I2C2_RX_EMPTY,        
  | 
59  |     I2C2_SEND_RESTART_READ,
  | 
60  |     I2C2_SEND_RESTART_WRITE,
  | 
61  |     I2C2_SEND_RESTART,
  | 
62  |     I2C2_SEND_STOP,
  | 
63  |     I2C2_RX_ACK,
  | 
64  |     I2C2_TX_ACK,
  | 
65  |     I2C2_RX_NACK_STOP,
  | 
66  |     I2C2_RX_NACK_RESTART,
  | 
67  |     I2C2_RESET,
  | 
68  |     I2C2_ADDRESS_NACK,
  | 
69  |     I2C2_BUS_COLLISION,
  | 
70  |     I2C2_BUS_ERROR
  | 
71  | } i2c2_fsm_states_t;
  | 
72  | 
  | 
73  | // I2C2 Event callBack List
  | 
74  | typedef enum {
 | 
75  |     I2C2_DATA_COMPLETE = 0,
  | 
76  |     I2C2_WRITE_COLLISION,
  | 
77  |     I2C2_ADDR_NACK,
  | 
78  |     I2C2_DATA_NACK,
  | 
79  |     I2C2_TIMEOUT,
  | 
80  |     I2C2_NULL
  | 
81  | } i2c2_callbackIndex_t;
  | 
82  | 
  | 
83  | // I2C2 Status Structure
  | 
84  | typedef struct
  | 
85  | {
 | 
86  |     i2c2_callback_t callbackTable[6];
  | 
87  |     void *callbackPayload[6];           //  each callBack can have a payload
  | 
88  |     uint16_t time_out;                  // I2C2 Timeout Counter between I2C2 Events.
  | 
89  |     uint16_t time_out_value;            // Reload value for the timeouts
  | 
90  |     i2c2_address_t address;             // The I2C2 Address
  | 
91  |     uint8_t *data_ptr;                  // pointer to a data buffer
  | 
92  |     size_t data_length;                 // Bytes in the data buffer
  | 
93  |     i2c2_fsm_states_t state;            // Driver State
  | 
94  |     i2c2_error_t error;
  | 
95  |     unsigned addressNackCheck:2;
  | 
96  |     unsigned busy:1;
  | 
97  |     unsigned inUse:1;
  | 
98  |     unsigned bufferFree:1;
  | 
99  | 
  | 
100  | } i2c2_status_t;
  | 
101  | 
  | 
102  | static void I2C2_SetCallback(i2c2_callbackIndex_t idx, i2c2_callback_t cb, void *ptr);
  | 
103  | static void I2C2_Poller(void);
  | 
104  | static inline void I2C2_ClearInterruptFlags(void);
  | 
105  | static inline void I2C2_MasterFsm(void);
  | 
106  | 
  | 
107  | /* I2C2 interfaces */
  | 
108  | static inline bool I2C2_MasterOpen(void);
  | 
109  | static inline void I2C2_MasterClose(void);    
  | 
110  | static inline uint8_t I2C2_MasterGetRxData(void);
  | 
111  | static inline void I2C2_MasterSendTxData(uint8_t data);
  | 
112  | static inline void I2C2_MasterSetCounter(uint8_t counter);
  | 
113  | static inline uint8_t I2C2_MasterGetCounter();
  | 
114  | static inline void I2C2_MasterResetBus(void);
  | 
115  | static inline void I2C2_MasterEnableRestart(void);
  | 
116  | static inline void I2C2_MasterDisableRestart(void);
  | 
117  | static inline void I2C2_MasterStop(void);
  | 
118  | static inline bool I2C2_MasterIsNack(void);
  | 
119  | static inline void I2C2_MasterSendAck(void);
  | 
120  | static inline void I2C2_MasterSendNack(void);
  | 
121  | static inline void I2C2_MasterClearBusCollision(void);
  | 
122  | static inline bool I2C2_MasterIsRxBufFull(void);
  | 
123  | static inline bool I2C2_MasterIsTxBufEmpty(void);
  | 
124  | static inline bool I2C2_MasterIsStopFlagSet(void);
  | 
125  | static inline bool I2C2_MasterIsCountFlagSet(void);
  | 
126  | static inline bool I2C2_MasterIsNackFlagSet(void);
  | 
127  | static inline void I2C2_MasterClearStopFlag(void);
  | 
128  | static inline void I2C2_MasterClearCountFlag(void);
  | 
129  | static inline void I2C2_MasterClearNackFlag(void);
  | 
130  | 
  | 
131  | /* Interrupt interfaces */
  | 
132  | static inline void I2C2_MasterEnableIrq(void);
  | 
133  | static inline bool I2C2_MasterIsIrqEnabled(void);
  | 
134  | static inline void I2C2_MasterDisableIrq(void);
  | 
135  | static inline void I2C2_MasterClearIrq(void);
  | 
136  | static inline void I2C2_MasterWaitForEvent(void);
  | 
137  | 
  | 
138  | static i2c2_fsm_states_t I2C2_DO_IDLE(void);
  | 
139  | static i2c2_fsm_states_t I2C2_DO_SEND_ADR_READ(void);
  | 
140  | static i2c2_fsm_states_t I2C2_DO_SEND_ADR_WRITE(void);
  | 
141  | static i2c2_fsm_states_t I2C2_DO_TX(void);
  | 
142  | static i2c2_fsm_states_t I2C2_DO_RX(void);
  | 
143  | static i2c2_fsm_states_t I2C2_DO_TX_EMPTY(void);
  | 
144  | static i2c2_fsm_states_t I2C2_DO_RX_EMPTY(void);
  | 
145  | static i2c2_fsm_states_t I2C2_DO_SEND_RESTART_READ(void);
  | 
146  | static i2c2_fsm_states_t I2C2_DO_SEND_RESTART_WRITE(void);
  | 
147  | static i2c2_fsm_states_t I2C2_DO_SEND_RESTART(void);
  | 
148  | static i2c2_fsm_states_t I2C2_DO_SEND_STOP(void);
  | 
149  | static i2c2_fsm_states_t I2C2_DO_RX_ACK(void);
  | 
150  | static i2c2_fsm_states_t I2C2_DO_TX_ACK(void);
  | 
151  | static i2c2_fsm_states_t I2C2_DO_RX_NACK_STOP(void);
  | 
152  | static i2c2_fsm_states_t I2C2_DO_RX_NACK_RESTART(void);
  | 
153  | static i2c2_fsm_states_t I2C2_DO_RESET(void);
  | 
154  | static i2c2_fsm_states_t I2C2_DO_ADDRESS_NACK(void);
  | 
155  | static i2c2_fsm_states_t I2C2_DO_BUS_COLLISION(void);
  | 
156  | static i2c2_fsm_states_t I2C2_DO_BUS_ERROR(void);
  | 
157  | 
  | 
158  | typedef i2c2_fsm_states_t (*i2c2FsmHandler)(void);
  | 
159  | const i2c2FsmHandler i2c2_fsmStateTable[] = {
 | 
160  |     I2C2_DO_IDLE,
  | 
161  |     I2C2_DO_SEND_ADR_READ,
  | 
162  |     I2C2_DO_SEND_ADR_WRITE,
  | 
163  |     I2C2_DO_TX,
  | 
164  |     I2C2_DO_RX,
  | 
165  |     I2C2_DO_TX_EMPTY,
  | 
166  |     I2C2_DO_RX_EMPTY,
  | 
167  |     I2C2_DO_SEND_RESTART_READ,
  | 
168  |     I2C2_DO_SEND_RESTART_WRITE,
  | 
169  |     I2C2_DO_SEND_RESTART,
  | 
170  |     I2C2_DO_SEND_STOP,
  | 
171  |     I2C2_DO_RX_ACK,
  | 
172  |     I2C2_DO_TX_ACK,
  | 
173  |     I2C2_DO_RX_NACK_STOP,
  | 
174  |     I2C2_DO_RX_NACK_RESTART,
  | 
175  |     I2C2_DO_RESET,
  | 
176  |     I2C2_DO_ADDRESS_NACK,
  | 
177  |     I2C2_DO_BUS_COLLISION,
  | 
178  |     I2C2_DO_BUS_ERROR
  | 
179  | };
  | 
180  | 
  | 
181  | i2c2_status_t I2C2_Status = {0};
 | 
182  | 
  | 
183  | void I2C2_Initialize()
  | 
184  | {
 | 
185  |     //EN disabled; RSEN disabled; S Cleared by hardware after Start; CSTR Enable clocking; MODE 7-bit address; 
  | 
186  |     I2C2CON0 = 0x04;
  | 
187  |     //ACKCNT Acknowledge; ACKDT Acknowledge; ACKSTAT ACK received; ACKT 0; RXO 0; TXU 0; CSD Clock Stretching enabled; 
  | 
188  |     I2C2CON1 = 0x80;
  | 
189  |     //ACNT disabled; GCEN disabled; FME disabled; ABD disabled; SDAHT 30 ns hold time; BFRET 8 I2C Clock pulses; 
  | 
190  |     I2C2CON2 = 0x18;
  | 
191  |     //CLK MFINTOSC; 
  | 
192  |     I2C2CLK = 0x03;
  | 
193  |     //CNTIF 0; ACKTIF 0; WRIF 0; ADRIF 0; PCIF 0; RSCIF 0; SCIF 0; 
  | 
194  |     I2C2PIR = 0x00;
  | 
195  |     //CNTIE disabled; ACKTIE disabled; WRIE disabled; ADRIE disabled; PCIE disabled; RSCIE disabled; SCIE disabled; 
  | 
196  |     I2C2PIE = 0x00;
  | 
197  |     //BTOIF No bus timout; BCLIF No bus collision detected; NACKIF No NACK/Error detected; BTOIE disabled; BCLIE disabled; NACKIE disabled; 
  | 
198  |     I2C2ERR = 0x00;
  | 
199  |     //Count register 
  | 
200  |     I2C2CNT = 0xFF;
  | 
201  |     return;
  | 
202  | }
  | 
203  | 
  | 
204  | i2c2_error_t I2C2_Open(i2c2_address_t address)
  | 
205  | {
 | 
206  |     i2c2_error_t returnValue = I2C2_BUSY;
  | 
207  |     
  | 
208  |     if(!I2C2_Status.inUse)
  | 
209  |     {
 | 
210  |         I2C2_Status.address = address;
  | 
211  |         I2C2_Status.busy = 0;
  | 
212  |         I2C2_Status.inUse = 1;
  | 
213  |         I2C2_Status.addressNackCheck = 0;
  | 
214  |         I2C2_Status.state = I2C2_RESET;
  | 
215  |         I2C2_Status.time_out_value = 500; // MCC should determine a reasonable starting value here.
  | 
216  |         I2C2_Status.bufferFree = 1;
  | 
217  | 
  | 
218  |         // set all the call backs to a default of sending stop
  | 
219  |         I2C2_Status.callbackTable[I2C2_DATA_COMPLETE]=I2C2_CallbackReturnStop;
  | 
220  |         I2C2_Status.callbackPayload[I2C2_DATA_COMPLETE] = NULL;
  | 
221  |         I2C2_Status.callbackTable[I2C2_WRITE_COLLISION]=I2C2_CallbackReturnStop;
  | 
222  |         I2C2_Status.callbackPayload[I2C2_WRITE_COLLISION] = NULL;
  | 
223  |         I2C2_Status.callbackTable[I2C2_ADDR_NACK]=I2C2_CallbackReturnStop;
  | 
224  |         I2C2_Status.callbackPayload[I2C2_ADDR_NACK] = NULL;
  | 
225  |         I2C2_Status.callbackTable[I2C2_DATA_NACK]=I2C2_CallbackReturnStop;
  | 
226  |         I2C2_Status.callbackPayload[I2C2_DATA_NACK] = NULL;
  | 
227  |         I2C2_Status.callbackTable[I2C2_TIMEOUT]=I2C2_CallbackReturnReset;
  | 
228  |         I2C2_Status.callbackPayload[I2C2_TIMEOUT] = NULL;
  | 
229  |         
  | 
230  |         I2C2_MasterClearIrq();
  | 
231  |         I2C2_MasterOpen();
  | 
232  |         returnValue = I2C2_NOERR;
  | 
233  |     }
  | 
234  |     return returnValue;
  | 
235  | }
  | 
236  | 
  | 
237  | i2c2_error_t I2C2_Close(void)
  | 
238  | {
 | 
239  |     i2c2_error_t returnValue = I2C2_BUSY;
  | 
240  |     if(!I2C2_Status.busy)
  | 
241  |     {
 | 
242  |         I2C2_Status.inUse = 0;
  | 
243  |         I2C2_Status.address = 0xff;
  | 
244  |         I2C2_MasterClearIrq();
  | 
245  |         I2C2_MasterDisableIrq();
  | 
246  |         I2C2_MasterClose();
  | 
247  |         returnValue = I2C2_Status.error;
  | 
248  |     }
  | 
249  |     return returnValue;
  | 
250  | }
  | 
251  | 
  | 
252  | i2c2_error_t I2C2_MasterOperation(bool read)
  | 
253  | {
 | 
254  |     i2c2_error_t returnValue = I2C2_BUSY;
  | 
255  |     if(!I2C2_Status.busy)
  | 
256  |     {
 | 
257  |         I2C2_Status.busy = true;
  | 
258  |         returnValue = I2C2_NOERR;
  | 
259  |         I2C2_MasterSetCounter((uint8_t) I2C2_Status.data_length);
  | 
260  | 
  | 
261  |         if(read)
  | 
262  |         {
 | 
263  |             I2C2_Status.state = I2C2_RX;
  | 
264  |             I2C2_DO_SEND_ADR_READ();
  | 
265  |         }
  | 
266  |         else
  | 
267  |         {
 | 
268  |             I2C2_Status.state = I2C2_TX;
  | 
269  |             I2C2_DO_SEND_ADR_WRITE();
  | 
270  |         }
  | 
271  |         I2C2_Poller();
  | 
272  |     }
  | 
273  |     return returnValue;
  | 
274  | }
  | 
275  | 
  | 
276  | i2c2_error_t I2C2_MasterRead(void)
  | 
277  | {
 | 
278  |     return I2C2_MasterOperation(true);
  | 
279  | }
  | 
280  | 
  | 
281  | i2c2_error_t I2C2_MasterWrite(void)
  | 
282  | {
 | 
283  |     return I2C2_MasterOperation(false);
  | 
284  | }
  | 
285  | 
  | 
286  | void I2C2_SetTimeOut(uint8_t timeOutValue)
  | 
287  | {
 | 
288  |     I2C2_MasterDisableIrq();
  | 
289  |     I2C2_Status.time_out_value = timeOutValue;
  | 
290  |     I2C2_MasterEnableIrq();
  | 
291  | }
  | 
292  | 
  | 
293  | void I2C2_SetBuffer(void *buffer, size_t bufferSize)
  | 
294  | {
 | 
295  |     if(I2C2_Status.bufferFree)
  | 
296  |     {
 | 
297  |         I2C2_Status.data_ptr = buffer;
  | 
298  |         I2C2_Status.data_length = bufferSize;
  | 
299  |         I2C2_Status.bufferFree = false;
  | 
300  |     }
  | 
301  | }
  | 
302  | 
  | 
303  | void I2C2_SetDataCompleteCallback(i2c2_callback_t cb, void *ptr)
  | 
304  | {
 | 
305  |     I2C2_SetCallback(I2C2_DATA_COMPLETE, cb, ptr);
  | 
306  | }
  | 
307  | 
  | 
308  | void I2C2_SetWriteCollisionCallback(i2c2_callback_t cb, void *ptr)
  | 
309  | {
 | 
310  |     I2C2_SetCallback(I2C2_WRITE_COLLISION, cb, ptr);
  | 
311  | }
  | 
312  | 
  | 
313  | void I2C2_SetAddressNackCallback(i2c2_callback_t cb, void *ptr)
  | 
314  | {
 | 
315  |     I2C2_SetCallback(I2C2_ADDR_NACK, cb, ptr);
  | 
316  | }
  | 
317  | 
  | 
318  | void I2C2_SetDataNackCallback(i2c2_callback_t cb, void *ptr)
  | 
319  | {
 | 
320  |     I2C2_SetCallback(I2C2_DATA_NACK, cb, ptr);
  | 
321  | }
  | 
322  | 
  | 
323  | void I2C2_SetTimeoutCallback(i2c2_callback_t cb, void *ptr)
  | 
324  | {
 | 
325  |     I2C2_SetCallback(I2C2_TIMEOUT, cb, ptr);
  | 
326  | }
  | 
327  | 
  | 
328  | static void I2C2_SetCallback(i2c2_callbackIndex_t idx, i2c2_callback_t cb, void *ptr)
  | 
329  | {
 | 
330  |     if(cb)
  | 
331  |     {
 | 
332  |         I2C2_Status.callbackTable[idx] = cb;
  | 
333  |         I2C2_Status.callbackPayload[idx] = ptr;
  | 
334  |     }
  | 
335  |     else
  | 
336  |     {
 | 
337  |         I2C2_Status.callbackTable[idx] = I2C2_CallbackReturnStop;
  | 
338  |         I2C2_Status.callbackPayload[idx] = NULL;
  | 
339  |     }
  | 
340  | }
  | 
341  | 
  | 
342  | static void I2C2_Poller(void)
  | 
343  | {
 | 
344  |     while(I2C2_Status.busy)
  | 
345  |     {
 | 
346  |         I2C2_MasterWaitForEvent();
  | 
347  |         I2C2_MasterFsm();
  | 
348  |     }
  | 
349  | }
  | 
350  | 
  | 
351  | static inline void I2C2_MasterFsm(void)
  | 
352  | {
 | 
353  |     I2C2_ClearInterruptFlags();
  | 
354  | 
  | 
355  |     if(I2C2_Status.addressNackCheck && I2C2_MasterIsNack())
  | 
356  |     {
 | 
357  |         I2C2_Status.state = I2C2_ADDRESS_NACK;
  | 
358  |     }
  | 
359  |     I2C2_Status.state = i2c2_fsmStateTable[I2C2_Status.state]();
  | 
360  | }
  | 
361  | 
  | 
362  | static inline void I2C2_ClearInterruptFlags(void)
  | 
363  | {
 | 
364  |     if(I2C2_MasterIsCountFlagSet())
  | 
365  |     {
 | 
366  |         I2C2_MasterClearCountFlag();
  | 
367  |     }
  | 
368  |     else if(I2C2_MasterIsStopFlagSet())
  | 
369  |     {
 | 
370  |         I2C2_MasterClearStopFlag();
  | 
371  |     }
  | 
372  |     else if(I2C2_MasterIsNackFlagSet())
  | 
373  |     {
 | 
374  |         I2C2_MasterClearNackFlag();
  | 
375  |     }
  | 
376  | }
  | 
377  | 
  | 
378  | static i2c2_fsm_states_t I2C2_DO_IDLE(void)
  | 
379  | {
 | 
380  |     I2C2_Status.busy = false;
  | 
381  |     I2C2_Status.error = I2C2_NOERR;
  | 
382  |     return I2C2_RESET;
  | 
383  | }
  | 
384  | 
  | 
385  | static i2c2_fsm_states_t I2C2_DO_SEND_ADR_READ(void)
  | 
386  | {
 | 
387  |     I2C2_Status.addressNackCheck = 2;
  | 
388  |     if(I2C2_Status.data_length ==  1)
  | 
389  |     {
 | 
390  |         I2C2_DO_RX_EMPTY();
  | 
391  |     }
  | 
392  |     I2C2_MasterSendTxData((uint8_t) (I2C2_Status.address << 1 | 1));
  | 
393  |     return I2C2_RX;
  | 
394  | }
  | 
395  | 
  | 
396  | static i2c2_fsm_states_t I2C2_DO_SEND_ADR_WRITE(void)
  | 
397  | {
 | 
398  |     I2C2_Status.addressNackCheck = 2;
  | 
399  |     I2C2_MasterSendTxData((uint8_t) (I2C2_Status.address << 1));
  | 
400  |     return I2C2_TX;
  | 
401  | }
  | 
402  | 
  | 
403  | static i2c2_fsm_states_t I2C2_DO_TX(void)
  | 
404  | {
 | 
405  |     if(I2C2_MasterIsNack())
  | 
406  |     {
 | 
407  |         switch(I2C2_Status.callbackTable[I2C2_DATA_NACK](I2C2_Status.callbackPayload[I2C2_DATA_NACK]))
  | 
408  |         {
 | 
409  |             case I2C2_RESTART_READ:
  | 
410  |                 return I2C2_DO_SEND_RESTART_READ();
  | 
411  |             case I2C2_RESTART_WRITE:
  | 
412  |                   return I2C2_DO_SEND_RESTART_WRITE();
  | 
413  |             default:
  | 
414  |             case I2C2_CONTINUE:
  | 
415  |             case I2C2_STOP:
  | 
416  |                 return I2C2_IDLE;
  | 
417  |         }
  | 
418  |     }
  | 
419  |     else if(I2C2_MasterIsTxBufEmpty())
  | 
420  |     {
 | 
421  |         if(I2C2_Status.addressNackCheck)
  | 
422  |         {
 | 
423  |             I2C2_Status.addressNackCheck--;
  | 
424  |         }
  | 
425  |         uint8_t dataTx = *I2C2_Status.data_ptr++;
  | 
426  |         i2c2_fsm_states_t retFsmState = (--I2C2_Status.data_length)?I2C2_TX:I2C2_DO_TX_EMPTY();
  | 
427  |         I2C2_MasterSendTxData(dataTx);
  | 
428  |         return retFsmState;
  | 
429  |     }
  | 
430  |     else
  | 
431  |     {
 | 
432  |         return I2C2_TX;
  | 
433  |     }
  | 
434  | }
  | 
435  | 
  | 
436  | static i2c2_fsm_states_t I2C2_DO_RX(void)
  | 
437  | {
 | 
438  |     if(!I2C2_MasterIsRxBufFull())
  | 
439  |     {
 | 
440  |         return I2C2_RX;
  | 
441  |     }
  | 
442  |     if(I2C2_Status.addressNackCheck)
  | 
443  |     {
 | 
444  |         I2C2_Status.addressNackCheck--;
  | 
445  |     }
  | 
446  | 
  | 
447  |     if(--I2C2_Status.data_length)
  | 
448  |     {
 | 
449  |         *I2C2_Status.data_ptr++ = I2C2_MasterGetRxData();
  | 
450  |         return I2C2_RX;
  | 
451  |     }
  | 
452  |     else
  | 
453  |     {
 | 
454  |         i2c2_fsm_states_t retFsmState = I2C2_DO_RX_EMPTY();
  | 
455  |         *I2C2_Status.data_ptr++ = I2C2_MasterGetRxData();
  | 
456  |         return retFsmState;
  | 
457  |     }
  | 
458  | }
  | 
459  | 
  | 
460  | static i2c2_fsm_states_t I2C2_DO_TX_EMPTY(void)
  | 
461  | {
 | 
462  |     I2C2_Status.bufferFree = true;
  | 
463  |     switch(I2C2_Status.callbackTable[I2C2_DATA_COMPLETE](I2C2_Status.callbackPayload[I2C2_DATA_COMPLETE]))
  | 
464  |     {
 | 
465  |         case I2C2_RESTART_READ:
  | 
466  |             I2C2_MasterEnableRestart();
  | 
467  |             return I2C2_SEND_RESTART_READ;
  | 
468  |         case I2C2_CONTINUE:
  | 
469  |             // Avoid the counter stop condition , Counter is incremented by 1
  | 
470  |             I2C2_MasterSetCounter((uint8_t) I2C2_Status.data_length + 1);
  | 
471  |             return I2C2_TX;
  | 
472  |         default:
  | 
473  |         case I2C2_STOP:
  | 
474  |             I2C2_MasterDisableRestart();
  | 
475  |             return I2C2_SEND_STOP;
  | 
476  |     }
  | 
477  | }
  | 
478  | 
  | 
479  | static i2c2_fsm_states_t I2C2_DO_RX_EMPTY(void)
  | 
480  | {
 | 
481  |     I2C2_Status.bufferFree = true;
  | 
482  |     switch(I2C2_Status.callbackTable[I2C2_DATA_COMPLETE](I2C2_Status.callbackPayload[I2C2_DATA_COMPLETE]))
  | 
483  |     {
 | 
484  |         case I2C2_RESTART_WRITE:
  | 
485  |             I2C2_MasterEnableRestart();
  | 
486  |             return I2C2_SEND_RESTART_WRITE;
  | 
487  |         case I2C2_RESTART_READ:
  | 
488  |             I2C2_MasterEnableRestart();
  | 
489  |             return I2C2_SEND_RESTART_READ;
  | 
490  |         case I2C2_CONTINUE:
  | 
491  |             // Avoid the counter stop condition , Counter is incremented by 1
  | 
492  |             I2C2_MasterSetCounter((uint8_t) (I2C2_Status.data_length + 1));
  | 
493  |             return I2C2_RX;
  | 
494  |         default:
  | 
495  |         case I2C2_STOP:
  | 
496  |             if(I2C2_Status.state != I2C2_SEND_RESTART_READ)
  | 
497  |             {
 | 
498  |                 I2C2_MasterDisableRestart();
  | 
499  |             }
  | 
500  |             return I2C2_RESET;
  | 
501  |     }
  | 
502  | }
  | 
503  | 
  | 
504  | static i2c2_fsm_states_t I2C2_DO_SEND_RESTART_READ(void)
  | 
505  | {
 | 
506  |     I2C2_MasterSetCounter((uint8_t) I2C2_Status.data_length);
  | 
507  |     return I2C2_DO_SEND_ADR_READ();
  | 
508  | }
  | 
509  | 
  | 
510  | static i2c2_fsm_states_t I2C2_DO_SEND_RESTART_WRITE(void)
  | 
511  | {
 | 
512  |     return I2C2_SEND_ADR_WRITE;
  | 
513  | }
  | 
514  | 
  | 
515  | 
  | 
516  | static i2c2_fsm_states_t I2C2_DO_SEND_RESTART(void)
  | 
517  | {
 | 
518  |     return I2C2_SEND_ADR_READ;
  | 
519  | }
  | 
520  | 
  | 
521  | static i2c2_fsm_states_t I2C2_DO_SEND_STOP(void)
  | 
522  | {
 | 
523  |     I2C2_MasterStop();
  | 
524  |     if(I2C2_MasterGetCounter())
  | 
525  |     {
 | 
526  |         I2C2_MasterSetCounter(0);
  | 
527  |         I2C2_MasterSendTxData(0);
  | 
528  |     }
  | 
529  |     return I2C2_IDLE;
  | 
530  | }
  | 
531  | 
  | 
532  | static i2c2_fsm_states_t I2C2_DO_RX_ACK(void)
  | 
533  | {
 | 
534  |     I2C2_MasterSendAck();
  | 
535  |     return I2C2_RX;
  | 
536  | }
  | 
537  | 
  | 
538  | static i2c2_fsm_states_t I2C2_DO_TX_ACK(void)
  | 
539  | {
 | 
540  |     I2C2_MasterSendAck();
  | 
541  |     return I2C2_TX;
  | 
542  | }
  | 
543  | 
  | 
544  | static i2c2_fsm_states_t I2C2_DO_RX_NACK_STOP(void)
  | 
545  | {
 | 
546  |     I2C2_MasterSendNack();
  | 
547  |     I2C2_MasterStop();
  | 
548  |     return I2C2_DO_IDLE();
  | 
549  | }
  | 
550  | 
  | 
551  | static i2c2_fsm_states_t I2C2_DO_RX_NACK_RESTART(void)
  | 
552  | {
 | 
553  |     I2C2_MasterSendNack();
  | 
554  |     return I2C2_SEND_RESTART;
  | 
555  | }
  | 
556  | 
  | 
557  | static i2c2_fsm_states_t I2C2_DO_RESET(void)
  | 
558  | {
 | 
559  |     I2C2_MasterResetBus();
  | 
560  |     I2C2_Status.busy = false;
  | 
561  |     I2C2_Status.error = I2C2_NOERR;
  | 
562  |     return I2C2_RESET;
  | 
563  | }
  | 
564  | static i2c2_fsm_states_t I2C2_DO_ADDRESS_NACK(void)
  | 
565  | {
 | 
566  |     I2C2_Status.addressNackCheck = 0;
  | 
567  |     I2C2_Status.error = I2C2_FAIL;
  | 
568  |     I2C2_Status.busy = false;
  | 
569  |     switch(I2C2_Status.callbackTable[I2C2_ADDR_NACK](I2C2_Status.callbackPayload[I2C2_ADDR_NACK]))
  | 
570  |     {
 | 
571  |         case I2C2_RESTART_READ:
  | 
572  |         case I2C2_RESTART_WRITE:
  | 
573  |             return I2C2_DO_SEND_RESTART();
  | 
574  |         default:
  | 
575  |             return I2C2_RESET;
  | 
576  |     }
  | 
577  | }
  | 
578  | 
  | 
579  | static i2c2_fsm_states_t I2C2_DO_BUS_COLLISION(void)
  | 
580  | {
 | 
581  |     // Clear bus collision status flag
  | 
582  |     I2C2_MasterClearIrq();
  | 
583  | 
  | 
584  |     I2C2_Status.error = I2C2_FAIL;
  | 
585  |     switch (I2C2_Status.callbackTable[I2C2_WRITE_COLLISION](I2C2_Status.callbackPayload[I2C2_WRITE_COLLISION])) {
 | 
586  |     case I2C2_RESTART_READ:
  | 
587  |         return I2C2_DO_SEND_RESTART_READ();
  | 
588  |     case I2C2_RESTART_WRITE:
  | 
589  |         return I2C2_DO_SEND_RESTART_WRITE();
  | 
590  |     default:
  | 
591  |         return I2C2_DO_RESET();
  | 
592  |     }
  | 
593  | }
  | 
594  | 
  | 
595  | static i2c2_fsm_states_t I2C2_DO_BUS_ERROR(void)
  | 
596  | {
 | 
597  |     I2C2_MasterResetBus();
  | 
598  |     I2C2_Status.busy  = false;
  | 
599  |     I2C2_Status.error = I2C2_FAIL;
  | 
600  |     return I2C2_RESET;
  | 
601  | }
  | 
602  | 
  | 
603  | void I2C2_BusCollisionIsr(void)
  | 
604  | {
 | 
605  |     I2C2_MasterClearBusCollision();
  | 
606  |     I2C2_Status.state = I2C2_RESET;
  | 
607  | }
  | 
608  | 
  | 
609  | i2c2_operations_t I2C2_CallbackReturnStop(void *funPtr)
  | 
610  | {
 | 
611  |     return I2C2_STOP;
  | 
612  | }
  | 
613  | 
  | 
614  | i2c2_operations_t I2C2_CallbackReturnReset(void *funPtr)
  | 
615  | {
 | 
616  |     return I2C2_RESET_LINK;
  | 
617  | }
  | 
618  | 
  | 
619  | i2c2_operations_t I2C2_CallbackRestartWrite(void *funPtr)
  | 
620  | {
 | 
621  |     return I2C2_RESTART_WRITE;
  | 
622  | }
  | 
623  | 
  | 
624  | i2c2_operations_t I2C2_CallbackRestartRead(void *funPtr)
  | 
625  | {
 | 
626  |     return I2C2_RESTART_READ;
  | 
627  | }
  | 
628  | 
  | 
629  | 
  | 
630  | 
  | 
631  | /* I2C2 Register Level interfaces */
  | 
632  | static inline bool I2C2_MasterOpen(void)
  | 
633  | {
 | 
634  |     if(!I2C2CON0bits.EN)
  | 
635  |     {
 | 
636  |         //CNTIF 0; ACKTIF 0; WRIF 0; ADRIF 0; PCIF 0; RSCIF 0; SCIF 0; 
  | 
637  |         I2C2PIR = 0x00;
  | 
638  |         //CNTIE disabled; ACKTIE disabled; WRIE disabled; ADRIE disabled; PCIE disabled; RSCIE disabled; SCIE disabled; 
  | 
639  |         I2C2PIE = 0x00;
  | 
640  |         //BTOIF No bus timout; BCLIF No bus collision detected; NACKIF No NACK/Error detected; BTOIE disabled; BCLIE disabled; NACKIE disabled; 
  | 
641  |         I2C2ERR = 0x00;
  | 
642  |         //Count register 
  | 
643  |         I2C2CNT = 0xFF;
  | 
644  |         //Clock PadReg Configuration
  | 
645  |         RB1I2C   = 0x51;
  | 
646  |         //Data PadReg Configuration
  | 
647  |         RB2I2C   = 0x51;
  | 
648  |         //Enable I2C2
  | 
649  |         I2C2CON0bits.EN = 1;
  | 
650  |         return true;
  | 
651  |     }
  | 
652  |     return false;
  | 
653  | }
  | 
654  | 
  | 
655  | static inline void I2C2_MasterClose(void)
  | 
656  | {
 | 
657  |     //Disable I2C2
  | 
658  |     I2C2CON0bits.EN = 0;
  | 
659  |     //CNTIF 0; ACKTIF 0; WRIF 0; ADRIF 0; PCIF 0; RSCIF 0; SCIF 0; 
  | 
660  |     I2C2PIR = 0x00;
  | 
661  |     //Set Clear Buffer Flag
  | 
662  |     I2C2STAT1bits.CLRBF = 1;
  | 
663  | }
  | 
664  | 
  | 
665  | static inline uint8_t I2C2_MasterGetRxData(void)
  | 
666  | {
 | 
667  |     return I2C2RXB;
  | 
668  | }
  | 
669  | 
  | 
670  | static inline void I2C2_MasterSendTxData(uint8_t data)
  | 
671  | {
 | 
672  |     I2C2TXB  = data;
  | 
673  | }
  | 
674  | 
  | 
675  | static inline uint8_t I2C2_MasterGetCounter()
  | 
676  | {
 | 
677  |     return I2C2CNT;
  | 
678  | }
  | 
679  | 
  | 
680  | static inline void I2C2_MasterSetCounter(uint8_t counter)
  | 
681  | {
 | 
682  |     I2C2CNT = counter;
  | 
683  | }
  | 
684  | 
  | 
685  | static inline void I2C2_MasterResetBus(void)
  | 
686  | {
 | 
687  |     //Disable I2C2
  | 
688  |     I2C2CON0bits.EN = 0;
  | 
689  |     //Set Clear Buffer Flag
  | 
690  |     I2C2STAT1bits.CLRBF = 1;
  | 
691  |     //Enable I2C2
  | 
692  |     I2C2CON0bits.EN = 1;
  | 
693  | }
  | 
694  | 
  | 
695  | static inline void I2C2_MasterEnableRestart(void)
  | 
696  | {
 | 
697  |     //Enable I2C2 Restart
  | 
698  |     I2C2CON0bits.RSEN = 1;
  | 
699  | }
  | 
700  | 
  | 
701  | static inline void I2C2_MasterDisableRestart(void)
  | 
702  | {
 | 
703  |     //Disable I2C2 Restart
  | 
704  |     I2C2CON0bits.RSEN = 0;
  | 
705  | }
  | 
706  | 
  | 
707  | static inline void I2C2_MasterStop(void)
  | 
708  | {
 | 
709  |     //Clear Start Bit
  | 
710  |     I2C2CON0bits.S = 0;
  | 
711  | }
  | 
712  | 
  | 
713  | static inline bool I2C2_MasterIsNack(void)
  | 
714  | {
 | 
715  |     return I2C2CON1bits.ACKSTAT;
  | 
716  | }
  | 
717  | 
  | 
718  | static inline void I2C2_MasterSendAck(void)
  | 
719  | {
 | 
720  |     I2C2CON1bits.ACKDT = 0;
  | 
721  | }
  | 
722  | 
  | 
723  | static inline void I2C2_MasterSendNack(void)
  | 
724  | {
 | 
725  |     I2C2CON1bits.ACKDT = 1;
  | 
726  | }
  | 
727  | 
  | 
728  | static inline void I2C2_MasterClearBusCollision(void)
  | 
729  | {
 | 
730  |     I2C2ERRbits.BCLIF = 0;
  | 
731  |     I2C2ERRbits.BTOIF = 0;
  | 
732  |     I2C2ERRbits.NACKIF = 0;
  | 
733  | }
  | 
734  | 
  | 
735  | static inline bool I2C2_MasterIsRxBufFull(void)
  | 
736  | {
 | 
737  |     return I2C2STAT1bits.RXBF;
  | 
738  | }
  | 
739  | 
  | 
740  | static inline bool I2C2_MasterIsTxBufEmpty(void)
  | 
741  | {
 | 
742  |     return I2C2STAT1bits.TXBE;
  | 
743  | }
  | 
744  | 
  | 
745  | static inline bool I2C2_MasterIsStopFlagSet(void)
  | 
746  | {
 | 
747  |     return I2C2PIRbits.PCIF;
  | 
748  | }
  | 
749  | 
  | 
750  | static inline bool I2C2_MasterIsCountFlagSet(void)
  | 
751  | {
 | 
752  |     return I2C2PIRbits.CNTIF;
  | 
753  | }
  | 
754  | 
  | 
755  | static inline bool I2C2_MasterIsNackFlagSet(void)
  | 
756  | {
 | 
757  |     return I2C2ERRbits.NACKIF;
  | 
758  | }
  | 
759  | 
  | 
760  | static inline void I2C2_MasterClearStopFlag(void)
  | 
761  | {
 | 
762  |     I2C2PIRbits.PCIF = 0;
  | 
763  | }
  | 
764  | 
  | 
765  | static inline void I2C2_MasterClearCountFlag(void)
  | 
766  | {
 | 
767  |     I2C2PIRbits.CNTIF = 0;
  | 
768  | }
  | 
769  | 
  | 
770  | static inline void I2C2_MasterClearNackFlag(void)
  | 
771  | {
 | 
772  |     I2C2ERRbits.NACKIF = 0;
  | 
773  | }
  | 
774  | 
  | 
775  | static inline void I2C2_MasterEnableIrq(void)
  | 
776  | {
 | 
777  |     PIE6bits.I2C2IE    = 1;
  | 
778  |     PIE6bits.I2C2EIE    = 1;
  | 
779  |     PIE5bits.I2C2RXIE  = 1;
  | 
780  |     PIE5bits.I2C2TXIE  = 1;
  | 
781  | 
  | 
782  |     I2C2PIEbits.PCIE = 1; 
  | 
783  |     I2C2PIEbits.CNTIE = 1; 
  | 
784  |     I2C2ERRbits.NACKIE = 1; 
  | 
785  | }
  | 
786  | 
  | 
787  | static inline bool I2C2_MasterIsIrqEnabled(void)
  | 
788  | {
 | 
789  |     return (PIE5bits.I2C2RXIE && PIE5bits.I2C2TXIE && PIE6bits.I2C2IE);
  | 
790  | }
  | 
791  | 
  | 
792  | static inline void I2C2_MasterDisableIrq(void)
  | 
793  | {
 | 
794  |     PIE6bits.I2C2IE    = 0;
  | 
795  |     PIE6bits.I2C2EIE    = 0;
  | 
796  |     PIE5bits.I2C2RXIE  = 0;
  | 
797  |     PIE5bits.I2C2TXIE  = 0;
  | 
798  |     I2C2PIEbits.SCIE = 0;
  | 
799  |     I2C2PIEbits.PCIE = 0;
  | 
800  |     I2C2PIEbits.CNTIE = 0;
  | 
801  |     I2C2PIEbits.ACKTIE = 0;
  | 
802  |     I2C2PIEbits.RSCIE = 0;
  | 
803  |     I2C2ERRbits.BCLIE = 0;
  | 
804  |     I2C2ERRbits.BTOIE = 0;
  | 
805  |     I2C2ERRbits.NACKIE = 0;
  | 
806  | }
  | 
807  | 
  | 
808  | static inline void I2C2_MasterClearIrq(void)
  | 
809  | {
 | 
810  |     I2C2PIR = 0x00;
  | 
811  | }
  | 
812  | 
  | 
813  | static inline void I2C2_MasterWaitForEvent(void)
  | 
814  | {
 | 
815  |     while(1)
  | 
816  |     {
 | 
817  |         if(PIR5bits.I2C2TXIF)
  | 
818  |         {    
 | 
819  |             break;
  | 
820  |         }
  | 
821  |         if(PIR5bits.I2C2RXIF)
  | 
822  |         {  
 | 
823  |             break;
  | 
824  |         } 
  | 
825  |         if(I2C2PIRbits.PCIF)
  | 
826  |         {
 | 
827  |             break;
  | 
828  |         } 
  | 
829  |         if(I2C2PIRbits.CNTIF)
  | 
830  |         {
 | 
831  |             break;
  | 
832  |         }
  | 
833  |         if(I2C2ERRbits.NACKIF)
  | 
834  |         {
 | 
835  |             break;
  | 
836  |         }
  | 
837  |     }
  | 
838  | }
  |