refactored real time task to general with configuration structure
This commit is contained in:
@@ -33,14 +33,12 @@ struct Devices {
|
||||
PCA9555* io = NULL;
|
||||
};
|
||||
|
||||
inline float adcReadChannel(ADS1256* adc, const uint32_t drdy_pin, const uint32_t ch){
|
||||
inline float adcReadChannel(ADS1256* adc, const uint8_t ch){
|
||||
adc->setMUX(ch);
|
||||
// scarta 3 conversioni
|
||||
for (int i = 0; i < 3; i++) {
|
||||
while (digitalRead(drdy_pin));
|
||||
adc->readSingle();
|
||||
}
|
||||
// ora lettura valida a 30kSPS → ~100 µs di settling
|
||||
while (digitalRead(drdy_pin));
|
||||
return adc->convertToVoltage(adc->readSingle());
|
||||
}
|
||||
|
||||
@@ -1,50 +1,34 @@
|
||||
#pragma once
|
||||
|
||||
// Test device Flag
|
||||
#define TEST
|
||||
|
||||
// Arduino Libraries
|
||||
#include <Arduino.h>
|
||||
#include <map>
|
||||
#include "soc/gpio_struct.h"
|
||||
#ifndef TEST
|
||||
#include "pins.h"
|
||||
#include "pins.h"
|
||||
#else
|
||||
#include "pins_test.h"
|
||||
#include "pins_test.h"
|
||||
#endif
|
||||
|
||||
#define CORE_0 0
|
||||
#define CORE_1 1
|
||||
#define TASK_STACK 4096 // in words
|
||||
#define TASK_PRIORITY 2 // priorità leggermente più alta
|
||||
#define TASK_PRIORITY (configMAX_PRIORITIES - 4) // highest priority after wifi tasks
|
||||
|
||||
// =====================
|
||||
// Event Flags (bitmask)
|
||||
// =====================
|
||||
#define TRIG_FLAG_A12P (1 << 0)
|
||||
#define TRIG_FLAG_A12N (1 << 2)
|
||||
#define TRIG_FLAG_A34P (1 << 1)
|
||||
#define TRIG_FLAG_A34N (1 << 3)
|
||||
#ifndef TEST
|
||||
#define TRIG_FLAG_B12P (1 << 4)
|
||||
#define TRIG_FLAG_B12N (1 << 6)
|
||||
#define TRIG_FLAG_B34P (1 << 5)
|
||||
#define TRIG_FLAG_B34N (1 << 7)
|
||||
#endif
|
||||
#define TRIG_FLAG_12P (1 << 0)
|
||||
#define TRIG_FLAG_12N (1 << 2)
|
||||
#define TRIG_FLAG_34P (1 << 1)
|
||||
#define TRIG_FLAG_34N (1 << 3)
|
||||
|
||||
#define SPARK_FLAG_A12 (1 << 8)
|
||||
#define SPARK_FLAG_A34 (1 << 9)
|
||||
#ifndef TEST
|
||||
#define SPARK_FLAG_B12 (1 << 10)
|
||||
#define SPARK_FLAG_B34 (1 << 11)
|
||||
#endif
|
||||
|
||||
static const std::map<const uint32_t, const char*> names = {
|
||||
{TRIG_FLAG_A12P, "TRIG_FLAG_A12P"},
|
||||
{TRIG_FLAG_A12N, "TRIG_FLAG_A12N"},
|
||||
{TRIG_FLAG_A34P, "TRIG_FLAG_A34P"},
|
||||
{TRIG_FLAG_A34N, "TRIG_FLAG_A34N"},
|
||||
{SPARK_FLAG_A12, "SPARK_FLAG_A12"},
|
||||
{SPARK_FLAG_A34, "SPARK_FLAG_A34"},
|
||||
};
|
||||
#define SPARK_FLAG_NIL (1 << 8)
|
||||
#define SPARK_FLAG_12 (1 << 9)
|
||||
#define SPARK_FLAG_34 (1 << 10)
|
||||
|
||||
// Task handle
|
||||
TaskHandle_t trigA_TaskHandle = NULL;
|
||||
@@ -78,20 +62,22 @@ struct coilsStatus
|
||||
int64_t spark_time;
|
||||
int64_t spark_delay;
|
||||
sparkStatus spark_status;
|
||||
softStartStatus soft_start_status;
|
||||
float pickup_volts;
|
||||
float output_volts;
|
||||
softStartStatus sstart_status;
|
||||
float peak_p_in, peak_n_in;
|
||||
float peak_p_out, peak_n_out;
|
||||
float trigger_spark;
|
||||
};
|
||||
|
||||
// Task internal Status
|
||||
struct ignitionBoxStatus
|
||||
{
|
||||
int64_t timestamp;
|
||||
// coils pairs for each ignition
|
||||
coilsStatus coils12;
|
||||
coilsStatus coils34;
|
||||
// voltage from generator
|
||||
float volts_gen = 0.0;
|
||||
|
||||
// spark flags
|
||||
bool spark12 = false;
|
||||
bool spark34 = false;
|
||||
};
|
||||
@@ -103,126 +89,72 @@ ignitionBoxStatus ignB_status;
|
||||
static uint32_t pin2trig[49] = {0};
|
||||
void initTriggerPinMapping()
|
||||
{
|
||||
pin2trig[TRIG_A12P] = TRIG_FLAG_A12P;
|
||||
pin2trig[TRIG_A12N] = TRIG_FLAG_A12N;
|
||||
pin2trig[TRIG_A34P] = TRIG_FLAG_A34P;
|
||||
pin2trig[TRIG_A34N] = TRIG_FLAG_A34N;
|
||||
#ifndef TEST
|
||||
pin2trig[TRIG_B12P] = TRIG_FLAG_B12P;
|
||||
pin2trig[TRIG_B12N] = TRIG_FLAG_B12N;
|
||||
pin2trig[TRIG_B34P] = TRIG_FLAG_B34P;
|
||||
pin2trig[TRIG_B34N] = TRIG_FLAG_B34N;
|
||||
#endif
|
||||
pin2trig[TRIG_A12P] = TRIG_FLAG_12P;
|
||||
pin2trig[TRIG_A12N] = TRIG_FLAG_12N;
|
||||
pin2trig[TRIG_A34P] = TRIG_FLAG_34P;
|
||||
pin2trig[TRIG_A34N] = TRIG_FLAG_34N;
|
||||
#ifndef TEST
|
||||
pin2trig[TRIG_B12P] = TRIG_FLAG_12P;
|
||||
pin2trig[TRIG_B12N] = TRIG_FLAG_12N;
|
||||
pin2trig[TRIG_B34P] = TRIG_FLAG_34P;
|
||||
pin2trig[TRIG_B34N] = TRIG_FLAG_34N;
|
||||
#endif
|
||||
};
|
||||
|
||||
static uint32_t pin2spark[49] = {0};
|
||||
void initSparkPinMapping()
|
||||
{
|
||||
pin2spark[SPARK_A12] = SPARK_FLAG_A12;
|
||||
pin2spark[SPARK_A34] = SPARK_FLAG_A34;
|
||||
#ifndef TEST
|
||||
pin2spark[SPARK_B12] = SPARK_FLAG_B12;
|
||||
pin2spark[SPARK_B34] = SPARK_FLAG_B34;
|
||||
#endif
|
||||
pin2spark[SPARK_A12] = SPARK_FLAG_12;
|
||||
pin2spark[SPARK_A34] = SPARK_FLAG_34;
|
||||
#ifndef TEST
|
||||
pin2spark[SPARK_B12] = SPARK_FLAG_12;
|
||||
pin2spark[SPARK_B34] = SPARK_FLAG_34;
|
||||
#endif
|
||||
};
|
||||
|
||||
// =====================
|
||||
// ISR (Pass return bitmask to ISR management function)
|
||||
// one function for each wake up pin conncted to a trigger
|
||||
// =====================
|
||||
void IRAM_ATTR trig_isr_a(void* arg)
|
||||
void IRAM_ATTR trig_isr_a(void *arg)
|
||||
{
|
||||
BaseType_t xHigherPriorityTaskWoken = pdFALSE;
|
||||
volatile const int64_t time_us = esp_timer_get_time();
|
||||
if (!trigA_TaskHandle)
|
||||
return; // exit if task is not running
|
||||
|
||||
uint32_t flag = (uint32_t)arg;
|
||||
// exit if task is not running
|
||||
if (!trigA_TaskHandle)
|
||||
return;
|
||||
|
||||
BaseType_t xHigherPriorityTaskWoken = pdFALSE;
|
||||
volatile const uint32_t flag = (uint32_t)arg;
|
||||
|
||||
// reset spark flags, cannot be same time as trigger flags
|
||||
ignA_status.spark12 = false;
|
||||
ignA_status.spark34 = false;
|
||||
|
||||
if (flag & TRIG_FLAG_A12P) {
|
||||
switch (flag)
|
||||
{
|
||||
case TRIG_FLAG_12P:
|
||||
ignA_status.coils12.trig_time = time_us;
|
||||
xTaskNotifyFromISR(trigA_TaskHandle, flag, eSetValueWithOverwrite, &xHigherPriorityTaskWoken);
|
||||
}
|
||||
if (flag & TRIG_FLAG_A34P) {
|
||||
break;
|
||||
case TRIG_FLAG_34P:
|
||||
ignA_status.coils34.trig_time = time_us;
|
||||
xTaskNotifyFromISR(trigA_TaskHandle, flag, eSetValueWithOverwrite, &xHigherPriorityTaskWoken);
|
||||
}
|
||||
|
||||
if (flag & SPARK_FLAG_A12) {
|
||||
break;
|
||||
case SPARK_FLAG_12:
|
||||
ignA_status.spark12 = true;
|
||||
ignA_status.coils12.spark_time = time_us;
|
||||
xTaskNotifyGive(trigA_TaskHandle);
|
||||
}
|
||||
if (flag & SPARK_FLAG_A34) {
|
||||
ignA_status.spark12 = false;
|
||||
vTaskNotifyGiveFromISR(trigA_TaskHandle, &xHigherPriorityTaskWoken);
|
||||
break;
|
||||
case SPARK_FLAG_34:
|
||||
ignA_status.spark34 = true;
|
||||
ignA_status.coils34.spark_time = time_us;
|
||||
xTaskNotifyGive(trigA_TaskHandle);
|
||||
vTaskNotifyGiveFromISR(trigA_TaskHandle, &xHigherPriorityTaskWoken);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
//xTaskNotifyFromISR(trigA_TaskHandle, flag, eSetValueWithOverwrite, &xHigherPriorityTaskWoken);
|
||||
if (xHigherPriorityTaskWoken) {
|
||||
if (xHigherPriorityTaskWoken)
|
||||
portYIELD_FROM_ISR();
|
||||
}
|
||||
}
|
||||
|
||||
// void IRAM_ATTR spark_a(void* arg)
|
||||
// {
|
||||
// BaseType_t xHigherPriorityTaskWoken = pdFALSE;
|
||||
// volatile const int64_t time_us = esp_timer_get_time();
|
||||
// if (!trigA_TaskHandle)
|
||||
// return;
|
||||
|
||||
// uint32_t flag = (uint32_t) arg;
|
||||
|
||||
// xTaskNotifyFromISR(trigA_TaskHandle, flag, eSetBits, &xHigherPriorityTaskWoken);
|
||||
// portYIELD_FROM_ISR(xHigherPriorityTaskWoken);
|
||||
// }
|
||||
|
||||
#ifndef TEST
|
||||
void IRAM_ATTR trig_isr_b()
|
||||
{
|
||||
BaseType_t xHigherPriorityTaskWoken = pdFALSE;
|
||||
volatile const int64_t time_us = esp_timer_get_time();
|
||||
if (!trigB_TaskHandle)
|
||||
return; // exit if task is not running
|
||||
|
||||
#ifndef TEST
|
||||
uint32_t status = GPIO.status;
|
||||
#else
|
||||
uint32_t status = GPIO.status1.val;
|
||||
#endif
|
||||
uint32_t pickup_flags = 0;
|
||||
|
||||
while (status)
|
||||
{
|
||||
uint32_t pin = __builtin_ctz(status); // trova primo bit attivo
|
||||
status &= ~(1 << pin); // clear bit
|
||||
pickup_flags |= pin2trig[pin];
|
||||
}
|
||||
|
||||
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, pickup_flags, eSetBits, &xHigherPriorityTaskWoken);
|
||||
portYIELD_FROM_ISR(xHigherPriorityTaskWoken);
|
||||
}
|
||||
|
||||
void IRAM_ATTR spark_b()
|
||||
{
|
||||
BaseType_t xHigherPriorityTaskWoken = pdFALSE;
|
||||
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.coils12.spark_time = time_us;
|
||||
if (spark_flag & SPARK_FLAG_B34)
|
||||
ignB_status.coils34.spark_time = time_us;
|
||||
xTaskNotifyFromISR(trigB_TaskHandle, spark_flag, eSetBits, &xHigherPriorityTaskWoken);
|
||||
portYIELD_FROM_ISR(xHigherPriorityTaskWoken);
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -1,5 +1,8 @@
|
||||
#pragma once
|
||||
|
||||
// Serial debug flag
|
||||
// #define DEBUG
|
||||
|
||||
// Arduino Libraries
|
||||
#include <Arduino.h>
|
||||
#include <DebugLog.h>
|
||||
@@ -11,156 +14,227 @@
|
||||
// DEVICES
|
||||
#include "devices.h"
|
||||
|
||||
//Global Variables and Flags
|
||||
// Global Variables and Flags
|
||||
static bool rt_task_running = true;
|
||||
const auto spark_timeout_max = 1000; // convert to microsecond timer
|
||||
const auto spark_timeout_max = 2; // in milliseconds
|
||||
|
||||
// RT task parameters
|
||||
struct rtTaskParams {
|
||||
bool rt_running;
|
||||
Devices *dev;
|
||||
// Debug Variables
|
||||
#ifdef DEBUG
|
||||
static const std::map<const uint32_t, const char *> names = {
|
||||
{TRIG_FLAG_A12P, "TRIG_FLAG_A12P"},
|
||||
{TRIG_FLAG_A12N, "TRIG_FLAG_A12N"},
|
||||
{TRIG_FLAG_A34P, "TRIG_FLAG_A34P"},
|
||||
{TRIG_FLAG_A34N, "TRIG_FLAG_A34N"},
|
||||
{SPARK_FLAG_A12, "SPARK_FLAG_A12"},
|
||||
{SPARK_FLAG_A34, "SPARK_FLAG_A34"},
|
||||
};
|
||||
#endif
|
||||
|
||||
// RT task Interrupt parameters
|
||||
struct rtTaskInterrupts
|
||||
{
|
||||
void (*isr_ptr)(void *);
|
||||
const uint8_t trig_pin_12p;
|
||||
const uint8_t trig_pin_12n;
|
||||
const uint8_t trig_pin_34p;
|
||||
const uint8_t trig_pin_34n;
|
||||
const uint8_t spark_pin_12;
|
||||
const uint8_t spark_pin_34;
|
||||
};
|
||||
|
||||
void ignitionA_task(void *pvParameters) {
|
||||
// RT Task Peak Detector Reset pins
|
||||
struct rtTaskResets
|
||||
{
|
||||
const uint8_t rst_io_12p;
|
||||
const uint8_t rst_io_12n;
|
||||
const uint8_t rst_io_34p;
|
||||
const uint8_t rst_io_34n;
|
||||
};
|
||||
|
||||
if (!pvParameters) {
|
||||
// RT Task Adc channels
|
||||
struct rtTaskAdChannels
|
||||
{
|
||||
const uint8_t adc_gen;
|
||||
const uint8_t adc_spark_12;
|
||||
const uint8_t adc_spark_34;
|
||||
const uint8_t adc_peak_12p_in;
|
||||
const uint8_t adc_peak_12n_in;
|
||||
const uint8_t adc_peak_34p_in;
|
||||
const uint8_t adc_peak_34n_in;
|
||||
const uint8_t adc_peak_12p_out;
|
||||
const uint8_t adc_peak_12n_out;
|
||||
const uint8_t adc_peak_34p_out;
|
||||
const uint8_t adc_peak_34n_out;
|
||||
};
|
||||
|
||||
// RT task parameters
|
||||
struct rtTaskParams
|
||||
{
|
||||
bool rt_running; // run flag, false to terminate
|
||||
Devices *dev;
|
||||
QueueHandle_t rt_queue;
|
||||
const rtTaskInterrupts rt_int; // interrupt pins to attach
|
||||
const rtTaskResets rt_resets; // reset ping for peak detectors
|
||||
const rtTaskAdChannels rt_adcch; // adc channels
|
||||
};
|
||||
|
||||
void ignitionA_task(void *pvParameters)
|
||||
{
|
||||
|
||||
if (!pvParameters)
|
||||
{
|
||||
LOG_ERROR("Null task parameters");
|
||||
vTaskDelete(NULL);
|
||||
}
|
||||
|
||||
// Task Parameters and Devices
|
||||
rtTaskParams* params = (rtTaskParams*) pvParameters;
|
||||
Devices* dev = (Devices*) params->dev;
|
||||
ADS1256* adc = dev->adc_a;
|
||||
const rtTaskParams *params = (const rtTaskParams *)pvParameters;
|
||||
const rtTaskInterrupts rt_int = params->rt_int; // copy to avoid external override
|
||||
const rtTaskResets rt_rst = params->rt_resets; // copy to avoid external override
|
||||
const rtTaskAdChannels rt_adcch = params->rt_adcch; // copy to avoid external override
|
||||
QueueHandle_t queue = params->rt_queue;
|
||||
Devices *dev = params->dev;
|
||||
ADS1256 *adc = dev->adc_a;
|
||||
PCA9555 *io = dev->io;
|
||||
|
||||
// Ignition A Interrupts
|
||||
attachInterruptArg(TRIG_A12P, trig_isr_a, (void*)TRIG_FLAG_A12P, RISING);
|
||||
attachInterruptArg(TRIG_A12N, trig_isr_a, (void*)TRIG_FLAG_A12N, RISING);
|
||||
attachInterruptArg(TRIG_A34P, trig_isr_a, (void*)TRIG_FLAG_A34P, RISING);
|
||||
attachInterruptArg(TRIG_A34N, trig_isr_a, (void*)TRIG_FLAG_A34N, RISING);
|
||||
attachInterruptArg(SPARK_A12, trig_isr_a, (void*)SPARK_FLAG_A12, RISING);
|
||||
attachInterruptArg(SPARK_A34, trig_isr_a, (void*)SPARK_FLAG_A34, RISING);
|
||||
// Attach Pin Interrupts
|
||||
attachInterruptArg(rt_int.trig_pin_12p, rt_int.isr_ptr, (void *)TRIG_FLAG_12P, RISING);
|
||||
attachInterruptArg(rt_int.trig_pin_12n, rt_int.isr_ptr, (void *)TRIG_FLAG_12N, RISING);
|
||||
attachInterruptArg(rt_int.trig_pin_34p, rt_int.isr_ptr, (void *)TRIG_FLAG_34P, RISING);
|
||||
attachInterruptArg(rt_int.trig_pin_34n, rt_int.isr_ptr, (void *)TRIG_FLAG_34N, RISING);
|
||||
attachInterruptArg(rt_int.spark_pin_12, rt_int.isr_ptr, (void *)SPARK_FLAG_12, RISING);
|
||||
attachInterruptArg(rt_int.spark_pin_34, rt_int.isr_ptr, (void *)SPARK_FLAG_34, RISING);
|
||||
|
||||
uint32_t it=0;
|
||||
while (rt_task_running) {
|
||||
// Compute Reset Pin Bitmask
|
||||
const uint16_t rst_bitmask = (1 << rt_rst.rst_io_12p) |
|
||||
(1 << rt_rst.rst_io_12n) |
|
||||
(1 << rt_rst.rst_io_34p) |
|
||||
(1 << rt_rst.rst_io_34n);
|
||||
|
||||
uint32_t it = 0;
|
||||
uint32_t q_fail_count = 0;
|
||||
while (rt_task_running)
|
||||
{
|
||||
// Global task variables
|
||||
uint32_t pickup_flag = 0;
|
||||
uint32_t spark_flag = 0;
|
||||
|
||||
#ifdef DEBUG
|
||||
Serial.print("\033[2J"); // clear screen
|
||||
Serial.print("\033[H"); // cursor home
|
||||
LOG_INFO("Iteration [", it, "]");
|
||||
#endif
|
||||
|
||||
// WAIT FOR PICKUP SIGNAL
|
||||
xTaskNotifyWait(
|
||||
0x00, // non pulire all'ingresso
|
||||
ULONG_MAX, // pulisci i primi 8 bit
|
||||
&pickup_flag, // valore ricevuto
|
||||
portMAX_DELAY
|
||||
);
|
||||
portMAX_DELAY);
|
||||
|
||||
Serial.print("\033[2J"); // clear screen
|
||||
Serial.print("\033[H"); // cursor home
|
||||
LOG_INFO("Iteration [", it, "]");
|
||||
|
||||
//LOG_INFO("Pickup Flags: ", printBits(pickup_flag).c_str());
|
||||
if (!names.contains(pickup_flag)) {
|
||||
#ifdef DEBUG
|
||||
LOG_INFO("Pickup Flags: ", printBits(pickup_flag).c_str());
|
||||
if (!names.contains(pickup_flag))
|
||||
{
|
||||
LOG_ERROR("Wrong Pickup Flag");
|
||||
continue;
|
||||
} else {
|
||||
}
|
||||
else
|
||||
{
|
||||
LOG_INFO("Pickup Trigger: ", names.at(pickup_flag));
|
||||
}
|
||||
#endif
|
||||
|
||||
// WAIT FOR SPARK TO HAPPEN
|
||||
auto spark_timeout = ulTaskNotifyTake(pdTRUE, pdMS_TO_TICKS(5));
|
||||
//auto spark_timeout = xTaskNotifyWait(
|
||||
// 0x00, // non pulire all'ingresso
|
||||
// ULONG_MAX, // pulisci gli 8 bit successivi
|
||||
// &spark_flag, // valore ricevuto
|
||||
// spark_timeout_max
|
||||
//);
|
||||
|
||||
digitalWrite(POT_A_CS, HIGH);
|
||||
if (ignA_status.spark12 || ignA_status.spark34) { //otherwise timeout
|
||||
//LOG_INFO("Spark Flags: ", printBits(spark_flag).c_str());
|
||||
spark_flag = ignA_status.spark12 ? SPARK_FLAG_A12 : SPARK_FLAG_A34;
|
||||
if (!names.contains(spark_flag)) {
|
||||
LOG_ERROR("Wrong Spark Flag");
|
||||
} else {
|
||||
LOG_INFO("Spark Trigger:", names.at(spark_flag));
|
||||
}
|
||||
} else {
|
||||
LOG_INFO("Spark Timeout");
|
||||
}
|
||||
auto spark_timeout = ulTaskNotifyTake(pdTRUE, pdMS_TO_TICKS(spark_timeout_max));
|
||||
if (ignA_status.spark12 || ignA_status.spark34) // otherwise timeout if none is set in the ISR
|
||||
spark_flag = ignA_status.spark12 ? SPARK_FLAG_12 : SPARK_FLAG_34;
|
||||
|
||||
xTaskNotifyStateClear(NULL);
|
||||
ulTaskNotifyValueClear(NULL, 0xFFFFFFFF);
|
||||
#ifdef DEBUG
|
||||
LOG_INFO("Spark Flags: ", printBits(spark_flag).c_str());
|
||||
if (!names.contains(spark_flag))
|
||||
LOG_ERROR("No Spark");
|
||||
else
|
||||
LOG_INFO("Spark Trigger:", names.at(spark_flag));
|
||||
#endif
|
||||
|
||||
// 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_FLAG_A12) {
|
||||
if ((pickup_flag == TRIG_FLAG_12P || pickup_flag == TRIG_FLAG_12N) && spark_flag != SPARK_FLAG_12)
|
||||
{
|
||||
ignA_status.coils12.spark_status = ignA_status.coils34.spark_status = sparkStatus::SPARK_SYNC_FAIL;
|
||||
// Save error on circular buffer and skip to next cycle //
|
||||
LOG_ERROR("Spark Mismatch");
|
||||
continue;
|
||||
}
|
||||
|
||||
coilsStatus* c;
|
||||
coilsStatus *c;
|
||||
switch (pickup_flag)
|
||||
{
|
||||
case TRIG_FLAG_A12P:
|
||||
case TRIG_FLAG_A12N:
|
||||
//case SPARK_FLAG_A12:
|
||||
case TRIG_FLAG_12P:
|
||||
case TRIG_FLAG_12N:
|
||||
c = &ignA_status.coils12;
|
||||
break;
|
||||
case TRIG_FLAG_A34P:
|
||||
case TRIG_FLAG_A34N:
|
||||
//case SPARK_FLAG_A34:
|
||||
case TRIG_FLAG_34P:
|
||||
case TRIG_FLAG_34N:
|
||||
c = &ignA_status.coils34;
|
||||
break;
|
||||
}
|
||||
|
||||
bool new_data = false;
|
||||
|
||||
switch (pickup_flag) {
|
||||
// CASES for NEGATIVE cycle triggering of pickup and sparks 12 & 34
|
||||
case TRIG_FLAG_A12P:
|
||||
case TRIG_FLAG_A34P:
|
||||
switch (pickup_flag)
|
||||
{
|
||||
// CASES for NEGATIVE cycle triggering of pickup and sparks 12 & 34
|
||||
case TRIG_FLAG_12P:
|
||||
case TRIG_FLAG_34P:
|
||||
{
|
||||
LOG_INFO("Trigger Pickup POSITIVE");
|
||||
// Timeout not occourred, expected POSITIVE edge spark OCCOURRED
|
||||
if (spark_timeout == pdPASS) {
|
||||
if (spark_timeout == pdPASS)
|
||||
{
|
||||
c->spark_delay = c->spark_time - c->trig_time;
|
||||
c->soft_start_status = softStartStatus::NORMAL; // because spark on positive edge
|
||||
c->sstart_status = softStartStatus::NORMAL; // because spark on positive edge
|
||||
c->spark_status = sparkStatus::SPARK_POS_OK; // do not wait for spark on negative edge
|
||||
#ifdef DEBUG
|
||||
LOG_INFO("Trigger Spark POSITIVE");
|
||||
LOG_INFO("Spark12 Delay Timer: ", (int)c->spark_delay);
|
||||
#endif
|
||||
}
|
||||
// Timeout occourred, expected POSITIVE edge spark NOT OCCOURRED
|
||||
else if (spark_timeout == pdFAIL) {
|
||||
else if (spark_timeout == pdFAIL)
|
||||
{
|
||||
c->spark_status = sparkStatus::SPARK_NEG_WAIT;
|
||||
c->soft_start_status = softStartStatus::NORMAL;
|
||||
c->sstart_status = softStartStatus::NORMAL;
|
||||
}
|
||||
new_data = false;
|
||||
break; // Do nothing more on positive pulse
|
||||
}
|
||||
// CASES for NEGATIVE cycle triggering of pickup and sparks 12 & 34
|
||||
case TRIG_FLAG_A12N:
|
||||
case TRIG_FLAG_A34N:
|
||||
case TRIG_FLAG_12N:
|
||||
case TRIG_FLAG_34N:
|
||||
{
|
||||
const bool expected_negative12 = c->spark_status == sparkStatus::SPARK_NEG_WAIT;
|
||||
LOG_INFO("Trigger Pickup NEGATIVE");
|
||||
// Timeout not occourred, expected NEGATIVE edge spark OCCOURRED
|
||||
if (spark_timeout == pdPASS && expected_negative12) {
|
||||
if (spark_timeout == pdPASS && expected_negative12)
|
||||
{
|
||||
c->spark_delay = c->spark_time - c->trig_time;
|
||||
c->soft_start_status = softStartStatus::SOFT_START;
|
||||
c->sstart_status = softStartStatus::SOFT_START;
|
||||
c->spark_status == sparkStatus::SPARK_NEG_OK;
|
||||
#ifdef DEBUG
|
||||
LOG_INFO("Trigger Spark NEGATIVE");
|
||||
LOG_INFO("Spark12 Delay Timer: ", (int)ignA_status.coils12.spark_delay);
|
||||
#endif
|
||||
}
|
||||
// Timeout occourred, expected POSITIVE edge spark NOT OCCOURRED
|
||||
else if (spark_timeout == pdFAIL && expected_negative12) {
|
||||
c->soft_start_status = softStartStatus::NORMAL;
|
||||
else if (spark_timeout == pdFAIL && expected_negative12)
|
||||
{
|
||||
c->sstart_status = softStartStatus::NORMAL;
|
||||
c->spark_status = sparkStatus::SPARK_NEG_FAIL;
|
||||
}
|
||||
// Timeout not occouured, unexpected negative edge spark
|
||||
else if (spark_timeout == pdPASS && !expected_negative12) {
|
||||
c->soft_start_status = softStartStatus::SOFT_START;
|
||||
else if (spark_timeout == pdPASS && !expected_negative12)
|
||||
{
|
||||
c->sstart_status = softStartStatus::SOFT_START;
|
||||
c->spark_status = sparkStatus::SPARK_NEG_UNEXPECTED;
|
||||
}
|
||||
// Wait for finish of negative pulse to save data to buffer
|
||||
@@ -168,84 +242,62 @@ void ignitionA_task(void *pvParameters) {
|
||||
break;
|
||||
}
|
||||
default:
|
||||
LOG_ERROR("Invalid A Interrupt");
|
||||
LOG_ERROR("Invalid Interrupt");
|
||||
break;
|
||||
}
|
||||
it++;
|
||||
digitalWrite(POT_A_CS, LOW);
|
||||
continue;
|
||||
|
||||
if (new_data) {
|
||||
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 ]
|
||||
if (adc) // read only if adc initialized
|
||||
{
|
||||
ignA_status.coils12.pickup_volts = adcReadChannel(adc, ADC_A_DRDY, IN_A12_P);
|
||||
ignA_status.coils12.output_volts = adcReadChannel(adc, ADC_A_DRDY, IN_A12_N);
|
||||
ignA_status.coils34.pickup_volts = adcReadChannel(adc, ADC_A_DRDY, IN_A34_P);
|
||||
ignA_status.coils34.output_volts = adcReadChannel(adc, ADC_A_DRDY, IN_A34_N);
|
||||
} else {
|
||||
LOG_WARN("ADC not initialized, skipping conversion");
|
||||
}
|
||||
// reset peak detectors -> gli output sono sull'expander, temporaneo uso il PC del pot non collegato
|
||||
digitalWrite(POT_A_CS, HIGH);
|
||||
// digitalWrite(RST_A12P, HIGH);
|
||||
// digitalWrite(RST_A12N, HIGH);
|
||||
// digitalWrite(RST_A34P, HIGH);
|
||||
// digitalWrite(RST_A34N, HIGH);
|
||||
vTaskDelay(1);
|
||||
digitalWrite(POT_A_CS, HIGH);
|
||||
// digitalWrite(RST_A12P, LOW);
|
||||
// digitalWrite(RST_A12N, LOW);
|
||||
// digitalWrite(RST_A34P, LOW);
|
||||
// digitalWrite(RST_A34N, LOW);
|
||||
// save on circluar buffer 12
|
||||
ignA_status.volts_gen = adcReadChannel(adc, rt_adcch.adc_gen);
|
||||
// from peak detector circuits
|
||||
ignA_status.coils12.peak_p_in = adcReadChannel(adc, rt_adcch.adc_peak_12p_in);
|
||||
ignA_status.coils12.peak_n_in = adcReadChannel(adc, rt_adcch.adc_peak_12n_in);
|
||||
ignA_status.coils34.peak_p_in = adcReadChannel(adc, rt_adcch.adc_peak_34p_in);
|
||||
ignA_status.coils34.peak_n_in = adcReadChannel(adc, rt_adcch.adc_peak_34n_in);
|
||||
ignA_status.coils12.peak_p_out = adcReadChannel(adc, rt_adcch.adc_peak_12p_out);
|
||||
ignA_status.coils12.peak_n_out = adcReadChannel(adc, rt_adcch.adc_peak_12n_out);
|
||||
ignA_status.coils34.peak_p_out = adcReadChannel(adc, rt_adcch.adc_peak_34p_out);
|
||||
ignA_status.coils34.peak_n_out = adcReadChannel(adc, rt_adcch.adc_peak_34n_out);
|
||||
// from sample and hold triggered from spark interrupt
|
||||
ignA_status.coils12.trigger_spark = adcReadChannel(adc, rt_adcch.adc_spark_12);
|
||||
ignA_status.coils34.trigger_spark = adcReadChannel(adc, rt_adcch.adc_spark_34);
|
||||
}
|
||||
else // simulate adc read timig
|
||||
vTaskDelay(pdMS_TO_TICKS(6));
|
||||
|
||||
// reset peak detectors + sample and hold
|
||||
// outputs on io expander
|
||||
if (io)
|
||||
{
|
||||
const uint16_t iostat = io->read();
|
||||
io->write(iostat | rst_bitmask);
|
||||
vTaskDelay(pdMS_TO_TICKS(1));
|
||||
io->write(iostat & ~rst_bitmask);
|
||||
}
|
||||
else
|
||||
vTaskDelay(pdMS_TO_TICKS(2));
|
||||
|
||||
// send essage to main loop with ignition info
|
||||
if (queue)
|
||||
ignA_status.timestamp = esp_timer_get_time(); // update data timestamp
|
||||
if (xQueueSendToBack(queue, (void*)&ignA_status, pdMS_TO_TICKS(1)) != pdPASS) {
|
||||
q_fail_count++;
|
||||
LOG_ERROR("Failed to send to queue");
|
||||
}
|
||||
}
|
||||
}
|
||||
LOG_WARN("Ending realTime Task");
|
||||
// Ignition A Interrupts DETACH
|
||||
detachInterrupt(TRIG_A12P);
|
||||
detachInterrupt(TRIG_A12N);
|
||||
detachInterrupt(TRIG_A34P);
|
||||
detachInterrupt(TRIG_A34N);
|
||||
detachInterrupt(SPARK_A12);
|
||||
detachInterrupt(SPARK_A34);
|
||||
detachInterrupt(rt_int.trig_pin_12p);
|
||||
detachInterrupt(rt_int.trig_pin_12n);
|
||||
detachInterrupt(rt_int.trig_pin_34p);
|
||||
detachInterrupt(rt_int.trig_pin_34n);
|
||||
detachInterrupt(rt_int.spark_pin_12);
|
||||
detachInterrupt(rt_int.spark_pin_34);
|
||||
// delete present task
|
||||
vTaskDelete(NULL);
|
||||
}
|
||||
|
||||
#ifndef TEST
|
||||
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(
|
||||
0x00, // non pulire all'ingresso
|
||||
0xFFFFFFFF, // pulisci tutti i bit all'uscita
|
||||
¬ifiedValue, // 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);
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
Reference in New Issue
Block a user