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