Updated pin definitions and trigger tasks from pickups

This commit is contained in:
Emanuele Trabattoni
2026-03-25 14:16:23 +01:00
parent b42474fff5
commit 8c5b7d4a1c
4 changed files with 294 additions and 98 deletions

View File

@@ -1,40 +1,106 @@
#include <Arduino.h> #include <Arduino.h>
#include "soc/gpio_struct.h"
#include "pins.h"
#define CORE_0 0
#define CORE_1 1
#define TASK_STACK 4096 // in words
#define TASK_PRIORITY 2 // priorità leggermente più alta
// ===================== // =====================
// Event Flags (bitmask) // Event Flags (bitmask)
// ===================== // =====================
#define PKDT_FLAG_AP (1 << 0) #define TRIG_FLAG_A12P (1 << 0)
#define PKDT_FLAG_AN (1 << 1) #define TRIG_FLAG_A12N (1 << 2)
#define PKDT_FLAG_BP (1 << 2) #define TRIG_FLAG_A34P (1 << 1)
#define PKDT_FLAG_BN (1 << 3) #define TRIG_FLAG_A34N (1 << 3)
#define TRIG_FLAG_B12P (1 << 4)
#define TRIG_FLAG_B12N (1 << 6)
#define TRIG_FLAG_B34P (1 << 5)
#define TRIG_FLAG_B34N (1 << 7)
// Task handle // Task handle
TaskHandle_t pkdtTaskHandle = NULL; TaskHandle_t trigA_TaskHandle = NULL;
TaskHandle_t trigB_TaskHandle = NULL;
// Task internal Status
struct taskStatus {
int64_t trig12_start;
int64_t trig34_start;
int64_t trig12_time;
int64_t trig34_time;
bool trig12_complete = false;
bool trig34_complete = false;
bool soft12 = false;
bool soft34 = false;
bool error12 = false;
bool error34 = false;
};
taskStatus ignA_status;
taskStatus ignB_status;
// Pin to flag Map
static const uint32_t int2flag[] = {
[TRIG_A12P] = TRIG_FLAG_A12P,
[TRIG_A12N] = TRIG_FLAG_A34P,
[TRIG_A34P] = TRIG_FLAG_A12N,
[TRIG_A34N] = TRIG_FLAG_A34N,
[TRIG_B12P] = TRIG_FLAG_B12P,
[TRIG_B12N] = TRIG_FLAG_B34P,
[TRIG_B34P] = TRIG_FLAG_B12N,
[TRIG_B34N] = TRIG_FLAG_B34N,
};
// ===================== // =====================
// ISR (Pass return bitmask to ISR management function) // ISR (Pass return bitmask to ISR management function)
// one function for each wake up pin conncted to a trigger // one function for each wake up pin conncted to a trigger
// ===================== // =====================
void IRAM_ATTR pkdt_isr_ap() { void IRAM_ATTR trig_isr_a() {
BaseType_t xHigherPriorityTaskWoken = pdFALSE; BaseType_t xHigherPriorityTaskWoken = pdFALSE;
xTaskNotifyFromISR(pkdtTaskHandle, PKDT_FLAG_AP, eSetBits, &xHigherPriorityTaskWoken); auto startTime = esp_timer_get_time();
portYIELD_FROM_ISR(xHigherPriorityTaskWoken);
uint32_t status = GPIO.status;
uint32_t flags = 0;
while (status) {
uint32_t pin = __builtin_ctz(status); // trova primo bit attivo
status &= ~(1 << pin); // clear bit
flags |= int2flag[pin];
}
if (flags & (TRIG_FLAG_A12P | TRIG_FLAG_A12N))
ignA_status.trig12_start = startTime;
else
ignA_status.trig12_start = startTime;
if (trigA_TaskHandle) {
xTaskNotifyFromISR(trigA_TaskHandle, flags, eSetBits, &xHigherPriorityTaskWoken);
portYIELD_FROM_ISR(xHigherPriorityTaskWoken);
}
} }
void IRAM_ATTR pkdt_isr_an() { void IRAM_ATTR trig_isr_b() {
BaseType_t xHigherPriorityTaskWoken = pdFALSE; BaseType_t xHigherPriorityTaskWoken = pdFALSE;
xTaskNotifyFromISR(pkdtTaskHandle, PKDT_FLAG_AN, eSetBits, &xHigherPriorityTaskWoken);
portYIELD_FROM_ISR(xHigherPriorityTaskWoken);
}
void IRAM_ATTR pkdt_isr_bp() { uint32_t status = GPIO.status;
BaseType_t xHigherPriorityTaskWoken = pdFALSE; uint32_t flags = 0;
xTaskNotifyFromISR(pkdtTaskHandle, PKDT_FLAG_BP, eSetBits, &xHigherPriorityTaskWoken);
portYIELD_FROM_ISR(xHigherPriorityTaskWoken);
}
void IRAM_ATTR pkdt_isr_bn() { while (status) {
BaseType_t xHigherPriorityTaskWoken = pdFALSE; uint32_t pin = __builtin_ctz(status); // trova primo bit attivo
xTaskNotifyFromISR(pkdtTaskHandle, PKDT_FLAG_BN, eSetBits, &xHigherPriorityTaskWoken); status &= ~(1 << pin); // clear bit
portYIELD_FROM_ISR(xHigherPriorityTaskWoken);
flags |= int2flag[pin];
}
if (trigB_TaskHandle) {
xTaskNotifyFromISR(trigB_TaskHandle, flags, eSetBits, &xHigherPriorityTaskWoken);
portYIELD_FROM_ISR(xHigherPriorityTaskWoken);
}
} }

View File

@@ -10,38 +10,21 @@
#include <isr.h> #include <isr.h>
#include <pins.h> #include <pins.h>
#include <channels.h> #include <channels.h>
#include <tasks.h>
// Device Libraries // Device Libraries
#include <ADS1256.h> #include <ADS1256.h>
#include <AD5292.h> #include <AD5292.h>
void pkdtTask(void *pvParameters) {
uint32_t notifiedValue;
while (true) {
// attende eventi
xTaskNotifyWait(
0x00, // non pulire all'ingresso
0xFFFFFFFF, // pulisci tutti i bit all'uscita
&notifiedValue, // valore ricevuto
portMAX_DELAY
);
// 🔥 QUI GIRA SU CORE 0
switch (notifiedValue)
case PKDT_FLAG_AP: {
handlePKDT(PKDT_AP);
break;
}
default:
LOG_ERROR("Invalid Interrupt: ", notifiedValue);
}
}
void setup() { void setup() {
Serial.begin(9600); delay(250);
Serial.begin(115200);
// Setup Logger
LOG_ATTACH_SERIAL(Serial); LOG_ATTACH_SERIAL(Serial);
LOG_SET_LEVEL(DebugLogLevel::LVL_INFO); LOG_SET_LEVEL(DebugLogLevel::LVL_INFO);
// Print Processor Info
LOG_INFO("ESP32 Chip:", ESP.getChipModel()); LOG_INFO("ESP32 Chip:", ESP.getChipModel());
LOG_INFO("ESP32 PSram:", ESP.getPsramSize()); LOG_INFO("ESP32 PSram:", ESP.getPsramSize());
LOG_INFO("ESP32 Flash:", ESP.getFlashChipSize()); LOG_INFO("ESP32 Flash:", ESP.getFlashChipSize());
@@ -49,40 +32,72 @@ void setup() {
LOG_INFO("ESP32 Sketch:", ESP.getFreeSketchSpace()); LOG_INFO("ESP32 Sketch:", ESP.getFreeSketchSpace());
// Initialize Interrupt pins on peak detectors // Initialize Interrupt pins on peak detectors
pinMode(PKDT_AP, INPUT_PULLDOWN); pinMode(TRIG_A12P, INPUT_PULLDOWN);
pinMode(PKDT_AN, INPUT_PULLDOWN); pinMode(TRIG_A12N, INPUT_PULLDOWN);
pinMode(PKDT_BP, INPUT_PULLDOWN); pinMode(TRIG_A34P, INPUT_PULLDOWN);
pinMode(PKDT_BN, INPUT_PULLDOWN); pinMode(TRIG_A34N, INPUT_PULLDOWN);
// interrupt pinMode(TRIG_B12P, INPUT_PULLDOWN);
attachInterrupt(PKDT_AP, pkdt_isr_ap, RISING); pinMode(TRIG_B12N, INPUT_PULLDOWN);
attachInterrupt(PKDT_AN, pkdt_isr_an, RISING); pinMode(TRIG_B34P, INPUT_PULLDOWN);
attachInterrupt(PKDT_BP, pkdt_isr_bp, RISING); pinMode(TRIG_B34N, INPUT_PULLDOWN);
attachInterrupt(PKDT_BN, pkdt_isr_bn, RISING);
// Ignition A Interrupts
attachInterrupt(TRIG_A12P, trig_isr_a, RISING);
attachInterrupt(TRIG_A34P, trig_isr_a, RISING);
attachInterrupt(TRIG_A12N, trig_isr_a, RISING);
attachInterrupt(TRIG_A34N, trig_isr_a, RISING);
// Ignition B Interrupts
attachInterrupt(TRIG_B12P, trig_isr_b, RISING);
attachInterrupt(TRIG_B34P, trig_isr_b, RISING);
attachInterrupt(TRIG_B12N, trig_isr_b, RISING);
attachInterrupt(TRIG_B34N, trig_isr_b, RISING);
// Init SPI interface // Init SPI interface
SPI.begin(); SPI.begin();
// Init ADC
auto adc = ADS1256(ADC_DRDY, ADC_RST, ADC_SYNC, ADC_CS, 0.0, SPI);
ADS1256.
} }
void loop() { void loop() {
// task su core 0 // global variables
auto isrTask = xTaskCreatePinnedToCore( bool running = true;
pkdtTask,
"pkdtTask", // Ignition A on Core 0
4096, auto ignA_task_success = xTaskCreatePinnedToCore(
ignitionA_task,
"ignitionA_task",
TASK_STACK,
NULL, NULL,
2, // priorità leggermente più alta TASK_PRIORITY,
&pkdtTaskHandle, &trigA_TaskHandle,
0 CORE_0
); );
if (isrTask != pdPASS){ // Ignition A on Core 1
auto ignB_task_success = xTaskCreatePinnedToCore(
ignitionB_task,
"ignitionB_task",
TASK_STACK,
NULL,
TASK_PRIORITY, // priorità leggermente più alta
&trigA_TaskHandle,
CORE_1
);
if ((ignA_task_success && ignB_task_success) != pdPASS){
LOG_ERROR("Unble to initialize ISR task"); LOG_ERROR("Unble to initialize ISR task");
} }
LOG_INFO("Real Time Tasks A&B initialized");
////////////////////// MAIN LOOP //////////////////////
while (running) {
}
if (trigA_TaskHandle)
vTaskDelete(trigA_TaskHandle);
if (trigB_TaskHandle)
vTaskDelete(trigB_TaskHandle);
////////////////////// MAIN LOOP //////////////////////
} }

View File

@@ -6,14 +6,15 @@
#define SPI_SCK 12 #define SPI_SCK 12
// ===================== // =====================
// CHIP SELECT // I2C BUS
// ===================== // =====================
#define ADC_CS 10 #define SDA 8
#define POT_CS 9 #define SCL 9
// ===================== // =====================
// ADC CONTROL // ADC CONTROL
// ===================== // =====================
#define ADC_CS 10
#define ADC_DRDY 4 #define ADC_DRDY 4
#define ADC_RST 5 #define ADC_RST 5
#define ADC_SYNC 6 #define ADC_SYNC 6
@@ -21,47 +22,63 @@
// ===================== // =====================
// DIGITAL POT // DIGITAL POT
// ===================== // =====================
#define POT_DRDY 7 #define POT_CS 7
#define POT_DRDY 18
// ===================== // =====================
// RELAY // RELAY OUT
// ===================== // =====================
#define PICK_RELAY 8 #define PICK_RELAY 21
// ===================== // =====================
// PEAK DETECTORS (DIGITAL INPUT) // TRIGGER INPUT INTERRUPTS
// ===================== // =====================
#define PKDT_AP 1 #define TRIG_A12P 1
#define PKDT_AN 2 #define TRIG_A12N 2
#define PKDT_BP 3 #define TRIG_A34P 3
#define PKDT_BN 14 #define TRIG_A34N 14
#define TRIG_B12P 15
#define TRIG_B12N 16
#define TRIG_B34P 17
#define TRIG_B34N 18
// ===================== // =====================
// TRIGGER INPUTS // PEAK DETECTOR RESET OUTPUTS
// ===================== // =====================
#define TRIG_AP 15 #define RST_A12P 39
#define TRIG_AN 16 #define RST_A12N 40
#define TRIG_BP 17 #define RST_A34P 41
#define TRIG_BN 18 #define RST_A34N 42
#define RST_B12P 35
#define RST_B12N 36
#define RST_B34P 37
#define RST_B34N 38
// ===================== // =====================
// SOFT START DETECT // SPARK DETECT INPUTS
// ===================== // =====================
#define SOFT_A 21 #define SPARK_A12 45 // input only
#define SOFT_B 47 #define SPARK_A34 46 // input only
#define SPARK_B12 47
#define SPARK_B34 48
// ===================== // =====================
// STATUS OUTPUT // STATUS & BUTTON su PCA9555 (I2C)
// ===================== // =====================
#define STA_1 35 #define STA_1 0
#define STA_2 36 #define STA_2 1
#define STA_3 37 #define STA_3 2
#define STA_4 38 #define STA_4 3
#define STA_5 4
#define STA_6 5
#define STA_7 6
#define STA_8 7
// ===================== #define BTN_1 8
// BUTTON INPUT #define BTN_2 9
// ===================== #define BTN_3 10
#define BTN_1 39 #define BTN_4 11
#define BTN_2 40 #define BTN_5 12
#define BTN_3 41 #define BTN_6 13
#define BTN_4 42 #define BTN_7 14
#define BTN_8 15

98
RotaxMonitor/src/tasks.h Normal file
View File

@@ -0,0 +1,98 @@
// Arduino Libraries
#include <Arduino.h>
#include <DebugLog.h>
// ISR
#include "isr.h"
const uint16_t spark_delay_us = 500;
void ignitionA_task(void *pvParameters) {
uint32_t notifiedValue;
while (true) {
// attende eventi
xTaskNotifyWait(
0x00, // non pulire all'ingresso
ULONG_MAX, // pulisci tutti i bit all'uscita
&notifiedValue, // valore ricevuto
portMAX_DELAY
);
uint64_t wait_time=0;
switch (notifiedValue) {
case TRIG_FLAG_A12P:
case TRIG_FLAG_A12N:
bool spark12_timeout = false;
if (ignA_status.trig12_complete) {
// read peak adc values from sample and hold
} else {
while(!digitalRead(SPARK_A12)) {
wait_time = ignA_status.trig12_start - esp_timer_get_time();
if (wait_time >= spark_delay_us) {
spark12_timeout = true;
break;
}
}
if (spark12_timeout) { // spark did not happen, timeout
ignA_status.trig12_complete = false;
} else { // spark did happen
ignA_status.trig12_complete = true;
ignA_status.trig12_time = wait_time;
}
}
break;
case TRIG_FLAG_A34P:
case TRIG_FLAG_A34N:
bool spark34_timeout = false;
if (ignA_status.trig12_complete) {
// read peak adc values from sample and hold
} else {
while(!digitalRead(SPARK_A34)) {
wait_time = ignA_status.trig34_start - esp_timer_get_time();
if (wait_time >= spark_delay_us) {
spark12_timeout = true;
break;
}
}
if (spark34_timeout) { // spark did not happen, timeout
ignA_status.trig34_complete = false;
} else { // spark did happen
ignA_status.trig34_complete = true;
ignA_status.trig34_time = wait_time;
}
}
break;
default:
LOG_ERROR("Invalid A Interrupt: ", notifiedValue);
}
}
}
void ignitionB_task(void *pvParameters) {
uint32_t notifiedValue;
while (true) {
// attende eventi
xTaskNotifyWait(
0x00, // non pulire all'ingresso
0xFFFFFFFF, // pulisci tutti i bit all'uscita
&notifiedValue, // valore ricevuto
portMAX_DELAY
);
switch (notifiedValue) {
case TRIG_FLAG_B12P:
break;
case TRIG_FLAG_B34P:
break;
case TRIG_FLAG_B12N:
break;
case TRIG_FLAG_B34N:
break;
default:
LOG_ERROR("Invalid B Interrupt: ", notifiedValue);
}
}
}