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, &reg);
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, &reg);
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