Compare commits
11 Commits
ec138553ad
...
debug
| Author | SHA1 | Date | |
|---|---|---|---|
| c5d80052e5 | |||
| 38c595fd7b | |||
| b0842aadef | |||
| 0dc5d1ce79 | |||
|
|
941a2b4eaa | ||
|
|
48df6a509d | ||
|
|
ebff6281af | ||
|
|
d7e0990e36 | ||
|
|
21e50bdca8 | ||
|
|
6072a603df | ||
|
|
27ad612844 |
4
RotaxMonitor/.vscode/extensions.json
vendored
4
RotaxMonitor/.vscode/extensions.json
vendored
@@ -1,7 +1,7 @@
|
|||||||
{
|
{
|
||||||
// See http://go.microsoft.com/fwlink/?LinkId=827846
|
|
||||||
// for the documentation about the extensions.json format
|
|
||||||
"recommendations": [
|
"recommendations": [
|
||||||
|
"Jason2866.esp-decoder",
|
||||||
|
"pioarduino.pioarduino-ide",
|
||||||
"platformio.platformio-ide"
|
"platformio.platformio-ide"
|
||||||
],
|
],
|
||||||
"unwantedRecommendations": [
|
"unwantedRecommendations": [
|
||||||
|
|||||||
@@ -11,8 +11,8 @@
|
|||||||
"-DARDUINO_RUNNING_CORE=1",
|
"-DARDUINO_RUNNING_CORE=1",
|
||||||
"-DARDUINO_EVENT_RUNNING_CORE=1",
|
"-DARDUINO_EVENT_RUNNING_CORE=1",
|
||||||
"-DBOARD_HAS_PSRAM",
|
"-DBOARD_HAS_PSRAM",
|
||||||
"-DARDUINO_USB_MODE=1",
|
"-DARDUINO_USB_MODE=0",
|
||||||
"-DARDUINO_USB_CDC_ON_BOOT=0"
|
"-DARDUINO_USB_CDC_ON_BOOT=1"
|
||||||
],
|
],
|
||||||
"f_cpu": "240000000L",
|
"f_cpu": "240000000L",
|
||||||
"f_flash": "80000000L",
|
"f_flash": "80000000L",
|
||||||
|
|||||||
@@ -8,9 +8,9 @@
|
|||||||
; Please visit documentation for the other options and examples
|
; Please visit documentation for the other options and examples
|
||||||
; https://docs.platformio.org/page/projectconf.html
|
; https://docs.platformio.org/page/projectconf.html
|
||||||
|
|
||||||
[env:esp32-s3-n16r8]
|
[env:esp32-s3-devkitc1-n16r8]
|
||||||
board = esp32-s3-n16r8
|
board = esp32-s3-devkitc1-n16r8
|
||||||
platform = https://github.com/pioarduino/platform-espressif32/releases/download/55.03.37/platform-espressif32.zip
|
platform = https://github.com/pioarduino/platform-espressif32/releases/download/stable/platform-espressif32.zip
|
||||||
framework = arduino
|
framework = arduino
|
||||||
lib_deps =
|
lib_deps =
|
||||||
hideakitai/DebugLog@^0.8.4
|
hideakitai/DebugLog@^0.8.4
|
||||||
@@ -18,51 +18,51 @@ 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
|
garfius/Menu-UI@^1.2.0
|
||||||
board_build.partitions = partitions/default_16MB.csv
|
|
||||||
board_build.psram = enabled
|
;Upload protocol configuration
|
||||||
monitor_speed = 115200
|
upload_protocol = esptool
|
||||||
|
upload_port = /dev/ttyACM2
|
||||||
upload_speed = 921600
|
upload_speed = 921600
|
||||||
|
|
||||||
|
;Monitor configuration
|
||||||
|
monitor_speed = 115200
|
||||||
|
monitor_port = /dev/ttyACM2
|
||||||
|
|
||||||
|
; Build configuration
|
||||||
build_type = release
|
build_type = release
|
||||||
|
build_flags =
|
||||||
|
-DARDUINO_USB_CDC_ON_BOOT=0
|
||||||
|
-DARDUINO_USB_MODE=0
|
||||||
|
-fstack-protector-all
|
||||||
|
-DCONFIG_FREERTOS_GENERATE_RUN_TIME_STATS=1
|
||||||
|
-DCONFIG_FREERTOS_USE_TRACE_FACILITY=1
|
||||||
|
|
||||||
[env:esp32-s3-n16r8-debug]
|
[env:esp32-s3-devkitc1-n16r8-debug]
|
||||||
board = ${env:esp32-s3-n16r8.board}
|
board = ${env:esp32-s3-devkitc1-n16r8.board}
|
||||||
platform = ${env:esp32-s3-n16r8.platform}
|
platform = ${env:esp32-s3-devkitc1-n16r8.platform}
|
||||||
framework = ${env:esp32-s3-n16r8.framework}
|
framework = ${env:esp32-s3-devkitc1-n16r8.framework}
|
||||||
lib_deps = ${env:esp32-s3-n16r8.lib_deps}
|
lib_deps = ${env:esp32-s3-devkitc1-n16r8.lib_deps}
|
||||||
board_build.partitions = partitions/default_16MB.csv
|
|
||||||
board_build.psram = enabled
|
;Upload protocol configuration
|
||||||
monitor_speed = 115200
|
upload_protocol = esptool
|
||||||
|
upload_port = /dev/ttyACM2
|
||||||
upload_speed = 921600
|
upload_speed = 921600
|
||||||
build_type = debug
|
|
||||||
build_flags =
|
|
||||||
-O0
|
|
||||||
-g3
|
|
||||||
-ggdb
|
|
||||||
-fno-inline
|
|
||||||
-fno-ipa-sra
|
|
||||||
-fno-tree-sra
|
|
||||||
-fno-builtin
|
|
||||||
|
|
||||||
|
;Monitor configuration
|
||||||
[env:esp32-devtest-debug]
|
|
||||||
board = esp32dev
|
|
||||||
platform = https://github.com/pioarduino/platform-espressif32/releases/download/55.03.37/platform-espressif32.zip
|
|
||||||
framework = arduino
|
|
||||||
lib_deps =
|
|
||||||
hideakitai/DebugLog@^0.8.4
|
|
||||||
bblanchon/ArduinoJson@^7.4.2
|
|
||||||
hideakitai/PCA95x5@^0.1.3
|
|
||||||
adafruit/Adafruit SSD1306@^2.5.16
|
|
||||||
garfius/Menu-UI@^1.2.0
|
|
||||||
board_build.flash_size = 4MB
|
|
||||||
board_build.partitions = default.csv
|
|
||||||
monitor_speed = 115200
|
monitor_speed = 115200
|
||||||
|
monitor_port = /dev/ttyACM2
|
||||||
|
|
||||||
|
; Debug configuration
|
||||||
|
debug_tool = esp-builtin
|
||||||
|
debug_speed = 15000
|
||||||
|
|
||||||
|
; Build configuration
|
||||||
build_type = debug
|
build_type = debug
|
||||||
build_flags =
|
build_flags =
|
||||||
-O0
|
-O0
|
||||||
-g3
|
-g3
|
||||||
-ggdb
|
-ggdb3
|
||||||
-fno-inline
|
-DCORE_DEBUG_LEVEL=5
|
||||||
-fno-ipa-sra
|
-DARDUINO_USB_CDC_ON_BOOT=0
|
||||||
-fno-tree-sra
|
-DARDUINO_USB_MODE=0
|
||||||
-fno-builtin
|
-fstack-protector-all
|
||||||
|
|||||||
@@ -13,37 +13,41 @@ void trig_isr(void *arg)
|
|||||||
return;
|
return;
|
||||||
|
|
||||||
BaseType_t xHigherPriorityTaskWoken = pdFALSE;
|
BaseType_t xHigherPriorityTaskWoken = pdFALSE;
|
||||||
isrParams *params = (isrParams*)arg;
|
isrParams *params = (isrParams *)arg;
|
||||||
ignitionBoxStatus *box = params->ign_stat;
|
ignitionBoxStatus *box = params->ign_stat;
|
||||||
TaskHandle_t task_handle = *params->rt_handle_ptr;
|
TaskHandle_t task_handle = params->rt_handle_ptr;
|
||||||
|
|
||||||
// exit if task not running
|
// exit if task not running
|
||||||
if (!task_handle)
|
if (!task_handle)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
// reset spark flags, cannot be same time as trigger flags
|
|
||||||
box->coils12.spark_ok = false;
|
|
||||||
box->coils34.spark_ok = false;
|
|
||||||
|
|
||||||
switch (params->flag)
|
switch (params->flag)
|
||||||
{
|
{
|
||||||
case TRIG_FLAG_12P:
|
case TRIG_FLAG_12P:
|
||||||
|
case TRIG_FLAG_12N:
|
||||||
|
// only on first trigger to avoid multiple firing due to noise, to be fixed with hardware debounce
|
||||||
box->coils12.trig_time = time_us;
|
box->coils12.trig_time = time_us;
|
||||||
xTaskNotifyFromISR(task_handle, params->flag, eSetValueWithOverwrite, &xHigherPriorityTaskWoken);
|
xTaskNotifyFromISR(task_handle, params->flag, eSetValueWithOverwrite, &xHigherPriorityTaskWoken);
|
||||||
break;
|
break;
|
||||||
case TRIG_FLAG_34P:
|
case TRIG_FLAG_34P:
|
||||||
|
case TRIG_FLAG_34N:
|
||||||
|
// only on first trigger to avoid multiple firing due to noise, to be fixed with hardware debounce
|
||||||
box->coils34.trig_time = time_us;
|
box->coils34.trig_time = time_us;
|
||||||
xTaskNotifyFromISR(task_handle, params->flag, eSetValueWithOverwrite, &xHigherPriorityTaskWoken);
|
xTaskNotifyFromISR(task_handle, params->flag, eSetValueWithOverwrite, &xHigherPriorityTaskWoken);
|
||||||
break;
|
break;
|
||||||
case SPARK_FLAG_12:
|
case SPARK_FLAG_12:
|
||||||
|
box->coils34.spark_ok = false;
|
||||||
box->coils12.spark_ok = true;
|
box->coils12.spark_ok = true;
|
||||||
box->coils12.spark_time = time_us;
|
box->coils12.spark_time = time_us;
|
||||||
vTaskNotifyGiveFromISR(task_handle, &xHigherPriorityTaskWoken);
|
xTaskNotifyFromISR(task_handle, params->flag, eSetValueWithOverwrite, &xHigherPriorityTaskWoken);
|
||||||
|
// vTaskNotifyGiveFromISR(task_handle, &xHigherPriorityTaskWoken);
|
||||||
break;
|
break;
|
||||||
case SPARK_FLAG_34:
|
case SPARK_FLAG_34:
|
||||||
|
box->coils12.spark_ok = false;
|
||||||
box->coils34.spark_ok = true;
|
box->coils34.spark_ok = true;
|
||||||
box->coils34.spark_time = time_us;
|
box->coils34.spark_time = time_us;
|
||||||
vTaskNotifyGiveFromISR(task_handle, &xHigherPriorityTaskWoken);
|
xTaskNotifyFromISR(task_handle, params->flag, eSetValueWithOverwrite, &xHigherPriorityTaskWoken);
|
||||||
|
// vTaskNotifyGiveFromISR(task_handle, &xHigherPriorityTaskWoken);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
|
|||||||
@@ -1,11 +1,12 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
// Test device Flag
|
// Test device Flag
|
||||||
#define TEST
|
// #define TEST
|
||||||
|
|
||||||
// Arduino Libraries
|
// Arduino Libraries
|
||||||
#include <Arduino.h>
|
#include <Arduino.h>
|
||||||
#include "soc/gpio_struct.h"
|
#include "soc/gpio_struct.h"
|
||||||
|
#include <map>
|
||||||
#ifndef TEST
|
#ifndef TEST
|
||||||
#include "pins.h"
|
#include "pins.h"
|
||||||
#else
|
#else
|
||||||
@@ -20,14 +21,15 @@
|
|||||||
// =====================
|
// =====================
|
||||||
// Event Flags (bitmask)
|
// Event Flags (bitmask)
|
||||||
// =====================
|
// =====================
|
||||||
#define TRIG_FLAG_12P (1 << 0)
|
static const uint32_t TRIG_FLAG_12P = (1 << 0);
|
||||||
#define TRIG_FLAG_12N (1 << 2)
|
static const uint32_t TRIG_FLAG_12N = (1 << 1);
|
||||||
#define TRIG_FLAG_34P (1 << 1)
|
static const uint32_t TRIG_FLAG_34P = (1 << 2);
|
||||||
#define TRIG_FLAG_34N (1 << 3)
|
static const uint32_t TRIG_FLAG_34N = (1 << 3);
|
||||||
|
|
||||||
#define SPARK_FLAG_NIL (1 << 8)
|
static const uint32_t SPARK_FLAG_NIL = (1 << 8);
|
||||||
#define SPARK_FLAG_12 (1 << 9)
|
static const uint32_t SPARK_FLAG_12 = (1 << 9);
|
||||||
#define SPARK_FLAG_34 (1 << 10)
|
static const uint32_t SPARK_FLAG_34 = (1 << 10);
|
||||||
|
static const uint32_t SPARK_FLAG_TIMEOUT = (1 << 11);
|
||||||
|
|
||||||
// Spark Status
|
// Spark Status
|
||||||
enum sparkStatus
|
enum sparkStatus
|
||||||
@@ -45,41 +47,65 @@ enum sparkStatus
|
|||||||
SPARK_SYNC_FAIL,
|
SPARK_SYNC_FAIL,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
static const std::map<const sparkStatus, const char *> sparkStatusNames = {
|
||||||
|
{SPARK_POS_OK, "SPARK_POS_OK"},
|
||||||
|
{SPARK_NEG_OK, "SPARK_NEG_OK"},
|
||||||
|
{SPARK_POS_SKIP, "SPARK_POS_SKIP"},
|
||||||
|
{SPARK_NEG_SKIP, "SPARK_NEG_SKIP"},
|
||||||
|
{SPARK_POS_WAIT, "SPARK_POS_WAIT"},
|
||||||
|
{SPARK_NEG_WAIT, "SPARK_NEG_WAIT"},
|
||||||
|
{SPARK_POS_FAIL, "SPARK_POS_FAIL"},
|
||||||
|
{SPARK_NEG_FAIL, "SPARK_NEG_FAIL"},
|
||||||
|
{SPARK_POS_UNEXPECTED, "SPARK_POS_UNEXPECTED"},
|
||||||
|
{SPARK_NEG_UNEXPECTED, "SPARK_NEG_UNEXPECTED"},
|
||||||
|
{SPARK_SYNC_FAIL, "SPARK_SYNC_FAIL"},
|
||||||
|
};
|
||||||
|
|
||||||
enum softStartStatus
|
enum softStartStatus
|
||||||
{
|
{
|
||||||
|
NORMAL,
|
||||||
SOFT_START,
|
SOFT_START,
|
||||||
NORMAL
|
ERROR,
|
||||||
|
};
|
||||||
|
|
||||||
|
const std::map<const softStartStatus, const char *> softStartStatusNames = {
|
||||||
|
{NORMAL, "NORMAL"},
|
||||||
|
{SOFT_START, "SOFT_START"},
|
||||||
|
{ERROR, "ERROR"},
|
||||||
};
|
};
|
||||||
|
|
||||||
struct coilsStatus
|
struct coilsStatus
|
||||||
{
|
{
|
||||||
int64_t trig_time;
|
int64_t trig_time = 0;
|
||||||
int64_t spark_time;
|
int64_t spark_time = 0;
|
||||||
int64_t spark_delay;
|
int64_t spark_delay = 0; // in microseconds
|
||||||
sparkStatus spark_status;
|
sparkStatus spark_status = sparkStatus::SPARK_POS_OK;
|
||||||
softStartStatus sstart_status;
|
softStartStatus sstart_status = softStartStatus::NORMAL;
|
||||||
float peak_p_in, peak_n_in;
|
float peak_p_in = 0.0, peak_n_in = 0.0;
|
||||||
float peak_p_out, peak_n_out;
|
float peak_p_out = 0.0, peak_n_out = 0.0;
|
||||||
float trigger_spark;
|
float trigger_spark = 0.0;
|
||||||
bool spark_ok;
|
bool spark_ok = false;
|
||||||
|
uint32_t n_events = 0;
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
// Task internal Status
|
// Task internal Status
|
||||||
struct ignitionBoxStatus
|
struct ignitionBoxStatus
|
||||||
{
|
{
|
||||||
int64_t timestamp;
|
int64_t timestamp = 0;
|
||||||
// coils pairs for each ignition
|
// coils pairs for each ignition
|
||||||
coilsStatus coils12;
|
coilsStatus coils12;
|
||||||
coilsStatus coils34;
|
coilsStatus coils34;
|
||||||
// voltage from generator
|
// voltage from generator
|
||||||
float volts_gen = 0.0;
|
float volts_gen = 0.0;
|
||||||
|
uint32_t n_queue_errors = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct isrParams {
|
struct isrParams
|
||||||
|
{
|
||||||
const uint32_t flag;
|
const uint32_t flag;
|
||||||
ignitionBoxStatus* ign_stat;
|
ignitionBoxStatus *ign_stat;
|
||||||
TaskHandle_t* rt_handle_ptr;
|
TaskHandle_t rt_handle_ptr;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
void IRAM_ATTR trig_isr(void *arg);
|
void IRAM_ATTR trig_isr(void *arg);
|
||||||
|
|||||||
@@ -10,19 +10,25 @@
|
|||||||
#include <tasks.h>
|
#include <tasks.h>
|
||||||
#include <channels.h>
|
#include <channels.h>
|
||||||
#include <devices.h>
|
#include <devices.h>
|
||||||
|
#include <ui.h>
|
||||||
|
|
||||||
void printTaskList()
|
// FreeRTOS directives
|
||||||
{
|
#include "freertos/FreeRTOS.h"
|
||||||
|
#include "freertos/task.h"
|
||||||
|
|
||||||
|
// #define CH_B_ENABLE
|
||||||
|
#define TEST
|
||||||
|
|
||||||
|
void printTaskStats() {
|
||||||
char buffer[1024];
|
char buffer[1024];
|
||||||
Serial.println("Task Name\tState\tPrio\tStack\tNum");
|
vTaskGetRunTimeStats(buffer);
|
||||||
vTaskList(buffer);
|
|
||||||
Serial.println(buffer);
|
Serial.println(buffer);
|
||||||
}
|
}
|
||||||
|
|
||||||
void setup()
|
void setup()
|
||||||
{
|
{
|
||||||
|
Serial.begin(921600);
|
||||||
delay(250);
|
delay(250);
|
||||||
Serial.begin(115200);
|
|
||||||
|
|
||||||
// Setup Logger
|
// Setup Logger
|
||||||
LOG_ATTACH_SERIAL(Serial);
|
LOG_ATTACH_SERIAL(Serial);
|
||||||
@@ -50,15 +56,15 @@ void loop()
|
|||||||
{
|
{
|
||||||
// global variables
|
// global variables
|
||||||
bool running = true;
|
bool running = true;
|
||||||
Devices dev;
|
static Devices dev;
|
||||||
|
|
||||||
// Task handle
|
// Task handle
|
||||||
TaskHandle_t trigA_TaskHandle = NULL;
|
static TaskHandle_t trigA_TaskHandle = NULL;
|
||||||
TaskHandle_t trigB_TaskHandle = NULL;
|
static TaskHandle_t trigB_TaskHandle = NULL;
|
||||||
|
|
||||||
QueueHandle_t rt_taskA_queue = xQueueCreate(10, sizeof(ignitionBoxStatus));
|
static QueueHandle_t rt_taskA_queue = xQueueCreate(10, sizeof(ignitionBoxStatus));
|
||||||
QueueHandle_t rt_taskB_queue = xQueueCreate(10, sizeof(ignitionBoxStatus));
|
static QueueHandle_t rt_taskB_queue = xQueueCreate(10, sizeof(ignitionBoxStatus));
|
||||||
rtTaskParams taskA_params {
|
static rtTaskParams taskA_params{
|
||||||
.rt_running = true,
|
.rt_running = true,
|
||||||
.dev = &dev,
|
.dev = &dev,
|
||||||
.rt_handle_ptr = &trigA_TaskHandle,
|
.rt_handle_ptr = &trigA_TaskHandle,
|
||||||
@@ -71,19 +77,17 @@ void loop()
|
|||||||
.trig_pin_34n = TRIG_PIN_A34N,
|
.trig_pin_34n = TRIG_PIN_A34N,
|
||||||
.spark_pin_12 = SPARK_PIN_A12,
|
.spark_pin_12 = SPARK_PIN_A12,
|
||||||
.spark_pin_34 = SPARK_PIN_A34},
|
.spark_pin_34 = SPARK_PIN_A34},
|
||||||
.rt_resets = rtTaskResets{
|
.rt_resets = rtTaskResets{.rst_io_12p = RST_EXT_A12P, .rst_io_12n = RST_EXT_A12N, .rst_io_34p = RST_EXT_A34P, .rst_io_34n = RST_EXT_A34N}};
|
||||||
.rst_io_12p = RST_EXT_A12P,
|
|
||||||
.rst_io_12n = RST_EXT_A12N,
|
LOG_INFO("Task Variables OK");
|
||||||
.rst_io_34p = RST_EXT_A34P,
|
|
||||||
.rst_io_34n = RST_EXT_A34N}
|
#ifdef CH_B_ENABLE
|
||||||
};
|
|
||||||
#ifndef TEST
|
|
||||||
QueueHandle_t rt_taskB_queue = xQueueCreate(10, sizeof(ignitionBoxStatus));
|
QueueHandle_t rt_taskB_queue = xQueueCreate(10, sizeof(ignitionBoxStatus));
|
||||||
rtTaskParams taskB_params {
|
rtTaskParams taskB_params{
|
||||||
.rt_running = true,
|
.rt_running = true,
|
||||||
.dev = &dev,
|
.dev = &dev,
|
||||||
.rt_queue = rt_taskB_queue,
|
|
||||||
.rt_handle_ptr = &trigB_TaskHandle,
|
.rt_handle_ptr = &trigB_TaskHandle,
|
||||||
|
.rt_queue = rt_taskB_queue,
|
||||||
.rt_int = rtTaskInterrupts{
|
.rt_int = rtTaskInterrupts{
|
||||||
.isr_ptr = trig_isr,
|
.isr_ptr = trig_isr,
|
||||||
.trig_pin_12p = TRIG_PIN_B12P,
|
.trig_pin_12p = TRIG_PIN_B12P,
|
||||||
@@ -92,24 +96,20 @@ void loop()
|
|||||||
.trig_pin_34n = TRIG_PIN_B34N,
|
.trig_pin_34n = TRIG_PIN_B34N,
|
||||||
.spark_pin_12 = SPARK_PIN_B12,
|
.spark_pin_12 = SPARK_PIN_B12,
|
||||||
.spark_pin_34 = SPARK_PIN_B34},
|
.spark_pin_34 = SPARK_PIN_B34},
|
||||||
.rt_resets = rtTaskResets{
|
.rt_resets = rtTaskResets{.rst_io_12p = RST_EXT_B12P, .rst_io_12n = RST_EXT_B12N, .rst_io_34p = RST_EXT_B34P, .rst_io_34n = RST_EXT_B34N}};
|
||||||
.rst_io_12p = RST_EXT_B12P,
|
|
||||||
.rst_io_12n = RST_EXT_B12N,
|
|
||||||
.rst_io_34p = RST_EXT_B34P,
|
|
||||||
.rst_io_34n = RST_EXT_B34N}
|
|
||||||
};
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// Init 2 SPI interfaces
|
|
||||||
bool spiA_ok = true;
|
bool spiA_ok = true;
|
||||||
|
bool spiB_ok = true;
|
||||||
|
|
||||||
|
#ifndef TEST
|
||||||
|
// Init 2 SPI interfaces
|
||||||
SPIClass SPI_A(FSPI);
|
SPIClass SPI_A(FSPI);
|
||||||
spiA_ok = SPI_A.begin(SPI_A_SCK, SPI_A_MISO, SPI_A_MOSI);
|
spiA_ok = SPI_A.begin(SPI_A_SCK, SPI_A_MISO, SPI_A_MOSI);
|
||||||
|
|
||||||
bool spiB_ok = true;
|
|
||||||
#ifndef TEST
|
|
||||||
SPIClass SPI_B(HSPI);
|
SPIClass SPI_B(HSPI);
|
||||||
spiB_ok = SPI_B.begin(SPI_B_SCK, SPI_B_MISO, SPI_B_MOSI);
|
spiB_ok = SPI_B.begin(SPI_B_SCK, SPI_B_MISO, SPI_B_MOSI);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (!spiA_ok || !spiB_ok)
|
if (!spiA_ok || !spiB_ok)
|
||||||
{
|
{
|
||||||
LOG_ERROR("Unable to Initialize SPI Busses");
|
LOG_ERROR("Unable to Initialize SPI Busses");
|
||||||
@@ -117,23 +117,23 @@ void loop()
|
|||||||
vTaskDelay(pdMS_TO_TICKS(5000));
|
vTaskDelay(pdMS_TO_TICKS(5000));
|
||||||
esp_restart();
|
esp_restart();
|
||||||
}
|
}
|
||||||
LOG_INFO("Init SPI [OK]");
|
LOG_INFO("Init SPI OK");
|
||||||
|
|
||||||
|
#ifndef TEST
|
||||||
// Init ADC_A
|
// Init ADC_A
|
||||||
dev.adc_a = new ADS1256(ADC_A_DRDY, ADC_A_RST, ADC_A_SYNC, ADC_A_CS, 2.5, &SPI_A);
|
dev.adc_a = new ADS1256(ADC_A_DRDY, ADC_A_RST, ADC_A_SYNC, ADC_A_CS, 2.5, &SPI_A);
|
||||||
dev.adc_a->InitializeADC();
|
dev.adc_a->InitializeADC();
|
||||||
dev.adc_a->setPGA(PGA_1);
|
dev.adc_a->setPGA(PGA_1);
|
||||||
dev.adc_a->setDRATE(DRATE_1000SPS);
|
dev.adc_a->setDRATE(DRATE_1000SPS);
|
||||||
|
|
||||||
#ifndef TEST
|
|
||||||
// Init ADC_B
|
// Init ADC_B
|
||||||
dev.adc_a = new ADS1256(ADC_B_DRDY, ADC_B_RST, ADC_B_SYNC, ADC_B_CS, 2.5, &SPI_B);
|
dev.adc_a = new ADS1256(ADC_B_DRDY, ADC_B_RST, ADC_B_SYNC, ADC_B_CS, 2.5, &SPI_B);
|
||||||
dev.adc_a->InitializeADC();
|
dev.adc_a->InitializeADC();
|
||||||
dev.adc_a->setPGA(PGA_1);
|
dev.adc_a->setPGA(PGA_1);
|
||||||
dev.adc_a->setDRATE(DRATE_1000SPS);
|
dev.adc_a->setDRATE(DRATE_1000SPS);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
LOG_INFO("Init ADC [OK]");
|
LOG_INFO("Init ADC OK");
|
||||||
|
|
||||||
// Ignition A on Core 0
|
// Ignition A on Core 0
|
||||||
auto ignA_task_success = pdPASS;
|
auto ignA_task_success = pdPASS;
|
||||||
@@ -148,10 +148,10 @@ void loop()
|
|||||||
|
|
||||||
// Ignition B on Core 1
|
// Ignition B on Core 1
|
||||||
auto ignB_task_success = pdPASS;
|
auto ignB_task_success = pdPASS;
|
||||||
#ifndef TEST
|
#ifdef CH_B_ENABLE
|
||||||
ignB_task_success = xTaskCreatePinnedToCore(
|
ignB_task_success = xTaskCreatePinnedToCore(
|
||||||
rtIgnitionTask,
|
rtIgnitionTask,
|
||||||
"rtIgnitionTask_boxA",
|
"rtIgnitionTask_boxB",
|
||||||
TASK_STACK,
|
TASK_STACK,
|
||||||
(void *)&taskB_params,
|
(void *)&taskB_params,
|
||||||
TASK_PRIORITY, // priorità leggermente più alta
|
TASK_PRIORITY, // priorità leggermente più alta
|
||||||
@@ -170,11 +170,58 @@ void loop()
|
|||||||
LOG_INFO("Real Time Tasks A & B initialized");
|
LOG_INFO("Real Time Tasks A & B initialized");
|
||||||
|
|
||||||
////////////////////// MAIN LOOP //////////////////////
|
////////////////////// MAIN LOOP //////////////////////
|
||||||
uint32_t count(0);
|
clearScreen();
|
||||||
|
setCursor(0, 0);
|
||||||
|
ignitionBoxStatus ignA;
|
||||||
|
int64_t last = esp_timer_get_time();
|
||||||
|
uint32_t missed_firings12 = 0;
|
||||||
|
uint32_t missed_firings34 = 0;
|
||||||
|
uint32_t counter = 0;
|
||||||
|
|
||||||
while (running)
|
while (running)
|
||||||
{
|
{
|
||||||
// printTaskList();
|
if (xQueueReceive(rt_taskA_queue, &ignA, pdMS_TO_TICKS(1000)) == pdTRUE)
|
||||||
delay(10000);
|
{
|
||||||
|
if (ignA.coils12.spark_status == sparkStatus::SPARK_NEG_FAIL || ignA.coils12.spark_status == sparkStatus::SPARK_POS_FAIL)
|
||||||
|
missed_firings12++;
|
||||||
|
if (ignA.coils34.spark_status == sparkStatus::SPARK_POS_FAIL || ignA.coils34.spark_status == sparkStatus::SPARK_NEG_FAIL)
|
||||||
|
missed_firings34++;
|
||||||
|
clearScreen();
|
||||||
|
setCursor(0, 0);
|
||||||
|
printField("++ Timestamp", (uint32_t)ignA.timestamp, 0, 0);
|
||||||
|
Serial.println("========== Coils 12 =============");
|
||||||
|
printField("Events", (uint32_t)ignA.coils12.n_events, 0, 1);
|
||||||
|
printField("Missed Firing", missed_firings12, 0, 2);
|
||||||
|
printField("Spark Dly", (uint32_t)ignA.coils12.spark_delay, 0, 3);
|
||||||
|
printField("Spark Sts", sparkStatusNames.at(ignA.coils12.spark_status), 0, 4);
|
||||||
|
// printField("Peak P_IN", ignA.coils12.peak_p_in, 0, 5);
|
||||||
|
// printField("Peak P_OUT", ignA.coils12.peak_p_out, 0, 6);
|
||||||
|
// printField("Peak N_IN", ignA.coils12.peak_n_in, 0, 7);
|
||||||
|
// printField("Peak N_OUT", ignA.coils12.peak_n_out, 0, 8);
|
||||||
|
printField("Soft Start ", softStartStatusNames.at(ignA.coils12.sstart_status), 0, 9);
|
||||||
|
|
||||||
|
Serial.println("========== Coils 34 =============");
|
||||||
|
printField("Events", (uint32_t)ignA.coils34.n_events, 0, 11);
|
||||||
|
printField("Missed Firing", missed_firings34, 0, 12);
|
||||||
|
printField("Spark Dly", (uint32_t)ignA.coils34.spark_delay, 0, 13);
|
||||||
|
printField("Spark Sts", sparkStatusNames.at(ignA.coils34.spark_status), 0, 14);
|
||||||
|
// printField("Peak P_IN", ignA.coils34.peak_p_in, 0, 15);
|
||||||
|
// printField("Peak P_OUT", ignA.coils34.peak_p_out, 0, 16);
|
||||||
|
// printField("Peak N_IN", ignA.coils34.peak_n_in, 0, 17);
|
||||||
|
// printField("Peak N_OUT", ignA.coils34.peak_n_out, 0, 18);
|
||||||
|
printField("Soft Start ", softStartStatusNames.at(ignA.coils34.sstart_status), 0, 19);
|
||||||
|
|
||||||
|
Serial.println("========== END =============");
|
||||||
|
Serial.println();
|
||||||
|
auto delta = (esp_timer_get_time() - last) / 1000000.0f; //in seconds
|
||||||
|
delta = delta > 0 ? 1.0f / delta : 0; // Calculate frequency (Hz)
|
||||||
|
printField("Frequency (Hz)", delta, 0, 21);
|
||||||
|
printField("Queue Errors", (uint32_t)ignA.n_queue_errors, 0, 22);
|
||||||
|
last = esp_timer_get_time();
|
||||||
|
} else
|
||||||
|
{
|
||||||
|
Serial.println("Waiting for data... ");;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (trigA_TaskHandle)
|
if (trigA_TaskHandle)
|
||||||
|
|||||||
@@ -59,16 +59,16 @@
|
|||||||
// =====================
|
// =====================
|
||||||
// DIGITAL POT
|
// DIGITAL POT
|
||||||
// =====================
|
// =====================
|
||||||
#define POT_A_CS 1
|
//#define POT_A_CS 1
|
||||||
#define POT_B_CS 2
|
//#define POT_B_CS 2
|
||||||
|
|
||||||
// =====================
|
// =====================
|
||||||
// TRIGGER INPUT INTERRUPTS
|
// TRIGGER INPUT INTERRUPTS
|
||||||
// =====================
|
// =====================
|
||||||
#define TRIG_PIN_A12P 18
|
#define TRIG_PIN_A12P 18
|
||||||
#define TRIG_PIN_A12N 21
|
#define TRIG_PIN_A12N 21
|
||||||
#define TRIG_PIN_A34P 33
|
#define TRIG_PIN_A34P 1
|
||||||
#define TRIG_PIN_A34N 34
|
#define TRIG_PIN_A34N 2
|
||||||
#define TRIG_PIN_B12P 38
|
#define TRIG_PIN_B12P 38
|
||||||
#define TRIG_PIN_B12N 39
|
#define TRIG_PIN_B12N 39
|
||||||
#define TRIG_PIN_B34P 40
|
#define TRIG_PIN_B34P 40
|
||||||
@@ -78,8 +78,8 @@
|
|||||||
// SPARK DETECT INPUTS
|
// SPARK DETECT INPUTS
|
||||||
// =====================
|
// =====================
|
||||||
#define SPARK_PIN_A12 42
|
#define SPARK_PIN_A12 42
|
||||||
#define SPARK_PIN_A34 45 // OK (strapping ma consentito)
|
#define SPARK_PIN_A34 45 // OK (strapping ma consentito) 45
|
||||||
#define SPARK_PIN_B12 46 // OK (strapping ma consentito)
|
#define SPARK_PIN_B12 46 // OK (strapping ma consentito) 46
|
||||||
#define SPARK_PIN_B34 47
|
#define SPARK_PIN_B34 47
|
||||||
|
|
||||||
// =====================
|
// =====================
|
||||||
|
|||||||
@@ -1,4 +1,11 @@
|
|||||||
#include "tasks.h"
|
#include "tasks.h"
|
||||||
|
#include <esp_timer.h>
|
||||||
|
|
||||||
|
// Timeout callback for microsecond precision
|
||||||
|
void spark_timeout_callback(void* arg) {
|
||||||
|
TaskHandle_t handle = (TaskHandle_t)arg;
|
||||||
|
xTaskNotify(handle, SPARK_FLAG_TIMEOUT, eSetValueWithOverwrite);
|
||||||
|
}
|
||||||
|
|
||||||
void rtIgnitionTask(void *pvParameters)
|
void rtIgnitionTask(void *pvParameters)
|
||||||
{
|
{
|
||||||
@@ -9,19 +16,21 @@ void rtIgnitionTask(void *pvParameters)
|
|||||||
LOG_ERROR("Null rt_task_ptr parameters");
|
LOG_ERROR("Null rt_task_ptr parameters");
|
||||||
vTaskDelete(NULL);
|
vTaskDelete(NULL);
|
||||||
}
|
}
|
||||||
|
LOG_INFO("rtTask Params OK");
|
||||||
|
|
||||||
// Task Parameters and Devices
|
// Task Parameters and Devices
|
||||||
rtTaskParams *params = (rtTaskParams *)pvParameters;
|
rtTaskParams *params = (rtTaskParams *)pvParameters;
|
||||||
const rtTaskInterrupts rt_int = params->rt_int; // copy to avoid external override
|
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 rtTaskResets rt_rst = params->rt_resets; // copy to avoid external override
|
||||||
QueueHandle_t rt_queue = params->rt_queue;
|
QueueHandle_t rt_queue = params->rt_queue;
|
||||||
TaskHandle_t* rt_handle_ptr = params->rt_handle_ptr;
|
TaskHandle_t rt_handle_ptr = *params->rt_handle_ptr;
|
||||||
Devices *dev = params->dev;
|
Devices *dev = params->dev;
|
||||||
ADS1256 *adc = dev->adc_a;
|
ADS1256 *adc = dev->adc_a;
|
||||||
PCA9555 *io = dev->io;
|
PCA9555 *io = dev->io;
|
||||||
|
|
||||||
|
ignitionBoxStatus ign_box_sts;
|
||||||
|
|
||||||
// Variables for ISR, static to be fixed in memory locations
|
// Variables for ISR, static to be fixed in memory locations
|
||||||
static ignitionBoxStatus ign_box_sts; // common for all ISR calls
|
|
||||||
static isrParams isr_params_t12p{
|
static isrParams isr_params_t12p{
|
||||||
.flag = TRIG_FLAG_12P,
|
.flag = TRIG_FLAG_12P,
|
||||||
.ign_stat = &ign_box_sts,
|
.ign_stat = &ign_box_sts,
|
||||||
@@ -47,13 +56,27 @@ void rtIgnitionTask(void *pvParameters)
|
|||||||
.ign_stat = &ign_box_sts,
|
.ign_stat = &ign_box_sts,
|
||||||
.rt_handle_ptr = rt_handle_ptr};
|
.rt_handle_ptr = rt_handle_ptr};
|
||||||
|
|
||||||
|
LOG_INFO("rtTask ISR Params OK");
|
||||||
|
|
||||||
|
// Create esp_timer for microsecond precision timeout
|
||||||
|
esp_timer_handle_t timeout_timer;
|
||||||
|
esp_timer_create_args_t timer_args = {
|
||||||
|
.callback = spark_timeout_callback,
|
||||||
|
.arg = (void*)rt_handle_ptr,
|
||||||
|
.dispatch_method = ESP_TIMER_TASK,
|
||||||
|
.name = "spark_timeout"
|
||||||
|
};
|
||||||
|
esp_timer_create(&timer_args, &timeout_timer);
|
||||||
|
|
||||||
// Attach Pin Interrupts
|
// Attach Pin Interrupts
|
||||||
attachInterruptArg(rt_int.trig_pin_12p, rt_int.isr_ptr, (void *)&isr_params_t12p, RISING);
|
attachInterruptArg(digitalPinToInterrupt(rt_int.trig_pin_12p), rt_int.isr_ptr, (void *)&isr_params_t12p, RISING);
|
||||||
attachInterruptArg(rt_int.trig_pin_12n, rt_int.isr_ptr, (void *)&isr_params_t12n, RISING);
|
attachInterruptArg(digitalPinToInterrupt(rt_int.trig_pin_12n), rt_int.isr_ptr, (void *)&isr_params_t12n, RISING);
|
||||||
attachInterruptArg(rt_int.trig_pin_34p, rt_int.isr_ptr, (void *)&isr_params_t34p, RISING);
|
attachInterruptArg(digitalPinToInterrupt(rt_int.trig_pin_34p), rt_int.isr_ptr, (void *)&isr_params_t34p, RISING);
|
||||||
attachInterruptArg(rt_int.trig_pin_34n, rt_int.isr_ptr, (void *)&isr_params_t34n, RISING);
|
attachInterruptArg(digitalPinToInterrupt(rt_int.trig_pin_34n), rt_int.isr_ptr, (void *)&isr_params_t34n, RISING);
|
||||||
attachInterruptArg(rt_int.spark_pin_12, rt_int.isr_ptr, (void *)&isr_params_sp12, RISING);
|
attachInterruptArg(digitalPinToInterrupt(rt_int.spark_pin_12), rt_int.isr_ptr, (void *)&isr_params_sp12, RISING);
|
||||||
attachInterruptArg(rt_int.spark_pin_34, rt_int.isr_ptr, (void *)&isr_params_sp34, RISING);
|
attachInterruptArg(digitalPinToInterrupt(rt_int.spark_pin_34), rt_int.isr_ptr, (void *)&isr_params_sp34, RISING);
|
||||||
|
|
||||||
|
LOG_INFO("rtTask ISR Attach OK");
|
||||||
|
|
||||||
// Compute Reset Pin Bitmask
|
// Compute Reset Pin Bitmask
|
||||||
const uint16_t rst_bitmask = (1 << rt_rst.rst_io_12p) |
|
const uint16_t rst_bitmask = (1 << rt_rst.rst_io_12p) |
|
||||||
@@ -61,20 +84,17 @@ void rtIgnitionTask(void *pvParameters)
|
|||||||
(1 << rt_rst.rst_io_34p) |
|
(1 << rt_rst.rst_io_34p) |
|
||||||
(1 << rt_rst.rst_io_34n);
|
(1 << rt_rst.rst_io_34n);
|
||||||
|
|
||||||
uint32_t it = 0;
|
LOG_WARN("rtTask Init Correct");
|
||||||
uint32_t q_fail_count = 0;
|
// Global rt_task_ptr variables
|
||||||
|
bool first_cycle = true;
|
||||||
|
bool cycle12 = false;
|
||||||
|
bool cycle34 = false;
|
||||||
|
|
||||||
while (params->rt_running)
|
while (params->rt_running)
|
||||||
{
|
{
|
||||||
// Global rt_task_ptr variables
|
|
||||||
uint32_t pickup_flag = 0;
|
uint32_t pickup_flag = 0;
|
||||||
uint32_t spark_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
|
// WAIT FOR PICKUP SIGNAL
|
||||||
xTaskNotifyWait(
|
xTaskNotifyWait(
|
||||||
0x00, // non pulire all'ingresso
|
0x00, // non pulire all'ingresso
|
||||||
@@ -82,11 +102,20 @@ void rtIgnitionTask(void *pvParameters)
|
|||||||
&pickup_flag, // valore ricevuto
|
&pickup_flag, // valore ricevuto
|
||||||
portMAX_DELAY);
|
portMAX_DELAY);
|
||||||
|
|
||||||
|
if (first_cycle && pickup_flag != TRIG_FLAG_12P) // skip first cycle because of possible initial noise on pickup signals at startu
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
LOG_INFO("Pickup Flags: ", printBits(pickup_flag).c_str());
|
Serial.print("\033[2J"); // clear screen
|
||||||
|
Serial.print("\033[H"); // cursor home
|
||||||
|
LOG_INFO("Iteration [", it++, "]");
|
||||||
|
|
||||||
if (!names.contains(pickup_flag))
|
if (!names.contains(pickup_flag))
|
||||||
{
|
{
|
||||||
LOG_ERROR("Wrong Pickup Flag");
|
LOG_ERROR("Wrong Pickup Flag");
|
||||||
|
LOG_ERROR("Pickup Flags: ", printBits(pickup_flag).c_str());
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@@ -95,27 +124,41 @@ void rtIgnitionTask(void *pvParameters)
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// WAIT FOR SPARK TO HAPPEN
|
// Start microsecond precision timeout timer
|
||||||
auto spark_timeout = ulTaskNotifyTake(pdTRUE, pdMS_TO_TICKS(spark_timeout_max));
|
esp_timer_stop(timeout_timer); // stop timer in case it was running from previous cycle
|
||||||
if (ign_box_sts.coils12.spark_ok || ign_box_sts.coils34.spark_ok) // otherwise timeout if none is set in the ISR
|
esp_timer_start_once(timeout_timer, spark_timeout_max);
|
||||||
spark_flag = ign_box_sts.coils12.spark_ok ? SPARK_FLAG_12 : SPARK_FLAG_34;
|
|
||||||
|
spark_flag = SPARK_FLAG_NIL; // default value in case of timeout, to be set by ISR if spark event occours
|
||||||
|
// WAIT FOR SPARK TO HAPPEN OR TIMEOUT
|
||||||
|
BaseType_t sp = pdFALSE;
|
||||||
|
sp = xTaskNotifyWait(
|
||||||
|
0x00, // non pulire all'ingresso
|
||||||
|
ULONG_MAX, // pulisci i primi 8 bit
|
||||||
|
&spark_flag, // valore ricevuto
|
||||||
|
portMAX_DELAY); // wait indefinitely, timeout handled by esp_timer
|
||||||
|
|
||||||
|
// Handle timeout or spark event
|
||||||
|
if (spark_flag == SPARK_FLAG_TIMEOUT) {
|
||||||
|
spark_flag = SPARK_FLAG_NIL;
|
||||||
|
} else {
|
||||||
|
// Spark occurred, stop the timer
|
||||||
|
esp_timer_stop(timeout_timer);
|
||||||
|
}
|
||||||
|
|
||||||
xTaskNotifyStateClear(NULL);
|
|
||||||
ulTaskNotifyValueClear(NULL, 0xFFFFFFFF);
|
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
LOG_INFO("Spark Flags: ", printBits(spark_flag).c_str());
|
// LOG_INFO("Spark Flags: ", printBits(spark_flag).c_str());
|
||||||
if (!names.contains(spark_flag))
|
LOG_INFO("Spark12:", ign_box_sts.coils12.spark_ok ? "TRUE" : "FALSE");
|
||||||
LOG_ERROR("No Spark");
|
LOG_INFO("Spark34:", ign_box_sts.coils34.spark_ok ? "TRUE" : "FALSE");
|
||||||
else
|
if (names.contains(spark_flag))
|
||||||
LOG_INFO("Spark Trigger:", names.at(spark_flag));
|
LOG_INFO("Spark Trigger:", names.at(spark_flag));
|
||||||
#endif
|
#endif
|
||||||
|
xTaskNotifyStateClear(NULL);
|
||||||
|
ulTaskNotifyValueClear(NULL, 0xFFFFFFFF);
|
||||||
|
|
||||||
// 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_12P || pickup_flag == TRIG_FLAG_12N) && spark_flag != SPARK_FLAG_12)
|
if ((pickup_flag == TRIG_FLAG_12P || pickup_flag == TRIG_FLAG_12N) && (spark_flag != SPARK_FLAG_12 && spark_flag != SPARK_FLAG_NIL))
|
||||||
{
|
{
|
||||||
ign_box_sts.coils12.spark_status = ign_box_sts.coils34.spark_status = sparkStatus::SPARK_SYNC_FAIL;
|
ign_box_sts.coils12.spark_status = ign_box_sts.coils34.spark_status = sparkStatus::SPARK_SYNC_FAIL;
|
||||||
// Save error on circular buffer and skip to next cycle //
|
|
||||||
LOG_ERROR("Spark Mismatch");
|
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -123,6 +166,7 @@ void rtIgnitionTask(void *pvParameters)
|
|||||||
switch (pickup_flag)
|
switch (pickup_flag)
|
||||||
{
|
{
|
||||||
case TRIG_FLAG_12P:
|
case TRIG_FLAG_12P:
|
||||||
|
first_cycle = false;
|
||||||
case TRIG_FLAG_12N:
|
case TRIG_FLAG_12N:
|
||||||
coils = &ign_box_sts.coils12;
|
coils = &ign_box_sts.coils12;
|
||||||
break;
|
break;
|
||||||
@@ -132,73 +176,80 @@ void rtIgnitionTask(void *pvParameters)
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool new_data = false;
|
|
||||||
switch (pickup_flag)
|
switch (pickup_flag)
|
||||||
{
|
{
|
||||||
// CASES for NEGATIVE cycle triggering of pickup and sparks 12 & 34
|
|
||||||
case TRIG_FLAG_12P:
|
case TRIG_FLAG_12P:
|
||||||
case TRIG_FLAG_34P:
|
case TRIG_FLAG_34P:
|
||||||
{
|
{
|
||||||
// Timeout not occourred, expected POSITIVE edge spark OCCOURRED
|
// Timeout not occourred, expected POSITIVE edge spark OCCOURRED
|
||||||
if (spark_timeout == pdPASS)
|
if (spark_flag != SPARK_FLAG_NIL)
|
||||||
{
|
{
|
||||||
coils->spark_delay = coils->spark_time - coils->trig_time;
|
coils->spark_delay = coils->spark_time - coils->trig_time;
|
||||||
coils->sstart_status = softStartStatus::NORMAL; // because spark on positive edge
|
coils->sstart_status = softStartStatus::NORMAL; // because spark on positive edge
|
||||||
coils->spark_status = sparkStatus::SPARK_POS_OK; // do not wait for spark on negative edge
|
coils->spark_status = sparkStatus::SPARK_POS_OK; // do not wait for spark on negative edge
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
LOG_INFO("Trigger Spark POSITIVE");
|
LOG_INFO("Spark on POSITIVE pulse");
|
||||||
LOG_INFO("Spark12 Delay Timer: ", (int)coils->spark_delay);
|
LOG_INFO("Spark Delay Time: ", (int32_t)coils->spark_delay);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
// Timeout occourred, expected POSITIVE edge spark NOT OCCOURRED
|
// Timeout occourred, expected POSITIVE edge spark NOT OCCOURRED
|
||||||
else if (spark_timeout == pdFAIL)
|
else if (spark_flag == SPARK_FLAG_NIL)
|
||||||
{
|
{
|
||||||
coils->spark_status = sparkStatus::SPARK_NEG_WAIT;
|
coils->spark_status = sparkStatus::SPARK_NEG_WAIT;
|
||||||
coils->sstart_status = softStartStatus::NORMAL;
|
coils->sstart_status = softStartStatus::NORMAL;
|
||||||
}
|
}
|
||||||
new_data = false;
|
continue; // Do nothing more on positive pulse
|
||||||
break; // Do nothing more on positive pulse
|
|
||||||
}
|
}
|
||||||
// CASES for NEGATIVE cycle triggering of pickup and sparks 12 & 34
|
// CASES for NEGATIVE cycle triggering of pickup and sparks 12 & 34
|
||||||
case TRIG_FLAG_12N:
|
case TRIG_FLAG_12N:
|
||||||
case TRIG_FLAG_34N:
|
case TRIG_FLAG_34N:
|
||||||
{
|
{
|
||||||
const bool expected_negative12 = coils->spark_status == sparkStatus::SPARK_NEG_WAIT;
|
const bool expected_negative = coils->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_flag != SPARK_FLAG_NIL && expected_negative)
|
||||||
{
|
{
|
||||||
coils->spark_delay = coils->spark_time - coils->trig_time;
|
coils->spark_delay = coils->spark_time - coils->trig_time;
|
||||||
coils->sstart_status = softStartStatus::SOFT_START;
|
coils->sstart_status = softStartStatus::SOFT_START;
|
||||||
coils->spark_status == sparkStatus::SPARK_NEG_OK;
|
coils->spark_status = sparkStatus::SPARK_NEG_OK;
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
LOG_INFO("Trigger Spark NEGATIVE");
|
LOG_INFO("Spark on NEGATIVE pulse");
|
||||||
LOG_INFO("Spark12 Delay Timer: ", (int)ign_box_sts.coils12.spark_delay);
|
LOG_INFO("Spark Delay Time: ", (int32_t)coils->spark_delay);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
// 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_flag == SPARK_FLAG_NIL && expected_negative)
|
||||||
{
|
{
|
||||||
coils->sstart_status = softStartStatus::NORMAL;
|
coils->sstart_status = softStartStatus::ERROR;
|
||||||
coils->spark_status = sparkStatus::SPARK_NEG_FAIL;
|
coils->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_flag != SPARK_FLAG_NIL && !expected_negative)
|
||||||
{
|
{
|
||||||
coils->sstart_status = softStartStatus::SOFT_START;
|
coils->sstart_status = softStartStatus::SOFT_START;
|
||||||
coils->spark_status = sparkStatus::SPARK_NEG_UNEXPECTED;
|
coils->spark_status = sparkStatus::SPARK_NEG_UNEXPECTED;
|
||||||
}
|
}
|
||||||
// Wait for finish of negative pulse to save data to buffer
|
// Wait for finish of negative pulse to save data to buffer
|
||||||
new_data = true;
|
coils->n_events++;
|
||||||
|
if (pickup_flag == TRIG_FLAG_12N)
|
||||||
|
cycle12 = true;
|
||||||
|
else
|
||||||
|
cycle34 = true;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
default:
|
default:
|
||||||
|
#ifdef DEUG
|
||||||
LOG_ERROR("Invalid Interrupt");
|
LOG_ERROR("Invalid Interrupt");
|
||||||
|
LOG_ERROR("Pickup Flags: ", printBits(pickup_flag).c_str());
|
||||||
|
LOG_ERROR("Spark Flags: ", printBits(spark_flag).c_str());
|
||||||
|
#endif
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (new_data)
|
if (cycle12 && cycle34) // wait for both 12 and 34 cycles to complete before sending data to main loop and resetting peak detectors
|
||||||
{
|
{
|
||||||
vTaskDelay(pdMS_TO_TICKS(1)); // delay 1ms to allow peak detectors to charge for negative cycle
|
cycle12 = false;
|
||||||
|
cycle34 = false;
|
||||||
|
// vTaskDelay(pdMS_TO_TICKS(1)); // delay 1ms to allow peak detectors to charge for negative cycle
|
||||||
// read adc channels: pickup12, out12 [ pos + neg ]
|
// read adc channels: pickup12, out12 [ pos + neg ]
|
||||||
if (adc) // read only if adc initialized
|
if (adc) // read only if adc initialized
|
||||||
{
|
{
|
||||||
@@ -213,7 +264,7 @@ void rtIgnitionTask(void *pvParameters)
|
|||||||
ign_box_sts.coils34.peak_n_out = adcReadChannel(adc, ADC_CH_PEAK_34N_OUT);
|
ign_box_sts.coils34.peak_n_out = adcReadChannel(adc, ADC_CH_PEAK_34N_OUT);
|
||||||
}
|
}
|
||||||
else // simulate adc read timig
|
else // simulate adc read timig
|
||||||
vTaskDelay(pdMS_TO_TICKS(6));
|
vTaskDelay(pdMS_TO_TICKS(1));
|
||||||
|
|
||||||
// reset peak detectors + sample and hold
|
// reset peak detectors + sample and hold
|
||||||
// outputs on io expander
|
// outputs on io expander
|
||||||
@@ -225,18 +276,20 @@ void rtIgnitionTask(void *pvParameters)
|
|||||||
io->write(iostat & ~rst_bitmask);
|
io->write(iostat & ~rst_bitmask);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
vTaskDelay(pdMS_TO_TICKS(2));
|
vTaskDelay(pdMS_TO_TICKS(1));
|
||||||
|
|
||||||
// send essage to main loop with ignition info, by copy so local static variable is ok
|
// send essage to main loop with ignition info, by copy so local static variable is ok
|
||||||
if (rt_queue)
|
if (rt_queue)
|
||||||
ign_box_sts.timestamp = esp_timer_get_time(); // update data timestamp
|
ign_box_sts.timestamp = esp_timer_get_time(); // update data timestamp
|
||||||
if (xQueueSendToBack(rt_queue, (void *)&ign_box_sts, pdMS_TO_TICKS(1)) != pdPASS)
|
if (xQueueSendToBack(rt_queue, (void *)&ign_box_sts, 0) != pdPASS)
|
||||||
{
|
{
|
||||||
q_fail_count++;
|
ign_box_sts.n_queue_errors++;
|
||||||
LOG_ERROR("Failed to send to rt_queue");
|
LOG_ERROR("Failed to send to rt_queue");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
// Delete the timeout timer
|
||||||
|
esp_timer_delete(timeout_timer);
|
||||||
LOG_WARN("Ending realTime Task");
|
LOG_WARN("Ending realTime Task");
|
||||||
// Ignition A Interrupts DETACH
|
// Ignition A Interrupts DETACH
|
||||||
detachInterrupt(rt_int.trig_pin_12p);
|
detachInterrupt(rt_int.trig_pin_12p);
|
||||||
|
|||||||
@@ -2,14 +2,12 @@
|
|||||||
#define DEBUGLOG_DEFAULT_LOG_LEVEL_DEBUG
|
#define DEBUGLOG_DEFAULT_LOG_LEVEL_DEBUG
|
||||||
|
|
||||||
// Serial debug flag
|
// Serial debug flag
|
||||||
// #define DEBUG
|
//#define DEBUG
|
||||||
|
|
||||||
// Arduino Libraries
|
// Arduino Libraries
|
||||||
#include <Arduino.h>
|
#include <Arduino.h>
|
||||||
#include <DebugLog.h>
|
#include <DebugLog.h>
|
||||||
#ifdef DEBUG
|
|
||||||
#include "utils.h"
|
#include "utils.h"
|
||||||
#endif
|
|
||||||
|
|
||||||
// ISR
|
// ISR
|
||||||
#include "isr.h"
|
#include "isr.h"
|
||||||
@@ -18,17 +16,18 @@
|
|||||||
#include "devices.h"
|
#include "devices.h"
|
||||||
|
|
||||||
// Global Variables and Flags
|
// Global Variables and Flags
|
||||||
const uint8_t spark_timeout_max = 2; // in milliseconds
|
const uint32_t spark_timeout_max = 500; // in microseconds
|
||||||
|
|
||||||
// Debug Variables
|
// Debug Variables
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
static const std::map<const uint32_t, const char *> names = {
|
static const std::map<const uint32_t, const char *> names = {
|
||||||
{TRIG_FLAG_A12P, "TRIG_FLAG_A12P"},
|
{TRIG_FLAG_12P, "TRIG_FLAG_12P"},
|
||||||
{TRIG_FLAG_A12N, "TRIG_FLAG_A12N"},
|
{TRIG_FLAG_12N, "TRIG_FLAG_12N"},
|
||||||
{TRIG_FLAG_A34P, "TRIG_FLAG_A34P"},
|
{TRIG_FLAG_34P, "TRIG_FLAG_34P"},
|
||||||
{TRIG_FLAG_A34N, "TRIG_FLAG_A34N"},
|
{TRIG_FLAG_34N, "TRIG_FLAG_34N"},
|
||||||
{SPARK_FLAG_A12, "SPARK_FLAG_A12"},
|
{SPARK_FLAG_12, "SPARK_FLAG_12"},
|
||||||
{SPARK_FLAG_A34, "SPARK_FLAG_A34"},
|
{SPARK_FLAG_34, "SPARK_FLAG_34"},
|
||||||
|
{SPARK_FLAG_TIMEOUT, "SPARK_FLAG_TIMEOUT"},
|
||||||
};
|
};
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|||||||
59
RotaxMonitor/src/ui.h
Normal file
59
RotaxMonitor/src/ui.h
Normal file
@@ -0,0 +1,59 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <Arduino.h>
|
||||||
|
|
||||||
|
static bool firstRun = true;
|
||||||
|
|
||||||
|
void clearScreen(){
|
||||||
|
Serial.print("\033[2J"); // clear screen
|
||||||
|
Serial.print("\033[H"); // cursor home
|
||||||
|
Serial.flush();
|
||||||
|
}
|
||||||
|
|
||||||
|
void setCursor(const uint8_t x, const uint8_t y) {
|
||||||
|
Serial.printf("\033[%d;%d", y, x+1);
|
||||||
|
Serial.flush();
|
||||||
|
}
|
||||||
|
|
||||||
|
void printField(const char name[], const uint32_t val, const uint8_t x, const uint8_t y) {
|
||||||
|
if (firstRun) {
|
||||||
|
setCursor(x,y);
|
||||||
|
Serial.printf("%15s: %06d\n", name, val);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
setCursor(x+16, y);
|
||||||
|
Serial.print(val);
|
||||||
|
}
|
||||||
|
|
||||||
|
void printField(const char name[], const int64_t val, const uint8_t x, const uint8_t y) {
|
||||||
|
if (firstRun) {
|
||||||
|
setCursor(x,y);
|
||||||
|
Serial.printf("%15s: %06u\n", name, (uint64_t)val);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
setCursor(x+16, y);
|
||||||
|
Serial.print((uint64_t)val);
|
||||||
|
Serial.flush();
|
||||||
|
}
|
||||||
|
|
||||||
|
void printField(const char name[], const float val, const uint8_t x, const uint8_t y) {
|
||||||
|
if (firstRun) {
|
||||||
|
setCursor(x,y);
|
||||||
|
Serial.printf("%15s: %4.2f\n", name, val);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
setCursor(x+16, y);
|
||||||
|
Serial.print(val);
|
||||||
|
Serial.flush();
|
||||||
|
}
|
||||||
|
|
||||||
|
void printField(const char name[], const char *val, const uint8_t x, const uint8_t y) {
|
||||||
|
if (firstRun) {
|
||||||
|
setCursor(x,y);
|
||||||
|
Serial.printf("%15s: %s\n", name, val);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
setCursor(x+16, y);
|
||||||
|
Serial.print(val);
|
||||||
|
Serial.flush();
|
||||||
|
}
|
||||||
14
RotaxMonitor/src/utils.cpp
Normal file
14
RotaxMonitor/src/utils.cpp
Normal file
@@ -0,0 +1,14 @@
|
|||||||
|
#include "utils.h"
|
||||||
|
|
||||||
|
std::string printBits(uint32_t value) {
|
||||||
|
std::string result;
|
||||||
|
for (int i = 31; i >= 0; i--) {
|
||||||
|
// ottieni il singolo bit
|
||||||
|
result += ((value >> i) & 1) ? '1' : '0';
|
||||||
|
// aggiungi uno spazio ogni 8 bit, tranne dopo l'ultimo
|
||||||
|
if (i % 8 == 0 && i != 0) {
|
||||||
|
result += ' ';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
@@ -3,15 +3,4 @@
|
|||||||
#include <Arduino.h>
|
#include <Arduino.h>
|
||||||
#include <string>
|
#include <string>
|
||||||
|
|
||||||
std::string printBits(uint32_t value) {
|
std::string printBits(uint32_t value);
|
||||||
std::string result;
|
|
||||||
for (int i = 31; i >= 0; i--) {
|
|
||||||
// ottieni il singolo bit
|
|
||||||
result += ((value >> i) & 1) ? '1' : '0';
|
|
||||||
// aggiungi uno spazio ogni 8 bit, tranne dopo l'ultimo
|
|
||||||
if (i % 8 == 0 && i != 0) {
|
|
||||||
result += ' ';
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|||||||
5
RotaxMonitorTester/.gitignore
vendored
Normal file
5
RotaxMonitorTester/.gitignore
vendored
Normal file
@@ -0,0 +1,5 @@
|
|||||||
|
.pio
|
||||||
|
.vscode/.browse.c_cpp.db*
|
||||||
|
.vscode/c_cpp_properties.json
|
||||||
|
.vscode/launch.json
|
||||||
|
.vscode/ipch
|
||||||
10
RotaxMonitorTester/.vscode/extensions.json
vendored
Normal file
10
RotaxMonitorTester/.vscode/extensions.json
vendored
Normal file
@@ -0,0 +1,10 @@
|
|||||||
|
{
|
||||||
|
"recommendations": [
|
||||||
|
"Jason2866.esp-decoder",
|
||||||
|
"pioarduino.pioarduino-ide",
|
||||||
|
"platformio.platformio-ide"
|
||||||
|
],
|
||||||
|
"unwantedRecommendations": [
|
||||||
|
"ms-vscode.cpptools-extension-pack"
|
||||||
|
]
|
||||||
|
}
|
||||||
37
RotaxMonitorTester/include/README
Normal file
37
RotaxMonitorTester/include/README
Normal file
@@ -0,0 +1,37 @@
|
|||||||
|
|
||||||
|
This directory is intended for project header files.
|
||||||
|
|
||||||
|
A header file is a file containing C declarations and macro definitions
|
||||||
|
to be shared between several project source files. You request the use of a
|
||||||
|
header file in your project source file (C, C++, etc) located in `src` folder
|
||||||
|
by including it, with the C preprocessing directive `#include'.
|
||||||
|
|
||||||
|
```src/main.c
|
||||||
|
|
||||||
|
#include "header.h"
|
||||||
|
|
||||||
|
int main (void)
|
||||||
|
{
|
||||||
|
...
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
Including a header file produces the same results as copying the header file
|
||||||
|
into each source file that needs it. Such copying would be time-consuming
|
||||||
|
and error-prone. With a header file, the related declarations appear
|
||||||
|
in only one place. If they need to be changed, they can be changed in one
|
||||||
|
place, and programs that include the header file will automatically use the
|
||||||
|
new version when next recompiled. The header file eliminates the labor of
|
||||||
|
finding and changing all the copies as well as the risk that a failure to
|
||||||
|
find one copy will result in inconsistencies within a program.
|
||||||
|
|
||||||
|
In C, the convention is to give header files names that end with `.h'.
|
||||||
|
|
||||||
|
Read more about using header files in official GCC documentation:
|
||||||
|
|
||||||
|
* Include Syntax
|
||||||
|
* Include Operation
|
||||||
|
* Once-Only Headers
|
||||||
|
* Computed Includes
|
||||||
|
|
||||||
|
https://gcc.gnu.org/onlinedocs/cpp/Header-Files.html
|
||||||
46
RotaxMonitorTester/lib/README
Normal file
46
RotaxMonitorTester/lib/README
Normal file
@@ -0,0 +1,46 @@
|
|||||||
|
|
||||||
|
This directory is intended for project specific (private) libraries.
|
||||||
|
PlatformIO will compile them to static libraries and link into the executable file.
|
||||||
|
|
||||||
|
The source code of each library should be placed in a separate directory
|
||||||
|
("lib/your_library_name/[Code]").
|
||||||
|
|
||||||
|
For example, see the structure of the following example libraries `Foo` and `Bar`:
|
||||||
|
|
||||||
|
|--lib
|
||||||
|
| |
|
||||||
|
| |--Bar
|
||||||
|
| | |--docs
|
||||||
|
| | |--examples
|
||||||
|
| | |--src
|
||||||
|
| | |- Bar.c
|
||||||
|
| | |- Bar.h
|
||||||
|
| | |- library.json (optional. for custom build options, etc) https://docs.platformio.org/page/librarymanager/config.html
|
||||||
|
| |
|
||||||
|
| |--Foo
|
||||||
|
| | |- Foo.c
|
||||||
|
| | |- Foo.h
|
||||||
|
| |
|
||||||
|
| |- README --> THIS FILE
|
||||||
|
|
|
||||||
|
|- platformio.ini
|
||||||
|
|--src
|
||||||
|
|- main.c
|
||||||
|
|
||||||
|
Example contents of `src/main.c` using Foo and Bar:
|
||||||
|
```
|
||||||
|
#include <Foo.h>
|
||||||
|
#include <Bar.h>
|
||||||
|
|
||||||
|
int main (void)
|
||||||
|
{
|
||||||
|
...
|
||||||
|
}
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
The PlatformIO Library Dependency Finder will find automatically dependent
|
||||||
|
libraries by scanning project source files.
|
||||||
|
|
||||||
|
More information about PlatformIO Library Dependency Finder
|
||||||
|
- https://docs.platformio.org/page/librarymanager/ldf.html
|
||||||
39
RotaxMonitorTester/platformio.ini
Normal file
39
RotaxMonitorTester/platformio.ini
Normal file
@@ -0,0 +1,39 @@
|
|||||||
|
; PlatformIO Project Configuration File
|
||||||
|
;
|
||||||
|
; Build options: build flags, source filter
|
||||||
|
; Upload options: custom upload port, speed and extra flags
|
||||||
|
; Library options: dependencies, extra library storages
|
||||||
|
; Advanced options: extra scripting
|
||||||
|
;
|
||||||
|
; Please visit documentation for the other options and examples
|
||||||
|
; https://docs.platformio.org/page/projectconf.html
|
||||||
|
|
||||||
|
[env:esp32-devtest-release]
|
||||||
|
board = esp32dev
|
||||||
|
platform = https://github.com/pioarduino/platform-espressif32/releases/download/stable/platform-espressif32.zip
|
||||||
|
framework = arduino
|
||||||
|
lib_deps =
|
||||||
|
hideakitai/DebugLog@^0.8.4
|
||||||
|
board_build.flash_size = 4MB
|
||||||
|
board_build.partitions = default.csv
|
||||||
|
monitor_speed = 115200
|
||||||
|
build_type = release
|
||||||
|
|
||||||
|
[env:esp32-devtest-debug]
|
||||||
|
board = esp32dev
|
||||||
|
platform = https://github.com/pioarduino/platform-espressif32/releases/download/stable/platform-espressif32.zip
|
||||||
|
|
||||||
|
lib_deps =
|
||||||
|
hideakitai/DebugLog@^0.8.4
|
||||||
|
board_build.flash_size = 4MB
|
||||||
|
board_build.partitions = default.csv
|
||||||
|
monitor_speed = 115200
|
||||||
|
build_type = debug
|
||||||
|
build_flags =
|
||||||
|
-O0
|
||||||
|
-g3
|
||||||
|
-ggdb
|
||||||
|
-fno-inline
|
||||||
|
-fno-ipa-sra
|
||||||
|
-fno-tree-sra
|
||||||
|
-fno-builtin
|
||||||
108
RotaxMonitorTester/src/main.cpp
Normal file
108
RotaxMonitorTester/src/main.cpp
Normal file
@@ -0,0 +1,108 @@
|
|||||||
|
#include <Arduino.h>
|
||||||
|
#include <DebugLog.h>
|
||||||
|
|
||||||
|
#include "timer.h"
|
||||||
|
#include <map>
|
||||||
|
|
||||||
|
static hw_timer_t *timerA = NULL;
|
||||||
|
static hw_timer_t *timerB = NULL;
|
||||||
|
TaskHandle_t main_t = NULL;
|
||||||
|
static uint32_t count = 0;
|
||||||
|
|
||||||
|
#define FREQUENCY 100000 // 100 KHz
|
||||||
|
#define PERIOD_US 10
|
||||||
|
|
||||||
|
#define SPARK_DLY_MIN 10
|
||||||
|
#define SPARK_DLY_MAX 490
|
||||||
|
|
||||||
|
#define PAUSE_LONG_MIN 5000
|
||||||
|
#define PAUSE_LONG_MAX PAUSE_LONG_MIN*100
|
||||||
|
|
||||||
|
void clearScreen(){
|
||||||
|
Serial.print("\033[2J"); // clear screen
|
||||||
|
Serial.print("\033[H"); // cursor home
|
||||||
|
Serial.flush();
|
||||||
|
}
|
||||||
|
|
||||||
|
static double filtered = 0;
|
||||||
|
|
||||||
|
static const std::map<const uint32_t, const char *> pin2Name = {
|
||||||
|
{PIN_TRIG_A12P, "HIGH_PIN_TRIG_A12P"},
|
||||||
|
{~PIN_TRIG_A12P, "LOW_PIN_TRIG_A12P"},
|
||||||
|
{PIN_TRIG_A12N, "HIGH_PIN_TRIG_A12N"},
|
||||||
|
{~PIN_TRIG_A12N, "LOW_PIN_TRIG_A12N"},
|
||||||
|
{PIN_TRIG_A34P, "HIGH_PIN_TRIG_A34P"},
|
||||||
|
{~PIN_TRIG_A34P, "LOW_PIN_TRIG_A34P"},
|
||||||
|
{PIN_TRIG_A34N, "HIGH_PIN_TRIG_A34N"},
|
||||||
|
{~PIN_TRIG_A34N, "LOW_PIN_TRIG_A34N"},
|
||||||
|
{SPARK_A12, "HIGH_SPARK_A12"},
|
||||||
|
{~SPARK_A12, "LOW_SPARK_A12"},
|
||||||
|
{SPARK_A34, "HIGH_SPARK_A34"},
|
||||||
|
{~SPARK_A34, "LOW_SPARK_A34"},
|
||||||
|
{State::S_WAIT_10MS_END, "S_WAIT_10MS_END"},
|
||||||
|
{State::S_WAIT_10MS, "S_WAIT_10MS"}};
|
||||||
|
|
||||||
|
static timerStatus stsA = {
|
||||||
|
.clock_period_us = (uint32_t)PERIOD_US,
|
||||||
|
.pause_long_us = 10000,
|
||||||
|
.pause_short_us = 1000,
|
||||||
|
.coil_pulse_us = 1000,
|
||||||
|
.spark_pulse_us = 100,
|
||||||
|
.spark_delay_us = 50,
|
||||||
|
.main_task = NULL};
|
||||||
|
|
||||||
|
void setup()
|
||||||
|
{
|
||||||
|
|
||||||
|
Serial.begin(115200);
|
||||||
|
delay(1000);
|
||||||
|
LOG_ATTACH_SERIAL(Serial);
|
||||||
|
|
||||||
|
pinMode(PIN_TRIG_A12P, OUTPUT);
|
||||||
|
pinMode(PIN_TRIG_A12N, OUTPUT);
|
||||||
|
pinMode(PIN_TRIG_A34P, OUTPUT);
|
||||||
|
pinMode(PIN_TRIG_A34N, OUTPUT);
|
||||||
|
pinMode(SPARK_A12, OUTPUT);
|
||||||
|
pinMode(SPARK_A34, OUTPUT);
|
||||||
|
|
||||||
|
pinMode(PIN_TRIG_B12P, OUTPUT);
|
||||||
|
pinMode(PIN_TRIG_B12N, OUTPUT);
|
||||||
|
pinMode(PIN_TRIG_B34P, OUTPUT);
|
||||||
|
pinMode(PIN_TRIG_B34N, OUTPUT);
|
||||||
|
pinMode(SPARK_B12, OUTPUT);
|
||||||
|
pinMode(SPARK_B34, OUTPUT);
|
||||||
|
|
||||||
|
pinMode(SPARK_DELAY_POT, ANALOG);
|
||||||
|
stsA.main_task = xTaskGetCurrentTaskHandleForCore(1);
|
||||||
|
|
||||||
|
timerA = timerBegin(FREQUENCY);
|
||||||
|
timerAttachInterruptArg(timerA, &onTimer, (void *)&stsA);
|
||||||
|
timerAlarm(timerA, 1, true, 0);
|
||||||
|
|
||||||
|
LOG_INFO("Setup Complete");
|
||||||
|
}
|
||||||
|
|
||||||
|
void loop()
|
||||||
|
{
|
||||||
|
LOG_INFO("Loop: ", count++);
|
||||||
|
uint32_t spark_delay = (uint32_t)(map(analogRead(SPARK_DELAY_POT), 0, 4096, SPARK_DLY_MIN, SPARK_DLY_MAX) / PERIOD_US);
|
||||||
|
stsA.spark_delay_us = spark_delay * PERIOD_US;
|
||||||
|
if (stsA.spark_delay_us > (SPARK_DLY_MIN + SPARK_DLY_MAX) / 2) {
|
||||||
|
stsA.soft_start = true;
|
||||||
|
stsA.spark_delay_us -= (SPARK_DLY_MIN + SPARK_DLY_MAX) / 2;
|
||||||
|
} else {
|
||||||
|
stsA.soft_start = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
double new_val = (float)(map(analogRead(FREQ_POT), 0, 4096, PAUSE_LONG_MIN, PAUSE_LONG_MAX));
|
||||||
|
filtered = filtered + 0.1 * (new_val - filtered);
|
||||||
|
stsA.pause_long_us = (uint32_t)filtered;
|
||||||
|
LOG_INFO("Spark Delay uS: ", stsA.spark_delay_us, "\tSoft Start: ", stsA.soft_start ? "TRUE" : "FALSE");
|
||||||
|
LOG_INFO("Pause: ", (uint32_t)(stsA.pause_long_us / 1000), "ms");
|
||||||
|
LOG_INFO("Coil Pulse: ", stsA.coil_pulse_us, "us");
|
||||||
|
LOG_INFO("Spark Pulse: ", stsA.spark_pulse_us, "us");
|
||||||
|
|
||||||
|
|
||||||
|
delay(100);
|
||||||
|
clearScreen();
|
||||||
|
}
|
||||||
23
RotaxMonitorTester/src/pins.h
Normal file
23
RotaxMonitorTester/src/pins.h
Normal file
@@ -0,0 +1,23 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
///// Ignition Box A /////
|
||||||
|
#define PIN_TRIG_A12P 18
|
||||||
|
#define PIN_TRIG_A12N 19
|
||||||
|
#define PIN_TRIG_A34P 21
|
||||||
|
#define PIN_TRIG_A34N 22
|
||||||
|
|
||||||
|
#define SPARK_A12 23
|
||||||
|
#define SPARK_A34 25
|
||||||
|
|
||||||
|
///// Ignition Box /////
|
||||||
|
#define PIN_TRIG_B12P 26
|
||||||
|
#define PIN_TRIG_B12N 27
|
||||||
|
#define PIN_TRIG_B34P 32
|
||||||
|
#define PIN_TRIG_B34N 33
|
||||||
|
|
||||||
|
#define SPARK_B12 4
|
||||||
|
#define SPARK_B34 5
|
||||||
|
|
||||||
|
// Pot
|
||||||
|
#define SPARK_DELAY_POT 13
|
||||||
|
#define FREQ_POT 14
|
||||||
192
RotaxMonitorTester/src/timer.cpp
Normal file
192
RotaxMonitorTester/src/timer.cpp
Normal file
@@ -0,0 +1,192 @@
|
|||||||
|
#include "timer.h"
|
||||||
|
|
||||||
|
volatile static bool wait_sent = false;
|
||||||
|
|
||||||
|
void onTimer(void *arg)
|
||||||
|
{
|
||||||
|
BaseType_t xHigherPriorityTaskWoken = pdFALSE;
|
||||||
|
timerStatus *params = (timerStatus *)(arg);
|
||||||
|
TaskHandle_t task = params->main_task;
|
||||||
|
|
||||||
|
// increment state time
|
||||||
|
params->state_time += params->clock_period_us;
|
||||||
|
|
||||||
|
digitalWrite(PIN_TRIG_B12P, HIGH);
|
||||||
|
|
||||||
|
switch (params->state)
|
||||||
|
{
|
||||||
|
|
||||||
|
case S_12P:
|
||||||
|
if (params->state_time == params->clock_period_us && !params->coil12p_high)
|
||||||
|
{
|
||||||
|
// xTaskNotifyFromISR(task, PIN_TRIG_A12P, eSetValueWithOverwrite, &xHigherPriorityTaskWoken);
|
||||||
|
digitalWrite(PIN_TRIG_A12P, HIGH);
|
||||||
|
params->coil12p_high = true;
|
||||||
|
wait_sent = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!params->soft_start)
|
||||||
|
{
|
||||||
|
if (params->state_time == params->spark_delay_us)
|
||||||
|
{
|
||||||
|
// xTaskNotifyFromISR(task, SPARK_A12, eSetValueWithOverwrite, &xHigherPriorityTaskWoken);
|
||||||
|
digitalWrite(SPARK_A12, HIGH);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (params->state_time == (params->spark_delay_us + params->spark_pulse_us))
|
||||||
|
{
|
||||||
|
// xTaskNotifyFromISR(task, ~SPARK_A12, eSetValueWithOverwrite, &xHigherPriorityTaskWoken);
|
||||||
|
digitalWrite(SPARK_A12, LOW);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (params->state_time >= params->coil_pulse_us && params->coil12p_high)
|
||||||
|
{
|
||||||
|
// xTaskNotifyFromISR(task, ~PIN_TRIG_A12P, eSetValueWithOverwrite, &xHigherPriorityTaskWoken);
|
||||||
|
digitalWrite(PIN_TRIG_A12P, LOW);
|
||||||
|
params->coil12p_high = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (params->state_time >= params->pause_short_us)
|
||||||
|
{
|
||||||
|
params->state = S_12N;
|
||||||
|
params->state_time = 0;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case S_12N:
|
||||||
|
if (params->state_time == params->clock_period_us && !params->coil12n_high)
|
||||||
|
{
|
||||||
|
// xTaskNotifyFromISR(task, PIN_TRIG_A12N, eSetValueWithOverwrite, &xHigherPriorityTaskWoken);
|
||||||
|
digitalWrite(PIN_TRIG_A12N, HIGH);
|
||||||
|
params->coil12n_high = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (params->soft_start)
|
||||||
|
{
|
||||||
|
if (params->state_time == params->spark_delay_us)
|
||||||
|
{
|
||||||
|
// xTaskNotifyFromISR(task, SPARK_A12, eSetValueWithOverwrite, &xHigherPriorityTaskWoken);
|
||||||
|
digitalWrite(SPARK_A12, HIGH);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (params->state_time == (params->spark_delay_us + params->spark_pulse_us))
|
||||||
|
{
|
||||||
|
// xTaskNotifyFromISR(task, ~SPARK_A12, eSetValueWithOverwrite, &xHigherPriorityTaskWoken);
|
||||||
|
digitalWrite(SPARK_A12, LOW);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (params->state_time >= params->coil_pulse_us && params->coil12n_high)
|
||||||
|
{
|
||||||
|
// xTaskNotifyFromISR(task, ~PIN_TRIG_A12N, eSetValueWithOverwrite, &xHigherPriorityTaskWoken);
|
||||||
|
digitalWrite(PIN_TRIG_A12N, LOW);
|
||||||
|
params->coil12n_high = false;
|
||||||
|
params->state = S_WAIT_10MS;
|
||||||
|
params->state_time = 0;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case S_WAIT_10MS:
|
||||||
|
if (!wait_sent)
|
||||||
|
{
|
||||||
|
// xTaskNotifyFromISR(task, S_WAIT_10MS, eSetValueWithOverwrite, &xHigherPriorityTaskWoken);
|
||||||
|
wait_sent = true;
|
||||||
|
}
|
||||||
|
if (params->state_time >= params->pause_long_us)
|
||||||
|
{
|
||||||
|
params->state = S_34P;
|
||||||
|
params->state_time = 0;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case S_34P:
|
||||||
|
if (params->state_time == params->clock_period_us && !params->coil34p_high)
|
||||||
|
{
|
||||||
|
// xTaskNotifyFromISR(task, PIN_TRIG_A34P, eSetValueWithOverwrite, &xHigherPriorityTaskWoken);
|
||||||
|
digitalWrite(PIN_TRIG_A34P, HIGH);
|
||||||
|
params->coil34p_high = true;;
|
||||||
|
wait_sent = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!params->soft_start)
|
||||||
|
{
|
||||||
|
if (params->state_time == params->spark_delay_us)
|
||||||
|
{
|
||||||
|
// xTaskNotifyFromISR(task, SPARK_A34, eSetValueWithOverwrite, &xHigherPriorityTaskWoken);
|
||||||
|
digitalWrite(SPARK_A34, HIGH);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (params->state_time == params->spark_delay_us + params->spark_pulse_us)
|
||||||
|
{
|
||||||
|
// xTaskNotifyFromISR(task, ~SPARK_A34, eSetValueWithOverwrite, &xHigherPriorityTaskWoken);
|
||||||
|
digitalWrite(SPARK_A34, LOW);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (params->state_time >= params->coil_pulse_us && params->coil34p_high)
|
||||||
|
{
|
||||||
|
// xTaskNotifyFromISR(task, ~PIN_TRIG_A34P, eSetValueWithOverwrite, &xHigherPriorityTaskWoken);
|
||||||
|
digitalWrite(PIN_TRIG_A34P, LOW);
|
||||||
|
params->coil34p_high = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (params->state_time >= params->pause_short_us)
|
||||||
|
{
|
||||||
|
params->state = S_34N;
|
||||||
|
params->state_time = 0;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case S_34N:
|
||||||
|
if (params->state_time == params->clock_period_us && !params->coil34n_high)
|
||||||
|
{
|
||||||
|
// xTaskNotifyFromISR(task, PIN_TRIG_A34N, eSetValueWithOverwrite, &xHigherPriorityTaskWoken);
|
||||||
|
digitalWrite(PIN_TRIG_A34N, HIGH);
|
||||||
|
params->coil34n_high = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (params->soft_start)
|
||||||
|
{
|
||||||
|
if (params->state_time == params->spark_delay_us)
|
||||||
|
{
|
||||||
|
// xTaskNotifyFromISR(task, SPARK_A34, eSetValueWithOverwrite, &xHigherPriorityTaskWoken);
|
||||||
|
digitalWrite(SPARK_A34, HIGH);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (params->state_time == params->spark_delay_us + params->spark_pulse_us)
|
||||||
|
{
|
||||||
|
// xTaskNotifyFromISR(task, ~SPARK_A34, eSetValueWithOverwrite, &xHigherPriorityTaskWoken);
|
||||||
|
digitalWrite(SPARK_A34, LOW);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (params->state_time >= params->coil_pulse_us && params->coil34n_high)
|
||||||
|
{
|
||||||
|
// xTaskNotifyFromISR(task, ~PIN_TRIG_A34N, eSetValueWithOverwrite, &xHigherPriorityTaskWoken);
|
||||||
|
digitalWrite(PIN_TRIG_A34N, LOW);
|
||||||
|
params->coil34n_high = false;
|
||||||
|
params->state = S_WAIT_10MS_END;
|
||||||
|
params->state_time = 0;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case S_WAIT_10MS_END:
|
||||||
|
if (!wait_sent)
|
||||||
|
{
|
||||||
|
// xTaskNotifyFromISR(task, S_WAIT_10MS_END, eSetValueWithOverwrite, &xHigherPriorityTaskWoken);
|
||||||
|
wait_sent = true;
|
||||||
|
}
|
||||||
|
if (params->state_time >= params->pause_long_us)
|
||||||
|
{
|
||||||
|
params->state = S_12P;
|
||||||
|
params->state_time = 0;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
digitalWrite(PIN_TRIG_B12P, LOW);
|
||||||
|
|
||||||
|
if (xHigherPriorityTaskWoken)
|
||||||
|
portYIELD_FROM_ISR();
|
||||||
|
}
|
||||||
40
RotaxMonitorTester/src/timer.h
Normal file
40
RotaxMonitorTester/src/timer.h
Normal file
@@ -0,0 +1,40 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <Arduino.h>
|
||||||
|
#include <DebugLog.h>
|
||||||
|
#include "pins.h"
|
||||||
|
|
||||||
|
#include "driver/gpio.h"
|
||||||
|
|
||||||
|
enum State
|
||||||
|
{
|
||||||
|
S_12P,
|
||||||
|
S_12N_DELAY,
|
||||||
|
S_12N,
|
||||||
|
S_WAIT_10MS,
|
||||||
|
S_34P,
|
||||||
|
S_34N_DELAY,
|
||||||
|
S_34N,
|
||||||
|
S_WAIT_1MS,
|
||||||
|
S_WAIT_10MS_END
|
||||||
|
};
|
||||||
|
|
||||||
|
struct timerStatus
|
||||||
|
{
|
||||||
|
State state = State::S_12P;
|
||||||
|
uint32_t state_time = 0;
|
||||||
|
uint32_t clock_period_us;
|
||||||
|
uint32_t pause_long_us;
|
||||||
|
uint32_t pause_short_us;
|
||||||
|
uint32_t coil_pulse_us;
|
||||||
|
uint32_t spark_pulse_us;
|
||||||
|
uint32_t spark_delay_us;
|
||||||
|
bool soft_start = false;
|
||||||
|
bool coil12p_high = false;
|
||||||
|
bool coil34p_high = false;
|
||||||
|
bool coil12n_high = false;
|
||||||
|
bool coil34n_high = false;
|
||||||
|
TaskHandle_t main_task;
|
||||||
|
};
|
||||||
|
|
||||||
|
void IRAM_ATTR onTimer(void *arg);
|
||||||
11
RotaxMonitorTester/test/README
Normal file
11
RotaxMonitorTester/test/README
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
|
||||||
|
This directory is intended for PlatformIO Test Runner and project tests.
|
||||||
|
|
||||||
|
Unit Testing is a software testing method by which individual units of
|
||||||
|
source code, sets of one or more MCU program modules together with associated
|
||||||
|
control data, usage procedures, and operating procedures, are tested to
|
||||||
|
determine whether they are fit for use. Unit testing finds problems early
|
||||||
|
in the development cycle.
|
||||||
|
|
||||||
|
More information about PlatformIO Unit Testing:
|
||||||
|
- https://docs.platformio.org/en/latest/advanced/unit-testing/index.html
|
||||||
Reference in New Issue
Block a user