diff --git a/src/main.cpp b/src/main.cpp index 09aa66c4..c8f3af3d 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -485,440 +485,3 @@ void setup() { } // setup() void loop() { vTaskDelete(NULL); } -3 MatrixDisplayIRQ -> matrix mux cycle -> 0,5ms (MATRIX_DISPLAY_SCAN_US) - - -// Interrupt routines -------------------------------------------------------------------------------- - -fired by hardware -DisplayIRQ -> esp32 timer 0 -> irqHandlerTask (Core 1) -CLOCKIRQ -> esp32 timer 1 -> ClockTask (Core 1) -ButtonIRQ -> external gpio -> irqHandlerTask (Core 1) -PMUIRQ -> PMU chip gpio -> irqHandlerTask (Core 1) - -fired by software (Ticker.h) -TIMESYNC_IRQ -> timeSync() -> irqHandlerTask (Core 1) -CYCLIC_IRQ -> housekeeping() -> irqHandlerTask (Core 1) -SENDCYCLE_IRQ -> sendcycle() -> irqHandlerTask (Core 1) -BME_IRQ -> bmecycle() -> irqHandlerTask (Core 1) - - -// External RTC timer (if present) -------------------------------------------------------------------------------- -triggers pps 1 sec impulse - -*/ - -// Basic Config -#include "main.h" - -configData_t cfg; // struct holds current device configuration -char lmic_event_msg[LMIC_EVENTMSG_LEN]; // display buffer for LMIC event message -uint8_t volatile channel = 0; // channel rotation counter -uint16_t volatile macs_total = 0, macs_wifi = 0, macs_ble = 0, - batt_voltage = 0; // globals for display - -hw_timer_t *ppsIRQ = NULL, *displayIRQ = NULL, *matrixDisplayIRQ = NULL; - -TaskHandle_t irqHandlerTask = NULL, ClockTask = NULL; -SemaphoreHandle_t I2Caccess; -bool volatile TimePulseTick = false; -time_t userUTCTime = 0; -timesource_t timeSource = _unsynced; - -// container holding unique MAC address hashes with Memory Alloctor using PSRAM, -// if present -std::set, Mallocator> macs; - -// initialize payload encoder -PayloadConvert payload(PAYLOAD_BUFFER_SIZE); - -// set Time Zone for user setting from paxcounter.conf -TimeChangeRule myDST = DAYLIGHT_TIME; -TimeChangeRule mySTD = STANDARD_TIME; -Timezone myTZ(myDST, mySTD); - -// local Tag for logging -static const char TAG[] = __FILE__; - -void setup() { - - char features[100] = ""; - - // create some semaphores for syncing / mutexing tasks - I2Caccess = xSemaphoreCreateMutex(); // for access management of i2c bus - assert(I2Caccess != NULL); - I2C_MUTEX_UNLOCK(); - - // disable brownout detection -#ifdef DISABLE_BROWNOUT - // register with brownout is at address DR_REG_RTCCNTL_BASE + 0xd4 - (*((uint32_t volatile *)ETS_UNCACHED_ADDR((DR_REG_RTCCNTL_BASE + 0xd4)))) = 0; -#endif - - // setup debug output or silence device -#if (VERBOSE) - Serial.begin(115200); - esp_log_level_set("*", ESP_LOG_VERBOSE); -#else - // mute logs completely by redirecting them to silence function - esp_log_level_set("*", ESP_LOG_NONE); -#endif - - do_after_reset(rtc_get_reset_reason(0)); - - // print chip information on startup if in verbose mode after coldstart -#if (VERBOSE) - - if (RTC_runmode == RUNMODE_POWERCYCLE) { - esp_chip_info_t chip_info; - esp_chip_info(&chip_info); - ESP_LOGI(TAG, - "This is ESP32 chip with %d CPU cores, WiFi%s%s, silicon revision " - "%d, %dMB %s Flash", - chip_info.cores, - (chip_info.features & CHIP_FEATURE_BT) ? "/BT" : "", - (chip_info.features & CHIP_FEATURE_BLE) ? "/BLE" : "", - chip_info.revision, spi_flash_get_chip_size() / (1024 * 1024), - (chip_info.features & CHIP_FEATURE_EMB_FLASH) ? "embedded" - : "external"); - ESP_LOGI(TAG, "Internal Total heap %d, internal Free Heap %d", - ESP.getHeapSize(), ESP.getFreeHeap()); -#ifdef BOARD_HAS_PSRAM - ESP_LOGI(TAG, "SPIRam Total heap %d, SPIRam Free Heap %d", - ESP.getPsramSize(), ESP.getFreePsram()); -#endif - ESP_LOGI(TAG, "ChipRevision %d, Cpu Freq %d, SDK Version %s", - ESP.getChipRevision(), ESP.getCpuFreqMHz(), ESP.getSdkVersion()); - ESP_LOGI(TAG, "Flash Size %d, Flash Speed %d", ESP.getFlashChipSize(), - ESP.getFlashChipSpeed()); - ESP_LOGI(TAG, "Wifi/BT software coexist version %s", - esp_coex_version_get()); - -#if (HAS_LORA) - ESP_LOGI(TAG, "IBM LMIC version %d.%d.%d", LMIC_VERSION_MAJOR, - LMIC_VERSION_MINOR, LMIC_VERSION_BUILD); - ESP_LOGI(TAG, "Arduino LMIC version %d.%d.%d.%d", - ARDUINO_LMIC_VERSION_GET_MAJOR(ARDUINO_LMIC_VERSION), - ARDUINO_LMIC_VERSION_GET_MINOR(ARDUINO_LMIC_VERSION), - ARDUINO_LMIC_VERSION_GET_PATCH(ARDUINO_LMIC_VERSION), - ARDUINO_LMIC_VERSION_GET_LOCAL(ARDUINO_LMIC_VERSION)); - showLoraKeys(); -#endif // HAS_LORA - -#if (HAS_GPS) - ESP_LOGI(TAG, "TinyGPS+ version %s", TinyGPSPlus::libraryVersion()); -#endif - } -#endif // VERBOSE - - // open i2c bus - i2c_init(); - -// setup power on boards with power management logic -#ifdef EXT_POWER_SW - pinMode(EXT_POWER_SW, OUTPUT); - digitalWrite(EXT_POWER_SW, EXT_POWER_ON); - strcat_P(features, " VEXT"); -#endif -#ifdef HAS_PMU - AXP192_init(); - strcat_P(features, " PMU"); -#endif - - // read (and initialize on first run) runtime settings from NVRAM - loadConfig(); // includes initialize if necessary - -// initialize display -#ifdef HAS_DISPLAY - strcat_P(features, " OLED"); - DisplayIsOn = cfg.screenon; - // display verbose info only after a coldstart (note: blocking call!) - init_display(RTC_runmode == RUNMODE_POWERCYCLE ? true : false); -#endif - - // scan i2c bus for devices - i2c_scan(); - -#ifdef BOARD_HAS_PSRAM - assert(psramFound()); - ESP_LOGI(TAG, "PSRAM found and initialized"); - strcat_P(features, " PSRAM"); -#endif - -#ifdef BAT_MEASURE_EN - pinMode(BAT_MEASURE_EN, OUTPUT); -#endif - -// initialize leds -#if (HAS_LED != NOT_A_PIN) - pinMode(HAS_LED, OUTPUT); - strcat_P(features, " LED"); - -#ifdef LED_POWER_SW - pinMode(LED_POWER_SW, OUTPUT); - digitalWrite(LED_POWER_SW, LED_POWER_ON); -#endif - -#ifdef HAS_TWO_LED - pinMode(HAS_TWO_LED, OUTPUT); - strcat_P(features, " LED1"); -#endif - -// use LED for power display if we have additional RGB LED, else for status -#ifdef HAS_RGB_LED - switch_LED(LED_ON); - strcat_P(features, " RGB"); - rgb_set_color(COLOR_PINK); -#endif - -#endif // HAS_LED - -#if (HAS_LED != NOT_A_PIN) || defined(HAS_RGB_LED) - // start led loop - ESP_LOGI(TAG, "Starting LED Controller..."); - xTaskCreatePinnedToCore(ledLoop, // task function - "ledloop", // name of task - 1024, // stack size of task - (void *)1, // parameter of the task - 3, // priority of the task - &ledLoopTask, // task handle - 0); // CPU core -#endif - -// initialize wifi antenna -#ifdef HAS_ANTENNA_SWITCH - strcat_P(features, " ANT"); - antenna_init(); - antenna_select(cfg.wifiant); -#endif - -// initialize battery status -#if (defined BAT_MEASURE_ADC || defined HAS_PMU) - strcat_P(features, " BATT"); - calibrate_voltage(); - batt_voltage = read_voltage(); -#endif - -#if (USE_OTA) - strcat_P(features, " OTA"); - // reboot to firmware update mode if ota trigger switch is set - if (RTC_runmode == RUNMODE_UPDATE) - start_ota_update(); -#endif - -// start BLE scan callback if BLE function is enabled in NVRAM configuration -// or switch off bluetooth, if not compiled -#if (BLECOUNTER) - strcat_P(features, " BLE"); - if (cfg.blescan) { - ESP_LOGI(TAG, "Starting Bluetooth..."); - start_BLEscan(); - } else - btStop(); -#else - // remove bluetooth stack to gain more free memory - btStop(); - ESP_ERROR_CHECK(esp_bt_mem_release(ESP_BT_MODE_BTDM)); - ESP_ERROR_CHECK(esp_coex_preference_set( - ESP_COEX_PREFER_WIFI)); // configure Wifi/BT coexist lib -#endif - -// initialize gps -#if (HAS_GPS) - strcat_P(features, " GPS"); - if (gps_init()) { - ESP_LOGI(TAG, "Starting GPS Feed..."); - xTaskCreatePinnedToCore(gps_loop, // task function - "gpsloop", // name of task - 2048, // stack size of task - (void *)1, // parameter of the task - 1, // priority of the task - &GpsTask, // task handle - 1); // CPU core - } -#endif - -// initialize sensors -#if (HAS_SENSORS) - strcat_P(features, " SENS"); - sensor_init(); -#endif - -// initialize LoRa -#if (HAS_LORA) - strcat_P(features, " LORA"); - // kick off join, except we come from sleep - assert(lora_stack_init(RTC_runmode == RUNMODE_WAKEUP ? false : true) == - ESP_OK); -#endif - -// initialize SPI -#ifdef HAS_SPI - strcat_P(features, " SPI"); - assert(spi_init() == ESP_OK); -#endif - -#ifdef HAS_SDCARD - if (sdcardInit()) - strcat_P(features, " SD"); -#endif - -#if (HAS_SDS011) -// ESP_LOGI(TAG, "init fine-dust-sensor"); - if ( sds011_init() ) - strcat_P(features, " SDS"); -#endif - -#if (VENDORFILTER) - strcat_P(features, " FILTER"); -#endif - -// initialize matrix display -#ifdef HAS_MATRIX_DISPLAY - strcat_P(features, " LED_MATRIX"); - MatrixDisplayIsOn = cfg.screenon; - init_matrix_display(); // note: blocking call -#endif - -// show payload encoder -#if PAYLOAD_ENCODER == 1 - strcat_P(features, " PLAIN"); -#elif PAYLOAD_ENCODER == 2 - strcat_P(features, " PACKED"); -#elif PAYLOAD_ENCODER == 3 - strcat_P(features, " LPPDYN"); -#elif PAYLOAD_ENCODER == 4 - strcat_P(features, " LPPPKD"); -#endif - -// initialize RTC -#ifdef HAS_RTC - strcat_P(features, " RTC"); - assert(rtc_init()); -#endif - -#if defined HAS_DCF77 - strcat_P(features, " DCF77"); -#endif - -#if defined HAS_IF482 - strcat_P(features, " IF482"); -#endif - -#if (WIFICOUNTER) - strcat_P(features, " WIFI"); - // start wifi in monitor mode and start channel rotation timer - ESP_LOGI(TAG, "Starting Wifi..."); - wifi_sniffer_init(); -#else - // switch off wifi - esp_wifi_deinit(); -#endif - - // initialize salt value using esp_random() called by random() in - // arduino-esp32 core. Note: do this *after* wifi has started, since - // function gets it's seed from RF noise - get_salt(); // get new 16bit for salting hashes - - // start state machine - ESP_LOGI(TAG, "Starting Interrupt Handler..."); - xTaskCreatePinnedToCore(irqHandler, // task function - "irqhandler", // name of task - 4096, // stack size of task - (void *)1, // parameter of the task - 2, // priority of the task - &irqHandlerTask, // task handle - 1); // CPU core - -// initialize BME sensor (BME280/BME680) -#if (HAS_BME) -#ifdef HAS_BME680 - strcat_P(features, " BME680"); -#elif defined HAS_BME280 - strcat_P(features, " BME280"); -#elif defined HAS_BMP180 - strcat_P(features, " BMP180"); -#endif - if (bme_init()) - ESP_LOGI(TAG, "Starting BME sensor..."); -#endif - - // starting timers and interrupts - assert(irqHandlerTask != NULL); // has interrupt handler task started? - ESP_LOGI(TAG, "Starting Timers..."); - -// display interrupt -#ifdef HAS_DISPLAY - // https://techtutorialsx.com/2017/10/07/esp32-arduino-timer-interrupts/ - // prescaler 80 -> divides 80 MHz CPU freq to 1 MHz, timer 0, count up - displayIRQ = timerBegin(0, 80, true); - timerAttachInterrupt(displayIRQ, &DisplayIRQ, true); - timerAlarmWrite(displayIRQ, DISPLAYREFRESH_MS * 1000, true); - timerAlarmEnable(displayIRQ); -#endif - -// LED Matrix display interrupt -#ifdef HAS_MATRIX_DISPLAY - // https://techtutorialsx.com/2017/10/07/esp32-arduino-timer-interrupts/ - // prescaler 80 -> divides 80 MHz CPU freq to 1 MHz, timer 3, count up - matrixDisplayIRQ = timerBegin(3, 80, true); - timerAttachInterrupt(matrixDisplayIRQ, &MatrixDisplayIRQ, true); - timerAlarmWrite(matrixDisplayIRQ, MATRIX_DISPLAY_SCAN_US, true); - timerAlarmEnable(matrixDisplayIRQ); -#endif - -// initialize button -#ifdef HAS_BUTTON - strcat_P(features, " BTN_"); -#ifdef BUTTON_PULLUP - strcat_P(features, "PU"); -#else - strcat_P(features, "PD"); -#endif // BUTTON_PULLUP - button_init(HAS_BUTTON); -#endif // HAS_BUTTON - - // cyclic function interrupts - sendcycler.attach(SENDCYCLE * 2, sendcycle); - housekeeper.attach(HOMECYCLE, housekeeping); - -#if (TIME_SYNC_INTERVAL) - -#if (!(TIME_SYNC_LORAWAN) && !(TIME_SYNC_LORASERVER) && !defined HAS_GPS && \ - !defined HAS_RTC) -#warning you did not specify a time source, time will not be synched -#endif - -// initialize gps time -#if (HAS_GPS) - fetch_gpsTime(); -#endif - -#if (defined HAS_IF482 || defined HAS_DCF77) - ESP_LOGI(TAG, "Starting Clock Controller..."); - clock_init(); -#endif - -#if (TIME_SYNC_LORASERVER) - timesync_init(); // create loraserver time sync task -#endif - - ESP_LOGI(TAG, "Starting Timekeeper..."); - assert(timepulse_init()); // setup pps timepulse - timepulse_start(); // starts pps and cyclic time sync - -#endif // TIME_SYNC_INTERVAL - - // show compiled features - ESP_LOGI(TAG, "Features:%s", features); - - // set runmode to normal - RTC_runmode = RUNMODE_NORMAL; - - vTaskDelete(NULL); - -} // setup() - -void loop() { vTaskDelete(NULL); }