From adf7bc61d0b661627447f1a5a6fb37ab287ae794 Mon Sep 17 00:00:00 2001 From: Linar Yusupov Date: Thu, 25 Jul 2024 14:24:45 +0300 Subject: [PATCH] build is possible with 'auxiliary BME280' driver --- .../source/SoftRF/src/driver/Baro.cpp | 134 +++++++++++++- .../firmware/source/SoftRF/src/driver/Baro.h | 3 +- .../src/platform/iomap/LilyGO_TUltima.h | 5 + .../SensorsLib/board/ESP32-S3-N4R2-QSPI.json | 41 ----- .../board/ESP32-S3-R8-N16-QSPI.json | 41 ----- .../SensorsLib/board/ESP32-S3-R8-OPI.json | 39 ----- .../SensorsLib/src/SensorBHI260AP.hpp | 163 +++++++++++++++--- 7 files changed, 282 insertions(+), 144 deletions(-) delete mode 100644 software/firmware/source/libraries/SensorsLib/board/ESP32-S3-N4R2-QSPI.json delete mode 100644 software/firmware/source/libraries/SensorsLib/board/ESP32-S3-R8-N16-QSPI.json delete mode 100644 software/firmware/source/libraries/SensorsLib/board/ESP32-S3-R8-OPI.json diff --git a/software/firmware/source/SoftRF/src/driver/Baro.cpp b/software/firmware/source/SoftRF/src/driver/Baro.cpp index c05622f5c..525ec09c0 100644 --- a/software/firmware/source/SoftRF/src/driver/Baro.cpp +++ b/software/firmware/source/SoftRF/src/driver/Baro.cpp @@ -20,8 +20,9 @@ #include "Baro.h" -#if defined(EXCLUDE_BMP180) && defined(EXCLUDE_BMP280) && \ - defined(EXCLUDE_BME680) && defined(EXCLUDE_MPL3115A2) +#if defined(EXCLUDE_BMP180) && defined(EXCLUDE_BMP280) && \ + defined(EXCLUDE_BME680) && defined(EXCLUDE_BME280AUX) && \ + defined(EXCLUDE_MPL3115A2) byte Baro_setup() {return BARO_MODULE_NONE;} void Baro_loop() {} void Baro_fini() {} @@ -39,6 +40,9 @@ float Baro_temperature() {return 0;} #if !defined(EXCLUDE_BME680) #include #endif /* EXCLUDE_BME680 */ +#if !defined(EXCLUDE_BME280AUX) +#include +#endif /* EXCLUDE_BME280AUX */ #if !defined(EXCLUDE_MPL3115A2) #include #endif /* EXCLUDE_MPL3115A2 */ @@ -56,6 +60,9 @@ Adafruit_BMP280 bmp280; #if !defined(EXCLUDE_BME680) Adafruit_BME680 bme680; #endif /* EXCLUDE_BME680 */ +#if !defined(EXCLUDE_BME280AUX) +SensorBHI260AP bhy; +#endif /* EXCLUDE_BME280AUX */ #if !defined(EXCLUDE_MPL3115A2) Adafruit_MPL3115A2 mpl3115a2 = Adafruit_MPL3115A2(); #endif /* EXCLUDE_MPL3115A2 */ @@ -246,6 +253,117 @@ barochip_ops_t bme680_ops = { }; #endif /* EXCLUDE_BME680 */ +#if !defined(EXCLUDE_BME280AUX) +static float aux_temperature = 0; +static float aux_pressure = 0; /* hPa */ + +void parse_bme280_sensor_data(uint8_t sensor_id, uint8_t *data_ptr, + uint32_t len, uint64_t *timestamp) +{ + switch (sensor_id) { + case SENSOR_ID_TEMP: + bhy2_parse_temperature_celsius(data_ptr, &aux_temperature); + Serial.print("temperature: "); + Serial.print(aux_temperature); + Serial.println(" *C"); + break; + case SENSOR_ID_BARO: + bhy2_parse_pressure(data_ptr, &aux_pressure); + Serial.print("pressure: "); + Serial.print(aux_pressure); + Serial.println(" hPa"); + break; + default: + break; + } +} + +static bool bme280aux_probe() +{ + return false; /* TBD */ +} + +static void bme280aux_setup() +{ + bhy.setPins(SOC_GPIO_PIN_IMU_TULTIMA_RST, SOC_GPIO_PIN_IMU_TULTIMA_INT); + bhy.setBootFormFlash(true); + + if (!bhy.init(SPI, + SOC_GPIO_PIN_IMU_TULTIMA_SS, SOC_GPIO_PIN_TULTIMA_MOSI, + SOC_GPIO_PIN_TULTIMA_MISO, SOC_GPIO_PIN_TULTIMA_SCK)) { + Serial.print("Failed to init BHI260AP - "); + Serial.println(bhy.getError()); + while (1) { + delay(1000); + } + } + + Serial.println("Init BHI260AP Sensor success!"); + + bhy.printSensors(Serial); + + float sample_rate = 0.0; /* Read out hintr_ctrl measured at 100Hz */ + uint32_t report_latency_ms = 0; /* Report immediately */ + + /* + * Enable BME280 function + * Function depends on BME280. + * If the hardware is not connected to BME280, the function cannot be used. + */ + bhy.configure(SENSOR_ID_TEMP, sample_rate, report_latency_ms); + bhy.configure(SENSOR_ID_BARO, sample_rate, report_latency_ms); + + bhy.onResultEvent(SENSOR_ID_TEMP, parse_bme280_sensor_data); + bhy.onResultEvent(SENSOR_ID_BARO, parse_bme280_sensor_data); +} + +static void bme280aux_fini() +{ + /* TBD */ +} + +/*! + * @brief Calculates the approximate altitude using barometric pressure and the + * supplied sea level hPa as a reference. + * @param seaLevelhPa + * The current hPa at sea level. + * @return The approximate altitude above sea level in meters. + */ +static float bme280aux_altitude(float seaLevelhPa) +{ + return 44330 * (1.0 - pow(aux_pressure / seaLevelhPa, 0.1903)); +} + +/*! + * Reads the barometric pressure from the device. + * @return Barometric pressure in Pa. + */ +static float bme280aux_pressure() +{ + return aux_pressure * 100; +} + +/*! + * Reads the temperature from the device. + * @return The temperature in degress celcius. + */ +static float bme280aux_temperature() +{ + return aux_temperature; +} + +barochip_ops_t bme280aux_ops = { + BARO_MODULE_BME280AUX, + "BME280", + bme280aux_probe, + bme280aux_setup, + bme280aux_fini, + bme280aux_altitude, + bme280aux_pressure, + bme280aux_temperature +}; +#endif /* EXCLUDE_BME280AUX */ + #if !defined(EXCLUDE_MPL3115A2) static bool mpl3115a2_probe() { @@ -322,6 +440,12 @@ bool Baro_probe() false || #endif /* EXCLUDE_BME680 */ +#if !defined(EXCLUDE_BME280AUX) + (baro_chip = &bme280aux_ops, baro_chip->probe()) || +#else + false || +#endif /* EXCLUDE_BME280AUX */ + #if !defined(EXCLUDE_MPL3115A2) (baro_chip = &mpl3115a2_ops, baro_chip->probe()) #else @@ -367,6 +491,12 @@ void Baro_loop() if (isTimeToBaroAltitude()) { +#if !defined(EXCLUDE_BME280AUX) + if (baro_chip->type == BARO_MODULE_BME280AUX) { + bhy.update(); + } +#endif /* EXCLUDE_BME280AUX */ + /* Draft of pressure altitude and vertical speed calculation */ Baro_altitude_cache = baro_chip->altitude(1013.25); diff --git a/software/firmware/source/SoftRF/src/driver/Baro.h b/software/firmware/source/SoftRF/src/driver/Baro.h index c7583cf33..2e1fec699 100644 --- a/software/firmware/source/SoftRF/src/driver/Baro.h +++ b/software/firmware/source/SoftRF/src/driver/Baro.h @@ -34,7 +34,8 @@ enum BARO_MODULE_BMP180, BARO_MODULE_BMP280, BARO_MODULE_BME680, - BARO_MODULE_MPL3115A2 + BARO_MODULE_BME280AUX, + BARO_MODULE_MPL3115A2, }; typedef struct barochip_ops_struct { diff --git a/software/firmware/source/SoftRF/src/platform/iomap/LilyGO_TUltima.h b/software/firmware/source/SoftRF/src/platform/iomap/LilyGO_TUltima.h index 6c5b2178f..fdeebb3a5 100644 --- a/software/firmware/source/SoftRF/src/platform/iomap/LilyGO_TUltima.h +++ b/software/firmware/source/SoftRF/src/platform/iomap/LilyGO_TUltima.h @@ -52,3 +52,8 @@ #define SOC_GPIO_PIN_I2S_TULTIMA_BCK _PINNUM(0, 24) // P0.24 #define SOC_GPIO_PIN_I2S_TULTIMA_DOUT _PINNUM(0, 22) // P0.22 #define SOC_GPIO_PIN_I2S_TULTIMA_MCK SOC_UNUSED_PIN + +/* IMU */ +#define SOC_GPIO_PIN_IMU_TULTIMA_SS _PINNUM(0, 28) // P0.28 +#define SOC_GPIO_PIN_IMU_TULTIMA_INT _PINNUM(0, 30) // P0.30 +#define SOC_GPIO_PIN_IMU_TULTIMA_RST SOC_UNUSED_PIN diff --git a/software/firmware/source/libraries/SensorsLib/board/ESP32-S3-N4R2-QSPI.json b/software/firmware/source/libraries/SensorsLib/board/ESP32-S3-N4R2-QSPI.json deleted file mode 100644 index d4d89d155..000000000 --- a/software/firmware/source/libraries/SensorsLib/board/ESP32-S3-N4R2-QSPI.json +++ /dev/null @@ -1,41 +0,0 @@ -{ - "build": { - "arduino": { - "ldscript": "esp32s3_out.ld", - "partitions": "default.csv", - "memory_type": "qio_qspi" - }, - "core": "esp32", - "extra_flags": [ - "-DARDUINO_ESP32S3_DEV_4M_QSPI", - "-DARDUINO_USB_MODE=1", - "-DARDUINO_USB_CDC_ON_BOOT=1", - "-DARDUINO_RUNNING_CORE=1", - "-DARDUINO_EVENT_RUNNING_CORE=1", - "-DBOARD_HAS_PSRAM" - ], - "f_cpu": "240000000L", - "f_flash": "80000000L", - "flash_mode": "qio", - "hwids": [["0x303A", "0x1001"]], - "mcu": "esp32s3", - "variant": "esp32s3" - }, - "connectivity": ["wifi"], - "debug": { - "default_tool": "esp-builtin", - "onboard_tools": ["esp-builtin"], - "openocd_target": "esp32s3.cfg" - }, - "frameworks": ["arduino", "espidf"], - "name": "ESP32-S3 Dev Modlue (4M Flash 2M QSPI PSRAM )", - "upload": { - "flash_size": "4MB", - "maximum_ram_size": 327680, - "maximum_size": 4194304, - "require_upload_port": true, - "speed": 921600 - }, - "url": "https://www.espressif.com", - "vendor": "espressif" -} diff --git a/software/firmware/source/libraries/SensorsLib/board/ESP32-S3-R8-N16-QSPI.json b/software/firmware/source/libraries/SensorsLib/board/ESP32-S3-R8-N16-QSPI.json deleted file mode 100644 index 21f635046..000000000 --- a/software/firmware/source/libraries/SensorsLib/board/ESP32-S3-R8-N16-QSPI.json +++ /dev/null @@ -1,41 +0,0 @@ -{ - "build": { - "arduino": { - "ldscript": "esp32s3_out.ld", - "partitions": "default.csv", - "memory_type": "qio_qspi" - }, - "core": "esp32", - "extra_flags": [ - "-DARDUINO_ESP32S3_DEV_16M_QSPI", - "-DARDUINO_USB_MODE=1", - "-DARDUINO_USB_CDC_ON_BOOT=1", - "-DARDUINO_RUNNING_CORE=1", - "-DARDUINO_EVENT_RUNNING_CORE=1", - "-DBOARD_HAS_PSRAM" - ], - "f_cpu": "240000000L", - "f_flash": "80000000L", - "flash_mode": "qio", - "hwids": [["0x303A", "0x1001"]], - "mcu": "esp32s3", - "variant": "esp32s3" - }, - "connectivity": ["wifi"], - "debug": { - "default_tool": "esp-builtin", - "onboard_tools": ["esp-builtin"], - "openocd_target": "esp32s3.cfg" - }, - "frameworks": ["arduino", "espidf"], - "name": "ESP32-S3 Dev Modlue (16M Flash 8M QSPI PSRAM )", - "upload": { - "flash_size": "16MB", - "maximum_ram_size": 327680, - "maximum_size": 16777216, - "require_upload_port": true, - "speed": 921600 - }, - "url": "https://www.espressif.com", - "vendor": "espressif" -} diff --git a/software/firmware/source/libraries/SensorsLib/board/ESP32-S3-R8-OPI.json b/software/firmware/source/libraries/SensorsLib/board/ESP32-S3-R8-OPI.json deleted file mode 100644 index 8fd781021..000000000 --- a/software/firmware/source/libraries/SensorsLib/board/ESP32-S3-R8-OPI.json +++ /dev/null @@ -1,39 +0,0 @@ -{ - "build": { - "arduino": { - "ldscript": "esp32s3_out.ld", - "memory_type": "qio_opi", - "partitions": "default_16MB.csv" - }, - "core": "esp32", - "extra_flags": [ - "-DARDUINO_ESP32S3_DEV_16M_OPI", - "-DARDUINO_USB_MODE=1", - "-DARDUINO_USB_CDC_ON_BOOT=1", - "-DARDUINO_RUNNING_CORE=1", - "-DARDUINO_EVENT_RUNNING_CORE=1", - "-DBOARD_HAS_PSRAM" - ], - "f_cpu": "240000000L", - "f_flash": "80000000L", - "flash_mode": "qio", - "hwids": [["0x303A", "0x1001"]], - "mcu": "esp32s3", - "variant": "esp32s3" - }, - "connectivity": ["wifi", "bluetooth"], - "debug": { - "openocd_target": "esp32s3.cfg" - }, - "frameworks": ["arduino", "espidf"], - "name": "ESP32-S3 Dev Modlue (16M Flash 8M OPI PSRAM )", - "upload": { - "flash_size": "16MB", - "maximum_ram_size": 327680, - "maximum_size": 16777216, - "require_upload_port": true, - "speed": 921600 - }, - "url": "https://www.espressif.com", - "vendor": "espressif" -} diff --git a/software/firmware/source/libraries/SensorsLib/src/SensorBHI260AP.hpp b/software/firmware/source/libraries/SensorsLib/src/SensorBHI260AP.hpp index 80d1a12df..26a52853d 100644 --- a/software/firmware/source/libraries/SensorsLib/src/SensorBHI260AP.hpp +++ b/software/firmware/source/libraries/SensorsLib/src/SensorBHI260AP.hpp @@ -115,10 +115,10 @@ class SensorBHI260AP void deinit() { - if (processBuffer) { - free(processBuffer); + if (__pro_buf) { + free(__pro_buf); } - processBuffer = NULL; + __pro_buf = NULL; if (bhy2) { free(bhy2); @@ -145,18 +145,23 @@ class SensorBHI260AP void update() { - if (!processBuffer) { + if (!__pro_buf) { return; } if (__handler.irq != SENSOR_PIN_NONE) { if (__data_available) { - bhy2_get_and_process_fifo(processBuffer, processBufferSize, bhy2); + bhy2_get_and_process_fifo(__pro_buf, __pro_buf_size, bhy2); } } else { - bhy2_get_and_process_fifo(processBuffer, processBufferSize, bhy2); + bhy2_get_and_process_fifo(__pro_buf, __pro_buf_size, bhy2); } } + void setBootFormFlash(bool boot_from_flash) + { + __boot_from_flash = boot_from_flash; + } + bool enablePowerSave() { return true; @@ -364,7 +369,7 @@ class SensorBHI260AP if (__error_code != BHY2_OK) { return false; } - return (boot_status & BHY2_BST_HOST_INTERFACE_READY) == false; + return (boot_status & BHY2_BST_HOST_INTERFACE_READY); } uint16_t getKernelVersion() @@ -374,7 +379,7 @@ class SensorBHI260AP if ((__error_code != BHY2_OK) && (version == 0)) { return 0; } - log_i("Boot successful. Kernel version %u.", version); + log_d("Boot successful. Kernel version %u.", version); return version; } @@ -425,7 +430,7 @@ class SensorBHI260AP void setProcessBufferSize(uint32_t size) { - processBufferSize = size; + __pro_buf_size = size; } @@ -468,7 +473,7 @@ class SensorBHI260AP log_e("%s", get_sensor_error_text(sensor_error)); return false; } - + if (write2Flash) { log_i("Booting from FLASH."); @@ -496,6 +501,9 @@ class SensorBHI260AP bool configure(uint8_t sensor_id, float sample_rate, uint32_t report_latency_ms) { + if (!bhy2_is_sensor_available(sensor_id, bhy2)) { + log_e("Sensor not present"); return false; + } __error_code = bhy2_set_virt_sensor_cfg(sensor_id, sample_rate, report_latency_ms, bhy2); BHY2_RLST_CHECK(__error_code != BHY2_OK, "bhy2_set_virt_sensor_cfg failed!", false); log_i("Enable %s at %.2fHz.", get_sensor_name(sensor_id), sample_rate); @@ -534,6 +542,110 @@ class SensorBHI260AP } private: + + bool bootFromFlash() + { + int8_t rslt; + uint8_t boot_status, feat_status; + uint8_t error_val = 0; + uint16_t tries = 300; /* Wait for up to little over 3s */ + + log_d("Waiting for firmware verification to complete"); + do { + __error_code = bhy2_get_boot_status(&boot_status, bhy2); + BHY2_RLST_CHECK(__error_code != BHY2_OK, "bhy2_get_boot_status failed!", false); + if (boot_status & BHY2_BST_FLASH_VERIFY_DONE) { + break; + } + delay(10); + } while (tries--); + + __error_code = bhy2_get_boot_status(&boot_status, bhy2); + BHY2_RLST_CHECK(__error_code != BHY2_OK, "bhy2_get_boot_status failed!", false); + print_boot_status(boot_status); + + if (boot_status & BHY2_BST_HOST_INTERFACE_READY) { + + if (boot_status & BHY2_BST_FLASH_DETECTED) { + + /* If no firmware is running, boot from Flash */ + log_d("Booting from flash"); + rslt = bhy2_boot_from_flash(bhy2); + if (rslt != BHY2_OK) { + log_e("%s. Booting from flash failed.\r\n", get_api_error(rslt)); + __error_code = bhy2_get_regs(BHY2_REG_ERROR_VALUE, &error_val, 1, bhy2); + BHY2_RLST_CHECK(__error_code != BHY2_OK, "bhy2_get_regs failed!", false); + if (error_val) { + log_e("%s\r\n", get_sensor_error_text(error_val)); + } + return false; + } + + __error_code = bhy2_get_boot_status(&boot_status, bhy2); + BHY2_RLST_CHECK(__error_code != BHY2_OK, "bhy2_get_boot_status failed!", false); + print_boot_status(boot_status); + + if (!(boot_status & BHY2_BST_HOST_INTERFACE_READY)) { + /* hub is not ready, need reset hub */ + log_d("Host interface is not ready, triggering a reset"); + __error_code = bhy2_soft_reset(bhy2); + BHY2_RLST_CHECK(__error_code != BHY2_OK, "bhy2_soft_reset failed!", false); + } + + __error_code = (bhy2_get_feature_status(&feat_status, bhy2)); + BHY2_RLST_CHECK(__error_code != BHY2_OK, "Reading Feature status failed, booting from flash failed!", false); + + } else { + log_e("Can't detect external flash"); + return false; + } + } else { + log_e("Host interface is not ready"); + return false; + } + + log_d("Booting from flash successful"); + return true; + } + + + + void print_boot_status(uint8_t boot_status) + { + log_d("Boot Status : 0x%02x: ", boot_status); + if (boot_status & BHY2_BST_FLASH_DETECTED) { + log_d("Flash detected. "); + } + + if (boot_status & BHY2_BST_FLASH_VERIFY_DONE) { + log_d("Flash verify done. "); + } + + if (boot_status & BHY2_BST_FLASH_VERIFY_ERROR) { + log_d("Flash verification failed. "); + } + + if (boot_status & BHY2_BST_NO_FLASH) { + log_d("No flash installed. "); + } + + if (boot_status & BHY2_BST_HOST_INTERFACE_READY) { + log_d("Host interface ready. "); + } + + if (boot_status & BHY2_BST_HOST_FW_VERIFY_DONE) { + log_d("Firmware verification done. "); + } + + if (boot_status & BHY2_BST_HOST_FW_VERIFY_ERROR) { + log_d("Firmware verification error. "); + } + + if (boot_status & BHY2_BST_HOST_FW_IDLE) { + log_d("Firmware halted. "); + } + } + static void handleISR() { __data_available = true; @@ -595,8 +707,6 @@ class SensorBHI260AP return false; } - - __error_code = bhy2_soft_reset(bhy2); BHY2_RLST_CHECK(__error_code != BHY2_OK, "reset bhy2 failed!", false); @@ -623,7 +733,19 @@ class SensorBHI260AP #endif } - if (!isReady()) { + if (__boot_from_flash) { + if (!bootFromFlash()) { + //** If the boot from flash fails, re-upload the firmware to flash + __error_code = bhy2_soft_reset(bhy2); + BHY2_RLST_CHECK(__error_code != BHY2_OK, "reset bhy2 failed!", false); + + if (!uploadFirmware(__firmware, __firmware_size, __write_flash)) { + log_e("uploadFirmware failed!"); + return false; + } + } + } else { + // ** Upload firmware to RAM if (!uploadFirmware(__firmware, __firmware_size, __write_flash)) { log_e("uploadFirmware failed!"); return false; @@ -646,16 +768,16 @@ class SensorBHI260AP //Set process buffer #if (defined(ESP32) || defined(ARDUINO_ARCH_ESP32)) && defined(BOARD_HAS_PSRAM) - processBuffer = (uint8_t *)ps_malloc(processBufferSize); + __pro_buf = (uint8_t *)ps_malloc(__pro_buf_size); #else - processBuffer = (uint8_t *)malloc(processBufferSize); + __pro_buf = (uint8_t *)malloc(__pro_buf_size); #endif - BHY2_RLST_CHECK(!processBuffer, "process buffer malloc failed!", false); + BHY2_RLST_CHECK(!__pro_buf, "process buffer malloc failed!", false); - __error_code = bhy2_get_and_process_fifo(processBuffer, processBufferSize, bhy2); + __error_code = bhy2_get_and_process_fifo(__pro_buf, __pro_buf_size, bhy2); if (__error_code != BHY2_OK) { log_e("bhy2_get_and_process_fifo failed"); - free(processBuffer); + free(__pro_buf); return false; } @@ -690,11 +812,12 @@ class SensorBHI260AP SensorLibConfigure __handler; int8_t __error_code; static volatile bool __data_available; - uint8_t *processBuffer = NULL; - size_t processBufferSize = BHY_PROCESS_BUFFER_SIZE; + uint8_t *__pro_buf = NULL; + size_t __pro_buf_size = BHY_PROCESS_BUFFER_SIZE; const uint8_t *__firmware; size_t __firmware_size; bool __write_flash; + bool __boot_from_flash; uint16_t __max_rw_length; uint8_t __accuracy; /* Accuracy is reported as a meta event. */ };