Pins and devices refactoring in progress

This commit is contained in:
Emanuele Trabattoni
2026-03-26 18:22:22 +01:00
parent 68ed8a2282
commit a0710f7ee7
7 changed files with 314 additions and 225 deletions

Binary file not shown.

After

Width:  |  Height:  |  Size: 141 KiB

View File

@@ -17,6 +17,7 @@ lib_deps =
bblanchon/ArduinoJson@^7.4.2 bblanchon/ArduinoJson@^7.4.2
hideakitai/PCA95x5@^0.1.3 hideakitai/PCA95x5@^0.1.3
adafruit/Adafruit SSD1306@^2.5.16 adafruit/Adafruit SSD1306@^2.5.16
garfius/Menu-UI@^1.2.0
board_build.partitions = partitions/default_16MB.csv board_build.partitions = partitions/default_16MB.csv
board_build.psram = enabled board_build.psram = enabled
monitor_speed = 115200 monitor_speed = 115200
@@ -31,6 +32,7 @@ lib_deps =
${env:esp32-s3-n16r8.lib_deps} ${env:esp32-s3-n16r8.lib_deps}
hideakitai/PCA95x5@^0.1.3 hideakitai/PCA95x5@^0.1.3
adafruit/Adafruit SSD1306@^2.5.16 adafruit/Adafruit SSD1306@^2.5.16
garfius/Menu-UI@^1.2.0
board_build.partitions = partitions/default_16MB.csv board_build.partitions = partitions/default_16MB.csv
board_build.psram = enabled board_build.psram = enabled
monitor_speed = 115200 monitor_speed = 115200

View File

@@ -6,33 +6,53 @@
#include <Adafruit_SSD1306.h> #include <Adafruit_SSD1306.h>
#include <PCA95x5.h> #include <PCA95x5.h>
// ADC Channel mapping // ADC Channel mapping Ignition A
#define PICKUP_IN_A12 SING_0 #define IN_A12_P SING_0
#define PICKUP_IN_A34 SING_1 #define IN_A12_N SING_1
#define PICKUP_OUT_A12 SING_2 #define IN_A34_P SING_2
#define PICKUP_OUT_A34 SING_3 #define IN_A34_N SING_3
#define OUT_A12_P SING_4
#define OUT_A12_N SING_5
#define OUT_A34_P SING_6
#define OUT_A34_N SING_7
#define PICKUP_IN_B12 SING_4 // ADC Channel mapping Ignition B
#define PICKUP_IN_B34 SING_5 #define IN_A12_P SING_0
#define PICKUP_OUT_B12 SING_6 #define IN_A12_N SING_1
#define PICKUP_OUT_B34 SING_7 #define IN_A34_P SING_2
#define IN_A34_N SING_3
#define OUT_A12_P SING_4
#define OUT_A12_N SING_5
#define OUT_A34_P SING_6
#define OUT_A34_N SING_7
struct Devices { struct Devices {
AD5292* pot; AD5292* pot_a, pot_b;
ADS1256* adc; ADS1256* adc_a, adc_b;
Adafruit_SSD1306* lcd; Adafruit_SSD1306* lcd;
PCA9555* io; PCA9555* io;
}; };
float adcReadChannel(ADS1256* adc, const uint32_t ch){ inline float adcAReadChannel(ADS1256* adc, const uint32_t ch){
adc->setMUX(PICKUP_IN_A12); adc->setMUX(ch);
// scarta 3 conversioni // scarta 3 conversioni
for (int i = 0; i < 3; i++) { for (int i = 0; i < 3; i++) {
while (digitalRead(ADC_DRDY)); while (digitalRead(ADC_A_DRDY));
adc->readSingle(); adc->readSingle();
} }
// ora lettura valida a 30kSPS → ~100 µs di settling // ora lettura valida a 30kSPS → ~100 µs di settling
while (digitalRead(ADC_DRDY)); while (digitalRead(ADC_A_DRDY));
return adc->convertToVoltage(adc->readSingle());
}
inline float adcBReadChannel(ADS1256* adc, const uint32_t ch){
adc->setMUX(ch);
// scarta 3 conversioni
for (int i = 0; i < 3; i++) {
while (digitalRead(ADC_B_DRDY));
adc->readSingle();
}
// ora lettura valida a 30kSPS → ~100 µs di settling
while (digitalRead(ADC_B_DRDY));
return adc->convertToVoltage(adc->readSingle()); return adc->convertToVoltage(adc->readSingle());
} }

View File

@@ -9,8 +9,6 @@
#define TASK_STACK 4096 // in words #define TASK_STACK 4096 // in words
#define TASK_PRIORITY 2 // priorità leggermente più alta #define TASK_PRIORITY 2 // priorità leggermente più alta
#define IGN_BUF_SIZE 128
// ===================== // =====================
// Event Flags (bitmask) // Event Flags (bitmask)
// ===================== // =====================
@@ -23,10 +21,10 @@
#define TRIG_FLAG_B34P (1 << 5) #define TRIG_FLAG_B34P (1 << 5)
#define TRIG_FLAG_B34N (1 << 7) #define TRIG_FLAG_B34N (1 << 7)
#define SPARK_FLAG_A12 (1 << 0) #define SPARK_FLAG_A12 (1 << 8)
#define SPARK_FLAG_A34 (1 << 2) #define SPARK_FLAG_A34 (1 << 9)
#define SPARK_FLAG_B12 (1 << 1) #define SPARK_FLAG_B12 (1 << 10)
#define SPARK_FLAG_B34 (1 << 3) #define SPARK_FLAG_B34 (1 << 11)
// Task handle // Task handle
TaskHandle_t trigA_TaskHandle = NULL; TaskHandle_t trigA_TaskHandle = NULL;
@@ -48,30 +46,29 @@ enum sparkStatus
SPARK_SYNC_FAIL, SPARK_SYNC_FAIL,
}; };
// Task internal Status enum softStartStatus
struct ignitionBoxStatus
{ {
// start time from ISR SOFT_START,
int64_t trig12_start = 0; NORMAL
int64_t trig34_start = 0; };
// time at which spark occours
int64_t spark12_start = 0; typedef struct coilsStatus
int64_t spark34_start = 0; {
// computed delay from pickup to spark int64_t trig_time;
int64_t spark12_delay = 0; int64_t spark_time;
int64_t spark34_delay = 0; int64_t spark_delay;
// spark status sparkStatus spark_status;
sparkStatus spark12_status = sparkStatus::SPARK_POS_OK; softStartStatus soft_start_status;
sparkStatus spark34_status = sparkStatus::SPARK_POS_OK; float pickup_volts;
// soft start status for circuits 12 and 34 float output_volts;
bool soft12_engaged = false; };
bool soft34_engaged = false;
// peak voltage from circuits 12 and 34 // Task internal Status
float volts12_pickup = 0.0; typedef struct ignitionBoxStatus
float volts34_pickup = 0.0; {
// peak voltage from conditioned output 12 and 34 // coils pairs for each ignition
float volts12_out = 0.0; coilsStatus coils12;
float volts34_out = 0.0; coilsStatus coils34;
// voltage from generator // voltage from generator
float volts_gen = 0.0; float volts_gen = 0.0;
}; };
@@ -79,9 +76,6 @@ struct ignitionBoxStatus
ignitionBoxStatus ignA_status; ignitionBoxStatus ignA_status;
ignitionBoxStatus ignB_status; ignitionBoxStatus ignB_status;
ignitionBoxStatus ingA_statusBuffer[IGN_BUF_SIZE];
ignitionBoxStatus ingB_statusBuffer[IGN_BUF_SIZE];
// Pin to flag Map // Pin to flag Map
static uint32_t pin2trig[49]; static uint32_t pin2trig[49];
void initTriggerPinMapping() void initTriggerPinMapping()
@@ -112,38 +106,40 @@ void initSparkPinMapping()
void IRAM_ATTR trig_isr_a() void IRAM_ATTR trig_isr_a()
{ {
BaseType_t xHigherPriorityTaskWoken = pdFALSE; BaseType_t xHigherPriorityTaskWoken = pdFALSE;
const int64_t startTime = esp_timer_get_time(); volatile const int64_t time_us = esp_timer_get_time();
if (!trigA_TaskHandle) return; // exit if task is not running if (!trigA_TaskHandle)
return; // exit if task is not running
uint32_t status = GPIO.status; uint32_t status = GPIO.status;
uint32_t flags = 0; uint32_t pickup_flags = 0;
while (status) while (status)
{ {
uint32_t pin = __builtin_ctz(status); // trova primo bit attivo uint32_t pin = __builtin_ctz(status); // trova primo bit attivo
status &= ~(1 << pin); // clear bit status &= ~(1 << pin); // clear bit
flags |= pin2trig[pin]; pickup_flags |= pin2trig[pin];
} }
if (flags & TRIG_FLAG_A12P) if (pickup_flags & TRIG_FLAG_A12P)
ignA_status.trig12_start = startTime; ignA_status.coils12.trig_time = time_us;
if (flags & TRIG_FLAG_A34P) if (pickup_flags & TRIG_FLAG_A34P)
ignA_status.trig34_start = startTime; ignA_status.coils34.trig_time = time_us;
xTaskNotifyFromISR(trigA_TaskHandle, flags, eSetBits, &xHigherPriorityTaskWoken); xTaskNotifyFromISR(trigA_TaskHandle, pickup_flags, eSetBits, &xHigherPriorityTaskWoken);
portYIELD_FROM_ISR(xHigherPriorityTaskWoken); portYIELD_FROM_ISR(xHigherPriorityTaskWoken);
} }
void IRAM_ATTR spark_a() void IRAM_ATTR spark_a()
{ {
BaseType_t xHigherPriorityTaskWoken = pdFALSE; BaseType_t xHigherPriorityTaskWoken = pdFALSE;
const int64_t startTime = esp_timer_get_time(); volatile const int64_t time_us = esp_timer_get_time();
if (!trigA_TaskHandle) return; if (!trigA_TaskHandle)
return;
uint32_t spark_flag = GPIO.status1.val & SPARK_A12 ? SPARK_FLAG_A12 : SPARK_FLAG_A34; uint32_t spark_flag = GPIO.status1.val & SPARK_A12 ? SPARK_FLAG_A12 : SPARK_FLAG_A34;
if (spark_flag & SPARK_FLAG_A12) if (spark_flag & SPARK_FLAG_A12)
ignA_status.spark12_start = startTime; ignA_status.coils12.spark_time = time_us;
if (spark_flag & SPARK_FLAG_A34) if (spark_flag & SPARK_FLAG_A34)
ignA_status.spark34_start = startTime; ignA_status.coils12.spark_time = time_us;
xTaskNotifyFromISR(trigA_TaskHandle, spark_flag, eSetBits, &xHigherPriorityTaskWoken); xTaskNotifyFromISR(trigA_TaskHandle, spark_flag, eSetBits, &xHigherPriorityTaskWoken);
portYIELD_FROM_ISR(xHigherPriorityTaskWoken); portYIELD_FROM_ISR(xHigherPriorityTaskWoken);
} }
@@ -151,38 +147,40 @@ void IRAM_ATTR spark_a()
void IRAM_ATTR trig_isr_b() void IRAM_ATTR trig_isr_b()
{ {
BaseType_t xHigherPriorityTaskWoken = pdFALSE; BaseType_t xHigherPriorityTaskWoken = pdFALSE;
const int64_t startTime = esp_timer_get_time(); volatile const int64_t time_us = esp_timer_get_time();
if (!trigB_TaskHandle) return; // exit if task is not running if (!trigB_TaskHandle)
return; // exit if task is not running
uint32_t status = GPIO.status; uint32_t status = GPIO.status;
uint32_t flags = 0; uint32_t pickup_flags = 0;
while (status) while (status)
{ {
uint32_t pin = __builtin_ctz(status); // trova primo bit attivo uint32_t pin = __builtin_ctz(status); // trova primo bit attivo
status &= ~(1 << pin); // clear bit status &= ~(1 << pin); // clear bit
flags |= pin2trig[pin]; pickup_flags |= pin2trig[pin];
} }
if (flags & TRIG_FLAG_B12P) if (pickup_flags & TRIG_FLAG_B12P)
ignB_status.trig12_start = startTime; ignB_status.coils12.trig_time = time_us;
if (flags & TRIG_FLAG_B34P) if (pickup_flags & TRIG_FLAG_B34P)
ignB_status.trig34_start = startTime; ignB_status.coils34.trig_time = time_us;
xTaskNotifyFromISR(trigB_TaskHandle, flags, eSetBits, &xHigherPriorityTaskWoken); xTaskNotifyFromISR(trigB_TaskHandle, pickup_flags, eSetBits, &xHigherPriorityTaskWoken);
portYIELD_FROM_ISR(xHigherPriorityTaskWoken); portYIELD_FROM_ISR(xHigherPriorityTaskWoken);
} }
void IRAM_ATTR spark_b() void IRAM_ATTR spark_b()
{ {
BaseType_t xHigherPriorityTaskWoken = pdFALSE; BaseType_t xHigherPriorityTaskWoken = pdFALSE;
const int64_t startTime = esp_timer_get_time(); volatile const int64_t time_us = esp_timer_get_time();
if (!trigB_TaskHandle) return; if (!trigB_TaskHandle)
return;
uint32_t spark_flag = GPIO.status1.val & SPARK_B12 ? SPARK_FLAG_B12 : SPARK_FLAG_B34; uint32_t spark_flag = GPIO.status1.val & SPARK_B12 ? SPARK_FLAG_B12 : SPARK_FLAG_B34;
if (spark_flag & SPARK_FLAG_B12) if (spark_flag & SPARK_FLAG_B12)
ignB_status.spark12_start = startTime; ignB_status.coils12.spark_time = time_us;
if (spark_flag & SPARK_FLAG_B34) if (spark_flag & SPARK_FLAG_B34)
ignB_status.spark34_start = startTime; ignB_status.coils34.spark_time = time_us;
xTaskNotifyFromISR(trigB_TaskHandle, spark_flag, eSetBits, &xHigherPriorityTaskWoken); xTaskNotifyFromISR(trigB_TaskHandle, spark_flag, eSetBits, &xHigherPriorityTaskWoken);
portYIELD_FROM_ISR(xHigherPriorityTaskWoken); portYIELD_FROM_ISR(xHigherPriorityTaskWoken);
} }

View File

@@ -28,38 +28,13 @@ void setup()
LOG_INFO("ESP32 Heap:", ESP.getHeapSize()); LOG_INFO("ESP32 Heap:", ESP.getHeapSize());
LOG_INFO("ESP32 Sketch:", ESP.getFreeSketchSpace()); LOG_INFO("ESP32 Sketch:", ESP.getFreeSketchSpace());
// Initialize Interrupt pins on coil detectors // Initialize Interrupt pins on PICKUP detectors
pinMode(TRIG_A12P, INPUT_PULLDOWN); initTriggerPinsInputs();
pinMode(TRIG_A12N, INPUT_PULLDOWN);
pinMode(TRIG_A34P, INPUT_PULLDOWN);
pinMode(TRIG_A34N, INPUT_PULLDOWN);
pinMode(TRIG_B12P, INPUT_PULLDOWN);
pinMode(TRIG_B12N, INPUT_PULLDOWN);
pinMode(TRIG_B34P, INPUT_PULLDOWN);
pinMode(TRIG_B34N, INPUT_PULLDOWN);
initTriggerPinMapping(); initTriggerPinMapping();
// Initialize Interrupt pins on spark detectors // Initialize Interrupt pins on SPARK detectors
pinMode(SPARK_A12, INPUT_PULLDOWN); initSparkPinInputs();
pinMode(SPARK_A34, INPUT_PULLDOWN);
pinMode(SPARK_B12, INPUT_PULLDOWN);
pinMode(SPARK_B34, INPUT_PULLDOWN);
initSparkPinMapping(); initSparkPinMapping();
// 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);
attachInterrupt(SPARK_A12, spark_a, RISING);
attachInterrupt(SPARK_A34, spark_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);
attachInterrupt(SPARK_B12, spark_b, RISING);
attachInterrupt(SPARK_B34, spark_b, RISING);
// Init SPI interface // Init SPI interface
SPI.begin(); SPI.begin();
} }
@@ -71,7 +46,7 @@ void loop()
Devices dev; Devices dev;
// Init devices // Init devices
dev.adc = new ADS1256(ADC_DRDY, ADC_RST, ADC_SYNC, ADC_CS, 2.5, &SPI); dev.adca = new ADS1256(ADC_DRDY, ADC_RST, ADC_SYNC, ADC_CS, 2.5, &SPI);
dev.adc->InitializeADC(); dev.adc->InitializeADC();
dev.adc->setPGA(PGA_1); dev.adc->setPGA(PGA_1);
dev.adc->setDRATE(DRATE_1000SPS); dev.adc->setDRATE(DRATE_1000SPS);
@@ -87,18 +62,22 @@ void loop()
CORE_0); CORE_0);
// Ignition B on Core 1 // Ignition B on Core 1
auto ignB_task_success = xTaskCreatePinnedToCore( auto ignB_task_success = pdPASS;
ignitionB_task, // auto ignB_task_success = xTaskCreatePinnedToCore(
"ignitionB_task", // ignitionB_task,
TASK_STACK, // "ignitionB_task",
(void *)&dev, // TASK_STACK,
TASK_PRIORITY, // priorità leggermente più alta // (void *)&dev,
&trigA_TaskHandle, // TASK_PRIORITY, // priorità leggermente più alta
CORE_1); // &trigA_TaskHandle,
// CORE_1);
if ((ignA_task_success && ignB_task_success) != pdPASS) if ((ignA_task_success && ignB_task_success) != pdPASS)
{ {
LOG_ERROR("Unble to initialize ISR task"); LOG_ERROR("Unble to initialize ISR task");
LOG_ERROR("5 seconds to restart...");
vTaskDelay(pdMS_TO_TICKS(5000));
esp_restart();
} }
LOG_INFO("Real Time Tasks A&B initialized"); LOG_INFO("Real Time Tasks A&B initialized");

View File

@@ -1,86 +1,129 @@
#pragma once #pragma once
// ===================== // =====================
// SPI BUS // USB (RISERVATA)
// ===================== // =====================
#define SPI_MOSI 11 #define USB_DM 19
#define SPI_MISO 13 #define USB_DP 20
#define SPI_SCK 12
// ===================== // =====================
// I2C BUS // UART DEBUG (RISERVATA)
// =====================
#define UART_TX 43
#define UART_RX 44
// =====================
// RGB Led
// =====================
#define LED 48
// =====================
// STRAPPING (NON USARE)
// =====================
// 0, 3
// =====================
// SPI BUS ADC1 (VSPI)
// =====================
#define SPI_A_MOSI 11
#define SPI_A_MISO 13
#define SPI_A_SCK 12
// =====================
// SPI BUS ADC2 (HSPI)
// =====================
#define SPI_B_MOSI 35
#define SPI_B_MISO 37
#define SPI_B_SCK 36
// =====================
// I2C BUS (PCA9555)
// ===================== // =====================
#define SDA 8 #define SDA 8
#define SCL 9 #define SCL 9
// ===================== // =====================
// ADC CONTROL // ADC CONTROL (NO CONFLICT)
// ===================== // =====================
#define ADC_CS 10 #define ADC_A_CS 4
#define ADC_DRDY 4 #define ADC_A_DRDY 5
#define ADC_RST 5 #define ADC_A_RST 6
#define ADC_SYNC 6 #define ADC_A_SYNC 7
#define ADC_B_CS 14
#define ADC_B_DRDY 15
#define ADC_B_RST 16
#define ADC_B_SYNC 17
// ===================== // =====================
// DIGITAL POT // DIGITAL POT
// ===================== // =====================
#define POT_CS 7 #define POT_A_CS 1
#define POT_DRDY 18 #define POT_B_CS 2
// =====================
// RELAY OUT
// =====================
#define PICK_RELAY 21
// ===================== // =====================
// TRIGGER INPUT INTERRUPTS // TRIGGER INPUT INTERRUPTS
// ===================== // =====================
#define TRIG_A12P 1 #define TRIG_A12P 21
#define TRIG_A12N 2 #define TRIG_A12N 33
#define TRIG_A34P 3 #define TRIG_A34P 34
#define TRIG_A34N 14 #define TRIG_A34N 38
#define TRIG_B12P 15 #define TRIG_B12P 39
#define TRIG_B12N 16 #define TRIG_B12N 40
#define TRIG_B34P 17 #define TRIG_B34P 41
#define TRIG_B34N 18 #define TRIG_B34N 42
// ===================== // =====================
// PEAK DETECTOR RESET OUTPUTS // SPARK DETECT INPUTS (INPUT ONLY SAFE)
// ===================== // =====================
#define RST_A12P 39 #define SPARK_A12 45
#define RST_A12N 40 #define SPARK_A34 46
#define RST_A34P 41
#define RST_A34N 42
#define RST_B12P 35
#define RST_B12N 36
#define RST_B34P 37
#define RST_B34N 38
// =====================
// SPARK DETECT INPUTS
// =====================
#define SPARK_A12 45 // input only
#define SPARK_A34 46 // input only
#define SPARK_B12 47 #define SPARK_B12 47
#define SPARK_B34 48 #define SPARK_B34 18
// ===================== // =====================
// STATUS & BUTTON su PCA9555 (I2C) // PCA9555 (I2C EXPANDER)
// ===================== // =====================
#define STA_1 0
#define STA_2 1
#define STA_3 2
#define STA_4 3
#define STA_5 4
#define STA_6 5
#define STA_7 6
#define STA_8 7
#define BTN_1 8 // --- RESET LINES (ora su expander) ---
#define BTN_2 9 #define RST_A12P 0
#define RST_A12N 1
#define RST_A34P 2
#define RST_A34N 3
#define RST_B12P 4
#define RST_B12N 5
#define RST_B34P 6
#define RST_B34N 7
// --- RELAY LINES ---
#define A_RELAY 8
#define B_RELAY 9
// --- STATUS OUTPUT ---
#define BTN_3 10 #define BTN_3 10
#define BTN_4 11 #define BTN_4 11
#define BTN_5 12 #define STA_1 12
#define BTN_6 13 #define STA_2 13
#define BTN_7 14 #define STA_3 14
#define BTN_8 15 #define STA_4 15
// Init Pin Functions
inline void initTriggerPinsInputs()
{
pinMode(TRIG_A12P, INPUT);
pinMode(TRIG_A12N, INPUT);
pinMode(TRIG_A34P, INPUT);
pinMode(TRIG_A34N, INPUT);
pinMode(TRIG_B12P, INPUT);
pinMode(TRIG_B12N, INPUT);
pinMode(TRIG_B34P, INPUT);
pinMode(TRIG_B34N, INPUT);
}
inline void initSparkPinInputs()
{
pinMode(SPARK_A12, INPUT);
pinMode(SPARK_A34, INPUT);
pinMode(SPARK_B12, INPUT);
pinMode(SPARK_B34, INPUT);
}

View File

@@ -10,111 +10,158 @@
// DEVICES // DEVICES
#include "devices.h" #include "devices.h"
const auto spark_timeout_max = 1; //Global Variables and Flags
static bool rt_task_running = true;
const auto spark_timeout_max = 1; // convert to microsecond timer
void ignitionA_task(void *pvParameters) { void ignitionA_task(void *pvParameters) {
if (!pvParameters) {
LOG_ERROR("Null device parameters");
vTaskDelete(NULL);
}
Devices* dev = (Devices*) pvParameters; Devices* dev = (Devices*) pvParameters;
ADS1256* adc = dev->adc; ADS1256* adc = dev->adc;
// 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);
attachInterrupt(SPARK_A12, spark_a, RISING);
attachInterrupt(SPARK_A34, spark_a, RISING);
uint32_t pickup_flag; uint32_t pickup_flag;
uint32_t spark_flag; uint32_t spark_flag;
while (true) { while (rt_task_running) {
// WAIT FOR PICKUP SIGNAL // WAIT FOR PICKUP SIGNAL
xTaskNotifyWait( xTaskNotifyWait(
0x00, // non pulire all'ingresso 0x00, // non pulire all'ingresso
ULONG_MAX, // pulisci tutti i bit all'uscita 0x000000FF, // pulisci i primi 8 bit
&pickup_flag, // valore ricevuto &pickup_flag, // valore ricevuto
portMAX_DELAY portMAX_DELAY
); );
// WAIT FOR SPARK TO HAPPEN // WAIT FOR SPARK TO HAPPEN
auto spark_timeout = xTaskNotifyWait( auto spark_timeout = xTaskNotifyWait(
0x00, // non pulire all'ingresso 0x00, // non pulire all'ingresso
ULONG_MAX, // pulisci tutti i bit all'uscita 0x0000FF00, // pulisci gli 8 bit successivi
&spark_flag, // valore ricevuto &spark_flag, // valore ricevuto
spark_timeout_max spark_timeout_max
); );
// A trigger from pickup 12 is followed by a spark event on 34 or vice versa pickup 34 triggers spark on 12 // A trigger from pickup 12 is followed by a spark event on 34 or vice versa pickup 34 triggers spark on 12
if ((pickup_flag == TRIG_FLAG_A12P || pickup_flag == TRIG_FLAG_A12N) && spark_flag != SPARK_A12) { if ((pickup_flag == TRIG_FLAG_A12P || pickup_flag == TRIG_FLAG_A12N) && spark_flag != SPARK_A12) {
ignA_status.trig12_start = ignA_status.trig34_start = -1; ignA_status.coils12.spark_status = ignA_status.coils34.spark_status = sparkStatus::SPARK_SYNC_FAIL;
ignA_status.spark12_start = ignA_status.spark34_start = -1;
ignA_status.spark12_delay = ignA_status.spark34_delay = -1;
ignA_status.soft12_engaged = ignA_status.soft34_engaged = false;
ignA_status.spark12_status = ignA_status.spark12_status = sparkStatus::SPARK_SYNC_FAIL;
// Save error on circular buffer and skip to next cycle // // Save error on circular buffer and skip to next cycle //
// [TODO]
continue; continue;
} }
bool new_data12 = false; const uint32_t combined_flags = pickup_flag & spark_flag;
coilsStatus* c;
switch (combined_flags)
{
case TRIG_A12P:
case TRIG_A12N:
case SPARK_A12:
c = &ignA_status.coils12;
case TRIG_A34P:
case TRIG_A34N:
case SPARK_A34:
c = &ignA_status.coils34;
}
bool new_data = false;
switch (pickup_flag) { switch (pickup_flag) {
case TRIG_FLAG_A12P: { // CASES for NEGATIVE cycle triggering of pickup and sparks 12 & 34
case TRIG_FLAG_A12P:
case TRIG_FLAG_A34P:
{
// Timeout not occourred, expected POSITIVE edge spark OCCOURRED // Timeout not occourred, expected POSITIVE edge spark OCCOURRED
if (spark_timeout == pdPASS) { if (spark_timeout == pdPASS) {
ignA_status.spark12_delay = ignA_status.spark12_start - ignA_status.trig12_start; c->spark_delay = c->spark_time - c->trig_time;
ignA_status.soft12_engaged = false; // because spark on positive edge c->soft_start_status = softStartStatus::NORMAL; // because spark on positive edge
ignA_status.spark12_status = sparkStatus::SPARK_POS_OK; // do not wait for spark on negative edge c->spark_status = sparkStatus::SPARK_POS_OK; // do not wait for spark on negative edge
} }
// Timeout occourred, expected POSITIVE edge spark NOT OCCOURRED // Timeout occourred, expected POSITIVE edge spark NOT OCCOURRED
else if (spark_timeout == pdFAIL) { else if (spark_timeout == pdFAIL) {
ignA_status.spark12_status = sparkStatus::SPARK_NEG_WAIT; c->spark_status = sparkStatus::SPARK_NEG_WAIT;
ignA_status.soft12_engaged = false; c->soft_start_status = softStartStatus::NORMAL;
} }
// Do nothing more on positive pulse new_data = false;
break; break; // Do nothing more on positive pulse
} }
case TRIG_FLAG_A12N: { // CASES for NEGATIVE cycle triggering of pickup and sparks 12 & 34
bool expected_negative12 = ignA_status.spark12_status == sparkStatus::SPARK_NEG_WAIT; case TRIG_FLAG_A12N:
case TRIG_FLAG_A34N:
{
const bool expected_negative12 = c->spark_status == sparkStatus::SPARK_NEG_WAIT;
// Timeout not occourred, expected NEGATIVE edge spark OCCOURRED // Timeout not occourred, expected NEGATIVE edge spark OCCOURRED
if (spark_timeout == pdPASS && expected_negative12) { if (spark_timeout == pdPASS && expected_negative12) {
ignA_status.spark12_delay = ignA_status.spark12_start - ignA_status.trig12_start; c->spark_delay = c->spark_time - c->trig_time;
ignA_status.soft12_engaged = true; c->soft_start_status = softStartStatus::SOFT_START;
ignA_status.spark12_status == sparkStatus::SPARK_NEG_OK; c->spark_status == sparkStatus::SPARK_NEG_OK;
} }
// Timeout occourred, expected POSITIVE edge spark NOT OCCOURRED // Timeout occourred, expected POSITIVE edge spark NOT OCCOURRED
else if (spark_timeout == pdFAIL && expected_negative12) { else if (spark_timeout == pdFAIL && expected_negative12) {
ignA_status.soft12_engaged = false; c->soft_start_status = softStartStatus::NORMAL;
ignA_status.spark12_status = sparkStatus::SPARK_NEG_FAIL; c->spark_status = sparkStatus::SPARK_NEG_FAIL;
} }
// Timeout not occouured, unexpected negative edge spark // Timeout not occouured, unexpected negative edge spark
else if (spark_timeout == pdPASS && !expected_negative12) { else if (spark_timeout == pdPASS && !expected_negative12) {
ignA_status.soft12_engaged = true; c->soft_start_status = softStartStatus::SOFT_START;
ignA_status.spark12_status = sparkStatus::SPARK_NEG_UNEXPECTED; c->spark_status = sparkStatus::SPARK_NEG_UNEXPECTED;
} }
// Save status on circular buffer // Wait for finish of negative pulse to save data to buffer
new_data12 = true; new_data = true;
break; break;
} }
case TRIG_FLAG_A34P:
case TRIG_FLAG_A34N:
break;
default: default:
LOG_ERROR("Invalid A Interrupt"); LOG_ERROR("Invalid A Interrupt");
} }
vTaskDelay(pdMS_TO_TICKS(1)); // delay 1ms to allow peak detectors to charge if (new_data) {
vTaskDelay(pdMS_TO_TICKS(1)); // delay 1ms to allow peak detectors to charge for negative cycle
if (new_data12) {
// read adc channels: pickup12, out12 [ pos + neg ] // read adc channels: pickup12, out12 [ pos + neg ]
ignA_status.volts12_pickup = adcReadChannel(adc, PICKUP_IN_A12); ignA_status.coils12.pickup_volts = adcReadChannel(adc, IN_A12_P);
ignA_status.volts12_out = adcReadChannel(adc, PICKUP_OUT_A12); ignA_status.coils12.output_volts = adcReadChannel(adc, PICKUP_OUT_A12);
// reset peak detectors ignA_status.coils34.pickup_volts = adcReadChannel(adc, PICKUP_IN_A34);
digitalWrite(RST_A12P, HIGH); ignA_status.coils34.output_volts = adcReadChannel(adc, PICKUP_OUT_A34);
digitalWrite(RST_A12N, HIGH); // reset peak detectors -> gli output sono sull'expander
vTaskDelay(pdMS_TO_TICKS(1));
digitalWrite(RST_A12P, HIGH); //digitalWrite(RST_A12P, HIGH);
digitalWrite(RST_A12N, HIGH); //digitalWrite(RST_A12N, HIGH);
//vTaskDelay(pdMS_TO_TICKS(1));
//digitalWrite(RST_A12P, HIGH);
//digitalWrite(RST_A12N, HIGH);
// save on circluar buffer 12 // save on circluar buffer 12
} }
} }
// Ignition A Interrupts DETACH
detachInterrupt(TRIG_A12P);
detachInterrupt(TRIG_A34P);
detachInterrupt(TRIG_A12N);
detachInterrupt(TRIG_A34N);
detachInterrupt(SPARK_A12);
detachInterrupt(SPARK_A34);
// delete present task
vTaskDelete(NULL);
} }
void ignitionB_task(void *pvParameters) { void ignitionB_task(void *pvParameters) {
uint32_t notifiedValue; uint32_t notifiedValue;
// 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);
attachInterrupt(SPARK_B12, spark_b, RISING);
attachInterrupt(SPARK_B34, spark_b, RISING);
while (true) { while (true) {
// attende eventi // attende eventi
xTaskNotifyWait( xTaskNotifyWait(