// SPDX-License-Identifier: Apache-2.0 // Copyright (c) 2012-2024 Scott Penrose and WII5 Buoy contributors // // This file is part of WII5 Buoy firmware. // See LICENSE for full terms. /** * @file WII5Setup.cpp * @brief Boot-time hardware bring-up: pin defaults, peripherals, and serial ports. */ /* Setup - Turn everything on etc */ #include #include #include #include #include // Debugging etc - move to header file #define DEBUG_SLEEP void WII5Setup::beginSafe() { // WDT #ifdef WDT_RESET pinMode(WDT_RESET, OUTPUT); digitalWrite(WDT_RESET, LOW); #endif // Make buzzer OUTPUT and OFF #ifdef POWER_BUZZER_PIN pinMode(POWER_BUZZER_PIN, OUTPUT); digitalWrite(POWER_BUZZER_PIN, LOW); #endif // 5V - FORCE On until sure Maths is off #ifdef SHARED_5VOLT_ON pinMode(SHARED_5VOLT_PIN, OUTPUT); digitalWrite(SHARED_5VOLT_PIN, HIGH); #endif // Maths - FORCE On until sure Maths is off #ifdef POWER_MATHS_PIN pinMode(POWER_MATHS_PIN, OUTPUT); digitalWrite(POWER_MATHS_PIN, HIGH); #endif // SD: Power #if POWER_STORAGE_1_PIN>0 pinMode(POWER_STORAGE_1_PIN, OUTPUT); digitalWrite(POWER_STORAGE_1_PIN, HIGH); #endif #if POWER_STORAGE_2_PIN>0 pinMode(POWER_STORAGE_2_PIN, OUTPUT); digitalWrite(POWER_STORAGE_2_PIN, HIGH); #endif // SD: Buffers #ifdef STORAGE_SD1_MATHS_PIN pinMode(STORAGE_SD1_MATHS_PIN, OUTPUT); digitalWrite(STORAGE_SD1_MATHS_PIN, HIGH); pinMode(STORAGE_SD2_MATHS_PIN, OUTPUT); digitalWrite(STORAGE_SD2_MATHS_PIN, LOW); #endif // Sub 1 and 2 #ifdef POWER_SUBBOARD_1_PIN pinMode(POWER_SUBBOARD_1_PIN, OUTPUT); digitalWrite(POWER_SUBBOARD_1_PIN, LOW); #endif #ifdef POWER_SUBBOARD_2_PIN pinMode(POWER_SUBBOARD_2_PIN, OUTPUT); digitalWrite(POWER_SUBBOARD_2_PIN, LOW); #endif // GPS pinMode(POWER_GPS_PIN, OUTPUT); digitalWrite(POWER_GPS_PIN, LOW); // Iridium pinMode(POWER_COMMS_PIN, OUTPUT); digitalWrite(POWER_COMMS_PIN, LOW); // Batt2 #ifdef BATTERY_2_PIN pinMode(BATTERY_2_PIN, OUTPUT); digitalWrite(BATTERY_2_PIN, LOW); #endif // Radio #ifdef WII5_RADIO_LORA pinMode(POWER_RADIO_PIN, OUTPUT); digitalWrite(POWER_RADIO_PIN, LOW); #endif // Strobe pinMode(POWER_STROBE1_ON, OUTPUT); digitalWrite(POWER_STROBE1_ON, LOW); #ifdef TIMING_SPARTON_RUN pinMode(TIMING_SPARTON_RUN, OUTPUT); #endif #ifdef TIMING_SPARTON_CHAR pinMode(TIMING_SPARTON_CHAR, OUTPUT); #endif #ifdef TIMING_SPARTON_RECORD pinMode(TIMING_SPARTON_RECORD, OUTPUT); #endif #ifdef TIMING_SD_WRITE pinMode(TIMING_SD_WRITE, OUTPUT); #endif } void WII5Setup::bootbeep() { #ifdef POWER_BUZZER_PIN #ifdef SHARED_5VOLT_ON digitalWrite(SHARED_5VOLT_PIN, HIGH); #endif digitalWrite(POWER_BUZZER_PIN, HIGH); delay(250); digitalWrite(POWER_BUZZER_PIN, LOW); delay(250); digitalWrite(POWER_BUZZER_PIN, HIGH); delay(250); digitalWrite(POWER_BUZZER_PIN, LOW); #endif } void WII5Setup::shutdownbeep() { #ifdef POWER_BUZZER_PIN #ifdef SHARED_5VOLT_ON digitalWrite(SHARED_5VOLT_PIN, HIGH); #endif delay(250); digitalWrite(POWER_BUZZER_PIN, HIGH); delay(125); digitalWrite(POWER_BUZZER_PIN, LOW); delay(125); digitalWrite(POWER_BUZZER_PIN, HIGH); delay(125); digitalWrite(POWER_BUZZER_PIN, LOW); delay(125); digitalWrite(POWER_BUZZER_PIN, HIGH); delay(125); digitalWrite(POWER_BUZZER_PIN, LOW); delay(125); digitalWrite(POWER_BUZZER_PIN, HIGH); delay(125); digitalWrite(POWER_BUZZER_PIN, LOW); delay(125); digitalWrite(POWER_BUZZER_PIN, HIGH); delay(125); digitalWrite(POWER_BUZZER_PIN, LOW); delay(125); digitalWrite(POWER_BUZZER_PIN, HIGH); delay(125); digitalWrite(POWER_BUZZER_PIN, LOW); delay(125); digitalWrite(POWER_BUZZER_PIN, HIGH); delay(125); digitalWrite(POWER_BUZZER_PIN, LOW); delay(125); digitalWrite(POWER_BUZZER_PIN, HIGH); delay(125); digitalWrite(POWER_BUZZER_PIN, LOW); #endif } void WII5Setup::begin() { // TODO 2024 - Check state of button 2 is on // if so set special Maths flag - alwayson? // If button 2 goes off at any point or button1 on, then always off is forever off? setupConsole(); setupPower(); setupIO(); setupNetwork(); setupWII5(); #ifdef WII5_STORAGE_SDBLOCK sdBlock.debug = false; sdBlock.stream = &Serial; sdBlock.begin(wii5Config.getDeviceId()); #endif } #ifdef WII5_DEBUG_SERIAL void cb(uint8_t l, char *buf) { switch(l) { case LOG_INFO: SerialDebug.print(F("LOG:INFO:")); break; case LOG_WARN: SerialDebug.print(F("LOG:WARN:")); break; case LOG_ERROR: SerialDebug.print(F("LOG:ERROR:")); break; case LOG_DEBUG: SerialDebug.print(F("LOG:DEBUG:")); break; case LOG_FATAL: SerialDebug.print(F("LOG:FATAL:")); break; default: SerialDebug.print(F("LOG:?:")); break; }; SerialDebug.print(buf); SerialDebug.println(); } #endif void WII5Setup::setupPower() { if (_setupPower) return; _setupPower = true; } void WII5Setup::setupConsole() { if (_setupConsole) return; _setupConsole = true; SerialConsole.begin(SerialConsole_Baud); // Hard coded BAD - Where to put this for reuse in WII5 buoys // Maybe a macro in the Board file? console.begin(wii5BufferConsolePrint, WII5_BUFFER_CONSOLE_PRINT, wii5BufferConsoleCmd, WII5_BUFFER_CONSOLE_CMD); // TODO ? console.enableNmea(); // Here we add the main console as an OUTPUT only #if defined(WII5_DEBUG_SERIAL) && defined(WII5_DEBUG_SERIAL_CONSOLE) console.add(&SerialConsole, CONSOLE_DIRECTION_OUTPUT); #else console.add(&SerialConsole); #endif // NOTE: We are using Iridium as it is currently only Binary code we need #ifdef WII5_GPS console.setBinaryBuffer(wii5BinaryIridium, WII5_IRIDIUM_BIN_MAX); #endif #ifdef WII5_DEBUG_SERIAL SerialDebug.begin(WII5_DEBUG_SERIAL_BAUD); #ifdef WII5_DEBUG_SERIAL_CONSOLE console.add(&SerialDebug, CONSOLE_DIRECTION_BOTH); #else console.setCallbackFunction(cb); console.setCallbackLevel(LOG_FATAL); #endif #endif #ifdef WII5_STATUS_SERIAL SerialStatus.begin(WII5_STATUS_SERIAL_BAUD); #endif #ifdef WII5_MATHS_SERIAL SerialMaths.begin(WII5_MATHS_SERIAL_BAUD); console.add(&SerialMaths, CONSOLE_DIRECTION_BOTH); #endif console.setLevel(LOG_INFO); } void WII5Setup::setupNetwork() { if (_setupNetwork) return; _setupNetwork = true; #ifdef WII5_RADIO_LORA wii5RadioLoRa.begin(); #endif } void WII5Setup::setupIO() { if (_setupIO) return; _setupIO = true; // IO - LED, Buttons et al sh3dNodeIO.begin(LED_1, LED_2, LED_3, LED_4, BUTTON_1, BUTTON_2, BUTTON_3, BUTTON_4); // SET LED to Fast Flash #if LED_1>0 sh3dNodeIO.led1Set( LED_SHORT ); sh3dNodeIO.led1SetDefault(LED_SHORT); sh3dNodeIO.led1SetTimeout(300000); #endif #if LED_2>0 #ifdef POWER_BUZZER_PIN // Off after 5 seconds sh3dNodeIO.led2Set( LED_OFF ); sh3dNodeIO.led2SetDefault(LED_OFF); sh3dNodeIO.led2SetTimeout(10000); #else sh3dNodeIO.led2Set( LED_SLOW ); sh3dNodeIO.led2SetDefault(LED_SLOW); sh3dNodeIO.led2SetTimeout(10000); #endif #endif #if LED_3>0 sh3dNodeIO.led3Set( LED_SLOW ); sh3dNodeIO.led3SetDefault(LED_SLOW); sh3dNodeIO.led3SetTimeout(10000); #endif #if LED_4>0 sh3dNodeIO.led4Set( LED_SLOW ); sh3dNodeIO.led4SetDefault(LED_SLOW); sh3dNodeIO.led4SetTimeout(10000); #endif } void WII5Setup::setupWII5() { if (_setupWII5) return; _setupWII5 = true; wii5Config.begin(); #ifdef WII5_RTC wii5RTC.begin(); #endif wii5Commands.begin(); wii5Battery.begin(); #ifdef WII5_GPS wii5Gps.begin(); #endif #ifdef WII5_COMMS_IRIDIUM wii5Iridium.begin(); #endif wii5Maths.begin(); // wii5MPU9250.begin(); wii5Weather_18B20.begin(); #ifdef WII5_IMU_SPARTON wii5Sparton.begin(); #endif wii5Communications.begin(); } void WII5Setup::sleepBefore(bool MathsON) { // Tell devices they are really off. wii5Sparton.stop(true); wii5Iridium.stop(true); wii5Gps.off(); sdBlock.cardForceClose(); #ifdef WII5_WDT_INTERNAL wdt_disable(); #endif // Turn off Shared, and Maths CPU pinMode(SHARED_5VOLT_PIN, OUTPUT); pinMode(POWER_MATHS_PIN, OUTPUT); if (MathsON) { digitalWrite(SHARED_5VOLT_PIN, HIGH); digitalWrite(POWER_MATHS_PIN, HIGH); } else { digitalWrite(SHARED_5VOLT_PIN, LOW); digitalWrite(POWER_MATHS_PIN, LOW); } // Storage SD Card #if POWER_STORAGE_1_PIN>0 pinMode(POWER_STORAGE_1_PIN, OUTPUT); digitalWrite(POWER_STORAGE_1_PIN, LOW); #endif #if POWER_STORAGE_2_PIN>0 pinMode(POWER_STORAGE_2_PIN, OUTPUT); digitalWrite(POWER_STORAGE_2_PIN, LOW); #endif // GPS, Radio, MPU and Strobe pinMode(POWER_GPS_PIN, OUTPUT); digitalWrite(POWER_GPS_PIN, LOW); pinMode(POWER_COMMS_PIN, OUTPUT); digitalWrite(POWER_COMMS_PIN, LOW); pinMode(POWER_RADIO_PIN, OUTPUT); digitalWrite(POWER_RADIO_PIN, LOW); pinMode(POWER_STROBE1_ON, OUTPUT); digitalWrite(POWER_STROBE1_ON, LOW); // Misc Controlling lines pinMode(STORAGE_SD1_MATHS_PIN, INPUT); pinMode(STORAGE_SD2_MATHS_PIN, INPUT); pinMode(SPARTON_RESET, INPUT); pinMode(RADIO_CS, INPUT); pinMode(STORAGE_CS, INPUT); // LEDs 2024 Updated to OUTPUT LOW #if LED_1>0 pinMode(LED_1, OUTPUT); digitalWrite(LED_1, LOW); #endif #if LED_2>0 pinMode(LED_2, OUTPUT); digitalWrite(LED_2, LOW); #endif #if LED_3>0 pinMode(LED_3, OUTPUT); #endif // Weather pinMode(POWER_WEATHER_18B20_PIN, INPUT); pinMode(POWER_WEATHER_PIN, INPUT); } void WII5Setup::sleepAfter() { // Really make sure still output pinMode(SHARED_5VOLT_PIN, OUTPUT); pinMode(POWER_MATHS_PIN, OUTPUT); // Storage SD Card #if POWER_STORAGE_1_PIN>0 pinMode(POWER_STORAGE_1_PIN, OUTPUT); digitalWrite(POWER_STORAGE_1_PIN, HIGH); #endif #if POWER_STORAGE_2_PIN>0 pinMode(POWER_STORAGE_2_PIN, OUTPUT); #endif // GPS, Radio, MPU and Strobe pinMode(POWER_GPS_PIN, OUTPUT); pinMode(POWER_COMMS_PIN, OUTPUT); pinMode(POWER_RADIO_PIN, OUTPUT); pinMode(POWER_STROBE1_ON, OUTPUT); // Misc Controlling lines pinMode(STORAGE_SD1_MATHS_PIN, OUTPUT); pinMode(STORAGE_SD2_MATHS_PIN, OUTPUT); pinMode(SPARTON_RESET, OUTPUT); pinMode(RADIO_CS, OUTPUT); pinMode(STORAGE_CS, OUTPUT); // LEDs pinMode(LED_1, OUTPUT); #if LED_2>0 pinMode(LED_2, OUTPUT); #endif #if LED_3>0 pinMode(LED_3, OUTPUT); #endif // Weather pinMode(POWER_WEATHER_18B20_PIN, OUTPUT); pinMode(POWER_WEATHER_PIN, OUTPUT); #ifdef WII5_WDT_INTERNAL wdt_enable(WDTO_8S); #endif } WII5Setup wii5Setup;