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