Compare commits

..

2 Commits

Author SHA1 Message Date
Emanuele Trabattoni
8c5b7d4a1c Updated pin definitions and trigger tasks from pickups 2026-03-25 14:16:23 +01:00
Emanuele Trabattoni
b42474fff5 Added custom board definition 2026-03-25 14:14:10 +01:00
7 changed files with 382 additions and 116 deletions

View File

@@ -0,0 +1,52 @@
{
"build": {
"arduino": {
"ldscript": "esp32s3_out.ld",
"partitions": "default_16MB.csv",
"memory_type": "qio_opi"
},
"core": "esp32",
"extra_flags": [
"-DARDUINO_ESP32S3_DEV",
"-DARDUINO_RUNNING_CORE=1",
"-DARDUINO_EVENT_RUNNING_CORE=1",
"-DBOARD_HAS_PSRAM",
"-DARDUINO_USB_MODE=1",
"-DARDUINO_USB_CDC_ON_BOOT=0"
],
"f_cpu": "240000000L",
"f_flash": "80000000L",
"flash_mode": "qio",
"psram_type": "opi",
"hwids": [
["0x303A", "0x1001"]
],
"mcu": "esp32s3",
"variant": "esp32s3"
},
"connectivity": [
"bluetooth",
"wifi"
],
"debug": {
"default_tool": "esp-builtin",
"onboard_tools": [
"esp-builtin"
],
"openocd_target": "esp32s3.cfg"
},
"frameworks": [
"arduino",
"espidf"
],
"name": "ESP32-S3 WROOM (16MB Flash / 8MB PSRAM / USB HOST)",
"upload": {
"flash_size": "16MB",
"maximum_ram_size": 327680,
"maximum_size": 16777216,
"require_upload_port": true,
"speed": 921600
},
"url": "https://www.pcb-hero.com/blogs/lickys-column/esp32-s3-chip-definition-pinout-processor-application-and-development-board",
"vendor": "Custom"
}

View File

@@ -0,0 +1,6 @@
# Name, Type, SubType, Offset, Size, Flags
nvs, data, nvs, 0x9000, 0x5000,
otadata, data, ota, 0xe000, 0x2000,
app0, app, ota_0, 0x10000, 0x700000,
app1, app, ota_1, 0x710000,0x700000,
spiffs, data, spiffs, 0xE10000,0x1F0000,
1 # Name Type SubType Offset Size Flags
2 nvs data nvs 0x9000 0x5000
3 otadata data ota 0xe000 0x2000
4 app0 app ota_0 0x10000 0x700000
5 app1 app ota_1 0x710000 0x700000
6 spiffs data spiffs 0xE10000 0x1F0000

View File

@@ -8,21 +8,33 @@
; 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-devkitc1-n8r8] [env:esp32-s3-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/55.03.37/platform-espressif32.zip
board = esp32-s3-devkitc1-n8r8 board = esp32-s3-n16r8
framework = arduino framework = arduino
lib_deps = lib_deps =
hideakitai/DebugLog@^0.8.4 hideakitai/DebugLog@^0.8.4
bblanchon/ArduinoJson@^7.4.2 bblanchon/ArduinoJson@^7.4.2
hideakitai/PCA95x5@^0.1.3
adafruit/Adafruit SSD1306@^2.5.16
board_build.partitions = partitions/default_16MB.csv
board_build.psram = enabled
monitor_speed = 115200
upload_speed = 921600
build_type = release build_type = release
[env:esp32-s3-devkitc1-n8r8-debug] [env:esp32-s3-n16r8-debug]
platform = ${env:esp32-s3-devkitc1-n8r8.platform} platform = ${env:esp32-s3-n16r8.platform}
board = ${env:esp32-s3-devkitc1-n8r8.board} board = ${env:esp32-s3-n16r8.board}
framework = ${env:esp32-s3-devkitc1-n8r8.framework} framework = ${env:esp32-s3-n16r8.framework}
lib_deps = ${env:esp32-s3-devkitc1-n8r8.lib_deps} lib_deps =
${env:esp32-s3-n16r8.lib_deps}
hideakitai/PCA95x5@^0.1.3
adafruit/Adafruit SSD1306@^2.5.16
board_build.partitions = partitions/default_16MB.csv
board_build.psram = enabled
monitor_speed = 115200
upload_speed = 921600
build_type = debug build_type = debug
build_flags = build_flags =
-O0 -O0

View File

@@ -1,40 +1,106 @@
#include <Arduino.h> #include <Arduino.h>
#include "soc/gpio_struct.h"
#include "pins.h"
#define CORE_0 0
#define CORE_1 1
#define TASK_STACK 4096 // in words
#define TASK_PRIORITY 2 // priorità leggermente più alta
// ===================== // =====================
// Event Flags (bitmask) // Event Flags (bitmask)
// ===================== // =====================
#define PKDT_FLAG_AP (1 << 0) #define TRIG_FLAG_A12P (1 << 0)
#define PKDT_FLAG_AN (1 << 1) #define TRIG_FLAG_A12N (1 << 2)
#define PKDT_FLAG_BP (1 << 2) #define TRIG_FLAG_A34P (1 << 1)
#define PKDT_FLAG_BN (1 << 3) #define TRIG_FLAG_A34N (1 << 3)
#define TRIG_FLAG_B12P (1 << 4)
#define TRIG_FLAG_B12N (1 << 6)
#define TRIG_FLAG_B34P (1 << 5)
#define TRIG_FLAG_B34N (1 << 7)
// Task handle // Task handle
TaskHandle_t pkdtTaskHandle = NULL; TaskHandle_t trigA_TaskHandle = NULL;
TaskHandle_t trigB_TaskHandle = NULL;
// Task internal Status
struct taskStatus {
int64_t trig12_start;
int64_t trig34_start;
int64_t trig12_time;
int64_t trig34_time;
bool trig12_complete = false;
bool trig34_complete = false;
bool soft12 = false;
bool soft34 = false;
bool error12 = false;
bool error34 = false;
};
taskStatus ignA_status;
taskStatus ignB_status;
// Pin to flag Map
static const uint32_t int2flag[] = {
[TRIG_A12P] = TRIG_FLAG_A12P,
[TRIG_A12N] = TRIG_FLAG_A34P,
[TRIG_A34P] = TRIG_FLAG_A12N,
[TRIG_A34N] = TRIG_FLAG_A34N,
[TRIG_B12P] = TRIG_FLAG_B12P,
[TRIG_B12N] = TRIG_FLAG_B34P,
[TRIG_B34P] = TRIG_FLAG_B12N,
[TRIG_B34N] = TRIG_FLAG_B34N,
};
// ===================== // =====================
// ISR (Pass return bitmask to ISR management function) // ISR (Pass return bitmask to ISR management function)
// one function for each wake up pin conncted to a trigger // one function for each wake up pin conncted to a trigger
// ===================== // =====================
void IRAM_ATTR pkdt_isr_ap() { void IRAM_ATTR trig_isr_a() {
BaseType_t xHigherPriorityTaskWoken = pdFALSE; BaseType_t xHigherPriorityTaskWoken = pdFALSE;
xTaskNotifyFromISR(pkdtTaskHandle, PKDT_FLAG_AP, eSetBits, &xHigherPriorityTaskWoken); auto startTime = esp_timer_get_time();
portYIELD_FROM_ISR(xHigherPriorityTaskWoken);
uint32_t status = GPIO.status;
uint32_t flags = 0;
while (status) {
uint32_t pin = __builtin_ctz(status); // trova primo bit attivo
status &= ~(1 << pin); // clear bit
flags |= int2flag[pin];
} }
void IRAM_ATTR pkdt_isr_an() { if (flags & (TRIG_FLAG_A12P | TRIG_FLAG_A12N))
BaseType_t xHigherPriorityTaskWoken = pdFALSE; ignA_status.trig12_start = startTime;
xTaskNotifyFromISR(pkdtTaskHandle, PKDT_FLAG_AN, eSetBits, &xHigherPriorityTaskWoken); else
ignA_status.trig12_start = startTime;
if (trigA_TaskHandle) {
xTaskNotifyFromISR(trigA_TaskHandle, flags, eSetBits, &xHigherPriorityTaskWoken);
portYIELD_FROM_ISR(xHigherPriorityTaskWoken); portYIELD_FROM_ISR(xHigherPriorityTaskWoken);
} }
}
void IRAM_ATTR pkdt_isr_bp() { void IRAM_ATTR trig_isr_b() {
BaseType_t xHigherPriorityTaskWoken = pdFALSE; BaseType_t xHigherPriorityTaskWoken = pdFALSE;
xTaskNotifyFromISR(pkdtTaskHandle, PKDT_FLAG_BP, eSetBits, &xHigherPriorityTaskWoken);
portYIELD_FROM_ISR(xHigherPriorityTaskWoken); uint32_t status = GPIO.status;
uint32_t flags = 0;
while (status) {
uint32_t pin = __builtin_ctz(status); // trova primo bit attivo
status &= ~(1 << pin); // clear bit
flags |= int2flag[pin];
} }
void IRAM_ATTR pkdt_isr_bn() { if (trigB_TaskHandle) {
BaseType_t xHigherPriorityTaskWoken = pdFALSE; xTaskNotifyFromISR(trigB_TaskHandle, flags, eSetBits, &xHigherPriorityTaskWoken);
xTaskNotifyFromISR(pkdtTaskHandle, PKDT_FLAG_BN, eSetBits, &xHigherPriorityTaskWoken);
portYIELD_FROM_ISR(xHigherPriorityTaskWoken); portYIELD_FROM_ISR(xHigherPriorityTaskWoken);
} }
}

View File

@@ -10,38 +10,21 @@
#include <isr.h> #include <isr.h>
#include <pins.h> #include <pins.h>
#include <channels.h> #include <channels.h>
#include <tasks.h>
// Device Libraries // Device Libraries
#include <ADS1256.h> #include <ADS1256.h>
#include <AD5292.h> #include <AD5292.h>
void pkdtTask(void *pvParameters) {
uint32_t notifiedValue;
while (true) {
// attende eventi
xTaskNotifyWait(
0x00, // non pulire all'ingresso
0xFFFFFFFF, // pulisci tutti i bit all'uscita
&notifiedValue, // valore ricevuto
portMAX_DELAY
);
// 🔥 QUI GIRA SU CORE 0
switch (notifiedValue)
case PKDT_FLAG_AP: {
handlePKDT(PKDT_AP);
break;
}
default:
LOG_ERROR("Invalid Interrupt: ", notifiedValue);
}
}
void setup() { void setup() {
Serial.begin(9600); delay(250);
Serial.begin(115200);
// Setup Logger
LOG_ATTACH_SERIAL(Serial); LOG_ATTACH_SERIAL(Serial);
LOG_SET_LEVEL(DebugLogLevel::LVL_INFO); LOG_SET_LEVEL(DebugLogLevel::LVL_INFO);
// Print Processor Info
LOG_INFO("ESP32 Chip:", ESP.getChipModel()); LOG_INFO("ESP32 Chip:", ESP.getChipModel());
LOG_INFO("ESP32 PSram:", ESP.getPsramSize()); LOG_INFO("ESP32 PSram:", ESP.getPsramSize());
LOG_INFO("ESP32 Flash:", ESP.getFlashChipSize()); LOG_INFO("ESP32 Flash:", ESP.getFlashChipSize());
@@ -49,40 +32,72 @@ void setup() {
LOG_INFO("ESP32 Sketch:", ESP.getFreeSketchSpace()); LOG_INFO("ESP32 Sketch:", ESP.getFreeSketchSpace());
// Initialize Interrupt pins on peak detectors // Initialize Interrupt pins on peak detectors
pinMode(PKDT_AP, INPUT_PULLDOWN); pinMode(TRIG_A12P, INPUT_PULLDOWN);
pinMode(PKDT_AN, INPUT_PULLDOWN); pinMode(TRIG_A12N, INPUT_PULLDOWN);
pinMode(PKDT_BP, INPUT_PULLDOWN); pinMode(TRIG_A34P, INPUT_PULLDOWN);
pinMode(PKDT_BN, INPUT_PULLDOWN); pinMode(TRIG_A34N, INPUT_PULLDOWN);
// interrupt pinMode(TRIG_B12P, INPUT_PULLDOWN);
attachInterrupt(PKDT_AP, pkdt_isr_ap, RISING); pinMode(TRIG_B12N, INPUT_PULLDOWN);
attachInterrupt(PKDT_AN, pkdt_isr_an, RISING); pinMode(TRIG_B34P, INPUT_PULLDOWN);
attachInterrupt(PKDT_BP, pkdt_isr_bp, RISING); pinMode(TRIG_B34N, INPUT_PULLDOWN);
attachInterrupt(PKDT_BN, pkdt_isr_bn, 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);
// 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);
// Init SPI interface // Init SPI interface
SPI.begin(); SPI.begin();
// Init ADC
auto adc = ADS1256(ADC_DRDY, ADC_RST, ADC_SYNC, ADC_CS, 0.0, SPI);
ADS1256.
} }
void loop() { void loop() {
// task su core 0 // global variables
auto isrTask = xTaskCreatePinnedToCore( bool running = true;
pkdtTask,
"pkdtTask", // Ignition A on Core 0
4096, auto ignA_task_success = xTaskCreatePinnedToCore(
ignitionA_task,
"ignitionA_task",
TASK_STACK,
NULL, NULL,
2, // priorità leggermente più alta TASK_PRIORITY,
&pkdtTaskHandle, &trigA_TaskHandle,
0 CORE_0
); );
if (isrTask != pdPASS){ // Ignition A on Core 1
auto ignB_task_success = xTaskCreatePinnedToCore(
ignitionB_task,
"ignitionB_task",
TASK_STACK,
NULL,
TASK_PRIORITY, // priorità leggermente più alta
&trigA_TaskHandle,
CORE_1
);
if ((ignA_task_success && ignB_task_success) != pdPASS){
LOG_ERROR("Unble to initialize ISR task"); LOG_ERROR("Unble to initialize ISR task");
} }
LOG_INFO("Real Time Tasks A&B initialized");
////////////////////// MAIN LOOP //////////////////////
while (running) {
} }
if (trigA_TaskHandle)
vTaskDelete(trigA_TaskHandle);
if (trigB_TaskHandle)
vTaskDelete(trigB_TaskHandle);
////////////////////// MAIN LOOP //////////////////////
}

View File

@@ -6,14 +6,15 @@
#define SPI_SCK 12 #define SPI_SCK 12
// ===================== // =====================
// CHIP SELECT // I2C BUS
// ===================== // =====================
#define ADC_CS 10 #define SDA 8
#define POT_CS 9 #define SCL 9
// ===================== // =====================
// ADC CONTROL // ADC CONTROL
// ===================== // =====================
#define ADC_CS 10
#define ADC_DRDY 4 #define ADC_DRDY 4
#define ADC_RST 5 #define ADC_RST 5
#define ADC_SYNC 6 #define ADC_SYNC 6
@@ -21,47 +22,63 @@
// ===================== // =====================
// DIGITAL POT // DIGITAL POT
// ===================== // =====================
#define POT_DRDY 7 #define POT_CS 7
#define POT_DRDY 18
// ===================== // =====================
// RELAY // RELAY OUT
// ===================== // =====================
#define PICK_RELAY 8 #define PICK_RELAY 21
// ===================== // =====================
// PEAK DETECTORS (DIGITAL INPUT) // TRIGGER INPUT INTERRUPTS
// ===================== // =====================
#define PKDT_AP 1 #define TRIG_A12P 1
#define PKDT_AN 2 #define TRIG_A12N 2
#define PKDT_BP 3 #define TRIG_A34P 3
#define PKDT_BN 14 #define TRIG_A34N 14
#define TRIG_B12P 15
#define TRIG_B12N 16
#define TRIG_B34P 17
#define TRIG_B34N 18
// ===================== // =====================
// TRIGGER INPUTS // PEAK DETECTOR RESET OUTPUTS
// ===================== // =====================
#define TRIG_AP 15 #define RST_A12P 39
#define TRIG_AN 16 #define RST_A12N 40
#define TRIG_BP 17 #define RST_A34P 41
#define TRIG_BN 18 #define RST_A34N 42
#define RST_B12P 35
#define RST_B12N 36
#define RST_B34P 37
#define RST_B34N 38
// ===================== // =====================
// SOFT START DETECT // SPARK DETECT INPUTS
// ===================== // =====================
#define SOFT_A 21 #define SPARK_A12 45 // input only
#define SOFT_B 47 #define SPARK_A34 46 // input only
#define SPARK_B12 47
#define SPARK_B34 48
// ===================== // =====================
// STATUS OUTPUT // STATUS & BUTTON su PCA9555 (I2C)
// ===================== // =====================
#define STA_1 35 #define STA_1 0
#define STA_2 36 #define STA_2 1
#define STA_3 37 #define STA_3 2
#define STA_4 38 #define STA_4 3
#define STA_5 4
#define STA_6 5
#define STA_7 6
#define STA_8 7
// ===================== #define BTN_1 8
// BUTTON INPUT #define BTN_2 9
// ===================== #define BTN_3 10
#define BTN_1 39 #define BTN_4 11
#define BTN_2 40 #define BTN_5 12
#define BTN_3 41 #define BTN_6 13
#define BTN_4 42 #define BTN_7 14
#define BTN_8 15

98
RotaxMonitor/src/tasks.h Normal file
View File

@@ -0,0 +1,98 @@
// Arduino Libraries
#include <Arduino.h>
#include <DebugLog.h>
// ISR
#include "isr.h"
const uint16_t spark_delay_us = 500;
void ignitionA_task(void *pvParameters) {
uint32_t notifiedValue;
while (true) {
// attende eventi
xTaskNotifyWait(
0x00, // non pulire all'ingresso
ULONG_MAX, // pulisci tutti i bit all'uscita
&notifiedValue, // valore ricevuto
portMAX_DELAY
);
uint64_t wait_time=0;
switch (notifiedValue) {
case TRIG_FLAG_A12P:
case TRIG_FLAG_A12N:
bool spark12_timeout = false;
if (ignA_status.trig12_complete) {
// read peak adc values from sample and hold
} else {
while(!digitalRead(SPARK_A12)) {
wait_time = ignA_status.trig12_start - esp_timer_get_time();
if (wait_time >= spark_delay_us) {
spark12_timeout = true;
break;
}
}
if (spark12_timeout) { // spark did not happen, timeout
ignA_status.trig12_complete = false;
} else { // spark did happen
ignA_status.trig12_complete = true;
ignA_status.trig12_time = wait_time;
}
}
break;
case TRIG_FLAG_A34P:
case TRIG_FLAG_A34N:
bool spark34_timeout = false;
if (ignA_status.trig12_complete) {
// read peak adc values from sample and hold
} else {
while(!digitalRead(SPARK_A34)) {
wait_time = ignA_status.trig34_start - esp_timer_get_time();
if (wait_time >= spark_delay_us) {
spark12_timeout = true;
break;
}
}
if (spark34_timeout) { // spark did not happen, timeout
ignA_status.trig34_complete = false;
} else { // spark did happen
ignA_status.trig34_complete = true;
ignA_status.trig34_time = wait_time;
}
}
break;
default:
LOG_ERROR("Invalid A Interrupt: ", notifiedValue);
}
}
}
void ignitionB_task(void *pvParameters) {
uint32_t notifiedValue;
while (true) {
// attende eventi
xTaskNotifyWait(
0x00, // non pulire all'ingresso
0xFFFFFFFF, // pulisci tutti i bit all'uscita
&notifiedValue, // 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);
}
}
}