2018-10-04 22:08:54 +02:00
|
|
|
#include "irqhandler.h"
|
|
|
|
|
|
|
|
// Local logging tag
|
2019-02-27 00:52:27 +01:00
|
|
|
static const char TAG[] = __FILE__;
|
2018-10-04 22:08:54 +02:00
|
|
|
|
|
|
|
// irq handler task, handles all our application level interrupts
|
|
|
|
void irqHandler(void *pvParameters) {
|
|
|
|
|
|
|
|
configASSERT(((uint32_t)pvParameters) == 1); // FreeRTOS check
|
|
|
|
|
|
|
|
uint32_t InterruptStatus;
|
2019-03-24 16:15:29 +01:00
|
|
|
static bool mask_irq = false;
|
2018-10-04 22:08:54 +02:00
|
|
|
|
|
|
|
// task remains in blocked state until it is notified by an irq
|
|
|
|
for (;;) {
|
2019-02-27 00:52:27 +01:00
|
|
|
xTaskNotifyWait(0x00, // Don't clear any bits on entry
|
|
|
|
ULONG_MAX, // Clear all bits on exit
|
|
|
|
&InterruptStatus, // Receives the notification value
|
|
|
|
portMAX_DELAY); // wait forever
|
2018-10-04 22:08:54 +02:00
|
|
|
|
2019-03-31 19:13:06 +02:00
|
|
|
if (InterruptStatus & UNMASK_IRQ) // interrupt handler to be enabled?
|
2019-03-24 16:15:29 +01:00
|
|
|
mask_irq = false;
|
2019-03-31 19:13:06 +02:00
|
|
|
else if (mask_irq) // suppress processing if interrupt handler is disabled
|
|
|
|
continue;
|
|
|
|
else if (InterruptStatus & MASK_IRQ) { // interrupt handler to be disabled?
|
2019-03-24 16:15:29 +01:00
|
|
|
mask_irq = true;
|
2019-03-31 19:13:06 +02:00
|
|
|
continue;
|
|
|
|
}
|
2019-03-24 16:15:29 +01:00
|
|
|
|
2018-10-04 22:08:54 +02:00
|
|
|
// button pressed?
|
|
|
|
#ifdef HAS_BUTTON
|
|
|
|
if (InterruptStatus & BUTTON_IRQ)
|
|
|
|
readButton();
|
|
|
|
#endif
|
|
|
|
|
|
|
|
// display needs refresh?
|
2019-03-13 22:08:05 +01:00
|
|
|
#ifdef HAS_DISPLAY
|
2019-03-31 19:13:06 +02:00
|
|
|
if (InterruptStatus & DISPLAY_IRQ)
|
2019-05-31 13:20:11 +02:00
|
|
|
refreshTheDisplay();
|
2018-10-04 22:08:54 +02:00
|
|
|
#endif
|
|
|
|
|
2019-05-05 23:43:18 +02:00
|
|
|
// LED Matrix display needs refresh?
|
|
|
|
#ifdef HAS_MATRIX_DISPLAY
|
|
|
|
if (InterruptStatus & MATRIX_DISPLAY_IRQ)
|
|
|
|
refreshTheMatrixDisplay();
|
|
|
|
#endif
|
|
|
|
|
2019-04-14 22:54:27 +02:00
|
|
|
// gps refresh buffer?
|
|
|
|
#if (HAS_GPS)
|
|
|
|
if (InterruptStatus & GPS_IRQ)
|
2019-04-15 12:57:55 +02:00
|
|
|
gps_storelocation(gps_status);
|
2019-04-14 22:54:27 +02:00
|
|
|
#endif
|
|
|
|
|
2018-10-04 22:08:54 +02:00
|
|
|
// are cyclic tasks due?
|
2019-03-03 12:57:00 +01:00
|
|
|
if (InterruptStatus & CYCLIC_IRQ)
|
2018-10-04 22:08:54 +02:00
|
|
|
doHousekeeping();
|
|
|
|
|
2019-03-09 00:53:11 +01:00
|
|
|
#if (TIME_SYNC_INTERVAL)
|
2019-03-03 12:57:00 +01:00
|
|
|
// is time to be synced?
|
2019-03-09 15:25:44 +01:00
|
|
|
if (InterruptStatus & TIMESYNC_IRQ) {
|
2019-04-15 13:46:58 +02:00
|
|
|
now(); // ensure sysTime is recent
|
2019-03-09 15:25:44 +01:00
|
|
|
time_t t = timeProvider();
|
|
|
|
if (timeIsValid(t))
|
|
|
|
setTime(t);
|
|
|
|
}
|
2019-03-03 12:57:00 +01:00
|
|
|
#endif
|
2019-03-03 00:30:57 +01:00
|
|
|
|
2018-10-04 22:08:54 +02:00
|
|
|
// is time to send the payload?
|
2019-03-03 12:57:00 +01:00
|
|
|
if (InterruptStatus & SENDCYCLE_IRQ)
|
2018-11-18 15:50:57 +01:00
|
|
|
sendCounter();
|
2018-10-04 22:08:54 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// esp32 hardware timer triggered interrupt service routines
|
|
|
|
// they notify the irq handler task
|
|
|
|
|
2019-03-13 22:08:05 +01:00
|
|
|
#ifdef HAS_DISPLAY
|
2018-10-04 22:08:54 +02:00
|
|
|
void IRAM_ATTR DisplayIRQ() {
|
2019-03-24 00:15:04 +01:00
|
|
|
BaseType_t xHigherPriorityTaskWoken = pdFALSE;
|
2019-03-03 12:57:00 +01:00
|
|
|
|
|
|
|
xTaskNotifyFromISR(irqHandlerTask, DISPLAY_IRQ, eSetBits,
|
2019-05-05 23:43:18 +02:00
|
|
|
&xHigherPriorityTaskWoken);
|
|
|
|
if (xHigherPriorityTaskWoken)
|
|
|
|
portYIELD_FROM_ISR();
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
|
|
|
#ifdef HAS_MATRIX_DISPLAY
|
|
|
|
void IRAM_ATTR MatrixDisplayIRQ() {
|
|
|
|
BaseType_t xHigherPriorityTaskWoken = pdFALSE;
|
|
|
|
|
|
|
|
xTaskNotifyFromISR(irqHandlerTask, MATRIX_DISPLAY_IRQ, eSetBits,
|
2019-03-03 12:57:00 +01:00
|
|
|
&xHigherPriorityTaskWoken);
|
|
|
|
if (xHigherPriorityTaskWoken)
|
|
|
|
portYIELD_FROM_ISR();
|
2018-10-04 22:08:54 +02:00
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
|
|
|
#ifdef HAS_BUTTON
|
|
|
|
void IRAM_ATTR ButtonIRQ() {
|
2019-03-24 00:15:04 +01:00
|
|
|
BaseType_t xHigherPriorityTaskWoken = pdFALSE;
|
2019-03-03 12:57:00 +01:00
|
|
|
|
|
|
|
xTaskNotifyFromISR(irqHandlerTask, BUTTON_IRQ, eSetBits,
|
|
|
|
&xHigherPriorityTaskWoken);
|
|
|
|
|
|
|
|
if (xHigherPriorityTaskWoken)
|
|
|
|
portYIELD_FROM_ISR();
|
2018-10-04 22:08:54 +02:00
|
|
|
}
|
|
|
|
#endif
|
2019-03-31 19:13:06 +02:00
|
|
|
|
2019-04-14 22:54:27 +02:00
|
|
|
#if (HAS_GPS)
|
|
|
|
void IRAM_ATTR GpsIRQ() {
|
|
|
|
BaseType_t xHigherPriorityTaskWoken = pdFALSE;
|
|
|
|
|
|
|
|
xTaskNotifyFromISR(irqHandlerTask, GPS_IRQ, eSetBits,
|
|
|
|
&xHigherPriorityTaskWoken);
|
|
|
|
if (xHigherPriorityTaskWoken)
|
|
|
|
portYIELD_FROM_ISR();
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
2019-03-31 19:13:06 +02:00
|
|
|
int mask_user_IRQ() {
|
|
|
|
// begin of time critical section: lock I2C bus to ensure accurate timing
|
2019-07-16 21:17:13 +02:00
|
|
|
if (I2C_MUTEX_LOCK()) {
|
|
|
|
xTaskNotify(irqHandlerTask, MASK_IRQ, eSetBits);
|
|
|
|
return 0;
|
|
|
|
} else
|
2019-03-31 19:13:06 +02:00
|
|
|
return 1; // failure
|
|
|
|
}
|
|
|
|
|
|
|
|
int unmask_user_IRQ() {
|
|
|
|
// end of time critical section: release I2C bus
|
|
|
|
I2C_MUTEX_UNLOCK();
|
|
|
|
xTaskNotify(irqHandlerTask, UNMASK_IRQ, eSetBits);
|
2019-07-16 21:17:13 +02:00
|
|
|
return 0;
|
|
|
|
}
|