commit
						d4974d9c72
					
				| @ -11,8 +11,8 @@ | ||||
| #include <OneBitDisplay.h> | ||||
| extern ONE_BIT_DISPLAY *dp; | ||||
| #elif (HAS_DISPLAY) == 2 | ||||
| #include <TFT_eSPI.h> | ||||
| extern TFT_eSPI *dp; | ||||
| #include <bb_spi_lcd.h> | ||||
| extern BB_SPI_LCD *dp; | ||||
| #endif | ||||
| 
 | ||||
| #define DISPLAY_PAGES (7) // number of paxcounter display pages
 | ||||
| @ -24,7 +24,6 @@ extern TFT_eSPI *dp; | ||||
| #define MY_FONT_NORMAL FONT_8x8 | ||||
| #define MY_FONT_LARGE FONT_16x32 | ||||
| #define MY_FONT_STRETCHED FONT_12x16 | ||||
| 
 | ||||
| #define MY_DISPLAY_FIRSTLINE 30 | ||||
| 
 | ||||
| #ifndef MY_DISPLAY_RST | ||||
| @ -51,22 +50,21 @@ extern TFT_eSPI *dp; | ||||
| // settings for TFT display library
 | ||||
| #elif (HAS_DISPLAY == 2) | ||||
| 
 | ||||
| #define MY_FONT_SMALL 1 | ||||
| #define MY_FONT_SMALL 2 | ||||
| #define MY_FONT_NORMAL 2 | ||||
| #define MY_FONT_LARGE 4 | ||||
| #define MY_FONT_STRETCHED 6 | ||||
| 
 | ||||
| #define MY_FONT_LARGE 2 | ||||
| #define MY_FONT_STRETCHED 2 | ||||
| #define MY_DISPLAY_FIRSTLINE 30 | ||||
| 
 | ||||
| #ifndef MY_DISPLAY_FGCOLOR | ||||
| #define MY_DISPLAY_FGCOLOR 0xFFFF // TFT_WHITE
 | ||||
| #endif | ||||
| #ifndef MY_DISPLAY_BGCOLOR | ||||
| #define MY_DISPLAY_BGCOLOR 0x0000 // TFT_BLACK
 | ||||
| #ifndef TFT_FREQUENCY | ||||
| #define TFT_FREQUENCY 400000L | ||||
| #endif | ||||
| 
 | ||||
| #ifndef TOUCH_CS | ||||
| #define TOUCH_CS NOT_A_PIN | ||||
| #ifndef MY_DISPLAY_FGCOLOR | ||||
| #define MY_DISPLAY_FGCOLOR TFT_YELLOW | ||||
| #endif | ||||
| #ifndef MY_DISPLAY_BGCOLOR | ||||
| #define MY_DISPLAY_BGCOLOR TFT_BLACK | ||||
| #endif | ||||
| 
 | ||||
| #endif | ||||
| @ -104,7 +102,6 @@ void dp_setup(int contrast = 0); | ||||
| void dp_refresh(bool nextPage = false); | ||||
| void dp_init(bool verbose = false); | ||||
| void dp_shutdown(void); | ||||
| void dp_message(const char *msg, int line, bool invers); | ||||
| void dp_setFont(int font, int inv = 0); | ||||
| void dp_dump(uint8_t *pBuffer = NULL); | ||||
| void dp_contrast(uint8_t contrast); | ||||
|  | ||||
| @ -39,7 +39,6 @@ | ||||
| #endif | ||||
| 
 | ||||
| class PayloadConvert { | ||||
| 
 | ||||
| public: | ||||
|   PayloadConvert(uint8_t size); | ||||
|   ~PayloadConvert(); | ||||
| @ -59,6 +58,7 @@ public: | ||||
|   void addSensor(uint8_t[]); | ||||
|   void addTime(time_t value); | ||||
|   void addSDS(sdsStatus_t value); | ||||
| 
 | ||||
| private: | ||||
|   void addChars( char* string, int len); | ||||
| 
 | ||||
|  | ||||
| @ -20,7 +20,7 @@ | ||||
| 
 | ||||
| #ifndef PMU_CHG_CUTOFF | ||||
| #ifdef HAS_PMU | ||||
| #define PMU_CHG_CUTOFF AXP202_TARGET_VOL_4_2V | ||||
| #define PMU_CHG_CUTOFF XPOWERS_CHG_VOL_4V2 | ||||
| #elif defined HAS_IP5306 | ||||
| #define PMU_CHG_CUTOFF 0 | ||||
| #endif | ||||
| @ -28,7 +28,7 @@ | ||||
| 
 | ||||
| #ifndef PMU_CHG_CURRENT | ||||
| #ifdef HAS_PMU | ||||
| #define PMU_CHG_CURRENT AXP1XX_CHARGE_CUR_450MA | ||||
| #define PMU_CHG_CURRENT XPOWERS_CHG_CUR_450MA | ||||
| #elif defined HAS_IP5306 | ||||
| #define PMU_CHG_CURRENT 2 | ||||
| #endif | ||||
| @ -55,8 +55,8 @@ void calibrate_voltage(void); | ||||
| bool batt_sufficient(void); | ||||
| 
 | ||||
| #ifdef HAS_PMU | ||||
| #include <axp20x.h> | ||||
| extern AXP20X_Class pmu; | ||||
| #include <XPowersLib.h> | ||||
| extern XPowersPMU pmu; | ||||
| enum pmu_power_t { pmu_power_on, pmu_power_off, pmu_power_sleep }; | ||||
| void AXP192_powerevent_IRQ(void); | ||||
| void AXP192_power(pmu_power_t powerlevel); | ||||
|  | ||||
| @ -23,7 +23,6 @@ | ||||
| #include <WString.h> | ||||
| 
 | ||||
| class BintrayClient { | ||||
| 
 | ||||
| public: | ||||
|     BintrayClient(const String& user, const String& repository, const String& package); | ||||
|     String getUser() const; | ||||
|  | ||||
| @ -46,7 +46,7 @@ description = Paxcounter is a device for metering passenger flows in realtime. I | ||||
| 
 | ||||
| [common] | ||||
| ; for release_version use max. 10 chars total, use any decimal format like "a.b.c" | ||||
| release_version = 3.3.0 | ||||
| release_version = 3.3.1 | ||||
| ; DEBUG LEVEL: For production run set to 0, otherwise device will leak RAM while running! | ||||
| ; 0=None, 1=Error, 2=Warn, 3=Info, 4=Debug, 5=Verbose | ||||
| debug_level = 3 | ||||
| @ -54,17 +54,16 @@ extra_scripts = pre:build.py | ||||
| otakeyfile = ota.conf | ||||
| lorakeyfile = loraconf.h | ||||
| lmicconfigfile = lmic_config.h | ||||
| platform_espressif32 = espressif32@5.0.0 | ||||
| platform_espressif32 = espressif32@5.1.0 | ||||
| monitor_speed = 115200 | ||||
| upload_speed = 115200 ; set by build.py and taken from hal file | ||||
| display_library = ; set by build.py and taken from hal file | ||||
| lib_deps_lora = | ||||
|     mcci-catena/MCCI LoRaWAN LMIC library @ ^4.1.1 | ||||
| lib_deps_display = | ||||
|     https://github.com/bitbank2/OneBitDisplay#8d4ab34 | ||||
|     ;bitbank2/OneBitDisplay @ ^2.1.0 | ||||
|     https://github.com/bitbank2/OneBitDisplay.git | ||||
|     https://github.com/bitbank2/bb_spi_lcd.git | ||||
|     ricmoo/QRCode @ ^0.0.1 | ||||
|     bodmer/TFT_eSPI @ ^2.3.84 | ||||
| lib_deps_ledmatrix = | ||||
|     seeed-studio/Ultrathin_LED_Matrix @ ^1.0.0 | ||||
| lib_deps_rgbled = | ||||
| @ -83,7 +82,7 @@ lib_deps_basic = | ||||
|     bblanchon/ArduinoJson @ ^6 | ||||
|     makuna/RTC @ ^2.3.5 | ||||
|     spacehuhn/SimpleButton  | ||||
|     lewisxhe/AXP202X_Library @ ^1.1.3 | ||||
|     https://github.com/lewisxhe/XPowersLib.git | ||||
|     256dpi/MQTT @ ^2.4.8 | ||||
| lib_deps_all = | ||||
|     ${common.lib_deps_basic} | ||||
|  | ||||
| @ -48,7 +48,6 @@ void setBMEIRQ() { xTaskNotify(irqHandlerTask, BME_IRQ, eSetBits); } | ||||
| // initialize MEMS sensor
 | ||||
| // return = 0 -> error / return = 1 -> success
 | ||||
| int bme_init(void) { | ||||
| 
 | ||||
|   int rc = 0; | ||||
| 
 | ||||
| #ifdef HAS_BME680 | ||||
| @ -77,7 +76,6 @@ int bme_init(void) { | ||||
|   if (rc) | ||||
|     bmecycler.attach(BMECYCLE, setBMEIRQ); // start cyclic data transmit
 | ||||
|   return rc; | ||||
| 
 | ||||
| } // bme_init()
 | ||||
| 
 | ||||
| #ifdef HAS_BME680 | ||||
| @ -108,7 +106,6 @@ int checkIaqSensorStatus(void) { | ||||
| 
 | ||||
| // store current BME sensor data in struct
 | ||||
| void bme_storedata(bmeStatus_t *bme_store) { | ||||
| 
 | ||||
|   if (cfg.payloadmask & MEMS_DATA) | ||||
| 
 | ||||
| #ifdef HAS_BME680 | ||||
| @ -138,7 +135,6 @@ void bme_storedata(bmeStatus_t *bme_store) { | ||||
|   // bme.readAltitude(SEALEVELPRESSURE_HPA);
 | ||||
|   bme_store->iaq = 0; // IAQ feature not present with BME280
 | ||||
| #endif | ||||
| 
 | ||||
| } // bme_storedata()
 | ||||
| 
 | ||||
| #ifdef HAS_BME680 | ||||
| @ -165,7 +161,6 @@ void updateState(void) { | ||||
|       stateUpdateCounter++; | ||||
|     } | ||||
|   } else { | ||||
| 
 | ||||
|     /* Update every STATE_SAVE_PERIOD minutes */ | ||||
|     if ((long)(millis() - stateUpdateCounter * STATE_SAVE_PERIOD) >= 0) { | ||||
|       update = true; | ||||
|  | ||||
| @ -75,7 +75,6 @@ void IRAM_ATTR watchdog() { xTaskResumeFromISR(RestartHandle); } | ||||
| // used for manually uploading a firmware file via wifi
 | ||||
| 
 | ||||
| void start_boot_menu(void) { | ||||
| 
 | ||||
|   const char *host = clientId; | ||||
|   const char *ssid = WIFI_SSID; | ||||
|   const char *password = WIFI_PASS; | ||||
| @ -150,9 +149,7 @@ void start_boot_menu(void) { | ||||
| 
 | ||||
|         // did we get a file name?
 | ||||
|         if (upload.filename != NULL) { | ||||
| 
 | ||||
|           switch (upload.status) { | ||||
| 
 | ||||
|           case UPLOAD_FILE_START: | ||||
|             // start file transfer
 | ||||
|             ESP_LOGI(TAG, "Uploading %s", upload.filename.c_str()); | ||||
| @ -177,7 +174,6 @@ void start_boot_menu(void) { | ||||
|           case UPLOAD_FILE_ABORTED: | ||||
|           default: | ||||
|             break; | ||||
| 
 | ||||
|           } // switch
 | ||||
| 
 | ||||
|           // don't boot to production if update failed
 | ||||
|  | ||||
| @ -26,7 +26,6 @@ static uint8_t buffer[cfgLen + cfgLen2]; | ||||
| // 3. magicByte [cfgLen2 bytes, containing a fixed identifier]
 | ||||
| 
 | ||||
| static void defaultConfig(configData_t *myconfig) { | ||||
| 
 | ||||
|   strncpy(myconfig->version, PROGVERSION, | ||||
|           sizeof(myconfig->version) - 1); // Firmware version
 | ||||
| 
 | ||||
| @ -92,7 +91,6 @@ void saveConfig(bool erase) { | ||||
| 
 | ||||
| // load configuration from NVRAM into RAM and make it current
 | ||||
| void loadConfig(void) { | ||||
| 
 | ||||
|   int readBytes = 0; | ||||
| 
 | ||||
|   ESP_LOGI(TAG, "Loading device configuration from NVRAM..."); | ||||
| @ -144,7 +142,6 @@ bool comp(char s1, char s2) { return (tolower(s1) < tolower(s2)); } | ||||
| // helper function to lexicographically compare two versions. Returns 1 if v2
 | ||||
| // is smaller, -1 if v1 is smaller, 0 if equal
 | ||||
| int version_compare(const String v1, const String v2) { | ||||
| 
 | ||||
|   if (v1 == v2) | ||||
|     return 0; | ||||
| 
 | ||||
|  | ||||
| @ -13,7 +13,6 @@ void setCyclicIRQ() { xTaskNotify(irqHandlerTask, CYCLIC_IRQ, eSetBits); } | ||||
| 
 | ||||
| // do all housekeeping
 | ||||
| void doHousekeeping() { | ||||
| 
 | ||||
|   // check if update or maintenance mode trigger switch was set by rcommand
 | ||||
|   if ((RTC_runmode == RUNMODE_UPDATE) || (RTC_runmode == RUNMODE_MAINTENANCE)) | ||||
|     do_reset(true); // warmstart
 | ||||
| @ -125,7 +124,6 @@ void doHousekeeping() { | ||||
| #if (HAS_SDCARD) | ||||
|   sdcard_flush(); | ||||
| #endif | ||||
| 
 | ||||
| } // doHousekeeping()
 | ||||
| 
 | ||||
| uint32_t getFreeRAM() { | ||||
|  | ||||
| @ -18,41 +18,33 @@ static const char TAG[] = __FILE__; | ||||
| 
 | ||||
| // triggered by second timepulse to ticker out DCF signal
 | ||||
| void DCF77_Pulse(uint8_t bit) { | ||||
| 
 | ||||
|   TickType_t startTime; | ||||
| 
 | ||||
|   // induce a DCF Pulse
 | ||||
|   for (uint8_t pulseLength = 0; pulseLength <= 2; pulseLength++) { | ||||
| 
 | ||||
|     startTime = xTaskGetTickCount(); // reference time pulse start
 | ||||
| 
 | ||||
|     switch (pulseLength) { | ||||
| 
 | ||||
|     case 0: // 0ms = start of pulse
 | ||||
|       digitalWrite(HAS_DCF77, dcf_low); | ||||
|       break; | ||||
| 
 | ||||
|     case 1: // 100ms = logic 0
 | ||||
|       if (bit == 0) | ||||
|         digitalWrite(HAS_DCF77, dcf_high); | ||||
|       break; | ||||
| 
 | ||||
|     case 2: // 200ms = logic 1
 | ||||
|       digitalWrite(HAS_DCF77, dcf_high); | ||||
|       break; | ||||
| 
 | ||||
|     } // switch
 | ||||
| 
 | ||||
|     // delay to genrate pulseLength
 | ||||
|     vTaskDelayUntil(&startTime, pdMS_TO_TICKS(100)); | ||||
| 
 | ||||
|   } // for
 | ||||
| } // DCF77_Pulse()
 | ||||
| 
 | ||||
| // helper function to convert decimal to bcd digit
 | ||||
| uint64_t dec2bcd(uint8_t const dec, uint8_t const startpos, | ||||
|                  uint8_t const endpos, uint8_t *parity) { | ||||
| 
 | ||||
|   uint8_t data = dec < 10 ? dec : ((dec / 10) << 4) + dec % 10; | ||||
|   uint64_t bcd = 0; | ||||
| 
 | ||||
| @ -68,7 +60,6 @@ uint64_t dec2bcd(uint8_t const dec, uint8_t const startpos, | ||||
| 
 | ||||
| // generates a 1 minute dcf pulse frame for calendar time t
 | ||||
| uint64_t DCF77_Frame(const struct tm t) { | ||||
| 
 | ||||
|   uint8_t parity = 0, parity_sum = 0; | ||||
|   uint64_t frame = 0; // start with all bits 0
 | ||||
| 
 | ||||
| @ -105,7 +96,6 @@ uint64_t DCF77_Frame(const struct tm t) { | ||||
|   frame += parity_sum ? set_dcfbit(58) : 0; | ||||
| 
 | ||||
|   return frame; | ||||
| 
 | ||||
| } // DCF77_Frame()
 | ||||
| 
 | ||||
| #endif // HAS_DCF77
 | ||||
							
								
								
									
										109
									
								
								src/display.cpp
									
									
									
									
									
								
							
							
						
						
									
										109
									
								
								src/display.cpp
									
									
									
									
									
								
							| @ -12,8 +12,8 @@ Display-Mask (128 x 64 pixel): | ||||
| 1|PAX:aabbccdd            LARGE | ||||
| 2| | ||||
| 3|WIFI:abcde BLTH:abcde   SMALL | ||||
| 4|Batt:abc%  chan:ab      SMALL | ||||
| 5|RLIM:abcd  Mem:abcdKB   SMALL | ||||
| 4|Batt:abc% chan:ab       SMALL | ||||
| 5|RLIM:abcd Mem:abcdeKB   SMALL | ||||
| 6|27.Feb 2019 20:27:00*   SMALL | ||||
| 7|yyyyyyyyyyyyy xx SFab   SMALL | ||||
| 
 | ||||
| @ -50,15 +50,15 @@ static QRCode qrcode; | ||||
| #if (HAS_DISPLAY) == 1 | ||||
| ONE_BIT_DISPLAY *dp = NULL; | ||||
| #elif (HAS_DISPLAY) == 2 | ||||
| TFT_eSPI *dp = NULL; | ||||
| BB_SPI_LCD *dp = NULL; | ||||
| #else | ||||
| #error Unknown display type specified in hal file | ||||
| #endif | ||||
| #endif | ||||
| 
 | ||||
| void dp_setup(int contrast) { | ||||
| 
 | ||||
| #if (HAS_DISPLAY) == 1 // I2C OLED
 | ||||
| 
 | ||||
|   dp = new ONE_BIT_DISPLAY; | ||||
|   dp->setI2CPins(MY_DISPLAY_SDA, MY_DISPLAY_SCL, MY_DISPLAY_RST); | ||||
|   dp->setBitBang(false); | ||||
| @ -68,35 +68,33 @@ void dp_setup(int contrast) { | ||||
|   dp->setRotation( | ||||
|       MY_DISPLAY_FLIP ? 2 : 0); // 0 = no rotation, 1 = 90°, 2 = 180°, 3 = 280°
 | ||||
| 
 | ||||
| #elif (HAS_DISPLAY) == 2 // SPI TFT
 | ||||
|   dp = new TFT_eSPI(MY_DISPLAY_WIDTH, MY_DISPLAY_HEIGHT); | ||||
|   dp->init(); | ||||
|   dp->setRotation(MY_DISPLAY_FLIP ? 3 : 1); | ||||
|   dp->invertDisplay(MY_DISPLAY_INVERT ? true : false); | ||||
| #elif (HAS_DISPLAY) == 2        // SPI TFT
 | ||||
| 
 | ||||
|   dp = new BB_SPI_LCD; | ||||
|   dp->begin(TFT_TYPE, FLAGS_NONE, TFT_FREQUENCY, TFT_CS, TFT_DC, TFT_RST, | ||||
|             TFT_BL, TFT_MISO, TFT_MOSI, TFT_SCLK); | ||||
|   dp->allocBuffer(); // render all outputs to lib internal backbuffer
 | ||||
|   dp->setRotation( | ||||
|       MY_DISPLAY_FLIP ? 1 : 3); // 0 = no rotation, 1 = 90°, 2 = 180°, 3 = 280°
 | ||||
|   // dp->invertDisplay(MY_DISPLAY_INVERT ? true : false);
 | ||||
|   // dp->setTextWrap(false);
 | ||||
|   dp->setTextColor(MY_DISPLAY_FGCOLOR, MY_DISPLAY_BGCOLOR); | ||||
| 
 | ||||
| #endif | ||||
| 
 | ||||
|   // clear display
 | ||||
|   dp_clear(); | ||||
|   if (contrast) | ||||
|     dp_contrast(contrast); | ||||
| } | ||||
| 
 | ||||
| void dp_init(bool verbose) { | ||||
| 
 | ||||
|   dp_setup(DISPLAYCONTRAST); | ||||
| 
 | ||||
|   // show chip information
 | ||||
|   if (verbose) { | ||||
| 
 | ||||
|     // show startup screen
 | ||||
|     // to come -> display .bmp file with logo
 | ||||
| 
 | ||||
| // show chip information
 | ||||
| #if (VERBOSE) | ||||
|     esp_chip_info_t chip_info; | ||||
|     esp_chip_info(&chip_info); | ||||
| 
 | ||||
|     dp_setFont(MY_FONT_NORMAL); | ||||
|     dp->printf("** PAXCOUNTER **\r\n"); | ||||
|     dp->printf("Software v%s\r\n", PROGVERSION); | ||||
| @ -107,8 +105,6 @@ void dp_init(bool verbose) { | ||||
|                (chip_info.features & CHIP_FEATURE_BLE) ? "/BLE" : ""); | ||||
|     dp->printf("%dMB %s Flash", spi_flash_get_chip_size() / (1024 * 1024), | ||||
|                (chip_info.features & CHIP_FEATURE_EMB_FLASH) ? "int." : "ext."); | ||||
| 
 | ||||
|     // give user some time to read or take picture
 | ||||
|     dp_dump(); | ||||
|     delay(2000); | ||||
|     dp_clear(); | ||||
| @ -142,17 +138,14 @@ void dp_init(bool verbose) { | ||||
| #endif | ||||
| 
 | ||||
| #endif // HAS_LORA
 | ||||
| 
 | ||||
|   } // verbose
 | ||||
| 
 | ||||
|   dp_power(cfg.screenon); // set display off if disabled
 | ||||
| 
 | ||||
| } // dp_init
 | ||||
| 
 | ||||
| // write display content to display buffer
 | ||||
| // nextpage = true -> flip 1 page
 | ||||
| void dp_refresh(bool nextPage) { | ||||
| 
 | ||||
|   struct count_payload_t count; // libpax count storage
 | ||||
|   static uint8_t DisplayPage = 0; | ||||
|   char timeState, strftime_buf[64]; | ||||
| @ -188,7 +181,6 @@ void dp_refresh(bool nextPage) { | ||||
|     dp->setCursor(0, 0); | ||||
| 
 | ||||
|   switch (DisplayPage) { | ||||
| 
 | ||||
|     // page 0: pax + parameters overview
 | ||||
|     // page 1: pax + lorawan parameters
 | ||||
|     // page 2: pax + GPS lat/lon
 | ||||
| @ -203,7 +195,7 @@ void dp_refresh(bool nextPage) { | ||||
|     // show pax
 | ||||
|     libpax_counter_count(&count); | ||||
|     dp_setFont(MY_FONT_LARGE); | ||||
|     dp->printf("%-8d", count.pax); | ||||
|     dp->printf("%-8u", count.pax); | ||||
| 
 | ||||
|     dp_setFont(MY_FONT_SMALL); | ||||
|     dp->setCursor(0, MY_DISPLAY_FIRSTLINE); | ||||
| @ -213,21 +205,21 @@ void dp_refresh(bool nextPage) { | ||||
| 
 | ||||
| #if ((WIFICOUNTER) && (BLECOUNTER)) | ||||
|     if (cfg.wifiscan) | ||||
|       dp->printf("WIFI:%-5d", count.wifi_count); | ||||
|       dp->printf("WIFI:%-5u", count.wifi_count); | ||||
|     else | ||||
|       dp->printf("WIFI:off"); | ||||
|     if (cfg.blescan) | ||||
|       dp->printf("BLTH:%-5d", count.ble_count); | ||||
|       dp->printf("BLTH:%-5u", count.ble_count); | ||||
|     else | ||||
|       dp->printf(" BLTH:off"); | ||||
| #elif ((WIFICOUNTER) && (!BLECOUNTER)) | ||||
|     if (cfg.wifiscan) | ||||
|       dp->printf("WIFI:%-5d", count.wifi_count); | ||||
|       dp->printf("WIFI:%-5u", count.wifi_count); | ||||
|     else | ||||
|       dp->printf("WIFI:off"); | ||||
| #elif ((!WIFICOUNTER) && (BLECOUNTER)) | ||||
|     if (cfg.blescan) | ||||
|       dp->printf("BLTH:%-5d", count.ble_count); | ||||
|       dp->printf("BLTH:%-5u", count.ble_count); | ||||
|     dp->printf("BLTH:off"); | ||||
| #else | ||||
|     dp->printf("Sniffer disabled"); | ||||
| @ -247,9 +239,9 @@ void dp_refresh(bool nextPage) { | ||||
|     dp->printf("chan:%02u\r\n", channel); | ||||
| 
 | ||||
|     // line 5: RSSI limiter + free memory
 | ||||
|     // RLIM:abcd  Mem:abcdKB
 | ||||
|     // RLIM:abcd Mem:abcdKB
 | ||||
|     dp->printf(!cfg.rssilimit ? "RLIM:off " : "RLIM:%-4d", cfg.rssilimit); | ||||
|     dp->printf("  Mem:%4dKB\r\n", getFreeRAM() / 1024); | ||||
|     dp->printf(" Mem:%uKB\r\n", getFreeRAM() / 1024); | ||||
| 
 | ||||
|     // line 6: time + date
 | ||||
|     // Wed Jan 12 21:49:08 *
 | ||||
| @ -300,15 +292,15 @@ void dp_refresh(bool nextPage) { | ||||
|     // show pax
 | ||||
|     libpax_counter_count(&count); | ||||
|     dp_setFont(MY_FONT_LARGE); | ||||
|     dp->printf("%-8d", count.pax); | ||||
|     dp->printf("%-8u", count.pax); | ||||
| 
 | ||||
|     dp_setFont(MY_FONT_SMALL); | ||||
|     dp->setCursor(0, MY_DISPLAY_FIRSTLINE); | ||||
|     dp->printf("Net:%06X   Pwr:%-2d\r\n", LMIC.netid & 0x001FFFFF, | ||||
|     dp->printf("Net:%06X   Pwr:%2u\r\n", LMIC.netid & 0x001FFFFF, | ||||
|                LMIC.radio_txpow); | ||||
|     dp->printf("Dev:%08X DR:%1d\r\n", LMIC.devaddr, LMIC.datarate); | ||||
|     dp->printf("Dev:%08X DR:%1u\r\n", LMIC.devaddr, LMIC.datarate); | ||||
|     dp->printf("ChMsk:%04X Nonce:%04X\r\n", LMIC.channelMap, LMIC.devNonce); | ||||
|     dp->printf("fUp:%-6d fDn:%-6d\r\n", LMIC.seqnoUp ? LMIC.seqnoUp - 1 : 0, | ||||
|     dp->printf("fUp:%-6u fDn:%-6u\r\n", LMIC.seqnoUp ? LMIC.seqnoUp - 1 : 0, | ||||
|                LMIC.seqnoDn ? LMIC.seqnoDn - 1 : 0); | ||||
|     dp->printf("SNR:%-5d  RSSI:%-5d", (LMIC.snr + 2) / 4, LMIC.rssi); | ||||
| 
 | ||||
| @ -327,7 +319,7 @@ void dp_refresh(bool nextPage) { | ||||
|     // show pax
 | ||||
|     libpax_counter_count(&count); | ||||
|     dp_setFont(MY_FONT_LARGE); | ||||
|     dp->printf("%-8d", count.pax); | ||||
|     dp->printf("%-8u", count.pax); | ||||
| 
 | ||||
|     // show satellite status at bottom line
 | ||||
|     dp_setFont(MY_FONT_SMALL); | ||||
| @ -382,7 +374,7 @@ void dp_refresh(bool nextPage) { | ||||
|     strftime(strftime_buf, sizeof(strftime_buf), "%T", &timeinfo); | ||||
|     dp->printf("%.8s\r\n", strftime_buf); | ||||
|     dp_setFont(MY_FONT_SMALL); | ||||
|     dp->printf("%21.1f", uptime() / 1000.0); | ||||
|     dp->printf("%-12.1f", uptime() / 1000.0); | ||||
|     dp_dump(); | ||||
|     break; | ||||
| 
 | ||||
| @ -404,59 +396,28 @@ void dp_refresh(bool nextPage) { | ||||
|     DisplayPage++; | ||||
|     break; | ||||
| #endif | ||||
| 
 | ||||
|   } // switch (page)
 | ||||
| } // dp_refresh
 | ||||
| 
 | ||||
| // ------------- display helper functions -----------------
 | ||||
| 
 | ||||
| void dp_setFont(int font, int inv) { | ||||
| 
 | ||||
|   // handle invers printing
 | ||||
|   dp->setFont(font); | ||||
|   if (inv) | ||||
|     dp->setTextColor(MY_DISPLAY_BGCOLOR, MY_DISPLAY_FGCOLOR); | ||||
|   else | ||||
|     dp->setTextColor(MY_DISPLAY_FGCOLOR, MY_DISPLAY_BGCOLOR); | ||||
| 
 | ||||
| #if (HAS_DISPLAY) == 1 | ||||
|   // set desired font
 | ||||
|   dp->setFont(font); | ||||
| #elif (HAS_DISPLAY) == 2 | ||||
|   // map desired oled font to tft font
 | ||||
|   switch (font) { | ||||
|   case MY_FONT_STRETCHED: // 16x16 on OLED
 | ||||
|   case MY_FONT_LARGE:     // 16x32 on OLED
 | ||||
|     dp->setTextFont(4);   // 26px
 | ||||
|     break; | ||||
|   case MY_FONT_SMALL:  // 6x8 on OLED
 | ||||
|   case MY_FONT_NORMAL: // 8x8 on OLED
 | ||||
|   default: | ||||
|     dp->setTextFont(2); // 16px
 | ||||
|     break; | ||||
|   } | ||||
| 
 | ||||
| #endif | ||||
| } | ||||
| 
 | ||||
| void dp_dump(uint8_t *pBuffer) { | ||||
| #if (HAS_DISPLAY) == 1 | ||||
|   if (pBuffer) | ||||
|     memcpy(dp->getBuffer(), pBuffer, PLOTBUFFERSIZE); | ||||
|   dp->display(); | ||||
| #elif (HAS_DISPLAY) == 2 | ||||
|   if (pBuffer) | ||||
|     dp->drawBitmap(0, 0, pBuffer, MY_DISPLAY_WIDTH, MY_DISPLAY_HEIGHT, | ||||
|                    MY_DISPLAY_FGCOLOR); | ||||
| #endif | ||||
| } | ||||
| 
 | ||||
| void dp_clear(void) { | ||||
| #if (HAS_DISPLAY) == 1 | ||||
|   dp->fillScreen(MY_DISPLAY_BGCOLOR); | ||||
|   dp->display(); | ||||
| #elif (HAS_DISPLAY) == 2 | ||||
|   dp->fillScreen(MY_DISPLAY_BGCOLOR); | ||||
| #endif | ||||
|   dp->setCursor(0, 0); | ||||
| } | ||||
| 
 | ||||
| @ -485,14 +446,6 @@ void dp_shutdown(void) { | ||||
| #endif | ||||
| } | ||||
| 
 | ||||
| // print static message on display
 | ||||
| void dp_message(const char *msg, int line, bool invers) { | ||||
|   dp_setFont(MY_FONT_SMALL, invers ? 1 : 0); | ||||
|   dp->setCursor(0, line * 8); | ||||
|   dp->printf("%-16s", msg); | ||||
|   dp_dump(); | ||||
| } // dp_message
 | ||||
| 
 | ||||
| // ------------- QR code plotter -----------------
 | ||||
| 
 | ||||
| void dp_printqr(uint16_t offset_x, uint16_t offset_y, const char *Message) { | ||||
| @ -523,7 +476,6 @@ void dp_printqr(uint16_t offset_x, uint16_t offset_y, const char *Message) { | ||||
| 
 | ||||
| int dp_drawPixel(uint8_t *buf, const uint16_t x, const uint16_t y, | ||||
|                  const uint8_t dot) { | ||||
| 
 | ||||
|   if (x > MY_DISPLAY_WIDTH || y > MY_DISPLAY_HEIGHT) | ||||
|     return -1; | ||||
| 
 | ||||
| @ -541,7 +493,6 @@ int dp_drawPixel(uint8_t *buf, const uint16_t x, const uint16_t y, | ||||
| 
 | ||||
| void dp_scrollHorizontal(uint8_t *buf, const uint16_t width, | ||||
|                          const uint16_t height, bool left) { | ||||
| 
 | ||||
|   uint16_t col, page, idx = 0; | ||||
| 
 | ||||
|   for (page = 0; page < height / 8; page++) { | ||||
| @ -564,7 +515,6 @@ void dp_scrollHorizontal(uint8_t *buf, const uint16_t width, | ||||
| 
 | ||||
| void dp_scrollVertical(uint8_t *buf, const uint16_t width, | ||||
|                        const uint16_t height, int offset) { | ||||
| 
 | ||||
|   uint64_t buf_col; | ||||
| 
 | ||||
|   if (!offset) | ||||
| @ -587,7 +537,6 @@ void dp_scrollVertical(uint8_t *buf, const uint16_t width, | ||||
| // ------------- curve plotter -----------------
 | ||||
| 
 | ||||
| void dp_plotCurve(uint16_t count, bool reset) { | ||||
| 
 | ||||
|   static uint16_t last_count = 0, col = 0, row = 0; | ||||
|   uint16_t v_scroll = 0; | ||||
| 
 | ||||
|  | ||||
| @ -28,9 +28,6 @@ | ||||
| #define CFG_sx1276_radio 1 // select LoRa chip
 | ||||
| #define DISABLE_BROWNOUT 1 // comment out if you want to keep brownout feature
 | ||||
| 
 | ||||
| #define HAS_DISPLAY 2 // TFT-LCD, support work in progess, not ready yet
 | ||||
| //#define MY_DISPLAY_FLIP  1 // use if display is rotated
 | ||||
| 
 | ||||
| #define HAS_LED NOT_A_PIN // no on board LED (?)
 | ||||
| #define HAS_BUTTON (39) // on board button A
 | ||||
| 
 | ||||
| @ -44,38 +41,22 @@ | ||||
| // GPS settings
 | ||||
| #define HAS_GPS 1 // use on board GPS
 | ||||
| #define GPS_SERIAL 9600, SERIAL_8N1, RXD2, TXD2 // UBlox NEO 6M RX, TX
 | ||||
| #define GPS_INT GPIO_NUM_35 // 30ns accurary timepulse, to be external wired on pcb: shorten R12!
 | ||||
| #define GPS_INT  | ||||
| 
 | ||||
| // Display Settings
 | ||||
| #define HAS_DISPLAY 2   // TFT-LCD
 | ||||
| //#define MY_DISPLAY_FLIP  1 // use if display is rotated
 | ||||
| #define MY_DISPLAY_WIDTH 320 | ||||
| #define MY_DISPLAY_HEIGHT 240 | ||||
| #define MY_DISPLAY_INVERT 1 | ||||
| 
 | ||||
| // setting for M5 display
 | ||||
| #define USER_SETUP_LOADED 1 | ||||
| #define ILI9341_DRIVER 1 | ||||
| #define M5STACK // needed for TFT driver
 | ||||
| 
 | ||||
| #define TFT_MISO MISO  // SPI
 | ||||
| #define TFT_MOSI MOSI // SPI
 | ||||
| #define TFT_SCLK SCK  // SPI
 | ||||
| #define TFT_CS   GPIO_NUM_14  // Chip select control
 | ||||
| #define TFT_DC   GPIO_NUM_27  // Data Command control
 | ||||
| #define TFT_RST  GPIO_NUM_33  // Reset
 | ||||
| #define TFT_BL   GPIO_NUM_32  // LED back-light
 | ||||
| 
 | ||||
| #define TFT_RGB_ORDER TFT_BGR  // Colour order Blue-Green-Red
 | ||||
| 
 | ||||
| //#define LOAD_GLCD   // Font 1. Original Adafruit 8 pixel font needs ~1820 bytes in FLASH
 | ||||
| #define LOAD_FONT2  // Font 2. Small 16 pixel high font, needs ~3534 bytes in FLASH, 96 characters
 | ||||
| #define LOAD_FONT4  // Font 4. Medium 26 pixel high font, needs ~5848 bytes in FLASH, 96 characters
 | ||||
| //#define LOAD_FONT6  // Font 6. Large 48 pixel font, needs ~2666 bytes in FLASH, only characters 1234567890:-.apm
 | ||||
| //#define LOAD_FONT7  // Font 7. 7 segment 48 pixel font, needs ~2438 bytes in FLASH, only characters 1234567890:-.
 | ||||
| //#define LOAD_FONT8  // Font 8. Large 75 pixel font needs ~3256 bytes in FLASH, only characters 1234567890:-.
 | ||||
| //#define LOAD_FONT8N // Font 8. Alternative to Font 8 above, slightly narrower, so 3 digits fit a 160 pixel TFT
 | ||||
| //#define LOAD_GFXFF  // FreeFonts. Include access to the 48 Adafruit_GFX free fonts FF1 to FF48 and custom fonts
 | ||||
| #define SMOOTH_FONT | ||||
| 
 | ||||
| #define SPI_FREQUENCY  40000000 | ||||
| #define TFT_TYPE LCD_ILI9341 | ||||
| #define TFT_MOSI MOSI   // SPI
 | ||||
| #define TFT_MISO MISO   // SPI
 | ||||
| #define TFT_SCLK SCK    // SPI
 | ||||
| #define TFT_CS   GPIO_NUM_14    // Chip select control
 | ||||
| #define TFT_DC   GPIO_NUM_27    // Data Command control
 | ||||
| #define TFT_RST  GPIO_NUM_33    // Reset
 | ||||
| #define TFT_BL   GPIO_NUM_32    // LED back-light
 | ||||
| #define TFT_FREQUENCY 40000000 | ||||
| 
 | ||||
| #endif | ||||
|  | ||||
| @ -20,7 +20,6 @@ | ||||
| #define LORA_IO1  GPIO_NUM_34 // must be wired by you on PCB!
 | ||||
| #define LORA_IO2  LMIC_UNUSED_PIN | ||||
| 
 | ||||
| 
 | ||||
| // enable only if you want to store a local paxcount table on the device
 | ||||
| #define HAS_SDCARD  1      // this board has an SD-card-reader/writer
 | ||||
| #define SDCARD_CS    GPIO_NUM_4 | ||||
| @ -31,9 +30,6 @@ | ||||
| #define CFG_sx1276_radio 1 // select LoRa chip
 | ||||
| #define DISABLE_BROWNOUT 1 // comment out if you want to keep brownout feature
 | ||||
| 
 | ||||
| #define HAS_DISPLAY 2 // TFT-LCD, support work in progess, not ready yet
 | ||||
| //#define MY_DISPLAY_FLIP  1 // use if display is rotated
 | ||||
| 
 | ||||
| #define HAS_LED NOT_A_PIN // no on board LED (?)
 | ||||
| #define RGB_LED_COUNT 10 | ||||
| 
 | ||||
| @ -53,35 +49,19 @@ | ||||
| // #define GPS_INT GPIO_NUM_35 // 30ns accurary timepulse, to be external wired on pcb: shorten R12!
 | ||||
| 
 | ||||
| // Display Settings
 | ||||
| #define HAS_DISPLAY 2   // TFT-LCD
 | ||||
| //#define MY_DISPLAY_FLIP  1 // use if display is rotated
 | ||||
| #define MY_DISPLAY_WIDTH 320 | ||||
| #define MY_DISPLAY_HEIGHT 240 | ||||
| #define MY_DISPLAY_INVERT 1 | ||||
| 
 | ||||
| // setting for M5 display
 | ||||
| #define USER_SETUP_LOADED 1 | ||||
| #define ILI9341_DRIVER 1 | ||||
| #define M5STACK // needed for TFT driver
 | ||||
| 
 | ||||
| #define TFT_MISO MISO  // SPI
 | ||||
| #define TFT_MOSI MOSI // SPI
 | ||||
| #define TFT_SCLK SCK  // SPI
 | ||||
| #define TFT_CS   GPIO_NUM_14  // Chip select control
 | ||||
| #define TFT_DC   GPIO_NUM_27  // Data Command control
 | ||||
| #define TFT_RST  GPIO_NUM_33  // Reset
 | ||||
| #define TFT_BL   GPIO_NUM_32  // LED back-light
 | ||||
| 
 | ||||
| #define TFT_RGB_ORDER TFT_BGR  // Colour order Blue-Green-Red
 | ||||
| 
 | ||||
| //#define LOAD_GLCD   // Font 1. Original Adafruit 8 pixel font needs ~1820 bytes in FLASH
 | ||||
| #define LOAD_FONT2  // Font 2. Small 16 pixel high font, needs ~3534 bytes in FLASH, 96 characters
 | ||||
| #define LOAD_FONT4  // Font 4. Medium 26 pixel high font, needs ~5848 bytes in FLASH, 96 characters
 | ||||
| //#define LOAD_FONT6  // Font 6. Large 48 pixel font, needs ~2666 bytes in FLASH, only characters 1234567890:-.apm
 | ||||
| //#define LOAD_FONT7  // Font 7. 7 segment 48 pixel font, needs ~2438 bytes in FLASH, only characters 1234567890:-.
 | ||||
| //#define LOAD_FONT8  // Font 8. Large 75 pixel font needs ~3256 bytes in FLASH, only characters 1234567890:-.
 | ||||
| //#define LOAD_FONT8N // Font 8. Alternative to Font 8 above, slightly narrower, so 3 digits fit a 160 pixel TFT
 | ||||
| //#define LOAD_GFXFF  // FreeFonts. Include access to the 48 Adafruit_GFX free fonts FF1 to FF48 and custom fonts
 | ||||
| #define SMOOTH_FONT | ||||
| 
 | ||||
| #define SPI_FREQUENCY  40000000 | ||||
| #define TFT_TYPE LCD_ILI9341 | ||||
| #define TFT_MOSI MOSI   // SPI
 | ||||
| #define TFT_MISO MISO   // SPI
 | ||||
| #define TFT_SCLK SCK    // SPI
 | ||||
| #define TFT_CS   GPIO_NUM_14    // Chip select control
 | ||||
| #define TFT_DC   GPIO_NUM_27    // Data Command control
 | ||||
| #define TFT_RST  GPIO_NUM_33    // Reset
 | ||||
| #define TFT_BL   GPIO_NUM_32    // LED back-light
 | ||||
| #define TFT_FREQUENCY 40000000 | ||||
| 
 | ||||
| #endif | ||||
| @ -34,19 +34,14 @@ Reset -> reset device | ||||
| 
 | ||||
| // power management settings
 | ||||
| #define HAS_PMU 1 // has AXP192 chip
 | ||||
| #define XPOWERS_CHIP_AXP192 1 | ||||
| #define PMU_INT GPIO_NUM_35 // battery interrupt
 | ||||
| #define PMU_CHG_CURRENT AXP1XX_CHARGE_CUR_1000MA // battery charge current
 | ||||
| #define PMU_CHG_CURRENT XPOWERS_CHG_CUR_1000MA // battery charge current
 | ||||
| // possible values (mA):
 | ||||
| // 100/190/280/360/450/550/630/700/780/880/960/1000/1080/1160/1240/1320
 | ||||
| #define PMU_CHG_CUTOFF AXP202_TARGET_VOL_4_2V // battery charge cutoff
 | ||||
| #define PMU_CHG_CUTOFF XPOWERS_CHG_VOL_4V2 // battery charge cutoff
 | ||||
| // possible values (V):
 | ||||
| // 4_1/4_15/4_2/4_36
 | ||||
| 
 | ||||
| // blue onboard led settings
 | ||||
| // possible values: 
 | ||||
| // AXP20X_LED_OFF / AXP20X_LED_LOW_LEVEL (means LED ON) / AXP20X_LED_BLINK_1HZ / AXP20X_LED_BLINK_4HZ
 | ||||
| #define PMU_LED_RUN_MODE AXP20X_LED_LOW_LEVEL  | ||||
| #define PMU_LED_SLEEP_MODE AXP20X_LED_OFF | ||||
| // 4V1/4V15/4V2/4V36
 | ||||
| 
 | ||||
| // GPS settings
 | ||||
| #define HAS_GPS 1 // use on board GPS
 | ||||
|  | ||||
| @ -9,9 +9,6 @@ | ||||
| 
 | ||||
| #define DISABLE_BROWNOUT 1 // comment out if you want to keep brownout feature
 | ||||
| 
 | ||||
| #define HAS_DISPLAY 2      // TFT-LCD, support work in progess, not ready yet
 | ||||
| #define MY_DISPLAY_FLIP  1 // use if display is rotated
 | ||||
| 
 | ||||
| #define HAS_LED NOT_A_PIN  // no on board LED (?)
 | ||||
| #define HAS_BUTTON (35)    // on board button A
 | ||||
| 
 | ||||
| @ -20,36 +17,19 @@ | ||||
| #define BAT_VOLTAGE_DIVIDER 2.605f           // voltage divider
 | ||||
| 
 | ||||
| // Display Settings
 | ||||
| #define HAS_DISPLAY 2       // TFT-LCD
 | ||||
| #define MY_DISPLAY_FLIP  1  // use if display is rotated
 | ||||
| #define MY_DISPLAY_WIDTH 135 | ||||
| #define MY_DISPLAY_HEIGHT 240 | ||||
| #define MY_DISPLAY_INVERT 1 | ||||
| 
 | ||||
| // setting for TTGO T-display
 | ||||
| #define USER_SETUP_LOADED 1 | ||||
| #define ST7789_DRIVER 1 | ||||
| 
 | ||||
| #define CGRAM_OFFSET | ||||
| 
 | ||||
| #define TFT_TYPE LCD_ST7789_135 // size 135x240 px
 | ||||
| #define TFT_MOSI GPIO_NUM_19 // SPI
 | ||||
| #define TFT_MISO NOT_A_PIN   // SPI
 | ||||
| #define TFT_SCLK GPIO_NUM_18 // SPI
 | ||||
| #define TFT_CS   GPIO_NUM_5  // Chip select control
 | ||||
| #define TFT_DC   GPIO_NUM_16 // Data Command control
 | ||||
| #define TFT_RST  GPIO_NUM_23 // Reset
 | ||||
| #define TFT_BL   GPIO_NUM_4  // LED back-light
 | ||||
| 
 | ||||
| #define TFT_RGB_ORDER TFT_BGR  // Colour order Blue-Green-Red
 | ||||
| 
 | ||||
| #define LOAD_GLCD   // Font 1. Original Adafruit 8 pixel font needs ~1820 bytes in FLASH
 | ||||
| #define LOAD_FONT2  // Font 2. Small 16 pixel high font, needs ~3534 bytes in FLASH, 96 characters
 | ||||
| #define LOAD_FONT4  // Font 4. Medium 26 pixel high font, needs ~5848 bytes in FLASH, 96 characters
 | ||||
| #define LOAD_FONT6  // Font 6. Large 48 pixel font, needs ~2666 bytes in FLASH, only characters 1234567890:-.apm
 | ||||
| #define LOAD_FONT7  // Font 7. 7 segment 48 pixel font, needs ~2438 bytes in FLASH, only characters 1234567890:-.
 | ||||
| #define LOAD_FONT8  // Font 8. Large 75 pixel font needs ~3256 bytes in FLASH, only characters 1234567890:-.
 | ||||
| //#define LOAD_FONT8N // Font 8. Alternative to Font 8 above, slightly narrower, so 3 digits fit a 160 pixel TFT
 | ||||
| #define LOAD_GFXFF  // FreeFonts. Include access to the 48 Adafruit_GFX free fonts FF1 to FF48 and custom fonts
 | ||||
| #define SMOOTH_FONT | ||||
| 
 | ||||
| #define SPI_FREQUENCY  40000000 | ||||
| #define SPI_READ_FREQUENCY 6000000 | ||||
| #define TFT_FREQUENCY 40000000 | ||||
| 
 | ||||
| #endif | ||||
|  | ||||
| @ -9,9 +9,6 @@ | ||||
| 
 | ||||
| #define DISABLE_BROWNOUT 1 // comment out if you want to keep brownout feature
 | ||||
| 
 | ||||
| #define HAS_DISPLAY 2      // TFT-LCD, support work in progess, not ready yet
 | ||||
| #define MY_DISPLAY_FLIP  1 // use if display is rotated
 | ||||
| 
 | ||||
| #define HAS_LED NOT_A_PIN  // no on board LED (?)
 | ||||
| #define HAS_BUTTON (33)    // on board button A
 | ||||
| 
 | ||||
| @ -20,39 +17,20 @@ | ||||
| #define BAT_VOLTAGE_DIVIDER 2.605f           // voltage divider
 | ||||
| 
 | ||||
| // Display Settings
 | ||||
| #define HAS_DISPLAY 2      // TFT-LCD
 | ||||
| #define MY_DISPLAY_FLIP  1 // use if display is rotated
 | ||||
| #define MY_DISPLAY_WIDTH 80 | ||||
| #define MY_DISPLAY_HEIGHT 160 | ||||
| #define MY_DISPLAY_INVERT 1 | ||||
| 
 | ||||
| // setting for TTGO T-display
 | ||||
| #define USER_SETUP_LOADED 1 | ||||
| #define ST7735_DRIVER 1 | ||||
| 
 | ||||
| #define CGRAM_OFFSET | ||||
| 
 | ||||
| #define TFT_MISO -1 | ||||
| #define TFT_TYPE LCD_ST7735S | ||||
| #define TFT_MOSI GPIO_NUM_19 // SPI
 | ||||
| #define TFT_MISO NOT_A_PIN   // SPI
 | ||||
| #define TFT_SCLK GPIO_NUM_18 // SPI
 | ||||
| #define TFT_CS   GPIO_NUM_5  // Chip select control
 | ||||
| #define TFT_DC   GPIO_NUM_23 // Data Command control
 | ||||
| #define TFT_RST  GPIO_NUM_26 // Reset
 | ||||
| #define TFT_BL   GPIO_NUM_27 // LED back-light
 | ||||
| #define TFT_BACKLIGHT_ON 1 | ||||
| #define ST7735_GREENTAB160x80 | ||||
| 
 | ||||
| #define TFT_RGB_ORDER TFT_BGR  // Colour order Blue-Green-Red
 | ||||
| 
 | ||||
| #define LOAD_GLCD   // Font 1. Original Adafruit 8 pixel font needs ~1820 bytes in FLASH
 | ||||
| #define LOAD_FONT2  // Font 2. Small 16 pixel high font, needs ~3534 bytes in FLASH, 96 characters
 | ||||
| #define LOAD_FONT4  // Font 4. Medium 26 pixel high font, needs ~5848 bytes in FLASH, 96 characters
 | ||||
| #define LOAD_FONT6  // Font 6. Large 48 pixel font, needs ~2666 bytes in FLASH, only characters 1234567890:-.apm
 | ||||
| #define LOAD_FONT7  // Font 7. 7 segment 48 pixel font, needs ~2438 bytes in FLASH, only characters 1234567890:-.
 | ||||
| #define LOAD_FONT8  // Font 8. Large 75 pixel font needs ~3256 bytes in FLASH, only characters 1234567890:-.
 | ||||
| #define LOAD_GFXFF  // FreeFonts. Include access to the 48 Adafruit_GFX free fonts FF1 to FF48 and custom fonts
 | ||||
| #define SMOOTH_FONT | ||||
| 
 | ||||
| #define SPI_FREQUENCY  27000000 | ||||
| #define SPI_READ_FREQUENCY 6000000 | ||||
| #define TFT_FREQUENCY 27000000 | ||||
| 
 | ||||
| #endif | ||||
| 
 | ||||
|  | ||||
| @ -15,7 +15,6 @@ void i2c_init(void) { | ||||
| void i2c_deinit(void) { Wire.end(); } | ||||
| 
 | ||||
| void i2c_scan(void) { | ||||
| 
 | ||||
|   // parts of the code in this function were taken from:
 | ||||
|   //
 | ||||
|   // Copyright (c) 2019 BitBank Software, Inc.
 | ||||
| @ -78,7 +77,6 @@ void i2c_scan(void) { | ||||
| 
 | ||||
| // functions for i2c r/w access, mutexing is done by Wire.cpp
 | ||||
| int i2c_readBytes(uint8_t addr, uint8_t reg, uint8_t *data, uint8_t len) { | ||||
| 
 | ||||
|   uint8_t ret = 0; | ||||
|   Wire.beginTransmission(addr); | ||||
|   Wire.write(reg); | ||||
| @ -100,7 +98,6 @@ finish: | ||||
| } | ||||
| 
 | ||||
| int i2c_writeBytes(uint8_t addr, uint8_t reg, uint8_t *data, uint8_t len) { | ||||
| 
 | ||||
|   uint8_t ret = 0; | ||||
|   Wire.beginTransmission(addr); | ||||
|   Wire.write(reg); | ||||
| @ -110,4 +107,4 @@ int i2c_writeBytes(uint8_t addr, uint8_t reg, uint8_t *data, uint8_t len) { | ||||
|   ret = Wire.endTransmission(); | ||||
| 
 | ||||
|   return ret ? ret : 0xFF; | ||||
| } | ||||
| } | ||||
| @ -85,7 +85,6 @@ not evaluated by model BU-190, use "F" instead for this model | ||||
| static const char TAG[] = __FILE__; | ||||
| 
 | ||||
| String IF482_Frame(time_t t) { | ||||
| 
 | ||||
|   char mon, out[IF482_FRAME_SIZE + 1], buf[IF482_FRAME_SIZE - 3]; | ||||
| 
 | ||||
|   if (sntp_get_sync_status() == SNTP_SYNC_STATUS_IN_PROGRESS) | ||||
|  | ||||
| @ -7,7 +7,6 @@ TaskHandle_t irqHandlerTask = NULL; | ||||
| 
 | ||||
| // irq handler task, handles all our application level interrupts
 | ||||
| void irqHandler(void *pvParameters) { | ||||
| 
 | ||||
|   _ASSERT((uint32_t)pvParameters == 1); // FreeRTOS check
 | ||||
| 
 | ||||
|   uint32_t irqSource; | ||||
|  | ||||
| @ -158,7 +158,6 @@ void ledLoop(void *parameter) { | ||||
|       } | ||||
|       // No custom blink, check LoRaWAN state
 | ||||
|     } else { | ||||
| 
 | ||||
| #if (HAS_LORA) | ||||
|       // LED indicators for viusalizing LoRaWAN state
 | ||||
|       if (LMIC.opmode & (OP_JOINING | OP_REJOIN)) { | ||||
|  | ||||
| @ -14,7 +14,6 @@ | ||||
|  *********************************************************************/ | ||||
| 
 | ||||
| void setABPParameters() { | ||||
| 
 | ||||
|     /** **************************************************************
 | ||||
|      * ************************************************************* */ | ||||
|     #if defined(CFG_eu868) | ||||
|  | ||||
| @ -84,7 +84,6 @@ static const char TAG[] = __FILE__; | ||||
| char clientId[20] = {0}; // unique ClientID
 | ||||
| 
 | ||||
| void setup() { | ||||
| 
 | ||||
|   char features[100] = ""; | ||||
| 
 | ||||
|   // disable brownout detection
 | ||||
| @ -487,7 +486,6 @@ void setup() { | ||||
|   RTC_runmode = RUNMODE_NORMAL; | ||||
| 
 | ||||
|   vTaskDelete(NULL); | ||||
| 
 | ||||
| } // setup()
 | ||||
| 
 | ||||
| void loop() { vTaskDelete(NULL); } | ||||
|  | ||||
| @ -19,7 +19,6 @@ void mqtt_deinit(void) { | ||||
| } | ||||
| 
 | ||||
| esp_err_t mqtt_init(void) { | ||||
| 
 | ||||
|   // setup network connection and MQTT client
 | ||||
|   ETH.begin(); | ||||
|   ETH.setHostname(clientId); | ||||
| @ -43,7 +42,6 @@ esp_err_t mqtt_init(void) { | ||||
| } | ||||
| 
 | ||||
| int mqtt_connect(const char *my_host, const uint16_t my_port) { | ||||
| 
 | ||||
|   IPAddress mqtt_server_ip; | ||||
| 
 | ||||
|   ESP_LOGI(TAG, "MQTT name is %s", MQTT_CLIENTNAME); | ||||
| @ -75,13 +73,10 @@ int mqtt_connect(const char *my_host, const uint16_t my_port) { | ||||
| } | ||||
| 
 | ||||
| void mqtt_client_task(void *param) { | ||||
| 
 | ||||
|   MessageBuffer_t msg; | ||||
| 
 | ||||
|   while (1) { | ||||
| 
 | ||||
|     if (mqttClient.connected()) { | ||||
| 
 | ||||
|       // check for incoming messages
 | ||||
|       mqttClient.loop(); | ||||
| 
 | ||||
| @ -124,11 +119,10 @@ void mqtt_client_task(void *param) { | ||||
| // process incoming MQTT messages
 | ||||
| void mqtt_callback(MQTTClient *client, char *topic, char *payload, int length) { | ||||
|   if (strcmp(topic, MQTT_INTOPIC) == 0) { | ||||
| 
 | ||||
|     // get length of base64 encoded message
 | ||||
|     size_t out_len = 0; | ||||
|     mbedtls_base64_decode(NULL, 0, &out_len, (unsigned char *)payload, length); | ||||
| 
 | ||||
|      | ||||
|     // decode the base64 message
 | ||||
|     unsigned char decoded[out_len]; | ||||
|     mbedtls_base64_decode(decoded, out_len, &out_len, (unsigned char *)payload, | ||||
|  | ||||
| @ -58,7 +58,6 @@ void PayloadConvert::addConfig(configData_t value) { | ||||
| void PayloadConvert::addStatus(uint16_t voltage, uint64_t uptime, float cputemp, | ||||
|                                uint32_t mem, uint8_t reset0, | ||||
|                                uint32_t restarts) { | ||||
| 
 | ||||
|   buffer[cursor++] = highByte(voltage); | ||||
|   buffer[cursor++] = lowByte(voltage); | ||||
|   buffer[cursor++] = (byte)((uptime & 0xFF00000000000000) >> 56); | ||||
|  | ||||
							
								
								
									
										164
									
								
								src/power.cpp
									
									
									
									
									
								
							
							
						
						
									
										164
									
								
								src/power.cpp
									
									
									
									
									
								
							| @ -23,59 +23,42 @@ static const adc_unit_t unit = ADC_UNIT_1; | ||||
| #endif // BAT_MEASURE_ADC
 | ||||
| 
 | ||||
| #ifdef HAS_PMU | ||||
| AXP20X_Class pmu; | ||||
| XPowersPMU pmu; | ||||
| 
 | ||||
| void AXP192_powerevent_IRQ(void) { | ||||
|   pmu.readIRQ(); | ||||
|   pmu.getIrqStatus(); | ||||
| 
 | ||||
|   if (pmu.isVbusOverVoltageIRQ()) | ||||
|   if (pmu.isVbusOverVoltageIrq()) | ||||
|     ESP_LOGI(TAG, "USB voltage %.2fV too high.", pmu.getVbusVoltage() / 1000); | ||||
|   if (pmu.isVbusPlugInIRQ()) | ||||
|   if (pmu.isVbusInsertIrq()) | ||||
|     ESP_LOGI(TAG, "USB plugged, %.2fV @ %.0mA", pmu.getVbusVoltage() / 1000, | ||||
|              pmu.getVbusCurrent()); | ||||
|   if (pmu.isVbusRemoveIRQ()) | ||||
|   if (pmu.isVbusRemoveIrq()) | ||||
|     ESP_LOGI(TAG, "USB unplugged."); | ||||
| 
 | ||||
|   if (pmu.isBattPlugInIRQ()) | ||||
|   if (pmu.isBatInsertIrq()) | ||||
|     ESP_LOGI(TAG, "Battery is connected."); | ||||
|   if (pmu.isBattRemoveIRQ()) | ||||
|   if (pmu.isBatRemoveIrq()) | ||||
|     ESP_LOGI(TAG, "Battery was removed."); | ||||
|   if (pmu.isChargingIRQ()) | ||||
|     ESP_LOGI(TAG, "Battery charging."); | ||||
|   if (pmu.isChargingDoneIRQ()) { | ||||
|   if (pmu.isBatChagerStartIrq()) | ||||
|     ESP_LOGI(TAG, "Battery charging started."); | ||||
|   if (pmu.isBatChagerDoneIrq()) | ||||
|     ESP_LOGI(TAG, "Battery charging done."); | ||||
| #ifdef PMU_LED_RUN_MODE | ||||
|     pmu.setChgLEDMode(PMU_LED_RUN_MODE); | ||||
| #else | ||||
|     pmu.setChgLEDMode(AXP20X_LED_LOW_LEVEL); | ||||
| #endif | ||||
|   } | ||||
|   if (pmu.isBattTempLowIRQ()) | ||||
|   if (pmu.isBattTempLowIrq()) | ||||
|     ESP_LOGI(TAG, "Battery high temperature."); | ||||
|   if (pmu.isBattTempHighIRQ()) | ||||
|   if (pmu.isBattTempHighIrq()) | ||||
|     ESP_LOGI(TAG, "Battery low temperature."); | ||||
|   if (pmu.isLowVoltageLevel1IRQ()) { | ||||
|     ESP_LOGI(TAG, "Battery has reached voltage level 1."); | ||||
|     pmu.setChgLEDMode(AXP20X_LED_BLINK_4HZ); | ||||
|   } | ||||
|   if (pmu.isLowVoltageLevel2IRQ()) { | ||||
|     ESP_LOGI(TAG, "Battery has reached voltage level 2."); | ||||
|     pmu.setChgLEDMode(AXP20X_LED_BLINK_1HZ); | ||||
|   } | ||||
| 
 | ||||
|   // PEK button handling:
 | ||||
|   // long press -> shutdown power, must be exited by another longpress
 | ||||
|   if (pmu.isPekeyLongPressIrq()) | ||||
|     AXP192_power(pmu_power_off); // switch off Lora, GPS, display
 | ||||
| #ifdef HAS_BUTTON | ||||
|   // short press -> esp32 deep sleep mode, can be exited by pressing user button
 | ||||
|   if (pmu.isPEKShortPressIRQ()) { | ||||
|   // short press -> esp32 deep sleep mode, must be exited by user button
 | ||||
|   if (pmu.isPekeyShortPressIrq()) | ||||
|     enter_deepsleep(0, HAS_BUTTON); | ||||
|   } | ||||
| #endif | ||||
| 
 | ||||
|   // long press -> shutdown power, can be exited by another longpress
 | ||||
|   if (pmu.isPEKLongtPressIRQ()) { | ||||
|     AXP192_power(pmu_power_off); // switch off Lora, GPS, display
 | ||||
|   } | ||||
| 
 | ||||
|   pmu.clearIRQ(); | ||||
|   pmu.clearIrqStatus(); | ||||
| 
 | ||||
|   // refresh stored voltage value
 | ||||
|   read_battlevel(); | ||||
| @ -84,48 +67,41 @@ void AXP192_powerevent_IRQ(void) { | ||||
| void AXP192_power(pmu_power_t powerlevel) { | ||||
|   switch (powerlevel) { | ||||
|   case pmu_power_off: | ||||
|     pmu.setChargerLedFunction(XPOWER_CHGLED_CTRL_MANUAL); | ||||
|     pmu.setChargingLedFreq(XPOWERS_CHG_LED_DISABLE); | ||||
|     pmu.shutdown(); | ||||
|     break; | ||||
| 
 | ||||
|   case pmu_power_sleep: | ||||
| #ifdef PMU_LED_SLEEP_MODE | ||||
|     pmu.setChgLEDMode(PMU_LED_SLEEP_MODE); | ||||
| #else | ||||
|     pmu.setChgLEDMode(AXP20X_LED_OFF); | ||||
| #endif | ||||
|     pmu.setChargerLedFunction(XPOWER_CHGLED_CTRL_MANUAL); | ||||
|     pmu.setChargingLedFreq(XPOWERS_CHG_LED_FRE_1HZ); | ||||
|     // we don't cut off DCDC1, because OLED display will then block i2c bus
 | ||||
|     // pmu.setPowerOutPut(AXP192_DCDC1, AXP202_OFF); // OLED off
 | ||||
|     pmu.setPowerOutPut(AXP192_LDO3, AXP202_OFF); // gps off
 | ||||
|     pmu.setPowerOutPut(AXP192_LDO2, AXP202_OFF); // lora off
 | ||||
|     // pmu.disableDC1(); // OLED off
 | ||||
|     pmu.disableLDO3(); // gps off
 | ||||
|     pmu.disableLDO2(); // lora off
 | ||||
|     pmu.enableSleep(); | ||||
|     break; | ||||
| 
 | ||||
|   case pmu_power_on: | ||||
|   default: | ||||
|     pmu.setPowerOutPut(AXP192_LDO2, AXP202_ON);   // Lora on T-Beam V1.0/1.1
 | ||||
|     pmu.setPowerOutPut(AXP192_LDO3, AXP202_ON);   // Gps on T-Beam V1.0/1.1
 | ||||
|     pmu.setPowerOutPut(AXP192_DCDC1, AXP202_ON);  // OLED on T-Beam v1.0/1.1
 | ||||
|     pmu.setPowerOutPut(AXP192_DCDC2, AXP202_OFF); // unused on T-Beam v1.0/1.1
 | ||||
|     pmu.setPowerOutPut(AXP192_EXTEN, AXP202_OFF); // unused on T-Beam v1.0/1.1
 | ||||
| #ifdef PMU_LED_RUN_MODE | ||||
|     pmu.setChgLEDMode(PMU_LED_RUN_MODE); | ||||
| #else | ||||
|     pmu.setChgLEDMode(AXP20X_LED_LOW_LEVEL); | ||||
| #endif | ||||
|     pmu.enableLDO2(); // Lora on T-Beam V1.0/1.1
 | ||||
|     pmu.enableLDO3(); // Gps on T-Beam V1.0/1.1
 | ||||
|     pmu.enableDC1();  // OLED on T-Beam v1.0/1.1
 | ||||
|     pmu.setChargerLedFunction(XPOWER_CHGLED_CTRL_MANUAL); | ||||
|     pmu.setChargingLedFreq(XPOWERS_CHG_LED_LEVEL_LOW); | ||||
|     break; | ||||
|   } | ||||
| } | ||||
| 
 | ||||
| void AXP192_showstatus(void) { | ||||
|   if (pmu.isBatteryConnect()) | ||||
|     if (pmu.isChargeing()) | ||||
|     if (pmu.isCharging()) | ||||
|       ESP_LOGI(TAG, "Battery charging, %.2fV @ %.0fmAh", | ||||
|                pmu.getBattVoltage() / 1000, pmu.getBattChargeCurrent()); | ||||
|                pmu.getBattVoltage() / 1000, pmu.getBatteryChargeCurrent()); | ||||
|     else | ||||
|       ESP_LOGI(TAG, "Battery not charging"); | ||||
|   else | ||||
|     ESP_LOGI(TAG, "No Battery"); | ||||
| 
 | ||||
|   if (pmu.isVBUSPlug()) | ||||
|   if (pmu.isVbusIn()) | ||||
|     ESP_LOGI(TAG, "USB powered, %.0fmW", | ||||
|              pmu.getVbusVoltage() / 1000 * pmu.getVbusCurrent()); | ||||
|   else | ||||
| @ -133,58 +109,58 @@ void AXP192_showstatus(void) { | ||||
| } | ||||
| 
 | ||||
| void AXP192_init(void) { | ||||
|   if (pmu.begin(i2c_readBytes, i2c_writeBytes, AXP192_PRIMARY_ADDRESS) == | ||||
|       AXP_FAIL) | ||||
|   if (!pmu.begin(Wire, AXP192_PRIMARY_ADDRESS, SCL, SDA)) | ||||
|     ESP_LOGI(TAG, "AXP192 PMU initialization failed"); | ||||
|   else { | ||||
|     // configure voltages
 | ||||
|     pmu.setDCDC1Voltage(3300); // for external OLED display
 | ||||
|     pmu.setLDO2Voltage(3300);  // LORA VDD 3v3
 | ||||
|     pmu.setLDO3Voltage(3300);  // GPS VDD 3v3
 | ||||
|     ESP_LOGD(TAG, "AXP192 ChipID:0x%x", pmu.getChipID()); | ||||
| 
 | ||||
|     // configure voltage warning levels
 | ||||
|     pmu.setVWarningLevel1(3600); | ||||
|     pmu.setVWarningLevel2(3800); | ||||
|     pmu.setPowerDownVoltage(3300); | ||||
|     // set pmu operating voltages
 | ||||
|     pmu.setMinSystemVoltage(2700); | ||||
|     pmu.setVbusVoltageLimit(XPOWERS_VBUS_VOL_LIM_4V5); | ||||
|     pmu.disableVbusCurrLimit(); | ||||
| 
 | ||||
|     // set device operating voltages
 | ||||
|     pmu.setDC1Voltage(3300);  // for external OLED display
 | ||||
|     pmu.setLDO2Voltage(3300); // LORA VDD 3v3
 | ||||
|     pmu.setLDO3Voltage(3300); // GPS VDD 3v3
 | ||||
| 
 | ||||
|     // configure PEK button settings
 | ||||
|     pmu.setTimeOutShutdown(false); // forced shutdown by PEK enabled
 | ||||
|     pmu.setShutdownTime( | ||||
|         AXP_POWER_OFF_TIME_6S); // 6 sec button press for shutdown
 | ||||
|     pmu.setlongPressTime( | ||||
|         AXP_LONGPRESS_TIME_1S5); // 1.5 sec button press for long press
 | ||||
|     pmu.setStartupTime( | ||||
|         AXP192_STARTUP_TIME_1S); // 1 sec button press for startup
 | ||||
|     pmu.setPowerKeyPressOffTime(XPOWERS_POWEROFF_4S); | ||||
|     pmu.setPowerKeyPressOnTime(XPOWERS_POWERON_128MS); | ||||
| 
 | ||||
|     // set battery temperature sensing pin off to save power
 | ||||
|     pmu.setTSmode(AXP_TS_PIN_MODE_DISABLE); | ||||
|     pmu.disableTSPinMeasure(); | ||||
| 
 | ||||
|     // switch ADCs on
 | ||||
|     pmu.adc1Enable(AXP202_BATT_VOL_ADC1, true); | ||||
|     pmu.adc1Enable(AXP202_BATT_CUR_ADC1, true); | ||||
|     pmu.adc1Enable(AXP202_VBUS_VOL_ADC1, true); | ||||
|     pmu.adc1Enable(AXP202_VBUS_CUR_ADC1, true); | ||||
|     // Enable internal ADC detection
 | ||||
|     pmu.enableBattDetection(); | ||||
|     pmu.enableVbusVoltageMeasure(); | ||||
|     pmu.enableBattVoltageMeasure(); | ||||
|     pmu.enableSystemVoltageMeasure(); | ||||
| 
 | ||||
| #ifdef PMU_INT | ||||
|     pinMode(PMU_INT, INPUT_PULLUP); | ||||
|     attachInterrupt(digitalPinToInterrupt(PMU_INT), PMUIRQ, FALLING); | ||||
|     pmu.enableIRQ(AXP202_VBUS_REMOVED_IRQ | AXP202_VBUS_CONNECT_IRQ | | ||||
|                       AXP202_BATT_REMOVED_IRQ | AXP202_BATT_CONNECT_IRQ | | ||||
|                       AXP202_CHARGING_FINISHED_IRQ | AXP202_PEK_SHORTPRESS_IRQ, | ||||
|                   1); | ||||
|     pmu.clearIRQ(); | ||||
|     // disable all interrupts
 | ||||
|     pmu.disableIRQ(XPOWERS_ALL_IRQ); | ||||
|     // clear all interrupt flags
 | ||||
|     pmu.clearIrqStatus(); | ||||
|     // enable the required interrupt function
 | ||||
|     pmu.enableIRQ(XPOWERS_BAT_INSERT_IRQ | XPOWERS_BAT_REMOVE_IRQ |   // BATTERY
 | ||||
|                   XPOWERS_VBUS_INSERT_IRQ | XPOWERS_VBUS_REMOVE_IRQ | // VBUS
 | ||||
|                   XPOWERS_PKEY_SHORT_IRQ | XPOWERS_PKEY_LONG_IRQ | // POWER KEY
 | ||||
|                   XPOWERS_BAT_CHG_DONE_IRQ | XPOWERS_BAT_CHG_START_IRQ // CHARGE
 | ||||
|     ); | ||||
| #endif // PMU_INT
 | ||||
| 
 | ||||
| // set charging parameterss according to user settings if we have (see power.h)
 | ||||
| // set charging parameters according to user settings if we have (see power.h)
 | ||||
| #ifdef PMU_CHG_CURRENT | ||||
|     pmu.setChargeControlCur(PMU_CHG_CURRENT); | ||||
|     pmu.setChargingTargetVoltage(PMU_CHG_CUTOFF); | ||||
|     pmu.enableChargeing(true); | ||||
|     pmu.setChargeCurrent(PMU_CHG_CURRENT); | ||||
|     pmu.setChargerVoltageLimit(PMU_CHG_CUTOFF); | ||||
|     pmu.enableCharge(); | ||||
| #endif | ||||
| 
 | ||||
|     // switch power rails on
 | ||||
|     AXP192_power(pmu_power_on); | ||||
| 
 | ||||
|     ESP_LOGI(TAG, "AXP192 PMU initialized"); | ||||
|   } | ||||
| } | ||||
| @ -263,6 +239,8 @@ uint8_t read_battlevel(mapFn_t mapFunction) { | ||||
|   uint8_t batt_percent = 0; | ||||
| #ifdef HAS_IP5306 | ||||
|   batt_percent = IP5306_GetBatteryLevel(); | ||||
| #elif defined HAS_PMU | ||||
|   batt_percent = pmu.getBatteryPercent(); | ||||
| #else | ||||
|   const uint16_t batt_voltage = read_voltage(); | ||||
|   if (batt_voltage <= BAT_MIN_VOLTAGE) | ||||
| @ -292,7 +270,7 @@ uint8_t read_battlevel(mapFn_t mapFunction) { | ||||
| 
 | ||||
| // overwrite calculated value if we have external power
 | ||||
| #ifdef HAS_PMU | ||||
|   if (pmu.isVBUSPlug()) | ||||
|   if (pmu.isVbusIn()) | ||||
|     LMIC_setBatteryLevel(MCMD_DEVS_EXT_POWER); | ||||
| #elif defined HAS_IP5306 | ||||
|   if (IP5306_GetPowerSource()) | ||||
|  | ||||
| @ -39,7 +39,6 @@ void do_reset(bool warmstart) { | ||||
| } | ||||
| 
 | ||||
| void do_after_reset(void) { | ||||
| 
 | ||||
|   struct timeval sleep_stop_time; | ||||
|   uint64_t sleep_time_ms; | ||||
| 
 | ||||
| @ -54,7 +53,6 @@ void do_after_reset(void) { | ||||
| #endif | ||||
| 
 | ||||
|   switch (rtc_get_reset_reason(0)) { | ||||
| 
 | ||||
|   case POWERON_RESET:          // 0x01 Vbat power on reset
 | ||||
|   case RTCWDT_BROWN_OUT_RESET: // 0x0f Reset when the vdd voltage is not
 | ||||
|                                // stable
 | ||||
| @ -102,26 +100,19 @@ void do_after_reset(void) { | ||||
| } | ||||
| 
 | ||||
| void enter_deepsleep(const uint64_t wakeup_sec, gpio_num_t wakeup_gpio) { | ||||
| 
 | ||||
|   ESP_LOGI(TAG, "Preparing to sleep..."); | ||||
| 
 | ||||
|   RTC_runmode = RUNMODE_SLEEP; | ||||
|   int i; | ||||
| 
 | ||||
|   // show message on display
 | ||||
| #ifdef HAS_DISPLAY | ||||
|   dp_message("-GOING TO SLEEP-", 7, true); | ||||
| #endif | ||||
| 
 | ||||
|   // validate wake up pin, if we have
 | ||||
|   if (!GPIO_IS_VALID_GPIO(wakeup_gpio)) | ||||
|     wakeup_gpio = GPIO_NUM_MAX; | ||||
| 
 | ||||
|     // stop further enqueuing of senddata and MAC processing
 | ||||
|     // -> skipped, because shutting down bluedroid stack tends to crash
 | ||||
|     // libpax_counter_stop();
 | ||||
|   // stop further enqueuing of senddata and MAC processing
 | ||||
|   libpax_counter_stop(); | ||||
| 
 | ||||
|     // switch off any power consuming hardware
 | ||||
|   // switch off any power consuming hardware
 | ||||
| #if (HAS_SDS011) | ||||
|   sds011_sleep(); | ||||
| #endif | ||||
| @ -205,4 +196,6 @@ void enter_deepsleep(const uint64_t wakeup_sec, gpio_num_t wakeup_gpio) { | ||||
|   esp_deep_sleep_start(); | ||||
| } | ||||
| 
 | ||||
| unsigned long long uptime() { return (RTC_millis + esp_timer_get_time() / 1000); } | ||||
| unsigned long long uptime() { | ||||
|   return (RTC_millis + esp_timer_get_time() / 1000); | ||||
| } | ||||
| @ -9,7 +9,6 @@ RtcDS3231<TwoWire> Rtc(Wire); // RTC hardware i2c interface | ||||
| 
 | ||||
| // initialize RTC
 | ||||
| uint8_t rtc_init(void) { | ||||
| 
 | ||||
|   Wire.begin(HAS_RTC); | ||||
|   Rtc.Begin(MY_DISPLAY_SDA, MY_DISPLAY_SCL); | ||||
| 
 | ||||
| @ -39,11 +38,9 @@ uint8_t rtc_init(void) { | ||||
| 
 | ||||
|   // failure
 | ||||
|   // return 0
 | ||||
| 
 | ||||
| } // rtc_init()
 | ||||
| 
 | ||||
| uint8_t set_rtctime(time_t t) { // t is sec epoch time
 | ||||
| 
 | ||||
| #ifdef RTC_INT // sync rtc 1Hz pulse on top of second
 | ||||
|   Rtc.SetSquareWavePin(DS3231SquareWavePin_ModeNone);  // off
 | ||||
|   Rtc.SetSquareWavePin(DS3231SquareWavePin_ModeClock); // start
 | ||||
| @ -51,11 +48,9 @@ uint8_t set_rtctime(time_t t) { // t is sec epoch time | ||||
|   Rtc.SetDateTime(RtcDateTime(t - SECS_YR_2000)); // epoch -> sec2000
 | ||||
|   ESP_LOGI(TAG, "RTC time synced"); | ||||
|   return 1; // success
 | ||||
| 
 | ||||
| } // set_rtctime()
 | ||||
| 
 | ||||
| time_t get_rtctime(uint16_t *msec) { | ||||
| 
 | ||||
|   time_t t = 0; | ||||
|   *msec = 0; | ||||
|   if (Rtc.IsDateTimeValid() && Rtc.GetIsRunning()) { | ||||
| @ -75,7 +70,6 @@ time_t get_rtctime(uint16_t *msec) { | ||||
| #endif | ||||
| 
 | ||||
|   return t; | ||||
| 
 | ||||
| } // get_rtctime()
 | ||||
| 
 | ||||
| float get_rtctemp(void) { | ||||
|  | ||||
| @ -67,7 +67,6 @@ int print_to_sd_card(const char *fmt, va_list args) { | ||||
| #endif | ||||
| 
 | ||||
| bool openFile(FILE **fd, const char *filename) { | ||||
| 
 | ||||
|   char _filename[50]; | ||||
|   sprintf(_filename, "%s%s", MOUNT_POINT, filename); | ||||
| 
 | ||||
| @ -81,7 +80,6 @@ bool openFile(FILE **fd, const char *filename) { | ||||
| } // openfile
 | ||||
| 
 | ||||
| bool sdcard_init(bool create) { | ||||
| 
 | ||||
|   esp_err_t ret; | ||||
| 
 | ||||
|   // for usage of SD drivers on ESP32 platform see
 | ||||
| @ -171,7 +169,6 @@ bool sdcard_init(bool create) { | ||||
|   snprintf(bufferFilename, sizeof(bufferFilename), "/%s.csv", SDCARD_FILE_NAME); | ||||
| 
 | ||||
|   if (openFile(&data_file, bufferFilename)) { | ||||
| 
 | ||||
|     fpos_t position; | ||||
|     fgetpos(data_file, &position); | ||||
| 
 | ||||
| @ -207,7 +204,6 @@ bool sdcard_init(bool create) { | ||||
| #endif | ||||
| 
 | ||||
|   return useSDCard; | ||||
| 
 | ||||
| } // sdcard_init
 | ||||
| 
 | ||||
| void sdcard_flush(void) { | ||||
| @ -236,7 +232,6 @@ void sdcard_close(void) { | ||||
| 
 | ||||
| void sdcardWriteData(uint16_t noWifi, uint16_t noBle, | ||||
|                      __attribute__((unused)) uint16_t voltage) { | ||||
| 
 | ||||
|   if (!useSDCard) | ||||
|     return; | ||||
| 
 | ||||
| @ -264,4 +259,4 @@ void sdcardWriteData(uint16_t noWifi, uint16_t noBle, | ||||
|   fprintf(data_file, "\n"); | ||||
| } | ||||
| 
 | ||||
| #endif // (HAS_SDCARD)
 | ||||
| #endif // (HAS_SDCARD)
 | ||||
| @ -25,7 +25,6 @@ void initSendDataTimer(uint8_t sendcycle) { | ||||
| 
 | ||||
| // put data to send in RTos Queues used for transmit over channels Lora and SPI
 | ||||
| void SendPayload(uint8_t port) { | ||||
| 
 | ||||
|   ESP_LOGD(TAG, "sending Payload for Port %d", port); | ||||
| 
 | ||||
|   MessageBuffer_t SendBuffer; // contains MessageSize, MessagePort, Message[]
 | ||||
| @ -69,12 +68,10 @@ void SendPayload(uint8_t port) { | ||||
| #ifdef HAS_MQTT | ||||
|   mqtt_enqueuedata(&SendBuffer); | ||||
| #endif | ||||
| 
 | ||||
| } // SendPayload
 | ||||
| 
 | ||||
| // timer triggered function to prepare payload to send
 | ||||
| void sendData() { | ||||
| 
 | ||||
|   uint8_t bitmask = cfg.payloadmask; | ||||
|   uint8_t mask = 1; | ||||
| 
 | ||||
| @ -93,7 +90,6 @@ void sendData() { | ||||
| 
 | ||||
|   while (bitmask) { | ||||
|     switch (bitmask & mask) { | ||||
| 
 | ||||
| #if ((WIFICOUNTER) || (BLECOUNTER)) | ||||
|     case COUNT_DATA: | ||||
|       payload.reset(); | ||||
| @ -199,7 +195,6 @@ void sendData() { | ||||
|         SendPayload(BATTPORT); | ||||
|         break; | ||||
| #endif | ||||
| 
 | ||||
|       } // switch
 | ||||
|       bitmask &= ~mask; | ||||
|       mask <<= 1; | ||||
|  | ||||
| @ -9,7 +9,6 @@ static const char TAG[] = __FILE__; | ||||
|   10 // max. size of user sensor data buffer in bytes [default=20]
 | ||||
| 
 | ||||
| void sensor_init(void) { | ||||
| 
 | ||||
|   // this function is called during device startup
 | ||||
|   // put your user sensor initialization routines here
 | ||||
| } | ||||
| @ -38,14 +37,11 @@ uint8_t sensor_mask(uint8_t sensor_no) { | ||||
| } | ||||
| 
 | ||||
| uint8_t *sensor_read(uint8_t sensor) { | ||||
| 
 | ||||
|   static uint8_t buf[SENSORBUFFER] = {0}; | ||||
|   uint8_t length = 3; | ||||
| 
 | ||||
|   switch (sensor) { | ||||
| 
 | ||||
|   case 1: | ||||
| 
 | ||||
|     // insert user specific sensor data frames here
 | ||||
|     buf[0] = length; | ||||
|     buf[1] = 0x01; | ||||
| @ -53,15 +49,12 @@ uint8_t *sensor_read(uint8_t sensor) { | ||||
|     buf[3] = 0x03; | ||||
|     break; | ||||
|   case 2: | ||||
| 
 | ||||
|     buf[0] = length; | ||||
|     buf[1] = 0x01; | ||||
|     buf[2] = 0x02; | ||||
|     buf[3] = 0x03; | ||||
|     break; | ||||
| 
 | ||||
|   case 3: | ||||
| 
 | ||||
|     buf[0] = length; | ||||
|     buf[1] = 0x01; | ||||
|     buf[2] = 0x02; | ||||
| @ -70,4 +63,4 @@ uint8_t *sensor_read(uint8_t sensor) { | ||||
|   } | ||||
| 
 | ||||
|   return buf; | ||||
| } | ||||
| } | ||||
| @ -332,7 +332,7 @@ time_t compileTime(void) { | ||||
| 
 | ||||
|   if (secs == -1) { | ||||
|     // determine date
 | ||||
|     sscanf(__DATE__, "%s %d %d", s_month, &t.tm_mday, &year); | ||||
|     sscanf(__DATE__, "%4s %d %d", s_month, &t.tm_mday, &year); | ||||
|     t.tm_mon = (strstr(month_names, s_month) - month_names) / 3; | ||||
|     t.tm_year = year - 1900; | ||||
|     // determine time
 | ||||
|  | ||||
| @ -56,7 +56,6 @@ void timesync_request(void) { | ||||
| 
 | ||||
| // task for processing time sync request
 | ||||
| void timesync_processReq(void *taskparameter) { | ||||
| 
 | ||||
|   uint32_t rcv_seqNo = TIME_SYNC_END_FLAG; | ||||
|   uint32_t time_offset_sec = 0, time_offset_ms = 0; | ||||
| 
 | ||||
| @ -68,7 +67,6 @@ void timesync_processReq(void *taskparameter) { | ||||
|   // --- asnychronous part: generate and collect timestamps from gateway ---
 | ||||
| 
 | ||||
|   while (1) { | ||||
| 
 | ||||
|     // wait for kickoff
 | ||||
|     ulTaskNotifyTake(pdFALSE, portMAX_DELAY); | ||||
| 
 | ||||
| @ -85,7 +83,6 @@ void timesync_processReq(void *taskparameter) { | ||||
| 
 | ||||
|     // collect timestamp samples in timestamp array
 | ||||
|     for (int8_t i = 0; i < TIME_SYNC_SAMPLES; i++) { | ||||
| 
 | ||||
| // send timesync request
 | ||||
| #if (TIME_SYNC_LORASERVER) // ask user's timeserver (for LoRAWAN < 1.0.3)
 | ||||
|       payload.reset(); | ||||
| @ -122,7 +119,6 @@ void timesync_processReq(void *taskparameter) { | ||||
|       // if we are not in last cycle, pause until next cycle
 | ||||
|       if (i < TIME_SYNC_SAMPLES - 1) | ||||
|         vTaskDelay(pdMS_TO_TICKS(TIME_SYNC_CYCLE * 1000)); | ||||
| 
 | ||||
|     } // for i
 | ||||
| 
 | ||||
|     // --- time critial part: evaluate timestamps and calculate time ---
 | ||||
| @ -161,7 +157,6 @@ void timesync_processReq(void *taskparameter) { | ||||
|     // end of time critical section: release app irq lock
 | ||||
|     timeSyncPending = false; | ||||
|     unmask_user_IRQ(); | ||||
| 
 | ||||
|   } // infinite while(1)
 | ||||
| } | ||||
| 
 | ||||
| @ -174,7 +169,6 @@ void timesync_store(uint32_t timestamp, timesync_t timestamp_type) { | ||||
| 
 | ||||
| // callback function to receive time answer from network or answer
 | ||||
| void timesync_serverAnswer(void *pUserData, int flag) { | ||||
| 
 | ||||
| #if (HAS_LORA_TIME) | ||||
| 
 | ||||
|   // if no timesync handshake is pending then exit
 | ||||
|  | ||||
		Loading…
	
		Reference in New Issue
	
	Block a user