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  mag3110_drv.c
11  * @brief The mag3110_drv.c file implements the MAG3110 sensor driver interfaces.
12  */
13 
14 //-----------------------------------------------------------------------
15 // ISSDK Includes
16 //-----------------------------------------------------------------------
17 #include "mag3110_drv.h"
18 
19 //-----------------------------------------------------------------------
20 // Functions
21 //-----------------------------------------------------------------------
MAG3110_I2C_Initialize(mag3110_i2c_sensorhandle_t * pSensorHandle,ARM_DRIVER_I2C * pBus,uint8_t index,uint16_t sAddress,uint8_t whoAmi)22 int32_t MAG3110_I2C_Initialize(
23     mag3110_i2c_sensorhandle_t *pSensorHandle, ARM_DRIVER_I2C *pBus, uint8_t index, uint16_t sAddress, uint8_t whoAmi)
24 {
25     int32_t status;
26     uint8_t reg;
27 
28     /*! Check the input parameters. */
29     if ((pSensorHandle == NULL) || (pBus == NULL))
30     {
31         return SENSOR_ERROR_INVALID_PARAM;
32     }
33 
34     pSensorHandle->deviceInfo.deviceInstance = index;
35     pSensorHandle->deviceInfo.functionParam = NULL;
36     pSensorHandle->deviceInfo.idleFunction = NULL;
37 
38     /*!  Read and store the device's WHO_AM_I.*/
39     status = Register_I2C_Read(pBus, &pSensorHandle->deviceInfo, sAddress, MAG3110_WHO_AM_I, 1, &reg);
40     if ((ARM_DRIVER_OK != status) || (whoAmi != reg))
41     {
42         pSensorHandle->isInitialized = false;
43         return SENSOR_ERROR_INIT;
44     }
45 
46     /*! Initialize the sensor handle. */
47     pSensorHandle->pCommDrv = pBus;
48     pSensorHandle->slaveAddress = sAddress;
49     pSensorHandle->isInitialized = true;
50     return SENSOR_ERROR_NONE;
51 }
52 
MAG3110_I2C_SetIdleTask(mag3110_i2c_sensorhandle_t * pSensorHandle,registeridlefunction_t idleTask,void * userParam)53 void MAG3110_I2C_SetIdleTask(mag3110_i2c_sensorhandle_t *pSensorHandle,
54                              registeridlefunction_t idleTask,
55                              void *userParam)
56 {
57     pSensorHandle->deviceInfo.functionParam = userParam;
58     pSensorHandle->deviceInfo.idleFunction = idleTask;
59 }
60 
MAG3110_I2C_Configure(mag3110_i2c_sensorhandle_t * pSensorHandle,const registerwritelist_t * pRegWriteList)61 int32_t MAG3110_I2C_Configure(mag3110_i2c_sensorhandle_t *pSensorHandle, const registerwritelist_t *pRegWriteList)
62 {
63     int32_t status;
64 
65     /*! Validate for the correct handle and register write list.*/
66     if ((pSensorHandle == NULL) || (pRegWriteList == NULL))
67     {
68         return SENSOR_ERROR_INVALID_PARAM;
69     }
70 
71     /*! Check whether sensor handle is initialized before applying configuration.*/
72     if (pSensorHandle->isInitialized != true)
73     {
74         return SENSOR_ERROR_INIT;
75     }
76 
77     /*! Put the device into standby mode so that configuration can be applied.*/
78     status = Register_I2C_Write(pSensorHandle->pCommDrv, &pSensorHandle->deviceInfo, pSensorHandle->slaveAddress,
79                                 MAG3110_CTRL_REG1, MAG3110_CTRL_REG1_AC_STANDBY, MAG3110_CTRL_REG1_AC_MASK, false);
80     if (ARM_DRIVER_OK != status)
81     {
82         return SENSOR_ERROR_WRITE;
83     }
84 
85     /*! Apply the Sensor Configuration based on the Register Write List */
86     status = Sensor_I2C_Write(pSensorHandle->pCommDrv, &pSensorHandle->deviceInfo, pSensorHandle->slaveAddress,
87                               pRegWriteList);
88     if (ARM_DRIVER_OK != status)
89     {
90         return SENSOR_ERROR_WRITE;
91     }
92 
93     /*! Put the device into active mode and ready for reading data.*/
94     status = Register_I2C_Write(pSensorHandle->pCommDrv, &pSensorHandle->deviceInfo, pSensorHandle->slaveAddress,
95                                 MAG3110_CTRL_REG1, MAG3110_CTRL_REG1_AC_ACTIVE, MAG3110_CTRL_REG1_AC_MASK, false);
96     if (ARM_DRIVER_OK != status)
97     {
98         return SENSOR_ERROR_WRITE;
99     }
100 
101     return SENSOR_ERROR_NONE;
102 }
103 
MAG3110_I2C_ReadData(mag3110_i2c_sensorhandle_t * pSensorHandle,const registerreadlist_t * pReadList,uint8_t * pBuffer)104 int32_t MAG3110_I2C_ReadData(mag3110_i2c_sensorhandle_t *pSensorHandle,
105                              const registerreadlist_t *pReadList,
106                              uint8_t *pBuffer)
107 {
108     int32_t status;
109 
110     /*! Validate for the correct handle and register read list.*/
111     if ((pSensorHandle == NULL) || (pReadList == NULL) || (pBuffer == NULL))
112     {
113         return SENSOR_ERROR_INVALID_PARAM;
114     }
115 
116     /*! Check whether sensor handle is initialized before reading sensor data.*/
117     if (pSensorHandle->isInitialized != true)
118     {
119         return SENSOR_ERROR_INIT;
120     }
121 
122     /*! Parse through the read list and read the data one by one. */
123     status = Sensor_I2C_Read(pSensorHandle->pCommDrv, &pSensorHandle->deviceInfo, pSensorHandle->slaveAddress,
124                              pReadList, pBuffer);
125     if (ARM_DRIVER_OK != status)
126     {
127         return SENSOR_ERROR_READ;
128     }
129 
130     return SENSOR_ERROR_NONE;
131 }
132 
MAG3110_I2C_DeInit(mag3110_i2c_sensorhandle_t * pSensorHandle)133 int32_t MAG3110_I2C_DeInit(mag3110_i2c_sensorhandle_t *pSensorHandle)
134 {
135     int32_t status;
136 
137     if (pSensorHandle == NULL)
138     {
139         return SENSOR_ERROR_INVALID_PARAM;
140     }
141 
142     /*! Check whether sensor handle is initialized before triggering sensor reset.*/
143     if (pSensorHandle->isInitialized != true)
144     {
145         return SENSOR_ERROR_INIT;
146     }
147 
148     /*! Trigger sensor device reset.*/
149     status = Register_I2C_Write(pSensorHandle->pCommDrv, &pSensorHandle->deviceInfo, pSensorHandle->slaveAddress,
150                                 MAG3110_CTRL_REG2, MAG3110_CTRL_REG2_MAG_RST_EN, MAG3110_CTRL_REG2_MAG_RST_MASK, false);
151     if (ARM_DRIVER_OK != status)
152     {
153         return SENSOR_ERROR_WRITE;
154     }
155     else
156     {
157         /*! De-initialize sensor handle. */
158         pSensorHandle->isInitialized = false;
159     }
160 
161     return SENSOR_ERROR_NONE;
162 }
163 
MAG3110_CalibrateHardIronOffset(int16_t * xValue,int16_t * yValue,int16_t * zValue)164 void MAG3110_CalibrateHardIronOffset(int16_t* xValue, int16_t* yValue, int16_t* zValue)
165 {
166     static int16_t xOffsetMax = 0x8000, yOffsetMax = 0x8000, zOffsetMax = 0x8000,
167                    xOffsetMin = 0x7FFF, yOffsetMin = 0x7FFF, zOffsetMin = 0x7FFF;
168 
169     xOffsetMax = (*xValue > xOffsetMax)?(*xValue):(xOffsetMax);
170     xOffsetMin = (*xValue < xOffsetMin)?(*xValue):(xOffsetMin);
171 
172     yOffsetMax = (*yValue > yOffsetMax)?(*yValue):(yOffsetMax);
173     yOffsetMin = (*yValue < yOffsetMin)?(*yValue):(yOffsetMin);
174 
175     zOffsetMax = (*zValue > zOffsetMax)?(*zValue):(zOffsetMax);
176     zOffsetMin = (*zValue < zOffsetMin)?(*zValue):(zOffsetMin);
177 
178     *xValue -= (xOffsetMax+xOffsetMin)/2;
179     *yValue -= (yOffsetMax+yOffsetMin)/2;
180     *zValue -= (zOffsetMax+zOffsetMin)/2;
181 }
182