rusEFI
The most advanced open source ECU
Loading...
Searching...
No Matches
accelerometer.cpp
Go to the documentation of this file.
1/*
2 * @file accelerometer.cpp
3 *
4 * stm32f4discovery has MEMS LIS302DL
5 * www.st.com/resource/en/datasheet/lis302dl.pdf
6 *
7 * SPI1
8 * LIS302DL_SPI_SCK PA5
9 * LIS302DL_SPI_MISO PA6
10 * LIS302DL_SPI_MOSI PA7
11 * LIS302DL_SPI_CS_PIN PE3
12 *
13 *
14 *
15 * @date May 19, 2016
16 * @author Andrey Belomutskiy, (c) 2012-2020
17 */
18
19#include "pch.h"
20
21#include "accelerometer.h"
22#include "hardware.h"
23
24#if EFI_ONBOARD_MEMS
25#include "mpu_util.h"
26#include "lis302dl.h"
28
29#if (EFI_ONBOARD_MEMS_LIS2DW12 == TRUE)
30#include "lis2dw12.h"
31#endif
32#if (EFI_ONBOARD_MEMS_LIS2DH12 == TRUE)
33#include "lsm303agr.h"
34#endif
35#if (EFI_ONBOARD_MEMS_LIS302DL == TRUE)
36#include "lis302dl.h"
37#endif
38#if (EFI_ONBOARD_MEMS_LIS3DSH == TRUE)
39#include "lis3dsh.h"
40#endif
41
42/*
43 * SPI1 configuration structure.
44 * Speed 5.25MHz, CPHA=1, CPOL=1, 8bits frames, MSb transmitted first.
45 */
46static SPIConfig accelerometerSpiCfg = {
47#if SPI_SUPPORTS_CIRCULAR == TRUE
48 .circular = false,
49#endif
50#ifdef _CHIBIOS_RT_CONF_VER_6_1_
51 .end_cb = NULL,
52#else
53 .slave = false,
54 .data_cb = NULL,
55 .error_cb = NULL,
56#endif
57 /* HW dependent part.*/
58 .ssport = NULL,
59 .sspad = 0,
60 .cr1 = SPI_CR1_BR_0 | SPI_CR1_BR_1 | SPI_CR1_CPOL | SPI_CR1_CPHA |
61 SPI_CR1_8BIT_MODE,
62 .cr2 = SPI_CR2_8BIT_MODE
63};
64
66
67#if (EFI_ONBOARD_MEMS_LIS2DW12 == TRUE)
68
69static LIS2DW12Config lis2dw12cfg = {
70#if LIS2DW12_USE_SPI
71 .spip = NULL,
72 .spicfg = &accelerometerSpiCfg,
73#endif
74#ifdef LIS2DW12_USE_I2C
75 /* TODO: */
76#endif
77 .accsensitivity = NULL,
78 .accbias = NULL,
79 .accodr = LIS2DW12_ACC_ODR_25HZ,
80 .accoutputresolution = LIS2DW12_ACC_OR_HP,
81 .acclowpowermode = LIS2DW12_ACC_LP_MODE2,
82 .accbadwidthselect = LIS2DW12_ACC_BW_ODR4,
83 .accfullscale = LIS2DW12_ACC_FS_4G,
84};
85
86/* LIS302DL Driver: This object represent an LIS302DL instance */
87static LIS2DW12Driver LIS2DW12;
88
89#endif //EFI_ONBOARD_MEMS_LIS2DW12 == TRUE
90
91#if (EFI_ONBOARD_MEMS_LIS2DH12 == TRUE)
92
93static LSM303AGRConfig lis2dh12cfg = {
94#if LSM303AGR_USE_SPI
95 .spip = NULL,
96 .spicfg = &accelerometerSpiCfg,
97#endif
98 .accsensitivity = NULL,
99 .accbias = NULL,
100 .accfullscale = LSM303AGR_ACC_FS_4G,
101 .accodr = LSM303AGR_ACC_ODR_50Hz,
102#if LSM303AGR_USE_ADVANCED
103 .accmode = LSM303AGR_ACC_MODE_HRES,
104 .accblockdataupdate = LSM303AGR_ACC_BDU_CONT,
105 .accendianess = LSM303AGR_ACC_END_LITTLE,
106#endif
107 /* LIS2DW12 is Accelerometer only, ignore following */
108 .compsensitivity = NULL,
109 .compbias = NULL,
110 .compodr = LSM303AGR_COMP_ODR_50HZ,
111#if LSM303AGR_USE_ADVANCED
112 .compmode = LSM303AGR_COMP_MODE_NORM,
113 .complp = LSM303AGR_COMP_LPOW_EN
114#endif
115};
116
117/* LSM303AGR Driver: This object represent an LIS2DH12 instance */
118static LSM303AGRDriver LIS2DH12;
119
120#endif //EFI_ONBOARD_MEMS_LIS2DH12 == TRUE
121
122#if (EFI_ONBOARD_MEMS_LIS302DL == TRUE)
123static LIS302DLConfig lis302dlcfg ={
124#if LIS302DL_USE_SPI
125 .spip = NULL,
126 .spicfg = &accelerometerSpiCfg,
127#endif
128#if LIS302DL_USE_I2C
129 /* TODO: */
130#endif
131 .accsensitivity = NULL,
132 .accbias = NULL,
133 .accfullscale = LIS302DL_ACC_FS_8G,
134 .accodr = LIS302DL_ACC_ODR_100HZ,
135#if LIS302DL_USE_ADVANCED
136 .acchighpass = LIS302DL_ACC_HP_0,
137#endif
138};
139
140static LIS302DLDriver LIS302DL;
141
142#endif //EFI_ONBOARD_MEMS_LIS302DL == TRUE
143
144#if (EFI_ONBOARD_MEMS_LIS3DSH == TRUE)
145
146static LIS3DSHConfig lis3dshcfg ={
147#if LIS3DSH_USE_SPI
148 .spip = NULL,
149 .spicfg = &accelerometerSpiCfg,
150#endif
151 .accsensitivity = NULL,
152 .accbias = NULL,
153 .accfullscale = LIS3DSH_ACC_FS_4G,
154 .accodr = LIS3DSH_ACC_ODR_50HZ,
155#if LIS3DSH_USE_ADVANCED
156 .accantialiasing = LIS3DSH_ACC_BW_50HZ,
157 .accblockdataupdate = LIS3DSH_ACC_BDU_CONTINUOUS,
158#endif
159};
160
161static LIS3DSHDriver LIS3DSH;
162
163#endif //EFI_ONBOARD_MEMS_LIS3DSH == TRUE
164
168 ACCEL_LIS2DH12, // Same as LSM303
169 ACCEL_LIS302DL, // STM32F4DISCOVERY (old?)
170 ACCEL_LIS3DSH, // STM32F4DISCOVERY
171};
172
174
175class AccelController : public PeriodicController<UTILITY_THREAD_STACK_SIZE> {
176public:
177 AccelController() : PeriodicController("Acc SPI") { }
178private:
179 void PeriodicTask(efitick_t nowNt) override {
180 UNUSED(nowNt);
181
182 msg_t ret = MSG_RESET;
183 float acccooked[3];
184
185 #if (EFI_ONBOARD_MEMS_LIS2DW12 == TRUE)
186 if (AccelType == ACCEL_LIS2DW12) {
187 ret = lis2dw12AccelerometerReadCooked(&LIS2DW12, acccooked);
188 }
189 #endif
190 #if (EFI_ONBOARD_MEMS_LIS2DH12 == TRUE)
191 if (AccelType == ACCEL_LIS2DH12) {
192 ret = lsm303agrAccelerometerReadCooked(&LIS2DH12, acccooked);
193 }
194 #endif
195 #if (EFI_ONBOARD_MEMS_LIS302DL == TRUE)
196 if (AccelType == ACCEL_LIS302DL) {
197 ret = lis302dlAccelerometerReadCooked(&LIS302DL, acccooked);
198 }
199 #endif
200 #if (EFI_ONBOARD_MEMS_LIS3DSH == TRUE)
201 if (AccelType == ACCEL_LIS3DSH) {
202 ret = lis3dshAccelerometerReadCooked(&LIS3DSH, acccooked);
203 }
204 #endif
205
206 if ((engineConfiguration->useSpiImu) && (ret == MSG_OK)) {
207 /* milli-G to G */
208 engine->sensors.accelerometer.lat = acccooked[0] / 1000.0;
209 engine->sensors.accelerometer.lon = acccooked[1] / 1000.0;
210 engine->sensors.accelerometer.vert = acccooked[2] / 1000.0;
211 }
212 }
213};
214
215static AccelController instance;
216
218#if HAL_USE_SPI
219 static SPIDriver *bus;
220 msg_t ret = MSG_RESET;
221
223 return; // not used
224
226 if (bus == nullptr) {
227 // error already reported
228 return;
229 }
230
231 /* so far only Hellen boards share SPI device for SD card and accelerometer
232 * thus need to make sure CS pin is in a well known proper state */
235 }
238
239 /* Try to detect any of enabled accels */
240 /* Hope all device drivers know how to detect correct chip */
241#if (EFI_ONBOARD_MEMS_LIS2DW12 == TRUE)
242 if (ret != MSG_OK) {
243 lis2dw12cfg.spip = bus;
244
245 /* LIS2DW12 Object Initialization.*/
246 lis2dw12ObjectInit(&LIS2DW12);
247
248 /* Activates the LIS2DW12 driver.*/
249 ret = lis2dw12Start(&LIS2DW12, &lis2dw12cfg);
250 if (ret == MSG_OK) {
252 }
253 }
254#endif //EFI_ONBOARD_MEMS_LIS2DW12 == TRUE
255#if (EFI_ONBOARD_MEMS_LIS2DH12 == TRUE)
256 if (ret != MSG_OK) {
257 lis2dh12cfg.spip = bus;
258
259 /* LIS2DH12 Object Initialization.*/
260 lsm303agrObjectInit(&LIS2DH12);
261
262 /* Activates the LIS2DH12 driver.*/
263 ret = lsm303agrStart(&LIS2DH12, &lis2dh12cfg);
264 if (ret == MSG_OK) {
266 }
267 }
268#endif //EFI_ONBOARD_MEMS_LIS2DH12 == TRUE
269#if (EFI_ONBOARD_MEMS_LIS302DL == TRUE)
270 if (ret != MSG_OK) {
271 lis302dlcfg.spip = bus;
272
273 /* LIS302DL Object Initialization.*/
274 lis302dlObjectInit(&LIS302DL);
275
276 /* Activates the LIS302DL driver.*/
277 ret = lis302dlStart(&LIS302DL, &lis302dlcfg);
278 if (ret == MSG_OK) {
280 }
281 }
282#endif //EFI_ONBOARD_MEMS_LIS302DL == TRUE
283#if (EFI_ONBOARD_MEMS_LIS3DSH == TRUE)
284 if (ret != MSG_OK) {
285 lis3dshcfg.spip = bus;
286
287 /* LIS3DSH Object Initialization.*/
288 lis3dshObjectInit(&LIS3DSH);
289
290 /* Activates the LIS3DSH driver.*/
291 ret = lis3dshStart(&LIS3DSH, &lis3dshcfg);
292 if (ret == MSG_OK) {
294 }
295 }
296#endif //EFI_ONBOARD_MEMS_LIS3DSH == TRUE
297
298 if (ret == MSG_OK) {
299 /* 50 Hz */
300 instance.setPeriod(20 /*ms*/);
301 instance.start();
302 efiPrintf("accelerometer init OK");
303 } else {
304 efiPrintf("accelerometer init failed %d", (int)ret);
305 }
306#endif /* HAL_USE_SPI */
307}
308
309#endif /* EFI_ONBOARD_MEMS */
AccelType_t
@ ACCEL_LIS2DH12
@ ACCEL_UNK
@ ACCEL_LIS3DSH
@ ACCEL_LIS302DL
@ ACCEL_LIS2DW12
static LIS2DW12Driver LIS2DW12
void initAccelerometer()
static LIS3DSHConfig lis3dshcfg
OutputPin accelerometerChipSelect
static LIS2DW12Config lis2dw12cfg
static AccelController instance
static LIS3DSHDriver LIS3DSH
static LIS302DLDriver LIS302DL
static SPIConfig accelerometerSpiCfg
static LSM303AGRDriver LIS2DH12
static AccelType_t AccelType
static LIS302DLConfig lis302dlcfg
static LSM303AGRConfig lis2dh12cfg
SensorsState sensors
Definition engine.h:353
Single output pin reference and state.
Definition efi_output.h:49
void initPin(const char *msg, brain_pin_e brainPin, pin_output_mode_e outputMode, bool forceInitWithFatalError=false)
Definition efi_gpio.cpp:711
bool isInitialized() const
Definition efi_gpio.cpp:559
Base class for a controller that needs to run periodically to perform work.
virtual void PeriodicTask(efitick_t nowNt)=0
Called periodically. Override this method to do work for your controller.
ioportid_t getHwPort(const char *msg, brain_pin_e brainPin)
ioportmask_t getHwPin(const char *msg, brain_pin_e brainPin)
static EngineAccessor engine
Definition engine.h:413
static constexpr engine_configuration_s * engineConfiguration
SPIDriver * getSpiDevice(spi_device_e spiDevice)
Definition hardware.cpp:149
UNUSED(samplingTimeSeconds)
bool isBrainPinValid(brain_pin_e brainPin)
Accelerometer accelerometer