diff --git a/RotaxMonitor/src/isr.h b/RotaxMonitor/src/isr.h index a034a75..02dee23 100644 --- a/RotaxMonitor/src/isr.h +++ b/RotaxMonitor/src/isr.h @@ -4,10 +4,10 @@ #include "soc/gpio_struct.h" #include "pins.h" -#define CORE_0 0 +#define CORE_0 0 #define CORE_1 1 -#define TASK_STACK 4096 // in words -#define TASK_PRIORITY 2 // priorità leggermente più alta +#define TASK_STACK 4096 // in words +#define TASK_PRIORITY 2 // priorità leggermente più alta #define IGN_BUF_SIZE 128 @@ -33,7 +33,8 @@ TaskHandle_t trigA_TaskHandle = NULL; TaskHandle_t trigB_TaskHandle = NULL; // Spark Status -enum sparkStatus { +enum sparkStatus +{ SPARK_POS_OK, SPARK_NEG_OK, SPARK_POS_SKIP, @@ -48,16 +49,17 @@ enum sparkStatus { }; // Task internal Status -struct ignitionBoxStatus { +struct ignitionBoxStatus +{ // start time from ISR - int64_t trig12_start; - int64_t trig34_start; + int64_t trig12_start = 0; + int64_t trig34_start = 0; // time at which spark occours - int64_t trig12_end; - int64_t trig34_end; + int64_t spark12_start = 0; + int64_t spark34_start = 0; // computed delay from pickup to spark - int64_t spark12_delay; - int64_t spark34_delay; + 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; @@ -65,13 +67,13 @@ struct ignitionBoxStatus { bool soft12_engaged = false; bool soft34_engaged = false; // peak voltage from circuits 12 and 34 - float volts12_pickup; - float volts34_pickup; + float volts12_pickup = 0.0; + float volts34_pickup = 0.0; // peak voltage from conditioned output 12 and 34 - float volts12_out; - float volts34_out; + float volts12_out = 0.0; + float volts34_out = 0.0; // voltage from generator - float volts_gen; + float volts_gen = 0.0; }; ignitionBoxStatus ignA_status; @@ -82,7 +84,8 @@ ignitionBoxStatus ingB_statusBuffer[IGN_BUF_SIZE]; // Pin to flag Map static uint32_t pin2trig[49]; -void initTriggerPinMapping() { +void initTriggerPinMapping() +{ pin2trig[TRIG_A12P] = TRIG_FLAG_A12P; pin2trig[TRIG_A12N] = TRIG_FLAG_A12N; pin2trig[TRIG_A34P] = TRIG_FLAG_A34P; @@ -94,7 +97,8 @@ void initTriggerPinMapping() { }; static uint32_t pin2spark[49]; -void initSparkPinMapping() { +void initSparkPinMapping() +{ pin2spark[SPARK_A12] = SPARK_FLAG_A12; pin2spark[SPARK_A34] = SPARK_FLAG_A34; pin2spark[SPARK_B12] = SPARK_FLAG_B12; @@ -105,64 +109,80 @@ void initSparkPinMapping() { // 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 IRAM_ATTR trig_isr_a() +{ BaseType_t xHigherPriorityTaskWoken = pdFALSE; - auto startTime = esp_timer_get_time(); + const int64_t startTime = esp_timer_get_time(); + if (!trigA_TaskHandle) return; // exit if task is not running uint32_t status = GPIO.status; uint32_t flags = 0; - while (status) { + while (status) + { uint32_t pin = __builtin_ctz(status); // trova primo bit attivo status &= ~(1 << pin); // clear bit - flags |= pin2trig[pin]; } - if (flags & (TRIG_FLAG_A12P | TRIG_FLAG_A12N)) - ignA_status.trig12_start = startTime; - else + if (flags & TRIG_FLAG_A12P) ignA_status.trig12_start = startTime; + if (flags & TRIG_FLAG_A34P) + ignA_status.trig34_start = startTime; - if (trigA_TaskHandle) { - xTaskNotifyFromISR(trigA_TaskHandle, flags, eSetBits, &xHigherPriorityTaskWoken); - portYIELD_FROM_ISR(xHigherPriorityTaskWoken); - } + xTaskNotifyFromISR(trigA_TaskHandle, flags, eSetBits, &xHigherPriorityTaskWoken); + portYIELD_FROM_ISR(xHigherPriorityTaskWoken); } -void IRAM_ATTR spark_a() { +void IRAM_ATTR spark_a() +{ BaseType_t xHigherPriorityTaskWoken = pdFALSE; - uint32_t spark_flag = GPIO.status1.val & SPARK_A12 ? SPARK_FLAG_A12 : SPARK_FLAG_A34 ; - if (trigA_TaskHandle) { - xTaskNotifyFromISR(trigA_TaskHandle, spark_flag, eSetBits, &xHigherPriorityTaskWoken); - portYIELD_FROM_ISR(xHigherPriorityTaskWoken); - } + const int64_t startTime = 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; + if (spark_flag & SPARK_FLAG_A34) + ignA_status.spark34_start = startTime; + xTaskNotifyFromISR(trigA_TaskHandle, spark_flag, eSetBits, &xHigherPriorityTaskWoken); + portYIELD_FROM_ISR(xHigherPriorityTaskWoken); } -void IRAM_ATTR trig_isr_b() { +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 - uint32_t status = GPIO.status1.val; + uint32_t status = GPIO.status; uint32_t flags = 0; - while (status) { + while (status) + { uint32_t pin = __builtin_ctz(status); // trova primo bit attivo status &= ~(1 << pin); // clear bit - flags |= pin2trig[pin]; } - if (trigB_TaskHandle) { - xTaskNotifyFromISR(trigB_TaskHandle, flags, eSetBits, &xHigherPriorityTaskWoken); - portYIELD_FROM_ISR(xHigherPriorityTaskWoken); - } + if (flags & TRIG_FLAG_B12P) + ignB_status.trig12_start = startTime; + if (flags & TRIG_FLAG_B34P) + ignB_status.trig34_start = startTime; + + xTaskNotifyFromISR(trigB_TaskHandle, flags, eSetBits, &xHigherPriorityTaskWoken); + portYIELD_FROM_ISR(xHigherPriorityTaskWoken); } -void IRAM_ATTR spark_b() { +void IRAM_ATTR spark_b() +{ BaseType_t xHigherPriorityTaskWoken = pdFALSE; - uint32_t spark_flag = GPIO.status1.val & SPARK_B12 ? SPARK_FLAG_B12 : SPARK_FLAG_B34 ; - if (trigB_TaskHandle) { - xTaskNotifyFromISR(trigB_TaskHandle, spark_flag, eSetBits, &xHigherPriorityTaskWoken); - portYIELD_FROM_ISR(xHigherPriorityTaskWoken); - } + const int64_t startTime = 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; + if (spark_flag & SPARK_FLAG_B34) + ignB_status.spark34_start = startTime; + xTaskNotifyFromISR(trigB_TaskHandle, spark_flag, eSetBits, &xHigherPriorityTaskWoken); + portYIELD_FROM_ISR(xHigherPriorityTaskWoken); } diff --git a/RotaxMonitor/src/main.cpp b/RotaxMonitor/src/main.cpp index 780d8bf..ef59223 100644 --- a/RotaxMonitor/src/main.cpp +++ b/RotaxMonitor/src/main.cpp @@ -12,108 +12,104 @@ #include #include +void setup() +{ + delay(250); + Serial.begin(115200); -void setup() { - delay(250); - Serial.begin(115200); + // Setup Logger + LOG_ATTACH_SERIAL(Serial); + LOG_SET_LEVEL(DebugLogLevel::LVL_INFO); - // Setup Logger - LOG_ATTACH_SERIAL(Serial); - LOG_SET_LEVEL(DebugLogLevel::LVL_INFO); + // Print Processor Info + LOG_INFO("ESP32 Chip:", ESP.getChipModel()); + LOG_INFO("ESP32 PSram:", ESP.getPsramSize()); + LOG_INFO("ESP32 Flash:", ESP.getFlashChipSize()); + LOG_INFO("ESP32 Heap:", ESP.getHeapSize()); + LOG_INFO("ESP32 Sketch:", ESP.getFreeSketchSpace()); - // Print Processor Info - LOG_INFO("ESP32 Chip:", ESP.getChipModel()); - LOG_INFO("ESP32 PSram:", ESP.getPsramSize()); - LOG_INFO("ESP32 Flash:", ESP.getFlashChipSize()); - 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); + 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); + initSparkPinMapping(); - // 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); - 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); - 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); - // 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(); + // Init SPI interface + SPI.begin(); } -void loop() { - // global variables - bool running = true; - Devices dev; +void loop() +{ + // global variables + bool running = true; + Devices dev; - // Init devices - dev.adc = 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); + // Init devices + dev.adc = 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); - // Ignition A on Core 0 + // Ignition A on Core 0 auto ignA_task_success = xTaskCreatePinnedToCore( ignitionA_task, "ignitionA_task", TASK_STACK, - (void*) &dev, - TASK_PRIORITY, + (void *)&dev, + TASK_PRIORITY, &trigA_TaskHandle, - CORE_0 - ); + CORE_0); - // Ignition A on Core 1 + // Ignition B on Core 1 auto ignB_task_success = xTaskCreatePinnedToCore( ignitionB_task, "ignitionB_task", TASK_STACK, - (void*) &dev, + (void *)&dev, TASK_PRIORITY, // priorità leggermente più alta &trigA_TaskHandle, - CORE_1 - ); + CORE_1); - if ((ignA_task_success && ignB_task_success) != pdPASS){ - LOG_ERROR("Unble to initialize ISR task"); + if ((ignA_task_success && ignB_task_success) != pdPASS) + { + LOG_ERROR("Unble to initialize ISR task"); } LOG_INFO("Real Time Tasks A&B initialized"); - ////////////////////// MAIN LOOP ////////////////////// - while (running) { - + while (running) + { } if (trigA_TaskHandle) - vTaskDelete(trigA_TaskHandle); + vTaskDelete(trigA_TaskHandle); if (trigB_TaskHandle) - vTaskDelete(trigB_TaskHandle); + vTaskDelete(trigB_TaskHandle); ////////////////////// MAIN LOOP ////////////////////// } - - diff --git a/RotaxMonitor/src/tasks.h b/RotaxMonitor/src/tasks.h index 001fb01..96ce5c3 100644 --- a/RotaxMonitor/src/tasks.h +++ b/RotaxMonitor/src/tasks.h @@ -34,13 +34,11 @@ void ignitionA_task(void *pvParameters) { &spark_flag, // valore ricevuto spark_timeout_max ); - // Save current time to compute delay from pickup to spark - auto curr_time = esp_timer_get_time(); // 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.trig12_end = ignA_status.trig34_end = -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; @@ -50,14 +48,12 @@ void ignitionA_task(void *pvParameters) { } bool new_data12 = false; - bool new_data34 = false; - + switch (pickup_flag) { case TRIG_FLAG_A12P: { // Timeout not occourred, expected POSITIVE edge spark OCCOURRED if (spark_timeout == pdPASS) { - ignA_status.trig12_end = curr_time; - ignA_status.spark12_delay = ignA_status.trig12_end - ignA_status.trig12_end; + 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 } @@ -72,9 +68,8 @@ void ignitionA_task(void *pvParameters) { case TRIG_FLAG_A12N: { bool expected_negative12 = ignA_status.spark12_status == sparkStatus::SPARK_NEG_WAIT; // Timeout not occourred, expected NEGATIVE edge spark OCCOURRED - if (spark_timeout == pdPASS && expected_negative12) { - ignA_status.trig12_end = curr_time; - ignA_status.spark12_delay = ignA_status.trig12_end - ignA_status.trig12_end; + 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; }