diff --git a/build.py b/build.py index 35084709..94b53ff9 100644 --- a/build.py +++ b/build.py @@ -74,12 +74,6 @@ board = env.BoardConfig(myboard) board.manifest['build']['partitions'] = mypartitiontable print('\033[94m' + "Partition table: " + mypartitiontable + '\033[0m') -# set display library -if "display_library" in mykeys: - mydisplay = mykeys["display_library"] - env.Append(display_library=mydisplay) - print('\033[94m' + "Display library: " + mydisplay + '\033[0m') - # parse ota key file with open(otakeyfile) as myfile: for line in myfile: diff --git a/include/bmesensor.h b/include/bmesensor.h index 5724db84..a038994e 100644 --- a/include/bmesensor.h +++ b/include/bmesensor.h @@ -1,6 +1,8 @@ #ifndef _BMESENSOR_H #define _BMESENSOR_H +#if (HAS_BME) + #include #include "globals.h" @@ -53,4 +55,6 @@ int checkIaqSensorStatus(void); void loadState(void); void updateState(void); +#endif + #endif \ No newline at end of file diff --git a/include/dcf77.h b/include/dcf77.h index df9400e9..6844c1b7 100644 --- a/include/dcf77.h +++ b/include/dcf77.h @@ -1,6 +1,8 @@ #ifndef _DCF77_H #define _DCF77_H +#ifdef HAS_DCF77 + #include "globals.h" #include "timekeeper.h" @@ -15,4 +17,6 @@ enum dcf_pinstate { dcf_low, dcf_high }; void DCF77_Pulse(uint8_t bit); uint64_t DCF77_Frame(const struct tm t); +#endif + #endif \ No newline at end of file diff --git a/include/gpsread.h b/include/gpsread.h index 95cd1afa..6eae7bb7 100644 --- a/include/gpsread.h +++ b/include/gpsread.h @@ -1,6 +1,8 @@ #ifndef _GPSREAD_H #define _GPSREAD_H +#if (HAS_GPS) + #include // library for parsing NMEA data #include #include "timekeeper.h" @@ -19,4 +21,6 @@ void gps_storelocation(gpsStatus_t *gps_store); void gps_loop(void *pvParameters); time_t get_gpstime(uint16_t *msec); +#endif + #endif \ No newline at end of file diff --git a/include/hash.h b/include/hash.h index fe756ec3..fab8df90 100644 --- a/include/hash.h +++ b/include/hash.h @@ -4,6 +4,6 @@ #include #include -uint32_t IRAM_ATTR myhash(const char *data, int len); +uint32_t myhash(const char *data, int len); #endif \ No newline at end of file diff --git a/include/if482.h b/include/if482.h index 9a3fe92f..4efdbd3f 100644 --- a/include/if482.h +++ b/include/if482.h @@ -1,6 +1,8 @@ #ifndef _IF482_H #define _IF482_H +#ifdef HAS_IF482 + #include "globals.h" #include "timekeeper.h" #include "esp_sntp.h" @@ -10,4 +12,6 @@ String IF482_Frame(time_t t); +#endif + #endif \ No newline at end of file diff --git a/include/ledmatrixdisplay.h b/include/ledmatrixdisplay.h index b27914c1..57b323c0 100644 --- a/include/ledmatrixdisplay.h +++ b/include/ledmatrixdisplay.h @@ -1,6 +1,8 @@ #ifndef _MATRIX_DISPLAY_H #define _MATRIX_DISPLAY_H +#ifdef HAS_MATRIX_DISPLAY + #include "LEDMatrix.h" #include "ledmatrixfonts.h" #include "ledmatrixdisplay.h" @@ -16,4 +18,6 @@ uint8_t GetCharFromFont(char cChar); uint8_t GetCharWidth(char cChar); void ScrollMatrixLeft(uint8_t *buf, const uint16_t cols, const uint16_t rows); +#endif + #endif \ No newline at end of file diff --git a/include/lorawan.h b/include/lorawan.h index 0c870bb9..32ddc4ba 100644 --- a/include/lorawan.h +++ b/include/lorawan.h @@ -38,10 +38,10 @@ void lora_send(void *pvParameters); void lora_enqueuedata(MessageBuffer_t *message); void lora_queuereset(void); uint32_t lora_queuewaiting(void); -void IRAM_ATTR myEventCallback(void *pUserData, ev_t ev); -void IRAM_ATTR myRxCallback(void *pUserData, uint8_t port, const uint8_t *pMsg, +void myEventCallback(void *pUserData, ev_t ev); +void myRxCallback(void *pUserData, uint8_t port, const uint8_t *pMsg, size_t nMsg); -void IRAM_ATTR myTxCallback(void *pUserData, int fSuccess); +void myTxCallback(void *pUserData, int fSuccess); const char *getSfName(rps_t rps); const char *getBwName(rps_t rps); const char *getCrName(rps_t rps); diff --git a/include/mqttclient.h b/include/mqttclient.h index 6151dd52..cfdad89f 100644 --- a/include/mqttclient.h +++ b/include/mqttclient.h @@ -1,6 +1,8 @@ #ifndef _MQTTCLIENT_H #define _MQTTCLIENT_H +#ifdef HAS_MQTT + #include "globals.h" #include "rcommand.h" #include "hash.h" @@ -24,4 +26,6 @@ void NetworkEvent(WiFiEvent_t event); esp_err_t mqtt_init(void); void mqtt_deinit(void); +#endif + #endif // _MQTTCLIENT_H \ No newline at end of file diff --git a/include/power.h b/include/power.h index 0e123c98..24f6fb67 100644 --- a/include/power.h +++ b/include/power.h @@ -3,7 +3,6 @@ #include #include -//include #include #include "i2c.h" @@ -56,7 +55,6 @@ void calibrate_voltage(void); bool batt_sufficient(void); #ifdef HAS_PMU - #include extern AXP20X_Class pmu; enum pmu_power_t { pmu_power_on, pmu_power_off, pmu_power_sleep }; @@ -64,7 +62,6 @@ void AXP192_powerevent_IRQ(void); void AXP192_power(pmu_power_t powerlevel); void AXP192_init(void); void AXP192_showstatus(void); - #endif // HAS_PMU #ifdef HAS_IP5306 diff --git a/include/rcommand.h b/include/rcommand.h index d842fdef..e01369b1 100644 --- a/include/rcommand.h +++ b/include/rcommand.h @@ -34,7 +34,7 @@ typedef struct { uint8_t cmdLen; } RcmdBuffer_t; -void IRAM_ATTR rcommand(const uint8_t *cmd, const size_t cmdlength); +void rcommand(const uint8_t *cmd, const size_t cmdlength); void rcmd_queuereset(void); uint32_t rcmd_queuewaiting(void); void rcmd_deinit(void); diff --git a/include/rtctime.h b/include/rtctime.h index 3f75eb37..802b06ee 100644 --- a/include/rtctime.h +++ b/include/rtctime.h @@ -1,6 +1,8 @@ #ifndef _RTCTIME_H #define _RTCTIME_H +#ifdef HAS_RTC + #include // must be included here so that Arduino library object file references work #include @@ -15,4 +17,6 @@ void sync_rtctime(void); time_t get_rtctime(uint16_t *msec); float get_rtctemp(void); +#endif + #endif // _RTCTIME_H \ No newline at end of file diff --git a/include/sdcard.h b/include/sdcard.h index 25fcf2c4..1f2b0bca 100644 --- a/include/sdcard.h +++ b/include/sdcard.h @@ -1,23 +1,18 @@ #ifndef _SDCARD_H #define _SDCARD_H +#if (HAS_SDCARD) + #include "globals.h" #include #include +#include "esp_vfs_fat.h" +#include "sdmmc_cmd.h" -#if (HAS_SDCARD) -#if HAS_SDCARD == 1 -#include -#elif HAS_SDCARD == 2 -#include -#else -#error HAS_SDCARD unknown card reader value, must be either 1 or 2 -#endif -#endif +#define MOUNT_POINT "/sdcard" -#ifdef HAS_SDS011 -#include "sds011read.h" -#endif +#if HAS_SDCARD == 1 // SPI interface +#include "driver/sdspi_host.h" #ifndef SDCARD_CS #define SDCARD_CS SS @@ -35,23 +30,23 @@ #define SDCARD_SCLK SCK #endif -// Default config for SDMMC_HOST_DEFAULT (4-bit bus width, slot 1) -// https://docs.espressif.com/projects/esp-idf/en/latest/esp32/api-reference/peripherals/sdmmc_host.html +#elif HAS_SDCARD == 2 // MMC interface +#include "driver/sdmmc_host.h" -#ifndef SDCARD_DATA0 -#define SDCARD_DATA0 2 +#ifndef SDCARD_SLOTWIDTH +#define SDCARD_SLOTWIDTH 1 #endif -#ifndef SDCARD_DATA1 -#define SDCARD_DATA1 4 +#ifndef SDCARD_PULLUP +#define SDCARD_PULLUP SDMMC_SLOT_FLAG_INTERNAL_PULLUP #endif -#ifndef SDCARD_DATA2 -#define SDCARD_DATA2 12 +#else +#error HAS_SDCARD unknown card reader value, must be either 1 or 2 #endif -#ifndef SDCARD_DATA3 -#define SDCARD_DATA3 13 +#ifdef HAS_SDS011 +#include "sds011read.h" #endif #define SDCARD_FILE_NAME clientId @@ -62,7 +57,10 @@ #endif bool sdcard_init(bool create = true); +void sdcard_flush(void); void sdcard_close(void); void sdcardWriteData(uint16_t, uint16_t, uint16_t = 0); +#endif + #endif // _SDCARD_H diff --git a/include/sds011read.h b/include/sds011read.h index f1b874d3..6345a267 100644 --- a/include/sds011read.h +++ b/include/sds011read.h @@ -1,10 +1,12 @@ #ifndef _SDS011READ_H #define _SDS011READ_H +#if (HAS_SDS011) + #include #include "globals.h" -#define SDCARD_FILE_HEADER_SDS011 ", PM10,PM25" +#define SDCARD_FILE_HEADER_SDS011 ", PM10,PM25" // use original pins from HardwareSerial if none defined #ifndef SDS_TX @@ -21,4 +23,7 @@ void sds011_loop(); void sds011_sleep(void); void sds011_wakeup(void); void sds011_store(sdsStatus_t *sds_store); + +#endif + #endif // _SDS011READ_H diff --git a/include/spislave.h b/include/spislave.h index 78b7a737..389aa573 100644 --- a/include/spislave.h +++ b/include/spislave.h @@ -24,6 +24,8 @@ licenses. Refer to LICENSE.txt file in repository for more details. #ifndef _SPISLAVE_H #define _SPISLAVE_H +#ifdef HAS_SPI + #include "globals.h" #include "rcommand.h" @@ -35,4 +37,6 @@ void spi_enqueuedata(MessageBuffer_t *message); uint32_t spi_queuewaiting(void); void spi_queuereset(void); +#endif + #endif // _SPISLAVE_H diff --git a/include/timekeeper.h b/include/timekeeper.h index ee20913e..e28b60d9 100644 --- a/include/timekeeper.h +++ b/include/timekeeper.h @@ -34,7 +34,7 @@ void setTimeSyncIRQ(void); uint8_t timepulse_init(void); bool timeIsValid(time_t const t); void calibrateTime(void); -bool IRAM_ATTR setMyTime(uint32_t t_sec, uint16_t t_msec, +bool setMyTime(uint32_t t_sec, uint16_t t_msec, timesource_t mytimesource); time_t compileTime(void); time_t mkgmtime(const struct tm *ptm); diff --git a/include/timesync.h b/include/timesync.h index cd517421..f12f70ec 100644 --- a/include/timesync.h +++ b/include/timesync.h @@ -21,7 +21,7 @@ enum timesync_t { void timesync_init(void); void timesync_request(void); void timesync_store(uint32_t timestamp, timesync_t timestamp_type); -void IRAM_ATTR timesync_processReq(void *taskparameter); -void IRAM_ATTR timesync_serverAnswer(void *pUserData, int flag); +void timesync_processReq(void *taskparameter); +void timesync_serverAnswer(void *pUserData, int flag); #endif diff --git a/platformio_orig.ini b/platformio_orig.ini index 2c2112cf..c9dc8755 100644 --- a/platformio_orig.ini +++ b/platformio_orig.ini @@ -1,10 +1,8 @@ -; PlatformIO Project Configuration File +; ---> SELECT ONE TARGET BOARD FROM FOLLOWING ROWS <--- +; +; Note: For "LILYGO TTGO ESP32-Paxcounter LoRa32 V2.1 1.6.1" select board ttgov21new.h +; ; -; Please visit documentation for the other options and examples -; http://docs.platformio.org/page/projectconf.html - - -; ---> SELECT THE TARGET PLATFORM HERE! <--- [board] ;halfile = generic.h ;halfile = ebox.h @@ -100,8 +98,6 @@ build_flags_basic = '-DCORE_DEBUG_LEVEL=${common.debug_level}' '-DLOG_LOCAL_LEVEL=${common.debug_level}' '-DPROGVERSION="${common.release_version}"' - '-Wno-unknown-pragmas' - '-Wno-unused-variable' '-D LIBPAX_WIFI' '-D LIBPAX_BLE' '-D LIBPAX_ARDUINO' @@ -113,6 +109,7 @@ build_flags_all = framework = arduino board = esp32dev board_build.partitions = min_spiffs.csv +build_type = release upload_speed = ${common.upload_speed} ;upload_port = COM12 platform = ${common.platform_espressif32} diff --git a/src/antenna.cpp b/src/antenna.cpp index 9f6a8a9b..5e3b0bd8 100644 --- a/src/antenna.cpp +++ b/src/antenna.cpp @@ -5,7 +5,7 @@ #include // Local logging tag -static const char TAG[] = "wifi"; +static const char TAG[] = __FILE__; typedef enum { ANTENNA_INT = 0, ANTENNA_EXT } antenna_type_t; diff --git a/src/cyclic.cpp b/src/cyclic.cpp index 385f9afe..27697efc 100644 --- a/src/cyclic.cpp +++ b/src/cyclic.cpp @@ -126,6 +126,10 @@ void doHousekeeping() { } #endif +#if (HAS_SDCARD) + sdcard_flush(); +#endif + } // doHousekeeping() uint32_t getFreeRAM() { diff --git a/src/hal/ttgov21new.h b/src/hal/ttgov21new.h index fbaae22b..47145374 100644 --- a/src/hal/ttgov21new.h +++ b/src/hal/ttgov21new.h @@ -9,14 +9,15 @@ /* Hardware related definitions for TTGO V2.1 Board // ATTENTION: check your board version! -// This settings are for boards labeled v1.6 on pcb, NOT for v1.5 or older +// This settings are for boards labeled v1.6 or v1.6.1 on pcb, NOT for v1.5 or older */ #define HAS_LORA 1 // comment out if device shall not send data via LoRa #define CFG_sx1276_radio 1 // HPD13A LoRa SoC // enable only if you want to store a local paxcount table on the device -#define HAS_SDCARD 2 // this board has a SDMMC card-reader/writer +#define HAS_SDCARD 2 // this board has a SD MMC card-reader/writer +#define SDCARD_SLOTWIDTH 4 // 4-line interface #define HAS_DISPLAY 1 #define HAS_LED (25) // green on board LED diff --git a/src/hash.cpp b/src/hash.cpp index 78f31d03..864a51cd 100644 --- a/src/hash.cpp +++ b/src/hash.cpp @@ -40,6 +40,6 @@ #undef ROKKIT_ENABLE_8BIT_OPTIMIZATIONS #endif -uint32_t IRAM_ATTR myhash(const char *data, int len) { +uint32_t myhash(const char *data, int len) { return rokkit(data, len); } diff --git a/src/i2c.cpp b/src/i2c.cpp index 538d1681..c908d250 100644 --- a/src/i2c.cpp +++ b/src/i2c.cpp @@ -53,7 +53,7 @@ void i2c_scan(void) { if (I2C_MUTEX_LOCK()) { memset(&bbi2c, 0, sizeof(bbi2c)); - bbi2c.bWire = 1; // use wire library, no bitbanging + bbi2c.bWire = 0; bbi2c.iSDA = MY_DISPLAY_SDA; bbi2c.iSCL = MY_DISPLAY_SCL; I2CInit(&bbi2c, 100000L); // Scan at 100KHz low speed diff --git a/src/lorawan.cpp b/src/lorawan.cpp index 299481fc..1d40e5eb 100644 --- a/src/lorawan.cpp +++ b/src/lorawan.cpp @@ -4,7 +4,7 @@ #include "lorawan.h" // Local logging Tag -static const char TAG[] = "lora"; +static const char TAG[] = __FILE__; #if CLOCK_ERROR_PROCENTAGE > 7 #warning CLOCK_ERROR_PROCENTAGE value in lmic_config.h is too high; values > 7 will cause side effects diff --git a/src/rcommand.cpp b/src/rcommand.cpp index 1654b345..639e6c84 100644 --- a/src/rcommand.cpp +++ b/src/rcommand.cpp @@ -84,8 +84,7 @@ void set_sendcycle(uint8_t val[]) { void set_sleepcycle(uint8_t val[]) { // swap byte order from msb to lsb, note: this is a platform dependent hack - uint16_t t = __builtin_bswap16(*(uint16_t *)(val)); - cfg.sleepcycle = t; + cfg.sleepcycle = __builtin_bswap16(*(uint16_t *)(val)); ESP_LOGI(TAG, "Remote command: set sleep cycle to %d seconds", cfg.sleepcycle * 10); } @@ -485,7 +484,7 @@ void rcmd_process(void *pvParameters) { } // rcmd_process() // enqueue remote command -void IRAM_ATTR rcommand(const uint8_t *cmd, const size_t cmdlength) { +void rcommand(const uint8_t *cmd, const size_t cmdlength) { RcmdBuffer_t rcmd = {0}; diff --git a/src/rtctime.cpp b/src/rtctime.cpp index eb25698d..9b12cd94 100644 --- a/src/rtctime.cpp +++ b/src/rtctime.cpp @@ -1,10 +1,10 @@ +#ifdef HAS_RTC // we have hardware RTC + #include "rtctime.h" // Local logging tag static const char TAG[] = __FILE__; -#ifdef HAS_RTC // we have hardware RTC - RtcDS3231 Rtc(Wire); // RTC hardware i2c interface // initialize RTC diff --git a/src/sdcard.cpp b/src/sdcard.cpp index c8696bb1..4794ce00 100644 --- a/src/sdcard.cpp +++ b/src/sdcard.cpp @@ -1,156 +1,267 @@ +#ifdef HAS_SDCARD + // routines for writing data to an SD-card, if present // use FAT32 formatted card // check whether your card reader supports SPI oder SDMMC and select appropriate -// SD low level driver in board hal file +// SD interface in board hal file // Local logging tag static const char TAG[] = __FILE__; #include "sdcard.h" -#ifdef HAS_SDCARD +sdmmc_card_t *card; -static bool useSDCard; -static void openFile(void); +const char mount_point[] = MOUNT_POINT; +static bool useSDCard = false; -File fileSDCard; +// This file stream will be used for payload logging +static FILE *data_file; +// This file stream will be used for system logging -#if HAS_SDCARD == 1 -SPIClass sd_spi; +#ifdef SD_LOGGING +static FILE *log_file; + +// Save UART stdout stream +static FILE *uart_stdout = stdout; + +// This function will be called by the ESP log library every time ESP_LOG needs +// to be performed. +// @important Do NOT use the ESP_LOG* macro's in this function ELSE +// recursive loop and stack overflow! So use printf() instead for debug +// messages. +// CURRENTLY NOT WORKING DUE TO AN ISSUE IN ARDUINO-ESP32 +int print_to_sd_card(const char *fmt, va_list args) { + static bool static_fatal_error = false; + static const uint32_t WRITE_CACHE_CYCLE = 5; + static uint32_t counter_write = 0; + int iresult; + + // #1 Write to file + if (log_file == NULL) { + printf("%s() ABORT. file handle log_file is NULL\n", __FUNCTION__); + return -1; + } + if (static_fatal_error == false) { + iresult = vfprintf(log_file, fmt, args); + if (iresult < 0) { + printf("%s() ABORT. failed vfprintf() -> logging disabled \n", + __FUNCTION__); + // MARK FATAL + static_fatal_error = true; + return iresult; + } + + // #2 Smart commit after x writes + counter_write++; + if (counter_write % WRITE_CACHE_CYCLE == 0) { + printf("%s() fsync'ing log file (WRITE_CACHE_CYCLE=%u)\n", + WRITE_CACHE_CYCLE); + fsync(fileno(log_file)); + } + } + + // #3 ALWAYS Write to stdout! + return vprintf(fmt, args); +} #endif +bool openFile(FILE **fd, const char *filename) { + + char _filename[50]; + sprintf(_filename, "%s%s", MOUNT_POINT, filename); + + if ((*fd = fopen(_filename, "a")) == NULL) { + ESP_LOGE(TAG, "file <%s> open error", _filename); + return false; + } else { + ESP_LOGI(TAG, "file <%s> opened", _filename); + return true; + } +} // openfile + bool sdcard_init(bool create) { + esp_err_t ret; + // for usage of SD drivers on ESP32 platform see // https://docs.espressif.com/projects/esp-idf/en/latest/esp32/api-reference/peripherals/sdspi_host.html // https://docs.espressif.com/projects/esp-idf/en/latest/esp32/api-reference/peripherals/sdmmc_host.html - ESP_LOGI(TAG, "looking for SD-card..."); -#if HAS_SDCARD == 1 // use SD SPI host driver - digitalWrite(SDCARD_CS, HIGH); - sd_spi.begin(SDCARD_SCLK, SDCARD_MISO, SDCARD_MOSI, SDCARD_CS); - digitalWrite(SDCARD_CS, LOW); - useSDCard = SD.begin(SDCARD_CS, sd_spi); -#elif HAS_SDCARD == 2 // use SD MMC host driver - // enable internal pullups of sd-data lines - gpio_set_pull_mode(gpio_num_t(SDCARD_DATA0), GPIO_PULLUP_ONLY); - gpio_set_pull_mode(gpio_num_t(SDCARD_DATA1), GPIO_PULLUP_ONLY); - gpio_set_pull_mode(gpio_num_t(SDCARD_DATA2), GPIO_PULLUP_ONLY); - gpio_set_pull_mode(gpio_num_t(SDCARD_DATA3), GPIO_PULLUP_ONLY); - useSDCard = SD_MMC.begin(); -#endif + // Options for mounting the filesystem. + // If format_if_mount_failed is set to true, SD card will be partitioned and + // formatted in case when mounting fails. + esp_vfs_fat_mount_config_t mount_config = {.format_if_mount_failed = false, + .max_files = 5}; - if (useSDCard) { - ESP_LOGI(TAG, "SD-card found"); - openFile(); - return true; - } else { - ESP_LOGI(TAG, "SD-card not found"); + ESP_LOGI(TAG, "looking for SD-card..."); + +#if (HAS_SDCARD == 1) // use SD interface in SPI host mode + + sdmmc_host_t host = SDSPI_HOST_DEFAULT(); + + spi_bus_config_t bus_cfg = { + .mosi_io_num = (gpio_num_t)SDCARD_MOSI, + .miso_io_num = (gpio_num_t)SDCARD_MISO, + .sclk_io_num = (gpio_num_t)SDCARD_SCLK, + .quadwp_io_num = -1, + .quadhd_io_num = -1, + .max_transfer_sz = 4000, + }; + + // This initializes the slot without card detect (CD) and write protect (WP) + // signals. Modify slot_config.gpio_cd and slot_config.gpio_wp if you want + // to use these signals (if your board has them) + sdspi_device_config_t slot_config = SDSPI_DEVICE_CONFIG_DEFAULT(); + slot_config.gpio_cs = (gpio_num_t)SDCARD_CS; + + ret = spi_bus_initialize(SPI_HOST, &bus_cfg, 1); + if (ret != ESP_OK) { + ESP_LOGE(TAG, "failed to initialize SPI bus"); return false; } + + // Use settings defined above to initialize SD card and mount FAT filesystem. + ret = esp_vfs_fat_sdspi_mount(mount_point, &host, &slot_config, &mount_config, + &card); + +#elif (HAS_SDCARD == 2) // use SD interface in MMC host mode + + sdmmc_host_t host = SDMMC_HOST_DEFAULT(); + + // This initializes the slot without card detect (CD) and write protect (WP) + // signals. Modify slot_config.gpio_cd and slot_config.gpio_wp if your board + // has these signals. + // Default config for SDMMC_HOST_DEFAULT (4-bit bus width, slot 1) + // https://docs.espressif.com/projects/esp-idf/en/latest/esp32/api-reference/peripherals/sdmmc_host.html + sdmmc_slot_config_t slot_config = SDMMC_SLOT_CONFIG_DEFAULT(); + + // Set 1-line or 4-line SD mode (default is 1-line) + slot_config.width = SDCARD_SLOTWIDTH; + + // Enable internal pullups on enabled pins. The internal pullups + // are insufficient however, please make sure 10k external pullups are + // connected on the bus. This is for debug / example purpose only. + slot_config.flags |= SDCARD_PULLUP; + + // Use settings defined above to initialize SD card and mount FAT filesystem. + ret = esp_vfs_fat_sdmmc_mount(mount_point, &host, &slot_config, &mount_config, + &card); + +#endif + + // mount error handling + if (ret != ESP_OK) { + if (ret == ESP_FAIL) { + ESP_LOGE(TAG, "failed to mount filesystem"); + } else { + ESP_LOGE(TAG, "SD-card not found (%d)", ret); + } + return false; + } + + // SD card is now initialized + useSDCard = true; + ESP_LOGI(TAG, "filesystem mounted"); + sdmmc_card_print_info(stdout, card); + + // open files for data and, optional, system logging + char bufferFilename[50]; + + snprintf(bufferFilename, sizeof(bufferFilename), "/%s.csv", SDCARD_FILE_NAME); + + if (openFile(&data_file, bufferFilename)) { + + fpos_t position; + fgetpos(data_file, &position); + + // empty file? then we write a header line + if (position == 0) { + fprintf(data_file, "%s", SDCARD_FILE_HEADER); +#if (defined BAT_MEASURE_ADC || defined HAS_PMU) + fprintf(data_file, "%s", SDCARD_FILE_HEADER_VOLTAGE); +#endif +#if (HAS_SDS011) + fprintf(data_file, "%s", SDCARD_FILE_HEADER_SDS011); +#endif + } + fprintf(data_file, "\n"); + + } else { + useSDCard = false; + } + +#ifdef SD_LOGGING + snprintf(bufferFilename, sizeof(bufferFilename), "/%s.log", SDCARD_FILE_NAME); + + if (openFile(&log_file, bufferFilename)) { + ESP_LOGI(TAG, "redirecting serial output to SD-card"); + esp_log_set_vprintf(&print_to_sd_card); + // Change stdout for THIS TASK ONLY + // stdout = log_file; + // Change stdout for all new tasks which will be created + //_GLOBAL_REENT->_stdout = log_file; + } else { + useSDCard = false; + } +#endif + + return useSDCard; + +} // sdcard_init + +void sdcard_flush(void) { + if (data_file) + fsync(fileno(data_file)); +#ifdef SD_LOGGING + if (log_file) + fsync(fileno(log_file)); +#endif } void sdcard_close(void) { ESP_LOGI(TAG, "closing SD-card"); - fileSDCard.flush(); - fileSDCard.close(); + sdcard_flush(); +#ifdef SD_LOGGING + // Reset logging output back to normal + ESP_LOGI(TAG, "redirect console back to serial output"); + // stdout = uart_stdout; + //_GLOBAL_REENT->_stdout = uart_stdout; + esp_log_set_vprintf(&vprintf); +#endif + fcloseall(); + esp_vfs_fat_sdcard_unmount(mount_point, card); + ESP_LOGI(TAG, "SD-card unmounted"); } void sdcardWriteData(uint16_t noWifi, uint16_t noBle, __attribute__((unused)) uint16_t voltage) { - static int counterWrites = 0; - char tempBuffer[20 + 1]; + + if (!useSDCard) + return; + + char timeBuffer[20 + 1]; time_t t = time(NULL); struct tm tt; gmtime_r(&t, &tt); // make UTC timestamp + strftime(timeBuffer, sizeof(timeBuffer), "%FT%TZ", &tt); #if (HAS_SDS011) sdsStatus_t sds; #endif - if (!useSDCard) - return; + ESP_LOGI(TAG, "writing data to SD-card"); - ESP_LOGI(TAG, "SD: writing data"); - strftime(tempBuffer, sizeof(tempBuffer), "%FT%TZ", &tt); - fileSDCard.print(tempBuffer); - snprintf(tempBuffer, sizeof(tempBuffer), ",%d,%d", noWifi, noBle); - fileSDCard.print(tempBuffer); + fprintf(data_file, "%s", timeBuffer); + fprintf(data_file, ",%d,%d", noWifi, noBle); #if (defined BAT_MEASURE_ADC || defined HAS_PMU) - snprintf(tempBuffer, sizeof(tempBuffer), ",%d", voltage); - fileSDCard.print(tempBuffer); + fprintf(data_file, ",%d", voltage); #endif #if (HAS_SDS011) sds011_store(&sds); - snprintf(tempBuffer, sizeof(tempBuffer), ",%5.1f,%4.1f", sds.pm10 / 10, - sds.pm25 / 10); - fileSDCard.print(tempBuffer); + fprintf(data_file, ",%5.1f,%4.1f", sds.pm10 / 10, sds.pm25 / 10); #endif - fileSDCard.println(); - - if (++counterWrites > 2) { - // force writing to SD-card - ESP_LOGI(TAG, "SD: flushing data"); - fileSDCard.flush(); - counterWrites = 0; - } -} - -void openFile(void) { - char bufferFilename[30]; - - useSDCard = false; - - snprintf(bufferFilename, sizeof(bufferFilename), "/%s.csv", SDCARD_FILE_NAME); - ESP_LOGI(TAG, "SD: looking for file <%s>", bufferFilename); - -#if HAS_SDCARD == 1 - bool fileExists = SD.exists(bufferFilename); -#elif HAS_SDCARD == 2 - bool fileExists = SD_MMC.exists(bufferFilename); -#endif - - // file not exists, create it - if (!fileExists) { - ESP_LOGD(TAG, "SD: file not found, creating..."); - -#if HAS_SDCARD == 1 - fileSDCard = SD.open(bufferFilename, FILE_WRITE); -#elif HAS_SDCARD == 2 - fileSDCard = SD_MMC.open(bufferFilename, FILE_WRITE); -#endif - - if (fileSDCard) { - ESP_LOGD(TAG, "SD: name opened: <%s>", bufferFilename); - fileSDCard.print(SDCARD_FILE_HEADER); -#if (defined BAT_MEASURE_ADC || defined HAS_PMU) - fileSDCard.print(SDCARD_FILE_HEADER_VOLTAGE); // for battery level data -#endif -#if (HAS_SDS011) - fileSDCard.print(SDCARD_FILE_HEADER_SDS011); -#endif - fileSDCard.println(); - useSDCard = true; - } - } - - // file exists, append data - else { - ESP_LOGD(TAG, "SD: file found, opening..."); - -#if HAS_SDCARD == 1 - fileSDCard = SD.open(bufferFilename, FILE_APPEND); -#elif HAS_SDCARD == 2 - fileSDCard = SD_MMC.open(bufferFilename, FILE_APPEND); -#endif - - if (fileSDCard) { - ESP_LOGD(TAG, "SD: name opened: <%s>", bufferFilename); - useSDCard = true; - } - } - - return; + fprintf(data_file, "\n"); } #endif // (HAS_SDCARD) diff --git a/src/senddata.cpp b/src/senddata.cpp index fedee7da..d55ee92c 100644 --- a/src/senddata.cpp +++ b/src/senddata.cpp @@ -1,6 +1,9 @@ // Basic Config #include "senddata.h" +// Local logging tag +static const char TAG[] = __FILE__; + void setSendIRQ(TimerHandle_t xTimer) { xTaskNotify(irqHandlerTask, SENDCYCLE_IRQ, eSetBits); } diff --git a/src/timekeeper.cpp b/src/timekeeper.cpp index d51d1570..32b1e0fe 100644 --- a/src/timekeeper.cpp +++ b/src/timekeeper.cpp @@ -63,7 +63,7 @@ void calibrateTime(void) { } // calibrateTime() // set system time (UTC), calibrate RTC and RTC_INT pps -bool IRAM_ATTR setMyTime(uint32_t t_sec, uint16_t t_msec, +bool setMyTime(uint32_t t_sec, uint16_t t_msec, timesource_t mytimesource) { struct timeval tv = {0}; diff --git a/src/timesync.cpp b/src/timesync.cpp index 80355eb8..8660c597 100644 --- a/src/timesync.cpp +++ b/src/timesync.cpp @@ -55,7 +55,7 @@ void timesync_request(void) { } // task for processing time sync request -void IRAM_ATTR timesync_processReq(void *taskparameter) { +void timesync_processReq(void *taskparameter) { uint32_t rcv_seqNo = TIME_SYNC_END_FLAG; uint32_t time_offset_sec = 0, time_offset_ms = 0; @@ -173,7 +173,7 @@ void timesync_store(uint32_t timestamp, timesync_t timestamp_type) { } // callback function to receive time answer from network or answer -void IRAM_ATTR timesync_serverAnswer(void *pUserData, int flag) { +void timesync_serverAnswer(void *pUserData, int flag) { #if (HAS_LORA_TIME)