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 sensor_io_i2c.c
11 * @brief The sensor_io_i2c.c file contains definitions for low-level interface functions
12 * for reading and writing data from/to sensor.
13 */
14
15 #include "Driver_I2C.h"
16 #include "sensor_drv.h"
17 #include "systick_utils.h"
18 #include "sensor_io_i2c.h"
19
20 /*******************************************************************************
21 * Code
22 ******************************************************************************/
23 /*! The interface function to block write commands to a sensor. */
Sensor_I2C_BlockWrite(ARM_DRIVER_I2C * pCommDrv,registerDeviceInfo_t * devInfo,uint16_t slaveAddress,const registercommandlist_t * pCommandList,uint8_t error_mask)24 int32_t Sensor_I2C_BlockWrite(ARM_DRIVER_I2C *pCommDrv,
25 registerDeviceInfo_t *devInfo,
26 uint16_t slaveAddress,
27 const registercommandlist_t *pCommandList,
28 uint8_t error_mask)
29 {
30 int32_t status;
31 bool commandComplete;
32 uint8_t cocoBuffer[2] = {0};
33
34 /*! Validate for the correct handle.*/
35 if ((pCommDrv == NULL) || (pCommandList == NULL))
36 {
37 return SENSOR_ERROR_BAD_ADDRESS;
38 }
39
40 const registercommandlist_t *pCmd = pCommandList;
41 /*! Update register values based on register write list unless the next Cmd is the list terminator */
42 do
43 { /*! Write the command based on the values in the command and value pair.*/
44 status =
45 Register_I2C_BlockWrite(pCommDrv, devInfo, slaveAddress, pCmd->writeTo, pCmd->pWriteBuffer, pCmd->numBytes);
46 if (ARM_DRIVER_OK != status)
47 {
48 return SENSOR_ERROR_WRITE;
49 }
50
51 do
52 { /*! Wait for Command Completion. */
53 BOARD_DELAY_ms(1);
54 status = Register_I2C_Read(pCommDrv, devInfo, slaveAddress, 0, sizeof(cocoBuffer), cocoBuffer);
55 if (ARM_DRIVER_OK != status)
56 {
57 return SENSOR_ERROR_READ;
58 }
59 commandComplete = cocoBuffer[1] & 0x80;
60 if (commandComplete && cocoBuffer[1] & error_mask)
61 {
62 return SENSOR_ERROR_WRITE;
63 }
64 } while (!commandComplete);
65 } while ((++pCmd)->writeTo != 0xFFFF);
66
67 return SENSOR_ERROR_NONE;
68 }
69
70 /*! The interface function to write register data to a sensor. */
Sensor_I2C_Write(ARM_DRIVER_I2C * pCommDrv,registerDeviceInfo_t * devInfo,uint16_t slaveAddress,const registerwritelist_t * pRegWriteList)71 int32_t Sensor_I2C_Write(ARM_DRIVER_I2C *pCommDrv,
72 registerDeviceInfo_t *devInfo,
73 uint16_t slaveAddress,
74 const registerwritelist_t *pRegWriteList)
75 {
76 int32_t status;
77 bool repeatedStart;
78
79 /*! Validate for the correct handle.*/
80 if ((pCommDrv == NULL) || (pRegWriteList == NULL))
81 {
82 return SENSOR_ERROR_BAD_ADDRESS;
83 }
84
85 const registerwritelist_t *pCmd = pRegWriteList;
86
87 /*! Update register values based on register write list unless the next Cmd is the list terminator */
88 do
89 {
90 repeatedStart = (pCmd + 1)->writeTo != 0xFFFF;
91 /*! Set the register based on the values in the register value pair.*/
92 status =
93 Register_I2C_Write(pCommDrv, devInfo, slaveAddress, pCmd->writeTo, pCmd->value, pCmd->mask, repeatedStart);
94 if (ARM_DRIVER_OK != status)
95 {
96 return SENSOR_ERROR_WRITE;
97 }
98 ++pCmd;
99 } while (repeatedStart);
100
101 return SENSOR_ERROR_NONE;
102 }
103
104 /*! The interface function to read register data from a sensor. */
Sensor_I2C_Read(ARM_DRIVER_I2C * pCommDrv,registerDeviceInfo_t * devInfo,uint16_t slaveAddress,const registerreadlist_t * pReadList,uint8_t * pOutBuffer)105 int32_t Sensor_I2C_Read(ARM_DRIVER_I2C *pCommDrv,
106 registerDeviceInfo_t *devInfo,
107 uint16_t slaveAddress,
108 const registerreadlist_t *pReadList,
109 uint8_t *pOutBuffer)
110 {
111 int32_t status;
112 uint8_t *pBuf;
113
114 /*! Validate for the correct handle.*/
115 if (pCommDrv == NULL || pReadList == NULL || pOutBuffer == NULL)
116 {
117 return SENSOR_ERROR_BAD_ADDRESS;
118 }
119 const registerreadlist_t *pCmd = pReadList;
120
121 /*! Traverse the read list and read the registers one by one unless the register read list numBytes is zero*/
122 for (pBuf = pOutBuffer; pCmd->numBytes != 0; pCmd++)
123 {
124 status = Register_I2C_Read(pCommDrv, devInfo, slaveAddress, pCmd->readFrom, pCmd->numBytes, pBuf);
125 if (ARM_DRIVER_OK != status)
126 {
127 return SENSOR_ERROR_READ;
128 }
129 pBuf += pCmd->numBytes;
130 }
131 return SENSOR_ERROR_NONE;
132 }
133