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 diff_p_drv.c
11 * @brief The diff_p_drv.c file implements the diff_p functional interface.
12 */
13
14 //-----------------------------------------------------------------------
15 // ISSDK Includes
16 //-----------------------------------------------------------------------
17 #include "gpio_driver.h"
18 #include "diff_p_drv.h"
19 #include "systick_utils.h"
20
21 //-----------------------------------------------------------------------
22 // Global Variables
23 //-----------------------------------------------------------------------
24 uint8_t diff_p_spiRead_CmdBuffer[DIFF_P_SPI_MAX_MSG_SIZE] = {0};
25 uint8_t diff_p_spiRead_DataBuffer[DIFF_P_SPI_MAX_MSG_SIZE] = {0};
26 uint8_t diff_p_spiWrite_CmdDataBuffer[DIFF_P_SPI_MAX_MSG_SIZE] = {0};
27
28 //-----------------------------------------------------------------------
29 // Functions
30 //-----------------------------------------------------------------------
DIFF_P_SPI_ReadPreprocess(void * pCmdOut,uint32_t offset,uint32_t size)31 void DIFF_P_SPI_ReadPreprocess(void *pCmdOut, uint32_t offset, uint32_t size)
32 {
33 spiCmdParams_t *pSlaveCmd = pCmdOut;
34
35 uint8_t *pWBuff = diff_p_spiRead_CmdBuffer;
36 uint8_t *pRBuff = diff_p_spiRead_DataBuffer;
37
38 /* Formatting for Read command of DIFF-P SENSOR. */
39 *pWBuff = offset & 0x7F; /* offset is the internal register address of the sensor at which write is performed. */
40
41 // Create the slave read command.
42 pSlaveCmd->size = size + DIFF_P_SPI_CMD_LEN;
43 pSlaveCmd->pWriteBuffer = pWBuff;
44 pSlaveCmd->pReadBuffer = pRBuff;
45 }
46
DIFF_P_SPI_WritePreprocess(void * pCmdOut,uint32_t offset,uint32_t size,void * pWritebuffer)47 void DIFF_P_SPI_WritePreprocess(void *pCmdOut, uint32_t offset, uint32_t size, void *pWritebuffer)
48 {
49 spiCmdParams_t *pSlaveCmd = pCmdOut;
50
51 uint8_t *pWBuff = diff_p_spiWrite_CmdDataBuffer;
52 uint8_t *pRBuff = diff_p_spiWrite_CmdDataBuffer + size + DIFF_P_SPI_CMD_LEN;
53
54 /* Formatting for Write command of DIFF-P SENSOR. */
55 *pWBuff = offset | 0x80; /* offset is the internal register address of the sensor at which write is performed. */
56
57 /* Copy the slave write command */
58 memcpy(pWBuff + DIFF_P_SPI_CMD_LEN, pWritebuffer, size);
59
60 /* Create the slave command. */
61 pSlaveCmd->size = size + DIFF_P_SPI_CMD_LEN;
62 pSlaveCmd->pWriteBuffer = pWBuff;
63 pSlaveCmd->pReadBuffer = pRBuff;
64 }
65
DIFF_P_SPI_Initialize(diff_p_spi_sensorhandle_t * pSensorHandle,ARM_DRIVER_SPI * pBus,uint8_t index,void * pSlaveSelect,uint8_t whoAmi)66 int32_t DIFF_P_SPI_Initialize(
67 diff_p_spi_sensorhandle_t *pSensorHandle, ARM_DRIVER_SPI *pBus, uint8_t index, void *pSlaveSelect, uint8_t whoAmi)
68 {
69 int32_t status;
70 uint8_t reg, retries = 1;
71 GENERIC_DRIVER_GPIO *pGPIODriver = &Driver_GPIO_KSDK;
72
73 /*! Check the input parameters. */
74 if ((pSensorHandle == NULL) || (pBus == NULL) || (pSlaveSelect == NULL))
75 {
76 return SENSOR_ERROR_INVALID_PARAM;
77 }
78
79 /*! Initialize the sensor handle. */
80 pSensorHandle->pCommDrv = pBus;
81 pSensorHandle->slaveParams.pReadPreprocessFN = DIFF_P_SPI_ReadPreprocess;
82 pSensorHandle->slaveParams.pWritePreprocessFN = DIFF_P_SPI_WritePreprocess;
83 pSensorHandle->slaveParams.pTargetSlavePinID = pSlaveSelect;
84 pSensorHandle->slaveParams.spiCmdLen = DIFF_P_SPI_CMD_LEN;
85 pSensorHandle->slaveParams.ssActiveValue = DIFF_P_SS_ACTIVE_VALUE;
86
87 pSensorHandle->deviceInfo.deviceInstance = index;
88 pSensorHandle->deviceInfo.functionParam = NULL;
89 pSensorHandle->deviceInfo.idleFunction = NULL;
90
91 /* Initialize the Slave Select Pin. */
92 pGPIODriver->pin_init(pSlaveSelect, GPIO_DIRECTION_OUT, NULL, NULL, NULL);
93 if (pSensorHandle->slaveParams.ssActiveValue == SPI_SS_ACTIVE_LOW)
94 {
95 pGPIODriver->set_pin(pSlaveSelect);
96 }
97 else
98 {
99 pGPIODriver->clr_pin(pSlaveSelect);
100 }
101
102 /*! Read and store the device's WHO_AM_I.*/
103 status = Register_SPI_Read(pSensorHandle->pCommDrv, &pSensorHandle->deviceInfo, &pSensorHandle->slaveParams,
104 DIFF_P_WHO_AM_I, 1, ®);
105 if ((ARM_DRIVER_OK != status) || (whoAmi != reg))
106 {
107 pSensorHandle->isInitialized = false;
108 return SENSOR_ERROR_INIT;
109 }
110
111 pSensorHandle->isInitialized = true;
112
113 do
114 { /*! Put the device into standby mode so that we can run calibration can be done. */
115 status = Register_SPI_Write(pSensorHandle->pCommDrv, &pSensorHandle->deviceInfo, &pSensorHandle->slaveParams,
116 DIFF_P_CTRL_REG1, DIFF_P_CTRL_REG1_SBYB_STANDBY, DIFF_P_CTRL_REG1_SBYB_MASK);
117 if (ARM_DRIVER_OK != status)
118 {
119 return SENSOR_ERROR_INIT;
120 }
121
122 /*! Run Calibration algorithm. */
123 status = Register_SPI_Write(pSensorHandle->pCommDrv, &pSensorHandle->deviceInfo, &pSensorHandle->slaveParams,
124 DIFF_P_CTRL_REG2, DIFF_P_CTRL_REG2_CTRL_AC_CALRUN, DIFF_P_CTRL_REG2_CTRL_AC_MASK);
125 if (ARM_DRIVER_OK != status)
126 {
127 return SENSOR_ERROR_INIT;
128 }
129 BOARD_DELAY_ms(1); /* Wait for calibration to finish... */
130 do
131 { /*! Wait for calibration to finish.*/
132 status = Register_SPI_Read(pSensorHandle->pCommDrv, &pSensorHandle->deviceInfo, &pSensorHandle->slaveParams,
133 DIFF_P_CTRL_REG2, 1, ®);
134 if (ARM_DRIVER_OK != status)
135 {
136 return SENSOR_ERROR_INIT;
137 }
138 } while (reg & DIFF_P_CTRL_REG2_CTRL_AC_MASK);
139
140 /* Check Calibration Result. */
141 status = Register_SPI_Read(pSensorHandle->pCommDrv, &pSensorHandle->deviceInfo, &pSensorHandle->slaveParams,
142 DIFF_P_STATUS, 1, ®);
143 if (ARM_DRIVER_OK != status)
144 {
145 return SENSOR_ERROR_INIT;
146 }
147 if ((reg & DIFF_P_STATUS_STAT_EP_MASK) == 0)
148 {
149 break;
150 }
151 BOARD_DELAY_ms(10); /* Wait and then retry calibration. */
152 } while (retries--);
153
154 return SENSOR_ERROR_NONE;
155 }
156
DIFF_P_SPI_SetIdleTask(diff_p_spi_sensorhandle_t * pSensorHandle,registeridlefunction_t idleTask,void * userParam)157 void DIFF_P_SPI_SetIdleTask(diff_p_spi_sensorhandle_t *pSensorHandle, registeridlefunction_t idleTask, void *userParam)
158 {
159 pSensorHandle->deviceInfo.functionParam = userParam;
160 pSensorHandle->deviceInfo.idleFunction = idleTask;
161 }
162
DIFF_P_SPI_Configure(diff_p_spi_sensorhandle_t * pSensorHandle,const registerwritelist_t * pRegWriteList)163 int32_t DIFF_P_SPI_Configure(diff_p_spi_sensorhandle_t *pSensorHandle, const registerwritelist_t *pRegWriteList)
164 {
165 int32_t status;
166
167 /*! Validate for the correct handle and register write list.*/
168 if ((pSensorHandle == NULL) || (pRegWriteList == NULL))
169 {
170 return SENSOR_ERROR_INVALID_PARAM;
171 }
172
173 /*! Check whether sensor handle is initialized before applying configuration.*/
174 if (pSensorHandle->isInitialized != true)
175 {
176 return SENSOR_ERROR_INIT;
177 }
178
179 /*! Put the device into standby mode so that configuration can be applied.*/
180 status = Register_SPI_Write(pSensorHandle->pCommDrv, &pSensorHandle->deviceInfo, &pSensorHandle->slaveParams,
181 DIFF_P_CTRL_REG1, DIFF_P_CTRL_REG1_SBYB_STANDBY, DIFF_P_CTRL_REG1_SBYB_MASK);
182 if (ARM_DRIVER_OK != status)
183 {
184 return SENSOR_ERROR_WRITE;
185 }
186
187 /*! Apply the Sensor Configuration based on the Register Write List */
188 status = Sensor_SPI_Write(pSensorHandle->pCommDrv, &pSensorHandle->deviceInfo, &pSensorHandle->slaveParams,
189 pRegWriteList);
190 if (ARM_DRIVER_OK != status)
191 {
192 return SENSOR_ERROR_WRITE;
193 }
194
195 /*! Put the device into active mode and ready for reading data.*/
196 status = Register_SPI_Write(pSensorHandle->pCommDrv, &pSensorHandle->deviceInfo, &pSensorHandle->slaveParams,
197 DIFF_P_CTRL_REG1, DIFF_P_CTRL_REG1_SBYB_ACTIVE, DIFF_P_CTRL_REG1_SBYB_MASK);
198 if (ARM_DRIVER_OK != status)
199 {
200 return SENSOR_ERROR_WRITE;
201 }
202
203 return SENSOR_ERROR_NONE;
204 }
205
DIFF_P_SPI_ReadData(diff_p_spi_sensorhandle_t * pSensorHandle,const registerreadlist_t * pReadList,uint8_t * pBuffer)206 int32_t DIFF_P_SPI_ReadData(diff_p_spi_sensorhandle_t *pSensorHandle,
207 const registerreadlist_t *pReadList,
208 uint8_t *pBuffer)
209 {
210 int32_t status;
211
212 /*! Validate for the correct handle and register read list.*/
213 if ((pSensorHandle == NULL) || (pReadList == NULL) || (pBuffer == NULL))
214 {
215 return SENSOR_ERROR_INVALID_PARAM;
216 }
217
218 /*! Check whether sensor handle is initialized before reading sensor data.*/
219 if (pSensorHandle->isInitialized != true)
220 {
221 return SENSOR_ERROR_INIT;
222 }
223
224 /*! Parse through the read list and read the data one by one. */
225 status = Sensor_SPI_Read(pSensorHandle->pCommDrv, &pSensorHandle->deviceInfo, &pSensorHandle->slaveParams,
226 pReadList, pBuffer);
227 if (ARM_DRIVER_OK != status)
228 {
229 return SENSOR_ERROR_READ;
230 }
231
232 return SENSOR_ERROR_NONE;
233 }
234
DIFF_P_SPI_DeInit(diff_p_spi_sensorhandle_t * pSensorHandle)235 int32_t DIFF_P_SPI_DeInit(diff_p_spi_sensorhandle_t *pSensorHandle)
236 {
237 int32_t status;
238
239 if (pSensorHandle == NULL)
240 {
241 return SENSOR_ERROR_INVALID_PARAM;
242 }
243
244 /*! Check whether sensor handle is initialized before triggering sensor reset.*/
245 if (pSensorHandle->isInitialized != true)
246 {
247 return SENSOR_ERROR_INIT;
248 }
249
250 /*! Trigger sensor device reset.*/
251 status = Register_SPI_Write(pSensorHandle->pCommDrv, &pSensorHandle->deviceInfo, &pSensorHandle->slaveParams,
252 DIFF_P_CTRL_REG1, DIFF_P_CTRL_REG1_RST_RESET, DIFF_P_CTRL_REG1_RST_MASK);
253 if (ARM_DRIVER_OK != status)
254 {
255 return SENSOR_ERROR_WRITE;
256 }
257 else
258 {
259 /*! De-initialize sensor handle. */
260 pSensorHandle->isInitialized = false;
261 }
262
263 return SENSOR_ERROR_NONE;
264 }
265
DIFF_P_I2C_Initialize(diff_p_i2c_sensorhandle_t * pSensorHandle,ARM_DRIVER_I2C * pBus,uint8_t index,uint16_t sAddress,uint8_t whoAmi)266 int32_t DIFF_P_I2C_Initialize(
267 diff_p_i2c_sensorhandle_t *pSensorHandle, ARM_DRIVER_I2C *pBus, uint8_t index, uint16_t sAddress, uint8_t whoAmi)
268 {
269 int32_t status;
270 uint8_t reg, retries = 1;
271
272 /*! Check the input parameters. */
273 if ((pSensorHandle == NULL) || (pBus == NULL))
274 {
275 return SENSOR_ERROR_INVALID_PARAM;
276 }
277
278 pSensorHandle->deviceInfo.deviceInstance = index;
279 pSensorHandle->deviceInfo.functionParam = NULL;
280 pSensorHandle->deviceInfo.idleFunction = NULL;
281
282 /*! Read and store the device's WHO_AM_I.*/
283 status = Register_I2C_Read(pBus, &pSensorHandle->deviceInfo, sAddress, DIFF_P_WHO_AM_I, 1, ®);
284 if ((ARM_DRIVER_OK != status) || (whoAmi != reg))
285 {
286 pSensorHandle->isInitialized = false;
287 return SENSOR_ERROR_INIT;
288 }
289
290 /*! Initialize the sensor handle. */
291 pSensorHandle->pCommDrv = pBus;
292 pSensorHandle->slaveAddress = sAddress;
293 pSensorHandle->isInitialized = true;
294
295 do
296 { /*! Put the device into standby mode so that we can run calibration can be done. */
297 status = Register_I2C_Write(pSensorHandle->pCommDrv, &pSensorHandle->deviceInfo, pSensorHandle->slaveAddress,
298 DIFF_P_CTRL_REG1, DIFF_P_CTRL_REG1_SBYB_STANDBY, DIFF_P_CTRL_REG1_SBYB_MASK, false);
299 if (ARM_DRIVER_OK != status)
300 {
301 return SENSOR_ERROR_INIT;
302 }
303
304 /*! Run Calibration algorithm. */
305 status =
306 Register_I2C_Write(pSensorHandle->pCommDrv, &pSensorHandle->deviceInfo, pSensorHandle->slaveAddress,
307 DIFF_P_CTRL_REG2, DIFF_P_CTRL_REG2_CTRL_AC_CALRUN, DIFF_P_CTRL_REG2_CTRL_AC_MASK, false);
308 if (ARM_DRIVER_OK != status)
309 {
310 return SENSOR_ERROR_INIT;
311 }
312 BOARD_DELAY_ms(1); /* Wait for calibration to finish... */
313 do
314 { /*! Wait for calibration to finish.*/
315 status = Register_I2C_Read(pSensorHandle->pCommDrv, &pSensorHandle->deviceInfo, pSensorHandle->slaveAddress,
316 DIFF_P_CTRL_REG2, 1, ®);
317 if (ARM_DRIVER_OK != status)
318 {
319 return SENSOR_ERROR_INIT;
320 }
321 } while (reg & DIFF_P_CTRL_REG2_CTRL_AC_MASK);
322
323 /* Check Calibration Result. */
324 status = Register_I2C_Read(pSensorHandle->pCommDrv, &pSensorHandle->deviceInfo, pSensorHandle->slaveAddress,
325 DIFF_P_STATUS, 1, ®);
326 if (ARM_DRIVER_OK != status)
327 {
328 return SENSOR_ERROR_INIT;
329 }
330 if ((reg & DIFF_P_STATUS_STAT_EP_MASK) == 0)
331 {
332 break;
333 }
334 BOARD_DELAY_ms(10); /* Wait and then retry calibration. */
335 } while (retries--);
336
337 return SENSOR_ERROR_NONE;
338 }
339
DIFF_P_I2C_SetIdleTask(diff_p_i2c_sensorhandle_t * pSensorHandle,registeridlefunction_t idleTask,void * userParam)340 void DIFF_P_I2C_SetIdleTask(diff_p_i2c_sensorhandle_t *pSensorHandle, registeridlefunction_t idleTask, void *userParam)
341 {
342 pSensorHandle->deviceInfo.functionParam = userParam;
343 pSensorHandle->deviceInfo.idleFunction = idleTask;
344 }
345
DIFF_P_I2C_Configure(diff_p_i2c_sensorhandle_t * pSensorHandle,const registerwritelist_t * pRegWriteList)346 int32_t DIFF_P_I2C_Configure(diff_p_i2c_sensorhandle_t *pSensorHandle, const registerwritelist_t *pRegWriteList)
347 {
348 int32_t status;
349
350 /*! Validate for the correct handle and register write list.*/
351 if ((pSensorHandle == NULL) || (pRegWriteList == NULL))
352 {
353 return SENSOR_ERROR_INVALID_PARAM;
354 }
355
356 /*! Check whether sensor handle is initialized before applying configuration.*/
357 if (pSensorHandle->isInitialized != true)
358 {
359 return SENSOR_ERROR_INIT;
360 }
361
362 /*! Put the device into standby mode so that configuration can be applied.*/
363 status = Register_I2C_Write(pSensorHandle->pCommDrv, &pSensorHandle->deviceInfo, pSensorHandle->slaveAddress,
364 DIFF_P_CTRL_REG1, DIFF_P_CTRL_REG1_SBYB_STANDBY, DIFF_P_CTRL_REG1_SBYB_MASK, false);
365 if (ARM_DRIVER_OK != status)
366 {
367 return SENSOR_ERROR_WRITE;
368 }
369
370 /*! Apply the Sensor Configuration based on the Register Write List */
371 status = Sensor_I2C_Write(pSensorHandle->pCommDrv, &pSensorHandle->deviceInfo, pSensorHandle->slaveAddress,
372 pRegWriteList);
373 if (ARM_DRIVER_OK != status)
374 {
375 return SENSOR_ERROR_WRITE;
376 }
377
378 /*! Put the device into active mode and ready for reading data.*/
379 status = Register_I2C_Write(pSensorHandle->pCommDrv, &pSensorHandle->deviceInfo, pSensorHandle->slaveAddress,
380 DIFF_P_CTRL_REG1, DIFF_P_CTRL_REG1_SBYB_ACTIVE, DIFF_P_CTRL_REG1_SBYB_MASK, false);
381 if (ARM_DRIVER_OK != status)
382 {
383 return SENSOR_ERROR_WRITE;
384 }
385
386 return SENSOR_ERROR_NONE;
387 }
388
DIFF_P_I2C_ReadData(diff_p_i2c_sensorhandle_t * pSensorHandle,const registerreadlist_t * pReadList,uint8_t * pBuffer)389 int32_t DIFF_P_I2C_ReadData(diff_p_i2c_sensorhandle_t *pSensorHandle,
390 const registerreadlist_t *pReadList,
391 uint8_t *pBuffer)
392 {
393 int32_t status;
394
395 /*! Validate for the correct handle and register read list.*/
396 if ((pSensorHandle == NULL) || (pReadList == NULL) || (pBuffer == NULL))
397 {
398 return SENSOR_ERROR_INVALID_PARAM;
399 }
400
401 /*! Check whether sensor handle is initialized before reading sensor data.*/
402 if (pSensorHandle->isInitialized != true)
403 {
404 return SENSOR_ERROR_INIT;
405 }
406
407 /*! Parse through the read list and read the data one by one. */
408 status = Sensor_I2C_Read(pSensorHandle->pCommDrv, &pSensorHandle->deviceInfo, pSensorHandle->slaveAddress,
409 pReadList, pBuffer);
410 if (ARM_DRIVER_OK != status)
411 {
412 return SENSOR_ERROR_READ;
413 }
414
415 return SENSOR_ERROR_NONE;
416 }
417
DIFF_P_I2C_DeInit(diff_p_i2c_sensorhandle_t * pSensorHandle)418 int32_t DIFF_P_I2C_DeInit(diff_p_i2c_sensorhandle_t *pSensorHandle)
419 {
420 int32_t status;
421
422 if (pSensorHandle == NULL)
423 {
424 return SENSOR_ERROR_INVALID_PARAM;
425 }
426
427 /*! Check whether sensor handle is initialized before triggering sensor reset.*/
428 if (pSensorHandle->isInitialized != true)
429 {
430 return SENSOR_ERROR_INIT;
431 }
432
433 /*! Trigger sensor device reset.*/
434 status = Register_I2C_Write(pSensorHandle->pCommDrv, &pSensorHandle->deviceInfo, pSensorHandle->slaveAddress,
435 DIFF_P_CTRL_REG1, DIFF_P_CTRL_REG1_RST_RESET, DIFF_P_CTRL_REG1_RST_MASK, false);
436 if (ARM_DRIVER_OK != status)
437 {
438 return SENSOR_ERROR_WRITE;
439 }
440 else
441 {
442 /*! De-initialize sensor handle. */
443 pSensorHandle->isInitialized = false;
444 }
445
446 return SENSOR_ERROR_NONE;
447 }
448