1+ /*
2+ © [2025] Microchip Technology Inc. and its subsidiaries.
3+
4+ Subject to your compliance with these terms, you may use Microchip
5+ software and any derivatives exclusively with Microchip products.
6+ You are responsible for complying with 3rd party license terms
7+ applicable to your use of 3rd party software (including open source
8+ software) that may accompany Microchip software. SOFTWARE IS ?AS IS.?
9+ NO WARRANTIES, WHETHER EXPRESS, IMPLIED OR STATUTORY, APPLY TO THIS
10+ SOFTWARE, INCLUDING ANY IMPLIED WARRANTIES OF NON-INFRINGEMENT,
11+ MERCHANTABILITY, OR FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT
12+ WILL MICROCHIP BE LIABLE FOR ANY INDIRECT, SPECIAL, PUNITIVE,
13+ INCIDENTAL OR CONSEQUENTIAL LOSS, DAMAGE, COST OR EXPENSE OF ANY
14+ KIND WHATSOEVER RELATED TO THE SOFTWARE, HOWEVER CAUSED, EVEN IF
15+ MICROCHIP HAS BEEN ADVISED OF THE POSSIBILITY OR THE DAMAGES ARE
16+ FORESEEABLE. TO THE FULLEST EXTENT ALLOWED BY LAW, MICROCHIP?S
17+ TOTAL LIABILITY ON ALL CLAIMS RELATED TO THE SOFTWARE WILL NOT
18+ EXCEED AMOUNT OF FEES, IF ANY, YOU PAID DIRECTLY TO MICROCHIP FOR
19+ THIS SOFTWARE.
20+ */
21+ /**
22+ * I2C_HOST EXAMPLE Generated Driver File
23+ *
24+ * @file i2c_host example.c
25+ *
26+ * @ingroup i2c_host example
27+ *
28+ * @version I2C_HOST EXAMPLE Example Version 1.0.0
29+ *
30+ * @brief Generated file for
31+ * Example: 4. I2C Proximity Sensor
32+ * Implementation: Interrupts with callbacks
33+ * Visualization: Printf with error handling
34+ * MCU Device family: PIC18F/18F
35+ */
36+ #include "mcc_generated_files/system/system.h"
37+
38+ // TODO: Replace TimerX with name of const struct TIMER_INTERFACE, from MCC Generated Files > timer > {timer_header}X
39+ static const struct TIMER_INTERFACE * Timer = & Timer2 ; // TODO: Replace TimerX with the timer instance number
40+
41+ uint8_t VCNL4200_Initialize (void );
42+ uint8_t VCNL4200_ProximityRead (uint16_t * proximityValue );
43+ void Timer_Callback_250ms (void );
44+ const uint8_t * I2CErrorToString (uint8_t error );
45+
46+ // Note: VCNL4200 - High Sensitivity Long Distance Proximity and Ambient Light Sensor With I2C Interface
47+ // Reference to the VCNL4200 data sheet: https://www.vishay.com/docs/84430/vcnl4200.pdf
48+ // The VCNL4200 command codes are located in Table 1 (page 9) of the VCNL4200 data sheet
49+ #define PROXIMITY_I2C_ADDRESS ((uint8_t)0x51)
50+ #define PROXIMITY_REGISTER ((uint8_t)0x08)
51+
52+ uint16_t proximityValue ; // VCNL4200 sensor result
53+ uint8_t errorState = I2C_ERROR_NONE ;
54+ volatile bool timerTick = 0 ; // volatile because this variable is used inside & outside the ISR.
55+
56+ uint8_t VCNL4200_ProximityRead (uint16_t * proximityValue )
57+ {
58+ union
59+ {
60+ uint8_t bytes [2 ];
61+ uint16_t value ;
62+ } proximityResponse ;
63+ uint8_t proximityData = PROXIMITY_REGISTER ;
64+
65+ I2C_Host .WriteRead (PROXIMITY_I2C_ADDRESS , & proximityData , sizeof (proximityData ), & proximityResponse .bytes [0 ], sizeof (proximityResponse ));
66+ while (I2C_Host .IsBusy ())
67+ {
68+ }
69+
70+ * proximityValue = proximityResponse .value ;
71+ errorState = I2C_Host .ErrorGet ();
72+ // Error states:
73+ // 0x00 = I2C_ERROR_NONE
74+ // 0x01 = I2C_ERROR_ADDR_NACK
75+ // 0x02 = I2C_ERROR_DATA_NACK
76+ // 0x03 = I2C_ERROR_BUS_COLLISION
77+ return errorState ;
78+ }
79+
80+ const uint8_t * I2CErrorToString (uint8_t error )
81+ {
82+ switch (error )
83+ {
84+ case I2C_ERROR_NONE :
85+ return "I2C_ERROR_NONE" ;
86+ case I2C_ERROR_ADDR_NACK :
87+ return "I2C_ERROR_ADDR_NACK" ;
88+ case I2C_ERROR_DATA_NACK :
89+ return "I2C_ERROR_DATA_NACK" ;
90+ case I2C_ERROR_BUS_COLLISION :
91+ return "I2C_ERROR_BUS_COLLISION" ;
92+ default :
93+ return "UNKNOWN_ERROR" ;
94+ }
95+ }
96+
97+ uint8_t VCNL4200_Initialize (void )
98+ {
99+ uint8_t initConfigOne [3 ] = {0x03 , 0x2A , 0x0A };
100+ uint8_t initConfigTwo [3 ] = {0x03 , 0x70 , 0x07 };
101+
102+ I2C_Host .Write (PROXIMITY_I2C_ADDRESS , & initConfigOne , sizeof (initConfigOne ));
103+ while (I2C_Host .IsBusy ())
104+ {
105+ }
106+
107+ I2C_Host .Write (PROXIMITY_I2C_ADDRESS , & initConfigTwo , sizeof (initConfigTwo ));
108+ while (I2C_Host .IsBusy ())
109+ {
110+ }
111+
112+ errorState = I2C_Host .ErrorGet ();
113+ return errorState ;
114+ }
115+
116+ void Timer_Callback_250ms (void )
117+ {
118+ timerTick = 1 ;
119+ }
120+
121+ int main (void )
122+ {
123+ __delay_ms (500 ); // Prevent program running when programming
124+
125+ SYSTEM_Initialize ();
126+ INTERRUPT_GlobalInterruptEnable ();
127+ printf ("Example: 4. I2C Proximity Sensor, Implementation: Interrupts with callbacks, Visualization: Printf with error handling \r\n" );
128+ printf ("MCU Device family: PIC18F/18F \r\n\r\n" );
129+
130+ errorState = VCNL4200_Initialize (); // Initializes the proximity sensor (VCNL4200) over the I2C bus
131+ printf ("I2C proximity sensor initialize status: %d - %s \r\n\r\n" , errorState , I2CErrorToString (errorState ));
132+ Timer -> TimeoutCallbackRegister (Timer_Callback_250ms );
133+ INTERRUPT_GlobalInterruptEnable ();
134+
135+ while (1 )
136+ {
137+ if (timerTick == 1 )
138+ {
139+ errorState = VCNL4200_ProximityRead (& proximityValue );
140+ if (errorState != I2C_ERROR_NONE )
141+ {
142+ printf ("The proximity sensor error is: %d - %s\r\n" , errorState , I2CErrorToString (errorState ));
143+ }
144+ printf ("The proximityValue is: %d\r\n" , proximityValue );
145+ IO_LED_Toggle ();
146+ IO_Debug_Toggle ();
147+ timerTick = 0 ;
148+ }
149+ }
150+ }
0 commit comments