From f4804c60d53562e05fe37dfd35fde934cc36d6d5 Mon Sep 17 00:00:00 2001 From: lewisxhe Date: Fri, 24 Jan 2025 11:08:43 +0800 Subject: [PATCH] =?UTF-8?q?=F0=9F=92=A5Major=20Changes?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/workflows/arduino_ci.yml | 118 +- .github/workflows/esp-idf.yml | 18 +- .github/workflows/pio.yml | 118 +- CMakeLists.txt | 13 +- README.md | 61 +- examples/BHI260AP_6DoF/BHI260AP_6DoF.ino | 95 +- .../BHI260AP_DebugInfo/BHI260AP_DebugInfo.ino | 105 -- .../BHI260AP_Expand_GPIO.ino | 97 +- .../BHI260AP_Orientation.ino | 100 +- .../BHI260AP_StepCounter.ino | 92 +- .../BHI260AP_UpdateFirmware.ino | 99 +- .../BHI260AP_aux_BMM150.ino | 97 +- .../BHI260AP_aux_BMM150_BME280.ino | 92 +- ...BHI260AP_aux_BMM150_BME280_Expand_GPIO.ino | 96 +- .../BHI260AP_aux_BMM150_euler.ino | 91 +- .../BHI260AP_aux_BMM150_quaternion.ino | 90 +- .../BMA423_Accelerometer.ino | 8 +- examples/BMA423_Feature/BMA423_Feature.ino | 8 +- .../BMA423_Orientation/BMA423_Orientation.ino | 7 +- .../BMA423_Temperature/BMA423_Temperature.ino | 13 +- .../BMM150_GetDataExample.ino | 4 +- .../BQ27220_GaugeExample.ino | 178 +++ .../CM32181_LightSensor.ino | 2 +- .../CM32181_LightSensorInterrupt.ino | 26 +- .../CustomCallbackTouchDrvInterface.ino | 294 +++++ .../CustomCallbackUsageExamples.ino | 219 ++++ examples/DRV2605_Basic/DRV2605_Basic.ino | 8 +- .../CMakeLists.txt | 2 +- examples/ESP_IDF_SensorExamples/Makefile | 10 + examples/ESP_IDF_SensorExamples/README.md | 840 +++++++++++++ .../main/CMakeLists.txt | 9 + .../main/Kconfig.projbuild | 115 ++ .../main/component.mk | 0 .../main/i2c_driver.cpp | 378 ++++++ .../ESP_IDF_SensorExamples/main/i2c_driver.h | 54 + examples/ESP_IDF_SensorExamples/main/main.cpp | 199 +++ .../main/sensor_bhi260.cpp | 205 +++ .../main/sensor_bma423.cpp | 119 ++ .../main/sensor_pcf8563.cpp | 137 ++ .../main/sensor_xl9555.cpp | 107 ++ .../main/touch_ft63x6.cpp | 116 ++ .../ESP_IDF_TouchDrvExample/CMakeLists.txt | 9 + .../Makefile | 0 examples/ESP_IDF_TouchDrvExample/README.md | 154 +++ .../main/CMakeLists.txt | 0 .../main/Kconfig.projbuild | 8 +- .../ESP_IDF_TouchDrvExample/main/component.mk | 4 + .../main/i2c_driver.cpp | 30 +- .../ESP_IDF_TouchDrvExample/main/i2c_driver.h | 53 + .../ESP_IDF_TouchDrvExample/main/main.cpp | 67 + .../main/touch_drv.cpp | 113 +- .../sdkconfig.defaults | 0 examples/ESP_IDF_TouchDrv_Example/README.md | 181 --- .../main/i2c_driver.h | 32 - .../ESP_IDF_TouchDrv_Example/main/main.cpp | 83 -- .../LTR553ALS_Sensor/LTR553ALS_Sensor.ino | 2 +- .../PCF85063_AlarmByUnits.ino | 12 +- .../PCF85063_ClockOutput.ino | 10 +- .../PCF85063_SimpleTime.ino | 10 +- .../PCF8563_AlarmByUnits.ino | 30 +- .../PCF8563_ClockOutput.ino | 18 +- .../PCF8563_SimpleTime/PCF8563_SimpleTime.ino | 25 +- examples/PCF8563_TimeLib/PCF8563_TimeLib.ino | 37 +- .../PCF8563_TimeSynchronization.ino | 25 +- .../QMC6310_CalibrateExample.ino | 31 +- .../QMC6310_CompassExample.ino | 43 +- .../QMC6310_GetDataExample.ino | 27 +- .../QMC6310_GetPolarExample.ino | 27 +- .../QMI8658_BlockExample.ino | 109 +- .../QMI8658_CalibrationExample.ino | 85 +- .../QMI8658_GetDataExample.ino | 76 +- .../QMI8658_InterruptBlockExample.ino | 103 +- .../QMI8658_InterruptExample.ino | 108 +- .../QMI8658_LockingMechanismExample.ino | 105 +- .../QMI8658_MadgwickAHRS.ino | 82 +- .../QMI8658_MotionDetectionExample.ino | 76 +- .../QMI8658_PedometerExample.ino | 76 +- .../QMI8658_ReadFromFifoExample.ino | 78 +- .../QMI8658_TapDetectionExample.ino | 76 +- .../QMI8658_WakeOnMotion.ino | 102 +- .../QMI8658_WakeOnMotionCallBackExample.ino | 103 +- .../TouchDrvInterface_Example.ino} | 112 +- .../TouchDrv_CHSC5816_GetPoint.ino | 47 +- .../TouchDrv_CST9217_GetPoint.ino | 38 +- .../TouchDrv_CSTxxx_GetPoint.ino | 44 +- .../TouchDrv_FT3267_LilyGo_T_RGB.ino | 115 -- .../TouchDrv_FT6232_GetPoint.ino | 18 +- .../TouchDrv_GT911_GetPoint.ino | 31 +- .../TouchDrv_GT911_LilyGo_T_RGB.ino | 165 --- .../TouchDrv_GT9895_GetPoint.ino | 20 +- .../XL9555_AdjustBacklight.ino | 2 +- .../XL9555_ExtensionIOInterrupt.ino | 8 +- .../XL9555_ExtensionIORead.ino | 8 +- .../XL9555_ExtensionIOWrite.ino | 8 +- examples/XL9555_ioEvent/XL9555_ioEvent.ino | 8 +- extras/images/SensroLib.jpg | Bin 0 -> 32195 bytes keywords.txt | 6 +- library.json | 2 +- library.properties | 2 +- platformio.ini | 147 ++- src/DevicesPins.h | 64 +- src/ExtensionIOXL9555.hpp | 129 +- src/{ExtensionSPI.tpp => ExtensionSPI.hpp} | 10 +- src/GaugeBQ27220.hpp | 734 +++++++++++ src/REG/BMA423Config.h | 545 ++++++++ src/REG/BMA423Constants.h | 929 ++++---------- src/REG/BQ27220Constants.h | 108 ++ src/REG/CHSC5816Constants.h | 34 - src/REG/CM32181Constants.h | 34 +- src/REG/CST9xxConstants.h | 53 +- src/REG/CSTxxxConstants.h | 15 +- src/REG/DRV2605Constants.h | 101 +- src/REG/FT6X36Constants.h | 58 +- src/REG/GT911Constants.h | 258 ++-- src/REG/GT9895Constants.h | 206 +++- src/REG/LTR533Constants.h | 68 +- src/REG/MPU6886Constants.h | 146 +-- src/REG/PCF85063Constants.h | 62 +- src/REG/PCF8563Constants.h | 73 +- src/REG/QMC6310Constants.h | 42 +- src/REG/QMI8658Constants.h | 228 ++-- src/REG/XL9555Constants.h | 63 +- src/SensorBHI260AP.cpp | 946 +++++++++++++- src/SensorBHI260AP.hpp | 1098 +++-------------- src/SensorBMA423.cpp | 730 +++++++++++ src/SensorBMA423.hpp | 799 ++---------- src/SensorBMM150.hpp | 232 ++-- src/SensorCM32181.hpp | 125 +- src/SensorCommon.tpp | 722 ----------- src/SensorDRV2605.hpp | 135 +- src/SensorLTR553.hpp | 175 +-- src/SensorLib.h | 169 +-- src/SensorLib_Version.h | 6 +- src/SensorPCF85063.hpp | 125 +- src/SensorPCF8563.hpp | 210 ++-- src/SensorPlatform.hpp | 116 ++ src/SensorQMC6310.hpp | 195 +-- src/SensorQMI8658.hpp | 653 +++++----- src/SensorRTC.h | 8 +- src/SensorWireHelper.cpp | 3 +- src/SensorWireHelper.h | 1 + src/TouchDrvCHSC5816.hpp | 299 ++--- src/TouchDrvCSTXXX.cpp | 269 ++++ src/TouchDrvCSTXXX.hpp | 487 ++------ src/TouchDrvFT6X36.hpp | 224 ++-- src/TouchDrvGT911.hpp | 425 +++---- src/TouchDrvGT9895.cpp | 266 ++-- src/TouchDrvGT9895.hpp | 236 +--- src/TouchDrvInterface.cpp | 50 +- src/TouchDrvInterface.hpp | 60 +- src/bosch/BoschParse.cpp | 2 +- src/bosch/BoschParse.h | 12 +- src/bosch/BoschPhySensorInfo.hpp | 155 +++ src/bosch/BoschSensorControl.hpp | 82 ++ src/bosch/BoschSensorInfo.hpp | 205 +++ src/bosch/SensorBhy2Define.h | 4 +- src/bosch/common/bosch_interfaces.cpp | 166 --- src/bosch/common/common.cpp | 15 - src/bosch/common/common.h | 6 - src/platform/SensorCommBase.hpp | 197 +++ src/platform/SensorCommCustom.hpp | 153 +++ src/platform/SensorCommCustomHal.hpp | 101 ++ .../SensorCommDebug.cpp} | 62 +- src/platform/SensorCommDebug.hpp | 150 +++ src/platform/SensorCommEnhanced.hpp | 117 ++ src/platform/SensorCommStatic.cpp | 61 + .../SensorCommStatic.hpp} | 28 +- src/platform/SensorDataTypeClass.hpp | 135 ++ src/platform/TouchDataTypeClass.hpp | 162 +++ src/platform/arduino/SensorCommArduino_HW.hpp | 89 ++ .../arduino/SensorCommArduino_I2C.hpp | 193 +++ .../arduino/SensorCommArduino_SPI.hpp | 225 ++++ src/platform/esp_arduino.cpp | 66 - src/platform/esp_arduino.h | 22 - src/platform/espidf/SensorCommEspIDF_HW.hpp | 110 ++ src/platform/espidf/SensorCommEspIDF_I2C.hpp | 305 +++++ src/platform/espidf/SensorCommEspIDF_SPI.hpp | 255 ++++ src/touch/TouchClassCST816.cpp | 334 ----- src/touch/TouchClassCST816.h | 102 -- ...ouchClassCST226.cpp => TouchDrvCST226.cpp} | 209 ++-- .../{TouchClassCST226.h => TouchDrvCST226.h} | 46 +- src/touch/TouchDrvCST816.cpp | 305 +++++ src/touch/TouchDrvCST816.h | 118 ++ src/touch/TouchDrvCST92xx.cpp | 487 ++++---- src/touch/TouchDrvCST92xx.h | 89 +- 185 files changed, 15716 insertions(+), 9207 deletions(-) delete mode 100644 examples/BHI260AP_DebugInfo/BHI260AP_DebugInfo.ino create mode 100644 examples/BQ27220_GaugeExample/BQ27220_GaugeExample.ino create mode 100644 examples/CustomCallbackTouchDrvInterface/CustomCallbackTouchDrvInterface.ino create mode 100644 examples/CustomCallbackUsageExamples/CustomCallbackUsageExamples.ino rename examples/{ESP_IDF_TouchDrv_Example => ESP_IDF_SensorExamples}/CMakeLists.txt (88%) create mode 100644 examples/ESP_IDF_SensorExamples/Makefile create mode 100644 examples/ESP_IDF_SensorExamples/README.md create mode 100644 examples/ESP_IDF_SensorExamples/main/CMakeLists.txt create mode 100644 examples/ESP_IDF_SensorExamples/main/Kconfig.projbuild rename examples/{ESP_IDF_TouchDrv_Example => ESP_IDF_SensorExamples}/main/component.mk (100%) create mode 100644 examples/ESP_IDF_SensorExamples/main/i2c_driver.cpp create mode 100644 examples/ESP_IDF_SensorExamples/main/i2c_driver.h create mode 100644 examples/ESP_IDF_SensorExamples/main/main.cpp create mode 100644 examples/ESP_IDF_SensorExamples/main/sensor_bhi260.cpp create mode 100644 examples/ESP_IDF_SensorExamples/main/sensor_bma423.cpp create mode 100644 examples/ESP_IDF_SensorExamples/main/sensor_pcf8563.cpp create mode 100644 examples/ESP_IDF_SensorExamples/main/sensor_xl9555.cpp create mode 100644 examples/ESP_IDF_SensorExamples/main/touch_ft63x6.cpp create mode 100644 examples/ESP_IDF_TouchDrvExample/CMakeLists.txt rename examples/{ESP_IDF_TouchDrv_Example => ESP_IDF_TouchDrvExample}/Makefile (100%) create mode 100644 examples/ESP_IDF_TouchDrvExample/README.md rename examples/{ESP_IDF_TouchDrv_Example => ESP_IDF_TouchDrvExample}/main/CMakeLists.txt (100%) rename examples/{ESP_IDF_TouchDrv_Example => ESP_IDF_TouchDrvExample}/main/Kconfig.projbuild (95%) create mode 100644 examples/ESP_IDF_TouchDrvExample/main/component.mk rename examples/{ESP_IDF_TouchDrv_Example => ESP_IDF_TouchDrvExample}/main/i2c_driver.cpp (86%) create mode 100644 examples/ESP_IDF_TouchDrvExample/main/i2c_driver.h create mode 100644 examples/ESP_IDF_TouchDrvExample/main/main.cpp rename examples/{ESP_IDF_TouchDrv_Example => ESP_IDF_TouchDrvExample}/main/touch_drv.cpp (57%) rename examples/{ESP_IDF_TouchDrv_Example => ESP_IDF_TouchDrvExample}/sdkconfig.defaults (100%) delete mode 100644 examples/ESP_IDF_TouchDrv_Example/README.md delete mode 100644 examples/ESP_IDF_TouchDrv_Example/main/i2c_driver.h delete mode 100644 examples/ESP_IDF_TouchDrv_Example/main/main.cpp rename examples/{TouchDrv_Interface_T_RGB/TouchDrv_Interface_T_RGB.ino => TouchDrvInterface_Example/TouchDrvInterface_Example.ino} (62%) delete mode 100644 examples/TouchDrv_FT3267_LilyGo_T_RGB/TouchDrv_FT3267_LilyGo_T_RGB.ino delete mode 100644 examples/TouchDrv_GT911_LilyGo_T_RGB/TouchDrv_GT911_LilyGo_T_RGB.ino create mode 100644 extras/images/SensroLib.jpg rename src/{ExtensionSPI.tpp => ExtensionSPI.hpp} (94%) create mode 100644 src/GaugeBQ27220.hpp create mode 100644 src/REG/BMA423Config.h create mode 100644 src/REG/BQ27220Constants.h create mode 100644 src/SensorBMA423.cpp delete mode 100644 src/SensorCommon.tpp create mode 100644 src/SensorPlatform.hpp create mode 100644 src/TouchDrvCSTXXX.cpp create mode 100644 src/bosch/BoschPhySensorInfo.hpp create mode 100644 src/bosch/BoschSensorControl.hpp create mode 100644 src/bosch/BoschSensorInfo.hpp delete mode 100644 src/bosch/common/bosch_interfaces.cpp create mode 100644 src/platform/SensorCommBase.hpp create mode 100644 src/platform/SensorCommCustom.hpp create mode 100644 src/platform/SensorCommCustomHal.hpp rename src/{bosch/common/bosch_interfaces.h => platform/SensorCommDebug.cpp} (58%) create mode 100644 src/platform/SensorCommDebug.hpp create mode 100644 src/platform/SensorCommEnhanced.hpp create mode 100644 src/platform/SensorCommStatic.cpp rename src/{SensorBMM150.cpp => platform/SensorCommStatic.hpp} (64%) create mode 100644 src/platform/SensorDataTypeClass.hpp create mode 100644 src/platform/TouchDataTypeClass.hpp create mode 100644 src/platform/arduino/SensorCommArduino_HW.hpp create mode 100644 src/platform/arduino/SensorCommArduino_I2C.hpp create mode 100644 src/platform/arduino/SensorCommArduino_SPI.hpp delete mode 100644 src/platform/esp_arduino.cpp delete mode 100644 src/platform/esp_arduino.h create mode 100644 src/platform/espidf/SensorCommEspIDF_HW.hpp create mode 100644 src/platform/espidf/SensorCommEspIDF_I2C.hpp create mode 100644 src/platform/espidf/SensorCommEspIDF_SPI.hpp delete mode 100644 src/touch/TouchClassCST816.cpp delete mode 100644 src/touch/TouchClassCST816.h rename src/touch/{TouchClassCST226.cpp => TouchDrvCST226.cpp} (51%) rename src/touch/{TouchClassCST226.h => TouchDrvCST226.h} (61%) create mode 100644 src/touch/TouchDrvCST816.cpp create mode 100644 src/touch/TouchDrvCST816.h diff --git a/.github/workflows/arduino_ci.yml b/.github/workflows/arduino_ci.yml index 83094d0..91de124 100644 --- a/.github/workflows/arduino_ci.yml +++ b/.github/workflows/arduino_ci.yml @@ -17,63 +17,67 @@ jobs: matrix: board: ["esp32:esp32:esp32s3"] examples: - - examples/BMA423_Accelerometer/BMA423_Accelerometer.ino - - examples/BMA423_Orientation/BMA423_Orientation.ino - - examples/BMA423_Temperature/BMA423_Temperature.ino - - examples/BMA423_Feature/BMA423_Feature.ino - - examples/CM32181_LightSensor/CM32181_LightSensor.ino - - examples/CM32181_LightSensorInterrupt/CM32181_LightSensorInterrupt.ino - - examples/DRV2605_Basic/DRV2605_Basic.ino - - examples/LTR553ALS_Sensor/LTR553ALS_Sensor.ino - - examples/PCF85063_SimpleTime/PCF85063_SimpleTime.ino - - examples/PCF8563_AlarmByUnits/PCF8563_AlarmByUnits.ino - - examples/PCF8563_SimpleTime/PCF8563_SimpleTime.ino - - examples/PCF8563_TimeLib/PCF8563_TimeLib.ino - - examples/PCF8563_TimeSynchronization/PCF8563_TimeSynchronization.ino - - examples/QMC6310_CalibrateExample/QMC6310_CalibrateExample.ino - - examples/QMC6310_CompassExample/QMC6310_CompassExample.ino - - examples/QMC6310_GetDataExample/QMC6310_GetDataExample.ino - - examples/QMC6310_GetPolarExample/QMC6310_GetPolarExample.ino - - examples/QMI8658_BlockExample/QMI8658_BlockExample.ino - - examples/QMI8658_CalibrationExample/QMI8658_CalibrationExample.ino - - examples/QMI8658_GetDataExample/QMI8658_GetDataExample.ino - - examples/QMI8658_InterruptBlockExample/QMI8658_InterruptBlockExample.ino - - examples/QMI8658_InterruptExample/QMI8658_InterruptExample.ino - - examples/QMI8658_LockingMechanismExample/QMI8658_LockingMechanismExample.ino - - examples/QMI8658_MadgwickAHRS/QMI8658_MadgwickAHRS.ino - - examples/QMI8658_PedometerExample/QMI8658_PedometerExample.ino - - examples/QMI8658_ReadFromFifoExample/QMI8658_ReadFromFifoExample.ino - - examples/QMI8658_WakeOnMotion/QMI8658_WakeOnMotion.ino - - examples/QMI8658_WakeOnMotionCallBackExample/QMI8658_WakeOnMotionCallBackExample.ino - - examples/QMI8658_TapDetectionExample/QMI8658_TapDetectionExample.ino - - examples/QMI8658_MotionDetectionExample/QMI8658_MotionDetectionExample.ino - - examples/TouchDrv_CHSC5816_GetPoint/TouchDrv_CHSC5816_GetPoint.ino - - examples/TouchDrv_CSTxxx_GetPoint/TouchDrv_CSTxxx_GetPoint.ino - - examples/TouchDrv_FT3267_LilyGo_T_RGB/TouchDrv_FT3267_LilyGo_T_RGB.ino - - examples/TouchDrv_FT6232_GetPoint/TouchDrv_FT6232_GetPoint.ino - - examples/TouchDrv_GT911_GetPoint/TouchDrv_GT911_GetPoint.ino - - examples/TouchDrv_GT911_LilyGo_T_RGB/TouchDrv_GT911_LilyGo_T_RGB.ino - - examples/XL9555_ExtensionIOInterrupt/XL9555_ExtensionIOInterrupt.ino - - examples/XL9555_ExtensionIORead/XL9555_ExtensionIORead.ino - - examples/XL9555_ExtensionIOWrite/XL9555_ExtensionIOWrite.ino - - examples/XL9555_ioEvent/XL9555_ioEvent.ino - - examples/XL9555_AdjustBacklight/XL9555_AdjustBacklight.ino - - examples/AW9364_LedDriver/AW9364_LedDriver.ino - - examples/BHI260AP_6DoF/BHI260AP_6DoF.ino - - examples/BHI260AP_Orientation/BHI260AP_Orientation.ino - - examples/BHI260AP_DebugInfo/BHI260AP_DebugInfo.ino - - examples/BHI260AP_StepCounter/BHI260AP_StepCounter.ino - - examples/BHI260AP_aux_BMM150/BHI260AP_aux_BMM150.ino - - examples/BHI260AP_aux_BMM150_euler/BHI260AP_aux_BMM150_euler.ino - - examples/BHI260AP_aux_BMM150_quaternion/BHI260AP_aux_BMM150_quaternion.ino - - examples/BHI260AP_aux_BMM150_BME280/BHI260AP_aux_BMM150_BME280.ino - - examples/BHI260AP_aux_BMM150_BME280_Expand_GPIO/BHI260AP_aux_BMM150_BME280_Expand_GPIO.ino - - examples/BHI260AP_Expand_GPIO/BHI260AP_Expand_GPIO.ino - - examples/BMM150_GetDataExample/BMM150_GetDataExample.ino - - examples/TouchDrv_Interface_T_RGB/TouchDrv_Interface_T_RGB.ino - - examples/TouchDrv_CST9217_GetPoint/TouchDrv_CST9217_GetPoint.ino - - examples/TouchDrv_GT9895_GetPoint/TouchDrv_GT9895_GetPoint.ino - + - examples/AW9364_LedDriver/AW9364_LedDriver.ino + - examples/BHI260AP_6DoF/BHI260AP_6DoF.ino + - examples/BHI260AP_aux_BMM150/BHI260AP_aux_BMM150.ino + - examples/BHI260AP_aux_BMM150_BME280/BHI260AP_aux_BMM150_BME280.ino + - examples/BHI260AP_aux_BMM150_BME280_Expand_GPIO/BHI260AP_aux_BMM150_BME280_Expand_GPIO.ino + - examples/BHI260AP_aux_BMM150_euler/BHI260AP_aux_BMM150_euler.ino + - examples/BHI260AP_aux_BMM150_quaternion/BHI260AP_aux_BMM150_quaternion.ino + - examples/BHI260AP_Expand_GPIO/BHI260AP_Expand_GPIO.ino + - examples/BHI260AP_Orientation/BHI260AP_Orientation.ino + - examples/BHI260AP_StepCounter/BHI260AP_StepCounter.ino + - examples/BHI260AP_UpdateFirmware/BHI260AP_UpdateFirmware.ino + - examples/BMA423_Accelerometer/BMA423_Accelerometer.ino + - examples/BMA423_Feature/BMA423_Feature.ino + - examples/BMA423_Orientation/BMA423_Orientation.ino + - examples/BMA423_Temperature/BMA423_Temperature.ino + - examples/BMM150_GetDataExample/BMM150_GetDataExample.ino + - examples/CM32181_LightSensor/CM32181_LightSensor.ino + - examples/CM32181_LightSensorInterrupt/CM32181_LightSensorInterrupt.ino + - examples/CustomCallbackTouchDrvInterface/CustomCallbackTouchDrvInterface.ino + - examples/CustomCallbackUsageExamples/CustomCallbackUsageExamples.ino + - examples/DRV2605_Basic/DRV2605_Basic.ino + - examples/BQ27220_GaugeExample/BQ27220_GaugeExample.ino + - examples/LTR553ALS_Sensor/LTR553ALS_Sensor.ino + - examples/PCF85063_AlarmByUnits/PCF85063_AlarmByUnits.ino + - examples/PCF85063_ClockOutput/PCF85063_ClockOutput.ino + - examples/PCF85063_SimpleTime/PCF85063_SimpleTime.ino + - examples/PCF8563_AlarmByUnits/PCF8563_AlarmByUnits.ino + - examples/PCF8563_ClockOutput/PCF8563_ClockOutput.ino + - examples/PCF8563_SimpleTime/PCF8563_SimpleTime.ino + - examples/PCF8563_TimeLib/PCF8563_TimeLib.ino + - examples/PCF8563_TimeSynchronization/PCF8563_TimeSynchronization.ino + - examples/QMC6310_CalibrateExample/QMC6310_CalibrateExample.ino + - examples/QMC6310_CompassExample/QMC6310_CompassExample.ino + - examples/QMC6310_GetDataExample/QMC6310_GetDataExample.ino + - examples/QMC6310_GetPolarExample/QMC6310_GetPolarExample.ino + - examples/QMI8658_BlockExample/QMI8658_BlockExample.ino + - examples/QMI8658_CalibrationExample/QMI8658_CalibrationExample.ino + - examples/QMI8658_GetDataExample/QMI8658_GetDataExample.ino + - examples/QMI8658_InterruptBlockExample/QMI8658_InterruptBlockExample.ino + - examples/QMI8658_InterruptExample/QMI8658_InterruptExample.ino + - examples/QMI8658_LockingMechanismExample/QMI8658_LockingMechanismExample.ino + - examples/QMI8658_MadgwickAHRS/QMI8658_MadgwickAHRS.ino + - examples/QMI8658_MotionDetectionExample/QMI8658_MotionDetectionExample.ino + - examples/QMI8658_PedometerExample/QMI8658_PedometerExample.ino + - examples/QMI8658_ReadFromFifoExample/QMI8658_ReadFromFifoExample.ino + - examples/QMI8658_TapDetectionExample/QMI8658_TapDetectionExample.ino + - examples/QMI8658_WakeOnMotion/QMI8658_WakeOnMotion.ino + - examples/QMI8658_WakeOnMotionCallBackExample/QMI8658_WakeOnMotionCallBackExample.ino + - examples/SensorWireHelper/SensorWireHelper.ino + - examples/TouchDrvInterface_Example/TouchDrvInterface_Example.ino + - examples/TouchDrv_CHSC5816_GetPoint/TouchDrv_CHSC5816_GetPoint.ino + - examples/TouchDrv_CST9217_GetPoint/TouchDrv_CST9217_GetPoint.ino + - examples/TouchDrv_CSTxxx_GetPoint/TouchDrv_CSTxxx_GetPoint.ino + - examples/TouchDrv_FT6232_GetPoint/TouchDrv_FT6232_GetPoint.ino + - examples/TouchDrv_GT911_GetPoint/TouchDrv_GT911_GetPoint.ino + - examples/TouchDrv_GT9895_GetPoint/TouchDrv_GT9895_GetPoint.ino + - examples/XL9555_AdjustBacklight/XL9555_AdjustBacklight.ino + - examples/XL9555_ExtensionIOInterrupt/XL9555_ExtensionIOInterrupt.ino + - examples/XL9555_ExtensionIORead/XL9555_ExtensionIORead.ino + - examples/XL9555_ExtensionIOWrite/XL9555_ExtensionIOWrite.ino + - examples/XL9555_ioEvent/XL9555_ioEvent.ino env: BOARD: ${{ matrix.board }} EXAMPLES: ${{matrix.examples}} diff --git a/.github/workflows/esp-idf.yml b/.github/workflows/esp-idf.yml index bbf69b6..2bb334d 100644 --- a/.github/workflows/esp-idf.yml +++ b/.github/workflows/esp-idf.yml @@ -6,7 +6,8 @@ on: push: paths: - "src/**" - - "examples/ESP_IDF_TouchDrv_Example/**" + - "examples/ESP_IDF_TouchDrvExample/**" + - "examples/ESP_IDF_SensorExamples/**" - ".github/workflows/esp-idf.yml" jobs: @@ -21,9 +22,18 @@ jobs: - uses: actions/checkout@v3 with: submodules: "recursive" - - name: Build esp-idf examples + - name: Export ESP-IDF environment variables + shell: bash + run: . ${IDF_PATH}/export.sh + - name: Build ESP_IDF_TouchDrvExample + shell: bash + run: | + cd $GITHUB_WORKSPACE ; + cd examples/ESP_IDF_TouchDrvExample + idf.py build + - name: Build ESP_IDF_SensorExamples shell: bash run: | - . ${IDF_PATH}/export.sh - cd examples/ESP_IDF_TouchDrv_Example + cd $GITHUB_WORKSPACE ; + cd examples/ESP_IDF_SensorExamples idf.py build diff --git a/.github/workflows/pio.yml b/.github/workflows/pio.yml index bfab8e5..0db2334 100644 --- a/.github/workflows/pio.yml +++ b/.github/workflows/pio.yml @@ -16,63 +16,67 @@ jobs: strategy: matrix: example: - - examples/BMA423_Accelerometer - - examples/BMA423_Orientation - - examples/BMA423_Temperature - - examples/BMA423_Feature - - examples/BHI260AP_6DoF - - examples/BHI260AP_aux_BMM150 - - examples/BHI260AP_aux_BMM150_euler - - examples/BHI260AP_aux_BMM150_quaternion - - examples/BHI260AP_aux_BMM150_BME280 - - examples/BHI260AP_aux_BMM150_BME280_Expand_GPIO - - examples/BHI260AP_Expand_GPIO - - examples/BHI260AP_DebugInfo - - examples/BHI260AP_Orientation - - examples/BHI260AP_StepCounter - - examples/BMM150_GetDataExample - - examples/CM32181_LightSensor - - examples/CM32181_LightSensorInterrupt - - examples/DRV2605_Basic - - examples/LTR553ALS_Sensor - - examples/PCF85063_AlarmByUnits - - examples/PCF85063_SimpleTime - - examples/PCF8563_AlarmByUnits - - examples/PCF8563_SimpleTime - - examples/PCF8563_TimeLib - - examples/PCF8563_TimeSynchronization - - examples/QMC6310_CalibrateExample - - examples/QMC6310_CompassExample - - examples/QMC6310_GetDataExample - - examples/QMC6310_GetPolarExample - - examples/QMI8658_BlockExample - - examples/QMI8658_CalibrationExample - - examples/QMI8658_GetDataExample - - examples/QMI8658_InterruptBlockExample - - examples/QMI8658_InterruptExample - - examples/QMI8658_LockingMechanismExample - - examples/QMI8658_MadgwickAHRS - - examples/QMI8658_PedometerExample - - examples/QMI8658_ReadFromFifoExample - - examples/QMI8658_WakeOnMotion - - examples/QMI8658_WakeOnMotionCallBackExample - - examples/QMI8658_TapDetectionExample - - examples/QMI8658_MotionDetectionExample - - examples/TouchDrv_CHSC5816_GetPoint - - examples/TouchDrv_CST9217_GetPoint - - examples/TouchDrv_CSTxxx_GetPoint - - examples/TouchDrv_FT3267_LilyGo_T_RGB - - examples/TouchDrv_FT6232_GetPoint - - examples/TouchDrv_GT911_GetPoint - - examples/TouchDrv_GT911_LilyGo_T_RGB - - examples/TouchDrv_Interface_T_RGB - - examples/TouchDrv_GT9895_GetPoint - - examples/XL9555_ExtensionIOInterrupt - - examples/XL9555_ExtensionIORead - - examples/XL9555_ExtensionIOWrite - - examples/XL9555_ioEvent - - examples/XL9555_AdjustBacklight - - examples/AW9364_LedDriver + - examples/AW9364_LedDriver + - examples/BHI260AP_6DoF + - examples/BHI260AP_Expand_GPIO + - examples/BHI260AP_Orientation + - examples/BHI260AP_StepCounter + - examples/BHI260AP_UpdateFirmware + - examples/BHI260AP_aux_BMM150 + - examples/BHI260AP_aux_BMM150_BME280 + - examples/BHI260AP_aux_BMM150_BME280_Expand_GPIO + - examples/BHI260AP_aux_BMM150_euler + - examples/BHI260AP_aux_BMM150_quaternion + - examples/BMA423_Accelerometer + - examples/BMA423_Feature + - examples/BMA423_Orientation + - examples/BMA423_Temperature + - examples/BMM150_GetDataExample + - examples/CM32181_LightSensor + - examples/CM32181_LightSensorInterrupt + - examples/CustomCallbackTouchDrvInterface + - examples/CustomCallbackUsageExamples + - examples/DRV2605_Basic + - examples/BQ27220_GaugeExample + - examples/LTR553ALS_Sensor + - examples/PCF85063_AlarmByUnits + - examples/PCF85063_ClockOutput + - examples/PCF85063_SimpleTime + - examples/PCF8563_AlarmByUnits + - examples/PCF8563_ClockOutput + - examples/PCF8563_SimpleTime + - examples/PCF8563_TimeLib + - examples/PCF8563_TimeSynchronization + - examples/QMC6310_CalibrateExample + - examples/QMC6310_CompassExample + - examples/QMC6310_GetDataExample + - examples/QMC6310_GetPolarExample + - examples/QMI8658_BlockExample + - examples/QMI8658_CalibrationExample + - examples/QMI8658_GetDataExample + - examples/QMI8658_InterruptBlockExample + - examples/QMI8658_InterruptExample + - examples/QMI8658_LockingMechanismExample + - examples/QMI8658_MadgwickAHRS + - examples/QMI8658_MotionDetectionExample + - examples/QMI8658_PedometerExample + - examples/QMI8658_ReadFromFifoExample + - examples/QMI8658_TapDetectionExample + - examples/QMI8658_WakeOnMotion + - examples/QMI8658_WakeOnMotionCallBackExample + - examples/SensorWireHelper + - examples/TouchDrvInterface_Example + - examples/TouchDrv_CHSC5816_GetPoint + - examples/TouchDrv_CST9217_GetPoint + - examples/TouchDrv_CSTxxx_GetPoint + - examples/TouchDrv_FT6232_GetPoint + - examples/TouchDrv_GT911_GetPoint + - examples/TouchDrv_GT9895_GetPoint + - examples/XL9555_AdjustBacklight + - examples/XL9555_ExtensionIOInterrupt + - examples/XL9555_ExtensionIORead + - examples/XL9555_ExtensionIOWrite + - examples/XL9555_ioEvent steps: - uses: actions/checkout@v3 diff --git a/CMakeLists.txt b/CMakeLists.txt index 04dcf14..76f90a9 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,10 +1,19 @@ set(src_dirs ./src ./src/touch - ./src/platform) + ./src/platform + ./src/bosch + ./src/bosch/BMM150 + ./src/bosch/common + ) set(include_dirs ./src ./src/REG ./src/touch - ./src/platform) + ./src/platform + ./src/bosch + ./src/bosch/firmware + ./src/bosch/BMM150 + ./src/bosch/common) + idf_component_register(SRC_DIRS ${src_dirs} INCLUDE_DIRS ${include_dirs} REQUIRES esp_timer esp_driver_gpio driver) diff --git a/README.md b/README.md index b9a4e65..9b734c2 100644 --- a/README.md +++ b/README.md @@ -1,14 +1,6 @@ -```bash - _____ _ _ _ -/ ___| | | (_)| | -\ `--. ___ _ __ ___ ___ _ __ | | _ | |__ - `--. \ / _ \| '_ \ / __| / _ \ | '__|| | | || '_ \ -/\__/ /| __/| | | |\__ \| (_) || | | |____| || |_) | -\____/ \___||_| |_||___/ \___/ |_| \_____/|_||_.__/ - ··· ··· -> Commonly used I2C , SPI device multi-platform libraries -``` +
+ [![Build esp-idf](https://github.com/lewisxhe/SensorLib/actions/workflows/esp-idf.yml/badge.svg)](https://github.com/lewisxhe/SensorLib/actions/workflows/esp-idf.yml) [![Arduino CI](https://github.com/lewisxhe/SensorLib/actions/workflows/arduino_ci.yml/badge.svg)](https://github.com/lewisxhe/SensorLib/actions/workflows/arduino_ci.yml) @@ -22,55 +14,6 @@ [![STAR](https://img.shields.io/github/stars/lewisxhe/SensorsLib)](https://github.com/lewisxhe/SensorsLib/stargazers) [![releases](https://img.shields.io/github/release/lewisxhe/SensorsLib)](https://github.com/lewisxhe/SensorLib/releases) -## RTC - -![PCF8563](https://img.shields.io/badge/PCF8563-GREEN) -![PCF85063](https://img.shields.io/badge/PCF85063-GREEN) -![HYM8563](https://img.shields.io/badge/HYM8563-GREEN) - -## Motion Sensor - -![QMI8658](https://img.shields.io/badge/QMI8658-blue) -![BMM150](https://img.shields.io/badge/BMM150-blue) -![QMC6310](https://img.shields.io/badge/QMC6310-blue) -![BMA423](https://img.shields.io/badge/BMA423-blue) -![BHI260AP](https://img.shields.io/badge/BHI260AP-blue) - -## GPIO Expansion - -![XL9555](https://img.shields.io/badge/XL9555-yellow) -![XL9535](https://img.shields.io/badge/XL9535-yellow) - -## Haptic Driver - -![DRV2605](https://img.shields.io/badge/DRV2605-teal) - -## Light Sensor - -![CM32181](https://img.shields.io/badge/CM32181-brown) -![LTR553](https://img.shields.io/badge/LTR553-brown) - -## Touchpad - -![FT5206](https://img.shields.io/badge/FT5206-red) -![FT6206](https://img.shields.io/badge/FT6206-red) -![FT6236](https://img.shields.io/badge/FT6236-red) -![FT3267](https://img.shields.io/badge/FT3267-red) -![CST816S](https://img.shields.io/badge/CST816S-red) -![CST816D](https://img.shields.io/badge/CST816D-red) -![CST816T](https://img.shields.io/badge/CST816T-red) -![CST820](https://img.shields.io/badge/CST820-red) -![CST226SE](https://img.shields.io/badge/CST226SE-red) -![CHSC5816](https://img.shields.io/badge/CHSC5816-red) -![GT911](https://img.shields.io/badge/GT911-red) -![CST9217](https://img.shields.io/badge/CST9217-red) -![CST9220](https://img.shields.io/badge/CST9220-red) -![GT9895](https://img.shields.io/badge/GT9895-red) - -## LedDriver - -![AW9364](https://img.shields.io/badge/AW9364-pink) - Support list: | Sensor | Description | I2C | SPI | diff --git a/examples/BHI260AP_6DoF/BHI260AP_6DoF.ino b/examples/BHI260AP_6DoF/BHI260AP_6DoF.ino index f5695e2..446e019 100644 --- a/examples/BHI260AP_6DoF/BHI260AP_6DoF.ino +++ b/examples/BHI260AP_6DoF/BHI260AP_6DoF.ino @@ -32,22 +32,66 @@ #include #include "SensorBHI260AP.hpp" -#ifdef BHY2_USE_I2C -#define BHI260AP_SDA 21 -#define BHI260AP_SCL 22 -#define BHI260AP_IRQ 39 -#define BHI260AP_RST -1 -#else -#define BHI260AP_MOSI 33 -#define BHI260AP_MISO 34 -#define BHI260AP_SCK 35 -#define BHI260AP_CS 36 -#define BHI260AP_IRQ 37 -#define BHI260AP_RST 47 + +// #define USE_I2C_INTERFACE true +// #define USE_SPI_INTERFACE true + +#if !defined(USE_I2C_INTERFACE) && !defined(USE_SPI_INTERFACE) +#define USE_I2C_INTERFACE +#warning "No interface type is selected, use I2C interface" +#endif + +#if defined(USE_SPI_INTERFACE) +#ifndef SPI_MOSI +#define SPI_MOSI 33 +#endif + +#ifndef SPI_MISO +#define SPI_MISO 34 +#endif + +#ifndef SPI_SCK +#define SPI_SCK 35 +#endif + +#ifndef BHI260_IRQ +#define BHI260_IRQ 37 +#endif + +#ifndef BHI260_CS +#define BHI260_CS 36 +#endif + +#else //* I2C */ + +#ifndef BHI260_SDA +#define BHI260_SDA 2 +#endif + +#ifndef BHI260_SCL +#define BHI260_SCL 3 +#endif + +#ifndef BHI260_IRQ +#define BHI260_IRQ 8 +#endif +#endif /*USE_SPI_INTERFACE*/ + +#ifndef BHI260_RST +#define BHI260_RST -1 #endif SensorBHI260AP bhy; + +bool isReadyFlag = false; + +void dataReadyISR() +{ + isReadyFlag = true; +} + + void accel_process_callback(uint8_t sensor_id, uint8_t *data_ptr, uint32_t len, uint64_t *timestamp) { struct bhy2_data_xyz data; @@ -82,28 +126,30 @@ void setup() Serial.begin(115200); while (!Serial); - // Set the reset pin and interrupt pin, if any - bhy.setPins(BHI260AP_RST, BHI260AP_IRQ); + // Set the reset pin + bhy.setPins(BHI260_RST); Serial.println("Initializing Sensors..."); /*Set the default firmware, only 6 axes, no other functions*/ bhy.setFirmware(bhy2_firmware_image, sizeof(bhy2_firmware_image)); -#ifdef BHY2_USE_I2C +#ifdef USE_I2C_INTERFACE // Using I2C interface // BHI260AP_SLAVE_ADDRESS_L = 0x28 // BHI260AP_SLAVE_ADDRESS_H = 0x29 - if (!bhy.init(Wire, BHI260AP_SDA, BHI260AP_SCL, BHI260AP_SLAVE_ADDRESS_L)) { + if (!bhy.begin(Wire, BHI260AP_SLAVE_ADDRESS_L, BHI260_SDA, BHI260_SCL)) { Serial.print("Failed to initialize sensor - error code:"); Serial.println(bhy.getError()); while (1) { delay(1000); } } -#else +#endif + +#ifdef USE_SPI_INTERFACE // Using SPI interface - if (!bhy.init(SPI, BHI260AP_CS, BHI260AP_MOSI, BHI260AP_MISO, BHI260AP_SCK)) { + if (!bhy.begin(SPI, BHI260_CS, SPI_MOSI, SPI_MISO, SPI_SCK)) { Serial.print("Failed to initialize sensor - error code:"); Serial.println(bhy.getError()); while (1) { @@ -114,8 +160,9 @@ void setup() Serial.println("Initializing the sensor successfully!"); - // Output all available sensors to Serial - bhy.printSensors(Serial); + // Output all sensors info to Serial + BoschSensorInfo info = bhy.getSensorInfo(); + info.printInfo(Serial); float sample_rate = 100.0; /* Read out hintr_ctrl measured at 100Hz */ uint32_t report_latency_ms = 0; /* Report immediately */ @@ -131,13 +178,19 @@ void setup() // Set the gyroscope sensor result callback function bhy.onResultEvent(SENSOR_ID_GYRO_PASS, gyro_process_callback); + // Register interrupt function + pinMode(BHI260_IRQ, INPUT); + attachInterrupt(BHI260_IRQ, dataReadyISR, RISING); } void loop() { // Update sensor fifo - bhy.update(); + if (isReadyFlag) { + isReadyFlag = false; + bhy.update(); + } delay(50); } diff --git a/examples/BHI260AP_DebugInfo/BHI260AP_DebugInfo.ino b/examples/BHI260AP_DebugInfo/BHI260AP_DebugInfo.ino deleted file mode 100644 index b4c108a..0000000 --- a/examples/BHI260AP_DebugInfo/BHI260AP_DebugInfo.ino +++ /dev/null @@ -1,105 +0,0 @@ -/** - * - * @license MIT License - * - * Copyright (c) 2023 lewis he - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - * @file BHI260AP_DebugInfo.ino - * @author Lewis He (lewishe@outlook.com) - * @date 2023-10-08 - * @note Changed from Boschsensortec API https://github.com/boschsensortec/BHY2_SensorAPI - */ -#include -#include -#include -#include "SensorBHI260AP.hpp" - -#ifdef BHY2_USE_I2C -#define BHI260AP_SDA 21 -#define BHI260AP_SCL 22 -#define BHI260AP_IRQ 39 -#define BHI260AP_RST -1 -#else -#define BHI260AP_MOSI 33 -#define BHI260AP_MISO 34 -#define BHI260AP_SCK 35 -#define BHI260AP_CS 36 -#define BHI260AP_IRQ 37 -#define BHI260AP_RST 47 -#endif - -SensorBHI260AP bhy; - - -void setup() -{ - Serial.begin(115200); - while (!Serial); - - - // Set the reset pin and interrupt pin, if any - bhy.setPins(BHI260AP_RST, BHI260AP_IRQ); - - Serial.println("Initializing Sensors..."); - - /*Set the default firmware, only 6 axes, no other functions*/ - bhy.setFirmware(bhy2_firmware_image, sizeof(bhy2_firmware_image)); - -#ifdef BHY2_USE_I2C - // Using I2C interface - // BHI260AP_SLAVE_ADDRESS_L = 0x28 - // BHI260AP_SLAVE_ADDRESS_H = 0x29 - if (!bhy.init(Wire, BHI260AP_SDA, BHI260AP_SCL, BHI260AP_SLAVE_ADDRESS_L)) { - Serial.print("Failed to initialize sensor - error code:"); - Serial.println(bhy.getError()); - while (1) { - delay(1000); - } - } -#else - // Using SPI interface - if (!bhy.init(SPI, BHI260AP_CS, BHI260AP_MOSI, BHI260AP_MISO, BHI260AP_SCK)) { - Serial.print("Failed to initialize sensor - error code:"); - Serial.println(bhy.getError()); - while (1) { - delay(1000); - } - } -#endif - - Serial.println("Initializing the sensor successfully!"); - - - // Output all current sensor information - bhy.printInfo(Serial); - - // Output interrupt configuration information to Serial - bhy.printInterruptCtrl(Serial); -} - - -void loop() -{ - // Update sensor fifo - bhy.update(); - delay(50); -} - diff --git a/examples/BHI260AP_Expand_GPIO/BHI260AP_Expand_GPIO.ino b/examples/BHI260AP_Expand_GPIO/BHI260AP_Expand_GPIO.ino index 84d276b..8043eda 100644 --- a/examples/BHI260AP_Expand_GPIO/BHI260AP_Expand_GPIO.ino +++ b/examples/BHI260AP_Expand_GPIO/BHI260AP_Expand_GPIO.ino @@ -68,50 +68,92 @@ const size_t fw_size = sizeof(bhy2_gpio_firmware_image); * RESV3 = N.A ! INVALID PIN * */ -#ifdef BHY2_USE_I2C -#define BHI260AP_SDA 21 -#define BHI260AP_SCL 22 -#define BHI260AP_IRQ 39 -#define BHI260AP_RST -1 -#else -#define BHI260AP_MOSI 27 -#define BHI260AP_MISO 46 -#define BHI260AP_SCK 3 -#define BHI260AP_CS 28 -#define BHI260AP_IRQ 30 -#define BHI260AP_RST -1 +// #define USE_I2C_INTERFACE true +// #define USE_SPI_INTERFACE true + +#if !defined(USE_I2C_INTERFACE) && !defined(USE_SPI_INTERFACE) +#define USE_I2C_INTERFACE +#warning "No interface type is selected, use I2C interface" +#endif + +#if defined(USE_SPI_INTERFACE) +#ifndef SPI_MOSI +#define SPI_MOSI 33 +#endif + +#ifndef SPI_MISO +#define SPI_MISO 34 +#endif + +#ifndef SPI_SCK +#define SPI_SCK 35 +#endif + +#ifndef BHI260_IRQ +#define BHI260_IRQ 37 +#endif + +#ifndef BHI260_CS +#define BHI260_CS 36 +#endif + +#else //* I2C */ + +#ifndef BHI260_SDA +#define BHI260_SDA 2 +#endif + +#ifndef BHI260_SCL +#define BHI260_SCL 3 +#endif + +#ifndef BHI260_IRQ +#define BHI260_IRQ 8 +#endif +#endif /*USE_SPI_INTERFACE*/ + +#ifndef BHI260_RST +#define BHI260_RST -1 #endif SensorBHI260AP bhy; +bool isReadyFlag = false; + +void dataReadyISR() +{ + isReadyFlag = true; +} + void setup() { Serial.begin(115200); while (!Serial); - // Set the reset pin and interrupt pin, if any - bhy.setPins(BHI260AP_RST, BHI260AP_IRQ); + // Set the reset pin + bhy.setPins(BHI260_RST); // Set the firmware array address and firmware size bhy.setFirmware(firmware, fw_size, false); // Set to load firmware from RAM bhy.setBootFromFlash(false); Serial.println("Initializing Sensors..."); - -#ifdef BHY2_USE_I2C +#ifdef USE_I2C_INTERFACE // Using I2C interface // BHI260AP_SLAVE_ADDRESS_L = 0x28 // BHI260AP_SLAVE_ADDRESS_H = 0x29 - if (!bhy.init(Wire, BHI260AP_SDA, BHI260AP_SCL, BHI260AP_SLAVE_ADDRESS_L)) { + if (!bhy.begin(Wire, BHI260AP_SLAVE_ADDRESS_L, BHI260_SDA, BHI260_SCL)) { Serial.print("Failed to initialize sensor - error code:"); Serial.println(bhy.getError()); while (1) { delay(1000); } } -#else +#endif + +#ifdef USE_SPI_INTERFACE // Using SPI interface - if (!bhy.init(SPI, BHI260AP_CS, BHI260AP_MOSI, BHI260AP_MISO, BHI260AP_SCK)) { + if (!bhy.begin(SPI, BHI260_CS, SPI_MOSI, SPI_MISO, SPI_SCK)) { Serial.print("Failed to initialize sensor - error code:"); Serial.println(bhy.getError()); while (1) { @@ -122,17 +164,19 @@ void setup() Serial.println("Initializing the sensor successfully!"); - // Output all current sensor information - bhy.printInfo(Serial); - - // Output interrupt configuration information to Serial - bhy.printInterruptCtrl(Serial); + // Output all sensors info to Serial + BoschSensorInfo info = bhy.getSensorInfo(); + info.printInfo(Serial); initialiseCommander(); Serial.println("Hello: Type 'help' to get help"); cmd.printCommandPrompt(); + + // Register interrupt function + pinMode(BHI260_IRQ, INPUT); + attachInterrupt(BHI260_IRQ, dataReadyISR, RISING); } uint32_t check_millis = 0; @@ -142,7 +186,10 @@ void loop() //Call the update functions using the activeCommander pointer cmd.update(); // Update sensor fifo - bhy.update(); + if (isReadyFlag) { + isReadyFlag = false; + bhy.update(); + } } diff --git a/examples/BHI260AP_Orientation/BHI260AP_Orientation.ino b/examples/BHI260AP_Orientation/BHI260AP_Orientation.ino index e6ba460..82f3b33 100644 --- a/examples/BHI260AP_Orientation/BHI260AP_Orientation.ino +++ b/examples/BHI260AP_Orientation/BHI260AP_Orientation.ino @@ -32,53 +32,95 @@ #include #include "SensorBHI260AP.hpp" -#ifdef BHY2_USE_I2C -#define BHI260AP_SDA 21 -#define BHI260AP_SCL 22 -#define BHI260AP_IRQ 39 -#define BHI260AP_RST -1 -#else -#define BHI260AP_MOSI 33 -#define BHI260AP_MISO 34 -#define BHI260AP_SCK 35 -#define BHI260AP_CS 36 -#define BHI260AP_IRQ 37 -#define BHI260AP_RST 47 +// #define USE_I2C_INTERFACE true +// #define USE_SPI_INTERFACE true + +#if !defined(USE_I2C_INTERFACE) && !defined(USE_SPI_INTERFACE) +#define USE_I2C_INTERFACE +#warning "No interface type is selected, use I2C interface" +#endif + +#if defined(USE_SPI_INTERFACE) +#ifndef SPI_MOSI +#define SPI_MOSI 33 +#endif + +#ifndef SPI_MISO +#define SPI_MISO 34 +#endif + +#ifndef SPI_SCK +#define SPI_SCK 35 +#endif + +#ifndef BHI260_IRQ +#define BHI260_IRQ 37 +#endif + +#ifndef BHI260_CS +#define BHI260_CS 36 +#endif + +#else //* I2C */ + +#ifndef BHI260_SDA +#define BHI260_SDA 2 +#endif + +#ifndef BHI260_SCL +#define BHI260_SCL 3 +#endif + +#ifndef BHI260_IRQ +#define BHI260_IRQ 8 +#endif +#endif /*USE_SPI_INTERFACE*/ + +#ifndef BHI260_RST +#define BHI260_RST -1 #endif void orientation_process_callback(uint8_t sensor_id, uint8_t *data_ptr, uint32_t len, uint64_t *timestamp); SensorBHI260AP bhy; +bool isReadyFlag = false; + +void dataReadyISR() +{ + isReadyFlag = true; +} + void setup() { Serial.begin(115200); while (!Serial); - - // Set the reset pin and interrupt pin, if any - bhy.setPins(BHI260AP_RST, BHI260AP_IRQ); + // Set the reset pin + bhy.setPins(BHI260_RST); Serial.println("Initializing Sensors..."); /*Set the default firmware, only 6 axes, no other functions*/ bhy.setFirmware(bhy2_firmware_image, sizeof(bhy2_firmware_image)); - -#ifdef BHY2_USE_I2C + +#ifdef USE_I2C_INTERFACE // Using I2C interface // BHI260AP_SLAVE_ADDRESS_L = 0x28 // BHI260AP_SLAVE_ADDRESS_H = 0x29 - if (!bhy.init(Wire, BHI260AP_SDA, BHI260AP_SCL, BHI260AP_SLAVE_ADDRESS_L)) { - Serial.print("Failed to init BHI260AP - "); + if (!bhy.begin(Wire, BHI260AP_SLAVE_ADDRESS_L, BHI260_SDA, BHI260_SCL)) { + Serial.print("Failed to initialize sensor - error code:"); Serial.println(bhy.getError()); while (1) { delay(1000); } } -#else +#endif + +#ifdef USE_SPI_INTERFACE // Using SPI interface - if (!bhy.init(SPI, BHI260AP_CS, BHI260AP_MOSI, BHI260AP_MISO, BHI260AP_SCK)) { - Serial.print("Failed to init BHI260AP - "); + if (!bhy.begin(SPI, BHI260_CS, SPI_MOSI, SPI_MISO, SPI_SCK)) { + Serial.print("Failed to initialize sensor - error code:"); Serial.println(bhy.getError()); while (1) { delay(1000); @@ -88,8 +130,9 @@ void setup() Serial.println("Init BHI260AP Sensor success!"); - // Output all available sensors to Serial - bhy.printSensors(Serial); + // Output all sensors info to Serial + BoschSensorInfo info = bhy.getSensorInfo(); + info.printInfo(Serial); float sample_rate = 100.0; /* Read out hintr_ctrl measured at 100Hz */ uint32_t report_latency_ms = 0; /* Report immediately */ @@ -100,13 +143,20 @@ void setup() bhy.configure(SENSOR_ID_DEVICE_ORI, sample_rate, report_latency_ms); // Set the direction detection result output processing function bhy.onResultEvent(SENSOR_ID_DEVICE_ORI, orientation_process_callback); + + // Register interrupt function + pinMode(BHI260_IRQ, INPUT); + attachInterrupt(BHI260_IRQ, dataReadyISR, RISING); } void loop() { // Update sensor fifo - bhy.update(); + if (isReadyFlag) { + isReadyFlag = false; + bhy.update(); + } delay(50); } diff --git a/examples/BHI260AP_StepCounter/BHI260AP_StepCounter.ino b/examples/BHI260AP_StepCounter/BHI260AP_StepCounter.ino index 2582598..ded50c8 100644 --- a/examples/BHI260AP_StepCounter/BHI260AP_StepCounter.ino +++ b/examples/BHI260AP_StepCounter/BHI260AP_StepCounter.ino @@ -32,22 +32,62 @@ #include #include "SensorBHI260AP.hpp" -#ifdef BHY2_USE_I2C -#define BHI260AP_SDA 21 -#define BHI260AP_SCL 22 -#define BHI260AP_IRQ 39 -#define BHI260AP_RST -1 -#else -#define BHI260AP_MOSI 33 -#define BHI260AP_MISO 34 -#define BHI260AP_SCK 35 -#define BHI260AP_CS 36 -#define BHI260AP_IRQ 37 -#define BHI260AP_RST 47 +// #define USE_I2C_INTERFACE true +// #define USE_SPI_INTERFACE true + +#if !defined(USE_I2C_INTERFACE) && !defined(USE_SPI_INTERFACE) +#define USE_I2C_INTERFACE +#warning "No interface type is selected, use I2C interface" +#endif + +#if defined(USE_SPI_INTERFACE) +#ifndef SPI_MOSI +#define SPI_MOSI 33 +#endif + +#ifndef SPI_MISO +#define SPI_MISO 34 +#endif + +#ifndef SPI_SCK +#define SPI_SCK 35 +#endif + +#ifndef BHI260_IRQ +#define BHI260_IRQ 37 +#endif + +#ifndef BHI260_CS +#define BHI260_CS 36 +#endif + +#else //* I2C */ + +#ifndef BHI260_SDA +#define BHI260_SDA 2 +#endif + +#ifndef BHI260_SCL +#define BHI260_SCL 3 +#endif + +#ifndef BHI260_IRQ +#define BHI260_IRQ 8 +#endif +#endif /*USE_SPI_INTERFACE*/ + +#ifndef BHI260_RST +#define BHI260_RST -1 #endif SensorBHI260AP bhy; +bool isReadyFlag = false; + +void dataReadyISR() +{ + isReadyFlag = true; +} void step_detector_process_callback(uint8_t sensor_id, uint8_t *data_ptr, uint32_t len, uint64_t *timestamp) { @@ -69,28 +109,30 @@ void setup() while (!Serial); - // Set the reset pin and interrupt pin, if any - bhy.setPins(BHI260AP_RST, BHI260AP_IRQ); + // Set the reset pin + bhy.setPins(BHI260_RST); Serial.println("Initializing Sensors..."); /*Set the default firmware, only 6 axes, no other functions*/ bhy.setFirmware(bhy2_firmware_image, sizeof(bhy2_firmware_image)); -#ifdef BHY2_USE_I2C +#ifdef USE_I2C_INTERFACE // Using I2C interface // BHI260AP_SLAVE_ADDRESS_L = 0x28 // BHI260AP_SLAVE_ADDRESS_H = 0x29 - if (!bhy.init(Wire, BHI260AP_SDA, BHI260AP_SCL, BHI260AP_SLAVE_ADDRESS_L)) { + if (!bhy.begin(Wire, BHI260AP_SLAVE_ADDRESS_L, BHI260_SDA, BHI260_SCL)) { Serial.print("Failed to initialize sensor - error code:"); Serial.println(bhy.getError()); while (1) { delay(1000); } } -#else +#endif + +#ifdef USE_SPI_INTERFACE // Using SPI interface - if (!bhy.init(SPI, BHI260AP_CS, BHI260AP_MOSI, BHI260AP_MISO, BHI260AP_SCK)) { + if (!bhy.begin(SPI, BHI260_CS, SPI_MOSI, SPI_MISO, SPI_SCK)) { Serial.print("Failed to initialize sensor - error code:"); Serial.println(bhy.getError()); while (1) { @@ -101,8 +143,9 @@ void setup() Serial.println("Initializing the sensor successfully!"); - // Output all available sensors to Serial - bhy.printSensors(Serial); + // Output all sensors info to Serial + BoschSensorInfo info = bhy.getSensorInfo(); + info.printInfo(Serial); float sample_rate = 100.0; /* Read out hintr_ctrl measured at 100Hz */ uint32_t report_latency_ms = 0; /* Report immediately */ @@ -117,13 +160,20 @@ void setup() // Set the number of steps to detect the callback function bhy.onResultEvent(SENSOR_ID_STD, step_detector_process_callback); bhy.onResultEvent(SENSOR_ID_STC, step_counter_process_callback); + + // Register interrupt function + pinMode(BHI260_IRQ, INPUT); + attachInterrupt(BHI260_IRQ, dataReadyISR, RISING); } void loop() { // Update sensor fifo - bhy.update(); + if (isReadyFlag) { + isReadyFlag = false; + bhy.update(); + } delay(50); } diff --git a/examples/BHI260AP_UpdateFirmware/BHI260AP_UpdateFirmware.ino b/examples/BHI260AP_UpdateFirmware/BHI260AP_UpdateFirmware.ino index 5817373..d6f661a 100644 --- a/examples/BHI260AP_UpdateFirmware/BHI260AP_UpdateFirmware.ino +++ b/examples/BHI260AP_UpdateFirmware/BHI260AP_UpdateFirmware.ino @@ -36,18 +36,52 @@ #include //Deplib https://github.com/adafruit/SdFat.git #include -#ifdef BHY2_USE_I2C -#define BHI260AP_SDA 21 -#define BHI260AP_SCL 22 -#define BHI260AP_IRQ 39 -#define BHI260AP_RST -1 -#else -#define BHI260AP_MOSI 27 -#define BHI260AP_MISO 46 -#define BHI260AP_SCK 3 -#define BHI260AP_CS 28 -#define BHI260AP_IRQ 30 -#define BHI260AP_RST -1 +// #define USE_I2C_INTERFACE true +// #define USE_SPI_INTERFACE true + +#if !defined(USE_I2C_INTERFACE) && !defined(USE_SPI_INTERFACE) +#define USE_I2C_INTERFACE +#warning "No interface type is selected, use I2C interface" +#endif + +#if defined(USE_SPI_INTERFACE) +#ifndef SPI_MOSI +#define SPI_MOSI 33 +#endif + +#ifndef SPI_MISO +#define SPI_MISO 34 +#endif + +#ifndef SPI_SCK +#define SPI_SCK 35 +#endif + +#ifndef BHI260_IRQ +#define BHI260_IRQ 37 +#endif + +#ifndef BHI260_CS +#define BHI260_CS 36 +#endif + +#else //* I2C */ + +#ifndef BHI260_SDA +#define BHI260_SDA 2 +#endif + +#ifndef BHI260_SCL +#define BHI260_SCL 3 +#endif + +#ifndef BHI260_IRQ +#define BHI260_IRQ 8 +#endif +#endif /*USE_SPI_INTERFACE*/ + +#ifndef BHI260_RST +#define BHI260_RST -1 #endif SensorBHI260AP bhy; @@ -67,6 +101,12 @@ SdFat32 sd; #define error(s) sd.errorHalt(&Serial, F(s)) #define SD_CONFIG SdSpiConfig(CS_PIN, DEDICATED_SPI, SPI_CLOCK) +bool isReadyFlag = false; + +void dataReadyISR() +{ + isReadyFlag = true; +} void parse_bme280_sensor_data(uint8_t sensor_id, uint8_t *data_ptr, uint32_t len, uint64_t *timestamp) { @@ -100,7 +140,7 @@ void setup() while (!Serial); // In this example, BHI260 and SD Card are on the same SPI bus - SPI.setPins(BHI260AP_MISO, BHI260AP_SCK, BHI260AP_MOSI); + SPI.setPins(SPI_MISO, SPI_SCK, SPI_MOSI); SPI.begin(); @@ -137,7 +177,7 @@ void setup() Serial.println("malloc memory failed!"); while (1); } - + firmware_file.readBytes(firmware, fw_size); firmware_file.close(); @@ -147,8 +187,8 @@ void setup() * BHI260 Initializing ***************************************/ Serial.println("Initializing Sensors..."); - // Set the reset pin and interrupt pin, if any - bhy.setPins(BHI260AP_RST, BHI260AP_IRQ); + // Set the reset pin + bhy.setPins(BHI260_RST); // Force update of the current firmware, regardless of whether it exists. // After uploading the firmware once, you can change it to false to speed up the startup time. bool force_update = true; @@ -159,20 +199,22 @@ void setup() // Set to load firmware from flash or ram bhy.setBootFromFlash(write_to_flash); -#ifdef BHY2_USE_I2C +#ifdef USE_I2C_INTERFACE // Using I2C interface // BHI260AP_SLAVE_ADDRESS_L = 0x28 // BHI260AP_SLAVE_ADDRESS_H = 0x29 - if (!bhy.init(Wire, BHI260AP_SDA, BHI260AP_SCL, BHI260AP_SLAVE_ADDRESS_L)) { + if (!bhy.begin(Wire, BHI260AP_SLAVE_ADDRESS_L, BHI260_SDA, BHI260_SCL)) { Serial.print("Failed to initialize sensor - error code:"); Serial.println(bhy.getError()); while (1) { delay(1000); } } -#else +#endif + +#ifdef USE_SPI_INTERFACE // Using SPI interface - if (!bhy.init(SPI, BHI260AP_CS, BHI260AP_MOSI, BHI260AP_MISO, BHI260AP_SCK)) { + if (!bhy.begin(SPI, BHI260_CS, SPI_MOSI, SPI_MISO, SPI_SCK)) { Serial.print("Failed to initialize sensor - error code:"); Serial.println(bhy.getError()); while (1) { @@ -186,11 +228,10 @@ void setup() Serial.println("Initializing the sensor successfully!"); - // Output all current sensor information - bhy.printInfo(Serial); + // Output all sensors info to Serial + BoschSensorInfo info = bhy.getSensorInfo(); + info.printInfo(Serial); - // Output interrupt configuration information to Serial - bhy.printInterruptCtrl(Serial); /* * Enable monitoring. @@ -213,12 +254,20 @@ void setup() bhy.onResultEvent(SENSOR_ID_TEMP, parse_bme280_sensor_data); bhy.onResultEvent(SENSOR_ID_HUM, parse_bme280_sensor_data); bhy.onResultEvent(SENSOR_ID_BARO, parse_bme280_sensor_data); + + // Register interrupt function + pinMode(BHI260_IRQ, INPUT); + attachInterrupt(BHI260_IRQ, dataReadyISR, RISING); } void loop() { // Update sensor fifo - bhy.update(); + if (isReadyFlag) { + isReadyFlag = false; + bhy.update(); + } + delay(50); } #else void setup() {} diff --git a/examples/BHI260AP_aux_BMM150/BHI260AP_aux_BMM150.ino b/examples/BHI260AP_aux_BMM150/BHI260AP_aux_BMM150.ino index 9a9ae79..f3f23c5 100644 --- a/examples/BHI260AP_aux_BMM150/BHI260AP_aux_BMM150.ino +++ b/examples/BHI260AP_aux_BMM150/BHI260AP_aux_BMM150.ino @@ -32,6 +32,55 @@ #include #include "SensorBHI260AP.hpp" + +// #define USE_I2C_INTERFACE true +// #define USE_SPI_INTERFACE true + +#if !defined(USE_I2C_INTERFACE) && !defined(USE_SPI_INTERFACE) +#define USE_I2C_INTERFACE +#warning "No interface type is selected, use I2C interface" +#endif + +#if defined(USE_SPI_INTERFACE) +#ifndef SPI_MOSI +#define SPI_MOSI 33 +#endif + +#ifndef SPI_MISO +#define SPI_MISO 34 +#endif + +#ifndef SPI_SCK +#define SPI_SCK 35 +#endif + +#ifndef BHI260_IRQ +#define BHI260_IRQ 37 +#endif + +#ifndef BHI260_CS +#define BHI260_CS 36 +#endif + +#else //* I2C */ + +#ifndef BHI260_SDA +#define BHI260_SDA 2 +#endif + +#ifndef BHI260_SCL +#define BHI260_SCL 3 +#endif + +#ifndef BHI260_IRQ +#define BHI260_IRQ 8 +#endif +#endif /*USE_SPI_INTERFACE*/ + +#ifndef BHI260_RST +#define BHI260_RST -1 +#endif + /* Write the firmware containing the BMM150 magnetometer function into the flash. This function requires the BHI260AP external SPI Flash. @@ -53,23 +102,15 @@ const uint8_t *firmware = bhi26ap_aux_bmm150_fw; const size_t fw_size = sizeof(bhi26ap_aux_bmm150_fw); #endif -#ifdef BHY2_USE_I2C -#define BHI260AP_SDA 21 -#define BHI260AP_SCL 22 -#define BHI260AP_IRQ 39 -#define BHI260AP_RST -1 -#else -#define BHI260AP_MOSI 27 -#define BHI260AP_MISO 46 -#define BHI260AP_SCK 3 -#define BHI260AP_CS 28 -#define BHI260AP_IRQ 30 -#define BHI260AP_RST -1 -#endif - SensorBHI260AP bhy; +bool isReadyFlag = false; + +void dataReadyISR() +{ + isReadyFlag = true; +} void bhy_process_callback(uint8_t sensor_id, uint8_t *data_ptr, uint32_t len, uint64_t *timestamp) { @@ -91,8 +132,8 @@ void setup() Serial.begin(115200); while (!Serial); - // Set the reset pin and interrupt pin, if any - bhy.setPins(BHI260AP_RST, BHI260AP_IRQ); + // Set the reset pin + bhy.setPins(BHI260_RST); // Force update of the current firmware, regardless of whether it exists. // After uploading the firmware once, you can change it to false to speed up the startup time. @@ -106,20 +147,23 @@ void setup() #endif Serial.println("Initializing Sensors..."); -#ifdef BHY2_USE_I2C + +#ifdef USE_I2C_INTERFACE // Using I2C interface // BHI260AP_SLAVE_ADDRESS_L = 0x28 // BHI260AP_SLAVE_ADDRESS_H = 0x29 - if (!bhy.init(Wire, BHI260AP_SDA, BHI260AP_SCL, BHI260AP_SLAVE_ADDRESS_L)) { + if (!bhy.begin(Wire, BHI260AP_SLAVE_ADDRESS_L, BHI260_SDA, BHI260_SCL)) { Serial.print("Failed to initialize sensor - error code:"); Serial.println(bhy.getError()); while (1) { delay(1000); } } -#else +#endif + +#ifdef USE_SPI_INTERFACE // Using SPI interface - if (!bhy.init(SPI, BHI260AP_CS, BHI260AP_MOSI, BHI260AP_MISO, BHI260AP_SCK)) { + if (!bhy.begin(SPI, BHI260_CS, SPI_MOSI, SPI_MISO, SPI_SCK)) { Serial.print("Failed to initialize sensor - error code:"); Serial.println(bhy.getError()); while (1) { @@ -130,8 +174,9 @@ void setup() Serial.println("Initializing the sensor successfully!"); - // Output all available sensors to Serial - bhy.printSensors(Serial); + // Output all sensors info to Serial + BoschSensorInfo info = bhy.getSensorInfo(); + info.printInfo(Serial); float sample_rate = 100.0; /* Read out hintr_ctrl measured at 100Hz */ uint32_t report_latency_ms = 0; /* 0 = report immediately */ @@ -157,13 +202,19 @@ void setup() // Set the magnetometer sensor result callback function bhy.onResultEvent(SENSOR_ID_MAG_PASS, bhy_process_callback); + // Register interrupt function + pinMode(BHI260_IRQ, INPUT); + attachInterrupt(BHI260_IRQ, dataReadyISR, RISING); } void loop() { // Update sensor fifo - bhy.update(); + if (isReadyFlag) { + isReadyFlag = false; + bhy.update(); + } delay(50); } diff --git a/examples/BHI260AP_aux_BMM150_BME280/BHI260AP_aux_BMM150_BME280.ino b/examples/BHI260AP_aux_BMM150_BME280/BHI260AP_aux_BMM150_BME280.ino index 21c23e7..f3d8d92 100644 --- a/examples/BHI260AP_aux_BMM150_BME280/BHI260AP_aux_BMM150_BME280.ino +++ b/examples/BHI260AP_aux_BMM150_BME280/BHI260AP_aux_BMM150_BME280.ino @@ -53,23 +53,62 @@ const uint8_t *firmware = bhi26ap_aux_bmm150_bme280_fw; const size_t fw_size = sizeof(bhi26ap_aux_bmm150_bme280_fw); #endif -#ifdef BHY2_USE_I2C -#define BHI260AP_SDA 21 -#define BHI260AP_SCL 22 -#define BHI260AP_IRQ 39 -#define BHI260AP_RST -1 -#else -#define BHI260AP_MOSI 27 -#define BHI260AP_MISO 46 -#define BHI260AP_SCK 3 -#define BHI260AP_CS 28 -#define BHI260AP_IRQ 30 -#define BHI260AP_RST -1 +// #define USE_I2C_INTERFACE true +// #define USE_SPI_INTERFACE true + +#if !defined(USE_I2C_INTERFACE) && !defined(USE_SPI_INTERFACE) +#define USE_I2C_INTERFACE +#warning "No interface type is selected, use I2C interface" +#endif + +#if defined(USE_SPI_INTERFACE) +#ifndef SPI_MOSI +#define SPI_MOSI 33 +#endif + +#ifndef SPI_MISO +#define SPI_MISO 34 +#endif + +#ifndef SPI_SCK +#define SPI_SCK 35 +#endif + +#ifndef BHI260_IRQ +#define BHI260_IRQ 37 +#endif + +#ifndef BHI260_CS +#define BHI260_CS 36 +#endif + +#else //* I2C */ + +#ifndef BHI260_SDA +#define BHI260_SDA 2 +#endif + +#ifndef BHI260_SCL +#define BHI260_SCL 3 #endif +#ifndef BHI260_IRQ +#define BHI260_IRQ 8 +#endif +#endif /*USE_SPI_INTERFACE*/ + +#ifndef BHI260_RST +#define BHI260_RST -1 +#endif SensorBHI260AP bhy; +bool isReadyFlag = false; + +void dataReadyISR() +{ + isReadyFlag = true; +} void parse_bme280_sensor_data(uint8_t sensor_id, uint8_t *data_ptr, uint32_t len, uint64_t *timestamp) { @@ -100,8 +139,8 @@ void setup() Serial.begin(115200); while (!Serial); - // Set the reset pin and interrupt pin, if any - bhy.setPins(BHI260AP_RST, BHI260AP_IRQ); + // Set the reset pin + bhy.setPins(BHI260_RST); // Force update of the current firmware, regardless of whether it exists. // After uploading the firmware once, you can change it to false to speed up the startup time. @@ -113,21 +152,22 @@ void setup() bhy.setBootFromFlash(WRITE_TO_FLASH); Serial.println("Initializing Sensors..."); -#ifdef BHY2_USE_I2C +#ifdef USE_I2C_INTERFACE // Using I2C interface // BHI260AP_SLAVE_ADDRESS_L = 0x28 // BHI260AP_SLAVE_ADDRESS_H = 0x29 - Serial.println(""); - if (!bhy.init(Wire, BHI260AP_SDA, BHI260AP_SCL, BHI260AP_SLAVE_ADDRESS_L)) { + if (!bhy.begin(Wire, BHI260AP_SLAVE_ADDRESS_L, BHI260_SDA, BHI260_SCL)) { Serial.print("Failed to initialize sensor - error code:"); Serial.println(bhy.getError()); while (1) { delay(1000); } } -#else +#endif + +#ifdef USE_SPI_INTERFACE // Using SPI interface - if (!bhy.init(SPI, BHI260AP_CS, BHI260AP_MOSI, BHI260AP_MISO, BHI260AP_SCK)) { + if (!bhy.begin(SPI, BHI260_CS, SPI_MOSI, SPI_MISO, SPI_SCK)) { Serial.print("Failed to initialize sensor - error code:"); Serial.println(bhy.getError()); while (1) { @@ -138,8 +178,9 @@ void setup() Serial.println("Initializing the sensor successfully!"); - // Output all available sensors to Serial - bhy.printSensors(Serial); + // Output all sensors info to Serial + BoschSensorInfo info = bhy.getSensorInfo(); + info.printInfo(Serial); /* * Enable monitoring. @@ -168,13 +209,20 @@ void setup() bhy.onResultEvent(SENSOR_ID_TEMP, parse_bme280_sensor_data); bhy.onResultEvent(SENSOR_ID_HUM, parse_bme280_sensor_data); bhy.onResultEvent(SENSOR_ID_BARO, parse_bme280_sensor_data); + + // Register interrupt function + pinMode(BHI260_IRQ, INPUT); + attachInterrupt(BHI260_IRQ, dataReadyISR, RISING); } void loop() { // Update sensor fifo - bhy.update(); + if (isReadyFlag) { + isReadyFlag = false; + bhy.update(); + } delay(50); } diff --git a/examples/BHI260AP_aux_BMM150_BME280_Expand_GPIO/BHI260AP_aux_BMM150_BME280_Expand_GPIO.ino b/examples/BHI260AP_aux_BMM150_BME280_Expand_GPIO/BHI260AP_aux_BMM150_BME280_Expand_GPIO.ino index 659c0b9..70cde85 100644 --- a/examples/BHI260AP_aux_BMM150_BME280_Expand_GPIO/BHI260AP_aux_BMM150_BME280_Expand_GPIO.ino +++ b/examples/BHI260AP_aux_BMM150_BME280_Expand_GPIO/BHI260AP_aux_BMM150_BME280_Expand_GPIO.ino @@ -79,22 +79,63 @@ const size_t fw_size = sizeof(BHI260AP_aux_BMM150_BME280_GPIO); * RESV3 = N.A ! INVALID PIN * */ -#ifdef BHY2_USE_I2C -#define BHI260AP_SDA 21 -#define BHI260AP_SCL 22 -#define BHI260AP_IRQ 39 -#define BHI260AP_RST -1 -#else -#define BHI260AP_MOSI 27 -#define BHI260AP_MISO 46 -#define BHI260AP_SCK 3 -#define BHI260AP_CS 28 -#define BHI260AP_IRQ 30 -#define BHI260AP_RST -1 +// #define USE_I2C_INTERFACE true +// #define USE_SPI_INTERFACE true + +#if !defined(USE_I2C_INTERFACE) && !defined(USE_SPI_INTERFACE) +#define USE_I2C_INTERFACE +#warning "No interface type is selected, use I2C interface" +#endif + +#if defined(USE_SPI_INTERFACE) +#ifndef SPI_MOSI +#define SPI_MOSI 33 +#endif + +#ifndef SPI_MISO +#define SPI_MISO 34 +#endif + +#ifndef SPI_SCK +#define SPI_SCK 35 +#endif + +#ifndef BHI260_IRQ +#define BHI260_IRQ 37 +#endif + +#ifndef BHI260_CS +#define BHI260_CS 36 +#endif + +#else //* I2C */ + +#ifndef BHI260_SDA +#define BHI260_SDA 2 +#endif + +#ifndef BHI260_SCL +#define BHI260_SCL 3 +#endif + +#ifndef BHI260_IRQ +#define BHI260_IRQ 8 +#endif +#endif /*USE_SPI_INTERFACE*/ + +#ifndef BHI260_RST +#define BHI260_RST -1 #endif SensorBHI260AP bhy; +bool isReadyFlag = false; + +void dataReadyISR() +{ + isReadyFlag = true; +} + void parse_bme280_sensor_data(uint8_t sensor_id, uint8_t *data_ptr, uint32_t len, uint64_t *timestamp) { float humidity = 0; @@ -142,8 +183,8 @@ void setup() Serial.begin(115200); while (!Serial); - // Set the reset pin and interrupt pin, if any - bhy.setPins(BHI260AP_RST, BHI260AP_IRQ); + // Set the reset pin + bhy.setPins(BHI260_RST); // Force update of the current firmware, regardless of whether it exists. // After uploading the firmware once, you can change it to false to speed up the startup time. bool force_update = true; @@ -154,20 +195,22 @@ void setup() bhy.setBootFromFlash(WRITE_TO_FLASH); Serial.println("Initializing Sensors..."); -#ifdef BHY2_USE_I2C +#ifdef USE_I2C_INTERFACE // Using I2C interface // BHI260AP_SLAVE_ADDRESS_L = 0x28 // BHI260AP_SLAVE_ADDRESS_H = 0x29 - if (!bhy.init(Wire, BHI260AP_SDA, BHI260AP_SCL, BHI260AP_SLAVE_ADDRESS_L)) { + if (!bhy.begin(Wire, BHI260AP_SLAVE_ADDRESS_L, BHI260_SDA, BHI260_SCL)) { Serial.print("Failed to initialize sensor - error code:"); Serial.println(bhy.getError()); while (1) { delay(1000); } } -#else +#endif + +#ifdef USE_SPI_INTERFACE // Using SPI interface - if (!bhy.init(SPI, BHI260AP_CS, BHI260AP_MOSI, BHI260AP_MISO, BHI260AP_SCK)) { + if (!bhy.begin(SPI, BHI260_CS, SPI_MOSI, SPI_MISO, SPI_SCK)) { Serial.print("Failed to initialize sensor - error code:"); Serial.println(bhy.getError()); while (1) { @@ -186,17 +229,19 @@ void setup() bhy.onResultEvent(SENSOR_ID_HUM, parse_bme280_sensor_data); bhy.onResultEvent(SENSOR_ID_BARO, parse_bme280_sensor_data); - // Output all current sensor information - bhy.printInfo(Serial); - - // Output interrupt configuration information to Serial - bhy.printInterruptCtrl(Serial); + // Output all sensors info to Serial + BoschSensorInfo info = bhy.getSensorInfo(); + info.printInfo(Serial); initialiseCommander(); Serial.println("Hello: Type 'help' to get help"); cmd.printCommandPrompt(); + + // Register interrupt function + pinMode(BHI260_IRQ, INPUT); + attachInterrupt(BHI260_IRQ, dataReadyISR, RISING); } uint32_t check_millis = 0; @@ -206,7 +251,10 @@ void loop() //Call the update functions using the activeCommander pointer cmd.update(); // Update sensor fifo - bhy.update(); + if (isReadyFlag) { + isReadyFlag = false; + bhy.update(); + } } diff --git a/examples/BHI260AP_aux_BMM150_euler/BHI260AP_aux_BMM150_euler.ino b/examples/BHI260AP_aux_BMM150_euler/BHI260AP_aux_BMM150_euler.ino index 65dea95..54f519b 100644 --- a/examples/BHI260AP_aux_BMM150_euler/BHI260AP_aux_BMM150_euler.ino +++ b/examples/BHI260AP_aux_BMM150_euler/BHI260AP_aux_BMM150_euler.ino @@ -53,23 +53,62 @@ const uint8_t *firmware = bhi26ap_aux_bmm150_fw; const size_t fw_size = sizeof(bhi26ap_aux_bmm150_fw); #endif -#ifdef BHY2_USE_I2C -#define BHI260AP_SDA 21 -#define BHI260AP_SCL 22 -#define BHI260AP_IRQ 39 -#define BHI260AP_RST -1 -#else -#define BHI260AP_MOSI 27 -#define BHI260AP_MISO 46 -#define BHI260AP_SCK 3 -#define BHI260AP_CS 28 -#define BHI260AP_IRQ 30 -#define BHI260AP_RST -1 +// #define USE_I2C_INTERFACE true +// #define USE_SPI_INTERFACE true + +#if !defined(USE_I2C_INTERFACE) && !defined(USE_SPI_INTERFACE) +#define USE_I2C_INTERFACE +#warning "No interface type is selected, use I2C interface" +#endif + +#if defined(USE_SPI_INTERFACE) +#ifndef SPI_MOSI +#define SPI_MOSI 33 +#endif + +#ifndef SPI_MISO +#define SPI_MISO 34 +#endif + +#ifndef SPI_SCK +#define SPI_SCK 35 +#endif + +#ifndef BHI260_IRQ +#define BHI260_IRQ 37 +#endif + +#ifndef BHI260_CS +#define BHI260_CS 36 +#endif + +#else //* I2C */ + +#ifndef BHI260_SDA +#define BHI260_SDA 2 +#endif + +#ifndef BHI260_SCL +#define BHI260_SCL 3 #endif +#ifndef BHI260_IRQ +#define BHI260_IRQ 8 +#endif +#endif /*USE_SPI_INTERFACE*/ + +#ifndef BHI260_RST +#define BHI260_RST -1 +#endif SensorBHI260AP bhy; +bool isReadyFlag = false; + +void dataReadyISR() +{ + isReadyFlag = true; +} void parse_euler(uint8_t sensor_id, uint8_t *data_ptr, uint32_t len, uint64_t *timestamp) { @@ -129,8 +168,8 @@ void setup() Serial.begin(115200); while (!Serial); - // Set the reset pin and interrupt pin, if any - bhy.setPins(BHI260AP_RST, BHI260AP_IRQ); + // Set the reset pin + bhy.setPins(BHI260_RST); // Force update of the current firmware, regardless of whether it exists. // After uploading the firmware once, you can change it to false to speed up the startup time. @@ -144,20 +183,22 @@ void setup() #endif Serial.println("Initializing Sensors..."); -#ifdef BHY2_USE_I2C +#ifdef USE_I2C_INTERFACE // Using I2C interface // BHI260AP_SLAVE_ADDRESS_L = 0x28 // BHI260AP_SLAVE_ADDRESS_H = 0x29 - if (!bhy.init(Wire, BHI260AP_SDA, BHI260AP_SCL, BHI260AP_SLAVE_ADDRESS_L)) { + if (!bhy.begin(Wire, BHI260AP_SLAVE_ADDRESS_L, BHI260_SDA, BHI260_SCL)) { Serial.print("Failed to initialize sensor - error code:"); Serial.println(bhy.getError()); while (1) { delay(1000); } } -#else +#endif + +#ifdef USE_SPI_INTERFACE // Using SPI interface - if (!bhy.init(SPI, BHI260AP_CS, BHI260AP_MOSI, BHI260AP_MISO, BHI260AP_SCK)) { + if (!bhy.begin(SPI, BHI260_CS, SPI_MOSI, SPI_MISO, SPI_SCK)) { Serial.print("Failed to initialize sensor - error code:"); Serial.println(bhy.getError()); while (1) { @@ -168,8 +209,9 @@ void setup() Serial.println("Initializing the sensor successfully!"); - // Output all available sensors to Serial - bhy.printSensors(Serial); + // Output all sensors info to Serial + BoschSensorInfo info = bhy.getSensorInfo(); + info.printInfo(Serial); float sample_rate = 100.0; /* Read out hintr_ctrl measured at 100Hz */ uint32_t report_latency_ms = 0; /* Report immediately */ @@ -184,14 +226,19 @@ void setup() // Register event callback function bhy.onResultEvent(SENSOR_EULER_ID, parse_euler); - + // Register interrupt function + pinMode(BHI260_IRQ, INPUT); + attachInterrupt(BHI260_IRQ, dataReadyISR, RISING); } void loop() { // Update sensor fifo - bhy.update(); + if (isReadyFlag) { + isReadyFlag = false; + bhy.update(); + } delay(50); } diff --git a/examples/BHI260AP_aux_BMM150_quaternion/BHI260AP_aux_BMM150_quaternion.ino b/examples/BHI260AP_aux_BMM150_quaternion/BHI260AP_aux_BMM150_quaternion.ino index 9049db7..b196edb 100644 --- a/examples/BHI260AP_aux_BMM150_quaternion/BHI260AP_aux_BMM150_quaternion.ino +++ b/examples/BHI260AP_aux_BMM150_quaternion/BHI260AP_aux_BMM150_quaternion.ino @@ -53,23 +53,62 @@ const uint8_t *firmware = bhi26ap_aux_bmm150_fw; const size_t fw_size = sizeof(bhi26ap_aux_bmm150_fw); #endif -#ifdef BHY2_USE_I2C -#define BHI260AP_SDA 21 -#define BHI260AP_SCL 22 -#define BHI260AP_IRQ 39 -#define BHI260AP_RST -1 -#else -#define BHI260AP_MOSI 27 -#define BHI260AP_MISO 46 -#define BHI260AP_SCK 3 -#define BHI260AP_CS 28 -#define BHI260AP_IRQ 30 -#define BHI260AP_RST -1 +// #define USE_I2C_INTERFACE true +// #define USE_SPI_INTERFACE true + +#if !defined(USE_I2C_INTERFACE) && !defined(USE_SPI_INTERFACE) +#define USE_I2C_INTERFACE +#warning "No interface type is selected, use I2C interface" +#endif + +#if defined(USE_SPI_INTERFACE) +#ifndef SPI_MOSI +#define SPI_MOSI 33 +#endif + +#ifndef SPI_MISO +#define SPI_MISO 34 +#endif + +#ifndef SPI_SCK +#define SPI_SCK 35 +#endif + +#ifndef BHI260_IRQ +#define BHI260_IRQ 37 #endif +#ifndef BHI260_CS +#define BHI260_CS 36 +#endif + +#else //* I2C */ + +#ifndef BHI260_SDA +#define BHI260_SDA 2 +#endif + +#ifndef BHI260_SCL +#define BHI260_SCL 3 +#endif + +#ifndef BHI260_IRQ +#define BHI260_IRQ 8 +#endif +#endif /*USE_SPI_INTERFACE*/ + +#ifndef BHI260_RST +#define BHI260_RST -1 +#endif SensorBHI260AP bhy; +bool isReadyFlag = false; + +void dataReadyISR() +{ + isReadyFlag = true; +} void parse_quaternion(uint8_t sensor_id, uint8_t *data_ptr, uint32_t len, uint64_t *timestamp) { @@ -112,8 +151,8 @@ void setup() Serial.begin(115200); while (!Serial); - // Set the reset pin and interrupt pin, if any - bhy.setPins(BHI260AP_RST, BHI260AP_IRQ); + // Set the reset pin + bhy.setPins(BHI260_RST); // Force update of the current firmware, regardless of whether it exists. // After uploading the firmware once, you can change it to false to speed up the startup time. @@ -127,20 +166,22 @@ void setup() #endif Serial.println("Initializing Sensors..."); -#ifdef BHY2_USE_I2C +#ifdef USE_I2C_INTERFACE // Using I2C interface // BHI260AP_SLAVE_ADDRESS_L = 0x28 // BHI260AP_SLAVE_ADDRESS_H = 0x29 - if (!bhy.init(Wire, BHI260AP_SDA, BHI260AP_SCL, BHI260AP_SLAVE_ADDRESS_L)) { + if (!bhy.begin(Wire, BHI260AP_SLAVE_ADDRESS_L, BHI260_SDA, BHI260_SCL)) { Serial.print("Failed to initialize sensor - error code:"); Serial.println(bhy.getError()); while (1) { delay(1000); } } -#else +#endif + +#ifdef USE_SPI_INTERFACE // Using SPI interface - if (!bhy.init(SPI, BHI260AP_CS, BHI260AP_MOSI, BHI260AP_MISO, BHI260AP_SCK)) { + if (!bhy.begin(SPI, BHI260_CS, SPI_MOSI, SPI_MISO, SPI_SCK)) { Serial.print("Failed to initialize sensor - error code:"); Serial.println(bhy.getError()); while (1) { @@ -151,8 +192,9 @@ void setup() Serial.println("Initializing the sensor successfully!"); - // Output all available sensors to Serial - bhy.printSensors(Serial); + // Output all sensors info to Serial + BoschSensorInfo info = bhy.getSensorInfo(); + info.printInfo(Serial); float sample_rate = 100.0; /* Read out hintr_ctrl measured at 100Hz */ uint32_t report_latency_ms = 0; /* Report immediately */ @@ -167,6 +209,9 @@ void setup() // Register event callback function bhy.onResultEvent(QUAT_SENSOR_ID, parse_quaternion); + // Register interrupt function + pinMode(BHI260_IRQ, INPUT); + attachInterrupt(BHI260_IRQ, dataReadyISR, RISING); } @@ -174,7 +219,10 @@ void setup() void loop() { // Update sensor fifo - bhy.update(); + if (isReadyFlag) { + isReadyFlag = false; + bhy.update(); + } delay(50); } diff --git a/examples/BMA423_Accelerometer/BMA423_Accelerometer.ino b/examples/BMA423_Accelerometer/BMA423_Accelerometer.ino index a2ba861..70f50a8 100644 --- a/examples/BMA423_Accelerometer/BMA423_Accelerometer.ino +++ b/examples/BMA423_Accelerometer/BMA423_Accelerometer.ino @@ -45,7 +45,7 @@ #endif SensorBMA423 accel; -uint32_t lastMillis; +uint32_t intervalue; void setup() { @@ -54,7 +54,11 @@ void setup() pinMode(SENSOR_IRQ, INPUT); - if (!accel.begin(Wire, BMA423_SLAVE_ADDRESS, SENSOR_SDA, SENSOR_SCL)) { + /* + * BMA423_I2C_ADDR_PRIMARY = 0x18 + * BMA423_I2C_ADDR_SECONDARY = 0x19 + * * */ + if (!accel.begin(Wire, BMA423_I2C_ADDR_SECONDARY, SENSOR_SDA, SENSOR_SCL)) { Serial.println("Failed to find BMA423 - check your wiring!"); while (1) { delay(1000); diff --git a/examples/BMA423_Feature/BMA423_Feature.ino b/examples/BMA423_Feature/BMA423_Feature.ino index 117291c..4338fda 100644 --- a/examples/BMA423_Feature/BMA423_Feature.ino +++ b/examples/BMA423_Feature/BMA423_Feature.ino @@ -45,7 +45,7 @@ #endif SensorBMA423 accel; -uint32_t lastMillis; +uint32_t intervalue; bool sensorIRQ = false; @@ -62,7 +62,11 @@ void setup() pinMode(SENSOR_IRQ, INPUT); attachInterrupt(SENSOR_IRQ, setFlag, RISING); - if (!accel.begin(Wire, BMA423_SLAVE_ADDRESS, SENSOR_SDA, SENSOR_SCL)) { + /* + * BMA423_I2C_ADDR_PRIMARY = 0x18 + * BMA423_I2C_ADDR_SECONDARY = 0x19 + * * */ + if (!accel.begin(Wire, BMA423_I2C_ADDR_SECONDARY, SENSOR_SDA, SENSOR_SCL)) { Serial.println("Failed to find BMA423 - check your wiring!"); while (1) { delay(1000); diff --git a/examples/BMA423_Orientation/BMA423_Orientation.ino b/examples/BMA423_Orientation/BMA423_Orientation.ino index 92beab4..139663c 100644 --- a/examples/BMA423_Orientation/BMA423_Orientation.ino +++ b/examples/BMA423_Orientation/BMA423_Orientation.ino @@ -54,7 +54,11 @@ void setup() pinMode(SENSOR_IRQ, INPUT); - if (!accel.begin(Wire, BMA423_SLAVE_ADDRESS, SENSOR_SDA, SENSOR_SCL)) { + /* + * BMA423_I2C_ADDR_PRIMARY = 0x18 + * BMA423_I2C_ADDR_SECONDARY = 0x19 + * * */ + if (!accel.begin(Wire, BMA423_I2C_ADDR_SECONDARY, SENSOR_SDA, SENSOR_SCL)) { Serial.println("Failed to find BMA423 - check your wiring!"); while (1) { delay(1000); @@ -66,6 +70,7 @@ void setup() accel.configAccelerometer(); accel.enableAccelerometer(); + Serial.println("Output ..."); } diff --git a/examples/BMA423_Temperature/BMA423_Temperature.ino b/examples/BMA423_Temperature/BMA423_Temperature.ino index 75c118d..3f1a748 100644 --- a/examples/BMA423_Temperature/BMA423_Temperature.ino +++ b/examples/BMA423_Temperature/BMA423_Temperature.ino @@ -30,6 +30,8 @@ #include #include #include + +#define SENSORLIB_DEBUG Serial.printf #include "SensorBMA423.hpp" #ifndef SENSOR_SDA @@ -53,7 +55,13 @@ void setup() pinMode(SENSOR_IRQ, INPUT); - if (!accel.begin(Wire, BMA423_SLAVE_ADDRESS, SENSOR_SDA, SENSOR_SCL)) { + DBG("BMA423 Sensor Temperature"); + + /* + * BMA423_I2C_ADDR_PRIMARY = 0x18 + * BMA423_I2C_ADDR_SECONDARY = 0x19 + * * */ + if (!accel.begin(Wire, BMA423_I2C_ADDR_SECONDARY, SENSOR_SDA, SENSOR_SCL)) { Serial.println("Failed to find BMA423 - check your wiring!"); while (1) { delay(1000); @@ -68,8 +76,9 @@ void loop() Serial.print("getTemperature:"); Serial.print(accel.getTemperature(SensorBMA423::TEMP_DEG)); Serial.print("*C "); - Serial.print(accel.getTemperature(SensorBMA423::TEMP_FAHREN)); + Serial.print(accel.getTemperature(SensorBMA423::TEMP_FAHRENHEIT)); Serial.print("*F"); + Serial.println(); delay(1000); } diff --git a/examples/BMM150_GetDataExample/BMM150_GetDataExample.ino b/examples/BMM150_GetDataExample/BMM150_GetDataExample.ino index 4009221..814aadf 100644 --- a/examples/BMM150_GetDataExample/BMM150_GetDataExample.ino +++ b/examples/BMM150_GetDataExample/BMM150_GetDataExample.ino @@ -60,7 +60,7 @@ void setup() while (!Serial); // Using I2C interface - if (!bmm.init(Wire, SENSOR_SDA, SENSOR_SCL, BMM150_I2C_ADDRESS_CSB_HIGH_SDO_LOW)) { + if (!bmm.begin(Wire, BMM150_I2C_ADDRESS_CSB_HIGH_SDO_LOW, SENSOR_SDA, SENSOR_SCL)) { Serial.print("Failed to init BMM150 - check your wiring!"); while (1) { delay(1000); @@ -85,7 +85,7 @@ void loop() { int16_t x, y, z; /* Read mag data */ - /* Unit for magnetometer data is microtesla(uT) */ + /* Unit for magnetometer data is micro tesla(uT) */ if (bmm.getMag(x, y, z)) { Serial.print("X:"); Serial.print(x); diff --git a/examples/BQ27220_GaugeExample/BQ27220_GaugeExample.ino b/examples/BQ27220_GaugeExample/BQ27220_GaugeExample.ino new file mode 100644 index 0000000..6037932 --- /dev/null +++ b/examples/BQ27220_GaugeExample/BQ27220_GaugeExample.ino @@ -0,0 +1,178 @@ +/** + * + * @license MIT License + * + * Copyright (c) 2025 lewis he + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * @file BQ27220_GaugeExample.ino + * @author Lewis He (lewishe@outlook.com) + * @date 2025-01-16 + * + */ +#include +#include +#include +#include "GaugeBQ27220.hpp" + +#ifndef SENSOR_SDA +#define SENSOR_SDA 2 +#endif + +#ifndef SENSOR_SCL +#define SENSOR_SCL 3 +#endif + +GaugeBQ27220 gauge; + +void setup() +{ + Serial.begin(115200); + while (!Serial); + + if (!gauge.begin(Wire, SENSOR_SDA, SENSOR_SCL)) { + Serial.println("Failed to BQ27220 - check your wiring!"); + while (1) { + delay(1000); + } + } + Serial.println("Init BQ27220 Sensor success!"); +} + + +void loop() +{ + int rate = gauge.getAtRate(); // mA + uint16_t atRateTimeToEmpty = gauge.getAtRateTimeToEmpty(); // minutes + float ntcTemperature = gauge.getTemperature(); // Celsius + uint16_t batteryVoltage = gauge.getBatteryVoltage(); // mV + uint16_t batteryStatusRaw = gauge.getBatteryStatusRaw(); // N.A + int instantaneousCurrent = gauge.getInstantaneousCurrent(); // mAh + uint16_t remainingCapacity = gauge.getRemainingCapacity(); // mAh + uint16_t fullChargeCapacity = gauge.getFullChargeCapacity(); // mAh + uint16_t time2Empty = gauge.getTimeToEmpty(); // minutes + uint16_t time2Full = gauge.getTimeToFull(); // minutes + uint16_t standbyCurrent = gauge.getStandbyCurrent(); // mA + + + uint16_t standbyTimeToEmpty = gauge.getStandbyTimeToEmpty(); // minutes + int maxLoadCurrent = gauge.getMaxLoadCurrent(); // mA + uint16_t maxLoadTimeToEmpty = gauge.getMaxLoadTimeToEmpty(); // minutes + uint16_t coulombCountRaw = gauge.getRawCoulombCount(); // mAh + uint16_t averagePower = gauge.getAveragePower(); // mW + float internalTemperature = gauge.getInternalTemperature(); // Celsius + uint16_t cycleCount = gauge.getCycleCount(); // Number + + uint16_t stateOfCharge = gauge.getStateOfCharge(); // % + uint16_t stateOfHealth = gauge.getStateOfHealth(); // % + uint16_t chargingVoltage = gauge.getChargingVoltage(); // mV + uint16_t chargingCurrent = gauge.getChargingCurrent(); // mA + uint16_t BTPDischargeSet = gauge.getBTPDischargeSet(); // mAh + uint16_t BTPChargeSet = gauge.getBTPChargeSet(); // mAh + uint16_t operationStatusRaw = gauge.getOperationStatusRaw(); // N.A + uint16_t designCapacity = gauge.getDesignCapacity(); // mAh + + + Serial.printf("getAtRate:%u mA\n", rate); + Serial.printf("getAtRateTimeToEmpty:%u minutes\n", atRateTimeToEmpty); + Serial.printf("getTemperature:%.2f ℃\n", ntcTemperature); + Serial.printf("getBatteryVoltage:%u mV\n", batteryVoltage); + Serial.printf("getBatteryStatusRaw:%u \n", batteryStatusRaw); + Serial.printf("getInstantaneousCurrent:%u mAh\n", instantaneousCurrent); + Serial.printf("getRemainingCapacity:%u mAh\n", remainingCapacity); + Serial.printf("getFullChargeCapacity:%u mAh\n", fullChargeCapacity); + Serial.printf("getTimeToEmpty:%u minutes\n", time2Empty); + Serial.printf("getTimeToFull:%u minutes\n", time2Full); + Serial.printf("getStandbyCurrent:%u mA\n", standbyCurrent); + + + Serial.printf("getStandbyTimeToEmpty:%u minutes\n", standbyTimeToEmpty); + Serial.printf("getMaxLoadCurrent:%d mA\n", maxLoadCurrent); + Serial.printf("getMaxLoadTimeToEmpty:%u minute\n", maxLoadTimeToEmpty); + Serial.printf("getRawCoulombCount:%u mAh\n", coulombCountRaw); + Serial.printf("getAveragePower:%u mW\n", averagePower); + Serial.printf("getInternalTemperature:%.2f ℃\n", internalTemperature); + Serial.printf("getCycleCount:%u \n", cycleCount); + + Serial.printf("getStateOfCharge:%u %%\n", stateOfCharge); + Serial.printf("getStateOfHealth:%u %%\n", stateOfHealth); + Serial.printf("getChargingVoltage:%u mV\n", chargingVoltage); + Serial.printf("getChargingCurrent:%u mA\n", chargingCurrent); + Serial.printf("getBTPDischargeSet:%u mAh\n", BTPDischargeSet); + Serial.printf("getBTPChargeSet:%u mAh\n", BTPChargeSet); + Serial.printf("getOperationStatusRaw:%u \n", operationStatusRaw); + Serial.printf("getDesignCapacity:%u mAh\n", designCapacity); + + BatteryStatus_t s = gauge.getBatteryStatus(); + + if (s.FD) { + Serial.println("1.Full discharge detected."); + } + if (s.OCVCOMP) { + Serial.println("2.OCV measurement update is complete."); + } + if (s.OCVFAIL) { + Serial.println("3.Status bit indicating that an OCV read failed due to current."); + Serial.println("\tThis bit can only be set if a battery is present after receiving an OCV_CMD()."); + } + if (s.SLEEP) { + Serial.println("4.The device operates in SLEEP mode"); + } + if (s.OTC) { + Serial.println("5.Over-temperature is detected during charging."); + } + if (s.OTD) { + Serial.println("6.Over-temperature detected during discharge condition."); + } + if (s.FC) { + Serial.println("7.Full charge detected."); + } + if (s.CHGINH) { + Serial.println("8.Charge Inhibit: If set, indicates that charging should not begin because the Temperature() is outside the range"); + Serial.println("\t[Charge Inhibit Temp Low, Charge Inhibit Temp High]. "); + } + if (s.TCA) { + Serial.println("9.Termination of charging alarm. This flag is set and cleared based on the selected SOC Flag Config A option."); + } + if (s.OCVGD) { + Serial.println("10.A good OCV measurement was made."); + } + if (s.AUTH_GD) { + Serial.println("11.Detects inserted battery."); + } + if (s.BATTPRES) { + Serial.println("12.Battery presence detected."); + } + if (s.TDA) { + Serial.println("13.Termination discharge alarm. This flag is set and cleared according to the selected SOC Flag Config A option."); + } + if (s.SYSDWN) { + Serial.println("14.System shutdown bit indicating that the system should be shut down. True when set. If set, the SOC_INT pin toggles once."); + } + if (s.DSG) { + Serial.println("15.When set, the device is in DISCHARGE mode; when cleared, the device is in CHARGING or RELAXATION mode."); + } + + Serial.println("==============================================="); + delay(3000); +} + + + diff --git a/examples/CM32181_LightSensor/CM32181_LightSensor.ino b/examples/CM32181_LightSensor/CM32181_LightSensor.ino index 41ee441..28b7042 100644 --- a/examples/CM32181_LightSensor/CM32181_LightSensor.ino +++ b/examples/CM32181_LightSensor/CM32181_LightSensor.ino @@ -54,7 +54,7 @@ void setup() pinMode(SENSOR_IRQ, INPUT_PULLUP); - if (!light.begin(Wire, CM32181_SLAVE_ADDRESS, SENSOR_SDA, SENSOR_SCL)) { + if (!light.begin(Wire, CM32181_ADDR_PRIMARY, SENSOR_SDA, SENSOR_SCL)) { Serial.println("Failed to find CM32181 - check your wiring!"); while (1) { delay(1000); diff --git a/examples/CM32181_LightSensorInterrupt/CM32181_LightSensorInterrupt.ino b/examples/CM32181_LightSensorInterrupt/CM32181_LightSensorInterrupt.ino index 03e847f..5f2cb41 100644 --- a/examples/CM32181_LightSensorInterrupt/CM32181_LightSensorInterrupt.ino +++ b/examples/CM32181_LightSensorInterrupt/CM32181_LightSensorInterrupt.ino @@ -46,15 +46,39 @@ SensorCM32181 light; +#ifdef ARDUINO_T_AMOLED_147 +#include //PMU Library https://github.com/lewisxhe/XPowersLib.git +XPowersAXP2101 power; +#endif + +void beginPower() +{ + // T_AMOLED_147 The PMU voltage needs to be turned on to use the sensor +#if defined(ARDUINO_T_AMOLED_147) + bool ret = power.begin(Wire, AXP2101_SLAVE_ADDRESS, SENSOR_SDA, SENSOR_SCL); + if (!ret) { + Serial.println("PMU NOT FOUND!\n"); + } + power.setALDO1Voltage(1800); power.enableALDO1(); + power.setALDO3Voltage(3300); power.enableALDO3(); + power.setBLDO1Voltage(1800); power.enableBLDO1(); +#endif +} + +#include "SensorWireHelper.h" void setup() { Serial.begin(115200); while (!Serial); + beginPower(); + + SensorWireHelper::dumpDevices(Wire); + pinMode(SENSOR_IRQ, INPUT_PULLUP); - if (!light.begin(Wire, CM32181_SLAVE_ADDRESS, SENSOR_SDA, SENSOR_SCL)) { + if (!light.begin(Wire, CM32181_ADDR_PRIMARY, SENSOR_SDA, SENSOR_SCL)) { Serial.println("Failed to find CM32181 - check your wiring!"); while (1) { delay(1000); diff --git a/examples/CustomCallbackTouchDrvInterface/CustomCallbackTouchDrvInterface.ino b/examples/CustomCallbackTouchDrvInterface/CustomCallbackTouchDrvInterface.ino new file mode 100644 index 0000000..7110922 --- /dev/null +++ b/examples/CustomCallbackTouchDrvInterface/CustomCallbackTouchDrvInterface.ino @@ -0,0 +1,294 @@ +/** + * + * @license MIT License + * + * Copyright (c) 2025 lewis he + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * @file CustomCallbackTouchDrvInterface.ino + * @author Lewis He (lewishe@outlook.com) + * @date 2025-01-21 + * @note CustomCallbackTouchDrvInterface use LilyGo T-RGB,T-RGB has three types of screens, each of which uses different touch driver chips. + * The example demonstrates using the touch interface class and one sketch is suitable for three types of touch chips. + * The example demonstrates using custom callbacks to read touch or sensors. This method is also applicable to other platforms. + * The prerequisite compilation platform must support C++11. + */ +#include +#include +#include +#include "TouchDrvFT6X36.hpp" +#include "TouchDrvCSTXXX.hpp" +#include "TouchDrvGT911.hpp" +#include "ExtensionIOXL9555.hpp" +#include "SensorWireHelper.h" + +#ifndef TOUCH_SDA +#define TOUCH_SDA 8 +#endif + +#ifndef TOUCH_SCL +#define TOUCH_SCL 48 +#endif + +#ifndef TOUCH_IRQ +#define TOUCH_IRQ 1 +#endif + +#ifndef TOUCH_RST +#define TOUCH_RST 1 +#endif + +// Use the TouchDrvInterface base class for automatic discovery and use of multi-touch devices +TouchDrvInterface *touchDrv; +// T-RGB uses XL9555 as the reset control of the touch screen +ExtensionIOXL9555 extension; + +int16_t x[5], y[5]; + +ExtensionIOXL9555::ExtensionGPIO tp_reset = ExtensionIOXL9555::IO1; + +/** + * @brief i2c_wr_function + * @note I2C communication using custom callbacks + * @param addr: 7-Bit Device Address + * @param reg: Register address, only needs to be written when writeReg is true + * @param *buf: When isWrite is true, it represents the written buf, otherwise it is the read data buffer + * @param len: When isWrite is true, it indicates the length of data written , otherwise it is the data read length + * @param writeReg: writeReg is the register address that needs to be written, otherwise the register address is not written + * @param isWrite: Data write and read direction, true means write, false means read + * @retval True means the device is executed successfully, false means it fails + */ +bool i2c_wr_function(uint8_t addr, uint8_t reg, uint8_t *buf, size_t len, bool writeReg, bool isWrite) +{ + if (isWrite) { + Wire.beginTransmission(addr); + if (writeReg) { + Wire.write(reg); + } + if (buf && len > 0) { + Wire.write(buf, len); + } + return (Wire.endTransmission() == 0); + } else { + if (writeReg) { + Wire.beginTransmission(addr); + Wire.write(reg); + Wire.endTransmission(); + } + Wire.requestFrom(addr, static_cast(len)); + for (size_t i = 0; i < len; ++i) { + if (Wire.available()) { + buf[i] = Wire.read(); + } else { + return false; + } + } + return true; + } +} + + +uint32_t hal_callback(SensorCommCustomHal::Operation op, void *param1, void *param2) +{ + switch (op) { + // Set GPIO mode + case SensorCommCustomHal::OP_PINMODE: { + uint8_t pin = reinterpret_cast(param1); + uint8_t mode = reinterpret_cast(param2); + pinMode(pin, mode); + } + break; + // Set GPIO level + case SensorCommCustomHal::OP_DIGITALWRITE: { + uint8_t pin = reinterpret_cast(param1); + uint8_t level = reinterpret_cast(param2); + digitalWrite(pin, level); + } + break; + // Read GPIO level + case SensorCommCustomHal::OP_DIGITALREAD: { + uint8_t pin = reinterpret_cast(param1); + return digitalRead(pin); + } + break; + // Get the current running milliseconds + case SensorCommCustomHal::OP_MILLIS: + return millis(); + + // Delay in milliseconds + case SensorCommCustomHal::OP_DELAY: { + if (param1) { + uint32_t ms = reinterpret_cast(param1); + delay(ms); + } + } + break; + // Delay in microseconds + case SensorCommCustomHal::OP_DELAYMICROSECONDS: { + uint32_t us = reinterpret_cast(param1); + delayMicroseconds(us); + } + break; + default: + break; + } + return 0; +} + +void TouchDrvDigitalWrite(uint8_t gpio, uint8_t level) +{ + if (gpio & 0x80) { + extension.digitalWrite(gpio & 0x7F, level); + } else { + digitalWrite(gpio, level); + } +} + +uint8_t TouchDrvDigitalRead(uint8_t gpio) +{ + if (gpio & 0x80) { + return extension.digitalRead(gpio & 0x7F); + } else { + return digitalRead(gpio); + } +} + +void TouchDrvPinMode(uint8_t gpio, uint8_t mode) +{ + if (gpio & 0x80) { + extension.pinMode(gpio & 0x7F, mode); + } else { + pinMode(gpio, mode); + } +} + +bool setupTouchDrv() +{ + // Add the highest bit to indicate that the GPIO extension is used, not the ESP's GPIO + const uint8_t touch_reset_pin = tp_reset | 0x80; + const uint8_t touch_irq_pin = TOUCH_IRQ; + bool result = false; + + touchDrv = new TouchDrvCSTXXX(); + touchDrv->setGpioCallback(TouchDrvPinMode, TouchDrvDigitalWrite, TouchDrvDigitalRead); + touchDrv->setPins(touch_reset_pin, touch_irq_pin); + result = touchDrv->begin(i2c_wr_function, hal_callback, CST816_SLAVE_ADDRESS); + if (result) { + const char *model = touchDrv->getModelName(); + Serial.printf("Successfully initialized %s, using %s Driver!\n", model, model); + return true; + } + delete touchDrv; + + touchDrv = new TouchDrvGT911(); + touchDrv->setGpioCallback(TouchDrvPinMode, TouchDrvDigitalWrite, TouchDrvDigitalRead); + touchDrv->setPins(touch_reset_pin, touch_irq_pin); + result = touchDrv->begin(i2c_wr_function, hal_callback, GT911_SLAVE_ADDRESS_L); + if (result) { + const char *model = touchDrv->getModelName(); + Serial.printf("Successfully initialized %s, using %s Driver!\n", model, model); + return true; + } + delete touchDrv; + + touchDrv = new TouchDrvFT6X36(); + touchDrv->setGpioCallback(TouchDrvPinMode, TouchDrvDigitalWrite, TouchDrvDigitalRead); + touchDrv->setPins(touch_reset_pin, touch_irq_pin); + result = touchDrv->begin(i2c_wr_function, hal_callback, FT3267_SLAVE_ADDRESS); + if (result) { + TouchDrvFT6X36 *tmp = static_cast(touchDrv); + tmp->interruptTrigger(); + const char *model = touchDrv->getModelName(); + Serial.printf("Successfully initialized %s, using %s Driver!\n", model, model); + return true; + } + delete touchDrv; + + Serial.println("Unable to find touch device."); + + touchDrv = NULL; + + return false; +} + +void setup() +{ + Serial.begin(115200); + while (!Serial); + Serial.println("Start!"); + +#if defined(ARDUINO_ARCH_RP2040) || defined(ARDUINO_ARCH_STM32) + Wire.setSCL(TOUCH_SCL); + Wire.setSDA(TOUCH_SDA); + Wire.begin(); +#elif defined(ARDUINO_ARCH_NRF52) + Wire.setPins(TOUCH_SDA, TOUCH_SCL); + Wire.begin(); +#elif defined(ARDUINO_ARCH_ESP32) + Wire.begin(TOUCH_SDA, TOUCH_SCL); +#else + Wire.being(); +#endif + + SensorWireHelper::dumpDevices(Wire); + + // Use unspecified address to test the address discovery function. + // T-RGB XL9555 uses 0X20 device address + if (!extension.begin(i2c_wr_function, XL9555_UNKOWN_ADDRESS)) { + Serial.println("Failed to find XL9555 - check your wiring!"); + while (1) { + delay(1000); + } + } + + if (!setupTouchDrv()) { + while (1) { + delay(3000); + } + } + +} + +void loop() +{ + if (touchDrv->isPressed()) { + uint8_t touched = touchDrv->getPoint(x, y, touchDrv->getSupportTouchPoint()); + if (touched) { + for (int i = 0; i < touched; ++i) { + Serial.print("X["); + Serial.print(i); + Serial.print("]:"); + Serial.print(x[i]); + Serial.print(" "); + Serial.print(" Y["); + Serial.print(i); + Serial.print("]:"); + Serial.print(y[i]); + Serial.print(" "); + } + Serial.println(); + } + } + delay(5); +} + + + + diff --git a/examples/CustomCallbackUsageExamples/CustomCallbackUsageExamples.ino b/examples/CustomCallbackUsageExamples/CustomCallbackUsageExamples.ino new file mode 100644 index 0000000..572303a --- /dev/null +++ b/examples/CustomCallbackUsageExamples/CustomCallbackUsageExamples.ino @@ -0,0 +1,219 @@ +/** + * + * @license MIT License + * + * Copyright (c) 2025 lewis he + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * @file CustomCallbackUsageExamples.ino + * @author Lewis He (lewishe@outlook.com) + * @date 2025-01-20 + * + */ +#include +#include +#include +#include "SensorPCF8563.hpp" +#include "SensorBMA423.hpp" + +#ifndef SENSOR_SDA +#define SENSOR_SDA 21 +#endif + +#ifndef SENSOR_SCL +#define SENSOR_SCL 22 +#endif + +SensorPCF8563 rtc; +SensorBMA423 accel; + +uint32_t intervalue; +char buf[64]; + +bool i2c_wr_function(uint8_t addr, uint8_t reg, uint8_t *buf, size_t len, bool writeReg, bool isWrite) +{ + if (isWrite) { + Wire.beginTransmission(addr); + if (writeReg) { + Wire.write(reg); + } + if (buf && len > 0) { + Wire.write(buf, len); + } + return (Wire.endTransmission() == 0); + + } else { + if (writeReg) { + Wire.beginTransmission(addr); + Wire.write(reg); + Wire.endTransmission(); + } + Wire.requestFrom(addr, static_cast(len)); + for (size_t i = 0; i < len; ++i) { + if (Wire.available()) { + buf[i] = Wire.read(); + } else { + return false; + } + } + return true; + } +} + + +uint32_t hal_callback(SensorCommCustomHal::Operation op, void *param1, void *param2) +{ + switch (op) { + case SensorCommCustomHal::OP_PINMODE: { + uint8_t pin = reinterpret_cast(param1); + uint8_t mode = reinterpret_cast(param2); + pinMode(pin, mode); + } + break; + case SensorCommCustomHal::OP_DIGITALWRITE: { + uint8_t pin = reinterpret_cast(param1); + uint8_t level = reinterpret_cast(param2); + digitalWrite(pin, level); + } + break; + case SensorCommCustomHal::OP_DIGITALREAD: { + uint8_t pin = reinterpret_cast(param1); + return digitalRead(pin); + } + break; + case SensorCommCustomHal::OP_MILLIS: + return millis(); + break; + case SensorCommCustomHal::OP_DELAY: { + if (param1) { + uint32_t ms = reinterpret_cast(param1); + delay(ms); + } + } + break; + case SensorCommCustomHal::OP_DELAYMICROSECONDS: { + uint32_t us = reinterpret_cast(param1); + delayMicroseconds(us); + } + break; + default: + break; + } + return 0; +} + +void setup() +{ + Serial.begin(115200); + while (!Serial); + +#if defined(ARDUINO_ARCH_RP2040) || defined(ARDUINO_ARCH_STM32) + Wire.setSCL(SENSOR_SCL); + Wire.setSDA(SENSOR_SDA); + Wire.begin(); +#elif defined(ARDUINO_ARCH_NRF52) + Wire.setPins(SENSOR_SDA, SENSOR_SCL); + Wire.begin(); +#elif defined(ARDUINO_ARCH_ESP32) + Wire.begin(SENSOR_SDA, SENSOR_SCL); +#else + Wire.being(); +#endif + + // Using SensorLib with callback functions + // Other sensor classes also support the same methods and can be applied to different platforms + if (!rtc.begin(i2c_wr_function)) { + Serial.println("Failed to find PCF8563 - check your wiring!"); + while (1) { + delay(1000); + } + } + + // The simplest way to set up + rtc.setDateTime(2024, 1, 17, 4, 21, 30); + + // Unix tm structure sets the time + struct tm timeinfo; + timeinfo.tm_yday = 2025 - 1900; //Counting starts from 1900, so subtract 1900 here + timeinfo.tm_mon = 1 - 1; //Months start at 0, so you need to subtract 1. + timeinfo.tm_mday = 17; + timeinfo.tm_hour = 4; + timeinfo.tm_min = 30; + timeinfo.tm_sec = 30; + rtc.setDateTime(timeinfo); + + if (!accel.begin(i2c_wr_function, hal_callback)) { + Serial.println("Failed to find BMA423 - check your wiring!"); + while (1) { + delay(1000); + } + } + + //Default 4G ,200HZ + accel.configAccelerometer(); + + accel.enableAccelerometer(); +} + + +void loop() +{ + if (millis() - intervalue > 1000) { + + intervalue = millis(); + + struct tm timeinfo; + // Get the time C library structure + rtc.getDateTime(&timeinfo); + + // Format the output using the strftime function + // For more formats, please refer to : + // https://man7.org/linux/man-pages/man3/strftime.3.html + + size_t written = strftime(buf, 64, "%A, %B %d %Y %H:%M:%S", &timeinfo); + + if (written != 0) { + Serial.println(buf); + } + + written = strftime(buf, 64, "%b %d %Y %H:%M:%S", &timeinfo); + if (written != 0) { + Serial.println(buf); + } + + + written = strftime(buf, 64, "%A, %d. %B %Y %I:%M%p", &timeinfo); + if (written != 0) { + Serial.println(buf); + } + + Serial.print("Temperature:"); + Serial.print(accel.getTemperature(SensorBMA423::TEMP_DEG)); + Serial.print("*C "); + Serial.print(accel.getTemperature(SensorBMA423::TEMP_FAHRENHEIT)); + Serial.print("*F"); + Serial.print("Dir:"); + Serial.print(accel.direction()); + Serial.println(); + } +} + + + diff --git a/examples/DRV2605_Basic/DRV2605_Basic.ino b/examples/DRV2605_Basic/DRV2605_Basic.ino index 194e244..ed90190 100644 --- a/examples/DRV2605_Basic/DRV2605_Basic.ino +++ b/examples/DRV2605_Basic/DRV2605_Basic.ino @@ -40,9 +40,6 @@ #define SENSOR_SCL 22 #endif -#ifndef SENSOR_IRQ -#define SENSOR_IRQ 39 -#endif SensorDRV2605 drv; @@ -53,9 +50,8 @@ void setup() Serial.begin(115200); while (!Serial); - pinMode(SENSOR_IRQ, INPUT); - if (!drv.begin(Wire, DRV2605_SLAVE_ADDRESS, SENSOR_SDA, SENSOR_SCL)) { + if (!drv.begin(Wire, SENSOR_SDA, SENSOR_SCL)) { Serial.println("Failed to find DRV2605 - check your wiring!"); while (1) { delay(1000); @@ -68,7 +64,7 @@ void setup() // I2C trigger by sending 'run' command // default, internal trigger when sending RUN command - drv.setMode(DRV2605_MODE_INTTRIG); + drv.setMode(SensorDRV2605::MODE_INTTRIG); } diff --git a/examples/ESP_IDF_TouchDrv_Example/CMakeLists.txt b/examples/ESP_IDF_SensorExamples/CMakeLists.txt similarity index 88% rename from examples/ESP_IDF_TouchDrv_Example/CMakeLists.txt rename to examples/ESP_IDF_SensorExamples/CMakeLists.txt index e32c540..8c902f3 100644 --- a/examples/ESP_IDF_TouchDrv_Example/CMakeLists.txt +++ b/examples/ESP_IDF_SensorExamples/CMakeLists.txt @@ -6,4 +6,4 @@ include($ENV{IDF_PATH}/tools/cmake/project.cmake) set(EXTRA_COMPONENT_DIRS ../../../SensorLib) -project(ESP_IDF_TouchDrv_Example) +project(ESP_IDF_SensorExamples) diff --git a/examples/ESP_IDF_SensorExamples/Makefile b/examples/ESP_IDF_SensorExamples/Makefile new file mode 100644 index 0000000..a3def65 --- /dev/null +++ b/examples/ESP_IDF_SensorExamples/Makefile @@ -0,0 +1,10 @@ +# +# This is a project Makefile. It is assumed the directory this Makefile resides in is a +# project subdirectory. +# + +PROJECT_NAME := ESP_IDF_SensorPCF8563 + +EXTRA_COMPONENT_DIRS = ../../../SensorLib + +include $(IDF_PATH)/make/project.mk diff --git a/examples/ESP_IDF_SensorExamples/README.md b/examples/ESP_IDF_SensorExamples/README.md new file mode 100644 index 0000000..7f93451 --- /dev/null +++ b/examples/ESP_IDF_SensorExamples/README.md @@ -0,0 +1,840 @@ +# ESP-IDF Sensor hub examples + +## Configure the Project + +Open the project configuration menu (`idf.py menuconfig`). + +In the `SensorLib Example Configuration` menu: + +* Select Sensor Type , Different sensors have different transmission methods, I2C, SPI + - BHI260 Sensor (I2C & SPI) + - PCF8563 (I2C Only) + - BMA423 (I2C Only) + - FT636X (I2C Only) + - XL9555 (I2C Only) + - The other models are the same +* If you choose a sensor with I2C communication, there will be three methods to choose from: +* Configuring the sensor pins + +## How to Use Example + +Before project configuration and build, be sure to set the correct chip target using `idf.py set-target `. default use **esp32** + +### Build and Flash + +Run `idf.py -p PORT flash monitor` to build, flash and monitor the project. + +(To exit the serial monitor, type ``Ctrl-]``.) + +See the [Getting Started Guide](https://docs.espressif.com/projects/esp-idf/en/latest/get-started/index.html) for full steps to configure and use ESP-IDF to build projects. + +## Example Output + +The output information is to configure the output voltage and enable status of the Sensor + +### LL Driver + +```bash +rst:0x1 (POWERON_RESET),boot:0x13 (SPI_FAST_FLASH_BOOT) +configsip: 0, SPIWP:0xee +clk_drv:0x00,q_drv:0x00,d_drv:0x00,cs0_drv:0x00,hd_drv:0x00,wp_drv:0x00 +mode:DIO, clock div:2 +load:0x3fff0030,len:7176 +load:0x40078000,len:15564 +ho 0 tail 12 room 4 +load:0x40080400,len:4 +0x40080400: _init at ??:? + +load:0x40080404,len:3904 +entry 0x40080640 +I (30) boot: ESP-IDF v5.3-beta1-105-g3f632df143-dirt 2nd stage bootloader +I (30) boot: compile time Jan 22 2025 17:30:49 +I (33) boot: Multicore bootloader +I (37) boot: chip revision: v1.0 +I (41) boot.esp32: SPI Speed : 40MHz +I (45) boot.esp32: SPI Mode : DIO +I (50) boot.esp32: SPI Flash Size : 2MB +I (54) boot: Enabling RNG early entropy source... +I (60) boot: Partition Table: +I (63) boot: ## Label Usage Type ST Offset Length +I (71) boot: 0 nvs WiFi data 01 02 00009000 00006000 +I (78) boot: 1 phy_init RF data 01 01 0000f000 00001000 +I (85) boot: 2 factory factory app 00 00 00010000 00100000 +I (93) boot: End of partition table +I (97) esp_image: segment 0: paddr=00010020 vaddr=3f400020 size=0d54ch ( 54604) map +I (124) esp_image: segment 1: paddr=0001d574 vaddr=3ffb0000 size=022b8h ( 8888) load +I (128) esp_image: segment 2: paddr=0001f834 vaddr=40080000 size=007e4h ( 2020) load +I (131) esp_image: segment 3: paddr=00020020 vaddr=400d0020 size=1c450h (115792) map +I (178) esp_image: segment 4: paddr=0003c478 vaddr=400807e4 size=0bf98h ( 49048) load +I (204) boot: Loaded app from partition at offset 0x10000 +I (204) boot: Disabling RNG early entropy source... +I (216) cpu_start: Multicore app +I (224) cpu_start: Pro cpu start user code +I (224) cpu_start: cpu freq: 240000000 Hz +I (224) app_init: Application information: +I (227) app_init: Project name: ESP_IDF_TouchDrv_Example +I (234) app_init: App version: v0.2.5-8-gde9a1d2-dirty +I (240) app_init: Compile time: Jan 22 2025 17:32:37 +I (246) app_init: ELF file SHA256: ef2e805bc... +I (251) app_init: ESP-IDF: v5.3-beta1-105-g3f632df143-dirt +I (258) efuse_init: Min chip rev: v0.0 +I (263) efuse_init: Max chip rev: v3.99 +I (268) efuse_init: Chip rev: v1.0 +I (273) heap_init: Initializing. RAM available for dynamic allocation: +I (280) heap_init: At 3FFAE6E0 len 00001920 (6 KiB): DRAM +I (286) heap_init: At 3FFB2BD0 len 0002D430 (181 KiB): DRAM +I (292) heap_init: At 3FFE0440 len 00003AE0 (14 KiB): D/IRAM +I (299) heap_init: At 3FFE4350 len 0001BCB0 (111 KiB): D/IRAM +I (305) heap_init: At 4008C77C len 00013884 (78 KiB): IRAM +I (313) spi_flash: detected chip: winbond +I (316) spi_flash: flash io: dio +W (320) spi_flash: Detected size(16384k) larger than the size in the binary image header(2048k). Using the size in the binary image header. +I (334) main_task: Started on CPU0 +I (344) main_task: Calling app_main() +I (344) I2C: Implemented using read and write callback methods (Use higher version >= 5.0 API) +W (344) i2c.master: Please check pull-up resistances whether be connected properly. Otherwise unexpected behavior would happen. For more detailed information, please read docs +I (364) gpio: GPIO[21]| InputEn: 1| OutputEn: 1| OpenDrain: 1| Pullup: 0| Pulldown: 0| Intr:0 +I (374) gpio: GPIO[22]| InputEn: 1| OutputEn: 1| OpenDrain: 1| Pullup: 0| Pulldown: 0| Intr:0 +I (384) main: I2C initialized successfully +Scan I2C Devices: + 0 1 2 3 4 5 6 7 8 9 a b c d e f +00: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- +10: -- -- -- -- -- -- -- -- -- 19 -- -- -- -- -- -- +20: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- +30: -- -- -- -- -- 35 -- -- -- -- -- -- -- -- -- -- +40: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- +50: -- 51 -- -- -- -- -- -- -- -- -- -- -- -- -- -- +60: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- +70: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- + + + +I (434) RTC: ----DRIVER PCF8563 ---- +I (434) RTC: Implemented using built-in read and write methods (Use higher version >= 5.0 API) +Using ESP-IDF Driver interface.Added Device Address : 0x51 New Dev Address: 0x3ffb4f9c Speed :400000 I (444) RTC: Initializing PCF8563 real-time clock successfully! +I (464) BMA: ----DRIVER BMA423---- +I (464) BMA: Implemented using built-in read and write methods (Use higher version >= 5.0 API) +Using ESP-IDF Driver interface.Added Device Address : 0x19 New Dev Address: 0x3ffb4ffc Speed :400000 No need configure!I (474) BMA: Initialization of BMA423 accelerometer is successful! +I (494) main: Run... +I (494) main_task: Returned from app_main() +I (494) RTC: Friday, January 17 2025 04:30:30 +I (504) RTC: Jan 17 2025 04:30:30 +I (504) RTC: Friday, 17. January 2025 04:30AM +I (514) BMA423: Temperature:38.00*C +I (514) BMA423: Temperature:100.40*F +I (524) BMA423: Direction:5 +I (1524) RTC: Friday, January 17 2025 04:30:31 +I (1524) RTC: Jan 17 2025 04:30:31 +I (1524) RTC: Friday, 17. January 2025 04:30AM +I (1524) BMA423: Temperature:38.00*C +I (1524) BMA423: Temperature:100.40*F +I (1534) BMA423: Direction:5 +I (2534) RTC: Friday, January 17 2025 04:30:32 +I (2534) RTC: Jan 17 2025 04:30:32 +I (2534) RTC: Friday, 17. January 2025 04:30AM +I (2534) BMA423: Temperature:38.00*C +I (2534) BMA423: Temperature:100.40*F +I (2544) BMA423: Direction:5 +I (3544) RTC: Friday, January 17 2025 04:30:33 +I (3544) RTC: Jan 17 2025 04:30:33 +I (3544) RTC: Friday, 17. January 2025 04:30AM +I (3544) BMA423: Temperature:38.00*C +I (3544) BMA423: Temperature:100.40*F +``` + +### Legacy Driver + +```bash +rst:0x1 (POWERON_RESET),boot:0x13 (SPI_FAST_FLASH_BOOT) +configsip: 0, SPIWP:0xee +clk_drv:0x00,q_drv:0x00,d_drv:0x00,cs0_drv:0x00,hd_drv:0x00,wp_drv:0x00 +mode:DIO, clock div:2 +load:0x3fff0030,len:7176 +load:0x40078000,len:15564 +ho 0 tail 12 room 4 +load:0x40080400,len:4 +0x40080400: _init at ??:? + +load:0x40080404,len:3904 +entry 0x40080640 +I (30) boot: ESP-IDF v5.3-beta1-105-g3f632df143-dirt 2nd stage bootloader +I (31) boot: compile time Jan 22 2025 17:30:49 +I (33) boot: Multicore bootloader +I (37) boot: chip revision: v1.0 +I (41) boot.esp32: SPI Speed : 40MHz +I (45) boot.esp32: SPI Mode : DIO +I (50) boot.esp32: SPI Flash Size : 2MB +I (54) boot: Enabling RNG early entropy source... +I (60) boot: Partition Table: +I (63) boot: ## Label Usage Type ST Offset Length +I (71) boot: 0 nvs WiFi data 01 02 00009000 00006000 +I (78) boot: 1 phy_init RF data 01 01 0000f000 00001000 +I (86) boot: 2 factory factory app 00 00 00010000 00100000 +I (93) boot: End of partition table +I (97) esp_image: segment 0: paddr=00010020 vaddr=3f400020 size=0d200h ( 53760) map +I (124) esp_image: segment 1: paddr=0001d228 vaddr=3ffb0000 size=022e8h ( 8936) load +I (128) esp_image: segment 2: paddr=0001f518 vaddr=40080000 size=00b00h ( 2816) load +I (131) esp_image: segment 3: paddr=00020020 vaddr=400d0020 size=1b71ch (112412) map +I (177) esp_image: segment 4: paddr=0003b744 vaddr=40080b00 size=0ccd8h ( 52440) load +I (204) boot: Loaded app from partition at offset 0x10000 +I (205) boot: Disabling RNG early entropy source... +I (216) cpu_start: Multicore app +I (225) cpu_start: Pro cpu start user code +I (225) cpu_start: cpu freq: 240000000 Hz +I (225) app_init: Application information: +I (228) app_init: Project name: ESP_IDF_SensorPCF8563 +I (234) app_init: App version: v0.2.5-8-gde9a1d2-dirty +I (240) app_init: Compile time: Jan 22 2025 17:47:23 +I (246) app_init: ELF file SHA256: 0fcff42da... +I (251) app_init: ESP-IDF: v5.3-beta1-105-g3f632df143-dirt +I (258) efuse_init: Min chip rev: v0.0 +I (263) efuse_init: Max chip rev: v3.99 +I (268) efuse_init: Chip rev: v1.0 +I (273) heap_init: Initializing. RAM available for dynamic allocation: +I (280) heap_init: At 3FFAE6E0 len 00001920 (6 KiB): DRAM +I (286) heap_init: At 3FFB2BF0 len 0002D410 (181 KiB): DRAM +I (292) heap_init: At 3FFE0440 len 00003AE0 (14 KiB): D/IRAM +I (299) heap_init: At 3FFE4350 len 0001BCB0 (111 KiB): D/IRAM +I (305) heap_init: At 4008D7D8 len 00012828 (74 KiB): IRAM +I (313) spi_flash: detected chip: winbond +I (316) spi_flash: flash io: dio +W (320) spi_flash: Detected size(16384k) larger than the size in the binary image header(2048k). Using the size in the binary image header. +W (333) i2c: This driver is an old driver, please migrate your application code to adapt `driver/i2c_master.h` +I (344) main_task: Started on CPU0 +I (354) main_task: Calling app_main() +I (354) I2C: Implemented using read and write callback methods (Use lower version < 5.0 API) +I (354) main: I2C initialized successfully + 0 1 2 3 4 5 6 7 8 9 a b c d e f +00: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- +10: -- -- -- -- -- -- -- -- -- 19 -- -- -- -- -- -- +20: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- +30: -- -- -- -- -- 35 -- -- -- -- -- -- -- -- -- -- +40: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- +50: -- 51 -- -- -- -- -- -- -- -- -- -- -- -- -- -- +60: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- +70: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- +I (404) RTC: ----DRIVER PCF8563 ---- +I (404) RTC: Implemented using built-in read and write methods (Use lower version < 5.0 API) +I (414) RTC: Initializing PCF8563 real-time clock successfully! +I (424) BMA: ----DRIVER BMA423---- +I (424) BMA: Implemented using built-in read and write methods (Use lower version < 5.0 API) +I (444) BMA: Initialization of BMA423 accelerometer is successful! +I (444) main: Run... +I (444) main_task: Returned from app_main() +I (454) RTC: Friday, January 17 2025 04:30:30 +I (454) RTC: Jan 17 2025 04:30:30 +I (464) RTC: Friday, 17. January 2025 04:30AM +I (464) BMA423: Temperature:37.00*C +I (474) BMA423: Temperature:98.60*F +I (474) BMA423: Direction:5 +I (1474) RTC: Friday, January 17 2025 04:30:31 +I (1474) RTC: Jan 17 2025 04:30:31 +I (1474) RTC: Friday, 17. January 2025 04:30AM +I (1474) BMA423: Temperature:37.00*C +I (1474) BMA423: Temperature:98.60*F +I (1484) BMA423: Direction:5 +``` + +### Use Read/Write/Hal Callback + +```bash +rst:0x1 (POWERON_RESET),boot:0x13 (SPI_FAST_FLASH_BOOT) +configsip: 0, SPIWP:0xee +clk_drv:0x00,q_drv:0x00,d_drv:0x00,cs0_drv:0x00,hd_drv:0x00,wp_drv:0x00 +mode:DIO, clock div:2 +load:0x3fff0030,len:7176 +load:0x40078000,len:15564 +ho 0 tail 12 room 4 +load:0x40080400,len:4 +0x40080400: _init at ??:? + +load:0x40080404,len:3904 +entry 0x40080640 +I (30) boot: ESP-IDF v5.3-beta1-105-g3f632df143-dirt 2nd stage bootloader +I (31) boot: compile time Jan 22 2025 17:30:49 +I (33) boot: Multicore bootloader +I (37) boot: chip revision: v1.0 +I (41) boot.esp32: SPI Speed : 40MHz +I (45) boot.esp32: SPI Mode : DIO +I (50) boot.esp32: SPI Flash Size : 2MB +I (54) boot: Enabling RNG early entropy source... +I (60) boot: Partition Table: +I (63) boot: ## Label Usage Type ST Offset Length +I (71) boot: 0 nvs WiFi data 01 02 00009000 00006000 +I (78) boot: 1 phy_init RF data 01 01 0000f000 00001000 +I (86) boot: 2 factory factory app 00 00 00010000 00100000 +I (93) boot: End of partition table +I (97) esp_image: segment 0: paddr=00010020 vaddr=3f400020 size=0d2b0h ( 53936) map +I (124) esp_image: segment 1: paddr=0001d2d8 vaddr=3ffb0000 size=022e8h ( 8936) load +I (128) esp_image: segment 2: paddr=0001f5c8 vaddr=40080000 size=00a50h ( 2640) load +I (131) esp_image: segment 3: paddr=00020020 vaddr=400d0020 size=1b97ch (113020) map +I (177) esp_image: segment 4: paddr=0003b9a4 vaddr=40080a50 size=0cd88h ( 52616) load +I (205) boot: Loaded app from partition at offset 0x10000 +I (205) boot: Disabling RNG early entropy source... +I (216) cpu_start: Multicore app +I (225) cpu_start: Pro cpu start user code +I (225) cpu_start: cpu freq: 240000000 Hz +I (225) app_init: Application information: +I (228) app_init: Project name: ESP_IDF_SensorPCF8563 +I (234) app_init: App version: v0.2.5-8-gde9a1d2-dirty +I (240) app_init: Compile time: Jan 22 2025 18:19:56 +I (246) app_init: ELF file SHA256: 952e2e97b... +I (252) app_init: ESP-IDF: v5.3-beta1-105-g3f632df143-dirt +I (259) efuse_init: Min chip rev: v0.0 +I (263) efuse_init: Max chip rev: v3.99 +I (268) efuse_init: Chip rev: v1.0 +I (273) heap_init: Initializing. RAM available for dynamic allocation: +I (281) heap_init: At 3FFAE6E0 len 00001920 (6 KiB): DRAM +I (286) heap_init: At 3FFB2BF0 len 0002D410 (181 KiB): DRAM +I (293) heap_init: At 3FFE0440 len 00003AE0 (14 KiB): D/IRAM +I (299) heap_init: At 3FFE4350 len 0001BCB0 (111 KiB): D/IRAM +I (306) heap_init: At 4008D7D8 len 00012828 (74 KiB): IRAM +I (313) spi_flash: detected chip: winbond +I (316) spi_flash: flash io: dio +W (320) spi_flash: Detected size(16384k) larger than the size in the binary image header(2048k). Using the size in the binary image header. +W (333) i2c: This driver is an old driver, please migrate your application code to adapt `driver/i2c_master.h` +I (345) main_task: Started on CPU0 +I (355) main_task: Calling app_main() +I (355) I2C: Implemented using read and write callback methods (Use lower version < 5.0 API) +I (355) main: I2C initialized successfully + 0 1 2 3 4 5 6 7 8 9 a b c d e f +00: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- +10: -- -- -- -- -- -- -- -- -- 19 -- -- -- -- -- -- +20: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- +30: -- -- -- -- -- 35 -- -- -- -- -- -- -- -- -- -- +40: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- +50: -- 51 -- -- -- -- -- -- -- -- -- -- -- -- -- -- +60: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- +70: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- +I (405) RTC: ----DRIVER PCF8563 ---- +I (405) RTC: Implemented using read and write callback methods +I (415) RTC: Initializing PCF8563 real-time clock successfully! +I (425) BMA: ----DRIVER BMA423---- +I (425) BMA: Implemented using read and write callback methods +I (435) BMA: Initialization of BMA423 accelerometer is successful! +I (445) main: Run... +I (445) main_task: Returned from app_main() +I (445) RTC: Friday, January 17 2025 04:30:30 +I (455) RTC: Jan 17 2025 04:30:30 +I (455) RTC: Friday, 17. January 2025 04:30AM +I (465) BMA423: Temperature:35.00*C +I (465) BMA423: Temperature:95.00*F +I (475) BMA423: Direction:5 +I (1475) RTC: Friday, January 17 2025 04:30:31 +I (1475) RTC: Jan 17 2025 04:30:31 +I (1475) RTC: Friday, 17. January 2025 04:30AM +I (1475) BMA423: Temperature:35.00*C +I (1475) BMA423: Temperature:95.00*F +I (1485) BMA423: Direction:5 +I (2485) RTC: Friday, January 17 2025 04:30:32 +I (2485) RTC: Jan 17 2025 04:30:32 +I (2485) RTC: Friday, 17. January 2025 04:30AM +``` + +### BHI260AP SPI Interface + +```bash +SPIWP:0xee +mode:DIO, clock div:1 +load:0x3fce2810,len:0x178c +load:0x403c8700,len:0x4 +load:0x403c8704,len:0xc10 +load:0x403cb700,len:0x2dac +entry 0x403c8904 +I (26) boot: ESP-IDF v5.3-beta1-105-g3f632df143-dirt 2nd stage bootloader +I (27) boot: compile time Jan 23 2025 11:42:56 +I (27) boot: Multicore bootloader +I (27) boot: chip revision: v0.1 +I (27) boot.esp32s3: Boot SPI Speed : 80MHz +I (27) boot.esp32s3: SPI Mode : DIO +I (28) boot.esp32s3: SPI Flash Size : 2MB +I (28) boot: Enabling RNG early entropy source... +I (28) boot: Partition Table: +I (28) boot: ## Label Usage Type ST Offset Length +I (29) boot: 0 nvs WiFi data 01 02 00009000 00006000 +I (29) boot: 1 phy_init RF data 01 01 0000f000 00001000 +I (29) boot: 2 factory factory app 00 00 00010000 00100000 +I (30) boot: End of partition table +I (30) esp_image: segment 0: paddr=00010020 vaddr=3c030020 size=29698h (169624) map +I (61) esp_image: segment 1: paddr=000396c0 vaddr=3fc94a00 size=02b0ch ( 11020) load +I (64) esp_image: segment 2: paddr=0003c1d4 vaddr=40374000 size=03e44h ( 15940) load +I (68) esp_image: segment 3: paddr=00040020 vaddr=42000020 size=28a70h (166512) map +I (98) esp_image: segment 4: paddr=00068a98 vaddr=40377e44 size=0cb2ch ( 52012) load +I (116) boot: Loaded app from partition at offset 0x10000 +I (117) boot: Disabling RNG early entropy source... +I (117) cpu_start: Multicore app +I (127) cpu_start: Pro cpu start user code +I (127) cpu_start: cpu freq: 240000000 Hz +I (127) app_init: Application information: +I (127) app_init: Project name: ESP_IDF_SensorExamples +I (127) app_init: App version: v0.2.5-8-gde9a1d2-dirty +I (128) app_init: Compile time: Jan 23 2025 11:44:54 +I (128) app_init: ELF file SHA256: 3512ddfc8... +I (128) app_init: ESP-IDF: v5.3-beta1-105-g3f632df143-dirt +I (128) efuse_init: Min chip rev: v0.0 +I (128) efuse_init: Max chip rev: v0.99 +I (128) efuse_init: Chip rev: v0.1 +I (129) heap_init: Initializing. RAM available for dynamic allocation: +I (129) heap_init: At 3FC97EC0 len 00051850 (326 KiB): RAM +I (129) heap_init: At 3FCE9710 len 00005724 (21 KiB): RAM +I (129) heap_init: At 3FCF0000 len 00008000 (32 KiB): DRAM +I (130) heap_init: At 600FE100 len 00001EE8 (7 KiB): RTCRAM +I (131) spi_flash: detected chip: generic +I (131) spi_flash: flash io: dio +W (131) spi_flash: Detected size(4096k) larger than the size in the binary image header(2048k). Using the size in the binary image header. +I (132) sleep: Configure to isolate all GPIO pins in sleep state +I (132) sleep: Enable automatic switching of GPIO sleep configuration +I (133) main_task: Started on CPU0 +I (143) main_task: Calling app_main() +I (143) BHI: ----DRIVER BHI260AP---- +I (143) gpio: GPIO[36]| InputEn: 0| OutputEn: 1| OpenDrain: 0| Pullup: 0| Pulldown: 0| Intr:0 +I (153) SensorLib: BHI260/BHA260 found. Product ID read 0x89 +I (583) SensorLib: Boot successful. Kernel version 5991. +I (583) SensorLib: [META EVENT WAKE UP] Firmware initialized. Firmware version 5991 +I (583) SensorLib: [META EVENT] Firmware initialized. Firmware version 5991 +I (943) BHI: Initialization of BHI260AP is successful! +Product ID : 89 +Kernel version : 5991 +User version : 5991 +ROM version : 5166 +Power state : sleeping +Host interface : SPI +Feature status : 0x4a +Boot Status : 0x38: No flash installed. Host interface ready. Firmware verification done. Virtual sensor list. +Sensor ID | Sensor Name | ID | Ver | Min rate | Max rate | +----------+--------------------------------------+-----+-----+-----------+-----------| + 1 | Accelerometer passthrough | 205 | 1 | 1.5625 | 400.0000 | + 3 | Accelerometer uncalibrated | 203 | 1 | 1.5625 | 400.0000 | + 4 | Accelerometer corrected | 241 | 1 | 1.5625 | 400.0000 | + 5 | Accelerometer offset | 209 | 1 | 1.0000 | 1.0000 | + 6 | Accelerometer corrected wake up | 192 | 1 | 1.5625 | 400.0000 | + 7 | Accelerometer uncalibrated wake up | 204 | 1 | 1.5625 | 400.0000 | + 10 | Gyroscope passthrough | 207 | 1 | 1.5625 | 400.0000 | + 12 | Gyroscope uncalibrated | 244 | 1 | 1.5625 | 400.0000 | + 13 | Gyroscope corrected | 243 | 1 | 1.5625 | 400.0000 | + 14 | Gyroscope offset | 208 | 1 | 1.0000 | 1.0000 | + 15 | Gyroscope wake up | 194 | 1 | 1.5625 | 400.0000 | + 16 | Gyroscope uncalibrated wake up | 195 | 1 | 1.5625 | 400.0000 | + 28 | Gravity vector | 247 | 1 | 1.5625 | 400.0000 | + 29 | Gravity vector wake up | 198 | 1 | 1.5625 | 400.0000 | + 31 | Linear acceleration | 246 | 1 | 1.5625 | 400.0000 | + 32 | Linear acceleration wake up | 197 | 1 | 1.5625 | 400.0000 | + 37 | Game rotation vector | 252 | 1 | 1.5625 | 400.0000 | + 38 | Game rotation vector wake up | 200 | 1 | 1.5625 | 400.0000 | + 48 | Tilt detector | 236 | 1 | 1.0000 | 1.0000 | + 50 | Step detector | 248 | 1 | 1.0000 | 1.0000 | + 52 | Step counter | 249 | 1 | 1.0000 | 1.0000 | + 53 | Step counter wake up | 231 | 1 | 0.0005 | 25.0000 | + 55 | Significant motion | 250 | 1 | 1.0000 | 1.0000 | + 57 | Wake gesture | 232 | 1 | 1.0000 | 1.0000 | + 59 | Glance gesture | 234 | 1 | 1.0000 | 1.0000 | + 61 | Pickup gesture | 233 | 1 | 1.0000 | 1.0000 | + 63 | Activity recognition | 235 | 1 | 1.0000 | 1.0000 | + 67 | Wrist tilt gesture | 162 | 1 | 1.0000 | 1.0000 | + 69 | Device orientation | 163 | 1 | 1.0000 | 1.0000 | + 70 | Device orientation wake up | 164 | 1 | 1.0000 | 1.0000 | + 75 | Stationary detect | 161 | 1 | 1.0000 | 1.0000 | + 77 | Motion detect | 160 | 1 | 1.0000 | 1.0000 | + 94 | Step detector wake up | 230 | 1 | 1.0000 | 1.0000 | +I (1293) gpio: GPIO[37]| InputEn: 1| OutputEn: 0| OpenDrain: 0| Pullup: 0| Pulldown: 0| Intr:2 +I (1293) main: Run... +I (1293) main_task: Returned from app_main() +I (1683) SensorLib: [META EVENT] Power mode changed for sensor id 1 +I (1683) SensorLib: [META EVENT] Sample rate changed for sensor id 1 +I (1683) SensorLib: [META EVENT] Power mode changed for sensor id 10 +I (1683) SensorLib: [META EVENT] Sample rate changed for sensor id 10 +I (1683) BHI: Accelerometer passthrough: x: -0.212646, y: 0.300293, z: 0.953613; +I (1683) BHI: Gyroscope passthrough: x: -0.671387, y: -0.732422, z: -0.122070; +I (2313) BHI: Accelerometer passthrough: x: -0.213379, y: 0.302734, z: 0.960205; +I (2313) BHI: Gyroscope passthrough: x: -0.610352, y: -0.671387, z: -0.061035; +I (2953) BHI: Accelerometer passthrough: x: -0.213623, y: 0.302734, z: 0.960449; +I (2953) BHI: Gyroscope passthrough: x: -0.671387, y: -0.732422, z: -0.061035; +I (3583) BHI: Accelerometer passthrough: x: -0.213379, y: 0.302979, z: 0.960205; +I (3583) BHI: Gyroscope passthrough: x: -0.610352, y: -0.610352, z: -0.061035; +I (4223) BHI: Accelerometer passthrough: x: -0.213623, y: 0.302490, z: 0.960449; +I (4223) BHI: Gyroscope passthrough: x: -0.610352, y: -0.671387, z: -0.122070; +I (4853) BHI: Accelerometer passthrough: x: -0.213867, y: 0.303467, z: 0.960205; +I (4853) BHI: Gyroscope passthrough: x: -0.610352, y: -0.671387, z: -0.122070; +``` + +### BHI260 I2C Interface + +```bash +SPIWP:0xee +mode:DIO, clock div:1 +load:0x3fce2810,len:0x178c +load:0x403c8700,len:0x4 +load:0x403c8704,len:0xcb8 +load:0x403cb700,len:0x2d9c +entry 0x403c8914 +I (26) boot: ESP-IDF v5.3-beta1-105-g3f632df143-dirt 2nd stage bootloader +I (27) boot: compile time Jan 23 2025 14:20:21 +I (28) boot: Multicore bootloader +I (32) boot: chip revision: v0.2 +I (36) boot.esp32s3: Boot SPI Speed : 80MHz +I (41) boot.esp32s3: SPI Mode : DIO +I (45) boot.esp32s3: SPI Flash Size : 2MB +I (50) boot: Enabling RNG early entropy source... +I (55) boot: Partition Table: +I (59) boot: ## Label Usage Type ST Offset Length +I (66) boot: 0 nvs WiFi data 01 02 00009000 00006000 +I (74) boot: 1 phy_init RF data 01 01 0000f000 00001000 +I (81) boot: 2 factory factory app 00 00 00010000 00100000 +I (89) boot: End of partition table +I (93) esp_image: segment 0: paddr=00010020 vaddr=3c030020 size=2abc8h (175048) map +I (133) esp_image: segment 1: paddr=0003abf0 vaddr=3fc95300 size=02bcch ( 11212) load +I (135) esp_image: segment 2: paddr=0003d7c4 vaddr=40374000 size=02854h ( 10324) load +I (141) esp_image: segment 3: paddr=00040020 vaddr=42000020 size=2b8d8h (178392) map +I (179) esp_image: segment 4: paddr=0006b900 vaddr=40376854 size=0ea24h ( 59940) load +I (199) boot: Loaded app from partition at offset 0x10000 +I (200) boot: Disabling RNG early entropy source... +I (211) cpu_start: Multicore app +I (220) cpu_start: Pro cpu start user code +I (221) cpu_start: cpu freq: 160000000 Hz +I (221) app_init: Application information: +I (223) app_init: Project name: ESP_IDF_SensorExamples +I (230) app_init: App version: v0.2.5-8-gde9a1d2-dirty +I (236) app_init: Compile time: Jan 23 2025 14:33:38 +I (242) app_init: ELF file SHA256: 54e4e1748... +I (247) app_init: ESP-IDF: v5.3-beta1-105-g3f632df143-dirt +I (254) efuse_init: Min chip rev: v0.0 +I (259) efuse_init: Max chip rev: v0.99 +I (264) efuse_init: Chip rev: v0.2 +I (269) heap_init: Initializing. RAM available for dynamic allocation: +I (276) heap_init: At 3FC988C8 len 00050E48 (323 KiB): RAM +I (282) heap_init: At 3FCE9710 len 00005724 (21 KiB): RAM +I (288) heap_init: At 3FCF0000 len 00008000 (32 KiB): DRAM +I (294) heap_init: At 600FE100 len 00001EE8 (7 KiB): RTCRAM +I (302) spi_flash: detected chip: winbond +I (305) spi_flash: flash io: dio +W (309) spi_flash: Detected size(16384k) larger than the size in the binary image header(2048k). Using the size in the binary image header. +I (322) sleep: Configure to isolate all GPIO pins in sleep state +I (329) sleep: Enable automatic switching of GPIO sleep configuration +I (337) main_task: Started on CPU0 +I (347) main_task: Calling app_main() +I (347) I2C: Implemented using read and write callback methods (Use higher version >= 5.0 API) +W (357) i2c.master: Please check pull-up resistances whether be connected properly. Otherwise unexpected behavior would happen. For more detailed information, please read docs +I (367) gpio: GPIO[2]| InputEn: 1| OutputEn: 1| OpenDrain: 1| Pullup: 0| Pulldown: 0| Intr:0 +I (377) gpio: GPIO[3]| InputEn: 1| OutputEn: 1| OpenDrain: 1| Pullup: 0| Pulldown: 0| Intr:0 +I (387) main: I2C initialized successfully +Scan I2C Devices: + 0 1 2 3 4 5 6 7 8 9 a b c d e f +00: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- +10: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- +20: -- -- -- -- -- -- -- -- 28 -- -- -- -- -- -- -- +30: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- +40: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- +50: -- 51 -- -- -- -- -- -- -- -- 5a -- -- -- -- -- +60: -- -- -- -- -- -- -- -- -- -- -- 6b -- -- -- -- +70: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- + + + +I (437) BHI: ----DRIVER BHI260AP---- +I (447) BHI: Implemented using built-in read and write methods (Use higher version >= 5.0 API) +I (457) SensorLib: Using ESP-IDF Driver interface. +I (457) SensorLib: Added Device Address : 0x28 New Dev Address: 0x3fc9cc34 Speed :400000 +I (477) SensorLib: BHI260/BHA260 found. Product ID read 0x89 +I (3497) SensorLib: Boot successful. Kernel version 5991. +I (3497) SensorLib: [META EVENT WAKE UP] Firmware initialized. Firmware version 5991 +I (3497) SensorLib: [META EVENT] Firmware initialized. Firmware version 5991 +I (3597) BHI: Initialize BHI260AP using I2C interface +Product ID : 89 +Kernel version : 5991 +User version : 5991 +ROM version : 5166 +Power state : sleeping +Host interface : I2C +Feature status : 0x4a +Boot Status : 0x38: No flash installed. Host interface ready. Firmware verification done. Virtual sensor list. +Sensor ID | Sensor Name | ID | Ver | Min rate | Max rate | +----------+--------------------------------------+-----+-----+-----------+-----------| + 1 | Accelerometer passthrough | 205 | 1 | 1.5625 | 400.0000 | + 3 | Accelerometer uncalibrated | 203 | 1 | 1.5625 | 400.0000 | + 4 | Accelerometer corrected | 241 | 1 | 1.5625 | 400.0000 | + 5 | Accelerometer offset | 209 | 1 | 1.0000 | 1.0000 | + 6 | Accelerometer corrected wake up | 192 | 1 | 1.5625 | 400.0000 | + 7 | Accelerometer uncalibrated wake up | 204 | 1 | 1.5625 | 400.0000 | + 10 | Gyroscope passthrough | 207 | 1 | 1.5625 | 400.0000 | + 12 | Gyroscope uncalibrated | 244 | 1 | 1.5625 | 400.0000 | + 13 | Gyroscope corrected | 243 | 1 | 1.5625 | 400.0000 | + 14 | Gyroscope offset | 208 | 1 | 1.0000 | 1.0000 | + 15 | Gyroscope wake up | 194 | 1 | 1.5625 | 400.0000 | + 16 | Gyroscope uncalibrated wake up | 195 | 1 | 1.5625 | 400.0000 | + 28 | Gravity vector | 247 | 1 | 1.5625 | 400.0000 | + 29 | Gravity vector wake up | 198 | 1 | 1.5625 | 400.0000 | + 31 | Linear acceleration | 246 | 1 | 1.5625 | 400.0000 | + 32 | Linear acceleration wake up | 197 | 1 | 1.5625 | 400.0000 | + 37 | Game rotation vector | 252 | 1 | 1.5625 | 400.0000 | + 38 | Game rotation vector wake up | 200 | 1 | 1.5625 | 400.0000 | + 48 | Tilt detector | 236 | 1 | 1.0000 | 1.0000 | + 50 | Step detector | 248 | 1 | 1.0000 | 1.0000 | + 52 | Step counter | 249 | 1 | 1.0000 | 1.0000 | + 53 | Step counter wake up | 231 | 1 | 0.0005 | 25.0000 | + 55 | Significant motion | 250 | 1 | 1.0000 | 1.0000 | + 57 | Wake gesture | 232 | 1 | 1.0000 | 1.0000 | + 59 | Glance gesture | 234 | 1 | 1.0000 | 1.0000 | + 61 | Pickup gesture | 233 | 1 | 1.0000 | 1.0000 | + 63 | Activity recognition | 235 | 1 | 1.0000 | 1.0000 | + 67 | Wrist tilt gesture | 162 | 1 | 1.0000 | 1.0000 | + 69 | Device orientation | 163 | 1 | 1.0000 | 1.0000 | + 70 | Device orientation wake up | 164 | 1 | 1.0000 | 1.0000 | + 75 | Stationary detect | 161 | 1 | 1.0000 | 1.0000 | + 77 | Motion detect | 160 | 1 | 1.0000 | 1.0000 | + 94 | Step detector wake up | 230 | 1 | 1.0000 | 1.0000 | +I (3937) gpio: GPIO[8]| InputEn: 1| OutputEn: 0| OpenDrain: 0| Pullup: 0| Pulldown: 0| Intr:2 +I (3947) main: Run... +I (3947) main_task: Returned from app_main() +I (4347) SensorLib: [META EVENT] Power mode changed for sensor id 1 +I (4347) SensorLib: [META EVENT] Sample rate changed for sensor id 1 +I (4347) SensorLib: [META EVENT] Power mode changed for sensor id 10 +I (4357) SensorLib: [META EVENT] Sample rate changed for sensor id 10 +I (4357) BHI: Accelerometer passthrough: x: 0.129395, y: 0.024658, z: 1.018799; +I (4367) BHI: Gyroscope passthrough: x: -0.305176, y: 0.183105, z: 0.183105; +I (4987) BHI: Accelerometer passthrough: x: 0.129639, y: 0.024414, z: 1.024902; +I (4987) BHI: Gyroscope passthrough: x: -0.244141, y: 0.183105, z: 0.183105; +I (5627) BHI: Accelerometer passthrough: x: 0.129639, y: 0.025391, z: 1.025635; +I (5627) BHI: Gyroscope passthrough: x: -0.305176, y: 0.183105, z: 0.183105; +I (6267) BHI: Accelerometer passthrough: x: 0.130127, y: 0.025146, z: 1.025391; +I (6267) BHI: Gyroscope passthrough: x: -0.244141, y: 0.244141, z: 0.183105; +I (6907) BHI: Accelerometer passthrough: x: 0.129883, y: 0.024902, z: 1.025635; +I (6907) BHI: Gyroscope passthrough: x: -0.305176, y: 0.244141, z: 0.244141; +I (7547) BHI: Accelerometer passthrough: x: 0.129883, y: 0.025635, z: 1.025635; +I (7547) BHI: Gyroscope passthrough: x: -0.305176, y: 0.183105, z: 0.244141; +I (8187) BHI: Accelerometer passthrough: x: 0.130127, y: 0.025146, z: 1.026123; +I (8187) BHI: Gyroscope passthrough: x: -0.305176, y: 0.244141, z: 0.183105; +I (8827) BHI: Accelerometer passthrough: x: 0.129883, y: 0.024902, z: 1.025879; +I (8827) BHI: Gyroscope passthrough: x: -0.305176, y: 0.183105, z: 0.183105; +``` + +### FT63XX + +```bash +rst:0x1 (POWERON_RESET),boot:0x13 (SPI_FAST_FLASH_BOOT) +configsip: 0, SPIWP:0xee +clk_drv:0x00,q_drv:0x00,d_drv:0x00,cs0_drv:0x00,hd_drv:0x00,wp_drv:0x00 +mode:DIO, clock div:2 +load:0x3fff0030,len:7176 +load:0x40078000,len:15564 +ho 0 tail 12 room 4 +load:0x40080400,len:4 +0x40080400: _init at ??:? + +load:0x40080404,len:3904 +entry 0x40080640 +I (30) boot: ESP-IDF v5.3-beta1-105-g3f632df143-dirt 2nd stage bootloader +I (30) boot: compile time Jan 23 2025 15:30:25 +I (33) boot: Multicore bootloader +I (37) boot: chip revision: v1.0 +I (41) boot.esp32: SPI Speed : 40MHz +I (45) boot.esp32: SPI Mode : DIO +I (50) boot.esp32: SPI Flash Size : 2MB +I (54) boot: Enabling RNG early entropy source... +I (60) boot: Partition Table: +I (63) boot: ## Label Usage Type ST Offset Length +I (71) boot: 0 nvs WiFi data 01 02 00009000 00006000 +I (78) boot: 1 phy_init RF data 01 01 0000f000 00001000 +I (85) boot: 2 factory factory app 00 00 00010000 00100000 +I (93) boot: End of partition table +I (97) esp_image: segment 0: paddr=00010020 vaddr=3f400020 size=0b860h ( 47200) map +I (122) esp_image: segment 1: paddr=0001b888 vaddr=3ffb0000 size=02258h ( 8792) load +I (125) esp_image: segment 2: paddr=0001dae8 vaddr=40080000 size=02530h ( 9520) load +I (131) esp_image: segment 3: paddr=00020020 vaddr=400d0020 size=18744h (100164) map +I (170) esp_image: segment 4: paddr=0003876c vaddr=40082530 size=0a210h ( 41488) load +I (193) boot: Loaded app from partition at offset 0x10000 +I (193) boot: Disabling RNG early entropy source... +I (205) cpu_start: Multicore app +I (214) cpu_start: Pro cpu start user code +I (214) cpu_start: cpu freq: 160000000 Hz +I (214) app_init: Application information: +I (217) app_init: Project name: ESP_IDF_SensorExamples +I (223) app_init: App version: v0.2.5-8-gde9a1d2-dirty +I (229) app_init: Compile time: Jan 23 2025 15:44:44 +I (235) app_init: ELF file SHA256: fe7a7c460... +I (240) app_init: ESP-IDF: v5.3-beta1-105-g3f632df143-dirt +I (247) efuse_init: Min chip rev: v0.0 +I (252) efuse_init: Max chip rev: v3.99 +I (257) efuse_init: Chip rev: v1.0 +I (262) heap_init: Initializing. RAM available for dynamic allocation: +I (269) heap_init: At 3FFAE6E0 len 00001920 (6 KiB): DRAM +I (275) heap_init: At 3FFB2B78 len 0002D488 (181 KiB): DRAM +I (281) heap_init: At 3FFE0440 len 00003AE0 (14 KiB): D/IRAM +I (288) heap_init: At 3FFE4350 len 0001BCB0 (111 KiB): D/IRAM +I (294) heap_init: At 4008C740 len 000138C0 (78 KiB): IRAM +I (302) spi_flash: detected chip: winbond +I (305) spi_flash: flash io: dio +W (309) spi_flash: Detected size(16384k) larger than the size in the binary image header(2048k). Using the size in the binary image header. +I (323) main_task: Started on CPU0 +I (333) main_task: Calling app_main() +I (333) I2C: Implemented using read and write callback methods (Use higher version >= 5.0 API) +I (333) gpio: GPIO[23]| InputEn: 1| OutputEn: 1| OpenDrain: 1| Pullup: 1| Pulldown: 0| Intr:0 +I (343) gpio: GPIO[32]| InputEn: 1| OutputEn: 1| OpenDrain: 1| Pullup: 1| Pulldown: 0| Intr:0 +I (353) main: I2C initialized successfully +Scan I2C Devices: + 0 1 2 3 4 5 6 7 8 9 a b c d e f +00: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- +10: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- +20: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- +30: -- -- -- -- -- -- -- -- 38 -- -- -- -- -- -- -- +40: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- +50: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- +60: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- +70: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- + + + +I (403) FT63XX: ----DRIVER FT63XX---- +I (403) FT63XX: Implemented using built-in read and write methods (Use higher version >= 5.0 API) +I (413) SensorLib: Using ESP-IDF Driver interface. +I (423) SensorLib: Added Device Address : 0x38 New Dev Address: 0x3ffb4f58 Speed :400000 +I (433) SensorLib: Vend ID: 0x11 +I (433) SensorLib: Chip ID: 0x64 +I (443) SensorLib: Firm Version: 0x3 +I (443) SensorLib: Point Rate Hz: 10 +I (453) SensorLib: Thresh : 60 +I (453) SensorLib: Chip library version : 0x501 +I (453) SensorLib: Chip period of monitor status : 0x28 +I (463) FT63XX: Initialization of FT63XX is successful! +I (473) main: Run... +I (473) main_task: Returned from app_main() +I (6733) FT63X6: Point[00] - X:113 Y:126 +I (6743) FT63X6: Point[00] - X:113 Y:126 +I (6753) FT63X6: Point[00] - X:113 Y:126 +I (6763) FT63X6: Point[00] - X:113 Y:126 +I (6773) FT63X6: Point[00] - X:113 Y:126 +I (6783) FT63X6: Point[00] - X:113 Y:126 +I (6793) FT63X6: Point[00] - X:113 Y:128 +I (6803) FT63X6: Point[00] - X:110 Y:140 +I (6813) FT63X6: Point[00] - X:109 Y:150 +I (6823) FT63X6: Point[00] - X:107 Y:162 +I (6833) FT63X6: Point[00] - X:105 Y:176 +I (6843) FT63X6: Point[00] - X:100 Y:193 +I (6853) FT63X6: Point[00] - X:92 Y:206 +I (7273) FT63X6: Point[00] - X:88 Y:273 +I (7283) FT63X6: Point[00] - X:88 Y:273 +I (7293) FT63X6: Point[00] - X:88 Y:273 +I (7303) FT63X6: Point[00] - X:90 Y:270 +I (7313) FT63X6: Point[00] - X:93 Y:266 +I (7323) FT63X6: Point[00] - X:99 Y:259 +I (7333) FT63X6: Point[00] - X:109 Y:247 +I (7343) FT63X6: Point[00] - X:118 Y:236 +I (7353) FT63X6: Point[00] - X:128 Y:223 +I (7363) FT63X6: Point[00] - X:138 Y:209 +I (7373) FT63X6: Point[00] - X:148 Y:195 +I (7383) FT63X6: Point[00] - X:158 Y:180 +I (7393) FT63X6: Point[00] - X:165 Y:169 +I (7403) FT63X6: Point[00] - X:170 Y:160 +I (7413) FT63X6: Point[00] - X:174 Y:153 +I (7423) FT63X6: Point[00] - X:177 Y:148 +I (7433) FT63X6: Point[00] - X:178 Y:145 +``` + +### XL9555 + +```bash +SPIWP:0xee +mode:DIO, clock div:1 +load:0x3fce2810,len:0x178c +load:0x403c8700,len:0x4 +load:0x403c8704,len:0xcb8 +load:0x403cb700,len:0x2d9c +entry 0x403c8914 +I (26) boot: ESP-IDF v5.3-beta1-105-g3f632df143-dirt 2nd stage bootloader +I (27) boot: compile time Jan 23 2025 16:15:44 +I (28) boot: Multicore bootloader +I (32) boot: chip revision: v0.1 +I (36) boot.esp32s3: Boot SPI Speed : 80MHz +I (41) boot.esp32s3: SPI Mode : DIO +I (45) boot.esp32s3: SPI Flash Size : 2MB +I (50) boot: Enabling RNG early entropy source... +I (55) boot: Partition Table: +I (59) boot: ## Label Usage Type ST Offset Length +I (66) boot: 0 nvs WiFi data 01 02 00009000 00006000 +I (74) boot: 1 phy_init RF data 01 01 0000f000 00001000 +I (81) boot: 2 factory factory app 00 00 00010000 00100000 +I (89) boot: End of partition table +I (93) esp_image: segment 0: paddr=00010020 vaddr=3c030020 size=0c95ch ( 51548) map +I (110) esp_image: segment 1: paddr=0001c984 vaddr=3fc93300 size=02ad8h ( 10968) load +I (113) esp_image: segment 2: paddr=0001f464 vaddr=40374000 size=00bb4h ( 2996) load +I (119) esp_image: segment 3: paddr=00020020 vaddr=42000020 size=20b8ch (134028) map +I (151) esp_image: segment 4: paddr=00040bb4 vaddr=40374bb4 size=0e6c4h ( 59076) load +I (170) boot: Loaded app from partition at offset 0x10000 +I (170) boot: Disabling RNG early entropy source... +I (182) cpu_start: Multicore app +I (191) cpu_start: Pro cpu start user code +I (191) cpu_start: cpu freq: 160000000 Hz +I (192) app_init: Application information: +I (194) app_init: Project name: ESP_IDF_SensorExamples +I (200) app_init: App version: v0.2.5-8-gde9a1d2-dirty +I (207) app_init: Compile time: Jan 23 2025 16:28:47 +I (213) app_init: ELF file SHA256: c5b0aa4bb... +I (218) app_init: ESP-IDF: v5.3-beta1-105-g3f632df143-dirt +I (225) efuse_init: Min chip rev: v0.0 +I (230) efuse_init: Max chip rev: v0.99 +I (235) efuse_init: Chip rev: v0.1 +I (240) heap_init: Initializing. RAM available for dynamic allocation: +I (247) heap_init: At 3FC967E8 len 00052F28 (331 KiB): RAM +I (253) heap_init: At 3FCE9710 len 00005724 (21 KiB): RAM +I (259) heap_init: At 3FCF0000 len 00008000 (32 KiB): DRAM +I (265) heap_init: At 600FE100 len 00001EE8 (7 KiB): RTCRAM +I (272) spi_flash: detected chip: winbond +I (276) spi_flash: flash io: dio +W (280) spi_flash: Detected size(16384k) larger than the size in the binary image header(2048k). Using the size in the binary image header. +I (293) sleep: Configure to isolate all GPIO pins in sleep state +I (300) sleep: Enable automatic switching of GPIO sleep configuration +I (307) main_task: Started on CPU0 +I (317) main_task: Calling app_main() +I (317) I2C: Implemented using read and write callback methods (Use higher version >= 5.0 API) +I (327) gpio: GPIO[8]| InputEn: 1| OutputEn: 1| OpenDrain: 1| Pullup: 1| Pulldown: 0| Intr:0 +I (337) gpio: GPIO[48]| InputEn: 1| OutputEn: 1| OpenDrain: 1| Pullup: 1| Pulldown: 0| Intr:0 +I (347) main: I2C initialized successfully +Scan I2C Devices: + 0 1 2 3 4 5 6 7 8 9 a b c d e f +00: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- +10: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- +20: 20 -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- +30: -- -- -- -- -- -- -- -- 38 -- -- -- -- -- -- -- +40: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- +50: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- +60: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- +70: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- + + + +I (397) XL9555: ----DRIVER XL9555 ---- +I (397) XL9555: Implemented using built-in read and write methods (Use higher version >= 5.0 API) +I (407) SensorLib: Using ESP-IDF Driver interface. +I (417) SensorLib: Added Device Address : 0xFF New Dev Address: 0x3fc9aad8 Speed :400000 +I (417) SensorLib: i2c_master_bus_rm_device +I (427) SensorLib: Using ESP-IDF Driver interface. +I (427) SensorLib: Added Device Address : 0x20 New Dev Address: 0x3fc9aad8 Speed :400000 +I (437) XL9555: Initializing XL9555 successfully! +I (447) main: Run... +I (447) main_task: Returned from app_main() +``` + +## Build process example + +Assuming you don't have esp-idf yet + +```bash +mkdir -p ~/esp +cd ~/esp +git clone --recursive https://github.com/espressif/esp-idf.git +git clone https://github.com/lewisxhe/SensorLib.git +cd esp-idf +./install.sh +. ./export.sh +cd .. +cd SensorLib/examples/ESP_IDF_SensorExamples + +Configure Sensor Type +Configure I2C Pins or SPI Pins +... +idf.py set-target esp32 +idf.py menuconfig +idf.py build +idf.py -b 921600 flash +idf.py monitor + +``` diff --git a/examples/ESP_IDF_SensorExamples/main/CMakeLists.txt b/examples/ESP_IDF_SensorExamples/main/CMakeLists.txt new file mode 100644 index 0000000..2371737 --- /dev/null +++ b/examples/ESP_IDF_SensorExamples/main/CMakeLists.txt @@ -0,0 +1,9 @@ +idf_component_register(SRCS + "sensor_pcf8563.cpp" + "sensor_bma423.cpp" + "sensor_bhi260.cpp" + "i2c_driver.cpp" + "touch_ft63x6.cpp" + "sensor_xl9555.cpp" + "main.cpp" + INCLUDE_DIRS ".") diff --git a/examples/ESP_IDF_SensorExamples/main/Kconfig.projbuild b/examples/ESP_IDF_SensorExamples/main/Kconfig.projbuild new file mode 100644 index 0000000..ce3a138 --- /dev/null +++ b/examples/ESP_IDF_SensorExamples/main/Kconfig.projbuild @@ -0,0 +1,115 @@ +menu "SensorLib Example Configuration" + + choice SENSOR_TYPE + prompt "Select Sensor Type" + default PCF8563 + help + Choose the type of sensor you are using. + + config PCF8563 + bool "PCF8563 Sensor" + config BMA423 + bool "BMA423 Sensor" + config BHI260 + bool "BHI260 Sensor" + config FT636X + bool "FT636X Capacitive touch" + config XL9555 + bool "XL9555 GPIO expansion" + endchoice + + choice BHI260_COMMUNICATION_TYPE + prompt "Select BHI260 Communication Type" + default USE_I2C_INTERFACE + depends on BHI260 + help + Choose the communication type for BHI260 sensor. + + config USE_I2C_INTERFACE + bool "I2C Communication" + config USE_SPI_INTERFACE + bool "SPI Communication" + endchoice + + choice I2C_COMMUNICATION_METHOD + prompt "SensorLib read and write methods" + default I2C_COMMUNICATION_METHOD_BUILTIN_RW + depends on (PCF8563 || BMA423 || FT636X || XL9555 || (BHI260 && USE_I2C_INTERFACE)) + help + Define SensorLib read and write methods + + config I2C_COMMUNICATION_METHOD_BUILTIN_RW + bool "Implemented using built-in read and write methods" + config I2C_COMMUNICATION_METHOD_CALLBACK_RW + bool "Implemented using read and write callback methods" + endchoice + + config I2C_MASTER_PORT_NUM + int "Sensor I2C Port Number" + default 1 + depends on (PCF8563 || BMA423 || FT636X || XL9555 || (BHI260 && USE_I2C_INTERFACE)) + help + Port number for I2C Master device. + + config I2C_MASTER_FREQUENCY + int "Master Frequency" + default 100000 + depends on (PCF8563 || BMA423 || FT636X || XL9555 || (BHI260 && USE_I2C_INTERFACE)) + help + I2C Speed of Master device. + + config SENSOR_SCL + int "Sensor SCL GPIO Num" + default 22 + depends on (PCF8563 || BMA423 || FT636X || XL9555 || (BHI260 && USE_I2C_INTERFACE)) + help + GPIO number for I2C clock line. + + config SENSOR_SDA + int "Sensor SDA GPIO Num" + default 21 + depends on (PCF8563 || BMA423 || FT636X || XL9555 || (BHI260 && USE_I2C_INTERFACE)) + help + GPIO number for I2C data line. + + config SPI_MISO + int "SPI MISO GPIO Num" + default 34 + depends on (BHI260 && USE_SPI_INTERFACE) + help + GPIO number for Sensor SPI MISO line. + + config SPI_MOSI + int "SPI MOSI GPIO Num" + default 33 + depends on (BHI260 && USE_SPI_INTERFACE) + help + GPIO number for Sensor SPI MOSI line. + + config SPI_SCK + int "SPI SCK GPIO Num" + default 35 + depends on (BHI260 && USE_SPI_INTERFACE) + help + GPIO number for Sensor SPI SCK line. + + config SPI_CS + int "SPI CS GPIO Num" + default 36 + depends on (BHI260 && USE_SPI_INTERFACE) + help + GPIO number for Sensor SPI CS line. + + config SENSOR_IRQ + int "Sensor Interrupt Pin" + default 37 + help + GPIO number for Sensor Interrupt line. + + config SENSOR_RST + int "Sensor reset Pin" + default 47 + help + GPIO number for Sensor Reset line. + +endmenu \ No newline at end of file diff --git a/examples/ESP_IDF_TouchDrv_Example/main/component.mk b/examples/ESP_IDF_SensorExamples/main/component.mk similarity index 100% rename from examples/ESP_IDF_TouchDrv_Example/main/component.mk rename to examples/ESP_IDF_SensorExamples/main/component.mk diff --git a/examples/ESP_IDF_SensorExamples/main/i2c_driver.cpp b/examples/ESP_IDF_SensorExamples/main/i2c_driver.cpp new file mode 100644 index 0000000..ece7abc --- /dev/null +++ b/examples/ESP_IDF_SensorExamples/main/i2c_driver.cpp @@ -0,0 +1,378 @@ +/** + * + * @license MIT License + * + * Copyright (c) 2025 lewis he + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * @file i2c_driver.cpp + * @author Lewis He (lewishe@outlook.com) + * @date 2025-01-19 + * + */ +#include +#include "freertos/FreeRTOS.h" +#include "freertos/task.h" +#include "driver/gpio.h" +#include "esp_log.h" +#include "sdkconfig.h" +#include "i2c_driver.h" + +#if CONFIG_I2C_COMMUNICATION_METHOD_BUILTIN_RW || CONFIG_I2C_COMMUNICATION_METHOD_CALLBACK_RW + +static const char *TAG = "I2C"; + +#define I2C_MASTER_NUM (i2c_port_t)CONFIG_I2C_MASTER_PORT_NUM +#define I2C_MASTER_SDA_IO (gpio_num_t)CONFIG_SENSOR_SDA +#define I2C_MASTER_SCL_IO (gpio_num_t)CONFIG_SENSOR_SCL +#define I2C_MASTER_FREQ_HZ CONFIG_I2C_MASTER_FREQUENCY /*!< I2C master clock frequency */ +#define I2C_MASTER_TX_BUF_DISABLE 0 /*!< I2C master doesn't need buffer */ +#define I2C_MASTER_RX_BUF_DISABLE 0 /*!< I2C master doesn't need buffer */ + +#if (ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL(5,0,0)) && defined(CONFIG_SENSORLIB_ESP_IDF_NEW_API) +#include "soc/clk_tree_defs.h" + +i2c_master_dev_handle_t i2c_device; + +// * Using the new API of esp-idf 5.x, you need to pass the I2C BUS handle, +// * which is useful when the bus shares multiple devices. +i2c_master_bus_handle_t bus_handle; +#endif + + +#if CONFIG_I2C_COMMUNICATION_METHOD_CALLBACK_RW + + + +bool i2c_wr_function(uint8_t addr, uint8_t reg, uint8_t *buf, size_t len, bool writeReg, bool isWrite) +{ + if (isWrite) { + esp_err_t ret; + if (buf == NULL) { + return false; + } + +#if (ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL(5,0,0)) && defined(CONFIG_SENSORLIB_ESP_IDF_NEW_API) + + if (writeReg) { + uint8_t *write_buffer = (uint8_t *)malloc(sizeof(uint8_t) * (len + 1)); + if (!write_buffer) { + return -1; + } + write_buffer[0] = reg; + memcpy(write_buffer + 1, buf, len); + + ret = i2c_master_transmit( + i2c_device, + write_buffer, + len + 1, + -1); + free(write_buffer); + } else { + ret = i2c_master_transmit(i2c_device, buf, len, -1); + } + +#else + + i2c_cmd_handle_t cmd = i2c_cmd_link_create(); + i2c_master_start(cmd); + i2c_master_write_byte(cmd, (addr << 1) | I2C_MASTER_WRITE, true); + if (writeReg) { + i2c_master_write_byte(cmd, reg, true); + } + i2c_master_write(cmd, buf, len, true); + i2c_master_stop(cmd); + ret = i2c_master_cmd_begin(I2C_MASTER_NUM, cmd, pdTICKS_TO_MS(1000)); + i2c_cmd_link_delete(cmd); + if (ret != ESP_OK) { + ESP_LOGE(TAG, "i2c_write_error."); + } + +#endif + return ret == ESP_OK ? true : false; + + } else { + esp_err_t ret; + if (len == 0) { + return true; + } + if (buf == NULL) { + return false; + } + +#if (ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL(5,0,0)) && defined(CONFIG_SENSORLIB_ESP_IDF_NEW_API) + + ret = i2c_master_transmit_receive(i2c_device, (const uint8_t *)®, 1, buf, len, -1); + +#else + + i2c_cmd_handle_t cmd; + if (writeReg) { + cmd = i2c_cmd_link_create(); + i2c_master_start(cmd); + i2c_master_write_byte(cmd, (addr << 1) | I2C_MASTER_WRITE, true); + i2c_master_write_byte(cmd, reg, true); + i2c_master_stop(cmd); + ret = i2c_master_cmd_begin(I2C_MASTER_NUM, cmd, pdTICKS_TO_MS(1000)); + i2c_cmd_link_delete(cmd); + if (ret != ESP_OK) { + ESP_LOGE(TAG, "i2c_master_cmd_begin failed!"); + return false; + } + } + + cmd = i2c_cmd_link_create(); + i2c_master_start(cmd); + i2c_master_write_byte(cmd, (addr << 1) | I2C_MASTER_READ, true); + if (len > 1) { + i2c_master_read(cmd, buf, len - 1, I2C_MASTER_ACK); + } + i2c_master_read_byte(cmd, &buf[len - 1], I2C_MASTER_NACK); + i2c_master_stop(cmd); + ret = i2c_master_cmd_begin(I2C_MASTER_NUM, cmd, pdTICKS_TO_MS(1000)); + i2c_cmd_link_delete(cmd); + if (ret != ESP_OK) { + ESP_LOGE(TAG, "i2c_read_error."); + } +#endif + return ret == ESP_OK ? true : false; + + } +} + +/** + * @brief Read a sequence of bytes from a pmu registers + */ +int i2c_read_callback(uint8_t devAddr, uint8_t regAddr, uint8_t *data, uint8_t len) +{ + esp_err_t ret; + if (len == 0) { + return ESP_OK; + } + if (data == NULL) { + return ESP_FAIL; + } + +#if (ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL(5,0,0)) && defined(CONFIG_SENSORLIB_ESP_IDF_NEW_API) + + ret = i2c_master_transmit_receive( + i2c_device, + (const uint8_t *)®Addr, + 1, + data, + len, + -1); +#else + + i2c_cmd_handle_t cmd; + + cmd = i2c_cmd_link_create(); + i2c_master_start(cmd); + i2c_master_write_byte(cmd, (devAddr << 1) | I2C_MASTER_WRITE, true); + i2c_master_write_byte(cmd, regAddr, true); + i2c_master_stop(cmd); + ret = i2c_master_cmd_begin(I2C_MASTER_NUM, cmd, pdTICKS_TO_MS(1000)); + i2c_cmd_link_delete(cmd); + if (ret != ESP_OK) { + ESP_LOGE(TAG, "i2c_master_cmd_begin failed!"); + return ESP_FAIL; + } + cmd = i2c_cmd_link_create(); + i2c_master_start(cmd); + i2c_master_write_byte(cmd, (devAddr << 1) | I2C_MASTER_READ, true); + if (len > 1) { + i2c_master_read(cmd, data, len - 1, I2C_MASTER_ACK); + } + i2c_master_read_byte(cmd, &data[len - 1], I2C_MASTER_NACK); + i2c_master_stop(cmd); + ret = i2c_master_cmd_begin(I2C_MASTER_NUM, cmd, pdTICKS_TO_MS(1000)); + i2c_cmd_link_delete(cmd); + if (ret != ESP_OK) { + ESP_LOGE(TAG, "i2c_read_error."); + } +#endif + return ret == ESP_OK ? 0 : -1; +} + +/** + * @brief Write a byte to a pmu register + */ +int i2c_write_callback(uint8_t devAddr, uint8_t regAddr, uint8_t *data, uint8_t len) +{ + esp_err_t ret; + if (data == NULL) { + return ESP_FAIL; + } + +#if (ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL(5,0,0)) && defined(CONFIG_SENSORLIB_ESP_IDF_NEW_API) + uint8_t *write_buffer = (uint8_t *)malloc(sizeof(uint8_t) * (len + 1)); + if (!write_buffer) { + return -1; + } + write_buffer[0] = regAddr; + memcpy(write_buffer + 1, data, len); + + ret = i2c_master_transmit( + i2c_device, + write_buffer, + len + 1, + -1); + free(write_buffer); +#else + i2c_cmd_handle_t cmd = i2c_cmd_link_create(); + i2c_master_start(cmd); + i2c_master_write_byte(cmd, (devAddr << 1) | I2C_MASTER_WRITE, true); + i2c_master_write_byte(cmd, regAddr, true); + i2c_master_write(cmd, data, len, true); + i2c_master_stop(cmd); + ret = i2c_master_cmd_begin(I2C_MASTER_NUM, cmd, pdTICKS_TO_MS(1000)); + i2c_cmd_link_delete(cmd); + if (ret != ESP_OK) { + ESP_LOGE(TAG, "i2c_write_error."); + } +#endif + return ret == ESP_OK ? 0 : -1; +} + +esp_err_t i2c_drv_device_init(uint8_t address) +{ +#if (ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL(5,0,0)) && defined(CONFIG_SENSORLIB_ESP_IDF_NEW_API) + i2c_device_config_t i2c_dev_conf = { + .dev_addr_length = I2C_ADDR_BIT_LEN_7, + .device_address = address, + .scl_speed_hz = I2C_MASTER_FREQ_HZ, + }; + return i2c_master_bus_add_device(bus_handle, &i2c_dev_conf, &i2c_device); +#else + return ESP_OK; +#endif +} + +#endif //CONFIG_I2C_COMMUNICATION_METHOD_CALLBACK_RW + + +/** + * @brief i2c master initialization + */ +esp_err_t i2c_drv_init(void) +{ +#if (ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL(5,0,0)) && defined(CONFIG_SENSORLIB_ESP_IDF_NEW_API) + + ESP_LOGI(TAG, "Implemented using read and write callback methods (Use higher version >= 5.0 API)"); + + i2c_master_bus_config_t i2c_bus_config; + memset(&i2c_bus_config, 0, sizeof(i2c_bus_config)); + i2c_bus_config.clk_source = I2C_CLK_SRC_DEFAULT; + i2c_bus_config.i2c_port = I2C_MASTER_NUM; + i2c_bus_config.scl_io_num = (gpio_num_t)I2C_MASTER_SCL_IO; + i2c_bus_config.sda_io_num = (gpio_num_t)I2C_MASTER_SDA_IO; + i2c_bus_config.glitch_ignore_cnt = 7; + i2c_bus_config.flags.enable_internal_pullup = true; + + ESP_ERROR_CHECK(i2c_new_master_bus(&i2c_bus_config, &bus_handle)); + + return ESP_OK; +#else + + ESP_LOGI(TAG, "Implemented using read and write callback methods (Use lower version < 5.0 API)"); + + i2c_config_t i2c_conf ; + memset(&i2c_conf, 0, sizeof(i2c_conf)); + i2c_conf.mode = I2C_MODE_MASTER; + i2c_conf.sda_io_num = I2C_MASTER_SDA_IO; + i2c_conf.scl_io_num = I2C_MASTER_SCL_IO; + i2c_conf.sda_pullup_en = GPIO_PULLUP_ENABLE; + i2c_conf.scl_pullup_en = GPIO_PULLUP_ENABLE; + i2c_conf.master.clk_speed = I2C_MASTER_FREQ_HZ; + i2c_param_config(I2C_MASTER_NUM, &i2c_conf); + return i2c_driver_install(I2C_MASTER_NUM, i2c_conf.mode, I2C_MASTER_RX_BUF_DISABLE, I2C_MASTER_TX_BUF_DISABLE, 0); +#endif +} + +void i2c_drv_scan() +{ +#if (ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL(5,0,0)) && defined(CONFIG_SENSORLIB_ESP_IDF_NEW_API) + + esp_err_t err = ESP_OK; + uint8_t address = 0x00; + printf("Scan I2C Devices:\n"); + printf(" 0 1 2 3 4 5 6 7 8 9 a b c d e f\r\n"); + for (int i = 0; i < 128; i += 16) { + printf("%02x: ", i); + for (int j = 0; j < 16; j++) { + fflush(stdout); + address = i + j; + err = i2c_master_probe(bus_handle, address, 100); + if (err == ESP_OK) { + printf("%02x ", address); + } else if (err == ESP_ERR_TIMEOUT) { + printf("UU "); + } else { + printf("-- "); + } + } + printf("\r\n"); + } + printf("\n\n\n"); +#else + uint8_t address; + printf("Scan I2C Devices:\n"); + printf(" 0 1 2 3 4 5 6 7 8 9 a b c d e f\r\n"); + for (int i = 0; i < 128; i += 16) { + printf("%02x: ", i); + for (int j = 0; j < 16; j++) { + fflush(stdout); + address = i + j; + i2c_cmd_handle_t cmd = i2c_cmd_link_create(); + i2c_master_start(cmd); + i2c_master_write_byte(cmd, (address << 1) | I2C_MASTER_WRITE, true); + i2c_master_stop(cmd); + esp_err_t ret = i2c_master_cmd_begin(I2C_MASTER_NUM, cmd, 50 / portTICK_PERIOD_MS); + i2c_cmd_link_delete(cmd); + if (ret == ESP_OK) { + printf("%02x ", address); + } else if (ret == ESP_ERR_TIMEOUT) { + printf("UU "); + } else { + printf("-- "); + } + } + printf("\r\n"); + } +#endif +} + +bool i2c_drv_probe(uint8_t devAddr) +{ +#if (ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL(5,0,0)) && defined(CONFIG_SENSORLIB_ESP_IDF_NEW_API) + return ESP_OK == i2c_master_probe(bus_handle, devAddr, 1000); +#else + i2c_cmd_handle_t cmd = i2c_cmd_link_create(); + i2c_master_start(cmd); + i2c_master_write_byte(cmd, (devAddr << 1) | I2C_MASTER_WRITE, true); + i2c_master_stop(cmd); + esp_err_t ret = i2c_master_cmd_begin(I2C_MASTER_NUM, cmd, 50 / portTICK_PERIOD_MS); + i2c_cmd_link_delete(cmd); + return (ret == ESP_OK); +#endif //ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL(5,0,0) +} + + +#endif \ No newline at end of file diff --git a/examples/ESP_IDF_SensorExamples/main/i2c_driver.h b/examples/ESP_IDF_SensorExamples/main/i2c_driver.h new file mode 100644 index 0000000..4d4441b --- /dev/null +++ b/examples/ESP_IDF_SensorExamples/main/i2c_driver.h @@ -0,0 +1,54 @@ +/** + * + * @license MIT License + * + * Copyright (c) 2025 lewis he + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * @file i2c_driver.h + * @author Lewis He (lewishe@outlook.com) + * @date 2025-01-19 + * + */ +#pragma once + +#include "esp_err.h" +#include "esp_log.h" +#include "driver/gpio.h" +#include "esp_idf_version.h" +#if ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL(5,0,0) && defined(CONFIG_SENSORLIB_ESP_IDF_NEW_API) +#include "driver/i2c_master.h" +#else +#include "driver/i2c.h" +#endif //ESP_IDF_VERSION + +#if CONFIG_I2C_COMMUNICATION_METHOD_BUILTIN_RW || CONFIG_I2C_COMMUNICATION_METHOD_CALLBACK_RW + +esp_err_t i2c_drv_init(void); +void i2c_drv_scan(); +bool i2c_drv_probe(uint8_t devAddr); +int i2c_read_callback(uint8_t devAddr, uint8_t regAddr, uint8_t *data, uint8_t len); +int i2c_write_callback(uint8_t devAddr, uint8_t regAddr, uint8_t *data, uint8_t len); +bool i2c_wr_function(uint8_t addr, uint8_t reg, uint8_t *buf, size_t len, bool writeReg, bool isWrite); +#if CONFIG_I2C_COMMUNICATION_METHOD_CALLBACK_RW +esp_err_t i2c_drv_device_init(uint8_t address); +#endif + +#endif diff --git a/examples/ESP_IDF_SensorExamples/main/main.cpp b/examples/ESP_IDF_SensorExamples/main/main.cpp new file mode 100644 index 0000000..80bbf8d --- /dev/null +++ b/examples/ESP_IDF_SensorExamples/main/main.cpp @@ -0,0 +1,199 @@ +/** + * + * @license MIT License + * + * Copyright (c) 2025 lewis he + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * @file main.cpp + * @author Lewis He (lewishe@outlook.com) + * @date 2025-01-19 + * + */ +#include "sdkconfig.h" +#include "freertos/FreeRTOS.h" +#include "i2c_driver.h" + +static const char *TAG = "main"; + +#ifdef CONFIG_PCF8563 +extern esp_err_t pcf8563_init(); +extern void pcf8563_loop(); +#endif + + +#ifdef CONFIG_BMA423 +extern esp_err_t bma423_init(); +extern void bma423_loop(); +#endif + +#ifdef CONFIG_FT636X +extern esp_err_t ft63x6_init(); +extern void ft63x6_loop(); +#endif + +#ifdef CONFIG_BHI260 +extern esp_err_t bhi260_init(); +extern void bhi260_loop(); +#endif + +#ifdef CONFIG_XL9555 +extern esp_err_t xl9555_init(); +extern void xl9555_loop(); +#endif + + +static void app_task(void *args); + +extern "C" void app_main(void) +{ + +#if CONFIG_I2C_COMMUNICATION_METHOD_BUILTIN_RW || CONFIG_I2C_COMMUNICATION_METHOD_CALLBACK_RW + ESP_ERROR_CHECK(i2c_drv_init()); + ESP_LOGI(TAG, "I2C initialized successfully"); + + // Run bus scan + i2c_drv_scan(); +#endif + +#ifdef CONFIG_PCF8563 + ESP_ERROR_CHECK(pcf8563_init()); +#endif + +#ifdef CONFIG_BMA423 + ESP_ERROR_CHECK(bma423_init()); +#endif + +#ifdef CONFIG_FT636X + ESP_ERROR_CHECK(ft63x6_init()); +#endif + +#ifdef CONFIG_BHI260 + ESP_ERROR_CHECK(bhi260_init()); +#endif + +#ifdef CONFIG_XL9555 + xl9555_init(); +#endif + + ESP_LOGI(TAG, "Run..."); + + xTaskCreate(app_task, "App", 20 * 1024, NULL, 10, NULL); + +} + +static void app_task(void *args) +{ + while (1) { + +#ifdef CONFIG_BMA423 + bma423_loop(); + vTaskDelay(pdMS_TO_TICKS(1000)); +#endif + +#ifdef CONFIG_FT636X + ft63x6_loop(); +#endif + +#ifdef CONFIG_BHI260 + bhi260_loop(); +#endif + +#ifdef CONFIG_XL9555 + xl9555_loop(); +#endif + + vTaskDelay(pdMS_TO_TICKS(10)); + } +} + + +#if CONFIG_I2C_COMMUNICATION_METHOD_CALLBACK_RW +/** + * @brief hal_callback + * @note SensorLib hal callback + * @param op: Operation Code + * @param *param1: parameter + * @param *param2: parameter + * @retval + */ +uint32_t hal_callback(SensorCommCustomHal::Operation op, void *param1, void *param2) +{ + switch (op) { + // Set GPIO mode + case SensorCommCustomHal::OP_PINMODE: { + uint8_t pin = reinterpret_cast(param1); + uint8_t mode = reinterpret_cast(param2); + gpio_config_t config; + memset(&config, 0, sizeof(config)); + config.pin_bit_mask = 1ULL << pin; + switch (mode) { + case INPUT: + config.mode = GPIO_MODE_INPUT; + break; + case OUTPUT: + config.mode = GPIO_MODE_OUTPUT; + break; + } + config.pull_up_en = GPIO_PULLUP_DISABLE; + config.pull_down_en = GPIO_PULLDOWN_DISABLE; + config.intr_type = GPIO_INTR_DISABLE; + ESP_ERROR_CHECK(gpio_config(&config)); + } + break; + // Set GPIO level + case SensorCommCustomHal::OP_DIGITALWRITE: { + uint8_t pin = reinterpret_cast(param1); + uint8_t level = reinterpret_cast(param2); + gpio_set_level((gpio_num_t )pin, level); + } + break; + // Read GPIO level + case SensorCommCustomHal::OP_DIGITALREAD: { + uint8_t pin = reinterpret_cast(param1); + return gpio_get_level((gpio_num_t)pin); + } + break; + // Get the current running milliseconds + case SensorCommCustomHal::OP_MILLIS: + return (uint32_t) (esp_timer_get_time() / 1000LL); + + // Delay in milliseconds + case SensorCommCustomHal::OP_DELAY: { + if (param1) { + uint32_t ms = reinterpret_cast(param1); + ets_delay_us((ms % portTICK_PERIOD_MS) * 1000UL); + } + } + break; + // Delay in microseconds + case SensorCommCustomHal::OP_DELAYMICROSECONDS: { + uint32_t us = reinterpret_cast(param1); + ets_delay_us(us); + } + break; + default: + break; + } + return 0; +} + + +#endif diff --git a/examples/ESP_IDF_SensorExamples/main/sensor_bhi260.cpp b/examples/ESP_IDF_SensorExamples/main/sensor_bhi260.cpp new file mode 100644 index 0000000..412896d --- /dev/null +++ b/examples/ESP_IDF_SensorExamples/main/sensor_bhi260.cpp @@ -0,0 +1,205 @@ +/** + * + * @license MIT License + * + * Copyright (c) 2025 lewis he + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * @file sensor_bhi260.cpp + * @author Lewis He (lewishe@outlook.com) + * @date 2025-01-23 + * + */ +#include "sdkconfig.h" +#include "esp_log.h" +#include "esp_err.h" +#include "freertos/FreeRTOS.h" +#include "driver/spi_master.h" +#include "driver/gpio.h" +#include "SensorBHI260AP.hpp" + +#if CONFIG_BHI260 + +static const char *TAG = "BHI"; + +extern uint32_t hal_callback(SensorCommCustomHal::Operation op, void *param1, void *param2); + +SensorBHI260AP bhy; + +static volatile bool dataReady = false; + +static bool init_done = false; + +static void IRAM_ATTR bhi260_set_flag(void *arg) +{ + dataReady = true; +} + +static void bhi260_isr_init() +{ + gpio_config_t io_conf; + io_conf.intr_type = GPIO_INTR_NEGEDGE; + io_conf.mode = GPIO_MODE_INPUT; + io_conf.pin_bit_mask = (1ULL << CONFIG_SENSOR_IRQ); + io_conf.pull_down_en = GPIO_PULLDOWN_DISABLE; + io_conf.pull_up_en = GPIO_PULLUP_DISABLE; + gpio_config(&io_conf); + gpio_set_intr_type((gpio_num_t)CONFIG_SENSOR_IRQ, GPIO_INTR_POSEDGE); + //install gpio isr service + gpio_install_isr_service(0); + //hook isr handler for specific gpio pin + gpio_isr_handler_add((gpio_num_t)CONFIG_SENSOR_IRQ, bhi260_set_flag, NULL); + +} + +static void accel_process_callback(uint8_t sensor_id, uint8_t *data_ptr, uint32_t len, uint64_t *timestamp) +{ + struct bhy2_data_xyz data; + float scaling_factor = get_sensor_default_scaling(sensor_id); + bhy2_parse_xyz(data_ptr, &data); + ESP_LOGI(TAG, "%s: x: %f, y: %f, z: %f;", bhy.getSensorName(sensor_id), + data.x * scaling_factor, + data.y * scaling_factor, + data.z * scaling_factor); +} + +static void gyro_process_callback(uint8_t sensor_id, uint8_t *data_ptr, uint32_t len, uint64_t *timestamp) +{ + struct bhy2_data_xyz data; + float scaling_factor = get_sensor_default_scaling(sensor_id); + bhy2_parse_xyz(data_ptr, &data); + ESP_LOGI(TAG, "%s: x: %f, y: %f, z: %f;", bhy.getSensorName(sensor_id), + data.x * scaling_factor, + data.y * scaling_factor, + data.z * scaling_factor); +} + +esp_err_t bhi260_init() +{ + ESP_LOGI(TAG, "----DRIVER BHI260AP----"); + + // Set the reset pin + bhy.setPins(CONFIG_SENSOR_RST); + + /*Set the default firmware, only 6 axes, no other functions*/ + bhy.setFirmware(bhy2_firmware_image, sizeof(bhy2_firmware_image)); + +#if CONFIG_USE_I2C_INTERFACE + // BHI260AP_SLAVE_ADDRESS_L = 0x28 + // BHI260AP_SLAVE_ADDRESS_H = 0x29 + uint8_t address = BHI260AP_SLAVE_ADDRESS_L; + + //* Implemented using read and write callback methods, applicable to other platforms +#if CONFIG_I2C_COMMUNICATION_METHOD_CALLBACK_RW + + // * Provide the device address to the callback function + i2c_drv_device_init(address); + + ESP_LOGI(TAG, "Implemented using read and write callback methods"); + if (bhy.begin(i2c_wr_function, hal_callback, address)) { + ESP_LOGI(TAG, "Initialize BHI260AP using I2C interface"); + } else { + ESP_LOGE(TAG, "Failed to initialize the BHI260AP !"); + return ESP_FAIL; + } +#endif + + //* Use the built-in esp-idf communication method +#if CONFIG_I2C_COMMUNICATION_METHOD_BUILTIN_RW +#if (ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL(5,0,0)) && defined(CONFIG_SENSORLIB_ESP_IDF_NEW_API) + + ESP_LOGI(TAG, "Implemented using built-in read and write methods (Use higher version >= 5.0 API)"); + + // * Using the new API of esp-idf 5.x, you need to pass the I2C BUS handle, + // * which is useful when the bus shares multiple devices. + extern i2c_master_bus_handle_t bus_handle; + + if (bhy.begin(bus_handle, address)) { + ESP_LOGI(TAG, "Initialize BHI260AP using I2C interface"); + } else { + ESP_LOGE(TAG, "Failed to initialize the BHI260AP !"); + return ESP_FAIL; + } + +#else + + ESP_LOGI(TAG, "Implemented using built-in read and write methods (Use lower version < 5.0 API)"); + if (bhy.begin((i2c_port_t)CONFIG_I2C_MASTER_PORT_NUM, address, CONFIG_SENSOR_SDA, CONFIG_SENSOR_SCL)) { + ESP_LOGI(TAG, "Initialize BHI260AP using I2C interface"); + } else { + ESP_LOGE(TAG, "Failed to initialize the BHI260AP !"); + return ESP_FAIL; + } +#endif //ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL(5,0,0) +#endif //CONFIG_I2C_COMMUNICATION_METHOD_BUILTIN_RW + + +#else //USE_I2C_INTERFACE + + // Bus handle + spi_device_handle_t spi = NULL; + + // Using SPI interface + if (bhy.begin(SPI2_HOST, spi, CONFIG_SPI_CS, CONFIG_SPI_MOSI, CONFIG_SPI_MISO, CONFIG_SPI_SCK)) { + ESP_LOGI(TAG, "Initialize BHI260AP using SPI interface"); + } else { + ESP_LOGE(TAG, "Failed to initialize the BHI260AP !"); + return ESP_FAIL; + } +#endif //USE_SPI_INTERFACE + + // Output all sensors info to Serial + BoschSensorInfo info = bhy.getSensorInfo(); + info.printInfo(); + + float sample_rate = 1.0; /* Read out hintr_ctrl measured at 1Hz */ + uint32_t report_latency_ms = 0; /* Report immediately */ + + // Enable acceleration + bhy.configure(SENSOR_ID_ACC_PASS, sample_rate, report_latency_ms); + // Enable gyroscope + bhy.configure(SENSOR_ID_GYRO_PASS, sample_rate, report_latency_ms); + + // Set the acceleration sensor result callback function + bhy.onResultEvent(SENSOR_ID_ACC_PASS, accel_process_callback); + + // Set the gyroscope sensor result callback function + bhy.onResultEvent(SENSOR_ID_GYRO_PASS, gyro_process_callback); + + // Registration interruption + bhi260_isr_init(); + + init_done = true; + + return ESP_OK; +} + +void bhi260_loop() +{ + if (!init_done) { + return; + } + if (dataReady) { + dataReady = false; + bhy.update(); + } +} + +#endif \ No newline at end of file diff --git a/examples/ESP_IDF_SensorExamples/main/sensor_bma423.cpp b/examples/ESP_IDF_SensorExamples/main/sensor_bma423.cpp new file mode 100644 index 0000000..d8d70d3 --- /dev/null +++ b/examples/ESP_IDF_SensorExamples/main/sensor_bma423.cpp @@ -0,0 +1,119 @@ +/** + * + * @license MIT License + * + * Copyright (c) 2025 lewis he + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * @file sensor_bma423.cpp + * @author Lewis He (lewishe@outlook.com) + * @date 2025-01-19 + * + */ +#include "sdkconfig.h" +#include "esp_log.h" +#include "esp_err.h" +#include "i2c_driver.h" +#include "freertos/FreeRTOS.h" + +#ifdef CONFIG_BMA423 + +#include "SensorBMA423.hpp" + +static const char *TAG = "BMA"; + +SensorBMA423 accel; + +extern uint32_t hal_callback(SensorCommCustomHal::Operation op, void *param1, void *param2); + +static bool init_done = false; + +esp_err_t bma423_init() +{ + uint8_t address = BMA423_I2C_ADDR_SECONDARY; + + ESP_LOGI(TAG, "----DRIVER BMA423----"); + + //* Implemented using read and write callback methods, applicable to other platforms +#if CONFIG_I2C_COMMUNICATION_METHOD_CALLBACK_RW + + + // * Provide the device address to the callback function + i2c_drv_device_init(address); + + ESP_LOGI(TAG, "Implemented using read and write callback methods"); + if (accel.begin(i2c_wr_function, hal_callback, address)) { + ESP_LOGI(TAG, "Initialization of BMA423 accelerometer is successful!"); + } else { + ESP_LOGE(TAG, "Failed to initialize the BMA423 accelerometer!"); + return ESP_FAIL; + } +#endif + + //* Use the built-in esp-idf communication method +#if CONFIG_I2C_COMMUNICATION_METHOD_BUILTIN_RW +#if (ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL(5,0,0)) && defined(CONFIG_SENSORLIB_ESP_IDF_NEW_API) + + ESP_LOGI(TAG, "Implemented using built-in read and write methods (Use higher version >= 5.0 API)"); + + // * Using the new API of esp-idf 5.x, you need to pass the I2C BUS handle, + // * which is useful when the bus shares multiple devices. + extern i2c_master_bus_handle_t bus_handle; + + if (accel.begin(bus_handle, address)) { + ESP_LOGI(TAG, "Initialization of BMA423 accelerometer is successful!"); + } else { + ESP_LOGE(TAG, "Failed to initialize the BMA423 accelerometer!"); + return ESP_FAIL; + } + +#else + + ESP_LOGI(TAG, "Implemented using built-in read and write methods (Use lower version < 5.0 API)"); + if (accel.begin((i2c_port_t)CONFIG_I2C_MASTER_PORT_NUM, address, CONFIG_SENSOR_SDA, CONFIG_SENSOR_SCL)) { + ESP_LOGI(TAG, "Initialization of BMA423 accelerometer is successful!"); + } else { + ESP_LOGE(TAG, "Failed to initialize the BMA423 accelerometer!"); + return ESP_FAIL; + } +#endif //ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL(5,0,0) +#endif //CONFIG_I2C_COMMUNICATION_METHOD_BUILTIN_RW + + //Default 4G ,200HZ + accel.configAccelerometer(); + + accel.enableAccelerometer(); + + init_done = true; + + return ESP_OK; +} + +void bma423_loop() +{ + if (!init_done) { + return; + } + ESP_LOGI("BMA423", "Temperature:%.2f*C", accel.getTemperature(SensorBMA423::TEMP_DEG)); + ESP_LOGI("BMA423", "Temperature:%.2f*F", accel.getTemperature(SensorBMA423::TEMP_FAHRENHEIT)); + ESP_LOGI("BMA423", "Direction:%u", accel.direction()); +} + +#endif diff --git a/examples/ESP_IDF_SensorExamples/main/sensor_pcf8563.cpp b/examples/ESP_IDF_SensorExamples/main/sensor_pcf8563.cpp new file mode 100644 index 0000000..811afb6 --- /dev/null +++ b/examples/ESP_IDF_SensorExamples/main/sensor_pcf8563.cpp @@ -0,0 +1,137 @@ +/** + * + * @license MIT License + * + * Copyright (c) 2025 lewis he + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * @file sensor_pcf8563.cpp + * @author Lewis He (lewishe@outlook.com) + * @date 2025-01-19 + * + */ +#include "sdkconfig.h" +#include "esp_log.h" +#include "esp_err.h" +#include "i2c_driver.h" +#include "freertos/FreeRTOS.h" + +#ifdef CONFIG_PCF8563 + +#include "SensorPCF8563.hpp" + +static const char *TAG = "RTC"; + +SensorPCF8563 rtc; + +static bool init_done = false; + +esp_err_t pcf8563_init() +{ + ESP_LOGI(TAG, "----DRIVER PCF8563 ----"); + + //* Implemented using read and write callback methods, applicable to other platforms +#if CONFIG_I2C_COMMUNICATION_METHOD_CALLBACK_RW + + uint8_t address = 0x51; + + // * Provide the device address to the callback function + i2c_drv_device_init(address); + + ESP_LOGI(TAG, "Implemented using read and write callback methods"); + if (rtc.begin(i2c_wr_function)) { + ESP_LOGI(TAG, "Initializing PCF8563 real-time clock successfully!"); + } else { + ESP_LOGE(TAG, "Failed to initialize PCF8563 real time clock!"); + return ESP_FAIL; + } +#endif + + //* Use the built-in esp-idf communication method +#if CONFIG_I2C_COMMUNICATION_METHOD_BUILTIN_RW +#if (ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL(5,0,0)) && defined(CONFIG_SENSORLIB_ESP_IDF_NEW_API) + + ESP_LOGI(TAG, "Implemented using built-in read and write methods (Use higher version >= 5.0 API)"); + + // * Using the new API of esp-idf 5.x, you need to pass the I2C BUS handle, + // * which is useful when the bus shares multiple devices. + extern i2c_master_bus_handle_t bus_handle; + + if (rtc.begin(bus_handle)) { + ESP_LOGI(TAG, "Initializing PCF8563 real-time clock successfully!"); + } else { + ESP_LOGE(TAG, "Failed to initialize PCF8563 real time clock!"); + return ESP_FAIL; + } + +#else + + ESP_LOGI(TAG, "Implemented using built-in read and write methods (Use lower version < 5.0 API)"); + if (rtc.begin((i2c_port_t)CONFIG_I2C_MASTER_PORT_NUM, CONFIG_SENSOR_SDA, CONFIG_SENSOR_SCL)) { + ESP_LOGI(TAG, "Initializing PCF8563 real-time clock successfully!"); + } else { + ESP_LOGE(TAG, "Failed to initialize PCF8563 real time clock!"); + return ESP_FAIL; + } +#endif //ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL(5,0,0) +#endif //CONFIG_I2C_COMMUNICATION_METHOD_BUILTIN_RW + + // Unix tm structure sets the time + struct tm timeinfo; + timeinfo.tm_yday = 2025 - 1900; //Counting starts from 1900, so subtract 1900 here + timeinfo.tm_mon = 1 - 1; //Months start at 0, so you need to subtract 1. + timeinfo.tm_mday = 17; + timeinfo.tm_hour = 4; + timeinfo.tm_min = 30; + timeinfo.tm_sec = 30; + rtc.setDateTime(timeinfo); + + init_done = true; + + return ESP_OK; +} + +void pcf8563_loop() +{ + if (!init_done) { + return; + } + char buf[64]; + struct tm timeinfo; + // Get the time C library structure + rtc.getDateTime(&timeinfo); + // Format the output using the strftime function + // For more formats, please refer to : + // https://man7.org/linux/man-pages/man3/strftime.3.html + size_t written = strftime(buf, 64, "%A, %B %d %Y %H:%M:%S", &timeinfo); + if (written != 0) { + ESP_LOGI("RTC", "%s", buf); + } + written = strftime(buf, 64, "%b %d %Y %H:%M:%S", &timeinfo); + if (written != 0) { + ESP_LOGI("RTC", "%s", buf); + } + written = strftime(buf, 64, "%A, %d. %B %Y %I:%M%p", &timeinfo); + if (written != 0) { + ESP_LOGI("RTC", "%s", buf); + } +} + +#endif \ No newline at end of file diff --git a/examples/ESP_IDF_SensorExamples/main/sensor_xl9555.cpp b/examples/ESP_IDF_SensorExamples/main/sensor_xl9555.cpp new file mode 100644 index 0000000..6172b3d --- /dev/null +++ b/examples/ESP_IDF_SensorExamples/main/sensor_xl9555.cpp @@ -0,0 +1,107 @@ +/** + * + * @license MIT License + * + * Copyright (c) 2025 lewis he + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * @file sensor_xl9555.cpp + * @author Lewis He (lewishe@outlook.com) + * @date 2025-01-23 + * + */ +#include "sdkconfig.h" +#include "esp_log.h" +#include "esp_err.h" +#include "i2c_driver.h" +#include "freertos/FreeRTOS.h" + +#ifdef CONFIG_XL9555 + +#include "ExtensionIOXL9555.hpp" + +static const char *TAG = "XL9555"; + +ExtensionIOXL9555 io; + +static bool init_done = false; + +esp_err_t xl9555_init() +{ + ESP_LOGI(TAG, "----DRIVER XL9555 ----"); + + //* Implemented using read and write callback methods, applicable to other platforms +#if CONFIG_I2C_COMMUNICATION_METHOD_CALLBACK_RW + + uint8_t address = XL9555_SLAVE_ADDRESS0; + + // * Provide the device address to the callback function + i2c_drv_device_init(address); + + ESP_LOGI(TAG, "Implemented using read and write callback methods"); + if (io.begin(i2c_wr_function)) { + ESP_LOGI(TAG, "Initializing XL9555 successfully!"); + } else { + ESP_LOGE(TAG, "Failed to initialize XL9555 failed!"); + return ESP_FAIL; + } +#endif + + //* Use the built-in esp-idf communication method +#if CONFIG_I2C_COMMUNICATION_METHOD_BUILTIN_RW +#if (ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL(5,0,0)) && defined(CONFIG_SENSORLIB_ESP_IDF_NEW_API) + + ESP_LOGI(TAG, "Implemented using built-in read and write methods (Use higher version >= 5.0 API)"); + + // * Using the new API of esp-idf 5.x, you need to pass the I2C BUS handle, + // * which is useful when the bus shares multiple devices. + extern i2c_master_bus_handle_t bus_handle; + + if (io.begin(bus_handle)) { + ESP_LOGI(TAG, "Initializing XL9555 successfully!"); + } else { + ESP_LOGE(TAG, "Failed to initialize XL9555 failed!"); + return ESP_FAIL; + } + +#else + + ESP_LOGI(TAG, "Implemented using built-in read and write methods (Use lower version < 5.0 API)"); + if (io.begin((i2c_port_t)CONFIG_I2C_MASTER_PORT_NUM, CONFIG_SENSOR_SDA, CONFIG_SENSOR_SCL)) { + ESP_LOGI(TAG, "Initializing XL9555 successfully!"); + } else { + ESP_LOGE(TAG, "Failed to initialize XL9555 failed!"); + return ESP_FAIL; + } +#endif //ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL(5,0,0) +#endif //CONFIG_I2C_COMMUNICATION_METHOD_BUILTIN_RW + + + return ESP_OK; +} + +void xl9555_loop() +{ + if (!init_done) { + return; + } +} + +#endif diff --git a/examples/ESP_IDF_SensorExamples/main/touch_ft63x6.cpp b/examples/ESP_IDF_SensorExamples/main/touch_ft63x6.cpp new file mode 100644 index 0000000..9d44556 --- /dev/null +++ b/examples/ESP_IDF_SensorExamples/main/touch_ft63x6.cpp @@ -0,0 +1,116 @@ +/** + * + * @license MIT License + * + * Copyright (c) 2025 lewis he + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * @file ft63x6.cpp + * @author Lewis He (lewishe@outlook.com) + * @date 2025-01-19 + * + */ +#include "sdkconfig.h" +#include "esp_log.h" +#include "esp_err.h" +#include "i2c_driver.h" +#include "freertos/FreeRTOS.h" + +#ifdef CONFIG_FT636X + +#include "TouchDrvFT6X36.hpp" + +static const char *TAG = "FT63XX"; + +TouchDrvFT6X36 touch; + +extern uint32_t hal_callback(SensorCommCustomHal::Operation op, void *param1, void *param2); + +static bool init_done = false; + +esp_err_t ft63x6_init() +{ + ESP_LOGI(TAG, "----DRIVER FT63XX----"); + + //* Implemented using read and write callback methods, applicable to other platforms +#if CONFIG_I2C_COMMUNICATION_METHOD_CALLBACK_RW + + uint8_t address = FT3267_SLAVE_ADDRESS; + + // * Provide the device address to the callback function + i2c_drv_device_init(address); + + ESP_LOGI(TAG, "Implemented using read and write callback methods"); + if (touch.begin(i2c_wr_function, hal_callback, address)) { + ESP_LOGI(TAG, "Initialization of FT63XX is successful!"); + } else { + ESP_LOGE(TAG, "Failed to initialize the FT63XX!"); + return ESP_FAIL; + } +#endif + + //* Use the built-in esp-idf communication method +#if CONFIG_I2C_COMMUNICATION_METHOD_BUILTIN_RW +#if (ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL(5,0,0)) && defined(CONFIG_SENSORLIB_ESP_IDF_NEW_API) + + ESP_LOGI(TAG, "Implemented using built-in read and write methods (Use higher version >= 5.0 API)"); + + // * Using the new API of esp-idf 5.x, you need to pass the I2C BUS handle, + // * which is useful when the bus shares multiple devices. + extern i2c_master_bus_handle_t bus_handle; + + if (touch.begin(bus_handle)) { + ESP_LOGI(TAG, "Initialization of FT63XX is successful!"); + } else { + ESP_LOGE(TAG, "Failed to initialize the FT63XX!"); + return ESP_FAIL; + } + +#else + + ESP_LOGI(TAG, "Implemented using built-in read and write methods (Use lower version < 5.0 API)"); + if (touch.begin((i2c_port_t)CONFIG_I2C_MASTER_PORT_NUM, CONFIG_SENSOR_SDA, CONFIG_SENSOR_SCL)) { + ESP_LOGI(TAG, "Initialization of FT63XX is successful!"); + } else { + ESP_LOGE(TAG, "Failed to initialize the FT63XX!"); + return ESP_FAIL; + } +#endif //ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL(5,0,0) +#endif //CONFIG_I2C_COMMUNICATION_METHOD_BUILTIN_RW + + init_done = true; + + return ESP_OK; +} + +void ft63x6_loop() +{ + if (!init_done) { + return; + } + int16_t x[2], y[2]; + uint8_t numPoint = touch.getPoint(x, y, 2); + for (int i = 0; i < numPoint; ++i) { + ESP_LOGI("FT63X6", "Point[%02d] - X:%02d Y:%02d", i, x[i], y[i]); + } +} + +#endif + diff --git a/examples/ESP_IDF_TouchDrvExample/CMakeLists.txt b/examples/ESP_IDF_TouchDrvExample/CMakeLists.txt new file mode 100644 index 0000000..917f327 --- /dev/null +++ b/examples/ESP_IDF_TouchDrvExample/CMakeLists.txt @@ -0,0 +1,9 @@ +# The following five lines of boilerplate have to be in your project's +# CMakeLists in this exact order for cmake to work correctly +cmake_minimum_required(VERSION 3.5) + +include($ENV{IDF_PATH}/tools/cmake/project.cmake) + +set(EXTRA_COMPONENT_DIRS ../../../SensorLib) + +project(ESP_IDF_TouchDrvExample) diff --git a/examples/ESP_IDF_TouchDrv_Example/Makefile b/examples/ESP_IDF_TouchDrvExample/Makefile similarity index 100% rename from examples/ESP_IDF_TouchDrv_Example/Makefile rename to examples/ESP_IDF_TouchDrvExample/Makefile diff --git a/examples/ESP_IDF_TouchDrvExample/README.md b/examples/ESP_IDF_TouchDrvExample/README.md new file mode 100644 index 0000000..a8e2491 --- /dev/null +++ b/examples/ESP_IDF_TouchDrvExample/README.md @@ -0,0 +1,154 @@ +# ESP-IDF SensorLib TouchDrv examples + +```bash +The current example only writes the CSTxxx series touch application. +``` + +## Configure the Project + +Open the project configuration menu (`idf.py menuconfig`). + + +In the `SensorLib Example Configuration` menu: + +* Select the communication method, will interface, callback interface, LL new version interface + 1. Implemented using built-in read and write methods (Read and write methods are provided internally by SensorLib, supporting high version esp-idf >= 5.0, and low version methods (< 5.0)) + 2. Implemented using read and write callback methods (Implemented using externally provided methods, suitable for multiple platforms) +* In `Sensor SCL GPIO Num` select the clock pin to connect to the PMU,the default is 7 +* In `Sensor SDA GPIO Num` select the data pin connected to the PMU,the default is 6 +* Select the interrupt pin connected to the PMU in `Sensor Interrupt Pin`, the default is 8 +* Select `Sensor reset Pin` , the default is 17 +* `Master Frequency` The maximum communication frequency defaults to 100000HZ, and you can decide whether to change it according to the situation. + +## How to Use Example + +Before project configuration and build, be sure to set the correct chip target using `idf.py set-target `. default use **esp32s3** + +## Build and Flash + +Run `idf.py -p PORT flash monitor` to build, flash and monitor the project. + +(To exit the serial monitor, type ``Ctrl-]``.) + +See the [Getting Started Guide](https://docs.espressif.com/projects/esp-idf/en/latest/get-started/index.html) for full steps to configure and use ESP-IDF to build projects. + +## Example Output + +The output information is to configure the output voltage and enable status of the PMU + +```bash +SPIWP:0xee +mode:DIO, clock div:1 +load:0x3fce2810,len:0x178c +load:0x403c8700,len:0x4 +load:0x403c8704,len:0xc10 +load:0x403cb700,len:0x2dac +entry 0x403c8904 +I (26) boot: ESP-IDF v5.3-beta1-105-g3f632df143-dirt 2nd stage bootloader +I (27) boot: compile time Jan 23 2025 16:49:34 +I (27) boot: Multicore bootloader +I (27) boot: chip revision: v0.2 +I (27) boot.esp32s3: Boot SPI Speed : 80MHz +I (28) boot.esp32s3: SPI Mode : DIO +I (28) boot.esp32s3: SPI Flash Size : 2MB +I (28) boot: Enabling RNG early entropy source... +I (28) boot: Partition Table: +I (28) boot: ## Label Usage Type ST Offset Length +I (29) boot: 0 nvs WiFi data 01 02 00009000 00006000 +I (29) boot: 1 phy_init RF data 01 01 0000f000 00001000 +I (30) boot: 2 factory factory app 00 00 00010000 00100000 +I (30) boot: End of partition table +I (30) esp_image: segment 0: paddr=00010020 vaddr=3c030020 size=0ca94h ( 51860) map +I (40) esp_image: segment 1: paddr=0001cabc vaddr=3fc92e00 size=02a38h ( 10808) load +I (43) esp_image: segment 2: paddr=0001f4fc vaddr=40374000 size=00b1ch ( 2844) load +I (44) esp_image: segment 3: paddr=00020020 vaddr=42000020 size=21020h (135200) map +I (69) esp_image: segment 4: paddr=00041048 vaddr=40374b1c size=0e254h ( 57940) load +I (88) boot: Loaded app from partition at offset 0x10000 +I (88) boot: Disabling RNG early entropy source... +I (88) cpu_start: Multicore app +I (98) cpu_start: Pro cpu start user code +I (98) cpu_start: cpu freq: 240000000 Hz +I (98) app_init: Application information: +I (98) app_init: Project name: ESP_IDF_TouchDrvExample +I (98) app_init: App version: v0.2.5-8-gde9a1d2-dirty +I (99) app_init: Compile time: Jan 23 2025 16:51:47 +I (99) app_init: ELF file SHA256: 179a53fa8... +I (99) app_init: ESP-IDF: v5.3-beta1-105-g3f632df143-dirt +I (99) efuse_init: Min chip rev: v0.0 +I (99) efuse_init: Max chip rev: v0.99 +I (100) efuse_init: Chip rev: v0.2 +I (100) heap_init: Initializing. RAM available for dynamic allocation: +I (100) heap_init: At 3FC96158 len 000535B8 (333 KiB): RAM +I (100) heap_init: At 3FCE9710 len 00005724 (21 KiB): RAM +I (101) heap_init: At 3FCF0000 len 00008000 (32 KiB): DRAM +I (101) heap_init: At 600FE100 len 00001EE8 (7 KiB): RTCRAM +I (102) spi_flash: detected chip: winbond +I (102) spi_flash: flash io: dio +W (102) spi_flash: Detected size(16384k) larger than the size in the binary image header(2048k). Using the size in the binary image header. +I (103) sleep: Configure to isolate all GPIO pins in sleep state +I (103) sleep: Enable automatic switching of GPIO sleep configuration +I (104) main_task: Started on CPU0 +I (114) main_task: Calling app_main() +I (114) I2C: Implemented using read and write callback methods (Use higher version >= 5.0 API) +I (114) gpio: GPIO[6]| InputEn: 1| OutputEn: 1| OpenDrain: 1| Pullup: 1| Pulldown: 0| Intr:0 +I (114) gpio: GPIO[7]| InputEn: 1| OutputEn: 1| OpenDrain: 1| Pullup: 1| Pulldown: 0| Intr:0 +I (114) main: I2C initialized successfully +I (114) TOUCH: ----SensorLib TouchDrv Examples---- +Scand I2C Devices: + 0 1 2 3 4 5 6 7 8 9 a b c d e f +00: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- +10: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- +20: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- +30: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- +40: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- +50: -- -- -- -- -- -- -- -- -- -- 5a -- -- -- -- -- +60: -- -- -- -- -- -- -- -- -- -- 6a -- -- -- -- -- +70: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- + + + +I (224) TOUCH: Find touch address 0x5A +I (224) TOUCH: Implemented using built-in read and write methods (Use higher version >= 5.0 API) +I (224) SensorLib: Using ESP-IDF Driver interface. +I (224) SensorLib: Added Device Address : 0x5A New Dev Address: 0x3fc9a3a0 Speed :400000 +I (224) TOUCH: Initializing the capacitive touch screen successfully +I (224) TOUCH: Using CST226SE model +I (224) gpio: GPIO[8]| InputEn: 1| OutputEn: 0| OpenDrain: 0| Pullup: 1| Pulldown: 0| Intr:0 +I (224) main: Run... +I (224) main_task: Returned from app_main() +X[0]:143 Y[0]:167 +X[0]:143 Y[0]:167 +X[0]:143 Y[0]:167 +X[0]:143 Y[0]:167 +X[0]:143 Y[0]:167 +X[0]:143 Y[0]:167 +X[0]:143 Y[0]:167 +X[0]:143 Y[0]:167 +X[0]:143 Y[0]:167 +X[0]:143 Y[0]:167 +``` + +## Build process example + +Assuming you don't have esp-idf yet + +```bash +mkdir -p ~/esp +cd ~/esp +git clone --recursive https://github.com/espressif/esp-idf.git +git clone https://github.com/lewisxhe/SensorLib.git +cd esp-idf +./install.sh +. ./export.sh +cd .. +cd SensorLib/examples/ESP_IDF_TouchDrvExample + +Configure SDA,SCL,INT,RST,Pin +... + +idf.py menuconfig +idf.py build +idf.py -b 921600 flash +idf.py monitor + +``` diff --git a/examples/ESP_IDF_TouchDrv_Example/main/CMakeLists.txt b/examples/ESP_IDF_TouchDrvExample/main/CMakeLists.txt similarity index 100% rename from examples/ESP_IDF_TouchDrv_Example/main/CMakeLists.txt rename to examples/ESP_IDF_TouchDrvExample/main/CMakeLists.txt diff --git a/examples/ESP_IDF_TouchDrv_Example/main/Kconfig.projbuild b/examples/ESP_IDF_TouchDrvExample/main/Kconfig.projbuild similarity index 95% rename from examples/ESP_IDF_TouchDrv_Example/main/Kconfig.projbuild rename to examples/ESP_IDF_TouchDrvExample/main/Kconfig.projbuild index cccfbd5..397f756 100644 --- a/examples/ESP_IDF_TouchDrv_Example/main/Kconfig.projbuild +++ b/examples/ESP_IDF_TouchDrvExample/main/Kconfig.projbuild @@ -26,25 +26,25 @@ menu "SensorLib Example Configuration" config SENSOR_SCL int "Sensor SCL GPIO Num" - default 17 + default 7 help GPIO number for I2C clock line. config SENSOR_SDA int "Sensor SDA GPIO Num" - default 18 + default 6 help GPIO number for I2C data line. config SENSOR_IRQ int "Sensor Interrupt Pin" - default 16 + default 8 help Sensor interrupt pin. config SENSOR_RST int "Sensor reset Pin" - default 21 + default 17 help Sensor reset pin. diff --git a/examples/ESP_IDF_TouchDrvExample/main/component.mk b/examples/ESP_IDF_TouchDrvExample/main/component.mk new file mode 100644 index 0000000..a98f634 --- /dev/null +++ b/examples/ESP_IDF_TouchDrvExample/main/component.mk @@ -0,0 +1,4 @@ +# +# "main" pseudo-component makefile. +# +# (Uses default behaviour of compiling all source files in directory, adding 'include' to include path.) diff --git a/examples/ESP_IDF_TouchDrv_Example/main/i2c_driver.cpp b/examples/ESP_IDF_TouchDrvExample/main/i2c_driver.cpp similarity index 86% rename from examples/ESP_IDF_TouchDrv_Example/main/i2c_driver.cpp rename to examples/ESP_IDF_TouchDrvExample/main/i2c_driver.cpp index b444fa4..0da1652 100644 --- a/examples/ESP_IDF_TouchDrv_Example/main/i2c_driver.cpp +++ b/examples/ESP_IDF_TouchDrvExample/main/i2c_driver.cpp @@ -1,9 +1,30 @@ /** + * + * @license MIT License + * + * Copyright (c) 2025 lewis he + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * * @file port_i2c.cpp * @author Lewis He (lewishe@outlook.com) - * @license MIT - * @copyright Copyright (c) 2024 Shenzhen Xinyuan Electronic Technology Co., Ltd - * @date 2024-01-10 + * @date 2025-01-22 * */ #include @@ -163,7 +184,7 @@ esp_err_t i2c_drv_init(void) i2c_bus_config.scl_io_num = (gpio_num_t)I2C_MASTER_SCL_IO; i2c_bus_config.sda_io_num = (gpio_num_t)I2C_MASTER_SDA_IO; i2c_bus_config.glitch_ignore_cnt = 7; - + i2c_bus_config.flags.enable_internal_pullup = true; ESP_ERROR_CHECK(i2c_new_master_bus(&i2c_bus_config, &bus_handle)); return ESP_OK; @@ -211,6 +232,7 @@ void i2c_drv_scan() printf("\n\n\n"); #else uint8_t address; + printf("Scand I2C Devices:\n"); printf(" 0 1 2 3 4 5 6 7 8 9 a b c d e f\r\n"); for (int i = 0; i < 128; i += 16) { printf("%02x: ", i); diff --git a/examples/ESP_IDF_TouchDrvExample/main/i2c_driver.h b/examples/ESP_IDF_TouchDrvExample/main/i2c_driver.h new file mode 100644 index 0000000..6a44c11 --- /dev/null +++ b/examples/ESP_IDF_TouchDrvExample/main/i2c_driver.h @@ -0,0 +1,53 @@ +/** + * + * @license MIT License + * + * Copyright (c) 2025 lewis he + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * @file i2c_driver.h + * @author Lewis He (lewishe@outlook.com) + * @date 2025-01-22 + * + */ +#pragma once + +#include "esp_err.h" +#include "esp_log.h" +#include "driver/gpio.h" +#include "esp_idf_version.h" +#if ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL(5,0,0) && defined(CONFIG_SENSORLIB_ESP_IDF_NEW_API) +#include "driver/i2c_master.h" +#else +#include "driver/i2c.h" +#endif //ESP_IDF_VERSION + + +esp_err_t i2c_drv_init(void); +void i2c_drv_scan(); +bool i2c_drv_probe(uint8_t devAddr); +int i2c_read_callback(uint8_t devAddr, uint8_t regAddr, uint8_t *data, uint8_t len); +int i2c_write_callback(uint8_t devAddr, uint8_t regAddr, uint8_t *data, uint8_t len); + +#if CONFIG_I2C_COMMUNICATION_METHOD_CALLBACK_RW +esp_err_t i2c_drv_device_init(uint8_t address); +#endif + + diff --git a/examples/ESP_IDF_TouchDrvExample/main/main.cpp b/examples/ESP_IDF_TouchDrvExample/main/main.cpp new file mode 100644 index 0000000..7e6a853 --- /dev/null +++ b/examples/ESP_IDF_TouchDrvExample/main/main.cpp @@ -0,0 +1,67 @@ +/** + * + * @license MIT License + * + * Copyright (c) 2025 lewis he + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * @file main.cpp + * @author Lewis He (lewishe@outlook.com) + * @date 2025-01-22 + * + */ +#include "sdkconfig.h" +#include "freertos/FreeRTOS.h" +#include "freertos/task.h" +#include "driver/gpio.h" +#include "freertos/queue.h" +#include "i2c_driver.h" + +static const char *TAG = "main"; + +extern esp_err_t sensor_drv_init(); +extern esp_err_t touch_drv_init(); +extern void touch_loop(); +static void touch_task(void *); + +extern "C" void app_main(void) +{ + ESP_ERROR_CHECK(i2c_drv_init()); + ESP_LOGI(TAG, "I2C initialized successfully"); + + ESP_ERROR_CHECK(touch_drv_init()); + + xTaskCreate(touch_task, "touch", 4 * 1024, NULL, 10, NULL); + + ESP_LOGI(TAG, "Run..."); +} + + +static void touch_task(void *args) +{ + while (1) { + touch_loop(); + // vTaskDelay(pdMS_TO_TICKS(10)); + vTaskDelay(1 / portTICK_PERIOD_MS); + } +} + + + diff --git a/examples/ESP_IDF_TouchDrv_Example/main/touch_drv.cpp b/examples/ESP_IDF_TouchDrvExample/main/touch_drv.cpp similarity index 57% rename from examples/ESP_IDF_TouchDrv_Example/main/touch_drv.cpp rename to examples/ESP_IDF_TouchDrvExample/main/touch_drv.cpp index 430f01d..b2c2a2b 100644 --- a/examples/ESP_IDF_TouchDrv_Example/main/touch_drv.cpp +++ b/examples/ESP_IDF_TouchDrvExample/main/touch_drv.cpp @@ -1,9 +1,30 @@ /** + * + * @license MIT License + * + * Copyright (c) 2025 lewis he + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * * @file touch_drv.cpp * @author Lewis He (lewishe@outlook.com) - * @license MIT - * @copyright Copyright (c) 2024 Shenzhen Xinyuan Electronic Technology Co., Ltd - * @date 2024-01-10 + * @date 2025-01-22 * */ #include "sdkconfig.h" @@ -15,15 +36,45 @@ static const char *TAG = "TOUCH"; +#define SENSOR_INPUT_PIN (gpio_num_t)CONFIG_SENSOR_IRQ +#define SENSOR_INPUT_PIN_SEL (1ULL<= ESP_IDF_VERSION_VAL(5,0,0) #endif //CONFIG_I2C_COMMUNICATION_METHOD_BUILTIN_RW const char *model = touch.getModelName(); - if (strncmp(model, "CST8", 3) == 0) { + ESP_LOGI(TAG, "Using %s model", model); + if (strncmp(model, "CST8", 4) == 0) { ESP_LOGI(TAG, "Some CST816 will automatically enter sleep,can use the touch.disableAutoSleep() to turn off"); // Some CST816 will automatically enter sleep, // can use the touch.disableAutoSleep() to turn off @@ -134,13 +184,16 @@ esp_err_t touch_drv_init() // Mirror XY coordinates // touch.setMirrorXY(false, true); + + // Create a queue to handle gpio event from isr + xQueue = xQueueCreate(5, sizeof(uint32_t)); + + // Register Sensor interrupt pins + irq_init(); + return ESP_OK; } -static void touch_home_button_callback(void *user_data) -{ - ESP_LOGI(TAG, "Touch Home button pressed!"); -} void touch_drv_isr_handler() { @@ -163,4 +216,12 @@ void touch_drv_isr_handler() } } - +void touch_loop() +{ + uint32_t io_num; + // if (xQueueReceive(xQueue, &io_num, pdMS_TO_TICKS(10))) { + // if (gpio_get_level((gpio_num_t)CONFIG_SENSOR_IRQ) == 0) { + touch_drv_isr_handler(); + // } + // } +} diff --git a/examples/ESP_IDF_TouchDrv_Example/sdkconfig.defaults b/examples/ESP_IDF_TouchDrvExample/sdkconfig.defaults similarity index 100% rename from examples/ESP_IDF_TouchDrv_Example/sdkconfig.defaults rename to examples/ESP_IDF_TouchDrvExample/sdkconfig.defaults diff --git a/examples/ESP_IDF_TouchDrv_Example/README.md b/examples/ESP_IDF_TouchDrv_Example/README.md deleted file mode 100644 index 05788b2..0000000 --- a/examples/ESP_IDF_TouchDrv_Example/README.md +++ /dev/null @@ -1,181 +0,0 @@ -# ESP_IDF_TouchDrv_Example - -``` -The current example only writes the CSTxxx series touch application. -The other sensors have not been added, but the methods are the same. -``` - - -### Configure the Project - -Open the project configuration menu (`idf.py menuconfig`). - - -In the `SensorLib Example Configuration` menu: - -* Select the PMU Type in the `SensorLib read and write methods` option,Choose according to the situation - 1. Implemented using built-in read and write methods (Read and write methods are provided internally by SensorLib, supporting high version esp-idf >= 5.0, and low version methods (< 5.0)) - 2. Implemented using read and write callback methods (Implemented using externally provided methods, suitable for multiple platforms) -* In `Sensor SCL GPIO Num` select the clock pin to connect to the PMU,the default is 17 -* In `Sensor SDA GPIO Num` select the data pin connected to the PMU,the default is 18 -* Select the interrupt pin connected to the PMU in `Sensor Interrupt Pin`, the default is 16 -* Select `Sensor reset Pin` , the default is 21 -* `Master Frequency` The maximum communication frequency defaults to 100000HZ, and you can decide whether to change it according to the situation. - -## How to Use Example - -Before project configuration and build, be sure to set the correct chip target using `idf.py set-target `. default use **esp32s3** - - -### Build and Flash - -Run `idf.py -p PORT flash monitor` to build, flash and monitor the project. - -(To exit the serial monitor, type ``Ctrl-]``.) - -See the [Getting Started Guide](https://docs.espressif.com/projects/esp-idf/en/latest/get-started/index.html) for full steps to configure and use ESP-IDF to build projects. - -## Example Output - -The output information is to configure the output voltage and enable status of the PMU - -``` -ESP-ROM:esp32s3-20210327 -Build:Mar 27 2021 -rst:0x15 (USB_UART_CHIP_RESET),boot:0xa (SPI_FAST_FLASH_BOOT) -Saved PC:0x403788f6 -SPIWP:0xee -mode:DIO, clock div:1 -load:0x3fce3810,len:0x178c -load:0x403c9700,len:0x4 -load:0x403c9704,len:0xbfc -load:0x403cc700,len:0x2d64 -entry 0x403c9900 -I (26) boot: ESP-IDF v5.3-dev-1288-g5524b692ee 2nd stage bootloader -I (27) boot: compile time Jan 10 2024 22:49:17 -I (27) boot: Multicore bootloader -I (31) boot: chip revision: v0.2 -I (35) boot.esp32s3: Boot SPI Speed : 80MHz -I (40) boot.esp32s3: SPI Mode : DIO -I (45) boot.esp32s3: SPI Flash Size : 2MB -I (49) boot: Enabling RNG early entropy source... -I (55) boot: Partition Table: -I (58) boot: ## Label Usage Type ST Offset Length -I (66) boot: 0 nvs WiFi data 01 02 00009000 00006000 -I (73) boot: 1 phy_init RF data 01 01 0000f000 00001000 -I (81) boot: 2 factory factory app 00 00 00010000 00100000 -I (88) boot: End of partition table -I (92) esp_image: segment 0: paddr=00010020 vaddr=3c020020 size=0e0dch ( 57564) map -I (111) esp_image: segment 1: paddr=0001e104 vaddr=3fc93100 size=01f14h ( 7956) load -I (113) esp_image: segment 2: paddr=00020020 vaddr=42000020 size=1acb0h (109744) map -I (137) esp_image: segment 3: paddr=0003acd8 vaddr=3fc95014 size=00994h ( 2452) load -I (138) esp_image: segment 4: paddr=0003b674 vaddr=40374000 size=0f0e0h ( 61664) load -I (163) boot: Loaded app from partition at offset 0x10000 -I (163) boot: Disabling RNG early entropy source... -I (163) cpu_start: Multicore app -I (176) cpu_start: Pro cpu start user code -I (176) cpu_start: cpu freq: 240000000 Hz -I (177) cpu_start: Application information: -I (177) cpu_start: Project name: ESP_IDF_TouchDrv_Example -I (177) cpu_start: App version: v0.1.4-6-gfeaf675-dirty -I (177) cpu_start: Compile time: Jan 11 2024 14:01:31 -I (177) cpu_start: ELF file SHA256: 3ce1527fc... -I (178) cpu_start: ESP-IDF: v5.3-dev-1288-g5524b692ee -I (178) cpu_start: Min chip rev: v0.0 -I (178) cpu_start: Max chip rev: v0.99 -I (178) cpu_start: Chip rev: v0.2 -I (178) heap_init: Initializing. RAM available for dynamic allocation: -I (179) heap_init: At 3FC96290 len 00053480 (333 KiB): RAM -I (179) heap_init: At 3FCE9710 len 00005724 (21 KiB): RAM -I (179) heap_init: At 3FCF0000 len 00008000 (32 KiB): DRAM -I (180) heap_init: At 600FE010 len 00001FD8 (7 KiB): RTCRAM -I (181) spi_flash: detected chip: winbond -I (181) spi_flash: flash io: dio -W (181) spi_flash: Detected size(16384k) larger than the size in the binary image header(2048k). Using the size in the binary image header. -W (181) i2c: This driver is an old driver, please migrate your application code to adapt `driver/i2c_master.h` -I (182) sleep: Configure to isolate all GPIO pins in sleep state -I (182) sleep: Enable automatic switching of GPIO sleep configuration -I (183) main_task: Started on CPU0 -I (193) main_task: Calling app_main() -I (193) gpio: GPIO[16]| InputEn: 1| OutputEn: 0| OpenDrain: 0| Pullup: 1| Pulldown: 0| Intr:2 -I (193) I2C: Implemented using read and write callback methods (Use lower version < 5.0 API) -I (193) mian: I2C initialized successfully -I (193) TOUCH: ----touch_drv_init---- -0 1 2 3 4 5 6 7 8 9 a b c d e f -00: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -10: -- -- -- -- -- 15 -- -- -- -- -- -- -- -- -- -- -20: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -30: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -40: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -50: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -60: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -70: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -I (303) TOUCH: Find touch address 0x15 -I (303) TOUCH: Find touch address 0x15 -I (303) TOUCH: Implemented using built-in read and write methods (Use lower version < 5.0 API) -Using ESP-IDF Driver interface. -E (303) i2c: i2c driver install error -I (303) gpio: GPIO[21]| InputEn: 0| OutputEn: 1| OpenDrain: 0| Pullup: 0| Pulldown: 0| Intr:0 -I (303) gpio: GPIO[21]| InputEn: 0| OutputEn: 1| OpenDrain: 0| Pullup: 0| Pulldown: 0| Intr:0 -Chip ID:0xb5 -Version :0x2 -Touch type:CST816T -I (383) TOUCH: Init touch SUCCESS! -I (383) TOUCH: Some CST816 will automatically enter sleep,can use the touch.disableAutoSleep() to turn off -I (383) gpio: GPIO[21]| InputEn: 0| OutputEn: 1| OpenDrain: 0| Pullup: 0| Pulldown: 0| Intr:0 -I (513) mian: Run... -I (513) main_task: Returned from app_main() -X[0]:143 Y[0]:127 -X[0]:143 Y[0]:127 -X[0]:142 Y[0]:127 -X[0]:141 Y[0]:126 -X[0]:138 Y[0]:125 -X[0]:135 Y[0]:123 -X[0]:131 Y[0]:121 -X[0]:126 Y[0]:119 -X[0]:121 Y[0]:117 -X[0]:84 Y[0]:146 -X[0]:85 Y[0]:146 -X[0]:86 Y[0]:145 -X[0]:87 Y[0]:143 -X[0]:88 Y[0]:140 -X[0]:89 Y[0]:136 -X[0]:90 Y[0]:132 -X[0]:91 Y[0]:127 -X[0]:92 Y[0]:123 -X[0]:93 Y[0]:119 -X[0]:94 Y[0]:115 -X[0]:95 Y[0]:111 -I (513563) TOUCH: Touch Home button pressed! -I (513573) TOUCH: Touch Home button pressed! -I (513583) TOUCH: Touch Home button pressed! -I (513603) TOUCH: Touch Home button pressed! -I (513613) TOUCH: Touch Home button pressed! -I (513633) TOUCH: Touch Home button pressed! -I (513643) TOUCH: Touch Home button pressed! -``` - -## Build process example - -Assuming you don't have esp-idf yet - -``` -mkdir -p ~/esp -cd ~/esp -git clone --recursive https://github.com/espressif/esp-idf.git -git clone https://github.com/lewisxhe/XPowersLib.git -cd esp-idf -./install.sh -. ./export.sh -cd .. -cd SensorLib/examples/ESP_IDF_Example - -Configure SDA,SCL,INT,RST,Pin -... - -idf.py menuconfig -idf.py build -idf.py -b 921600 flash -idf.py monitor - -``` \ No newline at end of file diff --git a/examples/ESP_IDF_TouchDrv_Example/main/i2c_driver.h b/examples/ESP_IDF_TouchDrv_Example/main/i2c_driver.h deleted file mode 100644 index 8f13b48..0000000 --- a/examples/ESP_IDF_TouchDrv_Example/main/i2c_driver.h +++ /dev/null @@ -1,32 +0,0 @@ -/** - * @file i2c_driver.h - * @author Lewis He (lewishe@outlook.com) - * @license MIT - * @copyright Copyright (c) 2024 Shenzhen Xinyuan Electronic Technology Co., Ltd - * @date 2024-01-10 - * - */ -#pragma once - -#include "esp_err.h" -#include "esp_log.h" -#include "driver/gpio.h" -#include "esp_idf_version.h" -#if ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL(5,0,0) && defined(CONFIG_SENSORLIB_ESP_IDF_NEW_API) -#include "driver/i2c_master.h" -#else -#include "driver/i2c.h" -#endif //ESP_IDF_VERSION - - -esp_err_t i2c_drv_init(void); -void i2c_drv_scan(); -bool i2c_drv_probe(uint8_t devAddr); -int i2c_read_callback(uint8_t devAddr, uint8_t regAddr, uint8_t *data, uint8_t len); -int i2c_write_callback(uint8_t devAddr, uint8_t regAddr, uint8_t *data, uint8_t len); - -#if CONFIG_I2C_COMMUNICATION_METHOD_CALLBACK_RW -esp_err_t i2c_drv_device_init(uint8_t address); -#endif - - diff --git a/examples/ESP_IDF_TouchDrv_Example/main/main.cpp b/examples/ESP_IDF_TouchDrv_Example/main/main.cpp deleted file mode 100644 index b837b84..0000000 --- a/examples/ESP_IDF_TouchDrv_Example/main/main.cpp +++ /dev/null @@ -1,83 +0,0 @@ -/** - * @file main.cpp - * @author Lewis He (lewishe@outlook.com) - * @license MIT - * @copyright Copyright (c) 2024 Shenzhen Xinyuan Electronic Technology Co., Ltd - * @date 2024-01-10 - * - */ -#include "sdkconfig.h" -#include "freertos/FreeRTOS.h" -#include "freertos/task.h" -#include "driver/gpio.h" -#include "freertos/queue.h" -#include "i2c_driver.h" - -#define SENSOR_INPUT_PIN (gpio_num_t)CONFIG_SENSOR_IRQ /*!< axp power chip interrupt Pin*/ -#define SENSOR_INPUT_PIN_SEL (1ULL< 1000) { + if (millis() - intervalue > 1000) { /** /// Format output time* Option: @@ -98,7 +98,7 @@ void printDateTime() */ Serial.println(rtc.strftime()); - lastMillis = millis(); + intervalue = millis(); } } diff --git a/examples/PCF85063_ClockOutput/PCF85063_ClockOutput.ino b/examples/PCF85063_ClockOutput/PCF85063_ClockOutput.ino index 633db47..139b164 100644 --- a/examples/PCF85063_ClockOutput/PCF85063_ClockOutput.ino +++ b/examples/PCF85063_ClockOutput/PCF85063_ClockOutput.ino @@ -69,7 +69,7 @@ String freq_hz_str[] = { SensorPCF85063 rtc; -uint32_t lastMillis; +uint32_t intervalue; uint8_t i = 0; @@ -77,8 +77,8 @@ void setup() { Serial.begin(115200); while (!Serial); - if (!rtc.begin(Wire, PCF85063_SLAVE_ADDRESS, SENSOR_SDA, SENSOR_SCL)) { - Serial.println("Failed to find PCF8563 - check your wiring!"); + if (!rtc.begin(Wire, SENSOR_SDA, SENSOR_SCL)) { + Serial.println("Failed to find PCF85063 - check your wiring!"); while (1) { delay(1000); } @@ -88,8 +88,8 @@ void setup() void loop() { - if (millis() - lastMillis > 5000) { - lastMillis = millis(); + if (millis() - intervalue > 5000) { + intervalue = millis(); Serial.print("Set freq : "); Serial.println(freq_hz_str[i]); rtc.setClockOutput(clock_array[i]); diff --git a/examples/PCF85063_SimpleTime/PCF85063_SimpleTime.ino b/examples/PCF85063_SimpleTime/PCF85063_SimpleTime.ino index b476eae..41cb400 100644 --- a/examples/PCF85063_SimpleTime/PCF85063_SimpleTime.ino +++ b/examples/PCF85063_SimpleTime/PCF85063_SimpleTime.ino @@ -45,7 +45,7 @@ #endif SensorPCF85063 rtc; -uint32_t lastMillis; +uint32_t intervalue; void setup() { @@ -54,8 +54,8 @@ void setup() pinMode(SENSOR_IRQ, INPUT_PULLUP); - if (!rtc.begin(Wire, PCF85063_SLAVE_ADDRESS, SENSOR_SDA, SENSOR_SCL)) { - Serial.println("Failed to find PCF8563 - check your wiring!"); + if (!rtc.begin(Wire, SENSOR_SDA, SENSOR_SCL)) { + Serial.println("Failed to find PCF85063 - check your wiring!"); while (1) { delay(1000); } @@ -75,8 +75,8 @@ void setup() void loop() { - if (millis() - lastMillis > 1000) { - lastMillis = millis(); + if (millis() - intervalue > 1000) { + intervalue = millis(); RTC_DateTime datetime = rtc.getDateTime(); Serial.printf(" Year :"); Serial.print(datetime.year); Serial.printf(" Month:"); Serial.print(datetime.month); diff --git a/examples/PCF8563_AlarmByUnits/PCF8563_AlarmByUnits.ino b/examples/PCF8563_AlarmByUnits/PCF8563_AlarmByUnits.ino index c905411..fe8416d 100644 --- a/examples/PCF8563_AlarmByUnits/PCF8563_AlarmByUnits.ino +++ b/examples/PCF8563_AlarmByUnits/PCF8563_AlarmByUnits.ino @@ -33,22 +33,22 @@ #include #include "SensorPCF8563.hpp" -#ifdef ESP32 -#define SENSOR_SDA 42 -#define SENSOR_SCL 41 -#define SENSOR_IRQ 14 -#else -#define _PINNUM(port, pin) ((port)*32 + (pin)) -#define SENSOR_SDA _PINNUM(0,26) -#define SENSOR_SCL _PINNUM(0,27) -#define SENSOR_IRQ _PINNUM(0,16) +#ifndef SENSOR_SDA +#define SENSOR_SDA 42 #endif +#ifndef SENSOR_SCL +#define SENSOR_SCL 41 +#endif -SensorPCF8563 rtc; +#ifndef SENSOR_IRQ +#define SENSOR_IRQ 14 +#endif -uint32_t lastMillis = 0; +SensorPCF8563 rtc; + +uint32_t intervalue = 0; uint8_t nextHour = 22; uint8_t nextMonth = 1; uint8_t nextDay = 1; @@ -61,9 +61,7 @@ void setup() Serial.begin(115200); while (!Serial); - - - if (!rtc.begin(Wire, PCF8563_SLAVE_ADDRESS, SENSOR_SDA, SENSOR_SCL)) { + if (!rtc.begin(Wire, SENSOR_SDA, SENSOR_SCL)) { Serial.println("Failed to find PCF8563 - check your wiring!"); while (1) { delay(1000); @@ -83,7 +81,7 @@ void setup() void printDateTime() { - if (millis() - lastMillis > 1000) { + if (millis() - intervalue > 1000) { /** /// Format output time* Option: @@ -97,7 +95,7 @@ void printDateTime() */ Serial.println(rtc.strftime()); - lastMillis = millis(); + intervalue = millis(); } } diff --git a/examples/PCF8563_ClockOutput/PCF8563_ClockOutput.ino b/examples/PCF8563_ClockOutput/PCF8563_ClockOutput.ino index 7316d51..800600b 100644 --- a/examples/PCF8563_ClockOutput/PCF8563_ClockOutput.ino +++ b/examples/PCF8563_ClockOutput/PCF8563_ClockOutput.ino @@ -33,21 +33,21 @@ #include "SensorPCF8563.hpp" #ifndef SENSOR_SDA -#define SENSOR_SDA 17 +#define SENSOR_SDA 42 #endif #ifndef SENSOR_SCL -#define SENSOR_SCL 18 +#define SENSOR_SCL 41 #endif #ifndef SENSOR_IRQ -#define SENSOR_IRQ 7 +#define SENSOR_IRQ 14 #endif SensorPCF8563::ClockHz clock_array[] = { - SensorPCF8563::CLK_32_768KHZ, - SensorPCF8563::CLK_1024KHZ, + SensorPCF8563::CLK_32768HZ, + SensorPCF8563::CLK_1024HZ, SensorPCF8563::CLK_32HZ, SensorPCF8563::CLK_1HZ, SensorPCF8563::CLK_DISABLE, @@ -63,7 +63,7 @@ String freq_hz_str[] = { SensorPCF8563 rtc; -uint32_t lastMillis; +uint32_t intervalue; uint8_t i = 0; @@ -71,7 +71,7 @@ void setup() { Serial.begin(115200); while (!Serial); - if (!rtc.begin(Wire, PCF8563_SLAVE_ADDRESS, SENSOR_SDA, SENSOR_SCL)) { + if (!rtc.begin(Wire, SENSOR_SDA, SENSOR_SCL)) { Serial.println("Failed to find PCF8563 - check your wiring!"); while (1) { delay(1000); @@ -82,8 +82,8 @@ void setup() void loop() { - if (millis() - lastMillis > 5000) { - lastMillis = millis(); + if (millis() - intervalue > 5000) { + intervalue = millis(); Serial.print("Set freq : "); Serial.println(freq_hz_str[i]); rtc.setClockOutput(clock_array[i]); diff --git a/examples/PCF8563_SimpleTime/PCF8563_SimpleTime.ino b/examples/PCF8563_SimpleTime/PCF8563_SimpleTime.ino index 468a2a6..da76046 100644 --- a/examples/PCF8563_SimpleTime/PCF8563_SimpleTime.ino +++ b/examples/PCF8563_SimpleTime/PCF8563_SimpleTime.ino @@ -32,24 +32,29 @@ #include #include "SensorPCF8563.hpp" -// lilygo t-beam-s3-core pin -#define SENSOR_SDA 42 -#define SENSOR_SCL 41 -#define SENSOR_IRQ 14 +#ifndef SENSOR_SDA +#define SENSOR_SDA 42 +#endif + +#ifndef SENSOR_SCL +#define SENSOR_SCL 41 +#endif + +#ifndef SENSOR_IRQ +#define SENSOR_IRQ 14 +#endif SensorPCF8563 rtc; -uint32_t lastMillis; +uint32_t intervalue; void setup() { Serial.begin(115200); while (!Serial); - - pinMode(SENSOR_IRQ, INPUT_PULLUP); - if (!rtc.begin(Wire, PCF8563_SLAVE_ADDRESS, SENSOR_SDA, SENSOR_SCL)) { + if (!rtc.begin(Wire, SENSOR_SDA, SENSOR_SCL)) { Serial.println("Failed to find PCF8563 - check your wiring!"); while (1) { delay(1000); @@ -70,8 +75,8 @@ void setup() void loop() { - if (millis() - lastMillis > 1000) { - lastMillis = millis(); + if (millis() - intervalue > 1000) { + intervalue = millis(); RTC_DateTime datetime = rtc.getDateTime(); Serial.printf(" Year :"); Serial.print(datetime.year); Serial.printf(" Month:"); Serial.print(datetime.month); diff --git a/examples/PCF8563_TimeLib/PCF8563_TimeLib.ino b/examples/PCF8563_TimeLib/PCF8563_TimeLib.ino index 3cea9d9..de6201e 100644 --- a/examples/PCF8563_TimeLib/PCF8563_TimeLib.ino +++ b/examples/PCF8563_TimeLib/PCF8563_TimeLib.ino @@ -33,13 +33,20 @@ #include "SensorPCF8563.hpp" #include -// lilygo t-beam-s3-core pin -#define SENSOR_SDA 42 -#define SENSOR_SCL 41 -#define SENSOR_IRQ 14 +#ifndef SENSOR_SDA +#define SENSOR_SDA 42 +#endif + +#ifndef SENSOR_SCL +#define SENSOR_SCL 41 +#endif + +#ifndef SENSOR_IRQ +#define SENSOR_IRQ 14 +#endif SensorPCF8563 rtc; -uint32_t lastMillis; +uint32_t intervalue; char buf[64]; void setup() @@ -47,25 +54,35 @@ void setup() Serial.begin(115200); while (!Serial); - - pinMode(SENSOR_IRQ, INPUT_PULLUP); - if (!rtc.begin(Wire, PCF8563_SLAVE_ADDRESS, SENSOR_SDA, SENSOR_SCL)) { + if (!rtc.begin(Wire, SENSOR_SDA, SENSOR_SCL)) { Serial.println("Failed to find PCF8563 - check your wiring!"); while (1) { delay(1000); } } + // The simplest way to set up + rtc.setDateTime(2024, 1, 17, 4, 21, 30); + + // Unix tm structure sets the time + struct tm timeinfo; + timeinfo.tm_yday = 2025 - 1900; //Counting starts from 1900, so subtract 1900 here + timeinfo.tm_mon = 1 - 1; //Months start at 0, so you need to subtract 1. + timeinfo.tm_mday = 17; + timeinfo.tm_hour = 4; + timeinfo.tm_min = 30; + timeinfo.tm_sec = 30; + rtc.setDateTime(timeinfo); } void loop() { - if (millis() - lastMillis > 1000) { + if (millis() - intervalue > 1000) { - lastMillis = millis(); + intervalue = millis(); struct tm timeinfo; // Get the time C library structure diff --git a/examples/PCF8563_TimeSynchronization/PCF8563_TimeSynchronization.ino b/examples/PCF8563_TimeSynchronization/PCF8563_TimeSynchronization.ino index 78dd427..8f4fccc 100644 --- a/examples/PCF8563_TimeSynchronization/PCF8563_TimeSynchronization.ino +++ b/examples/PCF8563_TimeSynchronization/PCF8563_TimeSynchronization.ino @@ -36,10 +36,17 @@ #include #include "SensorPCF8563.hpp" -// lilygo t-beam-s3-core pin -#define SENSOR_SDA 42 -#define SENSOR_SCL 41 -#define SENSOR_IRQ 14 +#ifndef SENSOR_SDA +#define SENSOR_SDA 42 +#endif + +#ifndef SENSOR_SCL +#define SENSOR_SCL 41 +#endif + +#ifndef SENSOR_IRQ +#define SENSOR_IRQ 14 +#endif const char *ssid = "YOUR_SSID"; const char *password = "YOUR_PASS"; @@ -52,7 +59,7 @@ const int daylightOffset_sec = 3600; const char *time_zone = "CST-8"; // TimeZone rule for Europe/Rome including daylight adjustment rules (optional) SensorPCF8563 rtc; -uint32_t lastMillis; +uint32_t intervalue; // Callback function (get's called when time adjusts via NTP) @@ -69,11 +76,9 @@ void setup() Serial.begin(115200); while (!Serial); - - pinMode(SENSOR_IRQ, INPUT_PULLUP); - if (!rtc.begin(Wire, PCF8563_SLAVE_ADDRESS, SENSOR_SDA, SENSOR_SCL)) { + if (!rtc.begin(Wire, SENSOR_SDA, SENSOR_SCL)) { Serial.println("Failed to find PCF8563 - check your wiring!"); while (1) { delay(1000); @@ -123,9 +128,9 @@ void setup() void loop() { - if (millis() - lastMillis > 1000) { + if (millis() - intervalue > 1000) { - lastMillis = millis(); + intervalue = millis(); // hardware clock struct tm hwTimeinfo; diff --git a/examples/QMC6310_CalibrateExample/QMC6310_CalibrateExample.ino b/examples/QMC6310_CalibrateExample/QMC6310_CalibrateExample.ino index e81b61e..6ea74da 100644 --- a/examples/QMC6310_CalibrateExample/QMC6310_CalibrateExample.ino +++ b/examples/QMC6310_CalibrateExample/QMC6310_CalibrateExample.ino @@ -31,6 +31,9 @@ #include #include #include "SensorQMC6310.hpp" +#ifdef ARDUINO_T_BEAM_S3_SUPREME +#include //PMU Library https://github.com/lewisxhe/XPowersLib.git +#endif #ifndef SENSOR_SDA #define SENSOR_SDA 17 @@ -40,13 +43,23 @@ #define SENSOR_SCL 18 #endif -#ifndef SENSOR_IRQ -#define SENSOR_IRQ -1 -#endif - - SensorQMC6310 qmc; +void beginPower() +{ + // T_BEAM_S3_SUPREME The PMU voltage needs to be turned on to use the sensor +#if defined(ARDUINO_T_BEAM_S3_SUPREME) + XPowersAXP2101 power; + power.begin(Wire1, AXP2101_SLAVE_ADDRESS, 42, 41); + power.disableALDO1(); + power.disableALDO2(); + delay(250); + power.setALDO1Voltage(3300); + power.enableALDO1(); + power.setALDO2Voltage(3300); + power.enableALDO2(); +#endif +} void calibrate() { @@ -160,7 +173,9 @@ void setup() Serial.begin(115200); while (!Serial); - if (!qmc.begin(Wire, QMC6310_SLAVE_ADDRESS, SENSOR_SDA, SENSOR_SCL)) { + beginPower(); + + if (!qmc.begin(Wire, SENSOR_SDA, SENSOR_SCL)) { Serial.println("Failed to find QMC6310 - check your wiring!"); while (1) { delay(1000); @@ -215,9 +230,6 @@ void setup() * * */ SensorQMC6310::DSR_1); - - - // Calibration algorithm reference from // https://github.com/CoreElectronics/CE-PiicoDev-QMC6310-MicroPython-Module calibrate(); @@ -230,7 +242,6 @@ void setup() void loop() { - //Wait data ready if (qmc.isDataReady()) { diff --git a/examples/QMC6310_CompassExample/QMC6310_CompassExample.ino b/examples/QMC6310_CompassExample/QMC6310_CompassExample.ino index a71ccda..8bdc7a8 100644 --- a/examples/QMC6310_CompassExample/QMC6310_CompassExample.ino +++ b/examples/QMC6310_CompassExample/QMC6310_CompassExample.ino @@ -32,9 +32,11 @@ #include #if defined(ARDUINO_ARCH_ESP32) - #include "SensorQMC6310.hpp" #include "SH1106Wire.h" //Oled display from https://github.com/ThingPulse/esp8266-oled-ssd1306 +#ifdef ARDUINO_T_BEAM_S3_SUPREME +#include //PMU Library https://github.com/lewisxhe/XPowersLib.git +#endif #ifndef SENSOR_SDA #define SENSOR_SDA 17 @@ -44,15 +46,15 @@ #define SENSOR_SCL 18 #endif -#ifndef SENSOR_IRQ -#define SENSOR_IRQ -1 +#ifndef OLED_SDA +#define OLED_SDA 22 // Display Wire SDA Pin #endif +#ifndef OLED_SCL +#define OLED_SCL 21 // Display Wire SCL Pin +#endif -#define I2C1_SDA 22 //Display Wire SDA Pin -#define I2C1_SCL 21 //Display Wire SCL Pin - -SH1106Wire display(0x3c, I2C1_SDA, I2C1_SCL); +SH1106Wire display(0x3c, OLED_SDA, OLED_SCL); SensorQMC6310 qmc; int last_dx, last_dy, dx, dy, angle; @@ -84,14 +86,31 @@ void arrow(int x2, int y2, int x1, int y1, int alength, int awidth, OLEDDISPLAY_ display.drawLine(x2, y2, x4, y4); } + +void beginPower() +{ + // T_BEAM_S3_SUPREME The PMU voltage needs to be turned on to use the sensor +#if defined(ARDUINO_T_BEAM_S3_SUPREME) + XPowersAXP2101 power; + power.begin(Wire1, AXP2101_SLAVE_ADDRESS, 42, 41); + power.disableALDO1(); + power.disableALDO2(); + delay(250); + power.setALDO1Voltage(3300); + power.enableALDO1(); + power.setALDO2Voltage(3300); + power.enableALDO2(); +#endif +} + void setup() { Serial.begin(115200); while (!Serial); + beginPower(); - - if (!qmc.begin(Wire, QMC6310_SLAVE_ADDRESS, SENSOR_SDA, SENSOR_SCL)) { + if (!qmc.begin(Wire, SENSOR_SDA, SENSOR_SCL)) { Serial.println("Failed to find QMC6310 - check your wiring!"); while (1) { delay(1000); @@ -151,7 +170,7 @@ void setup() * * */ SensorQMC6310::DSR_1); - if (r != DEV_WIRE_NONE) { + if (r < 0) { Serial.println("Device config failed!"); while (1)delay(1000); } @@ -165,7 +184,7 @@ void setup() void loop() { - //Wiat data ready + //Wait data ready if (qmc.isDataReady()) { qmc.readData(); @@ -230,6 +249,6 @@ void setup() void loop() { - Serial.println("The graphics library may not be supported on the current platform"); delay(1000); + Serial.println("The graphics library may not be supported on the esp32 platform"); delay(1000); } #endif diff --git a/examples/QMC6310_GetDataExample/QMC6310_GetDataExample.ino b/examples/QMC6310_GetDataExample/QMC6310_GetDataExample.ino index 8d84cc9..dcb5ea0 100644 --- a/examples/QMC6310_GetDataExample/QMC6310_GetDataExample.ino +++ b/examples/QMC6310_GetDataExample/QMC6310_GetDataExample.ino @@ -31,6 +31,9 @@ #include #include #include "SensorQMC6310.hpp" +#ifdef ARDUINO_T_BEAM_S3_SUPREME +#include //PMU Library https://github.com/lewisxhe/XPowersLib.git +#endif #ifndef SENSOR_SDA #define SENSOR_SDA 17 @@ -40,20 +43,32 @@ #define SENSOR_SCL 18 #endif -#ifndef SENSOR_IRQ -#define SENSOR_IRQ -1 -#endif - SensorQMC6310 qmc; +void beginPower() +{ + // T_BEAM_S3_SUPREME The PMU voltage needs to be turned on to use the sensor +#if defined(ARDUINO_T_BEAM_S3_SUPREME) + XPowersAXP2101 power; + power.begin(Wire1, AXP2101_SLAVE_ADDRESS, 42, 41); + power.disableALDO1(); + power.disableALDO2(); + delay(250); + power.setALDO1Voltage(3300); + power.enableALDO1(); + power.setALDO2Voltage(3300); + power.enableALDO2(); +#endif +} + void setup() { Serial.begin(115200); while (!Serial); + beginPower(); - - if (!qmc.begin(Wire, QMC6310_SLAVE_ADDRESS, SENSOR_SDA, SENSOR_SCL)) { + if (!qmc.begin(Wire, SENSOR_SDA, SENSOR_SCL)) { Serial.println("Failed to find QMC6310 - check your wiring!"); while (1) { delay(1000); diff --git a/examples/QMC6310_GetPolarExample/QMC6310_GetPolarExample.ino b/examples/QMC6310_GetPolarExample/QMC6310_GetPolarExample.ino index ea9da61..7aa2023 100644 --- a/examples/QMC6310_GetPolarExample/QMC6310_GetPolarExample.ino +++ b/examples/QMC6310_GetPolarExample/QMC6310_GetPolarExample.ino @@ -31,6 +31,9 @@ #include #include #include "SensorQMC6310.hpp" +#ifdef ARDUINO_T_BEAM_S3_SUPREME +#include //PMU Library https://github.com/lewisxhe/XPowersLib.git +#endif #ifndef SENSOR_SDA #define SENSOR_SDA 17 @@ -40,20 +43,32 @@ #define SENSOR_SCL 18 #endif -#ifndef SENSOR_IRQ -#define SENSOR_IRQ -1 -#endif - SensorQMC6310 qmc; +void beginPower() +{ + // T_BEAM_S3_SUPREME The PMU voltage needs to be turned on to use the sensor +#if defined(ARDUINO_T_BEAM_S3_SUPREME) + XPowersAXP2101 power; + power.begin(Wire1, AXP2101_SLAVE_ADDRESS, 42, 41); + power.disableALDO1(); + power.disableALDO2(); + delay(250); + power.setALDO1Voltage(3300); + power.enableALDO1(); + power.setALDO2Voltage(3300); + power.enableALDO2(); +#endif +} + void setup() { Serial.begin(115200); while (!Serial); + beginPower(); - - if (!qmc.begin(Wire, QMC6310_SLAVE_ADDRESS, SENSOR_SDA, SENSOR_SCL)) { + if (!qmc.begin(Wire, SENSOR_SDA, SENSOR_SCL)) { Serial.println("Failed to find QMC6310 - check your wiring!"); while (1) { delay(1000); diff --git a/examples/QMI8658_BlockExample/QMI8658_BlockExample.ino b/examples/QMI8658_BlockExample/QMI8658_BlockExample.ino index 1916e04..53e0d4f 100644 --- a/examples/QMI8658_BlockExample/QMI8658_BlockExample.ino +++ b/examples/QMI8658_BlockExample/QMI8658_BlockExample.ino @@ -30,14 +30,18 @@ #include #include #include - #ifdef ARDUINO_ARCH_ESP32 #include "SensorQMI8658.hpp" #include //MadgwickAHRS from https://github.com/arduino-libraries/MadgwickAHRS #include "SH1106Wire.h" //Oled display from https://github.com/ThingPulse/esp8266-oled-ssd1306 +#ifdef ARDUINO_T_BEAM_S3_SUPREME +#include //PMU Library https://github.com/lewisxhe/XPowersLib.git +#endif + -// #define USE_WIRE +// #define USE_I2C //Using the I2C interface +#ifdef USE_I2C #ifndef SENSOR_SDA #define SENSOR_SDA 17 #endif @@ -46,74 +50,97 @@ #define SENSOR_SCL 18 #endif -#ifndef SENSOR_IRQ -#define SENSOR_IRQ -1 +#else /* SPI interface*/ + +#ifndef SPI_MOSI +#define SPI_MOSI (35) +#endif + +#ifndef SPI_SCK +#define SPI_SCK (36) +#endif + +#ifndef SPI_MISO +#define SPI_MISO (37) +#endif + +#endif /* USE_I2C*/ + +#ifndef IMU_CS +#define IMU_CS 34 // IMU CS PIN #endif -#define I2C1_SDA 22 //Display Wire SDA Pin -#define I2C1_SCL 21 //Display Wire SCL Pin +#ifndef IMU_IRQ +#define IMU_IRQ 33 // IMU INT PIN +#endif -SH1106Wire display(0x3c, I2C1_SDA, I2C1_SCL); +#ifndef OLED_SDA +#define OLED_SDA 22 // Display Wire SDA Pin +#endif +#ifndef OLED_SCL +#define OLED_SCL 21 // Display Wire SCL Pin +#endif + + +SH1106Wire display(0x3c, OLED_SDA, OLED_SCL); SensorQMI8658 qmi; IMUdata acc; IMUdata gyr; Madgwick filter; -unsigned long microsPerReading, microsPrevious; + float posX = 64; float posY = 32; float lastPosX = posX; float lastPosY = posY; +uint32_t microsPerReading, microsPrevious; +const uint8_t rectWidth = 10; + +void beginPower() +{ + // T_BEAM_S3_SUPREME The PMU voltage needs to be turned on to use the sensor +#if defined(ARDUINO_T_BEAM_S3_SUPREME) + XPowersAXP2101 power; + power.begin(Wire1, AXP2101_SLAVE_ADDRESS, 42, 41); + power.disableALDO1(); + power.disableALDO2(); + delay(250); + power.setALDO1Voltage(3300); + power.enableALDO1(); + power.setALDO2Voltage(3300); + power.enableALDO2(); +#endif +} void setup() { Serial.begin(115200); while (!Serial); - + beginPower(); display.init(); - -#ifdef USE_WIRE - //Using WIRE !! - if (!qmi.begin(Wire, QMI8658_L_SLAVE_ADDRESS, SENSOR_SDA, SENSOR_SCL)) { - Serial.println("Failed to find QMI8658 - check your wiring!"); - while (1) { - delay(1000); - } - } + bool ret = false; +#ifdef USE_I2C + ret = qmi.begin(Wire, QMI8658_L_SLAVE_ADDRESS, SENSOR_SDA, SENSOR_SCL); #else - -#ifndef CONFIG_IDF_TARGET_ESP32 -//Use LilyGo-T-Beam-S3 default spi pin -#define SPI_MOSI (35) -#define SPI_SCK (36) -#define SPI_MISO (37) -#define SPI_CS (47) -#define IMU_CS (34) -#define IMU_INT1 (33) //INTERRUPT PIN1 & PIN2 ,Use or logic to form a pin - - pinMode(SPI_CS, OUTPUT); //sdcard pin set high - digitalWrite(SPI_CS, HIGH); - if (!qmi.begin(IMU_CS, SPI_MOSI, SPI_MISO, SPI_SCK)) { - +#if defined(SPI_MOSI) && defined(SPI_SCK) && defined(SPI_MISO) + ret = qmi.begin(SPI, IMU_CS, SPI_MOSI, SPI_MISO, SPI_SCK); #else -//Use esp32dev module default spi pin -#define IMU_CS (5) -#define IMU_INT1 (15) -#define IMU_INT2 (22) - if (!qmi.begin(IMU_CS)) { + ret = qmi.begin(SPI, IMU_CS); #endif +#endif + + if (!ret) { Serial.println("Failed to find QMI8658 - check your wiring!"); while (1) { delay(1000); } } -#endif /* Get chip id*/ Serial.print("Device ID:"); @@ -205,11 +232,10 @@ void setup() Serial.println("Read data now..."); } -const uint8_t rectWidth = 10; void loop() { - float roll, pitch, heading; + float roll = 0, pitch = 0, heading = 0; // check if it's time to read data and update the filter if (micros() - microsPrevious >= microsPerReading) { @@ -256,7 +282,8 @@ void setup() void loop() { - Serial.println("The graphics library may not be supported on the current platform"); delay(1000); + Serial.println("The graphics library may not be supported on the esp32 platform"); + delay(1000); } #endif diff --git a/examples/QMI8658_CalibrationExample/QMI8658_CalibrationExample.ino b/examples/QMI8658_CalibrationExample/QMI8658_CalibrationExample.ino index 4affbb2..5f21fa3 100644 --- a/examples/QMI8658_CalibrationExample/QMI8658_CalibrationExample.ino +++ b/examples/QMI8658_CalibrationExample/QMI8658_CalibrationExample.ino @@ -31,11 +31,14 @@ #include #include #include "SensorQMI8658.hpp" +#ifdef ARDUINO_T_BEAM_S3_SUPREME +#include //PMU Library https://github.com/lewisxhe/XPowersLib.git +#endif -// #define USE_WIRE +// #define USE_I2C //Using the I2C interface -#if defined(USE_WIRE) +#ifdef USE_I2C #ifndef SENSOR_SDA #define SENSOR_SDA 17 #endif @@ -44,42 +47,58 @@ #define SENSOR_SCL 18 #endif -#ifndef SENSOR_IRQ -#define SENSOR_IRQ -1 -#endif - -#else +#else /*SPI interface*/ -//USE SPI #ifndef SPI_MOSI -#define SPI_MOSI (35) +#define SPI_MOSI (35) #endif #ifndef SPI_SCK -#define SPI_SCK (36) +#define SPI_SCK (36) #endif #ifndef SPI_MISO -#define SPI_MISO (37) +#define SPI_MISO (37) #endif +#endif /*USE_I2C*/ + #ifndef IMU_CS -#define IMU_CS (34) +#define IMU_CS 34 // IMU CS PIN +#endif + +#ifndef IMU_IRQ +#define IMU_IRQ 33 // IMU INT PIN #endif -#ifndef IMU_INT -#define IMU_INT (33) +#ifndef OLED_SDA +#define OLED_SDA 22 // Display Wire SDA Pin #endif +#ifndef OLED_SCL +#define OLED_SCL 21 // Display Wire SCL Pin #endif -SensorQMI8658 qmi; +SensorQMI8658 qmi; IMUdata acc; IMUdata gyr; +void beginPower() +{ + // T_BEAM_S3_SUPREME The PMU voltage needs to be turned on to use the sensor +#if defined(ARDUINO_T_BEAM_S3_SUPREME) + XPowersAXP2101 power; + power.begin(Wire1, AXP2101_SLAVE_ADDRESS, 42, 41); + power.disableALDO1(); + power.disableALDO2(); + delay(250); + power.setALDO1Voltage(3300); power.enableALDO1(); + power.setALDO2Voltage(3300); power.enableALDO2(); +#endif +} void setup() { @@ -89,22 +108,26 @@ void setup() delay(3000); -#ifdef USE_WIRE - //Using WIRE !! - if (!qmi.begin(Wire, QMI8658_L_SLAVE_ADDRESS, SENSOR_SDA, SENSOR_SCL)) { - Serial.println("Failed to find QMI8658 - check your wiring!"); - while (1) { - delay(1000); - } - } + beginPower(); + + + bool ret = false; +#ifdef USE_I2C + ret = qmi.begin(Wire, QMI8658_L_SLAVE_ADDRESS, SENSOR_SDA, SENSOR_SCL); +#else +#if defined(SPI_MOSI) && defined(SPI_SCK) && defined(SPI_MISO) + ret = qmi.begin(SPI, IMU_CS, SPI_MOSI, SPI_MISO, SPI_SCK); #else - if (!qmi.begin(IMU_CS, SPI_MOSI, SPI_MISO, SPI_SCK)) { + ret = qmi.begin(SPI, IMU_CS); +#endif +#endif + + if (!ret) { Serial.println("Failed to find QMI8658 - check your wiring!"); while (1) { delay(1000); } } -#endif /* Get chip id*/ Serial.print("Device ID:"); @@ -113,16 +136,16 @@ void setup() uint16_t gX_gain = 0, gY_gain = 0, gZ_gain = 0; // Call internal calibration to calibrate the sensor - bool result = false; + ret = false; - while (!result) { + while (!ret) { // Calibrate only once, do not obtain calibration value // result = qmi.calibration(); // Get the calibration value after calibration - result = qmi.calibration(&gX_gain, &gY_gain, &gZ_gain); - if (result) { + ret = qmi.calibration(&gX_gain, &gY_gain, &gZ_gain); + if (ret) { Serial.println("All calibrations are completed"); break; } @@ -141,8 +164,8 @@ void setup() Serial.print("Gyro-Z gain : "); Serial.println(gZ_gain); // The example only provides a method for writing calibration values - result = qmi.writeCalibration(gX_gain, gY_gain, gZ_gain); - if (result) { + ret = qmi.writeCalibration(gX_gain, gY_gain, gZ_gain); + if (ret) { Serial.println("Write calibrations successfully"); } else { Serial.println("Write calibrations failed!"); diff --git a/examples/QMI8658_GetDataExample/QMI8658_GetDataExample.ino b/examples/QMI8658_GetDataExample/QMI8658_GetDataExample.ino index 7d0d11e..c718324 100644 --- a/examples/QMI8658_GetDataExample/QMI8658_GetDataExample.ino +++ b/examples/QMI8658_GetDataExample/QMI8658_GetDataExample.ino @@ -31,11 +31,14 @@ #include #include #include "SensorQMI8658.hpp" +#ifdef ARDUINO_T_BEAM_S3_SUPREME +#include //PMU Library https://github.com/lewisxhe/XPowersLib.git +#endif -// #define USE_WIRE +// #define USE_I2C //Using the I2C interface -#if defined(USE_WIRE) +#ifdef USE_I2C #ifndef SENSOR_SDA #define SENSOR_SDA 17 #endif @@ -44,33 +47,36 @@ #define SENSOR_SCL 18 #endif -#ifndef SENSOR_IRQ -#define SENSOR_IRQ -1 -#endif - -#else +#else /* SPI interface*/ -//USE SPI #ifndef SPI_MOSI -#define SPI_MOSI (35) +#define SPI_MOSI (35) #endif #ifndef SPI_SCK -#define SPI_SCK (36) +#define SPI_SCK (36) #endif #ifndef SPI_MISO -#define SPI_MISO (37) +#define SPI_MISO (37) #endif +#endif /* USE_I2C*/ + #ifndef IMU_CS -#define IMU_CS (34) +#define IMU_CS 34 // IMU CS PIN #endif -#ifndef IMU_INT -#define IMU_INT (33) +#ifndef IMU_IRQ +#define IMU_IRQ 33 // IMU INT PIN #endif +#ifndef OLED_SDA +#define OLED_SDA 22 // Display Wire SDA Pin +#endif + +#ifndef OLED_SCL +#define OLED_SCL 21 // Display Wire SCL Pin #endif @@ -80,32 +86,44 @@ IMUdata acc; IMUdata gyr; +void beginPower() +{ + // T_BEAM_S3_SUPREME The PMU voltage needs to be turned on to use the sensor +#if defined(ARDUINO_T_BEAM_S3_SUPREME) + XPowersAXP2101 power; + power.begin(Wire1, AXP2101_SLAVE_ADDRESS, 42, 41); + power.disableALDO1(); + power.disableALDO2(); + delay(250); + power.setALDO1Voltage(3300); power.enableALDO1(); + power.setALDO2Voltage(3300); power.enableALDO2(); +#endif +} void setup() { Serial.begin(115200); while (!Serial); -#if IMU_INT > 0 - qmi.setPins(IMU_INT); -#endif + beginPower(); -#ifdef USE_WIRE - //Using WIRE !! - if (!qmi.begin(Wire, QMI8658_L_SLAVE_ADDRESS, SENSOR_SDA, SENSOR_SCL)) { - Serial.println("Failed to find QMI8658 - check your wiring!"); - while (1) { - delay(1000); - } - } + bool ret = false; +#ifdef USE_I2C + ret = qmi.begin(Wire, QMI8658_L_SLAVE_ADDRESS, SENSOR_SDA, SENSOR_SCL); #else - if (!qmi.begin(IMU_CS, SPI_MOSI, SPI_MISO, SPI_SCK)) { +#if defined(SPI_MOSI) && defined(SPI_SCK) && defined(SPI_MISO) + ret = qmi.begin(SPI, IMU_CS, SPI_MOSI, SPI_MISO, SPI_SCK); +#else + ret = qmi.begin(SPI, IMU_CS); +#endif +#endif + + if (!ret) { Serial.println("Failed to find QMI8658 - check your wiring!"); while (1) { delay(1000); } } -#endif /* Get chip id*/ Serial.print("Device ID:"); @@ -207,8 +225,8 @@ void setup() -#if IMU_INT > 0 - // If you want to enable interrupts, then turn on the interrupt enable +#if IMU_IRQ > 0 +// If you want to enable interrupts, then turn on the interrupt enable qmi.enableINT(SensorQMI8658::INTERRUPT_PIN_1, true); qmi.enableINT(SensorQMI8658::INTERRUPT_PIN_2, false); #endif diff --git a/examples/QMI8658_InterruptBlockExample/QMI8658_InterruptBlockExample.ino b/examples/QMI8658_InterruptBlockExample/QMI8658_InterruptBlockExample.ino index 0479897..c493723 100644 --- a/examples/QMI8658_InterruptBlockExample/QMI8658_InterruptBlockExample.ino +++ b/examples/QMI8658_InterruptBlockExample/QMI8658_InterruptBlockExample.ino @@ -34,9 +34,13 @@ #include "SensorQMI8658.hpp" #include //MadgwickAHRS from https://github.com/arduino-libraries/MadgwickAHRS #include "SH1106Wire.h" //Oled display from https://github.com/ThingPulse/esp8266-oled-ssd1306 +#ifdef ARDUINO_T_BEAM_S3_SUPREME +#include //PMU Library https://github.com/lewisxhe/XPowersLib.git +#endif -// #define USE_WIRE +// #define USE_I2C //Using the I2C interface +#ifdef USE_I2C #ifndef SENSOR_SDA #define SENSOR_SDA 17 #endif @@ -45,15 +49,40 @@ #define SENSOR_SCL 18 #endif -#ifndef SENSOR_IRQ -#define SENSOR_IRQ -1 +#else /*SPI interface*/ + +#ifndef SPI_MOSI +#define SPI_MOSI (35) +#endif + +#ifndef SPI_SCK +#define SPI_SCK (36) +#endif + +#ifndef SPI_MISO +#define SPI_MISO (37) +#endif + +#endif /*USE_I2C*/ + +#ifndef IMU_CS +#define IMU_CS 34 // IMU CS PIN +#endif + +#ifndef IMU_IRQ +#define IMU_IRQ 33 // IMU INT PIN +#endif + +#ifndef OLED_SDA +#define OLED_SDA 22 // Display Wire SDA Pin #endif +#ifndef OLED_SCL +#define OLED_SCL 21 // Display Wire SCL Pin +#endif -#define I2C1_SDA 22 //Display Wire SDA Pin -#define I2C1_SCL 21 //Display Wire SCL Pin -SH1106Wire display(0x3c, I2C1_SDA, I2C1_SCL); +SH1106Wire display(0x3c, OLED_SDA, OLED_SCL); SensorQMI8658 qmi; IMUdata acc; @@ -67,52 +96,49 @@ float posY = 32; float lastPosX = posX; float lastPosY = posY; + +void beginPower() +{ + // T_BEAM_S3_SUPREME The PMU voltage needs to be turned on to use the sensor +#if defined(ARDUINO_T_BEAM_S3_SUPREME) + XPowersAXP2101 power; + power.begin(Wire1, AXP2101_SLAVE_ADDRESS, 42, 41); + power.disableALDO1(); + power.disableALDO2(); + delay(250); + power.setALDO1Voltage(3300); power.enableALDO1(); + power.setALDO2Voltage(3300); power.enableALDO2(); +#endif +} + void setup() { Serial.begin(115200); while (!Serial); + beginPower(); display.init(); display.flipScreenVertically(); -#ifdef USE_WIRE - //Using WIRE !! - if (!qmi.begin(Wire, QMI8658_L_SLAVE_ADDRESS, SENSOR_SDA, SENSOR_SCL)) { - Serial.println("Failed to find QMI8658 - check your wiring!"); - while (1) { - delay(1000); - } - } + bool ret = false; +#ifdef USE_I2C + ret = qmi.begin(Wire, QMI8658_L_SLAVE_ADDRESS, SENSOR_SDA, SENSOR_SCL); #else - -#ifndef CONFIG_IDF_TARGET_ESP32 -//Use LilyGo-T-Beam-S3 default spi pin -#define SPI_MOSI (35) -#define SPI_SCK (36) -#define SPI_MISO (37) -#define SPI_CS (47) -#define IMU_CS (34) -#define IMU_INT1 (33) //INTERRUPT PIN1 & PIN2 ,Use or logic to form a pin - - pinMode(SPI_CS, OUTPUT); //sdcard pin set high - digitalWrite(SPI_CS, HIGH); - if (!qmi.begin(IMU_CS, SPI_MOSI, SPI_MISO, SPI_SCK)) { - +#if defined(SPI_MOSI) && defined(SPI_SCK) && defined(SPI_MISO) + ret = qmi.begin(SPI, IMU_CS, SPI_MOSI, SPI_MISO, SPI_SCK); #else -//Use esp32dev module default spi pin -#define IMU_CS (5) -#define IMU_INT1 (15) -#define IMU_INT2 (22) - if (!qmi.begin(IMU_CS)) { + ret = qmi.begin(SPI, IMU_CS); +#endif #endif + + if (!ret) { Serial.println("Failed to find QMI8658 - check your wiring!"); while (1) { delay(1000); } } -#endif /* Get chip id*/ Serial.print("Device ID:"); @@ -192,10 +218,7 @@ void setup() qmi.enableGyroscope(); qmi.enableAccelerometer(); - pinMode(IMU_INT1, INPUT); -#ifdef IMU_INT2 - pinMode(IMU_INT2, INPUT); -#endif + pinMode(IMU_IRQ, INPUT); // qmi.enableINT(SensorQMI8658::INTERRUPT_PIN_1); //no use // Enable data ready to interrupt pin2 @@ -225,7 +248,7 @@ void loop() if (micros() - microsPrevious >= microsPerReading) { // read raw data from IMU - if (digitalRead(IMU_INT1) == HIGH) { + if (digitalRead(IMU_IRQ) == HIGH) { qmi.getAccelerometer(acc.x, acc.y, acc.z); qmi.getGyroscope(gyr.x, gyr.y, gyr.z); @@ -266,7 +289,7 @@ void setup() void loop() { - Serial.println("The graphics library may not support your current platform"); delay(1000); + Serial.println("The graphics library may not support your esp32 platform"); delay(1000); } #endif diff --git a/examples/QMI8658_InterruptExample/QMI8658_InterruptExample.ino b/examples/QMI8658_InterruptExample/QMI8658_InterruptExample.ino index e07f21c..e2cc4dc 100644 --- a/examples/QMI8658_InterruptExample/QMI8658_InterruptExample.ino +++ b/examples/QMI8658_InterruptExample/QMI8658_InterruptExample.ino @@ -31,10 +31,14 @@ #include #include #include "SensorQMI8658.hpp" +#ifdef ARDUINO_T_BEAM_S3_SUPREME +#include //PMU Library https://github.com/lewisxhe/XPowersLib.git +#endif -// #define USE_WIRE +// #define USE_I2C //Using the I2C interface +#ifdef USE_I2C #ifndef SENSOR_SDA #define SENSOR_SDA 17 #endif @@ -43,58 +47,83 @@ #define SENSOR_SCL 18 #endif -#ifndef SENSOR_IRQ -#define SENSOR_IRQ -1 +#else /*SPI interface*/ + +#ifndef SPI_MOSI +#define SPI_MOSI (35) +#endif + +#ifndef SPI_SCK +#define SPI_SCK (36) +#endif + +#ifndef SPI_MISO +#define SPI_MISO (37) +#endif + +#endif /*USE_I2C*/ + +#ifndef IMU_CS +#define IMU_CS 34 // IMU CS PIN +#endif + +#ifndef IMU_IRQ +#define IMU_IRQ 33 // IMU INT PIN #endif +#ifndef OLED_SDA +#define OLED_SDA 22 // Display Wire SDA Pin +#endif + +#ifndef OLED_SCL +#define OLED_SCL 21 // Display Wire SCL Pin +#endif + +// #define IMU_IRQ2 -1 //QMI IRQ NUM2 + SensorQMI8658 qmi; IMUdata acc; IMUdata gyr; +void beginPower() +{ + // T_BEAM_S3_SUPREME The PMU voltage needs to be turned on to use the sensor +#if defined(ARDUINO_T_BEAM_S3_SUPREME) + XPowersAXP2101 power; + power.begin(Wire1, AXP2101_SLAVE_ADDRESS, 42, 41); + power.disableALDO1(); + power.disableALDO2(); + delay(250); + power.setALDO1Voltage(3300); power.enableALDO1(); + power.setALDO2Voltage(3300); power.enableALDO2(); +#endif +} + void setup() { Serial.begin(115200); while (!Serial); + beginPower(); - -#ifdef USE_WIRE - //Using WIRE !! - if (!qmi.begin(Wire, QMI8658_L_SLAVE_ADDRESS, SENSOR_SDA, SENSOR_SCL)) { - Serial.println("Failed to find QMI8658 - check your wiring!"); - while (1) { - delay(1000); - } - } + bool ret = false; +#ifdef USE_I2C + ret = qmi.begin(Wire, QMI8658_L_SLAVE_ADDRESS, SENSOR_SDA, SENSOR_SCL); #else - -#ifndef CONFIG_IDF_TARGET_ESP32 -//Use LilyGo-T-Beam-S3 default spi pin -#define SPI_MOSI (35) -#define SPI_SCK (36) -#define SPI_MISO (37) -#define SPI_CS (47) -#define IMU_CS (34) -#define IMU_INT1 (33) - - pinMode(SPI_CS, OUTPUT); //sdcard pin set high - digitalWrite(SPI_CS, HIGH); - if (!qmi.begin(IMU_CS, SPI_MOSI, SPI_MISO, SPI_SCK)) { - +#if defined(SPI_MOSI) && defined(SPI_SCK) && defined(SPI_MISO) + ret = qmi.begin(SPI, IMU_CS, SPI_MOSI, SPI_MISO, SPI_SCK); #else -//Use esp32dev module default spi pin -#define IMU_CS (5) -#define IMU_INT1 (15) -#define IMU_INT2 (22) - if (!qmi.begin(IMU_CS)) { + ret = qmi.begin(SPI, IMU_CS); #endif +#endif + + if (!ret) { Serial.println("Failed to find QMI8658 - check your wiring!"); while (1) { delay(1000); } } -#endif /* Get chip id*/ Serial.print("Device ID:"); @@ -174,11 +203,11 @@ void setup() qmi.enableAccelerometer(); - pinMode(IMU_INT1, INPUT); -#ifdef IMU_INT2 - pinMode(IMU_INT2, INPUT); -#endif + pinMode(IMU_IRQ, INPUT); +#ifdef IMU_IRQ2 + pinMode(IMU_IRQ2, INPUT); +#endif // qmi.enableINT(SensorQMI8658::INTERRUPT_PIN_1); //no use // Enable data ready to interrupt pin2 qmi.enableINT(SensorQMI8658::INTERRUPT_PIN_2); @@ -236,16 +265,15 @@ void readSensorData(const char *name) void loop() { - if (digitalRead(IMU_INT1) == HIGH) { + if (digitalRead(IMU_IRQ) == HIGH) { readSensorData("INT1"); } -#ifdef IMU_INT2 - if (digitalRead(IMU_INT2) == HIGH) { +#ifdef IMU_IRQ2 + if (digitalRead(IMU_IRQ2) == HIGH) { readSensorData("INT2"); } #endif - } diff --git a/examples/QMI8658_LockingMechanismExample/QMI8658_LockingMechanismExample.ino b/examples/QMI8658_LockingMechanismExample/QMI8658_LockingMechanismExample.ino index 861b0f3..d469e3c 100644 --- a/examples/QMI8658_LockingMechanismExample/QMI8658_LockingMechanismExample.ino +++ b/examples/QMI8658_LockingMechanismExample/QMI8658_LockingMechanismExample.ino @@ -31,9 +31,14 @@ #include #include #include "SensorQMI8658.hpp" +#ifdef ARDUINO_T_BEAM_S3_SUPREME +#include //PMU Library https://github.com/lewisxhe/XPowersLib.git +#endif + -// #define USE_WIRE +// #define USE_I2C //Using the I2C interface +#ifdef USE_I2C #ifndef SENSOR_SDA #define SENSOR_SDA 17 #endif @@ -42,8 +47,37 @@ #define SENSOR_SCL 18 #endif -#ifndef SENSOR_IRQ -#define SENSOR_IRQ -1 +#else /* SPI interface */ + +#ifndef SPI_MOSI +#define SPI_MOSI (35) +#endif + +#ifndef SPI_SCK +#define SPI_SCK (36) +#endif + +#ifndef SPI_MISO +#define SPI_MISO (37) +#endif + +#ifndef IMU_CS +#define IMU_CS 34 // IMU CS PIN +#endif + +#endif /* USE_I2C*/ + + +#ifndef IMU_IRQ +#define IMU_IRQ 33 // IMU INT PIN +#endif + +#ifndef OLED_SDA +#define OLED_SDA 22 // Display Wire SDA Pin +#endif + +#ifndef OLED_SCL +#define OLED_SCL 21 // Display Wire SCL Pin #endif SensorQMI8658 qmi; @@ -87,50 +121,45 @@ void lockingMechanismHandler() Serial.println("*C"); } + +void beginPower() +{ + // T_BEAM_S3_SUPREME The PMU voltage needs to be turned on to use the sensor +#if defined(ARDUINO_T_BEAM_S3_SUPREME) + XPowersAXP2101 power; + power.begin(Wire1, AXP2101_SLAVE_ADDRESS, 42, 41); + power.disableALDO1(); + power.disableALDO2(); + delay(250); + power.setALDO1Voltage(3300); power.enableALDO1(); + power.setALDO2Voltage(3300); power.enableALDO2(); +#endif +} + void setup() { Serial.begin(115200); while (!Serial); + beginPower(); - -#ifdef USE_WIRE - //Using WIRE !! - if (!qmi.begin(Wire, QMI8658_L_SLAVE_ADDRESS, SENSOR_SDA, SENSOR_SCL)) { - Serial.println("Failed to find QMI8658 - check your wiring!"); - while (1) { - delay(1000); - } - } + bool ret = false; +#ifdef USE_I2C + ret = qmi.begin(Wire, QMI8658_L_SLAVE_ADDRESS, SENSOR_SDA, SENSOR_SCL); #else - -#ifndef CONFIG_IDF_TARGET_ESP32 -//Use LilyGo-T-Beam-S3 default spi pin -#define SPI_MOSI (35) -#define SPI_SCK (36) -#define SPI_MISO (37) -#define SPI_CS (47) -#define IMU_CS (34) -#define IMU_INT1 (33) - - pinMode(SPI_CS, OUTPUT); //sdcard pin set high - digitalWrite(SPI_CS, HIGH); - if (!qmi.begin(IMU_CS, SPI_MOSI, SPI_MISO, SPI_SCK)) { - +#if defined(SPI_MOSI) && defined(SPI_SCK) && defined(SPI_MISO) + ret = qmi.begin(SPI, IMU_CS, SPI_MOSI, SPI_MISO, SPI_SCK); #else -//Use esp32dev module default spi pin -#define IMU_CS (5) -#define IMU_INT1 (15) -#define IMU_INT2 (22) - if (!qmi.begin(IMU_CS)) { + ret = qmi.begin(SPI, IMU_CS); +#endif #endif + + if (!ret) { Serial.println("Failed to find QMI8658 - check your wiring!"); while (1) { delay(1000); } } -#endif - /* Get chip id*/ Serial.print("Device ID:"); Serial.println(qmi.getChipID(), HEX); @@ -219,13 +248,9 @@ void setup() // Use interrupt . // QMI8658 interrupt always outputs low level by default, // and the interrupt is triggered when the rising edge - pinMode(IMU_INT1, INPUT_PULLUP); -#ifdef IMU_INT2 - pinMode(IMU_INT2, INPUT_PULLUP); - attachInterrupt(IMU_INT2, setFlag, RISING); -#else - attachInterrupt(IMU_INT1, setFlag, RISING); -#endif + pinMode(IMU_IRQ, INPUT_PULLUP); + + attachInterrupt(IMU_IRQ, setFlag, RISING); // qmi.enableINT(SensorQMI8658::INTERRUPT_PIN_1); //no use // Enable data ready to interrupt pin2 diff --git a/examples/QMI8658_MadgwickAHRS/QMI8658_MadgwickAHRS.ino b/examples/QMI8658_MadgwickAHRS/QMI8658_MadgwickAHRS.ino index 3ae42bd..3244e64 100644 --- a/examples/QMI8658_MadgwickAHRS/QMI8658_MadgwickAHRS.ino +++ b/examples/QMI8658_MadgwickAHRS/QMI8658_MadgwickAHRS.ino @@ -32,9 +32,14 @@ #include #include "SensorQMI8658.hpp" #include //MadgwickAHRS from https://github.com/arduino-libraries/MadgwickAHRS +#ifdef ARDUINO_T_BEAM_S3_SUPREME +#include //PMU Library https://github.com/lewisxhe/XPowersLib.git +#endif + -#define USE_WIRE +// #define USE_I2C //Using the I2C interface +#ifdef USE_I2C #ifndef SENSOR_SDA #define SENSOR_SDA 17 #endif @@ -43,11 +48,37 @@ #define SENSOR_SCL 18 #endif -#ifndef SENSOR_IRQ -#define SENSOR_IRQ -1 +#else /* SPI interface */ + +#ifndef SPI_MOSI +#define SPI_MOSI (35) +#endif + +#ifndef SPI_SCK +#define SPI_SCK (36) #endif -#define IMU_CS 5 +#ifndef SPI_MISO +#define SPI_MISO (37) +#endif + +#endif /* USE_I2C*/ + +#ifndef IMU_CS +#define IMU_CS 34 // IMU CS PIN +#endif + +#ifndef IMU_IRQ +#define IMU_IRQ 33 // IMU INT PIN +#endif + +#ifndef OLED_SDA +#define OLED_SDA 22 // Display Wire SDA Pin +#endif + +#ifndef OLED_SCL +#define OLED_SCL 21 // Display Wire SCL Pin +#endif SensorQMI8658 qmi; @@ -55,31 +86,50 @@ IMUdata acc; IMUdata gyr; Madgwick filter; -unsigned long microsPerReading, microsPrevious; +uint32_t microsPerReading, microsPrevious; + + +void beginPower() +{ + // T_BEAM_S3_SUPREME The PMU voltage needs to be turned on to use the sensor +#if defined(ARDUINO_T_BEAM_S3_SUPREME) + XPowersAXP2101 power; + power.begin(Wire1, AXP2101_SLAVE_ADDRESS, 42, 41); + power.disableALDO1(); + power.disableALDO2(); + delay(250); + power.setALDO1Voltage(3300); power.enableALDO1(); + power.setALDO2Voltage(3300); power.enableALDO2(); +#endif +} + void setup() { Serial.begin(115200); while (!Serial); + beginPower(); - -#ifdef USE_WIRE - //Using WIRE !! - if (!qmi.begin(Wire, QMI8658_L_SLAVE_ADDRESS, SENSOR_SDA, SENSOR_SCL)) { - Serial.println("Failed to find QMI8658 - check your wiring!"); - while (1) { - delay(1000); - } - } + bool ret = false; +#ifdef USE_I2C + ret = qmi.begin(Wire, QMI8658_L_SLAVE_ADDRESS, SENSOR_SDA, SENSOR_SCL); +#else +#if defined(SPI_MOSI) && defined(SPI_SCK) && defined(SPI_MISO) + ret = qmi.begin(SPI, IMU_CS, SPI_MOSI, SPI_MISO, SPI_SCK); #else - if (!qmi.begin(IMU_CS)) { + ret = qmi.begin(SPI, IMU_CS); +#endif +#endif + + if (!ret) { Serial.println("Failed to find QMI8658 - check your wiring!"); while (1) { delay(1000); } } -#endif + + /* Get chip id*/ Serial.print("Device ID:"); diff --git a/examples/QMI8658_MotionDetectionExample/QMI8658_MotionDetectionExample.ino b/examples/QMI8658_MotionDetectionExample/QMI8658_MotionDetectionExample.ino index 44eddbb..d40b196 100644 --- a/examples/QMI8658_MotionDetectionExample/QMI8658_MotionDetectionExample.ino +++ b/examples/QMI8658_MotionDetectionExample/QMI8658_MotionDetectionExample.ino @@ -31,11 +31,14 @@ #include #include #include "SensorQMI8658.hpp" +#ifdef ARDUINO_T_BEAM_S3_SUPREME +#include //PMU Library https://github.com/lewisxhe/XPowersLib.git +#endif -// #define USE_WIRE +// #define USE_I2C //Using the I2C interface -#if defined(USE_WIRE) +#ifdef USE_I2C #ifndef SENSOR_SDA #define SENSOR_SDA 17 #endif @@ -44,37 +47,55 @@ #define SENSOR_SCL 18 #endif -#ifndef SENSOR_IRQ -#define SENSOR_IRQ -1 -#endif - -#else +#else /* SPI interface */ -//USE SPI #ifndef SPI_MOSI -#define SPI_MOSI (35) +#define SPI_MOSI (35) #endif #ifndef SPI_SCK -#define SPI_SCK (36) +#define SPI_SCK (36) #endif #ifndef SPI_MISO -#define SPI_MISO (37) +#define SPI_MISO (37) #endif #ifndef IMU_CS -#define IMU_CS (34) +#define IMU_CS 34 // IMU CS PIN +#endif + +#endif /* USE_I2C*/ + + +#ifndef IMU_IRQ +#define IMU_IRQ 33 // IMU INT PIN #endif -#ifndef IMU_INT -#define IMU_INT (33) +#ifndef OLED_SDA +#define OLED_SDA 22 // Display Wire SDA Pin #endif +#ifndef OLED_SCL +#define OLED_SCL 21 // Display Wire SCL Pin #endif + SensorQMI8658 qmi; +void beginPower() +{ + // T_BEAM_S3_SUPREME The PMU voltage needs to be turned on to use the sensor +#if defined(ARDUINO_T_BEAM_S3_SUPREME) + XPowersAXP2101 power; + power.begin(Wire1, AXP2101_SLAVE_ADDRESS, 42, 41); + power.disableALDO1(); + power.disableALDO2(); + delay(250); + power.setALDO1Voltage(3300); power.enableALDO1(); + power.setALDO2Voltage(3300); power.enableALDO2(); +#endif +} bool interruptFlag = false; @@ -88,26 +109,25 @@ void setup() Serial.begin(115200); while (!Serial); -#if IMU_INT > 0 - qmi.setPins(IMU_INT); -#endif + beginPower(); -#ifdef USE_WIRE - //Using WIRE !! - if (!qmi.begin(Wire, QMI8658_L_SLAVE_ADDRESS, SENSOR_SDA, SENSOR_SCL)) { - Serial.println("Failed to find QMI8658 - check your wiring!"); - while (1) { - delay(1000); - } - } + bool ret = false; +#ifdef USE_I2C + ret = qmi.begin(Wire, QMI8658_L_SLAVE_ADDRESS, SENSOR_SDA, SENSOR_SCL); #else - if (!qmi.begin(IMU_CS, SPI_MOSI, SPI_MISO, SPI_SCK)) { +#if defined(SPI_MOSI) && defined(SPI_SCK) && defined(SPI_MISO) + ret = qmi.begin(SPI, IMU_CS, SPI_MOSI, SPI_MISO, SPI_SCK); +#else + ret = qmi.begin(SPI, IMU_CS); +#endif +#endif + + if (!ret) { Serial.println("Failed to find QMI8658 - check your wiring!"); while (1) { delay(1000); } } -#endif /* Get chip id*/ Serial.print("Device ID:"); @@ -169,7 +189,7 @@ void setup() * When the QMI8658 is configured as Wom, the interrupt level is arbitrary, * not absolute high or low, and it is in the jump transition state */ - attachInterrupt(IMU_INT, setFlag, CHANGE); + attachInterrupt(IMU_IRQ, setFlag, CHANGE); } diff --git a/examples/QMI8658_PedometerExample/QMI8658_PedometerExample.ino b/examples/QMI8658_PedometerExample/QMI8658_PedometerExample.ino index 897532f..a070337 100644 --- a/examples/QMI8658_PedometerExample/QMI8658_PedometerExample.ino +++ b/examples/QMI8658_PedometerExample/QMI8658_PedometerExample.ino @@ -31,11 +31,14 @@ #include #include #include "SensorQMI8658.hpp" +#ifdef ARDUINO_T_BEAM_S3_SUPREME +#include //PMU Library https://github.com/lewisxhe/XPowersLib.git +#endif -// #define USE_WIRE +// #define USE_I2C //Using the I2C interface -#if defined(USE_WIRE) +#ifdef USE_I2C #ifndef SENSOR_SDA #define SENSOR_SDA 17 #endif @@ -44,39 +47,57 @@ #define SENSOR_SCL 18 #endif -#ifndef SENSOR_IRQ -#define SENSOR_IRQ -1 -#endif - -#else +#else /* SPI interface */ -//USE SPI #ifndef SPI_MOSI -#define SPI_MOSI (35) +#define SPI_MOSI (35) #endif #ifndef SPI_SCK -#define SPI_SCK (36) +#define SPI_SCK (36) #endif #ifndef SPI_MISO -#define SPI_MISO (37) +#define SPI_MISO (37) #endif +#endif /* USE_I2C*/ + #ifndef IMU_CS -#define IMU_CS (34) +#define IMU_CS 34 // IMU CS PIN +#endif + +#ifndef IMU_IRQ +#define IMU_IRQ 33 // IMU INT PIN #endif -#ifndef IMU_INT -#define IMU_INT (33) +#ifndef OLED_SDA +#define OLED_SDA 22 // Display Wire SDA Pin #endif +#ifndef OLED_SCL +#define OLED_SCL 21 // Display Wire SCL Pin #endif SensorQMI8658 qmi; bool interruptFlag = false; + +void beginPower() +{ + // T_BEAM_S3_SUPREME The PMU voltage needs to be turned on to use the sensor +#if defined(ARDUINO_T_BEAM_S3_SUPREME) + XPowersAXP2101 power; + power.begin(Wire1, AXP2101_SLAVE_ADDRESS, 42, 41); + power.disableALDO1(); + power.disableALDO2(); + delay(250); + power.setALDO1Voltage(3300); power.enableALDO1(); + power.setALDO2Voltage(3300); power.enableALDO2(); +#endif +} + void setFlag(void) { interruptFlag = true; @@ -95,26 +116,25 @@ void setup() Serial.begin(115200); while (!Serial); -#if IMU_INT > 0 - qmi.setPins(IMU_INT); -#endif + beginPower(); -#ifdef USE_WIRE - //Using WIRE !! - if (!qmi.begin(Wire, QMI8658_L_SLAVE_ADDRESS, SENSOR_SDA, SENSOR_SCL)) { - Serial.println("Failed to find QMI8658 - check your wiring!"); - while (1) { - delay(1000); - } - } + bool ret = false; +#ifdef USE_I2C + ret = qmi.begin(Wire, QMI8658_L_SLAVE_ADDRESS, SENSOR_SDA, SENSOR_SCL); #else - if (!qmi.begin(IMU_CS, SPI_MOSI, SPI_MISO, SPI_SCK)) { +#if defined(SPI_MOSI) && defined(SPI_SCK) && defined(SPI_MISO) + ret = qmi.begin(SPI, IMU_CS, SPI_MOSI, SPI_MISO, SPI_SCK); +#else + ret = qmi.begin(SPI, IMU_CS); +#endif +#endif + + if (!ret) { Serial.println("Failed to find QMI8658 - check your wiring!"); while (1) { delay(1000); } } -#endif /* Get chip id*/ Serial.print("Device ID:"); @@ -171,7 +191,7 @@ void setup() * When the QMI8658 is configured as Wom, the interrupt level is arbitrary, * not absolute high or low, and it is in the jump transition state */ - attachInterrupt(IMU_INT, setFlag, CHANGE); + attachInterrupt(IMU_IRQ, setFlag, CHANGE); } diff --git a/examples/QMI8658_ReadFromFifoExample/QMI8658_ReadFromFifoExample.ino b/examples/QMI8658_ReadFromFifoExample/QMI8658_ReadFromFifoExample.ino index 4d65d5c..3e6b5ff 100644 --- a/examples/QMI8658_ReadFromFifoExample/QMI8658_ReadFromFifoExample.ino +++ b/examples/QMI8658_ReadFromFifoExample/QMI8658_ReadFromFifoExample.ino @@ -31,11 +31,14 @@ #include #include #include "SensorQMI8658.hpp" +#ifdef ARDUINO_T_BEAM_S3_SUPREME +#include //PMU Library https://github.com/lewisxhe/XPowersLib.git +#endif -// #define USE_WIRE +// #define USE_I2C //Using the I2C interface -#if defined(USE_WIRE) +#ifdef USE_I2C #ifndef SENSOR_SDA #define SENSOR_SDA 17 #endif @@ -44,33 +47,37 @@ #define SENSOR_SCL 18 #endif -#ifndef SENSOR_IRQ -#define SENSOR_IRQ -1 -#endif - -#else +#else /* SPI interface */ -//USE SPI #ifndef SPI_MOSI -#define SPI_MOSI (35) +#define SPI_MOSI (35) #endif #ifndef SPI_SCK -#define SPI_SCK (36) +#define SPI_SCK (36) #endif #ifndef SPI_MISO -#define SPI_MISO (37) +#define SPI_MISO (37) #endif #ifndef IMU_CS -#define IMU_CS (34) +#define IMU_CS 34 // IMU CS PIN +#endif + +#endif /* USE_I2C*/ + + +#ifndef IMU_IRQ +#define IMU_IRQ 33 // IMU INT PIN #endif -#ifndef IMU_INT -#define IMU_INT (33) +#ifndef OLED_SDA +#define OLED_SDA 22 // Display Wire SDA Pin #endif +#ifndef OLED_SCL +#define OLED_SCL 21 // Display Wire SCL Pin #endif @@ -82,31 +89,46 @@ IMUdata gyro[buffer_size]; bool disable_fifo = false; uint32_t timestamp = 0; +void beginPower() +{ + // T_BEAM_S3_SUPREME The PMU voltage needs to be turned on to use the sensor +#if defined(ARDUINO_T_BEAM_S3_SUPREME) + XPowersAXP2101 power; + power.begin(Wire1, AXP2101_SLAVE_ADDRESS, 42, 41); + power.disableALDO1(); + power.disableALDO2(); + delay(250); + power.setALDO1Voltage(3300); power.enableALDO1(); + power.setALDO2Voltage(3300); power.enableALDO2(); +#endif +} void setup() { Serial.begin(115200); while (!Serial); -#if IMU_INT > 0 - qmi.setPins(IMU_INT); -#endif + beginPower(); -#ifdef USE_WIRE - if (!qmi.begin(Wire, QMI8658_L_SLAVE_ADDRESS, SENSOR_SDA, SENSOR_SCL)) { - Serial.println("Failed to find QMI8658 - check your wiring!"); - while (1) { - delay(1000); - } - } + beginPower(); + + bool ret = false; +#ifdef USE_I2C + ret = qmi.begin(Wire, QMI8658_L_SLAVE_ADDRESS, SENSOR_SDA, SENSOR_SCL); #else - if (!qmi.begin(IMU_CS, SPI_MOSI, SPI_MISO, SPI_SCK)) { +#if defined(SPI_MOSI) && defined(SPI_SCK) && defined(SPI_MISO) + ret = qmi.begin(SPI, IMU_CS, SPI_MOSI, SPI_MISO, SPI_SCK); +#else + ret = qmi.begin(SPI, IMU_CS); +#endif +#endif + + if (!ret) { Serial.println("Failed to find QMI8658 - check your wiring!"); while (1) { delay(1000); } } -#endif /* * Get chip id @@ -222,8 +244,8 @@ void setup() -#if IMU_INT > 0 - // If you want to enable interrupts, then turn on the interrupt enable +#if IMU_IRQ > 0 +// If you want to enable interrupts, then turn on the interrupt enable qmi.enableINT(SensorQMI8658::INTERRUPT_PIN_1, true); qmi.enableINT(SensorQMI8658::INTERRUPT_PIN_2, false); #endif diff --git a/examples/QMI8658_TapDetectionExample/QMI8658_TapDetectionExample.ino b/examples/QMI8658_TapDetectionExample/QMI8658_TapDetectionExample.ino index 790da9d..3c8245d 100644 --- a/examples/QMI8658_TapDetectionExample/QMI8658_TapDetectionExample.ino +++ b/examples/QMI8658_TapDetectionExample/QMI8658_TapDetectionExample.ino @@ -31,11 +31,14 @@ #include #include #include "SensorQMI8658.hpp" +#ifdef ARDUINO_T_BEAM_S3_SUPREME +#include //PMU Library https://github.com/lewisxhe/XPowersLib.git +#endif -// #define USE_WIRE +// #define USE_I2C //Using the I2C interface -#if defined(USE_WIRE) +#ifdef USE_I2C #ifndef SENSOR_SDA #define SENSOR_SDA 17 #endif @@ -44,33 +47,37 @@ #define SENSOR_SCL 18 #endif -#ifndef SENSOR_IRQ -#define SENSOR_IRQ -1 -#endif - -#else +#else /* SPI interface */ -//USE SPI #ifndef SPI_MOSI -#define SPI_MOSI (35) +#define SPI_MOSI (35) #endif #ifndef SPI_SCK -#define SPI_SCK (36) +#define SPI_SCK (36) #endif #ifndef SPI_MISO -#define SPI_MISO (37) +#define SPI_MISO (37) #endif #ifndef IMU_CS -#define IMU_CS (34) +#define IMU_CS 34 // IMU CS PIN +#endif + +#endif /* USE_I2C*/ + + +#ifndef IMU_IRQ +#define IMU_IRQ 33 // IMU INT PIN #endif -#ifndef IMU_INT -#define IMU_INT (33) +#ifndef OLED_SDA +#define OLED_SDA 22 // Display Wire SDA Pin #endif +#ifndef OLED_SCL +#define OLED_SCL 21 // Display Wire SCL Pin #endif SensorQMI8658 qmi; @@ -84,6 +91,20 @@ void setFlag(void) } +void beginPower() +{ + // T_BEAM_S3_SUPREME The PMU voltage needs to be turned on to use the sensor +#if defined(ARDUINO_T_BEAM_S3_SUPREME) + XPowersAXP2101 power; + power.begin(Wire1, AXP2101_SLAVE_ADDRESS, 42, 41); + power.disableALDO1(); + power.disableALDO2(); + delay(250); + power.setALDO1Voltage(3300); power.enableALDO1(); + power.setALDO2Voltage(3300); power.enableALDO2(); +#endif +} + void tapEventCallback() { SensorQMI8658::TapEvent event = qmi.getTapStatus(); @@ -104,26 +125,25 @@ void setup() Serial.begin(115200); while (!Serial); -#if IMU_INT > 0 - qmi.setPins(IMU_INT); -#endif + beginPower(); -#ifdef USE_WIRE - //Using WIRE !! - if (!qmi.begin(Wire, QMI8658_L_SLAVE_ADDRESS, SENSOR_SDA, SENSOR_SCL)) { - Serial.println("Failed to find QMI8658 - check your wiring!"); - while (1) { - delay(1000); - } - } + bool ret = false; +#ifdef USE_I2C + ret = qmi.begin(Wire, QMI8658_L_SLAVE_ADDRESS, SENSOR_SDA, SENSOR_SCL); #else - if (!qmi.begin(IMU_CS, SPI_MOSI, SPI_MISO, SPI_SCK)) { +#if defined(SPI_MOSI) && defined(SPI_SCK) && defined(SPI_MISO) + ret = qmi.begin(SPI, IMU_CS, SPI_MOSI, SPI_MISO, SPI_SCK); +#else + ret = qmi.begin(SPI, IMU_CS); +#endif +#endif + + if (!ret) { Serial.println("Failed to find QMI8658 - check your wiring!"); while (1) { delay(1000); } } -#endif /* Get chip id*/ Serial.print("Device ID:"); @@ -193,7 +213,7 @@ void setup() * When the QMI8658 is configured as Wom, the interrupt level is arbitrary, * not absolute high or low, and it is in the jump transition state */ - attachInterrupt(IMU_INT, setFlag, CHANGE); + attachInterrupt(IMU_IRQ, setFlag, CHANGE); } diff --git a/examples/QMI8658_WakeOnMotion/QMI8658_WakeOnMotion.ino b/examples/QMI8658_WakeOnMotion/QMI8658_WakeOnMotion.ino index 752b143..c38cfc8 100644 --- a/examples/QMI8658_WakeOnMotion/QMI8658_WakeOnMotion.ino +++ b/examples/QMI8658_WakeOnMotion/QMI8658_WakeOnMotion.ino @@ -31,9 +31,14 @@ #include #include #include "SensorQMI8658.hpp" +#ifdef ARDUINO_T_BEAM_S3_SUPREME +#include //PMU Library https://github.com/lewisxhe/XPowersLib.git +#endif + -// #define USE_WIRE +// #define USE_I2C //Using the I2C interface +#ifdef USE_I2C #ifndef SENSOR_SDA #define SENSOR_SDA 17 #endif @@ -42,8 +47,37 @@ #define SENSOR_SCL 18 #endif -#ifndef SENSOR_IRQ -#define SENSOR_IRQ -1 +#else /* SPI interface */ + +#ifndef SPI_MOSI +#define SPI_MOSI (35) +#endif + +#ifndef SPI_SCK +#define SPI_SCK (36) +#endif + +#ifndef SPI_MISO +#define SPI_MISO (37) +#endif + +#ifndef IMU_CS +#define IMU_CS 34 // IMU CS PIN +#endif + +#endif /* USE_I2C*/ + + +#ifndef IMU_IRQ +#define IMU_IRQ 33 // IMU INT PIN +#endif + +#ifndef OLED_SDA +#define OLED_SDA 22 // Display Wire SDA Pin +#endif + +#ifndef OLED_SCL +#define OLED_SCL 21 // Display Wire SCL Pin #endif @@ -61,49 +95,44 @@ void setFlag(void) } +void beginPower() +{ + // T_BEAM_S3_SUPREME The PMU voltage needs to be turned on to use the sensor +#if defined(ARDUINO_T_BEAM_S3_SUPREME) + XPowersAXP2101 power; + power.begin(Wire1, AXP2101_SLAVE_ADDRESS, 42, 41); + power.disableALDO1(); + power.disableALDO2(); + delay(250); + power.setALDO1Voltage(3300); power.enableALDO1(); + power.setALDO2Voltage(3300); power.enableALDO2(); +#endif +} + void setup() { Serial.begin(115200); while (!Serial); + beginPower(); - -#ifdef USE_WIRE - //Using WIRE !! - if (!qmi.begin(Wire, QMI8658_L_SLAVE_ADDRESS, SENSOR_SDA, SENSOR_SCL)) { - Serial.println("Failed to find QMI8658 - check your wiring!"); - while (1) { - delay(1000); - } - } + bool ret = false; +#ifdef USE_I2C + ret = qmi.begin(Wire, QMI8658_L_SLAVE_ADDRESS, SENSOR_SDA, SENSOR_SCL); #else - -#ifndef CONFIG_IDF_TARGET_ESP32 - //Use LilyGo-T-Beam-S3 default spi pinz -#define SPI_MOSI (35) -#define SPI_SCK (36) -#define SPI_MISO (37) -#define SPI_CS (47) -#define IMU_CS (34) -#define IMU_INT1 (33) //INTERRUPT PIN1 & PIN2 ,Use or logic to form a pin - - pinMode(SPI_CS, OUTPUT); //sdcard pin set high - digitalWrite(SPI_CS, HIGH); - if (!qmi.begin(IMU_CS, SPI_MOSI, SPI_MISO, SPI_SCK)) { - +#if defined(SPI_MOSI) && defined(SPI_SCK) && defined(SPI_MISO) + ret = qmi.begin(SPI, IMU_CS, SPI_MOSI, SPI_MISO, SPI_SCK); #else -//Use esp32dev module default spi pin -#define IMU_CS (5) -#define IMU_INT1 (15) -#define IMU_INT2 (22) - if (!qmi.begin(IMU_CS)) { + ret = qmi.begin(SPI, IMU_CS); +#endif #endif + + if (!ret) { Serial.println("Failed to find QMI8658 - check your wiring!"); while (1) { delay(1000); } } -#endif /* Get chip id*/ Serial.print("Device ID:"); @@ -117,14 +146,9 @@ void setup() * When the QMI8658 is configured as Wom, the interrupt level is arbitrary, * not absolute high or low, and it is in the jump transition state */ - pinMode(IMU_INT1, INPUT_PULLUP); -#ifdef IMU_INT2 - pinMode(IMU_INT2, INPUT_PULLUP); - attachInterrupt(IMU_INT2, setFlag, CHANGE); -#else - attachInterrupt(IMU_INT1, setFlag, CHANGE); -#endif + pinMode(IMU_IRQ, INPUT_PULLUP); + attachInterrupt(IMU_IRQ, setFlag, CHANGE); // Print register configuration information qmi.dumpCtrlRegister(); diff --git a/examples/QMI8658_WakeOnMotionCallBackExample/QMI8658_WakeOnMotionCallBackExample.ino b/examples/QMI8658_WakeOnMotionCallBackExample/QMI8658_WakeOnMotionCallBackExample.ino index 17ef258..300e688 100644 --- a/examples/QMI8658_WakeOnMotionCallBackExample/QMI8658_WakeOnMotionCallBackExample.ino +++ b/examples/QMI8658_WakeOnMotionCallBackExample/QMI8658_WakeOnMotionCallBackExample.ino @@ -31,9 +31,14 @@ #include #include #include "SensorQMI8658.hpp" +#ifdef ARDUINO_T_BEAM_S3_SUPREME +#include //PMU Library https://github.com/lewisxhe/XPowersLib.git +#endif + -// #define USE_WIRE +// #define USE_I2C //Using the I2C interface +#ifdef USE_I2C #ifndef SENSOR_SDA #define SENSOR_SDA 17 #endif @@ -42,8 +47,37 @@ #define SENSOR_SCL 18 #endif -#ifndef SENSOR_IRQ -#define SENSOR_IRQ -1 +#else /* SPI interface */ + +#ifndef SPI_MOSI +#define SPI_MOSI (35) +#endif + +#ifndef SPI_SCK +#define SPI_SCK (36) +#endif + +#ifndef SPI_MISO +#define SPI_MISO (37) +#endif + +#ifndef IMU_CS +#define IMU_CS 34 // IMU CS PIN +#endif + +#endif /* USE_I2C*/ + + +#ifndef IMU_IRQ +#define IMU_IRQ 33 // IMU INT PIN +#endif + +#ifndef OLED_SDA +#define OLED_SDA 22 // Display Wire SDA Pin +#endif + +#ifndef OLED_SCL +#define OLED_SCL 21 // Display Wire SCL Pin #endif @@ -65,50 +99,44 @@ void wakeUp() Serial.println("Awake!"); } +void beginPower() +{ + // T_BEAM_S3_SUPREME The PMU voltage needs to be turned on to use the sensor +#if defined(ARDUINO_T_BEAM_S3_SUPREME) + XPowersAXP2101 power; + power.begin(Wire1, AXP2101_SLAVE_ADDRESS, 42, 41); + power.disableALDO1(); + power.disableALDO2(); + delay(250); + power.setALDO1Voltage(3300); power.enableALDO1(); + power.setALDO2Voltage(3300); power.enableALDO2(); +#endif +} void setup() { Serial.begin(115200); while (!Serial); + beginPower(); - -#ifdef USE_WIRE - //Using WIRE !! - if (!qmi.begin(Wire, QMI8658_L_SLAVE_ADDRESS, SENSOR_SDA, SENSOR_SCL)) { - Serial.println("Failed to find QMI8658 - check your wiring!"); - while (1) { - delay(1000); - } - } + bool ret = false; +#ifdef USE_I2C + ret = qmi.begin(Wire, QMI8658_L_SLAVE_ADDRESS, SENSOR_SDA, SENSOR_SCL); #else - -#ifndef CONFIG_IDF_TARGET_ESP32 - //Use LilyGo-T-Beam-S3 default spi pinz -#define SPI_MOSI (35) -#define SPI_SCK (36) -#define SPI_MISO (37) -#define SPI_CS (47) -#define IMU_CS (34) -#define IMU_INT1 (33) //INTERRUPT PIN1 & PIN2 ,Use or logic to form a pin - - pinMode(SPI_CS, OUTPUT); //sdcard pin set high - digitalWrite(SPI_CS, HIGH); - if (!qmi.begin(IMU_CS, SPI_MOSI, SPI_MISO, SPI_SCK)) { - +#if defined(SPI_MOSI) && defined(SPI_SCK) && defined(SPI_MISO) + ret = qmi.begin(SPI, IMU_CS, SPI_MOSI, SPI_MISO, SPI_SCK); #else -//Use esp32dev module default spi pin -#define IMU_CS (5) -#define IMU_INT1 (15) -#define IMU_INT2 (22) - if (!qmi.begin(IMU_CS)) { + ret = qmi.begin(SPI, IMU_CS); +#endif #endif + + if (!ret) { Serial.println("Failed to find QMI8658 - check your wiring!"); while (1) { delay(1000); } } -#endif /* Get chip id*/ Serial.print("Device ID:"); @@ -125,14 +153,8 @@ void setup() * When the QMI8658 is configured as Wom, the interrupt level is arbitrary, * not absolute high or low, and it is in the jump transition state */ - pinMode(IMU_INT1, INPUT_PULLUP); -#ifdef IMU_INT2 - pinMode(IMU_INT2, INPUT_PULLUP); - attachInterrupt(IMU_INT2, setFlag, CHANGE); -#else - attachInterrupt(IMU_INT1, setFlag, CHANGE); -#endif - + pinMode(IMU_IRQ, INPUT_PULLUP); + attachInterrupt(IMU_IRQ, setFlag, CHANGE); // Print register configuration information qmi.dumpCtrlRegister(); @@ -141,7 +163,6 @@ void setup() void loop() { - if (interruptFlag) { interruptFlag = false; qmi.update(); diff --git a/examples/TouchDrv_Interface_T_RGB/TouchDrv_Interface_T_RGB.ino b/examples/TouchDrvInterface_Example/TouchDrvInterface_Example.ino similarity index 62% rename from examples/TouchDrv_Interface_T_RGB/TouchDrv_Interface_T_RGB.ino rename to examples/TouchDrvInterface_Example/TouchDrvInterface_Example.ino index e2def18..3c325c8 100644 --- a/examples/TouchDrv_Interface_T_RGB/TouchDrv_Interface_T_RGB.ino +++ b/examples/TouchDrvInterface_Example/TouchDrvInterface_Example.ino @@ -2,7 +2,7 @@ * * @license MIT License * - * Copyright (c) 2024 lewis he + * Copyright (c) 2025 lewis he * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -22,49 +22,47 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. * - * @file TouchDrv_LilyGo_T_RGB.ino + * @file TouchDrvInterface_Example.ino * @author Lewis He (lewishe@outlook.com) - * @date 2024-01-21 - * @note T-RGB has three types of screens, each of which uses different touch driver chips. + * @date 2025-01-20 + * @note TouchDrvInterface_Example use LilyGo T-RGB,T-RGB has three types of screens, each of which uses different touch driver chips. * The example demonstrates using the touch interface class and one sketch is suitable for three types of touch chips. */ #include #include #include -#include "ExtensionIOXL9555.hpp" -#include "TouchDrvGT911.hpp" #include "TouchDrvFT6X36.hpp" #include "TouchDrvCSTXXX.hpp" +#include "TouchDrvGT911.hpp" +#include "ExtensionIOXL9555.hpp" +#include "SensorWireHelper.h" - - -#ifndef SENSOR_SDA -#define SENSOR_SDA 8 +#ifndef TOUCH_SDA +#define TOUCH_SDA 8 #endif -#ifndef SENSOR_SCL -#define SENSOR_SCL 48 +#ifndef TOUCH_SCL +#define TOUCH_SCL 48 #endif -#ifndef SENSOR_IRQ -#define SENSOR_IRQ 1 //ESP32S3 GPIO1 +#ifndef TOUCH_IRQ +#define TOUCH_IRQ 1 #endif -#ifndef SENSOR_RST -#define SENSOR_RST 1 //XL9555 GPIO1 +#ifndef TOUCH_RST +#define TOUCH_RST 1 #endif -TouchDrvInterface *touchDrv = NULL; +// Use the TouchDrvInterface base class for automatic discovery and use of multi-touch devices +TouchDrvInterface *touchDrv; +// T-RGB uses XL9555 as the reset control of the touch screen ExtensionIOXL9555 extension; -ExtensionIOXL9555::ExtensionGPIO tp_reset = ExtensionIOXL9555::IO1; -ExtensionIOXL9555::ExtensionGPIO power_enable = ExtensionIOXL9555::IO2; - int16_t x[5], y[5]; +ExtensionIOXL9555::ExtensionGPIO tp_reset = ExtensionIOXL9555::IO1; -//GPIO callback function -void TouchDrvDigitalWrite(uint32_t gpio, uint8_t level) +void TouchDrvDigitalWrite(uint8_t gpio, uint8_t level) { if (gpio & 0x80) { extension.digitalWrite(gpio & 0x7F, level); @@ -73,8 +71,7 @@ void TouchDrvDigitalWrite(uint32_t gpio, uint8_t level) } } -//GPIO callback function -int TouchDrvDigitalRead(uint32_t gpio) +uint8_t TouchDrvDigitalRead(uint8_t gpio) { if (gpio & 0x80) { return extension.digitalRead(gpio & 0x7F); @@ -83,8 +80,7 @@ int TouchDrvDigitalRead(uint32_t gpio) } } -//GPIO callback function -void TouchDrvPinMode(uint32_t gpio, uint8_t mode) +void TouchDrvPinMode(uint8_t gpio, uint8_t mode) { if (gpio & 0x80) { extension.pinMode(gpio & 0x7F, mode); @@ -93,50 +89,52 @@ void TouchDrvPinMode(uint32_t gpio, uint8_t mode) } } - bool setupTouchDrv() { - //Touch interrupt uses ESP32S3 GPIO1, touch reset uses XL9555 extended IO chip GPIO1, and needs to add a mask to distinguish - const uint8_t touch_reset_pin = 1 | 0x80; - const uint8_t touch_irq_pin = 1; + // Add the highest bit to indicate that the GPIO extension is used, not the ESP's GPIO + const uint8_t touch_reset_pin = tp_reset | 0x80; + const uint8_t touch_irq_pin = TOUCH_IRQ; bool result = false; touchDrv = new TouchDrvCSTXXX(); - // T-RGB reset GPIO is connected through the expansion chip, and the GPIO callback function needs to be set. touchDrv->setGpioCallback(TouchDrvPinMode, TouchDrvDigitalWrite, TouchDrvDigitalRead); touchDrv->setPins(touch_reset_pin, touch_irq_pin); - result = touchDrv->begin(Wire, CST816_SLAVE_ADDRESS, SENSOR_SDA, SENSOR_SCL); + result = touchDrv->begin(Wire, CST816_SLAVE_ADDRESS, TOUCH_SDA, TOUCH_SCL); if (result) { const char *model = touchDrv->getModelName(); - Serial.printf("Successfully initialized %s, using %s Driver!", model, model); + Serial.printf("Successfully initialized %s, using %s Driver!\n", model, model); return true; } - delete touchDrv; touchDrv = new TouchDrvGT911(); - // T-RGB reset GPIO is connected through the expansion chip, and the GPIO callback function needs to be set. touchDrv->setGpioCallback(TouchDrvPinMode, TouchDrvDigitalWrite, TouchDrvDigitalRead); touchDrv->setPins(touch_reset_pin, touch_irq_pin); - result = touchDrv->begin(Wire, GT911_SLAVE_ADDRESS_H, SENSOR_SDA, SENSOR_SCL); + result = touchDrv->begin(Wire, GT911_SLAVE_ADDRESS_L, TOUCH_SDA, TOUCH_SCL); if (result) { - Serial.println("Successfully initialized GT911, using GT911 Driver!"); + const char *model = touchDrv->getModelName(); + Serial.printf("Successfully initialized %s, using %s Driver!\n", model, model); return true; } delete touchDrv; touchDrv = new TouchDrvFT6X36(); - // T-RGB reset GPIO is connected through the expansion chip, and the GPIO callback function needs to be set. touchDrv->setGpioCallback(TouchDrvPinMode, TouchDrvDigitalWrite, TouchDrvDigitalRead); touchDrv->setPins(touch_reset_pin, touch_irq_pin); - result = touchDrv->begin(Wire, FT3267_SLAVE_ADDRESS, SENSOR_SDA, SENSOR_SCL); + result = touchDrv->begin(Wire, FT3267_SLAVE_ADDRESS, TOUCH_SDA, TOUCH_SCL); if (result) { + TouchDrvFT6X36 *tmp = static_cast(touchDrv); + tmp->interruptTrigger(); const char *model = touchDrv->getModelName(); - Serial.printf("Successfully initialized %s, using %s Driver!", model, model); + Serial.printf("Successfully initialized %s, using %s Driver!\n", model, model); return true; } delete touchDrv; + Serial.println("Unable to find touch device."); + + touchDrv = NULL; + return false; } @@ -147,41 +145,40 @@ void setup() Serial.println("Start!"); #if defined(ARDUINO_ARCH_RP2040) - Wire.setSCL(SENSOR_SCL); - Wire.setSDA(SENSOR_SDA); + Wire.setSCL(TOUCH_SCL); + Wire.setSDA(TOUCH_SDA); Wire.begin(); -#elif defined(NRF52840_XXAA) || defined(NRF52832_XXAA) - Wire.setPins(SENSOR_SDA, SENSOR_SCL); +#elif defined(ARDUINO_ARCH_NRF52) + Wire.setPins(TOUCH_SDA, TOUCH_SCL); Wire.begin(); +#elif defined(ARDUINO_ARCH_ESP32) + Wire.begin(TOUCH_SDA, TOUCH_SCL); #else - Wire.begin(SENSOR_SDA, SENSOR_SCL); + Wire.begin(); #endif - // T-RGB XL9555 Use 0x20 device address - if (!extension.begin(Wire, XL9555_SLAVE_ADDRESS0, SENSOR_SDA, SENSOR_SCL)) { + SensorWireHelper::dumpDevices(Wire); + + // Use unspecified address to test the address discovery function. + // T-RGB XL9555 uses 0X20 device address + if (!extension.begin(Wire, XL9555_UNKOWN_ADDRESS, TOUCH_SDA, TOUCH_SCL)) { + Serial.println("Failed to find XL9555 - check your wiring!"); while (1) { - Serial.println("Failed to find XL9555 - check your wiring!"); delay(1000); } } - // T-RGB power enable GPIO connected to XL9555 expansion chip GPIO - extension.pinMode(power_enable, OUTPUT); - extension.digitalWrite(power_enable, HIGH); - - // Initialize touch using touch driver interface class if (!setupTouchDrv()) { while (1) { - Serial.println("Failed to find touch - check your wiring!"); - delay(1000); + delay(3000); } } + } void loop() { - if (touchDrv) { - if (touchDrv->isPressed()) { + if (touchDrv->isPressed()) { uint8_t touched = touchDrv->getPoint(x, y, touchDrv->getSupportTouchPoint()); if (touched) { for (int i = 0; i < touched; ++i) { @@ -198,7 +195,6 @@ void loop() } Serial.println(); } - } } delay(5); } diff --git a/examples/TouchDrv_CHSC5816_GetPoint/TouchDrv_CHSC5816_GetPoint.ino b/examples/TouchDrv_CHSC5816_GetPoint/TouchDrv_CHSC5816_GetPoint.ino index d1b7bfc..76ab768 100644 --- a/examples/TouchDrv_CHSC5816_GetPoint/TouchDrv_CHSC5816_GetPoint.ino +++ b/examples/TouchDrv_CHSC5816_GetPoint/TouchDrv_CHSC5816_GetPoint.ino @@ -32,31 +32,52 @@ #include #include "TouchDrvCHSC5816.hpp" -#ifndef SENSOR_SDA -#define SENSOR_SDA 39 +#ifndef TOUCH_SDA +#define TOUCH_SDA 1 #endif -#ifndef SENSOR_SCL -#define SENSOR_SCL 40 +#ifndef TOUCH_SCL +#define TOUCH_SCL 2 #endif -#ifndef SENSOR_IRQ -#define SENSOR_IRQ 13 +#ifndef TOUCH_IRQ +#define TOUCH_IRQ 13 #endif -#ifndef SENSOR_RST -#define SENSOR_RST 14 +#ifndef TOUCH_RST +#define TOUCH_RST 14 #endif TouchDrvCHSC5816 touch; +#ifdef ARDUINO_T_AMOLED_147 +#include //PMU Library https://github.com/lewisxhe/XPowersLib.git +XPowersAXP2101 power; +#endif + +void beginPower() +{ + // T_AMOLED_147 The PMU voltage needs to be turned on to use the sensor +#if defined(ARDUINO_T_AMOLED_147) + bool ret = power.begin(Wire, AXP2101_SLAVE_ADDRESS, SENSOR_SDA, SENSOR_SCL); + if (!ret) { + Serial.println("PMU NOT FOUND!\n"); + } + power.setALDO1Voltage(1800); power.enableALDO1(); + power.setALDO3Voltage(3300); power.enableALDO3(); + power.setBLDO1Voltage(1800); power.enableBLDO1(); +#endif +} + void setup() { Serial.begin(115200); while (!Serial); - touch.setPins(SENSOR_RST, SENSOR_IRQ); - if (!touch.begin(Wire, CHSC5816_SLAVE_ADDRESS, SENSOR_SDA, SENSOR_SCL)) { + beginPower(); + + touch.setPins(TOUCH_RST, TOUCH_IRQ); + if (!touch.begin(Wire, CHSC5816_SLAVE_ADDRESS, TOUCH_SDA, TOUCH_SCL)) { Serial.println("Failed to find CHSC5816 - check your wiring!"); while (1) { delay(1000); @@ -64,13 +85,17 @@ void setup() } Serial.println("Init CHSC5816 Touch device success!"); + + int16_t width = 0, height = 0; + touch.getResolution(&width, &height); + Serial.printf("Display Width:%d Height:%d\n", width, height); } void loop() { int16_t x[2], y[2]; - if (digitalRead(SENSOR_IRQ) == LOW) { + if (digitalRead(TOUCH_IRQ) == LOW) { uint8_t touched = touch.getPoint(x, y); for (int i = 0; i < touched; ++i) { Serial.print("X["); diff --git a/examples/TouchDrv_CST9217_GetPoint/TouchDrv_CST9217_GetPoint.ino b/examples/TouchDrv_CST9217_GetPoint/TouchDrv_CST9217_GetPoint.ino index c51e0b2..237f1b7 100644 --- a/examples/TouchDrv_CST9217_GetPoint/TouchDrv_CST9217_GetPoint.ino +++ b/examples/TouchDrv_CST9217_GetPoint/TouchDrv_CST9217_GetPoint.ino @@ -34,20 +34,20 @@ #include "SensorWireHelper.h" -#ifndef SENSOR_SDA -#define SENSOR_SDA 8 +#ifndef TOUCH_SDA +#define TOUCH_SDA 8 #endif -#ifndef SENSOR_SCL -#define SENSOR_SCL 10 +#ifndef TOUCH_SCL +#define TOUCH_SCL 10 #endif -#ifndef SENSOR_IRQ -#define SENSOR_IRQ 5 +#ifndef TOUCH_IRQ +#define TOUCH_IRQ 5 #endif -#ifndef SENSOR_RST -#define SENSOR_RST -1 +#ifndef TOUCH_RST +#define TOUCH_RST -1 #endif TouchDrvCST92xx touch; @@ -60,24 +60,24 @@ void setup() Serial.begin(115200); while (!Serial); -#if SENSOR_RST != -1 - pinMode(SENSOR_RST, OUTPUT); - digitalWrite(SENSOR_RST, LOW); +#if TOUCH_RST != -1 + pinMode(TOUCH_RST, OUTPUT); + digitalWrite(TOUCH_RST, LOW); delay(30); - digitalWrite(SENSOR_RST, HIGH); + digitalWrite(TOUCH_RST, HIGH); delay(50); delay(1000); #endif #if defined(ARDUINO_ARCH_RP2040) - Wire.setSCL(SENSOR_SCL); - Wire.setSDA(SENSOR_SDA); + Wire.setSCL(TOUCH_SCL); + Wire.setSDA(TOUCH_SDA); Wire.begin(); #elif defined(NRF52840_XXAA) || defined(NRF52832_XXAA) - Wire.setPins(SENSOR_SDA, SENSOR_SCL); + Wire.setPins(TOUCH_SDA, TOUCH_SCL); Wire.begin(); #else - Wire.begin(SENSOR_SDA, SENSOR_SCL); + Wire.begin(TOUCH_SDA, TOUCH_SCL); #endif // Scan I2C devices @@ -92,8 +92,8 @@ void setup() // touch.jumpCheck(); - touch.setPins(SENSOR_RST, SENSOR_IRQ); - bool result = touch.begin(Wire, touchAddress, SENSOR_SDA, SENSOR_SCL); + touch.setPins(TOUCH_RST, TOUCH_IRQ); + bool result = touch.begin(Wire, touchAddress, TOUCH_SDA, TOUCH_SCL); if (result == false) { Serial.println("touch is not online..."); while (1)delay(1000); } @@ -130,7 +130,7 @@ void setup() // touch.setMirrorXY(true, true); //Register touch plane interrupt pin - attachInterrupt(SENSOR_IRQ, []() { + attachInterrupt(TOUCH_IRQ, []() { isPressed = true; }, FALLING); } diff --git a/examples/TouchDrv_CSTxxx_GetPoint/TouchDrv_CSTxxx_GetPoint.ino b/examples/TouchDrv_CSTxxx_GetPoint/TouchDrv_CSTxxx_GetPoint.ino index b8bd714..694516f 100644 --- a/examples/TouchDrv_CSTxxx_GetPoint/TouchDrv_CSTxxx_GetPoint.ino +++ b/examples/TouchDrv_CSTxxx_GetPoint/TouchDrv_CSTxxx_GetPoint.ino @@ -32,20 +32,20 @@ #include #include "TouchDrvCSTXXX.hpp" -#ifndef SENSOR_SDA -#define SENSOR_SDA 8 +#ifndef TOUCH_SDA +#define TOUCH_SDA 8 #endif -#ifndef SENSOR_SCL -#define SENSOR_SCL 10 +#ifndef TOUCH_SCL +#define TOUCH_SCL 10 #endif -#ifndef SENSOR_IRQ -#define SENSOR_IRQ 5 +#ifndef TOUCH_IRQ +#define TOUCH_IRQ 5 #endif -#ifndef SENSOR_RST -#define SENSOR_RST -1 +#ifndef TOUCH_RST +#define TOUCH_RST -1 #endif TouchDrvCSTXXX touch; @@ -77,11 +77,11 @@ void setup() Serial.begin(115200); while (!Serial); -#if SENSOR_RST != -1 - pinMode(SENSOR_RST, OUTPUT); - digitalWrite(SENSOR_RST, LOW); +#if TOUCH_RST != -1 + pinMode(TOUCH_RST, OUTPUT); + digitalWrite(TOUCH_RST, LOW); delay(30); - digitalWrite(SENSOR_RST, HIGH); + digitalWrite(TOUCH_RST, HIGH); delay(50); // delay(1000); #endif @@ -90,14 +90,16 @@ void setup() uint8_t address = 0xFF; #if defined(ARDUINO_ARCH_RP2040) - Wire.setSCL(SENSOR_SCL); - Wire.setSDA(SENSOR_SDA); + Wire.setSCL(TOUCH_SCL); + Wire.setSDA(TOUCH_SDA); Wire.begin(); -#elif defined(NRF52840_XXAA) || defined(NRF52832_XXAA) - Wire.setPins(SENSOR_SDA, SENSOR_SCL); +#elif defined(ARDUINO_ARCH_NRF52) + Wire.setPins(TOUCH_SDA, TOUCH_SCL); Wire.begin(); +#elif defined(ARDUINO_ARCH_ESP32) + Wire.begin(TOUCH_SDA, TOUCH_SCL); #else - Wire.begin(SENSOR_SDA, SENSOR_SCL); + Wire.begin(); #endif // Scan I2C devices @@ -119,7 +121,7 @@ void setup() Serial.println("Could't find touch chip!"); delay(1000); } - touch.setPins(SENSOR_RST, SENSOR_IRQ); + touch.setPins(TOUCH_RST, TOUCH_IRQ); /* * Support type. @@ -133,7 +135,7 @@ void setup() // Support CST81X CST226 CST9217 CST9220 .... - bool result = touch.begin(Wire, address, SENSOR_SDA, SENSOR_SCL); + bool result = touch.begin(Wire, address, TOUCH_SDA, TOUCH_SCL); if (result == false) { while (1) { Serial.println("Failed to initialize CST series touch, please check the connection..."); @@ -143,7 +145,7 @@ void setup() Serial.print("Model :"); Serial.println(touch.getModelName()); - // T-Display-S3 CST816 touch panel, touch button coordinates are is 85 , 160 + // T-Display-S3 CST328 touch panel, touch button coordinates are is 85 , 360 // touch.setCenterButtonCoordinate(85, 360); // T-Display-AMOLED 1.91 Inch CST816T touch panel, touch button coordinates is 600, 120. @@ -173,7 +175,7 @@ void setup() // touch.setMirrorXY(true, true); //Register touch plane interrupt pin - attachInterrupt(SENSOR_IRQ, []() { + attachInterrupt(TOUCH_IRQ, []() { isPressed = true; }, FALLING); diff --git a/examples/TouchDrv_FT3267_LilyGo_T_RGB/TouchDrv_FT3267_LilyGo_T_RGB.ino b/examples/TouchDrv_FT3267_LilyGo_T_RGB/TouchDrv_FT3267_LilyGo_T_RGB.ino deleted file mode 100644 index 2dfe4f5..0000000 --- a/examples/TouchDrv_FT3267_LilyGo_T_RGB/TouchDrv_FT3267_LilyGo_T_RGB.ino +++ /dev/null @@ -1,115 +0,0 @@ -/** - * - * @license MIT License - * - * Copyright (c) 2022 lewis he - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - * @file TouchDrv_FT3267_LilyGo_T_RGB.ino - * @author Lewis He (lewishe@outlook.com) - * @date 2023-04-17 - * - */ -#include -#include -#include -#include "TouchDrvFT6X36.hpp" -#include "ExtensionIOXL9555.hpp" - -#ifndef SENSOR_SDA -#define SENSOR_SDA 8 -#endif - -#ifndef SENSOR_SCL -#define SENSOR_SCL 48 -#endif - -#ifndef SENSOR_IRQ -#define SENSOR_IRQ 1 -#endif - -#ifndef SENSOR_RST -#define SENSOR_RST 1 -#endif - -TouchDrvFT6X36 touch; -ExtensionIOXL9555 extIO; - -void setup() -{ - Serial.begin(115200); - while (!Serial); - - pinMode(SENSOR_IRQ, INPUT); - - // T-RGB Use 0x20 device address - if (!extIO.begin(Wire, XL9555_SLAVE_ADDRESS0, SENSOR_SDA, SENSOR_SCL)) { - Serial.println("Failed to find XL9555 - check your wiring!"); - while (1) { - delay(1000); - } - } - - // Set PORT0 as output - extIO.configPort(ExtensionIOXL9555::PORT0, OUTPUT); - extIO.writePort(ExtensionIOXL9555::PORT0, 0xFF); - - extIO.digitalWrite(SENSOR_RST, LOW); - delay(300); - extIO.digitalWrite(SENSOR_RST, HIGH); - delay(300); - - - if (!touch.begin(Wire, FT3267_SLAVE_ADDRESS, SENSOR_SDA, SENSOR_SCL)) { - Serial.println("Failed to find FT3267 - check your wiring!"); - while (1) { - delay(1000); - } - } - touch.interruptTrigger(); - - Serial.println("Init FT3267 Sensor success!"); -} - - -void loop() -{ - int16_t x[2], y[2]; - if (digitalRead(SENSOR_IRQ) == LOW) { - uint8_t touched = touch.getPoint(x, y, 2); - for (int i = 0; i < touched; ++i) { - Serial.print("X["); - Serial.print(i); - Serial.print("]:"); - Serial.print(x[i]); - Serial.print(" "); - Serial.print(" Y["); - Serial.print(i); - Serial.print("]:"); - Serial.print(y[i]); - Serial.print(" "); - } - Serial.println(); - } - delay(50); -} - - - diff --git a/examples/TouchDrv_FT6232_GetPoint/TouchDrv_FT6232_GetPoint.ino b/examples/TouchDrv_FT6232_GetPoint/TouchDrv_FT6232_GetPoint.ino index 54bf807..3fef020 100644 --- a/examples/TouchDrv_FT6232_GetPoint/TouchDrv_FT6232_GetPoint.ino +++ b/examples/TouchDrv_FT6232_GetPoint/TouchDrv_FT6232_GetPoint.ino @@ -32,16 +32,16 @@ #include #include "TouchDrvFT6X36.hpp" -#ifndef SENSOR_SDA -#define SENSOR_SDA 21 +#ifndef TOUCH_SDA +#define TOUCH_SDA 23 #endif -#ifndef SENSOR_SCL -#define SENSOR_SCL 22 +#ifndef TOUCH_SCL +#define TOUCH_SCL 32 #endif -#ifndef SENSOR_IRQ -#define SENSOR_IRQ 39 +#ifndef TOUCH_IRQ +#define TOUCH_IRQ 38 #endif TouchDrvFT6X36 touch; @@ -52,9 +52,9 @@ void setup() Serial.begin(115200); while (!Serial); - pinMode(SENSOR_IRQ, INPUT); + pinMode(TOUCH_IRQ, INPUT); - if (!touch.begin(Wire, FT6X36_SLAVE_ADDRESS, SENSOR_SDA, SENSOR_SCL)) { + if (!touch.begin(Wire, FT6X36_SLAVE_ADDRESS, TOUCH_SDA, TOUCH_SCL)) { Serial.println("Failed to find FT6X36 - check your wiring!"); while (1) { delay(1000); @@ -69,7 +69,7 @@ void setup() void loop() { int16_t x[2], y[2]; - if (digitalRead(SENSOR_IRQ) == LOW) { + if (digitalRead(TOUCH_IRQ) == LOW) { uint8_t touched = touch.getPoint(x, y, 2); for (int i = 0; i < touched; ++i) { Serial.print("X["); diff --git a/examples/TouchDrv_GT911_GetPoint/TouchDrv_GT911_GetPoint.ino b/examples/TouchDrv_GT911_GetPoint/TouchDrv_GT911_GetPoint.ino index 869a9c7..77c56d8 100644 --- a/examples/TouchDrv_GT911_GetPoint/TouchDrv_GT911_GetPoint.ino +++ b/examples/TouchDrv_GT911_GetPoint/TouchDrv_GT911_GetPoint.ino @@ -32,20 +32,20 @@ #include #include "TouchDrvGT911.hpp" -#ifndef SENSOR_SDA -#define SENSOR_SDA 2 +#ifndef TOUCH_SDA +#define TOUCH_SDA 2 #endif -#ifndef SENSOR_SCL -#define SENSOR_SCL 3 +#ifndef TOUCH_SCL +#define TOUCH_SCL 3 #endif -#ifndef SENSOR_IRQ -#define SENSOR_IRQ 1 +#ifndef TOUCH_IRQ +#define TOUCH_IRQ 1 #endif -#ifndef SENSOR_RST -#define SENSOR_RST 10 +#ifndef TOUCH_RST +#define TOUCH_RST 10 #endif TouchDrvGT911 touch; @@ -58,11 +58,10 @@ void setup() Serial.begin(115200); while (!Serial); - // If the reset pin and interrupt pin can be controlled by GPIO, the device address can be set arbitrarily // If the interrupt and reset pins are not connected, you can pass in the -1 parameter and the library will automatically determine the address. - touch.setPins(SENSOR_RST, SENSOR_IRQ); - if (!touch.begin(Wire, GT911_SLAVE_ADDRESS_L, SENSOR_SDA, SENSOR_SCL)) { + touch.setPins(TOUCH_RST, TOUCH_IRQ); + if (!touch.begin(Wire, GT911_SLAVE_ADDRESS_L, TOUCH_SDA, TOUCH_SCL)) { while (1) { Serial.println("Failed to find GT911 - check your wiring!"); delay(1000); @@ -78,7 +77,9 @@ void setup() /* - * GT911 Interrupt mode + * GT911 Interrupt mode ,It is not recommended to modify any touch settings + * Please do not modify the touch interrupt mode without a touch screen configuration file, + * otherwise the touch screen may become unusable. * * */ // Low level when idle, converts to high level when touched // touch.setInterruptMode(HIGH_LEVEL_QUERY); @@ -92,12 +93,6 @@ void setup() // Maintains high level when idle, and is triggered by the falling edge after being touched. The frequency is 100HZ and is triggered once. Maintains 10ms in the low level interval // touch.setInterruptMode(FALLING); - - /* - * GT911 Max touch point ,range: 1 ~ 5 - * */ - // touch.setMaxTouchPoint(1); - } diff --git a/examples/TouchDrv_GT911_LilyGo_T_RGB/TouchDrv_GT911_LilyGo_T_RGB.ino b/examples/TouchDrv_GT911_LilyGo_T_RGB/TouchDrv_GT911_LilyGo_T_RGB.ino deleted file mode 100644 index 48365fa..0000000 --- a/examples/TouchDrv_GT911_LilyGo_T_RGB/TouchDrv_GT911_LilyGo_T_RGB.ino +++ /dev/null @@ -1,165 +0,0 @@ -/** - * - * @license MIT License - * - * Copyright (c) 2022 lewis he - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - * @file TouchDrv_GT911_LilyGo_T_RGB.ino - * @author Lewis He (lewishe@outlook.com) - * @date 2023-04-12 - * - */ -#include -#include -#include -#include "TouchDrvGT911.hpp" -#include "ExtensionIOXL9555.hpp" - -#ifndef SENSOR_SDA -#define SENSOR_SDA 8 -#endif - -#ifndef SENSOR_SCL -#define SENSOR_SCL 48 -#endif - -#ifndef SENSOR_IRQ -#define SENSOR_IRQ 1 -#endif - -#ifndef SENSOR_RST -#define SENSOR_RST 1 -#endif - -TouchDrvGT911 touch; -ExtensionIOXL9555 extIO; -int16_t x[5], y[5]; - -void scanDevices(void) -{ - byte error, address; - int nDevices = 0; - Serial.println("Scanning for I2C devices ..."); - for (address = 0x01; address < 0x7f; address++) { - Wire.beginTransmission(address); - error = Wire.endTransmission(); - if (error == 0) { - Serial.printf("I2C device found at address 0x%02X\n", address); - nDevices++; - } else if (error != 2) { - Serial.printf("Error %d at address 0x%02X\n", error, address); - } - } - if (nDevices == 0) { - Serial.println("No I2C devices found"); - } -} - - -void digitalWrite_CB(uint32_t pin, uint8_t value) -{ - extIO.digitalWrite(pin, value); -} - -void pinMode_CB(uint32_t pin, uint8_t mode) -{ - extIO.pinMode(pin, mode); -} - - - -void setup() -{ - Serial.begin(115200); - while (!Serial); - Serial.println("Start!"); - -#if defined(ARDUINO_ARCH_RP2040) - Wire.setSCL(SENSOR_SCL); - Wire.setSDA(SENSOR_SDA); - Wire.begin(); -#elif defined(NRF52840_XXAA) || defined(NRF52832_XXAA) - Wire.setPins(SENSOR_SDA, SENSOR_SCL); - Wire.begin(); -#else - Wire.begin(SENSOR_SDA, SENSOR_SCL); -#endif - - scanDevices(); - - // T-RGB Use 0x20 device address - if (!extIO.begin(Wire, XL9555_SLAVE_ADDRESS0, SENSOR_SDA, SENSOR_SCL)) { - Serial.println("Failed to find XL9555 - check your wiring!"); - while (1) { - delay(1000); - } - } - // Set PORT0 as output - extIO.configPort(ExtensionIOXL9555::PORT0, OUTPUT); - extIO.writePort(ExtensionIOXL9555::PORT0, 0xFF); - - - touch.setPins(SENSOR_RST, SENSOR_IRQ); - touch.setGpioWriteCallback(digitalWrite_CB); - touch.setGpioModeCallback(pinMode_CB); - - if (!touch.begin(Wire, GT911_SLAVE_ADDRESS_L, SENSOR_SDA, SENSOR_SCL )) { - scanDevices(); - - while (1) { - Serial.println("Failed to find GT911 - check your wiring!"); - delay(1000); - } - } - - //Set to trigger on falling edge - touch.setInterruptMode(FALLING); - - Serial.println("Init GT911 Sensor success!"); - -} - -void loop() -{ - if (touch.isPressed()) { - uint8_t touched = touch.getPoint(x, y, touch.getSupportTouchPoint()); - if (touched) { - for (int i = 0; i < touched; ++i) { - Serial.print("X["); - Serial.print(i); - Serial.print("]:"); - Serial.print(x[i]); - Serial.print(" "); - Serial.print(" Y["); - Serial.print(i); - Serial.print("]:"); - Serial.print(y[i]); - Serial.print(" "); - } - Serial.println(); - } - } - delay(5); -} - - - - diff --git a/examples/TouchDrv_GT9895_GetPoint/TouchDrv_GT9895_GetPoint.ino b/examples/TouchDrv_GT9895_GetPoint/TouchDrv_GT9895_GetPoint.ino index e6c63c2..eea5ae2 100644 --- a/examples/TouchDrv_GT9895_GetPoint/TouchDrv_GT9895_GetPoint.ino +++ b/examples/TouchDrv_GT9895_GetPoint/TouchDrv_GT9895_GetPoint.ino @@ -30,20 +30,20 @@ #include #include "TouchDrvGT9895.hpp" -#ifndef SENSOR_SDA -#define SENSOR_SDA 2 +#ifndef TOUCH_SDA +#define TOUCH_SDA 2 #endif -#ifndef SENSOR_SCL -#define SENSOR_SCL 3 +#ifndef TOUCH_SCL +#define TOUCH_SCL 3 #endif -#ifndef SENSOR_IRQ -#define SENSOR_IRQ 1 +#ifndef TOUCH_IRQ +#define TOUCH_IRQ 1 #endif -#ifndef SENSOR_RST -#define SENSOR_RST 10 +#ifndef TOUCH_RST +#define TOUCH_RST 10 #endif TouchDrvGT9895 touch; @@ -59,9 +59,9 @@ void setup() delay(3000); // Set touch interrupt and reset Pin - touch.setPins(SENSOR_RST, SENSOR_IRQ); + touch.setPins(TOUCH_RST, TOUCH_IRQ); - if (!touch.begin(Wire, GT9895_SLAVE_ADDRESS_L, SENSOR_SDA, SENSOR_SCL )) { + if (!touch.begin(Wire, GT9895_SLAVE_ADDRESS_L, TOUCH_SDA, TOUCH_SCL )) { while (1) { Serial.println("Failed to find GT9895 - check your wiring!"); delay(1000); diff --git a/examples/XL9555_AdjustBacklight/XL9555_AdjustBacklight.ino b/examples/XL9555_AdjustBacklight/XL9555_AdjustBacklight.ino index a4184bf..7eda6c3 100644 --- a/examples/XL9555_AdjustBacklight/XL9555_AdjustBacklight.ino +++ b/examples/XL9555_AdjustBacklight/XL9555_AdjustBacklight.ino @@ -89,7 +89,7 @@ void setup() */ const uint8_t chip_address = XL9555_UNKOWN_ADDRESS; - if (!io.init(Wire, SENSOR_SDA, SENSOR_SCL, chip_address)) { + if (!io.begin(Wire, chip_address, SENSOR_SDA, SENSOR_SCL)) { while (1) { Serial.println("Failed to find XL9555 - check your wiring!"); delay(1000); diff --git a/examples/XL9555_ExtensionIOInterrupt/XL9555_ExtensionIOInterrupt.ino b/examples/XL9555_ExtensionIOInterrupt/XL9555_ExtensionIOInterrupt.ino index 07ee23f..f320bed 100644 --- a/examples/XL9555_ExtensionIOInterrupt/XL9555_ExtensionIOInterrupt.ino +++ b/examples/XL9555_ExtensionIOInterrupt/XL9555_ExtensionIOInterrupt.ino @@ -39,7 +39,7 @@ #endif #ifndef SENSOR_IRQ -#define SENSOR_IRQ -1 +#define SENSOR_IRQ 10 #endif ExtensionIOXL9555 io; @@ -76,9 +76,7 @@ void setup() Serial.begin(115200); // Set the interrupt input to input pull-up - if (SENSOR_IRQ > 0) { - pinMode(SENSOR_IRQ, INPUT_PULLUP); - } + pinMode(SENSOR_IRQ, INPUT_PULLUP); /* * @@ -99,7 +97,7 @@ void setup() */ const uint8_t chip_address = XL9555_UNKOWN_ADDRESS; - if (!io.init(Wire, SENSOR_SDA, SENSOR_SCL, chip_address)) { + if (!io.begin(Wire, chip_address, SENSOR_SDA, SENSOR_SCL)) { while (1) { Serial.println("Failed to find XL9555 - check your wiring!"); delay(1000); diff --git a/examples/XL9555_ExtensionIORead/XL9555_ExtensionIORead.ino b/examples/XL9555_ExtensionIORead/XL9555_ExtensionIORead.ino index 4baa8f3..0a8e0ff 100644 --- a/examples/XL9555_ExtensionIORead/XL9555_ExtensionIORead.ino +++ b/examples/XL9555_ExtensionIORead/XL9555_ExtensionIORead.ino @@ -39,7 +39,7 @@ #endif #ifndef SENSOR_IRQ -#define SENSOR_IRQ -1 +#define SENSOR_IRQ 10 #endif ExtensionIOXL9555 io; @@ -49,9 +49,7 @@ void setup() Serial.begin(115200); // Set the interrupt input to input pull-up - if (SENSOR_IRQ > 0) { - pinMode(SENSOR_IRQ, INPUT_PULLUP); - } + pinMode(SENSOR_IRQ, INPUT_PULLUP); /* * @@ -72,7 +70,7 @@ void setup() */ const uint8_t chip_address = XL9555_UNKOWN_ADDRESS; - if (!io.init(Wire, SENSOR_SDA, SENSOR_SCL, chip_address)) { + if (!io.begin(Wire, chip_address, SENSOR_SDA, SENSOR_SCL)) { while (1) { Serial.println("Failed to find XL9555 - check your wiring!"); delay(1000); diff --git a/examples/XL9555_ExtensionIOWrite/XL9555_ExtensionIOWrite.ino b/examples/XL9555_ExtensionIOWrite/XL9555_ExtensionIOWrite.ino index f8f6c78..7c7ae75 100644 --- a/examples/XL9555_ExtensionIOWrite/XL9555_ExtensionIOWrite.ino +++ b/examples/XL9555_ExtensionIOWrite/XL9555_ExtensionIOWrite.ino @@ -39,7 +39,7 @@ #endif #ifndef SENSOR_IRQ -#define SENSOR_IRQ -1 +#define SENSOR_IRQ 10 #endif ExtensionIOXL9555 io; @@ -49,9 +49,7 @@ void setup() Serial.begin(115200); // Set the interrupt input to input pull-up - if (SENSOR_IRQ > 0) { - pinMode(SENSOR_IRQ, INPUT_PULLUP); - } + pinMode(SENSOR_IRQ, INPUT_PULLUP); /* * @@ -72,7 +70,7 @@ void setup() */ const uint8_t chip_address = XL9555_UNKOWN_ADDRESS; - if (!io.init(Wire, SENSOR_SDA, SENSOR_SCL, chip_address)) { + if (!io.begin(Wire, chip_address, SENSOR_SDA, SENSOR_SCL)) { while (1) { Serial.println("Failed to find XL9555 - check your wiring!"); delay(1000); diff --git a/examples/XL9555_ioEvent/XL9555_ioEvent.ino b/examples/XL9555_ioEvent/XL9555_ioEvent.ino index b57fe24..47091c9 100644 --- a/examples/XL9555_ioEvent/XL9555_ioEvent.ino +++ b/examples/XL9555_ioEvent/XL9555_ioEvent.ino @@ -39,7 +39,7 @@ #endif #ifndef SENSOR_IRQ -#define SENSOR_IRQ -1 +#define SENSOR_IRQ 10 #endif ExtensionIOXL9555 io; @@ -61,9 +61,7 @@ void setup() Serial.begin(115200); // Set the interrupt input to input pull-up - if (SENSOR_IRQ > 0) { - pinMode(SENSOR_IRQ, INPUT_PULLUP); - } + pinMode(SENSOR_IRQ, INPUT_PULLUP); /* * @@ -84,7 +82,7 @@ void setup() */ const uint8_t chip_address = XL9555_UNKOWN_ADDRESS; - if (!io.init(Wire, SENSOR_SDA, SENSOR_SCL, chip_address)) { + if (!io.begin(Wire, chip_address, SENSOR_SDA, SENSOR_SCL)) { while (1) { Serial.println("Failed to find XL9555 - check your wiring!"); delay(1000); diff --git a/extras/images/SensroLib.jpg b/extras/images/SensroLib.jpg new file mode 100644 index 0000000000000000000000000000000000000000..71f121c43f903c112f8382b25f06c23a901a2e9d GIT binary patch literal 32195 zcmbTdbyQnV^amIUg(8LG4lPjJ2`(w6cyTBcE$$T80tJc|4;tLvihGNDkl^m_8YFDK zzu%tSbM~*@eK|QN@4d;L`P{j4ZSFkJJ+A@YD9Fgm08mg+0G`MX;CT@s1$c#yj)DI2 z6$S~82C(_12M5kNXf`4-ZL^Wv#Sx3z&J$Q948ZmG=l?Oiv%unOgOP)|pul$@x`YV0M7@%&EYl#7fNHtr~S;g&if#EKmxoCh44 zfV}9g{h!`YjNy5}rAf<`|M+16!6Qn|#@Gq;+DD?xW*0@m&SY`vMKQK^LH4upv-)U4 zX_V25IMgx%iJ$R5x@c1_`^XNkA$$=I)_kA8P(xUnH^4|PQYd_$G*fe|K2UJ5;`sb= zC(ydJc!@{)ue){rxtuQ84InC}PN)P0rk1{G&R>>OVmvT569uLgg5_I&RzEExX+f!3 z_^t~{Xq4WGP4P)0NfOS0kz;ib&i+EBgf=CpZjqv+EvEL_rI!e+w|WUnf105Q>c{Hl zW_*!8^-clk$B+ew=SZ_2AW>O|uajDh$TB$%GyxaE{ZlW*Clmh{@d&uRY+mai9W&d)OsI0|z>%7ere@{ynh3jBXw$zk%H%Gij*9CH7e zd`8Y}iV|`vex`%Sc(CO5k%v+xWTN^aT4)<}3nq{H#W0{%ij~ zEcrZDO+YB)1M?|f?ghvXu9-ct;L57X!n7Xn|GZF$%)B=F#`xP>Rkp%KOfZJ$kMem4>m7mza`*6{z` zMuAPZkUgjNr|Hr9Z>RTOm#EcT(ZMa_ooHax$EO% zD12*(i@}hXh6EmHtxA26!;?Y^L1y(xifP;ztu(9UnSx%|*WS6lb97Pj#eb|ZM;QXZ z4te}KoVd>ZB7U2)%!CdF%cokyapM-rBMfTan3fkJr%l-$_Iqi(Fixn{hPt-XCml)= z{vcO`X2IaTEVF(MMCq>^T?yZ3Wl>)n0x;pNziz>2PHS>fTJORTeMia{H7P@&pRhQ2 zAu>SZO|E8Q#4q^Q`g*((S@cu}A31t5ercvSx_9Y*T9nJJoV>Qolkpal2^5?`m){`P z#?X4T%P~}cV&>L=!s50nmh_Ap2BVavv2F0$0Ld1HEwzE(9LM|2YoXuFxTk6S5C=sZ zjozc|Hv%!rEF#Vg!TTQr&7AWZ|>yduUH+E5NV(q5dtgt-!*Iyu}U$U)3HSJ+XwOc{7HiaXl zuKfwALwY~yt$^L^hnxu=^4uglqBdb_Lw~c}$cxc_X67dQw^QXZE-NjoCFL*6G7ox~ zfca@2T_8>xb-WkM-mj(GLml!t)W8d1iNcKV+V{)ynXJ69w30bYY_*o$WtmfNcC_GX zYiv#P5{ zO|Br)!Ilic0Ja94s=^|el(bO}?0Jbi*x{t~ExghPe>Qj5x$~*^h zWUq!YUG_hi$c)=iFHI(?tt7MLS>r8V#CAhW6j1GjA8iD|^!1ePZpCP0&wztthx}WeYLEb3 zy6!I3{;laA(KA4I12NfEq%bC=tXz6;U6jQBVwM2|6?5}Jug5Lf7AhbqY$boQI>qOgg9xX5U|@#(jk z4O9qCM5vGuF<;cEbt`FGZ!EzFjLCQ-_JBrIRIpYeEV>D510I&5krY1udNH@$VJ67r z;1nm{3i;?B)81cHz_0Cb?pEO{tS^eUEOYP~&?ER67NFSxAQBLow6m~U?zj0-S{h1* zBdRGXk2dwYg(!P7`xr(-Q%`dODquV)Bac7DXv!0_$Qgi2LJVN#bo!S{)>_JVx-p*D z`F1qZU$Em(_1!kWV*oR%C!5v>tY0Tkg#t8OC4#n|nj@BAXoZZTX-;8$_nne%#3x|^ z#kSoFE{t>-W!ghwWP`+hZdbDqhIlbOl|}X??f9gFvp0o1VH`+k?7%4H89@AH_@2Vx zM3jO`DkVLM%HpR^W9CUEs=jaqVe4||*bEgklWdP#j-+J$$A=mtF?c*|d;6x(9}buyWW ze3UB3c?IE_=TXwD!3(N*7dQGI<&s1(^68+4YKxO^>gQ_<%-3T2Z&(yECR9r-4C1<} zb_=+T1BkW9n1WRZd2ef1*rqg03V$<|M4?ZvN0rP?kdl=^4tw)u7#nIPCs zs^5VQOb}t6%FlWQjO&^8B#%yzk1JOUq>Rh*NYx>y7s1X3cF12=J;`otCwXB23ohm8 zCqI^NUCH>F=Eiu!$^lDj->VMyaFWwSYMKLfw6qdItQh2*x+B#2rrbP>jfl^m4!WC1 z#SOGGuRqZU0h=Z2;MiJoB zVCy>HgjkX9r7ExdvFg@thi{pNY&B{8Q=xGSSsH$orPFjrP%Mbh(9bw38aG+cFw`9t z`#SYuk)vx^si_T{A@b(T{g@sB>H_J`HCETx(KZKb-rAYRz^=3>7Hno}{DD{pERhsr|sHoAUjsf|SY*uvswU_% zf}pa2n?03C+`36QVWbWQ61KLx&8^whQL@dXnDu-A;=!JQ=<&0%-qH&E+8!hdI9EN{ zND%O(w!X-5Aq*YZniT!!=%RL$PX(4`r3BNqZ3I4^*|6UfY|dnaH5=<#iXTWyNRpA2 zru`8DX2;G$6_U|L=>@{G=wqD}cY|n$XUbCLF(4n{Kxbk~&^=x<+IwT~60dO_|A3C_|&zl*gOq(GTWBo50BB z+K)dAL=WW5(9=5d&`{+@_iW&w7vC=<{YzHr{+TEkT&|hroAtkNVk0+ZKOTrXcKpfc zJK*TDSN^iXKPRMbItoiI`qs>7EmUX`x%0E>aU$;cGe-p9hsw~M_!QkJ*b!TSE8Tk<$$HX|pDmy$i!We&pH8Be{x;F=h8fgS&Azcy8^ z4+c6E-)gvwk`NDiP^mj?{8*N%+$MLlkp2Qk>WR9+#D}5itJVq zhl={0BGB0K&%EH3&ww@1Ob1^$AGQM$xf2Vo)f?9IxT zI(77;EskEl)?jerD+Rr}n2gMLEA^L5M9Z*W_p{PrROm98y}I?kmLyqg zZjADuekVQ%0ILlbcCDo(d_t6RT=;=*kOX^bV13OLIq`lQ;0?& zD`T8S^0z$L^s?Uf1=W}hWq(wi+jzKDD7DeO_Pj>F()LNqUA%+{#jfT#LKZ0W z?z`kJjaOTbo^z;|f-_bxh=#y9# zA`oWwwNIqOSUE!>st`&`8d^ZXsUVUbnszL|bE%4Sd`A5mO?SP*ABU8lY+l1G8KX6+ zdKUNaR2}k!_pIdfw-)awPdBoc=dSY{dqpvLI1wy@kg&!VX{``)-y0lr;Lmz|oUN#5wHEVB8jCG@V#=?`J~Pwu z0&UjT2(yPc{ail-|HeyS*s;d<`kPJS)0F@TRP2O+|3FFKA+hUjN1j6Nt-3oa`KxQ; zUe7pf%i7?)W1C_kH#}N>cqE6h+_)>(AZY#T{yBz*HoPtAWB})tT|?Clm3}SlADK_(%MCt^cYOYS=gz+xwZ8vR3}ygL?zYrq8&1mI@(*a= zFnZIUuXhv~(j5Ea_x_1**$AhhUU;T;{xW^Wi2N30x_!z`bTPCkb;FBlYa5QxTm<0_ zSS)*LnbQ7^ieFjjYT7f``CTyN`%()&=RA2qe=fiC- zh2MbU^4T$%0uH3#i}+HoL5fWNrFu{7#ORij(fpz<;IuhvWLl6z((y~^u*uxLD9(+r z4Mcl0%=P5*adkj*SGiMbX@>NhcZ%L48&g?@~fgDE}LOP z$NWoKyJ@@43JGA6#zXP)GhkWW+By5CJZsD_Aw;X_wZKz|-!Rt(08tmJ+@Us_zxoqB zxphfA{}&&s{0?4ralSm=hTID17KY4*m7x|7KCUl9#MUzt(XEybRT8lmc>RUE{p!3n zn~M45A;MA%y!{Z7wTYdQ6Mxn!2#UIEAN)_zc%+({h8yX}*_4jDOq-yYGKYuPYt7QJXWRC$~gt?Z_xY zSj})!x_uL-O6Gm8Rf}|;vREXhlNxbTiAZir3qp&DmN&(?ANQRTj~P^WM*Pp-J=qqX z`RjGw;ayjLYH$QCP|fPCV#hFJOg@m9uOV0@M)!K&gv~&?M*}`@`iVJrqlCp*?P`iC;b+i5^H1%U%;#AYBUQTME`sl~0kSC|eH*{|#U^y08i)o~=DW#zWpK@m)w zMRFNpjza1+rZ)o>%hH6*~Us^C_MYR(1U{MBGAHT@xpstz_$sb*;WE zj@`++Ca%2Di?*5W2M4YsT3)ngfc; z&Qjd`t+L|z&08PLj)kB}GIN(p-UzqkGJ&~Vz%zhaA8)e6=ItPr*U{>_k<#yO+1E)! zki8!>M&X|6GyJs9l2cjgA8qkX*~J{$XMmC7Ga$QO`}H$mU^2Pn(sOl9ZUgBbtkz5J5(wpA z_W!_o>Me8lku2gvBIqP@lBll~cdUGgLCsR&tHx=S>_KFayV?&VCDPH~OLlwreI{?^ zHRE~Y&TkA6hUH$ygRlW{YeA1uQS1zYlg)zv9O|pI;_BwXuT8nx7JqZWl4Id0YZ?Jt zun$)Sqr8}s!0arW7!Tl@&p5A&x4VtlZNah>3!jFxV@pBJ_tVWw4TA>Tv2W@B#9Z*; z7XLcAE^Nm)7^| zJgFS0ZN|gXo(!q(aq+f|EJH@QuW#HfcT<)^$%E||Q$3{kz|#DG$O2!{*Br{HYv)63 z_A`Ot-?h3i&~~I(7fCTW;o3J{B~}}U=E+-qc$Bw<2y8yrfq2>|S7@6>6ews}Ml+>+F7id0s`VFIPa zf7SL_6&@Rb8&t}?_L3Lf!zEXDb}vN~jt!zNz>$$pUIiCZ55M79$c#7qR$zI4*^IlJ ze6Lld^js;9Do2*i6Z-P~ZcNo34E81A5LS4KVGPXN+x^}qXz3pFKJI~iv)uB8@I=&) zHqqIGj~WSqD zc~wb&acZm>)~@f|xx3K(+C@^t=BacUqWICzeyPrDAH3u<>*y#WGA)SJy5>m1sLt(8 zEH3R!qL}%mTT?Z?iZB^Js3`3B7ue;GiA)>&kF!UlmwJ}0Q3(>IUKmK*{LS`S*G21X z5q0VX|J!vY(s4f@*i2Hb;pq0qc3}%~A|Duj-YC#XhWF$z){#AjX>Eg!2^H?w)|zWz zsY)Um{m7TPiDUb}mPQhik1FH7FRf4;gWCmDKv965fZy?w zfMkiq?jIbt5tC;U94EEicC_-!2 z@k%UaCV!xpgVUO`ph@~9Qm+$F@+}96$#>2DyO^^|_lq$fmKUGfXj?W<8sS%!w-JFm zGi=2W;WxaQufz{?Ga2O{`qAl8up-VU(s8{GWo*XszTLa^^$p7`<$1?Qov>z}I2r7h zu;uL@eAL|9dT44V{a zYh;VqHwb-s-0z&9nFFzTU(>FC`IpZWbXECYnC77Xw;$h$_w`3x&wrfn&9N|=E6T(P z9r2v~*M!$JTil~#jh2l@Lm}3fMxS(NH|k6D@|8u%Udbq{OPft`ym2CX3}(|=G)1PE zlJB%4&*esgp+)@h>1j(RH>!%JzosiU>ss8YWN)H^Xk+fQjn|sL=u~DX%V=kfwQcsW zE9KjRFZI!p#-yz6&RxE`8Fb8bQT2P1`TeOE-NjA@re5>nxJZOOSApMmj8YMr{&ZWU zi6I=7LUb6xr`e}7%sV%Hijg8Rk~LQ1a9gz}hWAhpl7`db8z9c_V>tTj8Kni0?wG_i z%tXqgm?Kqfn;aYGY_1n1-DfN=uSTP2Dc(D|ncLCaze+sY@ji~}{>dq5UX~$e2 zNh1Wzuf2_iIyR#_gE^|q!|{fi`nT8^@4s`(k&5wvCL8#JkP!4@?(h(SZ0Xah1Pf1k z_u8-xhTVkaYuTWHh_90o3pR5)ZQq8>1jlBCK$2{mv?fN?(DbA_FWaVb$bvI3U(lhU9|kG=d(WBZy|YqD zWw9#L-&0}?2E->5ygs-e9(`t|aRZ9FvV9?h*9uenGScoQwQUZ_t;^!skuc+ZNnIXk z^a5;C5FnXiUxUGnAhd^X=j@HvgCPm~-jcnQh zf}(v=tq4tDH~LTZKb70$#@PZBi}uJ1p3J#tz@abO*rRrKWh!@D-NyzO0dfqvtf{A| z#i=->e8*WLUw6gV;gi0!F1vhGjq^rtof+?&s@W2)l|XgEg+mglbYQm?^~*7JEh)iy+EV(}04R zbn^iWfT-x^QD(MB;YV8<(?<2(n|M@2$>kBt>H^y{K&;>~SmO)pD=gmuvLaRjd9=t& zD9{CWr1>fT=Os~=GE29bRDUAVzGho{MRVMI%ei7WcF3Ft^-IogwVclYt8CCg`pvO{ zN^m{Qjf6119Nm~>$=~CEEmB<%rwNssWk`n^r(az01&YR8jQ7Q*{);}1Tfg@;$L8dL zU87x9|G56$ihGDZsOc+%HwHNpO<d&$Fa=S)w=-GEs8GGLI3#h8?lvwi0FQaS4<(L)`zUfJgK;PgGW*SV0%)sau2) zp;wiaaX;zmBDc})aXzijN=1H6GGpEJ#6S~N^-tkfKF5(W3&trGDfBZ&@K4#?>!iLO zZP{3tk)!Psf9=8x4PL_KyVq_`-bu6`8y{gpfX~bjm&A=P#^jVtim2?s1o9mvqsa0b= z$Q0DGV6nzXjoEMs(3yDr09!Chnk3hx`M}^;A62qI%k!q@-{3cqIIY;iNi?4iYp4qy zQ%vjkIxU8iK7J;n=XZAPrNH%3&PH+ikLOVh72J(+Gz+`M(JDxP*Y);ZTbYb|pz6&^ zYlke|2M-oQthn)r>nz*@t`h4v`XF3MTyZig+F8h@%Om(fxHMsT11gFc6~ZBq2;n~@ zRj2t3KU#{Zu$xhCYpx^k&@ciiI1sAK7K9?`K3_h0`_~%s;GcX=NDms126eTI`|VY6 zo}-|zFrEA{Jp*lN7qhHs*Y=QAeGlwjb#sGLU3B~4Xertq^+%{$=a#J+a1`W?^am4P zz^1_Rl+4YdZ#!Veu5%Q&sap6xHI)h~;YlDXo^E?L-sti$WbiGr+&fd{IyurKgG=nv z6=Rc!WARoEy_Y6q)VD*ayQa4vk~i1S)1&@Zl7(&XO8mRb`OD~f2lM&_Dk|Q%5RE-q zo9Qa*NiMS~eou#gsOB zkGI2CpUSn`X8fub?Yh0WtLW07w%paDcH(;O8n&c;zcWXrhxQ^qhvFoX zA5(0s$YQlf*L8B|HZUI&)8f2(mS#KapgYz#K`1oxD{Gb>^s@}#b6EdZkWn3d-W zDzGe;pM1C+&5K|EisX6zN!LPqJ`IQ=Zde;(?rZC#Ro#L$>*=|s~*6+fOo$T8N~&s4c8 zDG|t>p9(5CwqkB?JF zClm{l!rv_ovGgjBXk8}D?pC$qzb4B!Cgy%Im?d}z4|K&6$3$q2^x_EAz*S4>P`Zi_ zuf-2bGqB5Q$NEgCF@~wXmP@=h>RT)v=j`#zLx#Gn`#?OZeeX>;&wyzYwMnc!Qu}ll z3p2bCeVDc#73WMf3y;)xdYn)WdZ}WUxlyS}Dixh%&uObfGfsxzL=`ldERoyHh2|Nk zq^Imz88STV&NI|`jCWpH#Xrb=(aN{@TO%T##il{g*W&!Vvs5q-H*uHov5dEkvob#r zlL{ZEUDC*EJ0_-NePiG*MS-K7s|F6p3~8yJmKfZ!fQdtGT8N^vF&=CDe0v={IWDbP zo&kl>C$?mz-Rj=&cQ1d>4QIhm-@C#*ehc%aJ($)J{hCNuC)CH74AyFe+1r_3a$3s8 zy0QPon<>5v`br@keXVpk;4V$$cj+JOwUyNQy+x3suJB|ntEuOg$~SQ~ohfHw9-#r_ z+4ko7;mv0N-lqqpN6Td?{CljpAEtSR|Ck$L@2p=45Tz41&AnlZ@{uFO;;>J^{YRQL znTvqdeEnkn=cil|>i~}~D+eDGF>5r$S?|nP8}NcRj#*gzj(@Kc51pM;_CfKnY}D<; zNGx>|y4quuw^8@RZ_29MWVm*>Q+j2^R*W{IgO0rXt*D3^OkGvttZJ0Lc~3lsdDiV^ zOph+a%R#OMoGETA`k;hNIcV-)6x{{Up2gcVlY?x*`?qDlK$rRuQP-+HcAU=nl6$U! zJ9a6*8N-6p<4?2~gUvW>%k5PlbjBSM}6;7H~p9kLrm|7+~4D)Q&m z)NqQKW-knwg4G+BM1mdX9%~IPEAHZv`6)i`lsbXz$E4DJE81g!&j(1CkCt)RO@7cx ztk6BJ?!yrmn#$beOmh1?%_kQK&Gbk4#paVQhIEtlB)#=V$}0gO{+#utujt>N8;LIP z34K-lBa-guI3TMAxyF0x8LtO^%J6JgyNi1>Q4yNdAK&^N`e`W|Z$>_tB%A;eX@^?H^CQL66)n|5A1dH#H^`8x zaa+s1VKvnyt3VLD-sjuYO+21C!IV)SD7cfAwNPYRawkIB`K1D5pjRP3)?b?Ane-A~ zDzUWMC8VQRDzpL=*8V8|0=bD&`eD<_`0e4q#rZuf)C;! z;5^Fl>mB9(94!73_Xjg!Mu%DdUyx=K!P=Oe*S7?b_L@o&8*pyI$CUh&# z%ANd`L8V4K^iGurVfyC<5uP)T9MqA_??AkL5PApu&5a_TA|bSfA~*SBD%c4`rD}1wHo7q8<^iDUodG%NS zh9hJ$v8{!&<$Dw-J<9iQ1jUC82C^`1?IK%uUC7Rgx#_YBnsyqo1MUZEsMHe+Mp8Vc z`sQ$gOS`ggRYvdGH8_#dn$8OEcl-LFXbn<+GTzRPj!zN?4RHI^(N`NBF>!r`U3=c^aj+-6p>t;tjU{Mj~|EphLER zoOo|y%&CrkP}!cI;%YrCSzM=ZjNOyqb?Xnf(|()*Nq9kJoQ3^FYOtT9p9RYM6M=&VkeGTESR@DxPb6G63CC(206Ls z>gvMHl#bN%+eX!njSq>B^Orvq7JJKXn6|pM(6##fTtuGM)4^apo7xfpF5;!$x}gH#8Nnn9X6<;QlLDxg!WiSlI^gk=BIx)FxrhU~Z+ zf==wA$Ii(?5*4Mhz__ofnk3N!f6Cs@GeTC3L&;x z^suIH(*|V`h%I_(%hh3i&vq7a;8nLhe&izA%Pp7xf>L;kR@cLB#v<1aqw2thoV}u8 zY>!^}8DOS4UjUuSm@CiR`MmHlJ=B@)(@F{SvfSqsS1zkfUeD?TU3Nnx;;Vh&>*5D3(}e$WFvuWJn`-uf z(zGlvKPYIWUeAE)7{|bMwI~-4gS#d#d%e81GE*eDwmOn*%(m2_Kf5m>$3ZL;+zF057GRsKL z%+Wli9m<(!bN=~8Mv^Xz1s^Kr5b3VSC~3&oc3Z43MR)v0P9=K)X;7qdC1eSfN(cWK z-vo9$8u?kxA$|pViA~CWfAb*_(A}vnyQ?H{UW_{YnMMeMU*`QY0K4_;-M?wM7blBO zsD)dgb;GnLw&5$X&W*AfER|ujUt8X5+C>qYJsfIRa2JQbrotvD#aq4KMun%b2Z(`+9FUI>z zel@38F5ktd&^^b--w>VHE{g$|;Xm?c#t?ikSG3ZO$A%T_d#MP;!u06@zb*T<4ro$!um*KD9KFN7Wd8i|9&!)ZH)3 z9!MclwNDeIot;?K9tJeuhzlz?Y|dl7PjXziS~ zH@QTAkqrk>?%%Fp|B(|l*Z;4LtaF|%i=!-4fEtVaDg&q7Gr-P2%8hI;@EeI1)_TZF z_D;hOrf0yrJO3sBZJk?;+p-Hgp?zHh5$GHg`qYQeI`=Ai=!u#8^BqnoJAU;OS!>E@ z#T0RY%SPj~QJ#grbo~(isDr@Qe;VjP*6qx$w15Z`5v$D@v~J>{7PgEQRnE8c=~;(H zmTLZ8>Q}OZYetWpkMoU1$oh%jNKUvN#XbW{j0!wgG7v5A5DU)$ksGe5>(-tw#% zsmC(+ZnuIZQf9{qA>%uWk;z0$SiYJ4U%d?|E+c@kWj5w|4uDh&c<}W*@cTHIDC|Q z0n%0__$qLzBfQKJtS_FmX z_>sqleneWp6H63vUuH21PaxiRZe-nxxaprHiEQKp< z>{nM0#uPusygcZW_%G)>tdF$+tQQaFxxf46FsH?u#ncBY43v}NKG|a zXFjrBay^V4P@ytEg!v;{Y=2_Q0u!^}U8rP+x$7lQWONoYfAvjyn;0p}0S-sZwsMeM zrpFVER4HpCnJ4=m4Ba-8RTRq^^g8*`z!XyUvFIc}-BRYq zz`Lk~)bN*a@!kHkq-!g6V3i*ULCIixo3>%*^ zw3dLJI8SlBoJyNRIUNtSJg$ySBLnc7^N5L4X|tJW+E^udiCSU0awvj?q}>+N4Jl#U##6b%tasP%g6*vhNt?gW}OA^H{4rA z2ocDm4939-`d1g44>Rb{UgO2bQQeUJtIEn@&va|{qR?L1t;h0Al^jdcA1+7@5{|zi zU}}6PiGzO9#D7%wmsa7tIrqZCDwCa?Uf6H`&~Qj%?_PZqhac-rZuNs`=fHZ`#yMH| z=mt$$_7}tEX8_G_#I?=;{<1|}|8Sta3%h3aCtxD1$mwHH z%tKe*rTXq z!_snOIe`LHj_Ai|t0!U)G}CFkKGTtdy3MzRXyuCicN2+v;|cTrzLV<2@cR`P0dGxT zFMRMm@=J8;x7ph+Zhe_fV06{u#i@b84%pnouDT72Slf#2A6b>d!Hrlj2~@nHxpfNq zsCc^DK)!=PuJW)RLmO->z42r*hgUbRXTWuv>l^8hYXz$lJv2@9dLJb_Oo!4*6FPgq zMxxTl{EpMyjkfC*#s$AJ=^W95NLZV{Nj~{Qqbfor(IqP`@kOlvnixeWc0%c`_&2J_X+1)&xo@Nx zd|tL~51WwMui~#~iYtnHcjgANozaoOP5NprWvW6y4KAe@cKYq1VKUDME}l|h+Zejn zc4~qH%K5D`I*4K+tIJr;XP~%@yZbRxMb%W{IY&nH3S8`@Rmj^(^Hq|BW~)K98FC09im zhcimn&xcuI7nb62+vXJT(BwDx2ls^{{+hErWSNH&a(i** z&j>cv&w|_{F=TZ>u=Nj-XFv=~|C50CerA7aqODfOiV`{UK%Qm9HqsNU4_>Y`%1S{ zX0Tm0ox0R#@@!y-;f2@Bt=2E43VlDNxlX#!tC^>a6?X?m>|a-~X(SuM%tAnMC)CM- z&X^L@nfD}3+W0?ZYk3HJ_F@hcdE3FCR!e@J z)n`{Rw-TLTr4rhrQ+h|tpA|iZ{+9*oOf>#nUiW&d|fqn zU~#9TeiLDxx4pMLT?$iGGhfBi-N392>l#|5yOoB5!kI2A9`szC#2kya=kU&p*Oj*4 zHO9OJl!oyI%%K=Kgyz*3-An(aaU#Q>{f0Dsk5JyeOIV_{19ZH&>D$>*ybrxIHwia} zv7(&PI}oB2?mNFD2)kU35FGDuO|zy#eVDIS7Fw6Rek_B&JgyM~_^)ZTZ!Rl+e>8QC zAdssdw%1JRXNzCGJLeyJ(ViVfds}uh68Nhc?kglQ`v8sVSKw!BCJ}=3YZ z`&ObQF&a^<5Y(f(yBsAK;QRI-2XX_iYVO;dtKO~#{Rldk#x)RthhuinqU;k#&ubAcSFq$+7MN4;GZ z;vN-_^+g`vLmt(aLVtYHrdz4VrQVv&?h<|B zmASCC%!>9EInDI46@s&|1^eZ?4wD!1D zRJ!_`*FYiT#J4e~ijWK3VVze1*SrWmhqy7iT?e5Oe%WM>!+37^D6VR z!kVX&g12#(PPha{F41@!ApKdeebk+FBFq#3jv4q80xq!;QM&RVIeQ%x8bc{nRdjvB zf4nQq?nK6qWxEo+y7hyTlGnMXS!ths!A0&b?|O)|h5lQ$vjYJjqYyQ=rf4}sMIv;(Pz4dPc|BM-wm|BysTbKkU-*=u&oS$DjPs@W#v|D&R-jBB!M<5N%siHDRP(%oH? zE&=HVr5i@~=$6q)OLupdFnTmdD&5k}c=vwXhyAv5?sK1WUH>{OD3?|f=M0aVSF$U7 z4YC`oj?QwQk0bBnqXb$tvcXqBWR{wQ|MSIU^~)% z_!oJ?EAsV{|2`|=5cToYKcb|Iu_8`gO~*Wdc>&VU_yVA(2imqiuPWu_RQgBU>0~0i zyH5gKfx@rgSLN+>b9`e9UET2&IYfL1q&KfCU^d)1sWx6$6YjGrVmKMFO*4IMRcX7J z@GZBXt{c+TI}gaz-V2}_ZrCZggT^x|_bA!!6k$cAfjk1nEUW0RSeUdcColhR+c#Vk z&^W*mJ13gmWZ85i;wF(}Lkw4T_KH7W_zTQ$;D?FRbg_{*Y9t``EBz#LOq~P5+qI7U z!r9l?WoFs(gJOO_2;o=7P4n?X2M#ZQS6Uvuupq`KE|vfKVXv0_RhWv{BgD4m+Uz`S z*!p4bKlDXMO*-Y_y(%!b4Qv29jv_1maENbmw^>~V3_xx48$A%%cAk4cK zt(P?dW2zdT5JR_hC3)oI7XJ)`F)9jK6~crR%zm$#b)$|fl$s$m?Y2|U-V zEs1oLPTAAm)w+KVKsiL>U@RRyk(e&YM3Yt+_Rpi%q!G@1H|RtiV&1Z6keONVQ<3O`gyok z$L~fMx~Sp+t~aHwCn3*vO!@5~uR6*--VN$Mu3=A~Y8ExywDKFp^=7-PGG(SAJ9QxW zOJ(m5PI!b*T+b}DGT`U=hd`!v&F!Z#hIwUiPlu?R0L#c9wY_axly_yg=TB-}H-47& zu`b}Gk8n%FIS0pxQmRKL0@v<=8@sl8E4VI_aYo{}*ZY-fPJ%B0?LDBOn(FdctuOJd zuoT_yTlSk5zzQuvY0JrQ`wyr?jE0%3D=(%vl9mznOy+5oBSBKZ$i_!2{y)Js)f}ZZ zLLc)jW_1PtYd=z90KuZS*Cqam!=hHbGl%*;3M>~!EkgOju`Ut2VFhEOR5DHvVo zx43JaP)vmmuhuQ{`7=|jo5AofQy6^A4v@mhst(mi$I+tAmSnSXd7b-3q`dOo;V8&o zYtNwzsAwA_T}|uvnEfRU{*l?>nme2^nbdbeLeln0 z3?nP!umF=+1yga{VN8*kWw@ebeaSm;^j%U-rXVZNF`D99+`khVu0!TS!C&6QPn;|{ zNm7ZJX|hW=>$o`(eOvtjvN9d#jpN|ru13&S@91AD~%JhqOFu7|)4Owv{7RcS7({q7tJ zztGP+kv;bl1f&4Y9JA`3*mxtlcWD>LcD3rq%{t<`;CcNPKMvK@QYw929)x%rROy|^rzE(J9LVrx0Kq)Q4Z%&yqJT$kyFcYd3gYp1j zK3mWV>yK#cR;r=cQQKo9@ZM-DTCk#xzzXp2^QI#%k#Dq4=UH(MbwXaqE(|F0H9)pIAQcB? zvg)34J4N1iI=H7aE#rK?kjp?{d54}1{88bg_o{r$!)0m>ClBpGTi;s20o=C79QZtM z3c{F&DqxpS`~NK4?>EHRGx1NB&0=(!S>7A8!Y(`~pKk%~Sh(Q*d34yj*D03TA|c|e zu>N5T@a|8zCjPUSaL7MlPlzW{W&~fur_6rP%5=gxxICpkl%RD7h^ zEdm5d_`C3<_h}R>v`B>HKEn$W$PYbx0R;P#sYmaAX&JX($e-ibF~=h|GwSGDMu*>N zerF{fcfe(MynsAZh*J>Fj=KUg2(Dj2^%dNFHR5Xo!N+!2m`$zU3P|mw{$4ViaB-)| zmARN2bBCQY3z&L=s`zJrJw!z4%2@dm-1M5SD0=2UqRc~tCxuZtZgWf~lMuMWawfc& zhi}}KwNs~szA>wLL1)_{so@ zbnL`Jbm+=X%k9sgA(clY6L#EFLjLAKb67>?RqdVzj{f7)b6yxVfe zhf7gJ%J8~Z^WHC!g^R7@g}_(?$r2l6Z{305`{8C_^X_>J`3$OapKX1t)fkye2WYa! z^e#3z>VabK^>-83S6IJ&%%0Z?te^znYxdZP=@o#DB5otW4MxCs9e% z?V>(>wkzf?nh`|7KkWM_EPBWYqQ7h$VUTaTb7v;?OzvY zSE_yy7dks2K`gW&WePq0Wrk03Q&bxD2fN}4(i@AfJNNHo420TW0Nvl<7p3s9V*X@W{~L=;H5pW=-!=gAQtS1kWFQKZD-QuNybq8j!(0zKCKHshM-(4ZfDEWk}Qn&A<$;R z{}qb0Px(!}L(02VNp1KV=I3Y#5PB*vFtO=PxXH^k)OP6pjwcwEoQfhuzFRD;DK;H(V8nHk z+LUm)6b7`tuW@lY!D7Y9aDGC{n0LeGSq1zOIZbX2G9nLHpeef0Vp}0zaIHo2gR`}5 zNy7Wz;@d6yPegFc1nHv)&y0;Fr^wr#u_osdp5yNgy^6fp~)~xk{0{ zY?#y0H)H_@dA7Y&5T%Ok=}?aab@HeI-z7jd*wMZK_O5C&^gLc&i$yTi+kb!pgY1Bz(N6n=uJyi8sZJkSq)v%K*CO7`h{?IEAdl#-E`yHih-Jp8DhasE9uWp z%eDop4tpFh>KJlXTLtMd2c2v~!pyx21{X4VB1)RDY)`uRrK9cZK6c$57`wDnBztX? zOBP-T{4w{n%%9_}uyHtd@YwB!baixg7cNNj^tPCF z7^+=0KOntF)KL-?oGu{6U^}w9urx36SiAMi-F{}nb_3UKLWS9(_9F!ovznPs3DZT~ zx_BCvw*%){l<75}GB<}(USHaAA$1SB@ar1P2<5iy8|gO4=jfS;f%d!>ZRN6#yZ5g5 zI^&!5S#+{p6)WR6hr7D5k}BY(YuUT$LKGxuBG7ZUcejXtjt?U;W`n8_sj1={d|_VuWd_ryh;}snRbj zu%Rh9gAZ0I$p^8y%TMOn|9s=JVxfk(g$#B0LShi4DJb%b&Mmk4m|N#>JN>MEj-|^b zVWRPsC08ZFCLg>e{4;5f}8wrpoezB(PO{VWZGz!vID+`)GSmqN0qC7OjKgq-icvh z$JrT_Ay4B7Y5)GLyAxTy&`##Ls6#prTW+GzV&6R;L}*b)3%~mEUFh9tqt*V_likP0 z%upI(w*kakEQRMZXqTN^$=rW3{@RpsFoI~5a!b>9pIMwbBf1~ z=qApsF7QYXO;v{E;#BTW&z8D$U5RRw*-G?bnD%W{XjxGMuQY~XFg-)h>nw-(R~K;j zqb{OJjXszMk-v4Qs$bs{Zx(q9K88G8*C$$!3|>)epNPr{Az#bcU#hXmX_R-o^IcKM zMp%Iaab6~K=|8Wa>!Tf$JaOq@%6(QgAjj{YMxYsf-Ln@OaR|r{pQ?N$4WC)378u=I ze5TIc`TgqGM%MNmjY=f&+6G$nIh70GtoGJ7;d8$HU`A||2IzXB2nT(e5OPN;BiU?? zHpav-FOMv>ll8N{j^15!zj`Vo2y-YvrK^W(+iMtg%Q7znY;f}at6ixZ52J-y3YEO8 zf>Ey_x!>q0Hr9y)0TTLz%*4dAL6|GK*E8hdYO&MeF<+u3P#*08&-QxE!BED581C}N zw4!p6CirILAl?<(|J2~)D`IGiccAE3=J`kW*v`?$ra+R4_mqDISXR(%M7?JlM~(ZW z47;MR`>fRJfX7q&kK8bzQ$uvMb)pj<(Ka;`JG zqArG>*xn2OAU^2j^RJ#y4!yW_d!-55ee*GW+g$T|ADsR(<5PpaFk1!P9XVo#X~cur7(rvH)b(&uDxt;4L1fAF20j7oYw#gNA;3 zZ6}OexX8m$6YkwAR7;n6aMnk0z%4a&O$4gGh@CZTi081L9t({4d3>cUYF<#0MX>S9Q(o4l8%7h({EC6!fn0b55(VvgxF;Hsc2SMrTc*$yrHI$q9WT4TZR(rzKxolE;XnS@fF`(_wN z<5&XJ-!U-UdN8`KZIdIKZte}cvRPE6HXAe#wK^R~{#+EMig>B$WxWmxmuILuFcNkC zkxUg|9u%h;@^q9OyzvDIFRt{5sgn3b9~`f57ynLN7KOY%MdWuz5r8u1Uq zkvp!im~9|x8|^tk&!@c6w%oB8W7VEy6@oj-Vk;dfm)6So?obzib5TjQh&7;unrE<0 z{q^J?Qzt4UPhCT-Q(0G*p4niO)_z4Pt}oZ-NzU~%lQ433l9GnWnyP?OY~LlsaA9RH z^}53UD*FN^$pAr9{HoVAGtQhl`6=+ph7S{Z9mMrPr12MwhhF|YMUr(T1`rig4nV!-Le9s$NzjwBg(bgv9-wJX9}$=HH;AH($+%fk={$D-p2t zPQd4wcOdW=VRq|5;u{u`xNT!Y-9JeW8uO_8a%2!hQR*r`X7;@8NaWLWE@40)yD zSm{oCkZ+bh&Yik{J$ZH;&8!1Ds?Z-1vo`&N@WEbfST%E+5J%zzVdo&n0I--#XXfF} zmjZ9tmk&=^YK-WkW60v$%QEfwmQ{e|BV~sz#aN@V6u67Cg7V!Khh|ti-@u1RRR*-v z91yt%bsX}zp8I`QLvT)6hHb7uqmd&y#B&E$GA>b}U=&G3&-8jt-1h>o2}Gn&SLZ+N zu2Tu2UVf>}SpDO${_0=G``ZcY z(tVYgTV&^X@}_RAZiLe***pBa9soZxx9U2}Cp4@{0?#Xp$gX?#G(}4brb~!dVhI|o$fq+##I=gfY3LhNLfGm-)#l4A%6MWr>cc^7 zcw*4{aZ7--w=RbX>zPc~212n-P{rDB8KT=J;e&e8_{C|0yI*o@y z?=I`Jp7YSk>*$kJaYceKAitAp_Efw=z1~1oKE;!MFO0`6Mh)5)cKhp{2RuqB8m%{(UFCA4|M%AJBe8LUrlvR9iQlPOq z&;|LNpjDXMo`$>5F9#6ntC4!IFl&OHQ$kOz2(dd8va4YELBs8B%e5NMl$yo^W8@%k z{CNQ$28P)f=cR-Y|Ms|b@p{5imwx>THTvyoD1ZeMrk9iYIZGYv<@k9l=K73y5tjBzP!HykZ3Q{a~sQws(sTeZF!}Kgv&>D)TWC@x2ipy}TKx=l8adxh!d&BM z@@^IJ>dCmiFgeVN+VL0njCWwxb8|oVh&gazU&eVz5KgZJD`pyV3_a(p`L=U=R|3%( zd-$bYMloxAg8BlmT~5kvHARI8|2PtMDa9Ln1^Fk5cBg|~Cx|qkYB0C%<8L%sUMRZU z6^?p`rbbcdACmI6U_I8w75LFui>G5fvxuK6i`zs6FX+O{g;PKa^{=^(NJ+o6j@X&{ z59l}o*}s1nFGO6XRx{0M+u${hko`A3j`sL-7ShO;7D9`3zDl-pXk`aP@OJzJkLTVl z)hOxAZ8iGj)Auycrl!0AP>Zu=2PN)zKoS~!O$8UE)DUKq<0BVA^xP_Ty?a6*yEcU; zU-!vjI;RSpv*Pa-$TE|%1o4QpwQ9Wpj+Z`74n7@__I)TcyDl2hXfvKkGYzrBT3!N{ z-h#+iNbg31*>^djLu{Wd`ijsF!F!!^*xhWi38!GY zCS^3TwbY+_Zy*5z!=_#-ZI?Nknjy~1gV%2nkSO3OhMAsG575!+=NBe|bicv3&Qm2@ zpSgbZIG6i#Ju8195>SL}T}M2%L^M#;)Z_0NMXI5)< zPvW6Es0cwqg4D`Uzp;{dANvU{I|bqtUCp2&qq^K)9Xdl^b006i(L#RdB-;v_O@*`8 zZJGZNP5-rrh3{A97=qij_bv#^N=|lV0w1wK>bCuI9}T6c1doX!ij#sq;Jfr$)&S~~ z0RkN!&EGwEXJH=20cB#Wb%ct6!^Iow-(Gf>sH z*s`!5mf{tbH%cUSkD3Vz*WT|@?c^^Ykqx*{o zo%Cq=x?8mCMJ=t>dVV+~-sku3RM=-N*S1G7%En4(g2h!VG6))N=YQcjvY@Mpi0eVU z(6>%&(#O5vT}9mhDL%$=c|(JEG*zZoh$h+13rPi~nE4w)l(RvLV+*~<(h_Z6t?db- zxbrh(i!UM^7khkRq9!~FZk8$V&xBOIt}1rFR{|Z$L)KP6lRxR@zI^rtrPt`ZN?Ryg zZ4~tjFq16b>7Z?HSx1pfXIAoq5rcxNR^+m`R;Uf6Kg4~>fe80U>wIs?s=Kwvm?15S z*A(EHAQ2qa#6)Wb>+K2ZHz-`J>S@!*Iwp5tY8+1@b5VfKX3vqZ>k0Mt*{Z#-Gm5{- z9oJx6s^R|>lMx4rYA0ltQE|Ch?`3hGcT^yX_lKIcL;CdHa$Um7I~4ZgdozEv#{GE) z1bnI;RK@jw(!|Qb2ra!%KX>F)iwzXK{)Mn2MA0>hM}?mB0!+Kp&?cM$P9sj2GF~nB8K42`ioSo+EQ%ZXi$9dub zp6x{aOvOrC9`Adh8L-jm}n z%>erHOy7c!;zm7B?;5njcFQeIn5p<7?YNLs+YnW8LF;7T>CSh56%&kvl7BQiJVLW6 zs^E<&^Zav()eVkY)7V!J8KLNr_hzs*XHa}u&aPvSrQj((6waG3%XHcIajzrytj3u2 ztgvY+uy-QSqgpsn?oOS|752{@iHn7U;D6QIlF;lGbN^XAF{6w2yLjxi?N&$$fT08h zDe0N}pLjne2r}$XPze@&c{-svB#s8J16WHDg9k2$A{}~A^2+6ShQ;$gb?sb-4> zq!J>S!TeAe;2)-N=~ET|A=`Faxu5a)yA+`~M!y2mE8f%KC(z^6Bg5j#`&K+O*n*yJ2kI+9byz53`#&W-}id%IgCm!glH53XSf7YrMIH)q0DZ zg{|j{l{%#Gfw$U8_E4s^@JHPxo7HFRnLju)MeDD>pUZ!kFG9tE@u7OU$_JSR%cA`> zr@|T5)Tq3`-TlpTJ1k=#U>UNcW#2d#ergBGw8mU(5u|xo@KN}0Rk0uaAPQ8Z=P&v< z-JV`*MFcWb(I}ua#cVb$L~!gqUqt_pmSY+CO)EKMiPjr5ng6K!*^#G?VpuJAGKg&o z#2cD0)#!(C+u}X#Y_wWrWYSA7TS{=(`}DllK<u^YzU^vF!8mROJe=%Zm2%Mo{!6+RD(h+F`p6+@_B_SO zEQF+}`(qOhuZ%po%LJ%7%_Uv&LaylJGsC~Gcm&Pbx=I=2&ap$*=|kHromEt11#Ok{ zX$smHQbd|>VlYI0zS@btTrU%7N3M_ z3i3j1(G~pn;5tK6*^P)TwI;F%Vn$9M;$B3Px@G!Y^$c!%wKL8_!+4sy6?d~(IG0+Z z%4&nvp{r4C9&xosv~HR4ezcOwk91OAk}Wj)Q~{zTbnbYeO>syz9yQ|*v`cb4Bp>J3 zoD!PMll)AoO%yVh&2+9kCLyvHMM!AxVcy$asQGUWCt7}V>u^B;rIS4pdt}z z@`nz*y^PJno`3>8Wfd!8Jbtlord+!e_(Ysd032%jru8UEi@5b953XKO`cD9&rebKt za9KK9-vXH|(G3*bEnEqKQ&+fBnm037&{dRjF`B!~ivmINtl9bxJS;IfG&}G=Hdu`zWl5CRUjYgt(a%`OMYO`>&!d!r zlbzz%Mgaaua?QKry+wk@d5gwpX8&VnzALiuBI>Z>4lEgCfF=OWzuCw63qEB;OhY!q zc#dX5-g@^@{+ad5O611UDq1x@qWv%(FEF^coO_dL_J4OHpYC$qe#u$!bB5Yf%Z_S> zyb#q`k2R9xvet|NlMv%`R{o>^wsA?2FXUSeoTiCDVU*(tY81z7LDDY_(8+3r&TriU9GX5*15Hl5;UBMvCSxREP01HgeIv;Ms2pvUp zQda$+S-RQBu359Gt7_7uO2p_R+!rTeK<=ccRgb0)8oM$iSGo>iF5tcCahE+4qj|@? z6ioO=dz;*?A0w*jt5f>!81SndnqW=jkz08elO6|mLRT2hh-JiDRt9*1J#d8pEG?$R zZQIw>fWqcnfOyT!7ryBI*1h*yN+~Dik=`+!Uqn+zj}J@I6umu(VK!DH6)pGKzYk)n zP=#thXIL4#*WEkUUx$BTF#3Bhg|E`~OI)*1Nyrdf#rJtfyRk*1P4i47r*XiUE6B0% zA)a|_C5$ZA;uG-K671;n_n%R}!tzbUCY&(lcIuz7nOm99?uzc>D~|_$WcdPY<%hhP z4?+0)H;#@`7+eP_H23qr8q#|LaUQLiG;1V*M4>Z%n^tE5mZT@&dv+S2UqUg`9peSi zJ)xf$E_4O^u>PZ%+(ZV*z5vW#sjRmiH2`$pd>(uAVLGRXyaY(Mvg_*P&Vsu``-d{` zz9g^9>>>*BlXQhYX^`akf{Og9jTS*joT63hXyK%`14VRMv5qFEoo=QVx|B~rx-w;G zh3m+)^^(m>Y-`&CN~m5dY!IK?eNtsK93UJB<_azVjwZq9LNN8d`RnRno~Ibss>!)I zYpUO_rt7&?#G~6K_Z|WWjjBAdyjP&L709bGdQ-eMff5rIBUmeSJjOjwZvv~%=F2A@ z=W!>Z2BxELZTR)%sdQKvFyu65`5b}A#r-5nF0oGqpqY9Nm9WX(w`Loz`1;x&m%YE6 zTf%sTBq91_%L2GI8oS9a6)q04m&;Z zhB4@Bxcr}K{Uv`9Sx@zQ2#>LhFxa*8(8v$2;*uDa_a2m>ce)*4J?yYZ(yKf!qhrI6 z&}}s&;tko-R?hDHbegi{*}Kfl);#dN5)leSbotJeNN{*CL}{l|tFFh_vd(@c;OiYh zkaJvDk+9}#MAclsg^Ng+f~qv4+~(fz>dE&~Rt}(@(KnsE02&gx=$f}nR?;{cBg(@Uq*r<1LRkjB8 zG&ec4X|PQTrpacPQ5Qdp=K>bVkSn`e5I>)gYV}V+2zpS^Pt=gqhpahe+l=}RzIKzqBxD_b-w!m%){?sIR^EM{NII=mb+T5sM zQB>0fZk0Dnw(9zirVuIeb{qOUYcl%J=d-B<8z=JZ zZ&K2x1Jtx)0A9^%h)WI3XrE)s{stGza&#hx| zl89P@KXjrWsU9=J80O|}8ieI*s&|l-$O>BQ8!?+pk~o4xYv2+l!pJU_Yc=lJKN$mh zd_k$m4_Pi)=9@bBZkdwa<;>yQc*ri-5zpKfw-3B~c6z+m+i!W7=}FNYiu5chlL@=O zhgREe&LVHtQn!dz=-@U%mJ>+)>6KI;c}Pq>?D+|}kQw-t80}xDs%zBFD@R#|e89ys z1l}FE5cA=qRx}H-x!nw2_218{C6whdhI;f!S+S%UG=*6W!ky!|>*z}bTu7s~tVpXG z-zo_G*3K>7M162r5(vW8S1K!^x~~-TA}L?|0Ow(!`h*tf4a#9E9mG|mZ8W!BVgj=J z*G2nChsOUZqu|f@UY*^2Q3i9((A|?_s)Jsk|m@?JZkh zV$vKv5wDXtvzVHhS_B_|nzfaV=4f&wZS;br@s}jxPqUa@v3Ok92O9ovTq$%@Hn^b- zE~)!G%LOZ!ul0nkCX{wy&>uB>(GgrsLe}S}*W8KpT!}u^(p+1~aIqDFyg7j}r(D0Q zXQtrIVgG}Ir-Lzf%K~aQ*h29+Z({-t(N~a1i8%6}HU){>Y4AQXN3%igy~Tv|t#e3@ zc#};*j^E-`qEe!dBg5(+EvwdCRQ3yXO_Qg(dMK4 z9U;r-IvJYVDQo?%GC=!nJ$TVoOT>*aBHK43#c|iTaK3=}s?ZvG>xzuwUi`8bvxcSg zb8C;nH#(kp3CStt<1+3gs9c0#cTRh=jo9EFe;aKg+flm&Y^bS4X1SRub(`NlOuNZ< zTc1{nXU%wrFyNtF6Oa`l1iv$n*+0KSn>zpOae+VXI9{^vUBnGKmsQ3hxB59j2G}S5 zLW(xLW@hoA9vX`u;SSP&oivp@T8RGdVT%5km*JUL194UodZTeA_>+nP019Kodfu4Q z$~PLkxO@WMU2`NxB#}HbzE(YDdSV=d-kbAWS4?Hr{#Sa?sn&w_ujTnN!w9K^htu3o zBV#gm?q{)Nkz1Kf4~^{j3xEU|RKy`*opw?ByPB*St+ohU5oaCY{Q+^GpZASv%QZk# z-G$AhtkLYZ`Z}i71o?I;rRrH`sIbxu`Strw6$sgF0HFH1T&2(bY^Sjca z>U64f0^iN#OnMSCBL7M27k~teo(i;9I23_pJm);Qx6epgRbypwOEv4)@fsA?9h2ch z*UXt3yS^hMrBv1=T+Kf6&Z!ERXT{KsCG<;0;9I*dGLWZ&G%o(+236hLJmCW8*KQkg zxi7!3m!7Fbxgs)jySWc%Hvp|lwpM@pO-nYsLpxRRH5bshm0%&u{M66aim;E4uwE?e z14mS$*1JFlC2d1UQ`TH*!*$#wA5yVZ>iuoU4+i{vc{gY5-j1Efc{PIM7zfu*zi(Mz zGiY^C?QF&T))0EOAqA%4uh(wnX94%*lj_Lw8eEsMqUrRuzrdYBW=l&IHl$=XxBT@K zHJd%CCMWh)c+~rxzMj6_EOe)x3ucP{>Ik?Q&P(4M6QcFaTGX`Sts?SHVU!rlP~)$< zS`(V$KiOJ~LZtWr>-Aq#t8DZ~Wy44dur7|3TVra&ssCH zG1JN)WA1AjtvXwE0RhcUoHj$P38G8-p)w-0E_ts(oE_+D zz}H34T%xCQ+cc|&?Whg5Kt^ojr}`-LgJ5OpvaX?ux+N3Xr zwy7=_W~{DL4t$k1D#EfvLd+_e3+`n1sWX%J!>XJ4VvkYoqkj(l zt(UC7e3FJJY6};ZqpLE>JzWWw&pcN+Dg}$gmpp7X=SgyTw6}%R5N$WA4E``G$b9Xg zO@8)=bg?B>GYT>zZyYLYju6#hh;Y<5Ds-Eiezw&`tiy1PIbj70ty!;2yJ^yJ(iJoB zR2ojS%PWbnCStkdk@KA^h}lC|)$bFqpP*YqU;AU?3Wiw5h=rE{yZi-u{;}kwY9DkA z$*)&CkW`sY&?}%M-Pnj%wifARVHJxN-oh0Jyor-`jYm~~n%c7CoEz5Gs1S=(!P&io z)tB}!4moFO&2u-uz6IgyBqGh+O73yHH?QR^;u9Wp$R2-sH)lhQl`)T3<;*MgO){d> zU9yu4jYQXGJJjT~`5fM89xt8jQ_})}MHfDVXVa!XlDA$VGbvq*McT;7f*(+k7Hd`? zzLNpSm=xlSN;`gRUwyvk*J!a-WL17tf!M0lj}ujsdmHMED0g%m%Fk2~x7P9!*;L?l z{jcu+Ps-E>_5;jMI(f<(N>URQ!jt;>116(n;)Y*+EaMMdIHX&EhI3Y*dx1O;Up0nO z3&>L7qHp;+Eta-2JUb&-w6dVr35?h8CqCWMoAiJ?_L=wVV=;+kdY)A03^~GSL^0T$QfLZZXu8Z>R z7eGr!I`73{VVU7W$=&SMY}M_z$RT7ed2=MQrx_i8urS)GkBmC@ie|StwpyJOsPFXhbb+9#4=`HXpQN9!auQnWuEf7< zR(k=wF7wM4lf`sSI-R=@<}LDV)^4c2!LB z2TB`3*{e;Ec8l5dM(!qR`0>}5-KZ3+X)-L||0b7+bAH=a(H$3lWv05RT(BYD@&J*3 zi}0lXJmW4xBBXperao-(cjs;1Bd^1g)REeAwyH>3y+JJr8X;E8lnJ*Xgqz* zuvF5(H&uq<3V>mBMU-mKt7mKpsmiCYacQb1>t!iGbzx4Qi?PQUf8x=-sq3hTL-H6E0kdoTgomW>W3oSIGcQAACT|? zf{!y1WqP>iOQm39PUyyPxhJF%L~3~uaW1f@L(1**2MShed?)J+L6M5GwJS3@!DmDg zK?CQ7j}HA;$r%Y%nmNP>K9Z&@$V~q1zDer?9(@HTh!g8hD|Ft}sk<T_v4Ym&ZtF+s%`mixm*BO3A6>U@>7n<--=cH(!q#bvEqK1oWa5S0) zpI!JTui8oOx5qcD3tf*@i0dy148|%{-R8$85Aon=rXUyg;A+^^w9M!4Hm5ZH55UuD z8Rxmx2U5^$9uCkvw8{$Fb2lyHDt~B#YvBVd;^w#>yUvg9mowssT#EVEGLy04FW#u8 z>t8U3j25@BtGO;YQbpj(5dKzjg$?>)PSw5ubT`zLz_;d4jQQ<)yBwh-t%m_A+TsOA zG6Z6==sG1^I#r;pZAh04;fO|AGtkVEdv4*UYx8avOA-t^60!&XO1d?bP2wK@^W zYDSF#G)W(xcz7XIWm^bR#u^n9^i3%j2}FIB5|Y6yj%E=LuPgzsmLk1%I>^87A!jz3 zJ4CdmI@7fBEa}gf-)4L2Lu?YNE55g-F@dO@mH{u^#XT6LC%gbEZIMb9muMCr1LB3d z(6o}jlFxm}(Vi65?JTZ(?~A99z5pt08LNxxevPWGS2PiPk@^_W#0vC@W|YBidO!8d zm>)kidkZ2(!sT;nG75zryvHwqd0>?i+C~y`yzU}QL?!zvD9<|&(=s%r6|RUvB#VCi z9#RSlBhcVVK)C`c%Dw>98S_hb(^Z^0A*7-H%Zz0S8B1pV%Mvru%#?rU;@t}W$q+2P zW1>BfA}pa7SD{(tgWt;5QBWC-c<>iz%9Gv*i8IyQ3XGZx;y zMTTl@9mx=uuTC0#&^bjAbnWL?5yvRV5KKM1o2!_KW;6vp@x8y|Ra1zyvPFK;>gD(U E0HD4400000 literal 0 HcmV?d00001 diff --git a/keywords.txt b/keywords.txt index c463c69..0f2fe20 100644 --- a/keywords.txt +++ b/keywords.txt @@ -225,7 +225,6 @@ isHighThreshold KEYWORD2 setPins KEYWORD2 setBootFromFlash KEYWORD2 getHandler KEYWORD2 -printSensors KEYWORD2 printInfo KEYWORD2 setInterruptCtrl KEYWORD2 getInterruptCtrl KEYWORD2 @@ -245,6 +244,11 @@ getScaling KEYWORD2 setFirmware KEYWORD2 getSensorName KEYWORD2 getAccuracy KEYWORD2 +getPhySensorInfo KEYWORD2 +getSensorInfo KEYWORD2 +disableGpio KEYWORD2 +setDebug KEYWORD2 +setDebugCallback KEYWORD2 ### SensorBMA423 Coloring Map ### enablePowerSave KEYWORD2 diff --git a/library.json b/library.json index c708174..cc7f4d6 100644 --- a/library.json +++ b/library.json @@ -1,6 +1,6 @@ { "name": "SensorLib", - "version": "0.2.6", + "version": "0.3.0", "description": "Commonly used I2C , SPI device multi-platform libraries", "keywords": "QMC6310, QMI8658, PCF8563, PCF85063, XL9555, BMA423, BHI260AP, DRV2605, CM32181, LTR553, FT5206, FT3267, FT6236, FT6336, CST816S,CST816T,CST816D, CST820, CST226, CHSC5816, GT911, CST9217, CST9220, AW9364", "authors": [ diff --git a/library.properties b/library.properties index 164da3c..b4c18bd 100644 --- a/library.properties +++ b/library.properties @@ -1,5 +1,5 @@ name=SensorLib -version=0.2.6 +version=0.3.0 author=Lewis He maintainer=Lewis He sentence=Commonly used I2C , SPI device multi-platform libraries diff --git a/platformio.ini b/platformio.ini index 7f70efb..eaeebe3 100644 --- a/platformio.ini +++ b/platformio.ini @@ -9,66 +9,91 @@ ; https://docs.platformio.org/page/projectconf.html [platformio] -; src_dir = examples/BMA423_Accelerometer -; src_dir = examples/BMA423_Temperature -; src_dir = examples/BMA423_Feature -; src_dir = examples/BMA423_Orientation -; src_dir = examples/PCF8563_AlarmByUnits -; src_dir = examples/PCF8563_SimpleTime -; src_dir = examples/PCF8563_TimeLib -; src_dir = examples/PCF8563_TimeSynchronization -; src_dir = examples/PCF85063_SimpleTime -; src_dir = examples/PCF85063_AlarmByUnits -; src_dir = examples/PCF8563_ClockOutput -; src_dir = examples/PCF85063_ClockOutput -; src_dir = examples/QMC6310_CalibrateExample -; src_dir = examples/QMC6310_CompassExample -; src_dir = examples/QMC6310_GetDataExample -; src_dir = examples/QMC6310_GetPolarExample -; src_dir = examples/QMI8658_BlockExample -; src_dir = examples/QMI8658_CalibrationExample -; src_dir = examples/QMI8658_GetDataExample -; src_dir = examples/QMI8658_InterruptBlockExample -; src_dir = examples/QMI8658_InterruptExample -; src_dir = examples/QMI8658_LockingMechanismExample -; src_dir = examples/QMI8658_MadgwickAHRS -; src_dir = examples/QMI8658_PedometerExample -; src_dir = examples/QMI8658_ReadFromFifoExample -; src_dir = examples/QMI8658_WakeOnMotion -; src_dir = examples/QMI8658_WakeOnMotionCallBackExample -; src_dir = examples/XL9555_ExtensionIOInterrupt -; src_dir = examples/XL9555_ExtensionIORead -; src_dir = examples/XL9555_ExtensionIOWrite -; src_dir = examples/XL9555_Event -; src_dir = examples/XL9555_AdjustBacklight -; src_dir = examples/AW9364_LedDriver -; src_dir = examples/DRV2605_Basic -; src_dir = examples/CM32181_LightSensor -; src_dir = examples/CM32181_LightSensorInterrupt -; src_dir = examples/LTR553ALS_Sensor -; src_dir = examples/BHI260AP_6DoF -; src_dir = examples/BHI260AP_Orientation -; src_dir = examples/BHI260AP_StepCounter -; src_dir = examples/BHI260AP_DebugInfo -; src_dir = examples/BHI260AP_aux_BMM150 -; src_dir = examples/BHI260AP_aux_BMM150_euler -; src_dir = examples/BHI260AP_aux_BMM150_quaternion -; src_dir = examples/BHI260AP_aux_BMM150_BME280 -; src_dir = examples/BHI260AP_aux_BMM150_BME280_Expand_GPIO -; src_dir = examples/BHI260AP_UpdateFirmware -; src_dir = examples/BMM150_GetDataExample - - -; Touch devices support list -; src_dir = examples/TouchDrv_FT3267_LilyGo_T_RGB -; src_dir = examples/TouchDrv_GT911_LilyGo_T_RGB -; src_dir = examples/TouchDrv_Interface_T_RGB -; src_dir = examples/TouchDrv_FT6232_GetPoint -; src_dir = examples/TouchDrv_GT911_GetPoint -; src_dir = examples/TouchDrv_CHSC5816_GetPoint -; src_dir = examples/TouchDrv_CSTxxx_GetPoint -; src_dir = examples/TouchDrv_CST9217_GetPoint -; src_dir = examples/TouchDrv_GT9895_GetPoint +; !LedDriver +# src_dir = examples/AW9364_LedDriver + +; !Fuel gauge +# src_dir = examples/BQ27220_GaugeExample + +; !Haptic Driver +# src_dir = examples/DRV2605_Basic + +; !Light Sensor +# src_dir = examples/LTR553ALS_Sensor +# src_dir = examples/CM32181_LightSensor +# src_dir = examples/CM32181_LightSensorInterrupt + +; !Real-time clock +# src_dir = examples/PCF85063_AlarmByUnits +# src_dir = examples/PCF85063_ClockOutput +# src_dir = examples/PCF85063_SimpleTime + +# src_dir = examples/PCF8563_AlarmByUnits +# src_dir = examples/PCF8563_ClockOutput +# src_dir = examples/PCF8563_SimpleTime +# src_dir = examples/PCF8563_TimeLib +# src_dir = examples/PCF8563_TimeSynchronization + +; !IMU examples +# src_dir = examples/BHI260AP_6DoF +# src_dir = examples/BHI260AP_Expand_GPIO +# src_dir = examples/BHI260AP_Orientation +# src_dir = examples/BHI260AP_StepCounter +# src_dir = examples/BHI260AP_UpdateFirmware +# src_dir = examples/BHI260AP_aux_BMM150 +# src_dir = examples/BHI260AP_aux_BMM150_BME280 +# src_dir = examples/BHI260AP_aux_BMM150_BME280_Expand_GPIO +# src_dir = examples/BHI260AP_aux_BMM150_euler +# src_dir = examples/BHI260AP_aux_BMM150_quaternion + +# src_dir = examples/QMI8658_BlockExample +# src_dir = examples/QMI8658_CalibrationExample +# src_dir = examples/QMI8658_GetDataExample +# src_dir = examples/QMI8658_InterruptBlockExample +# src_dir = examples/QMI8658_InterruptExample +# src_dir = examples/QMI8658_LockingMechanismExample +# src_dir = examples/QMI8658_MadgwickAHRS +# src_dir = examples/QMI8658_MotionDetectionExample +# src_dir = examples/QMI8658_PedometerExample +# src_dir = examples/QMI8658_ReadFromFifoExample +# src_dir = examples/QMI8658_TapDetectionExample +# src_dir = examples/QMI8658_WakeOnMotion +# src_dir = examples/QMI8658_WakeOnMotionCallBackExample + +; !Magnetometer +# src_dir = examples/QMC6310_CalibrateExample +# src_dir = examples/QMC6310_CompassExample +# src_dir = examples/QMC6310_GetDataExample +# src_dir = examples/QMC6310_GetPolarExample + +# src_dir = examples/BMM150_GetDataExample + +; !Accelerometer +# src_dir = examples/BMA423_Accelerometer +# src_dir = examples/BMA423_Feature +# src_dir = examples/BMA423_Orientation +# src_dir = examples/BMA423_Temperature + +; !GPIO Expansion examples +# src_dir = examples/XL9555_AdjustBacklight +# src_dir = examples/XL9555_ExtensionIOInterrupt +# src_dir = examples/XL9555_ExtensionIORead +# src_dir = examples/XL9555_ExtensionIOWrite +# src_dir = examples/XL9555_ioEvent + + +# src_dir = examples/CustomCallbackTouchDrvInterface +# src_dir = examples/CustomCallbackUsageExamples +# src_dir = examples/SensorWireHelper + +; !Touch devices support list +# src_dir = examples/TouchDrvInterface_Example +# src_dir = examples/TouchDrv_CHSC5816_GetPoint +# src_dir = examples/TouchDrv_CST9217_GetPoint +# src_dir = examples/TouchDrv_CSTxxx_GetPoint +# src_dir = examples/TouchDrv_FT6232_GetPoint +# src_dir = examples/TouchDrv_GT911_GetPoint +# src_dir = examples/TouchDrv_GT9895_GetPoint ; default_envs = esp32dev default_envs = esp32s3 @@ -77,8 +102,6 @@ default_envs = esp32s3 ; default_envs = nrf52840 ; default_envs = stm32 -; Custom board variant -boards_dir = ./board [env] lib_extra_dirs = . diff --git a/src/DevicesPins.h b/src/DevicesPins.h index 5d9153d..4250b3a 100644 --- a/src/DevicesPins.h +++ b/src/DevicesPins.h @@ -32,16 +32,16 @@ #if defined(ARDUINO_T_DECK) // T-Deck GT911 -#define SENSOR_SDA 18 -#define SENSOR_SCL 8 -#define SENSOR_IRQ 16 -#define SENSOR_RST -1 +#define TOUCH_SDA 18 +#define TOUCH_SCL 8 +#define TOUCH_IRQ 16 +#define TOUCH_RST -1 #elif defined(ARDUINO_T_AMOLED_191) // T-Display-AMOLED 1.91 Inch CST816T✅ -#define SENSOR_SDA 3 -#define SENSOR_SCL 2 -#define SENSOR_IRQ 21 -#define SENSOR_RST -1 +#define TOUCH_SDA 3 +#define TOUCH_SCL 2 +#define TOUCH_IRQ 21 +#define TOUCH_RST -1 #elif defined(ARDUINO_T_AMOLED_191_QWIIC) // T-Display-AMOLED 1.91 Inch QWIIC #define SENSOR_SDA 3 @@ -50,16 +50,19 @@ #define SENSOR_RST 44//RX #elif defined(ARDUINO_T_AMOLED_241) // T4-S3 CST226SE ✅ -#define SENSOR_SDA 6 -#define SENSOR_SCL 7 -#define SENSOR_IRQ 8 -#define SENSOR_RST 17 +#define TOUCH_SDA 6 +#define TOUCH_SCL 7 +#define TOUCH_IRQ 8 +#define TOUCH_RST 17 #elif defined(ARDUINO_T_AMOLED_147) // T-Display-Lite 1.47 Inch CHSC5816 ✅ #define SENSOR_SDA 1 #define SENSOR_SCL 2 -#define SENSOR_IRQ 13 -#define SENSOR_RST 14 +#define SENSOR_IRQ 8 +#define TOUCH_SDA 1 +#define TOUCH_SCL 2 +#define TOUCH_RST 14 +#define TOUCH_IRQ 13 #elif defined(ARDUINO_T_DISPLAY_S3_PRO) // T-Display-S3-Pro CST226SE✅ #define SENSOR_SDA 5 @@ -84,7 +87,38 @@ #define SENSOR_SCL 3 #define SENSOR_IRQ 12 #define SENSOR_RST 16 - +#elif defined(ARDUINO_T_WATCH_S3) +// T-Watch-S3 +#define SENSOR_SDA 10 +#define SENSOR_SCL 11 +#define PCF8563_IRQ 17 +#define BMA423_IRQ 14 +#define FT6336_SDA 39 +#define FT6336_SCL 40 +#define FT6336_IRQ 16 +#elif defined(ARDUINO_T_BEAM_S3_SUPREME) +#define OLED_SDA (17) +#define OLED_SCL (18) +#define SPI_MOSI (35) +#define SPI_SCK (36) +#define SPI_MISO (37) +#define SPI_CS (47) +#define IMU_CS (34) +#define IMU_IRQ (33) //INTERRUPT PIN1 & PIN2 ,Use or logic to form a pin +#define RTC_IRQ (14) +#define RTC_PMU_SDA (42) +#define RTC_PMU_SCL (41) +#elif defined(ARDUINO_BHI260_SENSOR) +#define SPI_MOSI 33 +#define SPI_MISO 34 +#define SPI_SCK 35 +#define BHI260_CS 36 +#define BHI260_IRQ 37 +#define BHI260_RST 47 +#define BHI260_POWER 48 +#define SENSOR_SDA 9 +#define SENSOR_SCL 8 +#define USE_SPI_INTERFACE 1 #endif diff --git a/src/ExtensionIOXL9555.hpp b/src/ExtensionIOXL9555.hpp index 3a9c775..07c58f8 100644 --- a/src/ExtensionIOXL9555.hpp +++ b/src/ExtensionIOXL9555.hpp @@ -30,8 +30,8 @@ #pragma once #include "REG/XL9555Constants.h" -#include "SensorCommon.tpp" -#include "ExtensionSPI.tpp" +#include "SensorPlatform.hpp" +#include "ExtensionSPI.hpp" #include "VirtualGpio.hpp" typedef void (*gpio_event_t)(void *user_data); @@ -49,10 +49,9 @@ typedef struct ioEvent { class ExtensionIOXL9555 : public VirtualGpio, - public SensorCommon, + public XL95xxConstants, public ExtensionSPI { - friend class SensorCommon; friend class ExtensionSPI; public: @@ -81,46 +80,66 @@ class ExtensionIOXL9555 : IO15, }; + ExtensionIOXL9555() : comm(nullptr) {} -#if defined(ARDUINO) - ExtensionIOXL9555(PLATFORM_WIRE_TYPE &w, int sda = DEFAULT_SDA, int scl = DEFAULT_SCL, uint8_t addr = XL9555_UNKOWN_ADDRESS) + ~ExtensionIOXL9555() { - __wire = &w; - __sda = sda; - __scl = scl; - __addr = addr; + if (comm) { + comm->deinit(); + } } -#endif - ExtensionIOXL9555() - { #if defined(ARDUINO) - __wire = &Wire; - __sda = DEFAULT_SDA; - __scl = DEFAULT_SCL; -#endif - __addr = XL9555_UNKOWN_ADDRESS; + bool begin(TwoWire &wire, uint8_t addr = XL9555_UNKOWN_ADDRESS, int sda = -1, int scl = -1) + { + comm = std::make_unique(wire, addr, sda, scl); + if (!comm) { + return false; + } + comm->init(); + return initImpl(addr); } - ~ExtensionIOXL9555() +#elif defined(ESP_PLATFORM) + +#if defined(USEING_I2C_LEGACY) + bool begin(i2c_port_t port_num, uint8_t addr = XL9555_UNKOWN_ADDRESS, int sda = -1, int scl = -1) { - deinit(); + comm = std::make_unique(port_num, addr, sda, scl); + if (!comm) { + return false; + } + comm->init(); + return initImpl(addr); } - -#if defined(ARDUINO) - bool init(PLATFORM_WIRE_TYPE &w, int sda = DEFAULT_SDA, int scl = DEFAULT_SCL, uint8_t addr = XL9555_UNKOWN_ADDRESS) +#else + bool begin(i2c_master_bus_handle_t handle, uint8_t addr = XL9555_UNKOWN_ADDRESS) { - return SensorCommon::begin(w, addr, sda, scl); + comm = std::make_unique(handle, addr); + if (!comm) { + return false; + } + comm->init(); + return initImpl(addr); } -#endif +#endif //ESP_PLATFORM +#endif //ARDUINO + bool begin(SensorCommCustom::CustomCallback callback, uint8_t addr) + { + comm = std::make_unique(callback, addr); + if (!comm) { + return false; + } + comm->init(); + return initImpl(addr); + } void deinit() { // end(); } - void pinMode(uint8_t pin, uint8_t mode) { uint8_t registers = 0; @@ -132,10 +151,10 @@ class ExtensionIOXL9555 : } switch (mode) { case INPUT: - setRegisterBit(registers, pin); + comm->setRegisterBit(registers, pin); break; case OUTPUT: - clrRegisterBit(registers, pin); + comm->clrRegisterBit(registers, pin); break; default: break; @@ -151,7 +170,7 @@ class ExtensionIOXL9555 : } else { registers = XL9555_CTRL_INP0; } - return getRegisterBit(registers, pin); + return comm->getRegisterBit(registers, pin); } void digitalWrite(uint8_t pin, uint8_t val) @@ -163,7 +182,7 @@ class ExtensionIOXL9555 : } else { registers = XL9555_CTRL_OUTP0; } - val ? setRegisterBit(registers, pin) : clrRegisterBit(registers, pin); + val ? comm->setRegisterBit(registers, pin) : comm->clrRegisterBit(registers, pin); } // Invert gpio @@ -176,20 +195,20 @@ class ExtensionIOXL9555 : // Read 8-bit gpio input status int readPort(uint8_t port) { - return readRegister(port == PORT0 ? XL9555_CTRL_INP0 : XL9555_CTRL_INP1); + return comm->readRegister(port == PORT0 ? XL9555_CTRL_INP0 : XL9555_CTRL_INP1); } // Write 8 bits of data to the specified port int writePort(uint8_t port, uint8_t mask) { - return writeRegister(port == PORT0 ? XL9555_CTRL_OUTP0 : XL9555_CTRL_OUTP1, mask); + return comm->writeRegister(port == PORT0 ? XL9555_CTRL_OUTP0 : XL9555_CTRL_OUTP1, mask); } // Read 16-bit gpio input status uint16_t read() { uint16_t val = 0x0; - readRegister(XL9555_CTRL_INP0, (uint8_t *)&val, 2); + comm->readRegister(XL9555_CTRL_INP0, (uint8_t *)&val, 2); return val; } @@ -197,19 +216,19 @@ class ExtensionIOXL9555 : void write(uint16_t value) { uint8_t buffer[2] = {highByte(value), lowByte(value)}; - writeRegister(XL9555_CTRL_OUTP0, buffer, 2); + comm->writeRegister(XL9555_CTRL_OUTP0, buffer, 2); } // Read the specified port configuration status int readConfig(uint8_t port) { - return readRegister(port == PORT0 ? XL9555_CTRL_CFG0 : XL9555_CTRL_CFG1); + return comm->readRegister(port == PORT0 ? XL9555_CTRL_CFG0 : XL9555_CTRL_CFG1); } // Configure the specified port as input or output , 0xFF = all pin input , 0x00 = all pin output int configPort(uint8_t port, uint8_t mask) { - return writeRegister(port == PORT0 ? XL9555_CTRL_CFG0 : XL9555_CTRL_CFG1, mask); + return comm->writeRegister(port == PORT0 ? XL9555_CTRL_CFG0 : XL9555_CTRL_CFG1, mask); } void setPinEvent(uint8_t pin, uint8_t mode, gpio_event_t event, void *user_data) @@ -259,43 +278,43 @@ class ExtensionIOXL9555 : val >>= 1; } } + void setClock(uint32_t frequency) { - SensorCommon::setClock(frequency); + //TODO: } uint32_t getClock() { - return SensorCommon::getClock(); + //TODO: + return 0; } private: - bool initImpl() + + bool initImpl(uint8_t addr) { - if (__addr == XL9555_UNKOWN_ADDRESS) { - for (uint8_t addr = XL9555_SLAVE_ADDRESS0; addr <= XL9555_SLAVE_ADDRESS7; ++addr) { - if (probe(addr)) { - log_e("Found the xl9555 chip address is 0x%X", addr); - __addr = addr; + if (addr == XL9555_UNKOWN_ADDRESS) { + log_d("Try to automatically discover the device"); + for (uint8_t a = XL9555_SLAVE_ADDRESS0; a <= XL9555_SLAVE_ADDRESS7; ++a) { + I2CParam params(I2CParam::I2C_SET_ADDR, a); + comm->setParams(params); + log_d("Try to use 0x%02x address.", a); + if (comm->readRegister(XL9555_CTRL_INP0) != -1) { + log_d("Found the xl9555 chip address is 0x%X", a); return true; } } log_e("No found xl9555 chip ..."); return false; } - return probe(); - } - - int getReadMaskImpl() - { - return -1; + if (comm->readRegister(XL9555_CTRL_INP0) < 0 ) { + return false; + } + return true; } ioEvent_t event[16]; - protected: uint32_t _frequency; - + std::unique_ptr comm; }; - - - diff --git a/src/ExtensionSPI.tpp b/src/ExtensionSPI.hpp similarity index 94% rename from src/ExtensionSPI.tpp rename to src/ExtensionSPI.hpp index 2c002cc..aea5699 100644 --- a/src/ExtensionSPI.tpp +++ b/src/ExtensionSPI.hpp @@ -49,12 +49,12 @@ class ExtensionSPI thisChip().pinMode(_mosi, OUTPUT); thisChip().pinMode(_sck, OUTPUT); - if (_cs != SENSOR_PIN_NONE) { + if (_cs != -1) { thisChip().pinMode(_cs, OUTPUT); thisChip().digitalWrite(_cs, HIGH); } - if (_miso != SENSOR_PIN_NONE) { + if (_miso != -1) { thisChip().pinMode(_miso, INPUT); } thisChip().digitalWrite(_mosi, HIGH); @@ -81,13 +81,13 @@ class ExtensionSPI { uint32_t mask = _BV(bits - 1); uint8_t out = 0; - if (_cs != SENSOR_PIN_NONE) { + if (_cs != -1) { thisChip().digitalWrite(_cs, LOW); } for (int i = 0; i < bits ; i++) { thisChip().digitalWrite(_sck, LOW); out <<= 1; - if (_miso != SENSOR_PIN_NONE) { + if (_miso != -1) { if (thisChip().digitalRead(_miso)) { out |= 0x01; } @@ -96,7 +96,7 @@ class ExtensionSPI val <<= 1; thisChip().digitalWrite(_sck, HIGH); } - if (_cs != SENSOR_PIN_NONE) { + if (_cs != -1) { thisChip().digitalWrite(_cs, HIGH); } return out; diff --git a/src/GaugeBQ27220.hpp b/src/GaugeBQ27220.hpp new file mode 100644 index 0000000..d230189 --- /dev/null +++ b/src/GaugeBQ27220.hpp @@ -0,0 +1,734 @@ +/** + * + * @license MIT License + * + * Copyright (c) 2025 lewis he + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * @file GaugeBQ27220.hpp + * @author Lewis He (lewishe@outlook.com) + * @date 2025-01-16 + * + */ +#pragma once + +#include "REG/BQ27220Constants.h" +#include "SensorPlatform.hpp" + +typedef struct { + //* Reserved bits + // bool RSV[6]; + //* The fuel gauge is in CONFIG UPDATE mode. Fuel gauging is suspended. + bool CFGUPDATE; + //* Reserved bits + // bool RSV2; + //* Flag indicating that the BTP threshold has been exceeded. + bool BTPINT; + //* Indicates that the RemainingCapacity() accumulation is currently being throttled by the smoothing engine. + bool SMTH; + //* Indicates whether the fuel gauge initialization is complete. This bit can only be set when a + //* battery is present. True when set. + bool INITCOMP; + //* Indicates whether the current discharge cycle complies or does not comply with the requirements of the FCC update. + //* The discharge cycle that is effective for the FCC update is set. + bool VDQ; + //* Indicates whether the measured battery voltage is above or below the EDV2 threshold. If set, indicates below. + bool EDV2; + //* Define current security access + //* 11 = Sealed Access + //* 10 = Unblock access + //* 01 = Full access + uint8_t SEC; + //* Use the 0x2D command to toggle to enable/disable CALIBRATION mode + bool CALMD; +} OperationStatus_t; + +typedef struct { + //* Full discharge detected. This flag is set and cleared based on the SOC + //* Flag Config B option selected. + bool FD; + //* OCV measurement update is complete. True when set + bool OCVCOMP; + //* Status bit indicating that an OCV read failed due to current. + //* This bit can only be set if a battery is present after receiving an OCV_CMD(). True when set + bool OCVFAIL; + //* The device operates in SLEEP mode when set. + //* This bit will be temporarily cleared during AD measurements in SLEEP mode. + bool SLEEP; + //* Over-temperature is detected during charging. If Operation Config B [INT_OT] bit = 1, + //* the SOC_INT pin toggles once when the [OTC] bit is set. + bool OTC; + //* Over-temperature detected during discharge condition. True when set. If Operation Config B [INT_OT] bit = 1, + //* the SOC_INT pin toggles once when the [OTD] bit is set. + bool OTD; + //* Full charge detected. This flag is set and cleared based on the SOC Flag Config A and SOC Flag Config B options selected. + bool FC; + //* Charge Inhibit: If set, indicates that charging should not begin because the Temperature() is outside the range + //* [Charge Inhibit Temp Low, Charge Inhibit Temp High]. True when set + bool CHGINH; + //* Reserve + // bool RSVD; + //* Termination of charging alarm. This flag is set and cleared based on the selected SOC Flag Config A option. + bool TCA; + //* A good OCV measurement was made. True when set + bool OCVGD; + //* Detects inserted battery. True when set. + bool AUTH_GD; + //* Battery presence detected. True when set. + bool BATTPRES; + //* Termination discharge alarm. This flag is set and cleared according to the selected SOC Flag Config A option. + bool TDA; + //* System shutdown bit indicating that the system should be shut down. True when set. If set, the SOC_INT pin toggles once. + bool SYSDWN; + //* When set, the device is in DISCHARGE mode; when cleared, the device is in CHARGING or RELAXATION mode. + bool DSG; +} BatteryStatus_t; + + + +class GaugeBQ27220 : public BQ27220Constants +{ +public: + + enum Access { + FULL_ACCESS = 1, + UNBLOCK_ACCESS, + SEALED_ACCESS, + }; + + GaugeBQ27220() : comm(nullptr), hal(nullptr) {} + + ~GaugeBQ27220() + { + if (comm) { + comm->deinit(); + } + } + +#if defined(ARDUINO) + bool begin(TwoWire &wire, int sda = -1, int scl = -1) + { + if (!beginCommon(comm, hal, wire, BQ27220_SLAVE_ADDRESS, sda, scl)) { + return false; + } + return initImpl(); + } + +#elif defined(ESP_PLATFORM) + +#if defined(USEING_I2C_LEGACY) + bool begin(i2c_port_t port_num, int sda = -1, int scl = -1) + { + if (!beginCommon(comm, hal, port_num, BQ27220_SLAVE_ADDRESS, sda, scl)) { + return false; + } + return initImpl(); + } +#else + bool begin(i2c_master_bus_handle_t handle) + { + if (!beginCommon(comm, hal, handle, BQ27220_SLAVE_ADDRESS)) { + return false; + } + return initImpl(); + } +#endif //ESP_PLATFORM +#endif //ARDUINO + + bool begin(SensorCommCustom::CustomCallback callback, + SensorCommCustomHal::CustomHalCallback hal_callback) + { + if (!beginCommCustomCallback(COMM_CUSTOM, + callback, hal_callback, BQ27220_SLAVE_ADDRESS, comm, hal)) { + return false; + } + return initImpl(); + } + + // Negative value indicates discharge current value + // The unit is mA. + int getAtRate() + { + return getHalfWord(BQ27220_REG_STA_AT_RATE_TIME_TO_EMPTY); + } + + // The unit is minutes + uint16_t getAtRateTimeToEmpty() + { + return getHalfWord(BQ27220_REG_STA_AT_RATE); + } + + // This read and write word function returns the unsigned integer value of + // the temperature measured by the fuel gauge. + // The unit is Celsius + float getTemperature() + { + return (getHalfWord(BQ27220_REG_STA_NTC_TEMP) * 0.1f) - 273.15f; + } + + // This value represents the measured battery pack voltage in mV, ranging from 0 to 6000mV. + // The unit is mV. + uint16_t getBatteryVoltage() + { + return getHalfWord(BQ27220_REG_STA_BAT_VOLTAGE); + } + + // The Read Word function returns the contents of the Fuel Gauge + // Status Register, describing the current battery status. + // Returns the full two bytes + uint16_t getBatteryStatusRaw() + { + return getHalfWord(BQ27220_REG_STA_BAT_STATUS); + } + + BatteryStatus_t getBatteryStatus() + { + BatteryStatus_t status; + uint16_t value = getHalfWord(BQ27220_REG_STA_BAT_STATUS); + uint8_t highByte = (value >> 8) & 0xFF; + uint8_t lowByte = value & 0xFF; + + status.FD = (highByte & _BV(7)) != 0; + status.OCVCOMP = (highByte & _BV(6)) != 0; + status.OCVFAIL = (highByte & _BV(5)) != 0; + status.SLEEP = (highByte & _BV(4)) != 0; + status.OTC = (highByte & _BV(3)) != 0; + status.OTD = (highByte & _BV(2)) != 0; + status.FC = (highByte & _BV(1)) != 0; + status.CHGINH = (highByte & _BV(0)) != 0; + + // status.RSVD = (lowByte & (1 << 7))!= 0; + status.TCA = (lowByte & _BV(6)) != 0; + status.OCVGD = (lowByte & _BV(5)) != 0; + status.AUTH_GD = (lowByte & _BV(4)) != 0; + status.BATTPRES = (lowByte & _BV(3)) != 0; + status.TDA = (lowByte & _BV(2)) != 0; + status.SYSDWN = (lowByte & _BV(1)) != 0; + status.DSG = (lowByte & _BV(0)) != 0; + return status; + } + + // The instantaneous current in the sense resistor. + // It is updated once per second. The unit is mA. + int getInstantaneousCurrent() + { + return getHalfWord(BQ27220_REG_STA_CURRENT); + } + + // The unit is mAh. + uint16_t getRemainingCapacity() + { + return getHalfWord(BQ27220_REG_STA_REMAINING_CAPACITY); + } + + // The unit is mAh + uint16_t getFullChargeCapacity() + { + return getHalfWord(BQ27220_REG_STA_FULL_CHARGE_CAPACITY); + } + + // The unit is minutes + uint16_t getTimeToEmpty() + { + uint16_t value = getHalfWord(BQ27220_REG_STA_TIME_TO_EMPTY); + if (value == 0xFFFF) { + return 0; + } + return value; + } + + // The unit is minutes + uint16_t getTimeToFull() + { + uint16_t value = getHalfWord(BQ27220_REG_STA_TIME_TO_FULL); + if (value == 0xFFFF) { + return 0; + } + return value; + } + + // Standby current measured by sense resistor + // The unit is mA + int getStandbyCurrent() + { + return getHalfWord(BQ27220_REG_STA_STANDBY_CURRENT); + } + + // Predicted remaining battery life in minutes at standby discharge rate + // The unit is minutes + uint16_t getStandbyTimeToEmpty() + { + uint16_t value = getHalfWord(BQ27220_REG_STA_STANDBY_TIME_TO_EMPTY); + if (value == 0xFFFF) { + return 0; + } + return value; + } + + // Signed integer value in mA at maximum load + int getMaxLoadCurrent() + { + return getHalfWord(BQ27220_REG_STA_MAX_LOAD_CURRENT); + } + + // Predicted remaining battery life in minutes at maximum load current discharge rate + uint16_t getMaxLoadTimeToEmpty() + { + return getHalfWord(BQ27220_REG_STA_MAX_LOAD_TO_EMPTY); + } + + // The amount of coulombs transferred from a battery during charge/discharge + uint16_t getRawCoulombCount() + { + return getHalfWord(BQ27220_REG_STA_COULOMB_COUNT); + } + + // The average power during battery charging and discharging. + // Values ​​are negative during discharging and positive during charging. + // A value of 0 means the battery is not discharging. This value is reported in mW. + uint16_t getAveragePower() + { + return getHalfWord(BQ27220_REG_STA_AVG_POWER); + } + + // This read-only function returns the unsigned integer + // value of the internal temperature sensor measured by the fuel gauge. + // The unit is Celsius + float getInternalTemperature() + { + return (getHalfWord(BQ27220_REG_STA_INTER_TEMP) * 0.1) - 273.15; + } + + // The number of cycles the active battery has experienced, ranging from 0 to 65535. + // A cycle occurs when the accumulated discharge ≥ the cycle threshold. + uint16_t getCycleCount() + { + return getHalfWord(BQ27220_REG_STA_CYCLE_COUNT); + } + + // This read-only function returns an unsigned integer value representing the predicted + // remaining battery capacity as a percentage of FullChargeCapacity(), in the range 0 to 100%. + uint16_t getStateOfCharge() + { + return getHalfWord(BQ27220_REG_STA_STATE_OF_CHARGE); + } + + // This read-only function returns an unsigned integer value representing the percentage of + // FullChargeCapacity() to DesignCapacity(), ranging from 0 to 100% + uint16_t getStateOfHealth() + { + return getHalfWord(BQ27220_REG_STA_STATE_OF_HEALTH); + } + + // This read-only function returns the unsigned integer value of the desired battery + // charging voltage. A value of 65,535 indicates that the battery is requesting the + // maximum voltage from the battery charger. + uint16_t getChargingVoltage() + { + return getHalfWord(BQ27220_REG_STA_CHARGING_VOLTAGE); + } + + // This read-only function returns an unsigned integer value for the desired battery + // charging current. A value of 65,535 indicates that the battery is requesting the maximum + // current from the battery charger. + uint16_t getChargingCurrent() + { + return getHalfWord(BQ27220_REG_STA_CHARGING_CURRENT); + } + + // This read/write word command updates the BTP setup threshold that triggers the BTP + // interrupt in the discharge direction and sets the OperationStatus()[BTPINT] bit. + uint16_t getBTPDischargeSet() + { + return getHalfWord(BQ27220_REG_STA_BTP_DISC_SET); + } + + int setBTPDischarge(uint8_t hsb, uint8_t lsb) + { + uint8_t buffer[2] = {lsb, hsb}; + return comm->writeRegister(BQ27220_REG_STA_BTP_DISC_SET, buffer, arraySize(buffer)); + } + + // This read/write word command updates the BTP setup threshold that triggers the BTP + // interrupt in the charge direction and sets the OperationStatus()[BTPINT] bit. + uint16_t getBTPChargeSet() + { + return getHalfWord(BQ27220_REG_STA_BTP_CHARGE_SET); + } + + int setBTPCharge(uint8_t hsb, uint8_t lsb) + { + uint8_t buffer[2] = {lsb, hsb}; + return comm->writeRegister(BQ27220_REG_STA_BTP_CHARGE_SET, buffer, arraySize(buffer)); + } + + // The Read Word function returns the contents of the internal status register + // See datasheet page 27. + uint16_t getOperationStatusRaw() + { + return getHalfWord(BQ27220_REG_STA_OPERATION_STATUS); + } + + OperationStatus_t getOperationStatus() + { + OperationStatus_t status; + uint16_t value = comm->readRegister(BQ27220_REG_STA_OPERATION_STATUS); + uint8_t highByte = (value >> 8) & 0xFF; + uint8_t lowByte = value & 0xFF; + // HIGH BYTE + status.CFGUPDATE = (highByte & _BV(1)) != 0; + + // LOW BYTE + status.BTPINT = (lowByte & _BV(7)) != 0; + status.SMTH = (lowByte & _BV(6)) != 0; + status.INITCOMP = (lowByte & _BV(5)) != 0; + status.VDQ = (lowByte & _BV(4)) != 0; + status.EDV2 = (lowByte & _BV(3)) != 0; + status.SEC = (lowByte >> 1) & 0x03; + status.CALMD = (lowByte & _BV(0)) != 0; + + return status; + } + + + // This read-only function returns the value stored in Design Capacity mAh. + // This value is used as the theoretical or nominal capacity of a new battery pack + // and is used to calculate StateOfHealth(). + uint16_t getDesignCapacity() + { + return getHalfWord(BQ27220_REG_STA_DESIGN_CAPACITY); + } + + // This read-write block will return the result data for the currently active subcommand. + int getMACData(uint8_t *buffer, uint8_t request_len) + { + const uint8_t max_size = BQ27220_REG_MAC_BUFFER_END - BQ27220_REG_MAC_BUFFER_START + 1; + if (request_len > max_size) { + return -1; + } + if (!buffer) { + return -1; + } + uint8_t reg = BQ27220_REG_MAC_BUFFER_START; + return comm->writeThenRead(®, 1, buffer, request_len); + } + + // This read and write function returns the checksum of the current subcommand and data block. + // Writing to this register provides the checksum required to execute a subcommand that requires data. + uint16_t getMACDataSum() + { + uint8_t sum = 0x00; + if (comm->readRegister(BQ27220_REG_MAC_DATA_SUM, &sum, 1) < 0) { + return 0; + } + return sum; + } + + // This read and write function returns the number of MACData() + // bytes contained in MACDataSum() as part of the response. + uint16_t getMACDataLen() + { + uint8_t length = 0x00; + if (comm->readRegister(BQ27220_REG_MAC_DATA_LEN, &length, 1) < 0) { + return 0; + } + return length; + } + + // This read-only function returns the analog counter. + // This value is incremented each time the analog data used for calibration is updated. + uint16_t getAnalogCount() + { + uint8_t count = 0x00; + if (comm->readRegister(BQ27220_REG_ANALOG_COUNT, &count, 1) < 0) { + return 0; + } + return count; + } + + // This read-only function returns the raw data from the coulomb counter. + uint16_t getRawCurrent() + { + return getHalfWord(BQ27220_REG_RAW_CURRENT); + } + + // This read-only function returns the raw data from the battery voltage reading. + uint16_t getRawVoltage() + { + return getHalfWord(BQ27220_REG_RAW_VOLTAGE); + } + + //* Subcommands + + int sendSubCommand(uint16_t subCmd) + { + uint8_t buffer[3]; + buffer[0] = 0x00; + buffer[1] = lowByte(subCmd); + buffer[2] = highByte(subCmd); + comm->writeBuffer(buffer, arraySize(buffer)); + constexpr uint8_t statusReg = 0x00; + int waitCount = 20; + hal->delay(10); + while (waitCount--) { + comm->writeThenRead(&statusReg, 1, buffer, 2); + uint16_t *value = reinterpret_cast(buffer); + if (*value == 0xFFA5) { + return 0; + } + hal->delay(1); + } + log_e("Subcommand failed!"); + return -1; + } + + // UNSEAL + int unsealDevice() + { + uint8_t cmd1[] = {0x00, 0x14, 0x04}; + if (comm->writeBuffer(cmd1, arraySize(cmd1)) < 0) { + return -1; + } + uint8_t cmd2[] = {0x00, 0x72, 0x36}; + if (comm->writeBuffer(cmd2, arraySize(cmd2)) < 0) { + return -1; + } + return 0; + } + + // UNSEAL FULL ACCESS + int unsealFullAccess() + { + if (unsealDevice() < 0) { + return -1; + } + uint8_t cmd1[] = {0x00, 0xFF, 0xFF}; + if (comm->writeBuffer(cmd1, arraySize(cmd1)) < 0) { + return -1; + } + if (comm->writeBuffer(cmd1, arraySize(cmd1)) < 0) { + return -1; + } + return 0; + } + + int exitSealMode() + { + return sendSubCommand(BQ27220_SUB_CMD_SEALED); + } + + bool setDesignCapacity(uint16_t newDesignCapacity) + { + //* 1.Check access settings + OperationStatus_t s; + s = getOperationStatus(); + if (s.SEC == SEALED_ACCESS) { + unsealDevice(); + } + if (s.SEC != FULL_ACCESS) { + unsealFullAccess(); + } + + //* 3.Send ENTER_CFG_UPDATE command (0x0090) + sendSubCommand(BQ27220_SUB_CMD_ENTER_CFG_UPDATE); + + //* 4.Confirm CFUPDATE mode by polling the OperationStatus() register until Bit 2 is set. + bool isConfigUpdate = false; + uint32_t timeout = hal->millis() + 3000UL; + while (true && timeout > hal->millis()) { + s = getOperationStatus(); + if (s.CFGUPDATE) { + isConfigUpdate = true; + break; + } + hal->delay(100); + } + if (!isConfigUpdate) { + log_e("Enter to CFUPDATE mode failed!"); + return false; + } + + //* 5.Write 0x9F to 0x3E to access the MSB of Design Capacity + constexpr uint8_t DesignCapacityMSB = 0x9F; + comm->writeRegister(BQ27220_REG_STA_DESIGN_CAPACITY_MSB, DesignCapacityMSB); + + //* 6.Write 0x92 to 0x3F to access the LSB of Design Capacity + constexpr uint8_t DesignCapacityLSB = 0x92; + comm->writeRegister(BQ27220_REG_STA_DESIGN_CAPACITY_LSB, DesignCapacityLSB); + + //* 7.Use the MACDataSum() command (0x60) to read the 1-byte checksum + uint8_t oldChksum = getMACDataSum(); + + //* 8.Use the MACDataLen() command (0x61) to read the 1-byte block length + uint8_t dataLen = getMACDataLen(); + + //* 9.Read two Design Capacity bytes starting from 0x40 + uint8_t buffer[2]; + getMACData(buffer, arraySize(buffer)); + uint8_t oldDcMsb = buffer[0]; + uint8_t oldDcLsb = buffer[1]; + + //* 10.Read and write two Design Capacity bytes starting from 0x40 + uint8_t newDcMsb = lowByte(newDesignCapacity); + uint8_t newDcLsb = highByte(newDesignCapacity); + + //* 11.Calculate new checksum + int temp = (255 - oldChksum - oldDcMsb - oldDcLsb + newDcMsb + newDcLsb) % 256; + uint8_t newChksum = 255 - temp; + + //* 12.Write new checksum + comm->writeRegister(BQ27220_REG_MAC_DATA_SUM, newChksum); + + //* 13.Write the block length, in this example, Data_Len is 0x24 + uint8_t dataLength = 0x24; + comm->writeRegister(BQ27220_REG_MAC_DATA_LEN, dataLength); + + //* 13.1.Write new Design Capacity bytes + comm->writeRegister(BQ27220_REG_STA_DESIGN_CAPACITY_MSB, newDcMsb); + comm->writeRegister(BQ27220_REG_STA_DESIGN_CAPACITY_LSB, newDcLsb); + + //* 14.Exit CFUPDATE mode by sending the EXIT_CFG_UPDATE_REINIT (0x0091) or EXIT_CFG_UPDATE (0x0092) command + sendSubCommand(BQ27220_SUB_CMD_EXIT_CFG_UPDATE_REINIT); + + //* 15.Confirm that CFUPDATE mode has been exited by polling the + //* OperationStatus() register until bit 2 is cleared + timeout = hal->millis() + 3000UL; + while (true && timeout > hal->millis()) { + s = getOperationStatus(); + if (s.CFGUPDATE == 0x00) { + timeout = hal->millis() + 1000; + break; + } + hal->delay(100); + } + if (hal->millis() > timeout) { + log_e("Wait CFUPDATE exit timeout"); + } + //* 16.If the device was previously in SEALED state, return + //* to SEALED mode by sending the Control(0x0030) subcommand + exitSealMode(); + + return true; + } + + // The fuel gauge enters CALIBRATION mode + int enterCalibration() + { + return sendSubCommand(BQ27220_SUB_CMD_ENTER_CAL); + } + + // The fuel gauge exit CALIBRATION mode + int exitCalibration() + { + return sendSubCommand(BQ27220_SUB_CMD_EXIT_CAL); + } + + int enterRomMode() + { + return sendSubCommand(BQ27220_SUB_CMD_RETURN_TO_ROM); + } + + // Get chip ID + uint16_t getChipID() + { + uint8_t buffer[2] = {0}; + if (sendSubCommand(BQ27220_SUB_CMD_DEVICE_NUMBER) < 0) { + return 0; + } + if (this->getMACData(buffer, arraySize(buffer)) < 0) { + return -1; + } + return static_cast((buffer[1] << 8) | buffer[0]); + } + + int getHardwareVersion() + { + uint8_t buffer[2]; + constexpr uint8_t value = 0x00; + comm->writeRegister(BQ27220_SUB_CMD_HW_VERSION, value); + if (this->getMACData(buffer, arraySize(buffer)) < 0) { + return -1; + } + return static_cast((buffer[1] << 8) | buffer[0]); + } + + int getFirmwareVersion() + { + uint8_t buffer[4]; + if (sendSubCommand(BQ27220_SUB_CMD_FW_VERSION) < 0) { + return -1; + } + if (this->getMACData(buffer, arraySize(buffer)) < 0) { + return -1; + } + return (buffer[3] << 24) | (buffer[2] << 16) | (buffer[1] << 8) | buffer[0]; + } + + void reset() + { + sendSubCommand(BQ27220_SUB_CMD_RESET); + } + + +private: + + int getHalfWord(uint8_t reg) + { + uint8_t buffer[2] = {0}; + if (comm->writeThenRead(®, 1, buffer, arraySize(buffer)) < 0) { + return 0xFFFF; + } + return (buffer[1] << 8) | buffer[0]; + } + + bool initImpl() + { + reset(); + + hal->delay(10); + + int chipID = getChipID(); + if (chipID != BQ27220_CHIP_ID) { + log_e("Chip id not match : %02X\n", chipID); + return false; + } + + int sw = getFirmwareVersion(); + if (sw < 0) { + log_e("Software version error!"); + } else { + log_d("Software version 0x%04X", sw); + } + hal->delay(100); + int hw = getHardwareVersion(); + if (hw < 0) { + log_e("Hardware version error!"); + } else { + log_d("Hardware version 0x%04X", hw); + } + + return true; + } + +protected: + std::unique_ptr comm; + std::unique_ptr hal; +}; + diff --git a/src/REG/BMA423Config.h b/src/REG/BMA423Config.h new file mode 100644 index 0000000..b86f53e --- /dev/null +++ b/src/REG/BMA423Config.h @@ -0,0 +1,545 @@ +/** + * + * @license MIT License + * + * Copyright (c) 2025 lewis he + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * @file BMA423Config.h + * @author Lewis He (lewishe@outlook.com) + * @date 2025-01-20 + * + */ +#pragma once +/**\name Feature configuration file */ +static const unsigned char bma423_config_file[6144] = { + 0x80, 0x2e, 0xfc, 0x00, 0x80, 0x2e, 0xfe, 0x00, 0xc8, 0x2e, 0x00, 0x2e, + 0x80, 0x2e, 0xfa, 0x00, 0x80, 0x2e, 0x23, 0xb1, 0x80, 0x2e, 0xfd, 0x00, + 0x80, 0x2e, 0xfb, 0x00, 0x80, 0x2e, 0x5a, 0xb1, 0x50, 0x39, 0x21, 0x2e, + 0xb0, 0xf0, 0x10, 0x30, 0x21, 0x2e, 0x16, 0xf0, 0x80, 0x2e, 0xfc, 0x01, + 0x5d, 0x50, 0x45, 0x52, 0x01, 0x42, 0x3b, 0x80, 0x41, 0x30, 0x01, 0x42, + 0x3c, 0x80, 0x00, 0x2e, 0x01, 0x40, 0x01, 0x42, 0x21, 0x2e, 0xff, 0xaf, + 0xb8, 0x2e, 0xb6, 0xd6, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, + 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, + 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, + 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, + 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, + 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, + 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, + 0xfd, 0x2d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x02, 0x01, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0xf8, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x49, 0x00, 0x24, 0x01, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x98, 0x2e, + 0x99, 0x01, 0x20, 0x26, 0x98, 0x2e, 0xf6, 0x00, 0x98, 0x2e, 0xe9, 0x01, + 0x10, 0x30, 0x21, 0x2e, 0x59, 0xf0, 0x98, 0x2e, 0xd8, 0x00, 0x00, 0x2e, + 0x00, 0x2e, 0xd0, 0x2e, 0x98, 0x2e, 0xdd, 0x00, 0x01, 0x2e, 0x56, 0x00, + 0x00, 0xb2, 0x11, 0x2f, 0x00, 0x30, 0x21, 0x2e, 0x56, 0x00, 0x41, 0x50, + 0x98, 0x2e, 0xcc, 0xb0, 0x41, 0x50, 0x98, 0x2e, 0x8f, 0xb4, 0x01, 0x2e, + 0x03, 0xf0, 0x0d, 0xbc, 0x0f, 0xb8, 0x00, 0x90, 0x02, 0x2f, 0x45, 0x50, + 0x21, 0x2e, 0xbc, 0xf0, 0x01, 0x2e, 0x55, 0x00, 0x00, 0xb2, 0x1a, 0x2f, + 0x00, 0x30, 0x21, 0x2e, 0x55, 0x00, 0x43, 0x50, 0x98, 0x2e, 0xcc, 0xb0, + 0x43, 0x50, 0x98, 0x2e, 0xdc, 0xb1, 0x43, 0x50, 0x98, 0x2e, 0x92, 0xb5, + 0x43, 0x50, 0x98, 0x2e, 0x00, 0xb0, 0x01, 0x2e, 0x1c, 0x01, 0x0f, 0xbc, + 0x0f, 0xb8, 0x00, 0x90, 0x45, 0x50, 0x02, 0x2f, 0x21, 0x2e, 0xbc, 0xf0, + 0x02, 0x2d, 0x21, 0x2e, 0xba, 0xf0, 0x98, 0x2e, 0xd8, 0x00, 0xc3, 0x2d, + 0x01, 0x2e, 0x55, 0xf0, 0xc0, 0x2e, 0x21, 0x2e, 0x55, 0xf0, 0x03, 0x2e, + 0x00, 0xf0, 0x45, 0x54, 0x01, 0x2e, 0x59, 0xf0, 0x4a, 0x0e, 0x02, 0x2f, + 0xf1, 0x33, 0x0d, 0x2c, 0x01, 0x08, 0xf2, 0x30, 0x4a, 0x08, 0x79, 0x84, + 0x82, 0xa2, 0x04, 0x2f, 0x02, 0x34, 0x82, 0x0a, 0x47, 0xa2, 0x03, 0x2c, + 0x10, 0x22, 0x45, 0x52, 0x01, 0x0a, 0xc0, 0x2e, 0x21, 0x2e, 0x59, 0xf0, + 0x00, 0x31, 0xc0, 0x2e, 0x21, 0x2e, 0xba, 0xf0, 0xc8, 0x2e, 0xc8, 0x2e, + 0xc8, 0x2e, 0xc8, 0x2e, 0xc8, 0x2e, 0x44, 0x47, 0xaa, 0x00, 0x05, 0x00, + 0x2d, 0x01, 0xd4, 0x7b, 0x3b, 0x01, 0xdb, 0x7a, 0x04, 0x00, 0x3f, 0x7b, + 0xcd, 0x6c, 0xc3, 0x04, 0x85, 0x09, 0xc3, 0x04, 0xec, 0xe6, 0x0c, 0x46, + 0x01, 0x00, 0x27, 0x00, 0x19, 0x00, 0x96, 0x00, 0xa0, 0x00, 0x01, 0x00, + 0x0c, 0x00, 0xf0, 0x3c, 0x00, 0x01, 0x01, 0x00, 0x03, 0x00, 0x01, 0x00, + 0x0e, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x43, 0x28, 0x88, 0x00, + 0x52, 0x00, 0x4f, 0x00, 0x80, 0x00, 0x5b, 0x00, 0x00, 0x40, 0xaf, 0x00, + 0xff, 0x00, 0xff, 0xb7, 0x00, 0x02, 0x00, 0xb0, 0x05, 0x80, 0xb1, 0xf0, + 0xc0, 0x00, 0x00, 0x01, 0x5e, 0xf0, 0x39, 0xf0, 0x89, 0xf0, 0x00, 0x20, + 0xff, 0x7f, 0x7d, 0x00, 0x5e, 0x00, 0x62, 0x00, 0x7c, 0x00, 0xff, 0xfb, + 0x52, 0xf0, 0x56, 0xf0, 0x33, 0x09, 0x33, 0x07, 0x00, 0x08, 0x90, 0x01, + 0x00, 0xf8, 0x67, 0x00, 0x4c, 0x04, 0xa0, 0x00, 0xe8, 0x03, 0x81, 0x00, + 0x82, 0x00, 0x6a, 0x00, 0x6d, 0x00, 0x6c, 0x00, 0xeb, 0x07, 0xae, 0x07, + 0x72, 0x00, 0x6f, 0x00, 0xa1, 0x01, 0x1e, 0x05, 0x47, 0xfd, 0x73, 0x00, + 0x77, 0x00, 0x79, 0x00, 0x76, 0x00, 0xcc, 0x00, 0x30, 0x50, 0x50, 0x40, + 0x00, 0x18, 0x50, 0x40, 0x56, 0x25, 0x47, 0x25, 0x00, 0x18, 0x2e, 0x00, + 0x41, 0x40, 0xa7, 0x02, 0x09, 0x18, 0xc6, 0x00, 0xfb, 0x7f, 0x00, 0x30, + 0x49, 0x52, 0x05, 0x30, 0x05, 0x2c, 0x17, 0x03, 0x1e, 0xbd, 0xd2, 0xba, + 0x92, 0xb8, 0x6a, 0x0b, 0x61, 0x0e, 0xf9, 0x2f, 0x61, 0x1a, 0x01, 0x2f, + 0x5d, 0x0e, 0xf5, 0x2f, 0xd4, 0x7f, 0x02, 0x30, 0x1f, 0x2c, 0xe3, 0x7f, + 0x85, 0x01, 0xd1, 0x03, 0x7c, 0x0e, 0x03, 0x2f, 0x7c, 0x1a, 0x0f, 0x2f, + 0x73, 0x0f, 0x0d, 0x2f, 0xe3, 0x6f, 0xde, 0x04, 0x5f, 0xba, 0x11, 0xbf, + 0xb4, 0x0b, 0xd4, 0x6f, 0x27, 0x07, 0xb3, 0x25, 0xd1, 0xbf, 0xeb, 0x7f, + 0x07, 0x00, 0xb4, 0x25, 0x96, 0x02, 0xdb, 0x7f, 0x2f, 0xbf, 0x9e, 0xbf, + 0x01, 0xb8, 0xd2, 0xba, 0x21, 0xb9, 0x92, 0xb8, 0x06, 0x0a, 0x6f, 0x0b, + 0x40, 0x90, 0xdf, 0x2f, 0x40, 0x91, 0xdd, 0x2f, 0xfb, 0x6f, 0xd0, 0x5f, + 0xb8, 0x2e, 0x57, 0x50, 0x41, 0x30, 0x02, 0x40, 0x51, 0x0a, 0x01, 0x42, + 0x18, 0x82, 0x4b, 0x50, 0x60, 0x42, 0x70, 0x3c, 0x4d, 0x54, 0x42, 0x42, + 0x69, 0x82, 0x82, 0x32, 0x43, 0x40, 0x18, 0x08, 0x02, 0x0a, 0x40, 0x42, + 0x42, 0x80, 0x02, 0x3f, 0x01, 0x40, 0x10, 0x50, 0x4a, 0x08, 0xfb, 0x7f, + 0x11, 0x42, 0x0b, 0x31, 0x0b, 0x42, 0x3e, 0x80, 0x01, 0x32, 0x01, 0x42, + 0x00, 0x2e, 0x01, 0x2e, 0x40, 0xf0, 0x13, 0x90, 0x20, 0x2f, 0x03, 0x30, + 0x51, 0x50, 0x4f, 0x54, 0xf4, 0x34, 0x06, 0x30, 0x55, 0x52, 0x55, 0x32, + 0x1d, 0x1a, 0xe3, 0x22, 0x18, 0x1a, 0x53, 0x58, 0xe3, 0x22, 0x04, 0x30, + 0xd5, 0x40, 0xb5, 0x0d, 0xe1, 0xbe, 0x6f, 0xbb, 0x80, 0x91, 0xa9, 0x0d, + 0x01, 0x89, 0xb5, 0x23, 0x10, 0xa1, 0xf7, 0x2f, 0xda, 0x0e, 0xf4, 0x34, + 0xeb, 0x2f, 0x01, 0x2e, 0x25, 0x00, 0x70, 0x1a, 0x00, 0x30, 0x21, 0x30, + 0x02, 0x2c, 0x08, 0x22, 0x30, 0x30, 0x00, 0xb2, 0x06, 0x2f, 0x21, 0x2e, + 0x59, 0xf0, 0x98, 0x2e, 0xd8, 0x00, 0x00, 0x2e, 0x00, 0x2e, 0xd0, 0x2e, + 0xfb, 0x6f, 0xf0, 0x5f, 0xb8, 0x2e, 0x01, 0x2e, 0xb1, 0xf0, 0x59, 0x52, + 0x01, 0x0a, 0x21, 0x2e, 0xb1, 0xf0, 0x01, 0x2e, 0x1c, 0x01, 0x0f, 0xbc, + 0x0f, 0xb8, 0x00, 0x90, 0x45, 0x50, 0x02, 0x2f, 0xc0, 0x2e, 0x21, 0x2e, + 0xbc, 0xf0, 0xc0, 0x2e, 0x21, 0x2e, 0xba, 0xf0, 0x1a, 0x24, 0x26, 0x00, + 0x80, 0x2e, 0x8f, 0x00, 0x03, 0x2e, 0x01, 0x01, 0x05, 0x2e, 0x01, 0x01, + 0x92, 0xbd, 0x20, 0x50, 0x03, 0x2e, 0x01, 0x01, 0xbf, 0xba, 0x21, 0xbd, + 0x2f, 0xbb, 0x1f, 0xba, 0x40, 0x91, 0xf0, 0x7f, 0x04, 0x2f, 0x80, 0x91, + 0x02, 0x2f, 0x00, 0xb3, 0x90, 0x2e, 0xc7, 0xb0, 0x03, 0x2e, 0x7b, 0x00, + 0x01, 0x80, 0x40, 0x90, 0x14, 0x2f, 0x41, 0x84, 0xf1, 0x6f, 0x25, 0x2e, + 0x7b, 0x00, 0x41, 0x40, 0x23, 0x2e, 0x5a, 0x00, 0x47, 0x52, 0x12, 0x40, + 0x52, 0x42, 0x02, 0x30, 0x00, 0x40, 0x40, 0x42, 0xe0, 0x5f, 0x25, 0x2e, + 0x57, 0x00, 0x25, 0x2e, 0x58, 0x00, 0x25, 0x2e, 0x5d, 0x00, 0xb8, 0x2e, + 0x07, 0x2e, 0x00, 0x01, 0x03, 0x2e, 0x01, 0x01, 0x05, 0x2e, 0x00, 0x01, + 0x24, 0xbd, 0x0f, 0x2e, 0x59, 0x00, 0xb5, 0xbd, 0x93, 0xbc, 0x2f, 0xb9, + 0xb5, 0xb9, 0x93, 0xb8, 0x3a, 0x1a, 0x06, 0x2f, 0x07, 0x30, 0x25, 0x2e, + 0x59, 0x00, 0x2f, 0x2e, 0x57, 0x00, 0x2f, 0x2e, 0x58, 0x00, 0x40, 0xb3, + 0x05, 0x30, 0x07, 0x30, 0x0a, 0x2f, 0xf7, 0x6f, 0xe6, 0x7f, 0x00, 0x2e, + 0xc6, 0x41, 0x0f, 0x2e, 0x5a, 0x00, 0xb7, 0x05, 0x80, 0xa9, 0xee, 0x05, + 0xf7, 0x23, 0xe6, 0x6f, 0x80, 0xb3, 0x06, 0x30, 0x09, 0x2f, 0xe7, 0x7f, + 0x00, 0x2e, 0x06, 0x40, 0x0f, 0x2e, 0x5b, 0x00, 0xb7, 0x05, 0x80, 0xa9, + 0xee, 0x05, 0xb7, 0x23, 0xe7, 0x6f, 0x00, 0xb3, 0x04, 0x30, 0x0b, 0x2f, + 0xf4, 0x6f, 0x02, 0x89, 0xe7, 0x7f, 0x00, 0x2e, 0x04, 0x41, 0x0f, 0x2e, + 0x5c, 0x00, 0x27, 0x05, 0x00, 0xa9, 0xec, 0x05, 0x27, 0x23, 0xe7, 0x6f, + 0x7b, 0x0f, 0x17, 0x30, 0x0b, 0x2f, 0x73, 0x0f, 0x05, 0x30, 0x17, 0x30, + 0x07, 0x2f, 0x63, 0x0f, 0x15, 0x30, 0x17, 0x30, 0x00, 0x2f, 0x07, 0x30, + 0xe3, 0x0e, 0x00, 0x2f, 0x05, 0x30, 0x80, 0x90, 0x05, 0x2e, 0x57, 0x00, + 0x13, 0x30, 0x13, 0x29, 0xf2, 0x6f, 0x47, 0x5c, 0x17, 0x2f, 0xc0, 0x91, + 0x05, 0x30, 0x0b, 0x2f, 0x07, 0x2e, 0x58, 0x00, 0xc1, 0x86, 0x2b, 0x2e, + 0x57, 0x00, 0x59, 0x0e, 0x27, 0x2e, 0x58, 0x00, 0x24, 0x2f, 0x2b, 0x2e, + 0x5d, 0x00, 0x22, 0x2d, 0x61, 0x0e, 0x29, 0x2e, 0x57, 0x00, 0x2b, 0x2e, + 0x58, 0x00, 0x1b, 0x2f, 0x27, 0x2e, 0x5d, 0x00, 0x19, 0x2d, 0x40, 0x91, + 0x05, 0x2f, 0x01, 0x30, 0x23, 0x2e, 0x57, 0x00, 0x23, 0x2e, 0x5d, 0x00, + 0x06, 0x2d, 0x29, 0x2e, 0x57, 0x00, 0x61, 0x0e, 0x01, 0x2f, 0x27, 0x2e, + 0x5d, 0x00, 0x81, 0x40, 0x23, 0x2e, 0x5a, 0x00, 0x30, 0x25, 0x47, 0x52, + 0xd4, 0x40, 0x54, 0x42, 0x00, 0x2e, 0xc3, 0x40, 0x43, 0x42, 0x00, 0x2e, + 0x03, 0x2e, 0x5d, 0x00, 0x40, 0xb2, 0x0d, 0x2f, 0x81, 0x40, 0x23, 0x2e, + 0x5a, 0x00, 0x11, 0x40, 0x91, 0x43, 0x01, 0x34, 0x00, 0x40, 0x80, 0x43, + 0x23, 0x2e, 0x5e, 0xf0, 0x03, 0x2d, 0x00, 0x30, 0x21, 0x2e, 0x7b, 0x00, + 0xe0, 0x5f, 0xb8, 0x2e, 0x50, 0x50, 0xf0, 0x7f, 0x1a, 0x25, 0x13, 0x40, + 0x7b, 0x84, 0xe0, 0x7f, 0x83, 0x42, 0x35, 0x30, 0x11, 0x40, 0x04, 0x40, + 0xc1, 0x7f, 0xd4, 0x7f, 0x86, 0x31, 0x07, 0x2e, 0x59, 0xf0, 0x03, 0x2e, + 0x1f, 0x01, 0x0d, 0x09, 0x02, 0xab, 0x05, 0x30, 0x8e, 0x09, 0x2c, 0x23, + 0xe3, 0xba, 0x42, 0xab, 0x16, 0x30, 0x75, 0x23, 0x59, 0x5c, 0x8e, 0x09, + 0x66, 0xbb, 0x82, 0xab, 0x27, 0x30, 0xbe, 0x23, 0x3e, 0x80, 0x25, 0x1a, + 0x06, 0x2f, 0x2e, 0x1a, 0x04, 0x2f, 0x26, 0x1a, 0x02, 0x2f, 0xf7, 0x3d, + 0x03, 0x2c, 0xdf, 0x08, 0x07, 0x32, 0xdf, 0x0a, 0x14, 0x01, 0x55, 0x01, + 0x04, 0x41, 0x14, 0x42, 0x16, 0x01, 0x42, 0x41, 0x45, 0x30, 0x4d, 0x09, + 0x04, 0x41, 0x12, 0x42, 0x04, 0x42, 0x40, 0xb3, 0x04, 0x2f, 0xf0, 0x6f, + 0x02, 0x30, 0x04, 0x40, 0x94, 0x04, 0x02, 0x42, 0x00, 0x32, 0x08, 0x08, + 0x00, 0xb2, 0x00, 0x30, 0x05, 0x2f, 0xe2, 0x6f, 0x00, 0x2e, 0x84, 0x40, + 0x04, 0x05, 0x84, 0x42, 0x00, 0x2e, 0x5b, 0x54, 0x4a, 0x08, 0x40, 0xb2, + 0xf1, 0x6f, 0x04, 0x2f, 0x42, 0x82, 0x00, 0x2e, 0x42, 0x40, 0x02, 0x04, + 0x40, 0x42, 0xb0, 0x5f, 0x27, 0x2e, 0x59, 0xf0, 0xb8, 0x2e, 0x50, 0x50, + 0xf7, 0x7f, 0x00, 0x2e, 0x0f, 0x2e, 0xb8, 0xf0, 0xf8, 0xbf, 0xff, 0xbb, + 0xc0, 0xb3, 0x2a, 0x2f, 0x0f, 0x2e, 0x01, 0xf0, 0xfe, 0xbf, 0xe6, 0x7f, + 0x7e, 0xbb, 0xd5, 0x7f, 0x37, 0x30, 0x5f, 0x5a, 0xbe, 0x05, 0x67, 0x41, + 0xc4, 0x7f, 0x78, 0xbe, 0x47, 0x41, 0x27, 0x0b, 0xb3, 0x7f, 0xe6, 0x11, + 0x41, 0x56, 0x43, 0x89, 0xd7, 0x42, 0x00, 0x2e, 0x27, 0x41, 0x05, 0x41, + 0xf8, 0xbf, 0x7d, 0x0b, 0x6e, 0x11, 0x03, 0x8f, 0xd5, 0x42, 0x14, 0x30, + 0xe5, 0x41, 0xc7, 0x41, 0xd8, 0xbe, 0x6f, 0x0b, 0x6e, 0x11, 0xc5, 0x42, + 0x29, 0x2e, 0x56, 0x00, 0x45, 0x56, 0x27, 0x2e, 0xb8, 0xf0, 0xe6, 0x6f, + 0xd5, 0x6f, 0xc4, 0x6f, 0xb3, 0x6f, 0xf7, 0x6f, 0xb0, 0x5f, 0xc8, 0x2e, + 0x50, 0x50, 0xe5, 0x7f, 0xd7, 0x7f, 0xf6, 0x7f, 0x36, 0x30, 0x0b, 0x2e, + 0x01, 0xf0, 0xde, 0xbe, 0xde, 0xbb, 0x61, 0x5a, 0xb7, 0x05, 0x67, 0x41, + 0xc4, 0x7f, 0x78, 0xbe, 0x47, 0x41, 0x27, 0x0b, 0xb3, 0x7f, 0xe6, 0x11, + 0x43, 0x56, 0x43, 0x89, 0xd7, 0x42, 0x00, 0x2e, 0x27, 0x41, 0x05, 0x41, + 0xf8, 0xbf, 0x7d, 0x0b, 0x6e, 0x11, 0x03, 0x8f, 0xd5, 0x42, 0x14, 0x30, + 0xe5, 0x41, 0xc7, 0x41, 0xd8, 0xbe, 0x6f, 0x0b, 0x6e, 0x11, 0xc5, 0x42, + 0x29, 0x2e, 0x55, 0x00, 0x03, 0x31, 0x27, 0x2e, 0xb8, 0xf0, 0xf6, 0x6f, + 0xe5, 0x6f, 0xd7, 0x6f, 0xc4, 0x6f, 0xb3, 0x6f, 0xb0, 0x5f, 0xc8, 0x2e, + 0x40, 0x50, 0xf6, 0x7f, 0x1a, 0x18, 0x63, 0x56, 0x33, 0x00, 0x06, 0x30, + 0xfe, 0x03, 0x0e, 0xb8, 0xf2, 0xbf, 0x07, 0x0a, 0x2a, 0x18, 0x63, 0x5a, + 0xb5, 0x01, 0x03, 0x30, 0xfb, 0x03, 0x6e, 0xbb, 0xf2, 0xbf, 0xe1, 0x7f, + 0xf7, 0x0b, 0x56, 0x40, 0x36, 0x25, 0x46, 0x40, 0x06, 0x28, 0xc7, 0x7f, + 0x22, 0x18, 0xd1, 0x7f, 0xb5, 0x00, 0x01, 0x30, 0x39, 0x03, 0x2e, 0xb9, + 0x42, 0xbe, 0x14, 0x0b, 0xf2, 0x6f, 0x10, 0x18, 0xb5, 0x00, 0xb9, 0x03, + 0x2e, 0xb9, 0x62, 0xbf, 0x96, 0x0a, 0xb6, 0x6f, 0x30, 0x18, 0x75, 0x01, + 0xb9, 0x03, 0x5c, 0x28, 0xe2, 0xbf, 0xde, 0xb9, 0xd6, 0x6f, 0xdf, 0x0a, + 0x8a, 0x28, 0xc4, 0x6f, 0x82, 0x43, 0x23, 0x29, 0xe5, 0x6f, 0xc0, 0x2e, + 0x44, 0x43, 0xc0, 0x5f, 0x40, 0x50, 0xd0, 0x7f, 0x4a, 0x17, 0x00, 0x40, + 0x01, 0x18, 0x46, 0x25, 0x07, 0x25, 0x65, 0x56, 0xd9, 0x04, 0x53, 0x18, + 0xeb, 0x18, 0x05, 0x30, 0x49, 0x16, 0x69, 0x06, 0xca, 0x18, 0xa6, 0x00, + 0xc7, 0x02, 0x65, 0x58, 0xcb, 0x7f, 0x98, 0x2e, 0x7f, 0xb6, 0xcb, 0x6f, + 0xd2, 0x6f, 0xc0, 0x2e, 0x80, 0x42, 0xc0, 0x5f, 0x09, 0x2e, 0x1b, 0x01, + 0x05, 0x2e, 0x1b, 0x01, 0xa3, 0xbc, 0x44, 0xbe, 0x90, 0x50, 0x4f, 0xb9, + 0x07, 0x2e, 0x1b, 0x01, 0x4a, 0x25, 0x9f, 0xb8, 0x39, 0x8f, 0xb2, 0xbd, + 0xf2, 0x7f, 0xbf, 0xb9, 0xeb, 0x7f, 0x8a, 0x0a, 0x37, 0x89, 0x0b, 0x30, + 0x93, 0x0a, 0x8b, 0x7f, 0xcb, 0x43, 0x0b, 0x43, 0x80, 0xb2, 0xd3, 0x7f, + 0xc1, 0x7f, 0x90, 0x2e, 0x87, 0xb2, 0x20, 0x25, 0x01, 0x2e, 0x64, 0x00, + 0x01, 0x90, 0x0e, 0x2f, 0x67, 0x52, 0x01, 0x2e, 0x61, 0x00, 0xb4, 0x7f, + 0xa2, 0x7f, 0x98, 0x2e, 0x8d, 0xb2, 0x00, 0x30, 0x21, 0x2e, 0x64, 0x00, + 0xc1, 0x6f, 0xd3, 0x6f, 0xa2, 0x6f, 0xb4, 0x6f, 0x0b, 0x30, 0x01, 0x2e, + 0x1b, 0x01, 0x06, 0xbc, 0x06, 0xbb, 0x57, 0x25, 0x01, 0x2e, 0x1b, 0x01, + 0x94, 0xb1, 0x05, 0xbc, 0xb6, 0x7f, 0x0f, 0xbb, 0x6b, 0x50, 0x80, 0xb3, + 0x0f, 0x2f, 0x0d, 0x2e, 0x1b, 0x01, 0x6f, 0x5e, 0xb7, 0x09, 0x2d, 0x2e, + 0x1b, 0x01, 0x71, 0x5c, 0x69, 0x5e, 0x9b, 0x43, 0x9b, 0x43, 0xdb, 0x43, + 0x9b, 0x43, 0x1b, 0x42, 0xcb, 0x43, 0x0b, 0x42, 0x8b, 0x43, 0x40, 0xb2, + 0x05, 0x2f, 0x69, 0x50, 0x00, 0x2e, 0x16, 0x40, 0x0b, 0x40, 0x76, 0x7f, + 0x8b, 0x7f, 0xcb, 0x0a, 0x01, 0x2e, 0x61, 0x00, 0x67, 0x52, 0x6d, 0x5c, + 0x98, 0x2e, 0xd3, 0xb2, 0x90, 0x6f, 0x00, 0xb2, 0x0b, 0x2f, 0xf0, 0x6f, + 0x00, 0xb2, 0x08, 0x2f, 0x69, 0x58, 0x6b, 0x50, 0x12, 0x41, 0x12, 0x42, + 0x21, 0x30, 0x04, 0x41, 0x04, 0x42, 0x23, 0x2e, 0x5e, 0xf0, 0xc0, 0x6f, + 0x00, 0xb2, 0x26, 0x2f, 0x74, 0x6f, 0x80, 0x6f, 0x71, 0x54, 0x88, 0xbd, + 0xc8, 0xb8, 0x4b, 0x0a, 0x94, 0x42, 0x91, 0x42, 0x90, 0x42, 0x88, 0xba, + 0x69, 0x52, 0xf3, 0x6f, 0x54, 0x42, 0x85, 0x42, 0xc0, 0x90, 0x40, 0x42, + 0x15, 0x2f, 0x6b, 0x52, 0x00, 0x2e, 0x52, 0x40, 0x41, 0x40, 0xa2, 0x04, + 0x41, 0x06, 0x40, 0xaa, 0x04, 0x2f, 0x40, 0x90, 0x0b, 0x2f, 0xb1, 0x6f, + 0x4a, 0x0f, 0x08, 0x2f, 0xb2, 0x6f, 0x80, 0xb2, 0x05, 0x2f, 0x6b, 0x54, + 0x21, 0x30, 0x94, 0x42, 0x80, 0x42, 0x23, 0x2e, 0x5e, 0xf0, 0xd0, 0x6f, + 0x00, 0xb2, 0x13, 0x2f, 0x01, 0x2e, 0x60, 0x00, 0x09, 0x2e, 0x7c, 0x00, + 0x04, 0x1a, 0x0d, 0x2f, 0x73, 0x50, 0x29, 0x2e, 0x60, 0x00, 0x24, 0x42, + 0x44, 0x30, 0x02, 0x40, 0x02, 0x42, 0x09, 0x80, 0x00, 0x2e, 0x04, 0x42, + 0x03, 0x2d, 0x10, 0x30, 0x21, 0x2e, 0x64, 0x00, 0xeb, 0x6f, 0x70, 0x5f, + 0xb8, 0x2e, 0x09, 0x86, 0x49, 0x54, 0xe4, 0x40, 0xc3, 0x80, 0x94, 0x04, + 0xc3, 0x40, 0x13, 0x05, 0x05, 0x40, 0x25, 0x05, 0x8a, 0x17, 0x73, 0x30, + 0x73, 0x09, 0x8c, 0x17, 0xf3, 0x08, 0xe3, 0x00, 0x4c, 0x82, 0x95, 0x00, + 0xb3, 0xb5, 0x23, 0xb5, 0x53, 0x42, 0x52, 0x42, 0x53, 0x42, 0x42, 0x42, + 0x71, 0x82, 0x75, 0x54, 0x52, 0x42, 0x10, 0x50, 0x77, 0x54, 0x52, 0x42, + 0xfb, 0x7f, 0x22, 0x30, 0x79, 0x56, 0x43, 0x42, 0x44, 0x82, 0x0b, 0x30, + 0x52, 0x42, 0x5b, 0x42, 0x7c, 0x84, 0x4b, 0x42, 0x35, 0x82, 0x8c, 0x80, + 0x8b, 0x42, 0x0b, 0x42, 0x39, 0x80, 0x04, 0x30, 0x0b, 0x42, 0x37, 0x80, + 0x15, 0x30, 0x60, 0x25, 0x98, 0x2e, 0xc6, 0xb2, 0x8b, 0x83, 0xfb, 0x6f, + 0x65, 0x42, 0xc0, 0x2e, 0x44, 0x42, 0xf0, 0x5f, 0x05, 0x80, 0x02, 0x30, + 0x51, 0x82, 0x02, 0x42, 0x13, 0x30, 0x41, 0x40, 0x4b, 0x08, 0x7b, 0x54, + 0x3e, 0x80, 0x51, 0x14, 0xc0, 0x2e, 0x01, 0x42, 0x00, 0x2e, 0x40, 0x51, + 0xd1, 0x7f, 0x12, 0x25, 0x02, 0x30, 0x42, 0x43, 0x32, 0x30, 0x82, 0x43, + 0xc6, 0x7f, 0xe5, 0x7f, 0xb4, 0x7f, 0xa3, 0x7f, 0x90, 0x7f, 0x8b, 0x7f, + 0x98, 0x2e, 0x54, 0x01, 0xc0, 0x7e, 0x00, 0xac, 0x01, 0x2f, 0x65, 0x50, + 0xc0, 0x7e, 0x00, 0x2e, 0x90, 0x6f, 0x09, 0x8a, 0xd1, 0x6f, 0x75, 0x7f, + 0x4c, 0x82, 0x63, 0x41, 0x65, 0x7f, 0x11, 0x7f, 0x00, 0x2e, 0x64, 0x41, + 0x44, 0x85, 0x52, 0x7f, 0x45, 0x7f, 0x00, 0x2e, 0xa6, 0x40, 0x80, 0x40, + 0x32, 0x7f, 0x82, 0x8e, 0xc2, 0x6e, 0x45, 0x41, 0xf0, 0x7f, 0x27, 0x7f, + 0x02, 0x7f, 0x98, 0x2e, 0x8a, 0xb1, 0x23, 0x6f, 0xd1, 0x6f, 0xc2, 0x40, + 0xf9, 0x86, 0x23, 0x7f, 0x80, 0xb2, 0xe0, 0x7e, 0x0f, 0x2f, 0x32, 0x6f, + 0x64, 0x6f, 0x82, 0x40, 0xf2, 0x7f, 0x4e, 0x82, 0x42, 0x6f, 0x50, 0x6f, + 0x73, 0x6f, 0x85, 0x40, 0xc3, 0x40, 0x04, 0x41, 0x06, 0x40, 0xe2, 0x6e, + 0x98, 0x2e, 0x8a, 0xb1, 0xe0, 0x7e, 0xf3, 0x31, 0x10, 0x6f, 0x36, 0x80, + 0xe1, 0x6e, 0x02, 0x40, 0x71, 0x7f, 0x51, 0x04, 0x02, 0x30, 0x40, 0xa8, + 0x91, 0x04, 0x4a, 0x22, 0x89, 0x16, 0x93, 0x08, 0x4a, 0x00, 0x95, 0xb4, + 0x09, 0x18, 0x8e, 0x16, 0x13, 0x30, 0x93, 0x08, 0x21, 0x6f, 0x60, 0x7f, + 0x4d, 0x86, 0x02, 0x80, 0xb2, 0x00, 0x41, 0x40, 0x21, 0xb5, 0x50, 0x7f, + 0x43, 0x7f, 0x98, 0x2e, 0xc2, 0xb1, 0x40, 0x6f, 0x62, 0x6f, 0x55, 0x6f, + 0x13, 0x40, 0x84, 0x40, 0x01, 0x40, 0x45, 0x41, 0x42, 0xbe, 0x1d, 0x18, + 0x4c, 0x04, 0x31, 0x0f, 0x04, 0x8a, 0xc0, 0x6f, 0x11, 0x30, 0x02, 0x2f, + 0x00, 0x2e, 0x03, 0x2c, 0x01, 0x42, 0x23, 0x30, 0x03, 0x42, 0x00, 0x2e, + 0xd6, 0x6f, 0x44, 0x41, 0x8a, 0x87, 0x76, 0x8b, 0x00, 0xb3, 0x53, 0x7f, + 0x15, 0x2f, 0x04, 0x6f, 0x7d, 0x5e, 0x8b, 0x8d, 0xe7, 0x01, 0xc0, 0xa5, + 0x84, 0x41, 0x01, 0x2f, 0x00, 0xa1, 0x03, 0x2f, 0xc0, 0xad, 0x08, 0x2f, + 0x00, 0xa5, 0x06, 0x2f, 0xc6, 0x40, 0x81, 0x8d, 0x07, 0x30, 0x3c, 0x05, + 0xd6, 0x42, 0x04, 0x2c, 0xc4, 0x42, 0x02, 0x2c, 0x07, 0x30, 0x07, 0x30, + 0x86, 0x86, 0x94, 0x6f, 0xd7, 0x7e, 0x0e, 0x8d, 0x00, 0x40, 0x74, 0x89, + 0xc7, 0x40, 0x02, 0xb2, 0xf9, 0x29, 0x45, 0x41, 0x86, 0x41, 0xbe, 0x80, + 0x21, 0x41, 0x75, 0x23, 0x82, 0x40, 0xc7, 0x42, 0x45, 0x7f, 0x34, 0x7f, + 0x20, 0x7f, 0x98, 0x2e, 0xc2, 0xb1, 0x31, 0x6f, 0x60, 0x6f, 0x24, 0x6f, + 0x22, 0x40, 0x05, 0x41, 0x43, 0x40, 0x13, 0x01, 0x43, 0x86, 0xac, 0x0f, + 0xd1, 0x6f, 0x30, 0x7f, 0x00, 0x2f, 0x44, 0x42, 0x48, 0x8a, 0x41, 0x88, + 0xe1, 0x40, 0x13, 0x7f, 0x04, 0x7f, 0xf5, 0x7e, 0x98, 0x2e, 0xc2, 0xb1, + 0x11, 0x6f, 0x60, 0x6f, 0x34, 0x6f, 0x42, 0x40, 0x03, 0x40, 0x9a, 0x04, + 0x04, 0x41, 0x43, 0x82, 0xa2, 0x0e, 0x03, 0x6f, 0x00, 0x2f, 0xc2, 0x42, + 0x00, 0x2e, 0x41, 0x40, 0x72, 0x6f, 0x98, 0x2e, 0xc2, 0xb1, 0x25, 0x6f, + 0x72, 0x6f, 0x53, 0x41, 0x93, 0x0e, 0xd1, 0x6f, 0x46, 0x80, 0x1b, 0x30, + 0x03, 0x30, 0x0c, 0x2f, 0x04, 0x40, 0x00, 0x91, 0x42, 0x42, 0x08, 0x2f, + 0xf6, 0x6e, 0x44, 0x6f, 0x86, 0x41, 0xb4, 0x0e, 0x03, 0x2f, 0x02, 0x88, + 0xdb, 0x7e, 0x03, 0x43, 0x0b, 0x42, 0x46, 0x8d, 0x44, 0x41, 0x47, 0x80, + 0x05, 0x6f, 0x94, 0x0f, 0x76, 0x7f, 0x60, 0x7f, 0x02, 0x2f, 0x45, 0x89, + 0x42, 0x43, 0x03, 0x43, 0x49, 0x88, 0xa5, 0x6f, 0x40, 0x91, 0xa4, 0x7f, + 0x15, 0x30, 0xe2, 0x6f, 0xd3, 0x6e, 0x03, 0x2f, 0x04, 0x30, 0x83, 0x42, + 0x80, 0x2e, 0x77, 0xb4, 0x04, 0x40, 0x25, 0x29, 0x04, 0x42, 0x83, 0x42, + 0x45, 0x82, 0x94, 0x6f, 0x04, 0x85, 0xc0, 0xb2, 0x90, 0x2e, 0x63, 0xb4, + 0x15, 0x87, 0x3c, 0x8c, 0xc4, 0x40, 0x46, 0x7f, 0xc2, 0x86, 0x07, 0x40, + 0x86, 0x41, 0xf4, 0xbf, 0x00, 0xb3, 0x0c, 0x2f, 0x90, 0x6f, 0x16, 0x80, + 0x46, 0x25, 0x00, 0x40, 0x57, 0x25, 0x04, 0x18, 0xae, 0x0e, 0x10, 0x30, + 0x06, 0x30, 0x75, 0x25, 0x46, 0x23, 0x60, 0x6f, 0x64, 0x25, 0xc4, 0x40, + 0xfa, 0x86, 0x00, 0xb3, 0x33, 0x7f, 0x09, 0x2f, 0x93, 0x6f, 0xd8, 0x88, + 0x53, 0x6f, 0x04, 0x41, 0xc3, 0x40, 0xdc, 0x0e, 0x13, 0x30, 0x04, 0x30, + 0xdc, 0x22, 0xb3, 0x25, 0x40, 0xb3, 0x02, 0x2f, 0x3b, 0x25, 0xc0, 0x90, + 0x05, 0x2f, 0x91, 0x6f, 0xd0, 0x6f, 0x98, 0x2e, 0xc6, 0xb2, 0x4d, 0x2c, + 0x04, 0x30, 0x8d, 0x88, 0x43, 0x40, 0x82, 0x40, 0x54, 0x7f, 0xda, 0x0f, + 0x04, 0x30, 0x08, 0x2f, 0xc1, 0x80, 0x40, 0x42, 0xc2, 0x0f, 0x02, 0x2f, + 0x00, 0x30, 0xc0, 0x7e, 0x1b, 0x2d, 0xc0, 0x7e, 0x19, 0x2d, 0xe1, 0xbc, + 0x92, 0x6f, 0x4f, 0x04, 0x90, 0x84, 0x40, 0xa8, 0x21, 0x05, 0x83, 0x40, + 0x4c, 0x22, 0x4b, 0x0e, 0xb6, 0x84, 0x21, 0x30, 0x02, 0x2f, 0x11, 0x30, + 0x04, 0x2c, 0xc1, 0x7e, 0xe3, 0x6f, 0xc1, 0x7e, 0xc1, 0x42, 0x00, 0x2e, + 0x00, 0x40, 0x81, 0x40, 0x04, 0xbd, 0x40, 0x6f, 0x98, 0x2e, 0xc2, 0xb1, + 0x50, 0x6f, 0x11, 0x30, 0x02, 0x40, 0x51, 0x08, 0xc3, 0x6e, 0x03, 0x80, + 0x99, 0x15, 0x0b, 0x40, 0xb1, 0x6f, 0xd0, 0x6f, 0xb6, 0x7f, 0x5b, 0x7f, + 0x04, 0x30, 0x4d, 0x54, 0x03, 0x30, 0x11, 0x2c, 0x10, 0x80, 0x55, 0x6f, + 0x06, 0x40, 0x75, 0x01, 0x58, 0xbb, 0x6a, 0x09, 0x05, 0x42, 0xc1, 0x86, + 0x47, 0x40, 0x51, 0x25, 0xbe, 0x01, 0x56, 0x43, 0x00, 0x2e, 0x46, 0x41, + 0xf4, 0x03, 0xb6, 0x6f, 0x47, 0x43, 0x5e, 0x0e, 0xed, 0x2f, 0x31, 0x6f, + 0x60, 0x6f, 0x42, 0x40, 0x15, 0x30, 0x02, 0x82, 0x95, 0x08, 0x04, 0x42, + 0x52, 0x42, 0x02, 0x2c, 0x44, 0x42, 0x04, 0x30, 0x3e, 0x8e, 0x91, 0x6f, + 0x4f, 0x8c, 0x02, 0x40, 0x83, 0x41, 0xb5, 0x8d, 0x93, 0x0e, 0xd0, 0x6f, + 0x01, 0x2f, 0x98, 0x2e, 0xc6, 0xb2, 0x00, 0x2e, 0xc0, 0x41, 0x81, 0x41, + 0xc1, 0x0f, 0xc0, 0x6f, 0x01, 0x2f, 0x04, 0x42, 0x00, 0x2e, 0x70, 0x6f, + 0x3c, 0x82, 0x00, 0x40, 0x41, 0x40, 0x89, 0x16, 0x95, 0x08, 0x4a, 0x00, + 0x04, 0xbc, 0x91, 0xb4, 0x01, 0x0e, 0xe0, 0x6f, 0x07, 0x2f, 0xa1, 0x6f, + 0x00, 0x2e, 0x41, 0x40, 0x40, 0xb2, 0x02, 0x2f, 0xa1, 0x6f, 0x05, 0x42, + 0x44, 0x42, 0x00, 0x2e, 0x8b, 0x6f, 0xc0, 0x5e, 0xb8, 0x2e, 0x03, 0x2e, + 0x1c, 0x01, 0x9c, 0xbc, 0x1d, 0xb9, 0x02, 0x82, 0x25, 0x2e, 0x8e, 0x00, + 0x83, 0x56, 0x13, 0x18, 0x01, 0x2e, 0x66, 0x00, 0x43, 0x40, 0xd8, 0x04, + 0x05, 0x2e, 0x65, 0x00, 0x40, 0x50, 0x27, 0x2e, 0x65, 0x00, 0xfb, 0x7f, + 0xda, 0x05, 0x8b, 0x50, 0x4b, 0x40, 0x02, 0x40, 0x81, 0x82, 0x01, 0x42, + 0x03, 0x80, 0x81, 0x52, 0xb1, 0x00, 0x03, 0x40, 0x3b, 0x82, 0x85, 0x58, + 0x14, 0x01, 0xc0, 0xb2, 0x37, 0x2e, 0x66, 0x00, 0xd1, 0x7f, 0xe2, 0x7f, + 0x04, 0x2f, 0x05, 0x2e, 0x6b, 0x00, 0x81, 0x84, 0x25, 0x2e, 0x6b, 0x00, + 0x62, 0x40, 0x3a, 0x0f, 0x45, 0x40, 0xc1, 0x7f, 0x21, 0x30, 0x12, 0x30, + 0x42, 0x2f, 0x0d, 0x2e, 0x69, 0x00, 0x3e, 0x0e, 0x33, 0x2f, 0x05, 0x2e, + 0x6a, 0x00, 0x01, 0x35, 0x91, 0x0e, 0x01, 0x30, 0x03, 0x2f, 0x09, 0x2e, + 0x6e, 0x00, 0x00, 0xb3, 0x24, 0x2f, 0xc0, 0x35, 0x90, 0x0e, 0x39, 0x2f, + 0x8f, 0x50, 0x02, 0x30, 0x01, 0x40, 0x7f, 0x82, 0x43, 0xa2, 0x02, 0x2f, + 0x00, 0x2e, 0x0c, 0x2c, 0x01, 0x30, 0xc0, 0xb2, 0x11, 0x30, 0x02, 0x2f, + 0x25, 0x2e, 0x6d, 0x00, 0x03, 0x2d, 0x23, 0x2e, 0x6d, 0x00, 0x21, 0x30, + 0x25, 0x2e, 0x6b, 0x00, 0x42, 0xb2, 0x04, 0x2f, 0x41, 0xb2, 0x02, 0x2f, + 0x25, 0x2e, 0x6d, 0x00, 0x31, 0x30, 0x3e, 0x80, 0x04, 0x86, 0x25, 0x2e, + 0x6c, 0x00, 0x02, 0x42, 0xc2, 0x42, 0x18, 0x2d, 0x02, 0x35, 0x01, 0x42, + 0x25, 0x2e, 0x6a, 0x00, 0x13, 0x2d, 0x2c, 0x04, 0x38, 0x1e, 0x21, 0x2e, + 0x69, 0x00, 0x7f, 0x50, 0x11, 0x30, 0x22, 0x30, 0x98, 0x2e, 0x66, 0xb5, + 0x09, 0x2c, 0x01, 0x30, 0x2c, 0x00, 0x38, 0x1c, 0x21, 0x2e, 0x68, 0x00, + 0x7f, 0x50, 0x98, 0x2e, 0x66, 0xb5, 0x01, 0x30, 0xc0, 0x6f, 0xd4, 0xb1, + 0xf5, 0xbd, 0x6b, 0xba, 0x91, 0x5a, 0x02, 0x40, 0x15, 0x18, 0xf5, 0xbe, + 0xeb, 0xbb, 0xe3, 0x0a, 0x3d, 0x0b, 0xd2, 0x6f, 0xe3, 0x00, 0x84, 0x40, + 0x63, 0x05, 0x93, 0x58, 0x2c, 0x18, 0xf5, 0xbe, 0x03, 0x42, 0xeb, 0xbb, + 0xfd, 0x0b, 0xe0, 0x6f, 0x58, 0x01, 0xdf, 0x01, 0x7d, 0x1f, 0x95, 0x42, + 0x18, 0x04, 0x85, 0x40, 0x5d, 0x05, 0x2c, 0x18, 0x75, 0xbe, 0xeb, 0xba, + 0x2c, 0x0b, 0xdc, 0x04, 0x18, 0x1c, 0x80, 0x42, 0x84, 0x80, 0x02, 0x30, + 0x00, 0x40, 0x00, 0xb2, 0x0c, 0x2f, 0x01, 0x2e, 0x6b, 0x00, 0x03, 0x35, + 0x83, 0x0e, 0x07, 0x2f, 0x8d, 0x50, 0x3e, 0x80, 0x25, 0x2e, 0x6d, 0x00, + 0x02, 0x42, 0x03, 0x80, 0x00, 0x2e, 0x02, 0x42, 0x40, 0xb2, 0x04, 0x2f, + 0x8b, 0x50, 0x04, 0x80, 0x25, 0x2e, 0x6a, 0x00, 0x02, 0x42, 0x42, 0xb2, + 0x89, 0x56, 0x9a, 0x22, 0x41, 0xb2, 0x01, 0x2e, 0x1c, 0x01, 0x87, 0x52, + 0x0b, 0xbc, 0x8a, 0x22, 0x0f, 0xb8, 0x00, 0x90, 0x01, 0x32, 0x06, 0x2f, + 0x10, 0x30, 0x90, 0x08, 0x80, 0xb2, 0x08, 0x2f, 0x23, 0x2e, 0x5e, 0xf0, + 0x06, 0x2d, 0x20, 0x30, 0x90, 0x08, 0x80, 0xb2, 0x01, 0x2f, 0x23, 0x2e, + 0x5e, 0xf0, 0xfb, 0x6f, 0xc0, 0x5f, 0xb8, 0x2e, 0x07, 0x86, 0xfc, 0x88, + 0xc6, 0x40, 0x05, 0x41, 0x31, 0x1a, 0x12, 0x2f, 0x80, 0x91, 0x22, 0x2f, + 0x01, 0x35, 0x29, 0x0f, 0x0a, 0x2f, 0x06, 0x80, 0x00, 0x2e, 0x00, 0x40, + 0x00, 0xb2, 0x01, 0x2f, 0x44, 0xa9, 0x03, 0x2f, 0x00, 0x30, 0xc0, 0x42, + 0x00, 0x43, 0xb8, 0x2e, 0xc2, 0x42, 0x01, 0x43, 0xb8, 0x2e, 0x01, 0x35, + 0xa9, 0x0e, 0x0e, 0x2f, 0x03, 0x3b, 0xeb, 0x00, 0xcc, 0xa8, 0x0a, 0x2f, + 0x05, 0x86, 0xc2, 0x80, 0xc3, 0x40, 0x02, 0x42, 0x3c, 0x84, 0xc1, 0x80, + 0x81, 0x42, 0x82, 0x84, 0xc0, 0x2e, 0x80, 0x42, 0x00, 0x2e, 0xb8, 0x2e, + 0x03, 0x2e, 0x1d, 0x01, 0x9f, 0xbc, 0x9f, 0xb8, 0x90, 0x50, 0x40, 0xb2, + 0x90, 0x2e, 0x71, 0xb6, 0x12, 0x40, 0x03, 0x30, 0x11, 0x40, 0x80, 0xa8, + 0x5a, 0x05, 0x9f, 0x58, 0x55, 0x23, 0x00, 0x40, 0x75, 0x7f, 0x40, 0xa8, + 0x16, 0x41, 0xd9, 0x05, 0xcf, 0x23, 0x56, 0x05, 0x40, 0xa9, 0x9d, 0x05, + 0x87, 0x7f, 0x6e, 0x23, 0x17, 0x41, 0xa5, 0x7f, 0x3e, 0x8b, 0x04, 0x41, + 0x52, 0x43, 0x00, 0xa8, 0x98, 0x05, 0xf2, 0x7f, 0x86, 0x22, 0xcf, 0x05, + 0xc0, 0xa9, 0x9f, 0x05, 0xbe, 0x23, 0x04, 0x05, 0x92, 0x7f, 0x00, 0xa9, + 0xdc, 0x05, 0x51, 0x43, 0xb6, 0x7f, 0x27, 0x23, 0xa7, 0x54, 0xe1, 0x7f, + 0x02, 0x18, 0x7d, 0x83, 0x40, 0x43, 0xeb, 0xba, 0x75, 0xbd, 0xaa, 0x0a, + 0x0b, 0x2e, 0x71, 0x00, 0x77, 0x5c, 0x2e, 0x18, 0xf5, 0xbe, 0x6b, 0xbb, + 0x75, 0x0b, 0xaa, 0x00, 0xc4, 0x7f, 0x25, 0x2e, 0x71, 0x00, 0xb2, 0x6f, + 0xa5, 0x6f, 0xaa, 0x00, 0x54, 0x01, 0x84, 0x6f, 0x72, 0x6f, 0x94, 0x05, + 0x80, 0xa9, 0xde, 0x05, 0xb7, 0x23, 0x99, 0x5e, 0x77, 0x0e, 0x41, 0x40, + 0x97, 0x5c, 0xb1, 0x01, 0xd5, 0x7f, 0x00, 0x2e, 0x85, 0x41, 0x0e, 0x2f, + 0x00, 0xa0, 0x0c, 0x2f, 0x14, 0x0f, 0x04, 0x2f, 0xe0, 0x6f, 0x00, 0xac, + 0x10, 0x30, 0x08, 0x2c, 0x18, 0x22, 0xf0, 0x6f, 0x00, 0xac, 0x30, 0x30, + 0x24, 0x30, 0x02, 0x2c, 0x20, 0x22, 0x40, 0x30, 0x0d, 0x2e, 0x71, 0x00, + 0x80, 0xa1, 0x1e, 0x23, 0x79, 0x5e, 0x37, 0x0f, 0xbc, 0x23, 0x00, 0x90, + 0x14, 0x30, 0x10, 0x30, 0x18, 0x2f, 0x9d, 0x50, 0x30, 0x00, 0x9b, 0x56, + 0x43, 0x0e, 0x02, 0x2f, 0x10, 0x30, 0x0a, 0x2c, 0x03, 0x30, 0x99, 0x50, + 0x10, 0x0e, 0x13, 0x30, 0x00, 0x2f, 0x03, 0x30, 0x90, 0x0f, 0x10, 0x30, + 0x00, 0x2f, 0x00, 0x30, 0x00, 0x90, 0x10, 0x30, 0x00, 0x2f, 0x00, 0x30, + 0xc0, 0x90, 0x13, 0x30, 0x00, 0x2f, 0x03, 0x30, 0x40, 0xb2, 0x87, 0x5c, + 0x22, 0x2f, 0x41, 0x90, 0x4a, 0x2f, 0xa5, 0x50, 0x00, 0x2e, 0x01, 0x40, + 0x41, 0x82, 0x01, 0x42, 0x02, 0x80, 0x4a, 0xa8, 0x01, 0x40, 0x06, 0x2f, + 0xd0, 0x6f, 0x85, 0x0e, 0x3e, 0x2f, 0x41, 0x80, 0x21, 0x2e, 0x78, 0x00, + 0x3b, 0x2d, 0x95, 0x50, 0xfb, 0x7f, 0x4a, 0xa8, 0x06, 0x2f, 0x98, 0x2e, + 0x73, 0xb6, 0xc0, 0x90, 0xfb, 0x6f, 0x32, 0x2f, 0x00, 0x2e, 0x30, 0x2d, + 0x98, 0x2e, 0x73, 0xb6, 0x29, 0x2e, 0x7a, 0x00, 0x2b, 0x2c, 0xfb, 0x6f, + 0xa1, 0x52, 0xd2, 0x6f, 0x95, 0x0e, 0x41, 0x40, 0x05, 0x2f, 0x00, 0x90, + 0x17, 0x2f, 0x05, 0x2e, 0x7a, 0x00, 0x80, 0x90, 0x13, 0x2f, 0x7f, 0x82, + 0x40, 0xac, 0x23, 0x2e, 0x77, 0x00, 0x01, 0x30, 0x18, 0x2f, 0xa1, 0x54, + 0x82, 0x84, 0x23, 0x2e, 0x77, 0x00, 0x82, 0x40, 0x80, 0xb2, 0x11, 0x2f, + 0x00, 0x90, 0x23, 0x2e, 0x79, 0x00, 0x0d, 0x2f, 0x29, 0x2e, 0x72, 0x00, + 0x0b, 0x2d, 0x41, 0x80, 0x21, 0x2e, 0x77, 0x00, 0x0f, 0xa4, 0x05, 0x2f, + 0xa3, 0x50, 0x3e, 0x80, 0xf1, 0x30, 0x29, 0x2e, 0x79, 0x00, 0x01, 0x42, + 0x06, 0x30, 0x34, 0x08, 0x00, 0xb2, 0x02, 0x2f, 0x80, 0x30, 0x21, 0x2e, + 0x5e, 0xf0, 0x70, 0x5f, 0xb8, 0x2e, 0x04, 0x84, 0x01, 0x30, 0x81, 0x42, + 0x82, 0x84, 0x01, 0x42, 0xa1, 0x42, 0x81, 0x42, 0x82, 0x84, 0x00, 0x2e, + 0x91, 0x42, 0x81, 0x42, 0xb8, 0x2e, 0x30, 0x50, 0xf3, 0x7f, 0xc0, 0xac, + 0xe4, 0x7f, 0xd5, 0x7f, 0x03, 0x2f, 0x00, 0x30, 0x82, 0x04, 0xf3, 0x6f, + 0xc3, 0x06, 0x40, 0xad, 0x05, 0x2f, 0xe0, 0x6f, 0x05, 0x30, 0x28, 0x04, + 0xd1, 0x6f, 0x69, 0x07, 0xe0, 0x7f, 0x40, 0xa1, 0x01, 0x30, 0x20, 0x2f, + 0x13, 0x25, 0x02, 0x25, 0x04, 0x32, 0x06, 0x30, 0x02, 0x30, 0x03, 0x30, + 0xaf, 0xbb, 0xb1, 0xbd, 0xdf, 0x0a, 0x9f, 0xbb, 0x21, 0xbd, 0x97, 0x0a, + 0x8f, 0xbb, 0x91, 0xbc, 0x01, 0xbc, 0x4f, 0x0a, 0x6b, 0x0e, 0x04, 0x2f, + 0x6b, 0x1a, 0x07, 0x2f, 0xe7, 0x6f, 0x7a, 0x0f, 0x04, 0x2f, 0xe7, 0x6f, + 0x97, 0x04, 0x17, 0x30, 0x07, 0x0a, 0xdd, 0x06, 0x81, 0x8d, 0x34, 0x0e, + 0xe6, 0x2f, 0x00, 0x2e, 0x0d, 0x2d, 0x6b, 0x0e, 0x00, 0x30, 0x05, 0x2f, + 0x6b, 0x1a, 0x07, 0x2f, 0xe0, 0x6f, 0x42, 0x0f, 0x00, 0x30, 0x03, 0x2f, + 0xe0, 0x6f, 0x90, 0x04, 0xdd, 0x06, 0x10, 0x30, 0xf5, 0x6f, 0xc3, 0x7f, + 0xb2, 0x7f, 0x40, 0xad, 0x06, 0x2f, 0x03, 0x30, 0xb2, 0x6f, 0x9a, 0x04, + 0xc4, 0x6f, 0xdc, 0x06, 0xb2, 0x7f, 0xc3, 0x7f, 0x00, 0x2e, 0xd2, 0x6f, + 0xaa, 0x0c, 0x80, 0xac, 0x02, 0x30, 0x01, 0x2f, 0x10, 0x04, 0x51, 0x06, + 0xd0, 0x5f, 0xb8, 0x2e, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, + 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, + 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, + 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, + 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, + 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, + 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, + 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, + 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, + 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, + 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, + 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, + 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, + 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, + 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, + 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, + 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, + 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, + 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, + 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, + 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, + 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, + 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, + 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, + 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, + 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, + 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, + 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, + 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, + 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, + 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, + 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, + 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, + 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, + 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, + 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, + 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, + 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, + 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, + 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, + 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, + 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, + 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, + 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, + 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, + 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, + 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, + 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, + 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, + 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, + 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, + 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, + 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, + 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, + 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, + 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, + 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, + 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, + 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, + 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, + 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, + 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, + 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, + 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, + 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, + 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, + 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, + 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, + 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, + 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, + 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, + 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, + 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, + 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, + 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, + 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, + 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, + 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, + 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, + 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, + 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, + 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, + 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, + 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, + 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, + 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, + 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, + 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, + 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, + 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, + 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, + 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, + 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, + 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, + 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, + 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, + 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, + 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, + 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, + 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, + 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, + 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, + 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, + 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, + 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, + 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, + 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, + 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, + 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, + 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, + 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, + 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, + 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, + 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, + 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, + 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, + 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, + 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, + 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, + 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, + 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, + 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, + 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, + 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, + 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, + 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, + 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, + 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, + 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, + 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, + 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, + 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, + 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, + 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, + 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00 +}; diff --git a/src/REG/BMA423Constants.h b/src/REG/BMA423Constants.h index d969cbd..ba5d61a 100644 --- a/src/REG/BMA423Constants.h +++ b/src/REG/BMA423Constants.h @@ -1,726 +1,213 @@ +/** + * + * @license MIT License + * + * Copyright (c) 2025 lewis he + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * @file BMA423Constants.h + * @author Lewis He (lewishe@outlook.com) + * @date 2025-01-17 + * + */ #pragma once +#include + +#define BMA423_I2C_ADDR_PRIMARY (0x18) +#define BMA423_I2C_ADDR_SECONDARY (0x19) + +class BMA423Constants +{ +protected: + static constexpr uint8_t BAM423_SENSOR_RESOLUTION = (12) ; //* + static constexpr uint8_t RESET_REG = (0x7E); //* + static constexpr uint8_t CHIP_ID_ADDR = (0x00); /**\name CHIP ID ADDRESS*/ + static constexpr uint8_t CHIP_ID = (0x13); /**\name Chip ID of BMA423 sensor */ + static constexpr uint8_t POWER_CONF_ADDR = (0x7C); /**\name POWER_CTRL REGISTER*/ + static constexpr uint8_t POWER_CTRL_ADDR = (0x7D); /**\name POWER_CTRL REGISTER*/ + static constexpr uint8_t ADVANCE_POWER_SAVE_MSK = (0x01); /**\name ADVANCE POWER SAVE POSITION AND MASK*/ + static constexpr uint8_t INT_MAP_1_ADDR = (0X56); /**\name MAP INTERRUPT 1 and 2 REGISTERS*/ + static constexpr uint8_t INT_MAP_2_ADDR = (0X57); /**\name MAP INTERRUPT 1 and 2 REGISTERS*/ + static constexpr uint8_t INT_MAP_DATA_ADDR = (0x58); /**\name MAP INTERRUPT 1 and 2 REGISTERS*/ + static constexpr uint8_t INIT_CTRL_ADDR = (0x59); /**\name MAP INTERRUPT 1 and 2 REGISTERS*/ + static constexpr uint8_t RESERVED_REG_5B_ADDR = (0x5B); /**\name FEATURE CONFIG RELATED */ + static constexpr uint8_t RESERVED_REG_5C_ADDR = (0x5C); /**\name FEATURE CONFIG RELATED */ + static constexpr uint8_t FEATURE_CONFIG_ADDR = (0x5E); /**\name FEATURE CONFIG RELATED */ + static constexpr uint8_t INTERNAL_ERROR = (0x5F); /**\name FEATURE CONFIG RELATED */ + static constexpr uint8_t STEP_CNT_OUT_0_ADDR = (0x1E); /**\name GPIO REGISTERS*/ + static constexpr uint8_t HIGH_G_OUT_ADDR = (0x1F); /**\name GPIO REGISTERS*/ + static constexpr uint8_t ACTIVITY_OUT_ADDR = (0x27); /**\name GPIO REGISTERS*/ + static constexpr uint8_t ORIENTATION_OUT_ADDR = (0x28); /**\name GPIO REGISTERS*/ + static constexpr uint8_t INTERNAL_STAT = (0x2A); /**\name GPIO REGISTERS*/ + static constexpr uint8_t SENSORTIME_0_ADDR = (0X18); /**\name SENSOR TIME REGISTERS*/ + static constexpr uint8_t INT_STAT_0_ADDR = (0X1C); /**\name INTERRUPT/FEATURE STATUS REGISTERS*/ + static constexpr uint8_t INT_STAT_1_ADDR = (0X1D); /**\name INTERRUPT/FEATURE STATUS REGISTERS*/ + static constexpr uint8_t DATA_0_ADDR = (0X0A); /**\name AUX/ACCEL DATA BASE ADDRESS REGISTERS*/ + static constexpr uint8_t DATA_8_ADDR = (0X12); /**\name AUX/ACCEL DATA BASE ADDRESS REGISTERS*/ + static constexpr uint8_t ACCEL_CONFIG_ADDR = (0X40); /**\name AUX/ACCEL DATA BASE ADDRESS REGISTERS*/ + static constexpr uint8_t TEMPERATURE_ADDR = (0X22); /**\name AUX/ACCEL DATA BASE ADDRESS REGISTERS*/ + static constexpr uint8_t INT1_IO_CTRL_ADDR = (0X53); /**\name INTERRUPT ENABLE REGISTERS*/ + static constexpr uint8_t INT2_IO_CTRL_ADDR = (0X54); /**\name INTERRUPT ENABLE REGISTERS*/ + static constexpr uint8_t INTR_LATCH_ADDR = (0X55); /**\name LATCH DURATION REGISTERS*/ + + + /**\name BUS READ AND WRITE LENGTH FOR MAG & ACCEL*/ + static constexpr uint8_t MAG_TRIM_DATA_SIZE = (16); + static constexpr uint8_t MAG_XYZ_DATA_LENGTH = (6); + static constexpr uint8_t MAG_XYZR_DATA_LENGTH = (8); + static constexpr uint8_t ACCEL_DATA_LENGTH = (6); + static constexpr uint8_t FIFO_DATA_LENGTH = (2); + static constexpr uint8_t TEMP_DATA_SIZE = (1); + + + + /**\name Feature offset address */ + static constexpr uint8_t ANY_NO_MOTION_OFFSET = (0x00); + static constexpr uint8_t STEP_CNTR_OFFSET = (0x36); + static constexpr uint8_t STEP_CNTR_PARAM_OFFSET = (0x04); + static constexpr uint8_t WAKEUP_OFFSET = (0x38); + static constexpr uint8_t TILT_OFFSET = (0x3A); + static constexpr uint8_t CONFIG_ID_OFFSET = (0x3C); + static constexpr uint8_t AXES_REMAP_OFFSET = (0x3E); + + /**\name Sensor feature size */ + static constexpr uint8_t FEATURE_SIZE = (64); + static constexpr uint8_t ANYMOTION_EN_LEN = (2); + static constexpr uint8_t RD_WR_MIN_LEN = (2); + + /**************************************************************/ + /**\name Remap Axes */ + /**************************************************************/ + static constexpr uint8_t X_AXIS_MASK = (0x03); + static constexpr uint8_t X_AXIS_SIGN_MASK = (0x04); + static constexpr uint8_t Y_AXIS_MASK = (0x18); + static constexpr uint8_t Y_AXIS_SIGN_MASK = (0x20); + static constexpr uint8_t Z_AXIS_MASK = (0xC0); + static constexpr uint8_t Z_AXIS_SIGN_MASK = (0x01); + + + + /**\name ACCELEROMETER ENABLE POSITION AND MASK*/ + static constexpr uint8_t ACCEL_ENABLE_MSK = (0x04); + static constexpr uint8_t ASIC_INITIALIZED = (0x01); + + /**************************************************************/ + /**\name Step Counter & Detector */ + /**************************************************************/ + /**\name Step counter enable macros */ + static constexpr uint8_t STEP_CNTR_EN_POS = (4); + static constexpr uint8_t STEP_CNTR_EN_MSK = (0x10); + static constexpr uint8_t ACTIVITY_EN_MSK = (0x20); + + /**\name Step counter watermark macros */ + static constexpr uint16_t STEP_CNTR_WM_MSK = (0x03FF); + + /**\name Step counter reset macros */ + static constexpr uint8_t STEP_CNTR_RST_POS = (2); + static constexpr uint8_t STEP_CNTR_RST_MSK = (0x04); + + /**\name Step detector enable macros */ + static constexpr uint8_t STEP_DETECTOR_EN_POS = (3); + static constexpr uint8_t STEP_DETECTOR_EN_MSK = (0x08); + + /**\name Tilt enable macros */ + static constexpr uint8_t TILT_EN_MSK = (0x01); + + /**\name Step count output length*/ + static constexpr uint8_t STEP_CNTR_DATA_SIZE = (4); + + /**\name Wakeup enable macros */ + static constexpr uint8_t WAKEUP_EN_MSK = (0x01); + + /**\name Wake up sensitivity macros */ + static constexpr uint8_t WAKEUP_SENS_POS = (1); + static constexpr uint8_t WAKEUP_SENS_MSK = (0x0E); + + /**\name Tap selection macro */ + static constexpr uint8_t TAP_SEL_POS = (4); + static constexpr uint8_t TAP_SEL_MSK = (0x10); + + /**************************************************************/ + /**\name Any Motion */ + /**************************************************************/ + /**\name Any motion threshold macros */ + static constexpr uint8_t ANY_NO_MOTION_THRES_POS = (0); + static constexpr uint16_t ANY_NO_MOTION_THRES_MSK = (0x07FF); + + /**\name Any motion selection macros */ + static constexpr uint8_t ANY_NO_MOTION_SEL_POS = (3); + static constexpr uint8_t ANY_NO_MOTION_SEL_MSK = (0x08); + + /**\name Any motion enable macros */ + static constexpr uint8_t ANY_NO_MOTION_AXIS_EN_POS = (5); + static constexpr uint8_t ANY_NO_MOTION_AXIS_EN_MSK = (0xE0); + + /**\name Any motion duration macros */ + static constexpr uint16_t ANY_NO_MOTION_DUR_MSK = (0x1FFF); + + /**\name INTERRUPT MAPS */ + static constexpr uint8_t INTR1_MAP = (0); + static constexpr uint8_t INTR2_MAP = (1); + + + + /**\name CONSTANTS */ + static constexpr uint8_t FIFO_CONFIG_LENGTH = (2); + static constexpr uint8_t ACCEL_CONFIG_LENGTH = (2); + static constexpr uint8_t FIFO_WM_LENGTH = (2); + static constexpr uint16_t CONFIG_STREAM_SIZE = (6144); + static constexpr uint8_t NON_LATCH_MODE = (0); + static constexpr uint8_t LATCH_MODE = (1); + static constexpr uint8_t PUSH_PULL = (0); + static constexpr uint8_t ACTIVE_HIGH = (1); + static constexpr uint8_t ACTIVE_LOW = (0); + static constexpr uint8_t EDGE_TRIGGER = (1); + static constexpr uint8_t LEVEL_TRIGGER = (0); + static constexpr uint8_t OUTPUT_ENABLE = (1); + static constexpr uint8_t OUTPUT_DISABLE = (0); + static constexpr uint8_t INPUT_ENABLE = (1); + static constexpr uint8_t INPUT_DISABLE = (0); + + + /**\name OUTPUT TYPE ENABLE POSITION AND MASK*/ + static constexpr uint8_t INT_EDGE_CTRL_MASK = (0x01); + static constexpr uint8_t INT_EDGE_CTRL_POS = (0x00); + static constexpr uint8_t INT_LEVEL_MASK = (0x02); + static constexpr uint8_t INT_LEVEL_POS = (0x01); + static constexpr uint8_t INT_OPEN_DRAIN_MASK = (0x04); + static constexpr uint8_t INT_OPEN_DRAIN_POS = (0x02); + static constexpr uint8_t INT_OUTPUT_EN_MASK = (0x08); + static constexpr uint8_t INT_OUTPUT_EN_POS = (0x03); + static constexpr uint8_t INT_INPUT_EN_MASK = (0x10); + static constexpr uint8_t INT_INPUT_EN_POS = (0x04); + + + /**\name Interrupt status macros */ + static constexpr uint8_t STEP_CNTR_INT = (0x02); + static constexpr uint8_t ACTIVITY_INT = (0x04); + static constexpr uint8_t TILT_INT = (0x08); + static constexpr uint8_t WAKEUP_INT = (0x20); + static constexpr uint8_t ANY_NO_MOTION_INT = (0x40); + static constexpr uint8_t ERROR_INT = (0x80); -#define BMA423_SLAVE_ADDRESS (0x19) - - -#define BAM423_SENSOR_RESOLUTION (12) - -#define BMA423_RESET_REG (0x7E) - -/**\name CHIP ID ADDRESS*/ -#define BMA4_CHIP_ID_ADDR (0x00) - -/**\name Chip ID of BMA423 sensor */ -#define BMA423_CHIP_ID (0x13) - -/**\name POWER_CTRL REGISTER*/ -#define BMA4_POWER_CONF_ADDR (0x7C) -#define BMA4_POWER_CTRL_ADDR (0x7D) - - -/**\name ADVANCE POWER SAVE POSITION AND MASK*/ -#define BMA4_ADVANCE_POWER_SAVE_MSK (0x01) - -/**\name MAP INTERRUPT 1 and 2 REGISTERS*/ -#define BMA4_INT_MAP_1_ADDR (0X56) -#define BMA4_INT_MAP_2_ADDR (0X57) -#define BMA4_INT_MAP_DATA_ADDR (0x58) -#define BMA4_INIT_CTRL_ADDR (0x59) - - -/**\name FEATURE CONFIG RELATED */ -#define BMA4_RESERVED_REG_5B_ADDR (0x5B) -#define BMA4_RESERVED_REG_5C_ADDR (0x5C) -#define BMA4_FEATURE_CONFIG_ADDR (0x5E) -#define BMA4_INTERNAL_ERROR (0x5F) - -/**\name GPIO REGISTERS*/ -#define BMA4_STEP_CNT_OUT_0_ADDR (0x1E) -#define BMA4_HIGH_G_OUT_ADDR (0x1F) -#define BMA4_ACTIVITY_OUT_ADDR (0x27) -#define BMA4_ORIENTATION_OUT_ADDR (0x28) -#define BMA4_INTERNAL_STAT (0x2A) - - - - -/**\name SENSOR TIME REGISTERS*/ -#define BMA4_SENSORTIME_0_ADDR (0X18) - -/**\name INTERRUPT/FEATURE STATUS REGISTERS*/ -#define BMA4_INT_STAT_0_ADDR (0X1C) - -/**\name INTERRUPT/FEATURE STATUS REGISTERS*/ -#define BMA4_INT_STAT_1_ADDR (0X1D) - -/**\name BUS READ AND WRITE LENGTH FOR MAG & ACCEL*/ -#define BMA4_MAG_TRIM_DATA_SIZE (16) -#define BMA4_MAG_XYZ_DATA_LENGTH (6) -#define BMA4_MAG_XYZR_DATA_LENGTH (8) -#define BMA4_ACCEL_DATA_LENGTH (6) -#define BMA4_FIFO_DATA_LENGTH (2) -#define BMA4_TEMP_DATA_SIZE (1) - -/**\name AUX/ACCEL DATA BASE ADDRESS REGISTERS*/ -#define BMA4_DATA_0_ADDR (0X0A) -#define BMA4_DATA_8_ADDR (0X12) - - -/**\name Feature offset address */ -#define BMA423_ANY_NO_MOTION_OFFSET (0x00) -#define BMA423_STEP_CNTR_OFFSET (0x36) -#define BMA423_STEP_CNTR_PARAM_OFFSET (0x04) -#define BMA423_WAKEUP_OFFSET (0x38) -#define BMA423_TILT_OFFSET (0x3A) -#define BMA423_CONFIG_ID_OFFSET (0x3C) -#define BMA423_AXES_REMAP_OFFSET (0x3E) - -/**\name Sensor feature size */ -#define BMA423_FEATURE_SIZE (64) -#define BMA423_ANYMOTION_EN_LEN (2) -#define BMA423_RD_WR_MIN_LEN (2) - -/**************************************************************/ -/**\name Remap Axes */ -/**************************************************************/ -#define BMA423_X_AXIS_MASK (0x03) -#define BMA423_X_AXIS_SIGN_MASK (0x04) -#define BMA423_Y_AXIS_MASK (0x18) -#define BMA423_Y_AXIS_SIGN_MASK (0x20) -#define BMA423_Z_AXIS_MASK (0xC0) -#define BMA423_Z_AXIS_SIGN_MASK (0x01) - - - -/**\name ACCELEROMETER ENABLE POSITION AND MASK*/ -#define BMA4_ACCEL_ENABLE_MSK (0x04) -#define BMA4_ASIC_INITIALIZED (0x01) - -#define BMA4_CONFIG_STREAM_SIZE (6144) - - -/**\name Feature configuration file */ -static const unsigned char bma423_config_file[] = { - 0x80, 0x2e, 0xfc, 0x00, 0x80, 0x2e, 0xfe, 0x00, 0xc8, 0x2e, 0x00, 0x2e, - 0x80, 0x2e, 0xfa, 0x00, 0x80, 0x2e, 0x23, 0xb1, 0x80, 0x2e, 0xfd, 0x00, - 0x80, 0x2e, 0xfb, 0x00, 0x80, 0x2e, 0x5a, 0xb1, 0x50, 0x39, 0x21, 0x2e, - 0xb0, 0xf0, 0x10, 0x30, 0x21, 0x2e, 0x16, 0xf0, 0x80, 0x2e, 0xfc, 0x01, - 0x5d, 0x50, 0x45, 0x52, 0x01, 0x42, 0x3b, 0x80, 0x41, 0x30, 0x01, 0x42, - 0x3c, 0x80, 0x00, 0x2e, 0x01, 0x40, 0x01, 0x42, 0x21, 0x2e, 0xff, 0xaf, - 0xb8, 0x2e, 0xb6, 0xd6, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, - 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, - 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, - 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, - 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, - 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, - 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, - 0xfd, 0x2d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x02, 0x01, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0xf8, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x49, 0x00, 0x24, 0x01, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x98, 0x2e, - 0x99, 0x01, 0x20, 0x26, 0x98, 0x2e, 0xf6, 0x00, 0x98, 0x2e, 0xe9, 0x01, - 0x10, 0x30, 0x21, 0x2e, 0x59, 0xf0, 0x98, 0x2e, 0xd8, 0x00, 0x00, 0x2e, - 0x00, 0x2e, 0xd0, 0x2e, 0x98, 0x2e, 0xdd, 0x00, 0x01, 0x2e, 0x56, 0x00, - 0x00, 0xb2, 0x11, 0x2f, 0x00, 0x30, 0x21, 0x2e, 0x56, 0x00, 0x41, 0x50, - 0x98, 0x2e, 0xcc, 0xb0, 0x41, 0x50, 0x98, 0x2e, 0x8f, 0xb4, 0x01, 0x2e, - 0x03, 0xf0, 0x0d, 0xbc, 0x0f, 0xb8, 0x00, 0x90, 0x02, 0x2f, 0x45, 0x50, - 0x21, 0x2e, 0xbc, 0xf0, 0x01, 0x2e, 0x55, 0x00, 0x00, 0xb2, 0x1a, 0x2f, - 0x00, 0x30, 0x21, 0x2e, 0x55, 0x00, 0x43, 0x50, 0x98, 0x2e, 0xcc, 0xb0, - 0x43, 0x50, 0x98, 0x2e, 0xdc, 0xb1, 0x43, 0x50, 0x98, 0x2e, 0x92, 0xb5, - 0x43, 0x50, 0x98, 0x2e, 0x00, 0xb0, 0x01, 0x2e, 0x1c, 0x01, 0x0f, 0xbc, - 0x0f, 0xb8, 0x00, 0x90, 0x45, 0x50, 0x02, 0x2f, 0x21, 0x2e, 0xbc, 0xf0, - 0x02, 0x2d, 0x21, 0x2e, 0xba, 0xf0, 0x98, 0x2e, 0xd8, 0x00, 0xc3, 0x2d, - 0x01, 0x2e, 0x55, 0xf0, 0xc0, 0x2e, 0x21, 0x2e, 0x55, 0xf0, 0x03, 0x2e, - 0x00, 0xf0, 0x45, 0x54, 0x01, 0x2e, 0x59, 0xf0, 0x4a, 0x0e, 0x02, 0x2f, - 0xf1, 0x33, 0x0d, 0x2c, 0x01, 0x08, 0xf2, 0x30, 0x4a, 0x08, 0x79, 0x84, - 0x82, 0xa2, 0x04, 0x2f, 0x02, 0x34, 0x82, 0x0a, 0x47, 0xa2, 0x03, 0x2c, - 0x10, 0x22, 0x45, 0x52, 0x01, 0x0a, 0xc0, 0x2e, 0x21, 0x2e, 0x59, 0xf0, - 0x00, 0x31, 0xc0, 0x2e, 0x21, 0x2e, 0xba, 0xf0, 0xc8, 0x2e, 0xc8, 0x2e, - 0xc8, 0x2e, 0xc8, 0x2e, 0xc8, 0x2e, 0x44, 0x47, 0xaa, 0x00, 0x05, 0x00, - 0x2d, 0x01, 0xd4, 0x7b, 0x3b, 0x01, 0xdb, 0x7a, 0x04, 0x00, 0x3f, 0x7b, - 0xcd, 0x6c, 0xc3, 0x04, 0x85, 0x09, 0xc3, 0x04, 0xec, 0xe6, 0x0c, 0x46, - 0x01, 0x00, 0x27, 0x00, 0x19, 0x00, 0x96, 0x00, 0xa0, 0x00, 0x01, 0x00, - 0x0c, 0x00, 0xf0, 0x3c, 0x00, 0x01, 0x01, 0x00, 0x03, 0x00, 0x01, 0x00, - 0x0e, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x43, 0x28, 0x88, 0x00, - 0x52, 0x00, 0x4f, 0x00, 0x80, 0x00, 0x5b, 0x00, 0x00, 0x40, 0xaf, 0x00, - 0xff, 0x00, 0xff, 0xb7, 0x00, 0x02, 0x00, 0xb0, 0x05, 0x80, 0xb1, 0xf0, - 0xc0, 0x00, 0x00, 0x01, 0x5e, 0xf0, 0x39, 0xf0, 0x89, 0xf0, 0x00, 0x20, - 0xff, 0x7f, 0x7d, 0x00, 0x5e, 0x00, 0x62, 0x00, 0x7c, 0x00, 0xff, 0xfb, - 0x52, 0xf0, 0x56, 0xf0, 0x33, 0x09, 0x33, 0x07, 0x00, 0x08, 0x90, 0x01, - 0x00, 0xf8, 0x67, 0x00, 0x4c, 0x04, 0xa0, 0x00, 0xe8, 0x03, 0x81, 0x00, - 0x82, 0x00, 0x6a, 0x00, 0x6d, 0x00, 0x6c, 0x00, 0xeb, 0x07, 0xae, 0x07, - 0x72, 0x00, 0x6f, 0x00, 0xa1, 0x01, 0x1e, 0x05, 0x47, 0xfd, 0x73, 0x00, - 0x77, 0x00, 0x79, 0x00, 0x76, 0x00, 0xcc, 0x00, 0x30, 0x50, 0x50, 0x40, - 0x00, 0x18, 0x50, 0x40, 0x56, 0x25, 0x47, 0x25, 0x00, 0x18, 0x2e, 0x00, - 0x41, 0x40, 0xa7, 0x02, 0x09, 0x18, 0xc6, 0x00, 0xfb, 0x7f, 0x00, 0x30, - 0x49, 0x52, 0x05, 0x30, 0x05, 0x2c, 0x17, 0x03, 0x1e, 0xbd, 0xd2, 0xba, - 0x92, 0xb8, 0x6a, 0x0b, 0x61, 0x0e, 0xf9, 0x2f, 0x61, 0x1a, 0x01, 0x2f, - 0x5d, 0x0e, 0xf5, 0x2f, 0xd4, 0x7f, 0x02, 0x30, 0x1f, 0x2c, 0xe3, 0x7f, - 0x85, 0x01, 0xd1, 0x03, 0x7c, 0x0e, 0x03, 0x2f, 0x7c, 0x1a, 0x0f, 0x2f, - 0x73, 0x0f, 0x0d, 0x2f, 0xe3, 0x6f, 0xde, 0x04, 0x5f, 0xba, 0x11, 0xbf, - 0xb4, 0x0b, 0xd4, 0x6f, 0x27, 0x07, 0xb3, 0x25, 0xd1, 0xbf, 0xeb, 0x7f, - 0x07, 0x00, 0xb4, 0x25, 0x96, 0x02, 0xdb, 0x7f, 0x2f, 0xbf, 0x9e, 0xbf, - 0x01, 0xb8, 0xd2, 0xba, 0x21, 0xb9, 0x92, 0xb8, 0x06, 0x0a, 0x6f, 0x0b, - 0x40, 0x90, 0xdf, 0x2f, 0x40, 0x91, 0xdd, 0x2f, 0xfb, 0x6f, 0xd0, 0x5f, - 0xb8, 0x2e, 0x57, 0x50, 0x41, 0x30, 0x02, 0x40, 0x51, 0x0a, 0x01, 0x42, - 0x18, 0x82, 0x4b, 0x50, 0x60, 0x42, 0x70, 0x3c, 0x4d, 0x54, 0x42, 0x42, - 0x69, 0x82, 0x82, 0x32, 0x43, 0x40, 0x18, 0x08, 0x02, 0x0a, 0x40, 0x42, - 0x42, 0x80, 0x02, 0x3f, 0x01, 0x40, 0x10, 0x50, 0x4a, 0x08, 0xfb, 0x7f, - 0x11, 0x42, 0x0b, 0x31, 0x0b, 0x42, 0x3e, 0x80, 0x01, 0x32, 0x01, 0x42, - 0x00, 0x2e, 0x01, 0x2e, 0x40, 0xf0, 0x13, 0x90, 0x20, 0x2f, 0x03, 0x30, - 0x51, 0x50, 0x4f, 0x54, 0xf4, 0x34, 0x06, 0x30, 0x55, 0x52, 0x55, 0x32, - 0x1d, 0x1a, 0xe3, 0x22, 0x18, 0x1a, 0x53, 0x58, 0xe3, 0x22, 0x04, 0x30, - 0xd5, 0x40, 0xb5, 0x0d, 0xe1, 0xbe, 0x6f, 0xbb, 0x80, 0x91, 0xa9, 0x0d, - 0x01, 0x89, 0xb5, 0x23, 0x10, 0xa1, 0xf7, 0x2f, 0xda, 0x0e, 0xf4, 0x34, - 0xeb, 0x2f, 0x01, 0x2e, 0x25, 0x00, 0x70, 0x1a, 0x00, 0x30, 0x21, 0x30, - 0x02, 0x2c, 0x08, 0x22, 0x30, 0x30, 0x00, 0xb2, 0x06, 0x2f, 0x21, 0x2e, - 0x59, 0xf0, 0x98, 0x2e, 0xd8, 0x00, 0x00, 0x2e, 0x00, 0x2e, 0xd0, 0x2e, - 0xfb, 0x6f, 0xf0, 0x5f, 0xb8, 0x2e, 0x01, 0x2e, 0xb1, 0xf0, 0x59, 0x52, - 0x01, 0x0a, 0x21, 0x2e, 0xb1, 0xf0, 0x01, 0x2e, 0x1c, 0x01, 0x0f, 0xbc, - 0x0f, 0xb8, 0x00, 0x90, 0x45, 0x50, 0x02, 0x2f, 0xc0, 0x2e, 0x21, 0x2e, - 0xbc, 0xf0, 0xc0, 0x2e, 0x21, 0x2e, 0xba, 0xf0, 0x1a, 0x24, 0x26, 0x00, - 0x80, 0x2e, 0x8f, 0x00, 0x03, 0x2e, 0x01, 0x01, 0x05, 0x2e, 0x01, 0x01, - 0x92, 0xbd, 0x20, 0x50, 0x03, 0x2e, 0x01, 0x01, 0xbf, 0xba, 0x21, 0xbd, - 0x2f, 0xbb, 0x1f, 0xba, 0x40, 0x91, 0xf0, 0x7f, 0x04, 0x2f, 0x80, 0x91, - 0x02, 0x2f, 0x00, 0xb3, 0x90, 0x2e, 0xc7, 0xb0, 0x03, 0x2e, 0x7b, 0x00, - 0x01, 0x80, 0x40, 0x90, 0x14, 0x2f, 0x41, 0x84, 0xf1, 0x6f, 0x25, 0x2e, - 0x7b, 0x00, 0x41, 0x40, 0x23, 0x2e, 0x5a, 0x00, 0x47, 0x52, 0x12, 0x40, - 0x52, 0x42, 0x02, 0x30, 0x00, 0x40, 0x40, 0x42, 0xe0, 0x5f, 0x25, 0x2e, - 0x57, 0x00, 0x25, 0x2e, 0x58, 0x00, 0x25, 0x2e, 0x5d, 0x00, 0xb8, 0x2e, - 0x07, 0x2e, 0x00, 0x01, 0x03, 0x2e, 0x01, 0x01, 0x05, 0x2e, 0x00, 0x01, - 0x24, 0xbd, 0x0f, 0x2e, 0x59, 0x00, 0xb5, 0xbd, 0x93, 0xbc, 0x2f, 0xb9, - 0xb5, 0xb9, 0x93, 0xb8, 0x3a, 0x1a, 0x06, 0x2f, 0x07, 0x30, 0x25, 0x2e, - 0x59, 0x00, 0x2f, 0x2e, 0x57, 0x00, 0x2f, 0x2e, 0x58, 0x00, 0x40, 0xb3, - 0x05, 0x30, 0x07, 0x30, 0x0a, 0x2f, 0xf7, 0x6f, 0xe6, 0x7f, 0x00, 0x2e, - 0xc6, 0x41, 0x0f, 0x2e, 0x5a, 0x00, 0xb7, 0x05, 0x80, 0xa9, 0xee, 0x05, - 0xf7, 0x23, 0xe6, 0x6f, 0x80, 0xb3, 0x06, 0x30, 0x09, 0x2f, 0xe7, 0x7f, - 0x00, 0x2e, 0x06, 0x40, 0x0f, 0x2e, 0x5b, 0x00, 0xb7, 0x05, 0x80, 0xa9, - 0xee, 0x05, 0xb7, 0x23, 0xe7, 0x6f, 0x00, 0xb3, 0x04, 0x30, 0x0b, 0x2f, - 0xf4, 0x6f, 0x02, 0x89, 0xe7, 0x7f, 0x00, 0x2e, 0x04, 0x41, 0x0f, 0x2e, - 0x5c, 0x00, 0x27, 0x05, 0x00, 0xa9, 0xec, 0x05, 0x27, 0x23, 0xe7, 0x6f, - 0x7b, 0x0f, 0x17, 0x30, 0x0b, 0x2f, 0x73, 0x0f, 0x05, 0x30, 0x17, 0x30, - 0x07, 0x2f, 0x63, 0x0f, 0x15, 0x30, 0x17, 0x30, 0x00, 0x2f, 0x07, 0x30, - 0xe3, 0x0e, 0x00, 0x2f, 0x05, 0x30, 0x80, 0x90, 0x05, 0x2e, 0x57, 0x00, - 0x13, 0x30, 0x13, 0x29, 0xf2, 0x6f, 0x47, 0x5c, 0x17, 0x2f, 0xc0, 0x91, - 0x05, 0x30, 0x0b, 0x2f, 0x07, 0x2e, 0x58, 0x00, 0xc1, 0x86, 0x2b, 0x2e, - 0x57, 0x00, 0x59, 0x0e, 0x27, 0x2e, 0x58, 0x00, 0x24, 0x2f, 0x2b, 0x2e, - 0x5d, 0x00, 0x22, 0x2d, 0x61, 0x0e, 0x29, 0x2e, 0x57, 0x00, 0x2b, 0x2e, - 0x58, 0x00, 0x1b, 0x2f, 0x27, 0x2e, 0x5d, 0x00, 0x19, 0x2d, 0x40, 0x91, - 0x05, 0x2f, 0x01, 0x30, 0x23, 0x2e, 0x57, 0x00, 0x23, 0x2e, 0x5d, 0x00, - 0x06, 0x2d, 0x29, 0x2e, 0x57, 0x00, 0x61, 0x0e, 0x01, 0x2f, 0x27, 0x2e, - 0x5d, 0x00, 0x81, 0x40, 0x23, 0x2e, 0x5a, 0x00, 0x30, 0x25, 0x47, 0x52, - 0xd4, 0x40, 0x54, 0x42, 0x00, 0x2e, 0xc3, 0x40, 0x43, 0x42, 0x00, 0x2e, - 0x03, 0x2e, 0x5d, 0x00, 0x40, 0xb2, 0x0d, 0x2f, 0x81, 0x40, 0x23, 0x2e, - 0x5a, 0x00, 0x11, 0x40, 0x91, 0x43, 0x01, 0x34, 0x00, 0x40, 0x80, 0x43, - 0x23, 0x2e, 0x5e, 0xf0, 0x03, 0x2d, 0x00, 0x30, 0x21, 0x2e, 0x7b, 0x00, - 0xe0, 0x5f, 0xb8, 0x2e, 0x50, 0x50, 0xf0, 0x7f, 0x1a, 0x25, 0x13, 0x40, - 0x7b, 0x84, 0xe0, 0x7f, 0x83, 0x42, 0x35, 0x30, 0x11, 0x40, 0x04, 0x40, - 0xc1, 0x7f, 0xd4, 0x7f, 0x86, 0x31, 0x07, 0x2e, 0x59, 0xf0, 0x03, 0x2e, - 0x1f, 0x01, 0x0d, 0x09, 0x02, 0xab, 0x05, 0x30, 0x8e, 0x09, 0x2c, 0x23, - 0xe3, 0xba, 0x42, 0xab, 0x16, 0x30, 0x75, 0x23, 0x59, 0x5c, 0x8e, 0x09, - 0x66, 0xbb, 0x82, 0xab, 0x27, 0x30, 0xbe, 0x23, 0x3e, 0x80, 0x25, 0x1a, - 0x06, 0x2f, 0x2e, 0x1a, 0x04, 0x2f, 0x26, 0x1a, 0x02, 0x2f, 0xf7, 0x3d, - 0x03, 0x2c, 0xdf, 0x08, 0x07, 0x32, 0xdf, 0x0a, 0x14, 0x01, 0x55, 0x01, - 0x04, 0x41, 0x14, 0x42, 0x16, 0x01, 0x42, 0x41, 0x45, 0x30, 0x4d, 0x09, - 0x04, 0x41, 0x12, 0x42, 0x04, 0x42, 0x40, 0xb3, 0x04, 0x2f, 0xf0, 0x6f, - 0x02, 0x30, 0x04, 0x40, 0x94, 0x04, 0x02, 0x42, 0x00, 0x32, 0x08, 0x08, - 0x00, 0xb2, 0x00, 0x30, 0x05, 0x2f, 0xe2, 0x6f, 0x00, 0x2e, 0x84, 0x40, - 0x04, 0x05, 0x84, 0x42, 0x00, 0x2e, 0x5b, 0x54, 0x4a, 0x08, 0x40, 0xb2, - 0xf1, 0x6f, 0x04, 0x2f, 0x42, 0x82, 0x00, 0x2e, 0x42, 0x40, 0x02, 0x04, - 0x40, 0x42, 0xb0, 0x5f, 0x27, 0x2e, 0x59, 0xf0, 0xb8, 0x2e, 0x50, 0x50, - 0xf7, 0x7f, 0x00, 0x2e, 0x0f, 0x2e, 0xb8, 0xf0, 0xf8, 0xbf, 0xff, 0xbb, - 0xc0, 0xb3, 0x2a, 0x2f, 0x0f, 0x2e, 0x01, 0xf0, 0xfe, 0xbf, 0xe6, 0x7f, - 0x7e, 0xbb, 0xd5, 0x7f, 0x37, 0x30, 0x5f, 0x5a, 0xbe, 0x05, 0x67, 0x41, - 0xc4, 0x7f, 0x78, 0xbe, 0x47, 0x41, 0x27, 0x0b, 0xb3, 0x7f, 0xe6, 0x11, - 0x41, 0x56, 0x43, 0x89, 0xd7, 0x42, 0x00, 0x2e, 0x27, 0x41, 0x05, 0x41, - 0xf8, 0xbf, 0x7d, 0x0b, 0x6e, 0x11, 0x03, 0x8f, 0xd5, 0x42, 0x14, 0x30, - 0xe5, 0x41, 0xc7, 0x41, 0xd8, 0xbe, 0x6f, 0x0b, 0x6e, 0x11, 0xc5, 0x42, - 0x29, 0x2e, 0x56, 0x00, 0x45, 0x56, 0x27, 0x2e, 0xb8, 0xf0, 0xe6, 0x6f, - 0xd5, 0x6f, 0xc4, 0x6f, 0xb3, 0x6f, 0xf7, 0x6f, 0xb0, 0x5f, 0xc8, 0x2e, - 0x50, 0x50, 0xe5, 0x7f, 0xd7, 0x7f, 0xf6, 0x7f, 0x36, 0x30, 0x0b, 0x2e, - 0x01, 0xf0, 0xde, 0xbe, 0xde, 0xbb, 0x61, 0x5a, 0xb7, 0x05, 0x67, 0x41, - 0xc4, 0x7f, 0x78, 0xbe, 0x47, 0x41, 0x27, 0x0b, 0xb3, 0x7f, 0xe6, 0x11, - 0x43, 0x56, 0x43, 0x89, 0xd7, 0x42, 0x00, 0x2e, 0x27, 0x41, 0x05, 0x41, - 0xf8, 0xbf, 0x7d, 0x0b, 0x6e, 0x11, 0x03, 0x8f, 0xd5, 0x42, 0x14, 0x30, - 0xe5, 0x41, 0xc7, 0x41, 0xd8, 0xbe, 0x6f, 0x0b, 0x6e, 0x11, 0xc5, 0x42, - 0x29, 0x2e, 0x55, 0x00, 0x03, 0x31, 0x27, 0x2e, 0xb8, 0xf0, 0xf6, 0x6f, - 0xe5, 0x6f, 0xd7, 0x6f, 0xc4, 0x6f, 0xb3, 0x6f, 0xb0, 0x5f, 0xc8, 0x2e, - 0x40, 0x50, 0xf6, 0x7f, 0x1a, 0x18, 0x63, 0x56, 0x33, 0x00, 0x06, 0x30, - 0xfe, 0x03, 0x0e, 0xb8, 0xf2, 0xbf, 0x07, 0x0a, 0x2a, 0x18, 0x63, 0x5a, - 0xb5, 0x01, 0x03, 0x30, 0xfb, 0x03, 0x6e, 0xbb, 0xf2, 0xbf, 0xe1, 0x7f, - 0xf7, 0x0b, 0x56, 0x40, 0x36, 0x25, 0x46, 0x40, 0x06, 0x28, 0xc7, 0x7f, - 0x22, 0x18, 0xd1, 0x7f, 0xb5, 0x00, 0x01, 0x30, 0x39, 0x03, 0x2e, 0xb9, - 0x42, 0xbe, 0x14, 0x0b, 0xf2, 0x6f, 0x10, 0x18, 0xb5, 0x00, 0xb9, 0x03, - 0x2e, 0xb9, 0x62, 0xbf, 0x96, 0x0a, 0xb6, 0x6f, 0x30, 0x18, 0x75, 0x01, - 0xb9, 0x03, 0x5c, 0x28, 0xe2, 0xbf, 0xde, 0xb9, 0xd6, 0x6f, 0xdf, 0x0a, - 0x8a, 0x28, 0xc4, 0x6f, 0x82, 0x43, 0x23, 0x29, 0xe5, 0x6f, 0xc0, 0x2e, - 0x44, 0x43, 0xc0, 0x5f, 0x40, 0x50, 0xd0, 0x7f, 0x4a, 0x17, 0x00, 0x40, - 0x01, 0x18, 0x46, 0x25, 0x07, 0x25, 0x65, 0x56, 0xd9, 0x04, 0x53, 0x18, - 0xeb, 0x18, 0x05, 0x30, 0x49, 0x16, 0x69, 0x06, 0xca, 0x18, 0xa6, 0x00, - 0xc7, 0x02, 0x65, 0x58, 0xcb, 0x7f, 0x98, 0x2e, 0x7f, 0xb6, 0xcb, 0x6f, - 0xd2, 0x6f, 0xc0, 0x2e, 0x80, 0x42, 0xc0, 0x5f, 0x09, 0x2e, 0x1b, 0x01, - 0x05, 0x2e, 0x1b, 0x01, 0xa3, 0xbc, 0x44, 0xbe, 0x90, 0x50, 0x4f, 0xb9, - 0x07, 0x2e, 0x1b, 0x01, 0x4a, 0x25, 0x9f, 0xb8, 0x39, 0x8f, 0xb2, 0xbd, - 0xf2, 0x7f, 0xbf, 0xb9, 0xeb, 0x7f, 0x8a, 0x0a, 0x37, 0x89, 0x0b, 0x30, - 0x93, 0x0a, 0x8b, 0x7f, 0xcb, 0x43, 0x0b, 0x43, 0x80, 0xb2, 0xd3, 0x7f, - 0xc1, 0x7f, 0x90, 0x2e, 0x87, 0xb2, 0x20, 0x25, 0x01, 0x2e, 0x64, 0x00, - 0x01, 0x90, 0x0e, 0x2f, 0x67, 0x52, 0x01, 0x2e, 0x61, 0x00, 0xb4, 0x7f, - 0xa2, 0x7f, 0x98, 0x2e, 0x8d, 0xb2, 0x00, 0x30, 0x21, 0x2e, 0x64, 0x00, - 0xc1, 0x6f, 0xd3, 0x6f, 0xa2, 0x6f, 0xb4, 0x6f, 0x0b, 0x30, 0x01, 0x2e, - 0x1b, 0x01, 0x06, 0xbc, 0x06, 0xbb, 0x57, 0x25, 0x01, 0x2e, 0x1b, 0x01, - 0x94, 0xb1, 0x05, 0xbc, 0xb6, 0x7f, 0x0f, 0xbb, 0x6b, 0x50, 0x80, 0xb3, - 0x0f, 0x2f, 0x0d, 0x2e, 0x1b, 0x01, 0x6f, 0x5e, 0xb7, 0x09, 0x2d, 0x2e, - 0x1b, 0x01, 0x71, 0x5c, 0x69, 0x5e, 0x9b, 0x43, 0x9b, 0x43, 0xdb, 0x43, - 0x9b, 0x43, 0x1b, 0x42, 0xcb, 0x43, 0x0b, 0x42, 0x8b, 0x43, 0x40, 0xb2, - 0x05, 0x2f, 0x69, 0x50, 0x00, 0x2e, 0x16, 0x40, 0x0b, 0x40, 0x76, 0x7f, - 0x8b, 0x7f, 0xcb, 0x0a, 0x01, 0x2e, 0x61, 0x00, 0x67, 0x52, 0x6d, 0x5c, - 0x98, 0x2e, 0xd3, 0xb2, 0x90, 0x6f, 0x00, 0xb2, 0x0b, 0x2f, 0xf0, 0x6f, - 0x00, 0xb2, 0x08, 0x2f, 0x69, 0x58, 0x6b, 0x50, 0x12, 0x41, 0x12, 0x42, - 0x21, 0x30, 0x04, 0x41, 0x04, 0x42, 0x23, 0x2e, 0x5e, 0xf0, 0xc0, 0x6f, - 0x00, 0xb2, 0x26, 0x2f, 0x74, 0x6f, 0x80, 0x6f, 0x71, 0x54, 0x88, 0xbd, - 0xc8, 0xb8, 0x4b, 0x0a, 0x94, 0x42, 0x91, 0x42, 0x90, 0x42, 0x88, 0xba, - 0x69, 0x52, 0xf3, 0x6f, 0x54, 0x42, 0x85, 0x42, 0xc0, 0x90, 0x40, 0x42, - 0x15, 0x2f, 0x6b, 0x52, 0x00, 0x2e, 0x52, 0x40, 0x41, 0x40, 0xa2, 0x04, - 0x41, 0x06, 0x40, 0xaa, 0x04, 0x2f, 0x40, 0x90, 0x0b, 0x2f, 0xb1, 0x6f, - 0x4a, 0x0f, 0x08, 0x2f, 0xb2, 0x6f, 0x80, 0xb2, 0x05, 0x2f, 0x6b, 0x54, - 0x21, 0x30, 0x94, 0x42, 0x80, 0x42, 0x23, 0x2e, 0x5e, 0xf0, 0xd0, 0x6f, - 0x00, 0xb2, 0x13, 0x2f, 0x01, 0x2e, 0x60, 0x00, 0x09, 0x2e, 0x7c, 0x00, - 0x04, 0x1a, 0x0d, 0x2f, 0x73, 0x50, 0x29, 0x2e, 0x60, 0x00, 0x24, 0x42, - 0x44, 0x30, 0x02, 0x40, 0x02, 0x42, 0x09, 0x80, 0x00, 0x2e, 0x04, 0x42, - 0x03, 0x2d, 0x10, 0x30, 0x21, 0x2e, 0x64, 0x00, 0xeb, 0x6f, 0x70, 0x5f, - 0xb8, 0x2e, 0x09, 0x86, 0x49, 0x54, 0xe4, 0x40, 0xc3, 0x80, 0x94, 0x04, - 0xc3, 0x40, 0x13, 0x05, 0x05, 0x40, 0x25, 0x05, 0x8a, 0x17, 0x73, 0x30, - 0x73, 0x09, 0x8c, 0x17, 0xf3, 0x08, 0xe3, 0x00, 0x4c, 0x82, 0x95, 0x00, - 0xb3, 0xb5, 0x23, 0xb5, 0x53, 0x42, 0x52, 0x42, 0x53, 0x42, 0x42, 0x42, - 0x71, 0x82, 0x75, 0x54, 0x52, 0x42, 0x10, 0x50, 0x77, 0x54, 0x52, 0x42, - 0xfb, 0x7f, 0x22, 0x30, 0x79, 0x56, 0x43, 0x42, 0x44, 0x82, 0x0b, 0x30, - 0x52, 0x42, 0x5b, 0x42, 0x7c, 0x84, 0x4b, 0x42, 0x35, 0x82, 0x8c, 0x80, - 0x8b, 0x42, 0x0b, 0x42, 0x39, 0x80, 0x04, 0x30, 0x0b, 0x42, 0x37, 0x80, - 0x15, 0x30, 0x60, 0x25, 0x98, 0x2e, 0xc6, 0xb2, 0x8b, 0x83, 0xfb, 0x6f, - 0x65, 0x42, 0xc0, 0x2e, 0x44, 0x42, 0xf0, 0x5f, 0x05, 0x80, 0x02, 0x30, - 0x51, 0x82, 0x02, 0x42, 0x13, 0x30, 0x41, 0x40, 0x4b, 0x08, 0x7b, 0x54, - 0x3e, 0x80, 0x51, 0x14, 0xc0, 0x2e, 0x01, 0x42, 0x00, 0x2e, 0x40, 0x51, - 0xd1, 0x7f, 0x12, 0x25, 0x02, 0x30, 0x42, 0x43, 0x32, 0x30, 0x82, 0x43, - 0xc6, 0x7f, 0xe5, 0x7f, 0xb4, 0x7f, 0xa3, 0x7f, 0x90, 0x7f, 0x8b, 0x7f, - 0x98, 0x2e, 0x54, 0x01, 0xc0, 0x7e, 0x00, 0xac, 0x01, 0x2f, 0x65, 0x50, - 0xc0, 0x7e, 0x00, 0x2e, 0x90, 0x6f, 0x09, 0x8a, 0xd1, 0x6f, 0x75, 0x7f, - 0x4c, 0x82, 0x63, 0x41, 0x65, 0x7f, 0x11, 0x7f, 0x00, 0x2e, 0x64, 0x41, - 0x44, 0x85, 0x52, 0x7f, 0x45, 0x7f, 0x00, 0x2e, 0xa6, 0x40, 0x80, 0x40, - 0x32, 0x7f, 0x82, 0x8e, 0xc2, 0x6e, 0x45, 0x41, 0xf0, 0x7f, 0x27, 0x7f, - 0x02, 0x7f, 0x98, 0x2e, 0x8a, 0xb1, 0x23, 0x6f, 0xd1, 0x6f, 0xc2, 0x40, - 0xf9, 0x86, 0x23, 0x7f, 0x80, 0xb2, 0xe0, 0x7e, 0x0f, 0x2f, 0x32, 0x6f, - 0x64, 0x6f, 0x82, 0x40, 0xf2, 0x7f, 0x4e, 0x82, 0x42, 0x6f, 0x50, 0x6f, - 0x73, 0x6f, 0x85, 0x40, 0xc3, 0x40, 0x04, 0x41, 0x06, 0x40, 0xe2, 0x6e, - 0x98, 0x2e, 0x8a, 0xb1, 0xe0, 0x7e, 0xf3, 0x31, 0x10, 0x6f, 0x36, 0x80, - 0xe1, 0x6e, 0x02, 0x40, 0x71, 0x7f, 0x51, 0x04, 0x02, 0x30, 0x40, 0xa8, - 0x91, 0x04, 0x4a, 0x22, 0x89, 0x16, 0x93, 0x08, 0x4a, 0x00, 0x95, 0xb4, - 0x09, 0x18, 0x8e, 0x16, 0x13, 0x30, 0x93, 0x08, 0x21, 0x6f, 0x60, 0x7f, - 0x4d, 0x86, 0x02, 0x80, 0xb2, 0x00, 0x41, 0x40, 0x21, 0xb5, 0x50, 0x7f, - 0x43, 0x7f, 0x98, 0x2e, 0xc2, 0xb1, 0x40, 0x6f, 0x62, 0x6f, 0x55, 0x6f, - 0x13, 0x40, 0x84, 0x40, 0x01, 0x40, 0x45, 0x41, 0x42, 0xbe, 0x1d, 0x18, - 0x4c, 0x04, 0x31, 0x0f, 0x04, 0x8a, 0xc0, 0x6f, 0x11, 0x30, 0x02, 0x2f, - 0x00, 0x2e, 0x03, 0x2c, 0x01, 0x42, 0x23, 0x30, 0x03, 0x42, 0x00, 0x2e, - 0xd6, 0x6f, 0x44, 0x41, 0x8a, 0x87, 0x76, 0x8b, 0x00, 0xb3, 0x53, 0x7f, - 0x15, 0x2f, 0x04, 0x6f, 0x7d, 0x5e, 0x8b, 0x8d, 0xe7, 0x01, 0xc0, 0xa5, - 0x84, 0x41, 0x01, 0x2f, 0x00, 0xa1, 0x03, 0x2f, 0xc0, 0xad, 0x08, 0x2f, - 0x00, 0xa5, 0x06, 0x2f, 0xc6, 0x40, 0x81, 0x8d, 0x07, 0x30, 0x3c, 0x05, - 0xd6, 0x42, 0x04, 0x2c, 0xc4, 0x42, 0x02, 0x2c, 0x07, 0x30, 0x07, 0x30, - 0x86, 0x86, 0x94, 0x6f, 0xd7, 0x7e, 0x0e, 0x8d, 0x00, 0x40, 0x74, 0x89, - 0xc7, 0x40, 0x02, 0xb2, 0xf9, 0x29, 0x45, 0x41, 0x86, 0x41, 0xbe, 0x80, - 0x21, 0x41, 0x75, 0x23, 0x82, 0x40, 0xc7, 0x42, 0x45, 0x7f, 0x34, 0x7f, - 0x20, 0x7f, 0x98, 0x2e, 0xc2, 0xb1, 0x31, 0x6f, 0x60, 0x6f, 0x24, 0x6f, - 0x22, 0x40, 0x05, 0x41, 0x43, 0x40, 0x13, 0x01, 0x43, 0x86, 0xac, 0x0f, - 0xd1, 0x6f, 0x30, 0x7f, 0x00, 0x2f, 0x44, 0x42, 0x48, 0x8a, 0x41, 0x88, - 0xe1, 0x40, 0x13, 0x7f, 0x04, 0x7f, 0xf5, 0x7e, 0x98, 0x2e, 0xc2, 0xb1, - 0x11, 0x6f, 0x60, 0x6f, 0x34, 0x6f, 0x42, 0x40, 0x03, 0x40, 0x9a, 0x04, - 0x04, 0x41, 0x43, 0x82, 0xa2, 0x0e, 0x03, 0x6f, 0x00, 0x2f, 0xc2, 0x42, - 0x00, 0x2e, 0x41, 0x40, 0x72, 0x6f, 0x98, 0x2e, 0xc2, 0xb1, 0x25, 0x6f, - 0x72, 0x6f, 0x53, 0x41, 0x93, 0x0e, 0xd1, 0x6f, 0x46, 0x80, 0x1b, 0x30, - 0x03, 0x30, 0x0c, 0x2f, 0x04, 0x40, 0x00, 0x91, 0x42, 0x42, 0x08, 0x2f, - 0xf6, 0x6e, 0x44, 0x6f, 0x86, 0x41, 0xb4, 0x0e, 0x03, 0x2f, 0x02, 0x88, - 0xdb, 0x7e, 0x03, 0x43, 0x0b, 0x42, 0x46, 0x8d, 0x44, 0x41, 0x47, 0x80, - 0x05, 0x6f, 0x94, 0x0f, 0x76, 0x7f, 0x60, 0x7f, 0x02, 0x2f, 0x45, 0x89, - 0x42, 0x43, 0x03, 0x43, 0x49, 0x88, 0xa5, 0x6f, 0x40, 0x91, 0xa4, 0x7f, - 0x15, 0x30, 0xe2, 0x6f, 0xd3, 0x6e, 0x03, 0x2f, 0x04, 0x30, 0x83, 0x42, - 0x80, 0x2e, 0x77, 0xb4, 0x04, 0x40, 0x25, 0x29, 0x04, 0x42, 0x83, 0x42, - 0x45, 0x82, 0x94, 0x6f, 0x04, 0x85, 0xc0, 0xb2, 0x90, 0x2e, 0x63, 0xb4, - 0x15, 0x87, 0x3c, 0x8c, 0xc4, 0x40, 0x46, 0x7f, 0xc2, 0x86, 0x07, 0x40, - 0x86, 0x41, 0xf4, 0xbf, 0x00, 0xb3, 0x0c, 0x2f, 0x90, 0x6f, 0x16, 0x80, - 0x46, 0x25, 0x00, 0x40, 0x57, 0x25, 0x04, 0x18, 0xae, 0x0e, 0x10, 0x30, - 0x06, 0x30, 0x75, 0x25, 0x46, 0x23, 0x60, 0x6f, 0x64, 0x25, 0xc4, 0x40, - 0xfa, 0x86, 0x00, 0xb3, 0x33, 0x7f, 0x09, 0x2f, 0x93, 0x6f, 0xd8, 0x88, - 0x53, 0x6f, 0x04, 0x41, 0xc3, 0x40, 0xdc, 0x0e, 0x13, 0x30, 0x04, 0x30, - 0xdc, 0x22, 0xb3, 0x25, 0x40, 0xb3, 0x02, 0x2f, 0x3b, 0x25, 0xc0, 0x90, - 0x05, 0x2f, 0x91, 0x6f, 0xd0, 0x6f, 0x98, 0x2e, 0xc6, 0xb2, 0x4d, 0x2c, - 0x04, 0x30, 0x8d, 0x88, 0x43, 0x40, 0x82, 0x40, 0x54, 0x7f, 0xda, 0x0f, - 0x04, 0x30, 0x08, 0x2f, 0xc1, 0x80, 0x40, 0x42, 0xc2, 0x0f, 0x02, 0x2f, - 0x00, 0x30, 0xc0, 0x7e, 0x1b, 0x2d, 0xc0, 0x7e, 0x19, 0x2d, 0xe1, 0xbc, - 0x92, 0x6f, 0x4f, 0x04, 0x90, 0x84, 0x40, 0xa8, 0x21, 0x05, 0x83, 0x40, - 0x4c, 0x22, 0x4b, 0x0e, 0xb6, 0x84, 0x21, 0x30, 0x02, 0x2f, 0x11, 0x30, - 0x04, 0x2c, 0xc1, 0x7e, 0xe3, 0x6f, 0xc1, 0x7e, 0xc1, 0x42, 0x00, 0x2e, - 0x00, 0x40, 0x81, 0x40, 0x04, 0xbd, 0x40, 0x6f, 0x98, 0x2e, 0xc2, 0xb1, - 0x50, 0x6f, 0x11, 0x30, 0x02, 0x40, 0x51, 0x08, 0xc3, 0x6e, 0x03, 0x80, - 0x99, 0x15, 0x0b, 0x40, 0xb1, 0x6f, 0xd0, 0x6f, 0xb6, 0x7f, 0x5b, 0x7f, - 0x04, 0x30, 0x4d, 0x54, 0x03, 0x30, 0x11, 0x2c, 0x10, 0x80, 0x55, 0x6f, - 0x06, 0x40, 0x75, 0x01, 0x58, 0xbb, 0x6a, 0x09, 0x05, 0x42, 0xc1, 0x86, - 0x47, 0x40, 0x51, 0x25, 0xbe, 0x01, 0x56, 0x43, 0x00, 0x2e, 0x46, 0x41, - 0xf4, 0x03, 0xb6, 0x6f, 0x47, 0x43, 0x5e, 0x0e, 0xed, 0x2f, 0x31, 0x6f, - 0x60, 0x6f, 0x42, 0x40, 0x15, 0x30, 0x02, 0x82, 0x95, 0x08, 0x04, 0x42, - 0x52, 0x42, 0x02, 0x2c, 0x44, 0x42, 0x04, 0x30, 0x3e, 0x8e, 0x91, 0x6f, - 0x4f, 0x8c, 0x02, 0x40, 0x83, 0x41, 0xb5, 0x8d, 0x93, 0x0e, 0xd0, 0x6f, - 0x01, 0x2f, 0x98, 0x2e, 0xc6, 0xb2, 0x00, 0x2e, 0xc0, 0x41, 0x81, 0x41, - 0xc1, 0x0f, 0xc0, 0x6f, 0x01, 0x2f, 0x04, 0x42, 0x00, 0x2e, 0x70, 0x6f, - 0x3c, 0x82, 0x00, 0x40, 0x41, 0x40, 0x89, 0x16, 0x95, 0x08, 0x4a, 0x00, - 0x04, 0xbc, 0x91, 0xb4, 0x01, 0x0e, 0xe0, 0x6f, 0x07, 0x2f, 0xa1, 0x6f, - 0x00, 0x2e, 0x41, 0x40, 0x40, 0xb2, 0x02, 0x2f, 0xa1, 0x6f, 0x05, 0x42, - 0x44, 0x42, 0x00, 0x2e, 0x8b, 0x6f, 0xc0, 0x5e, 0xb8, 0x2e, 0x03, 0x2e, - 0x1c, 0x01, 0x9c, 0xbc, 0x1d, 0xb9, 0x02, 0x82, 0x25, 0x2e, 0x8e, 0x00, - 0x83, 0x56, 0x13, 0x18, 0x01, 0x2e, 0x66, 0x00, 0x43, 0x40, 0xd8, 0x04, - 0x05, 0x2e, 0x65, 0x00, 0x40, 0x50, 0x27, 0x2e, 0x65, 0x00, 0xfb, 0x7f, - 0xda, 0x05, 0x8b, 0x50, 0x4b, 0x40, 0x02, 0x40, 0x81, 0x82, 0x01, 0x42, - 0x03, 0x80, 0x81, 0x52, 0xb1, 0x00, 0x03, 0x40, 0x3b, 0x82, 0x85, 0x58, - 0x14, 0x01, 0xc0, 0xb2, 0x37, 0x2e, 0x66, 0x00, 0xd1, 0x7f, 0xe2, 0x7f, - 0x04, 0x2f, 0x05, 0x2e, 0x6b, 0x00, 0x81, 0x84, 0x25, 0x2e, 0x6b, 0x00, - 0x62, 0x40, 0x3a, 0x0f, 0x45, 0x40, 0xc1, 0x7f, 0x21, 0x30, 0x12, 0x30, - 0x42, 0x2f, 0x0d, 0x2e, 0x69, 0x00, 0x3e, 0x0e, 0x33, 0x2f, 0x05, 0x2e, - 0x6a, 0x00, 0x01, 0x35, 0x91, 0x0e, 0x01, 0x30, 0x03, 0x2f, 0x09, 0x2e, - 0x6e, 0x00, 0x00, 0xb3, 0x24, 0x2f, 0xc0, 0x35, 0x90, 0x0e, 0x39, 0x2f, - 0x8f, 0x50, 0x02, 0x30, 0x01, 0x40, 0x7f, 0x82, 0x43, 0xa2, 0x02, 0x2f, - 0x00, 0x2e, 0x0c, 0x2c, 0x01, 0x30, 0xc0, 0xb2, 0x11, 0x30, 0x02, 0x2f, - 0x25, 0x2e, 0x6d, 0x00, 0x03, 0x2d, 0x23, 0x2e, 0x6d, 0x00, 0x21, 0x30, - 0x25, 0x2e, 0x6b, 0x00, 0x42, 0xb2, 0x04, 0x2f, 0x41, 0xb2, 0x02, 0x2f, - 0x25, 0x2e, 0x6d, 0x00, 0x31, 0x30, 0x3e, 0x80, 0x04, 0x86, 0x25, 0x2e, - 0x6c, 0x00, 0x02, 0x42, 0xc2, 0x42, 0x18, 0x2d, 0x02, 0x35, 0x01, 0x42, - 0x25, 0x2e, 0x6a, 0x00, 0x13, 0x2d, 0x2c, 0x04, 0x38, 0x1e, 0x21, 0x2e, - 0x69, 0x00, 0x7f, 0x50, 0x11, 0x30, 0x22, 0x30, 0x98, 0x2e, 0x66, 0xb5, - 0x09, 0x2c, 0x01, 0x30, 0x2c, 0x00, 0x38, 0x1c, 0x21, 0x2e, 0x68, 0x00, - 0x7f, 0x50, 0x98, 0x2e, 0x66, 0xb5, 0x01, 0x30, 0xc0, 0x6f, 0xd4, 0xb1, - 0xf5, 0xbd, 0x6b, 0xba, 0x91, 0x5a, 0x02, 0x40, 0x15, 0x18, 0xf5, 0xbe, - 0xeb, 0xbb, 0xe3, 0x0a, 0x3d, 0x0b, 0xd2, 0x6f, 0xe3, 0x00, 0x84, 0x40, - 0x63, 0x05, 0x93, 0x58, 0x2c, 0x18, 0xf5, 0xbe, 0x03, 0x42, 0xeb, 0xbb, - 0xfd, 0x0b, 0xe0, 0x6f, 0x58, 0x01, 0xdf, 0x01, 0x7d, 0x1f, 0x95, 0x42, - 0x18, 0x04, 0x85, 0x40, 0x5d, 0x05, 0x2c, 0x18, 0x75, 0xbe, 0xeb, 0xba, - 0x2c, 0x0b, 0xdc, 0x04, 0x18, 0x1c, 0x80, 0x42, 0x84, 0x80, 0x02, 0x30, - 0x00, 0x40, 0x00, 0xb2, 0x0c, 0x2f, 0x01, 0x2e, 0x6b, 0x00, 0x03, 0x35, - 0x83, 0x0e, 0x07, 0x2f, 0x8d, 0x50, 0x3e, 0x80, 0x25, 0x2e, 0x6d, 0x00, - 0x02, 0x42, 0x03, 0x80, 0x00, 0x2e, 0x02, 0x42, 0x40, 0xb2, 0x04, 0x2f, - 0x8b, 0x50, 0x04, 0x80, 0x25, 0x2e, 0x6a, 0x00, 0x02, 0x42, 0x42, 0xb2, - 0x89, 0x56, 0x9a, 0x22, 0x41, 0xb2, 0x01, 0x2e, 0x1c, 0x01, 0x87, 0x52, - 0x0b, 0xbc, 0x8a, 0x22, 0x0f, 0xb8, 0x00, 0x90, 0x01, 0x32, 0x06, 0x2f, - 0x10, 0x30, 0x90, 0x08, 0x80, 0xb2, 0x08, 0x2f, 0x23, 0x2e, 0x5e, 0xf0, - 0x06, 0x2d, 0x20, 0x30, 0x90, 0x08, 0x80, 0xb2, 0x01, 0x2f, 0x23, 0x2e, - 0x5e, 0xf0, 0xfb, 0x6f, 0xc0, 0x5f, 0xb8, 0x2e, 0x07, 0x86, 0xfc, 0x88, - 0xc6, 0x40, 0x05, 0x41, 0x31, 0x1a, 0x12, 0x2f, 0x80, 0x91, 0x22, 0x2f, - 0x01, 0x35, 0x29, 0x0f, 0x0a, 0x2f, 0x06, 0x80, 0x00, 0x2e, 0x00, 0x40, - 0x00, 0xb2, 0x01, 0x2f, 0x44, 0xa9, 0x03, 0x2f, 0x00, 0x30, 0xc0, 0x42, - 0x00, 0x43, 0xb8, 0x2e, 0xc2, 0x42, 0x01, 0x43, 0xb8, 0x2e, 0x01, 0x35, - 0xa9, 0x0e, 0x0e, 0x2f, 0x03, 0x3b, 0xeb, 0x00, 0xcc, 0xa8, 0x0a, 0x2f, - 0x05, 0x86, 0xc2, 0x80, 0xc3, 0x40, 0x02, 0x42, 0x3c, 0x84, 0xc1, 0x80, - 0x81, 0x42, 0x82, 0x84, 0xc0, 0x2e, 0x80, 0x42, 0x00, 0x2e, 0xb8, 0x2e, - 0x03, 0x2e, 0x1d, 0x01, 0x9f, 0xbc, 0x9f, 0xb8, 0x90, 0x50, 0x40, 0xb2, - 0x90, 0x2e, 0x71, 0xb6, 0x12, 0x40, 0x03, 0x30, 0x11, 0x40, 0x80, 0xa8, - 0x5a, 0x05, 0x9f, 0x58, 0x55, 0x23, 0x00, 0x40, 0x75, 0x7f, 0x40, 0xa8, - 0x16, 0x41, 0xd9, 0x05, 0xcf, 0x23, 0x56, 0x05, 0x40, 0xa9, 0x9d, 0x05, - 0x87, 0x7f, 0x6e, 0x23, 0x17, 0x41, 0xa5, 0x7f, 0x3e, 0x8b, 0x04, 0x41, - 0x52, 0x43, 0x00, 0xa8, 0x98, 0x05, 0xf2, 0x7f, 0x86, 0x22, 0xcf, 0x05, - 0xc0, 0xa9, 0x9f, 0x05, 0xbe, 0x23, 0x04, 0x05, 0x92, 0x7f, 0x00, 0xa9, - 0xdc, 0x05, 0x51, 0x43, 0xb6, 0x7f, 0x27, 0x23, 0xa7, 0x54, 0xe1, 0x7f, - 0x02, 0x18, 0x7d, 0x83, 0x40, 0x43, 0xeb, 0xba, 0x75, 0xbd, 0xaa, 0x0a, - 0x0b, 0x2e, 0x71, 0x00, 0x77, 0x5c, 0x2e, 0x18, 0xf5, 0xbe, 0x6b, 0xbb, - 0x75, 0x0b, 0xaa, 0x00, 0xc4, 0x7f, 0x25, 0x2e, 0x71, 0x00, 0xb2, 0x6f, - 0xa5, 0x6f, 0xaa, 0x00, 0x54, 0x01, 0x84, 0x6f, 0x72, 0x6f, 0x94, 0x05, - 0x80, 0xa9, 0xde, 0x05, 0xb7, 0x23, 0x99, 0x5e, 0x77, 0x0e, 0x41, 0x40, - 0x97, 0x5c, 0xb1, 0x01, 0xd5, 0x7f, 0x00, 0x2e, 0x85, 0x41, 0x0e, 0x2f, - 0x00, 0xa0, 0x0c, 0x2f, 0x14, 0x0f, 0x04, 0x2f, 0xe0, 0x6f, 0x00, 0xac, - 0x10, 0x30, 0x08, 0x2c, 0x18, 0x22, 0xf0, 0x6f, 0x00, 0xac, 0x30, 0x30, - 0x24, 0x30, 0x02, 0x2c, 0x20, 0x22, 0x40, 0x30, 0x0d, 0x2e, 0x71, 0x00, - 0x80, 0xa1, 0x1e, 0x23, 0x79, 0x5e, 0x37, 0x0f, 0xbc, 0x23, 0x00, 0x90, - 0x14, 0x30, 0x10, 0x30, 0x18, 0x2f, 0x9d, 0x50, 0x30, 0x00, 0x9b, 0x56, - 0x43, 0x0e, 0x02, 0x2f, 0x10, 0x30, 0x0a, 0x2c, 0x03, 0x30, 0x99, 0x50, - 0x10, 0x0e, 0x13, 0x30, 0x00, 0x2f, 0x03, 0x30, 0x90, 0x0f, 0x10, 0x30, - 0x00, 0x2f, 0x00, 0x30, 0x00, 0x90, 0x10, 0x30, 0x00, 0x2f, 0x00, 0x30, - 0xc0, 0x90, 0x13, 0x30, 0x00, 0x2f, 0x03, 0x30, 0x40, 0xb2, 0x87, 0x5c, - 0x22, 0x2f, 0x41, 0x90, 0x4a, 0x2f, 0xa5, 0x50, 0x00, 0x2e, 0x01, 0x40, - 0x41, 0x82, 0x01, 0x42, 0x02, 0x80, 0x4a, 0xa8, 0x01, 0x40, 0x06, 0x2f, - 0xd0, 0x6f, 0x85, 0x0e, 0x3e, 0x2f, 0x41, 0x80, 0x21, 0x2e, 0x78, 0x00, - 0x3b, 0x2d, 0x95, 0x50, 0xfb, 0x7f, 0x4a, 0xa8, 0x06, 0x2f, 0x98, 0x2e, - 0x73, 0xb6, 0xc0, 0x90, 0xfb, 0x6f, 0x32, 0x2f, 0x00, 0x2e, 0x30, 0x2d, - 0x98, 0x2e, 0x73, 0xb6, 0x29, 0x2e, 0x7a, 0x00, 0x2b, 0x2c, 0xfb, 0x6f, - 0xa1, 0x52, 0xd2, 0x6f, 0x95, 0x0e, 0x41, 0x40, 0x05, 0x2f, 0x00, 0x90, - 0x17, 0x2f, 0x05, 0x2e, 0x7a, 0x00, 0x80, 0x90, 0x13, 0x2f, 0x7f, 0x82, - 0x40, 0xac, 0x23, 0x2e, 0x77, 0x00, 0x01, 0x30, 0x18, 0x2f, 0xa1, 0x54, - 0x82, 0x84, 0x23, 0x2e, 0x77, 0x00, 0x82, 0x40, 0x80, 0xb2, 0x11, 0x2f, - 0x00, 0x90, 0x23, 0x2e, 0x79, 0x00, 0x0d, 0x2f, 0x29, 0x2e, 0x72, 0x00, - 0x0b, 0x2d, 0x41, 0x80, 0x21, 0x2e, 0x77, 0x00, 0x0f, 0xa4, 0x05, 0x2f, - 0xa3, 0x50, 0x3e, 0x80, 0xf1, 0x30, 0x29, 0x2e, 0x79, 0x00, 0x01, 0x42, - 0x06, 0x30, 0x34, 0x08, 0x00, 0xb2, 0x02, 0x2f, 0x80, 0x30, 0x21, 0x2e, - 0x5e, 0xf0, 0x70, 0x5f, 0xb8, 0x2e, 0x04, 0x84, 0x01, 0x30, 0x81, 0x42, - 0x82, 0x84, 0x01, 0x42, 0xa1, 0x42, 0x81, 0x42, 0x82, 0x84, 0x00, 0x2e, - 0x91, 0x42, 0x81, 0x42, 0xb8, 0x2e, 0x30, 0x50, 0xf3, 0x7f, 0xc0, 0xac, - 0xe4, 0x7f, 0xd5, 0x7f, 0x03, 0x2f, 0x00, 0x30, 0x82, 0x04, 0xf3, 0x6f, - 0xc3, 0x06, 0x40, 0xad, 0x05, 0x2f, 0xe0, 0x6f, 0x05, 0x30, 0x28, 0x04, - 0xd1, 0x6f, 0x69, 0x07, 0xe0, 0x7f, 0x40, 0xa1, 0x01, 0x30, 0x20, 0x2f, - 0x13, 0x25, 0x02, 0x25, 0x04, 0x32, 0x06, 0x30, 0x02, 0x30, 0x03, 0x30, - 0xaf, 0xbb, 0xb1, 0xbd, 0xdf, 0x0a, 0x9f, 0xbb, 0x21, 0xbd, 0x97, 0x0a, - 0x8f, 0xbb, 0x91, 0xbc, 0x01, 0xbc, 0x4f, 0x0a, 0x6b, 0x0e, 0x04, 0x2f, - 0x6b, 0x1a, 0x07, 0x2f, 0xe7, 0x6f, 0x7a, 0x0f, 0x04, 0x2f, 0xe7, 0x6f, - 0x97, 0x04, 0x17, 0x30, 0x07, 0x0a, 0xdd, 0x06, 0x81, 0x8d, 0x34, 0x0e, - 0xe6, 0x2f, 0x00, 0x2e, 0x0d, 0x2d, 0x6b, 0x0e, 0x00, 0x30, 0x05, 0x2f, - 0x6b, 0x1a, 0x07, 0x2f, 0xe0, 0x6f, 0x42, 0x0f, 0x00, 0x30, 0x03, 0x2f, - 0xe0, 0x6f, 0x90, 0x04, 0xdd, 0x06, 0x10, 0x30, 0xf5, 0x6f, 0xc3, 0x7f, - 0xb2, 0x7f, 0x40, 0xad, 0x06, 0x2f, 0x03, 0x30, 0xb2, 0x6f, 0x9a, 0x04, - 0xc4, 0x6f, 0xdc, 0x06, 0xb2, 0x7f, 0xc3, 0x7f, 0x00, 0x2e, 0xd2, 0x6f, - 0xaa, 0x0c, 0x80, 0xac, 0x02, 0x30, 0x01, 0x2f, 0x10, 0x04, 0x51, 0x06, - 0xd0, 0x5f, 0xb8, 0x2e, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, - 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, - 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, - 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, - 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, - 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, - 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, - 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, - 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, - 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, - 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, - 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, - 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, - 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, - 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, - 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, - 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, - 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, - 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, - 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, - 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, - 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, - 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, - 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, - 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, - 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, - 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, - 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, - 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, - 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, - 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, - 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, - 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, - 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, - 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, - 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, - 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, - 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, - 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, - 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, - 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, - 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, - 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, - 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, - 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, - 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, - 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, - 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, - 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, - 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, - 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, - 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, - 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, - 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, - 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, - 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, - 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, - 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, - 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, - 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, - 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, - 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, - 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, - 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, - 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, - 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, - 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, - 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, - 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, - 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, - 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, - 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, - 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, - 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, - 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, - 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, - 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, - 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, - 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, - 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, - 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, - 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, - 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, - 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, - 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, - 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, - 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, - 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, - 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, - 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, - 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, - 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, - 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, - 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, - 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, - 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, - 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, - 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, - 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, - 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, - 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, - 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, - 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, - 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, - 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, - 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, - 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, - 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, - 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, - 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, - 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, - 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, - 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, - 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, - 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, - 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, - 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, - 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, - 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, - 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, - 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, - 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, - 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, - 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, - 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, - 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, - 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, - 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, - 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, - 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, - 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, - 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, - 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, - 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, - 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00 }; -#define BMA4_ACCEL_CONFIG_ADDR (0X40) -#define BMA4_TEMPERATURE_ADDR (0X22) - - -/**************************************************************/ -/**\name Step Counter & Detector */ -/**************************************************************/ -/**\name Step counter enable macros */ -#define BMA423_STEP_CNTR_EN_POS (4) -#define BMA423_STEP_CNTR_EN_MSK (0x10) -#define BMA423_ACTIVITY_EN_MSK (0x20) - -/**\name Step counter watermark macros */ -#define BMA423_STEP_CNTR_WM_MSK (0x03FF) - -/**\name Step counter reset macros */ -#define BMA423_STEP_CNTR_RST_POS (2) -#define BMA423_STEP_CNTR_RST_MSK (0x04) - -/**\name Step detector enable macros */ -#define BMA423_STEP_DETECTOR_EN_POS (3) -#define BMA423_STEP_DETECTOR_EN_MSK (0x08) - -/**\name Tilt enable macros */ -#define BMA423_TILT_EN_MSK (0x01) - -/**\name Step count output length*/ -#define BMA423_STEP_CNTR_DATA_SIZE (4) - -/**\name Wakeup enable macros */ -#define BMA423_WAKEUP_EN_MSK (0x01) - -/**\name Wake up sensitivity macros */ -#define BMA423_WAKEUP_SENS_POS (1) -#define BMA423_WAKEUP_SENS_MSK (0x0E) - -/**\name Tap selection macro */ -#define BMA423_TAP_SEL_POS (4) -#define BMA423_TAP_SEL_MSK (0x10) - -/**************************************************************/ -/**\name Any Motion */ -/**************************************************************/ -/**\name Any motion threshold macros */ -#define BMA423_ANY_NO_MOTION_THRES_POS (0) -#define BMA423_ANY_NO_MOTION_THRES_MSK (0x07FF) - -/**\name Any motion selection macros */ -#define BMA423_ANY_NO_MOTION_SEL_POS (3) -#define BMA423_ANY_NO_MOTION_SEL_MSK (0x08) - -/**\name Any motion enable macros */ -#define BMA423_ANY_NO_MOTION_AXIS_EN_POS (5) -#define BMA423_ANY_NO_MOTION_AXIS_EN_MSK (0xE0) - -/**\name Any motion duration macros */ -#define BMA423_ANY_NO_MOTION_DUR_MSK (0x1FFF) - -/**\name INTERRUPT MAPS */ -#define BMA4_INTR1_MAP (0) -#define BMA4_INTR2_MAP (1) - -/**\name INTERRUPT ENABLE REGISTERS*/ -#define BMA4_INT1_IO_CTRL_ADDR (0X53) -#define BMA4_INT2_IO_CTRL_ADDR (0X54) - -/**\name LATCH DURATION REGISTERS*/ -#define BMA4_INTR_LATCH_ADDR (0X55) - -/**\name CONSTANTS */ -#define BMA4_FIFO_CONFIG_LENGTH (2) -#define BMA4_ACCEL_CONFIG_LENGTH (2) -#define BMA4_FIFO_WM_LENGTH (2) -#define BMA4_CONFIG_STREAM_SIZE (6144) -#define BMA4_NON_LATCH_MODE (0) -#define BMA4_LATCH_MODE (1) -#define BMA4_OPEN_DRAIN (1) -#define BMA4_PUSH_PULL (0) -#define BMA4_ACTIVE_HIGH (1) -#define BMA4_ACTIVE_LOW (0) -#define BMA4_EDGE_TRIGGER (1) -#define BMA4_LEVEL_TRIGGER (0) -#define BMA4_OUTPUT_ENABLE (1) -#define BMA4_OUTPUT_DISABLE (0) -#define BMA4_INPUT_ENABLE (1) -#define BMA4_INPUT_DISABLE (0) - - -/**\name OUTPUT TYPE ENABLE POSITION AND MASK*/ -#define BMA4_INT_EDGE_CTRL_MASK (0x01) -#define BMA4_INT_EDGE_CTRL_POS (0x00) -#define BMA4_INT_LEVEL_MASK (0x02) -#define BMA4_INT_LEVEL_POS (0x01) -#define BMA4_INT_OPEN_DRAIN_MASK (0x04) -#define BMA4_INT_OPEN_DRAIN_POS (0x02) -#define BMA4_INT_OUTPUT_EN_MASK (0x08) -#define BMA4_INT_OUTPUT_EN_POS (0x03) -#define BMA4_INT_INPUT_EN_MASK (0x10) -#define BMA4_INT_INPUT_EN_POS (0x04) - - -/**\name Interrupt status macros */ -#define BMA423_STEP_CNTR_INT (0x02) -#define BMA423_ACTIVITY_INT (0x04) -#define BMA423_TILT_INT (0x08) -#define BMA423_WAKEUP_INT (0x20) -#define BMA423_ANY_NO_MOTION_INT (0x40) -#define BMA423_ERROR_INT (0x80) + diff --git a/src/REG/BQ27220Constants.h b/src/REG/BQ27220Constants.h new file mode 100644 index 0000000..a010d52 --- /dev/null +++ b/src/REG/BQ27220Constants.h @@ -0,0 +1,108 @@ +/** + * + * @license MIT License + * + * Copyright (c) 2025 lewis he + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * @file BQ27220Constants.h + * @author Lewis He (lewishe@outlook.com) + * @date 2025-01-16 + * + */ + +#pragma once + +#include + + +class BQ27220Constants +{ +protected: + static constexpr uint8_t BQ27220_SLAVE_ADDRESS = (0x55); + + //* Sub command + static constexpr uint16_t BQ27220_SUB_CMD_CTRL_STATUS = (0x0000); + static constexpr uint16_t BQ27220_SUB_CMD_DEVICE_NUMBER = (0x0001); + static constexpr uint16_t BQ27220_SUB_CMD_FW_VERSION = (0x0002); + static constexpr uint16_t BQ27220_SUB_CMD_HW_VERSION = (0x0003); + static constexpr uint16_t BQ27220_SUB_CMD_BOARD_OFFSET = (0x0009); + static constexpr uint16_t BQ27220_SUB_CMD_CC_OFFSET = (0x000A); + static constexpr uint16_t BQ27220_SUB_CMD_CC_OFFSET_SAVE = (0x000B); + static constexpr uint16_t BQ27220_SUB_CMD_OCV_CMD = (0x000C); + static constexpr uint16_t BQ27220_SUB_CMD_BAT_INSERT = (0x000D); + static constexpr uint16_t BQ27220_SUB_CMD_BAT_REMOVE = (0x000E); + static constexpr uint16_t BQ27220_SUB_CMD_SET_SNOOZE = (0x0013); + static constexpr uint16_t BQ27220_SUB_CMD_CLEAR_SNOOZE = (0x0014); + static constexpr uint16_t BQ27220_SUB_CMD_SET_PROFILE_1 = (0x0015); + static constexpr uint16_t BQ27220_SUB_CMD_SET_PROFILE_2 = (0x0016); + static constexpr uint16_t BQ27220_SUB_CMD_SET_PROFILE_3 = (0x0017); + static constexpr uint16_t BQ27220_SUB_CMD_SET_PROFILE_4 = (0x0018); + static constexpr uint16_t BQ27220_SUB_CMD_SET_PROFILE_5 = (0x0019); + static constexpr uint16_t BQ27220_SUB_CMD_SET_PROFILE_6 = (0x001A); + static constexpr uint16_t BQ27220_SUB_CMD_CAL_TOGGLE = (0x002D); + static constexpr uint16_t BQ27220_SUB_CMD_SEALED = (0x0030); + static constexpr uint16_t BQ27220_SUB_CMD_RESET = (0x0041); + static constexpr uint16_t BQ27220_SUB_CMD_EXIT_CAL = (0x0080); + static constexpr uint16_t BQ27220_SUB_CMD_ENTER_CAL = (0x0081); + static constexpr uint16_t BQ27220_SUB_CMD_ENTER_CFG_UPDATE = (0x0090); + static constexpr uint16_t BQ27220_SUB_CMD_EXIT_CFG_UPDATE_REINIT = (0x0091); + static constexpr uint16_t BQ27220_SUB_CMD_EXIT_CFG_UPDATE = (0x0092); + static constexpr uint16_t BQ27220_SUB_CMD_RETURN_TO_ROM = (0x0F00); + + //* Standard commands + static constexpr uint8_t BQ27220_REG_STA_AT_RATE = (0x02); + static constexpr uint8_t BQ27220_REG_STA_AT_RATE_TIME_TO_EMPTY = (0x04); + static constexpr uint8_t BQ27220_REG_STA_NTC_TEMP = (0x06); + static constexpr uint8_t BQ27220_REG_STA_BAT_VOLTAGE = (0x08); + static constexpr uint8_t BQ27220_REG_STA_BAT_STATUS = (0x0A); + static constexpr uint8_t BQ27220_REG_STA_CURRENT = (0x0C); + static constexpr uint8_t BQ27220_REG_STA_REMAINING_CAPACITY = (0x10); + static constexpr uint8_t BQ27220_REG_STA_FULL_CHARGE_CAPACITY = (0x12); + static constexpr uint8_t BQ27220_REG_STA_TIME_TO_EMPTY = (0x16); + static constexpr uint8_t BQ27220_REG_STA_TIME_TO_FULL = (0x18); + static constexpr uint8_t BQ27220_REG_STA_STANDBY_CURRENT = (0x1A); + static constexpr uint8_t BQ27220_REG_STA_STANDBY_TIME_TO_EMPTY = (0x1C); + static constexpr uint8_t BQ27220_REG_STA_MAX_LOAD_CURRENT = (0x1E); + static constexpr uint8_t BQ27220_REG_STA_MAX_LOAD_TO_EMPTY = (0x20); + static constexpr uint8_t BQ27220_REG_STA_COULOMB_COUNT = (0x22); + static constexpr uint8_t BQ27220_REG_STA_AVG_POWER = (0x24); + static constexpr uint8_t BQ27220_REG_STA_INTER_TEMP = (0x28); + static constexpr uint8_t BQ27220_REG_STA_CYCLE_COUNT = (0x2A); + static constexpr uint8_t BQ27220_REG_STA_STATE_OF_CHARGE = (0x2C); + static constexpr uint8_t BQ27220_REG_STA_STATE_OF_HEALTH = (0x2E); + static constexpr uint8_t BQ27220_REG_STA_CHARGING_VOLTAGE = (0x30); + static constexpr uint8_t BQ27220_REG_STA_CHARGING_CURRENT = (0x32); + static constexpr uint8_t BQ27220_REG_STA_BTP_DISC_SET = (0x34); + static constexpr uint8_t BQ27220_REG_STA_BTP_CHARGE_SET = (0x36); + static constexpr uint8_t BQ27220_REG_STA_OPERATION_STATUS = (0x3A); + static constexpr uint8_t BQ27220_REG_STA_DESIGN_CAPACITY = (0x3C); + static constexpr uint8_t BQ27220_REG_STA_DESIGN_CAPACITY_MSB = (0x3E); + static constexpr uint8_t BQ27220_REG_STA_DESIGN_CAPACITY_LSB = (0x3F); + static constexpr uint8_t BQ27220_REG_MAC_BUFFER_START = (0x40); + static constexpr uint8_t BQ27220_REG_MAC_BUFFER_END = (0x5F); + static constexpr uint8_t BQ27220_REG_MAC_DATA_SUM = (0x60); + static constexpr uint8_t BQ27220_REG_MAC_DATA_LEN = (0x61); + static constexpr uint8_t BQ27220_REG_ANALOG_COUNT = (0x79); + static constexpr uint8_t BQ27220_REG_RAW_CURRENT = (0x7A); + static constexpr uint8_t BQ27220_REG_RAW_VOLTAGE = (0x7C); + + static constexpr uint16_t BQ27220_CHIP_ID = (0x0220); +}; \ No newline at end of file diff --git a/src/REG/CHSC5816Constants.h b/src/REG/CHSC5816Constants.h index f12832d..90f07c9 100644 --- a/src/REG/CHSC5816Constants.h +++ b/src/REG/CHSC5816Constants.h @@ -30,37 +30,3 @@ #pragma once -#define CHSC5816_SLAVE_ADDRESS (0x2E) - -#define CHSC5816_REG_CMD_BUFF (0x20000000U) -#define CHSC5816_REG_RSP_BUFF (0x20000000U) -#define CHSC5816_REG_IMG_HEAD (0x20000014U) -#define CHSC5816_REG_POINT (0x2000002CU) -#define CHSC5816_REG_WR_BUFF (0x20002000U) -#define CHSC5816_REG_RD_BUFF (0x20002400U) -#define CHSC5816_REG_HOLD_MCU (0x40007000U) -#define CHSC5816_REG_AUTO_FEED (0x40007010U) -#define CHSC5816_REG_REMAP_MCU (0x40007000U) -#define CHSC5816_REG_RELEASE_MCU (0x40007000U) -#define CHSC5816_REG_BOOT_STATE (0x20000018U) - - - -#define CHSC5816_HOLD_MCU_VAL (0x12044000U) -#define CHSC5816_AUTO_FEED_VAL (0x0000925aU) -#define CHSC5816_REMAP_MCU_VAL (0x12044002U) -#define CHSC5816_RELEASE_MCU_VAL (0x12044003U) - -#define CHSC5816_REG_VID_PID_BACKUP (40 * 1024 + 0x10U) - -#define CHSC5816_SIG_VALUE (0x43534843U) -/*ctp work staus*/ -#define CHSC5816_POINTING_WORK (0x00000000U) -#define CHSC5816_READY_UPGRADE (1 << 1) -#define CHSC5816_UPGRAD_RUNING (1 << 2) -#define CHSC5816_SLFTEST_RUNING (1 << 3) -#define CHSC5816_SUSPEND_GATE (1 << 16) -#define CHSC5816_GUESTURE_GATE (1 << 17) -#define CHSC5816_PROXIMITY_GATE (1 << 18) -#define CHSC5816_GLOVE_GATE (1 << 19) -#define CHSC5816_ORIENTATION_GATE (1 << 20) diff --git a/src/REG/CM32181Constants.h b/src/REG/CM32181Constants.h index aba30fd..cea0826 100644 --- a/src/REG/CM32181Constants.h +++ b/src/REG/CM32181Constants.h @@ -30,24 +30,26 @@ #pragma once -#define CM32181_SLAVE_ADDRESS (0x10) - - +#include // CM32181 slave address can be 0x10 or 0x48, determined by pin ADDR configuration -#define CM32181_ADDR_ALS (0x10) // 7-bit -#define CM32181_ADDR_ALS1 (0x48) // 7-bit - -// CM32181 registers -#define CM32181_REG_ALS_CONF (uint8_t)(0x00) -#define CM32181_REG_ALS_THDH (uint8_t)(0x01) -#define CM32181_REG_ALS_THDL (uint8_t)(0x02) -#define CM32181_REG_ALS_PSM (uint8_t)(0x03) -#define CM32181_REG_ALS_DATA (uint8_t)(0x04) -#define CM32181_REG_ALS_STATUS (uint8_t)(0x06) -#define CM32181_REG_ID (uint8_t)(0x07) - -#define CM32181_CHIP_ID (0x81) +#define CM32181_ADDR_PRIMARY (0x10) +#define CM32181_ADDR_SECONDARY (0x48) +#define CM32181_SLAVE_ADDRESS (0x10) //Compatible with previous version definitions + +class CM32181Constants +{ +protected: + // CM32181 registers + static constexpr uint8_t REG_ALS_CONF = 0x00; + static constexpr uint8_t REG_ALS_THDH = 0x01; + static constexpr uint8_t REG_ALS_THDL = 0x02; + static constexpr uint8_t REG_ALS_PSM = 0x03; + static constexpr uint8_t REG_ALS_DATA = 0x04; + static constexpr uint8_t REG_ALS_STATUS = 0x06; + static constexpr uint8_t REG_ID = 0x07; + static constexpr uint8_t CM32181_CHIP_ID = 0x81; +}; diff --git a/src/REG/CST9xxConstants.h b/src/REG/CST9xxConstants.h index 40a016a..42faf32 100644 --- a/src/REG/CST9xxConstants.h +++ b/src/REG/CST9xxConstants.h @@ -29,32 +29,39 @@ */ #pragma once -#define CST92XX_SLAVE_ADDRESS (0x5A) -#define CST92XX_BOOT_ADDRESS (0x5A) //Fixed, immutable +#include -#define CST9220_CHIP_ID (0x9220) -#define CST9217_CHIP_ID (0x9217) +#define CST92XX_SLAVE_ADDRESS (0x5A) +class CST92xxConstants +{ +protected: + typedef struct { + uint8_t finger_id; + uint8_t evt; + uint16_t x; + uint16_t y; + } cst9xx_point_t; + //Fixed, immutable + static constexpr uint8_t CST92XX_BOOT_ADDRESS = (0x5A); -#define CST92XX_MEM_SIZE (0x007F80) // 31KB -#define CST92XX_PROGRAM_PAGE_SIZE (128) -#define CST92XX_ACK (0xAB) -#define CST92XX_MAX_FINGER_NUM (2) - - -#define CST92XX_READ_COMMAND (0xD000) -#define CST92XX_REG_DEBUG_MODE (0xD101) -#define CST92XX_REG_SLEEP_MODE (0xD105) -#define CST92XX_REG_DIS_LOW_POWER_SCAN_MODE (0xD106) -#define CST92XX_REG_NORMAL_MODE (0xD109) -#define CST92XX_REG_RAW_MODE (0xD10A) -#define CST92XX_REG_DIFF_MODE (0xD10D) -#define CST92XX_REG_BASE_LINE_MODE (0xD10E) -#define CST92XX_REG_LOWPOWER_MODE (0xD10F) -#define CST92XX_REG_FACTORY_MODE (0xD114) - -#define CST92XX_GET_FINGER_NUM(X) (X & 0X7F) -#define CST92XX_GET_GESTURE(X) (X & 0xF0) + static constexpr uint16_t CST9220_CHIP_ID = (0x9220); + static constexpr uint16_t CST9217_CHIP_ID = (0x9217); + static constexpr uint16_t CST92XX_READ_COMMAND = (0xD000); + static constexpr uint16_t CST92XX_REG_DEBUG_MODE = (0xD101); + static constexpr uint16_t CST92XX_REG_SLEEP_MODE = (0xD105); + static constexpr uint16_t CST92XX_REG_DIS_LOW_POWER_SCAN_MODE = (0xD106); + static constexpr uint16_t CST92XX_REG_NORMAL_MODE = (0xD109); + static constexpr uint16_t CST92XX_REG_RAW_MODE = (0xD10A); + static constexpr uint16_t CST92XX_REG_DIFF_MODE = (0xD10D); + static constexpr uint16_t CST92XX_REG_BASE_LINE_MODE = (0xD10E); + static constexpr uint16_t CST92XX_REG_LOWPOWER_MODE = (0xD10F); + static constexpr uint16_t CST92XX_REG_FACTORY_MODE = (0xD114); + static constexpr uint8_t CST92XX_ACK = (0xAB); + static constexpr uint8_t CST92XX_MAX_FINGER_NUM = (2); + static constexpr uint8_t CST92XX_PROGRAM_PAGE_SIZE = (128); + static constexpr uint32_t CST92XX_MEM_SIZE = (0x007F80);// 31KB +}; const unsigned char cst92xx_firmware[] = { 0xFC, 0x0F, 0x00, 0x20, 0xAD, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, diff --git a/src/REG/CSTxxxConstants.h b/src/REG/CSTxxxConstants.h index 18ccd9b..c3b7c22 100644 --- a/src/REG/CSTxxxConstants.h +++ b/src/REG/CSTxxxConstants.h @@ -30,15 +30,12 @@ #pragma once -#define CSTXXX_SLAVE_ADDRESS (0x15) -#define CST816_SLAVE_ADDRESS (0x15) -#define CST328_SLAVE_ADDRESS (0x1A) -#define CST226SE_SLAVE_ADDRESS (0x5A) - -#define CST816S_CHIP_ID (0xB4) -#define CST816T_CHIP_ID (0xB5) -#define CST716_CHIP_ID (0x20) -#define CST226SE_CHIP_ID (0xA8) + + +// #define CST816S_CHIP_ID (0xB4) +// #define CST816T_CHIP_ID (0xB5) +// #define CST716_CHIP_ID (0x20) +// #define CST226SE_CHIP_ID (0xA8) diff --git a/src/REG/DRV2605Constants.h b/src/REG/DRV2605Constants.h index 9371a0c..92fe02b 100644 --- a/src/REG/DRV2605Constants.h +++ b/src/REG/DRV2605Constants.h @@ -29,52 +29,61 @@ */ #pragma once +#include + + +class DRV2605Constants +{ +protected: + + static constexpr uint8_t DRV2605_SLAVE_ADDRESS = 0x5A; + + // Chip IDs + static constexpr uint8_t DRV2604_CHIP_ID = 0x04; //* DRV2604 (contains RAM, does not contain licensed ROM library) + static constexpr uint8_t DRV2605_CHIP_ID = 0x03; //* DRV2605 (contains licensed ROM library, does not contain RAM) + static constexpr uint8_t DRV2604L_CHIP_ID = 0x06; //* DRV2604L (low-voltage version of the DRV2604 device) + static constexpr uint8_t DRV2605L_CHIP_ID = 0x07; //* DRV2605L (low-voltage version of the DRV2605 device) + + // Registers + static constexpr uint8_t DRV2605_REG_STATUS = 0x00; //* Status register + static constexpr uint8_t DRV2605_REG_MODE = 0x01; //* Mode register + static constexpr uint8_t DRV2605_REG_RTPIN = 0x02; //* Real-time playback input register + static constexpr uint8_t DRV2605_REG_LIBRARY = 0x03; //* Waveform library selection register + static constexpr uint8_t DRV2605_REG_WAVESEQ1 = 0x04; //* Waveform sequence register 1 + static constexpr uint8_t DRV2605_REG_WAVESEQ2 = 0x05; //* Waveform sequence register 2 + static constexpr uint8_t DRV2605_REG_WAVESEQ3 = 0x06; //* Waveform sequence register 3 + static constexpr uint8_t DRV2605_REG_WAVESEQ4 = 0x07; //* Waveform sequence register 4 + static constexpr uint8_t DRV2605_REG_WAVESEQ5 = 0x08; //* Waveform sequence register 5 + static constexpr uint8_t DRV2605_REG_WAVESEQ6 = 0x09; //* Waveform sequence register 6 + static constexpr uint8_t DRV2605_REG_WAVESEQ7 = 0x0A; //* Waveform sequence register 7 + static constexpr uint8_t DRV2605_REG_WAVESEQ8 = 0x0B; //* Waveform sequence register 8 + static constexpr uint8_t DRV2605_REG_GO = 0x0C; //* Go register + static constexpr uint8_t DRV2605_REG_OVERDRIVE = 0x0D; //* Overdrive time offset register + static constexpr uint8_t DRV2605_REG_SUSTAINPOS = 0x0E; //* Sustain time offset, positive register + static constexpr uint8_t DRV2605_REG_SUSTAINNEG = 0x0F; //* Sustain time offset, negative register + static constexpr uint8_t DRV2605_REG_BREAK = 0x10; //* Brake time offset register + static constexpr uint8_t DRV2605_REG_AUDIOCTRL = 0x11; //* Audio-to-vibe control register + static constexpr uint8_t DRV2605_REG_AUDIOLVL = 0x12; //* Audio-to-vibe minimum input level register + static constexpr uint8_t DRV2605_REG_AUDIOMAX = 0x13; //* Audio-to-vibe maximum input level register + static constexpr uint8_t DRV2605_REG_AUDIOOUTMIN = 0x14; //* Audio-to-vibe minimum output drive register + static constexpr uint8_t DRV2605_REG_AUDIOOUTMAX = 0x15; //* Audio-to-vibe maximum output drive register + static constexpr uint8_t DRV2605_REG_RATEDV = 0x16; //* Rated voltage register + static constexpr uint8_t DRV2605_REG_CLAMPV = 0x17; //* Overdrive clamp voltage register + static constexpr uint8_t DRV2605_REG_AUTOCALCOMP = 0x18; //* Auto-calibration compensation result register + static constexpr uint8_t DRV2605_REG_AUTOCALEMP = 0x19; //* Auto-calibration back-EMF result register + static constexpr uint8_t DRV2605_REG_FEEDBACK = 0x1A; //* Feedback control register + static constexpr uint8_t DRV2605_REG_CONTROL1 = 0x1B; //* Control1 Register + static constexpr uint8_t DRV2605_REG_CONTROL2 = 0x1C; //* Control2 Register + static constexpr uint8_t DRV2605_REG_CONTROL3 = 0x1D; //* Control3 Register + static constexpr uint8_t DRV2605_REG_CONTROL4 = 0x1E; //* Control4 Register + static constexpr uint8_t DRV2605_REG_VBAT = 0x21; //* Vbat voltage-monitor register + static constexpr uint8_t DRV2605_REG_LRARESON = 0x22; //* LRA resonance-period register + +}; + + + + -#define DRV2605_SLAVE_ADDRESS (0x5A) -#define DRV2604_CHIP_ID (0x04) //* DRV2604 (contains RAM, does not contain licensed ROM library) -#define DRV2605_CHIP_ID (0x03) //* DRV2605 (contains licensed ROM library, does not contain RAM) -#define DRV2604L_CHIP_ID (0x06) //* DRV2604L (low-voltage version of the DRV2604 device) -#define DRV2605L_CHIP_ID (0x07) //* DRV2605L (low-voltage version of the DRV2605 device) -#define DRV2605_REG_STATUS (0x00) //* Status register -#define DRV2605_REG_MODE (0x01) //* Mode register -#define DRV2605_MODE_INTTRIG (0x00) //* Internal trigger mode -#define DRV2605_MODE_EXTTRIGEDGE (0x01) //* External edge trigger mode -#define DRV2605_MODE_EXTTRIGLVL (0x02) //* External level trigger mode -#define DRV2605_MODE_PWMANALOG (0x03) //* PWM/Analog input mode -#define DRV2605_MODE_AUDIOVIBE (0x04) //* Audio-to-vibe mode -#define DRV2605_MODE_REALTIME (0x05) //* Real-time playback (RTP) mode -#define DRV2605_MODE_DIAGNOS (0x06) //* Diagnostics mode -#define DRV2605_MODE_AUTOCAL (0x07) //* Auto calibration mode -#define DRV2605_REG_RTPIN (0x02) //* Real-time playback input register -#define DRV2605_REG_LIBRARY (0x03) //* Waveform library selection register -#define DRV2605_REG_WAVESEQ1 (0x04) //* Waveform sequence register 1 -#define DRV2605_REG_WAVESEQ2 (0x05) //* Waveform sequence register 2 -#define DRV2605_REG_WAVESEQ3 (0x06) //* Waveform sequence register 3 -#define DRV2605_REG_WAVESEQ4 (0x07) //* Waveform sequence register 4 -#define DRV2605_REG_WAVESEQ5 (0x08) //* Waveform sequence register 5 -#define DRV2605_REG_WAVESEQ6 (0x09) //* Waveform sequence register 6 -#define DRV2605_REG_WAVESEQ7 (0x0A) //* Waveform sequence register 7 -#define DRV2605_REG_WAVESEQ8 (0x0B) //* Waveform sequence register 8 -#define DRV2605_REG_GO (0x0C) //* Go register -#define DRV2605_REG_OVERDRIVE (0x0D) //* Overdrive time offset register -#define DRV2605_REG_SUSTAINPOS (0x0E) //* Sustain time offset, positive register -#define DRV2605_REG_SUSTAINNEG (0x0F) //* Sustain time offset, negative register -#define DRV2605_REG_BREAK (0x10) //* Brake time offset register -#define DRV2605_REG_AUDIOCTRL (0x11) //* Audio-to-vibe control register -#define DRV2605_REG_AUDIOLVL (0x12) //* Audio-to-vibe minimum input level register -#define DRV2605_REG_AUDIOMAX (0x13) //* Audio-to-vibe maximum input level register -#define DRV2605_REG_AUDIOOUTMIN (0x14) //* Audio-to-vibe minimum output drive register -#define DRV2605_REG_AUDIOOUTMAX (0x15) //* Audio-to-vibe maximum output drive register -#define DRV2605_REG_RATEDV (0x16) //* Rated voltage register -#define DRV2605_REG_CLAMPV (0x17) //* Overdrive clamp voltage register -#define DRV2605_REG_AUTOCALCOMP (0x18) //* Auto-calibration compensation result register -#define DRV2605_REG_AUTOCALEMP (0x19) //* Auto-calibration back-EMF result register -#define DRV2605_REG_FEEDBACK (0x1A) //* Feedback control register -#define DRV2605_REG_CONTROL1 (0x1B) //* Control1 Register -#define DRV2605_REG_CONTROL2 (0x1C) //* Control2 Register -#define DRV2605_REG_CONTROL3 (0x1D) //* Control3 Register -#define DRV2605_REG_CONTROL4 (0x1E) //* Control4 Register -#define DRV2605_REG_VBAT (0x21) //* Vbat voltage-monitor register -#define DRV2605_REG_LRARESON (0x22) //* LRA resonance-period register \ No newline at end of file diff --git a/src/REG/FT6X36Constants.h b/src/REG/FT6X36Constants.h index 6b2362e..867099d 100644 --- a/src/REG/FT6X36Constants.h +++ b/src/REG/FT6X36Constants.h @@ -30,36 +30,36 @@ #pragma once -#define FT3267_SLAVE_ADDRESS (0x38) -#define FT5206_SLAVE_ADDRESS (0x38) -#define FT6X36_SLAVE_ADDRESS (0x38) +#define FT3267_SLAVE_ADDRESS (0x38) +#define FT5206_SLAVE_ADDRESS (0x38) +#define FT6X36_SLAVE_ADDRESS (0x38) -#define FT6X36_VEND_ID (0x11) -#define FT3267_CHIP_ID (0x33) -#define FT6206_CHIP_ID (0x06) -#define FT6236_CHIP_ID (0x36) -#define FT6236U_CHIP_ID (0x64) -#define FT5206U_CHIP_ID (0x64) +#define FT6X36_VEND_ID ((uint8_t)0x11) +#define FT3267_CHIP_ID ((uint8_t)0x33) +#define FT6206_CHIP_ID ((uint8_t)0x06) +#define FT6236_CHIP_ID ((uint8_t)0x36) +#define FT6236U_CHIP_ID ((uint8_t)0x64) +#define FT5206U_CHIP_ID ((uint8_t)0x64) -#define FT6X36_REG_MODE (0x00) -#define FT6X36_REG_GEST (0x01) -#define FT6X36_REG_STATUS (0x02) -#define FT6X36_REG_TOUCH1_XH (0x03) -#define FT6X36_REG_TOUCH1_XL (0x04) -#define FT6X36_REG_TOUCH1_YH (0x05) -#define FT6X36_REG_TOUCH1_YL (0x06) -#define FT6X36_REG_THRESHOLD (0x80) -#define FT6X36_REG_MONITOR_TIME (0x87) -#define FT6X36_REG_PERIOD_ACTIVE (0x88) -#define FT6X36_REG_PERIOD_MONITOR (0x89) +#define FT6X36_REG_MODE ((uint8_t)0x00) +#define FT6X36_REG_GEST ((uint8_t)0x01) +#define FT6X36_REG_STATUS ((uint8_t)0x02) +#define FT6X36_REG_TOUCH1_XH ((uint8_t)0x03) +#define FT6X36_REG_TOUCH1_XL ((uint8_t)0x04) +#define FT6X36_REG_TOUCH1_YH ((uint8_t)0x05) +#define FT6X36_REG_TOUCH1_YL ((uint8_t)0x06) +#define FT6X36_REG_THRESHOLD ((uint8_t)0x80) +#define FT6X36_REG_MONITOR_TIME ((uint8_t)0x87) +#define FT6X36_REG_PERIOD_ACTIVE ((uint8_t)0x88) +#define FT6X36_REG_PERIOD_MONITOR ((uint8_t)0x89) -#define FT6X36_REG_AUTO_CLB_MODE (0xA0) -#define FT6X36_REG_LIB_VERSION_H (0xA1) -#define FT6X36_REG_LIB_VERSION_L (0xA2) -#define FT6X36_REG_INT_STATUS (0xA4) -#define FT6X36_REG_POWER_MODE (0xA5) -#define FT6X36_REG_FIRM_VERS (0xA6) -#define FT6X36_REG_CHIP_ID (0xA3) -#define FT6X36_REG_VENDOR1_ID (0xA8) -#define FT6X36_REG_ERROR_STATUS (0xA9) \ No newline at end of file +#define FT6X36_REG_AUTO_CLB_MODE ((uint8_t)0xA0) +#define FT6X36_REG_LIB_VERSION_H ((uint8_t)0xA1) +#define FT6X36_REG_LIB_VERSION_L ((uint8_t)0xA2) +#define FT6X36_REG_INT_STATUS ((uint8_t)0xA4) +#define FT6X36_REG_POWER_MODE ((uint8_t)0xA5) +#define FT6X36_REG_FIRM_VERS ((uint8_t)0xA6) +#define FT6X36_REG_CHIP_ID ((uint8_t)0xA3) +#define FT6X36_REG_VENDOR1_ID ((uint8_t)0xA8) +#define FT6X36_REG_ERROR_STATUS ((uint8_t)0xA9) \ No newline at end of file diff --git a/src/REG/GT911Constants.h b/src/REG/GT911Constants.h index d8d5271..a942af4 100644 --- a/src/REG/GT911Constants.h +++ b/src/REG/GT911Constants.h @@ -30,137 +30,143 @@ #pragma once -#define GT911_SLAVE_ADDRESS_H (0x14) -#define GT911_SLAVE_ADDRESS_L (0x5D) -#define GT911_DEV_ID (911) -#define GT911_BASE_REF_RATE (5) -#define GT911_REG_LENGTH (186) +#include -// Real-time command (Write only) -#define GT911_COMMAND (0x8040) -#define GT911_ESD_CHECK (0x8041) -#define GT911_COMMAND_CHECK (0x8046) +#define GT911_SLAVE_ADDRESS_H (0x14) +#define GT911_SLAVE_ADDRESS_L (0x5D) +#define GT911_SLAVE_ADDRESS_UNKOWN (0xFF) -// Configuration information (R/W) -#define GT911_CONFIG_START (0x8047) -#define GT911_CONFIG_VERSION (0x8047) -#define GT911_X_OUTPUT_MAX_LOW (0x8048) -#define GT911_X_OUTPUT_MAX_HIGH (0x8049) -#define GT911_Y_OUTPUT_MAX_LOW (0x804A) -#define GT911_Y_OUTPUT_MAX_HIGH (0x804B) -#define GT911_TOUCH_NUMBER (0x804C) -#define GT911_MODULE_SWITCH_1 (0x804D) -#define GT911_MODULE_SWITCH_2 (0x804E) -#define GT911_SHAKE_COUNT (0x804F) -#define GT911_FILTER (0x8050) -#define GT911_LARGE_TOUCH (0x8051) -#define GT911_NOISE_REDUCTION (0x8052) -#define GT911_SCREEN_TOUCH_LEVEL (0x8053) -#define GT911_SCREEN_RELEASE_LEVEL (0x8054) -#define GT911_LOW_POWER_CONTROL (0x8055) -#define GT911_REFRESH_RATE (0x8056) -#define GT911_X_THRESHOLD (0x8057) -#define GT911_Y_THRESHOLD (0x8058) -#define GT911_X_SPEED_LIMIT (0x8059) // Reserve -#define GT911_Y_SPEED_LIMIT (0x805A) // Reserve -#define GT911_SPACE_TOP_BOTTOM (0x805B) -#define GT911_SPACE_LEFT_RIGHT (0x805C) -#define GT911_MINI_FILTER (0x805D) -#define GT911_STRETCH_R0 (0x805E) -#define GT911_STRETCH_R1 (0x805F) -#define GT911_STRETCH_R2 (0x8060) -#define GT911_STRETCH_RM (0x8061) -#define GT911_DRV_GROUPA_NUM (0x8062) -#define GT911_DRV_GROUPB_NUM (0x8063) -#define GT911_SENSOR_NUM (0x8064) -#define GT911_FREQ_A_FACTOR (0x8065) -#define GT911_FREQ_B_FACTOR (0x8066) -#define GT911_PANEL_BIT_FREQ_L (0x8067) -#define GT911_PANEL_BIT_FREQ_H (0x8068) -#define GT911_PANEL_SENSOR_TIME_L (0x8069) // Reserve -#define GT911_PANEL_SENSOR_TIME_H (0x806A) -#define GT911_PANEL_TX_GAIN (0x806B) -#define GT911_PANEL_RX_GAIN (0x806C) -#define GT911_PANEL_DUMP_SHIFT (0x806D) -#define GT911_DRV_FRAME_CONTROL (0x806E) -#define GT911_CHARGING_LEVEL_UP (0x806F) -#define GT911_MODULE_SWITCH3 (0x8070) -#define GT911_GESTURE_DIS (0X8071) -#define GT911_GESTURE_LONG_PRESS_TIME (0x8072) -#define GT911_X_Y_SLOPE_ADJUST (0X8073) -#define GT911_GESTURE_CONTROL (0X8074) -#define GT911_GESTURE_SWITCH1 (0X8075) -#define GT911_GESTURE_SWITCH2 (0X8076) -#define GT911_GESTURE_REFRESH_RATE (0x8077) -#define GT911_GESTURE_TOUCH_LEVEL (0x8078) -#define GT911_NEWGREENWAKEUPLEVEL (0x8079) -#define GT911_FREQ_HOPPING_START (0x807A) -#define GT911_FREQ_HOPPING_END (0X807B) -#define GT911_NOISE_DETECT_TIMES (0x807C) -#define GT911_HOPPING_FLAG (0X807D) -#define GT911_HOPPING_THRESHOLD (0X807E) -#define GT911_NOISE_THRESHOLD (0X807F) // Reserve -#define GT911_NOISE_MIN_THRESHOLD (0X8080) -#define GT911_HOPPING_SENSOR_GROUP (0X8082) -#define GT911_HOPPING_SEG1_NORMALIZE (0X8083) -#define GT911_HOPPING_SEG1_FACTOR (0X8084) -#define GT911_MAIN_CLOCK_AJDUST (0X8085) -#define GT911_HOPPING_SEG2_NORMALIZE (0X8086) -#define GT911_HOPPING_SEG2_FACTOR (0X8087) -#define GT911_HOPPING_SEG3_NORMALIZE (0X8089) -#define GT911_HOPPING_SEG3_FACTOR (0X808A) -#define GT911_HOPPING_SEG4_NORMALIZE (0X808C) -#define GT911_HOPPING_SEG4_FACTOR (0X808D) -#define GT911_HOPPING_SEG5_NORMALIZE (0X808F) -#define GT911_HOPPING_SEG5_FACTOR (0X8090) -#define GT911_HOPPING_SEG6_NORMALIZE (0X8092) -#define GT911_KEY_1 (0X8093) -#define GT911_KEY_2 (0X8094) -#define GT911_KEY_3 (0X8095) -#define GT911_KEY_4 (0X8096) -#define GT911_KEY_AREA (0X8097) -#define GT911_KEY_TOUCH_LEVEL (0X8098) -#define GT911_KEY_LEAVE_LEVEL (0X8099) -#define GT911_KEY_SENS_1_2 (0X809A) -#define GT911_KEY_SENS_3_4 (0X809B) -#define GT911_KEY_RESTRAIN (0X809C) -#define GT911_KEY_RESTRAIN_TIME (0X809D) -#define GT911_GESTURE_LARGE_TOUCH (0X809E) -#define GT911_HOTKNOT_NOISE_MAP (0X80A1) -#define GT911_LINK_THRESHOLD (0X80A2) -#define GT911_PXY_THRESHOLD (0X80A3) -#define GT911_GHOT_DUMP_SHIFT (0X80A4) -#define GT911_GHOT_RX_GAIN (0X80A5) -#define GT911_FREQ_GAIN0 (0X80A6) -#define GT911_FREQ_GAIN1 (0X80A7) -#define GT911_FREQ_GAIN2 (0X80A8) -#define GT911_FREQ_GAIN3 (0X80A9) -#define GT911_COMBINE_DIS (0X80B3) -#define GT911_SPLIT_SET (0X80B4) -#define GT911_SENSOR_CH0 (0X80B7) -#define GT911_DRIVER_CH0 (0X80D5) -#define GT911_CONFIG_CHKSUM (0X80FF) -#define GT911_CONFIG_FRESH (0X8100) -#define GT911_CONFIG_SIZE (0xFF - 0x46) +class GT911Constants +{ +protected: + // Real-time command (Write only) + static constexpr uint16_t GT911_COMMAND = (0x8040); + static constexpr uint16_t GT911_ESD_CHECK = (0x8041); + static constexpr uint16_t GT911_COMMAND_CHECK = (0x8046); -// Coordinate information -#define GT911_PRODUCT_ID (0x8140) -#define GT911_FIRMWARE_VERSION (0x8144) -#define GT911_X_RESOLUTION (0x8146) -#define GT911_Y_RESOLUTION (0x8148) + // Configuration information (R/W) + static constexpr uint16_t GT911_CONFIG_START = (0x8047); + static constexpr uint16_t GT911_CONFIG_VERSION = (0x8047); + static constexpr uint16_t GT911_X_OUTPUT_MAX_LOW = (0x8048); + static constexpr uint16_t GT911_X_OUTPUT_MAX_HIGH = (0x8049); + static constexpr uint16_t GT911_Y_OUTPUT_MAX_LOW = (0x804A); + static constexpr uint16_t GT911_Y_OUTPUT_MAX_HIGH = (0x804B); + static constexpr uint16_t GT911_TOUCH_NUMBER = (0x804C); + static constexpr uint16_t GT911_MODULE_SWITCH_1 = (0x804D); + static constexpr uint16_t GT911_MODULE_SWITCH_2 = (0x804E); + static constexpr uint16_t GT911_SHAKE_COUNT = (0x804F); + static constexpr uint16_t GT911_FILTER = (0x8050); + static constexpr uint16_t GT911_LARGE_TOUCH = (0x8051); + static constexpr uint16_t GT911_NOISE_REDUCTION = (0x8052); + static constexpr uint16_t GT911_SCREEN_TOUCH_LEVEL = (0x8053); + static constexpr uint16_t GT911_SCREEN_RELEASE_LEVEL = (0x8054); + static constexpr uint16_t GT911_LOW_POWER_CONTROL = (0x8055); + static constexpr uint16_t GT911_REFRESH_RATE = (0x8056); + static constexpr uint16_t GT911_X_THRESHOLD = (0x8057); + static constexpr uint16_t GT911_Y_THRESHOLD = (0x8058); + static constexpr uint16_t GT911_X_SPEED_LIMIT = (0x8059); // Reserve + static constexpr uint16_t GT911_Y_SPEED_LIMIT = (0x805A); // Reserve + static constexpr uint16_t GT911_SPACE_TOP_BOTTOM = (0x805B); + static constexpr uint16_t GT911_SPACE_LEFT_RIGHT = (0x805C); + static constexpr uint16_t GT911_MINI_FILTER = (0x805D); + static constexpr uint16_t GT911_STRETCH_R0 = (0x805E); + static constexpr uint16_t GT911_STRETCH_R1 = (0x805F); + static constexpr uint16_t GT911_STRETCH_R2 = (0x8060); + static constexpr uint16_t GT911_STRETCH_RM = (0x8061); + static constexpr uint16_t GT911_DRV_GROUPA_NUM = (0x8062); + static constexpr uint16_t GT911_DRV_GROUPB_NUM = (0x8063); + static constexpr uint16_t GT911_SENSOR_NUM = (0x8064); + static constexpr uint16_t GT911_FREQ_A_FACTOR = (0x8065); + static constexpr uint16_t GT911_FREQ_B_FACTOR = (0x8066); + static constexpr uint16_t GT911_PANEL_BIT_FREQ_L = (0x8067); + static constexpr uint16_t GT911_PANEL_BIT_FREQ_H = (0x8068); + static constexpr uint16_t GT911_PANEL_SENSOR_TIME_L = (0x8069); // Reserve + static constexpr uint16_t GT911_PANEL_SENSOR_TIME_H = (0x806A); + static constexpr uint16_t GT911_PANEL_TX_GAIN = (0x806B); + static constexpr uint16_t GT911_PANEL_RX_GAIN = (0x806C); + static constexpr uint16_t GT911_PANEL_DUMP_SHIFT = (0x806D); + static constexpr uint16_t GT911_DRV_FRAME_CONTROL = (0x806E); + static constexpr uint16_t GT911_CHARGING_LEVEL_UP = (0x806F); + static constexpr uint16_t GT911_MODULE_SWITCH3 = (0x8070); + static constexpr uint16_t GT911_GESTURE_DIS = (0X8071); + static constexpr uint16_t GT911_GESTURE_LONG_PRESS_TIME = (0x8072); + static constexpr uint16_t GT911_X_Y_SLOPE_ADJUST = (0X8073); + static constexpr uint16_t GT911_GESTURE_CONTROL = (0X8074); + static constexpr uint16_t GT911_GESTURE_SWITCH1 = (0X8075); + static constexpr uint16_t GT911_GESTURE_SWITCH2 = (0X8076); + static constexpr uint16_t GT911_GESTURE_REFRESH_RATE = (0x8077); + static constexpr uint16_t GT911_GESTURE_TOUCH_LEVEL = (0x8078); + static constexpr uint16_t GT911_NEWGREENWAKEUPLEVEL = (0x8079); + static constexpr uint16_t GT911_FREQ_HOPPING_START = (0x807A); + static constexpr uint16_t GT911_FREQ_HOPPING_END = (0X807B); + static constexpr uint16_t GT911_NOISE_DETECT_TIMES = (0x807C); + static constexpr uint16_t GT911_HOPPING_FLAG = (0X807D); + static constexpr uint16_t GT911_HOPPING_THRESHOLD = (0X807E); + static constexpr uint16_t GT911_NOISE_THRESHOLD = (0X807F); // Reserve + static constexpr uint16_t GT911_NOISE_MIN_THRESHOLD = (0X8080); + static constexpr uint16_t GT911_HOPPING_SENSOR_GROUP = (0X8082); + static constexpr uint16_t GT911_HOPPING_SEG1_NORMALIZE = (0X8083); + static constexpr uint16_t GT911_HOPPING_SEG1_FACTOR = (0X8084); + static constexpr uint16_t GT911_MAIN_CLOCK_ADJUST = (0X8085); + static constexpr uint16_t GT911_HOPPING_SEG2_NORMALIZE = (0X8086); + static constexpr uint16_t GT911_HOPPING_SEG2_FACTOR = (0X8087); + static constexpr uint16_t GT911_HOPPING_SEG3_NORMALIZE = (0X8089); + static constexpr uint16_t GT911_HOPPING_SEG3_FACTOR = (0X808A); + static constexpr uint16_t GT911_HOPPING_SEG4_NORMALIZE = (0X808C); + static constexpr uint16_t GT911_HOPPING_SEG4_FACTOR = (0X808D); + static constexpr uint16_t GT911_HOPPING_SEG5_NORMALIZE = (0X808F); + static constexpr uint16_t GT911_HOPPING_SEG5_FACTOR = (0X8090); + static constexpr uint16_t GT911_HOPPING_SEG6_NORMALIZE = (0X8092); + static constexpr uint16_t GT911_KEY_1 = (0X8093); + static constexpr uint16_t GT911_KEY_2 = (0X8094); + static constexpr uint16_t GT911_KEY_3 = (0X8095); + static constexpr uint16_t GT911_KEY_4 = (0X8096); + static constexpr uint16_t GT911_KEY_AREA = (0X8097); + static constexpr uint16_t GT911_KEY_TOUCH_LEVEL = (0X8098); + static constexpr uint16_t GT911_KEY_LEAVE_LEVEL = (0X8099); + static constexpr uint16_t GT911_KEY_SENS_1_2 = (0X809A); + static constexpr uint16_t GT911_KEY_SENS_3_4 = (0X809B); + static constexpr uint16_t GT911_KEY_RESTRAIN = (0X809C); + static constexpr uint16_t GT911_KEY_RESTRAIN_TIME = (0X809D); + static constexpr uint16_t GT911_GESTURE_LARGE_TOUCH = (0X809E); + static constexpr uint16_t GT911_HOTKNOT_NOISE_MAP = (0X80A1); + static constexpr uint16_t GT911_LINK_THRESHOLD = (0X80A2); + static constexpr uint16_t GT911_PXY_THRESHOLD = (0X80A3); + static constexpr uint16_t GT911_GHOT_DUMP_SHIFT = (0X80A4); + static constexpr uint16_t GT911_GHOT_RX_GAIN = (0X80A5); + static constexpr uint16_t GT911_FREQ_GAIN0 = (0X80A6); + static constexpr uint16_t GT911_FREQ_GAIN1 = (0X80A7); + static constexpr uint16_t GT911_FREQ_GAIN2 = (0X80A8); + static constexpr uint16_t GT911_FREQ_GAIN3 = (0X80A9); + static constexpr uint16_t GT911_COMBINE_DIS = (0X80B3); + static constexpr uint16_t GT911_SPLIT_SET = (0X80B4); + static constexpr uint16_t GT911_SENSOR_CH0 = (0X80B7); + static constexpr uint16_t GT911_DRIVER_CH0 = (0X80D5); + static constexpr uint16_t GT911_CONFIG_CHKSUM = (0X80FF); + static constexpr uint16_t GT911_CONFIG_FRESH = (0X8100); + static constexpr uint16_t GT911_CONFIG_SIZE = (0xFF - 0x46); + // Coordinate information + static constexpr uint16_t GT911_PRODUCT_ID = (0x8140); + static constexpr uint16_t GT911_FIRMWARE_VERSION = (0x8144); + static constexpr uint16_t GT911_X_RESOLUTION = (0x8146); + static constexpr uint16_t GT911_Y_RESOLUTION = (0x8148); -#define GT911_VENDOR_ID (0X8140) -#define GT911_IMFORMATION (0X8140) -#define GT911_POINT_INFO (0X814E) -#define GT911_POINT_1 (0X814F) -#define GT911_POINT_2 (0X8157) -#define GT911_POINT_3 (0X815F) -#define GT911_POINT_4 (0X8167) -#define GT911_POINT_5 (0X816F) + static constexpr uint16_t GT911_VENDOR_ID = (0X8140); + static constexpr uint16_t GT911_INFORMATION = (0X8140); + static constexpr uint16_t GT911_POINT_INFO = (0X814E); + static constexpr uint16_t GT911_POINT_1 = (0X814F); + static constexpr uint16_t GT911_POINT_2 = (0X8157); + static constexpr uint16_t GT911_POINT_3 = (0X815F); + static constexpr uint16_t GT911_POINT_4 = (0X8167); + static constexpr uint16_t GT911_POINT_5 = (0X816F); + + + static constexpr uint16_t GT911_DEV_ID = (911); + static constexpr uint8_t GT911_BASE_REF_RATE = (5); + static constexpr uint8_t GT911_REG_LENGTH = (186); + +}; -#define GT911_GET_POINT(x) (x & 0x0F) -#define GT911_GET_BUFFER_STATUS(x) (x & 0x80) -#define GT911_GET_HAVE_KEY(x) (x & 0x10) diff --git a/src/REG/GT9895Constants.h b/src/REG/GT9895Constants.h index 2f5f249..d5862fa 100644 --- a/src/REG/GT9895Constants.h +++ b/src/REG/GT9895Constants.h @@ -30,11 +30,16 @@ #pragma once +#include + #define GT9895_SLAVE_ADDRESS_H (0x14) #define GT9895_SLAVE_ADDRESS_L (0x5D) +class GT9895Constants +{ +public: #define GT9895_MAX_TOUCH (10) -#define GT9895_MAX_PEN_KEY (2) +#define GT9895_MAX_PEN_KEY (2) #define GT9895_INFO_MAX_LENGTH (1024) #define GT9895_MAX_SCAN_RATE_NUM (8) #define GT9895_MAX_SCAN_FREQ_NUM (8) @@ -42,20 +47,205 @@ #define GT9895_GESTURE_DATA_LEN (16) #define GT9895_IRQ_EVENT_HEAD_LEN (8) #define GT9895_BYTES_PER_POINT (8) -#define GT9895_COOR_DATA_CHECKSUM_SIZE (2) +#define GT9895_COORDS_DATA_CHECKSUM_SIZE (2) + + enum CHECKSUM_MODE { + CHECKSUM_MODE_U8_LE, + CHECKSUM_MODE_U16_LE, + }; + + enum TouchPointStatus { + TS_NONE, + TS_RELEASE, + TS_TOUCH, + }; + + /* interrupt event type */ + enum TsEventType { + EVENT_INVALID = 0, + EVENT_TOUCH = (1 << 0), /* finger touch event */ + EVENT_PEN = (1 << 1), /* pen event */ + EVENT_REQUEST = (1 << 2), + EVENT_GESTURE = (1 << 3), + }; + + enum brl_request_code { + BRL_REQUEST_CODE_CONFIG = 0x01, + BRL_REQUEST_CODE_REF_ERR = 0x02, + BRL_REQUEST_CODE_RESET = 0x03, + BRL_REQUEST_CODE_CLOCK = 0x04, + }; + + /* coordinate package */ + typedef struct { + int status; /* NONE, RELEASE, TOUCH */ + unsigned int x, y, w, p; + } TsCoords; + + /* touch event data */ + typedef struct { + int touch_num; + uint64_t timestamp; + TsCoords coords[GT9895_MAX_TOUCH]; + } TouchData; + + typedef struct { + int status; + int code; + } TsKey; + + typedef struct { + int status; /* NONE, RELEASE, TOUCH */ + int tool_type; /* BTN_TOOL_RUBBER BTN_TOOL_PEN */ + unsigned int x, y, p; + signed char tilt_x; + signed char tilt_y; + } PenCoords; -#define GT9895_POINT_TYPE_STYLUS_HOVER (0x01) -#define GT9895_POINT_TYPE_STYLUS (0x03) + typedef struct { + PenCoords coords; + TsKey keys[GT9895_MAX_PEN_KEY]; + } PenData; + typedef struct { + int id; + int x; + int y; + int w; + int p; + int tool_type; + } PointData; -#define GT9895_TOUCH_EVENT (0x80) -#define GT9895_REQUEST_EVENT (0x40) -#define GT9895_GESTURE_EVENT (0x20) -#define GT9895_FP_EVENT (0x08) + /* + * ChipTsEvent - touch event struct + * @event_type: touch event type, touch data or + * request event + * @event_data: event data + */ + typedef struct { + enum TsEventType event_type; + uint8_t fp_flag; /* finger print DOWN flag */ + uint8_t request_code; /* represent the request type */ + uint8_t gesture_type; + uint8_t gesture_data[GT9895_GESTURE_DATA_LEN]; + TouchData touch_data; + PenData pen_data; + } ChipTsEvent; + + typedef struct { + uint8_t rom_pid[6]; /* rom PID */ + uint8_t rom_vid[3]; /* Mask VID */ + uint8_t rom_vid_reserved; + uint8_t patch_pid[8]; /* Patch PID */ + uint8_t patch_vid[4]; /* Patch VID */ + uint8_t patch_vid_reserved; + uint8_t sensor_id; + uint8_t reserved[2]; + uint16_t checksum; + } ChipFirmwareVersion; + + typedef struct { + uint8_t info_customer_id; + uint8_t info_version_id; + uint8_t ic_die_id; + uint8_t ic_version_id; + uint32_t config_id; + uint8_t config_version; + uint8_t frame_data_customer_id; + uint8_t frame_data_version_id; + uint8_t touch_data_customer_id; + uint8_t touch_data_version_id; + uint8_t reserved[3]; + } ChipInfoVersion; + + typedef struct { /* feature info*/ + uint16_t freqhop_feature; + uint16_t calibration_feature; + uint16_t gesture_feature; + uint16_t side_touch_feature; + uint16_t stylus_feature; + } ChipInfoFeature; + + typedef struct { /* param */ + uint8_t drv_num; + uint8_t sen_num; + uint8_t button_num; + uint8_t force_num; + uint8_t active_scan_rate_num; + uint16_t active_scan_rate[GT9895_MAX_SCAN_RATE_NUM]; + uint8_t mutual_freq_num; + uint16_t mutual_freq[GT9895_MAX_SCAN_FREQ_NUM]; + uint8_t self_tx_freq_num; + uint16_t self_tx_freq[GT9895_MAX_SCAN_FREQ_NUM]; + uint8_t self_rx_freq_num; + uint16_t self_rx_freq[GT9895_MAX_SCAN_FREQ_NUM]; + uint8_t stylus_freq_num; + uint16_t stylus_freq[GT9895_MAX_FREQ_NUM_STYLUS]; + } ChipInfoParams; + + typedef struct { /* other data */ + uint32_t cmd_addr; + uint16_t cmd_max_len; + uint32_t cmd_reply_addr; + uint16_t cmd_reply_len; + uint32_t fw_state_addr; + uint16_t fw_state_len; + uint32_t fw_buffer_addr; + uint16_t fw_buffer_max_len; + uint32_t frame_data_addr; + uint16_t frame_data_head_len; + uint16_t fw_attr_len; + uint16_t fw_log_len; + uint8_t pack_max_num; + uint8_t pack_compress_version; + uint16_t stylus_struct_len; + uint16_t mutual_struct_len; + uint16_t self_struct_len; + uint16_t noise_struct_len; + uint32_t touch_data_addr; + uint16_t touch_data_head_len; + uint16_t point_struct_len; + uint16_t reserved1; + uint16_t reserved2; + uint32_t mutual_rawdata_addr; + uint32_t mutual_diffdata_addr; + uint32_t mutual_refdata_addr; + uint32_t self_rawdata_addr; + uint32_t self_diffdata_addr; + uint32_t self_refdata_addr; + uint32_t iq_rawdata_addr; + uint32_t iq_refdata_addr; + uint32_t im_rawdata_addr; + uint16_t im_readata_len; + uint32_t noise_rawdata_addr; + uint16_t noise_rawdata_len; + uint32_t stylus_rawdata_addr; + uint16_t stylus_rawdata_len; + uint32_t noise_data_addr; + uint32_t esd_addr; + } ChipInfoMisc; + + typedef struct { + uint16_t length; + ChipInfoVersion version; + ChipInfoFeature feature; + ChipInfoParams parm; + ChipInfoMisc misc; + } ChipInfo; +protected: + static constexpr uint8_t GT9895_POINT_TYPE_STYLUS_HOVER = (0x01); + static constexpr uint8_t GT9895_POINT_TYPE_STYLUS = (0x03); + static constexpr uint8_t GT9895_TOUCH_EVENT = (0x80); + static constexpr uint8_t GT9895_REQUEST_EVENT = (0x40); + static constexpr uint8_t GT9895_GESTURE_EVENT = (0x20); + static constexpr uint8_t GT9895_FP_EVENT = (0x08); #define GT9895_REG_FW_VERSION (0x00010014u) #define GT9895_REG_INFO (0x00010070u) #define GT9895_REG_CMD (0x00010174u) #define GT9895_REG_POINT (0x00010308u) +}; + + diff --git a/src/REG/LTR533Constants.h b/src/REG/LTR533Constants.h index 9df1278..5bf6ac8 100644 --- a/src/REG/LTR533Constants.h +++ b/src/REG/LTR533Constants.h @@ -22,42 +22,50 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. * - * @file LTR533Constants.tpp + * @file LTR533Constants.hpp * @author Lewis He (lewishe@outlook.com) * @date 2023-09-09 */ #pragma once -#define LTR553_SLAVE_ADDRESS (0x23) +#include -#define LTR553_REG_ALS_CONTR (0x80) -#define LTR553_REG_PS_CONTR (0x81) -#define LTR553_REG_PS_LED (0x82) -#define LTR553_REG_PS_N_PULSES (0x83) -#define LTR553_REG_PS_MEAS_RATE (0x84) -#define LTR553_REG_ALS_MEAS_RATE (0x85) -#define LTR553_REG_PART_ID (0x86) -#define LTR553_REG_MANUFAC_ID (0x87) -#define LTR553_REG_ALS_DATA_CH1_0 (0x88) -#define LTR553_REG_ALS_DATA_CH1_1 (0x89) -#define LTR553_REG_ALS_DATA_CH0_0 (0x8A) -#define LTR553_REG_ALS_DATA_CH0_1 (0x8B) -#define LTR553_REG_ALS_PS_STATUS (0x8C) -#define LTR553_REG_PS_DATA_0 (0x8D) -#define LTR553_REG_PS_DATA_1 (0x8E) -#define LTR553_REG_INTERRUPT (0x8F) -#define LTR553_REG_PS_THRES_UP_0 (0x90) -#define LTR553_REG_PS_THRES_UP_1 (0x91) -#define LTR553_REG_PS_THRES_LOW_0 (0x92) -#define LTR553_REG_PS_THRES_LOW_1 (0x93) -#define LTR553_REG_PS_OFFSET_1 (0x94) -#define LTR553_REG_PS_OFFSET_0 (0x95) -#define LTR553_REG_ALS_THRES_UP_0 (0x97) -#define LTR553_REG_ALS_THRES_UP_1 (0x98) -#define LTR553_REG_ALS_THRES_LOW_0 (0x99) -#define LTR553_REG_ALS_THRES_LOW_1 (0x9A) -#define LTR553_REG_INTERRUPT_PERSIST (0x9E) +class LTR553Constants +{ +protected: + // Unique I2C device address + static constexpr uint8_t LTR553_SLAVE_ADDRESS = 0x23; + // Registers + static constexpr uint8_t REG_ALS_CONTR = 0x80; + static constexpr uint8_t REG_PS_CONTR = 0x81; + static constexpr uint8_t REG_PS_LED = 0x82; + static constexpr uint8_t REG_PS_N_PULSES = 0x83; + static constexpr uint8_t REG_PS_MEAS_RATE = 0x84; + static constexpr uint8_t REG_ALS_MEAS_RATE = 0x85; + static constexpr uint8_t REG_PART_ID = 0x86; + static constexpr uint8_t REG_MANUFAC_ID = 0x87; + static constexpr uint8_t REG_ALS_DATA_CH1_0 = 0x88; + static constexpr uint8_t REG_ALS_DATA_CH1_1 = 0x89; + static constexpr uint8_t REG_ALS_DATA_CH0_0 = 0x8A; + static constexpr uint8_t REG_ALS_DATA_CH0_1 = 0x8B; + static constexpr uint8_t REG_ALS_PS_STATUS = 0x8C; + static constexpr uint8_t REG_PS_DATA_0 = 0x8D; + static constexpr uint8_t REG_PS_DATA_1 = 0x8E; + static constexpr uint8_t REG_INTERRUPT = 0x8F; + static constexpr uint8_t REG_PS_THRES_UP_0 = 0x90; + static constexpr uint8_t REG_PS_THRES_UP_1 = 0x91; + static constexpr uint8_t REG_PS_THRES_LOW_0 = 0x92; + static constexpr uint8_t REG_PS_THRES_LOW_1 = 0x93; + static constexpr uint8_t REG_PS_OFFSET_1 = 0x94; + static constexpr uint8_t REG_PS_OFFSET_0 = 0x95; + static constexpr uint8_t REG_ALS_THRES_UP_0 = 0x97; + static constexpr uint8_t REG_ALS_THRES_UP_1 = 0x98; + static constexpr uint8_t REG_ALS_THRES_LOW_0 = 0x99; + static constexpr uint8_t REG_ALS_THRES_LOW_1 = 0x9A; + static constexpr uint8_t REG_INTERRUPT_PERSIST = 0x9E; -#define LTR553_DEFAULT_MAN_ID (0x05) \ No newline at end of file + // Default Manufacturer ID + static constexpr uint8_t LTR553_DEFAULT_MAN_ID = 0x05; +}; \ No newline at end of file diff --git a/src/REG/MPU6886Constants.h b/src/REG/MPU6886Constants.h index 459bad2..1de1dfa 100644 --- a/src/REG/MPU6886Constants.h +++ b/src/REG/MPU6886Constants.h @@ -33,81 +33,81 @@ #define MPU6886_SLAVE_ADDRESS (0x68) -#define MPU6886_REG_XG_OFFS_TC_H (0x04) -#define MPU6886_REG_XG_OFFS_TC_L (0x05) -#define MPU6886_REG_YG_OFFS_TC_H (0x07) -#define MPU6886_REG_YG_OFFS_TC_L (0x08) -#define MPU6886_REG_ZG_OFFS_TC_H (0x0A) -#define MPU6886_REG_ZG_OFFS_TC_L (0x0B) -#define MPU6886_REG_SELF_TEST_X_ACCEL (0x0D) -#define MPU6886_REG_SELF_TEST_Y_ACCEL (0x0E) -#define MPU6886_REG_SELF_TEST_Z_ACCEL (0x0F) -#define MPU6886_REG_XG_OFFS_USRH (0x13) -#define MPU6886_REG_XG_OFFS_USRL (0x14) -#define MPU6886_REG_YG_OFFS_USRH (0x15) -#define MPU6886_REG_YG_OFFS_USRL (0x16) -#define MPU6886_REG_ZG_OFFS_USRH (0x17) -#define MPU6886_REG_ZG_OFFS_USRL (0x18) -#define MPU6886_REG_SMPLRT_DIV (0x19) -#define MPU6886_REG_CONFIG (0x1A) -#define MPU6886_REG_GYRO_CONFIG (0x1B) -#define MPU6886_REG_ACCEL_CONFIG (0x1C) -#define MPU6886_REG_ACCEL_CONFIG_2 (0x1D) -#define MPU6886_REG_LP_MODE_CFG (0x1E) -#define MPU6886_REG_ACCEL_WOM_X_THR (0x20) -#define MPU6886_REG_ACCEL_WOM_Y_THR (0x21) -#define MPU6886_REG_ACCEL_WOM_Z_THR (0x22) -#define MPU6886_REG_FIFO_EN (0x23) -#define MPU6886_REG_FSYNC_INT (0x36) -#define MPU6886_REG_INT_PIN_CFG (0x37) -#define MPU6886_REG_INT_ENABLE (0x38) -#define MPU6886_REG_FIFO_WM_INT_STATUS (0x39) -#define MPU6886_REG_INT_STATUS (0x3A) -#define MPU6886_REG_ACCEL_XOUT_H (0x3B) -#define MPU6886_REG_ACCEL_XOUT_L (0x3C) -#define MPU6886_REG_ACCEL_YOUT_H (0x3D) -#define MPU6886_REG_ACCEL_YOUT_L (0x3E) -#define MPU6886_REG_ACCEL_ZOUT_H (0x3F) -#define MPU6886_REG_ACCEL_ZOUT_L (0x40) -#define MPU6886_REG_TEMP_OUT_H (0x41) -#define MPU6886_REG_TEMP_OUT_L (0x42) -#define MPU6886_REG_GYRO_XOUT_H (0x43) -#define MPU6886_REG_GYRO_XOUT_L (0x44) -#define MPU6886_REG_GYRO_YOUT_H (0x45) -#define MPU6886_REG_GYRO_YOUT_L (0x46) -#define MPU6886_REG_GYRO_ZOUT_H (0x47) -#define MPU6886_REG_GYRO_ZOUT_L (0x48) -#define MPU6886_REG_SELF_TEST_X_GYRO (0x50) -#define MPU6886_REG_SELF_TEST_Y_GYRO (0x51) -#define MPU6886_REG_SELF_TEST_Z_GYRO (0x52) -#define MPU6886_REG_E_ID0 (0x53) -#define MPU6886_REG_E_ID1 (0x54) -#define MPU6886_REG_E_ID2 (0x55) -#define MPU6886_REG_E_ID3 (0x56) -#define MPU6886_REG_E_ID4 (0x57) -#define MPU6886_REG_E_ID5 (0x58) -#define MPU6886_REG_E_ID6 (0x59) -#define MPU6886_REG_FIFO_WM_TH1 (0x60) -#define MPU6886_REG_FIFO_WM_TH2 (0x61) -#define MPU6886_REG_SIGNAL_PATH_RESET (0x68) -#define MPU6886_REG_ACCEL_INTEL_CTRL (0x69) -#define MPU6886_REG_USER_CTRL (0x6A) -#define MPU6886_REG_PWR_MGMT_1 (0x6B) -#define MPU6886_REG_PWR_MGMT_2 (0x6C) -#define MPU6886_REG_I2C_IF (0x70) -#define MPU6886_REG_FIFO_COUNTH (0x72) -#define MPU6886_REG_FIFO_COUNTL (0x73) -#define MPU6886_REG_FIFO_R_W (0x74) -#define MPU6886_REG_WHO_AM_I (0x75) -#define MPU6886_REG_XA_OFFSET_H (0x77) -#define MPU6886_REG_XA_OFFSET_L (0x78) -#define MPU6886_REG_YA_OFFSET_H (0x7A) -#define MPU6886_REG_YA_OFFSET_L (0x7B) -#define MPU6886_REG_ZA_OFFSET_H (0x7D) -#define MPU6886_REG_ZA_OFFSET_L (0x7E) +#define MPU6886_REG_XG_OFFS_TC_H ((uint8_t)0x04) +#define MPU6886_REG_XG_OFFS_TC_L ((uint8_t)0x05) +#define MPU6886_REG_YG_OFFS_TC_H ((uint8_t)0x07) +#define MPU6886_REG_YG_OFFS_TC_L ((uint8_t)0x08) +#define MPU6886_REG_ZG_OFFS_TC_H ((uint8_t)0x0A) +#define MPU6886_REG_ZG_OFFS_TC_L ((uint8_t)0x0B) +#define MPU6886_REG_SELF_TEST_X_ACCEL ((uint8_t)0x0D) +#define MPU6886_REG_SELF_TEST_Y_ACCEL ((uint8_t)0x0E) +#define MPU6886_REG_SELF_TEST_Z_ACCEL ((uint8_t)0x0F) +#define MPU6886_REG_XG_OFFS_USRH ((uint8_t)0x13) +#define MPU6886_REG_XG_OFFS_USRL ((uint8_t)0x14) +#define MPU6886_REG_YG_OFFS_USRH ((uint8_t)0x15) +#define MPU6886_REG_YG_OFFS_USRL ((uint8_t)0x16) +#define MPU6886_REG_ZG_OFFS_USRH ((uint8_t)0x17) +#define MPU6886_REG_ZG_OFFS_USRL ((uint8_t)0x18) +#define MPU6886_REG_SMPLRT_DIV ((uint8_t)0x19) +#define MPU6886_REG_CONFIG ((uint8_t)0x1A) +#define MPU6886_REG_GYRO_CONFIG ((uint8_t)0x1B) +#define MPU6886_REG_ACCEL_CONFIG ((uint8_t)0x1C) +#define MPU6886_REG_ACCEL_CONFIG_2 ((uint8_t)0x1D) +#define MPU6886_REG_LP_MODE_CFG ((uint8_t)0x1E) +#define MPU6886_REG_ACCEL_WOM_X_THR ((uint8_t)0x20) +#define MPU6886_REG_ACCEL_WOM_Y_THR ((uint8_t)0x21) +#define MPU6886_REG_ACCEL_WOM_Z_THR ((uint8_t)0x22) +#define MPU6886_REG_FIFO_EN ((uint8_t)0x23) +#define MPU6886_REG_FSYNC_INT ((uint8_t)0x36) +#define MPU6886_REG_INT_PIN_CFG ((uint8_t)0x37) +#define MPU6886_REG_INT_ENABLE ((uint8_t)0x38) +#define MPU6886_REG_FIFO_WM_INT_STATUS ((uint8_t)0x39) +#define MPU6886_REG_INT_STATUS ((uint8_t)0x3A) +#define MPU6886_REG_ACCEL_XOUT_H ((uint8_t)0x3B) +#define MPU6886_REG_ACCEL_XOUT_L ((uint8_t)0x3C) +#define MPU6886_REG_ACCEL_YOUT_H ((uint8_t)0x3D) +#define MPU6886_REG_ACCEL_YOUT_L ((uint8_t)0x3E) +#define MPU6886_REG_ACCEL_ZOUT_H ((uint8_t)0x3F) +#define MPU6886_REG_ACCEL_ZOUT_L ((uint8_t)0x40) +#define MPU6886_REG_TEMP_OUT_H ((uint8_t)0x41) +#define MPU6886_REG_TEMP_OUT_L ((uint8_t)0x42) +#define MPU6886_REG_GYRO_XOUT_H ((uint8_t)0x43) +#define MPU6886_REG_GYRO_XOUT_L ((uint8_t)0x44) +#define MPU6886_REG_GYRO_YOUT_H ((uint8_t)0x45) +#define MPU6886_REG_GYRO_YOUT_L ((uint8_t)0x46) +#define MPU6886_REG_GYRO_ZOUT_H ((uint8_t)0x47) +#define MPU6886_REG_GYRO_ZOUT_L ((uint8_t)0x48) +#define MPU6886_REG_SELF_TEST_X_GYRO ((uint8_t)0x50) +#define MPU6886_REG_SELF_TEST_Y_GYRO ((uint8_t)0x51) +#define MPU6886_REG_SELF_TEST_Z_GYRO ((uint8_t)0x52) +#define MPU6886_REG_E_ID0 ((uint8_t)0x53) +#define MPU6886_REG_E_ID1 ((uint8_t)0x54) +#define MPU6886_REG_E_ID2 ((uint8_t)0x55) +#define MPU6886_REG_E_ID3 ((uint8_t)0x56) +#define MPU6886_REG_E_ID4 ((uint8_t)0x57) +#define MPU6886_REG_E_ID5 ((uint8_t)0x58) +#define MPU6886_REG_E_ID6 ((uint8_t)0x59) +#define MPU6886_REG_FIFO_WM_TH1 ((uint8_t)0x60) +#define MPU6886_REG_FIFO_WM_TH2 ((uint8_t)0x61) +#define MPU6886_REG_SIGNAL_PATH_RESET ((uint8_t)0x68) +#define MPU6886_REG_ACCEL_INTEL_CTRL ((uint8_t)0x69) +#define MPU6886_REG_USER_CTRL ((uint8_t)0x6A) +#define MPU6886_REG_PWR_MGMT_1 ((uint8_t)0x6B) +#define MPU6886_REG_PWR_MGMT_2 ((uint8_t)0x6C) +#define MPU6886_REG_I2C_IF ((uint8_t)0x70) +#define MPU6886_REG_FIFO_COUNTH ((uint8_t)0x72) +#define MPU6886_REG_FIFO_COUNTL ((uint8_t)0x73) +#define MPU6886_REG_FIFO_R_W ((uint8_t)0x74) +#define MPU6886_REG_WHO_AM_I ((uint8_t)0x75) +#define MPU6886_REG_XA_OFFSET_H ((uint8_t)0x77) +#define MPU6886_REG_XA_OFFSET_L ((uint8_t)0x78) +#define MPU6886_REG_YA_OFFSET_H ((uint8_t)0x7A) +#define MPU6886_REG_YA_OFFSET_L ((uint8_t)0x7B) +#define MPU6886_REG_ZA_OFFSET_H ((uint8_t)0x7D) +#define MPU6886_REG_ZA_OFFSET_L ((uint8_t)0x7E) -#define MPU6886_WHO_AM_I_RES (0x19) +#define MPU6886_WHO_AM_I_RES ((uint8_t)0x19) diff --git a/src/REG/PCF85063Constants.h b/src/REG/PCF85063Constants.h index 17f89bc..662ca92 100644 --- a/src/REG/PCF85063Constants.h +++ b/src/REG/PCF85063Constants.h @@ -30,34 +30,42 @@ #pragma once +#include -#define PCF85063_SLAVE_ADDRESS (0x51) +class PCF85063Constants +{ +protected: + // Unique I2C device address + static constexpr uint8_t PCF85063_SLAVE_ADDRESS = 0x51; -#define PCF85063_CTRL1_REG (0x00) -#define PCF85063_CTRL2_REG (0x01) -#define PCF85063_OFFSET_REG (0x02) -#define PCF85063_RAM_REG (0x03) -#define PCF85063_SEC_REG (0x04) -#define PCF85063_MIN_REG (0x05) -#define PCF85063_HR_REG (0x06) -#define PCF85063_DAY_REG (0x07) -#define PCF85063_WEEKDAY_REG (0x08) -#define PCF85063_MONTH_REG (0x09) -#define PCF85063_YEAR_REG (0x0A) -#define PCF85063_ALRM_SEC_REG (0x0B) -#define PCF85063_ALRM_MIN_REG (0x0C) -#define PCF85063_ALRM_HR_REG (0x0D) -#define PCF85063_ALRM_DAY_REG (0x0E) -#define PCF85063_ALRM_WEEK_REG (0x0F) -#define PCF85063_TIMER_VAL_REG (0x10) -#define PCF85063_TIMER_MD_REG (0x11) + // Register addresses + static constexpr uint8_t PCF85063_CTRL1_REG = 0x00; + static constexpr uint8_t PCF85063_CTRL2_REG = 0x01; + static constexpr uint8_t PCF85063_OFFSET_REG = 0x02; + static constexpr uint8_t PCF85063_RAM_REG = 0x03; + static constexpr uint8_t PCF85063_SEC_REG = 0x04; + static constexpr uint8_t PCF85063_MIN_REG = 0x05; + static constexpr uint8_t PCF85063_HR_REG = 0x06; + static constexpr uint8_t PCF85063_DAY_REG = 0x07; + static constexpr uint8_t PCF85063_WEEKDAY_REG = 0x08; + static constexpr uint8_t PCF85063_MONTH_REG = 0x09; + static constexpr uint8_t PCF85063_YEAR_REG = 0x0A; + static constexpr uint8_t PCF85063_ALRM_SEC_REG = 0x0B; + static constexpr uint8_t PCF85063_ALRM_MIN_REG = 0x0C; + static constexpr uint8_t PCF8563_ALRM_HR_REG = 0x0D; + static constexpr uint8_t PCF85063_ALRM_DAY_REG = 0x0E; + static constexpr uint8_t PCF85063_ALRM_WEEK_REG = 0x0F; + static constexpr uint8_t PCF85063_TIMER_VAL_REG = 0x10; + static constexpr uint8_t PCF85063_TIMER_MD_REG = 0x11; -#define PCF85063_CTRL1_TEST_EN_MASK (1<<7u) -#define PCF85063_CTRL1_CLOCK_EN_MASK (1<<5u) -#define PCF85063_CTRL1_SOFTRST_EN_MASK (1<<4u) -#define PCF85063_CTRL1_CIE_EN_MASK (1<<2u) -#define PCF85063_CTRL1_HOUR_FORMAT_12H_MASK (1<<1u) + // Mask values + static constexpr uint8_t PCF85063_CTRL1_TEST_EN_MASK = (1 << 7u); + static constexpr uint8_t PCF85063_CTRL1_CLOCK_EN_MASK = (1 << 5u); + static constexpr uint8_t PCF85063_CTRL1_SOFTRST_EN_MASK = (1 << 4u); + static constexpr uint8_t PCF85063_CTRL1_CIE_EN_MASK = (1 << 2u); + static constexpr uint8_t PCF85063_CTRL1_HOUR_FORMAT_12H_MASK = (1 << 1u); - -#define PCF85063_NO_ALARM (0xFF) -#define PCF85063_ALARM_ENABLE (0x80) \ No newline at end of file + // Other constants + static constexpr uint8_t PCF85063_NO_ALARM = 0xFF; + static constexpr uint8_t PCF85063_ALARM_ENABLE = 0x80; +}; \ No newline at end of file diff --git a/src/REG/PCF8563Constants.h b/src/REG/PCF8563Constants.h index 685fc05..89da880 100644 --- a/src/REG/PCF8563Constants.h +++ b/src/REG/PCF8563Constants.h @@ -30,41 +30,50 @@ #pragma once +#include -#define PCF8563_SLAVE_ADDRESS (0x51) -#define PCF8563_STAT1_REG (0x00) -#define PCF8563_STAT2_REG (0x01) -#define PCF8563_SEC_REG (0x02) -#define PCF8563_MIN_REG (0x03) -#define PCF8563_HR_REG (0x04) -#define PCF8563_DAY_REG (0x05) -#define PCF8563_WEEKDAY_REG (0x06) -#define PCF8563_MONTH_REG (0x07) -#define PCF8563_YEAR_REG (0x08) -#define PCF8563_ALRM_MIN_REG (0x09) -#define PCF8563_SQW_REG (0x0D) -#define PCF8563_TIMER1_REG (0x0E) -#define PCF8563_TIMER2_REG (0x0F) +class PCF8563Constants +{ +protected: + // Unique I2C device address + static constexpr uint8_t PCF8563_SLAVE_ADDRESS = 0x51; -#define PCF8563_VOL_LOW_MASK (0x80) -#define PCF8563_MINUTES_MASK (0x7F) -#define PCF8563_HOUR_MASK (0x3F) -#define PCF8563_WEEKDAY_MASK (0x07) -#define PCF8563_CENTURY_MASK (0x80) -#define PCF8563_DAY_MASK (0x3F) -#define PCF8563_MONTH_MASK (0x1F) -#define PCF8563_TIMER_CTL_MASK (0x03) + // Register addresses + static constexpr uint8_t STAT1_REG = 0x00; + static constexpr uint8_t STAT2_REG = 0x01; + static constexpr uint8_t SEC_REG = 0x02; + static constexpr uint8_t MIN_REG = 0x03; + static constexpr uint8_t HR_REG = 0x04; + static constexpr uint8_t DAY_REG = 0x05; + static constexpr uint8_t WEEKDAY_REG = 0x06; + static constexpr uint8_t MONTH_REG = 0x07; + static constexpr uint8_t YEAR_REG = 0x08; + static constexpr uint8_t ALRM_MIN_REG = 0x09; + static constexpr uint8_t SQW_REG = 0x0D; + static constexpr uint8_t TIMER1_REG = 0x0E; + static constexpr uint8_t TIMER2_REG = 0x0F; + // Mask values + static constexpr uint8_t VOL_LOW_MASK = 0x80; + static constexpr uint8_t MINUTES_MASK = 0x7F; + static constexpr uint8_t HOUR_MASK = 0x3F; + static constexpr uint8_t WEEKDAY_MASK = 0x07; + static constexpr uint8_t CENTURY_MASK = 0x80; + static constexpr uint8_t DAY_MASK = 0x3F; + static constexpr uint8_t MONTH_MASK = 0x1F; + static constexpr uint8_t TIMER_CTL_MASK = 0x03; -#define PCF8563_ALARM_AF (0x08) -#define PCF8563_TIMER_TF (0x04) -#define PCF8563_ALARM_AIE (0x02) -#define PCF8563_TIMER_TIE (0x01) -#define PCF8563_TIMER_TE (0x80) -#define PCF8563_TIMER_TD10 (0x03) - -#define PCF8563_NO_ALARM (0xFF) -#define PCF8563_ALARM_ENABLE (0x80) -#define PCF8563_CLK_ENABLE (0x80) + // Alarm and Timer flags + static constexpr uint8_t ALARM_AF = 0x08; + static constexpr uint8_t TIMER_TF = 0x04; + static constexpr uint8_t ALARM_AIE = 0x02; + static constexpr uint8_t TIMER_TIE = 0x01; + static constexpr uint8_t TIMER_TE = 0x80; + static constexpr uint8_t TIMER_TD10 = 0x03; + // Other constants + static constexpr uint8_t NO_ALARM = 0xFF; + static constexpr uint8_t ALARM_ENABLE = 0x80; + static constexpr uint8_t CLK_ENABLE = 0x80; +}; \ No newline at end of file diff --git a/src/REG/QMC6310Constants.h b/src/REG/QMC6310Constants.h index 4f0fcd0..7269eb2 100644 --- a/src/REG/QMC6310Constants.h +++ b/src/REG/QMC6310Constants.h @@ -30,24 +30,30 @@ #pragma once -// @brief device address -#define QMC6310_SLAVE_ADDRESS (0x1C) -#define QMC6310_DEFAULT_ID (0x80) - - -#define QMC6310_REG_CHIP_ID (0x00) -#define QMC6310_REG_LSB_DX (0X01) -#define QMC6310_REG_MSB_DX (0X02) -#define QMC6310_REG_LSB_DY (0X03) -#define QMC6310_REG_MSB_DY (0X04) -#define QMC6310_REG_LSB_DZ (0X05) -#define QMC6310_REG_MSB_DZ (0X06) -#define QMC6310_REG_STAT (0X09) -#define QMC6310_REG_CMD1 (0x0A) -#define QMC6310_REG_CMD2 (0x0B) - - -#define QMC6310_REG_SIGN (0x29) +#include + + + +class QMC6310Constants +{ +protected: + // Unique I2C device address + static constexpr uint8_t QMC6310_SLAVE_ADDRESS = 0x1C; + + // Register addresses + static constexpr uint8_t REG_CHIP_ID = 0x00; + static constexpr uint8_t REG_LSB_DX = 0x01; + static constexpr uint8_t REG_MSB_DX = 0x02; + static constexpr uint8_t REG_LSB_DY = 0x03; + static constexpr uint8_t REG_MSB_DY = 0x04; + static constexpr uint8_t REG_LSB_DZ = 0x05; + static constexpr uint8_t REG_MSB_DZ = 0x06; + static constexpr uint8_t REG_STAT = 0x09; + static constexpr uint8_t REG_CMD1 = 0x0A; + static constexpr uint8_t REG_CMD2 = 0x0B; + static constexpr uint8_t REG_SIGN = 0x29; + static constexpr uint8_t QMC6310_CHIP_ID = 0x80; +}; diff --git a/src/REG/QMI8658Constants.h b/src/REG/QMI8658Constants.h index 5d26077..07c2f46 100644 --- a/src/REG/QMI8658Constants.h +++ b/src/REG/QMI8658Constants.h @@ -29,120 +29,122 @@ */ #pragma once +#include + // @brief device address #define QMI8658_L_SLAVE_ADDRESS (0x6B) #define QMI8658_H_SLAVE_ADDRESS (0x6A) - -// @brief registers default value -#define QMI8658_REG_WHOAMI_DEFAULT (0x05) -#define QMI8658_REG_STATUS_DEFAULT (0x03) -#define QMI8658_REG_RESET_DEFAULT (0xB0) - - -//* General Purpose Registers -#define QMI8658_REG_WHOAMI (0x00) -#define QMI8658_REG_REVISION (0x01) - - -//* Setup and Control Registers -#define QMI8658_REG_CTRL1 (0x02) -#define QMI8658_REG_CTRL2 (0x03) -#define QMI8658_REG_CTRL3 (0x04) -// Reserved (0x05) -#define QMI8658_REG_CTRL5 (0x06) -// Reserved (0x07) -#define QMI8658_REG_CTRL7 (0x08) -#define QMI8658_REG_CTRL8 (0x09) -#define QMI8658_REG_CTRL9 (0x0A) - -//* Host Controlled Calibration Registers (See CTRL9, Usage is Optional) -#define QMI8658_REG_CAL1_L (0x0B) -#define QMI8658_REG_CAL1_H (0x0C) -#define QMI8658_REG_CAL2_L (0x0D) -#define QMI8658_REG_CAL2_H (0x0E) -#define QMI8658_REG_CAL3_L (0x0F) -#define QMI8658_REG_CAL3_H (0x10) -#define QMI8658_REG_CAL4_L (0x11) -#define QMI8658_REG_CAL4_H (0x12) - -//* FIFO Registers -#define QMI8658_REG_FIFO_WTM_TH (0x13) -#define QMI8658_REG_FIFO_CTRL (0x14) -#define QMI8658_REG_FIFO_COUNT (0x15) -#define QMI8658_REG_FIFO_STATUS (0x16) -#define QMI8658_REG_FIFO_DATA (0x17) - -//* Status Registers -#define QMI8658_REG_STATUS_INT (0x2D) -#define QMI8658_REG_STATUS0 (0x2E) -#define QMI8658_REG_STATUS1 (0x2F) - -//* Timestamp Register -#define QMI8658_REG_TIMESTAMP_L (0x30) -#define QMI8658_REG_TIMESTAMP_M (0x31) -#define QMI8658_REG_TIMESTAMP_H (0x32) - -//* Data Output Registers (16 bits 2’s Complement Except COD Sensor Data) -#define QMI8658_REG_TEMPERATURE_L (0x33) -#define QMI8658_REG_TEMPERATURE_H (0x34) -#define QMI8658_REG_AX_L (0x35) -#define QMI8658_REG_AX_H (0x36) -#define QMI8658_REG_AY_L (0x37) -#define QMI8658_REG_AY_H (0x38) -#define QMI8658_REG_AZ_L (0x39) -#define QMI8658_REG_AZ_H (0x3A) -#define QMI8658_REG_GX_L (0x3B) -#define QMI8658_REG_GX_H (0x3C) -#define QMI8658_REG_GY_L (0x3D) -#define QMI8658_REG_GY_H (0x3E) -#define QMI8658_REG_GZ_L (0x3F) -#define QMI8658_REG_GZ_H (0x40) - -//* COD Indication and General Purpose Registers - -// Calibration-On-Demand status register -#define QMI8658_REG_COD_STATUS (0x46) -#define QMI8658_REG_DQW_L (0x49) -#define QMI8658_REG_DQW_H (0x4A) -#define QMI8658_REG_DQX_L (0x4B) -#define QMI8658_REG_DQX_H (0x4C) - -#define QMI8658_REG_DQY_L (0x4D) -#define QMI8658_REG_DQY_H (0x4E) -#define QMI8658_REG_DQZ_L (0x4F) -#define QMI8658_REG_DQZ_H (0x50) - -#define QMI8658_REG_DVX_L (0x51) -#define QMI8658_REG_DVX_H (0x52) -#define QMI8658_REG_DVY_L (0x53) -#define QMI8658_REG_DVY_H (0x54) -#define QMI8658_REG_DVZ_L (0x55) -#define QMI8658_REG_DVZ_H (0x56) - -//* Activity Detection Output Registers -#define QMI8658_REG_TAP_STATUS (0x59) -#define QMI8658_REG_STEP_CNT_LOW (0x5A) -#define QMI8658_REG_STEP_CNT_MID (0x5B) -#define QMI8658_REG_STEP_CNT_HIGH (0x5C) -#define QMI8658_REG_RESET (0x60) - -//* Reset Register -#define QMI8658_REG_RST_RESULT (0x4D) -#define QMI8658_REG_RST_RESULT_VAL (0x80) - -#define STATUS0_ACCEL_AVAIL (0x01) -#define STATUS0_GYRO_AVAIL (0x02) -#define QMI8658_ACCEL_LPF_MASK (0xF9) -#define QMI8658_GYRO_LPF_MASK (0x9F) - - - - - -#define QMI8658_ACCEL_EN_MASK (0x01) -#define QMI8658_GYRO_EN_MASK (0x02) -#define QMI8658_ACCEL_GYRO_EN_MASK (0x03) - - -#define QMI8658_FIFO_MAP_INT1 0x04 // ctrl1 +class QMI8658Constants +{ +protected: + + // @brief registers default value + static constexpr uint8_t QMI8658_REG_WHOAMI_DEFAULT = 0x05; + static constexpr uint8_t QMI8658_REG_STATUS_DEFAULT = 0x03; + static constexpr uint8_t QMI8658_REG_RESET_DEFAULT = 0xB0; + + + //* General Purpose Registers + static constexpr uint8_t QMI8658_REG_WHOAMI = 0x00; + static constexpr uint8_t QMI8658_REG_REVISION = 0x01; + + + //* Setup and Control Registers + static constexpr uint8_t QMI8658_REG_CTRL1 = 0x02; + static constexpr uint8_t QMI8658_REG_CTRL2 = 0x03; + static constexpr uint8_t QMI8658_REG_CTRL3 = 0x04; + // Reserved + static constexpr uint8_t QMI8658_REG_CTRL5 = 0x06; + // Reserved + static constexpr uint8_t QMI8658_REG_CTRL7 = 0x08; + static constexpr uint8_t QMI8658_REG_CTRL8 = 0x09; + static constexpr uint8_t QMI8658_REG_CTRL9 = 0x0A; + + //* Host Controlled Calibration Registers (See CTRL9, Usage is Optional) + static constexpr uint8_t QMI8658_REG_CAL1_L = 0x0B; + static constexpr uint8_t QMI8658_REG_CAL1_H = 0x0C; + static constexpr uint8_t QMI8658_REG_CAL2_L = 0x0D; + static constexpr uint8_t QMI8658_REG_CAL2_H = 0x0E; + static constexpr uint8_t QMI8658_REG_CAL3_L = 0x0F; + static constexpr uint8_t QMI8658_REG_CAL3_H = 0x10; + static constexpr uint8_t QMI8658_REG_CAL4_L = 0x11; + static constexpr uint8_t QMI8658_REG_CAL4_H = 0x12; + + //* FIFO Registers + static constexpr uint8_t QMI8658_REG_FIFO_WTM_TH = 0x13; + static constexpr uint8_t QMI8658_REG_FIFO_CTRL = 0x14; + static constexpr uint8_t QMI8658_REG_FIFO_COUNT = 0x15; + static constexpr uint8_t QMI8658_REG_FIFO_STATUS = 0x16; + static constexpr uint8_t QMI8658_REG_FIFO_DATA = 0x17; + + //* Status Registers + static constexpr uint8_t QMI8658_REG_STATUS_INT = 0x2D; + static constexpr uint8_t QMI8658_REG_STATUS0 = 0x2E; + static constexpr uint8_t QMI8658_REG_STATUS1 = 0x2F; + + //* Timestamp Register + static constexpr uint8_t QMI8658_REG_TIMESTAMP_L = 0x30; + static constexpr uint8_t QMI8658_REG_TIMESTAMP_M = 0x31; + static constexpr uint8_t QMI8658_REG_TIMESTAMP_H = 0x32; + + //* Data Output Registers (16 bits 2’s Complement Except COD Sensor Data) + static constexpr uint8_t QMI8658_REG_TEMPERATURE_L = 0x33; + static constexpr uint8_t QMI8658_REG_TEMPERATURE_H = 0x34; + static constexpr uint8_t QMI8658_REG_AX_L = 0x35; + static constexpr uint8_t QMI8658_REG_AX_H = 0x36; + static constexpr uint8_t QMI8658_REG_AY_L = 0x37; + static constexpr uint8_t QMI8658_REG_AY_H = 0x38; + static constexpr uint8_t QMI8658_REG_AZ_L = 0x39; + static constexpr uint8_t QMI8658_REG_AZ_H = 0x3A; + static constexpr uint8_t QMI8658_REG_GX_L = 0x3B; + static constexpr uint8_t QMI8658_REG_GX_H = 0x3C; + static constexpr uint8_t QMI8658_REG_GY_L = 0x3D; + static constexpr uint8_t QMI8658_REG_GY_H = 0x3E; + static constexpr uint8_t QMI8658_REG_GZ_L = 0x3F; + static constexpr uint8_t QMI8658_REG_GZ_H = 0x40; + + //* COD Indication and General Purpose Registers + + // Calibration-On-Demand status register + static constexpr uint8_t QMI8658_REG_COD_STATUS = 0x46; + static constexpr uint8_t QMI8658_REG_DQW_L = 0x49; + static constexpr uint8_t QMI8658_REG_DQW_H = 0x4A; + static constexpr uint8_t QMI8658_REG_DQX_L = 0x4B; + static constexpr uint8_t QMI8658_REG_DQX_H = 0x4C; + + static constexpr uint8_t QMI8658_REG_DQY_L = 0x4D; + static constexpr uint8_t QMI8658_REG_DQY_H = 0x4E; + static constexpr uint8_t QMI8658_REG_DQZ_L = 0x4F; + static constexpr uint8_t QMI8658_REG_DQZ_H = 0x50; + + static constexpr uint8_t QMI8658_REG_DVX_L = 0x51; + static constexpr uint8_t QMI8658_REG_DVX_H = 0x52; + static constexpr uint8_t QMI8658_REG_DVY_L = 0x53; + static constexpr uint8_t QMI8658_REG_DVY_H = 0x54; + static constexpr uint8_t QMI8658_REG_DVZ_L = 0x55; + static constexpr uint8_t QMI8658_REG_DVZ_H = 0x56; + + //* Activity Detection Output Registers + static constexpr uint8_t QMI8658_REG_TAP_STATUS = 0x59; + static constexpr uint8_t QMI8658_REG_STEP_CNT_LOW = 0x5A; + static constexpr uint8_t QMI8658_REG_STEP_CNT_MID = 0x5B; + static constexpr uint8_t QMI8658_REG_STEP_CNT_HIGH = 0x5C; + static constexpr uint8_t QMI8658_REG_RESET = 0x60; + + //* Reset Register + static constexpr uint8_t QMI8658_REG_RST_RESULT = 0x4D; + static constexpr uint8_t QMI8658_REG_RST_RESULT_VAL = 0x80; + + static constexpr uint8_t STATUS0_ACCEL_AVAIL = 0x01; + static constexpr uint8_t STATUS0_GYRO_AVAIL = 0x02; + static constexpr uint8_t QMI8658_ACCEL_LPF_MASK = 0xF9; + static constexpr uint8_t QMI8658_GYRO_LPF_MASK = 0x9F; + + static constexpr uint8_t QMI8658_ACCEL_EN_MASK = 0x01; + static constexpr uint8_t QMI8658_GYRO_EN_MASK = 0x02; + static constexpr uint8_t QMI8658_ACCEL_GYRO_EN_MASK = 0x03; + + + static constexpr uint8_t QMI8658_FIFO_MAP_INT1 = 0x04; // ctrl1 +}; \ No newline at end of file diff --git a/src/REG/XL9555Constants.h b/src/REG/XL9555Constants.h index 7061e41..e24baac 100644 --- a/src/REG/XL9555Constants.h +++ b/src/REG/XL9555Constants.h @@ -1,5 +1,36 @@ +/** + * + * @license MIT License + * + * Copyright (c) 2025 lewis he + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * @file XL9555Constants.h + * @author Lewis He (lewishe@outlook.com) + * @date 2025-01-17 + * + */ #pragma once +#include + // A0, A1, A2 connect to GND #define XL9555_UNKOWN_ADDRESS (0xFF) #define XL9555_SLAVE_ADDRESS0 (0x20) @@ -11,23 +42,17 @@ #define XL9555_SLAVE_ADDRESS6 (0x26) #define XL9555_SLAVE_ADDRESS7 (0x27) -// Input Port 0 /R -#define XL9555_CTRL_INP0 (0x00) -// Input Port 1 /R -#define XL9555_CTRL_INP1 (0x01) -// Output Port 0 /RW -#define XL9555_CTRL_OUTP0 (0x02) -// Output Port 1 /RW -#define XL9555_CTRL_OUTP1 (0x03) -// Polarity Inversion Port 0 /RW -#define XL9555_CTRL_PIP0 (0x04) -// Polarity Inversion Port 1 /RW -#define XL9555_CTRL_PIP1 (0x05) -// Configuration Port 0 /RW -#define XL9555_CTRL_CFG0 (0x06) -// Configuration Port 1 /RW -#define XL9555_CTRL_CFG1 (0x07) - -#define XL9555_MAX_PIN (15) - +class XL95xxConstants +{ +protected: + static constexpr uint8_t XL9555_CTRL_INP0 = (0x00); // Input Port 0 /R + static constexpr uint8_t XL9555_CTRL_INP1 = (0x01); // Input Port 1 /R + static constexpr uint8_t XL9555_CTRL_OUTP0 = (0x02); // Output Port 0 /RW + static constexpr uint8_t XL9555_CTRL_OUTP1 = (0x03); // Output Port 1 /RW + static constexpr uint8_t XL9555_CTRL_PIP0 = (0x04); // Polarity Inversion Port 0 /RW + static constexpr uint8_t XL9555_CTRL_PIP1 = (0x05); // Polarity Inversion Port 1 /RW + static constexpr uint8_t XL9555_CTRL_CFG0 = (0x06); // Configuration Port 0 /RW + static constexpr uint8_t XL9555_CTRL_CFG1 = (0x07); // Configuration Port 1 /RW + static constexpr uint8_t XL9555_MAX_PIN = (15); +}; diff --git a/src/SensorBHI260AP.cpp b/src/SensorBHI260AP.cpp index 2017065..267b4b3 100644 --- a/src/SensorBHI260AP.cpp +++ b/src/SensorBHI260AP.cpp @@ -29,8 +29,952 @@ */ #include "SensorBHI260AP.hpp" +static constexpr uint16_t max_process_buffer_size = 512; + +SensorBHI260AP::SensorBHI260AP(): comm(nullptr), + hal(nullptr), + staticComm(nullptr), + _rst(-1), _error_code(0), + _processBuffer(nullptr), + _processBufferSize(max_process_buffer_size), + _firmware_stream(nullptr), + _firmware_size(0), + _write_flash(false), + _boot_from_flash(false), + _force_update(false), + _max_rw_length(-1), + _accuracy(0), + _debug(false) +{ +} + +SensorBHI260AP::~SensorBHI260AP() +{ + if (_processBuffer) { + free(_processBuffer); + } + _processBuffer = NULL; +} + +void SensorBHI260AP::setPins(int rst) +{ + _rst = rst; +} + #if defined(ARDUINO) -volatile bool SensorBHI260AP::__data_available; +bool SensorBHI260AP::begin(TwoWire &wire, uint8_t addr, int sda, int scl) +{ + if (!beginCommonStatic(comm, staticComm, hal, wire, addr, sda, scl)) { + return false; + } + return initImpl(BHY2_I2C_INTERFACE); +} + +bool SensorBHI260AP::begin(SPIClass &spi, uint8_t csPin, int mosi, int miso, int sck) +{ + if (!beginCommonStatic(comm, + staticComm, hal, + spi, csPin, mosi, miso, sck)) { + return false; + } + return initImpl(BHY2_SPI_INTERFACE); +} + +#elif defined(ESP_PLATFORM) + +#if defined(USEING_I2C_LEGACY) +bool SensorBHI260AP::begin(i2c_port_t port_num, uint8_t addr, int sda, int scl) +{ + if (!beginCommonStatic(comm, staticComm, hal, port_num, addr, sda, scl)) { + return false; + } + return initImpl(BHY2_I2C_INTERFACE); +} +#else //USEING_I2C_LEGACY +bool SensorBHI260AP::begin(i2c_master_bus_handle_t handle, uint8_t addr) +{ + if (!beginCommonStatic(comm, staticComm, hal, handle, addr)) { + return false; + } + return initImpl(BHY2_I2C_INTERFACE); +} +#endif //USEING_I2C_LEGACY + + +bool SensorBHI260AP::begin(spi_host_device_t host, spi_device_handle_t handle, uint8_t csPin, int mosi, int miso, int sck) +{ + if (!beginCommonStatic(comm, + staticComm, hal, + host, handle, csPin, mosi, miso, sck)) { + return false; + } + return initImpl(BHY2_SPI_INTERFACE); +} + +#endif //ARDUINO + +bool SensorBHI260AP::begin(CommInterface interface, + SensorCommCustom::CustomCallback callback, + SensorCommCustomHal::CustomHalCallback hal_callback, + uint8_t addr) +{ + if (!beginCommCustomCallback(interface, + callback, hal_callback, addr, comm, hal)) { + return false; + } + return initImpl(static_cast(interface)); +} + +/** + * @brief reset + * @note Reset sensor + * @retval None + */ +void SensorBHI260AP::reset() +{ + if (_rst != -1) { + hal->digitalWrite(_rst, HIGH); + hal->delay(5); + hal->digitalWrite(_rst, LOW); + hal->delay(10); + hal->digitalWrite(_rst, HIGH); + hal->delay(5); + } +} + +/** + * @brief update + * @note Update sensor fifo data + * @retval None + */ +void SensorBHI260AP::update() +{ + if (!_processBuffer) { + log_e("Process buffer is empty."); + return; + } + bhy2_get_and_process_fifo(_processBuffer, _processBufferSize, _bhy2.get()); +} + +/** + * @brief setBootFromFlash + * @note Set whether to start from external flash + * @param boot_from_flash: true boot form flash or boot form ram + * @retval None + */ +void SensorBHI260AP::setBootFromFlash(bool boot_from_flash) +{ + _boot_from_flash = boot_from_flash; +} + +/** + * @brief getHandler + * @note Get the native BHI API handle + * @retval handle + */ +bhy2_dev *SensorBHI260AP::getHandler() +{ + return _bhy2.get(); +} + +/** + * @brief setInterruptCtrl + * @note Set the interrupt control mask + * @param data: + * BHY2_ICTL_DISABLE_FIFO_W + * BHY2_ICTL_DISABLE_FIFO_NW + * BHY2_ICTL_DISABLE_STATUS_FIFO + * BHY2_ICTL_DISABLE_DEBUG + * BHY2_ICTL_DISABLE_FAULT + * BHY2_ICTL_ACTIVE_LOW + * BHY2_ICTL_EDGE + * BHY2_ICTL_OPEN_DRAIN + * + * @retval true is success , false is failed + */ +bool SensorBHI260AP::setInterruptCtrl(uint8_t data) +{ + _error_code = bhy2_set_host_interrupt_ctrl(data, _bhy2.get()); + if (_error_code != BHY2_OK) { + return false; + } + return true; +} + +/** + * @brief getInterruptCtrl + * @note Get interrupt control info + * @retval SensorBHI260APCtrl class + */ +SensorBHI260APControl SensorBHI260AP::getInterruptCtrl() +{ + uint8_t data; + _error_code = bhy2_get_host_interrupt_ctrl(&data, _bhy2.get()); + SensorBHI260APControl result; + if (_error_code == BHY2_OK) { + result.wakeUpFIFOEnabled = !(data & BHY2_ICTL_DISABLE_FIFO_W); + result.nonWakeUpFIFOEnabled = !(data & BHY2_ICTL_DISABLE_FIFO_NW); + result.statusFIFOEnabled = !(data & BHY2_ICTL_DISABLE_STATUS_FIFO); + result.debuggingEnabled = !(data & BHY2_ICTL_DISABLE_DEBUG); + result.faultEnabled = !(data & BHY2_ICTL_DISABLE_FAULT); + result.interruptIsActiveLow = (data & BHY2_ICTL_ACTIVE_LOW); + result.interruptIsPulseTriggered = (data & BHY2_ICTL_EDGE); + result.interruptPinDriveIsOpenDrain = (data & BHY2_ICTL_OPEN_DRAIN); + } + return result; +} + + +/** + * @brief isReady + * @note Query whether the sensor is ready + * @retval 1 OK , 0 Not ready + */ +bool SensorBHI260AP::isReady() +{ + uint8_t boot_status = 0; + _error_code = bhy2_get_boot_status(&boot_status, _bhy2.get()); + log_d("boot_status:0x%x", boot_status); + if (_error_code != BHY2_OK) { + return false; + } + return (boot_status & BHY2_BST_HOST_INTERFACE_READY); +} + +/** + * @brief getKernelVersion + * @note Get the sensor firmware kernel version + * @retval 2 bytes + */ +uint16_t SensorBHI260AP::getKernelVersion() +{ + uint16_t version = 0; + _error_code = bhy2_get_kernel_version(&version, _bhy2.get()); + if ((_error_code != BHY2_OK) && (version == 0)) { + return 0; + } + log_d("Boot successful. Kernel version %u.", version); + return version; +} + + +/** + * @brief onEvent + * @note Registered sensor event callback function + * @param callback: Callback Function + * @retval None + */ +void SensorBHI260AP::onEvent(BhyEventCb callback) +{ + BoschParse::_event_callback = callback; +} + +/** + * @brief removeEvent + * @note Remove sensor event callback function + * @retval None + */ +void SensorBHI260AP::removeEvent() +{ + BoschParse::_event_callback = NULL; +} + +/** + * @brief onResultEvent + * @note Registered sensor result callback function , The same sensor ID can register multiple event callbacks. + * Please note that you should not register the same event callback repeatedly. + * @param sensor_id: Sensor ID , see enum BhySensorID + * @param callback: Callback Function + * @retval None + */ +void SensorBHI260AP::onResultEvent(BhySensorID sensor_id, BhyParseDataCallback callback) +{ +#ifdef USE_STD_VECTOR + ParseCallBackList_t newEventHandler; + newEventHandler.cb = callback; + newEventHandler.id = sensor_id; + BoschParse::bhyParseEventVector.push_back(newEventHandler); +#else + if (BoschParse::BoschParse_bhyParseEventVectorSize == BoschParse::BoschParse_bhyParseEventVectorCapacity) { + BoschParse::expandParseEventVector(); + } + ParseCallBackList_t newEventHandler; + newEventHandler.cb = callback; + newEventHandler.id = sensor_id; + BoschParse::BoschParse_bhyParseEventVector[BoschParse::BoschParse_bhyParseEventVectorSize++] = newEventHandler; +#endif +} + +/** + * @brief removeResultEvent + * @note Remove the registered result callback function + * @param sensor_id: Sensor ID , see enum BhySensorID + * @param callback: Callback Function + * @retval None + */ +void SensorBHI260AP::removeResultEvent(BhySensorID sensor_id, BhyParseDataCallback callback) +{ + if (!callback) { + return; + } +#ifdef USE_STD_VECTOR + for (uint32_t i = 0; i < BoschParse::bhyParseEventVector.size(); i++) { + ParseCallBackList_t entry = BoschParse::bhyParseEventVector[i]; + if (entry.cb == callback && entry.id == sensor_id) { + BoschParse::bhyParseEventVector.erase(BoschParse::bhyParseEventVector.begin() + i); + } + } +#else + for (uint32_t i = 0; i < BoschParse::BoschParse_bhyParseEventVectorSize; i++) { + ParseCallBackList_t entry = BoschParse::BoschParse_bhyParseEventVector[i]; + if (entry.cb == callback && entry.id == sensor_id) { + for (uint32_t j = i; j < BoschParse::BoschParse_bhyParseEventVectorSize - 1; j++) { + BoschParse::BoschParse_bhyParseEventVector[j] = BoschParse::BoschParse_bhyParseEventVector[j + 1]; + } + BoschParse::BoschParse_bhyParseEventVectorSize--; + break; + } + } +#endif +} + +/** + * @brief setProcessBufferSize + * @note The default value is 512Bytes , Must be called before initialization + * @param size: The set buffer size is requested by malloc, and if PSRAM is enabled, it is requested from PSRAM + * @retval None + */ +void SensorBHI260AP::setProcessBufferSize(uint32_t size) +{ + if (_processBuffer) { + log_e("The buffer size must be set before begin"); + return; + } + _processBufferSize = size; +} + +/** + * @brief uploadFirmware + * @note Update BHI sensor firmware + * @param *firmware: Firmware data address + * @param length: Firmware data length + * @param write2Flash: 1 is written to external flash, 0 is written to RAM + * @retval true success or failed + */ +bool SensorBHI260AP::uploadFirmware(const uint8_t *firmware, uint32_t length, bool write2Flash) +{ + uint8_t sensor_error; + uint8_t boot_status; + + log_d("Upload Firmware ..."); + + _error_code = bhy2_get_boot_status(&boot_status, _bhy2.get()); + BHY2_RLST_CHECK(_error_code != BHY2_OK, "bhy2_get_boot_status failed!", false); + + if (write2Flash) { + if (boot_status & BHY2_BST_FLASH_DETECTED) { + uint32_t start_addr = BHY2_FLASH_SECTOR_START_ADDR; + uint32_t end_addr = start_addr + length; + log_d("Flash detected. Erasing flash to upload firmware"); + _error_code = bhy2_erase_flash(start_addr, end_addr, _bhy2.get()); + BHY2_RLST_CHECK(_error_code != BHY2_OK, "bhy2_erase_flash failed!", false); + } else { + log_e("Flash not detected"); + return false; + } + log_d("Loading firmware into FLASH."); + _error_code = bhy2_upload_firmware_to_flash(firmware, length, _bhy2.get()); + BHY2_RLST_CHECK(_error_code != BHY2_OK, "bhy2_upload_firmware_to_flash failed!", false); + log_d("Loading firmware into FLASH Done"); + } else { + log_d("Loading firmware into RAM."); + log_d("upload size = %lu", length); + _error_code = bhy2_upload_firmware_to_ram(firmware, length, _bhy2.get()); + BHY2_RLST_CHECK(_error_code != BHY2_OK, "bhy2_upload_firmware_to_ram failed!", false); + log_d("Loading firmware into RAM Done"); + } + + _error_code = bhy2_get_error_value(&sensor_error, _bhy2.get()); + BHY2_RLST_CHECK(_error_code != BHY2_OK, "bhy2_get_error_value failed!", false); + if (sensor_error != BHY2_OK) { + _error_code = bhy2_get_error_value(&sensor_error, _bhy2.get()); + log_e("%s", get_sensor_error_text(sensor_error)); + return false; + } + + + if (write2Flash) { + log_d("Booting from FLASH."); + _error_code = bhy2_boot_from_flash(_bhy2.get()); + } else { + log_d("Booting from RAM."); + _error_code = bhy2_boot_from_ram(_bhy2.get()); + } + BHY2_RLST_CHECK(_error_code != BHY2_OK, "_bhy2 boot failed!", false); + + _error_code = bhy2_get_error_value(&sensor_error, _bhy2.get()); + if (sensor_error) { + log_e("%s", get_sensor_error_text(sensor_error)); + return false; + } + return sensor_error == BHY2_OK; +} + + +/** + * @brief getError + * @note Get the error status string + * @retval string + */ +const char *SensorBHI260AP::getError() +{ + snprintf(_err_buffer, 128, "API:%s\nSensor:%s\n", get_api_error(_error_code), get_sensor_error_text(_error_code)); + return static_cast(_err_buffer); +} + +/** + * @brief configure + * @note Sensor Configuration + * @param sensor_id: Sensor ID , see enum BhySensorID + * @param sample_rate: Data output rate, unit: HZ + * @param report_latency_ms: Report interval in milliseconds + * @return bool true-> Success false-> failure + */ +bool SensorBHI260AP::configure(uint8_t sensor_id, float sample_rate, uint32_t report_latency_ms) +{ + if (!bhy2_is_sensor_available(sensor_id, _bhy2.get())) { + log_e("Sensor not present"); return false; + } + _error_code = bhy2_set_virt_sensor_cfg(sensor_id, sample_rate, report_latency_ms, _bhy2.get()); + BHY2_RLST_CHECK(_error_code != BHY2_OK, "bhy2_set_virt_sensor_cfg failed!", false); + log_d("Enable %s at %.2fHz.", get_sensor_name(sensor_id), sample_rate); + return true; +} + +/** + * @brief configureRange + * @note Set range of the sensor + * @param sensor_id: Sensor ID , see enum BhySensorID + * @param range: Range for selected SensorID. See Table 79 in BHY260 datasheet 109 page + * @retval bool true-> Success false-> failure + */ +bool SensorBHI260AP::configureRange(uint8_t sensor_id, uint16_t range) +{ + _error_code = bhy2_set_virt_sensor_range(sensor_id, range, _bhy2.get()); + BHY2_RLST_CHECK(_error_code != BHY2_OK, "bhy2_set_virt_sensor_range failed!", false); + return true; +} + + +/** + * @brief getConfigure + * @note Get sensor configuration + * @param sensor_id: Sensor ID , see enum BhySensorID + * @retval struct bhy2_virt_sensor_conf + */ +struct bhy2_virt_sensor_conf SensorBHI260AP::getConfigure(uint8_t sensor_id) +{ + bhy2_virt_sensor_conf conf; + bhy2_get_virt_sensor_cfg(sensor_id, &conf, _bhy2.get()); + log_d("range:%u sample_rate:%f latency:%lu sensitivity:%u\n", conf.range, conf.sample_rate, conf.latency, conf.sensitivity); + return conf; +} + +/** + * @brief getScaling + * @note Get sensor scale factor + * @param sensor_id: Sensor ID , see enum BhySensorID + * @retval scale factor + */ +float SensorBHI260AP::getScaling(uint8_t sensor_id) +{ + return get_sensor_default_scaling(sensor_id); +} + +/** + * @brief setFirmware + * @note Set the firmware + * @param *image: firmware data address + * @param image_len: firmware length + * @param write_flash: true : write to flash otherwise ram + * @param force_update: true, rewrite to flash or ram regardless of whether there is firmware, false, do not write if firmware is detected + * @retval None + */ +void SensorBHI260AP::setFirmware(const uint8_t *image, size_t image_len, bool write_flash, bool force_update) +{ + _firmware_stream = image; + _firmware_size = image_len; + _write_flash = write_flash; + _force_update = force_update; +} + +/** + * @brief getSensorName + * @note Get sensor name + * @param sensor_id: Sensor ID , see enum BhySensorID + * @retval sensor name + */ +const char *SensorBHI260AP::getSensorName(uint8_t sensor_id) +{ + return get_sensor_name(sensor_id); +} + +// Get an accuracy report +uint8_t SensorBHI260AP::getAccuracy() +{ + return _accuracy; +} + +/** + * @brief digitalRead + * @note Read GPIO level, only for custom firmware + * @param pin: see BHI260AP_aux_BMM150_BME280_Expand_GPIO example + * @param pullup: true is set pullup or input mode + * @retval 1 is high ,0 is low + */ +uint8_t SensorBHI260AP::digitalRead(uint8_t pin, bool pullup) +{ + if (pin > JTAG_DIO)return 0; + uint32_t pin_mask = pin | BHY2_GPIO_SET; + if (pullup) { + pin_mask |= (BHY2_INPUT_PULLUP << 8); + } else { + pin_mask |= (BHY2_INPUT << 8); + } + bhy2_set_virt_sensor_cfg(SENSOR_ID_GPIO_EXP, (float)pin_mask, 0, _bhy2.get()); + pin_mask = pin /*GetCmd*/; + bhy2_set_virt_sensor_cfg(SENSOR_ID_GPIO_EXP, (float)pin_mask, 0, _bhy2.get()); + bhy2_virt_sensor_conf conf; + bhy2_get_virt_sensor_cfg(SENSOR_ID_GPIO_EXP, &conf, _bhy2.get()); + uint8_t level = conf.sample_rate; + return level; +} + +/** + * @brief hal->digitalWrite + * @note Write GPIO level, only for custom firmware + * @param pin: see BHI260AP_aux_BMM150_BME280_Expand_GPIO example + * @param level: 1 is high ,0 is low + * @retval None + */ +void SensorBHI260AP::digitalWrite(uint8_t pin, uint8_t level) +{ + if (pin > JTAG_DIO)return; + uint32_t pin_mask = pin | (BHY2_OUTPUT << 8) | (level << 6) | BHY2_GPIO_SET ; + bhy2_set_virt_sensor_cfg(SENSOR_ID_GPIO_EXP, (float)pin_mask, 0, _bhy2.get()); +} + +/** + * @brief disableGpio + * @note Disable GPIO function + * @param pin: see BHI260AP_aux_BMM150_BME280_Expand_GPIO example + * @retval None + */ +void SensorBHI260AP::disableGpio(uint8_t pin) +{ + if (pin > JTAG_DIO)return; + uint32_t pin_mask = pin | (BHY2_OPEN_DRAIN << 8) | BHY2_GPIO_SET; + bhy2_set_virt_sensor_cfg(SENSOR_ID_GPIO_EXP, (float)pin_mask, 0, _bhy2.get()); +} + +/** + * @brief setDebugKernel + * @note Whether to enable chip debug output , Must be called before begin, otherwise it will be invalid + * @param enable: true Enable message debug , false disable debug , Requires firmware support, the default firmware will not output any messages + * @retval None + */ +void SensorBHI260AP::setDebugKernel(bool enable) +{ + _debug = enable; +} + +/** + * @brief setDebugCallback + * @param cb: Sensor debug output callback function , Requires firmware support, the default firmware will not output any messages + * @retval None + */ +void SensorBHI260AP::setDebugCallback(BhyDebugMessageCallback cb) +{ + BoschParse::_debug_callback = cb; +} + + +/** + * @brief getPhySensorInfo + * @note Get all information about physical sensors + * @param sens_id: ID of the physical sensor + * @retval BoschPhySensorInfo Class + */ +#define INT4_TO_INT8(INT4) ((int8_t)(((INT4) > 1) ? -1 : (INT4))) + +BoschPhySensorInfo SensorBHI260AP::getPhySensorInfo(uint8_t sens_id) +{ + BoschPhySensorInfo result; + + struct bhy2_phys_sensor_info psi; + + memset(&psi, 0, sizeof(psi)); + + if (!_bhy2.get()) return result; + + uint16_t param_id = (uint16_t)(0x0120 | sens_id); + if (param_id >= 0x0121 && param_id <= 0x0160) { + int8_t assert_rslt = (bhy2_get_phys_sensor_info(sens_id, &psi, _bhy2.get())); + if (assert_rslt == BHY2_OK) { + result.sensor_type = psi.sensor_type; + result.driver_id = psi.driver_id; + result.driver_version = psi.driver_version; + result.power_current = psi.power_current / 10.f; + result.curr_range = psi.curr_range.u16_val; + result.irq_status = psi.flags & 0x01; + result.master_intf = (psi.flags >> 1) & 0x0F; + result.power_mode = (psi.flags >> 5) & 0x07; + result.slave_address = psi.slave_address; + result.gpio_assignment = psi.gpio_assignment; + result.curr_rate = psi.curr_rate.f_val; + result.num_axis = psi.num_axis; + struct bhy2_orient_matrix ort_mtx = { 0 }; + + ort_mtx.c[0] = INT4_TO_INT8(psi.orientation_matrix[0] & 0x0F); + ort_mtx.c[1] = INT4_TO_INT8(psi.orientation_matrix[0] >> 8); + ort_mtx.c[2] = INT4_TO_INT8(psi.orientation_matrix[1] & 0x0F); + ort_mtx.c[3] = INT4_TO_INT8(psi.orientation_matrix[1] >> 8); + ort_mtx.c[4] = INT4_TO_INT8(psi.orientation_matrix[2] & 0x0F); + ort_mtx.c[5] = INT4_TO_INT8(psi.orientation_matrix[2] >> 8); + ort_mtx.c[6] = INT4_TO_INT8(psi.orientation_matrix[3] & 0x0F); + ort_mtx.c[7] = INT4_TO_INT8(psi.orientation_matrix[3] >> 8); + ort_mtx.c[8] = INT4_TO_INT8(psi.orientation_matrix[4] & 0x0F); + for (int i = 0; i < 9; ++i) { + result.orientation_matrix[i] = ort_mtx.c[i]; + } + result.reserved = psi.reserved; + } + } + return result; +} + +/** + * @brief getSensorInfo + * @note Get all information about sensors + * @retval BoschSensorInfo Class + */ +BoschSensorInfo SensorBHI260AP::getSensorInfo() +{ + BoschSensorInfo sensorInfo; + if (bhy2_get_product_id(&sensorInfo.product_id, _bhy2.get()) != BHY2_OK) { + log_e("bhy2_get_product_id failed!"); + } + if (bhy2_get_kernel_version(&sensorInfo.kernel_version, _bhy2.get()) != BHY2_OK) { + log_e("bhy2_get_kernel_version failed!"); + } + if (bhy2_get_user_version(&sensorInfo.user_version, _bhy2.get()) != BHY2_OK) { + log_e("bhy2_get_user_version failed!"); + } + if (bhy2_get_rom_version(&sensorInfo.rom_version, _bhy2.get()) != BHY2_OK) { + log_e("bhy2_get_rom_version failed!"); + } + if (bhy2_get_host_status(&sensorInfo.host_status, _bhy2.get()) != BHY2_OK) { + log_e("bhy2_get_host_status failed!"); + } + if (bhy2_get_feature_status(&sensorInfo.feat_status, _bhy2.get()) != BHY2_OK) { + log_e("bhy2_get_feature_status failed!"); + } + if (bhy2_get_boot_status(&sensorInfo.boot_status, _bhy2.get()) != BHY2_OK) { + log_e("bhy2_get_boot_status failed!"); + } + if (bhy2_get_error_value(&sensorInfo.sensor_error, _bhy2.get()) != BHY2_OK) { + log_e("bhy2_get_error_value failed!"); + } + for (uint8_t i = 0; i < BHY2_SENSOR_ID_MAX; i++) { + if (bhy2_is_sensor_available(i, _bhy2.get())) { + if (bhy2_get_sensor_info(i, &sensorInfo.info[i], _bhy2.get()) != BHY2_OK) { + log_e("bhy2_get_sensor_info [%u] failed!", i); + } + } + } + sensorInfo.dev = _bhy2.get(); + return sensorInfo; +} + + +/** + * @brief setMaxiTransferSize + * @note Set the maximum number of bytes transmitted by the interface , Called before begin + * @param size_of_bytes: The maximum transmission bytes of different platforms are different. + * Set it according to the platform. If not set, the default is 32 bytes. + * @retval None + */ +void SensorBHI260AP::setMaxiTransferSize(uint16_t size_of_bytes) +{ + if (_processBuffer) { + log_e("Must be called before begin"); + return; + } + _max_rw_length = size_of_bytes; +} + +/** + * @brief bootFromFlash + * @note Boot from external flash + * @retval bool true-> Success false-> failure + */ +bool SensorBHI260AP::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.get()); + BHY2_RLST_CHECK(_error_code != BHY2_OK, "bhy2_get_boot_status failed!", false); + if (boot_status & BHY2_BST_FLASH_VERIFY_DONE) { + break; + } + hal->delay(10); + } while (tries--); + + _error_code = bhy2_get_boot_status(&boot_status, _bhy2.get()); + 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.get()); + 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.get()); + 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.get()); + 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.get()); + BHY2_RLST_CHECK(_error_code != BHY2_OK, "bhy2_soft_reset failed!", false); + } + + _error_code = (bhy2_get_feature_status(&feat_status, _bhy2.get())); + 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 SensorBHI260AP::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. "); + } +} + +bool SensorBHI260AP::initImpl(bhy2_intf interface) +{ + uint8_t product_id = 0; + + if (_rst != -1) { + hal->pinMode(_rst, OUTPUT); + } + + reset(); + + _bhy2 = std::make_unique(); + BHY2_RLST_CHECK(!_bhy2, " Device handler malloc failed!", false); + + if (_max_rw_length == -1) { + +#if defined(ARDUINO_ARCH_ESP32) + switch (interface) { + case BHY2_I2C_INTERFACE: + // esp32s3 test I2C maximum read and write is 64 bytes + _max_rw_length = 64; + break; + case BHY2_SPI_INTERFACE: + // esp32s3 test SPI maximum read and write is 256 bytes + _max_rw_length = 256; + break; + default: + return false; + } +#else + // Other platforms are set to 64 bytes + _max_rw_length = 32; +#endif + } + + _error_code = bhy2_init(interface, + SensorCommStatic::sensor_static_read_data, + SensorCommStatic::sensor_static_write_data, + SensorCommStatic::sensor_static_delay_us, + _max_rw_length, + staticComm.get(), + _bhy2.get()); + + BHY2_RLST_CHECK(_error_code != BHY2_OK, "bhy2_init failed!", false); + + + _error_code = bhy2_soft_reset(_bhy2.get()); + BHY2_RLST_CHECK(_error_code != BHY2_OK, "reset _bhy2 failed!", false); + + _error_code = bhy2_get_product_id(&product_id, _bhy2.get()); + BHY2_RLST_CHECK(_error_code != BHY2_OK, "bhy2_get_product_id failed!", false); + + /* Check for a valid product ID */ + if (product_id != BHY2_PRODUCT_ID) { + log_e("Product ID read 0x%02X. Expected 0x%02X", product_id, BHY2_PRODUCT_ID); + return false; + } else { + log_i("BHI260/BHA260 found. Product ID read 0x%02X", product_id); + } + + // Set default interrupt configure + uint8_t data = 0, data_exp; + bhy2_get_host_interrupt_ctrl(&data, _bhy2.get()); + data &= ~BHY2_ICTL_DISABLE_STATUS_FIFO; /* Enable status interrupts */ + if (_debug) { + data &= ~BHY2_ICTL_DISABLE_DEBUG; /* Enable debug interrupts */ + } else { + data |= BHY2_ICTL_DISABLE_DEBUG; /* Disable debug interrupts */ + } + data &= ~BHY2_ICTL_EDGE; /* Level */ + data &= ~BHY2_ICTL_ACTIVE_LOW; /* Active high */ + data &= ~BHY2_ICTL_OPEN_DRAIN; /* Push-pull */ + data_exp = data; + bhy2_set_host_interrupt_ctrl(data, _bhy2.get()); + bhy2_get_host_interrupt_ctrl(&data, _bhy2.get()); + if (data != data_exp) { + log_d("Expected Host Interrupt Control (0x07) to have value 0x%x but instead read 0x%x\r\n", data_exp, data); + } + /* Config status channel */ + bhy2_set_host_intf_ctrl(BHY2_HIF_CTRL_ASYNC_STATUS_CHANNEL, _bhy2.get()); + bhy2_get_host_intf_ctrl(&data, _bhy2.get()); + if (!(data & BHY2_HIF_CTRL_ASYNC_STATUS_CHANNEL)) { + log_d("Expected Host Interface Control (0x06) to have bit 0x%x to be set\r\n", BHY2_HIF_CTRL_ASYNC_STATUS_CHANNEL); + } + + if (_boot_from_flash) { + if (_force_update) { + if ((_firmware_stream == NULL) || (_firmware_size == 0)) { + log_e("No valid firmware is set. Please use the \"setFirmware\" method to set the valid firmware."); + return false; + } + _error_code = bhy2_soft_reset(_bhy2.get()); + BHY2_RLST_CHECK(_error_code != BHY2_OK, "reset _bhy2 failed!", false); + log_i("Force update firmware."); + if (!uploadFirmware(_firmware_stream, _firmware_size, _write_flash)) { + log_e("uploadFirmware failed!"); + return false; + } + } + if (!bootFromFlash()) { + return false; + } + } else { + if ((_firmware_stream == NULL) || (_firmware_size == 0)) { + log_e("No valid firmware is set. Please use the \"setFirmware\" method to set the valid firmware."); + return false; + } + + // ** Upload firmware to RAM **// + if (!uploadFirmware(_firmware_stream, _firmware_size, false)) { + log_e("uploadFirmware failed!"); + return false; + } + } + + uint16_t version = getKernelVersion(); + BHY2_RLST_CHECK(!version, "getKernelVersion failed!", false); + log_i("Boot successful. Kernel version %u.", version); + + //Set event callback + _error_code = bhy2_register_fifo_parse_callback(BHY2_SYS_ID_META_EVENT, BoschParse::parseMetaEvent, (void *)&_accuracy, _bhy2.get()); + BHY2_RLST_CHECK(_error_code != BHY2_OK, "bhy2_register_fifo_parse_callback failed!", false); + + _error_code = bhy2_register_fifo_parse_callback(BHY2_SYS_ID_META_EVENT_WU, BoschParse::parseMetaEvent, (void *)&_accuracy, _bhy2.get()); + BHY2_RLST_CHECK(_error_code != BHY2_OK, "bhy2_register_fifo_parse_callback failed!", false); + + if (_debug) { + _error_code = bhy2_register_fifo_parse_callback(BHY2_SYS_ID_DEBUG_MSG, BoschParse::parseDebugMessage, NULL, _bhy2.get()); + BHY2_RLST_CHECK(_error_code != BHY2_OK, "bhy2_register_fifo_parse_callback parseDebugMessage failed!", false); + } + + //Set process buffer +#if defined(ARDUINO_ARCH_ESP32) && defined(BOARD_HAS_PSRAM) + _processBuffer = (uint8_t *)ps_malloc(_processBufferSize); +#else + _processBuffer = (uint8_t *)malloc(_processBufferSize); #endif + BHY2_RLST_CHECK(!_processBuffer, "process buffer malloc failed!", false); + + _error_code = bhy2_get_and_process_fifo(_processBuffer, _processBufferSize, _bhy2.get()); + if (_error_code != BHY2_OK) { + log_e("bhy2_get_and_process_fifo failed"); + return false; + } + + /* Update the callback table to enable parsing of sensor hintr_ctrl */ + bhy2_update_virtual_sensor_list(_bhy2.get()); + /* Get present virtual sensor */ + bhy2_get_virt_sensor_list(_bhy2.get()); + // Only register valid sensor IDs + for (uint8_t i = 0; i < BHY2_SENSOR_ID_MAX; i++) { + if (bhy2_is_sensor_available(i, _bhy2.get())) { + bhy2_register_fifo_parse_callback(i, BoschParse::parseData, NULL, _bhy2.get()); + } + } + return _error_code == BHY2_OK; +} diff --git a/src/SensorBHI260AP.hpp b/src/SensorBHI260AP.hpp index 0a02644..99f6ddf 100644 --- a/src/SensorBHI260AP.hpp +++ b/src/SensorBHI260AP.hpp @@ -30,20 +30,20 @@ */ #pragma once -#if defined(ARDUINO) #include "bosch/BoschParse.h" #include "bosch/SensorBhy2Define.h" #include "bosch/firmware/BHI260AP.fw.h" - - - +#include "bosch/BoschSensorControl.hpp" +#include "bosch/BoschSensorControl.hpp" +#include "bosch/BoschPhySensorInfo.hpp" +#include "bosch/BoschSensorInfo.hpp" +#include "SensorPlatform.hpp" class SensorBHI260AP { friend class BoschParse; public: - // The pin names are named according to the sensor manual. enum BHI260AP_GPIO { MCSB1 = 1, @@ -74,132 +74,108 @@ class SensorBHI260AP RESV3 = 130, // Invalid Pin }; - SensorBHI260AP(PLATFORM_WIRE_TYPE &w, int sda = DEFAULT_SDA, int scl = DEFAULT_SCL, uint8_t addr = BHI260AP_SLAVE_ADDRESS_L) - { - __handler.u.i2c_dev.scl = scl; - __handler.u.i2c_dev.sda = sda; - __handler.u.i2c_dev.addr = addr; - __handler.u.i2c_dev.wire = &w; - __handler.intf = SENSORLIB_I2C_INTERFACE; - } + ~SensorBHI260AP(); - SensorBHI260AP(int cs, int mosi = -1, int miso = -1, int sck = -1, - PLATFORM_SPI_TYPE &spi = SPI - ) - { - __handler.u.spi_dev.cs = cs; - __handler.u.spi_dev.miso = miso; - __handler.u.spi_dev.mosi = mosi; - __handler.u.spi_dev.sck = sck; - __handler.u.spi_dev.spi = &spi; - __handler.intf = SENSORLIB_SPI_INTERFACE; - } + SensorBHI260AP(); - ~SensorBHI260AP() - { - deinit(); - } - - SensorBHI260AP() - { - memset(&__handler, 0, sizeof(__handler)); - } + /** + * @brief setPins + * @note Set the reset pin. reset pin is not set by default. + * @param rst: + * @retval None + */ + void setPins(int rst); - void setPins(int rst, int irq) - { - __handler.irq = irq; - __handler.rst = rst; +#if defined(ARDUINO) + /** + * @brief begin + * @note Initialization using the Arduino Wire Interface + * @param &wire: TwoWire Class + * @param addr: Device address, default 0x28, can also be changed to 0x29 + * @param sda: Set I2C SCL Pin, not set by default + * @param scl: Set I2C SDA Pin, not set by default + * @retval bool true-> Success false-> failure + */ + bool begin(TwoWire &wire, uint8_t addr = BHI260AP_SLAVE_ADDRESS_L, int sda = -1, int scl = -1); - } + /** + * @brief begin + * @note Initialization using the Arduino SPI Interface + * @param &spi: SPIClass + * @param csPin: Set CS SCL Pin, not set by default + * @param mosi: Set SPI MOSI SCL Pin, not set by default + * @param miso: Set SPI MISO SCL Pin, not set by default + * @param sck: Set SPI SCK SCL Pin, not set by default + * @retval bool true-> Success false-> failure + */ + bool begin(SPIClass &spi, uint8_t csPin, int mosi = -1, int miso = -1, int sck = -1); - bool init(PLATFORM_WIRE_TYPE &w, int sda = DEFAULT_SDA, int scl = DEFAULT_SCL, uint8_t addr = BHI260AP_SLAVE_ADDRESS_L) - { - __handler.u.i2c_dev.scl = scl; - __handler.u.i2c_dev.sda = sda; - __handler.u.i2c_dev.addr = addr; - __handler.u.i2c_dev.wire = &w; - __handler.intf = SENSORLIB_I2C_INTERFACE; - return initImpl(); - } +#elif defined(ESP_PLATFORM) - bool init( - PLATFORM_SPI_TYPE &spi, - int cs, int mosi = MOSI, int miso = MISO, int sck = SCK) - { - __handler.u.spi_dev.cs = cs; - __handler.u.spi_dev.miso = miso; - __handler.u.spi_dev.mosi = mosi; - __handler.u.spi_dev.sck = sck; - __handler.u.spi_dev.spi = &spi; - __handler.intf = SENSORLIB_SPI_INTERFACE; - return initImpl(); - } +#if defined(USEING_I2C_LEGACY) + /** + * @brief begin + * @note Initialization using the ESP-IDF I2C Legacy Interface + * @param port_num: I2C_NUM0 or I2C_NUM1 + * @param addr: Device address, default 0x28, can also be changed to 0x29 + * @param sda: Set I2C SCL Pin, not set by default + * @param scl: Set I2C SDA Pin, not set by default + * @retval bool true-> Success false-> failure + */ + bool begin(i2c_port_t port_num, uint8_t addr = BHI260AP_SLAVE_ADDRESS_L, int sda = -1, int scl = -1); +#else + /** + * @brief begin + * @note Initialization using the ESP-IDF I2C LL Interface idf version > 5.0.0 + * @param handle: I2C Handle + * @param addr: Device address, default 0x28, can also be changed to 0x29 + * @retval bool true-> Success false-> failure + */ + bool begin(i2c_master_bus_handle_t handle, uint8_t addr = BHI260AP_SLAVE_ADDRESS_L); +#endif //ESP_PLATFORM - bool init() - { - return initImpl(); - } - void deinit() - { - if (__pro_buf) { - free(__pro_buf); - } - __pro_buf = NULL; + /** + * @brief begin + * @note Initialization using the ESP-IDF SPI Interface + * @param host: spi_host_device_t enum + * @param handle: spi_device_handle_t handle + * @param csPin: cs pin + * @param mosi: spi mosi pin + * @param miso: spi miso pin + * @param sck: spi sck pin + * @retval bool true-> Success false-> failure + */ + bool begin(spi_host_device_t host, spi_device_handle_t handle, uint8_t csPin, int mosi, int miso, int sck); - if (bhy2) { - free(bhy2); - bhy2 = NULL; - } +#endif //ARDUINO - if (__handler.irq != SENSOR_PIN_NONE) { - detachInterrupt(__handler.irq); - } - // end(); - } + /** + * @brief begin + * @note Custom callback interface, suitable for other platforms + * @param interface: Communication mode, COMM_SPI or COMM_I2C + * @param callback: Register read and write callback function + * @param hal_callback: Platform digital IO and delay callback function + * @param addr: Device address, default 0x28, can also be changed to 0x29 + * @retval bool true-> Success false-> failure + */ + bool begin(CommInterface interface, SensorCommCustom::CustomCallback callback, + SensorCommCustomHal::CustomHalCallback hal_callback, + uint8_t addr = BHI260AP_SLAVE_ADDRESS_L); /** * @brief reset * @note Reset sensor * @retval None */ - void reset() - { - if (__handler.rst != SENSOR_PIN_NONE) { - digitalWrite(__handler.rst, HIGH); - delay(5); - digitalWrite(__handler.rst, LOW); - delay(10); - digitalWrite(__handler.rst, HIGH); - delay(5); - } - } + void reset(); /** * @brief update * @note Update sensor fifo data * @retval None */ - void update() - { - if (!__pro_buf) { - return; - } - if (__handler.irq != SENSOR_PIN_NONE) { - if (__data_available) { - bhy2_get_and_process_fifo(__pro_buf, __pro_buf_size, bhy2); - __data_available = false; - } - } else { - bhy2_get_and_process_fifo(__pro_buf, __pro_buf_size, bhy2); - } - } - - // Deprecated API, wrong word - void setBootFormFlash(bool boot_from_flash) __attribute__((deprecated("The setBootFormFlash method will be replaced by setBootFromFlash in the future. Please update it to setBootFromFlash."))) - { - __boot_from_flash = boot_from_flash; - } + void update(); /** * @brief setBootFromFlash @@ -207,170 +183,14 @@ class SensorBHI260AP * @param boot_from_flash: true boot form flash or boot form ram * @retval None */ - void setBootFromFlash(bool boot_from_flash) - { - __boot_from_flash = boot_from_flash; - } + void setBootFromFlash(bool boot_from_flash); /** * @brief getHandler * @note Get the native BHI API handle * @retval handle */ - bhy2_dev *getHandler() - { - return bhy2; - } - - /** - * @brief printSensors - * @note Output available sensor IDs to serial - * @param &port: Serial or other - * @retval None - */ - void printSensors(Stream &port) - { - uint8_t cnt = 0; - bool presentBuff[256]; - - for (uint16_t i = 0; i < sizeof(bhy2->present_buff); i++) { - for (uint8_t j = 0; j < 8; j++) { - presentBuff[i * 8 + j] = ((bhy2->present_buff[i] >> j) & 0x01); - } - } - - port.println("Present sensors: "); - for (int i = 0; i < (int)sizeof(presentBuff); i++) { - if (presentBuff[i]) { - cnt++; - port.print(i); - port.print(" - "); - port.print(get_sensor_name(i)); - port.println(); - } - } - port.printf("Total %u Sensor online .\n", cnt); - } - - /** - * @brief printInfo - * @note Print sensor information - * @param &stream: Serial or other - * @retval true is success , false is failed - */ - bool printInfo(Stream &stream) - { - uint16_t kernel_version = 0, user_version = 0; - uint16_t rom_version = 0; - uint8_t product_id = 0; - uint8_t host_status = 0, feat_status = 0; - uint8_t boot_status = 0; - uint8_t sensor_error; - struct bhy2_sensor_info info; - - /* Get product_id */ - __error_code = (bhy2_get_product_id(&product_id, bhy2)); - BHY2_RLST_CHECK(__error_code != BHY2_OK, "bhy2_get_product_id failed!", false); - - /* Get Kernel version */ - __error_code = (bhy2_get_kernel_version(&kernel_version, bhy2)); - BHY2_RLST_CHECK(__error_code != BHY2_OK, "bhy2_get_kernel_version failed!", false); - - /* Get User version */ - __error_code = (bhy2_get_user_version(&user_version, bhy2)); - BHY2_RLST_CHECK(__error_code != BHY2_OK, "bhy2_get_user_version failed!", false); - - /* Get ROM version */ - __error_code = (bhy2_get_rom_version(&rom_version, bhy2)); - BHY2_RLST_CHECK(__error_code != BHY2_OK, "bhy2_get_rom_version failed!", false); - - __error_code = (bhy2_get_host_status(&host_status, bhy2)); - BHY2_RLST_CHECK(__error_code != BHY2_OK, "bhy2_get_host_status failed!", false); - - __error_code = (bhy2_get_feature_status(&feat_status, bhy2)); - BHY2_RLST_CHECK(__error_code != BHY2_OK, "bhy2_get_feature_status failed!", false); - - stream.printf("Product ID : %02x\n", product_id); - stream.printf("Kernel version : %04u\n", kernel_version); - stream.printf("User version : %04u\n", user_version); - stream.printf("ROM version : %04u\n", rom_version); - stream.printf("Power state : %s\n", (host_status & BHY2_HST_POWER_STATE) ? "sleeping" : "active"); - stream.printf("Host interface : %s\n", (host_status & BHY2_HST_HOST_PROTOCOL) ? "SPI" : "I2C"); - stream.printf("Feature status : 0x%02x\n", feat_status); - - /* Read boot status */ - __error_code = (bhy2_get_boot_status(&boot_status, bhy2)); - BHY2_RLST_CHECK(__error_code != BHY2_OK, "bhy2_get_boot_status failed!", false); - - stream.printf("Boot Status : 0x%02x: ", boot_status); - - if (boot_status & BHY2_BST_FLASH_DETECTED) { - stream.println("\tFlash detected. "); - } - - if (boot_status & BHY2_BST_FLASH_VERIFY_DONE) { - stream.println("\tFlash verify done. "); - } - - if (boot_status & BHY2_BST_FLASH_VERIFY_ERROR) { - stream.println("Flash verification failed. "); - } - - if (boot_status & BHY2_BST_NO_FLASH) { - stream.println("\tNo flash installed. "); - } - - if (boot_status & BHY2_BST_HOST_INTERFACE_READY) { - stream.println("\tHost interface ready. "); - } - - if (boot_status & BHY2_BST_HOST_FW_VERIFY_DONE) { - stream.println("\tFirmware verification done. "); - } - - if (boot_status & BHY2_BST_HOST_FW_VERIFY_ERROR) { - stream.println("\tFirmware verification error. "); - } - - if (boot_status & BHY2_BST_HOST_FW_IDLE) { - stream.println("\tFirmware halted. "); - } - - /* Read error value */ - __error_code = (bhy2_get_error_value(&sensor_error, bhy2)); - BHY2_RLST_CHECK(__error_code != BHY2_OK, "bhy2_get_error_value failed!", false); - if (sensor_error) { - log_e("%s", get_sensor_error_text(sensor_error)); - } - - - if (feat_status & BHY2_FEAT_STATUS_OPEN_RTOS_MSK) { - - bhy2_update_virtual_sensor_list(bhy2); - - /* Get present virtual sensor */ - bhy2_get_virt_sensor_list(bhy2); - - stream.printf("Virtual sensor list.\r\n"); - stream.printf("Sensor ID | Sensor Name | ID | Ver | Min rate | Max rate |\r\n"); - stream.printf("----------+--------------------------------------+-----+-----+-----------+-----------|\r\n"); - for (uint8_t i = 0; i < BHY2_SENSOR_ID_MAX; i++) { - if (bhy2_is_sensor_available(i, bhy2)) { - if (i < BHY2_SENSOR_ID_CUSTOM_START) { - stream.printf(" %8u | %36s ", i, get_sensor_name(i)); - } - __error_code = (bhy2_get_sensor_info(i, &info, bhy2)); - BHY2_RLST_CHECK(__error_code != BHY2_OK, "bhy2_get_sensor_info failed!", false); - stream.printf("| %3u | %3u | %9.4f | %9.4f |\r\n", - info.driver_id, - info.driver_version, - info.min_rate.f_val, - info.max_rate.f_val); - } - } - } - return true; - } + bhy2_dev *getHandler(); /** * @brief setInterruptCtrl @@ -387,84 +207,29 @@ class SensorBHI260AP * * @retval true is success , false is failed */ - bool setInterruptCtrl(uint8_t data) - { - __error_code = bhy2_set_host_interrupt_ctrl(data, bhy2); - if (__error_code != BHY2_OK) { - return false; - } - } + bool setInterruptCtrl(uint8_t data); /** * @brief getInterruptCtrl - * @note Get interrupt control mask - * @retval interrupt mask + * @note Get interrupt control info + * @retval SensorBHI260APControl class */ - uint8_t getInterruptCtrl() - { - uint8_t data; - __error_code = bhy2_get_host_interrupt_ctrl(&data, bhy2); - if (__error_code != BHY2_OK) { - return 0; - } - return data; - } + SensorBHI260APControl getInterruptCtrl(); - /** - * @brief printInterruptCtrl - * @note Print sensor interrupt control methods to a stream - * @param &stream: Serial or other - * @retval None - */ - void printInterruptCtrl(Stream &stream) - { - uint8_t data; - __error_code = bhy2_get_host_interrupt_ctrl(&data, bhy2); - if (__error_code != BHY2_OK) { - return ; - } - stream.printf("Host interrupt control\r\n"); - stream.printf("-- Wake up FIFO %s.\r\n", (data & BHY2_ICTL_DISABLE_FIFO_W) ? "disabled" : "enabled"); - stream.printf("-- Non wake up FIFO %s.\r\n", (data & BHY2_ICTL_DISABLE_FIFO_NW) ? "disabled" : "enabled"); - stream.printf("-- Status FIFO %s.\r\n", (data & BHY2_ICTL_DISABLE_STATUS_FIFO) ? "disabled" : "enabled"); - stream.printf("-- Debugging %s.\r\n", (data & BHY2_ICTL_DISABLE_DEBUG) ? "disabled" : "enabled"); - stream.printf("-- Fault %s.\r\n", (data & BHY2_ICTL_DISABLE_FAULT) ? "disabled" : "enabled"); - stream.printf("-- Interrupt is %s.\r\n", (data & BHY2_ICTL_ACTIVE_LOW) ? "active low" : "active high"); - stream.printf("-- Interrupt is %s triggered.\r\n", (data & BHY2_ICTL_EDGE) ? "pulse" : "level"); - stream.printf("-- Interrupt pin drive is %s.\r\n", (data & BHY2_ICTL_OPEN_DRAIN) ? "open drain" : "push-pull"); - } /** * @brief isReady * @note Query whether the sensor is ready - * @retval 1 OK , 0 Not ready + * @retval true OK , false Not ready */ - bool isReady() - { - uint8_t boot_status = 0; - __error_code = bhy2_get_boot_status(&boot_status, bhy2); - log_i("boot_status:0x%x", boot_status); - if (__error_code != BHY2_OK) { - return false; - } - return (boot_status & BHY2_BST_HOST_INTERFACE_READY); - } + bool isReady(); /** * @brief getKernelVersion * @note Get the sensor firmware kernel version * @retval 2 bytes */ - uint16_t getKernelVersion() - { - uint16_t version = 0; - __error_code = bhy2_get_kernel_version(&version, bhy2); - if ((__error_code != BHY2_OK) && (version == 0)) { - return 0; - } - log_d("Boot successful. Kernel version %u.", version); - return version; - } + uint16_t getKernelVersion(); /** @@ -473,20 +238,14 @@ class SensorBHI260AP * @param callback: Callback Function * @retval None */ - void onEvent(BhyEventCb callback) - { - BoschParse::_event_callback = callback; - } + void onEvent(BhyEventCb callback); /** * @brief removeEvent * @note Remove sensor event callback function * @retval None */ - void removeEvent() - { - BoschParse::_event_callback = NULL; - } + void removeEvent(); /** * @brief onResultEvent @@ -496,23 +255,7 @@ class SensorBHI260AP * @param callback: Callback Function * @retval None */ - void onResultEvent(BhySensorID sensor_id, BhyParseDataCallback callback) - { -#ifdef USE_STD_VECTOR - ParseCallBackList_t newEventHandler; - newEventHandler.cb = callback; - newEventHandler.id = sensor_id; - BoschParse::bhyParseEventVector.push_back(newEventHandler); -#else - if (BoschParse::BoschParse_bhyParseEventVectorSize == BoschParse::BoschParse_bhyParseEventVectorCapacity) { - BoschParse::expandParseEventVector(); - } - ParseCallBackList_t newEventHandler; - newEventHandler.cb = callback; - newEventHandler.id = sensor_id; - BoschParse::BoschParse_bhyParseEventVector[BoschParse::BoschParse_bhyParseEventVectorSize++] = newEventHandler; -#endif - } + void onResultEvent(BhySensorID sensor_id, BhyParseDataCallback callback); /** * @brief removeResultEvent @@ -521,42 +264,15 @@ class SensorBHI260AP * @param callback: Callback Function * @retval None */ - void removeResultEvent(BhySensorID sensor_id, BhyParseDataCallback callback) - { - if (!callback) { - return; - } -#ifdef USE_STD_VECTOR - for (uint32_t i = 0; i < BoschParse::bhyParseEventVector.size(); i++) { - ParseCallBackList_t entry = BoschParse::bhyParseEventVector[i]; - if (entry.cb == callback && entry.id == sensor_id) { - BoschParse::bhyParseEventVector.erase(BoschParse::bhyParseEventVector.begin() + i); - } - } -#else - for (uint32_t i = 0; i < BoschParse::BoschParse_bhyParseEventVectorSize; i++) { - ParseCallBackList_t entry = BoschParse::BoschParse_bhyParseEventVector[i]; - if (entry.cb == callback && entry.id == sensor_id) { - for (uint32_t j = i; j < BoschParse::BoschParse_bhyParseEventVectorSize - 1; j++) { - BoschParse::BoschParse_bhyParseEventVector[j] = BoschParse::BoschParse_bhyParseEventVector[j + 1]; - } - BoschParse::BoschParse_bhyParseEventVectorSize--; - break; - } - } -#endif - } + void removeResultEvent(BhySensorID sensor_id, BhyParseDataCallback callback); /** * @brief setProcessBufferSize - * @note The default value is 512Bytes - * @param size: The default value is 512Bytes + * @note The default value is 512Bytes , Must be called before initialization + * @param size: The set buffer size is requested by malloc, and if PSRAM is enabled, it is requested from PSRAM * @retval None */ - void setProcessBufferSize(uint32_t size) - { - __pro_buf_size = size; - } + void setProcessBufferSize(uint32_t size); /** * @brief uploadFirmware @@ -564,73 +280,16 @@ class SensorBHI260AP * @param *firmware: Firmware data address * @param length: Firmware data length * @param write2Flash: 1 is written to external flash, 0 is written to RAM - * @retval true success or failed + * @retval bool true-> Success false-> failure */ - bool uploadFirmware(const uint8_t *firmware, uint32_t length, bool write2Flash = false) - { - uint8_t sensor_error; - uint8_t boot_status; - - log_i("Upload Firmware ..."); + bool uploadFirmware(const uint8_t *firmware, uint32_t length, bool write2Flash = false); - __error_code = bhy2_get_boot_status(&boot_status, bhy2); - BHY2_RLST_CHECK(__error_code != BHY2_OK, "bhy2_get_boot_status failed!", false); - - if (write2Flash) { - if (boot_status & BHY2_BST_FLASH_DETECTED) { - uint32_t start_addr = BHY2_FLASH_SECTOR_START_ADDR; - uint32_t end_addr = start_addr + length; - log_i("Flash detected. Erasing flash to upload firmware"); - __error_code = bhy2_erase_flash(start_addr, end_addr, bhy2); - BHY2_RLST_CHECK(__error_code != BHY2_OK, "bhy2_erase_flash failed!", false); - } else { - log_e("Flash not detected"); - return false; - } - log_i("Loading firmware into FLASH."); - __error_code = bhy2_upload_firmware_to_flash(firmware, length, bhy2); - BHY2_RLST_CHECK(__error_code != BHY2_OK, "bhy2_upload_firmware_to_flash failed!", false); - log_i("Loading firmware into FLASH Done"); - } else { - log_i("Loading firmware into RAM."); - log_i("upload size = %lu", length); - __error_code = bhy2_upload_firmware_to_ram(firmware, length, bhy2); - BHY2_RLST_CHECK(__error_code != BHY2_OK, "bhy2_upload_firmware_to_ram failed!", false); - log_i("Loading firmware into RAM Done"); - } - - __error_code = bhy2_get_error_value(&sensor_error, bhy2); - BHY2_RLST_CHECK(__error_code != BHY2_OK, "bhy2_get_error_value failed!", false); - if (sensor_error != BHY2_OK) { - __error_code = bhy2_get_error_value(&sensor_error, bhy2); - log_e("%s", get_sensor_error_text(sensor_error)); - return false; - } - - - if (write2Flash) { - log_i("Booting from FLASH."); - __error_code = bhy2_boot_from_flash(bhy2); - } else { - log_i("Booting from RAM."); - __error_code = bhy2_boot_from_ram(bhy2); - } - BHY2_RLST_CHECK(__error_code != BHY2_OK, "bhy2 boot failed!", false); - - __error_code = bhy2_get_error_value(&sensor_error, bhy2); - if (sensor_error) { - log_e("%s", get_sensor_error_text(sensor_error)); - return false; - } - return sensor_error == BHY2_OK; - } - - String getError() - { - String err = get_api_error(__error_code); - err += " Code:" + String(__error_code); - return err; - } + /** + * @brief getError + * @note Get the error status string + * @retval string + */ + const char *getError(); /** * @brief configure @@ -640,16 +299,7 @@ class SensorBHI260AP * @param report_latency_ms: Report interval in milliseconds * @return bool true-> Success false-> failure */ - 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); - return true; - } + bool configure(uint8_t sensor_id, float sample_rate, uint32_t report_latency_ms); /** * @brief configureRange @@ -658,12 +308,7 @@ class SensorBHI260AP * @param range: Range for selected SensorID. See Table 79 in BHY260 datasheet 109 page * @retval bool true-> Success false-> failure */ - bool configureRange(uint8_t sensor_id, uint16_t range) - { - __error_code = bhy2_set_virt_sensor_range(sensor_id, range, bhy2); - BHY2_RLST_CHECK(__error_code != BHY2_OK, "bhy2_set_virt_sensor_range failed!", false); - return true; - } + bool configureRange(uint8_t sensor_id, uint16_t range); /** @@ -672,13 +317,7 @@ class SensorBHI260AP * @param sensor_id: Sensor ID , see enum BhySensorID * @retval struct bhy2_virt_sensor_conf */ - struct bhy2_virt_sensor_conf getConfigure(uint8_t sensor_id) - { - bhy2_virt_sensor_conf conf; - bhy2_get_virt_sensor_cfg(sensor_id, &conf, bhy2); - log_i("range:%u sample_rate:%f latency:%lu sensitivity:%u\n", conf.range, conf.sample_rate, conf.latency, conf.sensitivity); - return conf; - } + struct bhy2_virt_sensor_conf getConfigure(uint8_t sensor_id); /** * @brief getScaling @@ -686,10 +325,7 @@ class SensorBHI260AP * @param sensor_id: Sensor ID , see enum BhySensorID * @retval scale factor */ - float getScaling(uint8_t sensor_id) - { - return get_sensor_default_scaling(sensor_id); - } + float getScaling(uint8_t sensor_id); /** * @brief setFirmware @@ -700,13 +336,7 @@ class SensorBHI260AP * @param force_update: true, rewrite to flash or ram regardless of whether there is firmware, false, do not write if firmware is detected * @retval None */ - void setFirmware(const uint8_t *image, size_t image_len, bool write_flash = false, bool force_update = false) - { - __firmware = image; - __firmware_size = image_len; - __write_flash = write_flash; - __force_update = force_update; - } + void setFirmware(const uint8_t *image, size_t image_len, bool write_flash = false, bool force_update = false); /** * @brief getSensorName @@ -714,16 +344,14 @@ class SensorBHI260AP * @param sensor_id: Sensor ID , see enum BhySensorID * @retval sensor name */ - static const char *getSensorName(uint8_t sensor_id) - { - return get_sensor_name(sensor_id); - } + const char *getSensorName(uint8_t sensor_id); - // Get an accuracy report - uint8_t getAccuracy() - { - return __accuracy; - } + /** + * @brief getAccuracy + * @note Get an accuracy report + * @retval Current report accuracy + */ + uint8_t getAccuracy(); /** * @brief digitalRead @@ -732,23 +360,7 @@ class SensorBHI260AP * @param pullup: true is set pullup or input mode * @retval 1 is high ,0 is low */ - uint8_t digitalRead(uint8_t pin, bool pullup = false) - { - if (pin > JTAG_DIO)return 0; - uint32_t pin_mask = pin | BHY2_GPIO_SET; - if (pullup) { - pin_mask |= (BHY2_INPUT_PULLUP << 8); - } else { - pin_mask |= (BHY2_INPUT << 8); - } - bhy2_set_virt_sensor_cfg(SENSOR_ID_GPIO_EXP, (float)pin_mask, 0, bhy2); - pin_mask = pin /*GetCmd*/; - bhy2_set_virt_sensor_cfg(SENSOR_ID_GPIO_EXP, (float)pin_mask, 0, bhy2); - bhy2_virt_sensor_conf conf; - bhy2_get_virt_sensor_cfg(SENSOR_ID_GPIO_EXP, &conf, bhy2); - uint8_t level = conf.sample_rate; - return level; - } + uint8_t digitalRead(uint8_t pin, bool pullup = false); /** * @brief digitalWrite @@ -757,12 +369,7 @@ class SensorBHI260AP * @param level: 1 is high ,0 is low * @retval None */ - void digitalWrite(uint8_t pin, uint8_t level) - { - if (pin > JTAG_DIO)return; - uint32_t pin_mask = pin | (BHY2_OUTPUT << 8) | (level << 6) | BHY2_GPIO_SET ; - bhy2_set_virt_sensor_cfg(SENSOR_ID_GPIO_EXP, (float)pin_mask, 0, bhy2); - } + void digitalWrite(uint8_t pin, uint8_t level); /** * @brief disableGpio @@ -770,12 +377,7 @@ class SensorBHI260AP * @param pin: see BHI260AP_aux_BMM150_BME280_Expand_GPIO example * @retval None */ - void disableGpio(uint8_t pin) - { - if (pin > JTAG_DIO)return; - uint32_t pin_mask = pin | (BHY2_OPEN_DRAIN << 8) | BHY2_GPIO_SET; - bhy2_set_virt_sensor_cfg(SENSOR_ID_GPIO_EXP, (float)pin_mask, 0, bhy2); - } + void disableGpio(uint8_t pin); /** * @brief setDebug @@ -784,424 +386,72 @@ class SensorBHI260AP * @param &serial: Stream * @retval None */ - void setDebug(bool enable) - { - uint8_t data = 0; - bhy2_get_host_interrupt_ctrl(&data, bhy2); - if (enable) { - data &= ~BHY2_ICTL_DISABLE_DEBUG; /* Enable debug interrupts */ - } else { - data |= BHY2_ICTL_DISABLE_DEBUG; /* Disable debug interrupts */ - } - bhy2_set_host_interrupt_ctrl(data, bhy2); - bhy2_register_fifo_parse_callback(BHY2_SYS_ID_DEBUG_MSG, enable ? BoschParse::parseDebugMessage : NULL, NULL, bhy2); - } + void setDebugKernel(bool enable); /** * @brief setDebugCallback * @param cb: Sensor debug output callback function , Requires firmware support, the default firmware will not output any messages * @retval None */ - void setDebugCallback(BhyDebugMessageCallback cb) - { - BoschParse::_debug_callback = cb; - } - -private: - -#if 0 - void get_phy_sensor_info(uint8_t sens_id) - { - Stream &stream = Serial; - int8_t assert_rslt = BHY2_OK; - uint16_t param_id = 0; - struct bhy2_phys_sensor_info psi; - - memset(&psi, 0, sizeof(psi)); - - if (!bhy2)return; - - // sens_id = (uint8_t)atoi((char *)&payload[0]); - param_id = (uint16_t)(0x0120 | sens_id); - - if (param_id >= 0x0121 && param_id <= 0x0160) { - BHY2_ASSERT(bhy2_get_phys_sensor_info(sens_id, &psi, bhy2)); - if (assert_rslt != BHY2_OK) { - return; - } - - stream.printf("Field Name hex | Value (dec)\r\n"); - stream.printf("----------------------------------------------------------\r\n"); - stream.printf("Physical Sensor ID %02X | %d\r\n", psi.sensor_type, psi.sensor_type); - stream.printf("Driver ID %02X | %d\r\n", psi.driver_id, psi.driver_id); - stream.printf("Driver Version %02X | %d\r\n", psi.driver_version, psi.driver_version); - stream.printf("Current Consumption %02X | %0.3fmA\r\n", - psi.power_current, - psi.power_current / 10.f); - stream.printf("Dynamic Range %04X | %d\r\n", psi.curr_range.u16_val, psi.curr_range.u16_val); - - const char *irq_status[2] = { "Disabled", "Enabled" }; - const char *master_intf[5] = { "None", "SPI0", "I2C0", "SPI1", "I2C1" }; - const char *power_mode[8] = { - "Sensor Not Present", "Power Down", "Suspend", "Self-Test", "Interrupt Motion", "One Shot", - "Low Power Active", "Active" - }; - - stream.printf("Flags %02X | IRQ status : %s\r\n", psi.flags, - irq_status[psi.flags & 0x01]); - stream.printf(" | Master interface : %s\r\n", - master_intf[(psi.flags >> 1) & 0x0F]); - stream.printf(" | Power mode : %s\r\n", - power_mode[(psi.flags >> 5) & 0x07]); - stream.printf("Slave Address %02X | %d\r\n", psi.slave_address, psi.slave_address); - stream.printf("GPIO Assignment %02X | %d\r\n", psi.gpio_assignment, psi.gpio_assignment); - stream.printf("Current Rate %08X | %.3fHz\r\n", psi.curr_rate.u32_val, psi.curr_rate.f_val); - stream.printf("Number of axes %02X | %d\r\n", psi.num_axis, psi.num_axis); - -#define INT4_TO_INT8(INT4) ((int8_t)(((INT4) > 1) ? -1 : (INT4))) - struct bhy2_orient_matrix ort_mtx = { 0 }; - ort_mtx.c[0] = INT4_TO_INT8(psi.orientation_matrix[0] & 0x0F); - ort_mtx.c[1] = INT4_TO_INT8(psi.orientation_matrix[0] >> 8); - ort_mtx.c[2] = INT4_TO_INT8(psi.orientation_matrix[1] & 0x0F); - ort_mtx.c[3] = INT4_TO_INT8(psi.orientation_matrix[1] >> 8); - ort_mtx.c[4] = INT4_TO_INT8(psi.orientation_matrix[2] & 0x0F); - ort_mtx.c[5] = INT4_TO_INT8(psi.orientation_matrix[2] >> 8); - ort_mtx.c[6] = INT4_TO_INT8(psi.orientation_matrix[3] & 0x0F); - ort_mtx.c[7] = INT4_TO_INT8(psi.orientation_matrix[3] >> 8); - ort_mtx.c[8] = INT4_TO_INT8(psi.orientation_matrix[4] & 0x0F); - - stream.printf("Orientation Matrix %02X%02X%02X%02X%02X | %+02d %+02d %+02d |\r\n", - psi.orientation_matrix[0], - psi.orientation_matrix[1], - psi.orientation_matrix[2], - psi.orientation_matrix[3], - psi.orientation_matrix[4], - ort_mtx.c[0], - ort_mtx.c[1], - ort_mtx.c[2]); - stream.printf(" | %+02d %+02d %+02d |\r\n", - ort_mtx.c[3], - ort_mtx.c[4], - ort_mtx.c[5]); - stream.printf(" | %+02d %+02d %+02d |\r\n", - ort_mtx.c[6], - ort_mtx.c[7], - ort_mtx.c[8]); - stream.printf("Reserved %02X | %d\r\n", psi.reserved, psi.reserved); - stream.printf("\r\n"); - - } - } -#endif - - - 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. "); - } - } + void setDebugCallback(BhyDebugMessageCallback cb); - static void handleISR() - { - __data_available = true; - } - - bool initImpl() - { - uint8_t product_id = 0; - - if (__handler.rst != SENSOR_PIN_NONE) { - pinMode(__handler.rst, OUTPUT); - } - - reset(); - - bhy2 = (struct bhy2_dev *)malloc(sizeof(struct bhy2_dev )); - BHY2_RLST_CHECK(!bhy2, " Device handler malloc failed!", false); - - switch (__handler.intf) { - case BHY2_I2C_INTERFACE: - // esp32s3 test I2C maximum read and write is 64 bytes - __max_rw_length = 64; - BHY2_RLST_CHECK(!__handler.u.i2c_dev.wire, "Wire ptr NULL", false); - if (!SensorInterfaces::setup_interfaces(__handler)) { - log_e("setup_interfaces failed"); - return false; - } - __error_code = bhy2_init(BHY2_I2C_INTERFACE, - SensorInterfaces::bhy2_i2c_read, - SensorInterfaces::bhy2_i2c_write, - SensorInterfaces::bhy2_delay_us, - __max_rw_length, &__handler, bhy2); - BHY2_RLST_CHECK(__error_code != BHY2_OK, "bhy2_init failed!", false); - // __error_code = bhy2_set_host_intf_ctrl(BHY2_I2C_INTERFACE, bhy2); - // BHY2_RLST_CHECK(__error_code != BHY2_OK, "bhy2_set_host_intf_ctrl failed!", false); - break; - - case BHY2_SPI_INTERFACE: - // esp32s3 test SPI maximum read and write is 256 bytes - __max_rw_length = 256; - BHY2_RLST_CHECK(!__handler.u.spi_dev.spi, "SPI ptr NULL", false); - if (!SensorInterfaces::setup_interfaces(__handler)) { - log_e("setup_interfaces failed"); - return false; - } - __error_code = bhy2_init(BHY2_SPI_INTERFACE, - SensorInterfaces::bhy2_spi_read, - SensorInterfaces::bhy2_spi_write, - SensorInterfaces::bhy2_delay_us, - __max_rw_length, - &__handler, - bhy2); - break; - default: - return false; - } - - __error_code = bhy2_soft_reset(bhy2); - BHY2_RLST_CHECK(__error_code != BHY2_OK, "reset bhy2 failed!", false); - - __error_code = bhy2_get_product_id(&product_id, bhy2); - BHY2_RLST_CHECK(__error_code != BHY2_OK, "bhy2_get_product_id failed!", false); - - - /* Check for a valid product ID */ - if (product_id != BHY2_PRODUCT_ID) { - log_e("Product ID read %X. Expected %X", product_id, BHY2_PRODUCT_ID); - return false; - } else { - log_i("BHI260/BHA260 found. Product ID read %X", product_id); - } - - // Set default interrupt configure - uint8_t data = 0, data_exp; - bhy2_get_host_interrupt_ctrl(&data, bhy2); - data &= ~BHY2_ICTL_DISABLE_STATUS_FIFO; /* Enable status interrupts */ - // data &= ~BHY2_ICTL_DISABLE_DEBUG; /* Enable debug interrupts */ - data |= BHY2_ICTL_DISABLE_DEBUG; /* Disable debug interrupts */ - data &= ~BHY2_ICTL_EDGE; /* Level */ - data &= ~BHY2_ICTL_ACTIVE_LOW; /* Active high */ - data &= ~BHY2_ICTL_OPEN_DRAIN; /* Push-pull */ - data_exp = data; - bhy2_set_host_interrupt_ctrl(data, bhy2); - bhy2_get_host_interrupt_ctrl(&data, bhy2); - if (data != data_exp) { - log_d("Expected Host Interrupt Control (0x07) to have value 0x%x but instead read 0x%x\r\n", data_exp, data); - } - /* Config status channel */ - bhy2_set_host_intf_ctrl(BHY2_HIF_CTRL_ASYNC_STATUS_CHANNEL, bhy2); - bhy2_get_host_intf_ctrl(&data, bhy2); - if (!(data & BHY2_HIF_CTRL_ASYNC_STATUS_CHANNEL)) { - log_d("Expected Host Interface Control (0x06) to have bit 0x%x to be set\r\n", BHY2_HIF_CTRL_ASYNC_STATUS_CHANNEL); - } - - /* - if (!__firmware) { - // Default write to ram - setFirmware(bhy2_firmware_image, sizeof(bhy2_firmware_image), false); - } - */ - - if (__boot_from_flash) { - if (__force_update) { - if ((__firmware == NULL) || (__firmware_size == 0)) { - log_e("No valid firmware is set. Please use the \"setFirmware\" method to set the valid firmware."); - return false; - } - __error_code = bhy2_soft_reset(bhy2); - BHY2_RLST_CHECK(__error_code != BHY2_OK, "reset bhy2 failed!", false); - log_i("Force update firmware."); - if (!uploadFirmware(__firmware, __firmware_size, __write_flash)) { - log_e("uploadFirmware failed!"); - return false; - } - } - if (!bootFromFlash()) { - return false; - } - } else { - if ((__firmware == NULL) || (__firmware_size == 0)) { - log_e("No valid firmware is set. Please use the \"setFirmware\" method to set the valid firmware."); - return false; - } - - // ** Upload firmware to RAM - if (!uploadFirmware(__firmware, __firmware_size, false)) { - log_e("uploadFirmware failed!"); - return false; - } - } - - uint16_t version = getKernelVersion(); - BHY2_RLST_CHECK(!version, "getKernelVersion failed!", false); - log_i("Boot successful. Kernel version %u.", version); - - //Set event callback - __error_code = bhy2_register_fifo_parse_callback(BHY2_SYS_ID_META_EVENT, BoschParse::parseMetaEvent, (void *)&__accuracy, bhy2); - BHY2_RLST_CHECK(__error_code != BHY2_OK, "bhy2_register_fifo_parse_callback failed!", false); - - __error_code = bhy2_register_fifo_parse_callback(BHY2_SYS_ID_META_EVENT_WU, BoschParse::parseMetaEvent, (void *)&__accuracy, bhy2); - BHY2_RLST_CHECK(__error_code != BHY2_OK, "bhy2_register_fifo_parse_callback failed!", false); - - // __error_code = bhy2_register_fifo_parse_callback(BHY2_SYS_ID_DEBUG_MSG, BoschParse::parseDebugMessage, NULL, bhy2); - // BHY2_RLST_CHECK(__error_code != BHY2_OK, "bhy2_register_fifo_parse_callback parseDebugMessage failed!", false); + /** + * @brief getPhySensorInfo + * @note Get all information about physical sensors + * @param sens_id: ID of the physical sensor + * @retval BoschPhySensorInfo Class + */ + BoschPhySensorInfo getPhySensorInfo(uint8_t sens_id); - //Set process buffer -#if (defined(ESP32) || defined(ARDUINO_ARCH_ESP32)) && defined(BOARD_HAS_PSRAM) - __pro_buf = (uint8_t *)ps_malloc(__pro_buf_size); -#else - __pro_buf = (uint8_t *)malloc(__pro_buf_size); -#endif - BHY2_RLST_CHECK(!__pro_buf, "process buffer malloc failed!", false); + /** + * @brief getSensorInfo + * @note Get all information about sensors + * @retval BoschSensorInfo Class + */ + BoschSensorInfo getSensorInfo(); - __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(__pro_buf); - return false; - } - /* Update the callback table to enable parsing of sensor hintr_ctrl */ - bhy2_update_virtual_sensor_list(bhy2); + /** + * @brief setMaxiTransferSize + * @note Set the maximum number of bytes transmitted by the interface , Called before begin + * @param size_of_bytes: The maximum transmission bytes of different platforms are different. + * Set it according to the platform. If not set, the default is 32 bytes. + * @retval None + */ + void setMaxiTransferSize(uint16_t size_of_bytes); - /* Get present virtual sensor */ - bhy2_get_virt_sensor_list(bhy2); +private: - // Only register valid sensor IDs - for (uint8_t i = 0; i < BHY2_SENSOR_ID_MAX; i++) { - if (bhy2_is_sensor_available(i, bhy2)) { - bhy2_register_fifo_parse_callback(i, BoschParse::parseData, NULL, bhy2); - } - } + /** + * @brief bootFromFlash + * @note Boot from external flash + * @retval bool true-> Success false-> failure + */ + bool bootFromFlash(); - if (__handler.irq != SENSOR_PIN_NONE) { -#if defined(ARDUINO_ARCH_RP2040) - attachInterrupt((pin_size_t)(__handler.irq), handleISR, (PinStatus )RISING); -#elif defined(ARDUINO_ARCH_NRF52) || defined(ARDUINO_ARCH_ESP32) || defined(ARDUINO_ARCH_STM32) - attachInterrupt(__handler.irq, handleISR, RISING); -#else -#error "Interrupt registration not implemented" -#endif - } + void print_boot_status(uint8_t boot_status); - return __error_code == BHY2_OK; - } + bool initImpl(bhy2_intf interface); protected: - struct bhy2_dev *bhy2 = NULL; - SensorLibConfigure __handler; - int8_t __error_code = 0; - static volatile bool __data_available; - uint8_t *__pro_buf = NULL; - size_t __pro_buf_size = BHY_PROCESS_BUFFER_SIZE; - const uint8_t *__firmware = NULL; - size_t __firmware_size = 0; - bool __write_flash = false; - bool __boot_from_flash = false; - bool __force_update = false; - uint16_t __max_rw_length = 32; - uint8_t __accuracy = 0; /* Accuracy is reported as a meta event. */ -}; - - -#endif /*defined(ARDUINO)*/ - + std::unique_ptr comm; + std::unique_ptr hal; + std::unique_ptr staticComm; + std::unique_ptr _bhy2; + int _rst; + int8_t _error_code; + uint8_t *_processBuffer; + size_t _processBufferSize; + const uint8_t *_firmware_stream; + size_t _firmware_size; + bool _write_flash; + bool _boot_from_flash; + bool _force_update; + int _max_rw_length; + uint8_t _accuracy; /* Accuracy is reported as a meta event. */ + bool _debug; + char _err_buffer[128]; +}; diff --git a/src/SensorBMA423.cpp b/src/SensorBMA423.cpp new file mode 100644 index 0000000..777b73a --- /dev/null +++ b/src/SensorBMA423.cpp @@ -0,0 +1,730 @@ +/** + * + * @license MIT License + * + * Copyright (c) 2022 lewis he + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * @file SensorBMA423.cpp + * @author Lewis He (lewishe@outlook.com) + * @date 2022-03-31 + * @note Most source code references come from the https://github.com/boschsensortec/BMA423-Sensor-API + * Simplification for Arduino + */ +#include "SensorBMA423.hpp" +#include "REG/BMA423Config.h" + +SensorBMA423::SensorBMA423() : comm(nullptr) {} + +SensorBMA423::~SensorBMA423() +{ + if (comm) { + comm->deinit(); + } +} + +#if defined(ARDUINO) +bool SensorBMA423::begin(TwoWire &wire, uint8_t addr, int sda, int scl) +{ + if (!beginCommon(comm, hal, wire, addr, sda, scl)) { + return false; + } + return initImpl(); +} + +#elif defined(ESP_PLATFORM) + +#if defined(USEING_I2C_LEGACY) +bool SensorBMA423::begin(i2c_port_t port_num, uint8_t addr, int sda, int scl) +{ + if (!beginCommon(comm, hal, port_num, addr, sda, scl)) { + return false; + } + return initImpl(); +} +#else /*USEING_I2C_LEGACY*/ +bool SensorBMA423::begin(i2c_master_bus_handle_t handle, uint8_t addr) +{ + if (!beginCommon(comm, hal, handle, addr)) { + return false; + } + return initImpl(); +} +#endif //ESP_PLATFORM +#endif //ARDUINO + + +bool SensorBMA423::begin(SensorCommCustom::CustomCallback callback, + SensorCommCustomHal::CustomHalCallback hal_callback, + uint8_t addr) +{ + if (!beginCommCustomCallback(COMM_CUSTOM, + callback, hal_callback, addr, comm, hal)) { + return false; + } + return initImpl(); +} + +void SensorBMA423::reset() +{ + comm->writeRegister(RESET_REG, 0xB6); + hal->delay(20); +} + +bool SensorBMA423::enablePowerSave() +{ + uint8_t val; + val = comm->readRegister(POWER_CONF_ADDR); + val |= ADVANCE_POWER_SAVE_MSK; + comm->writeRegister(POWER_CONF_ADDR, val); + return true; +} + +bool SensorBMA423::disablePowerSave() +{ + uint8_t val; + val = comm->readRegister(POWER_CONF_ADDR); + val &= ~(ADVANCE_POWER_SAVE_MSK); + comm->writeRegister(POWER_CONF_ADDR, val); + return true; +} + +void SensorBMA423::disableInterruptCtrl() +{ + comm->writeRegister(INIT_CTRL_ADDR, (uint8_t)0x00); +} + +void SensorBMA423::enableInterruptCtrl() +{ + comm->writeRegister(INIT_CTRL_ADDR, (uint8_t)0x01); +} + +bool SensorBMA423::enableAccelerometer() +{ + uint8_t val; + val = comm->readRegister(POWER_CTRL_ADDR); + val |= ACCEL_ENABLE_MSK; + comm->writeRegister(POWER_CTRL_ADDR, val); + return true; +} + +bool SensorBMA423::disableAccelerometer() +{ + uint8_t val; + val = comm->readRegister( POWER_CTRL_ADDR); + val &= (~ACCEL_ENABLE_MSK); + comm->writeRegister(POWER_CTRL_ADDR, val); + return true; +} + +bool SensorBMA423::configAccelerometer(AccelRange range, AccelODR odr, + BandWidth bw, + PerformanceMode perfMode ) + +{ + uint8_t buffer[2] = {0, 0}; + if (perfMode == PERF_CONTINUOUS_MODE) { + if (bw > BW_NORMAL_AVG4) { + return false; + } + } else if (perfMode == PERF_CIC_AVG_MODE) { + if (bw > BW_RES_AVG128) { + return false; + } + } else { + return false; + } + if ((odr < ODR_0_78HZ) || (odr > ODR_1600HZ)) { + return false; + } + + buffer[0] = odr & 0x0F; + buffer[0] |= (uint8_t)(bw << 4); + buffer[0] |= (uint8_t)(perfMode << 7); + buffer[1] = range & 0x03; + + /* Burst write is not possible in + suspend mode hence individual write is + used with hal->delay of 1 ms */ + comm->writeRegister(ACCEL_CONFIG_ADDR, buffer[0]); + hal->delay(2); + comm->writeRegister(ACCEL_CONFIG_ADDR + 1, buffer[1]); + return true; +} + + +bool SensorBMA423::getAccelRaw(int16_t *rawBuffer) +{ + uint8_t buffer[6] = {0}; + if (comm->readRegister(DATA_8_ADDR, buffer, 6) != -1) { + /* Accel data x axis */ + rawBuffer[0] = (int16_t)(buffer[1] << 8) | (buffer[0]); + /* Accel data y axis */ + rawBuffer[1] = (int16_t)(buffer[3] << 8) | (buffer[2]); + /* Accel data z axis */ + rawBuffer[2] = (int16_t)(buffer[5] << 8) | (buffer[4]); + } else { + return false; + } + return true; +} + +bool SensorBMA423::getAccelerometer(int16_t &x, int16_t &y, int16_t &z) +{ + int16_t raw[3]; + if (getAccelRaw(raw)) { + x = raw[0] / 16; + y = raw[1] / 16; + z = raw[2] / 16; + return true; + } + return false; +} + +float SensorBMA423::getTemperature(TemperatureUnit unit) +{ + int32_t raw = comm->readRegister(TEMPERATURE_ADDR); + /* '0' value read from the register corresponds to 23 degree C */ + raw = (raw * 1000) + (23 * 1000); + switch (unit) { + case TEMP_FAHRENHEIT: + /* Temperature in degree Fahrenheit */ + /* 1800 = 1.8 * 1000 */ + raw = ((raw / 1000) * 1800) + (32 * 1000); + break; + case TEMP_KELVIN: + /* Temperature in degree Kelvin */ + /* 273150 = 273.15 * 1000 */ + raw = raw + 273150; + break; + default: + break; + } + float res = (float)raw / (float)1000.0; + /* 0x80 - raw read from the register and 23 is the ambient raw added. + * If the raw read from register is 0x80, it means no valid + * information is available */ + if (((raw - 23) / 1000) == 0x80) { + return 0; + } + return res; +} + + +uint8_t SensorBMA423::direction() +{ + int16_t x = 0, y = 0, z = 0; + getAccelerometer(x, y, z); + uint16_t absX = abs(x); + uint16_t absY = abs(y); + uint16_t absZ = abs(z); + if ((absZ > absX) && (absZ > absY)) { + if (z > 0) { + return DIRECTION_TOP; + } else { + return DIRECTION_BOTTOM; + } + } else if ((absY > absX) && (absY > absZ)) { + if (y > 0) { + return DIRECTION_TOP_RIGHT; + } else { + return DIRECTION_BOTTOM_LEFT; + } + } else { + if (x < 0) { + return DIRECTION_BOTTOM_RIGHT; + } else { + return DIRECTION_TOP_LEFT; + } + } + return 0; +} + +bool SensorBMA423::setRemapAxes(SensorRemap remap) +{ + //Top + // No.1 REG: 0x3e -> 0x88 REG: 0x3f -> 0x0 + // No.2 REG: 0x3e -> 0xac REG: 0x3f -> 0x0 + // No.3 REG: 0x3e -> 0x85 REG: 0x3f -> 0x0 + // No.4 REG: 0x3e -> 0xa1 REG: 0x3f -> 0x0 + + // Bottom + // No.5 REG: 0x3e -> 0x81 REG: 0x3f -> 0x1 + // No.6 REG: 0x3e -> 0xa5 REG: 0x3f -> 0x1 + // No.7 REG: 0x3e -> 0x8c REG: 0x3f -> 0x1 + // No.8 REG: 0x3e -> 0xa8 REG: 0x3f -> 0x1 + + uint8_t configReg0[] = {0x88, 0xAC, 0x85, 0xA1, 0x81, 0xA5, 0x8C, 0xA8}; + if (remap > sizeof(configReg0) / sizeof(configReg0[0])) { + return false; + } + uint8_t buffer[FEATURE_SIZE] = {0}; + uint8_t index = AXES_REMAP_OFFSET; + if (comm->readRegister(FEATURE_CONFIG_ADDR, buffer, FEATURE_SIZE) == -1) { + return false; + } + buffer[index] = configReg0[remap]; + buffer[index + 1] = remap >= 4 ? 0x00 : 0x01; + return comm->writeRegister(FEATURE_CONFIG_ADDR, buffer, FEATURE_SIZE) != -1; +} + +bool SensorBMA423::setStepCounterWatermark(uint16_t watermark) +{ + uint8_t buffer[FEATURE_SIZE] = {0}; + uint8_t index = STEP_CNTR_OFFSET; + uint16_t wm_lsb = 0; + uint16_t wm_msb = 0; + int rslt; + uint16_t data = 0; + + rslt = comm->readRegister(FEATURE_CONFIG_ADDR, buffer, FEATURE_SIZE); + if (rslt != -1) { + wm_lsb = buffer[index]; + wm_msb = buffer[index + 1] << 8; + data = wm_lsb | wm_msb; + /* Sets only watermark bits in the complete 16 bits of data */ + data = ((data & ~(0x03FFU)) | (watermark & 0x03FFU)); + /* Splits 16 bits of data to individual 8 bits data */ + buffer[index] = (uint8_t)(data & 0x00FFU); + buffer[index + 1] = (uint8_t)((data & 0xFF00U) >> 8); + /* Writes stepcounter watermark settings in the sensor */ + rslt = comm->writeRegister(FEATURE_CONFIG_ADDR, buffer, FEATURE_SIZE); + } + return rslt != -1; +} + +bool SensorBMA423::disablePedometer() +{ + return enablePedometer(false); +} + +bool SensorBMA423::enablePedometer(bool enable) +{ + int rslt; + uint8_t buffer[FEATURE_SIZE] = {0}; + /* Step detector enable bit pos. is 1 byte ahead of the base address */ + uint8_t index = STEP_CNTR_OFFSET + 1; + rslt = comm->readRegister(FEATURE_CONFIG_ADDR, buffer, FEATURE_SIZE); + if (rslt != -1) { + buffer[index] = ((buffer[index] & ~0x08) | ((enable << 3) & 0x08)); + rslt = comm->writeRegister(FEATURE_CONFIG_ADDR, buffer, FEATURE_SIZE); + } + return rslt != -1; +} + +uint32_t SensorBMA423::getPedometerCounter() +{ + uint8_t buffer[4] = {0}; + /* Reads the step counter output data from the gpio register */ + int rslt = comm->readRegister(STEP_CNT_OUT_0_ADDR, buffer, 4); + if (rslt != -1) { + return ((uint32_t)buffer[0]) | ((uint32_t)buffer[1] << 8) | ((uint32_t)buffer[2] << 16) | ((uint32_t)buffer[3] << 24); + } + return 0; +} + +void SensorBMA423::resetPedometer() +{ + uint8_t buffer[FEATURE_SIZE] = {0}; + /* Reset bit is 1 byte ahead of base address */ + uint8_t index = STEP_CNTR_OFFSET + 1; + int rslt = comm->readRegister(FEATURE_CONFIG_ADDR, buffer, FEATURE_SIZE); + if (rslt != -1) { + buffer[index] = ((buffer[index] & ~0x04U) | ((1 << 2U) & 0x04U)); + comm->writeRegister(FEATURE_CONFIG_ADDR, buffer, FEATURE_SIZE); + } +} + +bool SensorBMA423::enableFeature(uint8_t feature, uint8_t enable) +{ + uint8_t buffer[FEATURE_SIZE] = {0}; + int rslt; + uint8_t len; + /* Update the length for read and write */ + update_len(&len, feature, enable); + rslt = comm->readRegister(FEATURE_CONFIG_ADDR, buffer, len); + if (rslt != -1) { + if (enable) { + /* Enables the feature */ + rslt = feature_enable(feature, len, buffer); + } else { + /* Disables the feature */ + rslt = feature_disable(feature, len, buffer); + } + } + return rslt != -1; +} + +uint16_t SensorBMA423::readIrqStatus() +{ + uint8_t data[2] = {0}; + if (comm->readRegister(INT_STAT_0_ADDR, data, 2) != -1) { + int_status = data[0] | (data[1] << 8); + return int_status; + } + return 0; +} + +uint16_t SensorBMA423::getIrqStatus() +{ + return int_status; +} + +bool SensorBMA423::configInterrupt( + /*! Trigger condition of interrupt pin */ + uint8_t edge_ctrl, + /*! Level of interrupt pin */ + uint8_t level, + /*! Behaviour of interrupt pin to open drain */ + uint8_t od, + /*! Output enable for interrupt pin */ + uint8_t output_en, + /*! Input enable for interrupt pin */ + uint8_t input_en, + /*! Variable used to select the interrupt pin1 or pin2 for interrupt configuration. */ + uint8_t int_line +) +{ + uint8_t interrupt_address_array[2] = {INT1_IO_CTRL_ADDR, INT2_IO_CTRL_ADDR}; + uint8_t data = 0; + if (int_line > 1) { + return false; + } + data = ((uint8_t)((edge_ctrl & INT_EDGE_CTRL_MASK) | + ((level << 1) & INT_LEVEL_MASK) | + ((od << 2) & INT_OPEN_DRAIN_MASK) | + ((output_en << 3) & INT_OUTPUT_EN_MASK) | + ((input_en << 4) & INT_INPUT_EN_MASK))); + + this->int_line = int_line; + + return comm->writeRegister(interrupt_address_array[int_line], &data, 1) != -1; +} + +bool SensorBMA423::configFeatureInterrupt(uint16_t feature_interrupt_mask, bool enable) +{ + return interruptMap(int_line, feature_interrupt_mask, enable); +} + + +bool SensorBMA423::enablePedometerIRQ() +{ + return (interruptMap(int_line, INT_STEP_CNTR, true)); +} + +bool SensorBMA423::enableTiltIRQ() +{ + return (interruptMap(int_line, INT_TILT, true)); +} + +bool SensorBMA423::enableWakeupIRQ() +{ + return (interruptMap(int_line, INT_WAKEUP, true)); +} + +bool SensorBMA423::enableAnyNoMotionIRQ() +{ + return (interruptMap(int_line, INT_ANY_NO_MOTION, true)); +} + +bool SensorBMA423::enableActivityIRQ() +{ + return (interruptMap(int_line, INT_ACTIVITY, true)); +} + +bool SensorBMA423::disablePedometerIRQ() +{ + return (interruptMap(int_line, INT_STEP_CNTR, false)); +} + +bool SensorBMA423::disableTiltIRQ() +{ + return (interruptMap(int_line, INT_TILT, false)); +} + +bool SensorBMA423::disableWakeupIRQ() +{ + return (interruptMap(int_line, INT_WAKEUP, false)); +} + +bool SensorBMA423::disableAnyNoMotionIRQ() +{ + return (interruptMap(int_line, INT_ANY_NO_MOTION, false)); +} + +bool SensorBMA423::disableActivityIRQ() +{ + return (interruptMap(int_line, INT_ACTIVITY, false)); +} + + +bool SensorBMA423::isActivity() +{ + return (int_status & ACTIVITY_INT); +} + +bool SensorBMA423::isTilt() +{ + return (int_status & TILT_INT); +} + +bool SensorBMA423::isDoubleTap() +{ + return (int_status & WAKEUP_INT); +} + +bool SensorBMA423::isAnyNoMotion() +{ + return (int_status & ACTIVITY_INT); +} + +bool SensorBMA423::isPedometer() +{ + return (int_status & STEP_CNTR_INT); +} + +bool SensorBMA423::interruptMap(uint8_t int_line, uint16_t int_map, uint8_t enable) +{ + int rslt; + uint8_t data[3] = {0, 0, 0}; + uint8_t index[2] = {INT_MAP_1_ADDR, INT_MAP_2_ADDR}; + rslt = comm->readRegister(INT_MAP_1_ADDR, data, 3); + if (enable) { + /* Feature interrupt mapping */ + data[int_line] |= (uint8_t)(int_map & (0x00FF)); + /* Hardware interrupt mapping */ + if (int_line == INTR2_MAP) + data[2] |= (uint8_t)((int_map & (0xFF00)) >> 4); + else + data[2] |= (uint8_t)((int_map & (0xFF00)) >> 8); + + rslt = comm->writeRegister(index[int_line], &data[int_line], 1); + rslt = comm->writeRegister(INT_MAP_DATA_ADDR, &data[2], 1); + + } else { + /* Feature interrupt un-mapping */ + data[int_line] &= (~(uint8_t)(int_map & (0x00FF))); + /* Hardware interrupt un-mapping */ + if (int_line == INTR2_MAP) + data[2] &= (~(uint8_t)((int_map & (0xFF00)) >> 4)); + else + data[2] &= (~(uint8_t)((int_map & (0xFF00)) >> 8)); + + rslt = comm->writeRegister(index[int_line], &data[int_line], 1); + rslt = comm->writeRegister(INT_MAP_DATA_ADDR, &data[2], 1); + + } + return rslt != -1; +} + +/*! + * @brief This API sets the interrupt mode in the sensor. + */ +bool SensorBMA423::setInterruptMode(uint8_t mode) +{ + if (mode == NON_LATCH_MODE || mode == LATCH_MODE) + return comm->writeRegister(INTR_LATCH_ADDR, &mode, 1) != -1; + return false; +} + + +bool SensorBMA423::feature_disable(uint8_t feature, uint8_t len, uint8_t *buffer) +{ + uint8_t index = 0; + + /* Disable step counter */ + if ((feature & FEATURE_STEP_CNTR) > 0) { + /* Step counter enable bit pos. is 1 byte ahead of the + base address */ + index = STEP_CNTR_OFFSET + 1; + buffer[index] = buffer[index] & (~STEP_CNTR_EN_MSK); + } + + /* Disable activity */ + if ((feature & FEATURE_ACTIVITY) > 0) { + /* Activity enable bit pos. is 1 byte ahead of the + base address */ + index = STEP_CNTR_OFFSET + 1; + buffer[index] = buffer[index] & (~ACTIVITY_EN_MSK); + } + /* Disable tilt */ + if ((feature & FEATURE_TILT) > 0) { + /* Tilt enable bit pos. is the base address(0x3A) of tilt */ + index = TILT_OFFSET; + buffer[index] = buffer[index] & (~TILT_EN_MSK); + } + + /* Disable wakeup */ + if ((feature & FEATURE_WAKEUP) > 0) { + /* Tilt enable bit pos. is the base address(0x38) of wakeup */ + index = WAKEUP_OFFSET; + buffer[index] = buffer[index] & (~WAKEUP_EN_MSK); + } + + /* Disable anymotion/nomotion */ + if ((feature & FEATURE_ANY_MOTION) > 0 || (feature & FEATURE_NO_MOTION) > 0) { + /* Any/Nomotion enable bit pos. is 1 bytes ahead of the + any/nomotion base address(0x00) */ + index = 1; + + if ((feature & FEATURE_ANY_MOTION) > 0) { + /* Disable anymotion */ + buffer[index] = buffer[index] | ANY_NO_MOTION_SEL_MSK; + } else { + /* Disable nomotion */ + buffer[index] = buffer[index] & (~ANY_NO_MOTION_SEL_MSK); + } + /* Any/Nomotion axis enable bit pos. is 3 byte ahead of the + any/nomotion base address(0x00) */ + index = 3; + buffer[index] = buffer[index] & (~ANY_NO_MOTION_AXIS_EN_MSK); + } + /* Write the configured settings in the sensor */ + return comm->writeRegister(FEATURE_CONFIG_ADDR, buffer, len) != -1; +} + +int SensorBMA423::feature_enable(uint8_t feature, uint8_t len, uint8_t *buffer) +{ + uint8_t index = 0; + + /* Enable step counter */ + if ((feature & FEATURE_STEP_CNTR) > 0) { + /* Step counter enable bit pos. is 1 byte ahead of the + base address */ + index = STEP_CNTR_OFFSET + 1; + buffer[index] = buffer[index] | STEP_CNTR_EN_MSK; + } + + /* Enable activity */ + if ((feature & FEATURE_ACTIVITY) > 0) { + /* Activity enable bit pos. is 1 byte ahead of the + base address */ + index = STEP_CNTR_OFFSET + 1; + buffer[index] = buffer[index] | ACTIVITY_EN_MSK; + } + /* Enable tilt */ + if ((feature & FEATURE_TILT) > 0) { + /* Tilt enable bit pos. is the base address(0x3A) of tilt */ + index = TILT_OFFSET; + buffer[index] = buffer[index] | TILT_EN_MSK; + } + + /* Enable wakeup */ + if ((feature & FEATURE_WAKEUP) > 0) { + /* Wakeup enable bit pos. is the base address(0x38) of wakeup */ + index = WAKEUP_OFFSET; + buffer[index] = buffer[index] | WAKEUP_EN_MSK; + } + + /* Enable anymotion/nomotion */ + if ((feature & FEATURE_ANY_MOTION) > 0 || (feature & FEATURE_NO_MOTION) > 0) { + /* Any/Nomotion enable bit pos. is 1 bytes ahead of the + any/nomotion base address(0x00) */ + index = 1; + + if ((feature & FEATURE_ANY_MOTION) > 0) { + /* Enable anymotion */ + buffer[index] = buffer[index] & (~ANY_NO_MOTION_SEL_MSK); + } else { + /* Enable nomotion */ + buffer[index] = buffer[index] | ANY_NO_MOTION_SEL_MSK; + } + } + + /* Write the feature enable settings in the sensor */ + return comm->writeRegister(FEATURE_CONFIG_ADDR, buffer, len) != -1; +} + +void SensorBMA423::update_len(uint8_t *len, uint8_t feature, uint8_t enable) +{ + uint8_t length = FEATURE_SIZE; + + if ((feature == FEATURE_ANY_MOTION) || (feature == FEATURE_NO_MOTION)) { + /* Change the feature length to 2 for reading and writing of 2 bytes for + any/no-motion enable */ + length = ANYMOTION_EN_LEN; + + /* Read and write 4 byte to disable the any/no motion completely along with + all axis */ + if (!enable) { + /*Change the feature length to 4 for reading and writing + of 4 bytes for any/no-motion enable */ + length = length + 2; + } + } + *len = length; +} + +bool SensorBMA423::configure() +{ + uint8_t val; + val = comm->readRegister(INTERNAL_STAT); + if (val == ASIC_INITIALIZED) { + log_d("No need configure!"); + readIrqStatus(); //clear irq status + return true; + } + + disablePowerSave(); + hal->delay(1); + disableInterruptCtrl(); + + + const uint8_t *stream_data = bma423_config_file; + const uint8_t maxReadWriteLength = 32; + + for (size_t index = 0; index < CONFIG_STREAM_SIZE; index += maxReadWriteLength) { + uint8_t msb = (uint8_t)((index / 2) >> 4); + uint8_t lsb = ((index / 2) & 0x0F); + comm->writeRegister(RESERVED_REG_5B_ADDR, lsb); + comm->writeRegister(RESERVED_REG_5C_ADDR, msb); + comm->writeRegister(FEATURE_CONFIG_ADDR, (uint8_t *)(stream_data + index), maxReadWriteLength); + } + + enableInterruptCtrl(); + + hal->delay(150); + + val = comm->readRegister(INTERNAL_STAT); + if (val == ASIC_INITIALIZED) { + log_d("BMA configure SUCCESS!"); + } else { + log_d("BMA configure FAILED!"); + } + return val == ASIC_INITIALIZED; +} + +bool SensorBMA423::initImpl() +{ + uint8_t id = 0x00; + int retry = 5; + while (retry--) { + id = comm->readRegister(CHIP_ID_ADDR); + if (id != CHIP_ID) { + reset(); + } + } + if (id == CHIP_ID) { + return configure(); + } + log_d("ChipID:0x%x should be 0x%x", id, CHIP_ID); + return false; +} + diff --git a/src/SensorBMA423.hpp b/src/SensorBMA423.hpp index 41ecabc..51cb5a3 100644 --- a/src/SensorBMA423.hpp +++ b/src/SensorBMA423.hpp @@ -31,14 +31,11 @@ #pragma once #include "REG/BMA423Constants.h" -#include "SensorCommon.tpp" +#include "SensorPlatform.hpp" -class SensorBMA423 : - public SensorCommon +class SensorBMA423 : public BMA423Constants { - friend class SensorCommon; public: - enum AccelRange { RANGE_2G, RANGE_4G, @@ -81,7 +78,7 @@ class SensorBMA423 : enum TemperatureUnit { TEMP_DEG, - TEMP_FAHREN, + TEMP_FAHRENHEIT, TEMP_KELVIN, }; @@ -135,712 +132,138 @@ class SensorBMA423 : INT_ANY_NO_MOTION = 0x40, }; + SensorBMA423(); + + ~SensorBMA423(); + #if defined(ARDUINO) - SensorBMA423(PLATFORM_WIRE_TYPE &w, int sda = DEFAULT_SDA, int scl = DEFAULT_SCL, uint8_t addr = BMA423_SLAVE_ADDRESS) - { - __wire = &w; - __sda = sda; - __scl = scl; - __addr = addr; - } -#endif - - SensorBMA423() - { -#if defined(ARDUINO) - __wire = &Wire; - __sda = DEFAULT_SDA; - __scl = DEFAULT_SCL; -#endif - __addr = BMA423_SLAVE_ADDRESS; - } + bool begin(TwoWire &wire, uint8_t addr = BMA423_I2C_ADDR_SECONDARY, int sda = -1, int scl = -1); - ~SensorBMA423() - { - deinit(); - } +#elif defined(ESP_PLATFORM) +#if defined(USEING_I2C_LEGACY) + bool begin(i2c_port_t port_num, uint8_t addr = BMA423_I2C_ADDR_SECONDARY, int sda = -1, int scl = -1); +#else + bool begin(i2c_master_bus_handle_t handle, uint8_t addr = BMA423_I2C_ADDR_SECONDARY); +#endif //ESP_PLATFORM +#endif //ARDUINO -#if defined(ARDUINO) - bool init(PLATFORM_WIRE_TYPE &w, int sda = DEFAULT_SDA, int scl = DEFAULT_SCL, uint8_t addr = BMA423_SLAVE_ADDRESS) - { - return SensorCommon::begin(w, addr, sda, scl); - } -#endif - - - void deinit() - { - // end(); - } - - void reset() - { - writeRegister(BMA423_RESET_REG, 0xB6); - delay(20); - } - - bool enablePowerSave() - { - uint8_t val; - - val = readRegister(BMA4_POWER_CONF_ADDR); - val |= BMA4_ADVANCE_POWER_SAVE_MSK; - writeRegister(BMA4_POWER_CONF_ADDR, val); - return true; - } - - bool disablePowerSave() - { - uint8_t val; - val = readRegister(BMA4_POWER_CONF_ADDR); - val &= ~(BMA4_ADVANCE_POWER_SAVE_MSK); - writeRegister(BMA4_POWER_CONF_ADDR, val); - return true; - } - - void disableInterruptCtrl() - { - writeRegister(BMA4_INIT_CTRL_ADDR, 0x00); - } - - void enableInterruptCtrl() - { - writeRegister(BMA4_INIT_CTRL_ADDR, 0x01); - } - - - bool enableAccelerometer() - { - uint8_t val; - val = readRegister(BMA4_POWER_CTRL_ADDR); - val |= BMA4_ACCEL_ENABLE_MSK; - writeRegister(BMA4_POWER_CTRL_ADDR, val); - return true; - } - - bool disableAccelerometer() - { - uint8_t val; - val = readRegister( BMA4_POWER_CTRL_ADDR); - val &= (~BMA4_ACCEL_ENABLE_MSK); - writeRegister(BMA4_POWER_CTRL_ADDR, val); - return true; - } + bool begin(SensorCommCustom::CustomCallback callback, + SensorCommCustomHal::CustomHalCallback hal_callback, + uint8_t addr = BMA423_I2C_ADDR_SECONDARY); + + void reset(); + + bool enablePowerSave(); + + bool disablePowerSave(); + + void disableInterruptCtrl(); + + void enableInterruptCtrl(); + + bool enableAccelerometer(); + + bool disableAccelerometer(); bool configAccelerometer(AccelRange range = RANGE_4G, AccelODR odr = ODR_200HZ, BandWidth bw = BW_NORMAL_AVG4, - PerformanceMode perfMode = PERF_CONTINUOUS_MODE) - - { - uint8_t buffer[2] = {0, 0}; - if (perfMode == PERF_CONTINUOUS_MODE) { - if (bw > BW_NORMAL_AVG4) { - return false; - } - } else if (perfMode == PERF_CIC_AVG_MODE) { - if (bw > BW_RES_AVG128) { - return false; - } - } else { - return false; - } - if ((odr < ODR_0_78HZ) || (odr > ODR_1600HZ)) { - return false; - } - - buffer[0] = odr & 0x0F; - buffer[0] |= (uint8_t)(bw << 4); - buffer[0] |= (uint8_t)(perfMode << 7); - buffer[1] = range & 0x03; - - /* Burst write is not possible in - suspend mode hence individual write is - used with delay of 1 ms */ - writeRegister(BMA4_ACCEL_CONFIG_ADDR, buffer[0]); - delay(2); - writeRegister(BMA4_ACCEL_CONFIG_ADDR + 1, buffer[1]); - return true; - } - - - bool getAccelRaw(int16_t *rawBuffer) - { - uint8_t buffer[6] = {0}; - if (readRegister(BMA4_DATA_8_ADDR, buffer, 6) != DEV_WIRE_ERR) { - /* Accel data x axis */ - rawBuffer[0] = (int16_t)(buffer[1] << 8) | (buffer[0]); - /* Accel data y axis */ - rawBuffer[1] = (int16_t)(buffer[3] << 8) | (buffer[2]); - /* Accel data z axis */ - rawBuffer[2] = (int16_t)(buffer[5] << 8) | (buffer[4]); - } else { - return false; - } - return true; - } - - bool getAccelerometer(int16_t &x, int16_t &y, int16_t &z) - { - int16_t raw[3]; - if (getAccelRaw(raw)) { - x = raw[0] / 16; - y = raw[1] / 16; - z = raw[2] / 16; - return true; - } - return false; - } - - float getTemperature(TemperatureUnit unit) - { - int32_t raw = readRegister(BMA4_TEMPERATURE_ADDR); - /* '0' value read from the register corresponds to 23 degree C */ - raw = (raw * 1000) + (23 * 1000); - switch (unit) { - case TEMP_FAHREN: - /* Temperature in degree Fahrenheit */ - /* 1800 = 1.8 * 1000 */ - raw = ((raw / 1000) * 1800) + (32 * 1000); - break; - case TEMP_KELVIN: - /* Temperature in degree Kelvin */ - /* 273150 = 273.15 * 1000 */ - raw = raw + 273150; - break; - default: - break; - } - float res = (float)raw / (float)1000.0; - /* 0x80 - raw read from the register and 23 is the ambient raw added. - * If the raw read from register is 0x80, it means no valid - * information is available */ - if (((raw - 23) / 1000) == 0x80) { - return 0; - } - return res; - } - - - uint8_t direction() - { - int16_t x = 0, y = 0, z = 0; - getAccelerometer(x, y, z); - uint16_t absX = abs(x); - uint16_t absY = abs(y); - uint16_t absZ = abs(z); - if ((absZ > absX) && (absZ > absY)) { - if (z > 0) { - return DIRECTION_TOP; - } else { - return DIRECTION_BOTTOM; - } - } else if ((absY > absX) && (absY > absZ)) { - if (y > 0) { - return DIRECTION_TOP_RIGHT; - } else { - return DIRECTION_BOTTOM_LEFT; - } - } else { - if (x < 0) { - return DIRECTION_BOTTOM_RIGHT; - } else { - return DIRECTION_TOP_LEFT; - } - } - return 0; - } - - bool setRemapAxes(SensorRemap remap) - { - //Top - // No.1 REG: 0x3e -> 0x88 REG: 0x3f -> 0x0 - // No.2 REG: 0x3e -> 0xac REG: 0x3f -> 0x0 - // No.3 REG: 0x3e -> 0x85 REG: 0x3f -> 0x0 - // No.4 REG: 0x3e -> 0xa1 REG: 0x3f -> 0x0 - - // Bottom - // No.5 REG: 0x3e -> 0x81 REG: 0x3f -> 0x1 - // No.6 REG: 0x3e -> 0xa5 REG: 0x3f -> 0x1 - // No.7 REG: 0x3e -> 0x8c REG: 0x3f -> 0x1 - // No.8 REG: 0x3e -> 0xa8 REG: 0x3f -> 0x1 - - uint8_t configReg0[] = {0x88, 0xAC, 0x85, 0xA1, 0x81, 0xA5, 0x8C, 0xA8}; - if (remap > sizeof(configReg0) / sizeof(configReg0[0])) { - return false; - } - uint8_t buffer[BMA423_FEATURE_SIZE] = {0}; - uint8_t index = BMA423_AXES_REMAP_OFFSET; - if (readRegister(BMA4_FEATURE_CONFIG_ADDR, buffer, BMA423_FEATURE_SIZE) == DEV_WIRE_ERR) { - return false; - } - buffer[index] = configReg0[remap]; - buffer[index + 1] = remap >= 4 ? 0x00 : 0x01; - return writeRegister(BMA4_FEATURE_CONFIG_ADDR, buffer, BMA423_FEATURE_SIZE) != DEV_WIRE_ERR; - } - - - - - bool setStepCounterWatermark(uint16_t watermark) - { - uint8_t buffer[BMA423_FEATURE_SIZE] = {0}; - uint8_t index = BMA423_STEP_CNTR_OFFSET; - uint16_t wm_lsb = 0; - uint16_t wm_msb = 0; - int rslt; - uint16_t data = 0; - - rslt = readRegister(BMA4_FEATURE_CONFIG_ADDR, buffer, BMA423_FEATURE_SIZE); - if (rslt != DEV_WIRE_ERR) { - wm_lsb = buffer[index]; - wm_msb = buffer[index + 1] << 8; - data = wm_lsb | wm_msb; - /* Sets only watermark bits in the complete 16 bits of data */ - data = ((data & ~(0x03FFU)) | (watermark & 0x03FFU)); - /* Splits 16 bits of data to individual 8 bits data */ - buffer[index] = (uint8_t)(data & 0x00FFU); - buffer[index + 1] = (uint8_t)((data & 0xFF00U) >> 8); - /* Writes stepcounter watermark settings in the sensor */ - rslt = writeRegister(BMA4_FEATURE_CONFIG_ADDR, buffer, BMA423_FEATURE_SIZE); - } - return rslt != DEV_WIRE_ERR; - } - - bool disablePedometer() - { - return enablePedometer(false); - } - - bool enablePedometer(bool enable = true) - { - int rslt; - uint8_t buffer[BMA423_FEATURE_SIZE] = {0}; - /* Step detector enable bit pos. is 1 byte ahead of the base address */ - uint8_t index = BMA423_STEP_CNTR_OFFSET + 1; - rslt = readRegister(BMA4_FEATURE_CONFIG_ADDR, buffer, BMA423_FEATURE_SIZE); - if (rslt != DEV_WIRE_ERR) { - buffer[index] = ((buffer[index] & ~0x08) | ((enable << 3) & 0x08)); - rslt = writeRegister(BMA4_FEATURE_CONFIG_ADDR, buffer, BMA423_FEATURE_SIZE); - } - return rslt != DEV_WIRE_ERR; - } - - uint32_t getPedometerCounter() - { - uint8_t buffer[4] = {0}; - /* Reads the step counter output data from the gpio register */ - int rslt = readRegister(BMA4_STEP_CNT_OUT_0_ADDR, buffer, 4); - if (rslt != DEV_WIRE_ERR) { - return ((uint32_t)buffer[0]) | ((uint32_t)buffer[1] << 8) | ((uint32_t)buffer[2] << 16) | ((uint32_t)buffer[3] << 24); - } - return DEV_WIRE_NONE; - } - - void resetPedometer() - { - uint8_t buffer[BMA423_FEATURE_SIZE] = {0}; - /* Reset bit is 1 byte ahead of base address */ - uint8_t index = BMA423_STEP_CNTR_OFFSET + 1; - int rslt = readRegister(BMA4_FEATURE_CONFIG_ADDR, buffer, BMA423_FEATURE_SIZE); - if (rslt != DEV_WIRE_ERR) { - buffer[index] = ((buffer[index] & ~0x04U) | ((1 << 2U) & 0x04U)); - writeRegister(BMA4_FEATURE_CONFIG_ADDR, buffer, BMA423_FEATURE_SIZE); - } - } - - bool enableFeature(uint8_t feature, uint8_t enable) - { - uint8_t buffer[BMA423_FEATURE_SIZE] = {0}; - int rslt; - uint8_t len; - /* Update the length for read and write */ - update_len(&len, feature, enable); - rslt = readRegister(BMA4_FEATURE_CONFIG_ADDR, buffer, len); - if (rslt != DEV_WIRE_ERR) { - if (enable) { - /* Enables the feature */ - rslt = feature_enable(feature, len, buffer); - } else { - /* Disables the feature */ - rslt = feature_disable(feature, len, buffer); - } - } - return rslt != DEV_WIRE_ERR; - } - - uint16_t readIrqStatus() - { - uint8_t data[2] = {0}; - if (readRegister(BMA4_INT_STAT_0_ADDR, data, 2) != DEV_WIRE_ERR) { - int_status = data[0] | (data[1] << 8); - return int_status; - } - return DEV_WIRE_NONE; - } - - uint16_t getIrqStatus() - { - return int_status; - } + PerformanceMode perfMode = PERF_CONTINUOUS_MODE); + + bool getAccelRaw(int16_t *rawBuffer); + + bool getAccelerometer(int16_t &x, int16_t &y, int16_t &z); + + float getTemperature(TemperatureUnit unit); + + uint8_t direction(); + + bool setRemapAxes(SensorRemap remap); + + bool setStepCounterWatermark(uint16_t watermark); + + bool disablePedometer(); + + bool enablePedometer(bool enable = true); + + uint32_t getPedometerCounter(); + + void resetPedometer(); + + bool enableFeature(uint8_t feature, uint8_t enable); + + uint16_t readIrqStatus(); + + uint16_t getIrqStatus(); bool configInterrupt( /*! Trigger condition of interrupt pin */ - uint8_t edge_ctrl = BMA4_LEVEL_TRIGGER, + uint8_t edge_ctrl = LEVEL_TRIGGER, /*! Level of interrupt pin */ - uint8_t level = BMA4_ACTIVE_HIGH, + uint8_t level = ACTIVE_HIGH, /*! Behaviour of interrupt pin to open drain */ - uint8_t od = BMA4_PUSH_PULL, + uint8_t od = PUSH_PULL, /*! Output enable for interrupt pin */ - uint8_t output_en = BMA4_OUTPUT_ENABLE, + uint8_t output_en = OUTPUT_ENABLE, /*! Input enable for interrupt pin */ - uint8_t input_en = BMA4_INPUT_DISABLE, + uint8_t input_en = INPUT_DISABLE, /*! Variable used to select the interrupt pin1 or pin2 for interrupt configuration. */ - uint8_t int_line = BMA4_INTR1_MAP - ) - { - uint8_t interrupt_address_array[2] = {BMA4_INT1_IO_CTRL_ADDR, BMA4_INT2_IO_CTRL_ADDR}; - uint8_t data = 0; - if (int_line > 1) { - return false; - } - data = ((uint8_t)((edge_ctrl & BMA4_INT_EDGE_CTRL_MASK) | - ((level << 1) & BMA4_INT_LEVEL_MASK) | - ((od << 2) & BMA4_INT_OPEN_DRAIN_MASK) | - ((output_en << 3) & BMA4_INT_OUTPUT_EN_MASK) | - ((input_en << 4) & BMA4_INT_INPUT_EN_MASK))); - - this->int_line = int_line; - - return writeRegister(interrupt_address_array[int_line], &data, 1) != DEV_WIRE_ERR; - } - - bool configFeatureInterrupt(uint16_t feature_interrupt_mask, bool enable) - { - return interruptMap(int_line, feature_interrupt_mask, enable); - } - - - bool enablePedometerIRQ() - { - return (interruptMap(int_line, INT_STEP_CNTR, true)); - } - - bool enableTiltIRQ() - { - return (interruptMap(int_line, INT_TILT, true)); - } - - bool enableWakeupIRQ() - { - return (interruptMap(int_line, INT_WAKEUP, true)); - } - - bool enableAnyNoMotionIRQ() - { - return (interruptMap(int_line, INT_ANY_NO_MOTION, true)); - } - - bool enableActivityIRQ() - { - return (interruptMap(int_line, INT_ACTIVITY, true)); - } - - bool disablePedometerIRQ() - { - return (interruptMap(int_line, INT_STEP_CNTR, false)); - } - - bool disableTiltIRQ() - { - return (interruptMap(int_line, INT_TILT, false)); - } - - bool disableWakeupIRQ() - { - return (interruptMap(int_line, INT_WAKEUP, false)); - } - - bool disableAnyNoMotionIRQ() - { - return (interruptMap(int_line, INT_ANY_NO_MOTION, false)); - } - - bool disableActivityIRQ() - { - return (interruptMap(int_line, INT_ACTIVITY, false)); - } - - - inline bool isActivity() - { - return (int_status & BMA423_ACTIVITY_INT); - } - - inline bool isTilt() - { - return (int_status & BMA423_TILT_INT); - } - - inline bool isDoubleTap() - { - return (int_status & BMA423_WAKEUP_INT); - } - - inline bool isAnyNoMotion() - { - return (int_status & BMA423_ACTIVITY_INT); - } - - inline bool isPedometer() - { - return (int_status & BMA423_STEP_CNTR_INT); - } + uint8_t int_line = INTR1_MAP + ); + + bool configFeatureInterrupt(uint16_t feature_interrupt_mask, bool enable); + + bool enablePedometerIRQ(); + + bool enableTiltIRQ(); + + bool enableWakeupIRQ(); + + bool enableAnyNoMotionIRQ(); + + bool enableActivityIRQ(); + + bool disablePedometerIRQ(); + + bool disableTiltIRQ(); + + bool disableWakeupIRQ(); + + bool disableAnyNoMotionIRQ(); + + bool disableActivityIRQ(); + + bool isActivity(); + + bool isTilt(); + + bool isDoubleTap(); + + bool isAnyNoMotion(); + + bool isPedometer(); private: - bool interruptMap(uint8_t int_line, uint16_t int_map, uint8_t enable) - { - int rslt; - uint8_t data[3] = {0, 0, 0}; - uint8_t index[2] = {BMA4_INT_MAP_1_ADDR, BMA4_INT_MAP_2_ADDR}; - rslt = readRegister(BMA4_INT_MAP_1_ADDR, data, 3); - if (enable) { - /* Feature interrupt mapping */ - data[int_line] |= (uint8_t)(int_map & (0x00FF)); - /* Hardware interrupt mapping */ - if (int_line == BMA4_INTR2_MAP) - data[2] |= (uint8_t)((int_map & (0xFF00)) >> 4); - else - data[2] |= (uint8_t)((int_map & (0xFF00)) >> 8); - - rslt = writeRegister(index[int_line], &data[int_line], 1); - rslt = writeRegister(BMA4_INT_MAP_DATA_ADDR, &data[2], 1); - - } else { - /* Feature interrupt un-mapping */ - data[int_line] &= (~(uint8_t)(int_map & (0x00FF))); - /* Hardware interrupt un-mapping */ - if (int_line == BMA4_INTR2_MAP) - data[2] &= (~(uint8_t)((int_map & (0xFF00)) >> 4)); - else - data[2] &= (~(uint8_t)((int_map & (0xFF00)) >> 8)); - - rslt = writeRegister(index[int_line], &data[int_line], 1); - rslt = writeRegister(BMA4_INT_MAP_DATA_ADDR, &data[2], 1); - - } - return rslt != DEV_WIRE_ERR; - } + bool interruptMap(uint8_t int_line, uint16_t int_map, uint8_t enable); /*! * @brief This API sets the interrupt mode in the sensor. */ - bool setInterruptMode(uint8_t mode) - { - if (mode == BMA4_NON_LATCH_MODE || mode == BMA4_LATCH_MODE) - return writeRegister(BMA4_INTR_LATCH_ADDR, &mode, 1) != DEV_WIRE_ERR; - return false; - } - - - bool feature_disable(uint8_t feature, uint8_t len, uint8_t *buffer) - { - uint8_t index = 0; - - /* Disable step counter */ - if ((feature & FEATURE_STEP_CNTR) > 0) { - /* Step counter enable bit pos. is 1 byte ahead of the - base address */ - index = BMA423_STEP_CNTR_OFFSET + 1; - buffer[index] = buffer[index] & (~BMA423_STEP_CNTR_EN_MSK); - } - - /* Disable activity */ - if ((feature & FEATURE_ACTIVITY) > 0) { - /* Activity enable bit pos. is 1 byte ahead of the - base address */ - index = BMA423_STEP_CNTR_OFFSET + 1; - buffer[index] = buffer[index] & (~BMA423_ACTIVITY_EN_MSK); - } - /* Disable tilt */ - if ((feature & FEATURE_TILT) > 0) { - /* Tilt enable bit pos. is the base address(0x3A) of tilt */ - index = BMA423_TILT_OFFSET; - buffer[index] = buffer[index] & (~BMA423_TILT_EN_MSK); - } - - /* Disable wakeup */ - if ((feature & FEATURE_WAKEUP) > 0) { - /* Tilt enable bit pos. is the base address(0x38) of wakeup */ - index = BMA423_WAKEUP_OFFSET; - buffer[index] = buffer[index] & (~BMA423_WAKEUP_EN_MSK); - } - - /* Disable anymotion/nomotion */ - if ((feature & FEATURE_ANY_MOTION) > 0 || (feature & FEATURE_NO_MOTION) > 0) { - /* Any/Nomotion enable bit pos. is 1 bytes ahead of the - any/nomotion base address(0x00) */ - index = 1; - - if ((feature & FEATURE_ANY_MOTION) > 0) { - /* Disable anymotion */ - buffer[index] = buffer[index] | BMA423_ANY_NO_MOTION_SEL_MSK; - } else { - /* Disable nomotion */ - buffer[index] = buffer[index] & (~BMA423_ANY_NO_MOTION_SEL_MSK); - } - /* Any/Nomotion axis enable bit pos. is 3 byte ahead of the - any/nomotion base address(0x00) */ - index = 3; - buffer[index] = buffer[index] & (~BMA423_ANY_NO_MOTION_AXIS_EN_MSK); - } - /* Write the configured settings in the sensor */ - return writeRegister(BMA4_FEATURE_CONFIG_ADDR, buffer, len) != DEV_WIRE_ERR; - } - - int feature_enable(uint8_t feature, uint8_t len, uint8_t *buffer) - { - uint8_t index = 0; - - /* Enable step counter */ - if ((feature & FEATURE_STEP_CNTR) > 0) { - /* Step counter enable bit pos. is 1 byte ahead of the - base address */ - index = BMA423_STEP_CNTR_OFFSET + 1; - buffer[index] = buffer[index] | BMA423_STEP_CNTR_EN_MSK; - } - - /* Enable activity */ - if ((feature & FEATURE_ACTIVITY) > 0) { - /* Activity enable bit pos. is 1 byte ahead of the - base address */ - index = BMA423_STEP_CNTR_OFFSET + 1; - buffer[index] = buffer[index] | BMA423_ACTIVITY_EN_MSK; - } - /* Enable tilt */ - if ((feature & FEATURE_TILT) > 0) { - /* Tilt enable bit pos. is the base address(0x3A) of tilt */ - index = BMA423_TILT_OFFSET; - buffer[index] = buffer[index] | BMA423_TILT_EN_MSK; - } - - /* Enable wakeup */ - if ((feature & FEATURE_WAKEUP) > 0) { - /* Wakeup enable bit pos. is the base address(0x38) of wakeup */ - index = BMA423_WAKEUP_OFFSET; - buffer[index] = buffer[index] | BMA423_WAKEUP_EN_MSK; - } - - /* Enable anymotion/nomotion */ - if ((feature & FEATURE_ANY_MOTION) > 0 || (feature & FEATURE_NO_MOTION) > 0) { - /* Any/Nomotion enable bit pos. is 1 bytes ahead of the - any/nomotion base address(0x00) */ - index = 1; - - if ((feature & FEATURE_ANY_MOTION) > 0) { - /* Enable anymotion */ - buffer[index] = buffer[index] & (~BMA423_ANY_NO_MOTION_SEL_MSK); - } else { - /* Enable nomotion */ - buffer[index] = buffer[index] | BMA423_ANY_NO_MOTION_SEL_MSK; - } - } - - /* Write the feature enable settings in the sensor */ - return writeRegister(BMA4_FEATURE_CONFIG_ADDR, buffer, len) != DEV_WIRE_ERR; - } - - void update_len(uint8_t *len, uint8_t feature, uint8_t enable) - { - uint8_t length = BMA423_FEATURE_SIZE; - - if ((feature == FEATURE_ANY_MOTION) || (feature == FEATURE_NO_MOTION)) { - /* Change the feature length to 2 for reading and writing of 2 bytes for - any/no-motion enable */ - length = BMA423_ANYMOTION_EN_LEN; - - /* Read and write 4 byte to disable the any/no motion completely along with - all axis */ - if (!enable) { - /*Change the feature length to 4 for reading and writing - of 4 bytes for any/no-motion enable */ - length = length + 2; - } - } - *len = length; - } - - bool configure() - { - uint8_t val; - val = readRegister(BMA4_INTERNAL_STAT); - if (val == BMA4_ASIC_INITIALIZED) { - log_d("No need configure!"); - readIrqStatus(); //clear irq status - return true; - } - - disablePowerSave(); - delay(1); - disableInterruptCtrl(); - - const uint8_t *stream_data = bma423_config_file; - const uint8_t maxReadWriteLenght = 32; - - for (size_t index = 0; index < BMA4_CONFIG_STREAM_SIZE; index += maxReadWriteLenght) { - uint8_t asic_msb = (uint8_t)((index / 2) >> 4); - uint8_t asic_lsb = ((index / 2) & 0x0F); - writeRegister(BMA4_RESERVED_REG_5B_ADDR, asic_lsb); - writeRegister(BMA4_RESERVED_REG_5C_ADDR, asic_msb); - writeRegister(BMA4_FEATURE_CONFIG_ADDR, (uint8_t *)(stream_data + index), maxReadWriteLenght); - } - - enableInterruptCtrl(); - delay(150); - val = readRegister(BMA4_INTERNAL_STAT); - if (val == BMA4_ASIC_INITIALIZED) { - log_d("BMA configure SUCCESS!"); - } else { - log_d("BMA configure FAILED!"); - } - return val == BMA4_ASIC_INITIALIZED; - } - - bool initImpl() - { - uint8_t id; - int retry = 2; - - while (retry--) { - id = readRegister(BMA4_CHIP_ID_ADDR); - if (id != BMA423_CHIP_ID) { - reset(); - } - } - - if (id == BMA423_CHIP_ID) { - return configure(); - } - - log_d("ChipID:0x%x should be 0x%x", id, BMA423_CHIP_ID); - return false; - - } - - - int getReadMaskImpl() - { - return DEV_WIRE_ERR; - } - - uint16_t int_status; - uint8_t int_line; - -protected: + bool setInterruptMode(uint8_t mode); + bool feature_disable(uint8_t feature, uint8_t len, uint8_t *buffer); -}; + int feature_enable(uint8_t feature, uint8_t len, uint8_t *buffer); + void update_len(uint8_t *len, uint8_t feature, uint8_t enable); + bool configure(); + bool initImpl(); + + uint16_t int_status; + uint8_t int_line; + std::unique_ptr comm; + std::unique_ptr hal; +}; diff --git a/src/SensorBMM150.hpp b/src/SensorBMM150.hpp index 93e848c..422a429 100644 --- a/src/SensorBMM150.hpp +++ b/src/SensorBMM150.hpp @@ -30,9 +30,9 @@ */ #pragma once -#include "bosch/common/bosch_interfaces.h" #include "bosch/BMM150/bmm150.h" #include "bosch/SensorBhy2Define.h" +#include "SensorPlatform.hpp" #if defined(ARDUINO) @@ -46,7 +46,6 @@ class SensorBMM150 { public: - enum PowerMode { POWERMODE_NORMAL, POWERMODE_FORCED, @@ -59,88 +58,85 @@ class SensorBMM150 INTERRUPT_LOW_ACTIVE, }; - SensorBMM150(PLATFORM_WIRE_TYPE &w, int sda = DEFAULT_SDA, int scl = DEFAULT_SCL, uint8_t addr = BMM150_DEFAULT_I2C_ADDRESS) - { - __handler.u.i2c_dev.scl = scl; - __handler.u.i2c_dev.sda = sda; - __handler.u.i2c_dev.addr = addr; - __handler.u.i2c_dev.wire = &w; - __handler.intf = SENSORLIB_I2C_INTERFACE; - } - - SensorBMM150(int cs, int mosi = -1, int miso = -1, int sck = -1, PLATFORM_SPI_TYPE &spi = SPI ) + SensorBMM150(): comm(nullptr), + hal(nullptr), + staticComm(nullptr), + dev(nullptr), + _rst(-1), + _error_code(0) { - __handler.u.spi_dev.cs = cs; - __handler.u.spi_dev.miso = miso; - __handler.u.spi_dev.mosi = mosi; - __handler.u.spi_dev.sck = sck; - __handler.u.spi_dev.spi = &spi; - __handler.intf = SENSORLIB_SPI_INTERFACE; } ~SensorBMM150() { - deinit(); } - SensorBMM150() + void setPins(int rst) { - memset(&__handler, 0, sizeof(__handler)); + _rst = rst; } - void setPins(int rst, int irq) +#if defined(ARDUINO) + bool begin(TwoWire &wire, uint8_t addr, int sda, int scl) { - __handler.irq = irq; - __handler.rst = rst; - + if (!beginCommonStatic(comm, staticComm, hal, wire, addr, sda, scl)) { + return false; + } + return initImpl(BMM150_I2C_INTF); } - bool init(PLATFORM_WIRE_TYPE &w, int sda = DEFAULT_SDA, int scl = DEFAULT_SCL, uint8_t addr = BMM150_DEFAULT_I2C_ADDRESS) + bool begin(SPIClass &spi, uint8_t csPin, int mosi, int miso, int sck) { - __handler.u.i2c_dev.scl = scl; - __handler.u.i2c_dev.sda = sda; - __handler.u.i2c_dev.addr = addr; - __handler.u.i2c_dev.wire = &w; - __handler.intf = SENSORLIB_I2C_INTERFACE; - return initImpl(); + if (!beginCommonStatic(comm, + staticComm, hal, + spi, csPin, mosi, miso, sck)) { + return false; + } + return initImpl(BMM150_I2C_INTF); } - bool init( PLATFORM_SPI_TYPE &spi, int cs, int mosi = -1, int miso = -1, int sck = -1) +#elif defined(ESP_PLATFORM) + +#if defined(USEING_I2C_LEGACY) + bool begin(i2c_port_t port_num, uint8_t addr, int sda, int scl) { - __handler.u.spi_dev.cs = cs; - __handler.u.spi_dev.miso = miso; - __handler.u.spi_dev.mosi = mosi; - __handler.u.spi_dev.sck = sck; - __handler.u.spi_dev.spi = &spi; - __handler.intf = SENSORLIB_SPI_INTERFACE; - return initImpl(); + if (!beginCommonStatic(comm, staticComm, hal, port_num, addr, sda, scl)) { + return false; + } + return initImpl(BHY2_I2C_INTERFACE); } - - bool init() +#else + bool begin(i2c_master_bus_handle_t handle, uint8_t addr) { - return initImpl(); + if (!beginCommonStatic(comm, staticComm, hal, handle, addr)) { + return false; + } + return initImpl(BHY2_I2C_INTERFACE); } +#endif //ESP_PLATFORM +#endif //ARDUINO - void deinit() + bool begin(CommInterface interface, + SensorCommCustom::CustomCallback callback, + SensorCommCustomHal::CustomHalCallback hal_callback, + uint8_t addr) { - if (dev) { - free(dev); - dev = NULL; - } - if (__handler.irq != SENSOR_PIN_NONE) { - detachInterrupt(__handler.irq); + if (!beginCommCustomCallback(interface, + callback, hal_callback, addr, comm, hal)) { + return false; } + return initImpl(static_cast(interface)); } void reset() { - if (__handler.rst != SENSOR_PIN_NONE) { - digitalWrite(__handler.rst, HIGH); - delay(5); - digitalWrite(__handler.rst, LOW); - delay(10); - digitalWrite(__handler.rst, HIGH); - delay(5); + if (_rst != -1) { + hal->digitalWrite(_rst, HIGH); + hal->delay(5); + hal->digitalWrite(_rst, LOW); + hal->delay(10); + hal->digitalWrite(_rst, HIGH); + hal->delay(5); } } @@ -152,44 +148,44 @@ class SensorBMM150 bool setMode(PowerMode mode) { settings.pwr_mode = mode; - return bmm150_set_op_mode(&settings, dev) == BMM150_OK; + return bmm150_set_op_mode(&settings, dev.get()) == BMM150_OK; } bool setThreshold(uint8_t high_th, uint8_t low_th) { settings.int_settings.high_threshold = high_th; settings.int_settings.low_threshold = low_th; - return bmm150_set_sensor_settings(BMM150_SEL_HIGH_THRESHOLD_SETTING, &settings, dev) == BMM150_OK; + return bmm150_set_sensor_settings(BMM150_SEL_HIGH_THRESHOLD_SETTING, &settings, dev.get()) == BMM150_OK; } bool setInterruptLevel(InterruptLevel level) { settings.int_settings.high_int_en = level; - return bmm150_set_sensor_settings(BMM150_SEL_HIGH_THRESHOLD_INT, &settings, dev) == BMM150_OK; + return bmm150_set_sensor_settings(BMM150_SEL_HIGH_THRESHOLD_INT, &settings, dev.get()) == BMM150_OK; } bool enableINT() { settings.int_settings.int_pin_en = BMM150_INT_ENABLE; - return bmm150_set_sensor_settings(BMM150_SEL_INT_PIN_EN, &settings, dev) == BMM150_OK; + return bmm150_set_sensor_settings(BMM150_SEL_INT_PIN_EN, &settings, dev.get()) == BMM150_OK; } bool disableINT() { settings.int_settings.int_pin_en = BMM150_INT_DISABLE; - return bmm150_set_sensor_settings(BMM150_SEL_INT_PIN_EN, &settings, dev) == BMM150_OK; + return bmm150_set_sensor_settings(BMM150_SEL_INT_PIN_EN, &settings, dev.get()) == BMM150_OK; } bool enabledDataReady() { settings.int_settings.drdy_pin_en = BMM150_INT_ENABLE; - return bmm150_set_sensor_settings(BMM150_SEL_DRDY_PIN_EN, &settings, dev) == BMM150_OK; + return bmm150_set_sensor_settings(BMM150_SEL_DRDY_PIN_EN, &settings, dev.get()) == BMM150_OK; } bool disabledDataReady() { settings.int_settings.drdy_pin_en = BMM150_INT_DISABLE; - return bmm150_set_sensor_settings(BMM150_SEL_DRDY_PIN_EN, &settings, dev) == BMM150_OK; + return bmm150_set_sensor_settings(BMM150_SEL_DRDY_PIN_EN, &settings, dev.get()) == BMM150_OK; } uint8_t getChipID() @@ -199,7 +195,7 @@ class SensorBMM150 uint8_t getIrqStatus() { - bmm150_get_interrupt_status(dev); + bmm150_get_interrupt_status(dev.get()); return dev->int_status; } @@ -221,14 +217,14 @@ class SensorBMM150 struct bmm150_mag_data getMag() { struct bmm150_mag_data data = {0, 0, 0}; - bmm150_read_mag_data(&data, dev); + bmm150_read_mag_data(&data, dev.get()); return data; } bool getMag(int16_t &x, int16_t &y, int16_t &z) { struct bmm150_mag_data data; - if (bmm150_read_mag_data(&data, dev) != BMM150_OK) { + if (bmm150_read_mag_data(&data, dev.get()) != BMM150_OK) { return false; } x = data.x; @@ -239,99 +235,49 @@ class SensorBMM150 private: - static void handleISR(/*void *available*/) - { - // *(bool *)(available) = true; - __data_available = true; - } - bool initImpl() + bool initImpl(bmm150_intf interface) { memset(&settings, 0, sizeof(settings)); - if (__handler.rst != SENSOR_PIN_NONE) { - pinMode(__handler.rst, OUTPUT); + if (_rst != -1) { + hal->pinMode(_rst, OUTPUT); } reset(); - dev = (struct bmm150_dev *)malloc(sizeof(struct bmm150_dev)); - BHY2_RLST_CHECK(!dev, " Device handler malloc failed!", false); - - switch (__handler.intf) { - case SENSORLIB_I2C_INTERFACE: - BHY2_RLST_CHECK(!__handler.u.i2c_dev.wire, "Wire ptr NULL", false); - if (!SensorInterfaces::setup_interfaces(__handler)) { - log_e("setup_interfaces failed"); - free(dev); - return false; - } - dev->intf = BMM150_I2C_INTF; - dev->read = SensorInterfaces::bhy2_i2c_read; - dev->write = SensorInterfaces::bhy2_i2c_write; - dev->intf_ptr = &__handler; - break; - - case SENSORLIB_SPI_INTERFACE: - BHY2_RLST_CHECK(!__handler.u.spi_dev.spi, "SPI ptr NULL", false); - if (!SensorInterfaces::setup_interfaces(__handler)) { - log_e("setup_interfaces failed"); - free(dev); - return false; - } - dev->intf = BMM150_I2C_INTF; - dev->read = SensorInterfaces::bhy2_spi_read; - dev->write = SensorInterfaces::bhy2_spi_write; - dev->intf_ptr = &__handler; - break; - default: - free(dev); + dev = std::make_unique(); + if (!dev) { + log_e(" Device handler malloc failed!"); return false; } - dev->delay_us = SensorInterfaces::bhy2_delay_us; - __error_code = bmm150_init(dev); - if (__error_code != BMM150_OK) { - log_e("bmm150 init failed!"); - free(dev); - return false; - } + dev->intf = interface; + dev->read = SensorCommStatic::sensor_static_read_data; + dev->write = SensorCommStatic::sensor_static_write_data; + dev->intf_ptr = staticComm.get(); + dev->delay_us = SensorCommStatic::sensor_static_delay_us; - __error_code = bmm150_soft_reset(dev); - if (__error_code != BMM150_OK) { - log_e("reset failed!"); - free(dev); + _error_code = bmm150_init(dev.get()); + if (_error_code != BMM150_OK) { return false; } - - bmm150_get_sensor_settings(&settings, dev); - - if (__handler.irq != SENSOR_PIN_NONE) { - /* - #if defined(ARDUINO_ARCH_RP2040) - attachInterruptParam((pin_size_t)(__handler.irq), handleISR, (PinStatus )RISING, (void *)&__data_available); - #else - attachInterruptArg(__handler.irq, handleISR, (void *)&__data_available, RISING); - #endif - */ -#if defined(ARDUINO_ARCH_RP2040) - attachInterrupt((pin_size_t)(__handler.irq), handleISR, (PinStatus )RISING); -#elif defined(ARDUINO_ARCH_NRF52) || defined(ARDUINO_ARCH_ESP32) || defined(ARDUINO_ARCH_STM32) - attachInterrupt(__handler.irq, handleISR, RISING); -#else -#error "Interrupt registration not implemented" -#endif + _error_code = bmm150_soft_reset(dev.get()); + if (_error_code != BMM150_OK) { + return false; } - - return __error_code == BMM150_OK; + bmm150_get_sensor_settings(&settings, dev.get()); + return _error_code == BMM150_OK; } -protected: - struct bmm150_settings settings; - struct bmm150_dev *dev = NULL; - SensorLibConfigure __handler; - int8_t __error_code; - static volatile bool __data_available; + std::unique_ptr comm; + std::unique_ptr hal; + std::unique_ptr staticComm; + std::unique_ptr dev; + int _rst; + int8_t _error_code; + struct bmm150_settings settings; + }; diff --git a/src/SensorCM32181.hpp b/src/SensorCM32181.hpp index 63bc874..848e861 100644 --- a/src/SensorCM32181.hpp +++ b/src/SensorCM32181.hpp @@ -22,7 +22,7 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. * - * @file SensorCM32181.tpp + * @file SensorCM32181.hpp * @author Lewis He (lewishe@outlook.com) * @date 2023-04-14 * @@ -30,15 +30,11 @@ #pragma once #include "REG/CM32181Constants.h" -#include "SensorCommon.tpp" +#include "SensorPlatform.hpp" -class SensorCM32181 : - public SensorCommon +class SensorCM32181 : public CM32181Constants { - friend class SensorCommon; public: - - enum Sampling { SAMPLING_X1, //ALS Sensitivity x 1 SAMPLING_X2, //ALS Sensitivity x 2 @@ -68,42 +64,58 @@ class SensorCM32181 : ALS_EVENT_NULL, }; -#if defined(ARDUINO) - SensorCM32181(PLATFORM_WIRE_TYPE &w, int sda = DEFAULT_SDA, int scl = DEFAULT_SCL, uint8_t addr = CM32181_SLAVE_ADDRESS) + SensorCM32181() : comm(nullptr) {} + + ~SensorCM32181() { - __wire = &w; - __sda = sda; - __scl = scl; - __addr = addr; + if (comm) { + comm->deinit(); + } } -#endif - SensorCM32181() - { #if defined(ARDUINO) - __wire = &Wire; - __sda = DEFAULT_SDA; - __scl = DEFAULT_SCL; -#endif - __addr = CM32181_SLAVE_ADDRESS; + bool begin(TwoWire &wire, uint8_t addr = CM32181_ADDR_PRIMARY, int sda = -1, int scl = -1) + { + comm = std::make_unique(wire, addr, sda, scl); + if (!comm) { + return false; + } + comm->init(); + return initImpl(); } +#elif defined(ESP_PLATFORM) - ~SensorCM32181() +#if defined(USEING_I2C_LEGACY) + bool begin(i2c_port_t port_num, uint8_t addr = CM32181_ADDR_PRIMARY, int sda = -1, int scl = -1) { - deinit(); + comm = std::make_unique(port_num, addr, sda, scl); + if (!comm) { + return false; + } + comm->init(); + return initImpl(); } - -#if defined(ARDUINO) - bool init(PLATFORM_WIRE_TYPE &w, int sda = DEFAULT_SDA, int scl = DEFAULT_SCL, uint8_t addr = CM32181_SLAVE_ADDRESS) +#else + bool begin(i2c_master_bus_handle_t handle, uint8_t addr = CM32181_ADDR_PRIMARY) { - return SensorCommon::begin(w, addr, sda, scl); + comm = std::make_unique(handle, addr); + if (!comm) { + return false; + } + comm->init(); + return initImpl(); } -#endif +#endif //ESP_PLATFORM +#endif //ARDUINO - - void deinit() + bool begin(SensorCommCustom::CustomCallback callback, uint8_t addr = CM32181_ADDR_PRIMARY) { - // end(); + comm = std::make_unique(callback, addr); + if (!comm) { + return false; + } + comm->init(); + return initImpl(); } void setSampling(Sampling tempSampling = SAMPLING_X1, @@ -111,12 +123,12 @@ class SensorCM32181 : ) { uint16_t data; - readRegister(CM32181_REG_ALS_CONF, (uint8_t *)&data, 2); + comm->readRegister(REG_ALS_CONF, (uint8_t *)&data, 2); data &= ~(0x03 << 11); data |= tempSampling << 11; data &= ~(0xF << 6); data |= int_time << 6; - readRegister(CM32181_REG_ALS_CONF, (uint8_t *)&data, 2); + comm->readRegister(REG_ALS_CONF, (uint8_t *)&data, 2); } void setIntThreshold(uint16_t low_threshold, uint16_t high_threshold) @@ -125,66 +137,66 @@ class SensorCM32181 : uint8_t buffer[2] = {0}; buffer[1] = highByte(high_threshold); buffer[0] = lowByte(high_threshold);; - writeRegister(CM32181_REG_ALS_THDH, buffer, 2); + comm->writeRegister(REG_ALS_THDH, buffer, 2); buffer[1] = highByte(low_threshold); buffer[0] = lowByte(low_threshold); - writeRegister(CM32181_REG_ALS_THDL, buffer, 2); + comm->writeRegister(REG_ALS_THDL, buffer, 2); } void powerSave(PowerSaveMode mode, bool enable) { uint16_t data = 0x00; - readRegister(CM32181_REG_ALS_PSM, (uint8_t *)&data, 2); + comm->readRegister(REG_ALS_PSM, (uint8_t *)&data, 2); data |= mode << 1; enable ? data |= 0x01 : data |= 0x00; - writeRegister(CM32181_REG_ALS_PSM, (uint8_t *)&data, 2); + comm->writeRegister(REG_ALS_PSM, (uint8_t *)&data, 2); } - // Read CM32181_REG_ALS_STATUS register to clear interrupt + // Read REG_ALS_STATUS register to clear interrupt InterruptEvent getIrqStatus() { uint16_t data; - readRegister(CM32181_REG_ALS_STATUS, (uint8_t *)&data, 2); + comm->readRegister(REG_ALS_STATUS, (uint8_t *)&data, 2); return bitRead(data, 15) ? ALS_EVENT_LOW_TRIGGER : bitRead(data, 14) ? ALS_EVENT_HIGH_TRIGGER : ALS_EVENT_NULL; } void enableINT() { uint16_t data; - readRegister(CM32181_REG_ALS_CONF, (uint8_t *)&data, 2); + comm->readRegister(REG_ALS_CONF, (uint8_t *)&data, 2); bitWrite(data, 1, 1); - writeRegister(CM32181_REG_ALS_CONF, (uint8_t *)&data, 2); + comm->writeRegister(REG_ALS_CONF, (uint8_t *)&data, 2); } void disableINT() { uint16_t data; - readRegister(CM32181_REG_ALS_CONF, (uint8_t *)&data, 2); + comm->readRegister(REG_ALS_CONF, (uint8_t *)&data, 2); bitWrite(data, 1, 0); - writeRegister(CM32181_REG_ALS_CONF, (uint8_t *)&data, 2); + comm->writeRegister(REG_ALS_CONF, (uint8_t *)&data, 2); } void powerOn() { uint16_t data; - readRegister(CM32181_REG_ALS_CONF, (uint8_t *)&data, 2); + comm->readRegister(REG_ALS_CONF, (uint8_t *)&data, 2); bitClear(data, 0); - writeRegister(CM32181_REG_ALS_CONF, (uint8_t *)&data, 2); + comm->writeRegister(REG_ALS_CONF, (uint8_t *)&data, 2); } void powerDown() { uint16_t data; - readRegister(CM32181_REG_ALS_CONF, (uint8_t *)&data, 2); + comm->readRegister(REG_ALS_CONF, (uint8_t *)&data, 2); bitSet(data, 0); - writeRegister(CM32181_REG_ALS_CONF, (uint8_t *)&data, 2); + comm->writeRegister(REG_ALS_CONF, (uint8_t *)&data, 2); } uint16_t getRaw() { uint8_t buffer[2] = {0}; - readRegister(CM32181_REG_ALS_DATA, buffer, 2); + comm->readRegister(REG_ALS_DATA, buffer, 2); return (uint16_t) buffer[0] | (uint16_t)(buffer[1] << 8); } @@ -196,7 +208,7 @@ class SensorCM32181 : int getChipID() { uint8_t buffer[2] = {0}; - readRegister(CM32181_REG_ID, buffer, 2); + comm->readRegister(REG_ID, buffer, 2); return lowByte(buffer[0]); } @@ -204,12 +216,11 @@ class SensorCM32181 : bool initImpl() { - setReadRegisterSendStop(false); - + I2CParam params(I2CParam::I2C_SET_FLAG, false); + comm->setParams(params); int chipID = getChipID(); log_i("chipID:%d\n", chipID); - - if (chipID == DEV_WIRE_ERR ) { + if (chipID < 0 ) { return false; } if (chipID != CM32181_CHIP_ID) { @@ -218,13 +229,7 @@ class SensorCM32181 : return true; } - int getReadMaskImpl() - { - return -1; - } - - -protected: + std::unique_ptr comm; // The default calibration value, learned from the manual, // is now unable to obtain the calibration value from the specified register const float calibration_factor = 0.286; diff --git a/src/SensorCommon.tpp b/src/SensorCommon.tpp deleted file mode 100644 index 1e74f23..0000000 --- a/src/SensorCommon.tpp +++ /dev/null @@ -1,722 +0,0 @@ -/** - * - * @license MIT License - * - * Copyright (c) 2022 lewis he - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - * @file SensorCommon.tpp - * @author Lewis He (lewishe@outlook.com) - * @date 2022-10-16 - * - */ - - -#pragma once - -#include "SensorLib.h" - -typedef int (*iic_fptr_t)(uint8_t devAddr, uint8_t regAddr, uint8_t *data, uint8_t len); -typedef void (*gpio_write_fptr_t)(uint32_t gpio, uint8_t value); -typedef int (*gpio_read_fptr_t)(uint32_t gpio); -typedef void (*gpio_mode_fptr_t)(uint32_t gpio, uint8_t mode); -typedef void (*delay_ms_fptr_t)(uint32_t ms); - -template -class SensorCommon -{ -public: - ~SensorCommon() - { -#if defined(ARDUINO) - if (__spiSetting) { - delete __spiSetting; - } -#endif - } - -#if defined(ARDUINO) - void setSpiSetting(uint32_t freq, uint8_t dataOrder = SPI_DATA_ORDER, uint8_t dataMode = SPI_MODE0) - { - __freq = freq; - __dataOrder = dataOrder; - __dataMode = dataMode; - } - - bool begin(PLATFORM_WIRE_TYPE &w, uint8_t addr, int sda, int scl) - { - log_i("Using Arduino Wire interface."); - if (__has_init)return thisChip().initImpl(); - __wire = &w; - __sda = sda; - __scl = scl; -#if defined(ARDUINO_ARCH_NRF52) - if (__sda != 0xFF && __scl != 0xFF) { - __wire->setPins(__sda, __scl); - } - __wire->begin(); -#elif defined(ARDUINO_ARCH_RP2040) || defined(ARDUINO_ARCH_STM32) - if (__sda != 0xFF && __scl != 0xFF) { - __wire->end(); - __wire->setSDA(__sda); - __wire->setSCL(__scl); - } - __wire->begin(); -#elif defined(ARDUINO_ARCH_ESP32) - __wire->begin(__sda, __scl); -#else - __wire->begin(); -#endif - __addr = addr; - __spi = NULL; - __i2c_master_read = NULL; - __i2c_master_write = NULL; - __has_init = thisChip().initImpl(); - return __has_init; - } - - bool begin(int cs, int mosi = -1, int miso = -1, int sck = -1, - PLATFORM_SPI_TYPE &spi = SPI - ) - { - log_i("Using Arduino SPI interface."); - if (__has_init)return thisChip().initImpl(); - __cs = cs; - __spi = &spi; - pinMode(__cs, OUTPUT); - digitalWrite(__cs, HIGH); - __spiSetting = new DEFAULT_SPISETTING; - if (!__spiSetting) { - return false; - } - if (mosi != -1 && miso != -1 && sck != -1) { -#if defined(ARDUINO_ARCH_NRF52) - __spi->begin(); -#elif defined(ARDUINO_ARCH_RP2040) - __spi->setSCK(sck); - __spi->setRX(miso); - __spi->setTX(mosi); - __spi->begin(); -#elif defined(ARDUINO_ARCH_STM32) - __spi->setSCLK(sck); - __spi->setMISO(miso); - __spi->setMOSI(mosi); - __spi->begin(); -#else - __spi->begin(sck, miso, mosi); -#endif - } else { - __spi->begin(); - } - __wire = NULL; - __readMask = thisChip().getReadMaskImpl(); - __has_init = thisChip().initImpl(); - return __has_init; - } - -#elif defined(ESP_PLATFORM) && !defined(ARDUINO) - -#if ((ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL(5,0,0)) && defined(CONFIG_SENSORLIB_ESP_IDF_NEW_API)) - // * Using the new API of esp-idf 5.x, you need to pass the I2C BUS handle, - // * which is useful when the bus shares multiple devices. - - bool begin(i2c_master_bus_handle_t i2c_dev_bus_handle, uint8_t addr) - { - log_i("Using ESP-IDF Driver interface."); - if (i2c_dev_bus_handle == NULL) return false; - if (__has_init)return thisChip().initImpl(); - - __i2c_master_read = NULL; - __i2c_master_write = NULL; - __addr = addr; - - /* - i2c_master_bus_config_t i2c_bus_config; - memset(&i2c_bus_config, 0, sizeof(i2c_bus_config)); - i2c_bus_config.clk_source = I2C_CLK_SRC_DEFAULT; - i2c_bus_config.i2c_port = port_num; - i2c_bus_config.scl_io_num = (gpio_num_t)__scl; - i2c_bus_config.sda_io_num = (gpio_num_t)__sda; - i2c_bus_config.glitch_ignore_cnt = 7; - - i2c_new_master_bus(&i2c_bus_config, &bus_handle); - */ - bus_handle = i2c_dev_bus_handle; - - __i2c_dev_conf.dev_addr_length = I2C_ADDR_BIT_LEN_7; - __i2c_dev_conf.device_address = __addr; - __i2c_dev_conf.scl_speed_hz = SENSORLIB_I2C_MASTER_SEEED; -#if (ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL(5,3,0)) -#if (ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL(5,4,0)) - // New fields since esp-idf-v5.3-beta1 - __i2c_dev_conf.scl_wait_us = 0; -#endif - __i2c_dev_conf.flags.disable_ack_check = 0; -#endif - if (ESP_OK != i2c_master_bus_add_device(bus_handle, - &__i2c_dev_conf, - &__i2c_device)) { - log_i("i2c_master_bus_add_device failed !"); - return false; - } - log_i("Added Device Address : 0x%X New Dev Address: %p Speed :%lu ", __addr, __i2c_device, __i2c_dev_conf.scl_speed_hz); - __has_init = thisChip().initImpl(); - - if (!__has_init) { - // Initialization failed, delete device - log_i("i2c_master_bus_rm_device !"); - i2c_master_bus_rm_device(__i2c_device); - } - - return __has_init; - } - -#else //ESP 4.X - - bool begin(i2c_port_t port_num, uint8_t addr, int sda, int scl) - { - __i2c_num = port_num; - log_i("Using ESP-IDF Driver interface."); - if (__has_init)return thisChip().initImpl(); - __sda = sda; - __scl = scl; - __addr = addr; - __i2c_master_read = NULL; - __i2c_master_write = NULL; - - i2c_config_t i2c_conf; - memset(&i2c_conf, 0, sizeof(i2c_conf)); - i2c_conf.mode = I2C_MODE_MASTER; - i2c_conf.sda_io_num = sda; - i2c_conf.scl_io_num = scl; - i2c_conf.sda_pullup_en = GPIO_PULLUP_ENABLE; - i2c_conf.scl_pullup_en = GPIO_PULLUP_ENABLE; - i2c_conf.master.clk_speed = SENSORLIB_I2C_MASTER_SEEED; - - /** - * @brief Without checking whether the initialization is successful, - * I2C may be initialized externally, - * so just make sure there is an initialization here. - */ - i2c_param_config(__i2c_num, &i2c_conf); - i2c_driver_install(__i2c_num, - i2c_conf.mode, - SENSORLIB_I2C_MASTER_RX_BUF_DISABLE, - SENSORLIB_I2C_MASTER_TX_BUF_DISABLE, 0); - __has_init = thisChip().initImpl(); - return __has_init; - } -#endif //ESP 5.X - -#endif - - - bool begin(uint8_t addr, iic_fptr_t readRegCallback, iic_fptr_t writeRegCallback) - { - log_i("Using Custom interface."); - if (__has_init)return thisChip().initImpl(); - __i2c_master_read = readRegCallback; - __i2c_master_write = writeRegCallback; - __addr = addr; -#if defined(ARDUINO) - __spi = NULL; -#endif - __has_init = thisChip().initImpl(); - return __has_init; - } - - void setGpioWriteCallback(gpio_write_fptr_t cb) - { - __set_gpio_level = cb; - } - - void setGpioReadCallback(gpio_read_fptr_t cb) - { - __get_gpio_level = cb; - } - - void setGpioModeCallback(gpio_mode_fptr_t cb) - { - __set_gpio_mode = cb; - } - - void setDelayCallback(delay_ms_fptr_t cb) - { - __delay_ms = cb; - } - -protected: - - inline void setGpioMode(uint32_t gpio, uint8_t mode) - { - if (__set_gpio_mode) { - return __set_gpio_mode(gpio, mode); - } -#if defined(ARDUINO) || defined(ESP_PLATFORM) - return pinMode(gpio, mode); -#endif - } - - inline void setGpioLevel(uint32_t gpio, uint8_t level) - { - if (__set_gpio_level) { - return __set_gpio_level(gpio, level); - } -#if defined(ARDUINO) || defined(ESP_PLATFORM) - return digitalWrite(gpio, level); -#endif - } - - inline int getGpioLevel(uint32_t gpio) - { - if (__get_gpio_level) { - return __get_gpio_level(gpio); - } -#if defined(ARDUINO) || defined(ESP_PLATFORM) - return digitalRead(gpio); -#endif - } - - bool probe(uint8_t address) - { -#if defined(ARDUINO) - if (__wire) { - __wire->beginTransmission(address); - return __wire->endTransmission() == 0; - } - return false; -#elif defined(ESP_PLATFORM) -#if ((ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL(5,0,0)) && defined(CONFIG_SENSORLIB_ESP_IDF_NEW_API)) - return i2c_master_probe(bus_handle, address, 1000); -#else - return true; -#endif -#else - return true; -#endif - } - - bool probe() - { -#if defined(ARDUINO) - if (__wire) { - __wire->beginTransmission(__addr); - return __wire->endTransmission() == 0; - } - return false; -#elif defined(ESP_PLATFORM) -#if ((ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL(5,0,0)) && defined(CONFIG_SENSORLIB_ESP_IDF_NEW_API)) - return i2c_master_probe(bus_handle, __addr, 1000); -#else - return true; -#endif -#else - return true; -#endif - } - - //! Write method - int writeRegister(uint8_t reg, uint8_t norVal, uint8_t orVal) - { - int val = readRegister(reg); - if (val == DEV_WIRE_ERR) { - return DEV_WIRE_ERR; - } - val &= norVal; - val |= orVal; - return writeRegister(reg, val); - } - - int writeRegister(int reg, uint8_t val) - { - return writeRegister(reg, &val, 1); - } - - - template - int writeThenRead(T write_register, uint8_t *read_buffer, size_t read_len) - { - constexpr size_t write_len = sizeof(T); - uint8_t write_buffer[write_len] = {0}; - for (size_t i = 0; i < write_len; ++i) { - // Big Endian - // write_buffer[i] = reinterpret_cast(&write_register)[i]; - // Little Endian - write_buffer[i] = reinterpret_cast(&write_register)[write_len - 1 - i]; - } - return writeThenRead(write_buffer, write_len, read_buffer, read_len); - } - - int writeThenRead(uint8_t *write_buffer, size_t write_len, uint8_t *read_buffer, size_t read_len) - { -#if defined(ARDUINO) - if (__wire) { - __wire->beginTransmission(__addr); - __wire->write(write_buffer, write_len); - if (__wire->endTransmission(__sendStop) != 0) { - return DEV_WIRE_ERR; - } - __wire->requestFrom(__addr, read_len); - return __wire->readBytes(read_buffer, read_len) == read_len ? DEV_WIRE_NONE : DEV_WIRE_ERR; - } -#elif defined(ESP_PLATFORM) - -#if ((ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL(5,0,0)) && defined(CONFIG_SENSORLIB_ESP_IDF_NEW_API)) - if (ESP_OK == i2c_master_transmit_receive( - __i2c_device, - write_buffer, - write_len, - read_buffer, - read_len, - -1)) { - return DEV_WIRE_NONE; - } -#else //ESP_IDF_VERSION - if (ESP_OK == i2c_master_write_read_device( - __i2c_num, - __addr, - write_buffer, - write_len, - read_buffer, - read_len, - SENSORLIB_I2C_MASTER_TIMEOUT_MS / portTICK_PERIOD_MS)) { - return DEV_WIRE_NONE; - } -#endif //ESP_IDF_VERSION - -#endif //ESP_PLATFORM - return DEV_WIRE_ERR; - } - - int writeBuffer(uint8_t *buf, size_t length) - { -#if defined(ARDUINO) - if (__wire) { - __wire->beginTransmission(__addr); - __wire->write(buf, length); - uint8_t ret = (__wire->endTransmission()); - return ret == 0 ? DEV_WIRE_NONE : DEV_WIRE_ERR; - } -#elif defined(ESP_PLATFORM) - -#if ((ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL(5,0,0)) && defined(CONFIG_SENSORLIB_ESP_IDF_NEW_API)) - if (ESP_OK == i2c_master_transmit( - __i2c_device, - buf, - length, - -1)) { - return DEV_WIRE_NONE; - } -#else //ESP_IDF_VERSION - if (ESP_OK == i2c_master_write_to_device(__i2c_num, - __addr, - buf, - length, - SENSORLIB_I2C_MASTER_TIMEOUT_MS / portTICK_PERIOD_MS)) { - return DEV_WIRE_NONE; - } -#endif //ESP_IDF_VERSION - -#endif //ESP_PLATFORM - return DEV_WIRE_ERR; - } - - int writeRegister(int reg, uint8_t *buf, size_t length) - { - if (__i2c_master_write) { - return __i2c_master_write(__addr, reg, buf, length); - } -#if defined(ARDUINO) - if (__wire) { - __wire->beginTransmission(__addr); - if (__reg_addr_len == 1) { - __wire->write(reg); - } else { - for (int i = 0; i < __reg_addr_len; ++i) { - __wire->write(reg >> (8 * ((__reg_addr_len - 1) - i))); - } - } - __wire->write(buf, length); - return (__wire->endTransmission() == 0) ? DEV_WIRE_NONE : DEV_WIRE_ERR; - } - if (__spi) { - __spi->beginTransaction(*__spiSetting); - digitalWrite(__cs, LOW); - if (__reg_addr_len == 1) { - __spi->transfer(reg); - } else { - for (int i = 0; i < __reg_addr_len; ++i) { - __spi->transfer(reg >> (8 * ((__reg_addr_len - 1) - i))); - } - } - __spi->transfer(buf, length); - digitalWrite(__cs, HIGH); - __spi->endTransaction(); - return DEV_WIRE_NONE; - } - return DEV_WIRE_ERR; - -#elif defined(ESP_PLATFORM) - uint8_t *write_buffer = (uint8_t *)malloc(sizeof(uint8_t) * (length + __reg_addr_len)); - if (!write_buffer) { - return DEV_WIRE_ERR; - } - write_buffer[0] = reg; - memcpy(write_buffer, ®, __reg_addr_len); - memcpy(write_buffer + __reg_addr_len, buf, length); - int ret = writeBuffer(write_buffer, __reg_addr_len + length); - free(write_buffer); - return ret; -#endif //ESP_PLATFORM - } - - //! Read method - int readRegister(int reg) - { - uint8_t val = 0; - return readRegister(reg, &val, 1) == -1 ? -1 : val; - } - - int readRegister(int reg, uint8_t *buf, size_t length) - { - if (__i2c_master_read) { - return __i2c_master_read(__addr, reg, buf, length); - } -#if defined(ARDUINO) - if (__wire) { - __wire->beginTransmission(__addr); - if (__reg_addr_len == 1) { - __wire->write(reg); - } else { - for (int i = 0; i < __reg_addr_len; ++i) { - __wire->write(reg >> (8 * ((__reg_addr_len - 1) - i))); - } - } - if (__wire->endTransmission(__sendStop) != 0) { - return DEV_WIRE_ERR; - } - __wire->requestFrom(__addr, length); - return __wire->readBytes(buf, length) == length ? DEV_WIRE_NONE : DEV_WIRE_ERR; - } - if (__spi) { - __spi->beginTransaction(*__spiSetting); - digitalWrite(__cs, LOW); - if (__reg_addr_len == 1) { - __spi->transfer(__readMask != -1 ? (reg | __readMask) : reg); - } else { - uint8_t firstBytes = reg >> (8 * ((__reg_addr_len - 1))); - __spi->transfer(__readMask != -1 ? (firstBytes | __readMask) : firstBytes); - for (int i = 1; i < __reg_addr_len; ++i) { - __spi->transfer(reg >> (8 * ((__reg_addr_len - 1) - i))); - } - } - -#if defined(ARDUINO_ARCH_ESP32) - __spi->transferBytes(NULL, buf, length); -#else - for (size_t i = 0; i < length; i++) { - buf[i] = __spi->transfer(0x00); - } -#endif - - digitalWrite(__cs, HIGH); - __spi->endTransaction(); - return DEV_WIRE_NONE; - } -#elif defined(ESP_PLATFORM) - //TODO:SPI INTERFACE -#if ((ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL(5,0,0)) && defined(CONFIG_SENSORLIB_ESP_IDF_NEW_API)) - if (ESP_OK == i2c_master_transmit_receive( - __i2c_device, - (const uint8_t *)®, - __reg_addr_len, - buf, - length, - -1)) { - return DEV_WIRE_NONE; - } -#else //ESP_IDF_VERSION - if (ESP_OK == i2c_master_write_read_device(__i2c_num, - __addr, - (uint8_t *)®, - __reg_addr_len, - buf, - length, - SENSORLIB_I2C_MASTER_TIMEOUT_MS / portTICK_PERIOD_MS)) { - return DEV_WIRE_NONE; - } -#endif //ESP_IDF_VERSION - -#endif //ESP_PLATFORM - return DEV_WIRE_ERR; - } - - bool inline clrRegisterBit(int registers, uint8_t bit) - { - int val = readRegister(registers); - if (val == DEV_WIRE_ERR) { - return false; - } - return writeRegister(registers, (val & (~_BV(bit)))) == DEV_WIRE_NONE; - } - - bool inline setRegisterBit(int registers, uint8_t bit) - { - int val = readRegister(registers); - if (val == DEV_WIRE_ERR) { - return false; - } - return writeRegister(registers, (val | (_BV(bit)))) == DEV_WIRE_NONE; - } - - bool inline getRegisterBit(int registers, uint8_t bit) - { - int val = readRegister(registers); - if (val == DEV_WIRE_ERR) { - return false; - } - return val & _BV(bit); - } - - void setRegAddressLength(uint8_t len) - { - __reg_addr_len = len; - } - - void setReadRegisterSendStop(bool sendStop) - { - __sendStop = sendStop; - } - - bool reallocBuffer(size_t realloc_size) - { -#if defined(ARDUINO) - -#ifdef ARDUINO_ARCH_ESP32 - // ESP32 I2C BUFFER : 128 Bytes - if (__wire) { - if (__wire->setBufferSize(realloc_size) != realloc_size) { - log_e("realloc I2C buffer failed!"); - return false; - } - } -#elif defined(ARDUINO_ARCH_RP2040) - // RP2040 I2C BUFFER : 256 Bytes - -#elif defined(ARDUINO_ARCH_NRF52) - // NRF52840 I2C BUFFER : 64 Bytes -// #warning "NRF Platform I2C Buffer expansion is not implemented" - //TODO:"NRF Platform I2C Buffer expansion is not implemented" -#endif -#endif - return true; - } - - - void setClock(uint32_t frequency) - { -#if defined(ARDUINO) - if (__wire) { - __wire->setClock(frequency); - } -#endif - } - - uint32_t getClock() - { -#if defined(ARDUINO) - if (__wire) { -#if defined(ARDUINO_ARCH_ESP32) - return __wire->getClock(); -#else - return 100000; -#endif - } -#endif - return 0; - } - - /* - * CRTP Helper - */ -protected: - - void end() - { -#if defined(ARDUINO) - if (__wire) { -#if defined(ESP_IDF_VERSION) -#if ESP_IDF_VERSION > ESP_IDF_VERSION_VAL(4,4,0) - __wire->end(); -#endif /*ESP_IDF_VERSION*/ -#endif /*ESP_IDF_VERSION*/ - } -#endif /*ARDUINO*/ - } - - - inline const chipType &thisChip() const - { - return static_cast(*this); - } - - inline chipType &thisChip() - { - return static_cast(*this); - } - -protected: - bool __has_init = false; -#if defined(ARDUINO) - PLATFORM_WIRE_TYPE *__wire = NULL; - PLATFORM_SPI_TYPE *__spi = NULL; - SPISettings *__spiSetting = NULL; - uint8_t __dataOrder = SPI_DATA_ORDER; - uint8_t __dataMode = SPI_MODE0; - uint32_t __freq = 400000; - -#elif defined(ESP_PLATFORM) - i2c_port_t __i2c_num; -#if ((ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL(5,0,0)) && defined(CONFIG_SENSORLIB_ESP_IDF_NEW_API)) - i2c_master_bus_handle_t bus_handle; - i2c_master_dev_handle_t __i2c_device; - i2c_device_config_t __i2c_dev_conf; -#endif //ESP_IDF_VERSION - -#endif //ESP_PLATFORM - - int __readMask = -1; - int __sda = -1; - int __scl = -1; - int __cs = -1; - int __miso = -1; - int __mosi = -1; - int __sck = -1; - bool __sendStop = true; - uint8_t __addr = 0xFF; - uint8_t __reg_addr_len = 1; - iic_fptr_t __i2c_master_read = NULL; - iic_fptr_t __i2c_master_write = NULL; - gpio_write_fptr_t __set_gpio_level = NULL; - gpio_read_fptr_t __get_gpio_level = NULL; - gpio_mode_fptr_t __set_gpio_mode = NULL; - delay_ms_fptr_t __delay_ms = NULL; - -}; diff --git a/src/SensorDRV2605.hpp b/src/SensorDRV2605.hpp index 87eef56..59ff0f7 100644 --- a/src/SensorDRV2605.hpp +++ b/src/SensorDRV2605.hpp @@ -22,7 +22,7 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. * - * @file SensorDRV2605.tpp + * @file SensorDRV2605.hpp * @author Lewis He (lewishe@outlook.com) * @date 2023-04-03 * @note Source code from https://github.com/adafruit/Adafruit_DRV2605_Library @@ -30,50 +30,72 @@ #pragma once #include "REG/DRV2605Constants.h" -#include "SensorCommon.tpp" +#include "SensorPlatform.hpp" -class SensorDRV2605 : - public SensorCommon +class SensorDRV2605 : public DRV2605Constants { - friend class SensorCommon; public: + static constexpr uint8_t MODE_INTTRIG = 0x00; //* Internal trigger mode + static constexpr uint8_t MODE_EXTTRIGEDGE = 0x01; //* External edge trigger mode + static constexpr uint8_t MODE_EXTTRIGLVL = 0x02; //* External level trigger mode + static constexpr uint8_t MODE_PWMANALOG = 0x03; //* PWM/Analog input mode + static constexpr uint8_t MODE_AUDIOVIBE = 0x04; //* Audio-to-vibe mode + static constexpr uint8_t MODE_REALTIME = 0x05; //* Real-time playback (RTP) mode + static constexpr uint8_t MODE_DIAGNOS = 0x06; //* Diagnostics mode + static constexpr uint8_t MODE_AUTOCAL = 0x07; //* Auto calibration mode -#if defined(ARDUINO) - SensorDRV2605(PLATFORM_WIRE_TYPE &w, int sda = DEFAULT_SDA, int scl = DEFAULT_SCL, uint8_t addr = DRV2605_SLAVE_ADDRESS) + SensorDRV2605() : comm(nullptr) {} + + ~SensorDRV2605() { - __wire = &w; - __sda = sda; - __scl = scl; - __addr = addr; + if (comm) { + comm->deinit(); + } } -#endif - SensorDRV2605() - { #if defined(ARDUINO) - __wire = &Wire; - __sda = DEFAULT_SDA; - __scl = DEFAULT_SCL; -#endif - __addr = DRV2605_SLAVE_ADDRESS; + bool begin(TwoWire &wire, int sda = -1, int scl = -1) + { + comm = std::make_unique(wire, DRV2605_SLAVE_ADDRESS, sda, scl); + if (!comm) { + return false; + } + comm->init(); + return initImpl(); } +#elif defined(ESP_PLATFORM) - ~SensorDRV2605() +#if defined(USEING_I2C_LEGACY) + bool begin(i2c_port_t port_num, int sda = -1, int scl = -1) { - deinit(); + comm = std::make_unique(port_num, DRV2605_SLAVE_ADDRESS, sda, scl); + if (!comm) { + return false; + } + comm->init(); + return initImpl(); } - -#if defined(ARDUINO) - bool init(PLATFORM_WIRE_TYPE &w, int sda = DEFAULT_SDA, int scl = DEFAULT_SCL, uint8_t addr = DRV2605_SLAVE_ADDRESS) +#else + bool begin(i2c_master_bus_handle_t handle) { - return SensorCommon::begin(w, addr, sda, scl); + comm = std::make_unique(handle, DRV2605_SLAVE_ADDRESS); + if (!comm) { + return false; + } + comm->init(); + return initImpl(); } -#endif - +#endif //ESP_PLATFORM +#endif //ARDUINO - void deinit() + bool begin(SensorCommCustom::CustomCallback callback) { - // end(); + comm = std::make_unique(callback, DRV2605_SLAVE_ADDRESS); + if (!comm) { + return false; + } + comm->init(); + return initImpl(); } /**************************************************************************/ @@ -89,7 +111,7 @@ class SensorDRV2605 : /**************************************************************************/ void setWaveform(uint8_t slot, uint8_t w) { - writeRegister(DRV2605_REG_WAVESEQ1 + slot, w); + comm->writeRegister(DRV2605_REG_WAVESEQ1 + slot, w); } /**************************************************************************/ @@ -103,7 +125,7 @@ class SensorDRV2605 : /**************************************************************************/ void selectLibrary(uint8_t lib) { - writeRegister(DRV2605_REG_LIBRARY, lib); + comm->writeRegister(DRV2605_REG_LIBRARY, lib); } /**************************************************************************/ @@ -113,7 +135,7 @@ class SensorDRV2605 : /**************************************************************************/ void run() { - writeRegister(DRV2605_REG_GO, 1); + comm->writeRegister(DRV2605_REG_GO, 1); } /**************************************************************************/ @@ -123,7 +145,7 @@ class SensorDRV2605 : /**************************************************************************/ void stop() { - writeRegister(DRV2605_REG_GO, 0); + comm->writeRegister(DRV2605_REG_GO, (uint8_t)0); } /**************************************************************************/ @@ -144,7 +166,7 @@ class SensorDRV2605 : /**************************************************************************/ void setMode(uint8_t mode) { - writeRegister(DRV2605_REG_MODE, mode); + comm->writeRegister(DRV2605_REG_MODE, mode); } /**************************************************************************/ @@ -156,7 +178,7 @@ class SensorDRV2605 : /**************************************************************************/ void setRealtimeValue(uint8_t rtp) { - writeRegister(DRV2605_REG_RTPIN, rtp); + comm->writeRegister(DRV2605_REG_RTPIN, rtp); } /**************************************************************************/ @@ -166,7 +188,7 @@ class SensorDRV2605 : /**************************************************************************/ void useERM() { - writeRegister(DRV2605_REG_FEEDBACK, readRegister(DRV2605_REG_FEEDBACK) & 0x7F); + comm->writeRegister(DRV2605_REG_FEEDBACK, comm->readRegister(DRV2605_REG_FEEDBACK) & 0x7F); } /**************************************************************************/ @@ -176,14 +198,14 @@ class SensorDRV2605 : /**************************************************************************/ void useLRA() { - writeRegister(DRV2605_REG_FEEDBACK, readRegister(DRV2605_REG_FEEDBACK) | 0x80); + comm->writeRegister(DRV2605_REG_FEEDBACK, comm->readRegister(DRV2605_REG_FEEDBACK) | 0x80); } private: bool initImpl() { - int chipID = readRegister(DRV2605_REG_STATUS); - if (chipID == -1) { + int chipID = comm->readRegister(DRV2605_REG_STATUS); + if (chipID < 0) { return false; } chipID >>= 5; @@ -192,43 +214,38 @@ class SensorDRV2605 : chipID != DRV2605_CHIP_ID && chipID != DRV2604L_CHIP_ID && chipID != DRV2605L_CHIP_ID ) { - LOG("ChipID:0x%x should be 0x03 or 0x04 or 0x06 or 0x07\n", chipID); + log_e("ChipID:0x%x should be 0x03 or 0x04 or 0x06 or 0x07\n", chipID); return false; } - writeRegister(DRV2605_REG_MODE, 0x00); // out of standby + comm->writeRegister(DRV2605_REG_MODE, (uint8_t)0x00); // out of standby - writeRegister(DRV2605_REG_RTPIN, 0x00); // no real-time-playback + comm->writeRegister(DRV2605_REG_RTPIN, (uint8_t)0x00); // no real-time-playback - writeRegister(DRV2605_REG_WAVESEQ1, 1); // strong click - writeRegister(DRV2605_REG_WAVESEQ2, 0); // end sequence + comm->writeRegister(DRV2605_REG_WAVESEQ1, (uint8_t)1); // strong click + comm->writeRegister(DRV2605_REG_WAVESEQ2, (uint8_t)0); // end sequence - writeRegister(DRV2605_REG_OVERDRIVE, 0); // no overdrive + comm->writeRegister(DRV2605_REG_OVERDRIVE, (uint8_t)0); // no overdrive - writeRegister(DRV2605_REG_SUSTAINPOS, 0); - writeRegister(DRV2605_REG_SUSTAINNEG, 0); - writeRegister(DRV2605_REG_BREAK, 0); - writeRegister(DRV2605_REG_AUDIOMAX, 0x64); + comm->writeRegister(DRV2605_REG_SUSTAINPOS, (uint8_t)0); + comm->writeRegister(DRV2605_REG_SUSTAINNEG, (uint8_t)0); + comm->writeRegister(DRV2605_REG_BREAK, (uint8_t)0); + comm->writeRegister(DRV2605_REG_AUDIOMAX, (uint8_t)0x64); // ERM open loop // turn off N_ERM_LRA - writeRegister(DRV2605_REG_FEEDBACK, - readRegister(DRV2605_REG_FEEDBACK) & 0x7F); + comm->writeRegister(DRV2605_REG_FEEDBACK, + comm->readRegister(DRV2605_REG_FEEDBACK) & 0x7F); // turn on ERM_OPEN_LOOP - writeRegister(DRV2605_REG_CONTROL3, - readRegister(DRV2605_REG_CONTROL3) | 0x20); + comm->writeRegister(DRV2605_REG_CONTROL3, + comm->readRegister(DRV2605_REG_CONTROL3) | 0x20); return true; } - int getReadMaskImpl() - { - return -1; - } - protected: - + std::unique_ptr comm; }; diff --git a/src/SensorLTR553.hpp b/src/SensorLTR553.hpp index 19b39d6..dcefa9d 100644 --- a/src/SensorLTR553.hpp +++ b/src/SensorLTR553.hpp @@ -22,7 +22,7 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. * - * @file SensorLTR553ALS.tpp + * @file SensorLTR553ALS.hpp * @author Lewis He (lewishe@outlook.com) * @date 2023-09-09 * @@ -30,13 +30,10 @@ #pragma once #include "REG/LTR533Constants.h" -#include "SensorCommon.tpp" +#include "SensorPlatform.hpp" - -class SensorLTR553 : - public SensorCommon +class SensorLTR553 : public LTR553Constants { - friend class SensorCommon; public: enum IrqLevel { @@ -112,114 +109,127 @@ class SensorLTR553 : ALS_MEASUREMENT_TIME_2000MS, }; -#if defined(ARDUINO) - SensorLTR553(PLATFORM_WIRE_TYPE &w, int sda = DEFAULT_SDA, int scl = DEFAULT_SCL, uint8_t addr = LTR553_SLAVE_ADDRESS) + SensorLTR553() : comm(nullptr) {} + + ~SensorLTR553() { - __wire = &w; - __sda = sda; - __scl = scl; - __addr = addr; + if (comm) { + comm->deinit(); + } } -#endif - SensorLTR553() - { #if defined(ARDUINO) - __wire = &Wire; - __sda = DEFAULT_SDA; - __scl = DEFAULT_SCL; -#endif - __addr = LTR553_SLAVE_ADDRESS; + bool begin(TwoWire &wire, int sda = -1, int scl = -1) + { + comm = std::make_unique(wire, LTR553_SLAVE_ADDRESS, sda, scl); + if (!comm) { + return false; + } + comm->init(); + return initImpl(); } +#elif defined(ESP_PLATFORM) - ~SensorLTR553() +#if defined(USEING_I2C_LEGACY) + bool begin(i2c_port_t port_num, int sda = -1, int scl = -1) { - deinit(); + comm = std::make_unique(port_num, LTR553_SLAVE_ADDRESS, sda, scl); + if (!comm) { + return false; + } + comm->init(); + return initImpl(); } - -#if defined(ARDUINO) - bool init(PLATFORM_WIRE_TYPE &w, int sda = DEFAULT_SDA, int scl = DEFAULT_SCL, uint8_t addr = LTR553_SLAVE_ADDRESS) +#else + bool begin(i2c_master_bus_handle_t handle) { - return SensorCommon::begin(w, addr, sda, scl); + comm = std::make_unique(handle, LTR553_SLAVE_ADDRESS); + if (!comm) { + return false; + } + comm->init(); + return initImpl(); } -#endif +#endif //ESP_PLATFORM +#endif //ARDUINO - - void deinit() + bool begin(SensorCommCustom::CustomCallback callback) { - // end(); + comm = std::make_unique(callback, LTR553_SLAVE_ADDRESS); + if (!comm) { + return false; + } + comm->init(); + return initImpl(); } void setIRQLevel(IrqLevel level) { - level ? setRegisterBit(LTR553_REG_INTERRUPT, 2) : clrRegisterBit(LTR553_REG_INTERRUPT, 2); + level ? comm->setRegisterBit(REG_INTERRUPT, 2) : comm->clrRegisterBit(REG_INTERRUPT, 2); } void enableIRQ(IrqMode mode) { - writeRegister(LTR553_REG_INTERRUPT, 0xFC, mode); + comm->writeRegister(REG_INTERRUPT, 0xFC, mode); } void disableIRQ() { - writeRegister(LTR553_REG_INTERRUPT, 0xFC, 0x00); + comm->writeRegister(REG_INTERRUPT, 0xFC, 0x00); } - //! Light Sensor ! bool psAvailable() { - return getRegisterBit(LTR553_REG_ALS_PS_STATUS, 0); + return comm->getRegisterBit(REG_ALS_PS_STATUS, 0); } void setLightSensorThreshold(uint16_t low, uint16_t high) { - uint8_t buffer[4] = { - (uint8_t)(high & 0xFF), - (uint8_t)((high >> 8) & 0xFF), - (uint8_t)(low & 0xFF), - (uint8_t)((low >> 8) & 0xFF), - }; - writeRegister(LTR553_REG_ALS_THRES_UP_0, buffer, 4); + uint8_t buffer[4] = {lowByte(high), highByte(high), + lowByte(low), highByte(low) + }; + comm->writeRegister(REG_ALS_THRES_UP_0, buffer, 4); } // Controls the N number of times the measurement data is outside the range // defined by the upper and lower threshold limits before asserting the interrupt. void setLightSensorPersists(uint8_t count) { - writeRegister(LTR553_REG_INTERRUPT_PERSIST, 0xF0, count - 1); + comm->writeRegister(REG_INTERRUPT_PERSIST, 0xF0, count - 1); } void setLightSensorRate(IntegrationTime integrationTime, MeasurementRate measurementRate) { - writeRegister(LTR553_REG_ALS_MEAS_RATE, 0x00, (integrationTime & 0xF) << 8 | (measurementRate & 0xF)); + uint8_t value = (integrationTime & 0xF) << 8 | (measurementRate & 0xF); + comm->writeRegister(REG_ALS_MEAS_RATE, 0x00, value); } void enableLightSensor() { - setRegisterBit(LTR553_REG_ALS_CONTR, 0); + comm->setRegisterBit(REG_ALS_CONTR, 0); } void disableLightSensor() { - clrRegisterBit(LTR553_REG_ALS_CONTR, 0); + comm->clrRegisterBit(REG_ALS_CONTR, 0); } void setLightSensorGain(LightSensorGain gain) { - writeRegister(LTR553_REG_ALS_CONTR, 0xE3, gain<<2); + comm->writeRegister(REG_ALS_CONTR, 0xE3, gain << 2); } int getLightSensor(uint8_t ch) { uint8_t buffer[2] = {0}; // Check ALS Data is Valid - if (getRegisterBit(LTR553_REG_ALS_PS_STATUS, 7) != false) { + if (comm->getRegisterBit(REG_ALS_PS_STATUS, 7) != false) { return 0; } - int val = readRegister(ch == 1 ? LTR553_REG_ALS_DATA_CH1_0 : LTR553_REG_ALS_DATA_CH0_0, buffer, 2); - if (val == DEV_WIRE_ERR) { - return DEV_WIRE_ERR; + int val = comm->readRegister(ch == 1 ? REG_ALS_DATA_CH1_0 : REG_ALS_DATA_CH0_0, buffer, 2); + if (val == -1) { + return -1; } return buffer[0] | (buffer[1] << 8); } @@ -229,90 +239,89 @@ class SensorLTR553 : // defined by the upper and lower threshold limits before asserting the interrupt. void setProximityPersists(uint8_t count) { - writeRegister(LTR553_REG_INTERRUPT_PERSIST, 0x0F, count == 0 ? 0 : count - 1); + comm->writeRegister(REG_INTERRUPT_PERSIST, 0x0F, count == 0 ? 0 : count - 1); } void setProximityThreshold(uint16_t low, uint16_t high) { - writeRegister(LTR553_REG_PS_THRES_UP_0, lowByte(high)); - writeRegister(LTR553_REG_PS_THRES_UP_1, lowByte(high >> 8) & 0x0F); - writeRegister(LTR553_REG_PS_THRES_LOW_0, lowByte(low)); - writeRegister(LTR553_REG_PS_THRES_LOW_1, lowByte(low >> 8) & 0x0F); + comm->writeRegister(REG_PS_THRES_UP_0, lowByte(high)); + comm->writeRegister(REG_PS_THRES_UP_1, lowByte(high >> 8) & 0x0F); + comm->writeRegister(REG_PS_THRES_LOW_0, lowByte(low)); + comm->writeRegister(REG_PS_THRES_LOW_1, lowByte(low >> 8) & 0x0F); } void setProximityRate(PsRate rate) { - writeRegister(LTR553_REG_PS_MEAS_RATE, 0xF0, rate & 0x0F); + comm->writeRegister(REG_PS_MEAS_RATE, 0xF0, rate & 0x0F); } void enableProximity() { - writeRegister(LTR553_REG_PS_CONTR, 0xF3u, 0x03u); + comm->writeRegister(REG_PS_CONTR, 0xF3u, 0x03u); } void disableProximity() { - writeRegister(LTR553_REG_PS_CONTR, 0xF3u, 0x00u); + comm->writeRegister(REG_PS_CONTR, 0xF3u, 0x00u); } void enablePsIndicator() { - setRegisterBit(LTR553_REG_PS_CONTR, 5); + comm->setRegisterBit(REG_PS_CONTR, 5); } void disablePsIndicator() { - clrRegisterBit(LTR553_REG_PS_CONTR, 5); + comm->clrRegisterBit(REG_PS_CONTR, 5); } int getProximity(bool *saturated = NULL ) { uint8_t buffer[2] = {0}; - int val = readRegister(LTR553_REG_PS_DATA_0, buffer, 2); - if (val == DEV_WIRE_ERR) { - return DEV_WIRE_ERR; + int val = comm->readRegister(REG_PS_DATA_0, buffer, 2); + if (val == -1) { + return -1; } if (saturated) { *saturated = buffer[1] & 0x80; } - int high = buffer[1] & 0x07; - return (high << 8) | buffer[0]; + return buffer[0] | (buffer[1] & 0x07); } void setPsLedPulsePeriod(PsLedPeriod period) { - writeRegister(LTR553_REG_PS_LED, 0x1F, period); + comm->writeRegister(REG_PS_LED, 0x1F, period); } void setPsLedDutyCycle(PsLedDuty duty) { - writeRegister(LTR553_REG_PS_LED, 0xE7, duty); + comm->writeRegister(REG_PS_LED, 0xE7, duty); } void setPsLedCurrent(PsLedCurrent cur) { - writeRegister(LTR553_REG_PS_LED, 0xF8, cur); + comm->writeRegister(REG_PS_LED, 0xF8, cur); } void setPsLedPulses(uint8_t pulesNum) { - writeRegister(LTR553_REG_PS_N_PULSES, 0xF0, pulesNum & 0x0F); + comm->writeRegister(REG_PS_N_PULSES, 0xF0, pulesNum & 0x0F); } int getPartID() { - int val = readRegister(LTR553_REG_PART_ID); - if (val == DEV_WIRE_ERR) { - return DEV_WIRE_ERR; + int val = comm->readRegister(REG_PART_ID); + if (val == -1) { + return -1; } return (val >> 4) & 0x0F; } int getRevisionID() { - int val = readRegister(LTR553_REG_PART_ID); - if (val == DEV_WIRE_ERR) { - return DEV_WIRE_ERR; + int val = comm->readRegister(REG_PART_ID); + if (val == -1) { + return -1; } return (val) & 0x0F; } @@ -320,30 +329,26 @@ class SensorLTR553 : int getManufacturerID() { // Manufacturer ID (0x05H) - return readRegister(LTR553_REG_MANUFAC_ID); + return comm->readRegister(REG_MANUFAC_ID); } void reset() { - setRegisterBit(LTR553_REG_ALS_CONTR, 1); + comm->setRegisterBit(REG_ALS_CONTR, 1); } private: bool initImpl() { - setReadRegisterSendStop(false); + I2CParam params(I2CParam::I2C_SET_FLAG, false); + comm->setParams(params); reset(); return getManufacturerID() == LTR553_DEFAULT_MAN_ID; } - int getReadMaskImpl() - { - return -1; - } - protected: - + std::unique_ptr comm; }; diff --git a/src/SensorLib.h b/src/SensorLib.h index fa05184..aa0a0e1 100644 --- a/src/SensorLib.h +++ b/src/SensorLib.h @@ -28,23 +28,10 @@ */ #pragma once - #if defined(ARDUINO) #include #include #include -#elif defined(ESP_PLATFORM) -#include "sdkconfig.h" -#include "freertos/FreeRTOS.h" -#include "esp_log.h" -#include "esp_err.h" -#include -#include "esp_idf_version.h" -#if ((ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL(5,0,0)) && defined(CONFIG_SENSORLIB_ESP_IDF_NEW_API)) -#include "driver/i2c_master.h" -#else -#include "driver/i2c.h" -#endif //ESP_IDF_VERSION #else #include #include @@ -52,182 +39,100 @@ #endif #include "SensorLib_Version.h" +#include "DevicesPins.h" #ifdef ARDUINO_ARCH_MBED // Not supported at the moment #error The Arduino RP2040 MBED board package is not supported when PIO is used. Use the community package by Earle Philhower. #endif -#if defined(ARDUINO) -#if defined(ARDUINO_ARCH_RP2040) -#define PLATFORM_SPI_TYPE SPIClassRP2040 -#define PLATFORM_WIRE_TYPE TwoWire -#define SPI_DATA_ORDER SPI_MSB_FIRST -#define DEFAULT_SDA (0xFF) -#define DEFAULT_SCL (0xFF) -#define DEFAULT_SPISETTING SPISettings() -#elif defined(ARDUINO_ARCH_STM32) -#define PLATFORM_SPI_TYPE SPIClass -#define PLATFORM_WIRE_TYPE TwoWire -#define SPI_DATA_ORDER MSBFIRST -#define DEFAULT_SDA (0xFF) -#define DEFAULT_SCL (0xFF) -#define DEFAULT_SPISETTING SPISettings() -#elif defined(ARDUINO_ARCH_NRF52) -#define PLATFORM_SPI_TYPE SPIClass -#define PLATFORM_WIRE_TYPE TwoWire -#define SPI_DATA_ORDER MSBFIRST -#define DEFAULT_SDA (0xFF) -#define DEFAULT_SCL (0xFF) -#define DEFAULT_SPISETTING SPISettings() -#else -#define PLATFORM_SPI_TYPE SPIClass -#define PLATFORM_WIRE_TYPE TwoWire -#define SPI_DATA_ORDER SPI_MSBFIRST -#define DEFAULT_SDA (SDA) -#define DEFAULT_SCL (SCL) -#define DEFAULT_SPISETTING SPISettings(__freq, __dataOrder, __dataMode); -#endif - -#elif defined(ESP_PLATFORM) - -#define SENSORLIB_I2C_MASTER_TX_BUF_DISABLE 0 /*!< I2C master doesn't need buffer */ -#define SENSORLIB_I2C_MASTER_RX_BUF_DISABLE 0 /*!< I2C master doesn't need buffer */ -#define SENSORLIB_I2C_MASTER_TIMEOUT_MS 1000 -#define SENSORLIB_I2C_MASTER_SEEED 400000 - -#endif - #ifndef I2C_BUFFER_LENGTH #define I2C_BUFFER_LENGTH (32) #endif -enum SensorLibInterface { - SENSORLIB_SPI_INTERFACE = 1, - SENSORLIB_I2C_INTERFACE -}; - -typedef struct __SensorLibPins { - int irq; - int rst; - union __ { - struct { - int sda; - int scl; - int addr; -#ifdef ARDUINO - PLATFORM_WIRE_TYPE *wire; -#endif - } i2c_dev; - struct { - int cs; - int miso; - int mosi; - int sck; -#ifdef ARDUINO - PLATFORM_SPI_TYPE *spi; +#if defined(ARDUINO_ARCH_RP2040) +#define SPIClass SPIClassRP2040 #endif - } spi_dev; - } u ; - SensorLibInterface intf; -} SensorLibConfigure; - - - - -#define SENSOR_PIN_NONE (-1) -#define DEV_WIRE_NONE (0) -#define DEV_WIRE_ERR (-1) -#define DEV_WIRE_TIMEOUT (-2) - - -#ifndef IRAM_ATTR -#define IRAM_ATTR -#endif - #ifdef _BV #undef _BV #endif #define _BV(b) (1UL << (uint32_t)(b)) -// #define LOG_PORT Serial -#ifdef LOG_PORT -#define LOG(fmt, ...) LOG_PORT.printf("[%s] " fmt "\n", __func__, ##__VA_ARGS__) -#define LOG_BIN(x) LOG_PORT.println(x,BIN); -#else -#define LOG(fmt, ...) printf("[%s] " fmt "\n", __func__, ##__VA_ARGS__) -#define LOG_BIN(x) printf("[%s] 0x%X\n", __func__, x) -#endif - #ifndef lowByte -#define lowByte(w) ((uint8_t) ((w) & 0xff)) +#define lowByte(w) ((uint8_t) ((w) & 0xff)) #endif #ifndef highByte -#define highByte(w) ((uint8_t) ((w) >> 8)) +#define highByte(w) ((uint8_t) ((w) >> 8)) #endif #ifndef bitRead -#define bitRead(value, bit) (((value) >> (bit)) & 0x01) +#define bitRead(value, bit) (((value) >> (bit)) & 0x01) #endif #ifndef bitSet -#define bitSet(value, bit) ((value) |= (1UL << (bit))) +#define bitSet(value, bit) ((value) |= (1UL << (bit))) #endif #ifndef bitClear -#define bitClear(value, bit) ((value) &= ~(1UL << (bit))) +#define bitClear(value, bit) ((value) &= ~(1UL << (bit))) #endif #ifndef bitToggle -#define bitToggle(value, bit) ((value) ^= (1UL << (bit))) +#define bitToggle(value, bit) ((value) ^= (1UL << (bit))) #endif #ifndef bitWrite -#define bitWrite(value, bit, bitvalue) ((bitvalue) ? bitSet(value, bit) : bitClear(value, bit)) +#define bitWrite(value, bit, bitvalue) ((bitvalue) ? bitSet(value, bit) : bitClear(value, bit)) #endif #ifndef isBitSet -#define isBitSet(value, bit) (((value) & (1UL << (bit))) == (1UL << (bit))) +#define isBitSet(value, bit) (((value) & (1UL << (bit))) == (1UL << (bit))) #endif -#define SENSORLIB_ATTR_NOT_IMPLEMENTED __attribute__((error("Not implemented"))) +#define ATTR_NOT_IMPLEMENTED __attribute__((error("Not implemented"))) -#define SENSORLIB_COUNT(x) (sizeof(x)/sizeof(*x)) #if !defined(ARDUINO_ARCH_ESP32) && defined(LOG_PORT) && defined(ARDUINO) #define LOG_FILE_LINE_INFO __FILE__, __LINE__ #ifndef log_e -#define log_e(fmt, ...) LOG_PORT.printf("[E][%s:%d] " fmt "\n", LOG_FILE_LINE_INFO, ##__VA_ARGS__) +#define log_e(fmt, ...) LOG_PORT.printf("[E][%s:%d] " fmt "\n", LOG_FILE_LINE_INFO, ##__VA_ARGS__) #endif /*log_e*/ #ifndef log_i -#define log_i(fmt, ...) LOG_PORT.printf("[I][%s:%d] " fmt "\n", LOG_FILE_LINE_INFO, ##__VA_ARGS__) +#define log_i(fmt, ...) LOG_PORT.printf("[I][%s:%d] " fmt "\n", LOG_FILE_LINE_INFO, ##__VA_ARGS__) #endif /*log_i*/ #ifndef log_d -#define log_d(fmt, ...) LOG_PORT.printf("[D][%s:%d] " fmt "\n", LOG_FILE_LINE_INFO, ##__VA_ARGS__) +#define log_d(fmt, ...) LOG_PORT.printf("[D][%s:%d] " fmt "\n", LOG_FILE_LINE_INFO, ##__VA_ARGS__) #endif /*log_d*/ -#elif defined(ESP_PLATFORM) +#elif defined(ESP_PLATFORM) && !defined(ARDUINO) -#ifndef log_e -#define log_e(...) printf(__VA_ARGS__) -#endif +#include "esp_log.h" -#ifndef log_i -#define log_i(...) printf(__VA_ARGS__) -#endif +#define ESP_TAG_LIB "SensorLib" +#if defined(__cplusplus) && (__cplusplus > 201703L) +#define log_e(format, ... ) ESP_LOG_LEVEL_LOCAL(ESP_LOG_ERROR, ESP_TAG_LIB, format __VA_OPT__(,) __VA_ARGS__) +#define log_w(format, ... ) ESP_LOG_LEVEL_LOCAL(ESP_LOG_WARN, ESP_TAG_LIB, format __VA_OPT__(,) __VA_ARGS__) +#define log_i(format, ... ) ESP_LOG_LEVEL_LOCAL(ESP_LOG_INFO, ESP_TAG_LIB, format __VA_OPT__(,) __VA_ARGS__) +#define log_d(format, ... ) ESP_LOG_LEVEL_LOCAL(ESP_LOG_DEBUG, ESP_TAG_LIB, format __VA_OPT__(,) __VA_ARGS__) +#define log_v(format, ... ) ESP_LOG_LEVEL_LOCAL(ESP_LOG_VERBOSE, ESP_TAG_LIB, format __VA_OPT__(,) __VA_ARGS__) +#else // !(defined(__cplusplus) && (__cplusplus > 201703L)) +#define log_e(format, ... ) ESP_LOG_LEVEL_LOCAL(ESP_LOG_ERROR, ESP_TAG_LIB, format, ##__VA_ARGS__) +#define log_w(format, ... ) ESP_LOG_LEVEL_LOCAL(ESP_LOG_WARN, ESP_TAG_LIB, format, ##__VA_ARGS__) +#define log_i(format, ... ) ESP_LOG_LEVEL_LOCAL(ESP_LOG_INFO, ESP_TAG_LIB, format, ##__VA_ARGS__) +#define log_d(format, ... ) ESP_LOG_LEVEL_LOCAL(ESP_LOG_DEBUG, ESP_TAG_LIB, format, ##__VA_ARGS__) +#define log_v(format, ... ) ESP_LOG_LEVEL_LOCAL(ESP_LOG_VERBOSE, ESP_TAG_LIB, format, ##__VA_ARGS__) +#endif // !(defined(__cplusplus) && (__cplusplus > 201703L)) -#ifndef log_d -#define log_d(...) printf(__VA_ARGS__) -#endif -#else + +#else /*ESP_PLATFORM*/ #ifndef log_e #define log_e(...) @@ -262,16 +167,12 @@ typedef struct __SensorLibPins { #endif #ifndef LOW -#define LOW 0 +#define LOW (0) #endif #ifndef HIGH -#define HIGH 1 +#define HIGH (1) #endif -#include "platform/esp_arduino.h" - #endif - -#include "DevicesPins.h" \ No newline at end of file diff --git a/src/SensorLib_Version.h b/src/SensorLib_Version.h index 1346183..bae1bd1 100644 --- a/src/SensorLib_Version.h +++ b/src/SensorLib_Version.h @@ -33,9 +33,9 @@ /** Major version number (X.x.x) */ #define SENSORLIB_VERSION_MAJOR 0 /** Minor version number (x.X.x) */ -#define SENSORLIB_VERSION_MINOR 2 +#define SENSORLIB_VERSION_MINOR 3 /** Patch version number (x.x.X) */ -#define SENSORLIB_VERSION_PATCH 5 +#define SENSORLIB_VERSION_PATCH 0 /** * Macro to convert SENSORLIB version number into an integer @@ -53,4 +53,4 @@ SENSORLIB_VERSION_MINOR, \ SENSORLIB_VERSION_PATCH) -#define SENSORLIB_VERSION_STR "v0.2.5" +#define SENSORLIB_VERSION_STR "v0.3.0" diff --git a/src/SensorPCF85063.hpp b/src/SensorPCF85063.hpp index 2b8cf45..525fa69 100644 --- a/src/SensorPCF85063.hpp +++ b/src/SensorPCF85063.hpp @@ -29,15 +29,14 @@ */ #pragma once #include "REG/PCF85063Constants.h" -#include "SensorCommon.tpp" #include "SensorRTC.h" +#include "SensorPlatform.hpp" class SensorPCF85063 : - public SensorCommon, - public RTCCommon + public RTCCommon, + public PCF85063Constants { - friend class SensorCommon; friend class RTCCommon; public: @@ -52,43 +51,58 @@ class SensorPCF85063 : CLK_LOW, }; + SensorPCF85063() : comm(nullptr) {} -#if defined(ARDUINO) - SensorPCF85063(PLATFORM_WIRE_TYPE &w, int sda = DEFAULT_SDA, int scl = DEFAULT_SCL, uint8_t addr = PCF85063_SLAVE_ADDRESS) + ~SensorPCF85063() { - __wire = &w; - __sda = sda; - __scl = scl; - __addr = addr; + if (comm) { + comm->deinit(); + } } -#endif - SensorPCF85063() - { #if defined(ARDUINO) - __wire = &Wire; - __sda = DEFAULT_SDA; - __scl = DEFAULT_SCL; -#endif - __addr = PCF85063_SLAVE_ADDRESS; + bool begin(TwoWire &wire, int sda = -1, int scl = -1) + { + comm = std::make_unique(wire, PCF85063_SLAVE_ADDRESS, sda, scl); + if (!comm) { + return false; + } + comm->init(); + return initImpl(); } +#elif defined(ESP_PLATFORM) - ~SensorPCF85063() +#if defined(USEING_I2C_LEGACY) + bool begin(i2c_port_t port_num, int sda = -1, int scl = -1) { - deinit(); + comm = std::make_unique(port_num, PCF85063_SLAVE_ADDRESS, sda, scl); + if (!comm) { + return false; + } + comm->init(); + return initImpl(); } - -#if defined(ARDUINO) - bool init(PLATFORM_WIRE_TYPE &w, int sda = DEFAULT_SDA, int scl = DEFAULT_SCL, uint8_t addr = PCF85063_SLAVE_ADDRESS) +#else + bool begin(i2c_master_bus_handle_t handle) { - return SensorCommon::begin(w, addr, sda, scl); + comm = std::make_unique(handle, PCF85063_SLAVE_ADDRESS); + if (!comm) { + return false; + } + comm->init(); + return initImpl(); } -#endif - +#endif //ESP_PLATFORM +#endif //ARDUINO - void deinit() + bool begin(SensorCommCustom::CustomCallback callback) { - // end(); + comm = std::make_unique(callback, PCF85063_SLAVE_ADDRESS); + if (!comm) { + return false; + } + comm->init(); + return initImpl(); } void setDateTime(RTC_DateTime datetime) @@ -96,6 +110,11 @@ class SensorPCF85063 : setDateTime(datetime.year, datetime.month, datetime.day, datetime.hour, datetime.minute, datetime.second); } + void setDateTime(struct tm timeinfo) + { + setDateTime(timeinfo.tm_yday + 1900, timeinfo.tm_mon + 1, timeinfo.tm_mday, timeinfo.tm_hour, timeinfo.tm_min, timeinfo.tm_sec); + } + void setDateTime(uint16_t year, uint8_t month, uint8_t day, @@ -112,7 +131,7 @@ class SensorPCF85063 : buffer[5] = DEC2BCD(month); buffer[6] = DEC2BCD(year % 100); - writeRegister(PCF85063_SEC_REG, buffer, 7); + comm->writeRegister(PCF85063_SEC_REG, buffer, 7); } @@ -120,7 +139,7 @@ class SensorPCF85063 : { RTC_DateTime datetime; uint8_t buffer[7]; - readRegister(PCF85063_SEC_REG, buffer, 7); + comm->readRegister(PCF85063_SEC_REG, buffer, 7); datetime.available = ((buffer[0] & 0x80) == 0x80) ? false : true; datetime.second = BCD2DEC(buffer[0] & 0x7F); datetime.minute = BCD2DEC(buffer[1] & 0x7F); @@ -144,7 +163,7 @@ class SensorPCF85063 : } /* - Defalut use 24H mode + Default use 24H mode bool is24HourMode() { return is24Hour; @@ -158,55 +177,55 @@ class SensorPCF85063 : void set24Hour() { is24Hour = true; - clrRegisterBit(PCF85063_CTRL1_REG, 1); + comm->clrRegisterBit(PCF85063_CTRL1_REG, 1); } void set12Hour() { is24Hour = false; - setRegisterBit(PCF85063_CTRL1_REG, 1); + comm->setRegisterBit(PCF85063_CTRL1_REG, 1); } */ void stop() { - setRegisterBit(PCF85063_CTRL1_REG, 5); + comm->setRegisterBit(PCF85063_CTRL1_REG, 5); } void start() { - clrRegisterBit(PCF85063_CTRL1_REG, 5); + comm->clrRegisterBit(PCF85063_CTRL1_REG, 5); } bool isRunning() { - return !getRegisterBit(PCF85063_CTRL1_REG, 5); + return !comm->getRegisterBit(PCF85063_CTRL1_REG, 5); } void enableAlarm() { - setRegisterBit(PCF85063_CTRL2_REG, 7); + comm->setRegisterBit(PCF85063_CTRL2_REG, 7); } void disableAlarm() { - clrRegisterBit(PCF85063_CTRL2_REG, 7); + comm->clrRegisterBit(PCF85063_CTRL2_REG, 7); } void resetAlarm() { - clrRegisterBit(PCF85063_CTRL2_REG, 6); + comm->clrRegisterBit(PCF85063_CTRL2_REG, 6); } bool isAlarmActive() { - return getRegisterBit(PCF85063_CTRL2_REG, 6); + return comm->getRegisterBit(PCF85063_CTRL2_REG, 6); } RTC_Alarm getAlarm() { uint8_t buffer[5]; - readRegister(PCF85063_ALRM_MIN_REG, buffer, 5); + comm->readRegister(PCF85063_ALRM_MIN_REG, buffer, 5); buffer[0] = BCD2DEC(buffer[0] & 0x80); //second buffer[1] = BCD2DEC(buffer[1] & 0x40); //minute buffer[2] = BCD2DEC(buffer[2] & 0x40); //hour @@ -277,7 +296,6 @@ class SensorPCF85063 : buffer[2] = PCF85063_ALARM_ENABLE; } if (day != PCF85063_NO_ALARM) { - //TODO:Check day in Month buffer[3] = DEC2BCD(((day) < (1) ? (1) : ((day) > (daysInMonth) ? (daysInMonth) : (day)))); buffer[3] &= ~PCF85063_ALARM_ENABLE; } else { @@ -292,7 +310,7 @@ class SensorPCF85063 : } else { buffer[4] = PCF85063_ALARM_ENABLE; } - writeRegister(PCF85063_ALRM_SEC_REG, buffer, 4); + comm->writeRegister(PCF85063_ALRM_SEC_REG, buffer, 4); } void setAlarmByHours(uint8_t hour) @@ -342,11 +360,11 @@ class SensorPCF85063 : void setClockOutput(ClockHz hz) { - int val = readRegister(PCF85063_CTRL2_REG); - if (val == DEV_WIRE_ERR)return; + int val = comm->readRegister(PCF85063_CTRL2_REG); + if (val == -1)return; val &= 0xF8; val |= hz; - writeRegister(PCF85063_CTRL2_REG, val); + comm->writeRegister(PCF85063_CTRL2_REG, val); } private: @@ -357,8 +375,8 @@ class SensorPCF85063 : // it will return failure. Here only to judge whether the device communication is normal //Check device is online - int ret = readRegister(PCF85063_SEC_REG); - if (ret == DEV_WIRE_ERR) { + int ret = comm->readRegister(PCF85063_SEC_REG); + if (ret == -1) { return false; } if (BCD2DEC(ret & 0x7F) > 59) { @@ -366,10 +384,10 @@ class SensorPCF85063 : } //Default use 24-hour mode - is24Hour = !getRegisterBit(PCF85063_CTRL1_REG, 1); + is24Hour = !comm->getRegisterBit(PCF85063_CTRL1_REG, 1); if (!is24Hour) { // Set 24H Mode - clrRegisterBit(PCF85063_CTRL1_REG, 1); + comm->clrRegisterBit(PCF85063_CTRL1_REG, 1); } //Turn on RTC @@ -378,14 +396,9 @@ class SensorPCF85063 : return isRunning(); } - int getReadMaskImpl() - { - return -1; - } - protected: - bool is24Hour = true; + std::unique_ptr comm; }; diff --git a/src/SensorPCF8563.hpp b/src/SensorPCF8563.hpp index a4c1a14..edc345a 100644 --- a/src/SensorPCF8563.hpp +++ b/src/SensorPCF8563.hpp @@ -30,62 +30,76 @@ #pragma once #include "REG/PCF8563Constants.h" -#include "SensorCommon.tpp" #include "SensorRTC.h" +#include "SensorPlatform.hpp" class SensorPCF8563 : - public SensorCommon, - public RTCCommon + public RTCCommon, + public PCF8563Constants { - friend class SensorCommon; friend class RTCCommon; public: enum ClockHz { - CLK_32_768KHZ, - CLK_1024KHZ, + CLK_32768HZ, + CLK_1024HZ, CLK_32HZ, CLK_1HZ, CLK_DISABLE, }; + SensorPCF8563() : comm(nullptr) {} -#if defined(ARDUINO) - SensorPCF8563(PLATFORM_WIRE_TYPE &w, int sda = DEFAULT_SDA, int scl = DEFAULT_SCL, uint8_t addr = PCF8563_SLAVE_ADDRESS) + ~SensorPCF8563() { - __wire = &w; - __sda = sda; - __scl = scl; - __addr = addr; + if (comm) { + comm->deinit(); + } } -#endif - SensorPCF8563() - { #if defined(ARDUINO) - __wire = &Wire; - __sda = DEFAULT_SDA; - __scl = DEFAULT_SCL; -#endif - __addr = PCF8563_SLAVE_ADDRESS; + bool begin(TwoWire &wire, int sda = -1, int scl = -1) + { + comm = std::make_unique(wire, PCF8563_SLAVE_ADDRESS, sda, scl); + if (!comm) { + return false; + } + comm->init(); + return initImpl(); } +#elif defined(ESP_PLATFORM) - ~SensorPCF8563() +#if defined(USEING_I2C_LEGACY) + bool begin(i2c_port_t port_num, int sda = -1, int scl = -1) { - deinit(); + comm = std::make_unique(port_num, PCF8563_SLAVE_ADDRESS, sda, scl); + if (!comm) { + return false; + } + comm->init(); + return initImpl(); } - -#if defined(ARDUINO) - bool init(PLATFORM_WIRE_TYPE &w, int sda = DEFAULT_SDA, int scl = DEFAULT_SCL, uint8_t addr = PCF8563_SLAVE_ADDRESS) +#else + bool begin(i2c_master_bus_handle_t handle) { - return SensorCommon::begin(w, addr, sda, scl); + comm = std::make_unique(handle, PCF8563_SLAVE_ADDRESS); + if (!comm) { + return false; + } + comm->init(); + return initImpl(); } -#endif - +#endif //ESP_PLATFORM +#endif //ARDUINO - void deinit() + bool begin(SensorCommCustom::CustomCallback callback) { - // end(); + comm = std::make_unique(callback, PCF8563_SLAVE_ADDRESS); + if (!comm) { + return false; + } + comm->init(); + return initImpl(); } void setDateTime(RTC_DateTime datetime) @@ -93,6 +107,10 @@ class SensorPCF8563 : setDateTime(datetime.year, datetime.month, datetime.day, datetime.hour, datetime.minute, datetime.second); } + void setDateTime(struct tm timeinfo) + { + setDateTime(timeinfo.tm_yday + 1900, timeinfo.tm_mon + 1, timeinfo.tm_mday, timeinfo.tm_hour, timeinfo.tm_min, timeinfo.tm_sec); + } void setDateTime(uint16_t year, uint8_t month, @@ -115,15 +133,14 @@ class SensorPCF8563 : } else { buffer[5] |= 0x80; } - writeRegister(PCF8563_SEC_REG, buffer, 7); + comm->writeRegister(SEC_REG, buffer, 7); } - RTC_DateTime getDateTime() { RTC_DateTime datetime; uint8_t buffer[7]; - readRegister(PCF8563_SEC_REG, buffer, 7); + comm->readRegister(SEC_REG, buffer, 7); datetime.available = ((buffer[0] & 0x80) == 0x80) ? false : true; datetime.second = BCD2DEC(buffer[0] & 0x7F); datetime.minute = BCD2DEC(buffer[1] & 0x7F); @@ -132,8 +149,8 @@ class SensorPCF8563 : datetime.week = BCD2DEC(buffer[4] & 0x07); datetime.month = BCD2DEC(buffer[5] & 0x1F); datetime.year = BCD2DEC(buffer[6]); - //cetury : 0 = 1900 , 1 = 2000 - datetime.year += (buffer[5] & PCF8563_CENTURY_MASK) ? 1900 : 2000; + //century : 0 = 1900 , 1 = 2000 + datetime.year += (buffer[5] & CENTURY_MASK) ? 1900 : 2000; return datetime; } @@ -146,7 +163,7 @@ class SensorPCF8563 : RTC_Alarm getAlarm() { uint8_t buffer[4]; - readRegister(PCF8563_ALRM_MIN_REG, buffer, 4); + comm->readRegister(ALRM_MIN_REG, buffer, 4); buffer[0] = BCD2DEC(buffer[0] & 0x80); //minute buffer[1] = BCD2DEC(buffer[1] & 0x40); //hour buffer[2] = BCD2DEC(buffer[2] & 0x40); //day @@ -157,22 +174,22 @@ class SensorPCF8563 : void enableAlarm() { - setRegisterBit(PCF8563_STAT2_REG, 1); + comm->setRegisterBit(STAT2_REG, 1); } void disableAlarm() { - clrRegisterBit(PCF8563_STAT2_REG, 1); + comm->clrRegisterBit(STAT2_REG, 1); } void resetAlarm() { - clrRegisterBit(PCF8563_STAT2_REG, 3); + comm->clrRegisterBit(STAT2_REG, 3); } bool isAlarmActive() { - return getRegisterBit(PCF8563_STAT2_REG, 3); + return comm->getRegisterBit(STAT2_REG, 3); } void setAlarm(RTC_Alarm alarm) @@ -188,168 +205,131 @@ class SensorPCF8563 : uint8_t daysInMonth = getDaysInMonth(datetime.month, datetime.year); - if (minute != PCF8563_NO_ALARM) { + if (minute != NO_ALARM) { if (minute > 59) { minute = 59; } buffer[0] = DEC2BCD(minute); - buffer[0] &= ~PCF8563_ALARM_ENABLE; + buffer[0] &= ~ALARM_ENABLE; } else { - buffer[0] = PCF8563_ALARM_ENABLE; + buffer[0] = ALARM_ENABLE; } - if (hour != PCF8563_NO_ALARM) { + if (hour != NO_ALARM) { if (hour > 23) { hour = 23; } buffer[1] = DEC2BCD(hour); - buffer[1] &= ~PCF8563_ALARM_ENABLE; + buffer[1] &= ~ALARM_ENABLE; } else { - buffer[1] = PCF8563_ALARM_ENABLE; + buffer[1] = ALARM_ENABLE; } - if (day != PCF8563_NO_ALARM) { - //TODO:Check day in Month + if (day != NO_ALARM) { buffer[2] = DEC2BCD(((day) < (1) ? (1) : ((day) > (daysInMonth) ? (daysInMonth) : (day)))); - buffer[2] &= ~PCF8563_ALARM_ENABLE; + buffer[2] &= ~ALARM_ENABLE; } else { - buffer[2] = PCF8563_ALARM_ENABLE; + buffer[2] = ALARM_ENABLE; } - if (week != PCF8563_NO_ALARM) { + if (week != NO_ALARM) { if (week > 6) { week = 6; } buffer[3] = DEC2BCD(week); - buffer[3] &= ~PCF8563_ALARM_ENABLE; + buffer[3] &= ~ALARM_ENABLE; } else { - buffer[3] = PCF8563_ALARM_ENABLE; + buffer[3] = ALARM_ENABLE; } - writeRegister(PCF8563_ALRM_MIN_REG, buffer, 4); + comm->writeRegister(ALRM_MIN_REG, buffer, 4); } void setAlarmByMinutes(uint8_t minute) { - setAlarm(PCF8563_NO_ALARM, minute, PCF8563_NO_ALARM, PCF8563_NO_ALARM); + setAlarm(NO_ALARM, minute, NO_ALARM, NO_ALARM); } void setAlarmByDays(uint8_t day) { - setAlarm(PCF8563_NO_ALARM, PCF8563_NO_ALARM, day, PCF8563_NO_ALARM); + setAlarm(NO_ALARM, NO_ALARM, day, NO_ALARM); } void setAlarmByHours(uint8_t hour) { - setAlarm(hour, PCF8563_NO_ALARM, PCF8563_NO_ALARM, PCF8563_NO_ALARM); + setAlarm(hour, NO_ALARM, NO_ALARM, NO_ALARM); } void setAlarmByWeekDay(uint8_t week) { - setAlarm(PCF8563_NO_ALARM, PCF8563_NO_ALARM, PCF8563_NO_ALARM, week); + setAlarm(NO_ALARM, NO_ALARM, NO_ALARM, week); } bool isCountdownTimerEnable() { uint8_t buffer[2]; - buffer[0] = readRegister(PCF8563_STAT2_REG); - buffer[1] = readRegister(PCF8563_TIMER1_REG); - if (buffer[0] & PCF8563_TIMER_TIE) { - return buffer[1] & PCF8563_TIMER_TE ? true : false; + buffer[0] = comm->readRegister(STAT2_REG); + buffer[1] = comm->readRegister(TIMER1_REG); + if (buffer[0] & TIMER_TIE) { + return buffer[1] & TIMER_TE ? true : false; } return false; } bool isCountdownTimerActive() { - return getRegisterBit(PCF8563_STAT2_REG, 2); + return comm->getRegisterBit(STAT2_REG, 2); } void enableCountdownTimer() { - setRegisterBit(PCF8563_STAT2_REG, 0); + comm->setRegisterBit(STAT2_REG, 0); } void disableCountdownTimer() { - clrRegisterBit(PCF8563_STAT2_REG, 0); + comm->clrRegisterBit(STAT2_REG, 0); } void setCountdownTimer(uint8_t val, uint8_t freq) { uint8_t buffer[3]; - buffer[1] = readRegister(PCF8563_TIMER1_REG); - buffer[1] |= (freq & PCF8563_TIMER_TD10); + buffer[1] = comm->readRegister(TIMER1_REG); + buffer[1] |= (freq & TIMER_TD10); buffer[2] = val; - writeRegister(PCF8563_TIMER1_REG, buffer[1]); - writeRegister(PCF8563_TIMER2_REG, buffer[2]); + comm->writeRegister(TIMER1_REG, buffer[1]); + comm->writeRegister(TIMER2_REG, buffer[2]); } void clearCountdownTimer() { uint8_t val; - val = readRegister(PCF8563_STAT2_REG); - val &= ~(PCF8563_TIMER_TF | PCF8563_TIMER_TIE); - val |= PCF8563_ALARM_AF; - writeRegister(PCF8563_STAT2_REG, val); - writeRegister(PCF8563_TIMER1_REG, 0x00); + val = comm->readRegister(STAT2_REG); + val &= ~(TIMER_TF | TIMER_TIE); + val |= ALARM_AF; + comm->writeRegister(STAT2_REG, val); + comm->writeRegister(TIMER1_REG, (uint8_t)0x00); } void setClockOutput(ClockHz freq) { if (freq == CLK_DISABLE) { - clrRegisterBit(PCF8563_SQW_REG, 7); + comm->clrRegisterBit(SQW_REG, 7); } else { - writeRegister(PCF8563_SQW_REG, freq | PCF8563_CLK_ENABLE); + comm->writeRegister(SQW_REG, freq | CLK_ENABLE); } } - private: bool initImpl() { - // Check whether RTC time is valid? If it is invalid, it can be judged - // that there is a problem with the hardware, or the RTC power supply voltage is too low - /* - int count = 0; - for (int i = 0; i < 3; ++i) { - if (!getRegisterBit(PCF8563_SEC_REG, 7)) { - count++; - } - } - if (count != 3 ) { - return false; - } - */ - - // 230704:Does not use power-off judgment, if the RTC backup battery is not installed, - // it will return failure. Here only to judge whether the device communication is normal - //Check device is online - int ret = readRegister(PCF8563_SEC_REG); - if (ret == DEV_WIRE_ERR) { + int ret = comm->readRegister(SEC_REG); + if (ret < 0) { return false; } if (BCD2DEC(ret & 0x7F) > 59) { return false; } - - // Determine whether the hardware clock year, month, and day match the internal time of the RTC. - // If they do not match, it will be updated to the compilation date - // RTC_DateTime compileDatetime = RTC_DateTime(__DATE__, __TIME__); - // RTC_DateTime hwDatetime = getDateTime(); - // if (compileDatetime.year != hwDatetime.year || - // compileDatetime.month != hwDatetime.month || - // compileDatetime.day != hwDatetime.month - // ) { - // LOG("No match yy:mm:dd . set datetime to compilation date time"); - // setDateTime(compileDatetime); - // } return true; } - int getReadMaskImpl() - { - return -1; - } - protected: - - + std::unique_ptr comm; }; diff --git a/src/SensorPlatform.hpp b/src/SensorPlatform.hpp new file mode 100644 index 0000000..d87203e --- /dev/null +++ b/src/SensorPlatform.hpp @@ -0,0 +1,116 @@ +/** + * + * @license MIT License + * + * Copyright (c) 2025 lewis he + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * @file SensorPlatform.hpp + * @author Lewis He (lewishe@outlook.com) + * @date 2025-01-18 + * + */ +#pragma once + +#if defined(ARDUINO) +#include "platform/arduino/SensorCommArduino_HW.hpp" +#include "platform/arduino/SensorCommArduino_I2C.hpp" +#include "platform/arduino/SensorCommArduino_SPI.hpp" +#elif !defined(ARDUINO) && defined(ESP_PLATFORM) +#include "platform/espidf/SensorCommEspIDF_HW.hpp" +#include "platform/espidf/SensorCommEspIDF_I2C.hpp" +#include "platform/espidf/SensorCommEspIDF_SPI.hpp" +#endif +#include "platform/SensorCommCustom.hpp" +#include "platform/SensorCommCustomHal.hpp" +#include "platform/SensorCommDebug.hpp" +#include "platform/SensorCommStatic.hpp" + +enum CommInterface { + COMM_CUSTOM = 0, + COMM_SPI = 1, + COMM_I2C = 2 +}; + +template +bool beginCommonStatic( + std::unique_ptr &comm, + std::unique_ptr &staticComm, + std::unique_ptr &hal, + Args &&... args) +{ + hal = std::make_unique(); + if (!hal) { + return false; + } + comm = std::make_unique(std::forward(args)..., hal.get()); + if (!comm) { + hal.reset(); + return false; + } + if (!comm->init()) { + log_e("Bus init failed!"); + return false; + } + staticComm = std::make_unique(comm.get(), hal.get()); + if (!staticComm) { + return false; + } + return true; +} + +template +bool beginCommon( + std::unique_ptr &comm, + std::unique_ptr &hal, + Args &&... args) +{ + hal = std::make_unique(); + if (!hal) { + return false; + } + comm = std::make_unique(std::forward(args)..., hal.get()); + if (!comm) { + hal.reset(); + return false; + } + comm->init(); + return true; +} + +template +bool beginCommCustomCallback(CommInterface interface, + typename CommType::CustomCallback callback, + typename HalType::CustomHalCallback hal_callback, + uint8_t addr, + std::unique_ptr &comm, + std::unique_ptr &hal) +{ + hal = std::make_unique(hal_callback); + if (!hal) { + return false; + } + comm = std::make_unique(callback, addr); + if (!comm) { + return false; + } + comm->init(); + return true; +} diff --git a/src/SensorQMC6310.hpp b/src/SensorQMC6310.hpp index baa4bd7..ba872ce 100644 --- a/src/SensorQMC6310.hpp +++ b/src/SensorQMC6310.hpp @@ -30,7 +30,7 @@ #pragma once #include "REG/QMC6310Constants.h" -#include "SensorCommon.tpp" +#include "SensorPlatform.hpp" class Polar { @@ -43,13 +43,9 @@ class Polar }; -class SensorQMC6310 : - public SensorCommon +class SensorQMC6310 : public QMC6310Constants { - friend class SensorCommon; public: - - enum SensorMode { MODE_SUSPEND, MODE_NORMAL, @@ -57,7 +53,7 @@ class SensorQMC6310 : MODE_CONTINUOUS, }; - // Unit:Guass + // Unit:Gauss enum MagRange { RANGE_30G, RANGE_12G, @@ -92,170 +88,179 @@ class SensorQMC6310 : DSR_8, }; -#if defined(ARDUINO) - SensorQMC6310(PLATFORM_WIRE_TYPE &w, int sda = DEFAULT_SDA, int scl = DEFAULT_SCL, uint8_t addr = QMC6310_SLAVE_ADDRESS) + SensorQMC6310() : comm(nullptr), hal(nullptr) {} + + ~SensorQMC6310() { - __wire = &w; - __sda = sda; - __scl = scl; - __addr = addr; + if (comm) { + comm->deinit(); + } } -#endif - SensorQMC6310() - { #if defined(ARDUINO) - __wire = &Wire; - __sda = DEFAULT_SDA; - __scl = DEFAULT_SCL; -#endif - __addr = QMC6310_SLAVE_ADDRESS; + bool begin(TwoWire &wire, int sda = -1, int scl = -1) + { + if (!beginCommon(comm, hal, wire, QMC6310_SLAVE_ADDRESS, sda, scl)) { + return false; + } + return initImpl(); } +#elif defined(ESP_PLATFORM) - ~SensorQMC6310() +#if defined(USEING_I2C_LEGACY) + bool begin(i2c_port_t port_num, int sda = -1, int scl = -1) { - deinit(); + if (!beginCommon(comm, hal, port_num, QMC6310_SLAVE_ADDRESS, sda, scl)) { + return false; + } + return initImpl(); } - -#if defined(ARDUINO) - bool init(PLATFORM_WIRE_TYPE &w, int sda = DEFAULT_SDA, int scl = DEFAULT_SCL, uint8_t addr = QMC6310_SLAVE_ADDRESS) +#else + bool begin(i2c_master_bus_handle_t handle) { - return SensorCommon::begin(w, addr, sda, scl); + if (!beginCommon(comm, hal, handle, QMC6310_SLAVE_ADDRESS, sda, scl)) { + return false; + } + return initImpl(); } +#endif #endif - - void deinit() + bool begin(SensorCommCustom::CustomCallback callback, + SensorCommCustomHal::CustomHalCallback hal_callback) { - // end(); + if (!beginCommCustomCallback(COMM_CUSTOM, + callback, hal_callback, QMC6310_SLAVE_ADDRESS, comm, hal)) { + return false; + } + return initImpl(); } void reset() { - writeRegister(QMC6310_REG_CMD2, 0x80); - delay(10); - writeRegister(QMC6310_REG_CMD2, 0x00); + comm->writeRegister(REG_CMD2, (uint8_t)0x80); + hal->delay(10); + comm->writeRegister(REG_CMD2, (uint8_t)0x00); } uint8_t getChipID() { - return readRegister(QMC6310_REG_CHIP_ID); + return comm->readRegister(REG_CHIP_ID); } int getStatus() { - return readRegister(QMC6310_REG_STAT); + return comm->readRegister(REG_STAT); } bool isDataReady() { - if (readRegister(QMC6310_REG_STAT) & 0x01) { + if (comm->readRegister(REG_STAT) & 0x01) { return true; } - LOG("No ready!\n"); return false; } bool isDataOverflow() { - if (readRegister(QMC6310_REG_STAT) & 0x02) { + if (comm->readRegister(REG_STAT) & 0x02) { return true; } return false; } - int setSelfTest(bool en) + void setSelfTest(bool en) { - return en ? setRegisterBit(QMC6310_REG_CMD2, 1) - : clrRegisterBit(QMC6310_REG_CMD2, 1); + en ? comm->setRegisterBit(REG_CMD2, 1) + : comm->clrRegisterBit(REG_CMD2, 1); } int setMode(SensorMode m) { - return writeRegister(QMC6310_REG_CMD1, 0xFC, m); + return comm->writeRegister(REG_CMD1, 0xFC, m); } int setCtrlRegister(CtrlReg c) { - return writeRegister(QMC6310_REG_CMD2, 0xFC, c); + return comm->writeRegister(REG_CMD2, 0xFC, c); } int setDataOutputRate(OutputRate odr) { - return writeRegister(QMC6310_REG_CMD1, 0xF3, (odr << 2)); + return comm->writeRegister(REG_CMD1, 0xF3, (odr << 2)); } int setOverSampleRate(OverSampleRatio osr) { - return writeRegister(QMC6310_REG_CMD1, 0xCF, (osr << 4)); + return comm->writeRegister(REG_CMD1, 0xCF, (osr << 4)); } int setDownSampleRate(DownSampleRatio dsr) { - return writeRegister(QMC6310_REG_CMD1, 0x3F, (dsr << 6)); + return comm->writeRegister(REG_CMD1, 0x3F, (dsr << 6)); } // Define the sign for X Y and Z axis int setSign(uint8_t x, uint8_t y, uint8_t z) { int sign = x + y * 2 + z * 4; - return writeRegister(QMC6310_REG_SIGN, sign); + return comm->writeRegister(REG_SIGN, sign); } int configMagnetometer(SensorMode mode, MagRange range, OutputRate odr, OverSampleRatio osr, DownSampleRatio dsr) { - if (setMagRange(range) != DEV_WIRE_NONE) { - return DEV_WIRE_ERR; + if (setMagRange(range) < 0) { + return -1;; } - if (writeRegister(QMC6310_REG_CMD1, 0xFC, mode) != DEV_WIRE_NONE) { - return DEV_WIRE_ERR; + if (comm->writeRegister(REG_CMD1, 0xFC, mode) < 0) { + return -1;; } - if (writeRegister(QMC6310_REG_CMD1, 0xF3, (odr << 2)) != DEV_WIRE_NONE) { - return DEV_WIRE_ERR; + if (comm->writeRegister(REG_CMD1, 0xF3, (odr << 2)) < 0) { + return -1;; } - if (writeRegister(QMC6310_REG_CMD1, 0xCF, (osr << 4)) != DEV_WIRE_NONE) { - return DEV_WIRE_ERR; + if (comm->writeRegister(REG_CMD1, 0xCF, (osr << 4)) < 0) { + return -1;; } - if (writeRegister(QMC6310_REG_CMD1, 0x3F, (dsr << 6)) != DEV_WIRE_NONE) { - return DEV_WIRE_ERR; + if (comm->writeRegister(REG_CMD1, 0x3F, (dsr << 6)) < 0) { + return -1;; } - return DEV_WIRE_NONE; + return 0; } int setMagRange(MagRange range) { switch (range) { case RANGE_30G: - sensitivity = 0.1; + _sensitivity = 0.1; break; case RANGE_12G: - sensitivity = 0.04; + _sensitivity = 0.04; break; case RANGE_8G: - sensitivity = 0.026; + _sensitivity = 0.026; break; case RANGE_2G: - sensitivity = 0.0066; + _sensitivity = 0.0066; break; default: break; } - return writeRegister(QMC6310_REG_CMD2, 0xF3, (range << 2)); + return comm->writeRegister(REG_CMD2, 0xF3, (range << 2)); } void setOffset(int x, int y, int z) { - x_offset = x; y_offset = y; z_offset = z; + _x_offset = x; _y_offset = y; _z_offset = z; } int readData() { uint8_t buffer[6]; int16_t x, y, z; - if (readRegister(QMC6310_REG_LSB_DX, buffer, - 6) != DEV_WIRE_ERR) { + if (comm->readRegister(REG_LSB_DX, buffer, + 6) != -1) { x = (int16_t)(buffer[1] << 8) | (buffer[0]); y = (int16_t)(buffer[3] << 8) | (buffer[2]); z = (int16_t)(buffer[5] << 8) | (buffer[4]); @@ -263,26 +268,26 @@ class SensorQMC6310 : if (x == 32767) { x = -((65535 - x) + 1); } - x = (x - x_offset); + x = (x - _x_offset); if (y == 32767) { y = -((65535 - y) + 1); } - y = (y - y_offset); + y = (y - _y_offset); if (z == 32767) { z = -((65535 - z) + 1); } - z = (z - z_offset); + z = (z - _z_offset); - raw[0] = x; - raw[1] = y; - raw[2] = z; + _raw[0] = x; + _raw[1] = y; + _raw[2] = z; - mag[0] = (float)x * sensitivity; - mag[1] = (float)y * sensitivity; - mag[2] = (float)z * sensitivity; - return DEV_WIRE_NONE; + _mag[0] = (float)x * _sensitivity; + _mag[1] = (float)y * _sensitivity; + _mag[2] = (float)z * _sensitivity; + return 0; } - return DEV_WIRE_ERR; + return -1;; } void setDeclination(float dec) @@ -308,45 +313,45 @@ class SensorQMC6310 : int16_t getRawX() { - return raw[0]; + return _raw[0]; } int16_t getRawY() { - return raw[1]; + return _raw[1]; } int16_t getRawZ() { - return raw[2]; + return _raw[2]; } float getX() { - return mag[0]; + return _mag[0]; } float getY() { - return mag[1]; + return _mag[1]; } float getZ() { - return mag[2]; + return _mag[2]; } void getMag(float &x, float &y, float &z) { - x = mag[0]; - y = mag[1]; - z = mag[2]; + x = _mag[0]; + y = _mag[1]; + z = _mag[2]; } void dumpCtrlRegister() { uint8_t buffer[2]; - readRegister(QMC6310_REG_CMD1, buffer, 2); + comm->readRegister(REG_CMD1, buffer, 2); for (int i = 0; i < 2; ++i) { log_d("CMD%d: 0x%02x", i + 1, buffer[i]); } @@ -369,19 +374,17 @@ class SensorQMC6310 : bool initImpl() { reset(); - return getChipID() == QMC6310_DEFAULT_ID; + return getChipID() == QMC6310_CHIP_ID; } - int getReadMaskImpl() - { - return -1; - } protected: - int16_t raw[3]; - float mag[3]; + std::unique_ptr comm; + std::unique_ptr hal; + int16_t _raw[3]; + float _mag[3]; float _declination; - float sensitivity; - int16_t x_offset = 0, y_offset = 0, z_offset = 0; + float _sensitivity; + int16_t _x_offset = 0, _y_offset = 0, _z_offset = 0; }; diff --git a/src/SensorQMI8658.hpp b/src/SensorQMI8658.hpp index ab85b14..e93015e 100644 --- a/src/SensorQMI8658.hpp +++ b/src/SensorQMI8658.hpp @@ -30,21 +30,16 @@ #pragma once #include "REG/QMI8658Constants.h" -#include "SensorCommon.tpp" -#ifndef ARDUINO -#include -#include -#endif -typedef struct __IMUdata { +#include "SensorPlatform.hpp" + +typedef struct { float x; float y; float z; } IMUdata; -class SensorQMI8658 : - public SensorCommon +class SensorQMI8658 : public QMI8658Constants { - friend class SensorCommon; public: typedef void (*EventCallBack_t)(void); @@ -213,101 +208,133 @@ class SensorQMI8658 : NO_MOTION_LOGIC_OR = _BV(7), }; + SensorQMI8658() : comm(nullptr), hal(nullptr) {} + + ~SensorQMI8658() + { + if (comm) { + comm->deinit(); + } + if (fifo_buffer) { + free(fifo_buffer); + fifo_buffer = NULL; + } + } + #if defined(ARDUINO) - SensorQMI8658(PLATFORM_WIRE_TYPE &w, int sda = DEFAULT_SDA, int scl = DEFAULT_SCL, uint8_t addr = QMI8658_L_SLAVE_ADDRESS) + bool begin(TwoWire &wire, uint8_t addr = QMI8658_L_SLAVE_ADDRESS, int sda = -1, int scl = -1) { - __wire = &w; - __sda = sda; - __scl = scl; - __addr = addr; + if (!beginCommon(comm, hal, wire, addr, sda, scl)) { + return false; + } + return initImpl(); } - SensorQMI8658(int cs, int mosi = -1, int miso = -1, int sck = -1, PLATFORM_SPI_TYPE &spi = SPI) + bool begin(SPIClass &spi, uint8_t csPin, int mosi = -1, int miso = -1, int sck = -1) { - __spi = &spi; - __cs = cs; - __miso = miso; - __mosi = mosi; - __sck = sck; + if (!beginCommon(comm, hal, spi, csPin, mosi, miso, sck)) { + return false; + } + return initImpl(); } -#endif +#elif defined(ESP_PLATFORM) - SensorQMI8658() +#if defined(USEING_I2C_LEGACY) + bool begin(i2c_port_t port_num, uint8_t addr = QMI8658_L_SLAVE_ADDRESS, int sda = -1, int scl = -1) { -#if defined(ARDUINO) - __wire = &Wire; - __sda = DEFAULT_SDA; - __scl = DEFAULT_SCL; -#endif - __addr = QMI8658_L_SLAVE_ADDRESS; + hal = std::make_unique(); + if (!hal) { + return false; + } + comm = std::make_unique(port_num, addr, sda, scl); + if (!comm) { + return false; + } + comm->init(); + return initImpl(); } - - ~SensorQMI8658() +#else + bool begin(i2c_master_bus_handle_t handle, uint8_t addr = QMI8658_L_SLAVE_ADDRESS) { - log_i("~SensorQMI8658"); - if (__fifo_buffer) { - free(__fifo_buffer); - __fifo_buffer = NULL; + hal = std::make_unique(); + if (!hal) { + return false; + } + comm = std::make_unique(handle, addr); + if (!comm) { + return false; } - deinit(); + comm->init(); + return initImpl(); } +#endif //ESP_PLATFORM -#if defined(ARDUINO) - bool init(PLATFORM_WIRE_TYPE &w, int sda = DEFAULT_SDA, int scl = DEFAULT_SCL, uint8_t addr = QMI8658_L_SLAVE_ADDRESS) + + bool begin(spi_host_device_t host, spi_device_handle_t handle, uint8_t csPin, int mosi, int miso, int sck) { - return SensorCommon::begin(w, addr, sda, scl); + if (!beginCommon(comm, hal, + host, handle, csPin, mosi, miso, sck)) { + return false; + } + return initImpl(); } -#endif +#endif //ARDUINO - void deinit() + bool begin(SensorCommCustom::CustomCallback callback, + SensorCommCustomHal::CustomHalCallback hal_callback, + uint8_t addr = QMI8658_L_SLAVE_ADDRESS) { - // end(); + if (!beginCommCustomCallback(COMM_CUSTOM, + callback, hal_callback, addr, comm, hal)) { + return false; + } + return initImpl(); } bool reset(bool waitResult = true, uint32_t timeout = 500) { int val = 0; // initialize with some value to avoid compilation errors - writeRegister(QMI8658_REG_RESET, QMI8658_REG_RESET_DEFAULT); + comm->writeRegister(QMI8658_REG_RESET, QMI8658_REG_RESET_DEFAULT); // Maximum 15ms for the Reset process to be finished if (waitResult) { - uint32_t start = millis(); - while (millis() - start < timeout) { - val = readRegister(QMI8658_REG_RST_RESULT); - if (val != DEV_WIRE_ERR && val == QMI8658_REG_RST_RESULT_VAL) { + uint32_t start = hal->millis(); + while (hal->millis() - start < timeout) { + val = comm->readRegister(QMI8658_REG_RST_RESULT); + if (val != -1 && val == QMI8658_REG_RST_RESULT_VAL) { //EN.ADDR_AI - setRegisterBit(QMI8658_REG_CTRL1, 6); + comm->setRegisterBit(QMI8658_REG_CTRL1, 6); return true; } - delay(10); + hal->delay(10); } log_e("Reset chip failed, Response val = %d - 0x%X", val, val); return false; } //EN.ADDR_AI - setRegisterBit(QMI8658_REG_CTRL1, 6); + comm->setRegisterBit(QMI8658_REG_CTRL1, 6); return true; } uint8_t getChipID() { - return readRegister(QMI8658_REG_REVISION); + return comm->readRegister(QMI8658_REG_REVISION); } int whoAmI() { - return readRegister(QMI8658_REG_WHOAMI); + return comm->readRegister(QMI8658_REG_WHOAMI); } uint32_t getTimestamp() { uint8_t buffer[3]; uint32_t timestamp; - if (readRegister(QMI8658_REG_TIMESTAMP_L, buffer, 3) != DEV_WIRE_ERR) { + if (comm->readRegister(QMI8658_REG_TIMESTAMP_L, buffer, 3) != -1) { timestamp = (uint32_t)(((uint32_t)buffer[2] << 16) | ((uint32_t)buffer[1] << 8) | buffer[0]); if (timestamp > lastTimestamp) { @@ -323,7 +350,7 @@ class SensorQMI8658 : float getTemperature_C() { uint8_t buffer[2]; - if (readRegister(QMI8658_REG_TEMPERATURE_L, buffer, 2) != DEV_WIRE_ERR) { + if (comm->readRegister(QMI8658_REG_TEMPERATURE_L, buffer, 2) != -1) { return (float)buffer[1] + ((float)buffer[0] / 256.0); } return NAN; @@ -333,12 +360,12 @@ class SensorQMI8658 : { switch (pin) { case INTERRUPT_PIN_1: - enable ? setRegisterBit(QMI8658_REG_CTRL1, 3) : clrRegisterBit(QMI8658_REG_CTRL1, 3); - __irq_enable_mask = enable ? __irq_enable_mask | 0x01 : __irq_enable_mask & 0xFE; + enable ? comm->setRegisterBit(QMI8658_REG_CTRL1, 3) : comm->clrRegisterBit(QMI8658_REG_CTRL1, 3); + _irq_enable_mask = enable ? _irq_enable_mask | 0x01 : _irq_enable_mask & 0xFE; break; case INTERRUPT_PIN_2: - enable ? setRegisterBit(QMI8658_REG_CTRL1, 4) : clrRegisterBit(QMI8658_REG_CTRL1, 4); - __irq_enable_mask = enable ? __irq_enable_mask | 0x02 : __irq_enable_mask & 0xFD; + enable ? comm->setRegisterBit(QMI8658_REG_CTRL1, 4) : comm->clrRegisterBit(QMI8658_REG_CTRL1, 4); + _irq_enable_mask = enable ? _irq_enable_mask | 0x02 : _irq_enable_mask & 0xFD; break; default: break; @@ -347,14 +374,14 @@ class SensorQMI8658 : uint8_t getIrqStatus() { - return readRegister(QMI8658_REG_STATUS_INT); + return comm->readRegister(QMI8658_REG_STATUS_INT); } void enableDataReadyINT(bool enable = true) { - enable ? clrRegisterBit(QMI8658_REG_CTRL7, 5) : - setRegisterBit(QMI8658_REG_CTRL7, 5); + enable ? comm->clrRegisterBit(QMI8658_REG_CTRL7, 5) : + comm->setRegisterBit(QMI8658_REG_CTRL7, 5); } @@ -367,8 +394,8 @@ class SensorQMI8658 : } //setAccelRange - if (writeRegister(QMI8658_REG_CTRL2, 0x8F, (range << 4)) != DEV_WIRE_NONE) { - return DEV_WIRE_ERR; + if (comm->writeRegister(QMI8658_REG_CTRL2, 0x8F, (range << 4)) != 0) { + return -1; } switch (range) { @@ -383,30 +410,30 @@ class SensorQMI8658 : } // setAccelOutputDataRate - if (writeRegister(QMI8658_REG_CTRL2, 0xF0, odr) != DEV_WIRE_NONE) { - return DEV_WIRE_ERR; + if (comm->writeRegister(QMI8658_REG_CTRL2, 0xF0, odr) != 0) { + return -1; } if (lpfOdr != LPF_OFF) { // setAccelLowPassFitterOdr - if (writeRegister(QMI8658_REG_CTRL5, QMI8658_ACCEL_LPF_MASK, (lpfOdr << 1)) != DEV_WIRE_NONE) { - return DEV_WIRE_ERR; + if (comm->writeRegister(QMI8658_REG_CTRL5, QMI8658_ACCEL_LPF_MASK, (lpfOdr << 1)) != 0) { + return -1; } // Enable Low-Pass Fitter - setRegisterBit(QMI8658_REG_CTRL5, 0); + comm->setRegisterBit(QMI8658_REG_CTRL5, 0); } else { // Disable Low-Pass Fitter - clrRegisterBit(QMI8658_REG_CTRL5, 0); + comm->clrRegisterBit(QMI8658_REG_CTRL5, 0); } // setAccelSelfTest - // selfTest ? setRegisterBit(QMI8658_REG_CTRL2, 7) : clrRegisterBit(QMI8658_REG_CTRL2, 7); + // selfTest ? comm->setRegisterBit(QMI8658_REG_CTRL2, 7) : comm->clrRegisterBit(QMI8658_REG_CTRL2, 7); if (en) { enableAccelerometer(); } - return DEV_WIRE_NONE; + return 0; } @@ -419,8 +446,8 @@ class SensorQMI8658 : } // setGyroRange - if (writeRegister(QMI8658_REG_CTRL3, 0x8F, (range << 4)) != DEV_WIRE_NONE) { - return DEV_WIRE_ERR; + if (comm->writeRegister(QMI8658_REG_CTRL3, 0x8F, (range << 4)) != 0) { + return -1; } switch (range) { @@ -438,30 +465,30 @@ class SensorQMI8658 : } // setGyroOutputDataRate - if (writeRegister(QMI8658_REG_CTRL3, 0xF0, odr) != DEV_WIRE_NONE) { - return DEV_WIRE_ERR; + if (comm->writeRegister(QMI8658_REG_CTRL3, 0xF0, odr) != 0) { + return -1; } // setGyroLowPassFitterOdr if (lpfOdr != LPF_OFF) { - if (writeRegister(QMI8658_REG_CTRL5, QMI8658_GYRO_LPF_MASK, (lpfOdr << 5)) != DEV_WIRE_NONE) { - return DEV_WIRE_ERR; + if (comm->writeRegister(QMI8658_REG_CTRL5, QMI8658_GYRO_LPF_MASK, (lpfOdr << 5)) != 0) { + return -1; } // Enable Low-Pass Fitter - setRegisterBit(QMI8658_REG_CTRL5, 4); + comm->setRegisterBit(QMI8658_REG_CTRL5, 4); } else { // Disable Low-Pass Fitter - clrRegisterBit(QMI8658_REG_CTRL5, 4); + comm->clrRegisterBit(QMI8658_REG_CTRL5, 4); } // setGyroSelfTest - // selfTest ? setRegisterBit(QMI8658_REG_CTRL3, 7) : clrRegisterBit(QMI8658_REG_CTRL3, 7); + // selfTest ? comm->setRegisterBit(QMI8658_REG_CTRL3, 7) : comm->clrRegisterBit(QMI8658_REG_CTRL3, 7); if (en) { enableGyroscope(); } - return DEV_WIRE_NONE; + return 0; } @@ -482,40 +509,40 @@ class SensorQMI8658 : } // Reset FIFO configure - if (writeCommand(CTRL_CMD_RST_FIFO) != DEV_WIRE_NONE) { + if (writeCommand(CTRL_CMD_RST_FIFO) != 0) { log_e("Reset fifo failed!"); - return DEV_WIRE_ERR; + return -1; } - __fifo_interrupt = true; + _fifo_interrupt = true; switch (pin) { case INTERRUPT_PIN_1: - setRegisterBit(QMI8658_REG_CTRL1, 2); + comm->setRegisterBit(QMI8658_REG_CTRL1, 2); break; case INTERRUPT_PIN_2: - clrRegisterBit(QMI8658_REG_CTRL1, 2); + comm->clrRegisterBit(QMI8658_REG_CTRL1, 2); break; case INTERRUPT_PIN_DISABLE: // Saves whether the fifo interrupt pin is enabled - __fifo_interrupt = false; + _fifo_interrupt = false; break; default: break; } // Set fifo mode and samples len - __fifo_mode = (samples << 2) | mode; - if (writeRegister(QMI8658_REG_FIFO_CTRL, __fifo_mode) == DEV_WIRE_ERR) { - return DEV_WIRE_ERR; + _fifo_mode = (samples << 2) | mode; + if (comm->writeRegister(QMI8658_REG_FIFO_CTRL, _fifo_mode) == -1) { + return -1; } /* * The FIFO_WTM register(0x13) indicates the expected level of FIFO data that host wants to get the FIFO Watermark interrupt. * The unit is sample, which means 6 bytes if one of accelerometer and gyroscope is enabled, and 12 bytes if both are enabled. * */ - if (writeRegister(QMI8658_REG_FIFO_WTM_TH, trigger_samples ) == DEV_WIRE_ERR) { - return DEV_WIRE_ERR; + if (comm->writeRegister(QMI8658_REG_FIFO_WTM_TH, trigger_samples ) == -1) { + return -1; } if (enGyro) { @@ -526,7 +553,7 @@ class SensorQMI8658 : enableAccelerometer(); } - int res = readRegister(QMI8658_REG_FIFO_CTRL); + int res = comm->readRegister(QMI8658_REG_FIFO_CTRL); log_d("QMI8658_REG_FIFO_CTRL : 0x%X", res); if ((res & 0x02) == 0x02) { log_d("Enabled Stream mode."); @@ -546,17 +573,17 @@ class SensorQMI8658 : log_d("16 samples."); } - return DEV_WIRE_NONE; + return 0; } uint16_t readFromFifo(IMUdata *acc, uint16_t accLength, IMUdata *gyro, uint16_t gyrLength) { - if (__fifo_mode == FIFO_MODE_BYPASS) { + if (_fifo_mode == FIFO_MODE_BYPASS) { log_e("FIFO is not configured."); return 0; } - if (!__gyro_enabled && !__accel_enabled) { + if (!_gyro_enabled && !_accel_enabled) { log_e("Sensor not enabled."); return 0; } @@ -566,12 +593,12 @@ class SensorQMI8658 : return 0; } - if (!__fifo_buffer) { + if (!fifo_buffer) { log_e("FIFO buffer is NULL"); return 0; } - uint8_t enabled_sensor_count = (__accel_enabled && __gyro_enabled) ? 2 : 1; + uint8_t enabled_sensor_count = (_accel_enabled && _gyro_enabled) ? 2 : 1; uint16_t samples_per_sensor = data_bytes / (6 * enabled_sensor_count); uint16_t total_samples = samples_per_sensor * enabled_sensor_count; @@ -581,12 +608,12 @@ class SensorQMI8658 : uint16_t gyro_index = 0; for (uint16_t i = 0; i < total_samples; ++i) { - auto data = reinterpret_cast(&__fifo_buffer[i * 6]); + auto data = reinterpret_cast(&fifo_buffer[i * 6]); int16_t x = data[0]; int16_t y = data[1]; int16_t z = data[2]; - if (__accel_enabled && __gyro_enabled) { + if (_accel_enabled && _gyro_enabled) { if (i % 2 == 0) { // Accel if (accel_index < accLength) { @@ -604,14 +631,14 @@ class SensorQMI8658 : gyro_index++; } } - } else if (__accel_enabled) { + } else if (_accel_enabled) { if (accel_index < accLength) { acc[accel_index].x = x * accelScales; acc[accel_index].y = y * accelScales; acc[accel_index].z = z * accelScales; accel_index++; } - } else if (__gyro_enabled) { + } else if (_gyro_enabled) { if (gyro_index < gyrLength) { gyro[gyro_index].x = x * gyroScales; gyro[gyro_index].y = y * gyroScales; @@ -630,12 +657,12 @@ class SensorQMI8658 : { uint8_t sam[] = {16, 32, 64, 128}; uint8_t sensors = 0; - if (__gyro_enabled && __accel_enabled) { + if (_gyro_enabled && _accel_enabled) { sensors = 2; - } else if (__gyro_enabled || __accel_enabled) { + } else if (_gyro_enabled || _accel_enabled) { sensors = 1; } - uint8_t samples = ((__fifo_mode >> 2) & 0x03) ; + uint8_t samples = ((_fifo_mode >> 2) & 0x03) ; return sam[samples] * 6 * sensors; } @@ -649,38 +676,38 @@ class SensorQMI8658 : uint8_t status[2]; uint16_t fifo_bytes = 0; - if ((__irq != -1) && __fifo_interrupt) { + if ((_irq != -1) && _fifo_interrupt) { /* * Once the corresponds INT pin is configured to the push-pull mode, the FIFO watermark interrupt can be seen on the * corresponds INT pin. It will keep high level as long as the FIFO filled level is equal to or higher than the watermark, will * drop to low level as long as the FIFO filled level is lower than the configured FIFO watermark after reading out by host * and FIFO_RD_MODE is cleared. */ - if (this->getGpioLevel(__irq) == LOW) { + if (hal->digitalRead(_irq) == LOW) { return false; } } size_t alloc_size = getFifoNeedBytes(); - if (!__fifo_buffer) { - __fifo_buffer = (uint8_t *)calloc(alloc_size, sizeof(uint8_t)); - if (!__fifo_buffer) { + if (!fifo_buffer) { + fifo_buffer = (uint8_t *)calloc(alloc_size, sizeof(uint8_t)); + if (!fifo_buffer) { log_e("Calloc buffer size %u bytes failed!", alloc_size); return 0; } - __fifo_size = alloc_size; + _fifo_size = alloc_size; - } else if (alloc_size > __fifo_size) { - __fifo_buffer = (uint8_t *)realloc(__fifo_buffer, alloc_size); - if (!__fifo_buffer) { + } else if (alloc_size > _fifo_size) { + fifo_buffer = (uint8_t *)realloc(fifo_buffer, alloc_size); + if (!fifo_buffer) { log_e("Realloc buffer size %u bytes failed!", alloc_size); return 0; } } // 1.Got FIFO watermark interrupt by INT pin or polling the FIFO_STATUS register (FIFO_WTM and/or FIFO_FULL). - int val = readRegister(QMI8658_REG_FIFO_STATUS); - if (val == DEV_WIRE_ERR) { + int val = comm->readRegister(QMI8658_REG_FIFO_STATUS); + if (val == -1) { return 0; } log_d("FIFO status:0x%x", val); @@ -701,7 +728,7 @@ class SensorQMI8658 : } // 2.Read the FIFO_SMPL_CNT and FIFO_STATUS registers, to calculate the level of FIFO content data, refer to 8.4 FIFO Sample Count. - if (readRegister(QMI8658_REG_FIFO_COUNT, status, 2) == DEV_WIRE_ERR) { + if (comm->readRegister(QMI8658_REG_FIFO_COUNT, status, 2) == -1) { log_e("Bus communication failed!"); return 0; } @@ -717,18 +744,18 @@ class SensorQMI8658 : //Samples 128 * 6 * 2 = 1536 // 3.Send CTRL_CMD_REQ_FIFO (0x05) by CTRL9 command, to enable FIFO read mode. Refer to CTRL_CMD_REQ_FIFO for details. - if (writeCommand(CTRL_CMD_REQ_FIFO) != DEV_WIRE_NONE) { + if (writeCommand(CTRL_CMD_REQ_FIFO) != 0) { log_e("Request FIFO failed!"); return 0; } // 4.Read from the FIFO_DATA register per FIFO_Sample_Count. - if (readRegister(QMI8658_REG_FIFO_DATA, __fifo_buffer, fifo_bytes) == DEV_WIRE_ERR) { + if (comm->readRegister(QMI8658_REG_FIFO_DATA, fifo_buffer, fifo_bytes) == -1) { log_e("Request FIFO data failed !"); return 0; } // 5.Disable the FIFO Read Mode by setting FIFO_CTRL.FIFO_rd_mode to 0. New data will be filled into FIFO afterwards. - if (writeRegister(QMI8658_REG_FIFO_CTRL, __fifo_mode) == DEV_WIRE_ERR) { + if (comm->writeRegister(QMI8658_REG_FIFO_CTRL, _fifo_mode) == -1) { log_e("Clear FIFO flag failed!"); return 0; } @@ -741,16 +768,16 @@ class SensorQMI8658 : bool enableAccelerometer() { - if (setRegisterBit(QMI8658_REG_CTRL7, 0)) { - __accel_enabled = true; + if (comm->setRegisterBit(QMI8658_REG_CTRL7, 0)) { + _accel_enabled = true; } - return __accel_enabled; + return _accel_enabled; } bool disableAccelerometer() { - if (clrRegisterBit(QMI8658_REG_CTRL7, 0)) { - __accel_enabled = false; + if (comm->clrRegisterBit(QMI8658_REG_CTRL7, 0)) { + _accel_enabled = false; return true; } return false; @@ -758,26 +785,26 @@ class SensorQMI8658 : bool isEnableAccelerometer() { - return __accel_enabled; + return _accel_enabled; } bool isEnableGyroscope() { - return __gyro_enabled; + return _gyro_enabled; } bool enableGyroscope() { - if (setRegisterBit(QMI8658_REG_CTRL7, 1)) { - __gyro_enabled = true; + if (comm->setRegisterBit(QMI8658_REG_CTRL7, 1)) { + _gyro_enabled = true; } - return __gyro_enabled; + return _gyro_enabled; } bool disableGyroscope() { - if (clrRegisterBit(QMI8658_REG_CTRL7, 1)) { - __gyro_enabled = false; + if (comm->clrRegisterBit(QMI8658_REG_CTRL7, 1)) { + _gyro_enabled = false; return true; } return false; @@ -785,11 +812,11 @@ class SensorQMI8658 : bool getAccelRaw(int16_t *rawBuffer) { - if (!__accel_enabled) { + if (!_accel_enabled) { return false; } uint8_t buffer[6] = {0}; - if (readRegister(QMI8658_REG_AX_L, buffer, 6) != DEV_WIRE_ERR) { + if (comm->readRegister(QMI8658_REG_AX_L, buffer, 6) != -1) { rawBuffer[0] = (int16_t)(buffer[1] << 8) | (buffer[0]); rawBuffer[1] = (int16_t)(buffer[3] << 8) | (buffer[2]); rawBuffer[2] = (int16_t)(buffer[5] << 8) | (buffer[4]); @@ -801,7 +828,7 @@ class SensorQMI8658 : bool getAccelerometer(float &x, float &y, float &z) { - if (!__accel_enabled) { + if (!_accel_enabled) { return false; } int16_t raw[3]; @@ -826,11 +853,11 @@ class SensorQMI8658 : bool getGyroRaw(int16_t *rawBuffer) { - if (!__gyro_enabled) { + if (!_gyro_enabled) { return false; } uint8_t buffer[6] = {0}; - if (readRegister(QMI8658_REG_GX_L, buffer, 6) != DEV_WIRE_ERR) { + if (comm->readRegister(QMI8658_REG_GX_L, buffer, 6) != -1) { rawBuffer[0] = (int16_t)(buffer[1] << 8) | (buffer[0]); rawBuffer[1] = (int16_t)(buffer[3] << 8) | (buffer[2]); rawBuffer[2] = (int16_t)(buffer[5] << 8) | (buffer[4]); @@ -842,7 +869,7 @@ class SensorQMI8658 : int getGyroscope(float &x, float &y, float &z) { - if (!__gyro_enabled) { + if (!_gyro_enabled) { return false; } int16_t raw[3]; @@ -857,23 +884,23 @@ class SensorQMI8658 : bool getDataReady() { - if ((__irq_enable_mask & 0x03) && (__irq != -1)) { - if (this->getGpioLevel(__irq)) { + if ((_irq_enable_mask & 0x03) && (_irq != -1)) { + if (hal->digitalRead(_irq)) { return false; } } switch (sampleMode) { case SYNC_MODE: - return getRegisterBit(QMI8658_REG_STATUS_INT, 1); + return comm->getRegisterBit(QMI8658_REG_STATUS_INT, 1); case ASYNC_MODE: //TODO: When Accel and Gyro are configured with different rates, this will always be false - if (__accel_enabled & __gyro_enabled) { - return readRegister(QMI8658_REG_STATUS0) & 0x03; - } else if (__gyro_enabled) { - return readRegister(QMI8658_REG_STATUS0) & 0x02; - } else if (__accel_enabled) { - return readRegister(QMI8658_REG_STATUS0) & 0x01; + if (_accel_enabled & _gyro_enabled) { + return comm->readRegister(QMI8658_REG_STATUS0) & 0x03; + } else if (_gyro_enabled) { + return comm->readRegister(QMI8658_REG_STATUS0) & 0x02; + } else if (_accel_enabled) { + return comm->readRegister(QMI8658_REG_STATUS0) & 0x01; } break; default: @@ -885,20 +912,20 @@ class SensorQMI8658 : int enableSyncSampleMode() { sampleMode = SYNC_MODE; - return setRegisterBit(QMI8658_REG_CTRL7, 7); + return comm->setRegisterBit(QMI8658_REG_CTRL7, 7); } int disableSyncSampleMode() { sampleMode = ASYNC_MODE; - return clrRegisterBit(QMI8658_REG_CTRL7, 7); + return comm->clrRegisterBit(QMI8658_REG_CTRL7, 7); } int enableLockingMechanism() { enableSyncSampleMode(); - if (writeRegister(QMI8658_REG_CAL1_L, 0x01) != DEV_WIRE_NONE) { - return DEV_WIRE_ERR; + if (comm->writeRegister(QMI8658_REG_CAL1_L, 0x01) != 0) { + return -1; } return writeCommand(CTRL_CMD_AHB_CLOCK_GATING); @@ -907,8 +934,8 @@ class SensorQMI8658 : int disableLockingMechanism() { disableSyncSampleMode(); - if (writeRegister(QMI8658_REG_CAL1_L, 0x00) != DEV_WIRE_NONE) { - return DEV_WIRE_ERR; + if (comm->writeRegister(QMI8658_REG_CAL1_L, (uint8_t)0x00) != 0) { + return -1; } return writeCommand(CTRL_CMD_AHB_CLOCK_GATING); } @@ -916,12 +943,12 @@ class SensorQMI8658 : void dumpCtrlRegister() { uint8_t buffer[9]; - readRegister(QMI8658_REG_CTRL1, buffer, 9); + comm->readRegister(QMI8658_REG_CTRL1, buffer, 9); for (int i = 0; i < 9; ++i) { log_d("CTRL%d: REG:0x%02X HEX:0x%02X\n", i + 1, QMI8658_REG_CTRL1 + i, buffer[i]); } - buffer[0] = readRegister(QMI8658_REG_FIFO_CTRL); + buffer[0] = comm->readRegister(QMI8658_REG_FIFO_CTRL); log_d("FIFO_CTRL: REG:0x%02X HEX:0x%02X\n", QMI8658_REG_FIFO_CTRL, buffer[0]); } @@ -929,23 +956,23 @@ class SensorQMI8658 : { disableAccelerometer(); disableGyroscope(); - setRegisterBit(QMI8658_REG_CTRL1, 1); + comm->setRegisterBit(QMI8658_REG_CTRL1, 1); } void powerOn() { - clrRegisterBit(QMI8658_REG_CTRL1, 1); + comm->clrRegisterBit(QMI8658_REG_CTRL1, 1); } int getStatusRegister() { - return readRegister(QMI8658_REG_STATUS1); + return comm->readRegister(QMI8658_REG_STATUS1); } int configActivityInterruptMap(IntPin pin) { - return pin == INTERRUPT_PIN_1 ? setRegisterBit(QMI8658_REG_CTRL8, 6) - : clrRegisterBit(QMI8658_REG_CTRL8, 6); + return pin == INTERRUPT_PIN_1 ? comm->setRegisterBit(QMI8658_REG_CTRL8, 6) + : comm->clrRegisterBit(QMI8658_REG_CTRL8, 6); } /** @@ -994,25 +1021,25 @@ class SensorQMI8658 : disableAccelerometer(); } - writeRegister(QMI8658_REG_CAL1_L, ped_sample_cnt & 0xFF); - writeRegister(QMI8658_REG_CAL1_H, (ped_sample_cnt >> 8) & 0xFF); - writeRegister(QMI8658_REG_CAL2_L, ped_fix_peak2peak & 0xFF); - writeRegister(QMI8658_REG_CAL2_H, (ped_fix_peak2peak >> 8) & 0xFF); - writeRegister(QMI8658_REG_CAL3_L, ped_fix_peak & 0xFF); - writeRegister(QMI8658_REG_CAL3_H, (ped_fix_peak >> 8) & 0xFF); - writeRegister(QMI8658_REG_CAL4_H, 0x01); - writeRegister(QMI8658_REG_CAL4_L, 0x02); + comm->writeRegister(QMI8658_REG_CAL1_L, ped_sample_cnt & 0xFF); + comm->writeRegister(QMI8658_REG_CAL1_H, (ped_sample_cnt >> 8) & 0xFF); + comm->writeRegister(QMI8658_REG_CAL2_L, ped_fix_peak2peak & 0xFF); + comm->writeRegister(QMI8658_REG_CAL2_H, (ped_fix_peak2peak >> 8) & 0xFF); + comm->writeRegister(QMI8658_REG_CAL3_L, ped_fix_peak & 0xFF); + comm->writeRegister(QMI8658_REG_CAL3_H, (ped_fix_peak >> 8) & 0xFF); + comm->writeRegister(QMI8658_REG_CAL4_H, 0x01); + comm->writeRegister(QMI8658_REG_CAL4_L, 0x02); writeCommand(CTRL_CMD_CONFIGURE_PEDOMETER); - writeRegister(QMI8658_REG_CAL1_L, ped_time_up & 0xFF); - writeRegister(QMI8658_REG_CAL1_H, (ped_time_up >> 8) & 0xFF); - writeRegister(QMI8658_REG_CAL2_L, ped_time_low); - writeRegister(QMI8658_REG_CAL2_H, ped_time_cnt_entry); - writeRegister(QMI8658_REG_CAL3_L, ped_fix_precision); - writeRegister(QMI8658_REG_CAL3_H, ped_sig_count); - writeRegister(QMI8658_REG_CAL4_H, 0x02); - writeRegister(QMI8658_REG_CAL4_L, 0x02); + comm->writeRegister(QMI8658_REG_CAL1_L, ped_time_up & 0xFF); + comm->writeRegister(QMI8658_REG_CAL1_H, (ped_time_up >> 8) & 0xFF); + comm->writeRegister(QMI8658_REG_CAL2_L, ped_time_low); + comm->writeRegister(QMI8658_REG_CAL2_H, ped_time_cnt_entry); + comm->writeRegister(QMI8658_REG_CAL3_L, ped_fix_precision); + comm->writeRegister(QMI8658_REG_CAL3_H, ped_sig_count); + comm->writeRegister(QMI8658_REG_CAL4_H, 0x02); + comm->writeRegister(QMI8658_REG_CAL4_L, 0x02); writeCommand(CTRL_CMD_CONFIGURE_PEDOMETER); @@ -1029,7 +1056,7 @@ class SensorQMI8658 : uint32_t getPedometerCounter() { uint8_t buffer[3]; - if (readRegister(QMI8658_REG_STEP_CNT_LOW, buffer, 3) != DEV_WIRE_ERR) { + if (comm->readRegister(QMI8658_REG_STEP_CNT_LOW, buffer, 3) != -1) { return (uint32_t)(((uint32_t)buffer[2] << 16) | ((uint32_t)buffer[1] << 8) | buffer[0]); } return 0; @@ -1043,7 +1070,7 @@ class SensorQMI8658 : // The Pedometer can only work in Non-SyncSample mode bool enablePedometer(IntPin pin = INTERRUPT_PIN_DISABLE) { - if (!__accel_enabled)return false; + if (!_accel_enabled)return false; switch (pin) { case INTERRUPT_PIN_1: @@ -1054,13 +1081,13 @@ class SensorQMI8658 : default: break; } - return setRegisterBit(QMI8658_REG_CTRL8, 4); + return comm->setRegisterBit(QMI8658_REG_CTRL8, 4); } bool disablePedometer() { - if (!__accel_enabled)return false; - return clrRegisterBit(QMI8658_REG_CTRL8, 4); + if (!_accel_enabled)return false; + return comm->clrRegisterBit(QMI8658_REG_CTRL8, 4); } @@ -1113,24 +1140,24 @@ class SensorQMI8658 : if (enAccel) { disableAccelerometer(); } - writeRegister(QMI8658_REG_CAL1_L, peakWindow); - writeRegister(QMI8658_REG_CAL1_H, priority); - writeRegister(QMI8658_REG_CAL2_L, tapWindow & 0xFF); - writeRegister(QMI8658_REG_CAL2_H, (tapWindow >> 8) & 0xFF); - writeRegister(QMI8658_REG_CAL3_L, dTapWindow & 0xFF); - writeRegister(QMI8658_REG_CAL3_H, (dTapWindow >> 8) & 0xFF); - // writeRegister(QMI8658_REG_CAL4_L, 0x02); - writeRegister(QMI8658_REG_CAL4_H, 0x01); + comm->writeRegister(QMI8658_REG_CAL1_L, peakWindow); + comm->writeRegister(QMI8658_REG_CAL1_H, priority); + comm->writeRegister(QMI8658_REG_CAL2_L, tapWindow & 0xFF); + comm->writeRegister(QMI8658_REG_CAL2_H, (tapWindow >> 8) & 0xFF); + comm->writeRegister(QMI8658_REG_CAL3_L, dTapWindow & 0xFF); + comm->writeRegister(QMI8658_REG_CAL3_H, (dTapWindow >> 8) & 0xFF); + // comm->writeRegister(QMI8658_REG_CAL4_L, 0x02); + comm->writeRegister(QMI8658_REG_CAL4_H, 0x01); writeCommand(CTRL_CMD_CONFIGURE_TAP); // 1-byte unsigned,7-bits fraction uint8_t alphaHex = (uint8_t)(alpha * 128); - writeRegister(QMI8658_REG_CAL1_L, alphaHex); + comm->writeRegister(QMI8658_REG_CAL1_L, alphaHex); // 1-byte unsigned,7-bits fraction uint8_t gammaHex = (uint8_t)(gamma * 128); - writeRegister(QMI8658_REG_CAL1_H, gammaHex); + comm->writeRegister(QMI8658_REG_CAL1_H, gammaHex); const double g = 9.81; // Earth's gravitational acceleration m/s^2 double resolution = 0.001 * g * g; // Calculation resolution 0.001g^2 @@ -1138,16 +1165,16 @@ class SensorQMI8658 : double acceleration_square = peakMagThr * g * g; // Calculate the square of the acceleration uint16_t value = (uint16_t)(acceleration_square / resolution); // Calculates the value of a 2-byte unsigned integer - writeRegister(QMI8658_REG_CAL2_L, lowByte(value)); - writeRegister(QMI8658_REG_CAL2_H, highByte(value)); + comm->writeRegister(QMI8658_REG_CAL2_L, lowByte(value)); + comm->writeRegister(QMI8658_REG_CAL2_H, highByte(value)); acceleration_square = UDMThr * g * g; // Calculate the square of the acceleration value = (uint16_t)(acceleration_square / resolution); // Calculates the value of a 2-byte unsigned integer - writeRegister(QMI8658_REG_CAL3_L, lowByte(value)); - writeRegister(QMI8658_REG_CAL3_H, highByte(value)); - // writeRegister(QMI8658_REG_CAL4_L, 0x02); - writeRegister(QMI8658_REG_CAL4_H, 0x02); + comm->writeRegister(QMI8658_REG_CAL3_L, lowByte(value)); + comm->writeRegister(QMI8658_REG_CAL3_H, highByte(value)); + // comm->writeRegister(QMI8658_REG_CAL4_L, 0x02); + comm->writeRegister(QMI8658_REG_CAL4_H, 0x02); writeCommand(CTRL_CMD_CONFIGURE_TAP); @@ -1164,7 +1191,7 @@ class SensorQMI8658 : bool enableTap(IntPin pin = INTERRUPT_PIN_DISABLE) { - if (!__accel_enabled)return false; + if (!_accel_enabled)return false; switch (pin) { case INTERRUPT_PIN_1: case INTERRUPT_PIN_2: @@ -1174,17 +1201,17 @@ class SensorQMI8658 : default: break; } - return setRegisterBit(QMI8658_REG_CTRL8, 0); + return comm->setRegisterBit(QMI8658_REG_CTRL8, 0); } bool disableTap() { - return clrRegisterBit(QMI8658_REG_CTRL8, 0); + return comm->clrRegisterBit(QMI8658_REG_CTRL8, 0); } TapEvent getTapStatus() { - int val = readRegister(QMI8658_REG_TAP_STATUS); + int val = comm->readRegister(QMI8658_REG_TAP_STATUS); if (val & _BV(7)) { log_i("Tap was detected on the negative direction of the Tap axis"); } else { @@ -1268,25 +1295,25 @@ class SensorQMI8658 : disableAccelerometer(); } - writeRegister(QMI8658_REG_CAL1_L, mgToBytes(AnyMotionXThr)); - writeRegister(QMI8658_REG_CAL1_H, mgToBytes(AnyMotionYThr)); - writeRegister(QMI8658_REG_CAL2_L, mgToBytes(AnyMotionZThr)); - writeRegister(QMI8658_REG_CAL2_H, mgToBytes(NoMotionXThr)); - writeRegister(QMI8658_REG_CAL3_L, mgToBytes(NoMotionYThr)); - writeRegister(QMI8658_REG_CAL3_H, mgToBytes(NoMotionZThr)); - writeRegister(QMI8658_REG_CAL4_L, modeCtrl); - writeRegister(QMI8658_REG_CAL4_H, 0x01); + comm->writeRegister(QMI8658_REG_CAL1_L, mgToBytes(AnyMotionXThr)); + comm->writeRegister(QMI8658_REG_CAL1_H, mgToBytes(AnyMotionYThr)); + comm->writeRegister(QMI8658_REG_CAL2_L, mgToBytes(AnyMotionZThr)); + comm->writeRegister(QMI8658_REG_CAL2_H, mgToBytes(NoMotionXThr)); + comm->writeRegister(QMI8658_REG_CAL3_L, mgToBytes(NoMotionYThr)); + comm->writeRegister(QMI8658_REG_CAL3_H, mgToBytes(NoMotionZThr)); + comm->writeRegister(QMI8658_REG_CAL4_L, modeCtrl); + comm->writeRegister(QMI8658_REG_CAL4_H, 0x01); writeCommand(CTRL_CMD_CONFIGURE_MOTION); - writeRegister(QMI8658_REG_CAL1_L, AnyMotionWindow); - writeRegister(QMI8658_REG_CAL1_H, NoMotionWindow); - writeRegister(QMI8658_REG_CAL2_L, lowByte(SigMotionWaitWindow)); - writeRegister(QMI8658_REG_CAL2_H, highByte(SigMotionWaitWindow)); - writeRegister(QMI8658_REG_CAL3_L, lowByte(SigMotionConfirmWindow)); - writeRegister(QMI8658_REG_CAL3_H, highByte(SigMotionConfirmWindow)); - // writeRegister(QMI8658_REG_CAL4_L, 0x02); - writeRegister(QMI8658_REG_CAL4_H, 0x02); + comm->writeRegister(QMI8658_REG_CAL1_L, AnyMotionWindow); + comm->writeRegister(QMI8658_REG_CAL1_H, NoMotionWindow); + comm->writeRegister(QMI8658_REG_CAL2_L, lowByte(SigMotionWaitWindow)); + comm->writeRegister(QMI8658_REG_CAL2_H, highByte(SigMotionWaitWindow)); + comm->writeRegister(QMI8658_REG_CAL3_L, lowByte(SigMotionConfirmWindow)); + comm->writeRegister(QMI8658_REG_CAL3_H, highByte(SigMotionConfirmWindow)); + // comm->writeRegister(QMI8658_REG_CAL4_L, 0x02); + comm->writeRegister(QMI8658_REG_CAL4_H, 0x02); writeCommand(CTRL_CMD_CONFIGURE_MOTION); @@ -1302,7 +1329,7 @@ class SensorQMI8658 : bool enableMotionDetect(IntPin pin = INTERRUPT_PIN_DISABLE) { - if (!__accel_enabled)return false; + if (!_accel_enabled)return false; switch (pin) { case INTERRUPT_PIN_1: case INTERRUPT_PIN_2: @@ -1312,17 +1339,17 @@ class SensorQMI8658 : default: break; } - setRegisterBit(QMI8658_REG_CTRL8, 1); - setRegisterBit(QMI8658_REG_CTRL8, 2); - setRegisterBit(QMI8658_REG_CTRL8, 3); + comm->setRegisterBit(QMI8658_REG_CTRL8, 1); + comm->setRegisterBit(QMI8658_REG_CTRL8, 2); + comm->setRegisterBit(QMI8658_REG_CTRL8, 3); return true; } bool disableMotionDetect() { - clrRegisterBit(QMI8658_REG_CTRL8, 1); - clrRegisterBit(QMI8658_REG_CTRL8, 2); - clrRegisterBit(QMI8658_REG_CTRL8, 3); + comm->clrRegisterBit(QMI8658_REG_CTRL8, 1); + comm->clrRegisterBit(QMI8658_REG_CTRL8, 2); + comm->clrRegisterBit(QMI8658_REG_CTRL8, 3); return false; } @@ -1356,25 +1383,25 @@ class SensorQMI8658 : //Reset default value if (!reset()) { - return DEV_WIRE_ERR; + return -1; } // Disable sensors - clrRegisterBit(QMI8658_REG_CTRL7, 0); + comm->clrRegisterBit(QMI8658_REG_CTRL7, 0); //setAccelRange - if (writeRegister(QMI8658_REG_CTRL2, 0x8F, (ACC_RANGE_8G << 4)) != DEV_WIRE_NONE) { - return DEV_WIRE_ERR; + if (comm->writeRegister(QMI8658_REG_CTRL2, 0x8F, (ACC_RANGE_8G << 4)) != 0) { + return -1; } // setAccelOutputDataRate - if (writeRegister(QMI8658_REG_CTRL2, 0xF0, odr) != DEV_WIRE_NONE) { - return DEV_WIRE_ERR; + if (comm->writeRegister(QMI8658_REG_CTRL2, 0xF0, odr) != 0) { + return -1; } //set wom - if (writeRegister(QMI8658_REG_CAL1_L, WoMThreshold) != DEV_WIRE_NONE) { - return DEV_WIRE_ERR; + if (comm->writeRegister(QMI8658_REG_CAL1_L, WoMThreshold) != 0) { + return -1; } if ( pin == INTERRUPT_PIN_1) { @@ -1385,19 +1412,19 @@ class SensorQMI8658 : val <<= 6; val |= (blankingTime & 0x3F); - if (writeRegister(QMI8658_REG_CAL1_H, val) != DEV_WIRE_NONE) { - return DEV_WIRE_ERR; + if (comm->writeRegister(QMI8658_REG_CAL1_H, val) != 0) { + return -1; } - if (writeCommand(CTRL_CMD_WRITE_WOM_SETTING) != DEV_WIRE_NONE) { - return DEV_WIRE_ERR; + if (writeCommand(CTRL_CMD_WRITE_WOM_SETTING) != 0) { + return -1; } enableAccelerometer(); enableINT(pin); - return DEV_WIRE_NONE; + return 0; } @@ -1428,7 +1455,7 @@ class SensorQMI8658 : // STATUS0 0x2E // STATUS1 0x2F uint8_t status[3]; - if (readRegister(QMI8658_REG_STATUS_INT, status, 3) != DEV_WIRE_NONE) { + if (comm->readRegister(QMI8658_REG_STATUS_INT, status, 3) != 0) { return 0; } @@ -1475,7 +1502,7 @@ class SensorQMI8658 : if (status[1] & 0x02) { result |= STATUS0_GYRO_DATA_READY; if (eventGyroDataReady)eventGyroDataReady(); - __gDataReady = true; + _gDataReady = true; } // Accelerometer new data available // 0: No updates since last read. @@ -1483,7 +1510,7 @@ class SensorQMI8658 : if (status[1] & 0x01) { result |= STATUS0_ACCEL_DATA_READY; if (eventAccelDataReady)eventAccelDataReady(); - __aDataReady = true; + _aDataReady = true; } } @@ -1582,22 +1609,22 @@ class SensorQMI8658 : bool calibration(uint16_t *gX_gain = NULL, uint16_t *gY_gain = NULL, uint16_t *gZ_gain = NULL) { // 1.Set CTRL7.aEN = 0 and CTRL7.gEN = 0, to disable the accelerometer and gyroscope. - if (writeRegister(QMI8658_REG_CTRL7, 0x00) != DEV_WIRE_NONE) { + if (comm->writeRegister(QMI8658_REG_CTRL7, (uint8_t)0x00) != 0) { return false; } // 2.Issue the CTRL_CMD_ON_DEMAND_CALIBRATION (0xA2) by CTRL9 command. - if (writeCommand(CTRL_CMD_ON_DEMAND_CALIBRATION, 3000) != DEV_WIRE_NONE) { + if (writeCommand(CTRL_CMD_ON_DEMAND_CALIBRATION, 3000) != 0) { return false; } // 3.And wait about 1.5 seconds for QMI8658A to finish the CTRL9 command. - delay(1600); + hal->delay(1600); // 4.Read the COD_STATUS register (0x46) to check the result/status of the COD implementation. - int result = readRegister(QMI8658_REG_COD_STATUS); + int result = comm->readRegister(QMI8658_REG_COD_STATUS); - if (result == DEV_WIRE_ERR)return false; + if (result == -1)return false; // During the process, it is recommended to place the device in quiet, otherwise, the COD might fail and report error. @@ -1637,7 +1664,7 @@ class SensorQMI8658 : if (gX_gain && gY_gain && gZ_gain) { uint8_t rawBuffer[6] = {0}; - if (readRegister(QMI8658_REG_DVX_L, rawBuffer, 6) != DEV_WIRE_NONE) { + if (comm->readRegister(QMI8658_REG_DVX_L, rawBuffer, 6) != 0) { return false; } *gX_gain = ((uint16_t)rawBuffer[0]) | (uint16_t)(rawBuffer[1] << 8); @@ -1652,7 +1679,7 @@ class SensorQMI8658 : bool writeCalibration(uint16_t gX_gain, uint16_t gY_gain, uint16_t gZ_gain) { // 1. Disable Accelerometer and Gyroscope by setting CTRL7.aEN = 0 and CTRL7.gEN = 0 - if (writeRegister(QMI8658_REG_CTRL7, 0x00) != DEV_WIRE_NONE) { + if (comm->writeRegister(QMI8658_REG_CTRL7, (uint8_t)0x00) != 0) { return false; } @@ -1669,10 +1696,10 @@ class SensorQMI8658 : highByte(gZ_gain), }; - writeRegister(QMI8658_REG_CAL1_L, buffer, sizeof(buffer)); + comm->writeRegister(QMI8658_REG_CAL1_L, buffer, sizeof(buffer)); // 5. Write 0xAA to CTRL9 and follow CTRL9 protocol - if (writeCommand(CTRL_CMD_APPLY_GYRO_GAINS, 3000) != DEV_WIRE_NONE) { + if (writeCommand(CTRL_CMD_APPLY_GYRO_GAINS, 3000) != 0) { return false; } @@ -1683,12 +1710,12 @@ class SensorQMI8658 : bool selfTestAccel() { // 1- Disable the sensors (CTRL7 = 0x00). - if (writeRegister(QMI8658_REG_CTRL7, 0x00) != DEV_WIRE_NONE) { + if (comm->writeRegister(QMI8658_REG_CTRL7, (uint8_t)0x00) != 0) { return false; } // 2- Set proper accelerometer ODR (CTRL2.aODR) and bit CTRL2.aST (bit7) to 1 to trigger the Self-Test. - if (writeRegister(QMI8658_REG_CTRL2, 0xF0, ACC_ODR_1000Hz | 0x80) != DEV_WIRE_NONE) { + if (comm->writeRegister(QMI8658_REG_CTRL2, 0xF0, ACC_ODR_1000Hz | 0x80) != 0) { return false; } @@ -1696,11 +1723,11 @@ class SensorQMI8658 : int retry = 50; int dataReady = 0x00; while (dataReady != 0x01) { - uint8_t reg_var = readRegister(QMI8658_REG_STATUS_INT); + uint8_t reg_var = comm->readRegister(QMI8658_REG_STATUS_INT); log_d("reg_var : %x", reg_var); dataReady = reg_var & 0x01; - // dataReady = readRegister(QMI8658_REG_STATUS_INT) & 0x01; - delay(20); + // dataReady = comm->readRegister(QMI8658_REG_STATUS_INT) & 0x01; + hal->delay(20); if (--retry <= 0) { log_e("No response."); return false; @@ -1710,16 +1737,16 @@ class SensorQMI8658 : log_i("Data is ready for reading...."); //4- Set CTRL2.aST(bit7) to 0, to clear STATUSINT1.bit0 and/or INT2. - clrRegisterBit(QMI8658_REG_CTRL2, 7); + comm->clrRegisterBit(QMI8658_REG_CTRL2, 7); // 5- Check for QMI8658A drives INT2 back to Low, and sets STATUSINT1.bit0 to 0. retry = 50; while (dataReady == 0x01) { - uint8_t reg_var = readRegister(QMI8658_REG_STATUS_INT); + uint8_t reg_var = comm->readRegister(QMI8658_REG_STATUS_INT); log_d("reg_var : %x", reg_var); dataReady = (reg_var & 0x01); - // dataReady = !(readRegister(QMI8658_REG_STATUS_INT) & 0x01); - delay(20); + // dataReady = !(comm->readRegister(QMI8658_REG_STATUS_INT) & 0x01); + hal->delay(20); if (--retry <= 0) { log_e("No response."); return false; @@ -1735,7 +1762,7 @@ class SensorQMI8658 : */ uint8_t rawBuffer[6]; - if (readRegister(QMI8658_REG_DVX_L, rawBuffer, 6) != DEV_WIRE_NONE) { + if (comm->readRegister(QMI8658_REG_DVX_L, rawBuffer, 6) != 0) { return false; } @@ -1764,19 +1791,19 @@ class SensorQMI8658 : bool selfTestGyro() { // 1- Disable the sensors (CTRL7 = 0x00). - if (writeRegister(QMI8658_REG_CTRL7, 0x00) != DEV_WIRE_NONE) { + if (comm->writeRegister(QMI8658_REG_CTRL7, (uint8_t)0x00) != 0) { return false; } // 2- Set the bit gST to 1. (CTRL3.bit7 = 1’b1). - setRegisterBit(QMI8658_REG_CTRL3, 7); + comm->setRegisterBit(QMI8658_REG_CTRL3, 7); // 3- Wait for QMI8658A to drive INT2 to High, if INT2 is enabled, or STATUS_INT.bit0 is set to 1. int retry = 50; int dataReady = 0x00; while (dataReady != 0x01) { - dataReady = readRegister(QMI8658_REG_STATUS_INT) & 0x01; - delay(20); + dataReady = comm->readRegister(QMI8658_REG_STATUS_INT) & 0x01; + hal->delay(20); if (--retry <= 0) { log_e("No response."); return false; @@ -1786,13 +1813,13 @@ class SensorQMI8658 : log_i("Data is ready for reading...."); //4- Set CTRL3.aST(bit7) to 0, to clear STATUS_INT1.bit0 and/or INT2. - clrRegisterBit(QMI8658_REG_CTRL3, 7); + comm->clrRegisterBit(QMI8658_REG_CTRL3, 7); // 5- Check for QMI8658A drives INT2 back to Low, or sets STATUSINT1.bit0 to 0. retry = 50; while (dataReady != 0x00) { - dataReady = !(readRegister(QMI8658_REG_STATUS_INT) & 0x01); - delay(20); + dataReady = !(comm->readRegister(QMI8658_REG_STATUS_INT) & 0x01); + hal->delay(20); if (--retry <= 0) { log_e("No response."); return false; @@ -1807,7 +1834,7 @@ class SensorQMI8658 : Read the 16 bits result in format signed U12.4, resolution is 62.5mdps (1 / 2^4 dps). */ uint8_t rawBuffer[6]; - if (readRegister(QMI8658_REG_DVX_L, rawBuffer, 6) != DEV_WIRE_NONE) { + if (comm->readRegister(QMI8658_REG_DVX_L, rawBuffer, 6) != 0) { return false; } @@ -1850,9 +1877,9 @@ class SensorQMI8658 : data[4] = lowByte(offset_z); data[5] = highByte(offset_z); - writeRegister(QMI8658_REG_CAL1_L, data, 2); - writeRegister(QMI8658_REG_CAL2_L, data + 2, 2); - writeRegister(QMI8658_REG_CAL3_L, data + 4, 2); + comm->writeRegister(QMI8658_REG_CAL1_L, data, 2); + comm->writeRegister(QMI8658_REG_CAL2_L, data + 2, 2); + comm->writeRegister(QMI8658_REG_CAL3_L, data + 4, 2); writeCommand(CTRL_CMD_ACCEL_HOST_DELTA_OFFSET); } @@ -1870,35 +1897,35 @@ class SensorQMI8658 : data[4] = lowByte(offset_z); data[5] = highByte(offset_z); - writeRegister(QMI8658_REG_CAL1_L, data, 2); - writeRegister(QMI8658_REG_CAL2_L, data + 2, 2); - writeRegister(QMI8658_REG_CAL3_L, data + 4, 2); + comm->writeRegister(QMI8658_REG_CAL1_L, data, 2); + comm->writeRegister(QMI8658_REG_CAL2_L, data + 2, 2); + comm->writeRegister(QMI8658_REG_CAL3_L, data + 4, 2); writeCommand(CTRL_CMD_GYRO_HOST_DELTA_OFFSET); } - void setPins(int irq) + void setPins(int _irq) { - __irq = irq; + _irq = _irq; } private: float accelScales, gyroScales; uint32_t lastTimestamp = 0; uint8_t sampleMode = ASYNC_MODE; - bool __accel_enabled = false; - bool __gyro_enabled = false; + bool _accel_enabled = false; + bool _gyro_enabled = false; uint32_t revisionID; uint8_t usid[6]; - bool __gDataReady = false; - bool __aDataReady = false; - int __irq = -1; - uint8_t __irq_enable_mask = false; - uint8_t __fifo_mode; - bool __fifo_interrupt = false;; - uint8_t *__fifo_buffer = NULL; - uint16_t __fifo_size = 0; + bool _gDataReady = false; + bool _aDataReady = false; + int _irq = -1; + uint8_t _irq_enable_mask = false; + uint8_t _fifo_mode; + bool _fifo_interrupt = false;; + uint8_t *fifo_buffer = NULL; + uint16_t _fifo_size = 0; EventCallBack_t eventWomEvent = NULL; EventCallBack_t eventTagEvent = NULL; @@ -1915,34 +1942,34 @@ class SensorQMI8658 : { int val; uint32_t startMillis; - if (writeRegister(QMI8658_REG_CTRL9, cmd) == DEV_WIRE_ERR) { - return DEV_WIRE_ERR; + if (comm->writeRegister(QMI8658_REG_CTRL9, cmd) == -1) { + return -1; } - startMillis = millis(); + startMillis = hal->millis(); do { - val = readRegister(QMI8658_REG_STATUS_INT); - delay(1); - if (millis() - startMillis > wait_ms) { + val = comm->readRegister(QMI8658_REG_STATUS_INT); + hal->delay(1); + if (hal->millis() - startMillis > wait_ms) { log_e("wait for ctrl9 command done time out : %d val:%d", cmd, val); - return DEV_WIRE_TIMEOUT; + return -1; } - } while (val != DEV_WIRE_ERR && !(val & 0x80)); + } while (val != -1 && !(val & 0x80)); - if (writeRegister(QMI8658_REG_CTRL9, CTRL_CMD_ACK) == DEV_WIRE_ERR) { - return DEV_WIRE_ERR; + if (comm->writeRegister(QMI8658_REG_CTRL9, CTRL_CMD_ACK) == -1) { + return -1; } - startMillis = millis(); + startMillis = hal->millis(); do { - val = readRegister(QMI8658_REG_STATUS_INT); - delay(1); - if (millis() - startMillis > wait_ms) { + val = comm->readRegister(QMI8658_REG_STATUS_INT); + hal->delay(1); + if (hal->millis() - startMillis > wait_ms) { log_e("Clear ctrl9 command done flag timeout : %d val:%d", cmd, val); - return DEV_WIRE_TIMEOUT; + return -1; } - } while (val != DEV_WIRE_ERR && (val & 0x80)); + } while (val != -1 && (val & 0x80)); - return DEV_WIRE_NONE; + return 0; } @@ -1962,8 +1989,8 @@ class SensorQMI8658 : uint8_t buffer[6] = {0}; - if (__irq != -1) { - this->setGpioMode(__irq, INPUT); + if (_irq != -1) { + hal->pinMode(_irq, INPUT); } if (!reset()) { @@ -1976,27 +2003,27 @@ class SensorQMI8658 : return false; } // Enable address auto increment, Big-Endian format - // writeRegister(QMI8658_REG_CTRL1, 0x60); + // comm->writeRegister(QMI8658_REG_CTRL1, 0x60); // Little-Endian / address auto increment - // writeRegister(QMI8658_REG_CTRL1, 0x40); + // comm->writeRegister(QMI8658_REG_CTRL1, 0x40); // no need . reset function has set //EN.ADDR_AI - // setRegisterBit(QMI8658_REG_CTRL1, 6); + // comm->setRegisterBit(QMI8658_REG_CTRL1, 6); // Use STATUS_INT.bit7 as CTRL9 handshake - writeRegister(QMI8658_REG_CTRL8, 0x80); + comm->writeRegister(QMI8658_REG_CTRL8, 0x80); // Get firmware version and usid writeCommand(CTRL_CMD_COPY_USID); - if (readRegister(QMI8658_REG_DQW_L, buffer, 3) != DEV_WIRE_ERR) { + if (comm->readRegister(QMI8658_REG_DQW_L, buffer, 3) != -1) { revisionID = buffer[0] | (uint32_t)(buffer[1] << 8) | (uint32_t)(buffer[2] << 16); log_d("FW Version :0x%02X%02X%02X", buffer[0], buffer[1], buffer[2]); } - if (readRegister(QMI8658_REG_DVX_L, usid, 6) != DEV_WIRE_ERR) { + if (comm->readRegister(QMI8658_REG_DVX_L, usid, 6) != -1) { log_d("USID :%02X%02X%02X%02X%02X%02X", usid[0], usid[1], usid[2], usid[3], usid[4], usid[5]); @@ -2005,11 +2032,9 @@ class SensorQMI8658 : return true; } - int getReadMaskImpl() - { - return 0x80; - } - +protected: + std::unique_ptr comm; + std::unique_ptr hal; }; diff --git a/src/SensorRTC.h b/src/SensorRTC.h index 915748e..b251645 100644 --- a/src/SensorRTC.h +++ b/src/SensorRTC.h @@ -50,7 +50,7 @@ #define RTC_DAYS_IN_NOVEMBER (30u) #define RTC_DAYS_IN_DECEMBER (31u) -enum { +enum DataTimeFormat { DATETIME_FORMAT_HM, DATETIME_FORMAT_HMS, DATETIME_FORMAT_YYYY_MM_DD, @@ -60,8 +60,6 @@ enum { DATETIME_FORMAT_YYYY_MM_DD_H_M_S_WEEK, }; - - class RTC_DateTime { public: @@ -184,12 +182,12 @@ template class RTCCommon { public: - const char *strftime(uint8_t sytle = DATETIME_FORMAT_YYYY_MM_DD_H_M_S_WEEK) + const char *strftime(uint8_t style = DATETIME_FORMAT_YYYY_MM_DD_H_M_S_WEEK) { const char *weekString[] = {"Sun", "Mon", "Tue", "Wed", "Thur", "Fri", "Sat"}; static char format[64]; RTC_DateTime t = thisChip().getDateTime(); - switch (sytle) { + switch (style) { case DATETIME_FORMAT_HM: snprintf(format, sizeof(format), "%02d:%02d", t.hour, t.minute); break; diff --git a/src/SensorWireHelper.cpp b/src/SensorWireHelper.cpp index 5983ac1..4fb8a58 100644 --- a/src/SensorWireHelper.cpp +++ b/src/SensorWireHelper.cpp @@ -32,12 +32,11 @@ #if defined(ARDUINO) - +// regdump does not call Wire.begin, you need to call it before using regdump int SensorWireHelper::regdump(TwoWire &w, Stream &serial, uint8_t devAddr, uint8_t start, uint8_t length) { uint8_t *buffer = (uint8_t *)malloc(length); if (!buffer) return -1; - w.begin(); w.beginTransmission(devAddr); w.write(start); if (w.endTransmission() != 0) { diff --git a/src/SensorWireHelper.h b/src/SensorWireHelper.h index bfd1131..5c303fc 100644 --- a/src/SensorWireHelper.h +++ b/src/SensorWireHelper.h @@ -36,6 +36,7 @@ class SensorWireHelper { public: + // regdump,dumpDevices method does not call Wire.begin, you need to call it before using regdump or dumpDevices static int regdump(TwoWire &w, Stream &serial, uint8_t devAddr, uint8_t start, uint8_t len); static void dumpDevices(TwoWire &w, Stream &serial = Serial, int first = 0, int last = 127); static void hexdump(uint8_t *data, size_t len, Stream &serial = Serial); diff --git a/src/TouchDrvCHSC5816.hpp b/src/TouchDrvCHSC5816.hpp index 31efa43..dfa5425 100644 --- a/src/TouchDrvCHSC5816.hpp +++ b/src/TouchDrvCHSC5816.hpp @@ -22,7 +22,7 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. * - * @file TouchDrvCHSC5816.tpp + * @file TouchDrvCHSC5816.hpp * @author Lewis He (lewishe@outlook.com) * @date 2023-04-12 * @@ -31,127 +31,110 @@ #include "REG/CHSC5816Constants.h" #include "TouchDrvInterface.hpp" -#include "SensorCommon.tpp" - -typedef struct __CHSC5816_Header { - uint16_t fw_ver; - uint16_t checksum; - uint32_t sig; - uint32_t vid_pid; - uint16_t raw_offet; - uint16_t dif_offet; -} CHSC5816_Header_t; - -union __CHSC5816_PointReg { - struct { - uint8_t status; - uint8_t fingerNumber; - uint8_t x_l8; - uint8_t y_l8; - uint8_t z; - uint8_t x_h4: 4; - uint8_t y_h4: 4; - uint8_t id: 4; - uint8_t event: 4; - uint8_t p2; - } rp; - unsigned char data[8]; -}; -class TouchDrvCHSC5816 : - public TouchDrvInterface, - public SensorCommon +#define CHSC5816_SLAVE_ADDRESS (0x2E) + +class TouchDrvCHSC5816 : public TouchDrvInterface { - friend class SensorCommon; -public: + typedef struct { + uint16_t fw_ver; + uint16_t checksum; + uint32_t sig; + uint32_t vid_pid; + uint16_t raw_offset; + uint16_t dif_offset; + } Header_t; + + union PointReg { + struct { + uint8_t status; + uint8_t fingerNumber; + uint8_t x_l8; + uint8_t y_l8; + uint8_t z; + uint8_t x_h4: 4; + uint8_t y_h4: 4; + uint8_t id: 4; + uint8_t event: 4; + uint8_t p2; + } report; + unsigned char data[8]; + }; +public: -#if defined(ARDUINO) - TouchDrvCHSC5816(PLATFORM_WIRE_TYPE &w, - int sda = DEFAULT_SDA, - int scl = DEFAULT_SCL, - uint8_t addr = CHSC5816_SLAVE_ADDRESS) - { - __wire = &w; - __sda = sda; - __scl = scl; - __rst = SENSOR_PIN_NONE; - __irq = SENSOR_PIN_NONE; - __addr = addr; - } -#endif - - TouchDrvCHSC5816() - { -#if defined(ARDUINO) - __wire = &Wire; - __sda = DEFAULT_SDA; - __scl = DEFAULT_SCL; -#endif - __rst = SENSOR_PIN_NONE; - __irq = SENSOR_PIN_NONE; - __addr = CHSC5816_SLAVE_ADDRESS; - } + TouchDrvCHSC5816() : comm(nullptr), hal(nullptr) {} ~TouchDrvCHSC5816() { - // deinit(); + if (comm) { + comm->deinit(); + } } #if defined(ARDUINO) - bool begin(PLATFORM_WIRE_TYPE &w, - uint8_t addr = CHSC5816_SLAVE_ADDRESS, - int sda = DEFAULT_SDA, - int scl = DEFAULT_SCL) + bool begin(TwoWire &wire, uint8_t addr = CHSC5816_SLAVE_ADDRESS, int sda = -1, int scl = -1) { - return SensorCommon::begin(w, addr, sda, scl); + if (!beginCommon(comm, hal, wire, addr, sda, scl)) { + return false; + } + return initImpl(); } -#endif +#elif defined(ESP_PLATFORM) -#if defined(ESP_PLATFORM) && !defined(ARDUINO) -#if ((ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL(5,0,0)) && defined(CONFIG_SENSORLIB_ESP_IDF_NEW_API)) - bool begin(i2c_master_bus_handle_t i2c_dev_bus_handle, uint8_t addr) +#if defined(USEING_I2C_LEGACY) + bool begin(i2c_port_t port_num, uint8_t addr = CHSC5816_SLAVE_ADDRESS, int sda = -1, int scl = -1) { - return SensorCommon::begin(i2c_dev_bus_handle, addr); + if (!beginCommon(comm, hal, port_num, addr, sda, scl)) { + return false; + } + return initImpl(); } #else - bool begin(i2c_port_t port_num, uint8_t addr, int sda, int scl) + bool begin(i2c_master_bus_handle_t handle, uint8_t addr = CHSC5816_SLAVE_ADDRESS) { - return SensorCommon::begin(port_num, addr, sda, scl); + if (!beginCommon(comm, hal, handle, addr)) { + return false; + } + return initImpl(); } -#endif //ESP_IDF_VERSION -#endif +#endif //ESP_PLATFORM +#endif //ARDUINO - bool begin(uint8_t addr, iic_fptr_t readRegCallback, iic_fptr_t writeRegCallback) + bool begin(SensorCommCustom::CustomCallback callback, + SensorCommCustomHal::CustomHalCallback hal_callback, + uint8_t addr = CHSC5816_SLAVE_ADDRESS) { - return SensorCommon::begin(addr, readRegCallback, writeRegCallback); + if (!beginCommCustomCallback(COMM_CUSTOM, + callback, hal_callback, addr, comm, hal)) { + return false; + } + return initImpl(); } void reset() { - if (__rst != SENSOR_PIN_NONE) { - this->setGpioLevel(__rst, LOW); - delay(3); - this->setGpioLevel(__rst, HIGH); - delay(5); + if (_rst != -1) { + hal->digitalWrite(_rst, LOW); + hal->delay(3); + hal->digitalWrite(_rst, HIGH); + hal->delay(5); } } uint8_t getPoint(int16_t *x_array, int16_t *y_array, uint8_t get_point = 1) { - __CHSC5816_PointReg touch; - - // CHSC5816_REG_POINT - uint8_t write_buffer[] = {0x20, 0x00, 0x00, 0x2c}; - writeThenRead(write_buffer, SENSORLIB_COUNT(write_buffer), touch.data, 8); - if (touch.rp.status == 0xFF && touch.rp.fingerNumber == 0) { + PointReg touch; + uint8_t CHSC5816_REG_POINT[] = {0x20, 0x00, 0x00, 0x2c}; + comm->writeThenRead(CHSC5816_REG_POINT, arraySize(CHSC5816_REG_POINT), touch.data, 8); + if (touch.report.status == 0xFF && touch.report.fingerNumber == 0) { return 0; } if (x_array) { - *x_array = (unsigned int)(touch.rp.x_h4 << 8) | touch.rp.x_l8; + *x_array = (unsigned int)(touch.report.x_h4 << 8) | touch.report.x_l8; } if (y_array) { - *y_array = (unsigned int)(touch.rp.y_h4 << 8) | touch.rp.y_l8; + *y_array = (unsigned int)(touch.report.y_h4 << 8) | touch.report.y_l8; } updateXY(1, x_array, y_array); @@ -161,8 +144,8 @@ class TouchDrvCHSC5816 : bool isPressed() { - if (__irq != SENSOR_PIN_NONE) { - return this->getGpioLevel(__irq) == LOW; + if (_irq != -1) { + return hal->digitalRead(_irq) == LOW; } return getPoint(NULL, NULL); } @@ -175,12 +158,12 @@ class TouchDrvCHSC5816 : //2uA void sleep() { - uint8_t write_buffer[] = { + uint8_t CHSC5816_REG_SLEEP[] = { 0x20, 0x00, 0x00, 0x00, // CHSC5816_REG_CMD_BUFF 0xF8, 0x16, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0xE9 }; - writeBuffer(write_buffer, SENSORLIB_COUNT(write_buffer)); + comm->writeBuffer(CHSC5816_REG_SLEEP, arraySize(CHSC5816_REG_SLEEP)); } void wakeup() @@ -190,12 +173,12 @@ class TouchDrvCHSC5816 : void idle() { - uint8_t write_buffer[] = { + uint8_t CHSC5816_REG_IDEL[] = { 0x20, 0x00, 0x00, 0x00, // CHSC5816_REG_CMD_BUFF 0x20, 0x16, 0x02, 0x00, 0xDB, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0xE9 }; - writeBuffer(write_buffer, SENSORLIB_COUNT(write_buffer)); + comm->writeBuffer(CHSC5816_REG_IDEL, arraySize(CHSC5816_REG_IDEL)); } uint8_t getSupportTouchPoint() @@ -203,74 +186,86 @@ class TouchDrvCHSC5816 : return 1; } - bool getResolution(int16_t *x, int16_t *y) + bool getResolution(int16_t *width, int16_t *height) { - /* - uint8_t buffer[16] = { +#if 0 + //TODO: NEED TEST + uint8_t CHSC5816_REG_FW[] = { + 0x20, 0x00, 0x00, 0x00, // CHSC5816_REG_CMD_BUFF 0xFC, 0x16, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0xe9 }; - writeRegister(CHSC5816_REG_CMD_BUFF, buffer, 16); - memset(buffer, 0, 16); - readRegister(CHSC5816_REG_CMD_BUFF, buffer, 16); - for (int i = 0; i < 16; ++i) { - Serial.print(buffer[i], HEX); - Serial.print(","); + if (comm->writeThenRead(CHSC5816_REG_FW, + arraySize(CHSC5816_REG_FW), + CHSC5816_REG_FW, + arraySize(CHSC5816_REG_FW)) < 0) { + return false; + } + + SensorLibDumpBuffer(CHSC5816_REG_FW, arraySize(CHSC5816_REG_FW)); + + int16_t res_w = (CHSC5816_REG_FW[2] << 8) | CHSC5816_REG_FW[3]; + int16_t res_h = (CHSC5816_REG_FW[4] << 8) | CHSC5816_REG_FW[5]; + if (width) { + *width = res_w; + } + if (height) { + *height = res_h; } - Serial.println(); return true; - */ +#endif return false; } - void setGpioCallback(gpio_mode_fptr_t mode_cb, - gpio_write_fptr_t write_cb, - gpio_read_fptr_t read_cb) + void setGpioCallback(CustomMode mode_cb, + CustomWrite write_cb, + CustomRead read_cb) { - SensorCommon::setGpioModeCallback(mode_cb); - SensorCommon::setGpioWriteCallback(write_cb); - SensorCommon::setGpioReadCallback(read_cb); + SensorHalCustom::setCustomMode(mode_cb); + SensorHalCustom::setCustomWrite(write_cb); + SensorHalCustom::setCustomRead(read_cb); } private: bool checkOnline() { - CHSC5816_Header_t tmp; - memset(&tmp, 0, sizeof(CHSC5816_Header_t)); - memset(&__header, 0, sizeof(CHSC5816_Header_t)); + Header_t first; + Header_t second; - // CHSC5816_REG_BOOT_STATE 0x20000018 - uint8_t write_buffer[] = {0x20, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0x00}; + memset(&second, 0, sizeof(Header_t)); + memset(&first, 0, sizeof(Header_t)); - if (writeBuffer(write_buffer, SENSORLIB_COUNT(write_buffer)) == DEV_WIRE_ERR) { - log_e("writeBuffer clean boot state failed!\n"); + // CHSC5816_REG_BOOT_STATE 0x20000018 + uint8_t CHSC5816_REG_BOOT_STATE[] = {0x20, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0x00}; + if (comm->writeBuffer(CHSC5816_REG_BOOT_STATE, arraySize(CHSC5816_REG_BOOT_STATE)) < 0) { + log_e("comm->writeBuffer clean boot state failed!\n"); return false; } reset(); for (int i = 0; i < 10; ++i) { - delay(10); + hal->delay(10); // CHSC5816_REG_IMG_HEAD 0x20000014 - uint8_t write_buffer[] = {0x20, 0x00, 0x00, 0x14}; - if (writeThenRead(write_buffer, SENSORLIB_COUNT(write_buffer), - (uint8_t *)&__header, - sizeof(CHSC5816_Header_t)) == DEV_WIRE_ERR) { - printf("readRegister 1 failed!\n"); + uint8_t CHSC5816_REG_IMG_HEAD[] = {0x20, 0x00, 0x00, 0x14}; + if (comm->writeThenRead(CHSC5816_REG_IMG_HEAD, + arraySize(CHSC5816_REG_IMG_HEAD), + (uint8_t *)&first, + sizeof(Header_t)) < 0) { return false; } - if (writeThenRead(write_buffer, SENSORLIB_COUNT(write_buffer), - (uint8_t *)&tmp, - sizeof(CHSC5816_Header_t)) == DEV_WIRE_ERR) { - printf("readRegister 2 failed!\n"); + if (comm->writeThenRead(CHSC5816_REG_IMG_HEAD, + arraySize(CHSC5816_REG_IMG_HEAD), + (uint8_t *)&second, + sizeof(Header_t)) < 0) { return false; } - if (memcmp(&tmp, &__header, sizeof(CHSC5816_Header_t)) != 0 ) { + if (memcmp(&second, &first, sizeof(Header_t)) != 0 ) { continue; } - if (__header.sig == CHSC5816_SIG_VALUE) { + if (first.sig == CHSC5816_SIG_VALUE) { return true; } } @@ -280,12 +275,12 @@ class TouchDrvCHSC5816 : bool initImpl() { - if (__irq != SENSOR_PIN_NONE) { - this->setGpioMode(__irq, INPUT); + if (_irq != -1) { + hal->pinMode(_irq, INPUT); } - if (__rst != SENSOR_PIN_NONE) { - this->setGpioMode(__rst, OUTPUT); + if (_rst != -1) { + hal->pinMode(_rst, OUTPUT); } reset(); @@ -298,15 +293,39 @@ class TouchDrvCHSC5816 : return false; } - int getReadMaskImpl() - { - return -1; - } - protected: - CHSC5816_Header_t __header; + std::unique_ptr comm; + std::unique_ptr hal; + + static constexpr uint32_t CHSC5816_SIG_VALUE = (0x43534843U); }; +// #define CHSC5816_REG_CMD_BUFF (0x20000000U) +// #define CHSC5816_REG_RSP_BUFF (0x20000000U) +// #define CHSC5816_REG_IMG_HEAD (0x20000014U) +// #define CHSC5816_REG_POINT (0x2000002CU) +// #define CHSC5816_REG_WR_BUFF (0x20002000U) +// #define CHSC5816_REG_RD_BUFF (0x20002400U) +// #define CHSC5816_REG_HOLD_MCU (0x40007000U) +// #define CHSC5816_REG_AUTO_FEED (0x40007010U) +// #define CHSC5816_REG_REMAP_MCU (0x40007000U) +// #define CHSC5816_REG_RELEASE_MCU (0x40007000U) +// #define CHSC5816_REG_BOOT_STATE (0x20000018U) +// #define CHSC5816_HOLD_MCU_VAL (0x12044000U) +// #define CHSC5816_AUTO_FEED_VAL (0x0000925aU) +// #define CHSC5816_REMAP_MCU_VAL (0x12044002U) +// #define CHSC5816_RELEASE_MCU_VAL (0x12044003U) +// #define CHSC5816_REG_VID_PID_BACKUP (40 * 1024 + 0x10U) +// /*ctp work staus*/ +// #define CHSC5816_POINTING_WORK (0x00000000U) +// #define CHSC5816_READY_UPGRADE (1 << 1) +// #define CHSC5816_UPGRAD_RUNING (1 << 2) +// #define CHSC5816_SLFTEST_RUNING (1 << 3) +// #define CHSC5816_SUSPEND_GATE (1 << 16) +// #define CHSC5816_GUESTURE_GATE (1 << 17) +// #define CHSC5816_PROXIMITY_GATE (1 << 18) +// #define CHSC5816_GLOVE_GATE (1 << 19) +// #define CHSC5816_ORIENTATION_GATE (1 << 20) diff --git a/src/TouchDrvCSTXXX.cpp b/src/TouchDrvCSTXXX.cpp new file mode 100644 index 0000000..70bf327 --- /dev/null +++ b/src/TouchDrvCSTXXX.cpp @@ -0,0 +1,269 @@ +/** + * + * @license MIT License + * + * Copyright (c) 2022 lewis he + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * @file TouchDrvCSTXXX.cpp + * @author Lewis He (lewishe@outlook.com) + * @date 2023-04-24 + * @date last 2025-01-20 + * + */ +#include "TouchDrvCSTXXX.hpp" + +#define CSTXXX_SLAVE_ADDRESS (0x15) +#define CST328_SLAVE_ADDRESS (0x1A) + +TouchDrvCSTXXX::DriverCreator TouchDrvCSTXXX::driverCreators[TouchDrvCSTXXX::driverCreatorMaxNum] = { + []() -> std::unique_ptr { return std::make_unique(); }, + []() -> std::unique_ptr { return std::make_unique(); }, + []() -> std::unique_ptr { return std::make_unique(); } +}; + +TouchDrvCSTXXX::TouchDrvCSTXXX(): + _writePtr(nullptr), + _readPtr(nullptr), + _modePtr(nullptr), + _touchType(TouchDrv_UNKOWN), + _drv(nullptr) {} + +TouchDrvCSTXXX::~TouchDrvCSTXXX() {} + +void TouchDrvCSTXXX::setTouchDrvModel(TouchDrvType model) +{ + _touchType = model; +} + +void TouchDrvCSTXXX::setupDriver() +{ + if (_drv) { + _drv->setPins(_rst, _irq); + _drv->setCustomMode(_modePtr); + _drv->setCustomWrite(_writePtr); + _drv->setCustomRead(_readPtr); + } +} + +#if defined(ARDUINO) +bool TouchDrvCSTXXX::begin(TwoWire &wire, uint8_t addr, int sda, int scl) +{ + bool success = false; + for (int i = (_touchType == TouchDrv_UNKOWN) ? 0 : _touchType; i < driverCreatorMaxNum; ++i) { + _drv = createDriver(static_cast(i)); + setupDriver(); + if (_drv && _drv->begin(wire, addr, sda, scl)) { + _touchType = static_cast(i); + success = true; + break; + } + } + if (!success) { + _touchType = TouchDrv_UNKOWN; + } + return success; +} +#elif defined(ESP_PLATFORM) +#if defined(USEING_I2C_LEGACY) +bool TouchDrvCSTXXX::begin(i2c_port_t port_num, uint8_t addr, int sda, int scl) +{ + bool success = false; + for (int i = (_touchType == TouchDrv_UNKOWN) ? 0 : _touchType; i < driverCreatorMaxNum; ++i) { + _drv = createDriver(static_cast(i)); + setupDriver(); + if (_drv && _drv->begin(port_num, addr, sda, scl)) { + _touchType = static_cast(i); + success = true; + break; + } + } + if (!success) { + _touchType = TouchDrv_UNKOWN; + } + return success; +} +#else +bool TouchDrvCSTXXX::begin(i2c_master_bus_handle_t handle, uint8_t addr) +{ + bool success = false; + for (int i = (_touchType == TouchDrv_UNKOWN) ? 0 : _touchType; i < driverCreatorMaxNum; ++i) { + _drv = createDriver(static_cast(i)); + setupDriver(); + if (_drv && _drv->begin(handle, addr)) { + _touchType = static_cast(i); + success = true; + break; + } + } + if (!success) { + _touchType = TouchDrv_UNKOWN; + } + return success; +} +#endif // ESP_PLATFORM +#endif // ARDUINO + +void TouchDrvCSTXXX::setGpioCallback(SensorHalCustom::CustomMode mode_cb, + SensorHalCustom::CustomWrite write_cb, + SensorHalCustom::CustomRead read_cb) +{ + _writePtr = write_cb; + _readPtr = read_cb; + _modePtr = mode_cb; +} + +bool TouchDrvCSTXXX::begin(SensorCommCustom::CustomCallback callback, + SensorCommCustomHal::CustomHalCallback hal_callback, + uint8_t addr) +{ + bool success = false; + for (int i = (_touchType == TouchDrv_UNKOWN) ? 0 : _touchType; i < driverCreatorMaxNum; ++i) { + _drv = createDriver(static_cast(i)); + setupDriver(); + if (_drv && _drv->begin(callback, hal_callback, addr)) { + _touchType = static_cast(i); + success = true; + break; + } + } + if (!success) { + _touchType = TouchDrv_UNKOWN; + } + return success; +} + + +void TouchDrvCSTXXX::reset() +{ + if (!_drv)return; + _drv->reset(); +} + +uint8_t TouchDrvCSTXXX::getPoint(int16_t *x_array, int16_t *y_array, uint8_t get_point) +{ + if (!_drv)return 0; + return _drv->getPoint(x_array, y_array, get_point); +} + +bool TouchDrvCSTXXX::isPressed() +{ + if (!_drv)return false; + return _drv->isPressed(); +} + +const char *TouchDrvCSTXXX::getModelName() +{ + if (!_drv)return "NULL"; + return _drv->getModelName(); +} + +void TouchDrvCSTXXX::sleep() +{ + if (!_drv)return; + _drv->sleep(); +} + +void TouchDrvCSTXXX::wakeup() +{ + if (!_drv)return; + _drv->reset(); +} + +void TouchDrvCSTXXX::idle() +{ + if (!_drv)return; + _drv->idle(); +} + +uint8_t TouchDrvCSTXXX::getSupportTouchPoint() +{ + if (!_drv)return 0; + return _drv->getSupportTouchPoint(); +} + +bool TouchDrvCSTXXX::getResolution(int16_t *x, int16_t *y) +{ + if (!_drv)return false; + return _drv->getResolution(x, y); +} + +void TouchDrvCSTXXX::setCenterButtonCoordinate(uint16_t x, uint16_t y) +{ + if (!_drv)return ; + const char *model = _drv->getModelName(); + if (strncmp(model, "CST8", 3) == 0) { + TouchDrvCST816 *pT = static_cast(_drv.get()); + pT->setCenterButtonCoordinate(x, y); + } +} + +void TouchDrvCSTXXX::setHomeButtonCallback(TouchDrvInterface::HomeButtonCallback callback, void *user_data) +{ + if (!_drv)return ; + const char *model = _drv->getModelName(); + if (strncmp(model, "CST8", 3) == 0) { + TouchDrvCST816 *pT = static_cast(_drv.get()); + pT->setHomeButtonCallback(callback, user_data); + + } else if (strncmp(model, "CST2", 3) == 0) { + TouchDrvCST226 *pT = static_cast(_drv.get()); + pT->setHomeButtonCallback(callback, user_data); + } +} + +void TouchDrvCSTXXX::disableAutoSleep() +{ + if (!_drv)return ; + const char *model = _drv->getModelName(); + if (strncmp(model, "CST8", 3) == 0) { + TouchDrvCST816 *pT = static_cast(_drv.get()); + pT->disableAutoSleep(); + } +} + +void TouchDrvCSTXXX::enableAutoSleep() +{ + if (!_drv)return ; + const char *model = _drv->getModelName(); + if (strncmp(model, "CST8", 3) == 0) { + TouchDrvCST816 *pT = static_cast(_drv.get()); + pT->enableAutoSleep(); + } +} + +void TouchDrvCSTXXX::setSwapXY(bool swap) +{ + if (!_drv)return ; + _drv->setSwapXY(swap); +} + +void TouchDrvCSTXXX::setMirrorXY(bool mirrorX, bool mirrorY) +{ + if (!_drv)return ; + _drv->setMirrorXY(mirrorX, mirrorY); +} + +void TouchDrvCSTXXX::setMaxCoordinates(uint16_t x, uint16_t y) +{ + if (!_drv)return ; + _drv->setMaxCoordinates(x, y); +} + diff --git a/src/TouchDrvCSTXXX.hpp b/src/TouchDrvCSTXXX.hpp index 3c46e4d..dfb8457 100644 --- a/src/TouchDrvCSTXXX.hpp +++ b/src/TouchDrvCSTXXX.hpp @@ -22,19 +22,20 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. * - * @file TouchDrvCSTXXX.tpp + * @file TouchDrvCSTXXX.hpp * @author Lewis He (lewishe@outlook.com) * @date 2023-04-24 - * @date last 2023-10-05 + * @date last 2025-01-20 * */ #pragma once -#include "REG/CSTxxxConstants.h" -#include "touch/TouchClassCST226.h" -#include "touch/TouchClassCST816.h" +#include "touch/TouchDrvCST226.h" +#include "touch/TouchDrvCST816.h" #include "touch/TouchDrvCST92xx.h" -#include "SensorCommon.tpp" + +#define CSTXXX_SLAVE_ADDRESS (0x15) +#define CST328_SLAVE_ADDRESS (0x1A) enum TouchDrvType { TouchDrv_UNKOWN, @@ -43,440 +44,108 @@ enum TouchDrvType { TouchDrv_CST92XX, }; -#if defined(ARDUINO) -template -CST_TouchClass *newTouchClassArduino(PLATFORM_WIRE_TYPE &wire, - uint8_t address, - int sda, - int scl, - int rst, - int irq, - gpio_write_fptr_t set_level_ptr, - gpio_read_fptr_t get_level_ptr, - gpio_mode_fptr_t set_mode_ptr - ) -{ - CST_TouchClass *ptr = new CST_TouchClass(); - ptr->setGpioCallback(set_mode_ptr, set_level_ptr, get_level_ptr); - ptr->setPins(rst, irq); - if (!ptr->begin(wire, address, sda, scl)) { - delete ptr; - ptr = NULL; - } - return ptr; -} - -#elif defined(ESP_PLATFORM) - -#if ((ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL(5,0,0)) && defined(CONFIG_SENSORLIB_ESP_IDF_NEW_API)) - -template -CST_TouchClass *newTouchClassIDF(i2c_master_bus_handle_t i2c_dev_bus_handle, - uint8_t addr, - int rst, - int irq, - gpio_write_fptr_t set_level_ptr, - gpio_read_fptr_t get_level_ptr, - gpio_mode_fptr_t set_mode_ptr) -{ - CST_TouchClass *ptr = new CST_TouchClass(); - ptr->setGpioCallback(set_mode_ptr, set_level_ptr, get_level_ptr); - ptr->setPins(rst, irq); - if (!ptr->begin(i2c_dev_bus_handle, addr)) { - delete ptr; - ptr = NULL; - } - return ptr; -} - -#else /*ESP_IDF_VERSION*/ - -template -CST_TouchClass *newTouchClassIDF(i2c_port_t port_num, - uint8_t addr, - int sda, - int scl, - int rst, - int irq, - gpio_write_fptr_t set_level_ptr, - gpio_read_fptr_t get_level_ptr, - gpio_mode_fptr_t set_mode_ptr) -{ - CST_TouchClass *ptr = new CST_TouchClass(); - ptr->setGpioCallback(set_mode_ptr, set_level_ptr, get_level_ptr); - ptr->setPins(rst, irq); - if (!ptr->begin(port_num, addr, sda, scl)) { - delete ptr; - ptr = NULL; - } - return ptr; -} - -#endif /*ESP_IDF_VERSION*/ -#endif /*ESP_PLATFORM*/ - -template -CST_TouchClass *newTouchClassCallFunction(uint8_t address, - iic_fptr_t readRegCallback, - iic_fptr_t writeRegCallback, - int rst, - int irq, - gpio_write_fptr_t set_level_ptr, - gpio_read_fptr_t get_level_ptr, - gpio_mode_fptr_t set_mode_ptr) -{ - CST_TouchClass *ptr = new CST_TouchClass(); - ptr->setGpioCallback(set_mode_ptr, set_level_ptr, get_level_ptr); - ptr->setPins(rst, irq); - if (!ptr->begin(address, readRegCallback, writeRegCallback)) { - delete ptr; - ptr = NULL; - } - return ptr; -} - - - - class TouchDrvCSTXXX : public TouchDrvInterface { public: - TouchDrvCSTXXX(): drv(NULL), __touch_type(TouchDrv_UNKOWN) - { - } + TouchDrvCSTXXX(); - ~TouchDrvCSTXXX() - { - if (drv) { - delete drv; - drv = NULL; - } - } + ~TouchDrvCSTXXX(); - void setTouchDrvModel(TouchDrvType model) - { - __touch_type = model; - } + // Set the touch screen model. If not set, the default is to read + // the touch screen version information to determine which screen it is. + void setTouchDrvModel(TouchDrvType model); #if defined(ARDUINO) - bool begin(PLATFORM_WIRE_TYPE &wire, - uint8_t address, - int sda, - int scl) - { - if (__touch_type == TouchDrv_UNKOWN) { - drv = newTouchClassArduino(wire, address, sda, scl, __rst, __irq, - __set_gpio_level, __get_gpio_level, - __set_gpio_mode); - if (drv) { - __touch_type = TouchDrv_CST8XX; - return true; - } - drv = newTouchClassArduino(wire, address, sda, scl, __rst, __irq, - __set_gpio_level, __get_gpio_level, - __set_gpio_mode); - if (drv) { - __touch_type = TouchDrv_CST226; - return true; - } - drv = newTouchClassArduino(wire, address, sda, scl, __rst, __irq, - __set_gpio_level, __get_gpio_level, - __set_gpio_mode); - if (drv) { - __touch_type = TouchDrv_CST92XX; - return true; - } - } else if (__touch_type == TouchDrv_CST8XX) { - drv = newTouchClassArduino(wire, address, sda, scl, __rst, __irq, - __set_gpio_level, __get_gpio_level, - __set_gpio_mode); - } else if (__touch_type == TouchDrv_CST226) { - drv = newTouchClassArduino(wire, address, sda, scl, __rst, __irq, - __set_gpio_level, __get_gpio_level, - __set_gpio_mode); - } else if (__touch_type == TouchDrv_CST92XX) { - drv = newTouchClassArduino(wire, address, sda, scl, __rst, __irq, - __set_gpio_level, __get_gpio_level, - __set_gpio_mode); - } - if (!drv) { - __touch_type = TouchDrv_UNKOWN; - return false; - } - return drv != NULL; - } + bool begin(TwoWire &wire, uint8_t addr, int sda, int scl)override; #elif defined(ESP_PLATFORM) -#if ((ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL(5,0,0)) && defined(CONFIG_SENSORLIB_ESP_IDF_NEW_API)) - bool begin(i2c_master_bus_handle_t i2c_dev_bus_handle, uint8_t addr) - { - if (__touch_type == TouchDrv_UNKOWN) { - drv = newTouchClassIDF(i2c_dev_bus_handle, addr, __rst, __irq, - __set_gpio_level, __get_gpio_level, - __set_gpio_mode); - if (drv) { - __touch_type = TouchDrv_CST8XX; - return true; - } - drv = newTouchClassIDF(i2c_dev_bus_handle, addr, __rst, __irq, - __set_gpio_level, __get_gpio_level, - __set_gpio_mode); - if (drv) { - __touch_type = TouchDrv_CST226; - return true; - } - drv = newTouchClassIDF(i2c_dev_bus_handle, addr, __rst, __irq, - __set_gpio_level, __get_gpio_level, - __set_gpio_mode); - if (drv) { - __touch_type = TouchDrv_CST92XX; - return true; - } - } else if (__touch_type == TouchDrv_CST8XX) { - drv = newTouchClassIDF(i2c_dev_bus_handle, addr, __rst, __irq, - __set_gpio_level, __get_gpio_level, - __set_gpio_mode); - } else if (__touch_type == TouchDrv_CST226) { - drv = newTouchClassIDF(i2c_dev_bus_handle, addr, __rst, __irq, - __set_gpio_level, __get_gpio_level, - __set_gpio_mode); - } else if (__touch_type == TouchDrv_CST92XX) { - drv = newTouchClassIDF(i2c_dev_bus_handle, addr, __rst, __irq, - __set_gpio_level, __get_gpio_level, - __set_gpio_mode); - } - if (!drv) { - __touch_type = TouchDrv_UNKOWN; - return false; - } - return drv != NULL; - } +#if defined(USEING_I2C_LEGACY) + bool begin(i2c_port_t port_num, uint8_t addr, int sda = -1, int scl = -1)override; #else - bool begin(i2c_port_t port_num, uint8_t addr, int sda, int scl) - { + bool begin(i2c_master_bus_handle_t handle, uint8_t addr)override; +#endif // ESP_PLATFORM +#endif // ARDUINO - if (__touch_type == TouchDrv_UNKOWN) { - drv = newTouchClassIDF(port_num, addr, sda, scl, __rst, __irq, - __set_gpio_level, __get_gpio_level, - __set_gpio_mode); - if (drv) { - __touch_type = TouchDrv_CST8XX; - return true; - } - drv = newTouchClassIDF(port_num, addr, sda, scl, __rst, __irq, - __set_gpio_level, __get_gpio_level, - __set_gpio_mode); - if (drv) { - __touch_type = TouchDrv_CST226; - return true; - } - drv = newTouchClassIDF(port_num, addr, sda, scl, __rst, __irq, - __set_gpio_level, __get_gpio_level, - __set_gpio_mode); - if (drv) { - __touch_type = TouchDrv_CST92XX; - return true; - } - } else if (__touch_type == TouchDrv_CST8XX) { - drv = newTouchClassIDF(port_num, addr, sda, scl, __rst, __irq, - __set_gpio_level, __get_gpio_level, - __set_gpio_mode); - } else if (__touch_type == TouchDrv_CST226) { - drv = newTouchClassIDF(port_num, addr, sda, scl, __rst, __irq, - __set_gpio_level, __get_gpio_level, - __set_gpio_mode); - } else if (__touch_type == TouchDrv_CST92XX) { - drv = newTouchClassIDF(port_num, addr, sda, scl, __rst, __irq, - __set_gpio_level, __get_gpio_level, - __set_gpio_mode); - } - if (!drv) { - __touch_type = TouchDrv_UNKOWN; - return false; - } - return drv != NULL; - } -#endif //ESP_IDF_VERSION -#endif//ARDUINO + // Set the callback I2C read and write method and initialize the touch screen. + // If successful, return true, otherwise false + bool begin(SensorCommCustom::CustomCallback callback, + SensorCommCustomHal::CustomHalCallback hal_callback, + uint8_t addr) override; - void setGpioCallback(gpio_mode_fptr_t mode_cb, - gpio_write_fptr_t write_cb, - gpio_read_fptr_t read_cb) - { - __set_gpio_level = write_cb; - __get_gpio_level = read_cb; - __set_gpio_mode = mode_cb; - } + // Set other ways to control touch RST or INT + void setGpioCallback(SensorHalCustom::CustomMode mode_cb, + SensorHalCustom::CustomWrite write_cb, + SensorHalCustom::CustomRead read_cb) override; - bool begin(uint8_t address, iic_fptr_t readRegCallback, iic_fptr_t writeRegCallback) - { - if (__touch_type == TouchDrv_UNKOWN) { - drv = newTouchClassCallFunction(address, readRegCallback, writeRegCallback, __rst, __irq, - __set_gpio_level, __get_gpio_level, - __set_gpio_mode); - if (drv) { - __touch_type = TouchDrv_CST8XX; - return true; - } - drv = newTouchClassCallFunction(address, readRegCallback, writeRegCallback, __rst, __irq, - __set_gpio_level, __get_gpio_level, - __set_gpio_mode); - if (drv) { - __touch_type = TouchDrv_CST226; - return true; - } - drv = newTouchClassCallFunction(address, readRegCallback, writeRegCallback, __rst, __irq, - __set_gpio_level, __get_gpio_level, - __set_gpio_mode); - if (drv) { - __touch_type = TouchDrv_CST92XX; - return true; - } - } else if (__touch_type == TouchDrv_CST8XX) { - drv = newTouchClassCallFunction(address, readRegCallback, writeRegCallback, __rst, __irq, - __set_gpio_level, __get_gpio_level, - __set_gpio_mode); - } else if (__touch_type == TouchDrv_CST226) { - drv = newTouchClassCallFunction(address, readRegCallback, writeRegCallback, __rst, __irq, - __set_gpio_level, __get_gpio_level, - __set_gpio_mode); - } else if (__touch_type == TouchDrv_CST92XX) { - drv = newTouchClassCallFunction(address, readRegCallback, writeRegCallback, __rst, __irq, - __set_gpio_level, __get_gpio_level, - __set_gpio_mode); - } - if (!drv) { - __touch_type = TouchDrv_UNKOWN; - return false; - } - return drv != NULL; - } + // Reset Touch + void reset()override; + // Get the XY coordinates of the touch screen touch + uint8_t getPoint(int16_t *x_array, int16_t *y_array, uint8_t get_point = 1)override; - void reset() - { - if (!drv)return; - drv->reset(); - } + // Get whether the touch screen is pressed + bool isPressed()override; - uint8_t getPoint(int16_t *x_array, int16_t *y_array, uint8_t get_point = 1) - { - if (!drv)return 0; - return drv->getPoint(x_array, y_array, get_point); - } + // Get the touch screen model + const char *getModelName()override; - bool isPressed() - { - if (!drv)return false; - return drv->isPressed(); - } + // Set the touch screen to sleep mode + void sleep()override; - const char *getModelName() - { - if (!drv)return "NULL"; - return drv->getModelName(); - } + // Wake up the touch screen, depends on the RST Pin, if it is not connected, it will be invalid + void wakeup()override; - void sleep() - { - if (!drv)return; - drv->sleep(); - } + // Idle mode, this is not implemented, most of the CSTXXX series have automatic sleep function + void idle()override; - void wakeup() - { - if (!drv)return; - drv->reset(); - } + // Get the maximum number of touch points supported by the touch screen + uint8_t getSupportTouchPoint()override; - void idle() - { - if (!drv)return; - drv->idle(); - } + // Get touch screen resolution, not implemented + bool getResolution(int16_t *x, int16_t *y)override; - uint8_t getSupportTouchPoint() - { - if (!drv)return 0; - return drv->getSupportTouchPoint(); - } + // Set the screen touch button coordinates + void setCenterButtonCoordinate(uint16_t x, uint16_t y); - bool getResolution(int16_t *x, int16_t *y) - { - if (!drv)return false; - return drv->getResolution(x, y); - } + // Set screen touch button callback function + void setHomeButtonCallback(TouchDrvInterface::HomeButtonCallback callback, void *user_data = NULL); - void setCenterButtonCoordinate(uint16_t x, uint16_t y) - { - if (!drv)return ; - const char *model = drv->getModelName(); - if (strncmp(model, "CST8", 3) == 0) { - TouchClassCST816 *pT = static_cast(drv); - pT->setCenterButtonCoordinate(x, y); - } - } + // Disable automatic sleep, only for CST328 + void disableAutoSleep(); - void setHomeButtonCallback(home_button_callback_t callback, void *user_data = NULL) - { - if (!drv)return ; - const char *model = drv->getModelName(); - if (strncmp(model, "CST8", 3) == 0) { - TouchClassCST816 *pT = static_cast(drv); - pT->setHomeButtonCallback(callback, user_data); - // pT->setCenterButtonCoordinate(600, 120); // Only suitable for AMOLED 1.91 inch - - } if (strncmp(model, "CST2", 3) == 0) { - TouchClassCST226 *pT = static_cast(drv); - pT->setHomeButtonCallback(callback, user_data); - } - } + // Enable automatic sleep, only for CST328 + void enableAutoSleep(); - void disableAutoSleep() - { - if (!drv)return ; - const char *model = drv->getModelName(); - if (strncmp(model, "CST8", 3) == 0) { - TouchClassCST816 *pT = static_cast(drv); - pT->disableAutoSleep(); - } - } + // Swap XY coordinates + void setSwapXY(bool swap); - void enableAutoSleep() - { - if (!drv)return ; - const char *model = drv->getModelName(); - if (strncmp(model, "CST8", 3) == 0) { - TouchClassCST816 *pT = static_cast(drv); - pT->enableAutoSleep(); - } - } + // Mirror XY Coordinates + void setMirrorXY(bool mirrorX, bool mirrorY); - void setSwapXY(bool swap) - { - if (!drv)return ; - drv->setSwapXY(swap); - } + // Set the maximum X, Y coordinates of the screen + void setMaxCoordinates(uint16_t x, uint16_t y); - void setMirrorXY(bool mirrorX, bool mirrorY) - { - if (!drv)return ; - drv->setMirrorXY(mirrorX, mirrorY); - } +private: - void setMaxCoordinates(uint16_t x, uint16_t y) - { - if (!drv)return ; - drv->setMaxCoordinates(x, y); - } + using DriverCreator = std::unique_ptr (*)(); -private: - gpio_write_fptr_t __set_gpio_level = NULL; - gpio_read_fptr_t __get_gpio_level = NULL; - gpio_mode_fptr_t __set_gpio_mode = NULL; - TouchDrvInterface *drv = NULL; - TouchDrvType __touch_type; -}; + static constexpr uint8_t driverCreatorMaxNum = 3; + static DriverCreator driverCreators[driverCreatorMaxNum]; + std::unique_ptr createDriver(TouchDrvType type) + { + if (/*type >= TouchDrv_UNKOWN &&*/ + type < sizeof(driverCreators) / sizeof(driverCreators[0])) { + return driverCreators[type](); + } + return nullptr; + } + void setupDriver(); + SensorHalCustom::CustomWrite _writePtr; + SensorHalCustom::CustomRead _readPtr; + SensorHalCustom::CustomMode _modePtr; + TouchDrvType _touchType; + std::unique_ptr _drv; +}; diff --git a/src/TouchDrvFT6X36.hpp b/src/TouchDrvFT6X36.hpp index 866bd44..ba0e190 100644 --- a/src/TouchDrvFT6X36.hpp +++ b/src/TouchDrvFT6X36.hpp @@ -22,7 +22,7 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. * - * @file TouchDrvFT6X36.tpp + * @file TouchDrvFT6X36.hpp * @author Lewis He (lewishe@outlook.com) * @date 2023-04-01 * @@ -31,16 +31,10 @@ #include "REG/FT6X36Constants.h" #include "TouchDrvInterface.hpp" -#include "SensorCommon.tpp" -class TouchDrvFT6X36 : - public TouchDrvInterface, - public SensorCommon +class TouchDrvFT6X36 : public TouchDrvInterface { - friend class SensorCommon; public: - - enum GesTrue { NO_GESTURE, MOVE_UP, @@ -61,82 +55,70 @@ class TouchDrvFT6X36 : enum PowerMode { PMODE_ACTIVE = 0, // ~4mA PMODE_MONITOR = 1, // ~3mA - PMODE_DEEPSLEEP = 3, // ~100uA The reset pin must be pulled down to wake up + PMODE_DEEP_SLEEP = 3, // ~100uA The reset pin must be pulled down to wake up } ; EventFlag event; -#if defined(ARDUINO) - TouchDrvFT6X36(PLATFORM_WIRE_TYPE &w, int sda = DEFAULT_SDA, int scl = DEFAULT_SCL, uint8_t addr = FT6X36_SLAVE_ADDRESS) - { - __wire = &w; - __sda = sda; - __scl = scl; - __addr = addr; - } -#endif - - TouchDrvFT6X36() - { -#if defined(ARDUINO) - __wire = &Wire; - __sda = DEFAULT_SDA; - __scl = DEFAULT_SCL; -#endif - __addr = FT6X36_SLAVE_ADDRESS; - } + TouchDrvFT6X36() : comm(nullptr), hal(nullptr) {} ~TouchDrvFT6X36() { - deinit(); + if (comm) { + comm->deinit(); + } } #if defined(ARDUINO) - - bool begin(PLATFORM_WIRE_TYPE &w, - uint8_t addr = FT6X36_SLAVE_ADDRESS, - int sda = DEFAULT_SDA, - int scl = DEFAULT_SCL) + bool begin(TwoWire &wire, uint8_t addr = FT6X36_SLAVE_ADDRESS, int sda = -1, int scl = -1) { - return SensorCommon::begin(w, addr, sda, scl); + if (!beginCommon(comm, hal, wire, addr, sda, scl)) { + return false; + } + return initImpl(); } -#elif defined(ESP_PLATFORM) && !defined(ARDUINO) +#elif defined(ESP_PLATFORM) -#if ((ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL(5,0,0)) && defined(CONFIG_SENSORLIB_ESP_IDF_NEW_API)) - bool begin(i2c_master_bus_handle_t i2c_dev_bus_handle, uint8_t addr) +#if defined(USEING_I2C_LEGACY) + bool begin(i2c_port_t port_num, uint8_t addr = FT6X36_SLAVE_ADDRESS, int sda = -1, int scl = -1) { - return SensorCommon::begin(i2c_dev_bus_handle, addr); + if (!beginCommon(comm, hal, port_num, addr, sda, scl)) { + return false; + } + return initImpl(); } #else - bool begin(i2c_port_t port_num, uint8_t addr, int sda, int scl) + bool begin(i2c_master_bus_handle_t handle, uint8_t addr = FT6X36_SLAVE_ADDRESS) { - return SensorCommon::begin(port_num, addr, sda, scl); - } -#endif //ESP_IDF_VERSION - -#endif - - bool begin(uint8_t addr, iic_fptr_t readRegCallback, iic_fptr_t writeRegCallback) - { - return SensorCommon::begin(addr, readRegCallback, writeRegCallback); + if (!beginCommon(comm, hal, handle, addr)) { + return false; + } + return initImpl(); } +#endif //ESP_PLATFORM +#endif //ARDUINO - - void deinit() + bool begin(SensorCommCustom::CustomCallback callback, + SensorCommCustomHal::CustomHalCallback hal_callback, + uint8_t addr) { - // end(); + if (!beginCommCustomCallback(COMM_CUSTOM, + callback, hal_callback, addr, comm, hal)) { + return false; + } + return initImpl(); } uint8_t getDeviceMode(void) { - return readRegister(FT6X36_REG_MODE) & 0x03; + return comm->readRegister(FT6X36_REG_MODE) & 0x03; } // Obtaining gestures depends on whether the built-in firmware of the chip has this function uint8_t getGesture() { - int val = readRegister(FT6X36_REG_GEST); + int val = comm->readRegister(FT6X36_REG_GEST); switch (val) { case 0x10: return MOVE_UP; @@ -158,22 +140,22 @@ class TouchDrvFT6X36 : void setThreshold(uint8_t value) { - writeRegister(FT6X36_REG_THRESHOLD, value); + comm->writeRegister(FT6X36_REG_THRESHOLD, value); } uint8_t getThreshold(void) { - return readRegister(FT6X36_REG_THRESHOLD); + return comm->readRegister(FT6X36_REG_THRESHOLD); } uint8_t getMonitorTime(void) { - return readRegister(FT6X36_REG_MONITOR_TIME); + return comm->readRegister(FT6X36_REG_MONITOR_TIME); } void setMonitorTime(uint8_t sec) { - writeRegister(FT6X36_REG_MONITOR_TIME, sec); + comm->writeRegister(FT6X36_REG_MONITOR_TIME, sec); } // Calibration useless actually, @@ -182,19 +164,19 @@ class TouchDrvFT6X36 : /* void enableAutoCalibration(void) { - writeRegister(FT6X36_REG_AUTO_CLB_MODE, 0x00); + comm->writeRegister(FT6X36_REG_AUTO_CLB_MODE, 0x00); } void disableAutoCalibration(void) { - writeRegister(FT6X36_REG_AUTO_CLB_MODE, 0xFF); + comm->writeRegister(FT6X36_REG_AUTO_CLB_MODE, 0xFF); } */ uint16_t getLibraryVersion() { uint8_t buffer[2]; - readRegister(FT6X36_REG_LIB_VERSION_H, buffer, 2); + comm->readRegister(FT6X36_REG_LIB_VERSION_H, buffer, 2); return (buffer[0] << 8) | buffer[1]; } @@ -202,14 +184,14 @@ class TouchDrvFT6X36 : void interruptPolling(void) { //datasheet this bit is 0,Actually, it's wrong - writeRegister(FT6X36_REG_INT_STATUS, 1); + comm->writeRegister(FT6X36_REG_INT_STATUS, 1); } // Triggers an interrupt whenever a touch is detected void interruptTrigger(void) { //datasheet this bit is 1,Actually, it's wrong - writeRegister(FT6X36_REG_INT_STATUS, 0); + comm->writeRegister(FT6X36_REG_INT_STATUS, (uint8_t)0); } uint8_t getPoint(int16_t *x_array, int16_t *y_array, uint8_t size = 1) @@ -219,7 +201,7 @@ class TouchDrvFT6X36 : if (!x_array || !y_array || !size) return 0; - if (readRegister(FT6X36_REG_MODE, buffer, 16) == DEV_WIRE_ERR) { + if (comm->readRegister(FT6X36_REG_MODE, buffer, 16) == -1) { return 0; } @@ -227,8 +209,8 @@ class TouchDrvFT6X36 : //REG 0x01 // uint8_t gesture = buffer[1]; //REG 0x02 - uint8_t point = buffer[2] & 0x0F; - if (point == 0 || point == 0x0F) { + uint8_t numPoints = buffer[2] & 0x0F; + if (numPoints == 0 || numPoints == 0x0F) { return 0; } @@ -242,56 +224,38 @@ class TouchDrvFT6X36 : x_array[0] = posX; y_array[0] = posY; -#ifdef LOG_PORT - LOG_PORT.println("----------------------------------------------------------------------------"); - LOG_PORT.println("Touched Gesture EvenFlag [0]PosX [0]PosY [1]PosX [1]PosY"); - LOG_PORT.print(point); LOG_PORT.print("\t"); - // LOG_PORT.print(gesture); LOG_PORT.print("\t"); - // LOG_PORT.print(eventFlag); LOG_PORT.print("\t"); - LOG_PORT.print(posX); LOG_PORT.print("\t"); - LOG_PORT.print(posY); LOG_PORT.print("\t"); -#endif - - if (point == 2) { + if (numPoints == 2) { //REG 0x09 ~ 0x0A posX = ((buffer[9] & 0x0F) << 8) | buffer[10]; //REG 0x0B ~ 0x0C posY = ((buffer[11] & 0x0F) << 8) | buffer[12] ; -#ifdef LOG_PORT - LOG_PORT.print(posX); LOG_PORT.print("\t"); - LOG_PORT.print(posY); LOG_PORT.print("\t"); -#endif - if (size == 2) { x_array[1] = posX; y_array[1] = posY; } } -#ifdef LOG_PORT - LOG_PORT.println(); -#endif - updateXY(point, x_array, y_array); + updateXY(numPoints, x_array, y_array); - return point; + return numPoints; } bool isPressed() { - if (__irq != SENSOR_PIN_NONE) { - return this->getGpioLevel(__irq) == LOW; + if (_irq != -1) { + return hal->digitalRead(_irq) == LOW; } - return readRegister(FT6X36_REG_STATUS) & 0x0F; + return comm->readRegister(FT6X36_REG_STATUS) & 0x0F; } void setPowerMode(PowerMode mode) { - writeRegister(FT6X36_REG_POWER_MODE, mode); + comm->writeRegister(FT6X36_REG_POWER_MODE, mode); } void sleep() { - writeRegister(FT6X36_REG_POWER_MODE, PMODE_DEEPSLEEP); + comm->writeRegister(FT6X36_REG_POWER_MODE, PMODE_DEEP_SLEEP); } void wakeup() @@ -311,22 +275,22 @@ class TouchDrvFT6X36 : uint32_t getChipID(void) { - return readRegister(FT6X36_REG_CHIP_ID); + return comm->readRegister(FT6X36_REG_CHIP_ID); } uint8_t getVendorID(void) { - return readRegister(FT6X36_REG_VENDOR1_ID); + return comm->readRegister(FT6X36_REG_VENDOR1_ID); } uint8_t getErrorCode(void) { - return readRegister(FT6X36_REG_ERROR_STATUS); + return comm->readRegister(FT6X36_REG_ERROR_STATUS); } const char *getModelName() { - switch (__chipID) { + switch (_chipID) { case FT6206_CHIP_ID: return "FT6206"; case FT6236_CHIP_ID: return "FT6236"; case FT6236U_CHIP_ID: return "FT6236U"; @@ -343,39 +307,39 @@ class TouchDrvFT6X36 : void reset() { - if (__rst != SENSOR_PIN_NONE) { - this->setGpioMode(__rst, OUTPUT); - this->setGpioLevel(__rst, HIGH); - delay(10); - this->setGpioLevel(__rst, LOW); - delay(30); - this->setGpioLevel(__rst, HIGH); + if (_rst != -1) { + hal->pinMode(_rst, OUTPUT); + hal->digitalWrite(_rst, HIGH); + hal->delay(10); + hal->digitalWrite(_rst, LOW); + hal->delay(30); + hal->digitalWrite(_rst, HIGH); // For the variant of GPIO extended RST, - // communication and delay are carried out simultaneously, and 160ms is measured in T-RGB esp-idf new api - delay(160); + // communication and hal->delay are carried out simultaneously, and 160ms is measured in T-RGB esp-idf new api + hal->delay(160); } } - void setGpioCallback(gpio_mode_fptr_t mode_cb, - gpio_write_fptr_t write_cb, - gpio_read_fptr_t read_cb) + void setGpioCallback(CustomMode mode_cb, + CustomWrite write_cb, + CustomRead read_cb) { - SensorCommon::setGpioModeCallback(mode_cb); - SensorCommon::setGpioWriteCallback(write_cb); - SensorCommon::setGpioReadCallback(read_cb); + SensorHalCustom::setCustomMode(mode_cb); + SensorHalCustom::setCustomWrite(write_cb); + SensorHalCustom::setCustomRead(read_cb); } private: bool initImpl() { - if (__irq != SENSOR_PIN_NONE) { - this->setGpioMode(__irq, INPUT); + if (_irq != -1) { + hal->pinMode(_irq, INPUT); } reset(); - uint8_t vendId = readRegister(FT6X36_REG_VENDOR1_ID); + uint8_t vendId = comm->readRegister(FT6X36_REG_VENDOR1_ID); if (vendId != FT6X36_VEND_ID) { @@ -383,31 +347,31 @@ class TouchDrvFT6X36 : return false; } - __chipID = readRegister(FT6X36_REG_CHIP_ID); + _chipID = comm->readRegister(FT6X36_REG_CHIP_ID); - if ((__chipID != FT6206_CHIP_ID) && - (__chipID != FT6236_CHIP_ID) && - (__chipID != FT6236U_CHIP_ID) && - (__chipID != FT3267_CHIP_ID) + if ((_chipID != FT6206_CHIP_ID) && + (_chipID != FT6236_CHIP_ID) && + (_chipID != FT6236U_CHIP_ID) && + (_chipID != FT3267_CHIP_ID) ) { log_e("Vendor id is not match!"); - log_e("ChipID:0x%lx should be 0x06 or 0x36 or 0x64", __chipID); + log_e("ChipID:0x%lx should be 0x06 or 0x36 or 0x64", _chipID); return false; } log_i("Vend ID: 0x%X", vendId); - log_i("Chip ID: 0x%lx", __chipID); - log_i("Firm Version: 0x%X", readRegister(FT6X36_REG_FIRM_VERS)); - log_i("Point Rate Hz: %u", readRegister(FT6X36_REG_PERIOD_ACTIVE)); - log_i("Thresh : %u", readRegister(FT6X36_REG_THRESHOLD)); + log_i("Chip ID: 0x%lx", _chipID); + log_i("Firm Version: 0x%X", comm->readRegister(FT6X36_REG_FIRM_VERS)); + log_i("Point Rate Hz: %u", comm->readRegister(FT6X36_REG_PERIOD_ACTIVE)); + log_i("Thresh : %u", comm->readRegister(FT6X36_REG_THRESHOLD)); // change threshold to be higher/lower - writeRegister(FT6X36_REG_THRESHOLD, 60); + comm->writeRegister(FT6X36_REG_THRESHOLD, 60); log_i("Chip library version : 0x%x", getLibraryVersion()); // This register describes period of monitor status, it should not less than 30. - log_i("Chip period of monitor status : 0x%x", readRegister(FT6X36_REG_PERIOD_MONITOR)); + log_i("Chip period of monitor status : 0x%x", comm->readRegister(FT6X36_REG_PERIOD_MONITOR)); // This register describes the period of active status, it should not less than 12 @@ -415,11 +379,9 @@ class TouchDrvFT6X36 : return true; } - int getReadMaskImpl() - { - return -1; - } - +protected: + std::unique_ptr comm; + std::unique_ptr hal; }; diff --git a/src/TouchDrvGT911.hpp b/src/TouchDrvGT911.hpp index dc349f6..55a3367 100644 --- a/src/TouchDrvGT911.hpp +++ b/src/TouchDrvGT911.hpp @@ -22,7 +22,7 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. * - * @file TouchDrvGT911.tpp + * @file TouchDrvGT911.hpp * @author Lewis He (lewishe@outlook.com) * @date 2023-04-12 * @@ -31,112 +31,87 @@ #include "REG/GT911Constants.h" #include "TouchDrvInterface.hpp" -#include "SensorCommon.tpp" - #if defined(ARDUINO_ARCH_NRF52) // NRF52840 I2C BUFFER : 64 Bytes , #warning "NRF Platform I2C Buffer expansion is not implemented , GT911 requires at least 188 bytes to read all configurations" #endif -typedef struct GT911_Struct { - uint8_t trackID; - int16_t x; - int16_t y; - int16_t size; -} GT911Point_t; - - -#define LOW_LEVEL_QUERY 0x03 -#define HIGH_LEVEL_QUERY 0x04 +#define GT911_GET_POINT(x) (x & 0x0F) +#define GT911_GET_BUFFER_STATUS(x) (x & 0x80) +#define GT911_GET_HAVE_KEY(x) (x & 0x10) -class TouchDrvGT911 : - public TouchDrvInterface, - public SensorCommon +class TouchDrvGT911 : public TouchDrvInterface, public GT911Constants { - friend class SensorCommon; -public: - + typedef struct { + uint8_t trackID; + int16_t x; + int16_t y; + int16_t size; + } PointReg; -#if defined(ARDUINO) - TouchDrvGT911(PLATFORM_WIRE_TYPE &w, - int sda = DEFAULT_SDA, - int scl = DEFAULT_SCL, - uint8_t addr = GT911_SLAVE_ADDRESS_H) - { - __wire = &w; - __sda = sda; - __scl = scl; - __rst = SENSOR_PIN_NONE; - __irq = SENSOR_PIN_NONE; - __addr = addr; - } -#endif +public: - TouchDrvGT911() - { -#if defined(ARDUINO) - __wire = &Wire; - __sda = DEFAULT_SDA; - __scl = DEFAULT_SCL; -#endif - __rst = SENSOR_PIN_NONE; - __irq = SENSOR_PIN_NONE; - __addr = GT911_SLAVE_ADDRESS_H; - } + TouchDrvGT911() : comm(nullptr), hal(nullptr) {} ~TouchDrvGT911() { - deinit(); + if (comm) { + comm->deinit(); + } } #if defined(ARDUINO) - bool begin(PLATFORM_WIRE_TYPE &w, - uint8_t addr = GT911_SLAVE_ADDRESS_H, - int sda = DEFAULT_SDA, - int scl = DEFAULT_SCL - ) + bool begin(TwoWire &wire, uint8_t addr = GT911_SLAVE_ADDRESS_H, int sda = -1, int scl = -1) { - return SensorCommon::begin(w, addr, sda, scl); + if (!beginCommon(comm, hal, wire, addr, sda, scl)) { + return false; + } + return initImpl(addr); } -#elif defined(ESP_PLATFORM) && !defined(ARDUINO) +#elif defined(ESP_PLATFORM) -#if ((ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL(5,0,0)) && defined(CONFIG_SENSORLIB_ESP_IDF_NEW_API)) - bool begin(i2c_master_bus_handle_t i2c_dev_bus_handle, uint8_t addr) +#if defined(USEING_I2C_LEGACY) + bool begin(i2c_port_t port_num, uint8_t addr = GT911_SLAVE_ADDRESS_H, int sda = -1, int scl = -1) { - return SensorCommon::begin(i2c_dev_bus_handle, addr); + if (!beginCommon(comm, hal, port_num, addr, sda, scl)) { + return false; + } + return initImpl(addr); } #else - bool begin(i2c_port_t port_num, uint8_t addr, int sda, int scl) + bool begin(i2c_master_bus_handle_t handle, uint8_t addr = GT911_SLAVE_ADDRESS_H) { - return SensorCommon::begin(port_num, addr, sda, scl); - } -#endif //ESP_IDF_VERSION - -#endif - - bool begin(uint8_t addr, iic_fptr_t readRegCallback, iic_fptr_t writeRegCallback) - { - return SensorCommon::begin(addr, readRegCallback, writeRegCallback); + if (!beginCommon(comm, hal, handle, addr)) { + return false; + } + return initImpl(addr); } +#endif //ESP_PLATFORM +#endif //ARDUINO - void deinit() + bool begin(SensorCommCustom::CustomCallback callback, + SensorCommCustomHal::CustomHalCallback hal_callback, + uint8_t addr) { - // end(); + if (!beginCommCustomCallback(COMM_CUSTOM, + callback, hal_callback, addr, comm, hal)) { + return false; + } + return initImpl(addr); } - void reset() { - if (__rst != SENSOR_PIN_NONE) { - this->setGpioMode(__rst, OUTPUT); - this->setGpioLevel(__rst, HIGH); - delay(10); + if (_rst != -1) { + hal->pinMode(_rst, OUTPUT); + hal->digitalWrite(_rst, HIGH); + hal->delay(10); } - if (__irq != SENSOR_PIN_NONE) { - this->setGpioMode(__irq, INPUT); + if (_irq != -1) { + hal->pinMode(_irq, INPUT); } /* * If you perform a software reset on a board without a reset pin connected, @@ -144,17 +119,17 @@ class TouchDrvGT911 : * For example, when debugging a LilyGo T-Deck, resetting the interrupt mode will * be invalid after a software reset. * */ - // writeRegister(GT911_COMMAND, 0x02); + // comm->writeRegister(GT911_COMMAND, 0x02); // writeCommand(0x02); } void sleep() { - if (__irq != SENSOR_PIN_NONE) { - this->setGpioMode(__irq, OUTPUT); - this->setGpioLevel(__irq, LOW); + if (_irq != -1) { + hal->pinMode(_irq, OUTPUT); + hal->digitalWrite(_irq, LOW); } - // writeRegister(GT911_COMMAND, 0x05); + // comm->writeRegister(GT911_COMMAND, 0x05); writeCommand(0x05); /* @@ -162,8 +137,8 @@ class TouchDrvGT911 : * The chip platform determines whether * * * */ - // if (__irq != SENSOR_PIN_NONE) { - // this->setGpioLevel(__irq, INPUT); + // if (_irq != -1) { + // hal->digitalWrite(_irq, INPUT); // } } @@ -171,11 +146,11 @@ class TouchDrvGT911 : void wakeup() { - if (__irq != SENSOR_PIN_NONE) { - this->setGpioMode(__irq, OUTPUT); - this->setGpioLevel(__irq, HIGH); - delay(8); - this->setGpioMode(__irq, INPUT); + if (_irq != -1) { + hal->pinMode(_irq, OUTPUT); + hal->digitalWrite(_irq, HIGH); + hal->delay(8); + hal->pinMode(_irq, INPUT); } else { reset(); } @@ -195,7 +170,7 @@ class TouchDrvGT911 : { uint8_t buffer[39]; uint8_t touchPoint = 0; - GT911Point_t p[5]; + PointReg p[5]; if (!x_array || !y_array || size == 0) return 0; @@ -206,8 +181,8 @@ class TouchDrvGT911 : // bool bufferStatus = GT911_GET_BUFFER_STATUS(val); // log_i("REG:0x%X S:0X%d K:%d\n", val,bufferStatus,haveKey); - if (__homeButtonCb && haveKey) { - __homeButtonCb(__userData); + if (_HButtonCallback && haveKey) { + _HButtonCallback(_userData); } clearBuffer(); @@ -219,8 +194,8 @@ class TouchDrvGT911 : // GT911_POINT_1 0X814F uint8_t write_buffer[2] = {0x81, 0x4F}; - if (writeThenRead(write_buffer, SENSORLIB_COUNT(write_buffer), - buffer, 39) == DEV_WIRE_ERR) { + if (comm->writeThenRead(write_buffer, arraySize(write_buffer), + buffer, 39) == -1) { return 0; } @@ -237,19 +212,6 @@ class TouchDrvGT911 : y_array[i] = p[i].y; } -#ifdef LOG_PORT - LOG_PORT.println("---------------------------------------------------------------------------------------------------------------------------------------------------------------------------"); - LOG_PORT.println("Touched [0]ID [0]Size [0]X [0]Y [1]ID [1]Size [1]X [1]Y [2]ID [2]Size [2]X [2]Y [3]ID [3]Size [3]X [3]Y [4]ID [4]Size [4]X [4]Y "); - LOG_PORT.print(touchPoint); LOG_PORT.print("\t"); - for (int i = 0; i < size; ++i) { - LOG_PORT.print(p[i].trackID); LOG_PORT.print("\t"); - LOG_PORT.print(p[i].size); LOG_PORT.print("\t"); - LOG_PORT.print( p[i].x); LOG_PORT.print("\t"); - LOG_PORT.print( p[i].y); LOG_PORT.print("\t"); - } - LOG_PORT.println(); -#endif - updateXY(touchPoint, x_array, y_array); return touchPoint; @@ -258,15 +220,15 @@ class TouchDrvGT911 : bool isPressed() { - if (__irq != SENSOR_PIN_NONE) { - if (__irq_mode == FALLING) { - return this->getGpioLevel(__irq) == LOW; - } else if (__irq_mode == RISING ) { - return this->getGpioLevel(__irq) == HIGH; - } else if (__irq_mode == LOW_LEVEL_QUERY) { - return this->getGpioLevel(__irq) == LOW; - } else if (__irq_mode == HIGH_LEVEL_QUERY) { - return this->getGpioLevel(__irq) == HIGH; + if (_irq != -1) { + if (_irq_mode == FALLING) { + return hal->digitalRead(_irq) == LOW; + } else if (_irq_mode == RISING ) { + return hal->digitalRead(_irq) == HIGH; + } else if (_irq_mode == LOW_LEVEL_QUERY) { + return hal->digitalRead(_irq) == LOW; + } else if (_irq_mode == HIGH_LEVEL_QUERY) { + return hal->digitalRead(_irq) == HIGH; } } return getPoint(); @@ -286,7 +248,7 @@ class TouchDrvGT911 : } else if (mode == HIGH_LEVEL_QUERY ) { val |= 0x03; } - __irq_mode = mode; + _irq_mode = mode; writeGT911(GT911_MODULE_SWITCH_1, val); return reloadConfig(); } @@ -304,13 +266,13 @@ class TouchDrvGT911 : // return val & 0x03; val &= 0x03; if (val == 0x00) { - __irq_mode = RISING; + _irq_mode = RISING; } else if (val == 0x01) { - __irq_mode = FALLING; + _irq_mode = FALLING; } else if (val == 0x02) { - __irq_mode = LOW_LEVEL_QUERY; + _irq_mode = LOW_LEVEL_QUERY; } else if (val == 0x03) { - __irq_mode = HIGH_LEVEL_QUERY; + _irq_mode = HIGH_LEVEL_QUERY; } return val; } @@ -399,24 +361,24 @@ class TouchDrvGT911 : return "GT911"; } - void setGpioCallback(gpio_mode_fptr_t mode_cb, - gpio_write_fptr_t write_cb, - gpio_read_fptr_t read_cb) + void setGpioCallback(CustomMode mode_cb, + CustomWrite write_cb, + CustomRead read_cb) { - SensorCommon::setGpioModeCallback(mode_cb); - SensorCommon::setGpioWriteCallback(write_cb); - SensorCommon::setGpioReadCallback(read_cb); + SensorHalCustom::setCustomMode(mode_cb); + SensorHalCustom::setCustomWrite(write_cb); + SensorHalCustom::setCustomRead(read_cb); } - void setHomeButtonCallback(home_button_callback_t cb, void *user_data) + void setHomeButtonCallback(HomeButtonCallback cb, void *user_data) { - __homeButtonCb = cb; - __userData = user_data; + _HButtonCallback = cb; + _userData = user_data; } bool writeConfig(const uint8_t *config_buffer, size_t buffer_size) { - setRegAddressLength(2); +#if 0 //TODO: uint8_t check_sum = 0; for (int i = 0; i < (GT911_REG_LENGTH - 2 ); i++) { check_sum += config_buffer[i]; @@ -427,16 +389,19 @@ class TouchDrvGT911 : return false; } log_d("Update touch config , write %lu Bytes check sum:0x%X", buffer_size, check_sum); - int err = writeRegister(GT911_CONFIG_VERSION, (uint8_t *)config_buffer, buffer_size); - setRegAddressLength(1); + uint8_t cmd[] = {lowByte(GT911_CONFIG_VERSION), highByte(GT911_CONFIG_VERSION)}; + int err = comm->writeRegister(GT911_CONFIG_VERSION, (uint8_t *)config_buffer, buffer_size); + #if 0 - while (digitalRead(__irq)) { - log_i("Wait irq.."); delay(500); + while (digitalRead(_irq)) { + log_i("Wait irq.."); hal->delay(500); } - int err = writeBuffer((uint8_t *)config_buffer, buffer_size); + int err = comm->writeBuffer((uint8_t *)config_buffer, buffer_size); +#endif + return err == 0; #endif - return err == DEV_WIRE_NONE; + return false; } uint8_t *loadConfig(size_t *output_size, bool print_out = false) @@ -445,7 +410,7 @@ class TouchDrvGT911 : uint8_t *buffer = (uint8_t * )malloc(GT911_REG_LENGTH * sizeof(uint8_t)); if (!buffer)return NULL; uint8_t write_buffer[2] = {highByte(GT911_CONFIG_VERSION), lowByte(GT911_CONFIG_VERSION)}; - if (writeThenRead(write_buffer, SENSORLIB_COUNT(write_buffer), buffer, GT911_REG_LENGTH) == DEV_WIRE_ERR) { + if (comm->writeThenRead(write_buffer, arraySize(write_buffer), buffer, GT911_REG_LENGTH) == -1) { free(buffer); return NULL; } @@ -469,7 +434,7 @@ class TouchDrvGT911 : bool reloadConfig() { uint8_t buffer[GT911_REG_LENGTH] = {highByte(GT911_CONFIG_VERSION), lowByte(GT911_CONFIG_VERSION)}; - if (writeThenRead(buffer, 2, buffer, GT911_REG_LENGTH - 2) == DEV_WIRE_ERR) { + if (comm->writeThenRead(buffer, 2, buffer, GT911_REG_LENGTH - 2) == -1) { return false; } @@ -517,8 +482,8 @@ class TouchDrvGT911 : void setConfigData(uint8_t *data, uint16_t length) { - __config = data; - __config_size = length; + _config = data; + _config_size = length; } private: @@ -527,15 +492,15 @@ class TouchDrvGT911 : { uint8_t value = 0x00; uint8_t write_buffer[2] = {highByte(cmd), lowByte(cmd)}; - writeThenRead(write_buffer, SENSORLIB_COUNT(write_buffer), - &value, 1); + comm->writeThenRead(write_buffer, arraySize(write_buffer), + &value, 1); return value; } int writeGT911(uint16_t cmd, uint8_t value) { uint8_t write_buffer[3] = {highByte(cmd), lowByte(cmd), value}; - return writeBuffer(write_buffer, SENSORLIB_COUNT(write_buffer)); + return comm->writeBuffer(write_buffer, arraySize(write_buffer)); } @@ -543,7 +508,7 @@ class TouchDrvGT911 : { // GT911_COMMAND 0x8040 uint8_t write_buffer[3] = {0x80, 0x40, command}; - writeBuffer(write_buffer, SENSORLIB_COUNT(write_buffer)); + comm->writeBuffer(write_buffer, arraySize(write_buffer)); } void inline clearBuffer() @@ -554,132 +519,122 @@ class TouchDrvGT911 : bool probeAddress() { const uint8_t device_address[2] = {GT911_SLAVE_ADDRESS_L, GT911_SLAVE_ADDRESS_H}; - for (size_t i = 0; i < SENSORLIB_COUNT(device_address); ++i) { - __addr = device_address[i]; + for (size_t i = 0; i < arraySize(device_address); ++i) { + I2CParam params(I2CParam::I2C_SET_ADDR, device_address[i]); + comm->setParams(params); for (int retry = 0; retry < 3; ++retry) { - if (getChipID() == GT911_DEV_ID) { + _chipID = getChipID(); + if (_chipID == GT911_DEV_ID) { + log_i("Touch device address found is : 0x%X", device_address[i]); return true; } } } + log_e("GT911 not found, touch device 7-bit address should be 0x5D or 0x14"); return false; } - bool initImpl() + bool initImpl(uint8_t addr) { int16_t x = 0, y = 0; - if (__rst == SENSOR_PIN_NONE || __irq == SENSOR_PIN_NONE) { - - if (__rst != SENSOR_PIN_NONE) { - this->setGpioMode(__rst, OUTPUT); - this->setGpioLevel(__rst, HIGH); - delay(10); - } + if (addr == GT911_SLAVE_ADDRESS_H && _rst != -1 && _irq != -1) { - // Automatically determine the current device - // address when using the reset pin without connection - log_d("Probe address ...."); - if (!probeAddress()) { - return false; - } - log_d("Probe address is : 0x%X", __addr); - - // Reset Config - reset(); + log_i("Try using 0x14 as the device address"); - this->setGpioMode(__irq, INPUT); + hal->pinMode(_rst, OUTPUT); + hal->pinMode(_irq, OUTPUT); - } else if (__addr == GT911_SLAVE_ADDRESS_H && - __rst != SENSOR_PIN_NONE && - __irq != SENSOR_PIN_NONE) { - - log_i("GT911 using 0x28 address!"); - - this->setGpioMode(__rst, OUTPUT); - this->setGpioMode(__irq, OUTPUT); - - this->setGpioLevel(__rst, LOW); - this->setGpioLevel(__irq, HIGH); - delayMicroseconds(120); - this->setGpioLevel(__rst, HIGH); + hal->digitalWrite(_rst, LOW); + hal->digitalWrite(_irq, HIGH); + hal->delayMicroseconds(120); + hal->digitalWrite(_rst, HIGH); #if defined(ARDUINO) - // In the Arduino ESP32 platform, the test delay is 8ms and the GT911 + // In the Arduino ESP32 platform, the test delay is 8ms and the GT911 // can be accessed correctly. If the time is too long, it will not be accessible. - delay(8); + hal->delay(8); #elif defined(ESP_PLATFORM) // For the variant of GPIO extended RST, // communication and delay are carried out simultaneously, and 18 ms is measured in T-RGB esp-idf new api - delay(18); + hal->delay(18); #endif - - this->setGpioMode(__irq, INPUT); - } else if (__addr == GT911_SLAVE_ADDRESS_L && - __rst != SENSOR_PIN_NONE && - __irq != SENSOR_PIN_NONE) { + hal->pinMode(_irq, INPUT); + } else if (addr == GT911_SLAVE_ADDRESS_L && _rst != -1 && _irq != -1) { - log_i("GT911 using 0xBA address!"); + log_i("Try using 0x5D as the device address"); - this->setGpioMode(__rst, OUTPUT); - this->setGpioMode(__irq, OUTPUT); + hal->pinMode(_rst, OUTPUT); + hal->pinMode(_irq, OUTPUT); - this->setGpioLevel(__rst, LOW); - this->setGpioLevel(__irq, LOW); - delayMicroseconds(120); - this->setGpioLevel(__rst, HIGH); + hal->digitalWrite(_rst, LOW); + hal->digitalWrite(_irq, LOW); + hal->delayMicroseconds(120); + hal->digitalWrite(_rst, HIGH); #if defined(ARDUINO) - // In the Arduino ESP32 platform, the test delay is 8ms and the GT911 + // In the Arduino ESP32 platform, the test hal->delay is 8ms and the GT911 // can be accessed correctly. If the time is too long, it will not be accessible. - delay(8); + hal->delay(8); #elif defined(ESP_PLATFORM) // For the variant of GPIO extended RST, - // communication and delay are carried out simultaneously, and 18 ms is measured in T-RGB esp-idf new api - delay(18); + // communication and hal->delay are carried out simultaneously, and 18 ms is measured in T-RGB esp-idf new api + hal->delay(18); #endif - this->setGpioMode(__irq, INPUT); + hal->pinMode(_irq, INPUT); + } else { + if (!autoProbe()) { + return false; + } } - // For variants where the GPIO is controlled by I2C, a delay is required here - delay(20); + // For variants where the GPIO is controlled by I2C, a hal->delay is required here + hal->delay(20); /* * For the ESP32 platform, the default buffer is 128. * Need to re-apply for a larger buffer to fully read the configuration table. - * */ + * + * TODO: NEED FIX if (!this->reallocBuffer(GT911_REG_LENGTH + 2)) { log_e("realloc i2c buffer failed !"); return false; } + */ + _chipID = getChipID(); - __chipID = getChipID(); - log_i("Product id:%ld", __chipID); - - if (__chipID != GT911_DEV_ID) { - log_i("Not find device GT911"); - return false; + if (_chipID != GT911_DEV_ID) { + log_i("Not found device GT911,Try to found the GT911"); + if (!autoProbe()) { + return false; + } } - if (__config && __config_size != 0) { + log_i("Product id:%ld", _chipID); + +#if 0 + /*If the configuration is not written, the touch screen may be damaged. */ + if (_config && _config_size != 0) { log_d("Current version char :%x", getConfigVersion()); - delay(100); - writeConfig(__config, __config_size); - if (__irq != -1) { - this->setGpioMode(__irq, INPUT); + hal->delay(100); + writeConfig(_config, _config_size); + if (_irq != -1) { + hal->pinMode(_irq, INPUT); } log_d("WriteConfig version char :%x", getConfigVersion()); - // delay(1000); + // hal->delay(1000); // size_t output_size; // loadConfig(&output_size, true); // log_d("loadConfig version char :%x", version_char); } +#endif + log_i("Firmware version: 0x%x", getFwVersion()); getResolution(&x, &y); @@ -692,13 +647,13 @@ class TouchDrvGT911 : // Get the default interrupt trigger mode of the current screen getInterruptMode(); - if ( __irq_mode == RISING) { + if ( _irq_mode == RISING) { log_i("Interrupt Mode: RISING"); - } else if (__irq_mode == FALLING) { + } else if (_irq_mode == FALLING) { log_i("Interrupt Mode: FALLING"); - } else if (__irq_mode == LOW_LEVEL_QUERY) { + } else if (_irq_mode == LOW_LEVEL_QUERY) { log_i("Interrupt Mode: LOW_LEVEL_QUERY"); - } else if (__irq_mode == HIGH_LEVEL_QUERY) { + } else if (_irq_mode == HIGH_LEVEL_QUERY) { log_i("Interrupt Mode: HIGH_LEVEL_QUERY"); } else { log_e("UNKOWN"); @@ -708,20 +663,42 @@ class TouchDrvGT911 : log_e("The screen configuration is lost, please update the configuration file again !"); return false; } + return true; } - int getReadMaskImpl() + bool autoProbe() { - return -1; - } + if (_rst != -1) { + hal->pinMode(_rst, OUTPUT); + hal->digitalWrite(_rst, HIGH); + hal->delay(10); + } + + // Automatically determine the current device + // address when using the reset pin without connection + if (!probeAddress()) { + return false; + } + // Reset Config + reset(); -protected: - int __irq_mode; - uint8_t *__config = NULL; - uint16_t __config_size = 0; -}; + if (_irq != -1) { + hal->pinMode(_irq, INPUT); + } + return true; + } + + static constexpr uint8_t LOW_LEVEL_QUERY = 0x03; + static constexpr uint8_t HIGH_LEVEL_QUERY = 0x04; +protected: + std::unique_ptr comm; + std::unique_ptr hal; + int _irq_mode; + uint8_t *_config = NULL; + uint16_t _config_size = 0; +}; diff --git a/src/TouchDrvGT9895.cpp b/src/TouchDrvGT9895.cpp index fbe880f..1f257d2 100644 --- a/src/TouchDrvGT9895.cpp +++ b/src/TouchDrvGT9895.cpp @@ -29,78 +29,82 @@ */ #include "TouchDrvGT9895.hpp" -TouchDrvGT9895::TouchDrvGT9895() -{ -#if defined(ARDUINO) - __wire = &Wire; - __sda = DEFAULT_SDA; - __scl = DEFAULT_SCL; -#endif - __rst = SENSOR_PIN_NONE; - __irq = SENSOR_PIN_NONE; - __addr = GT9895_SLAVE_ADDRESS_L; -} +TouchDrvGT9895::TouchDrvGT9895() : comm(nullptr), hal(nullptr) {} TouchDrvGT9895::~TouchDrvGT9895() { - deinit(); + if (comm) { + comm->deinit(); + } } #if defined(ARDUINO) -bool TouchDrvGT9895::begin(PLATFORM_WIRE_TYPE &w, uint8_t addr, int sda, int scl ) +bool TouchDrvGT9895::begin(TwoWire &wire, uint8_t addr, int sda, int scl) { - return SensorCommon::begin(w, addr, sda, scl); + if (!beginCommon(comm, hal, wire, addr, sda, scl)) { + return false; + } + return initImpl(); } -#elif defined(ESP_PLATFORM) && !defined(ARDUINO) +#elif defined(ESP_PLATFORM) -#if ((ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL(5,0,0)) && defined(CONFIG_SENSORLIB_ESP_IDF_NEW_API)) -bool TouchDrvGT9895::begin(i2c_master_bus_handle_t i2c_dev_bus_handle, uint8_t addr) +#if defined(USEING_I2C_LEGACY) +bool TouchDrvGT9895::begin(i2c_port_t port_num, uint8_t addr, int sda, int scl) { - return SensorCommon::begin(i2c_dev_bus_handle, addr); + if (!beginCommon(comm, hal, port_num, addr, sda, scl)) { + return false; + } + return initImpl(); } #else -bool TouchDrvGT9895::begin(i2c_port_t port_num, uint8_t addr, int sda, int scl) +bool TouchDrvGT9895::begin(i2c_master_bus_handle_t handle, uint8_t addr) { - return SensorCommon::begin(port_num, addr, sda, scl); + if (!beginCommon(comm, hal, handle, addr)) { + return false; + } + return initImpl(); } -#endif //ESP_IDF_VERSION - -#endif +#endif //ESP_PLATFORM +#endif //ARDUINO -bool TouchDrvGT9895::begin(uint8_t addr, iic_fptr_t readRegCallback, iic_fptr_t writeRegCallback) +bool TouchDrvGT9895::begin(SensorCommCustom::CustomCallback callback, + SensorCommCustomHal::CustomHalCallback hal_callback, + uint8_t addr) { - return SensorCommon::begin(addr, readRegCallback, writeRegCallback); + if (!beginCommCustomCallback(COMM_CUSTOM, + callback, hal_callback, addr, comm, hal)) { + return false; + } + return initImpl(); } - void TouchDrvGT9895::deinit() { - // end(); -} +} void TouchDrvGT9895::reset() { - if (__rst != SENSOR_PIN_NONE) { - this->setGpioMode(__rst, OUTPUT); - this->setGpioLevel(__rst, HIGH); - delay(10); - this->setGpioLevel(__rst, LOW); - delay(30); - this->setGpioLevel(__rst, HIGH); - delay(100); - } - if (__irq != SENSOR_PIN_NONE) { - this->setGpioMode(__irq, INPUT); + if (_rst != -1) { + hal->pinMode(_rst, OUTPUT); + hal->digitalWrite(_rst, HIGH); + hal->delay(10); + hal->digitalWrite(_rst, LOW); + hal->delay(30); + hal->digitalWrite(_rst, HIGH); + hal->delay(100); + } + if (_irq != -1) { + hal->pinMode(_irq, INPUT); } } void TouchDrvGT9895::sleep() { - if (__irq != SENSOR_PIN_NONE) { - this->setGpioMode(__irq, OUTPUT); - this->setGpioLevel(__irq, LOW); + if (_irq != -1) { + hal->pinMode(_irq, OUTPUT); + hal->digitalWrite(_irq, LOW); } uint8_t sleep_cmd[] = { @@ -110,15 +114,15 @@ void TouchDrvGT9895::sleep() (GT9895_REG_CMD & 0xFF), 0x00, 0x00, 0x04, 0x84, 0x88, 0x00 }; - writeBuffer(sleep_cmd, sizeof(sleep_cmd)); + comm->writeBuffer(sleep_cmd, sizeof(sleep_cmd)); } void TouchDrvGT9895::wakeup() { - if (__irq != SENSOR_PIN_NONE) { - this->setGpioMode(__irq, OUTPUT); - this->setGpioLevel(__irq, HIGH); - delay(8); + if (_irq != -1) { + hal->pinMode(_irq, OUTPUT); + hal->digitalWrite(_irq, HIGH); + hal->delay(8); } reset(); } @@ -138,9 +142,11 @@ uint8_t TouchDrvGT9895::getPoint(int16_t *x_array, int16_t *y_array, uint8_t siz uint8_t buffer[32] = {0}; uint8_t event_status; - int length = GT9895_IRQ_EVENT_HEAD_LEN + GT9895_BYTES_PER_POINT * 2 + GT9895_COOR_DATA_CHECKSUM_SIZE; + int length = GT9895_IRQ_EVENT_HEAD_LEN + GT9895_BYTES_PER_POINT * 2 + GT9895_COORDS_DATA_CHECKSUM_SIZE; - if (writeThenRead(GT9895_REG_POINT, buffer, length) == DEV_WIRE_ERR) { + ByteUnion u; + u.value = GT9895_REG_POINT; + if (comm->writeThenRead(u.byte_array, 4, buffer, length) == -1) { return 0; } @@ -166,8 +172,8 @@ uint8_t TouchDrvGT9895::getPoint(int16_t *x_array, int16_t *y_array, uint8_t siz if ( x_array && y_array && size) { uint8_t length = size < touchNum ? size : touchNum; for (int i = 0; i < length; ++i) { - x_array[i] = __ts_event.touch_data.coords[i].x; - y_array[i] = __ts_event.touch_data.coords[i].y; + x_array[i] = _ts_event.touch_data.coords[i].x; + y_array[i] = _ts_event.touch_data.coords[i].y; } updateXY(touchNum, x_array, y_array); } @@ -177,20 +183,20 @@ uint8_t TouchDrvGT9895::getPoint(int16_t *x_array, int16_t *y_array, uint8_t siz #if 0 if (event_status & GT9895_REQUEST_EVENT) { - __ts_event.event_type = EVENT_REQUEST; + _ts_event.event_type = EVENT_REQUEST; if (buffer[2] == BRL_REQUEST_CODE_CONFIG) - __ts_event.request_code = REQUEST_TYPE_CONFIG; + _ts_event.request_code = REQUEST_TYPE_CONFIG; else if (buffer[2] == BRL_REQUEST_CODE_RESET) - __ts_event.request_code = REQUEST_TYPE_RESET; + _ts_event.request_code = REQUEST_TYPE_RESET; else log_e("unsupported request code 0x%x", buffer[2]); } if (event_status & GT9895_GESTURE_EVENT) { - __ts_event.event_type = EVENT_GESTURE; - __ts_event.gesture_type = buffer[4]; - memcpy(__ts_event.gesture_data, &buffer[8], GT9895_GESTURE_DATA_LEN); + _ts_event.event_type = EVENT_GESTURE; + _ts_event.gesture_type = buffer[4]; + memcpy(_ts_event.gesture_data, &buffer[8], GT9895_GESTURE_DATA_LEN); } #endif @@ -201,8 +207,8 @@ uint8_t TouchDrvGT9895::getPoint(int16_t *x_array, int16_t *y_array, uint8_t siz bool TouchDrvGT9895::isPressed() { - if (__irq != SENSOR_PIN_NONE) { - return this->getGpioLevel(__irq) == LOW; + if (_irq != -1) { + return hal->digitalRead(_irq) == LOW; } else { return getPoint(NULL, NULL, 0); } @@ -211,7 +217,7 @@ bool TouchDrvGT9895::isPressed() uint32_t TouchDrvGT9895::getChipID() { - return (uint32_t)strtol((const char *)__version.patch_pid, NULL, 16); + return (uint32_t)strtol((const char *)_version.patch_pid, NULL, 16); } @@ -225,13 +231,13 @@ const char *TouchDrvGT9895::getModelName() return "GT9895"; } -void TouchDrvGT9895::setGpioCallback(gpio_mode_fptr_t mode_cb, - gpio_write_fptr_t write_cb, - gpio_read_fptr_t read_cb) +void TouchDrvGT9895::setGpioCallback(CustomMode mode_cb, + CustomWrite write_cb, + CustomRead read_cb) { - SensorCommon::setGpioModeCallback(mode_cb); - SensorCommon::setGpioWriteCallback(write_cb); - SensorCommon::setGpioReadCallback(read_cb); + SensorHalCustom::setCustomMode(mode_cb); + SensorHalCustom::setCustomWrite(write_cb); + SensorHalCustom::setCustomRead(read_cb); } int TouchDrvGT9895::is_risk_data(const uint8_t *data, int size) @@ -274,35 +280,38 @@ int TouchDrvGT9895::checksum_cmp(const uint8_t *data, int size, int mode) return cal_checksum == r_checksum ? 0 : 1; } -int TouchDrvGT9895::readVersion(struct goodix_fw_version *version) +int TouchDrvGT9895::readVersion(ChipFirmwareVersion *version) { int ret = 0; - uint8_t buffer[sizeof(struct goodix_fw_version)] = {0}; + uint8_t buffer[sizeof(ChipFirmwareVersion)] = {0}; uint8_t temp_pid[8] = {0}; if (!version) { - return DEV_WIRE_ERR; + return -1; } for (int i = 0; i < 2; i++) { - if (writeThenRead(GT9895_REG_FW_VERSION, buffer, sizeof(buffer)) == DEV_WIRE_ERR) { + + ByteUnion u; + u.value = GT9895_REG_FW_VERSION; + if (comm->writeThenRead(u.byte_array, 4, buffer, sizeof(buffer)) == -1) { log_e("read fw version: %d, retry %d", ret, i); - ret = DEV_WIRE_ERR; - delay(5); + ret = -1; + hal->delay(5); continue; } if (!checksum_cmp(buffer, sizeof(buffer), CHECKSUM_MODE_U8_LE)) { - ret = DEV_WIRE_NONE; + ret = 0; break; } log_e("Invalid fw version: checksum error!"); log_e("Firmware version:%*ph", (int)sizeof(buffer), buffer); - ret = DEV_WIRE_ERR; - delay(15); + ret = -1; + hal->delay(15); } - if (ret == DEV_WIRE_ERR) { + if (ret == -1) { log_e("Failed get valid firmware version"); return ret; } @@ -315,25 +324,25 @@ int TouchDrvGT9895::readVersion(struct goodix_fw_version *version) log_d("VID:%*p", (int)sizeof(version->patch_vid), version->patch_vid); log_d("Sensor ID:%d", version->sensor_id); - return DEV_WIRE_NONE; + return 0; } -int TouchDrvGT9895::convertChipInfo(struct goodix_ic_info *info, const uint8_t *data) +int TouchDrvGT9895::convertChipInfo(ChipInfo *info, const uint8_t *data) { int i = 0; - struct goodix_ic_info_version *version = &info->version; - struct goodix_ic_info_feature *feature = &info->feature; - struct goodix_ic_info_param *parm = &info->parm; - struct goodix_ic_info_misc *misc = &info->misc; + ChipInfoVersion *version = &info->version; + ChipInfoFeature *feature = &info->feature; + ChipInfoParams *parm = &info->parm; + ChipInfoMisc *misc = &info->misc; info->length = *((uint16_t *)data); data += 2; memcpy(version, data, sizeof(*version)); - data += sizeof(struct goodix_ic_info_version); + data += sizeof(ChipInfoVersion); memcpy(feature, data, sizeof(*feature)); - data += sizeof(struct goodix_ic_info_feature); + data += sizeof(ChipInfoFeature); parm->drv_num = *(data++); parm->sen_num = *(data++); @@ -343,7 +352,7 @@ int TouchDrvGT9895::convertChipInfo(struct goodix_ic_info *info, const uint8_t * if (parm->active_scan_rate_num > GT9895_MAX_SCAN_RATE_NUM) { log_e("Invalid scan rate num %d > %d", parm->active_scan_rate_num, GT9895_MAX_SCAN_RATE_NUM); - return DEV_WIRE_ERR; + return -1; } for (i = 0; i < parm->active_scan_rate_num; i++) parm->active_scan_rate[i] = *((uint16_t *)(data + i * 2)); @@ -352,7 +361,7 @@ int TouchDrvGT9895::convertChipInfo(struct goodix_ic_info *info, const uint8_t * parm->mutual_freq_num = *(data++); if (parm->mutual_freq_num > GT9895_MAX_SCAN_FREQ_NUM) { log_e("invalid mutual freq num %d > %d", parm->mutual_freq_num, GT9895_MAX_SCAN_FREQ_NUM); - return DEV_WIRE_ERR; + return -1; } for (i = 0; i < parm->mutual_freq_num; i++) parm->mutual_freq[i] = *((uint16_t *)(data + i * 2)); @@ -361,7 +370,7 @@ int TouchDrvGT9895::convertChipInfo(struct goodix_ic_info *info, const uint8_t * parm->self_tx_freq_num = *(data++); if (parm->self_tx_freq_num > GT9895_MAX_SCAN_FREQ_NUM) { log_e("Invalid tx freq num %d > %d", parm->self_tx_freq_num, GT9895_MAX_SCAN_FREQ_NUM); - return DEV_WIRE_ERR; + return -1; } for (i = 0; i < parm->self_tx_freq_num; i++) parm->self_tx_freq[i] = *((uint16_t *)(data + i * 2)); @@ -370,7 +379,7 @@ int TouchDrvGT9895::convertChipInfo(struct goodix_ic_info *info, const uint8_t * parm->self_rx_freq_num = *(data++); if (parm->self_rx_freq_num > GT9895_MAX_SCAN_FREQ_NUM) { log_e("Invalid rx freq num %d > %d", parm->self_rx_freq_num, GT9895_MAX_SCAN_FREQ_NUM); - return DEV_WIRE_ERR; + return -1; } for (i = 0; i < parm->self_rx_freq_num; i++) parm->self_rx_freq[i] = *((uint16_t *)(data + i * 2)); @@ -379,22 +388,22 @@ int TouchDrvGT9895::convertChipInfo(struct goodix_ic_info *info, const uint8_t * parm->stylus_freq_num = *(data++); if (parm->stylus_freq_num > GT9895_MAX_FREQ_NUM_STYLUS) { log_e("Invalid stylus freq num %d > %d", parm->stylus_freq_num, GT9895_MAX_FREQ_NUM_STYLUS); - return DEV_WIRE_ERR; + return -1; } for (i = 0; i < parm->stylus_freq_num; i++) parm->stylus_freq[i] = *((uint16_t *)(data + i * 2)); data += parm->stylus_freq_num * 2; memcpy(misc, data, sizeof(*misc)); - return DEV_WIRE_NONE; + return 0; } -void TouchDrvGT9895::printChipInfo(struct goodix_ic_info *ic_info) +void TouchDrvGT9895::printChipInfo(ChipInfo *ic_info) { - struct goodix_ic_info_version *version = &ic_info->version; - struct goodix_ic_info_feature *feature = &ic_info->feature; - struct goodix_ic_info_param *parm = &ic_info->parm; - struct goodix_ic_info_misc *misc = &ic_info->misc; + ChipInfoVersion *version = &ic_info->version; + ChipInfoFeature *feature = &ic_info->feature; + ChipInfoParams *parm = &ic_info->parm; + ChipInfoMisc *misc = &ic_info->misc; (void)version; (void)feature; @@ -432,62 +441,65 @@ void TouchDrvGT9895::printChipInfo(struct goodix_ic_info *ic_info) log_d("esd_addr: 0x%04lX", misc->esd_addr); } -int TouchDrvGT9895::readChipInfo(struct goodix_ic_info *ic_info) +int TouchDrvGT9895::readChipInfo(ChipInfo *ic_info) { int i = 0; uint16_t length = 0; uint8_t afe_data[GT9895_INFO_MAX_LENGTH] = {0}; for (i = 0; i < 3; i++) { - if (writeThenRead(GT9895_REG_INFO, (uint8_t *)&length, sizeof(length)) == DEV_WIRE_ERR) { + + ByteUnion u; + u.value = GT9895_REG_INFO; + if (comm->writeThenRead(u.byte_array, 4, (uint8_t *)&length, sizeof(length)) == -1) { log_e("Failed get ic info length"); - delay(5); + hal->delay(5); continue; } if (length >= GT9895_INFO_MAX_LENGTH || length == 0) { log_e("Invalid ic info length %d, retry %d", length, i); continue; } - if (writeThenRead(GT9895_REG_INFO, afe_data, length) == DEV_WIRE_ERR) { + if (comm->writeThenRead(u.byte_array, 4, afe_data, length) == -1) { log_e("Failed get ic info data"); - delay(5); + hal->delay(5); continue; } /* judge whether the data is valid */ if (is_risk_data((const uint8_t *)afe_data, length)) { log_e("Firmware info data invalid"); - delay(5); + hal->delay(5); continue; } if (checksum_cmp((const uint8_t *)afe_data, length, CHECKSUM_MODE_U8_LE)) { log_e("Firmware info checksum error!"); - delay(5); + hal->delay(5); continue; } break; } if (i == 3) { log_e("Failed get ic info"); - return DEV_WIRE_ERR; + return -1; } - if (convertChipInfo(ic_info, afe_data) == DEV_WIRE_ERR) { + if (convertChipInfo(ic_info, afe_data) == -1) { log_e("Convert ic info encounter error"); - return DEV_WIRE_ERR; + return -1; } printChipInfo(ic_info); /* check some key info */ if (!ic_info->misc.cmd_addr || !ic_info->misc.fw_buffer_addr || !ic_info->misc.touch_data_addr) { log_e("cmd_addr fw_buf_addr and touch_data_addr is null"); - return DEV_WIRE_ERR; + return -1; } - return DEV_WIRE_NONE; + return 0; } void TouchDrvGT9895::clearStatus() { uint8_t buffer[5] = { 0x00, 0x01, 0x03, 0x08, 0x00}; - writeBuffer(buffer, 5); + comm->writeBuffer(buffer, 5); } int TouchDrvGT9895::getTouchData(uint8_t *pre_buf, uint32_t pre_buf_len) @@ -497,7 +509,7 @@ int TouchDrvGT9895::getTouchData(uint8_t *pre_buf, uint32_t pre_buf_len) uint8_t buffer[GT9895_IRQ_EVENT_HEAD_LEN + GT9895_BYTES_PER_POINT * GT9895_MAX_TOUCH + 2]; /* clean event buffer */ - memset(&__ts_event, 0, sizeof(__ts_event)); + memset(&_ts_event, 0, sizeof(_ts_event)); /* copy pre-data to buffer */ memcpy(buffer, pre_buf, pre_buf_len); @@ -508,8 +520,9 @@ int TouchDrvGT9895::getTouchData(uint8_t *pre_buf, uint32_t pre_buf_len) } if (touch_num > 2) { - uint32_t addr = GT9895_REG_POINT + pre_buf_len; - if (writeThenRead(addr, &buffer[pre_buf_len], (touch_num - 2) * GT9895_BYTES_PER_POINT) == DEV_WIRE_ERR) { + ByteUnion u; + u.value = GT9895_REG_POINT + pre_buf_len; + if (comm->writeThenRead(u.byte_array, 4, &buffer[pre_buf_len], (touch_num - 2) * GT9895_BYTES_PER_POINT) == -1) { log_e("Failed get touch data"); return 0; } @@ -530,9 +543,9 @@ int TouchDrvGT9895::getTouchData(uint8_t *pre_buf, uint32_t pre_buf_len) } } - __ts_event.fp_flag = pre_buf[0] & GT9895_FP_EVENT; + _ts_event.fp_flag = pre_buf[0] & GT9895_FP_EVENT; /* finger info */ - __ts_event.event_type = EVENT_TOUCH; + _ts_event.event_type = EVENT_TOUCH; uint32_t id = 0, x = 0, y = 0, w = 0; uint8_t *pdat = &buffer[GT9895_IRQ_EVENT_HEAD_LEN]; @@ -540,47 +553,42 @@ int TouchDrvGT9895::getTouchData(uint8_t *pre_buf, uint32_t pre_buf_len) id = (pdat[0] >> 4) & 0x0F; if (id >= GT9895_MAX_TOUCH) { log_e("Invalid finger id"); - __ts_event.touch_data.touch_num = 0; + _ts_event.touch_data.touch_num = 0; return 0; } x = *((uint16_t *)(pdat + 2)); y = *((uint16_t *)(pdat + 4)); w = *((uint16_t *)(pdat + 6)); - __ts_event.touch_data.coords[id].status = TS_TOUCH; - __ts_event.touch_data.coords[id].x = x; - __ts_event.touch_data.coords[id].y = y; - __ts_event.touch_data.coords[id].w = w; + _ts_event.touch_data.coords[id].status = TS_TOUCH; + _ts_event.touch_data.coords[id].x = x; + _ts_event.touch_data.coords[id].y = y; + _ts_event.touch_data.coords[id].w = w; pdat += GT9895_BYTES_PER_POINT; } - __ts_event.touch_data.touch_num = touch_num; + _ts_event.touch_data.touch_num = touch_num; return touch_num; } bool TouchDrvGT9895::initImpl() { - if (__irq != SENSOR_PIN_NONE) { - this->setGpioMode(__irq, INPUT); + if (_irq != -1) { + hal->pinMode(_irq, INPUT); } reset(); - if (readVersion(&__version) != DEV_WIRE_NONE) { + if (readVersion(&_version) != 0) { return false; } - readChipInfo(&__ic_info); + readChipInfo(&_ic_info); return true; } -int TouchDrvGT9895::getReadMaskImpl() -{ - return 0X80; -} - /* -[ 7142][I][SensorCommon.tpp:65] begin(): Using Arduino Wire interface. +[ 7142][I][SensorCommon.hpp:65] begin(): Using Arduino Wire interface. [ 7148][W][Wire.cpp:301] begin(): Bus already started in Master Mode. [ 7197][D][TouchDrvGT9895.cpp:348] readVersion(): Rom_pid:BERLIN [ 7203][D][TouchDrvGT9895.cpp:349] readVersion(): Rom_vid:0x3fc95c33 diff --git a/src/TouchDrvGT9895.hpp b/src/TouchDrvGT9895.hpp index 7fe1a7d..d79cb7e 100644 --- a/src/TouchDrvGT9895.hpp +++ b/src/TouchDrvGT9895.hpp @@ -31,215 +31,27 @@ #include "REG/GT9895Constants.h" #include "TouchDrvInterface.hpp" -#include "SensorCommon.tpp" - -enum CHECKSUM_MODE { - CHECKSUM_MODE_U8_LE, - CHECKSUM_MODE_U16_LE, -}; - -enum touch_point_status { - TS_NONE, - TS_RELEASE, - TS_TOUCH, -}; - -/* interrupt event type */ -enum ts_event_type { - EVENT_INVALID = 0, - EVENT_TOUCH = (1 << 0), /* finger touch event */ - EVENT_PEN = (1 << 1), /* pen event */ - EVENT_REQUEST = (1 << 2), - EVENT_GESTURE = (1 << 3), -}; - -enum brl_request_code { - BRL_REQUEST_CODE_CONFIG = 0x01, - BRL_REQUEST_CODE_REF_ERR = 0x02, - BRL_REQUEST_CODE_RESET = 0x03, - BRL_REQUEST_CODE_CLOCK = 0x04, -}; - -/* coordinate package */ -struct goodix_ts_coords { - int status; /* NONE, RELEASE, TOUCH */ - unsigned int x, y, w, p; -}; - -/* touch event data */ -struct goodix_touch_data { - int touch_num; - uint64_t timestamp; - struct goodix_ts_coords coords[GT9895_MAX_TOUCH]; -}; - -struct goodix_ts_key { - int status; - int code; -}; -struct goodix_pen_coords { - int status; /* NONE, RELEASE, TOUCH */ - int tool_type; /* BTN_TOOL_RUBBER BTN_TOOL_PEN */ - unsigned int x, y, p; - signed char tilt_x; - signed char tilt_y; -}; - -struct goodix_pen_data { - struct goodix_pen_coords coords; - struct goodix_ts_key keys[GT9895_MAX_PEN_KEY]; -}; - -struct goodix_point_t { - int id; - int x; - int y; - int w; - int p; - int tool_type; -}; - -/* - * struct goodix_ts_event - touch event struct - * @event_type: touch event type, touch data or - * request event - * @event_data: event data - */ -struct goodix_ts_event { - enum ts_event_type event_type; - uint8_t fp_flag; /* finger print DOWN flag */ - uint8_t request_code; /* represent the request type */ - uint8_t gesture_type; - uint8_t gesture_data[GT9895_GESTURE_DATA_LEN]; - struct goodix_touch_data touch_data; - struct goodix_pen_data pen_data; -}; - -struct goodix_fw_version { - uint8_t rom_pid[6]; /* rom PID */ - uint8_t rom_vid[3]; /* Mask VID */ - uint8_t rom_vid_reserved; - uint8_t patch_pid[8]; /* Patch PID */ - uint8_t patch_vid[4]; /* Patch VID */ - uint8_t patch_vid_reserved; - uint8_t sensor_id; - uint8_t reserved[2]; - uint16_t checksum; -}; - -struct goodix_ic_info_version { - uint8_t info_customer_id; - uint8_t info_version_id; - uint8_t ic_die_id; - uint8_t ic_version_id; - uint32_t config_id; - uint8_t config_version; - uint8_t frame_data_customer_id; - uint8_t frame_data_version_id; - uint8_t touch_data_customer_id; - uint8_t touch_data_version_id; - uint8_t reserved[3]; -}; - -struct goodix_ic_info_feature { /* feature info*/ - uint16_t freqhop_feature; - uint16_t calibration_feature; - uint16_t gesture_feature; - uint16_t side_touch_feature; - uint16_t stylus_feature; -}; - -struct goodix_ic_info_param { /* param */ - uint8_t drv_num; - uint8_t sen_num; - uint8_t button_num; - uint8_t force_num; - uint8_t active_scan_rate_num; - uint16_t active_scan_rate[GT9895_MAX_SCAN_RATE_NUM]; - uint8_t mutual_freq_num; - uint16_t mutual_freq[GT9895_MAX_SCAN_FREQ_NUM]; - uint8_t self_tx_freq_num; - uint16_t self_tx_freq[GT9895_MAX_SCAN_FREQ_NUM]; - uint8_t self_rx_freq_num; - uint16_t self_rx_freq[GT9895_MAX_SCAN_FREQ_NUM]; - uint8_t stylus_freq_num; - uint16_t stylus_freq[GT9895_MAX_FREQ_NUM_STYLUS]; -}; - -struct goodix_ic_info_misc { /* other data */ - uint32_t cmd_addr; - uint16_t cmd_max_len; - uint32_t cmd_reply_addr; - uint16_t cmd_reply_len; - uint32_t fw_state_addr; - uint16_t fw_state_len; - uint32_t fw_buffer_addr; - uint16_t fw_buffer_max_len; - uint32_t frame_data_addr; - uint16_t frame_data_head_len; - uint16_t fw_attr_len; - uint16_t fw_log_len; - uint8_t pack_max_num; - uint8_t pack_compress_version; - uint16_t stylus_struct_len; - uint16_t mutual_struct_len; - uint16_t self_struct_len; - uint16_t noise_struct_len; - uint32_t touch_data_addr; - uint16_t touch_data_head_len; - uint16_t point_struct_len; - uint16_t reserved1; - uint16_t reserved2; - uint32_t mutual_rawdata_addr; - uint32_t mutual_diffdata_addr; - uint32_t mutual_refdata_addr; - uint32_t self_rawdata_addr; - uint32_t self_diffdata_addr; - uint32_t self_refdata_addr; - uint32_t iq_rawdata_addr; - uint32_t iq_refdata_addr; - uint32_t im_rawdata_addr; - uint16_t im_readata_len; - uint32_t noise_rawdata_addr; - uint16_t noise_rawdata_len; - uint32_t stylus_rawdata_addr; - uint16_t stylus_rawdata_len; - uint32_t noise_data_addr; - uint32_t esd_addr; -}; - -struct goodix_ic_info { - uint16_t length; - struct goodix_ic_info_version version; - struct goodix_ic_info_feature feature; - struct goodix_ic_info_param parm; - struct goodix_ic_info_misc misc; -}; - - -class TouchDrvGT9895 : - public TouchDrvInterface, - public SensorCommon +class TouchDrvGT9895 : public TouchDrvInterface, public GT9895Constants { - friend class SensorCommon; public: TouchDrvGT9895(); ~TouchDrvGT9895(); #if defined(ARDUINO) - - bool begin(PLATFORM_WIRE_TYPE &w, uint8_t addr = GT9895_SLAVE_ADDRESS_L, int sda = DEFAULT_SDA, int scl = DEFAULT_SCL); - -#elif defined(ESP_PLATFORM) && !defined(ARDUINO) -#if ((ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL(5,0,0)) && defined(CONFIG_SENSORLIB_ESP_IDF_NEW_API)) - bool begin(i2c_master_bus_handle_t i2c_dev_bus_handle, uint8_t addr); + bool begin(TwoWire &wire, uint8_t address = GT9895_SLAVE_ADDRESS_L, int sda = -1, int scl = -1); +#elif defined(ESP_PLATFORM) +#if defined(USEING_I2C_LEGACY) + bool begin(i2c_port_t port_num, uint8_t addr = GT9895_SLAVE_ADDRESS_L, int sda = -1, int scl = -1); #else - bool begin(i2c_port_t port_num, uint8_t addr, int sda, int scl); -#endif //ESP_IDF_VERSION -#endif + bool begin(i2c_master_bus_handle_t handle, uint8_t addr = GT9895_SLAVE_ADDRESS_L); +#endif //ESP_PLATFORM +#endif //ARDUINO + + bool begin(SensorCommCustom::CustomCallback callback, + SensorCommCustomHal::CustomHalCallback hal_callback, + uint8_t addr = GT9895_SLAVE_ADDRESS_L); - bool begin(uint8_t addr, iic_fptr_t readRegCallback, iic_fptr_t writeRegCallback); void deinit(); void reset(); void sleep(); @@ -254,29 +66,33 @@ class TouchDrvGT9895 : bool getResolution(int16_t *x, int16_t *y); const char *getModelName(); - void setGpioCallback(gpio_mode_fptr_t mode_cb, gpio_write_fptr_t write_cb, gpio_read_fptr_t read_cb); + + void setGpioCallback(CustomMode mode_cb, + CustomWrite write_cb, + CustomRead read_cb); private: int is_risk_data(const uint8_t *data, int size); int checksum_cmp(const uint8_t *data, int size, int mode); - int readVersion(struct goodix_fw_version *version); - int convertChipInfo(struct goodix_ic_info *info, const uint8_t *data); - void printChipInfo(struct goodix_ic_info *ic_info); - int readChipInfo(struct goodix_ic_info *ic_info); + int readVersion(ChipFirmwareVersion *version); + int convertChipInfo(ChipInfo *info, const uint8_t *data); + void printChipInfo(ChipInfo *ic_info); + int readChipInfo(ChipInfo *ic_info); void clearStatus(); int getTouchData( uint8_t *pre_buf, uint32_t pre_buf_len); bool initImpl(); - int getReadMaskImpl(); - protected: - struct goodix_ts_event __ts_event; - struct goodix_fw_version __version; - struct goodix_ic_info __ic_info; + std::unique_ptr comm; + std::unique_ptr hal; + + ChipTsEvent _ts_event; + ChipFirmwareVersion _version; + ChipInfo _ic_info; }; diff --git a/src/TouchDrvInterface.cpp b/src/TouchDrvInterface.cpp index 5e43a30..e0e5fb7 100644 --- a/src/TouchDrvInterface.cpp +++ b/src/TouchDrvInterface.cpp @@ -30,18 +30,18 @@ #include "TouchDrvInterface.hpp" TouchDrvInterface::TouchDrvInterface() : - __resX(0), - __resY(0), - __xMax(0), - __yMax(0), - __swapXY(false), - __mirrorX(false), - __mirrorY(false), - __rst(-1), - __irq(-1), - __chipID(0x00), - __homeButtonCb(NULL), - __userData(NULL) + _resX(0), + _resY(0), + _xMax(0), + _yMax(0), + _swapXY(false), + _mirrorX(false), + _mirrorY(false), + _rst(-1), + _irq(-1), + _chipID(0x00), + _HButtonCallback(nullptr), + _userData(nullptr) { } @@ -53,31 +53,31 @@ TouchDrvInterface::~TouchDrvInterface() uint32_t TouchDrvInterface::getChipID() { - return __chipID; + return _chipID; } void TouchDrvInterface::setPins(int rst, int irq) { - __irq = irq; - __rst = rst; + _irq = irq; + _rst = rst; } void TouchDrvInterface::setSwapXY(bool swap) { - __swapXY = swap; + _swapXY = swap; } void TouchDrvInterface::setMirrorXY(bool mirrorX, bool mirrorY) { - __mirrorX = mirrorX; - __mirrorY = mirrorY; + _mirrorX = mirrorX; + _mirrorY = mirrorY; } void TouchDrvInterface::setMaxCoordinates(uint16_t x, uint16_t y) { - __xMax = x; - __yMax = y; + _xMax = x; + _yMax = y; } void TouchDrvInterface::updateXY(uint8_t pointNum, int16_t *xBuffer, int16_t *yBuffer) @@ -85,16 +85,16 @@ void TouchDrvInterface::updateXY(uint8_t pointNum, int16_t *xBuffer, int16_t *yB if (!pointNum) return; for (int i = 0; i < pointNum; ++i) { - if (__swapXY) { + if (_swapXY) { uint16_t tmp = xBuffer[i]; xBuffer[i] = yBuffer[i]; yBuffer[i] = tmp; } - if (__mirrorX && __xMax ) { - xBuffer[i] = __xMax - xBuffer[i]; + if (_mirrorX && _xMax ) { + xBuffer[i] = _xMax - xBuffer[i]; } - if (__mirrorY && __yMax) { - yBuffer[i] = __yMax - yBuffer[i]; + if (_mirrorY && _yMax) { + yBuffer[i] = _yMax - yBuffer[i]; } } } diff --git a/src/TouchDrvInterface.hpp b/src/TouchDrvInterface.hpp index b41ea4d..02c3937 100644 --- a/src/TouchDrvInterface.hpp +++ b/src/TouchDrvInterface.hpp @@ -29,13 +29,7 @@ */ #pragma once -#include -#include -#include "SensorLib.h" -#include "SensorCommon.tpp" - -typedef void (*home_button_callback_t)(void *user_data); - +#include "SensorPlatform.hpp" class TouchData { @@ -69,28 +63,29 @@ class TouchData -class TouchDrvInterface +class TouchDrvInterface : public SensorHalCustom { public: + using HomeButtonCallback = void(*)(void *user_data); + TouchDrvInterface(); virtual ~TouchDrvInterface(); #if defined(ARDUINO) - - virtual bool begin(PLATFORM_WIRE_TYPE &wire, uint8_t address, int sda, int scl) = 0; - -#elif defined(ESP_PLATFORM) && !defined(ARDUINO) - -#if ((ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL(5,0,0)) && defined(CONFIG_SENSORLIB_ESP_IDF_NEW_API)) - virtual bool begin(i2c_master_bus_handle_t i2c_dev_bus_handle, uint8_t addr) = 0; -#else + virtual bool begin(TwoWire &wire, uint8_t address, int sda, int scl) = 0; +#elif defined(ESP_PLATFORM) +#if defined(USEING_I2C_LEGACY) virtual bool begin(i2c_port_t port_num, uint8_t addr, int sda, int scl) = 0; -#endif //ESP_IDF_VERSION +#else + virtual bool begin(i2c_master_bus_handle_t handle, uint8_t addr) = 0; +#endif +#endif // defined(ARDUINO) -#endif //defined(ESP_PLATFORM) && !defined(ARDUINO) - virtual bool begin(uint8_t addr, iic_fptr_t readRegCallback, iic_fptr_t writeRegCallback) = 0; + virtual bool begin(SensorCommCustom::CustomCallback callback, + SensorCommCustomHal::CustomHalCallback hal_callback, + uint8_t addr) = 0; virtual void reset() = 0; @@ -110,9 +105,9 @@ class TouchDrvInterface virtual bool getResolution(int16_t *x, int16_t *y) = 0; - virtual void setGpioCallback(gpio_mode_fptr_t mode_cb, - gpio_write_fptr_t write_cb, - gpio_read_fptr_t read_cb) = 0; + virtual void setGpioCallback(CustomMode mode_cb, + CustomWrite write_cb, + CustomRead read_cb) = 0; uint32_t getChipID(); @@ -127,19 +122,12 @@ class TouchDrvInterface void updateXY(uint8_t pointNum, int16_t *xBuffer, int16_t *yBuffer); protected: - uint16_t __resX, __resY, __xMax, __yMax; - bool __swapXY, __mirrorX, __mirrorY; - int __rst; - int __irq; - uint32_t __chipID; - home_button_callback_t __homeButtonCb; - void *__userData; + uint16_t _resX, _resY, _xMax, _yMax; + bool _swapXY, _mirrorX, _mirrorY; + int _rst; + int _irq; + uint32_t _chipID; + HomeButtonCallback _HButtonCallback; + void *_userData; }; - - - - - - - diff --git a/src/bosch/BoschParse.cpp b/src/bosch/BoschParse.cpp index a162bd7..8145df7 100644 --- a/src/bosch/BoschParse.cpp +++ b/src/bosch/BoschParse.cpp @@ -225,7 +225,7 @@ void BoschParse::parseDebugMessage(const struct bhy2_fifo_parse_data_info *callb debug_msg[msg_length] = '\0'; /* Terminate the string */ // log_i("[DEBUG MSG]; T: %lu.%09lu; %s", s, ns, debug_msg); - log_i("[DEBUG MSG]: %s", debug_msg); + log_d("[DEBUG MSG]: %s", debug_msg); if (_debug_callback) { _debug_callback((const char *)debug_msg); diff --git a/src/bosch/BoschParse.h b/src/bosch/BoschParse.h index c31b993..12c8028 100644 --- a/src/bosch/BoschParse.h +++ b/src/bosch/BoschParse.h @@ -28,18 +28,22 @@ * */ #pragma once - -#include "SensorCommon.tpp" +#include "SensorLib.h" #include "SensorBhy2Define.h" #include "bosch/bhy2_parse.h" #include "bosch/common/common.h" -#if defined(ARDUINO_ARCH_RP2040) || defined(ARDUINO_ARCH_ESP32) || defined(ARDUINO_ARCH_STM32) -#include +#if __cplusplus >= 201103L #include +#include #define USE_STD_VECTOR #endif +// nrf52 arduino ide not applicable vector +#if defined(ARDUINO) && !defined(PLATFORMIO) && defined(ARDUINO_ARCH_NRF52) +#undef USE_STD_VECTOR +#endif + enum BoschOrientation { BHY2_DIRECTION_TOP_RIGHT, diff --git a/src/bosch/BoschPhySensorInfo.hpp b/src/bosch/BoschPhySensorInfo.hpp new file mode 100644 index 0000000..8f11a5b --- /dev/null +++ b/src/bosch/BoschPhySensorInfo.hpp @@ -0,0 +1,155 @@ +/** + * + * @license MIT License + * + * Copyright (c) 2025 lewis he + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * @file BHI260APSensorInfo.hpp + * @author Lewis He (lewishe@outlook.com) + * @date 2025-01-22 + * + */ +#pragma once + +#include +#include +#include "bhy2_parse.h" +#ifdef ARDUINO +#include +#endif + +class BoschPhySensorInfo +{ +public: + uint8_t sensor_type; + uint8_t driver_id; + uint8_t driver_version; + float power_current; + uint16_t curr_range; + bool irq_status; + int master_intf; + int power_mode; + uint8_t slave_address; + uint8_t gpio_assignment; + float curr_rate; + uint8_t num_axis; + int8_t orientation_matrix[9]; + uint8_t reserved; + uint8_t flags; + + + BoschPhySensorInfo() : sensor_type(0), driver_id(0), driver_version(0), power_current(0), curr_range(0), irq_status(false), + master_intf(0), power_mode(0), slave_address(0), gpio_assignment(0), curr_rate(0), num_axis(0), reserved(0), flags(0) + { + memset(orientation_matrix, 0, sizeof(orientation_matrix)); + } + +#ifdef ARDUINO + void print(Stream &stream) + { + const char *irq_status_str[2] = { "Disabled", "Enabled" }; + const char *master_intf_str[5] = { "None", "SPI0", "I2C0", "SPI1", "I2C1" }; + const char *power_mode_str[8] = { + "Sensor Not Present", "Power Down", "Suspend", "Self-Test", "Interrupt Motion", "One Shot", + "Low Power Active", "Active" + }; + + stream.printf("Field Name hex | Value (dec)\n"); + stream.printf("----------------------------------------------------------\n"); + stream.printf("Physical Sensor ID %02X | %d\n", sensor_type, sensor_type); + stream.printf("Driver ID %02X | %d\n", driver_id, driver_id); + stream.printf("Driver Version %02X | %d\n", driver_version, driver_version); + stream.printf("Current Consumption %02X | %0.3f mA\n", (int)power_current, power_current); + stream.printf("Dynamic Range %04X | %d\n", curr_range, curr_range); + stream.printf("Flags %02X | IRQ status : %s\n", flags, irq_status_str[irq_status ? 1 : 0]); + stream.printf(" | Master interface : %s\n", master_intf_str[master_intf]); + stream.printf(" | Power mode : %s\n", power_mode_str[power_mode]); + stream.printf("Slave Address %02X | %d\n", slave_address, slave_address); + stream.printf("GPIO Assignment %02X | %d\n", gpio_assignment, gpio_assignment); + stream.printf("Current Rate %08X | %.3f Hz\n", (unsigned int)curr_rate, curr_rate); + stream.printf("Number of axes %02X | %d\n", num_axis, num_axis); + stream.printf("Orientation Matrix %02X%02X%02X%02X%02X | %+02d %+02d %+02d |\n", + orientation_matrix[0], + orientation_matrix[1], + orientation_matrix[2], + orientation_matrix[3], + orientation_matrix[4], + orientation_matrix[0], + orientation_matrix[1], + orientation_matrix[2]); + stream.printf(" | %+02d %+02d %+02d |\n", + orientation_matrix[3], + orientation_matrix[4], + orientation_matrix[5]); + stream.printf(" | %+02d %+02d %+02d |\n", + orientation_matrix[6], + orientation_matrix[7], + orientation_matrix[8]); + stream.printf("Reserved %02X | %d\n", reserved, reserved); + stream.printf("\n"); + } +#else + void print() + { + const char *irq_status_str[2] = { "Disabled", "Enabled" }; + const char *master_intf_str[5] = { "None", "SPI0", "I2C0", "SPI1", "I2C1" }; + const char *power_mode_str[8] = { + "Sensor Not Present", "Power Down", "Suspend", "Self-Test", "Interrupt Motion", "One Shot", + "Low Power Active", "Active" + }; + + printf("Field Name hex | Value (dec)\n"); + printf("----------------------------------------------------------\n"); + printf("Physical Sensor ID %02X | %d\n", sensor_type, sensor_type); + printf("Driver ID %02X | %d\n", driver_id, driver_id); + printf("Driver Version %02X | %d\n", driver_version, driver_version); + printf("Current Consumption %02X | %0.3f mA\n", (int)power_current, power_current); + printf("Dynamic Range %04X | %d\n", curr_range, curr_range); + printf("Flags %02X | IRQ status : %s\n", flags, irq_status_str[irq_status ? 1 : 0]); + printf(" | Master interface : %s\n", master_intf_str[master_intf]); + printf(" | Power mode : %s\n", power_mode_str[power_mode]); + printf("Slave Address %02X | %d\n", slave_address, slave_address); + printf("GPIO Assignment %02X | %d\n", gpio_assignment, gpio_assignment); + printf("Current Rate %08X | %.3f Hz\n", (unsigned int)curr_rate, curr_rate); + printf("Number of axes %02X | %d\n", num_axis, num_axis); + printf("Orientation Matrix %02X%02X%02X%02X%02X | %+02d %+02d %+02d |\n", + orientation_matrix[0], + orientation_matrix[1], + orientation_matrix[2], + orientation_matrix[3], + orientation_matrix[4], + orientation_matrix[0], + orientation_matrix[1], + orientation_matrix[2]); + printf(" | %+02d %+02d %+02d |\n", + orientation_matrix[3], + orientation_matrix[4], + orientation_matrix[5]); + printf(" | %+02d %+02d %+02d |\n", + orientation_matrix[6], + orientation_matrix[7], + orientation_matrix[8]); + printf("Reserved %02X | %d\n", reserved, reserved); + printf("\n"); + } +#endif +}; + diff --git a/src/bosch/BoschSensorControl.hpp b/src/bosch/BoschSensorControl.hpp new file mode 100644 index 0000000..584a263 --- /dev/null +++ b/src/bosch/BoschSensorControl.hpp @@ -0,0 +1,82 @@ +/** + * + * @license MIT License + * + * Copyright (c) 2025 lewis he + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * @file BoschSensorControl.hpp + * @author Lewis He (lewishe@outlook.com) + * @date 2025-01-22 + * + */ +#pragma once + +#include +#include +#ifdef ARDUINO +#include +#endif + +class SensorBHI260APControl +{ +public: + bool wakeUpFIFOEnabled; + bool nonWakeUpFIFOEnabled; + bool statusFIFOEnabled; + bool debuggingEnabled; + bool faultEnabled; + bool interruptIsActiveLow; + bool interruptIsPulseTriggered; + bool interruptPinDriveIsOpenDrain; + + SensorBHI260APControl() : wakeUpFIFOEnabled(true), nonWakeUpFIFOEnabled(true), statusFIFOEnabled(true), + debuggingEnabled(true), faultEnabled(true), interruptIsActiveLow(false), + interruptIsPulseTriggered(false), interruptPinDriveIsOpenDrain(false) {} + +#ifdef ARDUINO + void print(Stream &stream) + { + stream.printf("Host interrupt control\n"); + stream.printf("-- Wake up FIFO :%s\n", (wakeUpFIFOEnabled ? "enabled" : "disabled")); + stream.printf("-- Non wake up FIFO :%s\n", (nonWakeUpFIFOEnabled ? "enabled" : "disabled")); + stream.printf("-- Status FIFO :%s\n", (statusFIFOEnabled ? "enabled" : "disabled")); + stream.printf("-- Debugging :%s\n", (debuggingEnabled ? "enabled" : "disabled")); + stream.printf("-- Fault :%s\n", (faultEnabled ? "enabled" : "disabled")); + stream.printf("-- Interrupt is :%s\n", (interruptIsActiveLow ? "active low" : "active high")); + stream.printf("-- Interrupt is :%s triggered.\n", (interruptIsPulseTriggered ? "pulse" : "level")); + stream.printf("-- Interrupt pin drive is :%s\n", (interruptPinDriveIsOpenDrain ? "open drain" : "push-pull")); + } +#else + void print() + { + printf("Host interrupt control\n"); + printf("-- Wake up FIFO :%s\n", (wakeUpFIFOEnabled ? "enabled" : "disabled")); + printf("-- Non wake up FIFO :%s\n", (nonWakeUpFIFOEnabled ? "enabled" : "disabled")); + printf("-- Status FIFO :%s\n", (statusFIFOEnabled ? "enabled" : "disabled")); + printf("-- Debugging :%s\n", (debuggingEnabled ? "enabled" : "disabled")); + printf("-- Fault :%s\n", (faultEnabled ? "enabled" : "disabled")); + printf("-- Interrupt is :%s\n", (interruptIsActiveLow ? "active low" : "active high")); + printf("-- Interrupt is :%s triggered.\n", (interruptIsPulseTriggered ? "pulse" : "level")); + printf("-- Interrupt pin drive is :%s\n", (interruptPinDriveIsOpenDrain ? "open drain" : "push-pull")); + } +#endif +}; + diff --git a/src/bosch/BoschSensorInfo.hpp b/src/bosch/BoschSensorInfo.hpp new file mode 100644 index 0000000..f15dbe6 --- /dev/null +++ b/src/bosch/BoschSensorInfo.hpp @@ -0,0 +1,205 @@ +/** + * + * @license MIT License + * + * Copyright (c) 2025 lewis he + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * @file BoschSensorInfo.hpp + * @author Lewis He (lewishe@outlook.com) + * @date 2025-01-22 + * + */ +#pragma once + +#include +#include +#include "bhy2_parse.h" +#include "bhy2_defs.h" +#include "common/common.h" +#ifdef ARDUINO +#include +#endif + +class BoschSensorInfo +{ +public: + uint16_t kernel_version; + uint16_t user_version; + uint16_t rom_version; + uint8_t product_id; + uint8_t host_status; + uint8_t feat_status; + uint8_t boot_status; + uint8_t sensor_error; + bhy2_dev *dev; + struct bhy2_sensor_info *info; + + BoschSensorInfo() : kernel_version(0), user_version(0), rom_version(0), + product_id(0), host_status(0), feat_status(0), boot_status(0), sensor_error(0), dev(nullptr), info(nullptr) + { + info = (struct bhy2_sensor_info *)calloc(BHY2_SENSOR_ID_MAX, sizeof(struct bhy2_sensor_info)); + } + + ~BoschSensorInfo() + { + free(info); + } + +#ifdef ARDUINO + void printVirtualSensorList(Stream &stream) + { + if (!dev) { + return; + } + if (feat_status & BHY2_FEAT_STATUS_OPEN_RTOS_MSK) { + stream.printf("Virtual sensor list.\n"); + stream.printf("Sensor ID | Sensor Name | ID | Ver | Min rate | Max rate |\n"); + stream.printf("----------+--------------------------------------+-----+-----+-----------+-----------|\n"); + for (uint8_t i = 0; i < BHY2_SENSOR_ID_MAX; i++) { + if (bhy2_is_sensor_available(i, dev)) { + if (i < BHY2_SENSOR_ID_CUSTOM_START) { + stream.printf(" %8u | %36s ", i, get_sensor_name(i)); + } + stream.printf("| %3u | %3u | %9.4f | %9.4f |\n", + (unsigned int)info[i].driver_id, + (unsigned int)info[i].driver_version, + info[i].min_rate.f_val, + info[i].max_rate.f_val); + } + } + } + } + + void printBootStatus(Stream &stream) + { + stream.printf("Boot Status : 0x%02x: ", boot_status); + if (boot_status & BHY2_BST_FLASH_DETECTED) { + stream.printf("\tFlash detected. "); + } + if (boot_status & BHY2_BST_FLASH_VERIFY_DONE) { + stream.printf("\tFlash verify done. "); + } + if (boot_status & BHY2_BST_FLASH_VERIFY_ERROR) { + stream.printf("Flash verification failed. "); + } + if (boot_status & BHY2_BST_NO_FLASH) { + stream.printf("\tNo flash installed. "); + } + if (boot_status & BHY2_BST_HOST_INTERFACE_READY) { + stream.printf("\tHost interface ready. "); + } + if (boot_status & BHY2_BST_HOST_FW_VERIFY_DONE) { + stream.printf("\tFirmware verification done. "); + } + if (boot_status & BHY2_BST_HOST_FW_VERIFY_ERROR) { + stream.printf("\tFirmware verification error. "); + } + if (boot_status & BHY2_BST_HOST_FW_IDLE) { + stream.printf("\tFirmware halted. "); + } + } + + void printInfo(Stream &stream) + { + stream.printf("Product ID : %02x\n", product_id); + stream.printf("Kernel version : %04u\n", kernel_version); + stream.printf("User version : %04u\n", user_version); + stream.printf("ROM version : %04u\n", rom_version); + stream.printf("Power state : %s\n", (host_status & BHY2_HST_POWER_STATE) ? "sleeping" : "active"); + stream.printf("Host interface : %s\n", (host_status & BHY2_HST_HOST_PROTOCOL) ? "SPI" : "I2C"); + stream.printf("Feature status : 0x%02x\n", feat_status); + printBootStatus(stream); + if (sensor_error) { + stream.printf( "%s\n", get_sensor_error_text(sensor_error)); + } + printVirtualSensorList(stream); + } +#else + void printVirtualSensorList() + { + if (!dev) { + return; + } + if (feat_status & BHY2_FEAT_STATUS_OPEN_RTOS_MSK) { + printf("Virtual sensor list.\n"); + printf("Sensor ID | Sensor Name | ID | Ver | Min rate | Max rate |\n"); + printf("----------+--------------------------------------+-----+-----+-----------+-----------|\n"); + for (uint8_t i = 0; i < BHY2_SENSOR_ID_MAX; i++) { + if (bhy2_is_sensor_available(i, dev)) { + if (i < BHY2_SENSOR_ID_CUSTOM_START) { + printf(" %8u | %36s ", i, get_sensor_name(i)); + } + printf("| %3u | %3u | %9.4f | %9.4f |\n", + (unsigned int)info[i].driver_id, + (unsigned int)info[i].driver_version, + info[i].min_rate.f_val, + info[i].max_rate.f_val); + } + } + } + } + + void printBootStatus() + { + printf("Boot Status : 0x%02x: ", boot_status); + if (boot_status & BHY2_BST_FLASH_DETECTED) { + printf("\tFlash detected. "); + } + if (boot_status & BHY2_BST_FLASH_VERIFY_DONE) { + printf("\tFlash verify done. "); + } + if (boot_status & BHY2_BST_FLASH_VERIFY_ERROR) { + printf("Flash verification failed. "); + } + if (boot_status & BHY2_BST_NO_FLASH) { + printf("\tNo flash installed. "); + } + if (boot_status & BHY2_BST_HOST_INTERFACE_READY) { + printf("\tHost interface ready. "); + } + if (boot_status & BHY2_BST_HOST_FW_VERIFY_DONE) { + printf("\tFirmware verification done. "); + } + if (boot_status & BHY2_BST_HOST_FW_VERIFY_ERROR) { + printf("\tFirmware verification error. "); + } + if (boot_status & BHY2_BST_HOST_FW_IDLE) { + printf("\tFirmware halted. "); + } + } + + void printInfo() + { + printf("Product ID : %02x\n", product_id); + printf("Kernel version : %04u\n", kernel_version); + printf("User version : %04u\n", user_version); + printf("ROM version : %04u\n", rom_version); + printf("Power state : %s\n", (host_status & BHY2_HST_POWER_STATE) ? "sleeping" : "active"); + printf("Host interface : %s\n", (host_status & BHY2_HST_HOST_PROTOCOL) ? "SPI" : "I2C"); + printf("Feature status : 0x%02x\n", feat_status); + if (sensor_error) { + printf( "%s\n", get_sensor_error_text(sensor_error)); + } + printBootStatus(); + printVirtualSensorList(); + } +#endif +}; diff --git a/src/bosch/SensorBhy2Define.h b/src/bosch/SensorBhy2Define.h index 786226f..afc497b 100644 --- a/src/bosch/SensorBhy2Define.h +++ b/src/bosch/SensorBhy2Define.h @@ -29,12 +29,10 @@ */ #pragma once -#include -#include +#include "../SensorLib.h" #define BHI260AP_SLAVE_ADDRESS_L 0x28 #define BHI260AP_SLAVE_ADDRESS_H 0x29 -#define BHY_PROCESS_BUFFER_SIZE 512 #define BHY2_RLST_CHECK(ret, str, val) \ do \ diff --git a/src/bosch/common/bosch_interfaces.cpp b/src/bosch/common/bosch_interfaces.cpp deleted file mode 100644 index 1dab7bc..0000000 --- a/src/bosch/common/bosch_interfaces.cpp +++ /dev/null @@ -1,166 +0,0 @@ -/** - * - * @license MIT License - * - * Copyright (c) 2022 lewis he - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - * @file bosch_interfaces.cpp - * @author Lewis He (lewishe@outlook.com) - * @date 2023-10-09 - * - */ -#include "bosch_interfaces.h" - -#if defined(ARDUINO) - -#if defined(ARDUINO_ARCH_RP2040) -SPISettings SensorInterfaces::__spiSetting = SPISettings(); -#else -SPISettings SensorInterfaces::__spiSetting = SPISettings(4000000, SPI_DATA_ORDER, SPI_MODE0); -#endif - -void SensorInterfaces::close_interfaces(SensorLibConfigure config) -{ - -} - -bool SensorInterfaces::setup_interfaces(SensorLibConfigure config) -{ - if (config.irq != SENSOR_PIN_NONE) { - pinMode(config.irq, INPUT_PULLDOWN); - } - switch (config.intf) { - case SENSORLIB_I2C_INTERFACE: -#if defined(ARDUINO_ARCH_RP2040) - config.u.i2c_dev.wire->end(); - config.u.i2c_dev.wire->setSDA(config.u.i2c_dev.sda); - config.u.i2c_dev.wire->setSCL(config.u.i2c_dev.scl); - config.u.i2c_dev.wire->begin(); -#elif defined(NRF52840_XXAA) || defined(NRF52832_XXAA) - config.u.i2c_dev.wire->end(); - config.u.i2c_dev.wire->setPins(config.u.i2c_dev.sda, config.u.i2c_dev.scl); - config.u.i2c_dev.wire->begin(); -#else - config.u.i2c_dev.wire->begin(config.u.i2c_dev.sda, config.u.i2c_dev.scl); -#endif - config.u.i2c_dev.wire->beginTransmission(config.u.i2c_dev.addr); - if (config.u.i2c_dev.wire->endTransmission() != 0) { - return false; - } - break; - case SENSORLIB_SPI_INTERFACE: - pinMode(config.u.spi_dev.cs, OUTPUT); - digitalWrite(config.u.spi_dev.cs, HIGH); -#if defined(ARDUINO_ARCH_RP2040) - config.u.spi_dev.spi->setSCK(config.u.spi_dev.sck); - config.u.spi_dev.spi->setRX(config.u.spi_dev.miso); - config.u.spi_dev.spi->setTX(config.u.spi_dev.mosi); - config.u.spi_dev.spi->begin(); -#elif defined(ARDUINO_ARCH_NRF52) - config.u.spi_dev.spi->setPins(config.u.spi_dev.miso, config.u.spi_dev.sck, config.u.spi_dev.mosi); - config.u.spi_dev.spi->begin(); -#elif defined(ARDUINO_ARCH_STM32) - config.u.spi_dev.spi->setSCLK(config.u.spi_dev.sck); - config.u.spi_dev.spi->setMISO(config.u.spi_dev.miso); - config.u.spi_dev.spi->setMOSI(config.u.spi_dev.mosi); - config.u.spi_dev.spi->begin(); -#else -config.u.spi_dev.spi->begin(config.u.spi_dev.sck, config.u.spi_dev.miso, config.u.spi_dev.mosi); -#endif - break; - default: - break; - } - return true; -} - - - - -int8_t SensorInterfaces::bhy2_spi_read(uint8_t reg_addr, uint8_t *reg_data, uint32_t length, void *intf_ptr) -{ - SensorLibConfigure *pConfig = (SensorLibConfigure *)intf_ptr; - if (!pConfig) { - return DEV_WIRE_ERR; - } - digitalWrite(pConfig->u.spi_dev.cs, LOW); - pConfig->u.spi_dev.spi->beginTransaction(__spiSetting); - pConfig->u.spi_dev.spi->transfer((reg_addr)); - for (size_t i = 0; i < length; i++) { - reg_data[i] = pConfig->u.spi_dev.spi->transfer(0x00); - } - pConfig->u.spi_dev.spi->endTransaction(); - digitalWrite(pConfig->u.spi_dev.cs, HIGH); - - return DEV_WIRE_NONE; -} - -int8_t SensorInterfaces::bhy2_spi_write(uint8_t reg_addr, const uint8_t *reg_data, uint32_t length, void *intf_ptr) -{ - SensorLibConfigure *pConfig = (SensorLibConfigure *)intf_ptr; - if (!pConfig) { - return DEV_WIRE_ERR; - } - digitalWrite(pConfig->u.spi_dev.cs, LOW); - pConfig->u.spi_dev.spi->beginTransaction(__spiSetting); - pConfig->u.spi_dev.spi->transfer(reg_addr); - pConfig->u.spi_dev.spi->transfer((uint8_t *)reg_data, length); - pConfig->u.spi_dev.spi->endTransaction(); - digitalWrite(pConfig->u.spi_dev.cs, HIGH); - return DEV_WIRE_NONE; -} - -int8_t SensorInterfaces::bhy2_i2c_read(uint8_t reg_addr, uint8_t *reg_data, uint32_t length, void *intf_ptr) -{ - SensorLibConfigure *pConfig = (SensorLibConfigure *)intf_ptr; - if (!pConfig) { - return DEV_WIRE_ERR; - } - pConfig->u.i2c_dev.wire->beginTransmission(pConfig->u.i2c_dev.addr); - pConfig->u.i2c_dev.wire->write(reg_addr); - if (pConfig->u.i2c_dev.wire->endTransmission() != 0) { - return DEV_WIRE_ERR; - } - pConfig->u.i2c_dev.wire->requestFrom(pConfig->u.i2c_dev.addr, length); - return pConfig->u.i2c_dev.wire->readBytes(reg_data, length) == length ? DEV_WIRE_NONE : DEV_WIRE_ERR; -} - -int8_t SensorInterfaces::bhy2_i2c_write(uint8_t reg_addr, const uint8_t *reg_data, uint32_t length, void *intf_ptr) -{ - SensorLibConfigure *pConfig = (SensorLibConfigure *)intf_ptr; - if (!pConfig) { - return DEV_WIRE_ERR; - } - pConfig->u.i2c_dev.wire->beginTransmission(pConfig->u.i2c_dev.addr); - pConfig->u.i2c_dev.wire->write(reg_addr); - pConfig->u.i2c_dev.wire->write(reg_data, length); - return (pConfig->u.i2c_dev.wire->endTransmission() == 0) ? 0 : DEV_WIRE_ERR; - -} - - -void SensorInterfaces::bhy2_delay_us(uint32_t us, void *private_data) -{ - (void)private_data; - delayMicroseconds(us); -} - -#endif /*Arduino */ \ No newline at end of file diff --git a/src/bosch/common/common.cpp b/src/bosch/common/common.cpp index c7f117d..9304ff3 100644 --- a/src/bosch/common/common.cpp +++ b/src/bosch/common/common.cpp @@ -973,18 +973,3 @@ const char *get_sensor_axis_names(uint8_t sensor_id) return ret; } - -void check_bhy2_api(unsigned int line, const char *func, int8_t val) -{ - int i = 3; - while (i--) { - - Serial.printf("BHI260 API failed at line %u. The function %s returned error code %d. %s\r\n", - line, - func, - val, - get_api_error(val)); - delay(1000); - } -} - diff --git a/src/bosch/common/common.h b/src/bosch/common/common.h index ed25075..4bbdc76 100644 --- a/src/bosch/common/common.h +++ b/src/bosch/common/common.h @@ -38,7 +38,6 @@ #ifndef _COMMON_H_ #define _COMMON_H_ -#include "bosch_interfaces.h" #include "bosch/bhy2.h" #include "bosch/bhi3.h" #include "bosch/bhi3_multi_tap.h" @@ -48,11 +47,6 @@ #include "bosch/bhy2_head_tracker.h" -#define BHY2_ASSERT(x) if (x) check_bhy2_api(__LINE__, __FUNCTION__, x) - - - -void check_bhy2_api(unsigned int line, const char *func, int8_t val); void time_to_s_ns(uint64_t time_ticks, uint32_t *s, uint32_t *ns, uint64_t *tns); const char *get_api_error(int8_t error_code); const char *get_sensor_error_text(uint8_t sensor_error); diff --git a/src/platform/SensorCommBase.hpp b/src/platform/SensorCommBase.hpp new file mode 100644 index 0000000..8b0a5ce --- /dev/null +++ b/src/platform/SensorCommBase.hpp @@ -0,0 +1,197 @@ +/** + * + * @license MIT License + * + * Copyright (c) 2025 lewis he + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * @file SensorCommBase.hpp + * @author Lewis He (lewishe@outlook.com) + * @date 2025-01-18 + * + */ +#pragma once +#include "SensorLib.h" +#include + +typedef struct { + uint8_t byte0 : 8; + uint8_t byte1 : 8; + uint8_t byte2 : 8; + uint8_t byte3 : 8; +} ByteStruct; + +typedef union { + uint32_t value; + ByteStruct bytes; + uint8_t byte_array[4]; +} ByteUnion; + +#if __cplusplus == 201103L +namespace std +{ +template +std::unique_ptr make_unique(Args &&... args) +{ + return std::unique_ptr(new T(std::forward(args)...)); +} +} +#endif + + +template +constexpr size_t arraySize(const T (&arr)[N]) +{ + return N; +} + + +class CommParamsBase +{ +public: + virtual ~CommParamsBase() = default; +}; + +class I2CParam : public CommParamsBase +{ +public: + enum I2CParamType { + I2C_SET_ADDR, + I2C_SET_FLAG, + I2C_SET_CLOCK, + }; + + I2CParam(I2CParamType type, uint8_t params) : type(type), params(params) {} + + uint8_t getParams() const + { + return params; + } + uint8_t getType() const + { + return type; + } + +protected: + enum I2CParamType type; + uint32_t params; +}; + +#if !defined(ARDUINO) + +#define SPI_MODE0 0 +#define SPI_MODE1 1 +#define SPI_MODE2 2 +#define SPI_MODE3 3 + +#define SPI_LSB 0 +#define SPI_MSB 1 + +class SPISettings +{ +public: + SPISettings() : clock(1000000), bitOrder(SPI_MSB), dataMode(SPI_MODE0) {} + SPISettings(uint32_t clock, uint8_t bitOrder, uint8_t dataMode) : + clock(clock), bitOrder(bitOrder), dataMode(dataMode) {} + uint32_t clock; + uint8_t bitOrder; + uint8_t dataMode; +}; +#endif + + +class SPIParam : public CommParamsBase +{ +private: + SPISettings setting; +public: + SPIParam(SPISettings setting) : setting(setting) {} + SPISettings getSetting() const + { + return setting; + } +}; + +class SensorCommBase +{ +public: + virtual bool init() = 0; + virtual void deinit() = 0; + + virtual int readRegister(const uint8_t reg) = 0; + virtual int readRegister(const uint8_t reg, uint8_t *buf, size_t len) = 0; + + virtual int writeRegister(const uint8_t reg, uint8_t val) = 0; + virtual int writeRegister(const uint8_t reg, uint8_t *buf, size_t len) = 0; + virtual int writeRegister(const uint8_t reg, uint8_t norVal, uint8_t orVal) = 0; + virtual int writeBuffer(uint8_t *buffer, size_t len) = 0; + + virtual int writeThenRead(const uint8_t *write_buffer, size_t write_len, uint8_t *read_buffer, size_t read_len) = 0; + + virtual bool setRegisterBit(const uint8_t reg, uint8_t bit) = 0; + virtual bool clrRegisterBit(const uint8_t reg, uint8_t bit) = 0; + virtual bool getRegisterBit(const uint8_t reg, uint8_t bit) = 0; + + virtual void setParams(const CommParamsBase ¶ms) = 0; + virtual ~SensorCommBase() = default; +}; + +class SensorHalCustom +{ +public: + using CustomWrite = void(*)(uint8_t pin, uint8_t level); + using CustomRead = uint8_t(*)(uint8_t pin); + using CustomMode = void(*)(uint8_t pin, uint8_t mode); + + SensorHalCustom() : writeCallback(nullptr), readCallback(nullptr), modeCallback(nullptr) {} + + void setCustomWrite(CustomWrite callback) + { + writeCallback = callback; + } + + void setCustomRead(CustomRead callback) + { + readCallback = callback; + } + + void setCustomMode(CustomMode callback) + { + modeCallback = callback; + } + +protected: + CustomWrite writeCallback; + CustomRead readCallback; + CustomMode modeCallback; +}; + +class SensorHal : public SensorHalCustom +{ +public: + virtual void pinMode(uint8_t pin, uint8_t mode) = 0; + virtual void digitalWrite(uint8_t pin, uint8_t level) = 0; + virtual uint8_t digitalRead(uint8_t pin) = 0; + virtual uint32_t millis() = 0; + virtual void delay(uint32_t ms) = 0; + virtual void delayMicroseconds(uint32_t us) = 0; +}; + + diff --git a/src/platform/SensorCommCustom.hpp b/src/platform/SensorCommCustom.hpp new file mode 100644 index 0000000..ebf069c --- /dev/null +++ b/src/platform/SensorCommCustom.hpp @@ -0,0 +1,153 @@ +/** + * + * @license MIT License + * + * Copyright (c) 2025 lewis he + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * @file SensorCommCustom.hpp + * @author Lewis He (lewishe@outlook.com) + * @date 2025-01-18 + * + */ +#pragma once + +#include "SensorCommBase.hpp" + +class SensorCommCustom : public SensorCommBase +{ +public: + using CustomCallback = bool(*)(uint8_t addr, uint8_t reg, uint8_t *buf, size_t len, bool writeReg, bool isWrite); + + SensorCommCustom(CustomCallback callback, uint8_t addr) : customCallback(callback), addr(addr) {} + + bool init() override + { + return true; + } + + void deinit() override {} + + int writeRegister(const uint8_t reg, uint8_t val) override + { + return writeRegister(reg, &val, 1); + } + + int writeRegister(const uint8_t reg, uint8_t norVal, uint8_t orVal) override + { + int val = readRegister(reg); + if (val < 0) { + return -1; + } + val &= norVal; + val |= orVal; + return writeRegister(reg, reinterpret_cast(&val), 1); + } + + int writeRegister(const uint8_t reg, uint8_t *buf, size_t len) override + { + if (customCallback(addr, reg, buf, len, true, true)) { + return 0; + } else { + return -1; + } + } + + int writeBuffer(uint8_t *buffer, size_t len) + { + if (customCallback(addr, 0x00, buffer, len, false, true)) { + return 0; + } else { + return -1; + } + } + + int readRegister(const uint8_t reg) override + { + uint8_t value = 0x00; + if (readRegister(reg, &value, 1) < 0) { + return -1; + } + return value; + } + + int readRegister(const uint8_t reg, uint8_t *buf, size_t len) override + { + if (customCallback(addr, reg, buf, len, true, false)) { + return 0; + } else { + return -1; + } + } + + int writeThenRead(const uint8_t *write_buffer, size_t write_len, uint8_t *read_buffer, size_t read_len) override + { + writeBuffer((uint8_t *)write_buffer, write_len); + if (customCallback(addr, 0x00, read_buffer, read_len, false, false)) { + return 0; + } else { + return -1; + } + } + + bool setRegisterBit(const uint8_t reg, uint8_t bit) override + { + uint8_t value = readRegister(reg); + value |= (1 << bit); + return writeRegister(reg, reinterpret_cast(&value), 1) == 0; + } + + bool clrRegisterBit(const uint8_t reg, uint8_t bit) override + { + uint8_t value = readRegister(reg); + value &= ~(1 << bit); + return writeRegister(reg, reinterpret_cast(&value), 1) == 0; + } + + bool getRegisterBit(const uint8_t reg, uint8_t bit) override + { + uint8_t value = readRegister(reg); + return (value & (1 << bit)) != 0; + } + + void setParams(const CommParamsBase ¶ms) override + { +#if defined(__cpp_rtti) + const auto pdat = dynamic_cast(¶ms); +#else + const auto pdat = static_cast(¶ms); +#endif + uint8_t type = pdat->getType(); + switch (type) { + case I2CParam::I2C_SET_ADDR: + addr = pdat->getParams(); + break; + case I2CParam::I2C_SET_FLAG: + // TODO: + // sendStopFlag = pdat->getParams(); + break; + default: + break; + } + } +private: + CustomCallback customCallback; + uint8_t addr; +}; diff --git a/src/platform/SensorCommCustomHal.hpp b/src/platform/SensorCommCustomHal.hpp new file mode 100644 index 0000000..ac57310 --- /dev/null +++ b/src/platform/SensorCommCustomHal.hpp @@ -0,0 +1,101 @@ +/** + * + * @license MIT License + * + * Copyright (c) 2025 lewis he + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * @file SensorCommCustomHal.hpp + * @author Lewis He (lewishe@outlook.com) + * @date 2025-01-18 + * + */ +#pragma once + +#include "SensorCommBase.hpp" + +class SensorCommCustomHal : public SensorHal +{ +public: + enum Operation { + OP_PINMODE, + OP_DIGITALWRITE, + OP_DIGITALREAD, + OP_MILLIS, + OP_DELAY, + OP_DELAYMICROSECONDS, + }; + + using CustomHalCallback = uint32_t (*)(Operation op, void *param1, void *param2); + + SensorCommCustomHal(CustomHalCallback callback) : halCallback(callback) {} + + void pinMode(uint8_t pin, uint8_t mode) override + { + if (modeCallback) { + modeCallback(pin, mode); + } else if (halCallback) { + halCallback(OP_PINMODE, reinterpret_cast(pin), reinterpret_cast(mode)); + } + } + + void digitalWrite(uint8_t pin, uint8_t level) override + { + if (writeCallback) { + writeCallback(pin, level); + } else if (halCallback) { + halCallback(OP_DIGITALWRITE, reinterpret_cast(pin), reinterpret_cast(level)); + } + } + + uint8_t digitalRead(uint8_t pin) override + { + if (readCallback) { + return readCallback(pin); + } else if (halCallback) { + return halCallback(OP_DIGITALREAD, reinterpret_cast(pin), nullptr); + } + return 0; + } + + uint32_t millis()override + { + if (halCallback) { + return halCallback(OP_MILLIS, nullptr, nullptr); + } + return 0; + } + + void delay(uint32_t ms) override + { + if (halCallback) { + halCallback(OP_DELAY, reinterpret_cast(ms), nullptr); + } + } + + void delayMicroseconds(uint32_t us)override + { + if (halCallback) { + halCallback(OP_DELAYMICROSECONDS, reinterpret_cast(us), nullptr); + } + } +private: + CustomHalCallback halCallback; +}; \ No newline at end of file diff --git a/src/bosch/common/bosch_interfaces.h b/src/platform/SensorCommDebug.cpp similarity index 58% rename from src/bosch/common/bosch_interfaces.h rename to src/platform/SensorCommDebug.cpp index cf69ae2..f3eda60 100644 --- a/src/bosch/common/bosch_interfaces.h +++ b/src/platform/SensorCommDebug.cpp @@ -2,7 +2,7 @@ * * @license MIT License * - * Copyright (c) 2022 lewis he + * Copyright (c) 2025 lewis he * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -22,40 +22,40 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. * - * @file bosch_interfaces.h + * @file SensorCommDebug.cpp * @author Lewis He (lewishe@outlook.com) - * @date 2023-10-09 + * @date 2025-01-24 * */ -#pragma once +#include "SensorCommDebug.hpp" -#include "SensorLib.h" -#if defined(ARDUINO) -class SensorInterfaces +void SensorLibDumpBuffer(const uint8_t *buffer, size_t size) { -public: - static bool setup_interfaces(SensorLibConfigure config); - static void close_interfaces(SensorLibConfigure config); - static int8_t bhy2_spi_read(uint8_t reg_addr, uint8_t *reg_data, uint32_t length, void *intf_ptr); - static int8_t bhy2_spi_write(uint8_t reg_addr, const uint8_t *reg_data, uint32_t length, void *intf_ptr); - static int8_t bhy2_i2c_read(uint8_t reg_addr, uint8_t *reg_data, uint32_t length, void *intf_ptr); - static int8_t bhy2_i2c_write(uint8_t reg_addr, const uint8_t *reg_data, uint32_t length, void *intf_ptr); - static void bhy2_delay_us(uint32_t us, void *private_data); - -private: - static SPISettings __spiSetting; -}; - -#endif - - - - - - - - - - + printf("->Buffer dump\n"); + const int bytesPerLine = 16; + for (size_t i = 0; i < size; i += bytesPerLine) { + printf("%08zx ", i); + for (int j = 0; j < bytesPerLine; ++j) { + if (i + j < size) { + printf("%02x ", buffer[i + j]); + } else { + printf(" "); + } + if (j == 7) { + printf(" "); + } + } + printf(" "); + for (int j = 0; j < bytesPerLine; ++j) { + if (i + j < size) { + char c = buffer[i + j]; + printf("%c", isprint(c) ? c : '.'); + } else { + printf(" "); + } + } + printf("\n"); + } +} diff --git a/src/platform/SensorCommDebug.hpp b/src/platform/SensorCommDebug.hpp new file mode 100644 index 0000000..060e334 --- /dev/null +++ b/src/platform/SensorCommDebug.hpp @@ -0,0 +1,150 @@ +/** + * + * @license MIT License + * + * Copyright (c) 2025 lewis he + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * @file SensorCommDebug.hpp + * @author Lewis He (lewishe@outlook.com) + * @date 2025-01-20 + * + */ +#pragma once + + +// Usage example, define SENSORLIB_DEBUG as the platform's print function +// *Arduino #define SENSORLIB_DEBUG Serial.printf */ +// *Other #define SENSORLIB_DEBUG printf */ + +#ifndef ARDUINO +#include +#include +#include +#else +#include +#endif + +#ifdef SENSORLIB_DEBUG +namespace +{ +#ifdef __GNUC__ +#define UNUSED __attribute__((unused)) +#else +#define UNUSED +#endif + + +template +static void DBG_PLAIN(T last); + + +template +static void DBG_PLAIN(T head, Args... tail); + + +template +static void DBG(Args... args); + + +template +static void printParam(T value) UNUSED; + +static void printParam(const char *str) UNUSED; + +static void printParam(int num) UNUSED; + +static void printParam(double num) UNUSED; + +static void printParam(float num) UNUSED; + +static void printParam(unsigned long num) UNUSED; + + +template +static void DBG_PLAIN(T last) +{ + printParam(last); + SENSORLIB_DEBUG("\n"); +} + +template +static void DBG_PLAIN(T head, Args... tail) +{ + printParam(head); + SENSORLIB_DEBUG(" "); + DBG_PLAIN(tail...); +} + +template +static void DBG(Args... args) +{ + SENSORLIB_DEBUG("["); + time_t now = time(NULL); + SENSORLIB_DEBUG("%lu] ", (unsigned long)now); + DBG_PLAIN(args...); +} + + +template +void printParam(T value) +{ + SENSORLIB_DEBUG("%s", "Unsupported type"); +} + + +void printParam(const char *str) +{ + SENSORLIB_DEBUG("%s", str); +} + +void printParam(int num) +{ + SENSORLIB_DEBUG("%d", num); +} + + +void printParam(double num) +{ + SENSORLIB_DEBUG("%lf", num); +} + + +void printParam(float num) +{ + SENSORLIB_DEBUG("%f", num); +} + + +void printParam(unsigned long num) +{ + SENSORLIB_DEBUG("%lu", num); +} + + +} // namespace +#else +#define DBG_PLAIN(...) +#define DBG(...) +#endif + + +void SensorLibDumpBuffer(const uint8_t *buffer, size_t size); + diff --git a/src/platform/SensorCommEnhanced.hpp b/src/platform/SensorCommEnhanced.hpp new file mode 100644 index 0000000..e6a18a8 --- /dev/null +++ b/src/platform/SensorCommEnhanced.hpp @@ -0,0 +1,117 @@ +/** + * + * @license MIT License + * + * Copyright (c) 2025 lewis he + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * @file SensorCommEnhanced.hpp + * @author Lewis He (lewishe@outlook.com) + * @date 2025-01-18 + * + */ +#pragma once + +#include "SensorCommBase.hpp" +#include + +class EnhancedSensorCommBase : public SensorCommBase +{ +private: + template + std::vector splitRegister(T reg) + { + std::vector result; + const size_t size = sizeof(T); + for (size_t i = 0; i < size; ++i) { + result.push_back(static_cast(reg >> (8 * (size - 1 - i)))); + } + return result; + } + + template + int readRegisterImpl(T reg, uint8_t *buf, size_t len) + { + std::vector splitReg = splitRegister(reg); + return readRegister(splitReg[0], buf, len); + } + + + template + int writeRegisterImpl(T reg, uint8_t val) + { + std::vector splitReg = splitRegister(reg); + return writeRegister(splitReg[0], val); + } + + + template + int writeRegisterImpl(T reg, uint8_t *buf, size_t len) + { + std::vector splitReg = splitRegister(reg); + return writeRegister(splitReg[0], buf, len); + } + + + template + int writeRegisterImpl(T reg, uint8_t norVal, uint8_t orVal) + { + std::vector splitReg = splitRegister(reg); + return writeRegister(splitReg[0], norVal, orVal); + } + + +public: + template + int readRegister(T reg) + { + std::vector splitReg = splitRegister(reg); + return readRegister(splitReg[0]); + } + + + template + int readRegister(T reg, uint8_t *buf, size_t len) + { + return readRegisterImpl(reg, buf, len); + } + + + template + int writeRegister(T reg, uint8_t val) + { + return writeRegisterImpl(reg, val); + } + + + template + int writeRegister(T reg, uint8_t *buf, size_t len) + { + return writeRegisterImpl(reg, buf, len); + } + + + template + int writeRegister(T reg, uint8_t norVal, uint8_t orVal) + { + return writeRegisterImpl(reg, norVal, orVal); + } +}; + diff --git a/src/platform/SensorCommStatic.cpp b/src/platform/SensorCommStatic.cpp new file mode 100644 index 0000000..3ed93a3 --- /dev/null +++ b/src/platform/SensorCommStatic.cpp @@ -0,0 +1,61 @@ +/** + * + * @license MIT License + * + * Copyright (c) 2025 lewis he + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * @file SensorCommStatic.cpp + * @author Lewis He (lewishe@outlook.com) + * @date 2025-01-21 + * + */ +#include "SensorCommBase.hpp" +#include "SensorCommStatic.hpp" + +int8_t SensorCommStatic::sensor_static_read_data(uint8_t reg_addr, uint8_t *reg_data, uint32_t length, void *intf_ptr) +{ + SensorCommStatic *pThis = static_cast(intf_ptr); + if (pThis) { + return pThis->comm->readRegister(reg_addr, reg_data, length); + } + log_e("This ptr is empty!"); + return -1; +} + +int8_t SensorCommStatic::sensor_static_write_data(uint8_t reg_addr, const uint8_t *reg_data, uint32_t length, void *intf_ptr) +{ + SensorCommStatic *pThis = static_cast(intf_ptr); + if (pThis) { + return pThis->comm->writeRegister(reg_addr, (uint8_t *) reg_data, length); + } + log_e("This ptr is empty!"); + return -1; +} + +void SensorCommStatic::sensor_static_delay_us(uint32_t us, void *private_data) +{ + SensorCommStatic *pThis = static_cast(private_data); + if (pThis) { + pThis->hal->delayMicroseconds(us); + } else { + log_e("This ptr is empty!"); + } +} \ No newline at end of file diff --git a/src/SensorBMM150.cpp b/src/platform/SensorCommStatic.hpp similarity index 64% rename from src/SensorBMM150.cpp rename to src/platform/SensorCommStatic.hpp index f6c28fa..7375bb7 100644 --- a/src/SensorBMM150.cpp +++ b/src/platform/SensorCommStatic.hpp @@ -2,7 +2,7 @@ * * @license MIT License * - * Copyright (c) 2024 lewis he + * Copyright (c) 2025 lewis he * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -22,15 +22,29 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. * - * @file SensorBMM150.cpp + * @file SensorCommStatic.hpp * @author Lewis He (lewishe@outlook.com) - * @date 2024-07-24 + * @date 2025-01-21 * */ -#include "SensorBMM150.hpp" +#pragma once + +#include "SensorCommBase.hpp" + +class SensorCommStatic +{ +public: + SensorCommStatic(SensorCommBase *comm, SensorHal *hal) + : comm(comm), hal(hal) + { + } + static int8_t sensor_static_read_data(uint8_t reg_addr, uint8_t *reg_data, uint32_t length, void *intf_ptr); + static int8_t sensor_static_write_data(uint8_t reg_addr,const uint8_t *reg_data, uint32_t length, void *intf_ptr); + static void sensor_static_delay_us(uint32_t us, void *private_data); +protected: + SensorCommBase *comm; + SensorHal *hal; +}; -#if defined(ARDUINO) -volatile bool SensorBMM150::__data_available; -#endif diff --git a/src/platform/SensorDataTypeClass.hpp b/src/platform/SensorDataTypeClass.hpp new file mode 100644 index 0000000..cd33caf --- /dev/null +++ b/src/platform/SensorDataTypeClass.hpp @@ -0,0 +1,135 @@ +/** + * + * @license MIT License + * + * Copyright (c) 2025 lewis he + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * @file SensorDataTypeClass.hpp + * @author Lewis He (lewishe@outlook.com) + * @date 2025-01-23 + * + */ +#pragma once + +template +class Vector3D { +public: + Vector3D(T x = 0, T y = 0, T z = 0) : x(x), y(y), z(z) {} + + // Get the x-axis component + T getX() const { return x; } + // Get the y-axis component + T getY() const { return y; } + // Get the z-axis component + T getZ() const { return z; } + + // Set the x-axis component + void setX(T value) { x = value; } + // Set the y-axis component + void setY(T value) { y = value; } + // Set the z-axis component + void setZ(T value) { z = value; } + +private: + T x; + T y; + T z; +}; + +class AccelerationData { +public: + AccelerationData(const Vector3D& accel = Vector3D()) : acceleration(accel) {} + + // Get acceleration data + Vector3D getAcceleration() const { return acceleration; } + // Set acceleration data + void setAcceleration(const Vector3D& accel) { acceleration = accel; } + +private: + Vector3D acceleration; +}; + +class GyroscopeData { +public: + GyroscopeData(const Vector3D& gyro = Vector3D()) : gyroscope(gyro) {} + + // Get gyroscope data + Vector3D getGyroscope() const { return gyroscope; } + // Set gyroscope data + void setGyroscope(const Vector3D& gyro) { gyroscope = gyro; } + +private: + Vector3D gyroscope; +}; + +class MagnetometerData { +public: + MagnetometerData(const Vector3D& mag = Vector3D()) : magnetometer(mag) {} + + // Get magnetometer data + Vector3D getMagnetometer() const { return magnetometer; } + // Set magnetometer data + void setMagnetometer(const Vector3D& mag) { magnetometer = mag; } + +private: + Vector3D magnetometer; +}; + + +class IMUData { +public: + IMUData(const AccelerationData* accel = nullptr, + const GyroscopeData* gyro = nullptr, + const MagnetometerData* mag = nullptr) + : acceleration(accel), gyroscope(gyro), magnetometer(mag) {} + + // Get the acceleration data pointer + const AccelerationData* getAccelerationData() const { return acceleration; } + // Get the gyroscope data pointer + const GyroscopeData* getGyroscopeData() const { return gyroscope; } + // Get the magnetometer data pointer + const MagnetometerData* getMagnetometerData() const { return magnetometer; } + + // Set the acceleration data pointer + void setAccelerationData(const AccelerationData* accel) { acceleration = accel; } + // Set the gyroscope data pointer + void setGyroscopeData(const GyroscopeData* gyro) { gyroscope = gyro; } + // Set the magnetometer data pointer + void setMagnetometerData(const MagnetometerData* mag) { magnetometer = mag; } + +private: + const AccelerationData* acceleration; + const GyroscopeData* gyroscope; + const MagnetometerData* magnetometer; +}; + +// Examples: +// Vector3D accelVec(1.0, 2.0, 3.0); +// AccelerationData accelData(accelVec); + +// Vector3D gyroVec(0.1, 0.2, 0.3); +// GyroscopeData gyroData(gyroVec); + +// Vector3D magVec(0.01, 0.02, 0.03); +// MagnetometerData magData(magVec); + +// IMUData imuDataWithAccelGyro(&accelData, &gyroData, nullptr); + diff --git a/src/platform/TouchDataTypeClass.hpp b/src/platform/TouchDataTypeClass.hpp new file mode 100644 index 0000000..e1c0cdd --- /dev/null +++ b/src/platform/TouchDataTypeClass.hpp @@ -0,0 +1,162 @@ +/** + * + * @license MIT License + * + * Copyright (c) 2025 lewis he + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * @file SensorDataTypeClass.hpp + * @author Lewis He (lewishe@outlook.com) + * @date 2025-01-23 + * + */ +#pragma once + +#include + +// Define the coordinate structure +template +struct Coordinate { + T x; + T y; +}; + +// Define the enumeration type of gesture +enum class Gesture { + TAP, + SWIPE_UP, + SWIPE_DOWN, + SWIPE_LEFT, + SWIPE_RIGHT, + HOLD +}; + +template +class TouchDataTypeClass +{ +private: + Coordinate coordinates[MAX_COORDINATES]; + int validCoordinateCount; + double pressure; + + // If gestures are enabled, store the gestures + typename std::conditional::type gesture; + +public: + + template + TouchDataTypeClass(const Coordinate *coords, int validCount, double p, Args... args) + : validCoordinateCount(validCount), pressure(p) + { + for (int i = 0; i < validCount && i < MAX_COORDINATES; ++i) { + coordinates[i] = coords[i]; + } + if constexpr (HAS_GESTURE) { + gesture = static_cast(args...); + } + } + + // Get the coordinate array + const Coordinate *getCoordinates() const + { + return coordinates; + } + + // Get the number of valid coordinate groups + int getValidCoordinateCount() const + { + return validCoordinateCount; + } + + // Get the compression pressure data + double getPressure() const + { + return pressure; + } + + // If the gesture function is enabled, how to get the gesture + template = 0> + Gesture getGesture() const + { + return gesture; + } + + // Set the coordinate array + void setCoordinates(const Coordinate *coords, int validCount) + { + validCoordinateCount = validCount; + for (int i = 0; i < validCount && i < MAX_COORDINATES; ++i) { + coordinates[i] = coords[i]; + } + } + + // Set the number of valid coordinate groups + void setValidCoordinateCount(int count) + { + validCoordinateCount = count; + } + + // Set the pressing pressure data + void setPressure(double p) + { + pressure = p; + } + + // If the gesture function is enabled, set the gesture method + template = 0> + void setGesture(Gesture g) + { + gesture = g; + } + + // Print touch information + void printTouchInfo() const + { + if constexpr (HAS_GESTURE) { + log_i("Gesture: "); + switch (gesture) { + case Gesture::TAP: + log_i("TAP"); + break; + case Gesture::SWIPE_UP: + log_i("SWIPE_UP"); + break; + case Gesture::SWIPE_DOWN: + log_i("SWIPE_DOWN"); + break; + case Gesture::SWIPE_LEFT: + log_i("SWIPE_LEFT"); + break; + case Gesture::SWIPE_RIGHT: + log_i("SWIPE_RIGHT"); + break; + case Gesture::HOLD: + log_i("HOLD"); + break; + } + } + log_i("Valid Coordinate Count: "); + log_i("Coordinates:"); + for (int i = 0; i < validCoordinateCount; ++i) { + log_i("x: %04d, y: %04d\n", coordinates[i].x, coordinates[i].y); + } + log_i("Pressure: %u", pressure ); + } +}; \ No newline at end of file diff --git a/src/platform/arduino/SensorCommArduino_HW.hpp b/src/platform/arduino/SensorCommArduino_HW.hpp new file mode 100644 index 0000000..9daf6c6 --- /dev/null +++ b/src/platform/arduino/SensorCommArduino_HW.hpp @@ -0,0 +1,89 @@ +/** + * + * @license MIT License + * + * Copyright (c) 2025 lewis he + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * @file SensorCommArduino_HW.hpp + * @author Lewis He (lewishe@outlook.com) + * @date 2025-01-18 + * + */ +#pragma once + +#include "../SensorCommBase.hpp" + +#ifdef ARDUINO + +class HalArduino : public SensorHal +{ +public: + void pinMode(uint8_t pin, uint8_t mode) + { + if (modeCallback) { + modeCallback(pin, mode); + } else { +#ifdef ARDUINO_ARCH_RP2040 + ::pinMode(pin, static_cast(mode)); +#else + ::pinMode(pin, mode); +#endif + } + } + + void digitalWrite(uint8_t pin, uint8_t level) + { + if (writeCallback) { + writeCallback(pin, level); + } else { +#ifdef ARDUINO_ARCH_RP2040 + ::digitalWrite(pin, static_cast(level)); +#else + ::digitalWrite(pin, level); +#endif + } + } + + uint8_t digitalRead(uint8_t pin) + { + if (readCallback) { + return readCallback(pin); + } + return ::digitalRead(pin); + } + + uint32_t millis() + { + return ::millis(); + } + + void delay(uint32_t ms) + { + ::delay(ms);; + } + + void delayMicroseconds(uint32_t us) + { + ::delayMicroseconds(us); + } +}; + +#endif //*ARDUINO diff --git a/src/platform/arduino/SensorCommArduino_I2C.hpp b/src/platform/arduino/SensorCommArduino_I2C.hpp new file mode 100644 index 0000000..57077f1 --- /dev/null +++ b/src/platform/arduino/SensorCommArduino_I2C.hpp @@ -0,0 +1,193 @@ +/** + * + * @license MIT License + * + * Copyright (c) 2025 lewis he + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * @file SensorCommArduino_I2C.hpp + * @author Lewis He (lewishe@outlook.com) + * @date 2025-01-18 + * + */ + +#pragma once + +#include "../SensorCommBase.hpp" + +#ifdef ARDUINO + +class SensorCommI2C : public SensorCommBase +{ +public: + SensorCommI2C(TwoWire &wire, uint8_t addr, int sda, int scl, SensorHal *ptr = nullptr) : wire(wire), addr(addr), sda(sda), scl(scl), sendStopFlag(true) {} + + bool init() override + { + setPins(); + wire.begin(); + return true; + } + + void deinit() override + { + // Do not destroy wire bus + // wire.end(); + } + + int writeRegister(const uint8_t reg, uint8_t val) override + { + return writeRegister(reg, &val, 1); + } + + int writeRegister(const uint8_t reg, uint8_t norVal, uint8_t orVal) override + { + int val = readRegister(reg); + if (val < 0) { + return -1; + } + val &= norVal; + val |= orVal; + return writeRegister(reg, reinterpret_cast(&val), 1); + } + + int writeRegister(const uint8_t reg, uint8_t *buf, size_t len) override + { + // log_d("ADDR:0x%02X REG:0x%02X, LEN:%u", addr, reg, len); + wire.beginTransmission(addr); + wire.write(reg); + if (buf && len > 0) { + wire.write(buf, len); + } + if (wire.endTransmission() == 0) { + return 0; + } else { + return -1; + } + } + + int writeBuffer(uint8_t *buffer, size_t len) + { + if (!buffer || len == 0)return -1; + wire.beginTransmission(addr); + wire.write(buffer, len); + if (wire.endTransmission() == 0) { + return 0; + } else { + return -1; + } + } + + + int readRegister(const uint8_t reg) override + { + uint8_t value = 0x00; + if (readRegister(reg, &value, 1) < 0) { + return -1; + } + return value; + } + + int readRegister(const uint8_t reg, uint8_t *buf, size_t len) override + { + // log_d("ADDR:0x%02X REG:0x%02X, LEN:%u", addr, reg, len); + wire.beginTransmission(addr); + wire.write(reg); + wire.endTransmission(sendStopFlag); + wire.requestFrom(addr, static_cast(len)); + return wire.readBytes(buf, len) == len ? 0 : -1; + } + + int writeThenRead(const uint8_t *write_buffer, size_t write_len, uint8_t *read_buffer, size_t read_len) override + { + wire.beginTransmission(addr); + wire.write(write_buffer, write_len); + if (wire.endTransmission(sendStopFlag) != 0) { + return -1; + } + wire.requestFrom(addr, read_len); + return wire.readBytes(read_buffer, read_len) == read_len ? 0 : -1; + } + + bool setRegisterBit(const uint8_t reg, uint8_t bit) override + { + uint8_t value = readRegister(reg); + value |= (1 << bit); + return writeRegister(reg, reinterpret_cast(&value), 1) == 0; + } + + bool clrRegisterBit(const uint8_t reg, uint8_t bit) override + { + uint8_t value = readRegister(reg); + value &= ~(1 << bit); + return writeRegister(reg, reinterpret_cast(&value), 1) == 0; + } + + bool getRegisterBit(const uint8_t reg, uint8_t bit) override + { + uint8_t value = readRegister(reg); + return (value & (1 << bit)) != 0; + } + + void setParams(const CommParamsBase ¶ms) override + { +#if defined(__cpp_rtti) + const auto pdat = dynamic_cast(¶ms); +#else + const auto pdat = static_cast(¶ms); +#endif + uint8_t type = pdat->getType(); + switch (type) { + case I2CParam::I2C_SET_ADDR: + addr = pdat->getParams(); + break; + case I2CParam::I2C_SET_FLAG: + sendStopFlag = pdat->getParams(); + break; + default: + break; + } + } + +private: + + void setPins() + { + if (sda != -1 && scl != -1) { +#if defined(ARDUINO_ARCH_NRF52) || defined(ARDUINO_ARCH_ESP32) + wire.setPins(sda, scl); +#elif defined(ARDUINO_ARCH_RP2040) || defined(ARDUINO_ARCH_STM32) + wire.end(); + wire.setSDA(sda); + wire.setSCL(scl); +#else +#warring "Wire custom GPIO mapping function is not implemented" +#endif + } + } + + TwoWire &wire; + uint8_t addr; + int sda; + int scl; + bool sendStopFlag; +}; + +#endif //*ARDUINO diff --git a/src/platform/arduino/SensorCommArduino_SPI.hpp b/src/platform/arduino/SensorCommArduino_SPI.hpp new file mode 100644 index 0000000..6ed7816 --- /dev/null +++ b/src/platform/arduino/SensorCommArduino_SPI.hpp @@ -0,0 +1,225 @@ +/** + * + * @license MIT License + * + * Copyright (c) 2025 lewis he + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * @file SensorCommArduino_SPI.hpp + * @author Lewis He (lewishe@outlook.com) + * @date 2025-01-18 + * + */ + +#pragma once + +#include "../SensorCommBase.hpp" + +#ifdef ARDUINO + + +#if defined(ARDUINO_ARCH_RP2040) || defined(ARDUINO_ARCH_STM32) +#define writeBytes(txBuf,size) spi.transfer(txBuf,nullptr,size) +#elif defined(ARDUINO_ARCH_NRF52) +#define writeBytes(txBuf,size) spi.transfer(txBuf,nullptr,size) +#else +#define writeBytes(txBuf,size) spi.writeBytes(txBuf,size) +#endif + + +class SensorCommSPI : public SensorCommBase +{ +public: + SensorCommSPI(SPIClass &spi, uint8_t csPin, SensorHal *hal) : spi(spi), csPin(csPin), hal(hal) {} + SensorCommSPI(SPIClass &spi, uint8_t csPin, int mosi, int miso, int sck, SensorHal *hal) : spi(spi), + csPin(csPin), hal(hal), mosi(mosi), miso(miso), sck(sck) {} + + bool init() override + { + log_d("SensorCommSPI"); + if (!hal) { + log_e("hal pointer is null"); + return false; + } + if (mosi != -1 && miso != -1 && sck != -1) { +#if defined(ARDUINO_ARCH_NRF52) + spi.setPins(miso, sck, mosi); + spi.begin(); +#elif defined(ARDUINO_ARCH_ESP32) + spi.begin(sck, miso, mosi); +#elif defined(ARDUINO_ARCH_RP2040) + spi.setSCK(sck); + spi.setRX(miso); + spi.setTX(mosi); + spi.begin(); +#elif defined(ARDUINO_ARCH_STM32) + spi.setMISO(miso); + spi.setMOSI(mosi); + spi.setSCLK(sck); + spi.begin(); +#else +#warring "SPI custom GPIO mapping function is not implemented" +#endif + } + hal->pinMode(csPin, OUTPUT); + hal->digitalWrite(csPin, HIGH); + return true; + } + + void deinit() override + { + // Do not destroy spi bus + // spi.end(); + } + + int writeRegister(const uint8_t reg, uint8_t val) override + { + return writeRegister(reg, &val, 1); + } + + int writeRegister(const uint8_t reg, uint8_t norVal, uint8_t orVal) override + { + int val = readRegister(reg); + if (val < 0) { + return -1; + } + val &= norVal; + val |= orVal; + return writeRegister(reg, reinterpret_cast(&val), 1); + } + + int writeRegister(const uint8_t reg, uint8_t *buf, size_t len) override + { + hal->digitalWrite(csPin, LOW); + spi.beginTransaction(setting); + spi.transfer(reg); + for (size_t i = 0; i < len; ++i) { + spi.transfer(buf[i]); + } + spi.endTransaction(); + hal->digitalWrite(csPin, HIGH); + return 0; + } + + int readRegister(const uint8_t reg) override + { + uint8_t value = 0x00; + if (readRegister(reg, &value, 1) < 0) { + return -1; + } + return value; + } + + int writeBuffer(uint8_t *buffer, size_t len) + { + hal->digitalWrite(csPin, LOW); + spi.beginTransaction(setting); + if (buffer && len > 0) { + // spi.writeBytes(buffer, len); + writeBytes(buffer, len); + } + spi.endTransaction(); + hal->digitalWrite(csPin, HIGH); + return 0; + } + + int readRegister(const uint8_t reg, uint8_t *buf, size_t len) override + { + hal->digitalWrite(csPin, LOW); + spi.beginTransaction(setting); + spi.transfer(reg | 0x80); +#if defined(ARDUINO_ARCH_ESP32) + spi.transferBytes(NULL, buf, len); +#else + for (size_t i = 0; i < len; i++) { + buf[i] = spi.transfer(0x00); + } +#endif + spi.endTransaction(); + hal->digitalWrite(csPin, HIGH); + return 0; + } + + int writeThenRead(const uint8_t *write_buffer, size_t write_len, uint8_t *read_buffer, size_t read_len) override + { + hal->digitalWrite(csPin, LOW); + spi.beginTransaction(setting); + + // spi.writeBytes(write_buffer, write_len); + writeBytes(write_buffer, write_len); + + spi.endTransaction(); + + spi.beginTransaction(setting); + for (size_t i = 0; i < read_len; ++i) { + read_buffer[i] = spi.transfer(0x00); + } + spi.endTransaction(); + hal->digitalWrite(csPin, HIGH); + return 0; + } + + bool setRegisterBit(const uint8_t reg, uint8_t bit) override + { + uint8_t value = readRegister(reg); + value |= (1 << bit); + return writeRegister(reg, reinterpret_cast(&value), 1) == 0; + } + + bool clrRegisterBit(const uint8_t reg, uint8_t bit) override + { + uint8_t value = readRegister(reg); + value &= ~(1 << bit); + return writeRegister(reg, reinterpret_cast(&value), 1) == 0; + } + + bool getRegisterBit(const uint8_t reg, uint8_t bit) override + { + uint8_t value = readRegister(reg); + return (value & (1 << bit)) != 0; + } + + void setParams(const CommParamsBase ¶ms) override + { +#if defined(__cpp_rtti) + const auto pdat = dynamic_cast(¶ms); +#else + const auto pdat = static_cast(¶ms); +#endif + setting = pdat->getSetting(); + } + +private: + SPIClass &spi; + uint8_t csPin; + SensorHal *hal; + SPISettings setting; + int mosi, miso, sck; +}; + +#endif //*ARDUINO + + + + + + + + diff --git a/src/platform/esp_arduino.cpp b/src/platform/esp_arduino.cpp deleted file mode 100644 index 169265a..0000000 --- a/src/platform/esp_arduino.cpp +++ /dev/null @@ -1,66 +0,0 @@ -/** - * @file esp_arduino.cpp - * @author Lewis He (lewishe@outlook.com) - * @license MIT - * @copyright Copyright (c) 2024 Shenzhen Xinyuan Electronic Technology Co., Ltd - * @date 2024-01-08 - * - */ -#if !defined(ARDUINO) && defined(ESP_PLATFORM) -#include "SensorLib.h" -#include "driver/gpio.h" -#include "esp_timer.h" -#include "freertos/FreeRTOS.h" -#include - - -void pinMode(uint32_t gpio, uint8_t mode) -{ - gpio_config_t config; - memset(&config, 0, sizeof(config)); - config.pin_bit_mask = 1ULL << gpio; - switch (mode) { - case INPUT: - config.mode = GPIO_MODE_INPUT; - break; - case OUTPUT: - config.mode = GPIO_MODE_OUTPUT; - break; - } - config.pull_up_en = GPIO_PULLUP_DISABLE; - config.pull_down_en = GPIO_PULLDOWN_DISABLE; - config.intr_type = GPIO_INTR_DISABLE; - ESP_ERROR_CHECK(gpio_config(&config)); -} - -void digitalWrite(uint32_t gpio, uint8_t level) -{ - gpio_set_level((gpio_num_t )gpio, level); -} - -int digitalRead(uint32_t gpio) -{ - return gpio_get_level((gpio_num_t)gpio); -} - -void delay(uint32_t ms) -{ - vTaskDelay(pdMS_TO_TICKS(ms)); - ets_delay_us((ms % portTICK_PERIOD_MS) * 1000UL); -} - -uint32_t millis() -{ - return (uint32_t) (esp_timer_get_time() / 1000LL); -} - -uint32_t micros() -{ - return (uint32_t) esp_timer_get_time(); -} - -void delayMicroseconds(uint32_t us) -{ - ets_delay_us(us); -} -#endif diff --git a/src/platform/esp_arduino.h b/src/platform/esp_arduino.h deleted file mode 100644 index 876de66..0000000 --- a/src/platform/esp_arduino.h +++ /dev/null @@ -1,22 +0,0 @@ -/** - * @file esp_arduino.h - * @author Lewis He (lewishe@outlook.com) - * @license MIT - * @copyright Copyright (c) 2024 Shenzhen Xinyuan Electronic Technology Co., Ltd - * @date 2024-01-08 - * - */ -#pragma once - -#if !defined(ARDUINO) && defined(ESP_PLATFORM) - -void pinMode(uint32_t gpio, uint8_t mode); -void digitalWrite(uint32_t gpio, uint8_t level); -int digitalRead(uint32_t gpio); -void delay(uint32_t ms); -uint32_t millis(); -uint32_t micros(); -void delayMicroseconds(uint32_t us); - -#endif - diff --git a/src/platform/espidf/SensorCommEspIDF_HW.hpp b/src/platform/espidf/SensorCommEspIDF_HW.hpp new file mode 100644 index 0000000..c656b72 --- /dev/null +++ b/src/platform/espidf/SensorCommEspIDF_HW.hpp @@ -0,0 +1,110 @@ +/** + * + * @license MIT License + * + * Copyright (c) 2025 lewis he + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * @file SensorCommEspIDF_HW.hpp + * @author Lewis He (lewishe@outlook.com) + * @date 2025-01-18 + * + */ +#pragma once + +#include "../SensorCommBase.hpp" + +#if !defined(ARDUINO) && defined(ESP_PLATFORM) + +#include "sdkconfig.h" +#include "freertos/FreeRTOS.h" +#include "esp_idf_version.h" +#include "esp_err.h" +#include "esp_timer.h" +#include "rom/ets_sys.h" +#include "driver/gpio.h" + +class HalEspIDF: public SensorHal +{ +public: + void pinMode(uint8_t pin, uint8_t mode) + { + if (modeCallback) { + modeCallback(pin, mode); + } else { + gpio_config_t config; + memset(&config, 0, sizeof(config)); + config.pin_bit_mask = 1ULL << pin; + switch (mode) { + case INPUT: + config.mode = GPIO_MODE_INPUT; + break; + case OUTPUT: + config.mode = GPIO_MODE_OUTPUT; + break; + } + config.pull_up_en = GPIO_PULLUP_DISABLE; + config.pull_down_en = GPIO_PULLDOWN_DISABLE; + config.intr_type = GPIO_INTR_DISABLE; + ESP_ERROR_CHECK(gpio_config(&config)); + } + } + + void digitalWrite(uint8_t pin, uint8_t level) + { + if (writeCallback) { + writeCallback(pin, level); + } else { + gpio_set_level((gpio_num_t )pin, level); + } + } + + uint8_t digitalRead(uint8_t pin) + { + if (readCallback) { + return readCallback(pin); + } + return gpio_get_level((gpio_num_t)pin); + } + + void delay(uint32_t ms) + { + ets_delay_us((ms % portTICK_PERIOD_MS) * 1000UL); + } + + uint32_t millis() + { + return (uint32_t) (esp_timer_get_time() / 1000LL); + } + + uint32_t micros() + { + return (uint32_t) esp_timer_get_time(); + } + + void delayMicroseconds(uint32_t us) + { + ets_delay_us(us); + } +}; + + + +#endif //*ESP_PLATFORM diff --git a/src/platform/espidf/SensorCommEspIDF_I2C.hpp b/src/platform/espidf/SensorCommEspIDF_I2C.hpp new file mode 100644 index 0000000..de13b1d --- /dev/null +++ b/src/platform/espidf/SensorCommEspIDF_I2C.hpp @@ -0,0 +1,305 @@ +/** + * + * @license MIT License + * + * Copyright (c) 2025 lewis he + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * @file SensorCommEspIDF_I2C.hpp + * @author Lewis He (lewishe@outlook.com) + * @date 2025-01-18 + * + */ +#pragma once + +#include "../SensorCommBase.hpp" + +#if !defined(ARDUINO) && defined(ESP_PLATFORM) + +#include "sdkconfig.h" +#include "freertos/FreeRTOS.h" +#include "esp_idf_version.h" +#include "esp_err.h" +#if ((ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL(5,0,0)) && defined(CONFIG_SENSORLIB_ESP_IDF_NEW_API)) +#include "driver/i2c_master.h" +#else +#include "driver/i2c.h" +#define USEING_I2C_LEGACY 1 +#endif //ESP_IDF_VERSION + +#define SENSORLIB_I2C_MASTER_TIMEOUT_MS 1000 +#define SENSORLIB_I2C_MASTER_SPEED 400000 + +class SensorCommI2C : public SensorCommBase +{ +public: + +#if defined(USEING_I2C_LEGACY) + SensorCommI2C(i2c_port_t i2c_num, uint8_t addr, int sda, int scl, SensorHal *ptr = nullptr) : + addr(addr), sda(sda), scl(scl), _i2cNum(i2c_num), sendStopFlag(true) + {} +#else + SensorCommI2C(i2c_master_bus_handle_t handle, uint8_t addr, SensorHal *ptr = nullptr) : + addr(addr), _busHandle(handle), _i2cDevice(nullptr), sendStopFlag(true) {} +#endif + + bool init() override + { +#if defined(USEING_I2C_LEGACY) + return init_legacy(); +#else + return init_ll_hal(); +#endif + } + + void deinit() override + { +#ifndef USEING_I2C_LEGACY + if (_i2cDevice) { + // Initialization failed, delete device + log_i("i2c_master_bus_rm_device"); + i2c_master_bus_rm_device(_i2cDevice); + } +#endif + } + + int writeRegister(const uint8_t reg, uint8_t val) override + { + return writeRegister(reg, &val, 1); + } + + int writeRegister(const uint8_t reg, uint8_t norVal, uint8_t orVal) override + { + int val = readRegister(reg); + if (val < 0) { + return -1; + } + val &= norVal; + val |= orVal; + return writeRegister(reg, reinterpret_cast(&val), 1); + } + + int writeRegister(const uint8_t reg, uint8_t *buf, size_t len) override + { + size_t totalLength = sizeof(uint8_t) + len; + uint8_t *write_buffer = (uint8_t *)malloc(totalLength); + if (!write_buffer) { + return -1; + } + write_buffer[0] = reg; + if (buf && len > 0) { + memcpy(write_buffer + 1, buf, len); + } + int ret = writeBuffer(write_buffer, totalLength); + free(write_buffer); + return ret; + } + + int writeBuffer(uint8_t *buffer, size_t len) + { + +#if defined(USEING_I2C_LEGACY) + if (ESP_OK == i2c_master_write_to_device(_i2cNum, addr, buffer, len, + SENSORLIB_I2C_MASTER_TIMEOUT_MS / portTICK_PERIOD_MS)) { + return 0; + } +#else //ESP_IDF_VERSION + if (ESP_OK == i2c_master_transmit(_i2cDevice, buffer, len, -1)) { + return 0; + } + +#endif //ESP_IDF_VERSION + return -1; + } + + + int readRegister(const uint8_t reg) override + { + uint8_t value = 0x00; + if (readRegister(reg, &value, 1) < 0) { + return -1; + } + return value; + } + + int readRegister(const uint8_t reg, uint8_t *buf, size_t len) override + { +#if defined(USEING_I2C_LEGACY) + if (ESP_OK == i2c_master_write_read_device(_i2cNum, addr, (uint8_t *)®, 1, buf, len, + SENSORLIB_I2C_MASTER_TIMEOUT_MS / portTICK_PERIOD_MS)) { + return 0; + } +#else //ESP_IDF_VERSION + if (ESP_OK == i2c_master_transmit_receive(_i2cDevice, (const uint8_t *)®, 1, buf, len, -1)) { + return 0; + } +#endif //ESP_IDF_VERSION + return -1; + } + + int writeThenRead(const uint8_t *write_buffer, size_t write_len, uint8_t *read_buffer, size_t read_len) override + { +#if defined(USEING_I2C_LEGACY) + if (ESP_OK == i2c_master_write_read_device( + _i2cNum, + addr, + write_buffer, + write_len, + read_buffer, + read_len, + SENSORLIB_I2C_MASTER_TIMEOUT_MS / portTICK_PERIOD_MS)) { + return 0; + } +#else //ESP_IDF_VERSION + if (ESP_OK == i2c_master_transmit_receive( + _i2cDevice, + write_buffer, + write_len, + read_buffer, + read_len, + -1)) { + return 0; + } +#endif //ESP_IDF_VERSION + return -1; + } + + bool setRegisterBit(const uint8_t reg, uint8_t bit) override + { + uint8_t value = readRegister(reg); + value |= (1 << bit); + return writeRegister(reg, reinterpret_cast(&value), 1) == 0; + } + + bool clrRegisterBit(const uint8_t reg, uint8_t bit) override + { + uint8_t value = readRegister(reg); + value &= ~(1 << bit); + return writeRegister(reg, reinterpret_cast(&value), 1) == 0; + } + + bool getRegisterBit(const uint8_t reg, uint8_t bit) override + { + uint8_t value = readRegister(reg); + return (value & (1 << bit)) != 0; + } + + void setParams(const CommParamsBase ¶ms) override + { +#if defined(__cpp_rtti) + const auto pdat = dynamic_cast(¶ms); +#else + const auto pdat = static_cast(¶ms); +#endif + uint8_t type = pdat->getType(); + switch (type) { + case I2CParam::I2C_SET_ADDR: + addr = pdat->getParams(); + break; + case I2CParam::I2C_SET_FLAG: + sendStopFlag = pdat->getParams(); + break; + default: + break; + } + +#if !defined(USEING_I2C_LEGACY) + deinit(); + init_ll_hal(); +#endif + } + +private: + + + +#if defined(USEING_I2C_LEGACY) + + bool init_legacy() + { + if (sda != -1 || scl != -1) { + return true; + } + i2c_config_t i2c_conf; + memset(&i2c_conf, 0, sizeof(i2c_conf)); + i2c_conf.mode = I2C_MODE_MASTER; + i2c_conf.sda_io_num = sda; + i2c_conf.scl_io_num = scl; + i2c_conf.sda_pullup_en = GPIO_PULLUP_ENABLE; + i2c_conf.scl_pullup_en = GPIO_PULLUP_ENABLE; + i2c_conf.master.clk_speed = SENSORLIB_I2C_MASTER_SPEED; + + /** + * @brief Without checking whether the initialization is successful, + * I2C may be initialized externally, + * so just make sure there is an initialization here. + */ + // static const IDF_TX_BUF_DISABLE = 0; /*!< I2C master doesn't need buffer */ + // static const IDF_RX_BUF_DISABLE = 0; /*!< I2C master doesn't need buffer */ + + i2c_param_config(_i2cNum, &i2c_conf); + i2c_driver_install(_i2cNum, i2c_conf.mode, 0, 0, 0); + return true; + } + +#else //USEING_I2C_LEGACY + + // * Using the new API of esp-idf 5.x, need to pass the I2C BUS handle, + // * which is useful when the bus shares multiple devices. + bool init_ll_hal() + { + log_i("Using ESP-IDF Driver interface."); + + i2c_device_config_t devConf; + if (_busHandle == NULL) return false; + devConf.dev_addr_length = I2C_ADDR_BIT_LEN_7; + devConf.device_address = addr; + devConf.scl_speed_hz = SENSORLIB_I2C_MASTER_SPEED; + +#if (ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL(5,3,0)) +#if (ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL(5,4,0)) + // New fields since esp-idf-v5.3-beta1 + devConf.scl_wait_us = 0; +#endif + devConf.flags.disable_ack_check = 0; +#endif + + if (ESP_OK != i2c_master_bus_add_device(_busHandle, &devConf, &_i2cDevice)) { + log_i("i2c_master_bus_add_device failed !"); + return false; + } + log_i("Added Device Address : 0x%X New Dev Address: %p Speed :%lu ", addr, _i2cDevice, devConf.scl_speed_hz); + return true; + } +#endif //ESP 5.X + + uint8_t addr; +#if defined(USEING_I2C_LEGACY) + int sda; + int scl; + i2c_port_t _i2cNum; +#else + i2c_master_bus_handle_t _busHandle; + i2c_master_dev_handle_t _i2cDevice; +#endif + bool sendStopFlag; +}; + +#endif //*ESP_PLATFORM diff --git a/src/platform/espidf/SensorCommEspIDF_SPI.hpp b/src/platform/espidf/SensorCommEspIDF_SPI.hpp new file mode 100644 index 0000000..c981f4d --- /dev/null +++ b/src/platform/espidf/SensorCommEspIDF_SPI.hpp @@ -0,0 +1,255 @@ +/** + * + * @license MIT License + * + * Copyright (c) 2025 lewis he + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * @file SensorCommEspIDF_SPI.hpp + * @author Lewis He (lewishe@outlook.com) + * @date 2025-01-18 + * + */ +#pragma once + +#include "../SensorCommBase.hpp" + +#if !defined(ARDUINO) && defined(ESP_PLATFORM) +#include "driver/spi_master.h" +#include "driver/gpio.h" +#include "esp_err.h" +#include "esp_log.h" + + + +class SensorCommSPI : public SensorCommBase +{ +public: + SensorCommSPI(spi_host_device_t host, spi_device_handle_t &spi, uint8_t csPin, SensorHal *hal) : host(host), spi(spi), csPin(csPin), hal(hal) {} + SensorCommSPI(spi_host_device_t host, spi_device_handle_t &spi, uint8_t csPin, int mosi, int miso, int sck, SensorHal *hal) : host(host), spi(spi), + csPin(csPin), hal(hal), mosi(mosi), miso(miso), sck(sck) {} + + bool init() override + { + if (!hal) { + return false; + } + if (mosi != -1 && miso != -1 && sck != -1) { + spi_bus_config_t buscfg ; + buscfg.miso_io_num = miso, + buscfg.mosi_io_num = mosi, + buscfg.sclk_io_num = sck, + buscfg.quadwp_io_num = -1, + buscfg.quadhd_io_num = -1, + buscfg.data4_io_num = -1, + buscfg.data5_io_num = -1, + buscfg.data6_io_num = -1, + buscfg.data7_io_num = -1, + buscfg.max_transfer_sz = 128; + buscfg.flags = 0; + buscfg.isr_cpu_id = ESP_INTR_CPU_AFFINITY_AUTO; + buscfg.intr_flags = 0; + + spi_device_interface_config_t devcfg ; + memset(&devcfg, 0, sizeof(devcfg)); + devcfg.address_bits = 8; + devcfg.clock_speed_hz = spiSetting.clock; + devcfg.mode = spiSetting.dataMode; + devcfg.spics_io_num = -1; + devcfg.queue_size = 2; + devcfg.pre_cb = NULL; + + esp_err_t ret; + ret = spi_bus_initialize(host, &buscfg, SPI_DMA_CH_AUTO); + if (ret != ESP_OK)return false; + + ret = spi_bus_add_device(host, &devcfg, &spi); + if (ret != ESP_OK)return false; + } + + hal->pinMode(csPin, OUTPUT); + hal->digitalWrite(csPin, HIGH); + + return true; + } + + void deinit() override + { + spi_bus_remove_device(spi); + // spi_bus_free(host); + } + + int writeRegister(const uint8_t reg, uint8_t val) override + { + return writeRegister(reg, &val, 1); + } + + int writeRegister(const uint8_t reg, uint8_t norVal, uint8_t orVal) override + { + int val = readRegister(reg); + if (val < 0) { + return -1; + } + val &= norVal; + val |= orVal; + return writeRegister(reg, reinterpret_cast(&val), 1); + } + + int writeRegister(const uint8_t reg, uint8_t *buf, size_t len) override + { + hal->digitalWrite(csPin, LOW); + + spi_transaction_t trans; + memset(&trans, 0, sizeof(trans)); + trans.flags = 0; + trans.cmd = 0; + trans.addr = reg & WRITE_MASK; + trans.length = len * 8; + trans.rxlength = 0; + trans.user = NULL; + trans.tx_buffer = buf; + trans.rx_buffer = NULL; + esp_err_t ret = spi_device_transmit(spi, &trans); + + hal->digitalWrite(csPin, HIGH); + + return ret; + } + + int readRegister(const uint8_t reg) override + { + uint8_t value = 0x00; + if (readRegister(reg, &value, 1) < 0) { + return -1; + } + return value; + } + + int writeBuffer(uint8_t *buf, size_t len) + { + if (!buf || len == 0)return -1; + + hal->digitalWrite(csPin, LOW); + + spi_transaction_t trans; + memset(&trans, 0, sizeof(trans)); + trans.length = 8 * len; + trans.tx_buffer = buf; + esp_err_t ret = spi_device_polling_transmit(spi, &trans); + + hal->digitalWrite(csPin, HIGH); + return ret == ESP_OK ? 0 : -1; + } + + int readRegister(const uint8_t reg, uint8_t *buf, size_t len) override + { + + if (!buf || len == 0)return -1; + + hal->digitalWrite(csPin, LOW); + + spi_transaction_t trans; + memset(&trans, 0, sizeof(trans)); + trans.addr = reg | READ_MASK; + trans.length = len * 8; + trans.rxlength = len * 8; + trans.rx_buffer = buf; + esp_err_t ret = spi_device_transmit(spi, &trans); + + hal->digitalWrite(csPin, HIGH); + return ret == ESP_OK ? 0 : -1; + } + + int writeThenRead(const uint8_t *write_buffer, size_t write_len, uint8_t *read_buffer, size_t read_len) override + { + if (!write_buffer || write_len == 0 || !read_buffer || read_len == 0) return -1; + + hal->digitalWrite(csPin, LOW); + + esp_err_t ret; + spi_transaction_t trans; + memset(&trans, 0, sizeof(trans)); // Zero out the trans + + auto perform_transmission = [&](const uint8_t *tx_buf, size_t len, uint8_t *rx_buf) { + trans.length = 8 * len; + trans.tx_buffer = tx_buf; + trans.rx_buffer = rx_buf; + return spi_device_polling_transmit(spi, &trans); + }; + + ret = perform_transmission(write_buffer, write_len, nullptr); + if (ret != ESP_OK) { + hal->digitalWrite(csPin, HIGH); + return -1; + } + + ret = perform_transmission(nullptr, read_len, read_buffer); + + hal->digitalWrite(csPin, HIGH); + + return ret == ESP_OK ? 0 : -1; + } + + bool setRegisterBit(const uint8_t reg, uint8_t bit) override + { + uint8_t value = readRegister(reg); + value |= (1 << bit); + return writeRegister(reg, reinterpret_cast(&value), 1) == 0; + } + + bool clrRegisterBit(const uint8_t reg, uint8_t bit) override + { + uint8_t value = readRegister(reg); + value &= ~(1 << bit); + return writeRegister(reg, reinterpret_cast(&value), 1) == 0; + } + + bool getRegisterBit(const uint8_t reg, uint8_t bit) override + { + uint8_t value = readRegister(reg); + return (value & (1 << bit)) != 0; + } + + void setParams(const CommParamsBase ¶ms) override + { +#if defined(__cpp_rtti) + const auto pdat = dynamic_cast(¶ms); +#else + const auto pdat = static_cast(¶ms); +#endif + pdat->getSetting(); + + /*Remove SPI BUS and re-initialize according to the new settings*/ + // spi_bus_remove_device(spi); + // spi_bus_free(host); + } + +private: + static constexpr const uint8_t READ_MASK = 0x80; + static constexpr const uint8_t WRITE_MASK = 0x7F; + spi_host_device_t host; + spi_device_handle_t spi; + uint8_t csPin; + SensorHal *hal; + int mosi, miso, sck; + SPISettings spiSetting; +}; + +#endif //*ESP_PLATFORM diff --git a/src/touch/TouchClassCST816.cpp b/src/touch/TouchClassCST816.cpp deleted file mode 100644 index 51b8cd3..0000000 --- a/src/touch/TouchClassCST816.cpp +++ /dev/null @@ -1,334 +0,0 @@ -/** - * - * @license MIT License - * - * Copyright (c) 2023 lewis he - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - * @file TouchClassCST816.cpp - * @author Lewis He (lewishe@outlook.com) - * @date 2023-10-06 - */ -#include "TouchClassCST816.h" - -#define CST8xx_REG_STATUS (0x00) -#define CST8xx_REG_XPOS_HIGH (0x03) -#define CST8xx_REG_XPOS_LOW (0x04) -#define CST8xx_REG_YPOS_HIGH (0x05) -#define CST8xx_REG_YPOS_LOW (0x06) -#define CST8xx_REG_DIS_AUTOSLEEP (0xFE) -#define CST8xx_REG_CHIP_ID (0xA7) -#define CST8xx_REG_FW_VERSION (0xA9) -#define CST8xx_REG_SLEEP (0xE5) - -#define CST816S_CHIP_ID (0xB4) -#define CST816T_CHIP_ID (0xB5) -#define CST716_CHIP_ID (0x20) -#define CST820_CHIP_ID (0xB7) -#define CST816D_CHIP_ID (0xB6) - -#if defined(ARDUINO) -TouchClassCST816::TouchClassCST816(): - __center_btn_x(0), - __center_btn_y(0) -{ -} - -bool TouchClassCST816::begin(PLATFORM_WIRE_TYPE &wire, uint8_t address, int sda, int scl) -{ - return SensorCommon::begin(wire, address, sda, scl); -} - -#elif defined(ESP_PLATFORM) - -#if ((ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL(5,0,0)) && defined(CONFIG_SENSORLIB_ESP_IDF_NEW_API)) -bool TouchClassCST816::begin(i2c_master_bus_handle_t i2c_dev_bus_handle, uint8_t addr) -{ - return SensorCommon::begin(i2c_dev_bus_handle, addr); -} -#else -bool TouchClassCST816::begin(i2c_port_t port_num, uint8_t addr, int sda, int scl) -{ - return SensorCommon::begin(port_num, addr, sda, scl); -} - -#endif //ESP_IDF_VERSION -#endif //ARDUINO - -bool TouchClassCST816::begin(uint8_t addr, iic_fptr_t readRegCallback, iic_fptr_t writeRegCallback) -{ - return SensorCommon::begin(addr, readRegCallback, writeRegCallback); -} - -void TouchClassCST816::reset() -{ - if (__rst != SENSOR_PIN_NONE) { - this->setGpioMode(__rst, OUTPUT); - this->setGpioLevel(__rst, LOW); - delay(30); - this->setGpioLevel(__rst, HIGH); - delay(50); - } -} - -uint8_t TouchClassCST816::getPoint(int16_t *x_array, int16_t *y_array, uint8_t get_point) -{ - uint8_t buffer[13]; - if (readRegister(CST8xx_REG_STATUS, buffer, 13) == DEV_WIRE_ERR) { - return 0; - } - - if (!buffer[2] || !x_array || !y_array || !get_point) { - return 0; - } - - // Some CST816T will return all 0xFF after turning off automatic sleep. - if (buffer[2] == 0xFF) { - return 0; - } - - // Only suitable for AMOLED 1.91 inch - // RAW:00,00,01,80,78,02,58,00,00,FF,FF,FF,FF, - // if (buffer[2] == 0x01 && buffer[3] == 0x80 && buffer[4] == 0x78 && buffer[5] == 0x02 && buffer[6] == 0x58) { - // if (__homeButtonCb) { - // __homeButtonCb(__userData); - // } - // return 0; - // } - - uint8_t point = buffer[2] & 0x0F; - - // CST816 only supports single touch - if (point > 1) { - return 0; - } - -#ifdef LOG_PORT - LOG_PORT.print("RAW:"); - for (int i = 0; i < 13; ++i) { - LOG_PORT.printf("%02X,", buffer[i]); - } - LOG_PORT.println(); -#endif - - int16_t tmp_x, tmp_y; - - tmp_x = ((buffer[CST8xx_REG_XPOS_HIGH] & 0x0F) << 8 | buffer[CST8xx_REG_XPOS_LOW]); - tmp_y = ((buffer[CST8xx_REG_YPOS_HIGH] & 0x0F) << 8 | buffer[CST8xx_REG_YPOS_LOW]); - - // Depends on touch screen firmware - if (tmp_x == __center_btn_x && tmp_y == __center_btn_y && __homeButtonCb) { - __homeButtonCb(__userData); - return 0; - } - - // if (get_point == 2) { - // x_array[1] = ((buffer[((uint8_t)0x09)] & 0x0F) << 8 | buffer[((uint8_t)0x10)]); - // y_array[1] = ((buffer[((uint8_t)0x11)] & 0x0F) << 8 | buffer[((uint8_t)0x12)]); - // } - - x_array[0] = tmp_x; - y_array[0] = tmp_y; - -#ifdef LOG_PORT - for (int i = 0; i < point; i++) { - LOG_PORT.printf("[%d] --> X:%d Y:%d \n", i, x_array[i], y_array[i]); - } -#endif - updateXY(point, x_array, y_array); - - return point; -} - -bool TouchClassCST816::isPressed() -{ - static uint32_t lastPulse = 0; - if (__irq != SENSOR_PIN_NONE) { - int val = this->getGpioLevel(__irq) == LOW; - if (val) { - //Filter low levels with intervals greater than 1000ms - val = (millis() - lastPulse > 1000) ? false : true; - lastPulse = millis(); - return val; - } - return false; - } - return getPoint(NULL, NULL, 1); -} - - -const char *TouchClassCST816::getModelName() -{ - switch (__chipID) { - case CST816S_CHIP_ID: - return "CST816S"; - case CST816T_CHIP_ID: - return "CST816T"; - case CST716_CHIP_ID: - return "CST716"; - case CST820_CHIP_ID: - return "CST820"; - case CST816D_CHIP_ID: - return "CST816D"; - default: - break; - } - return "UNKNOW"; -} - -void TouchClassCST816::sleep() -{ - writeRegister(CST8xx_REG_SLEEP, 0x03); -#ifdef ESP32 - if (__irq != SENSOR_PIN_NONE) { - this->setGpioMode(__irq, OPEN_DRAIN); - } - if (__rst != SENSOR_PIN_NONE) { - this->setGpioMode(__rst, OPEN_DRAIN); - } -#endif -} - -void TouchClassCST816::wakeup() -{ - reset(); -} - -void TouchClassCST816::idle() -{ - -} - -uint8_t TouchClassCST816::getSupportTouchPoint() -{ - return 1; -} - -bool TouchClassCST816::getResolution(int16_t *x, int16_t *y) -{ - return false; -} - -void TouchClassCST816::setHomeButtonCallback(home_button_callback_t cb, void *user_data) -{ - __homeButtonCb = cb; - __userData = user_data; -} - -void TouchClassCST816::setCenterButtonCoordinate(int16_t x, int16_t y) -{ - __center_btn_x = x; - __center_btn_y = y; -} - - -void TouchClassCST816::disableAutoSleep() -{ - switch (__chipID) { - case CST816S_CHIP_ID: - case CST816T_CHIP_ID: - case CST820_CHIP_ID: - case CST816D_CHIP_ID: - reset(); - delay(50); - writeRegister(CST8xx_REG_DIS_AUTOSLEEP, 0x01); - break; - case CST716_CHIP_ID: - default: - break; - } -} - -void TouchClassCST816::enableAutoSleep() -{ - switch (__chipID) { - case CST816S_CHIP_ID: - case CST816T_CHIP_ID: - case CST820_CHIP_ID: - case CST816D_CHIP_ID: - reset(); - delay(50); - writeRegister(CST8xx_REG_DIS_AUTOSLEEP, 0x00); - break; - case CST716_CHIP_ID: - default: - break; - } -} - -void TouchClassCST816::setGpioCallback(gpio_mode_fptr_t mode_cb, - gpio_write_fptr_t write_cb, - gpio_read_fptr_t read_cb) -{ - SensorCommon::setGpioModeCallback(mode_cb); - SensorCommon::setGpioWriteCallback(write_cb); - SensorCommon::setGpioReadCallback(read_cb); -} - -bool TouchClassCST816::initImpl() -{ - - if (__rst != SENSOR_PIN_NONE) { - this->setGpioMode(__rst, OUTPUT); - } - - if (__irq != SENSOR_PIN_NONE) { - this->setGpioMode(__irq, INPUT); - } - - reset(); - - int chip_id = readRegister(CST8xx_REG_CHIP_ID); - log_i("Chip ID:0x%x", chip_id); - - int version = readRegister(CST8xx_REG_FW_VERSION); - log_i("Version :0x%x", version); - - // CST716 : 0x20 - // CST816S : 0xB4 - // CST816T : 0xB5 - // CST816D : 0xB6 - // CST226SE : A7 = 0X20 - if (chip_id != CST816S_CHIP_ID && - chip_id != CST816T_CHIP_ID && - chip_id != CST820_CHIP_ID && - chip_id != CST816D_CHIP_ID && - (chip_id != CST716_CHIP_ID || version == 0)) { - log_e("Chip ID does not match, should be CST816S:0X%02X , CST816T:0X%02X , CST816D:0X%02X , CST820:0X%02X , CST716:0X%02X", - CST816S_CHIP_ID, CST816T_CHIP_ID, CST816D_CHIP_ID, CST820_CHIP_ID, CST716_CHIP_ID); - return false; - } - - __chipID = chip_id; - - log_i("Touch type:%s", getModelName()); - - return true; -} - -int TouchClassCST816::getReadMaskImpl() -{ - return -1; -} - - - - - diff --git a/src/touch/TouchClassCST816.h b/src/touch/TouchClassCST816.h deleted file mode 100644 index e261a1a..0000000 --- a/src/touch/TouchClassCST816.h +++ /dev/null @@ -1,102 +0,0 @@ -/** - * - * @license MIT License - * - * Copyright (c) 2023 lewis he - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - * @file TouchClassCST816.h - * @author Lewis He (lewishe@outlook.com) - * @date 2023-10-06 - */ -#pragma once - -#include "../TouchDrvInterface.hpp" -#include "../SensorCommon.tpp" -#include "../SensorLib.h" - -class TouchClassCST816 : public TouchDrvInterface, - public SensorCommon -{ - friend class SensorCommon; - -public: - -#if defined(ARDUINO) - TouchClassCST816(); - - bool begin(PLATFORM_WIRE_TYPE &wire, uint8_t address, int sda, int scl); - -#elif defined(ESP_PLATFORM) -#if ((ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL(5,0,0)) && defined(CONFIG_SENSORLIB_ESP_IDF_NEW_API)) - bool begin(i2c_master_bus_handle_t i2c_dev_bus_handle, uint8_t addr); -#else - bool begin(i2c_port_t port_num, uint8_t addr, int sda, int scl); -#endif //ESP_IDF_VERSION -#endif - - bool begin(uint8_t addr, iic_fptr_t readRegCallback, iic_fptr_t writeRegCallback); - - - void reset(); - - uint8_t getPoint(int16_t *x_array, int16_t *y_array, uint8_t get_point); - - bool isPressed(); - - const char *getModelName(); - - void sleep(); - - void wakeup(); - - void idle(); - - uint8_t getSupportTouchPoint(); - - bool getResolution(int16_t *x, int16_t *y); - - void setCenterButtonCoordinate(int16_t x, int16_t y); - - void setHomeButtonCallback(home_button_callback_t cb, void *user_data); - - void disableAutoSleep(); - - void enableAutoSleep(); - - void setGpioCallback(gpio_mode_fptr_t mode_cb, - gpio_write_fptr_t write_cb, - gpio_read_fptr_t read_cb); - -private: - bool initImpl(); - int getReadMaskImpl(); - -protected: - int16_t __center_btn_x; - int16_t __center_btn_y; -}; - - - - - - - diff --git a/src/touch/TouchClassCST226.cpp b/src/touch/TouchDrvCST226.cpp similarity index 51% rename from src/touch/TouchClassCST226.cpp rename to src/touch/TouchDrvCST226.cpp index 0268f0a..2d92b8a 100644 --- a/src/touch/TouchClassCST226.cpp +++ b/src/touch/TouchDrvCST226.cpp @@ -22,83 +22,92 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. * - * @file TouchClassCST226.cpp + * @file TouchDrvCST226.cpp * @author Lewis He (lewishe@outlook.com) * @date 2023-10-06 */ -#include "TouchClassCST226.h" +#include "TouchDrvCST226.h" -#define CST2xx_REG_STATUS (0x00) -#define CST226SE_BUFFER_NUM (28) -#define CST226SE_CHIPTYPE (0xA8) - -#if defined(ARDUINO) -TouchClassCST226::TouchClassCST226() +TouchDrvCST226::TouchDrvCST226() : comm(nullptr), hal(nullptr) { } -bool TouchClassCST226::begin(PLATFORM_WIRE_TYPE &wire, uint8_t address, int sda, int scl) +TouchDrvCST226::~TouchDrvCST226() { - return SensorCommon::begin(wire, address, sda, scl); + if (comm) { + comm->deinit(); + } } +#if defined(ARDUINO) +bool TouchDrvCST226::begin(TwoWire &wire, uint8_t addr, int sda, int scl) +{ + if (!beginCommon(comm, hal, wire, addr, sda, scl)) { + return false; + } + return initImpl(); +} #elif defined(ESP_PLATFORM) -#if ((ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL(5,0,0)) && defined(CONFIG_SENSORLIB_ESP_IDF_NEW_API)) -bool TouchClassCST226::begin(i2c_master_bus_handle_t i2c_dev_bus_handle, uint8_t addr) +#if defined(USEING_I2C_LEGACY) +bool TouchDrvCST226::begin(i2c_port_t port_num, uint8_t addr, int sda, int scl) { - return SensorCommon::begin(i2c_dev_bus_handle, addr); + if (!beginCommon(comm, hal, port_num, addr, sda, scl)) { + return false; + } + return true; } #else -bool TouchClassCST226::begin(i2c_port_t port_num, uint8_t addr, int sda, int scl) +bool TouchDrvCST226::begin(i2c_master_bus_handle_t handle, uint8_t addr) { - return SensorCommon::begin(port_num, addr, sda, scl); + if (!beginCommon(comm, hal, handle, addr)) { + return false; + } + return true; } -#endif //ESP_IDF_VERSION - +#endif //USEING_I2C_LEGACY #endif //ARDUINO - -bool TouchClassCST226::begin(uint8_t addr, iic_fptr_t readRegCallback, iic_fptr_t writeRegCallback) +bool TouchDrvCST226::begin(SensorCommCustom::CustomCallback callback, + SensorCommCustomHal::CustomHalCallback hal_callback, + uint8_t addr) { - return SensorCommon::begin(addr, readRegCallback, writeRegCallback); + if (!beginCommCustomCallback(COMM_CUSTOM, + callback, hal_callback, addr, comm, hal)) { + return false; + } + return initImpl(); } -void TouchClassCST226::reset() +void TouchDrvCST226::reset() { - if (__rst != SENSOR_PIN_NONE) { - this->setGpioMode(__rst, OUTPUT); - this->setGpioLevel(__rst, LOW); - delay(100); - this->setGpioLevel(__rst, HIGH); - delay(100); + if (_rst != -1) { + hal->pinMode(_rst, OUTPUT); + hal->digitalWrite(_rst, LOW); + hal->delay(100); + hal->digitalWrite(_rst, HIGH); + hal->delay(100); } else { - writeRegister(0xD1, 0x0E); - delay(20); + comm->writeRegister(0xD1, 0x0E); + hal->delay(20); } } -uint8_t TouchClassCST226::getPoint(int16_t *x_array, int16_t *y_array, uint8_t get_point) +uint8_t TouchDrvCST226::getPoint(int16_t *x_array, int16_t *y_array, uint8_t get_point) { - uint8_t buffer[CST226SE_BUFFER_NUM]; + static constexpr uint8_t statusReg = (0x00); + static constexpr uint8_t bufferSize = (28); + + uint8_t buffer[bufferSize]; uint8_t index = 0; - if (readRegister(CST2xx_REG_STATUS, buffer, CST226SE_BUFFER_NUM) == DEV_WIRE_ERR) { + if (comm->readRegister(statusReg, buffer, bufferSize) == -1) { return 0; } - -#ifdef LOG_PORT - LOG_PORT.print("RAW:"); - for (int i = 0; i < CST226SE_BUFFER_NUM; ++i) { - LOG_PORT.printf("%02X,", buffer[i]); - } - LOG_PORT.println(); -#endif - if (buffer[0] == 0x83 && buffer[1] == 0x17 && buffer[5] == 0x80) { - if (__homeButtonCb) { - __homeButtonCb(__userData); + if (_HButtonCallback) { + _HButtonCallback(_userData); } return 0; } @@ -107,13 +116,14 @@ uint8_t TouchClassCST226::getPoint(int16_t *x_array, int16_t *y_array, uint8_t g if (buffer[0] == 0xAB)return 0; if (buffer[5] == 0x80)return 0; - uint8_t point = buffer[5] & 0x7F; - if (point > 5 || !point) { - writeRegister(0x00, 0xAB); + uint8_t numPoints = buffer[5] & 0x7F; + + if (numPoints > 5 || !numPoints) { + comm->writeRegister(0x00, 0xAB); return 0; } - for (int i = 0; i < point; i++) { + for (int i = 0; i < numPoints; i++) { report.id[i] = buffer[index] >> 4; report.status[i] = buffer[index] & 0x0F; report.x[i] = (uint16_t)((buffer[index + 1] << 4) | ((buffer[index + 3] >> 4) & 0x0F)); @@ -122,34 +132,27 @@ uint8_t TouchClassCST226::getPoint(int16_t *x_array, int16_t *y_array, uint8_t g index = (i == 0) ? (index + 7) : (index + 5); } - updateXY(point, report.x, report.y); + updateXY(numPoints, report.x, report.y); -#ifdef LOG_PORT - for (int i = 0; i < point; i++) { - LOG_PORT.printf("[%d]-X:%u Y:%u P:%u sta:%u ", report.id[i], report.x[i], report.y[i], report.pressure[i], report.status[i]); - } - LOG_PORT.println(); -#endif - - if (point) { + if (numPoints) { for (int i = 0; i < get_point; i++) { x_array[i] = report.x[i]; y_array[i] = report.y[i]; } } - return point; + return numPoints; } -bool TouchClassCST226::isPressed() +bool TouchDrvCST226::isPressed() { static uint32_t lastPulse = 0; - if (__irq != SENSOR_PIN_NONE) { - int val = this->getGpioLevel(__irq) == LOW; + if (_irq != -1) { + int val = hal->digitalRead(_irq) == LOW; if (val) { //Filter low levels with intervals greater than 1000ms - val = (millis() - lastPulse > 1000) ? false : true; - lastPulse = millis(); + val = (hal->millis() - lastPulse > 1000) ? false : true; + lastPulse = hal->millis(); return val; } return false; @@ -158,80 +161,80 @@ bool TouchClassCST226::isPressed() } -const char *TouchClassCST226::getModelName() +const char *TouchDrvCST226::getModelName() { return "CST226SE"; } -void TouchClassCST226::sleep() +void TouchDrvCST226::sleep() { - writeRegister(0xD1, 0x05); -#ifdef ESP32 - if (__irq != SENSOR_PIN_NONE) { - this->setGpioMode(__irq, OPEN_DRAIN); + comm->writeRegister(0xD1, 0x05); +#ifdef ARDUINO_ARCH_ESP32 + if (_irq != -1) { + hal->pinMode(_irq, OPEN_DRAIN); } - if (__rst != SENSOR_PIN_NONE) { - this->setGpioMode(__rst, OPEN_DRAIN); + if (_rst != -1) { + hal->pinMode(_rst, OPEN_DRAIN); } #endif } -void TouchClassCST226::wakeup() +void TouchDrvCST226::wakeup() { reset(); } -void TouchClassCST226::idle() +void TouchDrvCST226::idle() { } -uint8_t TouchClassCST226::getSupportTouchPoint() +uint8_t TouchDrvCST226::getSupportTouchPoint() { return 5; } -bool TouchClassCST226::getResolution(int16_t *x, int16_t *y) +bool TouchDrvCST226::getResolution(int16_t *x, int16_t *y) { - *x = __resX; - *y = __resY; + *x = _resX; + *y = _resY; return true; } -void TouchClassCST226::setHomeButtonCallback(home_button_callback_t cb, void *user_data) +void TouchDrvCST226::setHomeButtonCallback(HomeButtonCallback cb, void *user_data) { - __homeButtonCb = cb; - __userData = user_data; + _HButtonCallback = cb; + _userData = user_data; } -void TouchClassCST226::setGpioCallback(gpio_mode_fptr_t mode_cb, - gpio_write_fptr_t write_cb, - gpio_read_fptr_t read_cb) +void TouchDrvCST226::setGpioCallback(CustomMode mode_cb, + CustomWrite write_cb, + CustomRead read_cb) { - SensorCommon::setGpioModeCallback(mode_cb); - SensorCommon::setGpioWriteCallback(write_cb); - SensorCommon::setGpioReadCallback(read_cb); + SensorHalCustom::setCustomMode(mode_cb); + SensorHalCustom::setCustomWrite(write_cb); + SensorHalCustom::setCustomRead(read_cb); } -bool TouchClassCST226::initImpl() +bool TouchDrvCST226::initImpl() { - if (__rst != SENSOR_PIN_NONE) { - this->setGpioMode(__rst, OUTPUT); + if (_rst != -1) { + hal->pinMode(_rst, OUTPUT); } - if (__irq != SENSOR_PIN_NONE) { - this->setGpioMode(__irq, INPUT); + if (_irq != -1) { + hal->pinMode(_irq, INPUT); } reset(); uint8_t buffer[8]; // Enter Command mode - writeRegister(0xD1, 0x01); - delay(10); + comm->writeRegister(0xD1, 0x01); + hal->delay(10); uint8_t write_buffer[2] = {0xD1, 0xFC}; - writeThenRead(write_buffer, 2, buffer, 4); + comm->writeThenRead(write_buffer, 2, buffer, 4); uint32_t checkcode = 0; checkcode = buffer[3]; checkcode <<= 8; @@ -245,14 +248,14 @@ bool TouchClassCST226::initImpl() write_buffer[0] = {0xD1}; write_buffer[1] = {0xF8}; - writeThenRead(write_buffer, 2, buffer, 4); - __resX = ( buffer[1] << 8) | buffer[0]; - __resY = ( buffer[3] << 8) | buffer[2]; - log_i("Chip resolution X:%u Y:%u", __resX, __resY); + comm->writeThenRead(write_buffer, 2, buffer, 4); + _resX = ( buffer[1] << 8) | buffer[0]; + _resY = ( buffer[3] << 8) | buffer[2]; + log_i("Chip resolution X:%u Y:%u", _resX, _resY); write_buffer[0] = {0xD2}; write_buffer[1] = {0x04}; - writeThenRead(write_buffer, 2, buffer, 4); + comm->writeThenRead(write_buffer, 2, buffer, 4); uint32_t chipType = buffer[3]; chipType <<= 8; chipType |= buffer[2]; @@ -268,7 +271,7 @@ bool TouchClassCST226::initImpl() write_buffer[0] = {0xD2}; write_buffer[1] = {0x08}; - writeThenRead(write_buffer, 2, buffer, 8); + comm->writeThenRead(write_buffer, 2, buffer, 8); uint32_t fwVersion = buffer[3]; fwVersion <<= 8; @@ -303,18 +306,14 @@ bool TouchClassCST226::initImpl() return false; } - __chipID = chipType; + _chipID = chipType; // Exit Command mode - writeRegister(0xD1, 0x09); + comm->writeRegister(0xD1, 0x09); return true; } -int TouchClassCST226::getReadMaskImpl() -{ - return -1; -} diff --git a/src/touch/TouchClassCST226.h b/src/touch/TouchDrvCST226.h similarity index 61% rename from src/touch/TouchClassCST226.h rename to src/touch/TouchDrvCST226.h index 7d1ceaa..e62a680 100644 --- a/src/touch/TouchClassCST226.h +++ b/src/touch/TouchDrvCST226.h @@ -22,37 +22,38 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. * - * @file TouchClassCST226.h + * @file TouchDrvCST226.h * @author Lewis He (lewishe@outlook.com) * @date 2023-10-06 */ #pragma once -#include "../TouchDrvInterface.hpp" -#include "../SensorCommon.tpp" +#include "TouchDrvInterface.hpp" -class TouchClassCST226 : public TouchDrvInterface, - public SensorCommon -{ - friend class SensorCommon; +#define CST226SE_SLAVE_ADDRESS (0x5A) +class TouchDrvCST226 : public TouchDrvInterface +{ public: -#if defined(ARDUINO) - TouchClassCST226(); + TouchDrvCST226(); - bool begin(PLATFORM_WIRE_TYPE &wire, uint8_t address, int sda, int scl); + ~TouchDrvCST226(); +#if defined(ARDUINO) + bool begin(TwoWire &wire, uint8_t addr = CST226SE_SLAVE_ADDRESS, int sda = -1, int scl = -1); #elif defined(ESP_PLATFORM) -#if ((ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL(5,0,0)) && defined(CONFIG_SENSORLIB_ESP_IDF_NEW_API)) - bool begin(i2c_master_bus_handle_t i2c_dev_bus_handle, uint8_t addr); +#if defined(USEING_I2C_LEGACY) + bool begin(i2c_port_t port_num, uint8_t addr = CST226SE_SLAVE_ADDRESS, int sda = -1, int scl = -1); #else - bool begin(i2c_port_t port_num, uint8_t addr, int sda, int scl); -#endif //ESP_IDF_VERSION - + bool begin(i2c_master_bus_handle_t handle, uint8_t addr = CST226SE_SLAVE_ADDRESS); +#endif #endif - bool begin(uint8_t addr, iic_fptr_t readRegCallback, iic_fptr_t writeRegCallback); + + bool begin(SensorCommCustom::CustomCallback callback, + SensorCommCustomHal::CustomHalCallback hal_callback, + uint8_t addr = CST226SE_SLAVE_ADDRESS); void reset(); @@ -72,18 +73,19 @@ class TouchClassCST226 : public TouchDrvInterface, bool getResolution(int16_t *x, int16_t *y); - void setHomeButtonCallback(home_button_callback_t cb, void *user_data); + void setHomeButtonCallback(HomeButtonCallback cb, void *user_data); - void setGpioCallback(gpio_mode_fptr_t mode_cb, - gpio_write_fptr_t write_cb, - gpio_read_fptr_t read_cb); + void setGpioCallback(CustomMode mode_cb, + CustomWrite write_cb, + CustomRead read_cb); private: bool initImpl(); - int getReadMaskImpl(); protected: + std::unique_ptr comm; + std::unique_ptr hal; TouchData report; - + static constexpr uint8_t CST226SE_CHIPTYPE = (0xA8); }; diff --git a/src/touch/TouchDrvCST816.cpp b/src/touch/TouchDrvCST816.cpp new file mode 100644 index 0000000..b8d0cc8 --- /dev/null +++ b/src/touch/TouchDrvCST816.cpp @@ -0,0 +1,305 @@ +/** + * + * @license MIT License + * + * Copyright (c) 2023 lewis he + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * @file TouchDrvCST816.cpp + * @author Lewis He (lewishe@outlook.com) + * @date 2023-10-06 + */ +#include "TouchDrvCST816.h" + +TouchDrvCST816::TouchDrvCST816() : comm(nullptr), hal(nullptr), + _center_btn_x(0), + _center_btn_y(0) +{ +} + +TouchDrvCST816::~TouchDrvCST816() +{ + if (comm) { + comm->deinit(); + } +} + +#if defined(ARDUINO) +bool TouchDrvCST816::begin(TwoWire &wire, uint8_t addr, int sda, int scl) +{ + if (!beginCommon(comm, hal, wire, addr, sda, scl)) { + return false; + } + return initImpl(); +} +#elif defined(ESP_PLATFORM) + +#if defined(USEING_I2C_LEGACY) +bool TouchDrvCST816::begin(i2c_port_t port_num, uint8_t addr, int sda, int scl) +{ + if (!beginCommon(comm, hal, port_num, addr, sda, scl)) { + return false; + } + return true; +} +#else +bool TouchDrvCST816::begin(i2c_master_bus_handle_t handle, uint8_t addr) +{ + if (!beginCommon(comm, hal, handle, addr)) { + return false; + } + return true; +} +#endif //USEING_I2C_LEGACY +#endif //ARDUINO + +bool TouchDrvCST816::begin(SensorCommCustom::CustomCallback callback, + SensorCommCustomHal::CustomHalCallback hal_callback, + uint8_t addr) +{ + if (!beginCommCustomCallback(COMM_CUSTOM, + callback, hal_callback, addr, comm, hal)) { + return false; + } + return initImpl(); +} + +void TouchDrvCST816::reset() +{ + if (_rst != -1) { + hal->pinMode(_rst, OUTPUT); + hal->digitalWrite(_rst, LOW); + hal->delay(30); + hal->digitalWrite(_rst, HIGH); + hal->delay(50); + } +} + +uint8_t TouchDrvCST816::getPoint(int16_t *x_array, int16_t *y_array, uint8_t get_point) +{ + uint8_t buffer[13]; + if (comm->readRegister(CST8xx_REG_STATUS, buffer, 13) == -1) { + return 0; + } + + if (!buffer[2] || !x_array || !y_array || !get_point) { + return 0; + } + + // Some CST816T will return all 0xFF after turning off automatic sleep. + if (buffer[2] == 0xFF) { + return 0; + } + + uint8_t numPoints = buffer[2] & 0x0F; + + // CST816 only supports single touch + if (numPoints > 1) { + return 0; + } + + int16_t tmp_x, tmp_y; + + tmp_x = ((buffer[CST8xx_REG_XPOS_HIGH] & 0x0F) << 8 | buffer[CST8xx_REG_XPOS_LOW]); + tmp_y = ((buffer[CST8xx_REG_YPOS_HIGH] & 0x0F) << 8 | buffer[CST8xx_REG_YPOS_LOW]); + + // Depends on touch screen firmware + if (tmp_x == _center_btn_x && tmp_y == _center_btn_y && _HButtonCallback) { + _HButtonCallback(_userData); + return 0; + } + + x_array[0] = tmp_x; + y_array[0] = tmp_y; + + updateXY(numPoints, x_array, y_array); + + return numPoints; +} + +bool TouchDrvCST816::isPressed() +{ + static uint32_t lastPulse = 0; + if (_irq != -1) { + int val = hal->digitalRead(_irq) == LOW; + if (val) { + //Filter low levels with intervals greater than 1000ms + val = (hal->millis() - lastPulse > 1000) ? false : true; + lastPulse = hal->millis(); + return val; + } + return false; + } + return getPoint(NULL, NULL, 1); +} + + +const char *TouchDrvCST816::getModelName() +{ + switch (_chipID) { + case CST816S_CHIP_ID: + return "CST816S"; + case CST816T_CHIP_ID: + return "CST816T"; + case CST716_CHIP_ID: + return "CST716"; + case CST820_CHIP_ID: + return "CST820"; + case CST816D_CHIP_ID: + return "CST816D"; + default: + break; + } + return "UNKNOW"; +} + +void TouchDrvCST816::sleep() +{ + comm->writeRegister(CST8xx_REG_SLEEP, 0x03); +#ifdef ARDUINO_ARCH_ESP32 + if (_irq != -1) { + hal->pinMode(_irq, OPEN_DRAIN); + } + if (_rst != -1) { + hal->pinMode(_rst, OPEN_DRAIN); + } +#endif +} + +void TouchDrvCST816::wakeup() +{ + reset(); +} + +void TouchDrvCST816::idle() +{ + +} + +uint8_t TouchDrvCST816::getSupportTouchPoint() +{ + return 1; +} + +bool TouchDrvCST816::getResolution(int16_t *x, int16_t *y) +{ + return false; +} + +void TouchDrvCST816::setHomeButtonCallback(HomeButtonCallback cb, void *user_data) +{ + _HButtonCallback = cb; + _userData = user_data; +} + +void TouchDrvCST816::setCenterButtonCoordinate(int16_t x, int16_t y) +{ + _center_btn_x = x; + _center_btn_y = y; +} + + +void TouchDrvCST816::disableAutoSleep() +{ + switch (_chipID) { + case CST816S_CHIP_ID: + case CST816T_CHIP_ID: + case CST820_CHIP_ID: + case CST816D_CHIP_ID: + reset(); + hal->delay(50); + comm->writeRegister(CST8xx_REG_DIS_AUTOSLEEP, 0x01); + break; + case CST716_CHIP_ID: + default: + break; + } +} + +void TouchDrvCST816::enableAutoSleep() +{ + switch (_chipID) { + case CST816S_CHIP_ID: + case CST816T_CHIP_ID: + case CST820_CHIP_ID: + case CST816D_CHIP_ID: + reset(); + hal->delay(50); + comm->writeRegister(CST8xx_REG_DIS_AUTOSLEEP, (uint8_t)0x00); + break; + case CST716_CHIP_ID: + default: + break; + } +} + +void TouchDrvCST816::setGpioCallback(CustomMode mode_cb, + CustomWrite write_cb, + CustomRead read_cb) +{ + SensorHalCustom::setCustomMode(mode_cb); + SensorHalCustom::setCustomWrite(write_cb); + SensorHalCustom::setCustomRead(read_cb); +} + +bool TouchDrvCST816::initImpl() +{ + + if (_rst != -1) { + hal->pinMode(_rst, OUTPUT); + } + + if (_irq != -1) { + hal->pinMode(_irq, INPUT); + } + + reset(); + + int chip_id = comm->readRegister(CST8xx_REG_CHIP_ID); + log_i("Chip ID:0x%x", chip_id); + + int version = comm->readRegister(CST8xx_REG_FW_VERSION); + log_i("Version :0x%x", version); + + // CST716 : 0x20 + // CST816S : 0xB4 + // CST816T : 0xB5 + // CST816D : 0xB6 + // CST226SE : A7 = 0X20 + if (chip_id != CST816S_CHIP_ID && + chip_id != CST816T_CHIP_ID && + chip_id != CST820_CHIP_ID && + chip_id != CST816D_CHIP_ID && + (chip_id != CST716_CHIP_ID || version == 0)) { + log_e("Chip ID does not match, should be CST816S:0X%02X , CST816T:0X%02X , CST816D:0X%02X , CST820:0X%02X , CST716:0X%02X", + CST816S_CHIP_ID, CST816T_CHIP_ID, CST816D_CHIP_ID, CST820_CHIP_ID, CST716_CHIP_ID); + return false; + } + + _chipID = chip_id; + + log_i("Touch type:%s", getModelName()); + + return true; +} + + + + diff --git a/src/touch/TouchDrvCST816.h b/src/touch/TouchDrvCST816.h new file mode 100644 index 0000000..3aa2a29 --- /dev/null +++ b/src/touch/TouchDrvCST816.h @@ -0,0 +1,118 @@ +/** + * + * @license MIT License + * + * Copyright (c) 2023 lewis he + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * @file TouchDrvCST816.h + * @author Lewis He (lewishe@outlook.com) + * @date 2023-10-06 + */ +#pragma once + +#include "TouchDrvInterface.hpp" + +#define CST816_SLAVE_ADDRESS 0x15 + +class TouchDrvCST816 : public TouchDrvInterface +{ +public: + TouchDrvCST816(); + + ~TouchDrvCST816(); + +#if defined(ARDUINO) + bool begin(TwoWire &wire, uint8_t address = CST816_SLAVE_ADDRESS, int sda = -1, int scl = -1); +#elif defined(ESP_PLATFORM) +#if defined(USEING_I2C_LEGACY) + bool begin(i2c_port_t port_num, uint8_t addr = CST816_SLAVE_ADDRESS, int sda = -1, int scl = -1); +#else + bool begin(i2c_master_bus_handle_t handle, uint8_t addr = CST816_SLAVE_ADDRESS); +#endif +#endif + + bool begin(SensorCommCustom::CustomCallback callback, + SensorCommCustomHal::CustomHalCallback hal_callback, + uint8_t addr = CST816_SLAVE_ADDRESS); + + void reset(); + + uint8_t getPoint(int16_t *x_array, int16_t *y_array, uint8_t get_point); + + bool isPressed(); + + const char *getModelName(); + + void sleep(); + + void wakeup(); + + void idle(); + + uint8_t getSupportTouchPoint(); + + bool getResolution(int16_t *x, int16_t *y); + + void setCenterButtonCoordinate(int16_t x, int16_t y); + + void setHomeButtonCallback(HomeButtonCallback cb, void *user_data); + + void disableAutoSleep(); + + void enableAutoSleep(); + + void setGpioCallback(CustomMode mode_cb, + CustomWrite write_cb, + CustomRead read_cb); + +private: + bool initImpl(); + +protected: + std::unique_ptr comm; + std::unique_ptr hal; + + int16_t _center_btn_x; + int16_t _center_btn_y; + + static constexpr uint8_t CST8xx_REG_STATUS = (0x00); + static constexpr uint8_t CST8xx_REG_XPOS_HIGH = (0x03); + static constexpr uint8_t CST8xx_REG_XPOS_LOW = (0x04); + static constexpr uint8_t CST8xx_REG_YPOS_HIGH = (0x05); + static constexpr uint8_t CST8xx_REG_YPOS_LOW = (0x06); + static constexpr uint8_t CST8xx_REG_DIS_AUTOSLEEP = (0xFE); + static constexpr uint8_t CST8xx_REG_CHIP_ID = (0xA7); + static constexpr uint8_t CST8xx_REG_FW_VERSION = (0xA9); + static constexpr uint8_t CST8xx_REG_SLEEP = (0xE5); + static constexpr uint8_t CST816S_CHIP_ID = (0xB4); + static constexpr uint8_t CST816T_CHIP_ID = (0xB5); + static constexpr uint8_t CST716_CHIP_ID = (0x20); + static constexpr uint8_t CST820_CHIP_ID = (0xB7); + static constexpr uint8_t CST816D_CHIP_ID = (0xB6); + +}; + + + + + + + diff --git a/src/touch/TouchDrvCST92xx.cpp b/src/touch/TouchDrvCST92xx.cpp index 305517d..d9c4d25 100644 --- a/src/touch/TouchDrvCST92xx.cpp +++ b/src/touch/TouchDrvCST92xx.cpp @@ -28,49 +28,69 @@ */ #include "TouchDrvCST92xx.h" -TouchDrvCST92xx::TouchDrvCST92xx(): - __center_btn_x(0), - __center_btn_y(0) - /*, - __jump_check(false)*/ +TouchDrvCST92xx::TouchDrvCST92xx() : comm(nullptr), hal(nullptr), + _slave_addr(-1), + _center_btn_x(0), + _center_btn_y(0) { } +TouchDrvCST92xx::~TouchDrvCST92xx() +{ + if (comm) { + comm->deinit(); + } +} + #if defined(ARDUINO) -bool TouchDrvCST92xx::begin(PLATFORM_WIRE_TYPE &wire, uint8_t address, int sda, int scl) +bool TouchDrvCST92xx::begin(TwoWire &wire, uint8_t addr, int sda, int scl) { - return SensorCommon::begin(wire, address, sda, scl); + if (!beginCommon(comm, hal, wire, addr, sda, scl)) { + return false; + } + return initImpl(); } #elif defined(ESP_PLATFORM) -#if ((ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL(5,0,0)) && defined(CONFIG_SENSORLIB_ESP_IDF_NEW_API)) -bool TouchDrvCST92xx::begin(i2c_master_bus_handle_t i2c_dev_bus_handle, uint8_t addr) +#if defined(USEING_I2C_LEGACY) +bool TouchDrvCST92xx::begin(i2c_port_t port_num, uint8_t addr, int sda, int scl) { - return SensorCommon::begin(i2c_dev_bus_handle, addr); + if (!beginCommon(comm, hal, port_num, addr, sda, scl)) { + return false; + } + return true; } #else -bool TouchDrvCST92xx::begin(i2c_port_t port_num, uint8_t addr, int sda, int scl) +bool TouchDrvCST92xx::begin(i2c_master_bus_handle_t handle, uint8_t addr) { - return SensorCommon::begin(port_num, addr, sda, scl); + if (!beginCommon(comm, hal, handle, addr)) { + return false; + } + return true; } +#endif //USEING_I2C_LEGACY +#endif //ARDUINO -#endif //ESP_IDF_VERSION -#endif //ARDUINO - -bool TouchDrvCST92xx::begin(uint8_t addr, iic_fptr_t readRegCallback, iic_fptr_t writeRegCallback) +bool TouchDrvCST92xx::begin(SensorCommCustom::CustomCallback callback, + SensorCommCustomHal::CustomHalCallback hal_callback, + uint8_t addr) { - return SensorCommon::begin(addr, readRegCallback, writeRegCallback); + if (!beginCommCustomCallback(COMM_CUSTOM, + callback, hal_callback, addr, comm, hal)) { + return false; + } + return initImpl(); } void TouchDrvCST92xx::reset() { - if (__rst != SENSOR_PIN_NONE) { - this->setGpioMode(__rst, OUTPUT); - this->setGpioLevel(__rst, LOW); - delay(10); - this->setGpioLevel(__rst, HIGH); + if (_rst != -1) { + hal->pinMode(_rst, OUTPUT); + hal->digitalWrite(_rst, LOW); + hal->delay(10); + hal->digitalWrite(_rst, HIGH); } } @@ -92,7 +112,7 @@ void TouchDrvCST92xx::parseFingerData(uint8_t *data, cst9xx_point_t *point) uint8_t TouchDrvCST92xx::getPoint(int16_t *x_array, int16_t *y_array, uint8_t get_point) { int16_t res = 0; - uint8_t point = 0; + uint8_t numPoints = 0; uint8_t read_buffer[CST92XX_MAX_FINGER_NUM * 5 + 5] = {0}; uint8_t write_buffer[4] = {0}; cst9xx_point_t point_info[CST92XX_MAX_FINGER_NUM]; @@ -105,8 +125,8 @@ uint8_t TouchDrvCST92xx::getPoint(int16_t *x_array, int16_t *y_array, uint8_t ge //Write read command write_buffer[0] = highByte(CST92XX_READ_COMMAND); write_buffer[1] = lowByte(CST92XX_READ_COMMAND); - res = writeThenRead(write_buffer, 2, read_buffer, sizeof(read_buffer)); - if (res != DEV_WIRE_NONE) { + res = comm->writeThenRead(write_buffer, 2, read_buffer, sizeof(read_buffer)); + if (res != 0) { log_e("Write read command error"); return 0; } @@ -114,8 +134,8 @@ uint8_t TouchDrvCST92xx::getPoint(int16_t *x_array, int16_t *y_array, uint8_t ge write_buffer[0] = highByte(CST92XX_READ_COMMAND); write_buffer[1] = lowByte(CST92XX_READ_COMMAND); write_buffer[2] = CST92XX_ACK; - res = writeBuffer(write_buffer, 3); - if (res != DEV_WIRE_NONE) { + res = comm->writeBuffer(write_buffer, 3); + if (res != 0) { log_e("Write read ack error"); return 0; } @@ -127,11 +147,11 @@ uint8_t TouchDrvCST92xx::getPoint(int16_t *x_array, int16_t *y_array, uint8_t ge } // palm + gesture - if (CST92XX_GET_GESTURE(read_buffer[4])) { + if (read_buffer[4] & 0xF0) { log_d("read point read_buffer[4]=0x%x.\n", read_buffer[4]); if ((read_buffer[4] >> 7) == 0x01) { - if (__homeButtonCb) { - __homeButtonCb(__userData); + if (_HButtonCallback) { + _HButtonCallback(_userData); } // bool palm = true; } else if (read_buffer[4] >> 4) { @@ -139,16 +159,16 @@ uint8_t TouchDrvCST92xx::getPoint(int16_t *x_array, int16_t *y_array, uint8_t ge } } - point = CST92XX_GET_FINGER_NUM(read_buffer[5]); - if (point > CST92XX_MAX_FINGER_NUM || point == 0) { + numPoints = (read_buffer[5] & 0x7F); + if (numPoints > CST92XX_MAX_FINGER_NUM || numPoints == 0) { return 0; } /* // button if ((read_buffer[5] & 0x80) == 0x80) { - uint8_t *data = read_buffer + point * 5; - if (point > 0) { + uint8_t *data = read_buffer + numPoints * 5; + if (numPoints > 0) { data += 2; } uint8_t key_id = data[0]; @@ -156,7 +176,7 @@ uint8_t TouchDrvCST92xx::getPoint(int16_t *x_array, int16_t *y_array, uint8_t ge } */ - for (uint8_t i = 0; i < point; ++i) { + for (uint8_t i = 0; i < numPoints; ++i) { uint8_t *data = read_buffer + (i * 5) + (i == 0 ? 0 : 2); parseFingerData(data, &point_info[i]); x_array[i] = point_info[i].x; @@ -169,16 +189,16 @@ uint8_t TouchDrvCST92xx::getPoint(int16_t *x_array, int16_t *y_array, uint8_t ge return 0; } - updateXY(point, x_array, y_array); + updateXY(numPoints, x_array, y_array); - return point; + return numPoints; } // CST9217/CST9217 touch level is once per second, not continuous low level bool TouchDrvCST92xx::isPressed() { - if (__irq != SENSOR_PIN_NONE) { - return this->getGpioLevel(__irq) == LOW; + if (_irq != -1) { + return hal->digitalRead(_irq) == LOW; } return getPoint(NULL, NULL, 1); } @@ -186,7 +206,7 @@ bool TouchDrvCST92xx::isPressed() const char *TouchDrvCST92xx::getModelName() { - switch (__chipID) { + switch (_chipID) { case CST9220_CHIP_ID: return "CST9220"; case CST9217_CHIP_ID: @@ -206,13 +226,13 @@ void TouchDrvCST92xx::sleep() //Send sleep command write_buffer[0] = highByte(CST92XX_REG_SLEEP_MODE); write_buffer[1] = lowByte(CST92XX_REG_SLEEP_MODE); - writeBuffer(write_buffer, 2); -#ifdef ESP32 - if (__irq != SENSOR_PIN_NONE) { - this->setGpioMode(__irq, OPEN_DRAIN); + comm->writeBuffer(write_buffer, 2); +#ifdef ARDUINO_ARCH_ESP32 + if (_irq != -1) { + hal->pinMode(_irq, OPEN_DRAIN); } - if (__rst != SENSOR_PIN_NONE) { - this->setGpioMode(__rst, OPEN_DRAIN); + if (_rst != -1) { + hal->pinMode(_rst, OPEN_DRAIN); } #endif } @@ -233,15 +253,15 @@ uint8_t TouchDrvCST92xx::getSupportTouchPoint() bool TouchDrvCST92xx::getResolution(int16_t *x, int16_t *y) { - *x = __resX; - *y = __resY; + *x = _resX; + *y = _resY; return true; } -void TouchDrvCST92xx::setCoverScreenCallback(home_button_callback_t cb, void *user_data) +void TouchDrvCST92xx::setCoverScreenCallback(HomeButtonCallback cb, void *user_data) { - __homeButtonCb = cb; - __userData = user_data; + _HButtonCallback = cb; + _userData = user_data; } /** @@ -253,16 +273,18 @@ uint32_t TouchDrvCST92xx::readWordFromMem(uint8_t type, uint16_t mem_addr) uint8_t write_buffer[4] = {0}; uint8_t read_buffer[4] = {0}; - uint8_t slave_address = __addr; + if (_slave_addr != -1 && _slave_addr != CST92XX_BOOT_ADDRESS) { + I2CParam params(I2CParam::I2C_SET_ADDR, CST92XX_BOOT_ADDRESS); + comm->setParams(params); + } - __addr = CST92XX_BOOT_ADDRESS; write_buffer[0] = 0xA0; write_buffer[1] = 0x10; write_buffer[2] = type; - res = writeBuffer(write_buffer, 3); - if (res != DEV_WIRE_NONE) { + res = comm->writeBuffer(write_buffer, 3); + if (res != 0) { log_e("Write 0A010 failed"); goto ERROR; } @@ -272,8 +294,8 @@ uint32_t TouchDrvCST92xx::readWordFromMem(uint8_t type, uint16_t mem_addr) write_buffer[2] = mem_addr; write_buffer[3] = mem_addr >> 8; - res = writeBuffer(write_buffer, 4); - if (res != DEV_WIRE_NONE) { + res = comm->writeBuffer(write_buffer, 4); + if (res != 0) { log_e("Write 0A00C failed"); goto ERROR; } @@ -282,8 +304,8 @@ uint32_t TouchDrvCST92xx::readWordFromMem(uint8_t type, uint16_t mem_addr) write_buffer[1] = 0x04; write_buffer[2] = 0xE4; - res = writeBuffer(write_buffer, 3); - if (res != DEV_WIRE_NONE) { + res = comm->writeBuffer(write_buffer, 3); + if (res != 0) { log_e("Write 0A004E4 failed"); goto ERROR; } @@ -294,8 +316,8 @@ uint32_t TouchDrvCST92xx::readWordFromMem(uint8_t type, uint16_t mem_addr) } write_buffer[0] = 0xA0; write_buffer[1] = 0x04; - res = writeThenRead(write_buffer, 2, read_buffer, 1); - if (res != DEV_WIRE_NONE) { + res = comm->writeThenRead(write_buffer, 2, read_buffer, 1); + if (res != 0) { log_e("Write 0A004 failed"); goto ERROR; } @@ -306,19 +328,25 @@ uint32_t TouchDrvCST92xx::readWordFromMem(uint8_t type, uint16_t mem_addr) } write_buffer[0] = 0xA0; write_buffer[1] = 0x18; - res = writeThenRead(write_buffer, 2, read_buffer, 4); - if (res != DEV_WIRE_NONE) { + res = comm->writeThenRead(write_buffer, 2, read_buffer, 4); + if (res != 0) { goto ERROR; } - __addr = slave_address; + if (_slave_addr != -1 && _slave_addr != CST92XX_BOOT_ADDRESS) { + I2CParam params(I2CParam::I2C_SET_ADDR, _slave_addr); + comm->setParams(params); + } return ((uint32_t)(read_buffer[0])) | (((uint32_t)(read_buffer[1])) << 8) | (((uint32_t)(read_buffer[2])) << 16) | (((uint32_t)(read_buffer[3])) << 24); ERROR: - __addr = slave_address; + if (_slave_addr != -1 && _slave_addr != CST92XX_BOOT_ADDRESS) { + I2CParam params(I2CParam::I2C_SET_ADDR, _slave_addr); + comm->setParams(params); + } return 0; } @@ -334,7 +362,7 @@ uint32_t TouchDrvCST92xx::getChipType() chip_type &= 0xffff; break; } - delay(10); + hal->delay(10); } log_d("Chip Type: 0x%04lx", chip_type); // log_d("Module_id: 0x%04x", chip_id); @@ -364,9 +392,10 @@ bool TouchDrvCST92xx::enterBootloader(void) uint8_t write_buffer[4] = {0}; uint8_t read_buffer[4] = {0}; - uint8_t slave_address = __addr; - - __addr = CST92XX_BOOT_ADDRESS; + if (_slave_addr != -1 && _slave_addr != CST92XX_BOOT_ADDRESS) { + I2CParam params(I2CParam::I2C_SET_ADDR, CST92XX_BOOT_ADDRESS); + comm->setParams(params); + } for (uint8_t i = 10;; i += 2) { @@ -377,23 +406,23 @@ bool TouchDrvCST92xx::enterBootloader(void) reset(); - delay(i); + hal->delay(i); for (check_cnt = 0; check_cnt < 5; check_cnt++) { write_buffer[0] = 0xA0; write_buffer[1] = 0x01; write_buffer[2] = 0xAA; - res = writeBuffer(write_buffer, 3); - if (res != DEV_WIRE_NONE) { - delay(2); + res = comm->writeBuffer(write_buffer, 3); + if (res != 0) { + hal->delay(2); continue; } - delay(2); + hal->delay(2); write_buffer[0] = 0xA0; write_buffer[1] = 0x02; - res = writeThenRead(write_buffer, 2, read_buffer, 2); - if (res != DEV_WIRE_NONE) { - delay(2); + res = comm->writeThenRead(write_buffer, 2, read_buffer, 2); + if (res != 0) { + hal->delay(2); continue; } if ((read_buffer[0] == 0x55) && (read_buffer[1] == 0xB0)) { @@ -408,17 +437,23 @@ bool TouchDrvCST92xx::enterBootloader(void) write_buffer[0] = 0xA0; write_buffer[1] = 0x01; write_buffer[2] = 0x00; - res = writeBuffer(write_buffer, 3); - if (res != DEV_WIRE_NONE) { + res = comm->writeBuffer(write_buffer, 3); + if (res != 0) { log_e("Enter boot exit error"); goto ERROR; } - __addr = slave_address; + if (_slave_addr != -1 && _slave_addr != CST92XX_BOOT_ADDRESS) { + I2CParam params(I2CParam::I2C_SET_ADDR, _slave_addr); + comm->setParams(params); + } log_d("Enter boot mode success!"); return true; ERROR: - __addr = slave_address; + if (_slave_addr != -1 && _slave_addr != CST92XX_BOOT_ADDRESS) { + I2CParam params(I2CParam::I2C_SET_ADDR, _slave_addr); + comm->setParams(params); + } return false; } @@ -428,14 +463,14 @@ bool TouchDrvCST92xx::getAttribute() reset(); // Wait exit boot mode - delay(30); + hal->delay(30); uint8_t buffer[8]; // Enter Command mode - writeRegister(0xD1, 0x01); - delay(10); + comm->writeRegister(0xD1, 0x01); + hal->delay(10); uint8_t write_buffer[2] = {0xD1, 0xFC}; - writeThenRead(write_buffer, 2, buffer, 4); + comm->writeThenRead(write_buffer, 2, buffer, 4); uint32_t checkcode = 0; checkcode = buffer[3]; checkcode <<= 8; @@ -449,14 +484,14 @@ bool TouchDrvCST92xx::getAttribute() write_buffer[0] = {0xD1}; write_buffer[1] = {0xF8}; - writeThenRead(write_buffer, 2, buffer, 4); - __resX = ( buffer[1] << 8) | buffer[0]; - __resY = ( buffer[3] << 8) | buffer[2]; - log_i("Chip resolution X:%u Y:%u", __resX, __resY); + comm->writeThenRead(write_buffer, 2, buffer, 4); + _resX = ( buffer[1] << 8) | buffer[0]; + _resY = ( buffer[3] << 8) | buffer[2]; + log_i("Chip resolution X:%u Y:%u", _resX, _resY); write_buffer[0] = {0xD2}; write_buffer[1] = {0x04}; - writeThenRead(write_buffer, 2, buffer, 4); + comm->writeThenRead(write_buffer, 2, buffer, 4); chipType = buffer[3]; chipType <<= 8; chipType |= buffer[2]; @@ -470,7 +505,7 @@ bool TouchDrvCST92xx::getAttribute() write_buffer[0] = {0xD2}; write_buffer[1] = {0x08}; - writeThenRead(write_buffer, 2, buffer, 8); + comm->writeThenRead(write_buffer, 2, buffer, 8); uint32_t fwVersion = buffer[3]; fwVersion <<= 8; @@ -519,23 +554,23 @@ bool TouchDrvCST92xx::setMode(uint8_t mode) for (i = 0; i < 3; i++) { write_buffer[0] = 0xD1; write_buffer[1] = 0x1E; - res = writeBuffer(write_buffer, 2); - if (res != DEV_WIRE_NONE) { - delay(200); + res = comm->writeBuffer(write_buffer, 2); + if (res != 0) { + hal->delay(200); continue; } write_buffer[0] = 0xD1; write_buffer[1] = 0x1E; - res = writeBuffer(write_buffer, 2); - if (res != DEV_WIRE_NONE) { - delay(200); + res = comm->writeBuffer(write_buffer, 2); + if (res != 0) { + hal->delay(200); continue; } write_buffer[0] = 0x00; write_buffer[1] = 0x02; - res = writeThenRead(write_buffer, 2, read_buffer, 4); - if (res != DEV_WIRE_NONE) { - delay(200); + res = comm->writeThenRead(write_buffer, 2, read_buffer, 4); + if (res != 0) { + hal->delay(200); continue; } if (read_buffer[1] == 0x1E) @@ -572,17 +607,17 @@ bool TouchDrvCST92xx::setMode(uint8_t mode) for (i = 0; i < 10; i++) { write_buffer[0] = highByte(CST92XX_REG_FACTORY_MODE); write_buffer[1] = lowByte(CST92XX_REG_FACTORY_MODE); - res = writeBuffer(write_buffer, 2); - if (res != DEV_WIRE_NONE) { - delay(1); + res = comm->writeBuffer(write_buffer, 2); + if (res != 0) { + hal->delay(1); continue; } - delay(10); + hal->delay(10); write_buffer[0] = 0x00; write_buffer[1] = 0x09; - res = writeThenRead(write_buffer, 2, read_buffer, 1); - if (res != DEV_WIRE_NONE) { - delay(1); + res = comm->writeThenRead(write_buffer, 2, read_buffer, 1); + if (res != 0) { + hal->delay(1); continue; } if (read_buffer[0] == 0x14) @@ -590,8 +625,8 @@ bool TouchDrvCST92xx::setMode(uint8_t mode) } write_buffer[0] = 0xD1; write_buffer[1] = 0x19; - res = writeBuffer(write_buffer, 2); - if (res != DEV_WIRE_NONE) { + res = comm->writeBuffer(write_buffer, 2); + if (res != 0) { log_e("set_work_mode 0xD119 error"); return false; } @@ -627,122 +662,64 @@ bool TouchDrvCST92xx::setMode(uint8_t mode) } } mode_cmd = write_buffer[1]; - res = writeBuffer(write_buffer, 2); - if (res != DEV_WIRE_NONE) { + res = comm->writeBuffer(write_buffer, 2); + if (res != 0) { log_e("set_work_mode 0x%x 0x%x error", write_buffer[0], write_buffer[1]); return false; } write_buffer[0] = 0x00; write_buffer[1] = 0x02; - res = writeThenRead(write_buffer, 2, read_buffer, 2); - if (res != DEV_WIRE_NONE) { + res = comm->writeThenRead(write_buffer, 2, read_buffer, 2); + if (res != 0) { log_e("set_work_mode read 0x0002 failed : 0x%X 0x%X", read_buffer[0], read_buffer[1]); } if (mode_cmd != read_buffer[1]) { log_e("set work mode read 0x0002=0x%x failed", read_buffer[1]); return false; } - delay(10); + hal->delay(10); return true; } -void TouchDrvCST92xx::setGpioCallback(gpio_mode_fptr_t mode_cb, - gpio_write_fptr_t write_cb, - gpio_read_fptr_t read_cb) +void TouchDrvCST92xx::setGpioCallback(CustomMode mode_cb, + CustomWrite write_cb, + CustomRead read_cb) { - SensorCommon::setGpioModeCallback(mode_cb); - SensorCommon::setGpioWriteCallback(write_cb); - SensorCommon::setGpioReadCallback(read_cb); + SensorHalCustom::setCustomMode(mode_cb); + SensorHalCustom::setCustomWrite(write_cb); + SensorHalCustom::setCustomRead(read_cb); } bool TouchDrvCST92xx::initImpl() { - if (__rst != SENSOR_PIN_NONE) { - this->setGpioMode(__rst, OUTPUT); + if (_rst != -1) { + hal->pinMode(_rst, OUTPUT); } - if (__irq != SENSOR_PIN_NONE) { - this->setGpioMode(__irq, INPUT); + if (_irq != -1) { + hal->pinMode(_irq, INPUT); } -#if 0 - int retry = 5; - - if (!__jump_check) { - - while (retry > 0) { - if (enterBootloader()) { - break; - } - retry--; - delay(1000); - } - if (0 == retry) { - log_e("Enter boot loader mode failed!"); - return false; - } - - chipType = getChipType(); - - log_d("Chip ID:0x%x", chipType); - - } else { - - log_d("Jump check setting default IC type : CST9217"); - // Jump check setting default IC type - chipType = CST9217_CHIP_ID; - - } - - // Exit Boot Mode - reset(); - - // Wait for a while after reset - delay(120); - - retry = 3; - - while (!this->probe()) { - log_e("Device not found!"); - delay(120); - } - - log_e("Exit boot mode successfully."); - - if (chipType != CST9220_CHIP_ID && chipType != CST9217_CHIP_ID) { - return false; - } - -#else - if (!getAttribute()) { return false; } -#endif - - __chipID = chipType; + _chipID = chipType; log_d("Touch type:%s", getModelName()); return true; } -int TouchDrvCST92xx::getReadMaskImpl() -{ - return -1; -} - - #if 0 /*DISABLE UPDATE FIRMWARE*/ void TouchDrvCST92xx::jumpCheck() { - __jump_check = true; + _jump_check = true; } bool TouchDrvCST92xx::getFirmwareInfo(void) @@ -755,12 +732,12 @@ bool TouchDrvCST92xx::getFirmwareInfo(void) setMode(CST92_MODE_DEBUG_INFO); - delay(1); + hal->delay(1); write_buffer[0] = 0xD1; write_buffer[1] = 0x01; - res = writeBuffer(write_buffer, 2); - res |= writeBuffer(write_buffer, 2); - if (res != DEV_WIRE_NONE) { + res = comm->writeBuffer(write_buffer, 2); + res |= comm->writeBuffer(write_buffer, 2); + if (res != 0) { log_e("write 0xD101 error"); return false; } @@ -768,8 +745,8 @@ bool TouchDrvCST92xx::getFirmwareInfo(void) // BOOT TIME + CBCB write_buffer[0] = 0xD1; write_buffer[1] = 0xFC; - res = writeThenRead(write_buffer, 2, read_buffer, 4); - if (res != DEV_WIRE_NONE) { + res = comm->writeThenRead(write_buffer, 2, read_buffer, 4); + if (res != 0) { log_e("read 0xD1FC error"); return false; } @@ -779,8 +756,8 @@ bool TouchDrvCST92xx::getFirmwareInfo(void) // firmware_project_id firmware_ic_type write_buffer[0] = 0xD2; write_buffer[1] = 0x04; - res = writeThenRead(write_buffer, 2, read_buffer, 4); - if (res != DEV_WIRE_NONE) { + res = comm->writeThenRead(write_buffer, 2, read_buffer, 4); + if (res != 0) { log_e("read 0xD204 error"); return false; } @@ -790,8 +767,8 @@ bool TouchDrvCST92xx::getFirmwareInfo(void) // firmware_version write_buffer[0] = 0xD2; write_buffer[1] = 0x08; - res = writeThenRead(write_buffer, 2, read_buffer, 4); - if (res != DEV_WIRE_NONE) { + res = comm->writeThenRead(write_buffer, 2, read_buffer, 4); + if (res != 0) { log_e("read 0xD208 error"); return false; } @@ -801,8 +778,8 @@ bool TouchDrvCST92xx::getFirmwareInfo(void) // firmware_info_checksum write_buffer[0] = 0xD2; write_buffer[1] = 0x1c; - res = writeThenRead(write_buffer, 2, read_buffer, 4); - if (res != DEV_WIRE_NONE) { + res = comm->writeThenRead(write_buffer, 2, read_buffer, 4); + if (res != 0) { log_e("read 0xD21c error"); return false; } @@ -813,8 +790,8 @@ bool TouchDrvCST92xx::getFirmwareInfo(void) // firmware_checksum write_buffer[0] = 0xD2; write_buffer[1] = 0x0C; - res = writeThenRead(write_buffer, 2, read_buffer, 4); - if (res != DEV_WIRE_NONE) { + res = comm->writeThenRead(write_buffer, 2, read_buffer, 4); + if (res != 0) { log_e("read 0xD20c error"); return false; } @@ -822,8 +799,8 @@ bool TouchDrvCST92xx::getFirmwareInfo(void) // tx_num rx_num key_num write_buffer[0] = 0xD1; write_buffer[1] = 0xF4; - res = writeThenRead(write_buffer, 2, read_buffer, 4); - if (res != DEV_WIRE_NONE) { + res = comm->writeThenRead(write_buffer, 2, read_buffer, 4); + if (res != 0) { log_e("read 0xD1F4 error"); return false; } @@ -850,54 +827,54 @@ int16_t TouchDrvCST92xx::eraseMem(void) int16_t res = 0; uint8_t write_buffer[4] = {0}; - uint8_t slave_address = __addr; + uint8_t slave_address = _addr; - __addr = CST92XX_BOOT_ADDRESS; + _addr = CST92XX_BOOT_ADDRESS; write_buffer[0] = 0xA0; write_buffer[1] = 0x14; write_buffer[2] = 0x00; write_buffer[3] = 0x00; - res = writeBuffer(write_buffer, 4); - if (res != DEV_WIRE_NONE) { + res = comm->writeBuffer(write_buffer, 4); + if (res != 0) { goto ERROR; } write_buffer[0] = 0xA0; write_buffer[1] = 0x0C; write_buffer[2] = 0x80; write_buffer[3] = 0x7F; - res = writeBuffer(write_buffer, 4); - if (res != DEV_WIRE_NONE) { + res = comm->writeBuffer(write_buffer, 4); + if (res != 0) { goto ERROR; } write_buffer[0] = 0xA0; write_buffer[1] = 0x04; write_buffer[2] = 0xEC; - res = writeBuffer(write_buffer, 3); - if (res != DEV_WIRE_NONE) { + res = comm->writeBuffer(write_buffer, 3); + if (res != 0) { goto ERROR; } - delay(300); + hal->delay(300); for (uint16_t i = 0;; i += 10) { if (i >= 1000) { goto ERROR; } - delay(10); + hal->delay(10); write_buffer[0] = 0xA0; write_buffer[1] = 0x05; - res = writeThenRead(write_buffer, 2, write_buffer, 2); - if (res != DEV_WIRE_NONE) { - delay(10); + res = comm->writeThenRead(write_buffer, 2, write_buffer, 2); + if (res != 0) { + hal->delay(10); continue; } if (write_buffer[0] == 0x88) { break; } } - __addr = slave_address; + _addr = slave_address; return 0; ERROR: - __addr = slave_address; + _addr = slave_address; return -1; } @@ -910,9 +887,9 @@ int16_t TouchDrvCST92xx::writeSRAM(uint8_t *buf, uint16_t len) uint16_t per_len = sizeof(write_buffer) - 2; - uint8_t slave_address = __addr; + uint8_t slave_address = _addr; - __addr = CST92XX_BOOT_ADDRESS; + _addr = CST92XX_BOOT_ADDRESS; while (len > 0) { uint16_t cur_len = len; @@ -922,16 +899,16 @@ int16_t TouchDrvCST92xx::writeSRAM(uint8_t *buf, uint16_t len) write_buffer[0] = reg >> 8; write_buffer[1] = reg; memcpy(write_buffer + 2, buf, cur_len); - res = writeBuffer(write_buffer, cur_len + 2); - if (res != DEV_WIRE_NONE) { - __addr = slave_address; + res = comm->writeBuffer(write_buffer, cur_len + 2); + if (res != 0) { + _addr = slave_address; return -1; } reg += cur_len; buf += cur_len; len -= cur_len; } - __addr = slave_address; + _addr = slave_address; return 0; } @@ -941,57 +918,57 @@ int16_t TouchDrvCST92xx::writeMemPage(uint16_t addr, uint8_t *buf, uint16_t len) uint8_t write_buffer[4] = {0}; - uint8_t slave_address = __addr; + uint8_t slave_address = _addr; - __addr = CST92XX_BOOT_ADDRESS; + _addr = CST92XX_BOOT_ADDRESS; write_buffer[0] = 0xA0; write_buffer[1] = 0x0C; write_buffer[2] = len; write_buffer[3] = len >> 8; - res = writeBuffer(write_buffer, 4); - if (res != DEV_WIRE_NONE) { + res = comm->writeBuffer(write_buffer, 4); + if (res != 0) { goto ERROR; } write_buffer[0] = 0xA0; write_buffer[1] = 0x14; write_buffer[2] = addr; write_buffer[3] = addr >> 8; - res = writeBuffer(write_buffer, 4); - if (res != DEV_WIRE_NONE) { + res = comm->writeBuffer(write_buffer, 4); + if (res != 0) { goto ERROR; } res = writeSRAM(buf, len); - if (res != DEV_WIRE_NONE) { + if (res != 0) { goto ERROR; } write_buffer[0] = 0xA0; write_buffer[1] = 0x04; write_buffer[2] = 0xEE; - res = writeBuffer(write_buffer, 3); - if (res != DEV_WIRE_NONE) { + res = comm->writeBuffer(write_buffer, 3); + if (res != 0) { goto ERROR; } for (uint16_t t = 0;; t += 10) { if (t >= 1000) { goto ERROR; } - delay(10); + hal->delay(10); write_buffer[0] = 0xA0; write_buffer[1] = 0x05; - res = writeThenRead(write_buffer, 2, write_buffer, 1); - if (res != DEV_WIRE_NONE) { - delay(10); + res = comm->writeThenRead(write_buffer, 2, write_buffer, 1); + if (res != 0) { + hal->delay(10); continue; } if (write_buffer[0] == 0x55) { break; } } - __addr = slave_address; + _addr = slave_address; return 0; ERROR: - __addr = slave_address; + _addr = slave_address; return -1; } @@ -1046,27 +1023,27 @@ int16_t TouchDrvCST92xx::calculateVerifyChecksum(void) uint8_t write_buffer[4] = {0}; uint32_t checksum = 0; - uint8_t slave_address = __addr; + uint8_t slave_address = _addr; - __addr = CST92XX_BOOT_ADDRESS; + _addr = CST92XX_BOOT_ADDRESS; write_buffer[0] = 0xA0; write_buffer[1] = 0x03; write_buffer[2] = 0x00; - res = writeBuffer(write_buffer, 3); - if (res != DEV_WIRE_NONE) { + res = comm->writeBuffer(write_buffer, 3); + if (res != 0) { return -1; } for (uint16_t t = 0;; t += 10) { if (t >= 1000) { goto ERROR; } - delay(10); + hal->delay(10); write_buffer[0] = 0xA0; write_buffer[1] = 0x00; - res = writeThenRead(write_buffer, 2, write_buffer, 1); - if (res != DEV_WIRE_NONE) { + res = comm->writeThenRead(write_buffer, 2, write_buffer, 1); + if (res != 0) { goto ERROR; } if (write_buffer[0] == 0x01) { @@ -1079,8 +1056,8 @@ int16_t TouchDrvCST92xx::calculateVerifyChecksum(void) write_buffer[0] = 0xA0; write_buffer[1] = 0x08; - res = writeThenRead(write_buffer, 2, write_buffer, 4); - if (res != DEV_WIRE_NONE) { + res = comm->writeThenRead(write_buffer, 2, write_buffer, 4); + if (res != 0) { goto ERROR; } @@ -1092,10 +1069,10 @@ int16_t TouchDrvCST92xx::calculateVerifyChecksum(void) if (checksum != bin_data.checksum) { goto ERROR; } - __addr = slave_address; + _addr = slave_address; return 0; ERROR: - __addr = slave_address; + _addr = slave_address; return -1; } @@ -1109,22 +1086,22 @@ int16_t TouchDrvCST92xx::upgradeFirmware(void) res = enterBootloader(); - if (res != DEV_WIRE_NONE) { + if (res != 0) { log_e("enterBootloader fail.%d", retry); continue; } res = eraseMem(); - if (res != DEV_WIRE_NONE) { + if (res != 0) { log_e("eraseMem fail.%d", retry); continue; } res = writeMemAll(); - if (res != DEV_WIRE_NONE) { + if (res != 0) { log_e("writeMemAll fail.%d", retry); continue; } res = calculateVerifyChecksum(); - if (res != DEV_WIRE_NONE) { + if (res != 0) { log_e("calculateVerifyChecksum fail.%d", retry); continue; } else { @@ -1134,7 +1111,7 @@ int16_t TouchDrvCST92xx::upgradeFirmware(void) reset(); - delay(40); + hal->delay(40); if ((retry == 0) && (res)) { log_e("upgradeFirmware fail exit.%d", retry); @@ -1263,7 +1240,7 @@ int16_t TouchDrvCST92xx::updateFirmware(void) goto END_UPGRADE; } res = upgradeFirmwareJudge(); - if (res != DEV_WIRE_NONE) { + if (res != 0) { log_d("upgradeFirmwareJudge return,no need update fw."); goto END_UPGRADE; } else { @@ -1272,13 +1249,13 @@ int16_t TouchDrvCST92xx::updateFirmware(void) log_d("need_upgrade=%d, firmware_version=0x%04X.", need_upgrade, bin_data.version); if (need_upgrade) { res = upgradeFirmware(); - if (res != DEV_WIRE_NONE) { + if (res != 0) { log_e("upgradeFirmware failed"); goto END_UPGRADE; } log_d("upgradeFirmware OK done."); reset(); - delay(40); + hal->delay(40); if (!getFirmwareInfo()) { log_e("get_firmware_info failed"); reset(); diff --git a/src/touch/TouchDrvCST92xx.h b/src/touch/TouchDrvCST92xx.h index cf089f1..842b8ec 100644 --- a/src/touch/TouchDrvCST92xx.h +++ b/src/touch/TouchDrvCST92xx.h @@ -28,52 +28,48 @@ */ #pragma once -#include "TouchDrvInterface.hpp" -#include "SensorCommon.tpp" -#include "SensorLib.h" #include "REG/CST9xxConstants.h" +#include "TouchDrvInterface.hpp" +#define CST92XX_SLAVE_ADDRESS (0x5A) -enum CST92_RunMode { - CST92_MODE_NORMAL = (0x00), - CST92_MODE_LOW_POWER = (0X01), - CST92_MODE_DEEP_SLEEP = (0X02), - CST92_MODE_WAKEUP = (0x03), - CST92_MODE_DEBUG_DIFF = (0x04), - CST92_MODE_DEBUG_RAWDATA = (0X05), - CST92_MODE_FACTORY = (0x06), - CST92_MODE_DEBUG_INFO = (0x07), - CST92_MODE_UPDATE_FW = (0x08), - CST92_MODE_FACTORY_HIGHDRV = (0x10), - CST92_MODE_FACTORY_LOWDRV = (0x11), - CST92_MODE_FACTORY_SHORT = (0x12), - CST92_MODE_LPSCAN = (0x13), -}; - - -class TouchDrvCST92xx : public TouchDrvInterface, - public SensorCommon +class TouchDrvCST92xx : public TouchDrvInterface, public CST92xxConstants { - friend class SensorCommon; - public: + enum CST92_RunMode { + CST92_MODE_NORMAL = (0x00), + CST92_MODE_LOW_POWER = (0X01), + CST92_MODE_DEEP_SLEEP = (0X02), + CST92_MODE_WAKEUP = (0x03), + CST92_MODE_DEBUG_DIFF = (0x04), + CST92_MODE_DEBUG_RAWDATA = (0X05), + CST92_MODE_FACTORY = (0x06), + CST92_MODE_DEBUG_INFO = (0x07), + CST92_MODE_UPDATE_FW = (0x08), + CST92_MODE_FACTORY_HIGHDRV = (0x10), + CST92_MODE_FACTORY_LOWDRV = (0x11), + CST92_MODE_FACTORY_SHORT = (0x12), + CST92_MODE_LPSCAN = (0x13), + }; + TouchDrvCST92xx(); + ~TouchDrvCST92xx(); #if defined(ARDUINO) - bool begin(PLATFORM_WIRE_TYPE &wire, uint8_t address, int sda, int scl); + bool begin(TwoWire &wire, uint8_t address = CST92XX_SLAVE_ADDRESS, int sda = -1, int scl = -1); #elif defined(ESP_PLATFORM) -#if ((ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL(5,0,0)) && defined(CONFIG_SENSORLIB_ESP_IDF_NEW_API)) - bool begin(i2c_master_bus_handle_t i2c_dev_bus_handle, uint8_t addr); +#if defined(USEING_I2C_LEGACY) + bool begin(i2c_port_t port_num, uint8_t addr = CST92XX_SLAVE_ADDRESS, int sda = -1, int scl = -1); #else - bool begin(i2c_port_t port_num, uint8_t addr, int sda, int scl); -#endif //ESP_IDF_VERSION + bool begin(i2c_master_bus_handle_t handle, uint8_t addr = CST92XX_SLAVE_ADDRESS); +#endif #endif - // void jumpCheck(); - - bool begin(uint8_t addr, iic_fptr_t readRegCallback, iic_fptr_t writeRegCallback); + bool begin(SensorCommCustom::CustomCallback callback, + SensorCommCustomHal::CustomHalCallback hal_callback, + uint8_t addr = CST92XX_SLAVE_ADDRESS); void reset(); @@ -93,24 +89,15 @@ class TouchDrvCST92xx : public TouchDrvInterface, bool getResolution(int16_t *x, int16_t *y); - void setCoverScreenCallback(home_button_callback_t cb, void *user_data = NULL); - - void setGpioCallback(gpio_mode_fptr_t mode_cb, - gpio_write_fptr_t write_cb, - gpio_read_fptr_t read_cb); - - - + void setCoverScreenCallback(HomeButtonCallback cb, void *user_data = NULL); + void setGpioCallback(CustomMode mode_cb, + CustomWrite write_cb, + CustomRead read_cb); private: - typedef struct { - uint8_t finger_id; - uint8_t evt; - uint16_t x; - uint16_t y; - } cst9xx_point_t; + bool setMode(uint8_t mode); bool enterBootloader(); @@ -160,14 +147,16 @@ class TouchDrvCST92xx : public TouchDrvInterface, uint32_t getChipType(); bool initImpl(); - int getReadMaskImpl(); uint16_t chipType; protected: - int16_t __center_btn_x; - int16_t __center_btn_y; - // bool __jump_check; + std::unique_ptr comm; + std::unique_ptr hal; + + int _slave_addr; + int16_t _center_btn_x; + int16_t _center_btn_y; };