From 0ddab50ad40a7d2cf3531d5c7f9a9a6ec71b798c Mon Sep 17 00:00:00 2001 From: PaulZC Date: Wed, 18 Aug 2021 08:31:25 +0100 Subject: [PATCH] Update stand alone examples for v2.1.0 of Apollo3 --- .../GNSS_Data_Logging/GNSS_Data_Logging.ino | 110 +++-- .../IMU_DMP_MultipleSensors.ino | 63 ++- .../IMU_DMP_Quat6/IMU_DMP_Quat6.ino | 38 +- .../IMU_DMP_Quat9/IMU_DMP_Quat9.ino | 7 +- .../LowPower_WithWork/LowPower_WithWork.ino | 236 ---------- .../Low Power/PowerDownRTC/PowerDownRTC.ino | 313 -------------- .../PowerDownRTCwithSD/PowerDownRTCwithSD.ino | 246 ----------- .../Low Power/PowerDownRTCwithSD/sd.ino | 63 --- .../PowerDownWithWake/PowerDownWithWake.ino | 265 ------------ .../PowerDown_FileWriteBug.ino | 184 -------- .../Low Power/PowerDown_FileWriteBug/sd.ino | 148 ------- .../OLA_IMU_Basics/OLA_IMU_Basics.ino | 40 +- .../SD/BasicFileTest/BasicFileTest.ino | 53 --- .../Test Sketches/SD/BasicFileTest/sd.ino | 125 ------ .../AHT20_Testing/AHT20_Testing.ino | 49 --- .../AutoDetectWithMux/extras.ino | 119 ------ .../BME280_Testing/BME280_Testing.ino | 66 --- .../CCS811_Testing/CCS811_Testing.ino | 93 ---- .../DST_and_TimeStamp_Adjustment_Testing.ino | 311 -------------- .../I2CScanner/I2CScanner.ino | 54 --- .../LPS25HB_Testing/LPS25HB_Testing.ino | 81 ---- .../MS5637_Testing/MS5637_Testing.ino | 66 --- .../MS8607_Testing/MS8607_Testing.ino | 137 ------ .../Sensor Autodetect/Mux/Mux.ino | 135 ------ .../SCD30_Testing/SCD30_Testing.ino | 74 ---- .../SGP30_Testing/SGP30_Testing.ino | 115 ----- .../SHTC3_Testing/SHTC3_Testing.ino | 63 --- .../VEML6075_Testing/VEML6075_Testing.ino | 49 --- .../VL53L1X_Testing/VL53L1X_Testing.ino | 87 ---- .../AutoDetectWithMux/AutoDetectWithMux.ino | 131 +++++- .../AutoDetectWithMux/Sensors.ino | 61 ++- .../AutoDetectWithMux/autoDetect.ino | 51 ++- .../AutoDetectWithMux/extras.ino | 403 ++++++++++++++++++ .../AutoDetectWithMux/menuAttachedDevices.ino | 80 +++- .../AutoDetectWithMux/settings.h | 9 + .../AutoDetectWithMux/settings.ino | 0 .../I2CScanner/I2CScanner.ino | 118 +++++ .../I2C_Detector/I2C_Detector.ino | 123 ++++-- .../ConstantSerialBlastTest.ino | 150 ------- .../OpenLog_Bare_Serial.ino | 239 ----------- .../TIM_TM2_Data_Logging.ino | 130 ++++-- 41 files changed, 1160 insertions(+), 3725 deletions(-) delete mode 100644 Firmware/Test Sketches/Low Power/LowPower_WithWork/LowPower_WithWork.ino delete mode 100644 Firmware/Test Sketches/Low Power/PowerDownRTC/PowerDownRTC.ino delete mode 100644 Firmware/Test Sketches/Low Power/PowerDownRTCwithSD/PowerDownRTCwithSD.ino delete mode 100644 Firmware/Test Sketches/Low Power/PowerDownRTCwithSD/sd.ino delete mode 100644 Firmware/Test Sketches/Low Power/PowerDownWithWake/PowerDownWithWake.ino delete mode 100644 Firmware/Test Sketches/Low Power/PowerDown_FileWriteBug/PowerDown_FileWriteBug.ino delete mode 100644 Firmware/Test Sketches/Low Power/PowerDown_FileWriteBug/sd.ino delete mode 100644 Firmware/Test Sketches/SD/BasicFileTest/BasicFileTest.ino delete mode 100644 Firmware/Test Sketches/SD/BasicFileTest/sd.ino delete mode 100644 Firmware/Test Sketches/Sensor Autodetect/AHT20_Testing/AHT20_Testing.ino delete mode 100644 Firmware/Test Sketches/Sensor Autodetect/AutoDetectWithMux/extras.ino delete mode 100644 Firmware/Test Sketches/Sensor Autodetect/BME280_Testing/BME280_Testing.ino delete mode 100644 Firmware/Test Sketches/Sensor Autodetect/CCS811_Testing/CCS811_Testing.ino delete mode 100644 Firmware/Test Sketches/Sensor Autodetect/DST_and_TimeStamp_Adjustment_Testing/DST_and_TimeStamp_Adjustment_Testing.ino delete mode 100644 Firmware/Test Sketches/Sensor Autodetect/I2CScanner/I2CScanner.ino delete mode 100644 Firmware/Test Sketches/Sensor Autodetect/LPS25HB_Testing/LPS25HB_Testing.ino delete mode 100644 Firmware/Test Sketches/Sensor Autodetect/MS5637_Testing/MS5637_Testing.ino delete mode 100644 Firmware/Test Sketches/Sensor Autodetect/MS8607_Testing/MS8607_Testing.ino delete mode 100644 Firmware/Test Sketches/Sensor Autodetect/Mux/Mux.ino delete mode 100644 Firmware/Test Sketches/Sensor Autodetect/SCD30_Testing/SCD30_Testing.ino delete mode 100644 Firmware/Test Sketches/Sensor Autodetect/SGP30_Testing/SGP30_Testing.ino delete mode 100644 Firmware/Test Sketches/Sensor Autodetect/SHTC3_Testing/SHTC3_Testing.ino delete mode 100644 Firmware/Test Sketches/Sensor Autodetect/VEML6075_Testing/VEML6075_Testing.ino delete mode 100644 Firmware/Test Sketches/Sensor Autodetect/VL53L1X_Testing/VL53L1X_Testing.ino rename Firmware/Test Sketches/{Sensor Autodetect => Sensor_Autodetect}/AutoDetectWithMux/AutoDetectWithMux.ino (67%) rename Firmware/Test Sketches/{Sensor Autodetect => Sensor_Autodetect}/AutoDetectWithMux/Sensors.ino (53%) rename Firmware/Test Sketches/{Sensor Autodetect => Sensor_Autodetect}/AutoDetectWithMux/autoDetect.ino (92%) create mode 100644 Firmware/Test Sketches/Sensor_Autodetect/AutoDetectWithMux/extras.ino rename Firmware/Test Sketches/{Sensor Autodetect => Sensor_Autodetect}/AutoDetectWithMux/menuAttachedDevices.ino (84%) rename Firmware/Test Sketches/{Sensor Autodetect => Sensor_Autodetect}/AutoDetectWithMux/settings.h (92%) rename Firmware/Test Sketches/{Sensor Autodetect => Sensor_Autodetect}/AutoDetectWithMux/settings.ino (100%) create mode 100644 Firmware/Test Sketches/Sensor_Autodetect/I2CScanner/I2CScanner.ino rename Firmware/Test Sketches/{Sensor Autodetect => Sensor_Autodetect}/I2C_Detector/I2C_Detector.ino (73%) delete mode 100644 Firmware/Test Sketches/Serial Logging/ConstantSerialBlastTest/ConstantSerialBlastTest.ino delete mode 100644 Firmware/Test Sketches/Serial Logging/OpenLog_Bare_Serial/OpenLog_Bare_Serial.ino diff --git a/Firmware/Test Sketches/GNSS_Data_Logging/GNSS_Data_Logging.ino b/Firmware/Test Sketches/GNSS_Data_Logging/GNSS_Data_Logging.ino index 780661c..84c16fc 100644 --- a/Firmware/Test Sketches/GNSS_Data_Logging/GNSS_Data_Logging.ino +++ b/Firmware/Test Sketches/GNSS_Data_Logging/GNSS_Data_Logging.ino @@ -5,13 +5,21 @@ By: Paul Clark SparkFun Electronics - Date: April 23rd, 2021 + Date: August 17th, 2021 License: MIT. See license file for more information but you can basically do whatever you want with this code. This example shows how to configure the u-blox GNSS to send RXM SFRBX and RAWX reports automatically and log the data to SD card in UBX format + This version uses v2.1.0 of the SparkFun Apollo3 (artemis) core. + + Please note: v2.1.1 of the core contains a change to the I2C interface which makes communication + with u-blox modules over I2C less reliable. If you are building this code yourself, + please use V2.1.0 of the core. + + The Board should be set to SparkFun Apollo3 \ RedBoard Artemis ATP. + ** Please note: this example will only work with u-blox ADR or High Precision GNSS or Time Sync products ** Data is logged in u-blox UBX format. Please see the u-blox protocol specification for more details. @@ -28,8 +36,6 @@ Insert a formatted micro-SD card into the socket on OpenLog Artemis. Connect OpenLog Artemis to your computer using a USB-C cable. Ensure you have the SparkFun Apollo3 boards installed: http://boardsmanager/All#SparkFun_Apollo3 - This code has been tested using version 1.2.1 of the Apollo3 boards on Arduino IDE 1.8.13. - Select "SparkFun Artemis ATP" as the board type. Press upload to upload the code onto the Artemis. Open the Serial Monitor at 115200 baud to see the output. @@ -49,7 +55,7 @@ #include //Click here to get the library: http://librarymanager/All#SparkFun_u-blox_GNSS SFE_UBLOX_GNSS myGNSS; -#include //SdFat v2.0.6 by Bill Greiman. Click here to get the library: http://librarymanager/All#SdFat_exFAT +#include //SdFat v2.0.7 by Bill Greiman. Click here to get the library: http://librarymanager/All#SdFat_exFAT #define SD_FAT_TYPE 3 // SD_FAT_TYPE = 0 for SdFat/File, 1 for FAT16/FAT32, 2 for exFAT, 3 for FAT16/FAT32 and exFAT. #define SD_CONFIG SdSpiConfig(PIN_MICROSD_CHIP_SELECT, SHARED_SPI, SD_SCK_MHZ(24)) // 24MHz @@ -72,7 +78,9 @@ File myFile; //File that all GNSS data is written to //Setup Qwiic Port #include -TwoWire qwiic(1); //Will use pads 8/9 +const byte PIN_QWIIC_SCL = 8; +const byte PIN_QWIIC_SDA = 9; +TwoWire qwiic(PIN_QWIIC_SDA,PIN_QWIIC_SCL); //Will use pads 8/9 //Define the pin functions //Depends on hardware version. This can be found as a marking on the PCB. @@ -103,8 +111,6 @@ const byte BREAKOUT_PIN_32 = 32; const byte BREAKOUT_PIN_TX = 12; const byte BREAKOUT_PIN_RX = 13; const byte BREAKOUT_PIN_11 = 11; -const byte PIN_QWIIC_SCL = 8; -const byte PIN_QWIIC_SDA = 9; // Globals and Consts @@ -115,6 +121,8 @@ const int lowBatteryReadingsLimit = 10; // Don't declare the battery voltage low const int sdPowerDownDelay = 100; //Delay for this many ms before turning off the SD card power bool powerLossSeen = false; //Interrupt flag for power loss detection bool stopLoggingSeen = false; //Interrupt flag for stop logging detection +bool ignorePowerLossInterrupt = true; // Ignore the power loss interrupt - when attaching the interrupt +bool ignoreStopLoggingInterrupt = true; // Ignore the stop logging interrupt - when attaching the interrupt // Data Logging Specifics: @@ -134,7 +142,9 @@ void setup() delay(1); // Let PIN_POWER_LOSS stabilize if (digitalRead(PIN_POWER_LOSS) == LOW) powerLossISR(); //Check PIN_POWER_LOSS just in case we missed the falling edge + ignorePowerLossInterrupt = true; // Ignore the power loss interrupt - when attaching the interrupt attachInterrupt(digitalPinToInterrupt(PIN_POWER_LOSS), powerLossISR, FALLING); + ignorePowerLossInterrupt = false; powerLEDOn(); // Turn the power LED on - if the hardware supports it @@ -155,15 +165,16 @@ void setup() beginSD(); // Enable power for the SD card - enableCIPOpullUp(); // Enable CIPO pull-up after beginSD - imuPowerOff(); // We're not using the IMU so turn it off delay(2500); // Give the GNSS time to power up pinMode(PIN_STOP_LOGGING, INPUT_PULLUP); delay(1); // Let the pin stabilize + ignoreStopLoggingInterrupt = true; // Ignore the stop logging interrupt - when attaching the interrupt attachInterrupt(digitalPinToInterrupt(PIN_STOP_LOGGING), stopLoggingISR, FALLING); // Enable the stop logging interrupt + pinMode(PIN_STOP_LOGGING, INPUT_PULLUP); //Re-attach the pull-up (bug in v2.1.0 of the core) + ignoreStopLoggingInterrupt = false; Serial.println("Initializing SD card..."); @@ -296,17 +307,23 @@ void loop() //Stop Logging ISR void stopLoggingISR(void) { - Serial.println(F("Stop Logging Seen!")); - detachInterrupt(digitalPinToInterrupt(PIN_STOP_LOGGING)); //Prevent multiple interrupts - stopLoggingSeen = true; + if (ignoreStopLoggingInterrupt == false) + { + Serial.println(F("Stop Logging Seen!")); + detachInterrupt(digitalPinToInterrupt(PIN_STOP_LOGGING)); //Prevent multiple interrupts + stopLoggingSeen = true; + } } //Power Loss ISR void powerLossISR(void) { - Serial.println(F("Power Loss Detected!")); - detachInterrupt(digitalPinToInterrupt(PIN_POWER_LOSS)); //Prevent multiple interrupts - powerLossSeen = true; + if (ignorePowerLossInterrupt == false) + { + Serial.println(F("Power Loss Detected!")); + detachInterrupt(digitalPinToInterrupt(PIN_POWER_LOSS)); //Prevent multiple interrupts + powerLossSeen = true; + } } // =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- @@ -357,7 +374,7 @@ void stopLogging(void) // Stop logging; close the SD file; go into deep sleep SPI.end(); //Power down SPI - power_adc_disable(); //Power down ADC. It it started by default before setup(). + powerControlADC(false); //Power down ADC. It it started by default before setup(). Serial.end(); //Power down UART @@ -383,9 +400,10 @@ void stopLogging(void) // Stop logging; close the SD file; go into deep sleep //Disable pads for (int x = 0; x < 50; x++) { - if ((x != ap3_gpio_pin2pad(PIN_MICROSD_POWER)) && - (x != ap3_gpio_pin2pad(PIN_QWIIC_POWER)) && - (x != ap3_gpio_pin2pad(PIN_IMU_POWER))) + if ((x != PIN_MICROSD_POWER) && + //(x != PIN_LOGIC_DEBUG) && + (x != PIN_QWIIC_POWER) && + (x != PIN_IMU_POWER)) { am_hal_gpio_pinconfig(x, g_AM_HAL_GPIO_DISABLE); } @@ -475,7 +493,43 @@ void beginQwiic() pinMode(PIN_QWIIC_POWER, OUTPUT); qwiicPowerOn(); qwiic.begin(); - qwiic.setPullups(0); //Just to make it really clear what pull-ups are being used, set pullups here. + setQwiicPullups(0); //Just to make it really clear what pull-ups are being used, set pullups here. +} + +void setQwiicPullups(uint32_t i2cBusPullUps) +{ + //Change SCL and SDA pull-ups manually using pin_config + am_hal_gpio_pincfg_t sclPinCfg = g_AM_BSP_GPIO_IOM1_SCL; + am_hal_gpio_pincfg_t sdaPinCfg = g_AM_BSP_GPIO_IOM1_SDA; + + if (i2cBusPullUps == 0) + { + sclPinCfg.ePullup = AM_HAL_GPIO_PIN_PULLUP_NONE; // No pull-ups + sdaPinCfg.ePullup = AM_HAL_GPIO_PIN_PULLUP_NONE; + } + else if (i2cBusPullUps == 1) + { + sclPinCfg.ePullup = AM_HAL_GPIO_PIN_PULLUP_1_5K; // Use 1K5 pull-ups + sdaPinCfg.ePullup = AM_HAL_GPIO_PIN_PULLUP_1_5K; + } + else if (i2cBusPullUps == 6) + { + sclPinCfg.ePullup = AM_HAL_GPIO_PIN_PULLUP_6K; // Use 6K pull-ups + sdaPinCfg.ePullup = AM_HAL_GPIO_PIN_PULLUP_6K; + } + else if (i2cBusPullUps == 12) + { + sclPinCfg.ePullup = AM_HAL_GPIO_PIN_PULLUP_12K; // Use 12K pull-ups + sdaPinCfg.ePullup = AM_HAL_GPIO_PIN_PULLUP_12K; + } + else + { + sclPinCfg.ePullup = AM_HAL_GPIO_PIN_PULLUP_24K; // Use 24K pull-ups + sdaPinCfg.ePullup = AM_HAL_GPIO_PIN_PULLUP_24K; + } + + pin_config(PinName(PIN_QWIIC_SCL), sclPinCfg); + pin_config(PinName(PIN_QWIIC_SDA), sdaPinCfg); } void beginSD() @@ -494,22 +548,6 @@ void beginSD() // =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- -bool enableCIPOpullUp() -{ - //Add CIPO pull-up - ap3_err_t retval = AP3_OK; - am_hal_gpio_pincfg_t cipoPinCfg = AP3_GPIO_DEFAULT_PINCFG; - cipoPinCfg.uFuncSel = AM_HAL_PIN_6_M0MISO; - cipoPinCfg.eDriveStrength = AM_HAL_GPIO_PIN_DRIVESTRENGTH_12MA; - cipoPinCfg.eGPOutcfg = AM_HAL_GPIO_PIN_OUTCFG_PUSHPULL; - cipoPinCfg.uIOMnum = AP3_SPI_IOM; - cipoPinCfg.ePullup = AM_HAL_GPIO_PIN_PULLUP_1_5K; - padMode(MISO, cipoPinCfg, &retval); - return (retval == AP3_OK); -} - -// =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- - //Read the VIN voltage float readVIN() { diff --git a/Firmware/Test Sketches/IMU_DMP_MultipleSensors/IMU_DMP_MultipleSensors.ino b/Firmware/Test Sketches/IMU_DMP_MultipleSensors/IMU_DMP_MultipleSensors.ino index fb174ee..7859416 100644 --- a/Firmware/Test Sketches/IMU_DMP_MultipleSensors/IMU_DMP_MultipleSensors.ino +++ b/Firmware/Test Sketches/IMU_DMP_MultipleSensors/IMU_DMP_MultipleSensors.ino @@ -4,11 +4,15 @@ * Example9_DMP_MultipleSensors.ino * ICM 20948 Arduino Library Demo * Initialize the DMP based on the TDK InvenSense ICM20948_eMD_nucleo_1.0 example-icm20948 - * Paul Clark, February 15th 2021 + * Paul Clark, August 17th 2021 * Based on original code by: * Owen Lyke @ SparkFun Electronics * Original Creation Date: April 17 2019 * + * This version uses v2.1.0 of the SparkFun Apollo3 (artemis) core. + * + * The Board should be set to SparkFun Apollo3 \ RedBoard Artemis ATP. + * * ** This example is based on InvenSense's _confidential_ Application Note "Programming Sequence for DMP Hardware Functions". * ** We are grateful to InvenSense for sharing this with us. * @@ -31,6 +35,9 @@ const byte PIN_IMU_POWER = 27; // The Red SparkFun version of the OLA (V10) uses //const byte PIN_IMU_POWER = 22; // The Black SparkX version of the OLA (X04) uses pin 22 const byte PIN_IMU_INT = 37; const byte PIN_IMU_CHIP_SELECT = 44; +const byte PIN_SPI_SCK = 5; +const byte PIN_SPI_CIPO = 6; +const byte PIN_SPI_COPI = 7; #include "ICM_20948.h" // Click here to get the library: http://librarymanager/All#SparkFun_ICM_20948_IMU @@ -43,9 +50,14 @@ ICM_20948_SPI myICM; // Create an ICM_20948_SPI object void setup() { + // Start the SPI port SPI_PORT.begin(); - - enableCIPOpullUp(); // Enable CIPO pull-up on the OLA + // 'Kickstart' the SPI hardware at 4MHz - this changes the CIPO pin mode + SPI_PORT.beginTransaction(SPISettings(4000000, MSBFIRST, SPI_MODE0)); + SPI_PORT.transfer(0x00); + SPI_PORT.endTransaction(); + // *Now* enable CIPO pull-up on the OLA + enableCIPOpullUp(); pinMode(PIN_IMU_CHIP_SELECT, OUTPUT); digitalWrite(PIN_IMU_CHIP_SELECT, HIGH); //Be sure IMU is deselected @@ -75,14 +87,27 @@ void setup() { //myICM.enableDebugging(); // Uncomment this line to enable helpful debug messages on Serial - bool initialized = false; + // Initialize the ICM-20948 + // If the DMP is enabled, .begin performs a minimal startup. We need to configure the sample mode etc. manually. + myICM.begin( CS_PIN, SPI_PORT, 4000000); //Set IMU SPI rate to 4MHz + bool initialized = (myICM.status == ICM_20948_Stat_Ok); + while( !initialized ){ - // Initialize the ICM-20948 - // If the DMP is enabled, .begin performs a minimal startup. We need to configure the sample mode etc. manually. - myICM.begin( CS_PIN, SPI_PORT ); + enableCIPOpullUp(); // Enable CIPO pull-up on the OLA + + //Reset ICM by power cycling it + imuPowerOff(); + + delay(10); + + imuPowerOn(); // Enable power for the OLA IMU + + delay(100); // Wait for the IMU to power up - SERIAL_PORT.print( F("Initialization of the sensor returned: ") ); + myICM.begin( CS_PIN, SPI_PORT, 4000000); //Set IMU SPI rate to 4MHz + + SERIAL_PORT.print( F("Initialization of the IMU returned: ") ); SERIAL_PORT.println( myICM.statusString() ); if( myICM.status != ICM_20948_Stat_Ok ){ SERIAL_PORT.println( F("Trying again...") ); @@ -92,7 +117,7 @@ void setup() { } } - SERIAL_PORT.println(F("Device connected!")); + SERIAL_PORT.println(F("IMU connected!")); bool success = true; // Use success to show if the DMP configuration was successful @@ -265,16 +290,16 @@ void imuPowerOff() digitalWrite(PIN_IMU_POWER, LOW); } -bool enableCIPOpullUp() +void enableCIPOpullUp() // updated for v2.1.0 of the Apollo3 core { - //Add CIPO pull-up - ap3_err_t retval = AP3_OK; - am_hal_gpio_pincfg_t cipoPinCfg = AP3_GPIO_DEFAULT_PINCFG; - cipoPinCfg.uFuncSel = AM_HAL_PIN_6_M0MISO; - cipoPinCfg.eDriveStrength = AM_HAL_GPIO_PIN_DRIVESTRENGTH_12MA; - cipoPinCfg.eGPOutcfg = AM_HAL_GPIO_PIN_OUTCFG_PUSHPULL; - cipoPinCfg.uIOMnum = AP3_SPI_IOM; + //Add 1K5 pull-up on CIPO + am_hal_gpio_pincfg_t cipoPinCfg = g_AM_BSP_GPIO_IOM0_MISO; cipoPinCfg.ePullup = AM_HAL_GPIO_PIN_PULLUP_1_5K; - padMode(MISO, cipoPinCfg, &retval); - return (retval == AP3_OK); + pin_config(PinName(PIN_SPI_CIPO), cipoPinCfg); +} + +void disableCIPOpullUp() // updated for v2.1.0 of the Apollo3 core +{ + am_hal_gpio_pincfg_t cipoPinCfg = g_AM_BSP_GPIO_IOM0_MISO; + pin_config(PinName(PIN_SPI_CIPO), cipoPinCfg); } diff --git a/Firmware/Test Sketches/IMU_DMP_Quat6/IMU_DMP_Quat6.ino b/Firmware/Test Sketches/IMU_DMP_Quat6/IMU_DMP_Quat6.ino index b6e4ff0..d1e64b5 100644 --- a/Firmware/Test Sketches/IMU_DMP_Quat6/IMU_DMP_Quat6.ino +++ b/Firmware/Test Sketches/IMU_DMP_Quat6/IMU_DMP_Quat6.ino @@ -4,11 +4,15 @@ * Example7_DMP_Quat6_EulerAngles.ino * ICM 20948 Arduino Library Demo * Initialize the DMP based on the TDK InvenSense ICM20948_eMD_nucleo_1.0 example-icm20948 - * Paul Clark, February 15th 2021 + * Paul Clark, August 17th 2021 * Based on original code by: * Owen Lyke @ SparkFun Electronics * Original Creation Date: April 17 2019 * + * This version uses v2.1.0 of the SparkFun Apollo3 (artemis) core. + * + * The Board should be set to SparkFun Apollo3 \ RedBoard Artemis ATP. + * * ** This example is based on InvenSense's _confidential_ Application Note "Programming Sequence for DMP Hardware Functions". * ** We are grateful to InvenSense for sharing this with us. * @@ -33,6 +37,9 @@ const byte PIN_IMU_POWER = 27; // The Red SparkFun version of the OLA (V10) uses //const byte PIN_IMU_POWER = 22; // The Black SparkX version of the OLA (X04) uses pin 22 const byte PIN_IMU_INT = 37; const byte PIN_IMU_CHIP_SELECT = 44; +const byte PIN_SPI_SCK = 5; +const byte PIN_SPI_CIPO = 6; +const byte PIN_SPI_COPI = 7; #include "ICM_20948.h" // Click here to get the library: http://librarymanager/All#SparkFun_ICM_20948_IMU @@ -45,9 +52,14 @@ ICM_20948_SPI myICM; // Create an ICM_20948_SPI object void setup() { + // Start the SPI port SPI_PORT.begin(); - - enableCIPOpullUp(); // Enable CIPO pull-up on the OLA + // 'Kickstart' the SPI hardware at 4MHz - this changes the CIPO pin mode + SPI_PORT.beginTransaction(SPISettings(4000000, MSBFIRST, SPI_MODE0)); + SPI_PORT.transfer(0x00); + SPI_PORT.endTransaction(); + // *Now* enable CIPO pull-up on the OLA + enableCIPOpullUp(); pinMode(PIN_IMU_CHIP_SELECT, OUTPUT); digitalWrite(PIN_IMU_CHIP_SELECT, HIGH); //Be sure IMU is deselected @@ -277,16 +289,16 @@ void imuPowerOff() digitalWrite(PIN_IMU_POWER, LOW); } -bool enableCIPOpullUp() +void enableCIPOpullUp() // updated for v2.1.0 of the Apollo3 core { - //Add CIPO pull-up - ap3_err_t retval = AP3_OK; - am_hal_gpio_pincfg_t cipoPinCfg = AP3_GPIO_DEFAULT_PINCFG; - cipoPinCfg.uFuncSel = AM_HAL_PIN_6_M0MISO; - cipoPinCfg.eDriveStrength = AM_HAL_GPIO_PIN_DRIVESTRENGTH_12MA; - cipoPinCfg.eGPOutcfg = AM_HAL_GPIO_PIN_OUTCFG_PUSHPULL; - cipoPinCfg.uIOMnum = AP3_SPI_IOM; + //Add 1K5 pull-up on CIPO + am_hal_gpio_pincfg_t cipoPinCfg = g_AM_BSP_GPIO_IOM0_MISO; cipoPinCfg.ePullup = AM_HAL_GPIO_PIN_PULLUP_1_5K; - padMode(MISO, cipoPinCfg, &retval); - return (retval == AP3_OK); + pin_config(PinName(PIN_SPI_CIPO), cipoPinCfg); +} + +void disableCIPOpullUp() // updated for v2.1.0 of the Apollo3 core +{ + am_hal_gpio_pincfg_t cipoPinCfg = g_AM_BSP_GPIO_IOM0_MISO; + pin_config(PinName(PIN_SPI_CIPO), cipoPinCfg); } diff --git a/Firmware/Test Sketches/IMU_DMP_Quat9/IMU_DMP_Quat9.ino b/Firmware/Test Sketches/IMU_DMP_Quat9/IMU_DMP_Quat9.ino index 0c25663..0015e62 100644 --- a/Firmware/Test Sketches/IMU_DMP_Quat9/IMU_DMP_Quat9.ino +++ b/Firmware/Test Sketches/IMU_DMP_Quat9/IMU_DMP_Quat9.ino @@ -4,7 +4,7 @@ * Example6_DMP_Quat9_Orientation.ino * ICM 20948 Arduino Library Demo * Initialize the DMP based on the TDK InvenSense ICM20948_eMD_nucleo_1.0 example-icm20948 - * Paul Clark, February 15th 2021 + * Paul Clark, August 17th 2021 * Based on original code by: * Owen Lyke @ SparkFun Electronics * Original Creation Date: April 17 2019 @@ -33,6 +33,9 @@ const byte PIN_IMU_POWER = 27; // The Red SparkFun version of the OLA (V10) uses //const byte PIN_IMU_POWER = 22; // The Black SparkX version of the OLA (X04) uses pin 22 const byte PIN_IMU_INT = 37; const byte PIN_IMU_CHIP_SELECT = 44; +const byte PIN_SPI_SCK = 5; +const byte PIN_SPI_CIPO = 6; +const byte PIN_SPI_COPI = 7; #include "ICM_20948.h" // Click here to get the library: http://librarymanager/All#SparkFun_ICM_20948_IMU @@ -294,7 +297,7 @@ bool enableCIPOpullUp() //Add 1K5 pull-up on CIPO am_hal_gpio_pincfg_t cipoPinCfg = g_AM_BSP_GPIO_IOM0_MISO; cipoPinCfg.ePullup = AM_HAL_GPIO_PIN_PULLUP_1_5K; - pin_config(D6, cipoPinCfg); + pin_config(PinName(PIN_SPI_CIPO), cipoPinCfg); return (true); } #else diff --git a/Firmware/Test Sketches/Low Power/LowPower_WithWork/LowPower_WithWork.ino b/Firmware/Test Sketches/Low Power/LowPower_WithWork/LowPower_WithWork.ino deleted file mode 100644 index b507b84..0000000 --- a/Firmware/Test Sketches/Low Power/LowPower_WithWork/LowPower_WithWork.ino +++ /dev/null @@ -1,236 +0,0 @@ -/* - Artemis Low Power: How low can we go? - By: Nathan Seidle - SparkFun Electronics - Date: February 26th, 2020 - License: This code is public domain. - - This example demonstrates how to do some work (talk to a device over I2C / IOM), - enter deep sleep, then wake and continue work. - - SparkFun labored with love to create this code. Feel like supporting open source hardware? - Buy a board from SparkFun! https://www.sparkfun.com/products/15376 - - How close can we get to 2.7uA in deep sleep? - This example shows how decrease the Artemis current consumption to ~2.4uA in deep sleep - with a wake up every 5 seconds to read a sensor. - - Note that Artemis modules with revision A1 silicon will use ~30uA. Please see the - Ambiq errata for more information: https://www.ambiqmicro.com/static/mcu/files/Apollo3_Blue_Errata_List_v1_0_external_release.pdf - - To monitor the current cut the MEAS jumper, solder in headers, and attach - a DMM via IC hooks (https://www.sparkfun.com/products/506). - - The USB to serial bridge draws some current: - Serial Basic C - ~1.2uA (https://www.sparkfun.com/products/15096) - FTDI Basic - ~5.5uA (https://www.sparkfun.com/products/9873) - - 518uA on RedBoard running while(1); - 28uA on RedBoard running this sketch with MS5637 attached - 2.93uA on RedBoard with microphone VCC trace cut (mic was using ~25uA) - 2.78uA on RedBoard with MS5637 detached -*/ - -#include - -#include "SparkFun_MS5637_Arduino_Library.h" //Click here to get the library: http://librarymanager/All#SparkFun_MS5637 -MS5637 barometricSensor; - -#include -#define SPI_SPEED 1000000 -#define SPI_ORDER MSBFIRST -#define SPI_MODE SPI_MODE0 -SPISettings mySettings(SPI_SPEED, SPI_ORDER, SPI_MODE); - -uint32_t msToSleep = 5000; //This is the user editable number of ms to sleep between RTC checks -#define TIMER_FREQ 32768L //Counter/Timer 6 will use the 32kHz clock -uint32_t sysTicksToSleep = msToSleep * TIMER_FREQ / 1000; - -const byte STAT_LED = 13; - -int counter = 0; - -const byte PIN_IMU_POWER = 22; -const byte PIN_MICROSD_POWER = 15; //x04 -const byte PIN_QWIIC_POWER = 18; - -void setup(void) { - Serial.begin(115200); - Serial.println("Artemis Low Power Example"); - - //We don't really use Serial1 in this example but we power it up and use it just to show its use. - Serial1.begin(115200); - Serial1.println("Serial1 now online!"); - - Wire.begin(); - - //We don't really use SPI in this example but we power it up and use it just to show its use. - SPI.begin(); - SPI.beginTransaction(mySettings); - SPI.transfer(0xAA); - SPI.endTransaction(); - - if (barometricSensor.begin() == false) - Serial.println("MS5637 sensor did not respond. Please check wiring."); - else - Serial.println("MS5637 sensor detected."); -} - -void loop(void) { - - float temperature = barometricSensor.getTemperature(); - float pressure = barometricSensor.getPressure(); - - Serial.print("Temperature="); - Serial.print(temperature, 1); - Serial.print("(C)"); - - Serial.print(" Pressure="); - Serial.print(pressure, 3); - Serial.print("(hPa or mbar)"); - - Serial.print(" counter="); - Serial.print(counter++); - - Serial.println(); - - digitalWrite(STAT_LED, HIGH); - delay(100); - digitalWrite(STAT_LED, LOW); - - goToSleep(); -} - -//Power everything down and wait for interrupt wakeup -void goToSleep() -{ - Wire.end(); //Power down I2C - - SPI.end(); //Power down SPI - //SPI1.end(); //This example doesn't use SPI1 but you will need to end any instance you may have created - - power_adc_disable(); //Power down ADC. It it started by default before setup(). - - Serial.end(); //Power down UART - Serial1.end(); - - //Disable all pads - for (int x = 0 ; x < 50 ; x++) - am_hal_gpio_pinconfig(x , g_AM_HAL_GPIO_DISABLE); - - //We can't leave these power control pins floating - pinMode(PIN_QWIIC_POWER, OUTPUT); - pinMode(PIN_IMU_POWER, OUTPUT); - pinMode(PIN_MICROSD_POWER, OUTPUT); - - qwiicPowerOff(); - imuPowerOff(); - microSDPowerOff(); - - //We use counter/timer 6 to cause us to wake up from sleep but 0 to 7 are available - //CT 7 is used for Software Serial. All CTs are used for Servo. - am_hal_stimer_int_clear(AM_HAL_STIMER_INT_COMPAREG); //Clear CT6 - am_hal_stimer_int_enable(AM_HAL_STIMER_INT_COMPAREG); //Enable C/T G=6 - - //Use the lower power 32kHz clock. Use it to run CT6 as well. - am_hal_stimer_config(AM_HAL_STIMER_CFG_CLEAR | AM_HAL_STIMER_CFG_FREEZE); - am_hal_stimer_config(AM_HAL_STIMER_XTAL_32KHZ | AM_HAL_STIMER_CFG_COMPARE_G_ENABLE); - - //Setup interrupt to trigger when the number of ms have elapsed - am_hal_stimer_compare_delta_set(6, sysTicksToSleep); - - //Power down Flash, SRAM, cache - am_hal_pwrctrl_memory_deepsleep_powerdown(AM_HAL_PWRCTRL_MEM_CACHE); //Turn off CACHE - am_hal_pwrctrl_memory_deepsleep_powerdown(AM_HAL_PWRCTRL_MEM_FLASH_512K); //Turn off everything but lower 512k - am_hal_pwrctrl_memory_deepsleep_powerdown(AM_HAL_PWRCTRL_MEM_SRAM_64K_DTCM); //Turn off everything but lower 64k - //am_hal_pwrctrl_memory_deepsleep_powerdown(AM_HAL_PWRCTRL_MEM_ALL); //Turn off all memory (doesn't recover) - - //Enable the timer interrupt in the NVIC. - NVIC_EnableIRQ(STIMER_CMPR6_IRQn); - - //Go to Deep Sleep. - am_hal_sysctrl_sleep(AM_HAL_SYSCTRL_SLEEP_DEEP); - - //Turn off interrupt - NVIC_DisableIRQ(STIMER_CMPR6_IRQn); - - //We're BACK! - wakeFromSleep(); -} - -//Power everything up gracefully -void wakeFromSleep() -{ - //Power up SRAM, turn on entire Flash - am_hal_pwrctrl_memory_deepsleep_powerdown(AM_HAL_PWRCTRL_MEM_MAX); - - //Go back to using the main clock - am_hal_stimer_int_enable(AM_HAL_STIMER_INT_OVERFLOW); - NVIC_EnableIRQ(STIMER_IRQn); - am_hal_stimer_config(AM_HAL_STIMER_CFG_CLEAR | AM_HAL_STIMER_CFG_FREEZE); - am_hal_stimer_config(AM_HAL_STIMER_HFRC_3MHZ); - - //Turn on ADC - ap3_adc_setup(); - - //Set any pinModes - pinMode(STAT_LED, OUTPUT); - - //Turn on Serial - Serial.begin(115200); - delay(10); - Serial.println("Back on"); - - //Turn on I2C - Wire.begin(); - - //Restart Sensors - if (barometricSensor.begin() == false) - { - Serial.println("MS5637 sensor did not respond. Please check wiring."); - } -} - -//Called once number of milliseconds has passed -extern "C" void am_stimer_cmpr6_isr(void) -{ - uint32_t ui32Status = am_hal_stimer_int_status_get(false); - if (ui32Status & AM_HAL_STIMER_INT_COMPAREG) - { - am_hal_stimer_int_clear(AM_HAL_STIMER_INT_COMPAREG); - } -} - - -void qwiicPowerOn() -{ - pinMode(PIN_QWIIC_POWER, OUTPUT); - digitalWrite(PIN_QWIIC_POWER, LOW); -} -void qwiicPowerOff() -{ - pinMode(PIN_QWIIC_POWER, OUTPUT); - digitalWrite(PIN_QWIIC_POWER, HIGH); -} - -void microSDPowerOn() -{ - pinMode(PIN_MICROSD_POWER, OUTPUT); - digitalWrite(PIN_MICROSD_POWER, LOW); -} -void microSDPowerOff() -{ - pinMode(PIN_MICROSD_POWER, OUTPUT); - digitalWrite(PIN_MICROSD_POWER, HIGH); -} - -void imuPowerOn() -{ - pinMode(PIN_IMU_POWER, OUTPUT); - digitalWrite(PIN_IMU_POWER, HIGH); -} -void imuPowerOff() -{ - pinMode(PIN_IMU_POWER, OUTPUT); - digitalWrite(PIN_IMU_POWER, LOW); -} diff --git a/Firmware/Test Sketches/Low Power/PowerDownRTC/PowerDownRTC.ino b/Firmware/Test Sketches/Low Power/PowerDownRTC/PowerDownRTC.ino deleted file mode 100644 index 1c4c653..0000000 --- a/Firmware/Test Sketches/Low Power/PowerDownRTC/PowerDownRTC.ino +++ /dev/null @@ -1,313 +0,0 @@ -/* Author: Nathan Seidle - Created: Septempter 27th, 2019 - License: MIT. See SparkFun Arduino Apollo3 Project for more information - - This example demonstrates how to put the core to sleep for a number of - milliseconds before waking and printing the current time/date. This - is helpful for checking power consumption of the core while RTC+CT6 are running. - - 3.2 microSD, no USB - 2.4 no microSD, no USB - - 6mA with Power LED, no microSD, USB - 4.58, no power LED, no microSD, USB - So power LED is ~1.5mA - 1.05mA no power, no microSD, no USB - So USB is ~3.5mA - Fully powered down, board is pulling 450uA from battery but that - seems to be because RTC batt is charging at ~360uA. - - 6.88 with microSD - 5.07 with microSD on? - - 3/5/20 - - 6.61mA, no LED, USB, SD - 4.78mA, no LED, USB, no SD - 0.67mA, no LED, no USB, SD with pin set LOW - 0.65mA, no LED, no USB, SD with pin set HIGH - 0.16mA, no LED, no USB, no SD - - 3/6/20 - 0.65mA, no LED, no USB, Kingston 16GB SD - 0.152mA, no LED, no USB, SparkX SD - 0.191mA, no LED, no USB, SparkX SD - 0.188mA, no LED, no USB, SparkX SD - 0.098mA, no LEd, no USB, no SD - - - -*/ - -#include "RTC.h" //Include RTC library included with the Aruino_Apollo3 core -APM3_RTC myRTC; //Create instance of RTC class - -const byte PIN_POWER_LOSS = 3; - -const byte LOGIC_DEBUG = 11; - -const byte PIN_QWIIC_POWER = 18; -const byte PIN_IMU_POWER = 22; -const byte PIN_MICROSD_POWER = 15; - -//uint32_t msToSleep = 10; //This is the user editable number of ms to sleep between RTC checks -////#define TIMER_FREQ 3000000L //Counter/Timer 6 will use the HFRC oscillator of 3MHz -//#define TIMER_FREQ 32768 //Counter/Timer 6 will use the external 32kHz Xtal -//uint32_t sysTicksToSleep = msToSleep * (TIMER_FREQ / 1000); - -void setup() -{ - pinMode(PIN_POWER_LOSS, INPUT); - attachInterrupt(digitalPinToInterrupt(PIN_POWER_LOSS), powerDown, FALLING); - - Serial.begin(115200); - Serial.println("SparkFun RTC Example"); - - pinMode(PIN_QWIIC_POWER, OUTPUT); - pinMode(PIN_IMU_POWER, OUTPUT); - pinMode(PIN_MICROSD_POWER, OUTPUT); - - digitalWrite(PIN_QWIIC_POWER, LOW); - digitalWrite(PIN_IMU_POWER, LOW); - digitalWrite(PIN_MICROSD_POWER, LOW); - - pinMode(LOGIC_DEBUG, OUTPUT); - - digitalWrite(LOGIC_DEBUG, HIGH); - delay(50); - digitalWrite(LOGIC_DEBUG, LOW); - - myRTC.getTime(); - Serial.printf(" %02d:", myRTC.hour); - Serial.printf("%02d:", myRTC.minute); - Serial.printf("%02d", myRTC.seconds); - Serial.printf(" %02d/", myRTC.month); - Serial.printf("%02d/", myRTC.dayOfMonth); - Serial.printf("%02d", myRTC.year); - Serial.println(); - - Serial.println("d) Display time"); - Serial.println("s) Set RTC to compiler macro"); - Serial.println("r) System reset"); - Serial.println("p) Power down"); - Serial.println("q) Toggle Qwiic Power"); - Serial.println("m) Toggle microSD Power"); - -} - -void loop() -{ - if (Serial.available()) - { - byte choice = Serial.read(); - - if (choice == 's') - { - Serial.println("Set RTC to compiler"); - myRTC.setToCompilerTime(); //Easily set RTC using the system __DATE__ and __TIME__ macros from compiler - //myRTC.setTime(7, 28, 51, 0, 21, 10, 15); //Manually set RTC back to the future: Oct 21st, 2015 at 7:28.51 AM - //myRTC.setTime(1, 0, 0, 0, 21, 10, 15); //Manually set RTC back to the future: Oct 21st, 2015 at 7:28.51 AM - } - else if (choice == 'r') - { - Serial.println("System reset"); - am_hal_reset_control(AM_HAL_RESET_CONTROL_SWPOI, 0); //Cause a system Power On Init to release as much of the stack as possible - } - else if (choice == 'p') - { - Serial.println("Power down"); - powerDown(); - } - else if (choice == 'd') - { - myRTC.getTime(); - - Serial.printf(" %02d:", myRTC.hour); - Serial.printf("%02d:", myRTC.minute); - Serial.printf("%02d", myRTC.seconds); - - Serial.printf(" %02d/", myRTC.month); - Serial.printf("%02d/", myRTC.dayOfMonth); - Serial.printf("%02d", myRTC.year); - - Serial.println(); - - } - else if (choice == 'q') - { - Serial.println("Toggle Qwiic Power"); - if (digitalRead(PIN_QWIIC_POWER) == HIGH) - { - digitalWrite(PIN_QWIIC_POWER, LOW); - Serial.println("Qwiic Power On / Pin Low"); - } - else - { - digitalWrite(PIN_QWIIC_POWER, HIGH); - pinMode(5, OUTPUT); - digitalWrite(5, LOW); - pinMode(6, OUTPUT); - digitalWrite(6, LOW); - pinMode(7, OUTPUT); - digitalWrite(7, LOW); - pinMode(10, OUTPUT); - digitalWrite(10, LOW); - Serial.println("Qwiic Power Off / Pin High"); - } - } - else if (choice == 'm') - { - Serial.println("Toggle microSD Power"); - if (digitalRead(PIN_MICROSD_POWER) == HIGH) - { - digitalWrite(PIN_MICROSD_POWER, LOW); - pinMode(5, INPUT); - pinMode(6, INPUT); - pinMode(7, INPUT); - pinMode(10, INPUT); - Serial.println("microSD On / Pin Low"); - } - else - { - digitalWrite(PIN_MICROSD_POWER, HIGH); - Serial.println("microSD Off / Pin High"); - } - } while (Serial.available()) Serial.read(); - } -} - -//Power down the entire system but maintain running of RTC -//This function takes 100us to run including GPIO setting -//This puts the Apollo3 into 2.36uA to 2.6uA consumption mode -void powerDown() -{ - //digitalWrite(LOGIC_DEBUG, HIGH); - - //Force the peripherals off - am_hal_pwrctrl_periph_disable(AM_HAL_PWRCTRL_PERIPH_IOM0); - am_hal_pwrctrl_periph_disable(AM_HAL_PWRCTRL_PERIPH_IOM1); - am_hal_pwrctrl_periph_disable(AM_HAL_PWRCTRL_PERIPH_IOM2); - am_hal_pwrctrl_periph_disable(AM_HAL_PWRCTRL_PERIPH_IOM3); - am_hal_pwrctrl_periph_disable(AM_HAL_PWRCTRL_PERIPH_IOM4); - am_hal_pwrctrl_periph_disable(AM_HAL_PWRCTRL_PERIPH_IOM5); - am_hal_pwrctrl_periph_disable(AM_HAL_PWRCTRL_PERIPH_ADC); - am_hal_pwrctrl_periph_disable(AM_HAL_PWRCTRL_PERIPH_UART0); - am_hal_pwrctrl_periph_disable(AM_HAL_PWRCTRL_PERIPH_UART1); - - //The supervisor circuit tends to wake us from sleep if it - //remains as an interrupt - detachInterrupt(digitalPinToInterrupt(PIN_POWER_LOSS)); - - //Serial.flush(); //Finish any prints - - //Wire.end(); //Power down I2C - //qwiic.end(); //Power down I2C - - //SPI.end(); //Power down SPI - - power_adc_disable(); //Power down ADC. It it started by default before setup(). - - // Serial.end(); //Power down UART - // Serial1.end(); - - for (int x = 0 ; x < 50 ; x++) - am_hal_gpio_pinconfig(x , g_AM_HAL_GPIO_DISABLE); - - //We can't leave these power control pins floating - pinMode(PIN_QWIIC_POWER, OUTPUT); - pinMode(PIN_IMU_POWER, OUTPUT); - pinMode(PIN_MICROSD_POWER, OUTPUT); - - digitalWrite(PIN_QWIIC_POWER, HIGH); //High = off - digitalWrite(PIN_IMU_POWER, LOW); - digitalWrite(PIN_MICROSD_POWER, HIGH); //High = off - -const byte PIN_SPI_MISO = 6; -const byte PIN_SPI_MOSI = 7; -const byte PIN_SPI_SCK = 5; -const byte PIN_SPI_CS = 10; - - pinMode(PIN_SPI_CS, OUTPUT); - digitalWrite(PIN_SPI_CS, HIGH); //pullup the CS pin on the SD card (but only if you don’t already have a hardware pullup on your module) - pinMode(PIN_SPI_MOSI, OUTPUT); - digitalWrite(PIN_SPI_MOSI, HIGH); //pullup the MOSI pin on the SD card - pinMode(PIN_SPI_MISO, INPUT_PULLUP); //pullup the MISO pin on the SD card - pinMode(PIN_SPI_SCK, OUTPUT); - digitalWrite(PIN_SPI_SCK, LOW); //pull DOWN the 13scl pin on the SD card (IDLES LOW IN MODE0) - // NOTE: In Mode (0), the SPI interface holds the CLK line low when the bus is inactive, so DO NOT put a pullup on it. - - - // The default Arduino environment runs the System Timer (STIMER) off the 48 MHZ HFRC clock source. - // The HFRC appears to take over 60 uA when it is running, so this is a big source of extra - // current consumption in deep sleep. - // For systems that might want to use the STIMER to generate a periodic wakeup, it needs to be left running. - // However, it does not have to run at 48 MHz. If we reconfigure STIMER (system timer) to use the 32768 Hz - // XTAL clock source instead the measured deepsleep power drops by about 64 uA. - am_hal_stimer_config(AM_HAL_STIMER_CFG_CLEAR | AM_HAL_STIMER_CFG_FREEZE); - - // This option selects 32768 Hz via crystal osc. This appears to cost about 0.1 uA versus selecting "no clock" - am_hal_stimer_config(AM_HAL_STIMER_XTAL_32KHZ); - - // This option would be available to systems that don't care about passing time, but might be set - // to wake up on a GPIO transition interrupt. - // am_hal_stimer_config(AM_HAL_STIMER_NO_CLK); - - // Turn OFF Flash1 - am_hal_pwrctrl_memory_enable(AM_HAL_PWRCTRL_MEM_FLASH_512K); - - // Power down SRAM - PWRCTRL->MEMPWDINSLEEP_b.SRAMPWDSLP = PWRCTRL_MEMPWDINSLEEP_SRAMPWDSLP_ALLBUTLOWER32K; - - //Serial.end(); //Disable Serial - //digitalWrite(LOGIC_DEBUG, LOW); - - am_hal_sysctrl_sleep(AM_HAL_SYSCTRL_SLEEP_DEEP); -} - -//We use counter/timer 6 for this example but 0 to 7 are available -//CT 7 is used for Software Serial. All CTs are used for Servo. -//void setupADCTimer() -//{ -// analogReadResolution(14); //Set resolution to 14 bit -// -// //Clear compare interrupt -// am_hal_stimer_int_clear(AM_HAL_STIMER_INT_COMPAREG); //Use CT6 -// -// am_hal_stimer_int_enable(AM_HAL_STIMER_INT_COMPAREG); // Enable C/T G=6 -// -// //Don't change from 3MHz system timer, but enable G timer -// am_hal_stimer_config(AM_HAL_STIMER_CFG_CLEAR | AM_HAL_STIMER_CFG_FREEZE); -// // am_hal_stimer_config(AM_HAL_STIMER_HFRC_3MHZ | AM_HAL_STIMER_CFG_COMPARE_G_ENABLE); -// am_hal_stimer_config(AM_HAL_STIMER_XTAL_32KHZ | AM_HAL_STIMER_CFG_COMPARE_G_ENABLE); -// -// //Setup ISR to trigger when the number of ms have elapsed -// am_hal_stimer_compare_delta_set(6, sysTicksToSleep); -// -// //Enable the timer interrupt in the NVIC. -// NVIC_EnableIRQ(STIMER_CMPR6_IRQn); -//} - -//Called once number of milliseconds has passed -//extern "C" void am_stimer_cmpr6_isr(void) -//{ -// uint32_t ui32Status = am_hal_stimer_int_status_get(false); -// if (ui32Status & AM_HAL_STIMER_INT_COMPAREG) -// { -// am_hal_stimer_int_clear(AM_HAL_STIMER_INT_COMPAREG); -// -// //Reset compare value. ISR will trigger when the number of ms have elapsed -// am_hal_stimer_compare_delta_set(6, sysTicksToSleep); -// -// int div3 = analogRead(ADC_INTERNAL_VCC_DIV3); //Read VCC across a 1/3 resistor divider -// float vcc = (float)div3 * 6 / 16384.0; //Convert 1/3 VCC to VCC -// // Serial.print(" VCC: "); -// // Serial.print(vcc, 2); -// // Serial.print("V"); -// // Serial.println(); -// -// if (vcc < 3.05) -// { -// NVIC_DisableIRQ(STIMER_CMPR6_IRQn); -// powerDown(); -// } -// } -//} diff --git a/Firmware/Test Sketches/Low Power/PowerDownRTCwithSD/PowerDownRTCwithSD.ino b/Firmware/Test Sketches/Low Power/PowerDownRTCwithSD/PowerDownRTCwithSD.ino deleted file mode 100644 index 76ecdfe..0000000 --- a/Firmware/Test Sketches/Low Power/PowerDownRTCwithSD/PowerDownRTCwithSD.ino +++ /dev/null @@ -1,246 +0,0 @@ -/* Author: Nathan Seidle - Created: Septempter 27th, 2019 - License: MIT. See SparkFun Arduino Apollo3 Project for more information - - This example demonstrates how to put the core to sleep for a number of - milliseconds before waking and printing the current time/date. This - is helpful for checking power consumption of the core while RTC+CT6 are running. - - 6mA with Power LED, no microSD, USB - 4.58, no power LED, no microSD, USB - So power LED is ~1.5mA - - 1.05mA no power LED, no microSD, no USB - So USB is ~3.5mA - - Fully powered down, board is pulling 450uA from battery but that - seems to be because RTC batt is charging at ~360uA. - - Measurements should be done at the MEAS jumper with the RTC battery disconnected. - - 3/5/20 - - 6.61mA, no LED, USB, SD - 4.78mA, no LED, USB, no SD - 0.67mA, no LED, no USB, SD with pin set LOW - 0.65mA, no LED, no USB, SD with pin set HIGH - 0.16mA, no LED, no USB, no SD - - 3/6/20 - 0.65mA, no LED, no USB, Kingston 16GB SD - 0.152mA, no LED, no USB, SparkX SD - 0.191mA, no LED, no USB, SparkX SD - 0.188mA, no LED, no USB, SparkX SD - 0.098mA, no LEd, no USB, no SD - - Various SD cards pull different current even when shut off. - - 3/18/20 - 0.171mA no USB, no SD - 0.110mA no USB, no SD after overnight - -*/ - -#include "RTC.h" //Include RTC library included with the Aruino_Apollo3 core -APM3_RTC myRTC; //Create instance of RTC class - -#include - -//microSD Interface -//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- -#include -#include //We use SdFat-Beta from Bill Greiman for increased read/write speed - -const byte PIN_MICROSD_CHIP_SELECT = 10; -const byte PIN_MICROSD_POWER = 15; //x04 - -#define SD_CONFIG SdSpiConfig(PIN_MICROSD_CHIP_SELECT, SHARED_SPI, SD_SCK_MHZ(24)) //Max of 24MHz -#define SD_CONFIG_MAX_SPEED SdSpiConfig(PIN_MICROSD_CHIP_SELECT, DEDICATED_SPI, SD_SCK_MHZ(24)) //Max of 24MHz - -SdFat sd; -File sensorDataFile; //File that all sensor data is written to -File serialDataFile; //File that all incoming serial data is written to - -//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- - -const byte PIN_POWER_LOSS = 3; - -const byte LOGIC_DEBUG = 11; - -const byte PIN_QWIIC_POWER = 18; -const byte PIN_IMU_POWER = 22; - -//uint32_t msToSleep = 10; //This is the user editable number of ms to sleep between RTC checks -////#define TIMER_FREQ 3000000L //Counter/Timer 6 will use the HFRC oscillator of 3MHz -//#define TIMER_FREQ 32768 //Counter/Timer 6 will use the external 32kHz Xtal -//uint32_t sysTicksToSleep = msToSleep * (TIMER_FREQ / 1000); - -void setup() -{ - pinMode(PIN_POWER_LOSS, INPUT); - attachInterrupt(digitalPinToInterrupt(PIN_POWER_LOSS), powerDown, FALLING); - - Serial.begin(115200); - Serial.println("SparkFun RTC Example"); - - Wire.begin(); - - qwiicPowerOff(); - microSDPowerOff(); - imuPowerOff(); - SPI.begin(); - - beginSD(); - - pinMode(LOGIC_DEBUG, OUTPUT); - - digitalWrite(LOGIC_DEBUG, HIGH); - delay(50); - digitalWrite(LOGIC_DEBUG, LOW); - - myRTC.getTime(); - Serial.printf(" %02d:", myRTC.hour); - Serial.printf("%02d:", myRTC.minute); - Serial.printf("%02d", myRTC.seconds); - Serial.printf(" %02d/", myRTC.month); - Serial.printf("%02d/", myRTC.dayOfMonth); - Serial.printf("%02d", myRTC.year); - Serial.println(); - - Serial.println("d) Display time"); - Serial.println("s) Set RTC to compiler macro"); - Serial.println("r) System reset"); - Serial.println("p) Power down"); - Serial.println("q) Toggle Qwiic Power"); - Serial.println("m) Toggle microSD Power"); - -} - -void loop() -{ - if (Serial.available()) - { - byte choice = Serial.read(); - - if (choice == 's') - { - Serial.println("Set RTC to compiler"); - myRTC.setToCompilerTime(); //Easily set RTC using the system __DATE__ and __TIME__ macros from compiler - //myRTC.setTime(7, 28, 51, 0, 21, 10, 15); //Manually set RTC back to the future: Oct 21st, 2015 at 7:28.51 AM - //myRTC.setTime(1, 0, 0, 0, 21, 10, 15); //Manually set RTC back to the future: Oct 21st, 2015 at 7:28.51 AM - } - else if (choice == 'r') - { - Serial.println("System reset"); - am_hal_reset_control(AM_HAL_RESET_CONTROL_SWPOI, 0); //Cause a system Power On Init to release as much of the stack as possible - } - else if (choice == 'p') - { - Serial.println("Power down"); - powerDown(); - } - else if (choice == 'd') - { - myRTC.getTime(); - - Serial.printf(" %02d:", myRTC.hour); - Serial.printf("%02d:", myRTC.minute); - Serial.printf("%02d", myRTC.seconds); - - Serial.printf(" %02d/", myRTC.month); - Serial.printf("%02d/", myRTC.dayOfMonth); - Serial.printf("%02d", myRTC.year); - - Serial.println(); - } - else if (choice == 'q') - { - Serial.println("Toggle Qwiic Power"); - if (digitalRead(PIN_QWIIC_POWER) == HIGH) - { - qwiicPowerOn(); - Serial.println("Qwiic Power On / Pin Low"); - } - else - { - qwiicPowerOff(); - Serial.println("Qwiic Power Off / Pin High"); - } - } - else if (choice == 'm') - { - Serial.println("Toggle microSD Power"); - if (digitalRead(PIN_MICROSD_POWER) == HIGH) - { - microSDPowerOn(); - Serial.println("microSD On / Pin Low"); - } - else - { - microSDPowerOff(); - Serial.println("microSD Off / Pin High"); - } - } - - while (Serial.available()) Serial.read(); - } -} - -//Power down the entire system but maintain running of RTC -//This function takes 100us to run including GPIO setting -//This puts the Apollo3 into 2.36uA to 2.6uA consumption mode -void powerDown() -{ - //digitalWrite(LOGIC_DEBUG, HIGH); - - //The supervisor circuit tends to wake us from sleep if it - //remains as an interrupt - detachInterrupt(digitalPinToInterrupt(PIN_POWER_LOSS)); - - Serial.flush(); //Finish any prints - - Wire.end(); //Power down I2C - //qwiic.end(); //Power down I2C - - SPI.end(); //Power down SPI - - power_adc_disable(); //Power down ADC. It it started by default before setup(). - - Serial.end(); //Power down UART - Serial1.end(); - - for (int x = 0 ; x < 50 ; x++) - am_hal_gpio_pinconfig(x , g_AM_HAL_GPIO_DISABLE); - - - //We can't leave these power control pins floating - qwiicPowerOff(); - imuPowerOff(); - //microSDPowerOff(); //355 - -// const byte PIN_SPI_MISO = 6; -// const byte PIN_SPI_MOSI = 7; -// const byte PIN_SPI_SCK = 5; -// const byte PIN_SPI_CS = 10; -// -// pinMode(PIN_SPI_CS, OUTPUT); -// digitalWrite(PIN_SPI_CS, HIGH); //pullup the CS pin on the SD card (but only if you don’t already have a hardware pullup on your module) -// pinMode(PIN_SPI_MOSI, OUTPUT); -// digitalWrite(PIN_SPI_MOSI, HIGH); //pullup the MOSI pin on the SD card -// pinMode(PIN_SPI_MISO, INPUT_PULLUP); //pullup the MISO pin on the SD card -// pinMode(PIN_SPI_SCK, OUTPUT); -// digitalWrite(PIN_SPI_SCK, LOW); //pull DOWN the 13scl pin on the SD card (IDLES LOW IN MODE0) -// // NOTE: In Mode (0), the SPI interface holds the CLK line low when the bus is inactive, so DO NOT put a pullup on it. - - am_hal_stimer_config(AM_HAL_STIMER_CFG_CLEAR | AM_HAL_STIMER_CFG_FREEZE); - am_hal_stimer_config(AM_HAL_STIMER_XTAL_32KHZ); - - //Power down Flash, SRAM, cache - // am_hal_pwrctrl_memory_deepsleep_powerdown(AM_HAL_PWRCTRL_MEM_CACHE); //Turn off CACHE - // am_hal_pwrctrl_memory_deepsleep_powerdown(AM_HAL_PWRCTRL_MEM_FLASH_512K); //Turn off everything but lower 512k - // am_hal_pwrctrl_memory_deepsleep_powerdown(AM_HAL_PWRCTRL_MEM_SRAM_64K_DTCM); //Turn off everything but lower 64k - am_hal_pwrctrl_memory_deepsleep_powerdown(AM_HAL_PWRCTRL_MEM_ALL); //Turn off all memory (doesn't recover) - - //digitalWrite(LOGIC_DEBUG, LOW); - - am_hal_sysctrl_sleep(AM_HAL_SYSCTRL_SLEEP_DEEP); //Sleep forever -} diff --git a/Firmware/Test Sketches/Low Power/PowerDownRTCwithSD/sd.ino b/Firmware/Test Sketches/Low Power/PowerDownRTCwithSD/sd.ino deleted file mode 100644 index 6899a58..0000000 --- a/Firmware/Test Sketches/Low Power/PowerDownRTCwithSD/sd.ino +++ /dev/null @@ -1,63 +0,0 @@ -void beginSD() -{ - pinMode(PIN_MICROSD_CHIP_SELECT, OUTPUT); - digitalWrite(PIN_MICROSD_CHIP_SELECT, HIGH); //Be sure SD is deselected - - microSDPowerOn(); - - //Max power up time is 250ms: https://www.kingston.com/datasheets/SDCIT-specsheet-64gb_en.pdf - //Max current is 200mA average across 1s, peak 300mA - delay(10); - - if (sd.begin(SD_CONFIG) == false) //Slightly Faster SdFat Beta (we don't have dedicated SPI) - { - delay(250); //Give SD more time to power up, then try again - if (sd.begin(SD_CONFIG) == false) //Slightly Faster SdFat Beta (we don't have dedicated SPI) - { - Serial.println("SD init failed. Do you have the correct board selected in Arduino? Is card present? Formatted?"); - digitalWrite(PIN_MICROSD_CHIP_SELECT, HIGH); //Be sure SD is deselected - return; - } - } - // } - - //Change to root directory. All new file creation will be in root. - if (sd.chdir() == false) - { - Serial.println("SD change directory failed"); - return; - } -} - -void qwiicPowerOn() -{ - pinMode(PIN_QWIIC_POWER, OUTPUT); - digitalWrite(PIN_QWIIC_POWER, LOW); -} -void qwiicPowerOff() -{ - pinMode(PIN_QWIIC_POWER, OUTPUT); - digitalWrite(PIN_QWIIC_POWER, HIGH); -} - -void microSDPowerOn() -{ - pinMode(PIN_MICROSD_POWER, OUTPUT); - digitalWrite(PIN_MICROSD_POWER, LOW); -} -void microSDPowerOff() -{ - pinMode(PIN_MICROSD_POWER, OUTPUT); - digitalWrite(PIN_MICROSD_POWER, HIGH); -} - -void imuPowerOn() -{ - pinMode(PIN_IMU_POWER, OUTPUT); - digitalWrite(PIN_IMU_POWER, HIGH); -} -void imuPowerOff() -{ - pinMode(PIN_IMU_POWER, OUTPUT); - digitalWrite(PIN_IMU_POWER, LOW); -} diff --git a/Firmware/Test Sketches/Low Power/PowerDownWithWake/PowerDownWithWake.ino b/Firmware/Test Sketches/Low Power/PowerDownWithWake/PowerDownWithWake.ino deleted file mode 100644 index 278ce0c..0000000 --- a/Firmware/Test Sketches/Low Power/PowerDownWithWake/PowerDownWithWake.ino +++ /dev/null @@ -1,265 +0,0 @@ -/* - Power down all parts of the board - Wake after three seconds - Take and log reading - Power back down - - Qwiic power pin takes ~2uA - Qwiic is turning on/off 6.18mA to 4.52mA - Core is running at 606uA and correctly shuts down to 2uA but board is pulling 3.91mA. - - Hmm, disabling the port in device manager gets me to 1.07mA. With micro in LP, I'm at 0.48mA. - With USB disabled, in LP, board is 0.288mA from battery. 0.195 with microSD evacuated. - CH340E is 0.09mA in suspend mode. - MCP73831 is ~1uA on battery (Vdd <= Vbat - 50mV) - AP2112K is ~50uA - So I think that's where the ~169uA - - .88mA in LP, with SD, no USB suspend - - On batt, no LP, 0.739mA! Charge LED is on. Core is at .583mA (0.150mA) - 0.173mA LP, no SD, on batt. No suspend over USB. - 0.169ma LP, no SD, on batt, with suspend over USB. - - Future rev - maybe attach to VUSB to detect when USB is connected or not. - - Working: - 2.22uA LP, 250uA board. Wake every 5 s. - - - The hard power down of IOMs seems to be an issue. - We should implement IOM power down with .end functions - Wire, SPI, UART - Working... 140uA in sleep - 205 with all IOMs not disabled so something is taking power - 131 with UARTs powered down so they seem to be a culprit - 127 without hard IOM power down. Good. - -*/ - -#include - -#include "SparkFun_MS5637_Arduino_Library.h" - -MS5637 barometricSensor; -TwoWire qwiic(1); //Will use pads 8/9 - -uint32_t msToSleep = 3000; //This is the user editable number of ms to sleep between RTC checks -#define TIMER_FREQ 32768L //Counter/Timer 6 will use the 32kHz clock -uint32_t sysTicksToSleep = msToSleep * TIMER_FREQ / 1000; - -const byte PIN_QWIIC_POWER = 18; -const byte PIN_STAT_LED = 19; -const byte PIN_IMU_POWER = 22; -const byte PIN_MICROSD_POWER = 15; - -void setup(void) { - Serial.begin(115200); - Serial.println("Qwiic Pressure Sensor MS5637 Example"); - - pinMode(PIN_QWIIC_POWER, OUTPUT); - pinMode(PIN_IMU_POWER, OUTPUT); - pinMode(PIN_MICROSD_POWER, OUTPUT); - pinMode(PIN_STAT_LED, OUTPUT); - - digitalWrite(PIN_QWIIC_POWER, LOW); - digitalWrite(PIN_IMU_POWER, LOW); - digitalWrite(PIN_MICROSD_POWER, LOW); - - qwiicPowerOn(); - delay(100); - qwiic.begin(); - - if (barometricSensor.begin(qwiic) == false) - { - Serial.println("MS5637 sensor did not respond. Please check wiring."); - //while (1); - } - else - Serial.println("MS5637 sensor detected."); - - Serial.flush(); - qwiic.end(); - - delay(100); - qwiic.begin(); - if (barometricSensor.begin(qwiic) == false) - { - Serial.println("MS5637 sensor did not respond. Please check wiring."); - //while (1); - } - else - Serial.println("MS5637 sensor detected."); - - Serial.println("Setup done"); -} - -void loop(void) { - - float temperature = 1.2; - float pressure = 2.5; - //temperature = barometricSensor.getTemperature(); - //pressure = barometricSensor.getPressure(); - - Serial.print("Temperature="); - Serial.print(temperature, 1); - Serial.print("(C)"); - - Serial.print(" Pressure="); - Serial.print(pressure, 3); - Serial.print("(hPa or mbar)"); - - Serial.println(); - - pinMode(PIN_STAT_LED, OUTPUT); - digitalWrite(PIN_STAT_LED, HIGH); - delay(100); - digitalWrite(PIN_STAT_LED, LOW); - - goToSleep(); -} - -//Power everything down and wait for RTC interrupt wakeup -void goToSleep() -{ - //digitalWrite(LOGIC_DEBUG, HIGH); - - qwiic.end(); //Power down I2C - - Serial.end(); //Power down UART - - power_adc_disable(); //Power down ADC - - digitalWrite(PIN_QWIIC_POWER, HIGH); //HIGH = Off - digitalWrite(PIN_IMU_POWER, LOW); - digitalWrite(PIN_MICROSD_POWER, LOW); - - for (int x = 0 ; x < 50 ; x++) - am_hal_gpio_pinconfig(x , g_AM_HAL_GPIO_DISABLE); - - //We can't leave these power control pins floating - pinMode(PIN_QWIIC_POWER, OUTPUT); - pinMode(PIN_IMU_POWER, OUTPUT); - pinMode(PIN_MICROSD_POWER, OUTPUT); - - qwiicPowerOff(); - digitalWrite(PIN_IMU_POWER, LOW); - digitalWrite(PIN_MICROSD_POWER, LOW); - - //We use counter/timer 6 to cause us to wake up from sleep but 0 to 7 are available - //CT 7 is used for Software Serial. All CTs are used for Servo. - am_hal_stimer_int_clear(AM_HAL_STIMER_INT_COMPAREG); //Clear CT6 - am_hal_stimer_int_enable(AM_HAL_STIMER_INT_COMPAREG); //Enable C/T G=6 - - //Use the lower power 32kHz clock - am_hal_stimer_config(AM_HAL_STIMER_CFG_CLEAR | AM_HAL_STIMER_CFG_FREEZE); - am_hal_stimer_config(AM_HAL_STIMER_XTAL_32KHZ | AM_HAL_STIMER_CFG_COMPARE_G_ENABLE); - - //Right here we need to reduce the sleep sys ticks by the amount we've been awake so that we hit exactly 0.12Hz - - //Setup interrupt to trigger when the number of ms have elapsed - am_hal_stimer_compare_delta_set(6, sysTicksToSleep); - - // Turn OFF Flash1 - am_hal_pwrctrl_memory_enable(AM_HAL_PWRCTRL_MEM_FLASH_512K); - - // Power down SRAM - // Nathan seems to have gone a little off script here and isn't using - // am_hal_pwrctrl_memory_deepsleep_powerdown or - // am_hal_pwrctrl_memory_deepsleep_retain. I wonder why? - //PWRCTRL->MEMPWDINSLEEP_b.SRAMPWDSLP = PWRCTRL_MEMPWDINSLEEP_SRAMPWDSLP_ALLBUTLOWER32K; - PWRCTRL->MEMPWDINSLEEP_b.SRAMPWDSLP = PWRCTRL_MEMPWDINSLEEP_SRAMPWDSLP_ALLBUTLOWER64K; - - //Enable the timer interrupt in the NVIC. - NVIC_EnableIRQ(STIMER_CMPR6_IRQn); - - // Go to Deep Sleep. - am_hal_sysctrl_sleep(AM_HAL_SYSCTRL_SLEEP_DEEP); - - //Turn off interrupt - NVIC_DisableIRQ(STIMER_CMPR6_IRQn); - - //We're BACK! - wakeFromSleep(); -} - -//Power everything up gracefully -void wakeFromSleep() -{ - // Set the clock frequency. (redundant?) - am_hal_clkgen_control(AM_HAL_CLKGEN_CONTROL_SYSCLK_MAX, 0); - - // Set the default cache configuration. (redundant?) - am_hal_cachectrl_config(&am_hal_cachectrl_defaults); - am_hal_cachectrl_enable(); - - // Note: because we called setupRTC earlier, - // we do NOT want to call am_bsp_low_power_init() here. - // It would configure the board for low power operation - // and calls am_hal_pwrctrl_low_power_init() - // but it also stops the RTC oscillator! - // (BSP = Board Support Package) - - // Initialize for low power in the power control block. (redundant?) - am_hal_pwrctrl_low_power_init(); - - // Power up SRAM - PWRCTRL->MEMPWDINSLEEP_b.SRAMPWDSLP = PWRCTRL_MEMPWDINSLEEP_SRAMPWDSLP_NONE; - - // Turn on Flash - // There is a chance this could fail but I guess we should move on regardless and not do a while(1); - am_hal_pwrctrl_memory_enable(AM_HAL_PWRCTRL_MEM_ALL); - - // Go back to using the main clock - am_hal_stimer_int_enable(AM_HAL_STIMER_INT_OVERFLOW); // (posssibly redundant?) - NVIC_EnableIRQ(STIMER_IRQn); // (posssibly redundant?) - am_hal_stimer_config(AM_HAL_STIMER_CFG_CLEAR | AM_HAL_STIMER_CFG_FREEZE); - am_hal_stimer_config(AM_HAL_STIMER_HFRC_3MHZ); - - // Restore the TX/RX connections between the Artemis module and the CH340S - am_hal_gpio_pinconfig(48 /* TXO-0 */, g_AM_BSP_GPIO_COM_UART_TX); - am_hal_gpio_pinconfig(49 /* RXI-0 */, g_AM_BSP_GPIO_COM_UART_RX); - - // Reenable the debugger GPIOs - am_hal_gpio_pinconfig(20 /* SWDCLK */, g_AM_BSP_GPIO_SWDCK); - am_hal_gpio_pinconfig(21 /* SWDIO */, g_AM_BSP_GPIO_SWDIO); - - // Turn on ADC - ap3_adc_setup(); - - // Start the console serial port again (zzz will have ended it) - Serial.begin(115200); - Serial.println("Back on"); - - //Turn on Qwiic - qwiicPowerOn(); - delay(100); - qwiic.begin(); - - //Restart Sensors - if (barometricSensor.begin(qwiic) == false) - { - Serial.println("MS5637 sensor did not respond. Please check wiring."); - //while (1); - } -} - -//Called once number of milliseconds has passed -extern "C" void am_stimer_cmpr6_isr(void) -{ - uint32_t ui32Status = am_hal_stimer_int_status_get(false); - if (ui32Status & AM_HAL_STIMER_INT_COMPAREG) - { - am_hal_stimer_int_clear(AM_HAL_STIMER_INT_COMPAREG); - } -} - -void qwiicPowerOn() -{ - digitalWrite(PIN_QWIIC_POWER, LOW); -} - -void qwiicPowerOff() -{ - digitalWrite(PIN_QWIIC_POWER, HIGH); -} diff --git a/Firmware/Test Sketches/Low Power/PowerDown_FileWriteBug/PowerDown_FileWriteBug.ino b/Firmware/Test Sketches/Low Power/PowerDown_FileWriteBug/PowerDown_FileWriteBug.ino deleted file mode 100644 index 7b82c3e..0000000 --- a/Firmware/Test Sketches/Low Power/PowerDown_FileWriteBug/PowerDown_FileWriteBug.ino +++ /dev/null @@ -1,184 +0,0 @@ -/* - Power down all parts of the board - Wake after three seconds - Write to a file - Power back down -*/ - -//#include - -//microSD Interface -//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- -#include -#include //We use SdFat-Beta from Bill Greiman for increased read/write speed - -const byte PIN_MICROSD_CHIP_SELECT = 10; -const byte PIN_MICROSD_POWER = 15; //x04 - -#define SD_CONFIG SdSpiConfig(PIN_MICROSD_CHIP_SELECT, SHARED_SPI, SD_SCK_MHZ(24)) //Max of 24MHz -#define SD_CONFIG_MAX_SPEED SdSpiConfig(PIN_MICROSD_CHIP_SELECT, DEDICATED_SPI, SD_SCK_MHZ(24)) //Max of 24MHz - -SdFat sd; -File sensorDataFile; //File that all sensor data is written to -File serialDataFile; //File that all incoming serial data is written to - -char sensorDataFileName[30] = ""; //We keep a record of this file name so that we can re-open it upon wakeup from sleep -char serialDataFileName[30] = ""; //We keep a record of this file name so that we can re-open it upon wakeup from sleep -const int sdPowerDownDelay = 100; //Delay for this many ms before turning off the SD card power -//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- - -uint32_t msToSleep = 3000; //This is the user editable number of ms to sleep between RTC checks -#define TIMER_FREQ 32768L //Counter/Timer 6 will use the 32kHz clock -uint32_t sysTicksToSleep = msToSleep * TIMER_FREQ / 1000; - -const byte PIN_QWIIC_POWER = 18; -const byte PIN_STAT_LED = 19; -const byte PIN_IMU_POWER = 22; - -void setup(void) { - Serial.begin(115200); - Serial.println(); - Serial.println("SD Write Test"); - - qwiicPowerOff(); - microSDPowerOff(); - imuPowerOff(); - - SPI.begin(); - - beginSD(); - - beginDataLogging(); - - Serial.println("Setup done"); -} - -void loop(void) -{ - String outputData = "Test string\n"; - - char temp[512]; - outputData.toCharArray(temp, 512); //Convert string to char array so sdfat can record it - sensorDataFile.write(temp, strlen(temp)); //Record the buffer to the card - sensorDataFile.sync(); - - Serial.println("File recorded"); - - goToSleep(); -} - -//Power everything down and wait for RTC interrupt wakeup -void goToSleep() -{ - //digitalWrite(LOGIC_DEBUG, HIGH); - - Serial.flush(); - Serial.end(); //Power down UART - - delay(sdPowerDownDelay); // Give the SD card time to finish writing ***** THIS IS CRITICAL ***** - - power_adc_disable(); //Power down ADC - - for (int x = 0 ; x < 50 ; x++) - am_hal_gpio_pinconfig(x , g_AM_HAL_GPIO_DISABLE); - - qwiicPowerOff(); - microSDPowerOff(); - imuPowerOff(); - - //We use counter/timer 6 to cause us to wake up from sleep but 0 to 7 are available - //CT 7 is used for Software Serial. All CTs are used for Servo. - am_hal_stimer_int_clear(AM_HAL_STIMER_INT_COMPAREG); //Clear CT6 - am_hal_stimer_int_enable(AM_HAL_STIMER_INT_COMPAREG); //Enable C/T G=6 - - //Use the lower power 32kHz clock - am_hal_stimer_config(AM_HAL_STIMER_CFG_CLEAR | AM_HAL_STIMER_CFG_FREEZE); - am_hal_stimer_config(AM_HAL_STIMER_XTAL_32KHZ | AM_HAL_STIMER_CFG_COMPARE_G_ENABLE); - - //Right here we need to reduce the sleep sys ticks by the amount we've been awake so that we hit exactly 0.12Hz - - //Setup interrupt to trigger when the number of ms have elapsed - am_hal_stimer_compare_delta_set(6, sysTicksToSleep); - - // Turn OFF Flash1 - am_hal_pwrctrl_memory_enable(AM_HAL_PWRCTRL_MEM_FLASH_512K); - - // Power down SRAM - // Nathan seems to have gone a little off script here and isn't using - // am_hal_pwrctrl_memory_deepsleep_powerdown or - // am_hal_pwrctrl_memory_deepsleep_retain. I wonder why? - //PWRCTRL->MEMPWDINSLEEP_b.SRAMPWDSLP = PWRCTRL_MEMPWDINSLEEP_SRAMPWDSLP_ALLBUTLOWER32K; - PWRCTRL->MEMPWDINSLEEP_b.SRAMPWDSLP = PWRCTRL_MEMPWDINSLEEP_SRAMPWDSLP_ALLBUTLOWER64K; - - //Enable the timer interrupt in the NVIC. - NVIC_EnableIRQ(STIMER_CMPR6_IRQn); - - // Go to Deep Sleep. - am_hal_sysctrl_sleep(AM_HAL_SYSCTRL_SLEEP_DEEP); - - //Turn off interrupt - NVIC_DisableIRQ(STIMER_CMPR6_IRQn); - - //We're BACK! - wakeFromSleep(); -} - -//Power everything up gracefully -void wakeFromSleep() -{ - // Set the clock frequency. (redundant?) - am_hal_clkgen_control(AM_HAL_CLKGEN_CONTROL_SYSCLK_MAX, 0); - - // Set the default cache configuration. (redundant?) - am_hal_cachectrl_config(&am_hal_cachectrl_defaults); - am_hal_cachectrl_enable(); - - // Note: because we called setupRTC earlier, - // we do NOT want to call am_bsp_low_power_init() here. - // It would configure the board for low power operation - // and calls am_hal_pwrctrl_low_power_init() - // but it also stops the RTC oscillator! - // (BSP = Board Support Package) - - // Initialize for low power in the power control block. (redundant?) - am_hal_pwrctrl_low_power_init(); - - // Power up SRAM - PWRCTRL->MEMPWDINSLEEP_b.SRAMPWDSLP = PWRCTRL_MEMPWDINSLEEP_SRAMPWDSLP_NONE; - - // Turn on Flash - // There is a chance this could fail but I guess we should move on regardless and not do a while(1); - am_hal_pwrctrl_memory_enable(AM_HAL_PWRCTRL_MEM_ALL); - - // Go back to using the main clock - am_hal_stimer_int_enable(AM_HAL_STIMER_INT_OVERFLOW); // (posssibly redundant?) - NVIC_EnableIRQ(STIMER_IRQn); // (posssibly redundant?) - am_hal_stimer_config(AM_HAL_STIMER_CFG_CLEAR | AM_HAL_STIMER_CFG_FREEZE); - am_hal_stimer_config(AM_HAL_STIMER_HFRC_3MHZ); - - // Restore the TX/RX connections between the Artemis module and the CH340S - am_hal_gpio_pinconfig(48 /* TXO-0 */, g_AM_BSP_GPIO_COM_UART_TX); - am_hal_gpio_pinconfig(49 /* RXI-0 */, g_AM_BSP_GPIO_COM_UART_RX); - - // Reenable the debugger GPIOs - am_hal_gpio_pinconfig(20 /* SWDCLK */, g_AM_BSP_GPIO_SWDCK); - am_hal_gpio_pinconfig(21 /* SWDIO */, g_AM_BSP_GPIO_SWDIO); - - // Turn on ADC - ap3_adc_setup(); - - // Start the console serial port again (zzz will have ended it) - Serial.begin(115200); - Serial.println("Back on"); - -} - -//Called once number of milliseconds has passed -extern "C" void am_stimer_cmpr6_isr(void) -{ - uint32_t ui32Status = am_hal_stimer_int_status_get(false); - if (ui32Status & AM_HAL_STIMER_INT_COMPAREG) - { - am_hal_stimer_int_clear(AM_HAL_STIMER_INT_COMPAREG); - } -} diff --git a/Firmware/Test Sketches/Low Power/PowerDown_FileWriteBug/sd.ino b/Firmware/Test Sketches/Low Power/PowerDown_FileWriteBug/sd.ino deleted file mode 100644 index 219247b..0000000 --- a/Firmware/Test Sketches/Low Power/PowerDown_FileWriteBug/sd.ino +++ /dev/null @@ -1,148 +0,0 @@ -//Returns next available log file name -//Checks the spots in EEPROM for the next available LOG# file name -//Updates EEPROM and then appends to the new log file. -char* findNextAvailableLog(int &newFileNumber, const char *fileLeader) -{ - File newFile; //This will contain the file for SD writing - - Serial.println("Next avail"); - Serial.flush(); - - if (newFileNumber > 0) - newFileNumber--; //Check if last log file was empty - - //Search for next available log spot - static char newFileName[40]; - while (1) - { - Serial.println("1"); - Serial.flush(); - - sprintf(newFileName, "%s%05u.TXT", fileLeader, newFileNumber); //Splice the new file number into this file name - - Serial.println("2"); - Serial.flush(); - - Serial.println(newFileName); - Serial.flush(); - - if (sd.exists(newFileName) == false) break; //File name not found so we will use it. - - Serial.println("3"); - Serial.flush(); - - //File exists so open and see if it is empty. If so, use it. - newFile = sd.open(newFileName, O_READ); - //newFile.open(newFileName, O_READ); //exFat - if (newFile.size() == 0) break; // File is empty so we will use it. - - Serial.println("4"); - Serial.flush(); - - newFile.close(); // Close this existing file we just opened. - - newFileNumber++; //Try the next number - } - Serial.println("5"); - Serial.flush(); - newFile.close(); //Close this new file we just opened - - Serial.println("6"); - Serial.flush(); - newFileNumber++; //Increment so the next power up uses the next file # - //recordSettings(); //Record new file number to EEPROM and to config file - - Serial.print(F("Created log file: ")); - Serial.println(newFileName); - Serial.flush(); - - return (newFileName); -} - -void beginDataLogging() -{ - int fileNumber = 10; - - //If we don't have a file yet, create one. Otherwise, re-open the last used file - if (strlen(sensorDataFileName) == 0) - strcpy(sensorDataFileName, findNextAvailableLog(fileNumber, "dataLog")); - - // O_CREAT - create the file if it does not exist - // O_APPEND - seek to the end of the file prior to each write - // O_WRITE - open for write - if (sensorDataFile.open(sensorDataFileName, O_CREAT | O_APPEND | O_WRITE) == false) - { - Serial.println("Failed to create sensor data file"); - return; - } - - Serial.println("Sensor data file open"); - Serial.flush(); -} - -void beginSD() -{ - pinMode(PIN_MICROSD_CHIP_SELECT, OUTPUT); - digitalWrite(PIN_MICROSD_CHIP_SELECT, HIGH); //Be sure SD is deselected - - microSDPowerOn(); - - //Max power up time is 250ms: https://www.kingston.com/datasheets/SDCIT-specsheet-64gb_en.pdf - //Max current is 200mA average across 1s, peak 300mA - delay(10); - - if (sd.begin(SD_CONFIG) == false) //Slightly Faster SdFat Beta (we don't have dedicated SPI) - { - delay(250); //Give SD more time to power up, then try again - if (sd.begin(SD_CONFIG) == false) //Slightly Faster SdFat Beta (we don't have dedicated SPI) - { - Serial.println("SD init failed. Do you have the correct board selected in Arduino? Is card present? Formatted?"); - digitalWrite(PIN_MICROSD_CHIP_SELECT, HIGH); //Be sure SD is deselected - return; - } - } - // } - - //Change to root directory. All new file creation will be in root. - if (sd.chdir() == false) - { - Serial.println("SD change directory failed"); - return; - } - - Serial.println("SD begin complete"); - Serial.flush(); -} - -void qwiicPowerOn() -{ - pinMode(PIN_QWIIC_POWER, OUTPUT); - digitalWrite(PIN_QWIIC_POWER, LOW); -} -void qwiicPowerOff() -{ - pinMode(PIN_QWIIC_POWER, OUTPUT); - digitalWrite(PIN_QWIIC_POWER, HIGH); -} - -void microSDPowerOn() -{ - pinMode(PIN_MICROSD_POWER, OUTPUT); - digitalWrite(PIN_MICROSD_POWER, LOW); -} -void microSDPowerOff() -{ - pinMode(PIN_MICROSD_POWER, OUTPUT); - digitalWrite(PIN_MICROSD_POWER, HIGH); -} - -void imuPowerOn() -{ - pinMode(PIN_IMU_POWER, OUTPUT); - digitalWrite(PIN_IMU_POWER, HIGH); -} -void imuPowerOff() -{ - pinMode(PIN_IMU_POWER, OUTPUT); - digitalWrite(PIN_IMU_POWER, LOW); -} diff --git a/Firmware/Test Sketches/OLA_IMU_Basics/OLA_IMU_Basics.ino b/Firmware/Test Sketches/OLA_IMU_Basics/OLA_IMU_Basics.ino index 121b1af..f5c8f35 100644 --- a/Firmware/Test Sketches/OLA_IMU_Basics/OLA_IMU_Basics.ino +++ b/Firmware/Test Sketches/OLA_IMU_Basics/OLA_IMU_Basics.ino @@ -21,6 +21,9 @@ const byte PIN_IMU_POWER = 27; // The Red SparkFun version of the OLA (V10) uses //const byte PIN_IMU_POWER = 22; // The Black SparkX version of the OLA (X04) uses pin 22 const byte PIN_IMU_INT = 37; const byte PIN_IMU_CHIP_SELECT = 44; +const byte PIN_SPI_SCK = 5; +const byte PIN_SPI_CIPO = 6; +const byte PIN_SPI_COPI = 7; #include "ICM_20948.h" // Click here to get the library: http://librarymanager/All#SparkFun_ICM_20948_IMU @@ -47,17 +50,27 @@ const byte PIN_IMU_CHIP_SELECT = 44; void setup() { #ifdef USE_SPI - SPI_PORT.begin(); -#else - WIRE_PORT.begin(); - WIRE_PORT.setClock(400000); -#endif + SPI_PORT.begin(); - enableCIPOpullUp(); // Enable CIPO pull-up on the OLA - pinMode(PIN_IMU_CHIP_SELECT, OUTPUT); digitalWrite(PIN_IMU_CHIP_SELECT, HIGH); //Be sure IMU is deselected + + enableCIPOpullUp(); // Enable CIPO pull-up on the OLA + + //There is a quirk in v2.1 of the Apollo3 mbed core which means that the first SPI transaction will + //disable the pull-up on CIPO. We need to do a fake transaction and then re-enable the pull-up + //to work around this... +#if defined(ARDUINO_ARCH_MBED) + SPI.beginTransaction(SPISettings(1000000, MSBFIRST, SPI_MODE0)); // Do a fake transaction + SPI.endTransaction(); + enableCIPOpullUp(); // Re-enable the CIPO pull-up +#endif +#else + WIRE_PORT.begin(); + WIRE_PORT.setClock(400000); +#endif + //Reset ICM by power cycling it imuPowerOff(); @@ -214,16 +227,27 @@ void imuPowerOff() digitalWrite(PIN_IMU_POWER, LOW); } +#if defined(ARDUINO_ARCH_MBED) // updated for v2.1.0 of the Apollo3 core +bool enableCIPOpullUp() +{ + //Add 1K5 pull-up on CIPO + am_hal_gpio_pincfg_t cipoPinCfg = g_AM_BSP_GPIO_IOM0_MISO; + cipoPinCfg.ePullup = AM_HAL_GPIO_PIN_PULLUP_1_5K; + pin_config(PinName(PIN_SPI_CIPO), cipoPinCfg); + return (true); +} +#else bool enableCIPOpullUp() { //Add CIPO pull-up ap3_err_t retval = AP3_OK; am_hal_gpio_pincfg_t cipoPinCfg = AP3_GPIO_DEFAULT_PINCFG; cipoPinCfg.uFuncSel = AM_HAL_PIN_6_M0MISO; + cipoPinCfg.ePullup = AM_HAL_GPIO_PIN_PULLUP_1_5K; cipoPinCfg.eDriveStrength = AM_HAL_GPIO_PIN_DRIVESTRENGTH_12MA; cipoPinCfg.eGPOutcfg = AM_HAL_GPIO_PIN_OUTCFG_PUSHPULL; cipoPinCfg.uIOMnum = AP3_SPI_IOM; - cipoPinCfg.ePullup = AM_HAL_GPIO_PIN_PULLUP_1_5K; padMode(MISO, cipoPinCfg, &retval); return (retval == AP3_OK); } +#endif diff --git a/Firmware/Test Sketches/SD/BasicFileTest/BasicFileTest.ino b/Firmware/Test Sketches/SD/BasicFileTest/BasicFileTest.ino deleted file mode 100644 index b8fdcfe..0000000 --- a/Firmware/Test Sketches/SD/BasicFileTest/BasicFileTest.ino +++ /dev/null @@ -1,53 +0,0 @@ -/* - This example shows how to write to a file - - Be sure to select "SparkFun RedBoard Artemis ATP" to get the pin assignments correct -*/ - -//microSD Interface -//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- -#include -#include //We use SdFat-Beta from Bill Greiman for increased read/write speed - -const byte PIN_MICROSD_CHIP_SELECT = 10; -const byte PIN_MICROSD_POWER = 15; //x04 - -#define SD_CONFIG SdSpiConfig(PIN_MICROSD_CHIP_SELECT, SHARED_SPI, SD_SCK_MHZ(24)) //Max of 24MHz - -SdFat sd; -File sensorDataFile; //File that all sensor data is written to - -char sensorDataFileName[30] = ""; //We keep a record of this file name so that we can re-open it upon wakeup from sleep -//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- - -const byte PIN_QWIIC_POWER = 18; -const byte PIN_STAT_LED = 19; -const byte PIN_IMU_POWER = 22; - -void setup(void) { - Serial.begin(115200); - Serial.println(); - Serial.println("SD Write Test"); - - SPI.begin(); - - beginSD(); - - beginDataLogging(); - - Serial.println("Setup done"); -} - -void loop(void) -{ - String outputData = "Test string\n"; - - char temp[512]; - outputData.toCharArray(temp, 512); //Convert string to char array so sdfat can record it - sensorDataFile.write(temp, strlen(temp)); //Record the buffer to the card - sensorDataFile.sync(); - - Serial.println("File recorded"); - - while(1); -} diff --git a/Firmware/Test Sketches/SD/BasicFileTest/sd.ino b/Firmware/Test Sketches/SD/BasicFileTest/sd.ino deleted file mode 100644 index 2255b28..0000000 --- a/Firmware/Test Sketches/SD/BasicFileTest/sd.ino +++ /dev/null @@ -1,125 +0,0 @@ -//Returns next available log file name -//Checks the spots in EEPROM for the next available LOG# file name -//Updates EEPROM and then appends to the new log file. -char* findNextAvailableLog(int &newFileNumber, const char *fileLeader) -{ - File newFile; //This will contain the file for SD writing - - if (newFileNumber > 0) - newFileNumber--; //Check if last log file was empty - - //Search for next available log spot - static char newFileName[40]; - while (1) - { - sprintf(newFileName, "%s%05u.TXT", fileLeader, newFileNumber); //Splice the new file number into this file name - if (sd.exists(newFileName) == false) break; //File name not found so we will use it. - - //File exists so open and see if it is empty. If so, use it. - newFile = sd.open(newFileName, O_READ); - //newFile.open(newFileName, O_READ); //exFat - if (newFile.size() == 0) break; // File is empty so we will use it. - - newFile.close(); // Close this existing file we just opened. - - newFileNumber++; //Try the next number - } - newFile.close(); //Close this new file we just opened - - newFileNumber++; //Increment so the next power up uses the next file # - //recordSettings(); //Record new file number to EEPROM and to config file - - Serial.print(F("Created log file: ")); - Serial.println(newFileName); - Serial.flush(); - - return (newFileName); -} - -void beginDataLogging() -{ - int fileNumber = 10; - - //If we don't have a file yet, create one. Otherwise, re-open the last used file - if (strlen(sensorDataFileName) == 0) - strcpy(sensorDataFileName, findNextAvailableLog(fileNumber, "dataLog")); - - // O_CREAT - create the file if it does not exist - // O_APPEND - seek to the end of the file prior to each write - // O_WRITE - open for write - if (sensorDataFile.open(sensorDataFileName, O_CREAT | O_APPEND | O_WRITE) == false) - { - Serial.println("Failed to create sensor data file"); - return; - } - - Serial.println("Sensor data file open"); - Serial.flush(); -} - -void beginSD() -{ - pinMode(PIN_MICROSD_CHIP_SELECT, OUTPUT); - digitalWrite(PIN_MICROSD_CHIP_SELECT, HIGH); //Be sure SD is deselected - - microSDPowerOn(); - - //Max power up time is 250ms: https://www.kingston.com/datasheets/SDCIT-specsheet-64gb_en.pdf - //Max current is 200mA average across 1s, peak 300mA - delay(10); - - if (sd.begin(SD_CONFIG) == false) //Slightly Faster SdFat Beta (we don't have dedicated SPI) - { - delay(250); //Give SD more time to power up, then try again - if (sd.begin(SD_CONFIG) == false) //Slightly Faster SdFat Beta (we don't have dedicated SPI) - { - Serial.println("SD init failed. Do you have the correct board selected in Arduino? Is card present? Formatted?"); - digitalWrite(PIN_MICROSD_CHIP_SELECT, HIGH); //Be sure SD is deselected - return; - } - } - // } - - //Change to root directory. All new file creation will be in root. - if (sd.chdir() == false) - { - Serial.println("SD change directory failed"); - return; - } - - Serial.println("SD begin complete"); - Serial.flush(); -} - -void qwiicPowerOn() -{ - pinMode(PIN_QWIIC_POWER, OUTPUT); - digitalWrite(PIN_QWIIC_POWER, LOW); -} -void qwiicPowerOff() -{ - pinMode(PIN_QWIIC_POWER, OUTPUT); - digitalWrite(PIN_QWIIC_POWER, HIGH); -} - -void microSDPowerOn() -{ - pinMode(PIN_MICROSD_POWER, OUTPUT); - digitalWrite(PIN_MICROSD_POWER, LOW); -} -void microSDPowerOff() -{ - pinMode(PIN_MICROSD_POWER, OUTPUT); - digitalWrite(PIN_MICROSD_POWER, HIGH); -} - -void imuPowerOn() -{ - pinMode(PIN_IMU_POWER, OUTPUT); - digitalWrite(PIN_IMU_POWER, HIGH); -} -void imuPowerOff() -{ - pinMode(PIN_IMU_POWER, OUTPUT); - digitalWrite(PIN_IMU_POWER, LOW); -} diff --git a/Firmware/Test Sketches/Sensor Autodetect/AHT20_Testing/AHT20_Testing.ino b/Firmware/Test Sketches/Sensor Autodetect/AHT20_Testing/AHT20_Testing.ino deleted file mode 100644 index c406b59..0000000 --- a/Firmware/Test Sketches/Sensor Autodetect/AHT20_Testing/AHT20_Testing.ino +++ /dev/null @@ -1,49 +0,0 @@ -/* - -*/ -#include -TwoWire qwiic(1); - -#include //Click here to get the library: http://librarymanager/All#Qwiic_Humidity_AHT20 by SparkFun -AHT20 humiditySensor; - -void setup() -{ - Serial.begin(115200); - Serial.println("Qwiic Humidity AHT20 examples"); - - qwiic.begin(); //Join I2C bus - - //Check if the AHT20 will acknowledge - if (humiditySensor.begin(qwiic) == false) - { - Serial.println("AHT20 not detected. Please check wiring. Freezing."); - while (1); - } - Serial.println("AHT20 acknowledged."); -} - -void loop() -{ - //If a new measurement is available - if (humiditySensor.available() == true) - { - //Get the new temperature and humidity value - float temperature = humiditySensor.getTemperature(); - float humidity = humiditySensor.getHumidity(); - - //Print the results - Serial.print("Temperature: "); - Serial.print(temperature, 2); - Serial.print(" C\t"); - Serial.print("Humidity: "); - Serial.print(humidity, 2); - Serial.print("% RH"); - - Serial.println(); - } - - //The AHT20 can respond with a reading every ~50ms. However, increased read time can cause the IC to heat around 1.0C above ambient. - //The datasheet recommends reading every 2 seconds. - delay(2000); -} diff --git a/Firmware/Test Sketches/Sensor Autodetect/AutoDetectWithMux/extras.ino b/Firmware/Test Sketches/Sensor Autodetect/AutoDetectWithMux/extras.ino deleted file mode 100644 index e6e9b0d..0000000 --- a/Firmware/Test Sketches/Sensor Autodetect/AutoDetectWithMux/extras.ino +++ /dev/null @@ -1,119 +0,0 @@ -//Get a string/value from user, remove all non-numeric values -//Returns STATUS_GETNUMBER_TIMEOUT if input times out -//Returns STATUS_PRESSED_X if user presses 'x' -int64_t getNumber(int numberOfSeconds) -{ - delay(10); //Wait for any incoming chars to hit buffer - while (Serial.available() > 0) Serial.read(); //Clear buffer - - //Get input from user - char cleansed[20]; //Good for very large numbers: 123,456,789,012,345,678\0 - - long startTime = millis(); - int spot = 0; - while (spot < 20 - 1) //Leave room for terminating \0 - { - while (Serial.available() == 0) //Wait for user input - { - if ( (millis() - startTime) / 1000 >= numberOfSeconds) - { - if (spot == 0) - { - Serial.println("No user input recieved. Do you have line endings turned on?"); - return (STATUS_GETNUMBER_TIMEOUT); //Timeout. No user input. - } - else if (spot > 0) - { - break; //Timeout, but we have data - } - } - } - - //See if we timed out waiting for a line ending - if (spot > 0 && (millis() - startTime) / 1000 >= numberOfSeconds) - { - Serial.println("Do you have line endings turned on?"); - break; //Timeout, but we have data - } - - byte incoming = Serial.read(); - if (incoming == '\n' || incoming == '\r') - { - Serial.println(); - break; - } - - if (isDigit(incoming) == true) - { - Serial.write(incoming); //Echo user's typing - cleansed[spot++] = (char)incoming; - } - - if (incoming == 'x') - { - return (STATUS_PRESSED_X); - } - } - - cleansed[spot] = '\0'; - - uint64_t largeNumber = 0; - for(int x = 0 ; x < spot ; x++) - { - largeNumber *= 10; - largeNumber += (cleansed[x] - '0'); - } - - return (largeNumber); -} - -//Option not known -void printUnknown(uint8_t unknownChoice) -{ - Serial.print("Unknown choice: "); - Serial.write(unknownChoice); - Serial.println(); -} -void printUnknown(int unknownValue) -{ - Serial.print("Unknown value: "); - Serial.write(unknownValue); - Serial.println(); -} - - -//Get single byte from user -//Waits for and returns the character that the user provides -//Returns STATUS_GETNUMBER_TIMEOUT if input times out -//Returns 'x' if user presses 'x' -uint8_t getByteChoice(int numberOfSeconds) -{ - Serial.flush(); - delay(50); //Wait for any incoming chars to hit buffer - while (Serial.available() > 0) Serial.read(); //Clear buffer - - long startTime = millis(); - byte incoming; - while (1) - { - if (Serial.available() > 0) - { - incoming = Serial.read(); -// Serial.print("byte: 0x"); -// Serial.println(incoming, HEX); - if (incoming >= 'a' && incoming <= 'z') break; - if (incoming >= 'A' && incoming <= 'Z') break; - if (incoming >= '0' && incoming <= '9') break; - } - - if ( (millis() - startTime) / 1000 >= numberOfSeconds) - { - Serial.println("No user input recieved."); - return (STATUS_GETBYTE_TIMEOUT); //Timeout. No user input. - } - - delay(10); - } - - return (incoming); -} diff --git a/Firmware/Test Sketches/Sensor Autodetect/BME280_Testing/BME280_Testing.ino b/Firmware/Test Sketches/Sensor Autodetect/BME280_Testing/BME280_Testing.ino deleted file mode 100644 index ead60a9..0000000 --- a/Firmware/Test Sketches/Sensor Autodetect/BME280_Testing/BME280_Testing.ino +++ /dev/null @@ -1,66 +0,0 @@ -/* - Get basic environmental readings from the BME280 - By: Nathan Seidle - SparkFun Electronics - Date: March 9th, 2018 - License: This code is public domain but you buy me a beer if you use this and we meet someday (Beerware license). - - Feel like supporting our work? Buy a board from SparkFun! - https://www.sparkfun.com/products/14348 - Qwiic Combo Board - https://www.sparkfun.com/products/13676 - BME280 Breakout Board - - This example shows how to read humidity, pressure, and current temperature from the BME280 over I2C. - - Hardware connections: - BME280 -> Arduino - GND -> GND - 3.3 -> 3.3 - SDA -> A4 - SCL -> A5 -*/ - -#include - -#include "SparkFunBME280.h" -BME280 mySensor; - -TwoWire qwiic(1); //Will use pads 8/9 - -void setup() -{ - Serial.begin(115200); - Serial.println("Reading basic values from BME280"); - - const byte PIN_QWIIC_PWR = 18; - pinMode(PIN_QWIIC_PWR, OUTPUT); - digitalWrite(PIN_QWIIC_PWR, LOW); //qwiicPowerOn(); - delay(10); - qwiic.begin(); - - if (mySensor.beginI2C(qwiic) == false) //Begin communication over I2C - { - Serial.println("The sensor did not respond. Please check wiring."); - while(1); //Freeze - } -} - -void loop() -{ - Serial.print("Humidity: "); - Serial.print(mySensor.readFloatHumidity(), 0); - - Serial.print(" Pressure: "); - Serial.print(mySensor.readFloatPressure(), 0); - - Serial.print(" Alt: "); - //Serial.print(mySensor.readFloatAltitudeMeters(), 1); - Serial.print(mySensor.readFloatAltitudeFeet(), 1); - - Serial.print(" Temp: "); - //Serial.print(mySensor.readTempC(), 2); - Serial.print(mySensor.readTempF(), 2); - - Serial.println(); - - delay(50); -} diff --git a/Firmware/Test Sketches/Sensor Autodetect/CCS811_Testing/CCS811_Testing.ino b/Firmware/Test Sketches/Sensor Autodetect/CCS811_Testing/CCS811_Testing.ino deleted file mode 100644 index 6846c2a..0000000 --- a/Firmware/Test Sketches/Sensor Autodetect/CCS811_Testing/CCS811_Testing.ino +++ /dev/null @@ -1,93 +0,0 @@ -/****************************************************************************** - Read basic CO2 and TVOCs - - Marshall Taylor @ SparkFun Electronics - Nathan Seidle @ SparkFun Electronics - - April 4, 2017 - - https://github.com/sparkfun/CCS811_Air_Quality_Breakout - https://github.com/sparkfun/SparkFun_CCS811_Arduino_Library - - Read the TVOC and CO2 values from the SparkFun CSS811 breakout board - - A new sensor requires at 48-burn in. Once burned in a sensor requires - 20 minutes of run in before readings are considered good. - - Hardware Connections (Breakoutboard to Arduino): - 3.3V to 3.3V pin - GND to GND pin - SDA to A4 - SCL to A5 - -******************************************************************************/ -#include - -#include "SparkFunCCS811.h" //Click here to get the library: http://librarymanager/All#SparkFun_CCS811 - -#define CCS811_ADDR 0x5B //Default I2C Address -//#define CCS811_ADDR 0x5A //Alternate I2C Address - -CCS811 mySensor(CCS811_ADDR); -TwoWire qwiic(1); //Will use pads 8/9 - -void setup() -{ - Serial.begin(115200); - Serial.println("CCS811 Basic Example"); - - const byte PIN_QWIIC_PWR = 18; - pinMode(PIN_QWIIC_PWR, OUTPUT); - digitalWrite(PIN_QWIIC_PWR, LOW); //qwiicPowerOn(); - delay(10); - qwiic.begin(); - - - //This begins the CCS811 sensor and prints error status of .beginWithStatus() - CCS811Core::CCS811_Status_e returnCode = mySensor.beginWithStatus(qwiic); - if (returnCode != CCS811Core::CCS811_Stat_SUCCESS) - { - Serial.print("CCS811 begin exited with: "); - Serial.println(mySensor.statusString(returnCode)); - while(1); - - } - Serial.println("CCS811 sensor online!"); - - - // if (returnCode == false) - // { - // delay(100); - // if (mySensor.begin(qwiic) == false) - // { - // Serial.print("CCS811 error. Please check wiring. Freezing..."); - // while (1) - // ; - // } - // } -} - -void loop() -{ - //Check to see if data is ready with .dataAvailable() - if (mySensor.dataAvailable()) - { - //If so, have the sensor read and calculate the results. - //Get them later - mySensor.readAlgorithmResults(); - - Serial.print("CO2["); - //Returns calculated CO2 reading - Serial.print(mySensor.getCO2()); - Serial.print("] tVOC["); - //Returns calculated TVOC reading - Serial.print(mySensor.getTVOC()); - Serial.print("] millis["); - //Display the time since program start - Serial.print(millis()); - Serial.print("]"); - Serial.println(); - } - - delay(10); //Don't spam the I2C bus -} diff --git a/Firmware/Test Sketches/Sensor Autodetect/DST_and_TimeStamp_Adjustment_Testing/DST_and_TimeStamp_Adjustment_Testing.ino b/Firmware/Test Sketches/Sensor Autodetect/DST_and_TimeStamp_Adjustment_Testing/DST_and_TimeStamp_Adjustment_Testing.ino deleted file mode 100644 index 1ec802c..0000000 --- a/Firmware/Test Sketches/Sensor Autodetect/DST_and_TimeStamp_Adjustment_Testing/DST_and_TimeStamp_Adjustment_Testing.ino +++ /dev/null @@ -1,311 +0,0 @@ - -void setup() { - Serial.begin(500000); - - Serial.println("GPS testing"); - - int year = 18; - int month = 12; - int day = 30; - int hour = 1; - int minute = 15; - int second = 5; - int localUTCOffset = -7; - - //Example: Date roll forward -// month = 1; -// day = 31; -// hour = 22; -// localUTCOffset = 6; - //Output should be 2/1/19 hour = 4 (no DST) - - //Example: Date roll back -// month = 1; -// day = 1; -// year = 15; -// hour = 2; -// localUTCOffset = -7; - //Output should be 12/31/14 hour = 19 (no DST) - - //Example: Date roll back with leap year interaction -// month = 3; -// day = 1; -// year = 8; //Leap year -// hour = 2; -// localUTCOffset = -7; - //Output should be 2/29/08 hour = 19 (no DST) - - //Example: UTC is 8AM, date is first day of DST, localOffset is -7, -// month = 3; -// day = 14; -// year = 10; -// hour = 8; -// localUTCOffset = -7; - //Output should be 3/14/10 hour = 1, we haven't sprung forward yet - - //Example: UTC is 9AM, date is first day of DST, localOffset is -7, -// month = 3; -// day = 14; -// year = 10; //Leap year -// hour = 9; -// localUTCOffset = -7; - //Output should be 3/14/10 hour = 3 (loose an hour) - - //Example: UTC is 7AM, date is last day of DST, localOffset is -7, -// month = 11; -// day = 3; -// year = 19; -// hour = 7; -// localUTCOffset = -7; - //Output should be 11/3/19 hour = 1 (not yet DST, no change) - - //Example: UTC is 8AM, date is last day of DST, localOffset is -7, -// month = 11; -// day = 3; -// year = 19; -// hour = 8; -// localUTCOffset = -7; - //Output should be 11/3/19 hour = 1 (repeat 1AM) - - //Example: UTC is 10AM, date is outside of DST, localOffset is -7, - // month = 12; - // day = 1; - // year = 19; - // hour = 10; - // localUTCOffset = -7; - //Output should be 12/1/19 hour = 3 (No DST add) - - //Example: UTC is 5AM, we are in DST, localOffset is -7, - // month = 7; - // day = 1; - // year = 19; - // hour = 5; - // localUTCOffset = -7; - //Output should be 6/30/19 hour = 23 (in DST) - - - adjustToLocalDateTime(year, month, day, hour, localUTCOffset); - - String myTime = ""; - - if (true) - { - char gpsDate[11]; //10/12/2019 - if (true) - sprintf(gpsDate, "%02d/%02d/20%02d", month, day, year); - else - sprintf(gpsDate, "%02d/%02d/20%02d", day, month, year); - myTime += String(gpsDate); - myTime += ","; - } - - char gpsTime[13]; //09:14:37.412 - sprintf(gpsTime, "%02d:%02d:%02d.%03d", hour, minute, second, millis() % 1000); //TODO get GPS hundredths() - myTime += String(gpsTime); - myTime += ","; - - Serial.println(myTime); -} - -void loop() { - -} - -//Given the date and hour, calculate local date/time -//Adjust the hour by local hour offset -//Adjust the hour by DST as necessary -//Adjust the date as necessary -//Leap year is taken into account but does not interact with DST (DST happens later in March) -void adjustToLocalDateTime(int &year, int &month, int &day, int &hour, int localUTCOffset) { - - //Adjust UTC with local offset - hour += localUTCOffset; - - //If the adjusted hour is outside 0 to 23, then adjust date as necessary - correctDate(year, month, day, hour); - - //Should we correct for daylight savings time? - if (true) - { - //Calculate DST adjustment based on date and local offset - hour += findUSDSTadjustment(year, month, day, hour); - - //DST may have pushed a date change so do one more time - correctDate(year, month, day, hour); - } - // if (settings.hour24Style == false) - // { - // if (hour > 12) hour -= 12; - // } -} - -//If the given hour is outside 0 to 23, then adjust date and hour as necessary -void correctDate(int &year, int &month, int &day, int &hour) -{ - //Adjust date forwards if the local hour offset causes it - if (hour > 23) - { - hour -= 24; - day++; - bool adjustMonth = false; - if (month == 1 && day == 32) - adjustMonth = true; - else if (month == 2) - { - if (year % 4 == 0 && day == 30) - adjustMonth = true; - else if (day == 29) - adjustMonth = true; - } - else if (month == 3 && day == 32) - adjustMonth = true; - else if (month == 4 && day == 31) - adjustMonth = true; - else if (month == 5 && day == 32) - adjustMonth = true; - else if (month == 6 && day == 31) - adjustMonth = true; - else if (month == 7 && day == 32) - adjustMonth = true; - else if (month == 8 && day == 32) - adjustMonth = true; - else if (month == 9 && day == 31) - adjustMonth = true; - else if (month == 10 && day == 32) - adjustMonth = true; - else if (month == 11 && day == 31) - adjustMonth = true; - else if (month == 11 && day == 32) - adjustMonth = true; - - if (adjustMonth == true) - { - month++; - day = 1; - if (month == 13) - { - month = 1; - year++; - } - } - } - - //Adjust date backwards if the local hour offset causes it - if (hour < 0) - { - hour += 24; - day--; - if (day == 0) - { - //Move back a month and reset day to the last day of the new month - month--; - switch (month) - { - case 0: //December - year--; - month = 12; - day = 31; - break; - case 1: //January - day = 31; - break; - case 2: //February - if (year % 4 == 0) day = 29; - else day = 28; - break; - case 3: //March - day = 31; - break; - case 4: //April - day = 30; - break; - case 5: //May - day = 31; - break; - case 6: //June - day = 30; - break; - case 7: //July - day = 31; - break; - case 8: //August - day = 31; - break; - case 9: //September - day = 30; - break; - case 10: //October - day = 31; - break; - case 11: //November - day = 30; - break; - } - } - } -} - -//Given a year/month/day/current UTC/local offset give me the amount to adjust the current hour -//Clocks adjust at 2AM so we need the local hour as well -int findUSDSTadjustment(int year, byte month, byte day, byte localHour) -{ - //Since 2007 DST starts on the second Sunday in March and ends the first Sunday of November - //Let's just assume it's going to be this way for awhile (silly US government!) - //Example from: http://stackoverflow.com/questions/5590429/calculating-daylight-savings-time-from-only-date - - //boolean dst = false; //Assume we're not in DST - if (month > 3 && month < 11) return (1); //DST is happening! - if (month < 3 || month > 11) return (0); //DST is not happening - - int firstSunday = getFirstSunday(year, month); - int secondSunday = firstSunday + 7; - - //In March, we are in DST if we are on or after the second sunday. - if (month == 3) - { - if (day > secondSunday) return (1); //We are in later march - if (day < secondSunday) return (0); //No DST - if (day == secondSunday) - { - if (localHour >= 2) return (1); //It's after 2AM, spring forward, add hour to clock - else return (0); //It's before 2AM, no DST - } - } - - //In November we must be before the first Sunday to be DST. - if (month == 11) - { - if (day < firstSunday) return (1); //Still in DST - if (day > firstSunday) return (0); //No DST - if (day == firstSunday) //Today is the last day of DST - { - //At 2AM the clock gets moved back to 1AM - //When we check the local hour we need to assume DST is still being applied (at least for the 12, 1AM, 2AM checks) - if ((localHour + 1) >= 2) return (0); //It's 2AM or later, fall back, remove hour from clock - else return (1); //It's before 2AM, continue adding DST - } - } - - return (0); //We should not get here -} - -//Given year/month, find day of first Sunday -byte getFirstSunday(int year, int month) -{ - int day = 1; - while (dayOfWeek(year, month, day) != 0) - day++; - return (day); -} - -//Given the current year/month/day -//Returns 0 (Sunday) through 6 (Saturday) for the day of the week -//From: http://en.wikipedia.org/wiki/Calculating_the_day_of_the_week -//This function assumes the month from the caller is 1-12 -char dayOfWeek(int year, int month, int day) -{ - //Devised by Tomohiko Sakamoto in 1993, it is accurate for any Gregorian date: - static int t[] = { 0, 3, 2, 5, 0, 3, 5, 1, 4, 6, 2, 4 }; - year -= month < 3; - return (year + year / 4 - year / 100 + year / 400 + t[month - 1] + day) % 7; -} diff --git a/Firmware/Test Sketches/Sensor Autodetect/I2CScanner/I2CScanner.ino b/Firmware/Test Sketches/Sensor Autodetect/I2CScanner/I2CScanner.ino deleted file mode 100644 index 2a7056a..0000000 --- a/Firmware/Test Sketches/Sensor Autodetect/I2CScanner/I2CScanner.ino +++ /dev/null @@ -1,54 +0,0 @@ -#include -TwoWire qwiic(1); //Will use pads 8/9 - -void setup() -{ - Serial.begin(115200); - Serial.println("Scanning..."); - - const byte PIN_QWIIC_PWR = 18; - pinMode(PIN_QWIIC_PWR, OUTPUT); - digitalWrite(PIN_QWIIC_PWR, HIGH); //qwiicPowerOn(); - - delay(1000); // Allow extra time for a u-blox module to start. It seems to need 1sec total. - - qwiic.begin(); - qwiic.setClock(100000); - - qwiic.setPullups(1); //Set pullups to 1k. If we don't have pullups, detectQwiicDevices() takes ~900ms to complete. We'll disable pullups if something is detected. - - byte error, address; - int nDevices = 0; - for (address = 1; address < 127; address++ ) - { - qwiic.beginTransmission(address); - error = qwiic.endTransmission(); - - if (error == 0) - { - Serial.print("I2C device found at address 0x"); - if (address < 16) - Serial.print("0"); - Serial.print(address, HEX); - Serial.println(); - - nDevices++; - } -// else if (error == 4) -// { -// Serial.print("Unknown error at address 0x"); -// if (address < 16) -// Serial.print("0"); -// Serial.println(address, HEX); -// } - } - if (nDevices == 0) - Serial.println("No I2C devices found\n"); - else - Serial.println("done\n"); -} - -void loop() -{ - -} diff --git a/Firmware/Test Sketches/Sensor Autodetect/LPS25HB_Testing/LPS25HB_Testing.ino b/Firmware/Test Sketches/Sensor Autodetect/LPS25HB_Testing/LPS25HB_Testing.ino deleted file mode 100644 index ab25009..0000000 --- a/Firmware/Test Sketches/Sensor Autodetect/LPS25HB_Testing/LPS25HB_Testing.ino +++ /dev/null @@ -1,81 +0,0 @@ -/* - -*/ - -#include -TwoWire qwiic(1); //Will use pads 8/9 - -#include // Click here to get the library: http://librarymanager/All#SparkFun_LPS25HB -LPS25HB pressureSensor; // Create an object of the LPS25HB class - -const byte PIN_QWIIC_POWER = 18; - -void setup() -{ - Serial.begin(115200); - Serial.println("LPS25HB Pressure Sensor Example 1 - Basic Readings"); - Serial.println(); - - qwiicPowerOn(); - delay(200); - - qwiic.begin(); - qwiic.setPullups(0); //Disable pull up resistors to avoid back feeding power to peripherals from SDA/SCL lines - qwiic.setClock(400000); -} - -int delayBeforeBegin = 5; //Min of 3 -int delayBeforeMeasurement = 40; //Min of 38 -void loop() -{ - if (Serial.available()) - { - byte incoming = Serial.read(); - if (incoming == 'a') delayBeforeMeasurement++; - else if (incoming == 'z') delayBeforeMeasurement--; - else if (incoming == '+') delayBeforeMeasurement += 10; - else if (incoming == '-') delayBeforeMeasurement -= 10; - - else if (incoming == 's') delayBeforeBegin++; - else if (incoming == 'x') delayBeforeBegin--; - else if (incoming == '1') delayBeforeBegin += 10; - else if (incoming == '2') delayBeforeBegin -= 10; - - Serial.printf("delayBeforeBegin: %d ", delayBeforeBegin); - Serial.printf("delayBeforeMeasurement: %d\n", delayBeforeMeasurement); - } - - qwiicPowerOff(); - qwiic.setPullups(0); //Disable pull up resistors to avoid back feeding power to peripherals from SDA/SCL lines - delay(200); //Make sure peripherals have powered down - - qwiicPowerOn(); - delay(delayBeforeBegin); - - pressureSensor.begin(qwiic); - - if (pressureSensor.isConnected() == false) - Serial.println("LPS25HB disconnected!"); - - delay(delayBeforeMeasurement); - float pressure = pressureSensor.getPressure_hPa(); - float temperature = pressureSensor.getTemperature_degC(); - - Serial.print("Pressure in hPa: "); - Serial.print(pressure); - Serial.print(", Temperature (degC): "); - Serial.println(temperature); - - //delay(40); // Wait - 40 ms corresponds to the maximum update rate of the sensor (25 Hz) -} - -void qwiicPowerOn() -{ - pinMode(PIN_QWIIC_POWER, OUTPUT); - digitalWrite(PIN_QWIIC_POWER, HIGH); -} -void qwiicPowerOff() -{ - pinMode(PIN_QWIIC_POWER, OUTPUT); - digitalWrite(PIN_QWIIC_POWER, LOW); -} diff --git a/Firmware/Test Sketches/Sensor Autodetect/MS5637_Testing/MS5637_Testing.ino b/Firmware/Test Sketches/Sensor Autodetect/MS5637_Testing/MS5637_Testing.ino deleted file mode 100644 index 7d140a8..0000000 --- a/Firmware/Test Sketches/Sensor Autodetect/MS5637_Testing/MS5637_Testing.ino +++ /dev/null @@ -1,66 +0,0 @@ -/* - Reading barometric pressure from the MS5637 - By: Nathan Seidle - SparkFun Electronics - Date: April 13th, 2018 - License: MIT. See license file for more information but you can - basically do whatever you want with this code. - - The original library and example code was written by TEConnectivity, - the company that made the sensor. Way to go TE! May other companies - learn from you. - - Feel like supporting open source hardware? - Buy a board from SparkFun! https://www.sparkfun.com/products/14688 - - This example prints the current pressure in hPa and temperature in C. - - Hardware Connections: - Attach the Qwiic Shield to your Arduino/Photon/ESP32 or other - Plug the sensor onto the shield - Serial.print it out at 9600 baud to serial monitor. -*/ - -#include - -#include "SparkFun_MS5637_Arduino_Library.h" - -MS5637 barometricSensor; -TwoWire qwiic(1); //Will use pads 8/9 - -void setup(void) { - Serial.begin(115200); - Serial.println("Qwiic Pressure Sensor MS5637 Example"); - - qwiic.begin(); - - const byte PIN_QWIIC_PWR = 18; - pinMode(PIN_QWIIC_PWR, OUTPUT); - digitalWrite(PIN_QWIIC_PWR, LOW); //qwiicPowerOn(); - delay(10); - qwiic.begin(); - - if (barometricSensor.begin(qwiic) == false) - { - Serial.println("MS5637 sensor did not respond. Please check wiring."); - while(1); - } -} - -void loop(void) { - - float temperature = barometricSensor.getTemperature(); - float pressure = barometricSensor.getPressure(); - - Serial.print("Temperature="); - Serial.print(temperature, 1); - Serial.print("(C)"); - - Serial.print(" Pressure="); - Serial.print(pressure, 3); - Serial.print("(hPa or mbar)"); - - Serial.println(); - - delay(10); -} diff --git a/Firmware/Test Sketches/Sensor Autodetect/MS8607_Testing/MS8607_Testing.ino b/Firmware/Test Sketches/Sensor Autodetect/MS8607_Testing/MS8607_Testing.ino deleted file mode 100644 index 1a8a563..0000000 --- a/Firmware/Test Sketches/Sensor Autodetect/MS8607_Testing/MS8607_Testing.ino +++ /dev/null @@ -1,137 +0,0 @@ -/* - Reading humidity from the MS8607 - By: PaulZC - Date: January 28th, 2020 - - Based extensively on: - Reading barometric pressure from the MS5637 - By: Nathan Seidle - SparkFun Electronics - License: MIT. See license file for more information but you can - basically do whatever you want with this code. - - The original library and example code was written by TEConnectivity, - the company that made the sensor. Way to go TE! May other companies - learn from you. - - Feel like supporting open source hardware? - Buy a board from SparkFun! - - This example reads and displays the humidity and temperature from the MS8607. - It also displays the temperature-compensated humidity and the dew point. -*/ - -#include - -#include -MS8607 barometricSensor; - -TwoWire qwiic(1); //Will use pads 8/9 - -void setup(void) { - Serial.begin(115200); - Serial.println("Qwiic PHT Sensor MS8607 Example - Humidity"); - - const byte PIN_QWIIC_PWR = 18; - pinMode(PIN_QWIIC_PWR, OUTPUT); - digitalWrite(PIN_QWIIC_PWR, LOW); //qwiicPowerOn(); - delay(10); - qwiic.begin(); - - if (barometricSensor.begin(qwiic) == false) - { - Serial.println("MS8607 sensor did not respond. Trying again..."); - if (barometricSensor.begin() == false) - { - Serial.println("MS8607 sensor did not respond. Please check wiring."); - while(1) - ; - } - } - - MS8607_pressure_resolution pressureResolution = MS8607_pressure_resolution_osr_8192; //17ms per reading, 0.016mbar resolution - - //The sensor has 6 resolution levels. The higher the resolution the longer each - //reading takes to complete. -// barometricSensor.set_pressure_resolution(MS8607_pressure_resolution_osr_256); //1ms per reading, 0.11mbar resolution -// barometricSensor.set_pressure_resolution(MS8607_pressure_resolution_osr_512); //2ms per reading, 0.062mbar resolution -// barometricSensor.set_pressure_resolution(MS8607_pressure_resolution_osr_1024); //3ms per reading, 0.039mbar resolution -// barometricSensor.set_pressure_resolution(MS8607_pressure_resolution_osr_2048); //5ms per reading, 0.028mbar resolution -// barometricSensor.set_pressure_resolution(MS8607_pressure_resolution_osr_4096); //9ms per reading, 0.021mbar resolution - barometricSensor.set_pressure_resolution(pressureResolution); //17ms per reading, 0.016mbar resolution - - // Example: set the humidity resolution - //int err = barometricSensor.set_humidity_resolution(MS8607_humidity_resolution_8b); // 8 bits - //int err = barometricSensor.set_humidity_resolution(MS8607_humidity_resolution_10b); // 10 bits - //int err = barometricSensor.set_humidity_resolution(MS8607_humidity_resolution_11b); // 11 bits - int err = barometricSensor.set_humidity_resolution(MS8607_humidity_resolution_12b); //12 bits - if (err != MS8607_status_ok) - { - Serial.print("Problem setting the MS8607 sensor humidity resolution. Error code = "); - Serial.println(err); - Serial.println("Freezing."); - while(1); - } - - // Turn the humidity sensor heater OFF - // The TE examples say that get_compensated_humidity and get_dew_point will only work if the heater is OFF - err = barometricSensor.disable_heater(); - if (err != MS8607_status_ok) - { - Serial.print("Problem disabling the MS8607 humidity sensor heater. Error code = "); - Serial.println(err); - Serial.println("Freezing."); - while(1); - } -} - -void loop(void) { - - float humidity = barometricSensor.getHumidity(); - float temperature = barometricSensor.getTemperature(); - float pressure = barometricSensor.getPressure(); - - Serial.print("Humidity="); - Serial.print(humidity, 1); - Serial.print("(%RH)"); - - Serial.print(" Pressure="); - Serial.print(pressure, 3); - Serial.print("(hPa or mbar)"); - - Serial.print(" Temperature="); - Serial.print(temperature, 1); - Serial.print("(C)"); - -// float compensated_RH; -// int err = barometricSensor.get_compensated_humidity(temperature, humidity, &compensated_RH); -// if (err != MS8607_status_ok) -// { -// Serial.println(); -// Serial.print("Problem getting the MS8607 compensated humidity. Error code = "); -// Serial.println(err); -// return; -// } - -// Serial.print(" Compensated humidity="); -// Serial.print(compensated_RH, 1); -// Serial.print("(%RH)"); -// -// float dew_point; -// err = barometricSensor.get_dew_point(temperature, humidity, &dew_point); -// if (err != MS8607_status_ok) -// { -// Serial.println(); -// Serial.print("Problem getting the MS8607 dew point. Error code = "); -// Serial.println(err); -// return; -// } -// -// Serial.print(" Dew point="); -// Serial.print(dew_point, 1); -// Serial.print("(C)"); - - Serial.println(); - - delay(10); -} diff --git a/Firmware/Test Sketches/Sensor Autodetect/Mux/Mux.ino b/Firmware/Test Sketches/Sensor Autodetect/Mux/Mux.ino deleted file mode 100644 index 864bfce..0000000 --- a/Firmware/Test Sketches/Sensor Autodetect/Mux/Mux.ino +++ /dev/null @@ -1,135 +0,0 @@ -/* - Use the Qwiic Mux to access multiple I2C devices on seperate busses. - By: Nathan Seidle @ SparkFun Electronics - Date: May 17th, 2020 - License: This code is public domain but you buy me a beer if you use this - and we meet someday (Beerware license). - - Some I2C devices respond to only one I2C address. This can be a problem - when you want to hook multiple of a device to the I2C bus. An I2C Mux - solves this issue by allowing you to change the 'channel' or port that - the master is talking to. - - This example shows how to hook up two VL53L1X laser distance sensors with the same address. - You can read the VL53L1X hookup guide and get the library from https://learn.sparkfun.com/tutorials/qwiic-distance-sensor-vl53l1x-hookup-guide - - The TCA9548A is a mux. This means when you enableMuxPort(2) then the SDA and SCL lines of the master (Arduino) - are connected to port 2. Whatever I2C traffic you do, such as distanceSensor.startRanging() will be communicated to whatever - sensor you have on port 2. This example creates an array of objects. This increases RAM but allows for - independent configuration of each sensor (one sensor may be configured for long range, the others for short, etc). - - Outputs two sets of distances in mm and ft. - - Hardware Connections: - Attach the Qwiic Mux Shield to your RedBoard or Uno. - Plug two Qwiic VL53L1X breakout boards into ports 0 and 1. - Serial.print it out at 115200 baud to serial monitor. - - SparkFun labored with love to create this code. Feel like supporting open - source? Buy a board from SparkFun! - https://www.sparkfun.com/products/14685 -*/ - -#include - -//TwoWire Wire1(1); //Will use pads 8/9 - -#include //Click here to get the library: http://librarymanager/All#SparkFun_I2C_Mux -QWIICMUX myMux; - -#define NUMBER_OF_SENSORS 2 - -#include "SparkFun_VL53L1X.h" //Click here to get the library: http://librarymanager/All#SparkFun_VL53L1X - -SFEVL53L1X **distanceSensor; //Create pointer to a set of pointers to the sensor class - -void setup() -{ - Serial.begin(115200); - Serial.println("Qwiic Mux Shield Read Example"); - - //Wire1.begin(); - Wire.begin(); - - //Create set of pointers to the class - distanceSensor = new SFEVL53L1X *[NUMBER_OF_SENSORS]; - - //Assign pointers to instances of the class - for (int x = 0 ; x < NUMBER_OF_SENSORS ; x++) - distanceSensor[x] = new SFEVL53L1X(Wire); - - //Setup mux to use Wire1. If you have multiple muxes, pass address as first argument - //if (myMux.begin(0x70, Wire1) == false) - if (myMux.begin() == false) - { - Serial.println("Mux not detected. Freezing..."); - while (1) - ; - } - Serial.println("Mux detected"); - - byte currentPortNumber = myMux.getPort(); - Serial.print("CurrentPort: "); - Serial.println(currentPortNumber); - - //Initialize all the sensors - bool initSuccess = true; - - for (byte x = 0; x < NUMBER_OF_SENSORS; x++) - { - myMux.setPort(x); - if (distanceSensor[x]->begin() != 0) //Begin returns 0 on a good init - { - Serial.print("Sensor "); - Serial.print(x); - Serial.println(" did not begin! Check wiring"); - initSuccess = false; - } - else - { - //Configure each sensor - distanceSensor[x]->setIntermeasurementPeriod(180); - distanceSensor[x]->setDistanceModeLong(); - distanceSensor[x]->startRanging(); //Write configuration bytes to initiate measurement - Serial.print("Sensor "); - Serial.print(x); - Serial.println(" configured"); - } - } - - if (initSuccess == false) - { - Serial.print("Freezing..."); - while (1); - } - - Serial.println("Mux Shield online"); -} - -void loop() -{ - int distance[NUMBER_OF_SENSORS]; - float distanceFeet; - - for (byte x = 0; x < NUMBER_OF_SENSORS; x++) - { - myMux.setPort(x); //Tell mux to connect to this port, and this port only - distance[x] = distanceSensor[x]->getDistance(); //Get the result of the measurement from the sensor - - Serial.print("\tDistance"); - Serial.print(x); - Serial.print("(mm): "); - Serial.print(distance[x]); - - distanceFeet = (distance[x] * 0.0393701) / 12.0; - - Serial.print("\tDistance"); - Serial.print(x); - Serial.print("(ft): "); - Serial.print(distanceFeet, 2); - } - - Serial.println(); - - delay(180); //Wait for next reading -} diff --git a/Firmware/Test Sketches/Sensor Autodetect/SCD30_Testing/SCD30_Testing.ino b/Firmware/Test Sketches/Sensor Autodetect/SCD30_Testing/SCD30_Testing.ino deleted file mode 100644 index c6734b2..0000000 --- a/Firmware/Test Sketches/Sensor Autodetect/SCD30_Testing/SCD30_Testing.ino +++ /dev/null @@ -1,74 +0,0 @@ -/* - Reading CO2, humidity and temperature from the SCD30 - By: Nathan Seidle - SparkFun Electronics - Date: May 22nd, 2018 - License: MIT. See license file for more information but you can - basically do whatever you want with this code. - - Feel like supporting open source hardware? - Buy a board from SparkFun! https://www.sparkfun.com/products/15112 - - This example prints the current CO2 level, relative humidity, and temperature in C. - - Hardware Connections: - Attach RedBoard to computer using a USB cable. - Connect SCD30 to RedBoard using Qwiic cable. - Open Serial Monitor at 115200 baud. -*/ - -#include - -#include "SparkFun_SCD30_Arduino_Library.h" //Click here to get the library: http://librarymanager/All#SparkFun_SCD30 -SCD30 airSensor; - -#include -TwoWire qwiic(1); //Will use pads 8/9 - -void setup() -{ - Serial.begin(115200); - Serial.println("SCD30 Example"); - - const byte PIN_QWIIC_PWR = 18; - pinMode(PIN_QWIIC_PWR, OUTPUT); - - //Turn off bus - digitalWrite(PIN_QWIIC_PWR, LOW); //qwiicPowerOff(); - delay(1000); - - //Turn on bus - digitalWrite(PIN_QWIIC_PWR, HIGH); //qwiicPowerOn(); - delay(100); - qwiic.begin(); - - if (airSensor.begin(qwiic) == false) - { - Serial.println("Air sensor not detected. Please check wiring. Freezing..."); - while (1) - ; - } - - //The SCD30 has data ready every two seconds -} - -void loop() -{ - if (airSensor.dataAvailable()) - { - Serial.print("co2(ppm):"); - Serial.print(airSensor.getCO2()); - - Serial.print(" temp(C):"); - Serial.print(airSensor.getTemperature(), 1); - - Serial.print(" humidity(%):"); - Serial.print(airSensor.getHumidity(), 1); - - Serial.println(); - } - else - Serial.println("Waiting for new data"); - - delay(500); -} diff --git a/Firmware/Test Sketches/Sensor Autodetect/SGP30_Testing/SGP30_Testing.ino b/Firmware/Test Sketches/Sensor Autodetect/SGP30_Testing/SGP30_Testing.ino deleted file mode 100644 index eab8da5..0000000 --- a/Firmware/Test Sketches/Sensor Autodetect/SGP30_Testing/SGP30_Testing.ino +++ /dev/null @@ -1,115 +0,0 @@ -/* - Log CO2 and tVOC - Log H2 and ethanol as well - - I2C fails when pullups are disabled? Might be a bad board. - - This board really can't be power cycled. It need to stay on for ~15s before readings are available - - But the sensor can be queried constantly for new data (if fully powered). - - The SGP30 seems to not like to be on the bus by itself using the main OLA firmware. -*/ - -#include "SparkFun_SGP30_Arduino_Library.h" // Click here to get the library: http://librarymanager/All#SparkFun_SGP30 -#include - -SGP30 mySensor; //create an object of the SGP30 class -TwoWire qwiic(1); //Will use pads 8/9 - -const byte PIN_QWIIC_POWER = 18; - -void setup() { - Serial.begin(115200); - - qwiicPowerOn(); - delay(200); - - qwiic.begin(); - //qwiic.setPullups(0); //Disable pull up resistors to avoid back feeding power to peripherals from SDA/SCL lines - qwiic.setClock(400000); - - //Initialize sensor - if (mySensor.begin(qwiic) == false) { - Serial.println("No SGP30 Detected. Check connections."); - while (1); - } - - //Initializes sensor for air quality readings - //measureAirQuality should be called in one second increments after a call to initAirQuality - mySensor.initAirQuality(); -} - -int count = 0 ; - -int delayBeforeBegin = 50; //Min of -int delayBeforeMeasurement = 100; //Min of - -void loop() -{ - if (Serial.available()) - { - byte incoming = Serial.read(); - if (incoming == 'a') delayBeforeMeasurement++; - else if (incoming == 'z') delayBeforeMeasurement--; - else if (incoming == '+') delayBeforeMeasurement += 10; - else if (incoming == '-') delayBeforeMeasurement -= 10; - - else if (incoming == 's') delayBeforeBegin++; - else if (incoming == 'x') delayBeforeBegin--; - else if (incoming == '1') delayBeforeBegin += 10; - else if (incoming == '2') delayBeforeBegin -= 10; - - Serial.printf("delayBeforeBegin: %d ", delayBeforeBegin); - Serial.printf("delayBeforeMeasurement: %d\n", delayBeforeMeasurement); - } - - //qwiicPowerOff(); - //qwiic.setPullups(0); //Disable pull up resistors to avoid back feeding power to peripherals from SDA/SCL lines - //delay(200); //Make sure peripherals have powered down - - //qwiicPowerOn(); - //qwiic.setPullups(1); - //delay(delayBeforeBegin); - - //Initialize sensor - // if (mySensor.begin(qwiic) == false) { - // Serial.println("No SGP30 Detected. Check connections."); - // while (1); - // } - // - // //Initializes sensor for air quality readings - // //measureAirQuality should be called in one second increments after a call to initAirQuality - // mySensor.initAirQuality(); - - //First fifteen readings will be - //CO2: 400 ppm TVOC: 0 ppb - - //measure CO2 and TVOC levels - mySensor.measureAirQuality(); - mySensor.measureRawSignals(); - - Serial.print(count++); - Serial.print(" CO2: "); - Serial.print(mySensor.CO2); - Serial.print(" ppm\tTVOC: "); - Serial.print(mySensor.TVOC); - Serial.print(" ppb"); - - - Serial.print("\tRaw H2: "); - Serial.print(mySensor.H2); - Serial.print(" \tRaw Ethanol: "); - Serial.println(mySensor.ethanol); -} - -void qwiicPowerOn() -{ - pinMode(PIN_QWIIC_POWER, OUTPUT); - digitalWrite(PIN_QWIIC_POWER, HIGH); -} -void qwiicPowerOff() -{ - pinMode(PIN_QWIIC_POWER, OUTPUT); - digitalWrite(PIN_QWIIC_POWER, LOW); -} diff --git a/Firmware/Test Sketches/Sensor Autodetect/SHTC3_Testing/SHTC3_Testing.ino b/Firmware/Test Sketches/Sensor Autodetect/SHTC3_Testing/SHTC3_Testing.ino deleted file mode 100644 index 2256308..0000000 --- a/Firmware/Test Sketches/Sensor Autodetect/SHTC3_Testing/SHTC3_Testing.ino +++ /dev/null @@ -1,63 +0,0 @@ -/* - Take humidity and temperature readings with the SHTC3 using I2C - By: Owen Lyke - SparkFun Electronics - Date: August 24 2018 - License: This code is public domain but you buy me a beer if you use this and we meet someday (Beerware license). - Example1_BasicReadings - To connect the sensor to an Arduino: - This library supports the sensor using the I2C protocol - On Qwiic enabled boards simply connnect the sensor with a Qwiic cable and it is set to go - On non-qwiic boards you will need to connect 4 wires between the sensor and the host board - (Arduino pin) = (Display pin) - SCL = SCL on display carrier - SDA = SDA - GND = GND - 3.3V = 3.3V -*/ - -#include "Wire.h" -TwoWire qwiic(1); //Will use pads 8/9 - -#include "SparkFun_SHTC3.h" // Click here to get the library: http://librarymanager/All#SparkFun_SHTC3 -SHTC3 mySHTC3; // Declare an instance of the SHTC3 class - -const byte PIN_QWIIC_POWER = 18; - -void setup() { - Serial.begin(115200); - - qwiic.begin(); - qwiicPowerOn(); - - Serial.println("SHTC3 Example"); - - if (mySHTC3.begin(qwiic) != 0) - { - Serial.println("The SHTC3 did not respond. Check wiring. Freezing..."); - while (1); - } -} - -void loop() { - - mySHTC3.update(); - - Serial.print(mySHTC3.toPercent()); // "toPercent" returns the percent humidity as a floating point number - Serial.print("% "); - Serial.print(mySHTC3.toDegC()); // "toDegF" and "toDegC" return the temperature as a flaoting point number in deg F and deg C respectively - Serial.println("C"); - - delay(10); -} - -void qwiicPowerOn() -{ - pinMode(PIN_QWIIC_POWER, OUTPUT); - digitalWrite(PIN_QWIIC_POWER, HIGH); -} -void qwiicPowerOff() -{ - pinMode(PIN_QWIIC_POWER, OUTPUT); - digitalWrite(PIN_QWIIC_POWER, LOW); -} diff --git a/Firmware/Test Sketches/Sensor Autodetect/VEML6075_Testing/VEML6075_Testing.ino b/Firmware/Test Sketches/Sensor Autodetect/VEML6075_Testing/VEML6075_Testing.ino deleted file mode 100644 index 0f2668d..0000000 --- a/Firmware/Test Sketches/Sensor Autodetect/VEML6075_Testing/VEML6075_Testing.ino +++ /dev/null @@ -1,49 +0,0 @@ -/* - Using the VEML6075 -- UVA, UVB, and UV Index monitoring - By: Jim Lindblom - SparkFun Electronics - Date: May 23, 2018 - License: This code is public domain but you buy me a beer if you use this and we meet someday (Beerware license). - Feel like supporting our work? Buy a board from SparkFun! - https://www.sparkfun.com/products/14748 - - This example demonstrates how to initialize the VEML6075, then poll it for UVA, UVB, and UV index readings. - - Quick-start: - - Use a SparkFun BlackBoard -or- attach the Qwiic Shield to your Arduino/Photon/ESP32 or other - - Upload example sketch - - Plug the Qwiic UV Sensor onto the BlackBoard/shield - - Open the serial monitor and set the baud rate to 9600 - - Sensor readings will stream every ~250ms. Output is: , , -*/ -// Include the SparkFun VEML6075 library. -// Click here to get the library: http://librarymanager/All#SparkFun_VEML6075 -#include - -VEML6075 uv; // Create a VEML6075 object -TwoWire qwiic(1); //Will use pads 8/9 - -void setup() { - Serial.begin(115200); - - const byte PIN_QWIIC_PWR = 18; - pinMode(PIN_QWIIC_PWR, OUTPUT); - digitalWrite(PIN_QWIIC_PWR, LOW); //qwiicPowerOn(); - delay(10); - qwiic.begin(); - - // the VEML6075's begin function can take no parameters - // It will return true on success or false on failure to communicate - if (uv.begin(qwiic) == false) { - Serial.println("Unable to communicate with VEML6075."); - while (1) ; - } - Serial.println("UVA, UVB, UV Index"); -} - -void loop() { - // Use the uva, uvb, and index functions to read calibrated UVA and UVB values and a - // calculated UV index value between 0-11. - Serial.println(String(uv.uva()) + ", " + String(uv.uvb()) + ", " + String(uv.index())); - delay(250); -} diff --git a/Firmware/Test Sketches/Sensor Autodetect/VL53L1X_Testing/VL53L1X_Testing.ino b/Firmware/Test Sketches/Sensor Autodetect/VL53L1X_Testing/VL53L1X_Testing.ino deleted file mode 100644 index 7520d20..0000000 --- a/Firmware/Test Sketches/Sensor Autodetect/VL53L1X_Testing/VL53L1X_Testing.ino +++ /dev/null @@ -1,87 +0,0 @@ -/* - Reading distance from the laser based VL53L1X - By: Nathan Seidle - SparkFun Electronics - Date: April 4th, 2018 - License: This code is public domain but you buy me a beer if you use this and we meet someday (Beerware license). - - SparkFun labored with love to create this code. Feel like supporting open source hardware? - Buy a board from SparkFun! https://www.sparkfun.com/products/14667 - - This example prints the distance to an object. - - Are you getting weird readings? Be sure the vacuum tape has been removed from the sensor. -*/ - -#include -#include "SparkFun_VL53L1X.h" - -//Optional interrupt and shutdown pins. -#define SHUTDOWN_PIN 2 -#define INTERRUPT_PIN 3 - -//TwoWire qwiic(1); //Will use pads 8/9 -//SFEVL53L1X distanceSensor(qwiic); -SFEVL53L1X distanceSensor(Wire); - -//Uncomment the following line to use the optional shutdown and interrupt pins. -//SFEVL53L1X distanceSensor(Wire, SHUTDOWN_PIN, INTERRUPT_PIN); - -void setup(void) -{ - Wire.begin(); - //qwiic.begin(); - - Serial.begin(115200); - Serial.println("VL53L1X Qwiic Test"); - - if (distanceSensor.begin() != 0) //Begin returns 0 on a good init - { - Serial.println("Sensor failed to begin. Please check wiring. Freezing..."); - while(1); - } - - //distanceSensor.setIntermeasurementPeriod(180); - Serial.println(distanceSensor.getIntermeasurementPeriod()); - - while(1); - distanceSensor.setDistanceModeLong(); - distanceSensor.startRanging(); //Write configuration bytes to initiate measurement -} - -void loop(void) -{ - long startTime = millis(); - long stopTime; - int oldDistance = distanceSensor.getDistance(); - int distance; - while (1) - { - // distanceSensor.startRanging(); //Write configuration bytes to initiate measurement - distance = distanceSensor.getDistance(); //Get the result of the measurement from the sensor - // distanceSensor.stopRanging(); - //if (distance != oldDistance) break; - break; - - } - stopTime = millis(); - - Serial.print("delta: "); - Serial.print(stopTime - startTime); - - Serial.print("\tDistance(mm): "); - Serial.print(distance); - - float distanceInches = distance * 0.0393701; - float distanceFeet = distanceInches / 12.0; - - Serial.print("\tDistance(ft): "); - Serial.print(distanceFeet, 2); - - Serial.print("\tperiod: "); - Serial.print(distanceSensor.getIntermeasurementPeriod()); - - Serial.println(); - - -} diff --git a/Firmware/Test Sketches/Sensor Autodetect/AutoDetectWithMux/AutoDetectWithMux.ino b/Firmware/Test Sketches/Sensor_Autodetect/AutoDetectWithMux/AutoDetectWithMux.ino similarity index 67% rename from Firmware/Test Sketches/Sensor Autodetect/AutoDetectWithMux/AutoDetectWithMux.ino rename to Firmware/Test Sketches/Sensor_Autodetect/AutoDetectWithMux/AutoDetectWithMux.ino index ef3b19e..cccd6d1 100644 --- a/Firmware/Test Sketches/Sensor Autodetect/AutoDetectWithMux/AutoDetectWithMux.ino +++ b/Firmware/Test Sketches/Sensor_Autodetect/AutoDetectWithMux/AutoDetectWithMux.ino @@ -5,7 +5,7 @@ -Setting file record/lookup -Configuration menu - For this sketch, only CCS811, BME280, VL53L1X and Mux's are auto identified. + For this sketch, only ICM20948, CCS811, BME280, VL53L1X and Mux's are auto identified. Autodetect theory of operation: @@ -43,39 +43,71 @@ #include "settings.h" #include -TwoWire qwiic(1); //Will use pads 8/9 +const byte PIN_QWIIC_SCL = 8; +const byte PIN_QWIIC_SDA = 9; +TwoWire qwiic(PIN_QWIIC_SDA,PIN_QWIIC_SCL); //Will use pads 8/9 + +//Define the pin functions +//Depends on hardware version. This can be found as a marking on the PCB. +//x04 was the SparkX 'black' version. +//v10 was the first red version. +#define HARDWARE_VERSION_MAJOR 1 +#define HARDWARE_VERSION_MINOR 0 + +#if(HARDWARE_VERSION_MAJOR == 0 && HARDWARE_VERSION_MINOR == 4) +const byte PIN_MICROSD_CHIP_SELECT = 10; +const byte PIN_IMU_POWER = 22; +#elif(HARDWARE_VERSION_MAJOR == 1 && HARDWARE_VERSION_MINOR == 0) +const byte PIN_MICROSD_CHIP_SELECT = 23; +const byte PIN_IMU_POWER = 27; +const byte PIN_PWR_LED = 29; +const byte PIN_VREG_ENABLE = 25; +const byte PIN_VIN_MONITOR = 34; // VIN/3 (1M/2M - will require a correction factor) +#endif +const byte PIN_POWER_LOSS = 3; +const byte PIN_MICROSD_POWER = 15; +const byte PIN_QWIIC_POWER = 18; +const byte PIN_STAT_LED = 19; +const byte PIN_IMU_INT = 37; +const byte PIN_IMU_CHIP_SELECT = 44; +const byte PIN_STOP_LOGGING = 32; +const byte BREAKOUT_PIN_32 = 32; +const byte BREAKOUT_PIN_TX = 12; +const byte BREAKOUT_PIN_RX = 13; +const byte BREAKOUT_PIN_11 = 11; + +#include "ICM_20948.h" // Click here to get the library: http://librarymanager/All#SparkFun_ICM_20948_IMU #include "SparkFun_I2C_Mux_Arduino_Library.h" //Click here to get the library: http://librarymanager/All#SparkFun_I2C_Mux #include "SparkFunCCS811.h" //Click here to get the library: http://librarymanager/All#SparkFun_CCS811 #include "SparkFun_VL53L1X.h" //Click here to get the library: http://librarymanager/All#SparkFun_VL53L1X #include "SparkFunBME280.h" //Click here to get the library: http://librarymanager/All#SparkFun_BME280 -const byte PIN_QWIIC_POWER = 18; - //microSD Interface //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- #include -#include //We use SdFat-Beta from Bill Greiman for increased read/write speed: https://github.com/greiman/SdFat-beta - -const byte PIN_MICROSD_CHIP_SELECT = 10; -const byte PIN_MICROSD_POWER = 15; //x04 - -#define SD_CONFIG SdSpiConfig(PIN_MICROSD_CHIP_SELECT, SHARED_SPI, SD_SCK_MHZ(24)) //Max of 24MHz -#define SD_CONFIG_MAX_SPEED SdSpiConfig(PIN_MICROSD_CHIP_SELECT, DEDICATED_SPI, SD_SCK_MHZ(24)) //Max of 24MHz - -//#define USE_EXFAT 1 - -#ifdef USE_EXFAT -//ExFat +#include //SdFat v2.0.7 by Bill Greiman. Click here to get the library: http://librarymanager/All#SdFat_exFAT + +#define SD_FAT_TYPE 3 // SD_FAT_TYPE = 0 for SdFat/File, 1 for FAT16/FAT32, 2 for exFAT, 3 for FAT16/FAT32 and exFAT. +#define SD_CONFIG SdSpiConfig(PIN_MICROSD_CHIP_SELECT, SHARED_SPI, SD_SCK_MHZ(24)) // 24MHz + +#if SD_FAT_TYPE == 1 +SdFat32 sd; +File32 sensorDataFile; //File that all sensor data is written to +File32 serialDataFile; //File that all incoming serial data is written to +#elif SD_FAT_TYPE == 2 +SdExFat sd; +ExFile sensorDataFile; //File that all sensor data is written to +ExFile serialDataFile; //File that all incoming serial data is written to +#elif SD_FAT_TYPE == 3 SdFs sd; FsFile sensorDataFile; //File that all sensor data is written to FsFile serialDataFile; //File that all incoming serial data is written to -#else -//Fat16/32 +#else // SD_FAT_TYPE == 0 SdFat sd; File sensorDataFile; //File that all sensor data is written to File serialDataFile; //File that all incoming serial data is written to -#endif +#endif // SD_FAT_TYPE char sensorDataFileName[30] = ""; //We keep a record of this file name so that we can re-open it upon wakeup from sleep char serialDataFileName[30] = ""; //We keep a record of this file name so that we can re-open it upon wakeup from sleep @@ -102,7 +134,7 @@ void setup() detectQwiicDevices(); - loadDeviceSettingsFromFile(); + //loadDeviceSettingsFromFile(); bubbleSortDevices(head); @@ -126,7 +158,7 @@ void loop() while (Serial.available()) Serial.read(); menuAttachedDevices(); - recordDeviceSettingsToFile(); + //recordDeviceSettingsToFile(); delay(10); while (Serial.available()) Serial.read(); @@ -221,6 +253,19 @@ void printHelperText() //No data to print for a mux } break; + case DEVICE_IMU_ICM20948: + { + struct_ICM20948 *nodeSetting = (struct_ICM20948 *)temp->configPtr; //Create a local pointer that points to same spot as node does + if (nodeSetting->logAccel) + strcat(helperText, "accelX_mg,accelY_mg,accelZ_mg,"); + if (nodeSetting->logGyro) + strcat(helperText, "gyroX_dps,gyroY_dps,gyroZ_dps,"); + if (nodeSetting->logMag) + strcat(helperText, "magX_uT,magY_uT,magZ_uT,"); + if (nodeSetting->logTemp) + strcat(helperText, "temp_degC,"); + } + break; case DEVICE_DISTANCE_VL53L1X: { struct_VL53L1X *nodeSetting = (struct_VL53L1X *)temp->configPtr; //Create a local pointer that points to same spot as node does @@ -268,12 +313,20 @@ void printHelperText() void qwiicPowerOn() { pinMode(PIN_QWIIC_POWER, OUTPUT); +#if(HARDWARE_VERSION_MAJOR == 0) digitalWrite(PIN_QWIIC_POWER, LOW); +#else + digitalWrite(PIN_QWIIC_POWER, HIGH); +#endif } void qwiicPowerOff() { pinMode(PIN_QWIIC_POWER, OUTPUT); +#if(HARDWARE_VERSION_MAJOR == 0) digitalWrite(PIN_QWIIC_POWER, HIGH); +#else + digitalWrite(PIN_QWIIC_POWER, LOW); +#endif } void microSDPowerOn() @@ -286,3 +339,39 @@ void microSDPowerOff() pinMode(PIN_MICROSD_POWER, OUTPUT); digitalWrite(PIN_MICROSD_POWER, HIGH); } + +void setQwiicPullups(uint32_t i2cBusPullUps) +{ + //Change SCL and SDA pull-ups manually using pin_config + am_hal_gpio_pincfg_t sclPinCfg = g_AM_BSP_GPIO_IOM1_SCL; + am_hal_gpio_pincfg_t sdaPinCfg = g_AM_BSP_GPIO_IOM1_SDA; + + if (i2cBusPullUps == 0) + { + sclPinCfg.ePullup = AM_HAL_GPIO_PIN_PULLUP_NONE; // No pull-ups + sdaPinCfg.ePullup = AM_HAL_GPIO_PIN_PULLUP_NONE; + } + else if (i2cBusPullUps == 1) + { + sclPinCfg.ePullup = AM_HAL_GPIO_PIN_PULLUP_1_5K; // Use 1K5 pull-ups + sdaPinCfg.ePullup = AM_HAL_GPIO_PIN_PULLUP_1_5K; + } + else if (i2cBusPullUps == 6) + { + sclPinCfg.ePullup = AM_HAL_GPIO_PIN_PULLUP_6K; // Use 6K pull-ups + sdaPinCfg.ePullup = AM_HAL_GPIO_PIN_PULLUP_6K; + } + else if (i2cBusPullUps == 12) + { + sclPinCfg.ePullup = AM_HAL_GPIO_PIN_PULLUP_12K; // Use 12K pull-ups + sdaPinCfg.ePullup = AM_HAL_GPIO_PIN_PULLUP_12K; + } + else + { + sclPinCfg.ePullup = AM_HAL_GPIO_PIN_PULLUP_24K; // Use 24K pull-ups + sdaPinCfg.ePullup = AM_HAL_GPIO_PIN_PULLUP_24K; + } + + pin_config(PinName(PIN_QWIIC_SCL), sclPinCfg); + pin_config(PinName(PIN_QWIIC_SDA), sdaPinCfg); +} diff --git a/Firmware/Test Sketches/Sensor Autodetect/AutoDetectWithMux/Sensors.ino b/Firmware/Test Sketches/Sensor_Autodetect/AutoDetectWithMux/Sensors.ino similarity index 53% rename from Firmware/Test Sketches/Sensor Autodetect/AutoDetectWithMux/Sensors.ino rename to Firmware/Test Sketches/Sensor_Autodetect/AutoDetectWithMux/Sensors.ino index 7de82e3..3f034fc 100644 --- a/Firmware/Test Sketches/Sensor Autodetect/AutoDetectWithMux/Sensors.ino +++ b/Firmware/Test Sketches/Sensor_Autodetect/AutoDetectWithMux/Sensors.ino @@ -4,6 +4,9 @@ void gatherDeviceValues() { char tempData[50]; + char tempData1[16]; + char tempData2[16]; + char tempData3[16]; outputData[0] = '\0'; //Clear string contents //Step through list, printing values as we go @@ -21,6 +24,52 @@ void gatherDeviceValues() //No data to print for a mux } break; + case DEVICE_IMU_ICM20948: + { + ICM_20948_I2C *nodeDevice = (ICM_20948_I2C *)temp->classPtr; + struct_ICM20948 *nodeSetting = (struct_ICM20948 *)temp->configPtr; //Create a local pointer that points to same spot as node does + + if (nodeSetting->log == true) + { + openConnection(temp->muxAddress, temp->portNumber); //Connect to this device through muxes as needed + + if (nodeDevice->dataReady()) + { + nodeDevice->getAGMT(); // The values are only updated when you call 'getAGMT' + if (nodeSetting->logAccel) + { + olaftoa(nodeDevice->accX(), tempData1, 2, sizeof(tempData1) / sizeof(char)); + olaftoa(nodeDevice->accY(), tempData2, 2, sizeof(tempData2) / sizeof(char)); + olaftoa(nodeDevice->accZ(), tempData3, 2, sizeof(tempData3) / sizeof(char)); + sprintf(tempData, "%s,%s,%s,", tempData1, tempData2, tempData3); + strcat(outputData, tempData); + } + if (nodeSetting->logGyro) + { + olaftoa(nodeDevice->gyrX(), tempData1, 2, sizeof(tempData1) / sizeof(char)); + olaftoa(nodeDevice->gyrY(), tempData2, 2, sizeof(tempData2) / sizeof(char)); + olaftoa(nodeDevice->gyrZ(), tempData3, 2, sizeof(tempData3) / sizeof(char)); + sprintf(tempData, "%s,%s,%s,", tempData1, tempData2, tempData3); + strcat(outputData, tempData); + } + if (nodeSetting->logMag) + { + olaftoa(nodeDevice->magX(), tempData1, 2, sizeof(tempData1) / sizeof(char)); + olaftoa(nodeDevice->magY(), tempData2, 2, sizeof(tempData2) / sizeof(char)); + olaftoa(nodeDevice->magZ(), tempData3, 2, sizeof(tempData3) / sizeof(char)); + sprintf(tempData, "%s,%s,%s,", tempData1, tempData2, tempData3); + strcat(outputData, tempData); + } + if (nodeSetting->logTemp) + { + olaftoa(nodeDevice->temp(), tempData1, 2, sizeof(tempData1) / sizeof(char)); + sprintf(tempData, "%s,", tempData1); + strcat(outputData, tempData); + } + } + } + } + break; case DEVICE_DISTANCE_VL53L1X: { SFEVL53L1X *nodeDevice = (SFEVL53L1X *)temp->classPtr; @@ -58,22 +107,26 @@ void gatherDeviceValues() if (nodeSetting->logPressure) { - sprintf(tempData, "%.02f,", nodeDevice->readFloatPressure()); + olaftoa(nodeDevice->readFloatPressure(), tempData1, 2, sizeof(tempData1) / sizeof(char)); + sprintf(tempData, "%s,", tempData1); strcat(outputData, tempData); } if (nodeSetting->logHumidity) { - sprintf(tempData, "%.02f,", nodeDevice->readFloatHumidity()); + olaftoa(nodeDevice->readFloatHumidity(), tempData1, 2, sizeof(tempData1) / sizeof(char)); + sprintf(tempData, "%s,", tempData1); strcat(outputData, tempData); } if (nodeSetting->logAltitude) { - sprintf(tempData, "%.02f,", nodeDevice->readFloatAltitudeMeters()); + olaftoa(nodeDevice->readFloatAltitudeMeters(), tempData1, 2, sizeof(tempData1) / sizeof(char)); + sprintf(tempData, "%s,", tempData1); strcat(outputData, tempData); } if (nodeSetting->logTemperature) { - sprintf(tempData, "%.02f,", nodeDevice->readTempC()); + olaftoa(nodeDevice->readTempC(), tempData1, 2, sizeof(tempData1) / sizeof(char)); + sprintf(tempData, "%s,", tempData1); strcat(outputData, tempData); } } diff --git a/Firmware/Test Sketches/Sensor Autodetect/AutoDetectWithMux/autoDetect.ino b/Firmware/Test Sketches/Sensor_Autodetect/AutoDetectWithMux/autoDetect.ino similarity index 92% rename from Firmware/Test Sketches/Sensor Autodetect/AutoDetectWithMux/autoDetect.ino rename to Firmware/Test Sketches/Sensor_Autodetect/AutoDetectWithMux/autoDetect.ino index c0fae35..7a6e6b7 100644 --- a/Firmware/Test Sketches/Sensor Autodetect/AutoDetectWithMux/autoDetect.ino +++ b/Firmware/Test Sketches/Sensor_Autodetect/AutoDetectWithMux/autoDetect.ino @@ -1,24 +1,3 @@ -/* - -*/ - -/* - getNodePointer(nodeNumber) - getNodePointer(deviceType, address, mux, port) - addDevice(address, deviceType) - - getConfigPointer(nodeNumber) - getConfigPointer(deviceType, address, mux, port) - - getConfigFunctionPtr(nodeNumber) - getDeviceName(deviceType) - - getNodeNumber(deviceType, address, mux, port) - - configureDevice(nodePointer) - configureDevice(nodeNumber) -*/ - //Given node number, get a pointer to the node node *getNodePointer(uint8_t nodeNumber) { @@ -139,6 +118,16 @@ bool addDevice(deviceType_e deviceType, uint8_t address, uint8_t muxAddress, uin temp->online = tempDevice->begin(qwiic); //Wire port } break; + case DEVICE_IMU_ICM20948: + { + temp->classPtr = new ICM_20948_I2C; + temp->configPtr = new struct_ICM20948; + + ICM_20948_I2C *tempDevice = (ICM_20948_I2C *)temp->classPtr; + tempDevice->begin(qwiic, address == 0x68 ? false : true); //Wire port, ad0val + temp->online = (tempDevice->status == ICM_20948_Stat_Ok); + } + break; default: Serial.printf("addDevice Device type not found: %d\n", deviceType); @@ -178,6 +167,9 @@ void configureDevice(node *temp) uint8_t deviceType = temp->deviceType; switch (deviceType) { + case DEVICE_IMU_ICM20948: + //Nothing to configure + break; case DEVICE_DISTANCE_VL53L1X: { SFEVL53L1X *tempDevice = (SFEVL53L1X *)temp->classPtr; @@ -230,6 +222,9 @@ FunctionPointer getConfigFunctionPtr(uint8_t nodeNumber) case DEVICE_VOC_CCS811: ptr = (FunctionPointer)menuConfigure_CCS811; break; + case DEVICE_IMU_ICM20948: + ptr = (FunctionPointer)menuConfigure_ICM20948; + break; default: Serial.println("getConfigFunctionPtr: Unknown device type"); Serial.flush(); @@ -294,6 +289,8 @@ bool openConnection(uint8_t muxAddress, uint8_t portNumber) #define ADR_VL53L1X 0x29 #define ADR_CCS811_2 0x5A #define ADR_CCS811_1 0x5B +#define ADR_ICM_20948_AD0 0x68 // Or 0x69 when AD0 is high +#define ADR_ICM_20948_AD1 0x69 // #define ADR_MUX_1 0x70 //to 0x77 #define ADR_MUX_2 0x71 #define ADR_BME280_2 0x76 @@ -319,6 +316,15 @@ deviceType_e testDevice(uint8_t i2cAddress, uint8_t muxAddress, uint8_t portNumb return (DEVICE_VOC_CCS811); break; } + case 0x68: + case 0x69: + { + ICM_20948_I2C imu_icm20948; + imu_icm20948.begin(qwiic, i2cAddress == 0x68 ? false : true); + if (imu_icm20948.status == ICM_20948_Stat_Ok) + return (DEVICE_IMU_ICM20948); + break; + } case 0x70: case 0x71: case 0x72: @@ -433,6 +439,9 @@ const char* getDeviceName(deviceType_e deviceNumber) case DEVICE_PRESSURE_MS8607: return "Pressure-MS8607"; break; + case DEVICE_IMU_ICM20948: + return "IMU-ICM20948"; + break; case DEVICE_UNKNOWN_DEVICE: return "Unknown device"; diff --git a/Firmware/Test Sketches/Sensor_Autodetect/AutoDetectWithMux/extras.ino b/Firmware/Test Sketches/Sensor_Autodetect/AutoDetectWithMux/extras.ino new file mode 100644 index 0000000..2a5195e --- /dev/null +++ b/Firmware/Test Sketches/Sensor_Autodetect/AutoDetectWithMux/extras.ino @@ -0,0 +1,403 @@ +//Get a string/value from user, remove all non-numeric values +//Returns STATUS_GETNUMBER_TIMEOUT if input times out +//Returns STATUS_PRESSED_X if user presses 'x' +int64_t getNumber(int numberOfSeconds) +{ + delay(10); //Wait for any incoming chars to hit buffer + while (Serial.available() > 0) Serial.read(); //Clear buffer + + //Get input from user + char cleansed[20]; //Good for very large numbers: 123,456,789,012,345,678\0 + + long startTime = millis(); + int spot = 0; + while (spot < 20 - 1) //Leave room for terminating \0 + { + while (Serial.available() == 0) //Wait for user input + { + if ( (millis() - startTime) / 1000 >= numberOfSeconds) + { + if (spot == 0) + { + Serial.println("No user input recieved. Do you have line endings turned on?"); + return (STATUS_GETNUMBER_TIMEOUT); //Timeout. No user input. + } + else if (spot > 0) + { + break; //Timeout, but we have data + } + } + } + + //See if we timed out waiting for a line ending + if (spot > 0 && (millis() - startTime) / 1000 >= numberOfSeconds) + { + Serial.println("Do you have line endings turned on?"); + break; //Timeout, but we have data + } + + byte incoming = Serial.read(); + if (incoming == '\n' || incoming == '\r') + { + Serial.println(); + break; + } + + if (isDigit(incoming) == true) + { + Serial.write(incoming); //Echo user's typing + cleansed[spot++] = (char)incoming; + } + + if (incoming == 'x') + { + return (STATUS_PRESSED_X); + } + } + + cleansed[spot] = '\0'; + + uint64_t largeNumber = 0; + for(int x = 0 ; x < spot ; x++) + { + largeNumber *= 10; + largeNumber += (cleansed[x] - '0'); + } + + return (largeNumber); +} + +//Option not known +void printUnknown(uint8_t unknownChoice) +{ + Serial.print("Unknown choice: "); + Serial.write(unknownChoice); + Serial.println(); +} +void printUnknown(int unknownValue) +{ + Serial.print("Unknown value: "); + Serial.write(unknownValue); + Serial.println(); +} + + +//Get single byte from user +//Waits for and returns the character that the user provides +//Returns STATUS_GETNUMBER_TIMEOUT if input times out +//Returns 'x' if user presses 'x' +uint8_t getByteChoice(int numberOfSeconds) +{ + Serial.flush(); + delay(50); //Wait for any incoming chars to hit buffer + while (Serial.available() > 0) Serial.read(); //Clear buffer + + long startTime = millis(); + byte incoming; + while (1) + { + if (Serial.available() > 0) + { + incoming = Serial.read(); +// Serial.print("byte: 0x"); +// Serial.println(incoming, HEX); + if (incoming >= 'a' && incoming <= 'z') break; + if (incoming >= 'A' && incoming <= 'Z') break; + if (incoming >= '0' && incoming <= '9') break; + } + + if ( (millis() - startTime) / 1000 >= numberOfSeconds) + { + Serial.println("No user input recieved."); + return (STATUS_GETBYTE_TIMEOUT); //Timeout. No user input. + } + + delay(10); + } + + return (incoming); +} + +//***************************************************************************** +// +// Divide an unsigned 32-bit value by 10. +// +// Note: Adapted from Ch10 of Hackers Delight (hackersdelight.org). +// +//***************************************************************************** +static uint64_t divu64_10(uint64_t ui64Val) +{ + uint64_t q64, r64; + uint32_t q32, r32, ui32Val; + + // + // If a 32-bit value, use the more optimal 32-bit routine. + // + if ( ui64Val >> 32 ) + { + q64 = (ui64Val>>1) + (ui64Val>>2); + q64 += (q64 >> 4); + q64 += (q64 >> 8); + q64 += (q64 >> 16); + q64 += (q64 >> 32); + q64 >>= 3; + r64 = ui64Val - q64*10; + return q64 + ((r64 + 6) >> 4); + } + else + { + ui32Val = (uint32_t)(ui64Val & 0xffffffff); + q32 = (ui32Val>>1) + (ui32Val>>2); + q32 += (q32 >> 4); + q32 += (q32 >> 8); + q32 += (q32 >> 16); + q32 >>= 3; + r32 = ui32Val - q32*10; + return (uint64_t)(q32 + ((r32 + 6) >> 4)); + } +} + +//***************************************************************************** +// +// Converts ui64Val to a string. +// Note: pcBuf[] must be sized for a minimum of 21 characters. +// +// Returns the number of decimal digits in the string. +// +// NOTE: If pcBuf is NULL, will compute a return ui64Val only (no chars +// written). +// +//***************************************************************************** +static int uint64_to_str(uint64_t ui64Val, char *pcBuf) +{ + char tbuf[25]; + int ix = 0, iNumDig = 0; + unsigned uMod; + uint64_t u64Tmp; + + do + { + // + // Divide by 10 + // + u64Tmp = divu64_10(ui64Val); + + // + // Get modulus + // + uMod = ui64Val - (u64Tmp * 10); + + tbuf[ix++] = uMod + '0'; + ui64Val = u64Tmp; + } while ( ui64Val ); + + // + // Save the total number of digits + // + iNumDig = ix; + + // + // Now, reverse the buffer when saving to the caller's buffer. + // + if ( pcBuf ) + { + while ( ix-- ) + { + *pcBuf++ = tbuf[ix]; + } + + // + // Terminate the caller's buffer + // + *pcBuf = 0x00; + } + + return iNumDig; +} + +//***************************************************************************** +// +// Float to ASCII text. A basic implementation for providing support for +// single-precision %f. +// +// param +// fValue = Float value to be converted. +// pcBuf = Buffer to place string AND input of buffer size. +// iPrecision = Desired number of decimal places. +// bufSize = The size (in bytes) of the buffer. +// The recommended size is at least 16 bytes. +// +// This function performs a basic translation of a floating point single +// precision value to a string. +// +// return Number of chars printed to the buffer. +// +//***************************************************************************** +#define OLA_FTOA_ERR_VAL_TOO_SMALL -1 +#define OLA_FTOA_ERR_VAL_TOO_LARGE -2 +#define OLA_FTOA_ERR_BUFSIZE -3 + +typedef union +{ + int32_t I32; + float F; +} ola_i32fl_t; + +static int olaftoa(float fValue, char *pcBuf, int iPrecision, int bufSize) +{ + ola_i32fl_t unFloatValue; + int iExp2, iBufSize; + int32_t i32Significand, i32IntPart, i32FracPart; + char *pcBufInitial, *pcBuftmp; + + iBufSize = bufSize; // *(uint32_t*)pcBuf; + if (iBufSize < 4) + { + return OLA_FTOA_ERR_BUFSIZE; + } + + if (fValue == 0.0f) + { + // "0.0" + *(uint32_t*)pcBuf = 0x00 << 24 | ('0' << 16) | ('.' << 8) | ('0' << 0); + return 3; + } + + pcBufInitial = pcBuf; + + unFloatValue.F = fValue; + + iExp2 = ((unFloatValue.I32 >> 23) & 0x000000FF) - 127; + i32Significand = (unFloatValue.I32 & 0x00FFFFFF) | 0x00800000; + i32FracPart = 0; + i32IntPart = 0; + + if (iExp2 >= 31) + { + return OLA_FTOA_ERR_VAL_TOO_LARGE; + } + else if (iExp2 < -23) + { + return OLA_FTOA_ERR_VAL_TOO_SMALL; + } + else if (iExp2 >= 23) + { + i32IntPart = i32Significand << (iExp2 - 23); + } + else if (iExp2 >= 0) + { + i32IntPart = i32Significand >> (23 - iExp2); + i32FracPart = (i32Significand << (iExp2 + 1)) & 0x00FFFFFF; + } + else // if (iExp2 < 0) + { + i32FracPart = (i32Significand & 0x00FFFFFF) >> -(iExp2 + 1); + } + + if (unFloatValue.I32 < 0) + { + *pcBuf++ = '-'; + } + + if (i32IntPart == 0) + { + *pcBuf++ = '0'; + } + else + { + if (i32IntPart > 0) + { + uint64_to_str(i32IntPart, pcBuf); + } + else + { + *pcBuf++ = '-'; + uint64_to_str(-i32IntPart, pcBuf); + } + while (*pcBuf) // Get to end of new string + { + pcBuf++; + } + } + + // + // Now, begin the fractional part + // + *pcBuf++ = '.'; + + if (i32FracPart == 0) + { + *pcBuf++ = '0'; + } + else + { + int jx, iMax; + + iMax = iBufSize - (pcBuf - pcBufInitial) - 1; + iMax = (iMax > iPrecision) ? iPrecision : iMax; + + for (jx = 0; jx < iMax; jx++) + { + i32FracPart *= 10; + *pcBuf++ = (i32FracPart >> 24) + '0'; + i32FracPart &= 0x00FFFFFF; + } + + // + // Per the printf spec, the number of digits printed to the right of the + // decimal point (i.e. iPrecision) should be rounded. + // Some examples: + // Value iPrecision Formatted value + // 1.36399 Unspecified (6) 1.363990 + // 1.36399 3 1.364 + // 1.36399 4 1.3640 + // 1.36399 5 1.36399 + // 1.363994 Unspecified (6) 1.363994 + // 1.363994 3 1.364 + // 1.363994 4 1.3640 + // 1.363994 5 1.36399 + // 1.363995 Unspecified (6) 1.363995 + // 1.363995 3 1.364 + // 1.363995 4 1.3640 + // 1.363995 5 1.36400 + // 1.996 Unspecified (6) 1.996000 + // 1.996 2 2.00 + // 1.996 3 1.996 + // 1.996 4 1.9960 + // + // To determine whether to round up, we'll look at what the next + // decimal value would have been. + // + if ( ((i32FracPart * 10) >> 24) >= 5 ) + { + // + // Yes, we need to round up. + // Go back through the string and make adjustments as necessary. + // + pcBuftmp = pcBuf - 1; + while ( pcBuftmp >= pcBufInitial ) + { + if ( *pcBuftmp == '.' ) + { + } + else if ( *pcBuftmp == '9' ) + { + *pcBuftmp = '0'; + } + else + { + *pcBuftmp += 1; + break; + } + pcBuftmp--; + } + } + } + + // + // Terminate the string and we're done + // + *pcBuf = 0x00; + + return (pcBuf - pcBufInitial); +} // ftoa() diff --git a/Firmware/Test Sketches/Sensor Autodetect/AutoDetectWithMux/menuAttachedDevices.ino b/Firmware/Test Sketches/Sensor_Autodetect/AutoDetectWithMux/menuAttachedDevices.ino similarity index 84% rename from Firmware/Test Sketches/Sensor Autodetect/AutoDetectWithMux/menuAttachedDevices.ino rename to Firmware/Test Sketches/Sensor_Autodetect/AutoDetectWithMux/menuAttachedDevices.ino index 3ee9d23..6e3fe9a 100644 --- a/Firmware/Test Sketches/Sensor Autodetect/AutoDetectWithMux/menuAttachedDevices.ino +++ b/Firmware/Test Sketches/Sensor_Autodetect/AutoDetectWithMux/menuAttachedDevices.ino @@ -11,14 +11,14 @@ bool detectQwiicDevices() qwiic.setClock(100000); //During detection, go slow - qwiic.setPullups(1); //Set pullups to 1k. If we don't have pullups, detectQwiicDevices() takes ~900ms to complete. We'll disable pullups if something is detected. + setQwiicPullups(1); //Set pullups to 1k. If we don't have pullups, detectQwiicDevices() takes ~900ms to complete. We'll disable pullups if something is detected. //24k causes a bunch of unknown devices to be falsely detected. - //qwiic.setPullups(24); //Set pullups to 24k. If we don't have pullups, detectQwiicDevices() takes ~900ms to complete. We'll disable pullups if something is detected. + //setQwiicPullups(24); //Set pullups to 24k. If we don't have pullups, detectQwiicDevices() takes ~900ms to complete. We'll disable pullups if something is detected. //Depending on what hardware is configured, the Qwiic bus may have only been turned on a few ms ago //Give sensors, specifically those with a low I2C address, time to turn on - delay(100); //SCD30 required >50ms to turn on + delay(1000); //GNSS requires at least 1s to turn on //First scan for Muxes. Valid addresses are 0x70 to 0x77. //If any are found, they will be begin()'d causing their ports to turn off @@ -71,7 +71,7 @@ bool detectQwiicDevices() node *muxNode = getNodePointer(muxNumber); QWIICMUX *myMux = (QWIICMUX *)muxNode->classPtr; - for (int portNumber = 0 ; portNumber < 7 ; portNumber++) + for (int portNumber = 0 ; portNumber < 8 ; portNumber++) { myMux->setPort(portNumber); @@ -104,7 +104,7 @@ bool detectQwiicDevices() printDetectedDevices(); } - if (somethingDetected) qwiic.setPullups(0); //We've detected something on the bus so disable pullups + if (somethingDetected) setQwiicPullups(0); //We've detected something on the bus so disable pullups Serial.println("Autodetect complete"); Serial.flush(); @@ -152,6 +152,9 @@ void menuAttachedDevices() case DEVICE_VOC_CCS811: Serial.printf("%s CCS811 tVOC and CO2 Sensor %s\n", strDeviceMenu, strAddress); break; + case DEVICE_IMU_ICM20948: + Serial.printf("%s ICM20948 IMU %s\n", strDeviceMenu, strAddress); + break; default: Serial.printf("Unknown device type %d in menuAttachedDevices\n", temp->deviceType); break; @@ -189,8 +192,6 @@ void menuAttachedDevices() } } - - void menuConfigure_Multiplexer(void *configPtr) { //struct_multiplexer *sensor = (struct_multiplexer*)configPtr; @@ -439,3 +440,68 @@ void menuConfigure_CCS811(void *configPtr) // sensor->online = false; //Mark as offline so it will be started with new settings } + +void menuConfigure_ICM20948(void *configPtr) +{ + struct_ICM20948 *sensor = (struct_ICM20948*)configPtr; + + while (1) + { + Serial.println(); + Serial.println("Menu: ICM20948 IMU"); + + Serial.print("1) Sensor Logging: "); + if (sensor->log == true) Serial.println("Enabled"); + else Serial.println("Disabled"); + + if (sensor->log == true) + { + Serial.print("2) Log Accel: "); + if (sensor->logAccel == true) Serial.println("Enabled"); + else Serial.println("Disabled"); + + Serial.print("3) Log Gyro: "); + if (sensor->logGyro == true) Serial.println("Enabled"); + else Serial.println("Disabled"); + + Serial.print("4) Log Mag: "); + if (sensor->logMag == true) Serial.println("Enabled"); + else Serial.println("Disabled"); + + Serial.print("5) Log Temp: "); + if (sensor->logTemp == true) Serial.println("Enabled"); + else Serial.println("Disabled"); + } + Serial.println("x) Exit"); + + byte incoming = getByteChoice(menuTimeout); //Timeout after x seconds + + if (incoming == '1') + sensor->log ^= 1; + else if (sensor->log == true) + { + if (incoming == '2') + sensor->logAccel ^= 1; + else if (incoming == '3') + sensor->logGyro ^= 1; + else if (incoming == '4') + sensor->logMag ^= 1; + else if (incoming == '5') + sensor->logTemp ^= 1; + else if (incoming == 'x') + break; + else if (incoming == STATUS_GETBYTE_TIMEOUT) + break; + else + printUnknown(incoming); + } + else if (incoming == 'x') + break; + else if (incoming == STATUS_GETBYTE_TIMEOUT) + break; + else + printUnknown(incoming); + } + + // sensor->online = false; //Mark as offline so it will be started with new settings +} diff --git a/Firmware/Test Sketches/Sensor Autodetect/AutoDetectWithMux/settings.h b/Firmware/Test Sketches/Sensor_Autodetect/AutoDetectWithMux/settings.h similarity index 92% rename from Firmware/Test Sketches/Sensor Autodetect/AutoDetectWithMux/settings.h rename to Firmware/Test Sketches/Sensor_Autodetect/AutoDetectWithMux/settings.h index b520e20..607f3f8 100644 --- a/Firmware/Test Sketches/Sensor Autodetect/AutoDetectWithMux/settings.h +++ b/Firmware/Test Sketches/Sensor_Autodetect/AutoDetectWithMux/settings.h @@ -14,6 +14,7 @@ typedef enum DEVICE_VOC_SGP30, DEVICE_CO2_SCD30, DEVICE_PRESSURE_MS8607, + DEVICE_IMU_ICM20948, DEVICE_TOTAL_DEVICES, //Marks the end, used to iterate loops DEVICE_UNKNOWN_DEVICE, @@ -78,4 +79,12 @@ struct struct_BME280 { bool logAltitude = true; bool logTemperature = true; }; + +struct struct_ICM20948 { + bool log = true; + bool logAccel = true; + bool logGyro = true; + bool logMag = true; + bool logTemp = true; +}; //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- diff --git a/Firmware/Test Sketches/Sensor Autodetect/AutoDetectWithMux/settings.ino b/Firmware/Test Sketches/Sensor_Autodetect/AutoDetectWithMux/settings.ino similarity index 100% rename from Firmware/Test Sketches/Sensor Autodetect/AutoDetectWithMux/settings.ino rename to Firmware/Test Sketches/Sensor_Autodetect/AutoDetectWithMux/settings.ino diff --git a/Firmware/Test Sketches/Sensor_Autodetect/I2CScanner/I2CScanner.ino b/Firmware/Test Sketches/Sensor_Autodetect/I2CScanner/I2CScanner.ino new file mode 100644 index 0000000..a55fa4d --- /dev/null +++ b/Firmware/Test Sketches/Sensor_Autodetect/I2CScanner/I2CScanner.ino @@ -0,0 +1,118 @@ +#include +const byte PIN_QWIIC_SCL = 8; +const byte PIN_QWIIC_SDA = 9; +TwoWire qwiic(PIN_QWIIC_SDA,PIN_QWIIC_SCL); //Will use pads 8/9 + +const byte PIN_QWIIC_POWER = 18; + +//Define the pin functions +//Depends on hardware version. This can be found as a marking on the PCB. +//x04 was the SparkX 'black' version. +//v10 was the first red version. +#define HARDWARE_VERSION_MAJOR 1 +#define HARDWARE_VERSION_MINOR 0 + +void setup() +{ + Serial.begin(115200); + Serial.println("Scanning..."); + + qwiicPowerOn(); + + delay(1000); // Allow extra time for a u-blox module to start. It seems to need 1sec total. + + qwiic.begin(); + qwiic.setClock(100000); + + setQwiicPullups(1); //Set pullups to 1k + + byte error, address; + int nDevices = 0; + for (address = 1; address < 127; address++ ) + { + qwiic.beginTransmission(address); + error = qwiic.endTransmission(); + + if (error == 0) + { + Serial.print("I2C device found at address 0x"); + if (address < 16) + Serial.print("0"); + Serial.print(address, HEX); + Serial.println(); + + nDevices++; + } +// else if (error == 4) +// { +// Serial.print("Unknown error at address 0x"); +// if (address < 16) +// Serial.print("0"); +// Serial.println(address, HEX); +// } + } + if (nDevices == 0) + Serial.println("No I2C devices found\n"); + else + Serial.println("done\n"); +} + +void loop() +{ + +} + +void qwiicPowerOn() +{ + pinMode(PIN_QWIIC_POWER, OUTPUT); +#if(HARDWARE_VERSION_MAJOR == 0) + digitalWrite(PIN_QWIIC_POWER, LOW); +#else + digitalWrite(PIN_QWIIC_POWER, HIGH); +#endif +} +void qwiicPowerOff() +{ + pinMode(PIN_QWIIC_POWER, OUTPUT); +#if(HARDWARE_VERSION_MAJOR == 0) + digitalWrite(PIN_QWIIC_POWER, HIGH); +#else + digitalWrite(PIN_QWIIC_POWER, LOW); +#endif +} + +void setQwiicPullups(uint32_t qwiicBusPullUps) +{ + //Change SCL and SDA pull-ups manually using pin_config + am_hal_gpio_pincfg_t sclPinCfg = g_AM_BSP_GPIO_IOM1_SCL; + am_hal_gpio_pincfg_t sdaPinCfg = g_AM_BSP_GPIO_IOM1_SDA; + + if (qwiicBusPullUps == 0) + { + sclPinCfg.ePullup = AM_HAL_GPIO_PIN_PULLUP_NONE; // No pull-ups + sdaPinCfg.ePullup = AM_HAL_GPIO_PIN_PULLUP_NONE; + } + else if (qwiicBusPullUps == 1) + { + sclPinCfg.ePullup = AM_HAL_GPIO_PIN_PULLUP_1_5K; // Use 1K5 pull-ups + sdaPinCfg.ePullup = AM_HAL_GPIO_PIN_PULLUP_1_5K; + } + else if (qwiicBusPullUps == 6) + { + sclPinCfg.ePullup = AM_HAL_GPIO_PIN_PULLUP_6K; // Use 6K pull-ups + sdaPinCfg.ePullup = AM_HAL_GPIO_PIN_PULLUP_6K; + } + else if (qwiicBusPullUps == 12) + { + sclPinCfg.ePullup = AM_HAL_GPIO_PIN_PULLUP_12K; // Use 12K pull-ups + sdaPinCfg.ePullup = AM_HAL_GPIO_PIN_PULLUP_12K; + } + else + { + sclPinCfg.ePullup = AM_HAL_GPIO_PIN_PULLUP_24K; // Use 24K pull-ups + sdaPinCfg.ePullup = AM_HAL_GPIO_PIN_PULLUP_24K; + } + + pin_config(PinName(PIN_QWIIC_SCL), sclPinCfg); + pin_config(PinName(PIN_QWIIC_SDA), sdaPinCfg); +} diff --git a/Firmware/Test Sketches/Sensor Autodetect/I2C_Detector/I2C_Detector.ino b/Firmware/Test Sketches/Sensor_Autodetect/I2C_Detector/I2C_Detector.ino similarity index 73% rename from Firmware/Test Sketches/Sensor Autodetect/I2C_Detector/I2C_Detector.ino rename to Firmware/Test Sketches/Sensor_Autodetect/I2C_Detector/I2C_Detector.ino index d1e2dc8..19e1191 100644 --- a/Firmware/Test Sketches/Sensor Autodetect/I2C_Detector/I2C_Detector.ino +++ b/Firmware/Test Sketches/Sensor_Autodetect/I2C_Detector/I2C_Detector.ino @@ -1,17 +1,31 @@ #include -TwoWire qwiic(1); //Will use pads 8/9 +const byte PIN_QWIIC_SCL = 8; +const byte PIN_QWIIC_SDA = 9; +TwoWire qwiic(PIN_QWIIC_SDA,PIN_QWIIC_SCL); //Will use pads 8/9 + +const byte PIN_QWIIC_POWER = 18; + +//Define the pin functions +//Depends on hardware version. This can be found as a marking on the PCB. +//x04 was the SparkX 'black' version. +//v10 was the first red version. +#define HARDWARE_VERSION_MAJOR 1 +#define HARDWARE_VERSION_MINOR 0 //Header files for all possible Qwiic sensors //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- +#include "ICM_20948.h" // Click here to get the library: http://librarymanager/All#SparkFun_ICM_20948_IMU +ICM_20948_I2C IMU_ICM20948; // Otherwise create an ICM_20948_I2C object + #include "SparkFun_Qwiic_Scale_NAU7802_Arduino_Library.h" //Click here to get the library: http://librarymanager/All#SparkFun_NAU7802 NAU7802 loadcellSensor_NAU7802; #include "SparkFun_VL53L1X.h" //Click here to get the library: http://librarymanager/All#SparkFun_VL53L1X SFEVL53L1X distanceSensor_VL53L1X(qwiic); -#include "SparkFun_Ublox_Arduino_Library.h" //http://librarymanager/All#SparkFun_Ublox_GPS -SFE_UBLOX_GPS gpsSensor_ublox; +#include "SparkFun_u-blox_GNSS_Arduino_Library.h" //http://librarymanager/All#SparkFun_u-blox_GNSS +SFE_UBLOX_GNSS gpsSensor_ublox; #include "SparkFun_VCNL4040_Arduino_Library.h" //Click here to get the library: http://librarymanager/All#SparkFun_VCNL4040 VCNL4040 proximitySensor_VCNL4040; @@ -35,9 +49,8 @@ BME280 phtSensor_BME280; VEML6075 uvSensor_VEML6075; #include "SparkFunCCS811.h" //Click here to get the library: http://librarymanager/All#SparkFun_CCS811 -#define CCS811_ADDR 0x5B //Default I2C Address -//#define CCS811_ADDR 0x5A //Alternate I2C Address -CCS811 vocSensor_CCS811(CCS811_ADDR); +#define ADR_CCS811_1 0x5B +CCS811 vocSensor_CCS811(ADR_CCS811_1); #include "SparkFun_SGP30_Arduino_Library.h" //Click here to get the library: http://librarymanager/All#SparkFun_SGP30 SGP30 vocSensor_SGP30; @@ -45,12 +58,13 @@ SGP30 vocSensor_SGP30; #include "SparkFun_SCD30_Arduino_Library.h" //Click here to get the library: http://librarymanager/All#SparkFun_SCD30 SCD30 co2Sensor_SCD30; -#include "MS8607_Library.h" //Click here to get the library: http://librarymanager/All#Qwiic_MS8607 +#include "SparkFun_PHT_MS8607_Arduino_Library.h" //Click here to get the library: http://librarymanager/All#SparkFun_PHT_MS8607 MS8607 pressureSensor_MS8607; //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- struct struct_QwiicSensors { + bool ICM_20948_I2C; bool LPS25HB; bool MCP9600; bool BH1749NUC; @@ -69,6 +83,7 @@ struct struct_QwiicSensors { }; struct_QwiicSensors qwiicAvailable = { + .ICM_20948_I2C = false, .LPS25HB = false, .MCP9600 = false, .BH1749NUC = false, @@ -86,8 +101,6 @@ struct_QwiicSensors qwiicAvailable = { .MS8607 = false, }; -const byte PIN_QWIIC_POWER = 18; - void setup() { Serial.begin(115200); @@ -98,37 +111,7 @@ void setup() qwiic.begin(); qwiic.setClock(100000); - qwiic.setPullups(1); //Set pullups to 1k. If we don't have pullups, detectQwiicDevices() takes ~900ms to complete. We'll disable pullups if something is detected. - - // byte error, address; - // int nDevices = 0; - // for (address = 1; address < 127; address++ ) - // { - // qwiic.beginTransmission(address); - // error = qwiic.endTransmission(); - // - // if (error == 0) - // { - // Serial.print("I2C device found at address 0x"); - // if (address < 16) - // Serial.print("0"); - // Serial.print(address, HEX); - // Serial.println(); - // - // nDevices++; - // } - // // else if (error == 4) - // // { - // // Serial.print("Unknown error at address 0x"); - // // if (address < 16) - // // Serial.print("0"); - // // Serial.println(address, HEX); - // // } - // } - // if (nDevices == 0) - // Serial.println("No I2C devices found\n"); - // else - // Serial.println("done\n"); + setQwiicPullups(1); //Set pullups to 1K5 } void loop() @@ -138,13 +121,13 @@ void loop() qwiicPowerOn(); //delay(1000); //SCD30 acks and responds //delay(100); //SCD30 acks but fails to start - delay(100); // + delay(1000); //u-blox GNSS needs at least 1s Serial.println("On!"); Serial.flush(); bool somethingDetected = false; - for (uint8_t address = 0x60 ; address < 127 ; address++) + for (uint8_t address = 0x10 ; address < 127 ; address++) { qwiic.beginTransmission(address); if (qwiic.endTransmission() == 0) @@ -170,12 +153,14 @@ void loop() #define ADR_TMP117 0x48 //Alternates: 0x49, 0x4A, and 0x4B #define ADR_SGP30 0x58 #define ADR_CCS811_2 0x5A -#define ADR_CCS811_1 0x5B +//#define ADR_CCS811_1 0x5B #define ADR_LPS25HB_2 0x5C #define ADR_LPS25HB_1 0x5D #define ADR_VCNL4040_OR_MCP9600 0x60 #define ADR_SCD30 0x61 #define ADR_MCP9600_1 0x66 +#define ADR_ICM_20948_AD0 0x68 // Or 0x69 when AD0 is high +#define ADR_ICM_20948_AD1 0x69 #define ADR_BME280_2 0x76 #define ADR_MS5637 0x76 //#define ADR_MS8607 0x76 //Pressure portion of the MS8607 sensor. We'll catch the 0x40 first @@ -187,6 +172,14 @@ bool testDevice(uint8_t i2cAddress) { switch (i2cAddress) { + case ADR_ICM_20948_AD0: + if (IMU_ICM20948.begin(qwiic, false) == true) //Wire port, ad0val + qwiicAvailable.ICM_20948_I2C = true; + break; + case ADR_ICM_20948_AD1: + if (IMU_ICM20948.begin(qwiic, true) == true) //Wire port, ad0val + qwiicAvailable.ICM_20948_I2C = true; + break; case ADR_LPS25HB_1: if (pressureSensor_LPS25HB.begin(qwiic, ADR_LPS25HB_1) == true) //Wire port, Address. if (pressureSensor_LPS25HB.isConnected() == true) @@ -280,10 +273,54 @@ bool testDevice(uint8_t i2cAddress) void qwiicPowerOn() { pinMode(PIN_QWIIC_POWER, OUTPUT); +#if(HARDWARE_VERSION_MAJOR == 0) digitalWrite(PIN_QWIIC_POWER, LOW); +#else + digitalWrite(PIN_QWIIC_POWER, HIGH); +#endif } void qwiicPowerOff() { pinMode(PIN_QWIIC_POWER, OUTPUT); +#if(HARDWARE_VERSION_MAJOR == 0) digitalWrite(PIN_QWIIC_POWER, HIGH); +#else + digitalWrite(PIN_QWIIC_POWER, LOW); +#endif +} + +void setQwiicPullups(uint32_t qwiicBusPullUps) +{ + //Change SCL and SDA pull-ups manually using pin_config + am_hal_gpio_pincfg_t sclPinCfg = g_AM_BSP_GPIO_IOM1_SCL; + am_hal_gpio_pincfg_t sdaPinCfg = g_AM_BSP_GPIO_IOM1_SDA; + + if (qwiicBusPullUps == 0) + { + sclPinCfg.ePullup = AM_HAL_GPIO_PIN_PULLUP_NONE; // No pull-ups + sdaPinCfg.ePullup = AM_HAL_GPIO_PIN_PULLUP_NONE; + } + else if (qwiicBusPullUps == 1) + { + sclPinCfg.ePullup = AM_HAL_GPIO_PIN_PULLUP_1_5K; // Use 1K5 pull-ups + sdaPinCfg.ePullup = AM_HAL_GPIO_PIN_PULLUP_1_5K; + } + else if (qwiicBusPullUps == 6) + { + sclPinCfg.ePullup = AM_HAL_GPIO_PIN_PULLUP_6K; // Use 6K pull-ups + sdaPinCfg.ePullup = AM_HAL_GPIO_PIN_PULLUP_6K; + } + else if (qwiicBusPullUps == 12) + { + sclPinCfg.ePullup = AM_HAL_GPIO_PIN_PULLUP_12K; // Use 12K pull-ups + sdaPinCfg.ePullup = AM_HAL_GPIO_PIN_PULLUP_12K; + } + else + { + sclPinCfg.ePullup = AM_HAL_GPIO_PIN_PULLUP_24K; // Use 24K pull-ups + sdaPinCfg.ePullup = AM_HAL_GPIO_PIN_PULLUP_24K; + } + + pin_config(PinName(PIN_QWIIC_SCL), sclPinCfg); + pin_config(PinName(PIN_QWIIC_SDA), sdaPinCfg); } diff --git a/Firmware/Test Sketches/Serial Logging/ConstantSerialBlastTest/ConstantSerialBlastTest.ino b/Firmware/Test Sketches/Serial Logging/ConstantSerialBlastTest/ConstantSerialBlastTest.ino deleted file mode 100644 index 52090ed..0000000 --- a/Firmware/Test Sketches/Serial Logging/ConstantSerialBlastTest/ConstantSerialBlastTest.ino +++ /dev/null @@ -1,150 +0,0 @@ -/* - Throws lots of serial at OpenLog Artemis -*/ - -int ledPin = 13; //Status LED connected to digital pin 13 - -int testAmt = 3; -//At 9600, testAmt of 4 takes about 1 minute, 10 takes about 3 minutes -//At 57600, testAmt of 10 takes about 1 minute, 40 takes about 5 minutes -//At 115200, testAmt of 30 takes about 1 minute - -unsigned long startTime = 0; - -void setup() -{ - pinMode(ledPin, OUTPUT); - - Serial.begin(115200); - Serial.println(); - Serial.println("Run OpenLog Test"); - - int rate = 115200 * 4; - Serial1.begin(rate); - - Serial.print("Current output baud rate: "); - Serial.println(rate); - - Serial.println("s)end test blob of text"); - Serial.println("1)Set baud to 115200"); - Serial.println("2)Set baud to 230400"); - Serial.println("3)Set baud to 460800"); - Serial.println("4)Set baud to 500000"); - Serial.println("5)Set baud to 691200"); - Serial.println("6)Set baud to 921600"); - Serial.println("a)Increase blob size"); - Serial.println("d)Decrease blob size"); - - //enableBurstMode(); //Go to 96MHz -} - -void loop() -{ - if (Serial.available()) - { - byte incoming = Serial.read(); - - if (incoming == 's') - { - Serial.println("Sending blob"); - sendBlob(); - } - else if (incoming == '1') - { - Serial.println("Serial set to: 115200"); - Serial1.begin(115200); - } - else if (incoming == '2') - { - Serial.println("Serial set to: 230400"); - Serial1.begin(230400); - } - else if (incoming == '3') - { - Serial.println("Serial set to: 460800"); - Serial1.begin(460800); - } - else if (incoming == '4') - { - Serial.println("Serial set to: 500000"); - Serial1.begin(500000); - } - else if (incoming == '5') - { - Serial.println("Serial set to: 691200"); - Serial1.begin(691200); - } - else if (incoming == '6') - { - Serial.println("Serial set to: 921600"); - Serial1.begin(921600); - } - else if (incoming == 'a') - { - testAmt++; - Serial.print("testAmt: "); - Serial.println(testAmt); - } - else if (incoming == 'z') - { - testAmt--; - Serial.print("testAmt: "); - Serial.println(testAmt); - } - else if (incoming == '\r' || incoming == '\n') - { - //Do nothing - } - else - { - Serial.println("Not recognized"); - } - } - - //Blink the Status LED because we're done! - digitalWrite(ledPin, HIGH); - delay(100); - digitalWrite(ledPin, LOW); - delay(100); -} - -void sendBlob() -{ - startTime = millis(); - - //Each test is 100 lines. 10 tests is 1000 lines (11,000 characters) - for (int numofTests = 0 ; numofTests < testAmt ; numofTests++) - { - //This loop will print 100 lines of 100 characters each - for (int k = 33; k < 43 ; k++) - { - //Print one line of 100 characters with marker in the front (markers go from '!' to '*') - Serial1.write(k); //Print the ASCII value directly: ! then " then #, etc - Serial1.print(":abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOP-!#\n"); - //delay(50); - - //Then print 9 lines of 100 characters with new line at the end of the line - for (int i = 1 ; i < 10 ; i++) - { - Serial1.print(i, DEC); - Serial1.print(":abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOP-!#\n"); - //delay(50); - } - - if (digitalRead(ledPin) == 0) //Turn the status LED on/off as we go - digitalWrite(ledPin, HIGH); - else - digitalWrite(ledPin, LOW); - } - } //End numofTests loop - - unsigned long totalCharacters = (long)testAmt * 100 * 100; - Serial.print("Characters pushed: "); - Serial.flush(); - Serial.println(totalCharacters); - Serial.print("Time taken (s): "); - Serial.flush(); - Serial.println((millis() - startTime) / 1000.0, 2); - Serial.println("Done!"); - Serial.flush(); -} diff --git a/Firmware/Test Sketches/Serial Logging/OpenLog_Bare_Serial/OpenLog_Bare_Serial.ino b/Firmware/Test Sketches/Serial Logging/OpenLog_Bare_Serial/OpenLog_Bare_Serial.ino deleted file mode 100644 index 2d46ea2..0000000 --- a/Firmware/Test Sketches/Serial Logging/OpenLog_Bare_Serial/OpenLog_Bare_Serial.ino +++ /dev/null @@ -1,239 +0,0 @@ -/* - October 11th, 2019 - - A stripped down sketch to test the reception of different speeds of serial - and recording them to an SD card. Use with another board (RedBoard Artemis) - and the ConstantSerialBlastTest.ino to send blocks of text. This sketch - will output the # of bytes received so you can quickly see if all 30,000 - bytes made it over or if bytes were dropped. - - 460800bps = 2.17 * 10^-6 or 2.17us per bit - 10 bits to the byte so 21.7us per byte - Write takes 54.13ms or 2494 bytes - - 16384 buffer size will allow for up to 355.532ms before bytes are dropped - 4096 buffer size will allow for up to 88.75ms before bytes are dropped - - ISR is currently 16us which supports 460800. We can burst mode to 8.5us. - - With the most recent pull of the Apollo3 core from Github (ISR reduced, buffers - increased to 4096), and a 512GB card, this sketch can correctly receive/store - non-stop serial at 500000bps. Burst mode is not needed. - - 691200bps is possible in burst mode - -*/ - -//microSD Interface -//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- -#include -#include - -const byte PIN_MICROSD_CHIP_SELECT = 10; -const byte PIN_MICROSD_POWER = 15; //x04 - -SdFs sd; //exFat Support -FsFile serialDataFile; //Record all incoming serial to this file - -//SdFat sd; -//SdFile serialDataFile; //Record all incoming serial to this file -//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- - -long overallStartTime; //Used to calc the actual update rate. - -const byte statLED = 19; //Should not be the SPI SCK pin 13 on most boards - -//Create UART instance for OpenLog style serial logging -//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- -Uart SerialLog(1, 13, 12); // Declares a Uart object called Serial1 using instance 1 of Apollo3 UART peripherals with RX on pin 13 and TX on pin 12 (note, you specify *pins* not Apollo3 pads. This uses the variant's pin map to determine the Apollo3 pad) -unsigned long lastSeriaLogSyncTime = 0; -const int MAX_IDLE_TIME_MSEC = 500; -bool newSerialData = false; -//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- - -int charsReceived = 0; -//char incomingBuffer[256 * 8]; //94ms -//char incomingBuffer[256 * 4]; //47ms -char incomingBuffer[256 * 2]; //26ms -//char incomingBuffer[256 * 1]; //25ms -int incomingBufferSpot = 0; - -void setup() { - Serial.begin(500000); - Serial.println("Artemis OpenLog"); - - pinMode(11, OUTPUT); - - int rate = 115200 * 4; - SerialLog.begin(rate); - Serial.print("Listening at baud rate: "); - Serial.println(rate); - - pinMode(statLED, OUTPUT); - digitalWrite(statLED, LOW); - - pinMode(PIN_MICROSD_CHIP_SELECT, OUTPUT); - digitalWrite(PIN_MICROSD_CHIP_SELECT, HIGH); //Be sure SD is deselected - - microSDPowerOn(); - delay(50); //Give SD time to power up - - if (sd.begin(PIN_MICROSD_CHIP_SELECT, SD_SCK_MHZ(24)) == false) - { - Serial.println("SD init failed"); - while (1); - } - if (sd.chdir() == false) - { - Serial.println("SD chdr failed"); - while (1); - } - - char fileName[9]; - sprintf(fileName, "serLog.txt"); - - if (sd.exists(fileName)) - { - Serial.println("serLog deleted"); - sd.remove(fileName); - } - - if (!serialDataFile.open(fileName, O_CREAT | O_APPEND | O_WRITE)) - { - Serial.println("Failed to open file"); - while (1); - } - Serial.println("serLog created"); - - overallStartTime = millis(); - //enableBurstMode(); //Go to 96MHz - - Serial.println("1)Set baud to 115200"); - Serial.println("2)Set baud to 230400"); - Serial.println("3)Set baud to 460800"); - Serial.println("4)Set baud to 500000"); - Serial.println("5)Set baud to 691200"); - Serial.println("6)Set baud to 921600"); - Serial.println("r)reset count"); - Serial.println("b)Enable Burst Mode"); - Serial.println("d)Disable Burst Mode"); -} - -void loop() -{ - //Check for incoming serial to record to serial log file - if (SerialLog.available()) - { - while (SerialLog.available()) - { - incomingBuffer[incomingBufferSpot++] = SerialLog.read(); - if (incomingBufferSpot == sizeof(incomingBuffer)) - { - serialDataFile.write(incomingBuffer, sizeof(incomingBuffer)); //Record the buffer to the card - incomingBufferSpot = 0; - } - charsReceived++; - } - lastSeriaLogSyncTime = millis(); - newSerialData = true; - } - else if (newSerialData == true) - { - if ((millis() - lastSeriaLogSyncTime) > MAX_IDLE_TIME_MSEC) //If we haven't received any characters recently then sync log file - { - if (incomingBufferSpot > 0) - { - //Write the remainder of the buffer - serialDataFile.write(incomingBuffer, incomingBufferSpot); //Record the buffer to the card - serialDataFile.sync(); - - incomingBufferSpot = 0; - } - - newSerialData = false; - lastSeriaLogSyncTime = millis(); //Reset the last sync time to now - - Serial.println("Total chars recevied: " + (String)charsReceived); - } - } - - if (Serial.available()) - { - byte incoming = Serial.read(); - - if (incoming == '1') - { - Serial.println("Serial set to: 115200"); - SerialLog.begin(115200); - } - else if (incoming == '2') - { - Serial.println("Serial set to: 230400"); - SerialLog.begin(230400); - } - else if (incoming == '3') - { - Serial.println("Serial set to: 460800"); - SerialLog.begin(460800); - } - else if (incoming == '4') - { - Serial.println("Serial set to: 500000"); - SerialLog.begin(500000); - } - else if (incoming == '5') - { - Serial.println("Serial set to: 691200"); - SerialLog.begin(691200); - } - else if (incoming == '6') - { - Serial.println("Serial set to: 921600"); - SerialLog.begin(921600); - } - else if (incoming == 'r') - { - Serial.println("Total count reset"); - charsReceived = 0; - } - else if (incoming == 'e') - { - Serial.println("Burst mode enabled"); - enableBurstMode(); //Go to 96MHz - } - else if (incoming == 'd') - { - Serial.println("Burst mode disabled"); - disableBurstMode(); //Go to 48MHz - } - else if (incoming == '\r' || incoming == '\n') - { - //Do nothing - } - else - { - Serial.println("Not recognized"); - } - } - - //Delay until we reach the requested read rate - // if (millis() - overallStartTime > 500) - // { - // overallStartTime = millis(); - // if (digitalRead(statLED) == HIGH) - // digitalWrite(statLED, LOW); - // else - // digitalWrite(statLED, HIGH); - // } -} - -void microSDPowerOn() -{ - pinMode(PIN_MICROSD_POWER, OUTPUT); - digitalWrite(PIN_MICROSD_POWER, LOW); -} -void microSDPowerOff() -{ - pinMode(PIN_MICROSD_POWER, OUTPUT); - digitalWrite(PIN_MICROSD_POWER, HIGH); -} diff --git a/Firmware/Test Sketches/TIM_TM2_Data_Logging/TIM_TM2_Data_Logging.ino b/Firmware/Test Sketches/TIM_TM2_Data_Logging/TIM_TM2_Data_Logging.ino index 081f343..2d4b735 100644 --- a/Firmware/Test Sketches/TIM_TM2_Data_Logging/TIM_TM2_Data_Logging.ino +++ b/Firmware/Test Sketches/TIM_TM2_Data_Logging/TIM_TM2_Data_Logging.ino @@ -7,7 +7,7 @@ By: Paul Clark SparkFun Electronics - Date: April 23rd, 2021 + Date: August 17th, 2021 License: MIT. See license file for more information but you can basically do whatever you want with this code. @@ -17,6 +17,14 @@ This example shows how to configure the u-blox ZED-F9P GNSS to send TIM TM2 reports when a sound event is detected and automatically log the data to SD card in UBX format. + This version uses v2.1.0 of the SparkFun Apollo3 (artemis) core. + + Please note: v2.1.1 of the core contains a change to the I2C interface which makes communication + with u-blox modules over I2C less reliable. If you are building this code yourself, + please use V2.1.0 of the core. + + The Board should be set to SparkFun Apollo3 \ RedBoard Artemis ATP. + ** Please note: this example will only work with u-blox ADR or High Precision GNSS or Time Sync products ** Hardware Connections: @@ -28,8 +36,6 @@ Use a jumper cable to connect the TRIG pin on the Qwiic Sound Trigger to the INT pin on the ZED-F9P breakout. Ensure you have the SparkFun Apollo3 boards installed: http://boardsmanager/All#SparkFun_Apollo3 - This code has been tested using version 1.2.1 of the Apollo3 boards on Arduino IDE 1.8.13. - Select "SparkFun Artemis ATP" as the board type. Press upload to upload the code onto the Artemis. Open the Serial Monitor at 115200 baud to see the output. @@ -66,18 +72,36 @@ PCA9536 myTrigger; #include -#include #include //Click here to get the library: http://librarymanager/All#SparkFun_u-blox_GNSS SFE_UBLOX_GNSS myGNSS; +#include //SdFat v2.0.7 by Bill Greiman. Click here to get the library: http://librarymanager/All#SdFat_exFAT + +#define SD_FAT_TYPE 3 // SD_FAT_TYPE = 0 for SdFat/File, 1 for FAT16/FAT32, 2 for exFAT, 3 for FAT16/FAT32 and exFAT. +#define SD_CONFIG SdSpiConfig(PIN_MICROSD_CHIP_SELECT, SHARED_SPI, SD_SCK_MHZ(24)) // 24MHz + +#if SD_FAT_TYPE == 1 +SdFat32 sd; +File32 myFile; //File that all GNSS data is written to +#elif SD_FAT_TYPE == 2 +SdExFat sd; +ExFile myFile; //File that all GNSS data is written to +#elif SD_FAT_TYPE == 3 +SdFs sd; +FsFile myFile; //File that all GNSS data is written to +#else // SD_FAT_TYPE == 0 +SdFat sd; File myFile; //File that all GNSS data is written to +#endif // SD_FAT_TYPE // OLA Specifics: //Setup Qwiic Port #include -TwoWire qwiic(1); //Will use pads 8/9 +const byte PIN_QWIIC_SCL = 8; +const byte PIN_QWIIC_SDA = 9; +TwoWire qwiic(PIN_QWIIC_SDA,PIN_QWIIC_SCL); //Will use pads 8/9 //Define the pin functions //Depends on hardware version. This can be found as a marking on the PCB. @@ -108,8 +132,9 @@ const byte BREAKOUT_PIN_32 = 32; const byte BREAKOUT_PIN_TX = 12; const byte BREAKOUT_PIN_RX = 13; const byte BREAKOUT_PIN_11 = 11; -const byte PIN_QWIIC_SCL = 8; -const byte PIN_QWIIC_SDA = 9; +const byte PIN_SPI_SCK = 5; +const byte PIN_SPI_CIPO = 6; +const byte PIN_SPI_COPI = 7; // Globals and Consts @@ -120,6 +145,8 @@ const int lowBatteryReadingsLimit = 10; // Don't declare the battery voltage low const int sdPowerDownDelay = 100; //Delay for this many ms before turning off the SD card power bool powerLossSeen = false; //Interrupt flag for power loss detection bool stopLoggingSeen = false; //Interrupt flag for stop logging detection +bool ignorePowerLossInterrupt = true; // Ignore the power loss interrupt - when attaching the interrupt +bool ignoreStopLoggingInterrupt = true; // Ignore the stop logging interrupt - when attaching the interrupt // Data Logging Specifics: @@ -176,7 +203,9 @@ void setup() delay(1); // Let PIN_POWER_LOSS stabilize if (digitalRead(PIN_POWER_LOSS) == LOW) powerLossISR(); //Check PIN_POWER_LOSS just in case we missed the falling edge + ignorePowerLossInterrupt = true; // Ignore the power loss interrupt - when attaching the interrupt attachInterrupt(digitalPinToInterrupt(PIN_POWER_LOSS), powerLossISR, FALLING); + ignorePowerLossInterrupt = false; powerLEDOn(); // Turn the power LED on - if the hardware supports it @@ -221,12 +250,15 @@ void setup() pinMode(PIN_STOP_LOGGING, INPUT_PULLUP); delay(1); // Let the pin stabilize + ignoreStopLoggingInterrupt = true; // Ignore the stop logging interrupt - when attaching the interrupt attachInterrupt(digitalPinToInterrupt(PIN_STOP_LOGGING), stopLoggingISR, FALLING); // Enable the stop logging interrupt + pinMode(PIN_STOP_LOGGING, INPUT_PULLUP); //Re-attach the pull-up (bug in v2.1.0 of the core) + ignoreStopLoggingInterrupt = false; Serial.println("Initializing SD card..."); // See if the card is present and can be initialized: - if (!SD.begin(PIN_MICROSD_CHIP_SELECT)) + if (!sd.begin(SD_CONFIG)) { Serial.println("Card failed, or not present. Freezing..."); // don't do anything more: @@ -236,7 +268,7 @@ void setup() // Create or open a file called "TIM_TM2.ubx" on the SD card. // If the file already exists, the new data is appended to the end of the file. - myFile = SD.open("TIM_TM2.ubx", FILE_WRITE); + myFile.open("TIM_TM2.ubx", FILE_WRITE); if(!myFile) { Serial.println(F("Failed to create UBX data file! Freezing...")); @@ -327,7 +359,7 @@ void loop() digitalWrite(PIN_STAT_LED, HIGH); // We will use PIN_STAT_LED to indicate when data is being written to the SD card #ifndef KEEP_FILE_OPEN - myFile = SD.open("TIM_TM2.ubx", FILE_WRITE); // Reopen the file + myFile.open("TIM_TM2.ubx", FILE_WRITE); // Reopen the file #endif myFile.write(myBuffer, packetLength); // Write exactly packetLength bytes from myBuffer to the ubxDataFile on the SD card @@ -391,17 +423,23 @@ void printBuffer(uint8_t *ptr) //Stop Logging ISR void stopLoggingISR(void) { - Serial.println(F("\nStop Logging Seen!")); - detachInterrupt(digitalPinToInterrupt(PIN_STOP_LOGGING)); //Prevent multiple interrupts - stopLoggingSeen = true; + if (ignoreStopLoggingInterrupt == false) + { + Serial.println(F("Stop Logging Seen!")); + detachInterrupt(digitalPinToInterrupt(PIN_STOP_LOGGING)); //Prevent multiple interrupts + stopLoggingSeen = true; + } } //Power Loss ISR void powerLossISR(void) { - Serial.println(F("\nPower Loss Detected!")); - detachInterrupt(digitalPinToInterrupt(PIN_POWER_LOSS)); //Prevent multiple interrupts - powerLossSeen = true; + if (ignorePowerLossInterrupt == false) + { + Serial.println(F("Power Loss Detected!")); + detachInterrupt(digitalPinToInterrupt(PIN_POWER_LOSS)); //Prevent multiple interrupts + powerLossSeen = true; + } } // =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- @@ -426,7 +464,7 @@ void stopLogging(void) // Stop logging; close the SD file; go into deep sleep SPI.end(); //Power down SPI - power_adc_disable(); //Power down ADC. It it started by default before setup(). + powerControlADC(false); //Power down ADC. It it started by default before setup(). Serial.end(); //Power down UART @@ -452,9 +490,10 @@ void stopLogging(void) // Stop logging; close the SD file; go into deep sleep //Disable pads for (int x = 0; x < 50; x++) { - if ((x != ap3_gpio_pin2pad(PIN_MICROSD_POWER)) && - (x != ap3_gpio_pin2pad(PIN_QWIIC_POWER)) && - (x != ap3_gpio_pin2pad(PIN_IMU_POWER))) + if ((x != PIN_MICROSD_POWER) && + //(x != PIN_LOGIC_DEBUG) && + (x != PIN_QWIIC_POWER) && + (x != PIN_IMU_POWER)) { am_hal_gpio_pinconfig(x, g_AM_HAL_GPIO_DISABLE); } @@ -544,7 +583,7 @@ void beginQwiic() pinMode(PIN_QWIIC_POWER, OUTPUT); qwiicPowerOn(); qwiic.begin(); - qwiic.setPullups(0); //Just to make it really clear what pull-ups are being used, set pullups here. + setQwiicPullups(0); //Just to make it really clear what pull-ups are being used, set pullups here. } void beginSD() @@ -561,20 +600,51 @@ void beginSD() microSDPowerOn(); } +void setQwiicPullups(uint32_t i2cBusPullUps) +{ + //Change SCL and SDA pull-ups manually using pin_config + am_hal_gpio_pincfg_t sclPinCfg = g_AM_BSP_GPIO_IOM1_SCL; + am_hal_gpio_pincfg_t sdaPinCfg = g_AM_BSP_GPIO_IOM1_SDA; + + if (i2cBusPullUps == 0) + { + sclPinCfg.ePullup = AM_HAL_GPIO_PIN_PULLUP_NONE; // No pull-ups + sdaPinCfg.ePullup = AM_HAL_GPIO_PIN_PULLUP_NONE; + } + else if (i2cBusPullUps == 1) + { + sclPinCfg.ePullup = AM_HAL_GPIO_PIN_PULLUP_1_5K; // Use 1K5 pull-ups + sdaPinCfg.ePullup = AM_HAL_GPIO_PIN_PULLUP_1_5K; + } + else if (i2cBusPullUps == 6) + { + sclPinCfg.ePullup = AM_HAL_GPIO_PIN_PULLUP_6K; // Use 6K pull-ups + sdaPinCfg.ePullup = AM_HAL_GPIO_PIN_PULLUP_6K; + } + else if (i2cBusPullUps == 12) + { + sclPinCfg.ePullup = AM_HAL_GPIO_PIN_PULLUP_12K; // Use 12K pull-ups + sdaPinCfg.ePullup = AM_HAL_GPIO_PIN_PULLUP_12K; + } + else + { + sclPinCfg.ePullup = AM_HAL_GPIO_PIN_PULLUP_24K; // Use 24K pull-ups + sdaPinCfg.ePullup = AM_HAL_GPIO_PIN_PULLUP_24K; + } + + pin_config(PinName(PIN_QWIIC_SCL), sclPinCfg); + pin_config(PinName(PIN_QWIIC_SDA), sdaPinCfg); +} + // =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- bool enableCIPOpullUp() { - //Add CIPO pull-up - ap3_err_t retval = AP3_OK; - am_hal_gpio_pincfg_t cipoPinCfg = AP3_GPIO_DEFAULT_PINCFG; - cipoPinCfg.uFuncSel = AM_HAL_PIN_6_M0MISO; - cipoPinCfg.eDriveStrength = AM_HAL_GPIO_PIN_DRIVESTRENGTH_12MA; - cipoPinCfg.eGPOutcfg = AM_HAL_GPIO_PIN_OUTCFG_PUSHPULL; - cipoPinCfg.uIOMnum = AP3_SPI_IOM; + //Add 1K5 pull-up on CIPO + am_hal_gpio_pincfg_t cipoPinCfg = g_AM_BSP_GPIO_IOM0_MISO; cipoPinCfg.ePullup = AM_HAL_GPIO_PIN_PULLUP_1_5K; - padMode(MISO, cipoPinCfg, &retval); - return (retval == AP3_OK); + pin_config(PinName(PIN_SPI_CIPO), cipoPinCfg); + return (true); } // =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-