From 7c68f7632ae39690dde750f5d57095e7aea3fe42 Mon Sep 17 00:00:00 2001 From: Klaus K Wilting Date: Sun, 27 Jan 2019 18:19:25 +0100 Subject: [PATCH] v1.7.14 (new feature IF482 time telegram complete) --- README.md | 1 + include/globals.h | 4 +++ include/if482.h | 7 +++-- include/irqhandler.h | 9 +------ platformio.ini | 8 +++--- src/hal/ttgofox.h | 3 +-- src/if482.cpp | 61 +++++++++++++++++++++++++++++++++++--------- src/irqhandler.cpp | 13 ---------- src/main.cpp | 30 ++++++++++++++++------ src/paxcounter.conf | 7 ++--- 10 files changed, 91 insertions(+), 52 deletions(-) diff --git a/README.md b/README.md index 4572dcc7..1a9f8858 100644 --- a/README.md +++ b/README.md @@ -50,6 +50,7 @@ Depending on board hardware following features are supported: - GPS (Generic serial NMEA, or Quectel L76 I2C) - Environmental sensor (Bosch BME680 I2C) - Real Time Clock (Maxim DS3231 I2C) +- IF482 time telegram generator (serial port) Target platform must be selected in [platformio.ini](https://github.com/cyberman54/ESP32-Paxcounter/blob/master/platformio.ini).
Hardware dependent settings (pinout etc.) are stored in board files in /hal directory. If you want to use a ESP32 board which is not yet supported, use hal file generic.h and tailor pin mappings to your needs. Pull requests for new boards welcome.
diff --git a/include/globals.h b/include/globals.h index 01f912ff..890e93cc 100644 --- a/include/globals.h +++ b/include/globals.h @@ -140,4 +140,8 @@ extern TaskHandle_t irqHandlerTask, wifiSwitchTask; #include "bme680mems.h" #endif +#ifdef HAS_IF482 +#include "if482.h" +#endif + #endif \ No newline at end of file diff --git a/include/if482.h b/include/if482.h index 85871867..7ceca1c5 100644 --- a/include/if482.h +++ b/include/if482.h @@ -4,7 +4,10 @@ #include "globals.h" #include "irqhandler.h" -void if482_init(void); -void sendIF482(time_t t); +extern TaskHandle_t IF482Task; + +int if482_init(void); +void if482_loop(void *pvParameters); +void IRAM_ATTR IF482IRQ(void); #endif \ No newline at end of file diff --git a/include/irqhandler.h b/include/irqhandler.h index 9adebe42..45d58fee 100644 --- a/include/irqhandler.h +++ b/include/irqhandler.h @@ -5,7 +5,6 @@ #define BUTTON_IRQ 0x02 #define SENDCOUNTER_IRQ 0x04 #define CYCLIC_IRQ 0x08 -#define IF482_IRQ 0x10 #include "globals.h" #include "cyclic.h" @@ -26,10 +25,4 @@ void IRAM_ATTR DisplayIRQ(); void IRAM_ATTR ButtonIRQ(); #endif -#ifdef HAS_IF482 -#include "if482.h" -void IRAM_ATTR IF482IRQ(); -#endif - - -#endif +#endif \ No newline at end of file diff --git a/platformio.ini b/platformio.ini index 8fb6b471..dc23914f 100644 --- a/platformio.ini +++ b/platformio.ini @@ -6,7 +6,7 @@ ; ---> SELECT TARGET PLATFORM HERE! <--- [platformio] -;env_default = generic +env_default = generic ;env_default = ebox ;env_default = eboxtube ;env_default = heltec @@ -16,7 +16,7 @@ ;env_default = ttgov21old ;env_default = ttgov21new ;env_default = ttgobeam -env_default = ttgofox +;env_default = ttgofox ;env_default = lopy ;env_default = lopy4 ;env_default = fipy @@ -30,7 +30,7 @@ description = Paxcounter is a proof-of-concept ESP32 device for metering passeng [common] ; for release_version use max. 10 chars total, use any decimal format like "a.b.c" -release_version = 1.7.12 +release_version = 1.7.14 ; 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 @@ -45,7 +45,7 @@ monitor_speed = 115200 lib_deps_lora = MCCI LoRaWAN LMIC library@^2.3.1 lib_deps_display = - U8g2@>=2.25.0 + U8g2@>=2.25.5 lib_deps_rgbled = SmartLeds@>=1.1.3 lib_deps_gps = diff --git a/src/hal/ttgofox.h b/src/hal/ttgofox.h index 4d60f877..414cedd1 100644 --- a/src/hal/ttgofox.h +++ b/src/hal/ttgofox.h @@ -25,8 +25,7 @@ #define RTC_INT GPIO_NUM_34 // interrupt input from rtc // Settings for IF482 interface -#define HAS_IF482 9600, SERIAL_7E1, GPIO_NUM_12, GPIO_NUM_15 // IF482 serial port parameters -#define IF482_PORT 1 // serial port 1 +//#define HAS_IF482 9600, SERIAL_7E1, GPIO_NUM_12, GPIO_NUM_14 // IF482 serial port parameters // Pins for LORA chip SPI interface, reset line and interrupt lines #define LORA_SCK (5) diff --git a/src/if482.cpp b/src/if482.cpp index cf6a9854..b1bc7efb 100644 --- a/src/if482.cpp +++ b/src/if482.cpp @@ -69,10 +69,12 @@ not evaluated by model BU-190 // Local logging tag static const char TAG[] = "main"; -HardwareSerial IF482(1); // use UART #1 +TaskHandle_t IF482Task; + +HardwareSerial IF482(2); // use UART #2 (note: #1 may be in use for serial GPS) // initialize and configure GPS -void if482_init(void) { +int if482_init(void) { // open serial interface IF482.begin(HAS_IF482); @@ -84,6 +86,8 @@ void if482_init(void) { ESP_LOGI(TAG, "IF482 generator initialized"); + return 1; + } // if482_init String if482Telegram(time_t t) { @@ -93,31 +97,64 @@ String if482Telegram(time_t t) { char out[17]; switch (timeStatus()) { // indicates if time has been set and recently synced - - case timeSet: // time is set and is synced + case timeSet: // time is set and is synced mon = 'A'; break; - case timeNeedsSync: // time had been set but sync attempt did not succeed mon = 'M'; break; - default: // time not set, no valid time mon = '?'; break; - } // switch if (!timeNotSet) // do we have valid time? - snprintf(buf, sizeof buf, "%02u%02u%02u%1u%02u%02u%02u", year(t)-2000, month(t), - day(t), weekday(t), hour(t), minute(t), second(t)); + snprintf(buf, sizeof buf, "%02u%02u%02u%1u%02u%02u%02u", year(t) - 2000, + month(t), day(t), weekday(t), hour(t), minute(t), second(t)); snprintf(out, sizeof out, "O%cL%s\r", mon, buf); - return out; } -// interrupt triggered routine -void sendIF482(time_t t) { IF482.print(if482Telegram(t)); } +void if482_loop(void *pvParameters) { + + configASSERT(((uint32_t)pvParameters) == 1); // FreeRTOS check + + TickType_t wakeTime; + time_t t, tt; + const TickType_t shotTime = pdMS_TO_TICKS(IF482_OFFSET); + + // wait until begin of a new second + t = tt = now(); + do { + tt = now(); + } while (t == tt); + + const TickType_t startTime = xTaskGetTickCount(); + + // task remains in blocked state until it is notified by isr + for (;;) { + xTaskNotifyWait( + 0x00, // don't clear any bits on entry + ULONG_MAX, // clear all bits on exit + &wakeTime, // receives moment of call from isr + portMAX_DELAY); // wait forever (missing error handling here...) + + t = now(); + wakeTime -= startTime; + + // now we're synced to start of second t and wait + // until it's time to start transmit telegram for t+1 + vTaskDelayUntil(&wakeTime, shotTime); + IF482.print(if482Telegram(t + 1)); + } + vTaskDelete(IF482Task); // shoud never be reached +} // if482_loop() + +// interrupt service routine triggered by RTC 1Hz precise clock +void IRAM_ATTR IF482IRQ() { + xTaskNotifyFromISR(IF482Task, xTaskGetTickCountFromISR(), eSetBits, NULL); + portYIELD_FROM_ISR(); +} #endif // HAS_IF482 \ No newline at end of file diff --git a/src/irqhandler.cpp b/src/irqhandler.cpp index ad01a592..f79e035e 100644 --- a/src/irqhandler.cpp +++ b/src/irqhandler.cpp @@ -18,12 +18,6 @@ void irqHandler(void *pvParameters) { &InterruptStatus, // Receives the notification value portMAX_DELAY); // wait forever (missing error handling here...) -// IF482 interrupt? -#ifdef HAS_IF482 - if (InterruptStatus & IF482_IRQ) - sendIF482(now()); -#endif - // button pressed? #ifdef HAS_BUTTON if (InterruptStatus & BUTTON_IRQ) @@ -78,10 +72,3 @@ void IRAM_ATTR ButtonIRQ() { portYIELD_FROM_ISR(); } #endif - -#ifdef HAS_IF482 -void IRAM_ATTR IF482IRQ() { - xTaskNotifyFromISR(irqHandlerTask, IF482_IRQ, eSetBits, NULL); - portYIELD_FROM_ISR(); -} -#endif diff --git a/src/main.cpp b/src/main.cpp index acaf8c0b..34940bf8 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -29,6 +29,7 @@ Task Core Prio Purpose ==================================================================================== wifiloop 0 4 rotates wifi channels ledloop 0 3 blinks LEDs +if482loop 1 3 serial feed of IF482 time telegrams spiloop 0 2 reads/writes data on spi interface IDLE 0 0 ESP32 arduino scheduler -> runs wifi sniffer @@ -44,11 +45,15 @@ Tasks using i2c bus all must have same priority, because using mutex semaphore (irqhandler, bmeloop) ESP32 hardware timers -========================== - 0 Trigger display refresh - 1 Trigger Wifi channel switch - 2 Trigger send payload cycle - 3 Trigger housekeeping cycle +================================ + 0 triggers display refresh + 1 triggers Wifi channel switch + 2 triggers send payload cycle + 3 triggers housekeeping cycle + + RTC hardware timer (if present) +================================ + triggers IF482 clock generator */ @@ -185,9 +190,18 @@ void setup() { sync_rtctime(); #ifdef HAS_IF482 strcat_P(features, " IF482"); - if482_init(); -#endif -#endif + if (if482_init()) { + ESP_LOGI(TAG, "Starting IF482loop..."); + xTaskCreatePinnedToCore(if482_loop, // task function + "if482loop", // name of task + 2048, // stack size of task + (void *)1, // parameter of the task + 3, // priority of the task + &IF482Task, // task handle + 0); // CPU core + } +#endif // HAS_IF482 +#endif // HAS_RTC // initialize wifi antenna #ifdef HAS_ANTENNA_SWITCH diff --git a/src/paxcounter.conf b/src/paxcounter.conf index e63b2d1c..1b1875e3 100644 --- a/src/paxcounter.conf +++ b/src/paxcounter.conf @@ -81,9 +81,10 @@ #define OTA_MIN_BATT 3600 // minimum battery level for OTA [millivolt] #define RESPONSE_TIMEOUT_MS 60000 // firmware binary server connection timeout [milliseconds] -// setting for syncing time of node -#define TIME_SYNC_INTERVAL 60 // sync time each ... minutes with external source [default = 60], comment out means off +// settings for syncing time of node and external time sources +//#define TIME_SYNC_INTERVAL 60 // sync time each ... minutes with external source [default = 60], comment out means off #define TIME_SYNC_INTERVAL_RTC 5 // sync time each ... minutes with RTC [default = 5], comment out means off +#define IF482_OFFSET 984 // 1sec minus IF482 serial transmit time [ms]: e.g. 9 bits * 17 bytes * 1/9600 bps = 16ms // LMIC settings -// moved to src/lmic_config.h +// moved to src/lmic_config.h \ No newline at end of file