1 /*
2  * Copyright (c) 2015 - 2016, Freescale Semiconductor, Inc.
3  * Copyright 2016-2017 NXP
4  * All rights reserved.
5  *
6  * SPDX-License-Identifier: BSD-3-Clause
7  */
8 
9 /**
10  * @file register_io_i2c.c
11  * @brief The register_io_i2c.c file contains definitions for low-level interface functions
12  *  for reading and writing sensor registers.
13  */
14 
15 /* Standard C Includes */
16 #include <string.h>
17 
18 /* ISSDK Includes */
19 #include "issdk_hal.h"
20 #include "register_io_i2c.h"
21 
22 /*******************************************************************************
23  * Types
24  ******************************************************************************/
25 #define I2C_COUNT (sizeof(i2cBases) / sizeof(void *))
26 
27 /*******************************************************************************
28  * Variables
29  ******************************************************************************/
30 #if defined(CPU_MCXN947VDF_cm33_core0) || defined(CPU_MCXN548VDF_cm33_core0)
31 LPI2C_Type *const i2cBases[] = LPI2C_BASE_PTRS;
32 #else
33 I2C_Type *const i2cBases[] = I2C_BASE_PTRS;
34 #endif
35 volatile bool b_I2C_CompletionFlag[I2C_COUNT] = {false};
36 volatile uint32_t g_I2C_ErrorEvent[I2C_COUNT] = {ARM_I2C_EVENT_TRANSFER_DONE};
37 
38 /*******************************************************************************
39  * Code
40  ******************************************************************************/
41 
42 #if defined(I2C0)
43 /* The I2C0 Signal Event Handler function. */
I2C0_SignalEvent_t(uint32_t event)44 void I2C0_SignalEvent_t(uint32_t event)
45 {
46     if (event != ARM_I2C_EVENT_TRANSFER_DONE)
47     {
48         g_I2C_ErrorEvent[0] = event;
49     }
50     b_I2C_CompletionFlag[0] = true;
51 }
52 #endif
53 
54 #if defined(I2C1)
55 /* The I2C1 Signal Event Handler function. */
I2C1_SignalEvent_t(uint32_t event)56 void I2C1_SignalEvent_t(uint32_t event)
57 {
58     if (event != ARM_I2C_EVENT_TRANSFER_DONE)
59     {
60         g_I2C_ErrorEvent[1] = event;
61     }
62     b_I2C_CompletionFlag[1] = true;
63 }
64 #endif
65 
66 #if defined(I2C2)
67 /* The I2C2 Signal Event Handler function. */
I2C2_SignalEvent_t(uint32_t event)68 void I2C2_SignalEvent_t(uint32_t event)
69 {
70     if (event != ARM_I2C_EVENT_TRANSFER_DONE)
71     {
72         g_I2C_ErrorEvent[2] = event;
73     }
74     b_I2C_CompletionFlag[2] = true;
75 }
76 #endif
77 
78 #if defined(I2C3)
79 /* The I2C3 Signal Event Handler function. */
I2C3_SignalEvent_t(uint32_t event)80 void I2C3_SignalEvent_t(uint32_t event)
81 {
82     if (event != ARM_I2C_EVENT_TRANSFER_DONE)
83     {
84         g_I2C_ErrorEvent[3] = event;
85     }
86     b_I2C_CompletionFlag[3] = true;
87 }
88 #endif
89 
90 #if defined(I2C4)
91 /* The I2C4 Signal Event Handler function. */
I2C4_SignalEvent_t(uint32_t event)92 void I2C4_SignalEvent_t(uint32_t event)
93 {
94     if (event != ARM_I2C_EVENT_TRANSFER_DONE)
95     {
96         g_I2C_ErrorEvent[4] = event;
97     }
98     b_I2C_CompletionFlag[4] = true;
99 }
100 #endif
101 
102 #if defined(I2C5)
103 /* The I2C5 Signal Event Handler function. */
I2C5_SignalEvent_t(uint32_t event)104 void I2C5_SignalEvent_t(uint32_t event)
105 {
106     if (event != ARM_I2C_EVENT_TRANSFER_DONE)
107     {
108         g_I2C_ErrorEvent[5] = event;
109     }
110     b_I2C_CompletionFlag[5] = true;
111 }
112 #endif
113 
114 #if defined(I2C6)
115 /* The I2C6 Signal Event Handler function. */
I2C6_SignalEvent_t(uint32_t event)116 void I2C6_SignalEvent_t(uint32_t event)
117 {
118     if (event != ARM_I2C_EVENT_TRANSFER_DONE)
119     {
120         g_I2C_ErrorEvent[6] = event;
121     }
122     b_I2C_CompletionFlag[6] = true;
123 }
124 #endif
125 
126 #if defined(I2C7)
127 /* The I2C7 Signal Event Handler function. */
I2C7_SignalEvent_t(uint32_t event)128 void I2C7_SignalEvent_t(uint32_t event)
129 {
130     if (event != ARM_I2C_EVENT_TRANSFER_DONE)
131     {
132         g_I2C_ErrorEvent[7] = event;
133     }
134     b_I2C_CompletionFlag[7] = true;
135 }
136 #endif
137 
138 #ifdef MIMXRT500_AGM01
139 #if defined(I2C11)
140 /* The I2C11 Signal Event Handler function. */
I2C11_SignalEvent_t(uint32_t event)141 void I2C11_SignalEvent_t(uint32_t event)
142 {
143     if (event != ARM_I2C_EVENT_TRANSFER_DONE)
144     {
145         g_I2C_ErrorEvent[11] = event;
146     }
147     b_I2C_CompletionFlag[11] = true;
148 }
149 #endif
150 #endif
151 
152 /*! The interface function to block write sensor registers. */
Register_I2C_BlockWrite(ARM_DRIVER_I2C * pCommDrv,registerDeviceInfo_t * devInfo,uint16_t slaveAddress,uint8_t offset,const uint8_t * pBuffer,uint8_t bytesToWrite)153 int32_t Register_I2C_BlockWrite(ARM_DRIVER_I2C *pCommDrv,
154                                 registerDeviceInfo_t *devInfo,
155                                 uint16_t slaveAddress,
156                                 uint8_t offset,
157                                 const uint8_t *pBuffer,
158                                 uint8_t bytesToWrite)
159 {
160     int32_t status;
161     uint8_t buffer[SENSOR_MAX_REGISTER_COUNT];
162 
163     buffer[0] = offset;
164     memcpy(buffer + 1, pBuffer, bytesToWrite);
165 
166     b_I2C_CompletionFlag[devInfo->deviceInstance] = false;
167     g_I2C_ErrorEvent[devInfo->deviceInstance] = ARM_I2C_EVENT_TRANSFER_DONE;
168     status = pCommDrv->MasterTransmit(slaveAddress, buffer, bytesToWrite + 1, false);
169     if (ARM_DRIVER_OK == status)
170     {
171         /* Wait for completion */
172         while (!b_I2C_CompletionFlag[devInfo->deviceInstance])
173         {
174             if (devInfo->idleFunction)
175             {
176                 devInfo->idleFunction(devInfo->functionParam);
177             }
178             else
179             {
180                 __NOP();
181             }
182         }
183         if (g_I2C_ErrorEvent[devInfo->deviceInstance] == ARM_I2C_EVENT_TRANSFER_INCOMPLETE)
184         {
185             pCommDrv->Control(ARM_I2C_ABORT_TRANSFER, 0);
186         }
187         if (g_I2C_ErrorEvent[devInfo->deviceInstance] != ARM_I2C_EVENT_TRANSFER_DONE)
188         {
189             status = ARM_DRIVER_ERROR;
190         }
191     }
192 
193     return status;
194 }
195 
196 /*! The interface function to write a sensor register. */
Register_I2C_Write(ARM_DRIVER_I2C * pCommDrv,registerDeviceInfo_t * devInfo,uint16_t slaveAddress,uint8_t offset,uint8_t value,uint8_t mask,bool repeatedStart)197 int32_t Register_I2C_Write(ARM_DRIVER_I2C *pCommDrv,
198                            registerDeviceInfo_t *devInfo,
199                            uint16_t slaveAddress,
200                            uint8_t offset,
201                            uint8_t value,
202                            uint8_t mask,
203                            bool repeatedStart)
204 {
205     int32_t status;
206     uint8_t config[] = {offset, 0x00};
207 
208     /*! Set the register based on the values in the register value pair configuration.*/
209     if (mask)
210     {
211         b_I2C_CompletionFlag[devInfo->deviceInstance] = false;
212         g_I2C_ErrorEvent[devInfo->deviceInstance] = ARM_I2C_EVENT_TRANSFER_DONE;
213         /*! Send the register address to read from.*/
214         status = pCommDrv->MasterTransmit(slaveAddress, &config[0], 1, true);
215         if (ARM_DRIVER_OK == status)
216         {
217             /* Wait for completion without calling idle function */
218             while (!b_I2C_CompletionFlag[devInfo->deviceInstance])
219             {
220                 if (devInfo->idleFunction)
221                 {
222                     devInfo->idleFunction(devInfo->functionParam);
223                 }
224                 else
225                 {
226                     __NOP();
227                 }
228             };
229             if (g_I2C_ErrorEvent[devInfo->deviceInstance] == ARM_I2C_EVENT_TRANSFER_INCOMPLETE)
230             {
231                 pCommDrv->Control(ARM_I2C_ABORT_TRANSFER, 0);
232             }
233             if (g_I2C_ErrorEvent[devInfo->deviceInstance] != ARM_I2C_EVENT_TRANSFER_DONE)
234             {
235                 return ARM_DRIVER_ERROR;
236             }
237         }
238         else
239         {
240             return status;
241         }
242         b_I2C_CompletionFlag[devInfo->deviceInstance] = false;
243         g_I2C_ErrorEvent[devInfo->deviceInstance] = ARM_I2C_EVENT_TRANSFER_DONE;
244         /*! Read the value.*/
245         status = pCommDrv->MasterReceive(slaveAddress, &config[1], 1, false);
246         if (ARM_DRIVER_OK == status)
247         {
248             /* Wait for completion */
249             while (!b_I2C_CompletionFlag[devInfo->deviceInstance])
250             {
251                 if (devInfo->idleFunction)
252                 {
253                     devInfo->idleFunction(devInfo->functionParam);
254                 }
255                 else
256                 {
257                     __NOP();
258                 }
259             }
260             if (g_I2C_ErrorEvent[devInfo->deviceInstance] == ARM_I2C_EVENT_TRANSFER_INCOMPLETE)
261             {
262                 pCommDrv->Control(ARM_I2C_ABORT_TRANSFER, 0);
263             }
264             if (g_I2C_ErrorEvent[devInfo->deviceInstance] != ARM_I2C_EVENT_TRANSFER_DONE)
265             {
266                 return ARM_DRIVER_ERROR;
267             }
268         }
269         else
270         {
271             return status;
272         }
273         /*! 'OR' in the requested values to the current contents of the register */
274         config[1] = (config[1] & ~mask) | value;
275     }
276     else
277     {
278         /*! Overwrite the register with specified value.*/
279         config[1] = value;
280     }
281 
282     b_I2C_CompletionFlag[devInfo->deviceInstance] = false;
283     g_I2C_ErrorEvent[devInfo->deviceInstance] = ARM_I2C_EVENT_TRANSFER_DONE;
284     /*!  Write the updated value. */
285     status = pCommDrv->MasterTransmit(slaveAddress, config, sizeof(config), repeatedStart);
286     if (ARM_DRIVER_OK == status)
287     {
288         /* Wait for completion */
289         while (!b_I2C_CompletionFlag[devInfo->deviceInstance])
290         {
291             if (devInfo->idleFunction)
292             {
293                 devInfo->idleFunction(devInfo->functionParam);
294             }
295             else
296             {
297                 __NOP();
298             }
299         }
300         if (g_I2C_ErrorEvent[devInfo->deviceInstance] == ARM_I2C_EVENT_TRANSFER_INCOMPLETE)
301         {
302             pCommDrv->Control(ARM_I2C_ABORT_TRANSFER, 0);
303         }
304         if (g_I2C_ErrorEvent[devInfo->deviceInstance] != ARM_I2C_EVENT_TRANSFER_DONE)
305         {
306             status = ARM_DRIVER_ERROR;
307         }
308     }
309 
310     return status;
311 }
312 
313 /*! The interface function to read a sensor register. */
Register_I2C_Read(ARM_DRIVER_I2C * pCommDrv,registerDeviceInfo_t * devInfo,uint16_t slaveAddress,uint8_t offset,uint8_t length,uint8_t * pOutBuffer)314 int32_t Register_I2C_Read(ARM_DRIVER_I2C *pCommDrv,
315                           registerDeviceInfo_t *devInfo,
316                           uint16_t slaveAddress,
317                           uint8_t offset,
318                           uint8_t length,
319                           uint8_t *pOutBuffer)
320 {
321     int32_t status;
322 
323     b_I2C_CompletionFlag[devInfo->deviceInstance] = false;
324     g_I2C_ErrorEvent[devInfo->deviceInstance] = ARM_I2C_EVENT_TRANSFER_DONE;
325     status = pCommDrv->MasterTransmit(slaveAddress, &offset, 1, true);
326     if (ARM_DRIVER_OK == status)
327     {
328         /* Wait for completion without calling idle function. */
329         while (!b_I2C_CompletionFlag[devInfo->deviceInstance])
330         {
331             if (devInfo->idleFunction)
332             {
333                 devInfo->idleFunction(devInfo->functionParam);
334             }
335             else
336             {
337                 __NOP();
338             }
339         };
340         if (g_I2C_ErrorEvent[devInfo->deviceInstance] == ARM_I2C_EVENT_TRANSFER_INCOMPLETE)
341         {
342             pCommDrv->Control(ARM_I2C_ABORT_TRANSFER, 0);
343         }
344         if (g_I2C_ErrorEvent[devInfo->deviceInstance] != ARM_I2C_EVENT_TRANSFER_DONE)
345         {
346             return ARM_DRIVER_ERROR;
347         }
348     }
349     else
350     {
351         return status;
352     }
353 
354     b_I2C_CompletionFlag[devInfo->deviceInstance] = false;
355     g_I2C_ErrorEvent[devInfo->deviceInstance] = ARM_I2C_EVENT_TRANSFER_DONE;
356     /*! Read and update the value.*/
357     status = pCommDrv->MasterReceive(slaveAddress, pOutBuffer, length, false);
358     if (ARM_DRIVER_OK == status)
359     {
360         /* Wait for completion */
361         while (!b_I2C_CompletionFlag[devInfo->deviceInstance])
362         {
363             if (devInfo->idleFunction)
364             {
365                 devInfo->idleFunction(devInfo->functionParam);
366             }
367             else
368             {
369                 __NOP();
370             }
371         }
372         if (g_I2C_ErrorEvent[devInfo->deviceInstance] == ARM_I2C_EVENT_TRANSFER_INCOMPLETE)
373         {
374             pCommDrv->Control(ARM_I2C_ABORT_TRANSFER, 0);
375         }
376         if (g_I2C_ErrorEvent[devInfo->deviceInstance] != ARM_I2C_EVENT_TRANSFER_DONE)
377         {
378             status = ARM_DRIVER_ERROR;
379         }
380     }
381 
382     return status;
383 }
384