added DCF77 function (experimental, not fully working yet)
This commit is contained in:
parent
9cb828bfbd
commit
39e2df7a05
@ -11,11 +11,14 @@
|
|||||||
#include "bme680mems.h"
|
#include "bme680mems.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// Needed for RTC time sync if RTC present on board
|
|
||||||
#ifdef HAS_RTC
|
#ifdef HAS_RTC
|
||||||
#include "rtctime.h"
|
#include "rtctime.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifdef HAS_DCF77
|
||||||
|
#include "dcf77.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
void doHousekeeping(void);
|
void doHousekeeping(void);
|
||||||
uint64_t uptime(void);
|
uint64_t uptime(void);
|
||||||
void reset_counters(void);
|
void reset_counters(void);
|
||||||
|
16
include/dcf77.h
Normal file
16
include/dcf77.h
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
#ifndef _DCF77_H
|
||||||
|
#define _DCF77_H
|
||||||
|
|
||||||
|
#include "globals.h"
|
||||||
|
|
||||||
|
extern TaskHandle_t DCF77Task;
|
||||||
|
extern hw_timer_t *dcfCycle;
|
||||||
|
|
||||||
|
enum dcf_pulses { dcf_off, dcf_zero, dcf_one };
|
||||||
|
|
||||||
|
int dcf77_init(void);
|
||||||
|
void dcf77_loop(void *pvParameters);
|
||||||
|
void IRAM_ATTR DCF77IRQ(void);
|
||||||
|
void sendDCF77(void);
|
||||||
|
|
||||||
|
#endif
|
@ -2,7 +2,6 @@
|
|||||||
#define _IF482_H
|
#define _IF482_H
|
||||||
|
|
||||||
#include "globals.h"
|
#include "globals.h"
|
||||||
#include "irqhandler.h"
|
|
||||||
|
|
||||||
extern TaskHandle_t IF482Task;
|
extern TaskHandle_t IF482Task;
|
||||||
|
|
||||||
|
@ -60,6 +60,10 @@ void doHousekeeping() {
|
|||||||
ESP_LOGD(TAG, "Bmeloop %d bytes left | Taskstate = %d",
|
ESP_LOGD(TAG, "Bmeloop %d bytes left | Taskstate = %d",
|
||||||
uxTaskGetStackHighWaterMark(BmeTask), eTaskGetState(BmeTask));
|
uxTaskGetStackHighWaterMark(BmeTask), eTaskGetState(BmeTask));
|
||||||
#endif
|
#endif
|
||||||
|
#ifdef HAS_DCF77
|
||||||
|
ESP_LOGD(TAG, "DCF77loop %d bytes left | Taskstate = %d",
|
||||||
|
uxTaskGetStackHighWaterMark(DCF77Task), eTaskGetState(DCF77Task));
|
||||||
|
#endif
|
||||||
|
|
||||||
#if (HAS_LED != NOT_A_PIN) || defined(HAS_RGB_LED)
|
#if (HAS_LED != NOT_A_PIN) || defined(HAS_RGB_LED)
|
||||||
ESP_LOGD(TAG, "LEDloop %d bytes left | Taskstate = %d",
|
ESP_LOGD(TAG, "LEDloop %d bytes left | Taskstate = %d",
|
||||||
@ -79,6 +83,11 @@ void doHousekeeping() {
|
|||||||
bme_status.temperature, bme_status.iaq, bme_status.iaq_accuracy);
|
bme_status.temperature, bme_status.iaq, bme_status.iaq_accuracy);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
// generate DCF77 timeframes
|
||||||
|
#ifdef HAS_DCF77
|
||||||
|
sendDCF77();
|
||||||
|
#endif
|
||||||
|
|
||||||
// check free heap memory
|
// check free heap memory
|
||||||
if (ESP.getMinFreeHeap() <= MEM_LOW) {
|
if (ESP.getMinFreeHeap() <= MEM_LOW) {
|
||||||
ESP_LOGI(TAG,
|
ESP_LOGI(TAG,
|
||||||
|
219
src/dcf77.cpp
Normal file
219
src/dcf77.cpp
Normal file
@ -0,0 +1,219 @@
|
|||||||
|
//
|
||||||
|
// source:
|
||||||
|
// https://www.elektormagazine.com/labs/dcf77-emulator-with-esp8266-elektor-labs-version-150713
|
||||||
|
//
|
||||||
|
/*
|
||||||
|
Simulate a DCF77 radio receiver
|
||||||
|
Emit a complete three minute pulses train from the GPIO output
|
||||||
|
the train is preceded by a single pulse and the lacking 59th pulse to allow
|
||||||
|
some clock model syncronization of the beginning frame. After the three pulses
|
||||||
|
train one more single pulse is sent to safely close the frame
|
||||||
|
*/
|
||||||
|
|
||||||
|
#if defined HAS_DCF77
|
||||||
|
|
||||||
|
#include "dcf77.h"
|
||||||
|
|
||||||
|
// Local logging tag
|
||||||
|
static const char TAG[] = "main";
|
||||||
|
|
||||||
|
TaskHandle_t DCF77Task;
|
||||||
|
QueueHandle_t DCFSendQueue;
|
||||||
|
hw_timer_t *dcfCycle = NULL;
|
||||||
|
|
||||||
|
#define DCF77_FRAME_SIZE 60
|
||||||
|
#define DCF_FRAME_QUEUE_SIZE (HOMECYCLE / 60 + 1)
|
||||||
|
|
||||||
|
// array of dcf pulses for three minutes
|
||||||
|
uint8_t DCFtimeframe[DCF77_FRAME_SIZE];
|
||||||
|
|
||||||
|
// initialize and configure DCF77 output
|
||||||
|
int dcf77_init(void) {
|
||||||
|
|
||||||
|
DCFSendQueue = xQueueCreate(DCF_FRAME_QUEUE_SIZE,
|
||||||
|
sizeof(DCFtimeframe) / sizeof(DCFtimeframe[0]));
|
||||||
|
if (!DCFSendQueue) {
|
||||||
|
ESP_LOGE(TAG, "Could not create DCF77 send queue. Aborting.");
|
||||||
|
return 0; // failure
|
||||||
|
}
|
||||||
|
ESP_LOGI(TAG, "DCF77 send queue created, size %d Bytes",
|
||||||
|
DCF_FRAME_QUEUE_SIZE * sizeof(DCFtimeframe) /
|
||||||
|
sizeof(DCFtimeframe[0]));
|
||||||
|
|
||||||
|
pinMode(HAS_DCF77, OUTPUT);
|
||||||
|
digitalWrite(HAS_DCF77, LOW);
|
||||||
|
|
||||||
|
return 1; // success
|
||||||
|
|
||||||
|
} // ifdcf77_init
|
||||||
|
|
||||||
|
// called every 100msec for DCF77 output
|
||||||
|
void DCF_Ticker() {
|
||||||
|
|
||||||
|
static uint8_t DCF_Frame[DCF77_FRAME_SIZE];
|
||||||
|
static uint8_t bit = 0;
|
||||||
|
static uint8_t pulse = 0;
|
||||||
|
static bool BitsPending = false;
|
||||||
|
|
||||||
|
while (BitsPending) {
|
||||||
|
switch (pulse++) {
|
||||||
|
|
||||||
|
case 0: // start of second -> start of timeframe for logic signal
|
||||||
|
if (DCF_Frame[bit] != dcf_off)
|
||||||
|
digitalWrite(HAS_DCF77, LOW);
|
||||||
|
return;
|
||||||
|
|
||||||
|
case 1: // 100ms after start of second -> end of timeframe for logic 0
|
||||||
|
if (DCF_Frame[bit] == dcf_zero)
|
||||||
|
digitalWrite(HAS_DCF77, HIGH);
|
||||||
|
return;
|
||||||
|
|
||||||
|
case 2: // 200ms after start of second -> end of timeframe for logic signal
|
||||||
|
digitalWrite(HAS_DCF77, HIGH);
|
||||||
|
return;
|
||||||
|
|
||||||
|
case 9: // last pulse before next second starts
|
||||||
|
pulse = 0;
|
||||||
|
if (bit++ != DCF77_FRAME_SIZE)
|
||||||
|
return;
|
||||||
|
else { // last pulse of DCF77 frame (59th second)
|
||||||
|
bit = 0;
|
||||||
|
BitsPending = false;
|
||||||
|
};
|
||||||
|
break;
|
||||||
|
|
||||||
|
}; // switch
|
||||||
|
}; // while
|
||||||
|
|
||||||
|
// get next frame to send from queue
|
||||||
|
if (xQueueReceive(DCFSendQueue, &DCF_Frame, (TickType_t)0) == pdTRUE)
|
||||||
|
BitsPending = true;
|
||||||
|
|
||||||
|
} // DCF_Ticker()
|
||||||
|
|
||||||
|
void dcf77_loop(void *pvParameters) {
|
||||||
|
|
||||||
|
configASSERT(((uint32_t)pvParameters) == 1); // FreeRTOS check
|
||||||
|
|
||||||
|
// 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
|
||||||
|
NULL,
|
||||||
|
portMAX_DELAY); // wait forever (missing error handling here...)
|
||||||
|
|
||||||
|
DCF_Ticker();
|
||||||
|
}
|
||||||
|
vTaskDelete(DCF77Task); // shoud never be reached
|
||||||
|
} // dcf77_loop()
|
||||||
|
|
||||||
|
uint8_t dec2bcd(uint8_t dec, uint8_t startpos, uint8_t endpos,
|
||||||
|
uint8_t pArray[]) {
|
||||||
|
|
||||||
|
uint8_t data = (dec < 10) ? dec : ((dec / 10) << 4) + (dec % 10);
|
||||||
|
uint8_t parity = 0;
|
||||||
|
|
||||||
|
for (uint8_t n = startpos; n <= endpos; n++) {
|
||||||
|
pArray[n] = (data & 1) ? dcf_one : dcf_zero;
|
||||||
|
parity += (data & 1);
|
||||||
|
data >>= 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
return parity;
|
||||||
|
}
|
||||||
|
|
||||||
|
void enqueueTimeframe(time_t t) {
|
||||||
|
|
||||||
|
uint8_t ParityCount;
|
||||||
|
|
||||||
|
// ENCODE HEAD
|
||||||
|
// bits 0..19 initialized with zeros
|
||||||
|
for (int n = 0; n <= 19; n++)
|
||||||
|
DCFtimeframe[n] = dcf_zero;
|
||||||
|
// bits 17..18: adjust for DayLightSaving
|
||||||
|
DCFtimeframe[18 - (myTZ.locIsDST(t) ? 1 : 0)] = dcf_one;
|
||||||
|
// bit 20: must be 1 to indicate time active
|
||||||
|
DCFtimeframe[20] = dcf_one;
|
||||||
|
|
||||||
|
// ENCODE MINUTE (bits 21..28)
|
||||||
|
ParityCount = dec2bcd(minute(t), 21, 27, DCFtimeframe);
|
||||||
|
DCFtimeframe[28] = (ParityCount & 1) ? dcf_one : dcf_zero;
|
||||||
|
|
||||||
|
// ENCODE HOUR (bits 29..35)
|
||||||
|
ParityCount = dec2bcd(hour(t), 29, 34, DCFtimeframe);
|
||||||
|
DCFtimeframe[35] = (ParityCount & 1) ? dcf_one : dcf_zero;
|
||||||
|
|
||||||
|
// ENCODE DATE (bits 36..58)
|
||||||
|
ParityCount = dec2bcd(day(t), 36, 41, DCFtimeframe);
|
||||||
|
ParityCount +=
|
||||||
|
dec2bcd((weekday(t) - 1) ? (weekday(t) - 1) : 7, 42, 44, DCFtimeframe);
|
||||||
|
ParityCount += dec2bcd(month(t), 45, 49, DCFtimeframe);
|
||||||
|
ParityCount +=
|
||||||
|
dec2bcd(year(t) - 2000, 50, 57,
|
||||||
|
DCFtimeframe); // yes, we have a millenium 3000 bug here ;-)
|
||||||
|
DCFtimeframe[58] = (ParityCount & 1) ? dcf_one : dcf_zero;
|
||||||
|
|
||||||
|
// ENCODE TAIL (bit 59)
|
||||||
|
DCFtimeframe[59] = dcf_off;
|
||||||
|
// --> missing code here for switching second!
|
||||||
|
/*
|
||||||
|
In unregelmäßigen Zeitabständen muss eine Schaltsekunde eingefügt werden. Dies
|
||||||
|
ist dadurch bedingt, dass sich die Erde nicht genau in 24 Stunden um sich
|
||||||
|
selbst dreht. Auf die koordinierte Weltzeitskala UTC bezogen, wird diese
|
||||||
|
Korrektur zum Ende der letzten Stunde des 31. Dezember oder 30. Juni
|
||||||
|
vorgenommen. In Mitteleuropa muss die Schaltsekunde daher am 1. Januar um 1.00
|
||||||
|
Uhr MEZ oder am 1.Juli um 2.00 MESZ eingeschoben werden. Zu den genannten
|
||||||
|
Zeiten werden daher 61 Sekunden gesendet.
|
||||||
|
*/
|
||||||
|
|
||||||
|
// post generated DCFtimeframe data to DCF SendQueue
|
||||||
|
if (xQueueSendToBack(DCFSendQueue, (void *)&DCFtimeframe[0], (TickType_t)0) !=
|
||||||
|
pdPASS)
|
||||||
|
ESP_LOGE(TAG, "Failed to send DCF data");
|
||||||
|
|
||||||
|
// for debug: print the DCF77 frame buffer
|
||||||
|
char out[DCF77_FRAME_SIZE + 1];
|
||||||
|
uint8_t i;
|
||||||
|
for (i = 0; i < DCF77_FRAME_SIZE; i++) {
|
||||||
|
out[i] = DCFtimeframe[i] + '0'; // convert int digit to printable ascii
|
||||||
|
}
|
||||||
|
out[DCF77_FRAME_SIZE] = '\0'; // string termination char
|
||||||
|
ESP_LOGD(TAG, "DCF=%s", out);
|
||||||
|
}
|
||||||
|
|
||||||
|
void sendDCF77() {
|
||||||
|
|
||||||
|
time_t t = now();
|
||||||
|
|
||||||
|
/*
|
||||||
|
if (second(t) > 56) {
|
||||||
|
delay(30000);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
|
// enqueue DCF timeframes for each i minute
|
||||||
|
for (uint8_t i = 0; i < DCF_FRAME_QUEUE_SIZE; i++)
|
||||||
|
enqueueTimeframe(t + i * 60);
|
||||||
|
|
||||||
|
/*
|
||||||
|
// how many to the minute end ?
|
||||||
|
// don't forget that we begin transmission at second 58
|
||||||
|
delay((58 - second(t)) * 1000);
|
||||||
|
|
||||||
|
// three minutes are needed to transmit all the packet
|
||||||
|
// then wait more 30 secs to locate safely at the half of minute
|
||||||
|
// NB 150+60=210sec, 60secs are lost from main routine
|
||||||
|
delay(150000);
|
||||||
|
*/
|
||||||
|
|
||||||
|
} // Ende ReadAndDecodeTime()
|
||||||
|
|
||||||
|
// interrupt service routine triggered each 100ms by ESP32 hardware timer
|
||||||
|
void IRAM_ATTR DCF77IRQ() {
|
||||||
|
xTaskNotifyFromISR(DCF77Task, xTaskGetTickCountFromISR(), eSetBits, NULL);
|
||||||
|
portYIELD_FROM_ISR();
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif // HAS_DCF77
|
@ -145,12 +145,14 @@ void refreshtheDisplay() {
|
|||||||
|
|
||||||
uint8_t msgWaiting;
|
uint8_t msgWaiting;
|
||||||
char buff[16]; // 16 chars line buffer
|
char buff[16]; // 16 chars line buffer
|
||||||
|
#if defined HAS_RTC || defined HAS_GPS
|
||||||
const char timeNosyncSymbol = '?';
|
const char timeNosyncSymbol = '?';
|
||||||
#ifdef HAS_IF482
|
#if defined HAS_IF482 || defined HAS_DCF77
|
||||||
const char timesyncSymbol = '+';
|
const char timesyncSymbol = '+';
|
||||||
#else
|
#else
|
||||||
const char timesyncSymbol = '*';
|
const char timesyncSymbol = '*';
|
||||||
#endif
|
#endif
|
||||||
|
#endif // HAS_RTC
|
||||||
|
|
||||||
// update counter (lines 0-1)
|
// update counter (lines 0-1)
|
||||||
snprintf(
|
snprintf(
|
||||||
@ -214,17 +216,16 @@ void refreshtheDisplay() {
|
|||||||
u8x8.printf("%4dKB", getFreeRAM() / 1024);
|
u8x8.printf("%4dKB", getFreeRAM() / 1024);
|
||||||
|
|
||||||
#ifdef HAS_LORA
|
#ifdef HAS_LORA
|
||||||
|
|
||||||
u8x8.setCursor(0, 6);
|
u8x8.setCursor(0, 6);
|
||||||
#ifndef HAS_RTC
|
#if (!defined HAS_RTC) && (!defined HAS_GPS)
|
||||||
// update LoRa status display (line 6)
|
// update LoRa status display (line 6)
|
||||||
u8x8.printf("%-16s", display_line6);
|
u8x8.printf("%-16s", display_line6);
|
||||||
#else
|
#else // HAS_RTC or HAS_GPS
|
||||||
// update time/date display (line 6)
|
// update time/date display (line 6)
|
||||||
time_t t = myTZ.toLocal(now());
|
time_t t = myTZ.toLocal(now());
|
||||||
char timeState =
|
char timeState =
|
||||||
timeStatus() == timeSet ? timesyncSymbol : timeNosyncSymbol;
|
timeStatus() == timeSet ? timesyncSymbol : timeNosyncSymbol;
|
||||||
#ifdef RTC_INT // make timestatus symbol blinking
|
#ifdef RTC_INT // make timestatus symbol blinking if pps line
|
||||||
if (second(t) % 2)
|
if (second(t) % 2)
|
||||||
timeState = ' ';
|
timeState = ' ';
|
||||||
#endif // RTC_INT
|
#endif // RTC_INT
|
||||||
|
@ -73,7 +73,7 @@ time_t get_gpstime(void) {
|
|||||||
if ((gps.time.age() < 1500) && (gps.time.isValid())) {
|
if ((gps.time.age() < 1500) && (gps.time.isValid())) {
|
||||||
t = tmConvert_t(gps.date.year(), gps.date.month(), gps.date.day(),
|
t = tmConvert_t(gps.date.year(), gps.date.month(), gps.date.day(),
|
||||||
gps.time.hour(), gps.time.minute(), gps.time.second());
|
gps.time.hour(), gps.time.minute(), gps.time.second());
|
||||||
ESP_LOGD(TAG, "GPS time: %d/%d/%d %d:%d:%d", year(t), month(t), day(t),
|
ESP_LOGD(TAG, "GPS time: %4d/%02d/%02d %02d:%02d:%02d", year(t), month(t), day(t),
|
||||||
hour(t), minute(t), second(t));
|
hour(t), minute(t), second(t));
|
||||||
} else {
|
} else {
|
||||||
ESP_LOGW(TAG, "GPS has no confident time");
|
ESP_LOGW(TAG, "GPS has no confident time");
|
||||||
|
@ -55,6 +55,9 @@
|
|||||||
// Settings for IF482 interface
|
// Settings for IF482 interface
|
||||||
#define HAS_IF482 9600, SERIAL_7E1, GPIO_NUM_12, GPIO_NUM_14 // IF482 serial port parameters
|
#define HAS_IF482 9600, SERIAL_7E1, GPIO_NUM_12, GPIO_NUM_14 // IF482 serial port parameters
|
||||||
|
|
||||||
|
// Settings for DCF77 interface
|
||||||
|
#define HAS_DCF77 GPIO_NUM_13
|
||||||
|
|
||||||
// Pins for LORA chip SPI interface, reset line and interrupt lines
|
// Pins for LORA chip SPI interface, reset line and interrupt lines
|
||||||
#define LORA_SCK (5)
|
#define LORA_SCK (5)
|
||||||
#define LORA_CS (18)
|
#define LORA_CS (18)
|
||||||
|
45
src/main.cpp
45
src/main.cpp
@ -28,7 +28,8 @@ Uused tasks and timers:
|
|||||||
Task Core Prio Purpose
|
Task Core Prio Purpose
|
||||||
====================================================================================
|
====================================================================================
|
||||||
ledloop 0 3 blinks LEDs
|
ledloop 0 3 blinks LEDs
|
||||||
if482loop 1 3 serial feed of IF482 time telegrams
|
if482loop 0 3 generates serial feed of IF482 time telegrams
|
||||||
|
dcf77loop 0 3 generates DCF77 timeframe pulses
|
||||||
spiloop 0 2 reads/writes data on spi interface
|
spiloop 0 2 reads/writes data on spi interface
|
||||||
IDLE 0 0 ESP32 arduino scheduler -> runs wifi sniffer
|
IDLE 0 0 ESP32 arduino scheduler -> runs wifi sniffer
|
||||||
|
|
||||||
@ -46,13 +47,13 @@ Tasks using i2c bus all must have same priority, because using mutex semaphore
|
|||||||
ESP32 hardware timers
|
ESP32 hardware timers
|
||||||
================================
|
================================
|
||||||
0 triggers display refresh
|
0 triggers display refresh
|
||||||
1 unused (reserved for DCF77)
|
1 triggers DCF77 clock signal
|
||||||
2 triggers send payload cycle
|
2 triggers send payload cycle
|
||||||
3 triggers housekeeping cycle
|
3 triggers housekeeping cycle
|
||||||
|
|
||||||
RTC hardware timer (if present)
|
RTC hardware timer (if present)
|
||||||
================================
|
================================
|
||||||
triggers IF482 clock generator
|
triggers IF482 clock signal
|
||||||
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
@ -64,8 +65,12 @@ char display_line6[16], display_line7[16]; // display buffers
|
|||||||
uint8_t volatile channel = 0; // channel rotation counter
|
uint8_t volatile channel = 0; // channel rotation counter
|
||||||
uint16_t volatile macs_total = 0, macs_wifi = 0, macs_ble = 0,
|
uint16_t volatile macs_total = 0, macs_wifi = 0, macs_ble = 0,
|
||||||
batt_voltage = 0; // globals for display
|
batt_voltage = 0; // globals for display
|
||||||
hw_timer_t *channelSwitch = NULL, *sendCycle = NULL, *homeCycle = NULL,
|
|
||||||
*displaytimer = NULL; // irq tasks
|
hw_timer_t *sendCycle = NULL, *homeCycle = NULL;
|
||||||
|
#ifdef HAS_DISPLAY
|
||||||
|
hw_timer_t *displaytimer = NULL;
|
||||||
|
#endif
|
||||||
|
|
||||||
TaskHandle_t irqHandlerTask;
|
TaskHandle_t irqHandlerTask;
|
||||||
SemaphoreHandle_t I2Caccess;
|
SemaphoreHandle_t I2Caccess;
|
||||||
|
|
||||||
@ -327,6 +332,16 @@ void setup() {
|
|||||||
setSyncInterval(TIME_SYNC_INTERVAL_RTC * 60);
|
setSyncInterval(TIME_SYNC_INTERVAL_RTC * 60);
|
||||||
#endif // HAS_RTC
|
#endif // HAS_RTC
|
||||||
|
|
||||||
|
#if defined HAS_DCF77
|
||||||
|
strcat_P(features, " DCF77");
|
||||||
|
assert(dcf77_init());
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if defined HAS_IF482 && defined RTC_INT
|
||||||
|
strcat_P(features, " IF482");
|
||||||
|
assert(if482_init());
|
||||||
|
#endif
|
||||||
|
|
||||||
// show compiled features
|
// show compiled features
|
||||||
ESP_LOGI(TAG, "Features:%s", features);
|
ESP_LOGI(TAG, "Features:%s", features);
|
||||||
|
|
||||||
@ -403,8 +418,6 @@ void setup() {
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if defined HAS_IF482 && defined RTC_INT
|
#if defined HAS_IF482 && defined RTC_INT
|
||||||
strcat_P(features, " IF482");
|
|
||||||
assert(if482_init());
|
|
||||||
ESP_LOGI(TAG, "Starting IF482 Generator...");
|
ESP_LOGI(TAG, "Starting IF482 Generator...");
|
||||||
xTaskCreatePinnedToCore(if482_loop, // task function
|
xTaskCreatePinnedToCore(if482_loop, // task function
|
||||||
"if482loop", // name of task
|
"if482loop", // name of task
|
||||||
@ -419,6 +432,24 @@ void setup() {
|
|||||||
attachInterrupt(digitalPinToInterrupt(RTC_INT), IF482IRQ, FALLING);
|
attachInterrupt(digitalPinToInterrupt(RTC_INT), IF482IRQ, FALLING);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#if defined HAS_DCF77
|
||||||
|
ESP_LOGI(TAG, "Starting DCF77 Generator...");
|
||||||
|
xTaskCreatePinnedToCore(dcf77_loop, // task function
|
||||||
|
"dcf77loop", // name of task
|
||||||
|
2048, // stack size of task
|
||||||
|
(void *)1, // parameter of the task
|
||||||
|
3, // priority of the task
|
||||||
|
&DCF77Task, // task handle
|
||||||
|
0); // CPU core
|
||||||
|
|
||||||
|
// setup 100ms clock signal for DCF77 generator using esp32 hardware timer 1
|
||||||
|
assert(DCF77Task != NULL); // has dcf77 task started?
|
||||||
|
dcfCycle = timerBegin(1, 8000, true);
|
||||||
|
timerAttachInterrupt(dcfCycle, &DCF77IRQ, true);
|
||||||
|
timerAlarmWrite(dcfCycle, 1000, true);
|
||||||
|
timerAlarmEnable(dcfCycle);
|
||||||
|
#endif
|
||||||
|
|
||||||
} // setup()
|
} // setup()
|
||||||
|
|
||||||
void loop() {
|
void loop() {
|
||||||
|
Loading…
Reference in New Issue
Block a user