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

View File

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

View File

@@ -6,33 +6,53 @@
#include <Adafruit_SSD1306.h>
#include <PCA95x5.h>
// ADC Channel mapping
#define PICKUP_IN_A12 SING_0
#define PICKUP_IN_A34 SING_1
#define PICKUP_OUT_A12 SING_2
#define PICKUP_OUT_A34 SING_3
// ADC Channel mapping Ignition A
#define IN_A12_P SING_0
#define IN_A12_N SING_1
#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
#define PICKUP_IN_B12 SING_4
#define PICKUP_IN_B34 SING_5
#define PICKUP_OUT_B12 SING_6
#define PICKUP_OUT_B34 SING_7
// ADC Channel mapping Ignition B
#define IN_A12_P SING_0
#define IN_A12_N SING_1
#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 {
AD5292* pot;
ADS1256* adc;
AD5292* pot_a, pot_b;
ADS1256* adc_a, adc_b;
Adafruit_SSD1306* lcd;
PCA9555* io;
};
float adcReadChannel(ADS1256* adc, const uint32_t ch){
adc->setMUX(PICKUP_IN_A12);
inline float adcAReadChannel(ADS1256* adc, const uint32_t ch){
adc->setMUX(ch);
// scarta 3 conversioni
for (int i = 0; i < 3; i++) {
while (digitalRead(ADC_DRDY));
while (digitalRead(ADC_A_DRDY));
adc->readSingle();
}
// 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());
}

View File

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

View File

@@ -28,38 +28,13 @@ void setup()
LOG_INFO("ESP32 Heap:", ESP.getHeapSize());
LOG_INFO("ESP32 Sketch:", ESP.getFreeSketchSpace());
// Initialize Interrupt pins on coil detectors
pinMode(TRIG_A12P, INPUT_PULLDOWN);
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);
// Initialize Interrupt pins on PICKUP detectors
initTriggerPinsInputs();
initTriggerPinMapping();
// Initialize Interrupt pins on spark detectors
pinMode(SPARK_A12, INPUT_PULLDOWN);
pinMode(SPARK_A34, INPUT_PULLDOWN);
pinMode(SPARK_B12, INPUT_PULLDOWN);
pinMode(SPARK_B34, INPUT_PULLDOWN);
// Initialize Interrupt pins on SPARK detectors
initSparkPinInputs();
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
SPI.begin();
}
@@ -71,7 +46,7 @@ void loop()
Devices dev;
// 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->setPGA(PGA_1);
dev.adc->setDRATE(DRATE_1000SPS);
@@ -87,19 +62,23 @@ void loop()
CORE_0);
// Ignition B on Core 1
auto ignB_task_success = xTaskCreatePinnedToCore(
ignitionB_task,
"ignitionB_task",
TASK_STACK,
(void *)&dev,
TASK_PRIORITY, // priorità leggermente più alta
&trigA_TaskHandle,
CORE_1);
auto ignB_task_success = pdPASS;
// auto ignB_task_success = xTaskCreatePinnedToCore(
// ignitionB_task,
// "ignitionB_task",
// TASK_STACK,
// (void *)&dev,
// 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("5 seconds to restart...");
vTaskDelay(pdMS_TO_TICKS(5000));
esp_restart();
}
LOG_INFO("Real Time Tasks A&B initialized");
////////////////////// MAIN LOOP //////////////////////

View File

@@ -1,86 +1,129 @@
#pragma once
// =====================
// SPI BUS
// USB (RISERVATA)
// =====================
#define SPI_MOSI 11
#define SPI_MISO 13
#define SPI_SCK 12
#define USB_DM 19
#define USB_DP 20
// =====================
// I2C BUS
// UART DEBUG (RISERVATA)
// =====================
#define SDA 8
#define SCL 9
#define UART_TX 43
#define UART_RX 44
// =====================
// ADC CONTROL
// RGB Led
// =====================
#define ADC_CS 10
#define ADC_DRDY 4
#define ADC_RST 5
#define ADC_SYNC 6
#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 SCL 9
// =====================
// ADC CONTROL (NO CONFLICT)
// =====================
#define ADC_A_CS 4
#define ADC_A_DRDY 5
#define ADC_A_RST 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
// =====================
#define POT_CS 7
#define POT_DRDY 18
// =====================
// RELAY OUT
// =====================
#define PICK_RELAY 21
#define POT_A_CS 1
#define POT_B_CS 2
// =====================
// TRIGGER INPUT INTERRUPTS
// =====================
#define TRIG_A12P 1
#define TRIG_A12N 2
#define TRIG_A34P 3
#define TRIG_A34N 14
#define TRIG_B12P 15
#define TRIG_B12N 16
#define TRIG_B34P 17
#define TRIG_B34N 18
#define TRIG_A12P 21
#define TRIG_A12N 33
#define TRIG_A34P 34
#define TRIG_A34N 38
#define TRIG_B12P 39
#define TRIG_B12N 40
#define TRIG_B34P 41
#define TRIG_B34N 42
// =====================
// PEAK DETECTOR RESET OUTPUTS
// SPARK DETECT INPUTS (INPUT ONLY SAFE)
// =====================
#define RST_A12P 39
#define RST_A12N 40
#define RST_A34P 41
#define RST_A34N 42
#define RST_B12P 35
#define RST_B12N 36
#define RST_B34P 37
#define RST_B34N 38
#define SPARK_A12 45
#define SPARK_A34 46
#define SPARK_B12 47
#define SPARK_B34 18
// =====================
// SPARK DETECT INPUTS
// PCA9555 (I2C EXPANDER)
// =====================
#define SPARK_A12 45 // input only
#define SPARK_A34 46 // input only
#define SPARK_B12 47
#define SPARK_B34 48
// =====================
// STATUS & BUTTON su PCA9555 (I2C)
// =====================
#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
// --- RESET LINES (ora su expander) ---
#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
#define BTN_1 8
#define BTN_2 9
#define BTN_3 10
#define BTN_4 11
#define BTN_5 12
#define BTN_6 13
#define BTN_7 14
#define BTN_8 15
// --- RELAY LINES ---
#define A_RELAY 8
#define B_RELAY 9
// --- STATUS OUTPUT ---
#define BTN_3 10
#define BTN_4 11
#define STA_1 12
#define STA_2 13
#define STA_3 14
#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
#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) {
if (!pvParameters) {
LOG_ERROR("Null device parameters");
vTaskDelete(NULL);
}
Devices* dev = (Devices*) pvParameters;
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 spark_flag;
while (true) {
while (rt_task_running) {
// WAIT FOR PICKUP SIGNAL
xTaskNotifyWait(
0x00, // non pulire all'ingresso
ULONG_MAX, // pulisci tutti i bit all'uscita
0x000000FF, // pulisci i primi 8 bit
&pickup_flag, // valore ricevuto
portMAX_DELAY
);
// WAIT FOR SPARK TO HAPPEN
auto spark_timeout = xTaskNotifyWait(
0x00, // non pulire all'ingresso
ULONG_MAX, // pulisci tutti i bit all'uscita
&spark_flag, // valore ricevuto
0x0000FF00, // pulisci gli 8 bit successivi
&spark_flag, // valore ricevuto
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
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.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;
ignA_status.coils12.spark_status = ignA_status.coils34.spark_status = sparkStatus::SPARK_SYNC_FAIL;
// Save error on circular buffer and skip to next cycle //
// [TODO]
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) {
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
if (spark_timeout == pdPASS) {
ignA_status.spark12_delay = ignA_status.spark12_start - ignA_status.trig12_start;
ignA_status.soft12_engaged = false; // because spark on positive edge
ignA_status.spark12_status = sparkStatus::SPARK_POS_OK; // do not wait for spark on negative edge
c->spark_delay = c->spark_time - c->trig_time;
c->soft_start_status = softStartStatus::NORMAL; // because spark on positive edge
c->spark_status = sparkStatus::SPARK_POS_OK; // do not wait for spark on negative edge
}
// Timeout occourred, expected POSITIVE edge spark NOT OCCOURRED
else if (spark_timeout == pdFAIL) {
ignA_status.spark12_status = sparkStatus::SPARK_NEG_WAIT;
ignA_status.soft12_engaged = false;
c->spark_status = sparkStatus::SPARK_NEG_WAIT;
c->soft_start_status = softStartStatus::NORMAL;
}
// Do nothing more on positive pulse
break;
new_data = false;
break; // Do nothing more on positive pulse
}
case TRIG_FLAG_A12N: {
bool expected_negative12 = ignA_status.spark12_status == sparkStatus::SPARK_NEG_WAIT;
// CASES for NEGATIVE cycle triggering of pickup and sparks 12 & 34
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
if (spark_timeout == pdPASS && expected_negative12) {
ignA_status.spark12_delay = ignA_status.spark12_start - ignA_status.trig12_start;
ignA_status.soft12_engaged = true;
ignA_status.spark12_status == sparkStatus::SPARK_NEG_OK;
c->spark_delay = c->spark_time - c->trig_time;
c->soft_start_status = softStartStatus::SOFT_START;
c->spark_status == sparkStatus::SPARK_NEG_OK;
}
// Timeout occourred, expected POSITIVE edge spark NOT OCCOURRED
else if (spark_timeout == pdFAIL && expected_negative12) {
ignA_status.soft12_engaged = false;
ignA_status.spark12_status = sparkStatus::SPARK_NEG_FAIL;
c->soft_start_status = softStartStatus::NORMAL;
c->spark_status = sparkStatus::SPARK_NEG_FAIL;
}
// Timeout not occouured, unexpected negative edge spark
else if (spark_timeout == pdPASS && !expected_negative12) {
ignA_status.soft12_engaged = true;
ignA_status.spark12_status = sparkStatus::SPARK_NEG_UNEXPECTED;
c->soft_start_status = softStartStatus::SOFT_START;
c->spark_status = sparkStatus::SPARK_NEG_UNEXPECTED;
}
// Save status on circular buffer
new_data12 = true;
// Wait for finish of negative pulse to save data to buffer
new_data = true;
break;
}
case TRIG_FLAG_A34P:
case TRIG_FLAG_A34N:
break;
default:
LOG_ERROR("Invalid A Interrupt");
}
vTaskDelay(pdMS_TO_TICKS(1)); // delay 1ms to allow peak detectors to charge
if (new_data12) {
if (new_data) {
vTaskDelay(pdMS_TO_TICKS(1)); // delay 1ms to allow peak detectors to charge for negative cycle
// read adc channels: pickup12, out12 [ pos + neg ]
ignA_status.volts12_pickup = adcReadChannel(adc, PICKUP_IN_A12);
ignA_status.volts12_out = adcReadChannel(adc, PICKUP_OUT_A12);
// reset peak detectors
digitalWrite(RST_A12P, HIGH);
digitalWrite(RST_A12N, HIGH);
vTaskDelay(pdMS_TO_TICKS(1));
digitalWrite(RST_A12P, HIGH);
digitalWrite(RST_A12N, HIGH);
ignA_status.coils12.pickup_volts = adcReadChannel(adc, IN_A12_P);
ignA_status.coils12.output_volts = adcReadChannel(adc, PICKUP_OUT_A12);
ignA_status.coils34.pickup_volts = adcReadChannel(adc, PICKUP_IN_A34);
ignA_status.coils34.output_volts = adcReadChannel(adc, PICKUP_OUT_A34);
// reset peak detectors -> gli output sono sull'expander
//digitalWrite(RST_A12P, HIGH);
//digitalWrite(RST_A12N, HIGH);
//vTaskDelay(pdMS_TO_TICKS(1));
//digitalWrite(RST_A12P, HIGH);
//digitalWrite(RST_A12N, HIGH);
// 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) {
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) {
// attende eventi
xTaskNotifyWait(