Da Vinci Firmware 1
Firmware for the DaVinci-M rocket avionics board.
Loading...
Searching...
No Matches
utilities.c
Go to the documentation of this file.
1
8#ifndef UTILITIES_H_
9#include "utilities.h"
10#endif
11
12extern SPI_HandleTypeDef hspi1;
13extern SPI_HandleTypeDef hspi2;
14extern SPI_HandleTypeDef hspi3;
15
16#ifdef DEBUG_EN
17
18extern UART_HandleTypeDef huart2;
19
20#include <string.h>
21
22HAL_StatusTypeDef COM_port_serial_print(const uint8_t* data) {
23 return HAL_UART_Transmit(&huart2, data, strlen((const char *)data) + 1, 100);
24}
25#endif
26
27#include <math.h>
28
29static uint8_t bmp390_p_addr = 0;
30static uint8_t bmp390_B_addr = 0;
31
32
33int32_t imuP_write(void *handle, uint8_t reg_addr, const uint8_t *buf, uint16_t len) {
34
35 int32_t result = HAL_ERROR;
36
37 BMP390_CS_HIGH;
38 MAG_CS_HIGH;
39 IMU_CS_LOW;
40
41 if (HAL_SPI_Transmit(&hspi2, &reg_addr, 1, 100) == HAL_OK) {
42 if (HAL_SPI_Transmit(&hspi2, (uint8_t *)buf, len, 100) == HAL_OK) {
43 result = HAL_OK;
44 }
45 }
46
47 IMU_CS_HIGH;
48
49 return result;
50}
51
52int32_t imuP_read(void *handle, uint8_t reg_addr, uint8_t *buf, uint16_t len) {
53
54 int32_t result = HAL_ERROR;
55
56 reg_addr |= 0x80;
57 BMP390_CS_HIGH;
58 MAG_CS_HIGH;
59 IMU_CS_LOW;
60
61 if (HAL_SPI_Transmit(&hspi2, &reg_addr, 1, 100) == HAL_OK) {
62 if (HAL_SPI_Receive(&hspi2, buf, len, 100) == HAL_OK) {
63 result = HAL_OK;
64 }
65 }
66
67 IMU_CS_HIGH;
68
69 return result;
70}
71int32_t imuP_read_2(void *handle, uint8_t reg_addr, uint8_t *buf, uint16_t len) {
72 int32_t result = HAL_ERROR;
73 uint8_t tx_buffer[len + 1]; // Buffer to send address + dummy bytes
74 uint8_t rx_buffer[len + 1]; // Buffer to receive dummy byte + actual data
75
76 reg_addr |= 0x80; // Correctly set the read bit
77 tx_buffer[0] = reg_addr; // First byte to transmit is the address
78
79 // Fill the rest of the transmit buffer with dummy bytes
80 for (int i = 1; i <= len; i++) {
81 tx_buffer[i] = 0xFF; // Dummy byte (value doesn't usually matter)
82 }
83 if(HAL_GPIO_ReadPin(BARO_CS_GPIO_Port,BARO_CS_Pin)!=GPIO_PIN_SET){BMP390_CS_HIGH;}
84 if(HAL_GPIO_ReadPin(MAG_CS_GPIO_Port,MAG_CS_Pin)!=GPIO_PIN_SET){MAG_CS_HIGH;}
85
86 IMU_CS_LOW; // Lower CS
87
88 // Use TransmitReceive for simultaneous sending and receiving
89 if (HAL_SPI_TransmitReceive(&hspi2, tx_buffer, rx_buffer, len + 1, 100) == HAL_OK) {
90 // The actual data is in rx_buffer starting from the second byte
91 for (int i = 0; i < len; i++) {
92 buf[i] = rx_buffer[i + 1];
93 }
94 result = HAL_OK;
95 }
96
97 IMU_CS_HIGH; // Raise CS
98
99 return result;
100}
101
102
103int8_t bmp390_P_write(uint8_t reg_addr, const uint8_t *buf, uint32_t len, void *intf_ptr) {
104
105 int8_t result = HAL_ERROR;
106 if(HAL_GPIO_ReadPin(IMU_CS_GPIO_Port,IMU_CS_Pin)!=GPIO_PIN_SET){IMU_CS_HIGH;}
107 if(HAL_GPIO_ReadPin(MAG_CS_GPIO_Port,MAG_CS_Pin)!=GPIO_PIN_SET){MAG_CS_HIGH;}
108
109 if(HAL_GPIO_ReadPin(BARO_CS_GPIO_Port,BARO_CS_Pin)!=GPIO_PIN_RESET){BMP390_CS_LOW;}
110
111 if (HAL_SPI_Transmit(&hspi2, &reg_addr, 1, 100) == HAL_OK) {
112 if (HAL_SPI_Transmit(&hspi2, (uint8_t *)buf, len, 100) == HAL_OK) {
113 result = HAL_OK;
114 }
115 }
116
117 if(HAL_GPIO_ReadPin(BARO_CS_GPIO_Port,BARO_CS_Pin)!=GPIO_PIN_SET){BMP390_CS_HIGH;}
118
119 return result;
120}
121
122int8_t bmp390_P_read(uint8_t reg_addr, uint8_t *buf, uint32_t len, void *intf_ptr) {
123
124
125 int8_t result = HAL_ERROR;
126 uint8_t tx_buffer[len + 1]; // Buffer for address + dummy bytes
127 uint8_t rx_buffer[len + 1]; // Buffer for received dummy byte + data
128
129 reg_addr |= 0x80; // Crucial: Set the MSB for a read operation (check datasheet if different)
130 tx_buffer[0] = reg_addr;
131
132 // Fill the rest of the transmit buffer with dummy bytes
133 for (uint32_t i = 1; i <= len; i++) {
134 tx_buffer[i] = 0xFF; // Or any dummy value
135 }
136
137 // Ensure other sensors are deselected
138 if(HAL_GPIO_ReadPin(IMU_CS_GPIO_Port,IMU_CS_Pin)!=GPIO_PIN_SET){IMU_CS_HIGH;}
139 if(HAL_GPIO_ReadPin(MAG_CS_GPIO_Port,MAG_CS_Pin)!=GPIO_PIN_SET){MAG_CS_HIGH;}
140
141 if(HAL_GPIO_ReadPin(BARO_CS_GPIO_Port,BARO_CS_Pin)!=GPIO_PIN_RESET){BMP390_CS_LOW;}
142
143
144
145 if (HAL_SPI_TransmitReceive(&hspi2, tx_buffer, rx_buffer, len + 1, 100) == HAL_OK) {
146 // Data from the sensor starts at rx_buffer[1]
147 for (uint32_t i = 0; i < len; i++) {
148 buf[i] = rx_buffer[i + 1];
149 }
150 result = HAL_OK;
151 }
152
153
154
155 if(HAL_GPIO_ReadPin(BARO_CS_GPIO_Port,BARO_CS_Pin)!=GPIO_PIN_SET){BMP390_CS_HIGH;}
156
157
158
159 return result;
160}
161
162
163static void bmp390_delay_us(uint32_t period, void *intf_ptr) {
164 uint32_t i;
165
166 while (period--) {
167 for (i = 0; i < 96; i++) {
168 ;
169 }
170 }
171}
172
173static int8_t bmp3_P_spi_init(struct bmp3_dev *dev) {
174 int8_t result = BMP3_OK;
175
176 if (dev != NULL) {
177 bmp390_p_addr = 0;
178 dev -> read = bmp390_P_read;
179 dev -> write = bmp390_P_write;
180 dev -> intf = BMP3_SPI_INTF;
181
182 dev -> delay_us = bmp390_delay_us;
183 dev -> intf_ptr = &bmp390_p_addr;
184 } else {
185 result = -1;
186 }
187
188 return result;
189}
190
191
192
193int8_t init_imup(stmdev_ctx_t *imu, lsm6dso32_fs_xl_t acc_full_scale, lsm6dso32_fs_g_t gyro_full_scale, lsm6dso32_odr_xl_t acc_output_data_rate, lsm6dso32_odr_g_t gyro_output_data_rate) {
194
195
196
197 uint8_t who_am_i = 0;
198 uint8_t rst = 1;
199 uint8_t result = 1;
200
201 imu -> write_reg = imuP_write;
202 imu -> read_reg = imuP_read;
203 imu -> handle = &hspi2;
204
205 HAL_Delay(10); //FIXME here HAL_Delay used because this init is done during startup, so before kernel takes control of execution
206
207 lsm6dso32_device_id_get(imu, &who_am_i);
208
209
210 if (who_am_i != LSM6DSO32_ID) {
211 return HAL_ERROR;
212 }
213
214 /* Restore default configuration */
216
217 /* Wait until the imu does not exit reset status */
218 do {
219 lsm6dso32_reset_get(imu, &rst);
220 } while (rst);
221
222 if (result != 0) {
223 return HAL_ERROR;
224 }
225
226 /* Disable I3C interface */
228
229 if (result != 0) {
230 return HAL_ERROR;
231 }
232
233 /* Enable Block Data Update, this means that registers
234 * are not update until all the data have been read */
236
237 if (result != 0) {
238 return HAL_ERROR;
239 }
240
241 /* Set accelerometer and gyroscope full scale */
242 lsm6dso32_xl_full_scale_set(imu, acc_full_scale);
243 lsm6dso32_gy_full_scale_set(imu, gyro_full_scale);
244
245 /* Set accelerometer and gyroscope output data rate ODR */
246 lsm6dso32_xl_data_rate_set(imu, acc_output_data_rate);
247 lsm6dso32_gy_data_rate_set(imu, gyro_output_data_rate);
248
249 return HAL_OK;
250}
251
252int8_t init_bmp390_p(struct bmp3_dev *bmp390) {
253
254 int8_t result = HAL_ERROR;
255 uint8_t settings_sel = 0;
256 struct bmp3_settings settings = { 0 };
257
258 //IMU_CS_HIGH;
259 //MAG_CS_HIGH;
260
261 result = bmp3_P_spi_init(bmp390);
262
263 if (result != BMP3_OK)
264 return HAL_ERROR;
265 //BMP390_CS_LOW;
266 result = bmp3_init(bmp390);
267
268 //BMP390_CS_HIGH;
269
270 if (result != BMP3_OK)
271
272 return HAL_ERROR;
273
274 /* enabling both pressure and temperature reading */
275 settings.press_en = BMP3_ENABLE;
276 settings.temp_en = BMP3_ENABLE;
277
278 /* interrupt disabling */
280
281 /* pressure and temperature oversampling */
284
285 /* output data rate */
286 settings.odr_filter.odr = BMP3_ODR_200_HZ;
287
288 /* IIR filter disabling */
290
291 /* specifying all the settings we want to modify using the bmp3_settings struct */
292 settings_sel = BMP3_SEL_PRESS_EN | BMP3_SEL_TEMP_EN |
295
296 /* setting the previously specified settings */
297 result = bmp3_set_sensor_settings(settings_sel, &settings, bmp390);
298
299 if (result != BMP3_OK)
300 return HAL_ERROR;
301
302 /* setting the operating mode of the sensor */
303 settings.op_mode = BMP3_MODE_NORMAL;
304
305 result = bmp3_set_op_mode(&settings, bmp390);
306
307 if (result != BMP3_OK)
308 return HAL_ERROR;
309
310 return HAL_OK;
311}
312
313
314
315
316
317
318
319uint16_t compute_air_density(float_t temperature,float_t pressure){
320 uint16_t air_d;
321
322 air_d = (uint16_t) pressure/(temperature*SPECIFIC_GAS_CONSTANT);
323 return air_d;
324}
325
326//FIXME put the function in the correct file and place
327//int8_t calibrateBMP390(struct bmp3_dev *bmp390, uint16_t iterationNum) {
328//
329// struct bmp3_data temp = { -1, -1 };
330// int8_t result = BMP3_E_NULL_PTR;
331//
332// result = bmp3_get_sensor_data(BMP3_PRESS_TEMP, &temp, bmp390);
333//
334// if (result != BMP3_OK) {
335// return result;
336// }
337//
338// double mean_pressure = temp.pressure;
339// double mean_temperature = temp.temperature;
340//
341// for (int i = 0; i < iterationNum; i++) {
342// struct bmp3_data data = { -1, -1 };
343// struct bmp3_status status = { { 0 } };
344//
345// result = bmp3_get_status(&status, bmp390);
346//
347// if (result != BMP3_OK) return result;
348//
349// result = bmp3_get_sensor_data(BMP3_PRESS_TEMP, &data, bmp390);
350//
351// mean_pressure += data.pressure;
352// mean_pressure /= 2;
353//
354// mean_temperature += data.temperature;
355// mean_temperature /= 2;
356// }
357//
358// // add the code to add a possible software offset, if needed
359//
360// return 0;
361//}
362
363
364//TODO remember that when on the rocket the gravity acceleration will be along the X axis
365
366int8_t calibrateIMU(stmdev_ctx_t *imu, uint16_t iterationNum, OFFSET_TYPE type) {
367
368 float_t mean_acceleration_mg[3] = {0};
369 float_t mean_angular_rate_mdps[3] = {0};
370 float_t mean_temperature_degC = 0.0;
371 float_t acceleration_mg[3] = {0};
372 float_t angular_rate_mdps[3] = {0};
373 float_t temperature_degC = 0.0;
374 int16_t data_raw_acceleration[3] = {0};
375 int16_t data_raw_angular_rate[3] = {0};
376 int16_t data_raw_temperature = 0.0;
377
378 lsm6dso32_acceleration_raw_get(imu, data_raw_acceleration);
379 lsm6dso32_angular_rate_raw_get(imu, data_raw_angular_rate);
380 lsm6dso32_temperature_raw_get(imu, &data_raw_temperature);
381
382 acceleration_mg[0] = lsm6dso32_from_fs16_to_mg(data_raw_acceleration[0]);
383 acceleration_mg[1] = lsm6dso32_from_fs16_to_mg(data_raw_acceleration[1]);
384 acceleration_mg[2] = lsm6dso32_from_fs16_to_mg(data_raw_acceleration[2]);
385
386 angular_rate_mdps[0] = lsm6dso32_from_fs2000_to_mdps(data_raw_angular_rate[0]);
387 angular_rate_mdps[1] = lsm6dso32_from_fs2000_to_mdps(data_raw_angular_rate[1]);
388 angular_rate_mdps[2] = lsm6dso32_from_fs2000_to_mdps(data_raw_angular_rate[2]);
389
390 temperature_degC = lsm6dso32_from_lsb_to_celsius(data_raw_temperature);
391
392 mean_acceleration_mg[0] += acceleration_mg[0];
393 mean_acceleration_mg[1] += acceleration_mg[1];
394 mean_acceleration_mg[2] += acceleration_mg[2];
395
396 mean_angular_rate_mdps[0] += angular_rate_mdps[0];
397 mean_angular_rate_mdps[1] += angular_rate_mdps[1];
398 mean_angular_rate_mdps[2] += angular_rate_mdps[2];
399
400 mean_temperature_degC += temperature_degC;
401
402 for (int i = 0; i < iterationNum; i++) {
403 lsm6dso32_reg_t reg;
404 /* Read output only if new data is available */
406
407 if (reg.status_reg.xlda) {
408 /* Read acceleration data */
409 memset(data_raw_acceleration, 0x00, 3 * sizeof(int16_t));
410 lsm6dso32_acceleration_raw_get(imu, data_raw_acceleration);
411 acceleration_mg[0] = lsm6dso32_from_fs16_to_mg(data_raw_acceleration[0]);
412 acceleration_mg[1] = lsm6dso32_from_fs16_to_mg(data_raw_acceleration[1]);
413 acceleration_mg[2] = lsm6dso32_from_fs16_to_mg(data_raw_acceleration[2]);
414 mean_acceleration_mg[0] += acceleration_mg[0];
415 mean_acceleration_mg[0] /= 2;
416 mean_acceleration_mg[1] += acceleration_mg[1];
417 mean_acceleration_mg[1] /= 2;
418 mean_acceleration_mg[2] += acceleration_mg[2];
419 mean_acceleration_mg[2] /= 2;
420 }
421
422 if (reg.status_reg.gda) {
423 /* Read angular rate field data */
424 memset(data_raw_angular_rate, 0x00, 3 * sizeof(int16_t));
425 lsm6dso32_angular_rate_raw_get(imu, data_raw_angular_rate);
426 angular_rate_mdps[0] = lsm6dso32_from_fs2000_to_mdps(data_raw_angular_rate[0]);
427 angular_rate_mdps[1] = lsm6dso32_from_fs2000_to_mdps(data_raw_angular_rate[1]);
428 angular_rate_mdps[2] = lsm6dso32_from_fs2000_to_mdps(data_raw_angular_rate[2]);
429 mean_angular_rate_mdps[0] += angular_rate_mdps[0];
430 mean_angular_rate_mdps[0] /= 2;
431 mean_angular_rate_mdps[1] += angular_rate_mdps[1];
432 mean_angular_rate_mdps[1] /= 2;
433 mean_angular_rate_mdps[2] += angular_rate_mdps[2];
434 mean_angular_rate_mdps[2] /= 2;
435 }
436
437 if (reg.status_reg.tda) {
438 /* Read temperature data */
439 memset(&data_raw_temperature, 0x00, sizeof(int16_t));
440 lsm6dso32_temperature_raw_get(imu, &data_raw_temperature);
441 temperature_degC = lsm6dso32_from_lsb_to_celsius(data_raw_temperature);
442 mean_temperature_degC += temperature_degC;
443 mean_temperature_degC /= 2;
444 }
445 }
446
447 switch(type) {
448// case SWOFFSET:
449// /* FIXME handle a possible sw offset type, store offset values somewhere and use
450// * them to calibrate measurements. */
451//
452// acceleration_mg_swoffset[0] = mean_acceleration_mg[0];
453// acceleration_mg_swoffset[1] = mean_acceleration_mg[1];
454// acceleration_mg_swoffset[2] = mean_acceleration_mg[2];
455//
456// angular_rate_mdps_swoffset[0] = mean_angular_rate_mdps[0];
457// angular_rate_mdps_swoffset[1] = mean_angular_rate_mdps[1];
458// angular_rate_mdps_swoffset[2] = mean_angular_rate_mdps[2];
459//
460// break;
461 case HWOFFSET:
462
463 // add code to set a possible hardware offset in the IMU, if needed
464
465 /*
466 LSM6DSO32_X_OFS_USR
467 LSM6DSO32_Y_OFS_USR
468 LSM6DSO32_Z_OFS_USR
469
470 are the registers used to set an hardware offset to accelerometer measurements
471
472 To enable offset USR_OFF_ON_OUT bit of the CTRL7_G register must be set.
473
474 The value of the offset is expressed on 8 bits 2's complement.
475
476 The weight [g/LSB] to be applied to the offset register values is independent
477 of the accelerometer selected full scale
478 and can be configured using the USR_OFF_W bit of the CTRL6_C register:
479 • 2^-10 g/LSB if the USR_OFF_W bit is set to 0
480 • 2^-6 g/LSB if the USR_OFF_W bit is set to 1
481 */
482
483 /*
484 * 1. offset is computed using the finest weight
485 * 2. we check whether the offset can be represented on 8 bits 2's complement
486 * 3.1. If yes, the weight is set
487 * 3.2. Otherwise, the coarser weight is used and the offsets are recomputed
488 * 4. the value of the offset is stored in imu's registers
489 */
490
491 float mean_acceleration_x = mean_acceleration_mg[0] / 2;
492 float mean_acceleration_y = mean_acceleration_mg[1] / 2;
493 float mean_acceleration_z = mean_acceleration_mg[2] / 2;
494
495 float mean_acceleration = sqrtf(
496 mean_acceleration_mg[0]*mean_acceleration_mg[0] +
497 mean_acceleration_mg[1]*mean_acceleration_mg[1] +
498 mean_acceleration_mg[2]*mean_acceleration_mg[2]
499 );
500
501 float mean_acc_direction_x = mean_acceleration_x / mean_acceleration;
502 float mean_acc_direction_y = mean_acceleration_y / mean_acceleration;
503 float mean_acc_direction_z = mean_acceleration_z / mean_acceleration;
504
505 float gravity = 1000;
506
507 mean_acceleration_x -= mean_acc_direction_x*gravity;
508 mean_acceleration_y -= mean_acc_direction_y*gravity;
509 mean_acceleration_z -= mean_acc_direction_z*gravity;
510
511 int16_t offsetValX = (int16_t)mean_acceleration_x;
512 int16_t offsetValY = (int16_t)mean_acceleration_y;
513 int16_t offsetValZ = (int16_t)mean_acceleration_z;
514
515 if (offsetValX > -128 && offsetValX < 128 && offsetValY > -128 && offsetValY < 128
516 && offsetValZ > -128 && offsetValZ < 128) {
517
519 } else {
520 /* the right shift by 4 operation is done to perform the division by 16 */
522 offsetValX /= 16;
523 offsetValY /= 16;
524 offsetValZ /= 16;
525 }
526
527 // int32_t lsm6dso32_xl_offset_weight_get(stmdev_ctx_t *ctx, lsm6dso32_usr_off_w_t *val);
528 // int32_t lsm6dso32_xl_usr_offset_x_get(stmdev_ctx_t *ctx, uint8_t *buff);
529 // int32_t lsm6dso32_xl_usr_offset_y_get(stmdev_ctx_t *ctx, uint8_t *buff);
530 // int32_t lsm6dso32_xl_usr_offset_z_get(stmdev_ctx_t *ctx, uint8_t *buff);
531 // int32_t lsm6dso32_xl_usr_offset_get(stmdev_ctx_t *ctx, uint8_t *val);
532
533 lsm6dso32_xl_usr_offset_x_set(imu, (uint8_t *) &offsetValX);
534 lsm6dso32_xl_usr_offset_y_set(imu, (uint8_t *) &offsetValY);
535 lsm6dso32_xl_usr_offset_z_set(imu, (uint8_t *) &offsetValZ);
536
537 /* this function call enables the offset previously set */
539
540 break;
541
542 case RESET_HWOFFSET:
543
547
549
550 break;
551
552 default:
553
554 break;
555 }
556
557
558
559 return 0;
560}
561
562
563int32_t imuB_write(void *handle, uint8_t reg_addr, const uint8_t *buf, uint16_t len) {
564
565 int32_t result = HAL_ERROR;
566
567 BMP390_CS_HIGH;
568 MAG_CS_HIGH;
569 IMU_CS_LOW;
570
571 if (HAL_SPI_Transmit(&hspi3, &reg_addr, 1, 100) == HAL_OK) {
572 if (HAL_SPI_Transmit(&hspi3, (uint8_t *)buf, len, 100) == HAL_OK) {
573 result = HAL_OK;
574 }
575 }
576
577 IMU_CS_HIGH;
578
579 return result;
580}
581
582int32_t imuB_read(void *handle, uint8_t reg_addr, uint8_t *buf, uint16_t len) {
583
584 int32_t result = HAL_ERROR;
585
586 reg_addr |= 0x80;
587
588 BMP390_CS_HIGH;
589 MAG_CS_HIGH;
590 IMU_CS_LOW;
591
592 if (HAL_SPI_Transmit(&hspi3, &reg_addr, 1, 100) == HAL_OK) {
593 if (HAL_SPI_Receive(&hspi3, buf, len, 100) == HAL_OK) {
594 result = HAL_OK;
595 }
596 }
597
598 IMU_CS_HIGH;
599
600 return result;
601}
602
603int8_t bmp390_B_write(uint8_t reg_addr, const uint8_t *buf, uint32_t len, void *intf_ptr) {
604
605 int8_t result = HAL_ERROR;
606
607
608 if(HAL_GPIO_ReadPin(IMU_CS_GPIO_Port,IMU_CS_Pin)!=GPIO_PIN_SET){IMU_CS_HIGH;}
609 if(HAL_GPIO_ReadPin(MAG_CS_GPIO_Port,MAG_CS_Pin)!=GPIO_PIN_SET){MAG_CS_HIGH;}
610 BMP390_CS_LOW;
611
612 if (HAL_SPI_Transmit(&hspi3, &reg_addr, 1, 100) == HAL_OK) {
613 if (HAL_SPI_Transmit(&hspi3, (uint8_t *)buf, len, 100) == HAL_OK) {
614 result = HAL_OK;
615 }
616 }
617
618 BMP390_CS_HIGH;
619
620 return result;
621}
622
623int8_t bmp390_B_read(uint8_t reg_addr, uint8_t *buf, uint32_t len, void *intf_ptr) {
624
625 int8_t result = HAL_ERROR;
626
627 if(HAL_GPIO_ReadPin(IMU_CS_GPIO_Port,IMU_CS_Pin)!=GPIO_PIN_SET){IMU_CS_HIGH;}
628 if(HAL_GPIO_ReadPin(MAG_CS_GPIO_Port,MAG_CS_Pin)!=GPIO_PIN_SET){MAG_CS_HIGH;}
629 BMP390_CS_LOW;
630
631
632
633 if (HAL_SPI_Transmit(&hspi3, &reg_addr, 1, 100) == HAL_OK) {
634 if (HAL_SPI_Receive(&hspi3, buf, len, 100) == HAL_OK) {
635 result = HAL_OK;
636 }
637 }
638
639
640 BMP390_CS_HIGH;
641
642
643
644 return result;
645}
646
647static int8_t bmp3_B_spi_init(struct bmp3_dev *dev) {
648 int8_t result = BMP3_OK;
649
650 if (dev != NULL) {
651 bmp390_B_addr = 0;
652 dev -> read = bmp390_B_read;
653 dev -> write = bmp390_B_write;
654 dev -> intf = BMP3_SPI_INTF;
655
656 dev -> delay_us = bmp390_delay_us;
657 dev -> intf_ptr = &bmp390_B_addr;
658 } else {
659 result = -1;
660 }
661
662 return result;
663}
664
665int8_t init_imuB(stmdev_ctx_t *imu, lsm6dso32_fs_xl_t acc_full_scale, lsm6dso32_fs_g_t gyro_full_scale, lsm6dso32_odr_xl_t acc_output_data_rate, lsm6dso32_odr_g_t gyro_output_data_rate) {
666
667// int8_t result = HAL_ERROR;
668
669 uint8_t who_am_i = 0;
670 uint8_t rst = 1;
671 uint8_t result = 1;
672
673 imu -> write_reg = imuB_write;
674 imu -> read_reg = imuB_read;
675 imu -> handle = &hspi3;
676
677 HAL_Delay(10); //FIXME here HAL_Delay used because this init is done during startup, so before kernel takes control of execution
678
679 lsm6dso32_device_id_get(imu, &who_am_i);
680
681 if (who_am_i != LSM6DSO32_ID) {
682 return HAL_ERROR;
683 }
684
685 /* Restore default configuration */
687
688 /* Wait until the imu does not exit reset status */
689 do {
690 lsm6dso32_reset_get(imu, &rst);
691 } while (rst);
692
693 if (result != 0) {
694 return HAL_ERROR;
695 }
696
697 /* Disable I3C interface */
699
700 if (result != 0) {
701 return HAL_ERROR;
702 }
703
704 /* Enable Block Data Update, this means that registers
705 * are not update until all the data have been read */
707
708 if (result != 0) {
709 return HAL_ERROR;
710 }
711
712 /* Set accelerometer and gyroscope full scale */
713 lsm6dso32_xl_full_scale_set(imu, acc_full_scale);
714 lsm6dso32_gy_full_scale_set(imu, gyro_full_scale);
715
716 /* Set accelerometer and gyroscope output data rate ODR */
717 lsm6dso32_xl_data_rate_set(imu, acc_output_data_rate);
718 lsm6dso32_gy_data_rate_set(imu, gyro_output_data_rate);
719
720 return HAL_OK;
721}
722
723int8_t init_bmp390_B(struct bmp3_dev *bmp390) {
724
725 int8_t result = HAL_ERROR;
726 uint8_t settings_sel = 0;
727 struct bmp3_settings settings = { 0 };
728
729
730 result = bmp3_B_spi_init(bmp390);
731
732 if (result != BMP3_OK)
733 return HAL_ERROR;
734
735 result = bmp3_init(bmp390);
736
737 if (result != BMP3_OK)
738 return HAL_ERROR;
739
740 /* enabling both pressure and temperature reading */
741 settings.press_en = BMP3_ENABLE;
742 settings.temp_en = BMP3_ENABLE;
743
744 /* interrupt disabling */
746
747 /* pressure and temperature oversampling */
750
751 /* output data rate */
752 settings.odr_filter.odr = BMP3_ODR_200_HZ;
753
754 /* IIR filter disabling */
756
757 /* specifying all the settings we want to modify using the bmp3_settings struct */
758 settings_sel = BMP3_SEL_PRESS_EN | BMP3_SEL_TEMP_EN |
761
762 /* setting the previously specified settings */
763 result = bmp3_set_sensor_settings(settings_sel, &settings, bmp390);
764
765 if (result != BMP3_OK)
766 return HAL_ERROR;
767
768 /* setting the operating mode of the sensor */
769 settings.op_mode = BMP3_MODE_NORMAL;
770
771 result = bmp3_set_op_mode(&settings, bmp390);
772
773 if (result != BMP3_OK)
774 return HAL_ERROR;
775
776 return HAL_OK;
777}
778
779
780float_t readAltitude(float_t seaLevelPa,float_t seaLevelT,float_t currentPa) {
781 float_t altitude;
782
783
784 altitude = (seaLevelT/TAU)*(1-pow(currentPa/seaLevelPa,RAST*TAU/GCONST));
785
786 return altitude;
787}
788
789
int8_t bmp3_set_sensor_settings(uint32_t desired_settings, struct bmp3_settings *settings, struct bmp3_dev *dev)
This API sets the power control(pressure enable and temperature enable), over sampling,...
Definition bmp3.c:909
int8_t bmp3_set_op_mode(struct bmp3_settings *settings, struct bmp3_dev *dev)
This API sets the power mode of the sensor.
Definition bmp3.c:1350
int8_t bmp3_init(struct bmp3_dev *dev)
This internal API converts the no. of frames required by the user to bytes so as to write in the wate...
Definition bmp3.c:738
#define BMP3_ODR_200_HZ
Definition bmp3_defs.h:232
#define NULL
Definition bmp3_defs.h:88
#define BMP3_DISABLE
Definition bmp3_defs.h:183
#define BMP3_IIR_FILTER_DISABLE
Definition bmp3_defs.h:222
@ BMP3_SPI_INTF
Definition bmp3_defs.h:505
#define BMP3_ENABLE
Definition bmp3_defs.h:182
#define BMP3_NO_OVERSAMPLING
Definition bmp3_defs.h:214
#define BMP3_SEL_ODR
Definition bmp3_defs.h:287
#define BMP3_OK
Definition bmp3_defs.h:258
#define BMP3_SEL_PRESS_EN
Definition bmp3_defs.h:281
#define BMP3_SEL_IIR_FILTER
Definition bmp3_defs.h:286
#define BMP3_SEL_PRESS_OS
Definition bmp3_defs.h:284
#define BMP3_SEL_TEMP_EN
Definition bmp3_defs.h:282
#define BMP3_SEL_TEMP_OS
Definition bmp3_defs.h:285
#define BMP3_MODE_NORMAL
Definition bmp3_defs.h:178
int32_t lsm6dso32_angular_rate_raw_get(stmdev_ctx_t *ctx, int16_t *val)
Angular rate sensor. The value is expressed as a 16-bit word in two’s complement.[get].
int32_t lsm6dso32_temperature_raw_get(stmdev_ctx_t *ctx, int16_t *val)
Temperature data output register (r). L and H registers together express a 16-bit word in two’s compl...
int32_t lsm6dso32_acceleration_raw_get(stmdev_ctx_t *ctx, int16_t *val)
Linear acceleration output register. The value is expressed as a 16-bit word in two’s complement....
#define LSM6DSO32_ID
float_t lsm6dso32_from_lsb_to_celsius(int16_t lsb)
float_t lsm6dso32_from_fs16_to_mg(int16_t lsb)
float_t lsm6dso32_from_fs2000_to_mdps(int16_t lsb)
int32_t lsm6dso32_reset_get(stmdev_ctx_t *ctx, uint8_t *val)
Software reset. Restore the default values in user registers.[get].
int32_t lsm6dso32_reset_set(stmdev_ctx_t *ctx, uint8_t val)
Software reset. Restore the default values in user registers[set].
int32_t lsm6dso32_device_id_get(stmdev_ctx_t *ctx, uint8_t *buff)
Device "Who am I".[get].
int8_t calibrateIMU(stmdev_ctx_t *imu, uint16_t iterationNum, OFFSET_TYPE type)
Calibrates the IMU by calculating sensor offsets.
Definition utilities.c:366
int32_t lsm6dso32_gy_full_scale_set(stmdev_ctx_t *ctx, lsm6dso32_fs_g_t val)
Gyroscope UI chain full-scale selection.[set].
int32_t imuP_read(void *handle, uint8_t reg_addr, uint8_t *buf, uint16_t len)
SPI read function for the primary IMU (LSM6DSO32).
Definition utilities.c:52
int32_t lsm6dso32_xl_offset_weight_set(stmdev_ctx_t *ctx, lsm6dso32_usr_off_w_t val)
Weight of XL user offset bits of registers X_OFS_USR (73h), Y_OFS_USR (74h), Z_OFS_USR (75h)....
int32_t lsm6dso32_xl_full_scale_set(stmdev_ctx_t *ctx, lsm6dso32_fs_xl_t val)
Accelerometer full-scale selection.[set].
OFFSET_TYPE
Specifies the type of offset compensation to be used.
Definition utilities.h:60
int32_t lsm6dso32_block_data_update_set(stmdev_ctx_t *ctx, uint8_t val)
Block data update.[set].
int32_t imuP_read_2(void *handle, uint8_t reg_addr, uint8_t *buf, uint16_t len)
SPI read function for the primary IMU (LSM6DSO32).
Definition utilities.c:71
int32_t lsm6dso32_xl_usr_offset_z_set(stmdev_ctx_t *ctx, uint8_t *buff)
Accelerometer Z-axis user offset correction expressed in two’s complement, weight depends on USR_OFF_...
int32_t imuB_read(void *handle, uint8_t reg_addr, uint8_t *buf, uint16_t len)
SPI read function for the backup IMU (LSM6DSO32).
Definition utilities.c:582
int32_t lsm6dso32_xl_data_rate_set(stmdev_ctx_t *ctx, lsm6dso32_odr_xl_t val)
Accelerometer UI data rate and power mode selection.[set].
int8_t init_imup(stmdev_ctx_t *imu, lsm6dso32_fs_xl_t acc_full_scale, lsm6dso32_fs_g_t gyro_full_scale, lsm6dso32_odr_xl_t acc_output_data_rate, lsm6dso32_odr_g_t gyro_output_data_rate)
Initializes the primary IMU (LSM6DSO32).
Definition utilities.c:193
int32_t lsm6dso32_xl_usr_offset_y_set(stmdev_ctx_t *ctx, uint8_t *buff)
Accelerometer Y-axis user offset correction expressed in two’s complement, weight depends on USR_OFF_...
int32_t lsm6dso32_i3c_disable_set(stmdev_ctx_t *ctx, lsm6dso32_i3c_disable_t val)
I3C Enable/Disable communication protocol[.set].
int32_t lsm6dso32_xl_usr_offset_x_set(stmdev_ctx_t *ctx, uint8_t *buff)
Accelerometer X-axis user offset correction expressed in two’s complement, weight depends on USR_OFF_...
int32_t lsm6dso32_gy_data_rate_set(stmdev_ctx_t *ctx, lsm6dso32_odr_g_t val)
Gyroscope UI data rate selection.[set].
int32_t lsm6dso32_status_reg_get(stmdev_ctx_t *ctx, lsm6dso32_status_reg_t *val)
The STATUS_REG register is read by the primary interface.[get].
int32_t imuP_write(void *handle, uint8_t reg_addr, const uint8_t *buf, uint16_t len)
SPI write function for the primary IMU (LSM6DSO32).
Definition utilities.c:33
int8_t init_imuB(stmdev_ctx_t *imu, lsm6dso32_fs_xl_t acc_full_scale, lsm6dso32_fs_g_t gyro_full_scale, lsm6dso32_odr_xl_t acc_output_data_rate, lsm6dso32_odr_g_t gyro_output_data_rate)
Initializes the backup IMU (LSM6DSO32).
Definition utilities.c:665
int32_t imuB_write(void *handle, uint8_t reg_addr, const uint8_t *buf, uint16_t len)
SPI write function for the backup IMU (LSM6DSO32).
Definition utilities.c:563
int32_t lsm6dso32_xl_usr_offset_set(stmdev_ctx_t *ctx, uint8_t val)
Enables user offset on out.[set].
@ HWOFFSET
Use the hardware's internal offset registers.
Definition utilities.h:61
@ RESET_HWOFFSET
Reset the hardware offset registers to their default values.
Definition utilities.h:63
#define TAU
Standard temperature lapse rate in K/m.
#define RAST
Specific gas constant for dry air in J/(kg·K).
#define GCONST
Standard gravity in m/s^2.
#define PROPERTY_ENABLE
int8_t bmp390_P_read(uint8_t reg_addr, uint8_t *buf, uint32_t len, void *intf_ptr)
SPI read function for the primary Barometer (bmp390).
Definition utilities.c:122
int8_t init_bmp390_B(struct bmp3_dev *bmp390)
Initializes the backup barometer (BMP390).
Definition utilities.c:723
int8_t bmp390_B_read(uint8_t reg_addr, uint8_t *buf, uint32_t len, void *intf_ptr)
SPI read function for the backup Barometer (bmp390).
Definition utilities.c:623
int8_t bmp390_B_write(uint8_t reg_addr, const uint8_t *buf, uint32_t len, void *intf_ptr)
SPI write function for the backup Barometer (bmp390).
Definition utilities.c:603
int8_t init_bmp390_p(struct bmp3_dev *bmp390)
Initializes the primary barometer (BMP390).
Definition utilities.c:252
int8_t bmp390_P_write(uint8_t reg_addr, const uint8_t *buf, uint32_t len, void *intf_ptr)
SPI write function for the primary Barometer (bmp390).
Definition utilities.c:103
@ LSM6DSO32_I3C_DISABLE
@ LSM6DSO32_LSb_16mg
@ LSM6DSO32_LSb_1mg
lsm6dso32_odr_xl_t
lsm6dso32_fs_g_t
lsm6dso32_odr_g_t
lsm6dso32_fs_xl_t
float_t altitude
Definition main.c:224
bmp3 device structure
Definition bmp3_defs.h:895
bmp3 device settings
Definition bmp3_defs.h:707
uint8_t op_mode
Definition bmp3_defs.h:709
uint8_t temp_en
Definition bmp3_defs.h:715
uint8_t press_en
Definition bmp3_defs.h:712
struct bmp3_int_ctrl_settings int_settings
Definition bmp3_defs.h:721
struct bmp3_odr_filter_settings odr_filter
Definition bmp3_defs.h:718
lsm6dso32_status_reg_t status_reg
float_t readAltitude(float_t seaLevelPa, float_t seaLevelT, float_t currentPa)
Calculates altitude based on the barometric formula.
Definition utilities.c:780
static int8_t bmp3_B_spi_init(struct bmp3_dev *dev)
Definition utilities.c:647
static void bmp390_delay_us(uint32_t period, void *intf_ptr)
Definition utilities.c:163
static uint8_t bmp390_p_addr
Definition utilities.c:29
uint16_t compute_air_density(float_t temperature, float_t pressure)
Definition utilities.c:319
SPI_HandleTypeDef hspi1
Definition main.c:61
static int8_t bmp3_P_spi_init(struct bmp3_dev *dev)
Definition utilities.c:173
SPI_HandleTypeDef hspi2
Definition main.c:62
static uint8_t bmp390_B_addr
Definition utilities.c:30
SPI_HandleTypeDef hspi3
Definition main.c:63
Provides low-level hardware drivers, sensor initialization routines, and various utility functions fo...
#define SPECIFIC_GAS_CONSTANT
Definition utilities.h:51
HAL_StatusTypeDef
HAL Status structures definition.
@ HAL_ERROR
@ HAL_OK