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, ®);
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