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 fxos8700_drv.c
11 * @brief The fxos8700_drv.c file implements the fxos8700 sensor driver functional interfaces.
12 */
13
14 //-----------------------------------------------------------------------
15 // ISSDK Includes
16 //-----------------------------------------------------------------------
17 #include "gpio_driver.h"
18 #include "fxos8700_drv.h"
19
20 //-----------------------------------------------------------------------
21 // Global Variables
22 //-----------------------------------------------------------------------
23 uint8_t fxos8700_spiRead_CmdBuffer[FXOS8700_SPI_MAX_MSG_SIZE] = {0};
24 uint8_t fxos8700_spiRead_DataBuffer[FXOS8700_SPI_MAX_MSG_SIZE] = {0};
25 uint8_t fxos8700_spiWrite_CmdDataBuffer[FXOS8700_SPI_MAX_MSG_SIZE] = {0};
26
27 //-----------------------------------------------------------------------
28 // Functions
29 //-----------------------------------------------------------------------
FXOS8700_SPI_ReadPreprocess(void * pCmdOut,uint32_t offset,uint32_t size)30 void FXOS8700_SPI_ReadPreprocess(void *pCmdOut, uint32_t offset, uint32_t size)
31 {
32 spiCmdParams_t *pSlaveCmd = pCmdOut;
33
34 uint8_t *pWBuff = fxos8700_spiRead_CmdBuffer;
35 uint8_t *pRBuff = fxos8700_spiRead_DataBuffer;
36
37 /* Formatting for Read command of FXOS8700 SENSOR. */
38 *(pWBuff) = offset & 0x7F; /* offset is the internal register address of the sensor at which write is performed. */
39 *(pWBuff + 1) = offset & 0x80;
40
41 /* Create the slave read command. */
42 pSlaveCmd->size = size + FXOS8700_SPI_CMD_LEN;
43 pSlaveCmd->pWriteBuffer = pWBuff;
44 pSlaveCmd->pReadBuffer = pRBuff;
45 }
46
FXOS8700_SPI_WritePreprocess(void * pCmdOut,uint32_t offset,uint32_t size,void * pWritebuffer)47 void FXOS8700_SPI_WritePreprocess(void *pCmdOut, uint32_t offset, uint32_t size, void *pWritebuffer)
48 {
49 spiCmdParams_t *pSlaveCmd = pCmdOut;
50
51 uint8_t *pWBuff = fxos8700_spiWrite_CmdDataBuffer;
52 uint8_t *pRBuff = fxos8700_spiWrite_CmdDataBuffer + size + FXOS8700_SPI_CMD_LEN;
53
54 /* Formatting for Write command of FXOS8700 SENSOR. */
55 *(pWBuff) = offset | 0x80; /* offset is the internal register address of the sensor at which write is performed. */
56 *(pWBuff + 1) = offset & 0x80;
57
58 /* Copy the slave write command */
59 memcpy(pWBuff + FXOS8700_SPI_CMD_LEN, pWritebuffer, size);
60
61 /* Create the slave command. */
62 pSlaveCmd->size = size + FXOS8700_SPI_CMD_LEN;
63 pSlaveCmd->pWriteBuffer = pWBuff;
64 pSlaveCmd->pReadBuffer = pRBuff;
65 }
66
FXOS8700_SPI_Initialize(fxos8700_spi_sensorhandle_t * pSensorHandle,ARM_DRIVER_SPI * pBus,uint8_t index,void * pSlaveSelect,uint8_t whoAmi)67 int32_t FXOS8700_SPI_Initialize(
68 fxos8700_spi_sensorhandle_t *pSensorHandle, ARM_DRIVER_SPI *pBus, uint8_t index, void *pSlaveSelect, uint8_t whoAmi)
69 {
70 int32_t status;
71 FXOS8700_WHO_AM_I_t reg;
72 GENERIC_DRIVER_GPIO *pGPIODriver = &Driver_GPIO_KSDK;
73
74 /*! Check the input parameters. */
75 if ((pSensorHandle == NULL) || (pBus == NULL) || (pSlaveSelect == NULL))
76 {
77 return SENSOR_ERROR_INVALID_PARAM;
78 }
79
80 /*! Initialize the sensor handle. */
81 pSensorHandle->pCommDrv = pBus;
82 pSensorHandle->slaveParams.pReadPreprocessFN = FXOS8700_SPI_ReadPreprocess;
83 pSensorHandle->slaveParams.pWritePreprocessFN = FXOS8700_SPI_WritePreprocess;
84 pSensorHandle->slaveParams.pTargetSlavePinID = pSlaveSelect;
85 pSensorHandle->slaveParams.spiCmdLen = FXOS8700_SPI_CMD_LEN;
86 pSensorHandle->slaveParams.ssActiveValue = FXOS8700_SS_ACTIVE_VALUE;
87
88 pSensorHandle->deviceInfo.deviceInstance = index;
89 pSensorHandle->deviceInfo.functionParam = NULL;
90 pSensorHandle->deviceInfo.idleFunction = NULL;
91
92 /* Initialize the Slave Select Pin. */
93 pGPIODriver->pin_init(pSlaveSelect, GPIO_DIRECTION_OUT, NULL, NULL, NULL);
94 if (pSensorHandle->slaveParams.ssActiveValue == SPI_SS_ACTIVE_LOW)
95 {
96 pGPIODriver->set_pin(pSlaveSelect);
97 }
98 else
99 {
100 pGPIODriver->clr_pin(pSlaveSelect);
101 }
102
103 /*! Read and store the device's WHO_AM_I.*/
104 status = Register_SPI_Read(pSensorHandle->pCommDrv, &pSensorHandle->deviceInfo, &pSensorHandle->slaveParams,
105 FXOS8700_WHO_AM_I, 1, ®);
106 if ((ARM_DRIVER_OK != status) || (whoAmi != reg))
107 {
108 pSensorHandle->isInitialized = false;
109 return SENSOR_ERROR_INIT;
110 }
111
112 pSensorHandle->isInitialized = true;
113 return SENSOR_ERROR_NONE;
114 }
115
FXOS8700_SPI_SetIdleTask(fxos8700_spi_sensorhandle_t * pSensorHandle,registeridlefunction_t idleTask,void * userParam)116 void FXOS8700_SPI_SetIdleTask(fxos8700_spi_sensorhandle_t *pSensorHandle,
117 registeridlefunction_t idleTask,
118 void *userParam)
119 {
120 pSensorHandle->deviceInfo.functionParam = userParam;
121 pSensorHandle->deviceInfo.idleFunction = idleTask;
122 }
123
FXOS8700_SPI_Configure(fxos8700_spi_sensorhandle_t * pSensorHandle,const registerwritelist_t * pRegWriteList)124 int32_t FXOS8700_SPI_Configure(fxos8700_spi_sensorhandle_t *pSensorHandle, const registerwritelist_t *pRegWriteList)
125 {
126 int32_t status;
127
128 /*! Validate for the correct handle and register write list.*/
129 if ((pSensorHandle == NULL) || (pRegWriteList == NULL))
130 {
131 return SENSOR_ERROR_INVALID_PARAM;
132 }
133
134 /*! Check whether sensor handle is initialized before applying configuration.*/
135 if (pSensorHandle->isInitialized != true)
136 {
137 return SENSOR_ERROR_INIT;
138 }
139
140 /*! Put the device into standby mode so that configuration can be applied.*/
141 status =
142 Register_SPI_Write(pSensorHandle->pCommDrv, &pSensorHandle->deviceInfo, &pSensorHandle->slaveParams,
143 FXOS8700_CTRL_REG1, FXOS8700_CTRL_REG1_ACTIVE_STANDBY_MODE, FXOS8700_CTRL_REG1_ACTIVE_MASK);
144 if (ARM_DRIVER_OK != status)
145 {
146 return SENSOR_ERROR_WRITE;
147 }
148
149 /*! Apply the Sensor Configuration based on the Register Write List */
150 status = Sensor_SPI_Write(pSensorHandle->pCommDrv, &pSensorHandle->deviceInfo, &pSensorHandle->slaveParams,
151 pRegWriteList);
152 if (ARM_DRIVER_OK != status)
153 {
154 return SENSOR_ERROR_WRITE;
155 }
156
157 /*! Put the device into active mode and ready for reading data.*/
158 status =
159 Register_SPI_Write(pSensorHandle->pCommDrv, &pSensorHandle->deviceInfo, &pSensorHandle->slaveParams,
160 FXOS8700_CTRL_REG1, FXOS8700_CTRL_REG1_ACTIVE_ACTIVE_MODE, FXOS8700_CTRL_REG1_ACTIVE_MASK);
161 if (ARM_DRIVER_OK != status)
162 {
163 return SENSOR_ERROR_WRITE;
164 }
165
166 return SENSOR_ERROR_NONE;
167 }
168
FXOS8700_SPI_ReadData(fxos8700_spi_sensorhandle_t * pSensorHandle,const registerreadlist_t * pReadList,uint8_t * pBuffer)169 int32_t FXOS8700_SPI_ReadData(fxos8700_spi_sensorhandle_t *pSensorHandle,
170 const registerreadlist_t *pReadList,
171 uint8_t *pBuffer)
172 {
173 int32_t status;
174
175 /*! Validate for the correct handle and register read list.*/
176 if ((pSensorHandle == NULL) || (pReadList == NULL) || (pBuffer == NULL))
177 {
178 return SENSOR_ERROR_INVALID_PARAM;
179 }
180
181 /*! Check whether sensor handle is initialized before reading sensor data.*/
182 if (pSensorHandle->isInitialized != true)
183 {
184 return SENSOR_ERROR_INIT;
185 }
186
187 /*! Parse through the read list and read the data one by one. */
188 status = Sensor_SPI_Read(pSensorHandle->pCommDrv, &pSensorHandle->deviceInfo, &pSensorHandle->slaveParams,
189 pReadList, pBuffer);
190 if (ARM_DRIVER_OK != status)
191 {
192 return SENSOR_ERROR_READ;
193 }
194
195 return SENSOR_ERROR_NONE;
196 }
197
FXOS8700_SPI_Deinit(fxos8700_spi_sensorhandle_t * pSensorHandle)198 int32_t FXOS8700_SPI_Deinit(fxos8700_spi_sensorhandle_t *pSensorHandle)
199 {
200 if (pSensorHandle == NULL)
201 {
202 return SENSOR_ERROR_INVALID_PARAM;
203 }
204
205 /*! Check whether sensor handle is initialized before triggering sensor reset.*/
206 if (pSensorHandle->isInitialized != true)
207 {
208 return SENSOR_ERROR_INIT;
209 }
210
211 /*! Trigger sensor device reset.*/
212 Register_SPI_Write(pSensorHandle->pCommDrv, &pSensorHandle->deviceInfo, &pSensorHandle->slaveParams,
213 FXOS8700_CTRL_REG2, FXOS8700_CTRL_REG2_RST_EN, FXOS8700_CTRL_REG2_RST_MASK);
214
215 /*! De-initialize sensor handle.
216 * We do not validate write success since 8700 reset before sensing ack for the transaction. */
217 pSensorHandle->isInitialized = false;
218
219 return SENSOR_ERROR_NONE;
220 }
221
FXOS8700_I2C_Initialize(fxos8700_i2c_sensorhandle_t * pSensorHandle,ARM_DRIVER_I2C * pBus,uint8_t index,uint16_t sAddress,uint8_t whoAmi)222 int32_t FXOS8700_I2C_Initialize(
223 fxos8700_i2c_sensorhandle_t *pSensorHandle, ARM_DRIVER_I2C *pBus, uint8_t index, uint16_t sAddress, uint8_t whoAmi)
224 {
225 int32_t status;
226 FXOS8700_WHO_AM_I_t reg;
227
228 if ((pSensorHandle == NULL) || (pBus == NULL))
229 {
230 return SENSOR_ERROR_INVALID_PARAM;
231 }
232
233 pSensorHandle->deviceInfo.deviceInstance = index;
234 pSensorHandle->deviceInfo.functionParam = NULL;
235 pSensorHandle->deviceInfo.idleFunction = NULL;
236
237 /*! Read and store the device's WHO_AM_I.*/
238 status = Register_I2C_Read(pBus, &pSensorHandle->deviceInfo, sAddress, FXOS8700_WHO_AM_I, 1, ®);
239 if ((ARM_DRIVER_OK != status) || (whoAmi != reg))
240 {
241 pSensorHandle->isInitialized = false;
242 return SENSOR_ERROR_INIT;
243 }
244
245 /*! Initialize the sensor handle. */
246 pSensorHandle->pCommDrv = pBus;
247 pSensorHandle->slaveAddress = sAddress;
248 pSensorHandle->isInitialized = true;
249 return SENSOR_ERROR_NONE;
250 }
251
FXOS8700_I2C_SetIdleTask(fxos8700_i2c_sensorhandle_t * pSensorHandle,registeridlefunction_t idleTask,void * userParam)252 void FXOS8700_I2C_SetIdleTask(fxos8700_i2c_sensorhandle_t *pSensorHandle,
253 registeridlefunction_t idleTask,
254 void *userParam)
255 {
256 pSensorHandle->deviceInfo.functionParam = userParam;
257 pSensorHandle->deviceInfo.idleFunction = idleTask;
258 }
259
FXOS8700_I2C_Configure(fxos8700_i2c_sensorhandle_t * pSensorHandle,const registerwritelist_t * pRegWriteList)260 int32_t FXOS8700_I2C_Configure(fxos8700_i2c_sensorhandle_t *pSensorHandle, const registerwritelist_t *pRegWriteList)
261 {
262 int32_t status;
263
264 /*! Validate for the correct handle and register write list.*/
265 if ((pSensorHandle == NULL) || (pRegWriteList == NULL))
266 {
267 return SENSOR_ERROR_INVALID_PARAM;
268 }
269
270 /*! Check whether sensor handle is initialized before applying configuration.*/
271 if (pSensorHandle->isInitialized != true)
272 {
273 return SENSOR_ERROR_INIT;
274 }
275
276 /* Put the device into standby mode so that configuration can be applied.*/
277 status = Register_I2C_Write(pSensorHandle->pCommDrv, &pSensorHandle->deviceInfo, pSensorHandle->slaveAddress,
278 FXOS8700_CTRL_REG1, FXOS8700_CTRL_REG1_ACTIVE_STANDBY_MODE,
279 FXOS8700_CTRL_REG1_ACTIVE_MASK, false);
280 if (ARM_DRIVER_OK != status)
281 {
282 return SENSOR_ERROR_WRITE;
283 }
284
285 /* Appy the Sensor Configuration based on the Register List */
286 status = Sensor_I2C_Write(pSensorHandle->pCommDrv, &pSensorHandle->deviceInfo, pSensorHandle->slaveAddress,
287 pRegWriteList);
288 if (ARM_DRIVER_OK != status)
289 {
290 return SENSOR_ERROR_WRITE;
291 }
292
293 /* Put the device into active mode and ready for reading data.*/
294 status = Register_I2C_Write(pSensorHandle->pCommDrv, &pSensorHandle->deviceInfo, pSensorHandle->slaveAddress,
295 FXOS8700_CTRL_REG1, FXOS8700_CTRL_REG1_ACTIVE_ACTIVE_MODE,
296 FXOS8700_CTRL_REG1_ACTIVE_MASK, false);
297 if (ARM_DRIVER_OK != status)
298 {
299 return SENSOR_ERROR_WRITE;
300 }
301
302 return SENSOR_ERROR_NONE;
303 }
304
FXOS8700_I2C_ReadData(fxos8700_i2c_sensorhandle_t * pSensorHandle,const registerreadlist_t * pReadList,uint8_t * pBuffer)305 int32_t FXOS8700_I2C_ReadData(fxos8700_i2c_sensorhandle_t *pSensorHandle,
306 const registerreadlist_t *pReadList,
307 uint8_t *pBuffer)
308 {
309 int32_t status;
310
311 /*! Validate for the correct handle and register read list.*/
312 if ((pSensorHandle == NULL) || (pReadList == NULL) || (pBuffer == NULL))
313 {
314 return SENSOR_ERROR_INVALID_PARAM;
315 }
316
317 /*! Check whether sensor handle is initialized before reading sensor data.*/
318 if (pSensorHandle->isInitialized != true)
319 {
320 return SENSOR_ERROR_INIT;
321 }
322
323 /*! Parse through the read list and read the data one by one*/
324 status = Sensor_I2C_Read(pSensorHandle->pCommDrv, &pSensorHandle->deviceInfo, pSensorHandle->slaveAddress,
325 pReadList, pBuffer);
326 if (ARM_DRIVER_OK != status)
327 {
328 return SENSOR_ERROR_READ;
329 }
330
331 return SENSOR_ERROR_NONE;
332 }
333
FXOS8700_I2C_Deinit(fxos8700_i2c_sensorhandle_t * pSensorHandle)334 int32_t FXOS8700_I2C_Deinit(fxos8700_i2c_sensorhandle_t *pSensorHandle)
335 {
336 if (pSensorHandle == NULL)
337 {
338 return SENSOR_ERROR_INVALID_PARAM;
339 }
340
341 /*! Check whether sensor handle is initialized before triggering sensor reset.*/
342 if (pSensorHandle->isInitialized != true)
343 {
344 return SENSOR_ERROR_INIT;
345 }
346
347 /*! Trigger sensor device reset.*/
348 Register_I2C_Write(pSensorHandle->pCommDrv, &pSensorHandle->deviceInfo, pSensorHandle->slaveAddress,
349 FXOS8700_CTRL_REG2, FXOS8700_CTRL_REG2_RST_EN, FXOS8700_CTRL_REG2_RST_MASK, false);
350 pSensorHandle->isInitialized = false;
351 return SENSOR_ERROR_NONE;
352 }
353