Set blackbox file handler to NULL after closing file
[inav.git] / src / main / drivers / compass / compass_ist8310.c
blobc7b5b0b1249f5925f62ff3da1a6707204818a745
1 /*
2 * This file is part of Cleanflight.
4 * Cleanflight is free software: you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation, either version 3 of the License, or
7 * (at your option) any later version.
9 * Cleanflight is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
14 * You should have received a copy of the GNU General Public License
15 * along with Cleanflight. If not, see <http://www.gnu.org/licenses/>.
18 #include <stdbool.h>
19 #include <stdint.h>
21 #include <math.h>
23 #include "platform.h"
25 #ifdef USE_MAG_IST8310
27 #include "build/debug.h"
29 #include "common/axis.h"
30 #include "common/maths.h"
32 #include "drivers/time.h"
33 #include "drivers/nvic.h"
34 #include "drivers/io.h"
35 #include "drivers/bus.h"
36 #include "drivers/light_led.h"
38 #include "drivers/sensor.h"
39 #include "drivers/compass/compass.h"
41 #include "drivers/compass/compass_ist8310.h"
43 #define IST8310_ADDRESS 0x0C
45 // Hardware descriptor
46 #if defined(MAG_I2C_BUS)
47 #endif
49 /* ist8310 Slave Address Select : default address 0x0C
50 * CAD1 | CAD0 | Address
51 * ------------------------------
52 * VSS | VSS | 0CH
53 * VSS | VDD | 0DH
54 * VDD | VSS | 0EH
55 * VDD | VDD | 0FH
56 * if CAD1 and CAD0 are floating, I2C address will be 0EH
59 * CTRL_REGA: Control Register 1
60 * Read Write
61 * Default value: 0x0A
62 * 7:4 0 Reserved.
63 * 3:0 DO2-DO0: Operating mode setting
64 * DO3 | DO2 | DO1 | DO0 | mode
65 * ------------------------------------------------------
66 * 0 | 0 | 0 | 0 | Stand-By mode
67 * 0 | 0 | 0 | 1 | Single measurement mode
68 * Others: Reserved
70 * CTRL_REGB: Control Register 2
71 * Read Write
72 * Default value: 0x0B
73 * 7:4 0 Reserved.
74 * 3 DREN : Data ready enable control:
75 * 0: disable
76 * 1: enable
77 * 2 DRP: DRDY pin polarity control
78 * 0: active low
79 * 1: active high
80 * 1 0 Reserved.
81 * 0 SRST: Soft reset, perform Power On Reset (POR) routine
82 * 0: no action
83 * 1: start immediately POR routine
84 * This bit will be set to zero after POR routine
87 #define IST8310_REG_DATA 0x03
88 #define IST8310_REG_WHOAMI 0x00
90 // I2C Contorl Register
91 #define IST8310_REG_CNTRL1 0x0A
92 #define IST8310_REG_CNTRL2 0x0B
93 #define IST8310_REG_AVERAGE 0x41
94 #define IST8310_REG_PDCNTL 0x42
96 // Parameter
97 // ODR = Output Data Rate, we use single measure mode for getting more data.
98 #define IST8310_ODR_SINGLE 0x01
99 #define IST8310_ODR_10_HZ 0x03
100 #define IST8310_ODR_20_HZ 0x05
101 #define IST8310_ODR_50_HZ 0x07
102 #define IST8310_ODR_100_HZ 0x06
104 // Device ID (ist8310 -> 0x10)
105 #define IST8310_CHIP_ID 0x10
106 #define IST8310_AVG_16 0x24
107 #define IST8310_PULSE_DURATION_NORMAL 0xC0
109 #define IST8310_CNTRL2_RESET 0x01
110 #define IST8310_CNTRL2_DRPOL 0x04
111 #define IST8310_CNTRL2_DRENA 0x08
113 static bool ist8310Init(magDev_t * mag)
115 busWrite(mag->busDev, IST8310_REG_CNTRL1, IST8310_ODR_50_HZ);
116 delay(5);
118 busWrite(mag->busDev, IST8310_REG_AVERAGE, IST8310_AVG_16);
119 delay(5);
121 busWrite(mag->busDev, IST8310_REG_PDCNTL, IST8310_PULSE_DURATION_NORMAL);
122 delay(5);
124 return true;
127 static bool ist8310Read(magDev_t * mag)
129 uint8_t buf[6];
130 uint8_t LSB2FSV = 3; // 3mG - 14 bit
132 // set magData to zero for case of failed read
133 mag->magADCRaw[X] = 0;
134 mag->magADCRaw[Y] = 0;
135 mag->magADCRaw[Z] = 0;
137 bool ack = busReadBuf(mag->busDev, IST8310_REG_DATA, buf, 6);
138 if (!ack) {
139 return false;
142 // Invert Y axis to co convert from left to right coordinate system
143 mag->magADCRaw[X] = (int16_t)(buf[1] << 8 | buf[0]) * LSB2FSV;
144 mag->magADCRaw[Y] = -(int16_t)(buf[3] << 8 | buf[2]) * LSB2FSV;
145 mag->magADCRaw[Z] = (int16_t)(buf[5] << 8 | buf[4]) * LSB2FSV;
147 return true;
150 #define DETECTION_MAX_RETRY_COUNT 5
151 static bool deviceDetect(magDev_t * mag)
153 for (int retryCount = 0; retryCount < DETECTION_MAX_RETRY_COUNT; retryCount++) {
154 delay(10);
156 uint8_t sig = 0;
157 bool ack = busRead(mag->busDev, IST8310_REG_WHOAMI, &sig);
159 if (ack && sig == IST8310_CHIP_ID) {
160 return true;
164 return false;
167 bool ist8310Detect(magDev_t * mag)
169 for (uint8_t index = 0; index < 2; ++index) {
170 mag->busDev = busDeviceInit(BUSTYPE_ANY, DEVHW_IST8310_0 + index, mag->magSensorToUse, OWNER_COMPASS);
171 if (mag->busDev == NULL) {
172 continue;
175 if (deviceDetect(mag)) {
176 mag->init = ist8310Init;
177 mag->read = ist8310Read;
178 return true;
179 } else {
180 busDeviceDeInit(mag->busDev);
184 return false;
187 #endif