ISSDK  1.7
IoT Sensing Software Development Kit
register_io_i2c.c
Go to the documentation of this file.
1 /*
2  * The Clear BSD License
3  * Copyright (c) 2015 - 2016, Freescale Semiconductor, Inc.
4  * Copyright 2016-2017 NXP
5  * All rights reserved.
6  *
7  * Redistribution and use in source and binary forms, with or without modification,
8  * are permitted (subject to the limitations in the disclaimer below) provided
9  * that the following conditions are met:
10  *
11  * o Redistributions of source code must retain the above copyright notice, this list
12  * of conditions and the following disclaimer.
13  *
14  * o Redistributions in binary form must reproduce the above copyright notice, this
15  * list of conditions and the following disclaimer in the documentation and/or
16  * other materials provided with the distribution.
17  *
18  * o Neither the name of the copyright holder nor the names of its
19  * contributors may be used to endorse or promote products derived from this
20  * software without specific prior written permission.
21  *
22  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
23  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
24  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
25  * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
26  * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
27  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
28  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
29  * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
30  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
31  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
32  */
33 
34 /**
35  * @file register_io_i2c.c
36  * @brief The register_io_i2c.c file contains definitions for low-level interface functions
37  * for reading and writing sensor registers.
38  */
39 
40 /* Standard C Includes */
41 #include <string.h>
42 
43 /* ISSDK Includes */
44 #include "issdk_hal.h"
45 #include "register_io_i2c.h"
46 
47 /*******************************************************************************
48  * Types
49  ******************************************************************************/
50 #define I2C_COUNT (sizeof(i2cBases) / sizeof(void *))
51 
52 /*******************************************************************************
53  * Variables
54  ******************************************************************************/
56 volatile bool b_I2C_CompletionFlag[I2C_COUNT] = {false};
57 volatile uint32_t g_I2C_ErrorEvent[I2C_COUNT] = {ARM_I2C_EVENT_TRANSFER_DONE};
58 
59 /*******************************************************************************
60  * Code
61  ******************************************************************************/
62 
63 #if defined(I2C0)
64 /* The I2C0 Signal Event Handler function. */
65 void I2C0_SignalEvent_t(uint32_t event)
66 {
67  if (event != ARM_I2C_EVENT_TRANSFER_DONE)
68  {
69  g_I2C_ErrorEvent[0] = event;
70  }
71  b_I2C_CompletionFlag[0] = true;
72 }
73 #endif
74 
75 #if defined(I2C1)
76 /* The I2C1 Signal Event Handler function. */
77 void I2C1_SignalEvent_t(uint32_t event)
78 {
79  if (event != ARM_I2C_EVENT_TRANSFER_DONE)
80  {
81  g_I2C_ErrorEvent[1] = event;
82  }
83  b_I2C_CompletionFlag[1] = true;
84 }
85 #endif
86 
87 #if defined(I2C2)
88 /* The I2C2 Signal Event Handler function. */
89 void I2C2_SignalEvent_t(uint32_t event)
90 {
91  if (event != ARM_I2C_EVENT_TRANSFER_DONE)
92  {
93  g_I2C_ErrorEvent[2] = event;
94  }
95  b_I2C_CompletionFlag[2] = true;
96 }
97 #endif
98 
99 #if defined(I2C3)
100 /* The I2C3 Signal Event Handler function. */
101 void I2C3_SignalEvent_t(uint32_t event)
102 {
103  if (event != ARM_I2C_EVENT_TRANSFER_DONE)
104  {
105  g_I2C_ErrorEvent[3] = event;
106  }
107  b_I2C_CompletionFlag[3] = true;
108 }
109 #endif
110 
111 #if defined(I2C4)
112 /* The I2C4 Signal Event Handler function. */
113 void I2C4_SignalEvent_t(uint32_t event)
114 {
115  if (event != ARM_I2C_EVENT_TRANSFER_DONE)
116  {
117  g_I2C_ErrorEvent[4] = event;
118  }
119  b_I2C_CompletionFlag[4] = true;
120 }
121 #endif
122 
123 #if defined(I2C5)
124 /* The I2C5 Signal Event Handler function. */
125 void I2C5_SignalEvent_t(uint32_t event)
126 {
127  if (event != ARM_I2C_EVENT_TRANSFER_DONE)
128  {
129  g_I2C_ErrorEvent[5] = event;
130  }
131  b_I2C_CompletionFlag[5] = true;
132 }
133 #endif
134 
135 #if defined(I2C6)
136 /* The I2C6 Signal Event Handler function. */
137 void I2C6_SignalEvent_t(uint32_t event)
138 {
139  if (event != ARM_I2C_EVENT_TRANSFER_DONE)
140  {
141  g_I2C_ErrorEvent[6] = event;
142  }
143  b_I2C_CompletionFlag[6] = true;
144 }
145 #endif
146 
147 #if defined(I2C7)
148 /* The I2C7 Signal Event Handler function. */
149 void I2C7_SignalEvent_t(uint32_t event)
150 {
151  if (event != ARM_I2C_EVENT_TRANSFER_DONE)
152  {
153  g_I2C_ErrorEvent[7] = event;
154  }
155  b_I2C_CompletionFlag[7] = true;
156 }
157 #endif
158 
159 /*! The interface function to block write sensor registers. */
160 int32_t Register_I2C_BlockWrite(ARM_DRIVER_I2C *pCommDrv,
161  registerDeviceInfo_t *devInfo,
162  uint16_t slaveAddress,
163  uint8_t offset,
164  const uint8_t *pBuffer,
165  uint8_t bytesToWrite)
166 {
167  int32_t status;
168  uint8_t buffer[SENSOR_MAX_REGISTER_COUNT];
169 
170  buffer[0] = offset;
171  memcpy(buffer + 1, pBuffer, bytesToWrite);
172 
173  b_I2C_CompletionFlag[devInfo->deviceInstance] = false;
174  g_I2C_ErrorEvent[devInfo->deviceInstance] = ARM_I2C_EVENT_TRANSFER_DONE;
175  status = pCommDrv->MasterTransmit(slaveAddress, buffer, bytesToWrite + 1, false);
176  if (ARM_DRIVER_OK == status)
177  {
178  /* Wait for completion */
179  while (!b_I2C_CompletionFlag[devInfo->deviceInstance])
180  {
181  if (devInfo->idleFunction)
182  {
183  devInfo->idleFunction(devInfo->functionParam);
184  }
185  else
186  {
187  __NOP();
188  }
189  }
190  if (g_I2C_ErrorEvent[devInfo->deviceInstance] == ARM_I2C_EVENT_TRANSFER_INCOMPLETE)
191  {
192  pCommDrv->Control(ARM_I2C_ABORT_TRANSFER, 0);
193  }
194  if (g_I2C_ErrorEvent[devInfo->deviceInstance] != ARM_I2C_EVENT_TRANSFER_DONE)
195  {
196  status = ARM_DRIVER_ERROR;
197  }
198  }
199 
200  return status;
201 }
202 
203 /*! The interface function to write a sensor register. */
204 int32_t Register_I2C_Write(ARM_DRIVER_I2C *pCommDrv,
205  registerDeviceInfo_t *devInfo,
206  uint16_t slaveAddress,
207  uint8_t offset,
208  uint8_t value,
209  uint8_t mask,
210  bool repeatedStart)
211 {
212  int32_t status;
213  uint8_t config[] = {offset, 0x00};
214 
215  /*! Set the register based on the values in the register value pair configuration.*/
216  if (mask)
217  {
218  b_I2C_CompletionFlag[devInfo->deviceInstance] = false;
219  g_I2C_ErrorEvent[devInfo->deviceInstance] = ARM_I2C_EVENT_TRANSFER_DONE;
220  /*! Send the register address to read from.*/
221  status = pCommDrv->MasterTransmit(slaveAddress, &config[0], 1, true);
222  if (ARM_DRIVER_OK == status)
223  {
224  /* Wait for completion without calling idle function */
225  while (!b_I2C_CompletionFlag[devInfo->deviceInstance])
226  {
227  if (devInfo->idleFunction)
228  {
229  devInfo->idleFunction(devInfo->functionParam);
230  }
231  else
232  {
233  __NOP();
234  }
235  };
236  if (g_I2C_ErrorEvent[devInfo->deviceInstance] == ARM_I2C_EVENT_TRANSFER_INCOMPLETE)
237  {
238  pCommDrv->Control(ARM_I2C_ABORT_TRANSFER, 0);
239  }
240  if (g_I2C_ErrorEvent[devInfo->deviceInstance] != ARM_I2C_EVENT_TRANSFER_DONE)
241  {
242  return ARM_DRIVER_ERROR;
243  }
244  }
245  else
246  {
247  return status;
248  }
249  b_I2C_CompletionFlag[devInfo->deviceInstance] = false;
250  g_I2C_ErrorEvent[devInfo->deviceInstance] = ARM_I2C_EVENT_TRANSFER_DONE;
251  /*! Read the value.*/
252  status = pCommDrv->MasterReceive(slaveAddress, &config[1], 1, false);
253  if (ARM_DRIVER_OK == status)
254  {
255  /* Wait for completion */
256  while (!b_I2C_CompletionFlag[devInfo->deviceInstance])
257  {
258  if (devInfo->idleFunction)
259  {
260  devInfo->idleFunction(devInfo->functionParam);
261  }
262  else
263  {
264  __NOP();
265  }
266  }
267  if (g_I2C_ErrorEvent[devInfo->deviceInstance] == ARM_I2C_EVENT_TRANSFER_INCOMPLETE)
268  {
269  pCommDrv->Control(ARM_I2C_ABORT_TRANSFER, 0);
270  }
271  if (g_I2C_ErrorEvent[devInfo->deviceInstance] != ARM_I2C_EVENT_TRANSFER_DONE)
272  {
273  return ARM_DRIVER_ERROR;
274  }
275  }
276  else
277  {
278  return status;
279  }
280  /*! 'OR' in the requested values to the current contents of the register */
281  config[1] = (config[1] & ~mask) | value;
282  }
283  else
284  {
285  /*! Overwrite the register with specified value.*/
286  config[1] = value;
287  }
288 
289  b_I2C_CompletionFlag[devInfo->deviceInstance] = false;
290  g_I2C_ErrorEvent[devInfo->deviceInstance] = ARM_I2C_EVENT_TRANSFER_DONE;
291  /*! Write the updated value. */
292  status = pCommDrv->MasterTransmit(slaveAddress, config, sizeof(config), repeatedStart);
293  if (ARM_DRIVER_OK == status)
294  {
295  /* Wait for completion */
296  while (!b_I2C_CompletionFlag[devInfo->deviceInstance])
297  {
298  if (devInfo->idleFunction)
299  {
300  devInfo->idleFunction(devInfo->functionParam);
301  }
302  else
303  {
304  __NOP();
305  }
306  }
307  if (g_I2C_ErrorEvent[devInfo->deviceInstance] == ARM_I2C_EVENT_TRANSFER_INCOMPLETE)
308  {
309  pCommDrv->Control(ARM_I2C_ABORT_TRANSFER, 0);
310  }
311  if (g_I2C_ErrorEvent[devInfo->deviceInstance] != ARM_I2C_EVENT_TRANSFER_DONE)
312  {
313  status = ARM_DRIVER_ERROR;
314  }
315  }
316 
317  return status;
318 }
319 
320 /*! The interface function to read a sensor register. */
321 int32_t Register_I2C_Read(ARM_DRIVER_I2C *pCommDrv,
322  registerDeviceInfo_t *devInfo,
323  uint16_t slaveAddress,
324  uint8_t offset,
325  uint8_t length,
326  uint8_t *pOutBuffer)
327 {
328  int32_t status;
329 
330  b_I2C_CompletionFlag[devInfo->deviceInstance] = false;
331  g_I2C_ErrorEvent[devInfo->deviceInstance] = ARM_I2C_EVENT_TRANSFER_DONE;
332  status = pCommDrv->MasterTransmit(slaveAddress, &offset, 1, true);
333  if (ARM_DRIVER_OK == status)
334  {
335  /* Wait for completion without calling idle function. */
336  while (!b_I2C_CompletionFlag[devInfo->deviceInstance])
337  {
338  if (devInfo->idleFunction)
339  {
340  devInfo->idleFunction(devInfo->functionParam);
341  }
342  else
343  {
344  __NOP();
345  }
346  };
347  if (g_I2C_ErrorEvent[devInfo->deviceInstance] == ARM_I2C_EVENT_TRANSFER_INCOMPLETE)
348  {
349  pCommDrv->Control(ARM_I2C_ABORT_TRANSFER, 0);
350  }
351  if (g_I2C_ErrorEvent[devInfo->deviceInstance] != ARM_I2C_EVENT_TRANSFER_DONE)
352  {
353  return ARM_DRIVER_ERROR;
354  }
355  }
356  else
357  {
358  return status;
359  }
360 
361  b_I2C_CompletionFlag[devInfo->deviceInstance] = false;
362  g_I2C_ErrorEvent[devInfo->deviceInstance] = ARM_I2C_EVENT_TRANSFER_DONE;
363  /*! Read and update the value.*/
364  status = pCommDrv->MasterReceive(slaveAddress, pOutBuffer, length, false);
365  if (ARM_DRIVER_OK == status)
366  {
367  /* Wait for completion */
368  while (!b_I2C_CompletionFlag[devInfo->deviceInstance])
369  {
370  if (devInfo->idleFunction)
371  {
372  devInfo->idleFunction(devInfo->functionParam);
373  }
374  else
375  {
376  __NOP();
377  }
378  }
379  if (g_I2C_ErrorEvent[devInfo->deviceInstance] == ARM_I2C_EVENT_TRANSFER_INCOMPLETE)
380  {
381  pCommDrv->Control(ARM_I2C_ABORT_TRANSFER, 0);
382  }
383  if (g_I2C_ErrorEvent[devInfo->deviceInstance] != ARM_I2C_EVENT_TRANSFER_DONE)
384  {
385  status = ARM_DRIVER_ERROR;
386  }
387  }
388 
389  return status;
390 }
The register_io_i2c.h file declares low-level interface functions for reading and writing sensor regi...
volatile bool b_I2C_CompletionFlag[I2C_COUNT]
registeridlefunction_t idleFunction
Definition: sensor_drv.h:130
#define SENSOR_MAX_REGISTER_COUNT
Definition: sensor_drv.h:68
volatile uint32_t g_I2C_ErrorEvent[I2C_COUNT]
I2C_Type *const i2cBases[]
int32_t status
#define I2C_BASE_PTRS
Definition: frdm_ke15z.h:158
#define I2C_Type
Definition: frdm_ke15z.h:156
int32_t Register_I2C_BlockWrite(ARM_DRIVER_I2C *pCommDrv, registerDeviceInfo_t *devInfo, uint16_t slaveAddress, uint8_t offset, const uint8_t *pBuffer, uint8_t bytesToWrite)
The interface function to write a sensor register.
typedef int32_t(DATA_FORMAT_Append_t))(void *pData
The interface function to append the data on the formated stream.
int32_t Register_I2C_Read(ARM_DRIVER_I2C *pCommDrv, registerDeviceInfo_t *devInfo, uint16_t slaveAddress, uint8_t offset, uint8_t length, uint8_t *pOutBuffer)
The interface function to read a sensor register.
int32_t Register_I2C_Write(ARM_DRIVER_I2C *pCommDrv, registerDeviceInfo_t *devInfo, uint16_t slaveAddress, uint8_t offset, uint8_t value, uint8_t mask, bool repeatedStart)
The interface function to write a sensor register.
This structure defines the device specific info required by register I/O.
Definition: sensor_drv.h:128
#define I2C_COUNT