ZCD fix - working code
This commit is contained in:
parent
394ba748f5
commit
3eeeb8304d
|
|
@ -20,7 +20,7 @@
|
|||
#ifndef DEBUG
|
||||
#define DEBUG 1 // Set to 0 to disable debug output
|
||||
#endif
|
||||
#undef DEBUG
|
||||
//#undef DEBUG
|
||||
|
||||
|
||||
//#define BLE_DEBUG
|
||||
|
|
|
|||
|
|
@ -10,7 +10,9 @@
|
|||
#include "OTA.h"
|
||||
#include "UI.h"
|
||||
#include "BLEScan.h"
|
||||
|
||||
#include "hal/timer_ll.h"
|
||||
#include "hal/timer_types.h"
|
||||
|
||||
|
||||
#if defined(ESP32)
|
||||
|
|
@ -54,8 +56,8 @@ MY_IRAM_ATTR void loop() {
|
|||
static uint8_t lastSecond = -1;
|
||||
|
||||
// Read timer from TG0-Timer0
|
||||
tg0->hw_timer[0].update.val = 1;
|
||||
uint32_t tNow = tg0->hw_timer[0].lo.val;
|
||||
tg0->hw_timer[1].update.val = 1;
|
||||
uint32_t tNow = (uint32_t)timer_ll_get_counter_value(tg0, 1);
|
||||
|
||||
g_millis = (uint32_t) (tNow / 10);
|
||||
unsigned long tickMillis = g_millis;
|
||||
|
|
@ -69,6 +71,8 @@ MY_IRAM_ATTR void loop() {
|
|||
// Every Second
|
||||
if (tickSecond != lastTickSecond)
|
||||
{
|
||||
lastTickSecond = tickSecond;
|
||||
|
||||
// Time and ZCD
|
||||
setACLoadStatus(tNow);
|
||||
setTime();
|
||||
|
|
@ -115,7 +119,6 @@ MY_IRAM_ATTR void loop() {
|
|||
default:
|
||||
break;
|
||||
}
|
||||
lastTickSecond = tickSecond;
|
||||
}
|
||||
yield();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -4,6 +4,9 @@
|
|||
#include "NTC_10K.h"
|
||||
#include "Config.h"
|
||||
|
||||
#include "driver/gpio.h"
|
||||
#include "driver/adc.h"
|
||||
|
||||
const float resistance[] = {
|
||||
3360850.37, // -40°C
|
||||
1973470.32, // -35°C
|
||||
|
|
@ -71,10 +74,6 @@ void NTC_10K::setup(bool bNegativePolarity) {
|
|||
m_nTemp = -9999;
|
||||
m_fTemp = -9999.0f;
|
||||
m_fLastTemp = 0.0f;
|
||||
|
||||
pinMode(PIN_NTC, INPUT); // Set PIN_NTC as input
|
||||
analogReadResolution(12); // Set ADC resolution to 12 bits (0-4095)
|
||||
analogSetAttenuation(ADC_11db); // Set attenuation for full-scale 3.3V
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -91,7 +90,7 @@ void NTC_10K::readSensor() {
|
|||
float currentInstantTemp; // High-precision intermediate
|
||||
|
||||
// 1. Hardware Acquisition
|
||||
int adcValue = constrain(analogRead(PIN_NTC), 1, 4094);
|
||||
int adcValue = constrain(adc1_get_raw(ADC1_CHANNEL_3), 1, 4094);
|
||||
|
||||
// 2. Voltage and Resistance Calculation
|
||||
Vin = (float)adcValue * _vRef / _RESO;
|
||||
|
|
|
|||
2
OTA.cpp
2
OTA.cpp
|
|
@ -17,7 +17,7 @@
|
|||
// OTA
|
||||
//
|
||||
// ==============================================================
|
||||
const char *HC__VERSION = "20260418036";
|
||||
const char *HC__VERSION = "20260419022";
|
||||
#define UPDATE_PORT ((uint16_t) 443)
|
||||
const char *url = "visionsoft.kr";
|
||||
const char *uri = "/sc/pages/firmware_download.php";
|
||||
|
|
|
|||
192
Setup.cpp
192
Setup.cpp
|
|
@ -13,6 +13,11 @@
|
|||
#include <esp_wifi.h>
|
||||
#include "esp_coexist.h"
|
||||
|
||||
// GPIO Headers
|
||||
#include "driver/gpio.h"
|
||||
#include "driver/timer.h"
|
||||
#include "driver/adc.h"
|
||||
|
||||
|
||||
#define TAG_SETUP "TAG_SETUP"
|
||||
// Task handle
|
||||
|
|
@ -24,14 +29,19 @@ bool g_bWiFiHasBeenConnected = false;
|
|||
extern STATUS_TYPE status;
|
||||
extern CHistory history;
|
||||
|
||||
// Hardware First
|
||||
void setupGPIO1();
|
||||
void setupGPIO2();
|
||||
void setupPWM();
|
||||
void setupZCD();
|
||||
void setupTimers();
|
||||
|
||||
void setupConfig();
|
||||
void setupStatus();
|
||||
void restoreStatus();
|
||||
void setupWiFi();
|
||||
void setupPostWiFi(bool bBoot);
|
||||
void setupPins();
|
||||
void setupSensor();
|
||||
void setupZCD();
|
||||
void setup_BLE();
|
||||
void scanI2C();
|
||||
|
||||
|
|
@ -44,9 +54,9 @@ void setup() {
|
|||
//esp_log_level_set("BLE_POLL", ESP_LOG_INFO); // Module-specific level
|
||||
//esp_coex_preference_set(ESP_COEX_PREFER_BT);
|
||||
|
||||
DPRINTLN(" **********************");
|
||||
DPRINTLN("**********************");
|
||||
DPRINTF(" SETUP - Start - ver. %s type: %d\n", HC__VERSION, THIS_DEVICE_TYPE);
|
||||
DPRINTLN(" **********************");
|
||||
DPRINTLN("**********************");
|
||||
g_bWiFiHasBeenConnected = false;
|
||||
g_bWiFiHasBeenConnected = false;
|
||||
g_nYear = 2024;
|
||||
|
|
@ -58,13 +68,15 @@ void setup() {
|
|||
bShowSensor = false;
|
||||
|
||||
|
||||
// Hardware
|
||||
setupPWM();
|
||||
setupGPIO1();
|
||||
|
||||
setupConfig();
|
||||
setupStatus();
|
||||
setupPins();
|
||||
scanI2C();
|
||||
setupSensor();
|
||||
ui.setup();
|
||||
ui.message(0, (char *) "WiFi...");
|
||||
setupWiFi();
|
||||
|
||||
if (aht25.sensor() || aht10_0x39.sensor()) {
|
||||
|
|
@ -95,6 +107,8 @@ void setup() {
|
|||
&TaskHandle_0, // Task handle
|
||||
0 // Core 0
|
||||
);
|
||||
setupTimers();
|
||||
setupGPIO2();
|
||||
DPRINTLN("Setup Completed\n========================\n");
|
||||
}
|
||||
|
||||
|
|
@ -104,6 +118,160 @@ void setup() {
|
|||
// Setup
|
||||
//
|
||||
// ======================================================================
|
||||
|
||||
void setupGPIO1() {
|
||||
// Set PIN Direction & Status
|
||||
// =========================
|
||||
// 1. NTC (ADC 설정)
|
||||
// =========================
|
||||
// adc1_config_channel_atten에서 내부적으로 핀 설정을 하므로 방향 설정은 생략 가능합니다.
|
||||
adc1_config_width(ADC_WIDTH_BIT_12); // 0~4095
|
||||
adc1_config_channel_atten(ADC1_CHANNEL_3, ADC_ATTEN_DB_11);
|
||||
|
||||
// =========================
|
||||
// 2. UI Buttons 설정
|
||||
// =========================
|
||||
gpio_config_t io_conf_ui = {};
|
||||
io_conf_ui.intr_type = GPIO_INTR_ANYEDGE;
|
||||
io_conf_ui.mode = GPIO_MODE_INPUT;
|
||||
io_conf_ui.pin_bit_mask = (1ULL << PIN_SW_SET) |
|
||||
(1ULL << PIN_SW_UP) |
|
||||
(1ULL << PIN_SW_DOWN);
|
||||
io_conf_ui.pull_up_en = GPIO_PULLUP_ENABLE;
|
||||
io_conf_ui.pull_down_en = GPIO_PULLDOWN_DISABLE;
|
||||
gpio_config(&io_conf_ui);
|
||||
|
||||
// =========================
|
||||
// 3. ZCD Inputs 설정
|
||||
// =========================
|
||||
gpio_config_t io_conf_zcd = {};
|
||||
io_conf_zcd.intr_type = GPIO_INTR_ANYEDGE;
|
||||
io_conf_zcd.mode = GPIO_MODE_INPUT;
|
||||
io_conf_zcd.pin_bit_mask = (1ULL << PIN_ZCD_AC) | (1ULL << PIN_ZCD_LOAD);
|
||||
io_conf_zcd.pull_up_en = GPIO_PULLUP_DISABLE;
|
||||
io_conf_zcd.pull_down_en = GPIO_PULLDOWN_DISABLE;
|
||||
gpio_config(&io_conf_zcd);
|
||||
|
||||
// =========================
|
||||
// 4. Heater Outputs 설정
|
||||
// =========================
|
||||
gpio_config_t io_conf_heater = {};
|
||||
io_conf_heater.intr_type = GPIO_INTR_DISABLE;
|
||||
io_conf_heater.mode = GPIO_MODE_OUTPUT;
|
||||
io_conf_heater.pin_bit_mask = (1ULL << PIN_HEATER1) | (1ULL << PIN_HEATER2);
|
||||
io_conf_heater.pull_up_en = GPIO_PULLUP_DISABLE;
|
||||
io_conf_heater.pull_down_en = GPIO_PULLDOWN_DISABLE;
|
||||
gpio_config(&io_conf_heater);
|
||||
|
||||
// 초기 상태 OFF 설정
|
||||
gpio_set_level((gpio_num_t)PIN_HEATER1, HEATER_OFF);
|
||||
gpio_set_level((gpio_num_t)PIN_HEATER2, HEATER_OFF);
|
||||
}
|
||||
|
||||
void setupGPIO2() {
|
||||
// =========================
|
||||
// ISR 서비스 및 핸들러 등록
|
||||
// =========================
|
||||
// LEVEL2 플래그를 사용하여 타이밍 정밀도를 높입니다.
|
||||
esp_err_t err = gpio_install_isr_service(ESP_INTR_FLAG_IRAM);
|
||||
if (err != ESP_OK && err != ESP_ERR_INVALID_STATE) {
|
||||
DPRINTLN("[GPIO] Error on gpio_install_isr_service");
|
||||
}
|
||||
|
||||
// 버튼 핸들러
|
||||
gpio_isr_handler_add((gpio_num_t)PIN_SW_SET, buttonSetISR, NULL);
|
||||
gpio_isr_handler_add((gpio_num_t)PIN_SW_UP, buttonUpISR, NULL);
|
||||
gpio_isr_handler_add((gpio_num_t)PIN_SW_DOWN, buttonDownISR, NULL);
|
||||
|
||||
// ZCD 핸들러 (이제 LEVEL2 우선순위로 동작)
|
||||
gpio_isr_handler_add((gpio_num_t)PIN_ZCD_AC, zcdACISR, NULL);
|
||||
gpio_isr_handler_add((gpio_num_t)PIN_ZCD_LOAD, zcdLoadISR, NULL);
|
||||
}
|
||||
|
||||
void setupTimers() {
|
||||
|
||||
//===============================================================================
|
||||
//
|
||||
// TIMER 설정 구조체 준비
|
||||
//
|
||||
static timer_config_t tcfg0t1 = {
|
||||
.alarm_en = TIMER_ALARM_DIS,
|
||||
.counter_en = TIMER_START,
|
||||
.intr_type = TIMER_INTR_LEVEL,
|
||||
.counter_dir = TIMER_COUNT_UP,
|
||||
.auto_reload = (timer_autoreload_t) TIMER_AUTORELOAD_DIS,
|
||||
.divider = 8000 // 10KHz (100us tick)
|
||||
};
|
||||
|
||||
esp_err_t err;
|
||||
#ifdef DEBUG
|
||||
bool bErr = false;
|
||||
#endif
|
||||
|
||||
// =========================
|
||||
// TG0 TIMER1 (millis replacement)
|
||||
// =========================
|
||||
if ((err = timer_init(TIMER_GROUP_0, TIMER_1, &tcfg0t1)) == ESP_OK ) {
|
||||
timer_set_counter_value(TIMER_GROUP_0, TIMER_1, 0); // init counter value
|
||||
timer_start(TIMER_GROUP_0, TIMER_1);
|
||||
}
|
||||
#ifdef DEBUG
|
||||
else {
|
||||
DPRINTLN("[Timer] Failed to init timer TG0 Timer1");
|
||||
bErr = true;
|
||||
}
|
||||
#endif
|
||||
|
||||
static timer_config_t tcfg1 = {
|
||||
.alarm_en = TIMER_ALARM_EN,
|
||||
.counter_en = TIMER_START,
|
||||
.intr_type = TIMER_INTR_LEVEL,
|
||||
.counter_dir = TIMER_COUNT_UP,
|
||||
.auto_reload = (timer_autoreload_t) TIMER_AUTORELOAD_EN,
|
||||
.divider = 80 // 1MHz (1us tick)
|
||||
};
|
||||
|
||||
// =========================
|
||||
// TG1 TIMER0 (heater1)
|
||||
// =========================
|
||||
if ((err = timer_init(TIMER_GROUP_1, TIMER_0, &tcfg1)) == ESP_OK ) {
|
||||
timer_set_counter_value(TIMER_GROUP_1, TIMER_0, 0);
|
||||
timer_set_alarm_value(TIMER_GROUP_1, TIMER_0, (uint64_t) 0xFFFFFFF0);
|
||||
err = timer_isr_register(TIMER_GROUP_1, TIMER_0, timer0ISR, NULL, ESP_INTR_FLAG_IRAM, NULL );
|
||||
DPRINTF("TimerG1T0 ISR Register Result: %d\n", err);
|
||||
timer_enable_intr(TIMER_GROUP_1, TIMER_0);
|
||||
timer_start(TIMER_GROUP_1, TIMER_0);
|
||||
}
|
||||
#ifdef DEBUG
|
||||
else {
|
||||
DPRINTLN("[Timer] Failed to init timer TG1 Timer0");
|
||||
bErr = true;
|
||||
}
|
||||
#endif
|
||||
|
||||
// =========================
|
||||
// TG1 TIMER1 (heater2)
|
||||
// =========================
|
||||
if ((err = timer_init(TIMER_GROUP_1, TIMER_1, &tcfg1)) == ESP_OK ) {
|
||||
timer_set_counter_value(TIMER_GROUP_1, TIMER_1, 0);
|
||||
timer_set_alarm_value(TIMER_GROUP_1, TIMER_1, (uint64_t) 0xFFFFFFF0);
|
||||
err = timer_isr_register(TIMER_GROUP_1, TIMER_1, timer1ISR, NULL, ESP_INTR_FLAG_IRAM, NULL );
|
||||
DPRINTF("TimerG1T1 ISR Register Result: %d\n", err);
|
||||
timer_enable_intr(TIMER_GROUP_1, TIMER_1);
|
||||
timer_start(TIMER_GROUP_1, TIMER_1);
|
||||
}
|
||||
#ifdef DEBUG
|
||||
else {
|
||||
DPRINTLN("[Timer] Failed to init timer TG1 Timer1");
|
||||
bErr = true;
|
||||
}
|
||||
|
||||
if (bErr == false) {
|
||||
DPRINTLN("[Timer] All Timers create and registered successfully!");
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
void setupConfig() {
|
||||
config.load();
|
||||
history.loadPID();
|
||||
|
|
@ -118,7 +286,7 @@ void setupWiFi() {
|
|||
// Connect WiFi for OTA
|
||||
if (config.ssid[0] && config.pw[0]) {
|
||||
esp_wifi_set_max_tx_power(74);
|
||||
|
||||
ui.message(0, (char *) "WiFi...");
|
||||
DPRINTF("BOOT: Connecting to WiFi: SSID: '%s', PW: '%s'\n", config.ssid, config.pw);
|
||||
WiFi.mode(WIFI_STA);
|
||||
WiFi.begin(config.ssid, config.pw);
|
||||
|
|
@ -163,7 +331,7 @@ void setupPostWiFi(bool bBoot = false) {
|
|||
DPRINTLN("Setup - TimeManager.begin()");
|
||||
DPRINTLN("\n===============================\n");
|
||||
DPRINTLN(" Trying OTA");
|
||||
ui.message(2, (char *) "Update check...");
|
||||
ui.message(2, (char *) "Update...");
|
||||
ledcWrite(PIN_LED_WIFI, PWM_FULL / 20);
|
||||
checkOTA(true);
|
||||
ledcWrite(PIN_LED_WIFI, PWM_FULL * 39 / 40);
|
||||
|
|
@ -185,13 +353,7 @@ void setupPostWiFi(bool bBoot = false) {
|
|||
}
|
||||
}
|
||||
|
||||
void setupPins() {
|
||||
// --- Basic Digital Pin Initialization ---
|
||||
pinMode(PIN_HEATER1, OUTPUT);
|
||||
pinMode(PIN_HEATER2, OUTPUT);
|
||||
digitalWrite(PIN_HEATER1, HEATER_OFF);
|
||||
digitalWrite(PIN_HEATER2, HEATER_OFF);
|
||||
|
||||
void setupPWM() {
|
||||
// --- 1. High Speed Group: Motor and Fan (~26kHz) ---
|
||||
// Core 2.0.17 uses APB (80MHz). 80MHz / (3 * 1024) ≈ 26kHz.
|
||||
ledcAttachChannel(PIN_MOTOR, PWM_26KHZ_FREQ, PWM_RESOLUTION, PWM_MOTOR_CHANNEL);
|
||||
|
|
|
|||
29
UI.cpp
29
UI.cpp
|
|
@ -11,6 +11,8 @@
|
|||
#include <Fonts/FreeSans12pt7b.h>
|
||||
#include <Fonts/FreeSans9pt7b.h>
|
||||
|
||||
#include "driver/gpio.h"
|
||||
|
||||
#define TAG_UI "UI"
|
||||
// Buttons
|
||||
#define DEBOUNCE_DELAY 100
|
||||
|
|
@ -210,12 +212,6 @@ const bool fineControl[] = {
|
|||
|
||||
true };
|
||||
|
||||
//
|
||||
// Buttons
|
||||
//
|
||||
void buttonSetISR();
|
||||
void buttonUpISR();
|
||||
void buttonDownISR();
|
||||
|
||||
|
||||
// Constructor for CUI class
|
||||
|
|
@ -294,16 +290,7 @@ void CUI::setup() {
|
|||
boxD1 = {POS_X_D1, POS_Y_BOTTOM - HEIGHT_D1, WIDTH_D1, HEIGHT_D1}; // 17 + 2
|
||||
boxD0 = {POS_X_D0, POS_Y_BOTTOM - HEIGHT_D0, WIDTH_D0, HEIGHT_D0}; // 17 + 2
|
||||
|
||||
|
||||
//
|
||||
// Buttons
|
||||
//
|
||||
pinMode(PIN_SW_SET, INPUT_PULLUP);
|
||||
pinMode(PIN_SW_UP, INPUT_PULLUP);
|
||||
pinMode(PIN_SW_DOWN, INPUT_PULLUP);
|
||||
attachInterrupt(digitalPinToInterrupt(PIN_SW_SET), buttonSetISR, CHANGE);
|
||||
attachInterrupt(digitalPinToInterrupt(PIN_SW_UP), buttonUpISR, CHANGE);
|
||||
attachInterrupt(digitalPinToInterrupt(PIN_SW_DOWN), buttonDownISR, CHANGE);
|
||||
initButtonState();
|
||||
}
|
||||
|
||||
|
|
@ -1071,7 +1058,7 @@ void CUI::checkButtonStates(unsigned long currentMillis) {
|
|||
if (bButtonSetChanged) {
|
||||
// Compare with the last interrupt time to ensure debounce delay
|
||||
if (currentMillis - buttonSetChangeTime > DEBOUNCE_DELAY) {
|
||||
if (digitalRead(PIN_SW_SET) == LOW) {
|
||||
if (gpio_get_level((gpio_num_t)PIN_SW_SET) == LOW) {
|
||||
// Button pressed
|
||||
buttonSetDownTime = buttonSetChangeTime;
|
||||
bButtonSetDown = true;
|
||||
|
|
@ -1092,7 +1079,7 @@ void CUI::checkButtonStates(unsigned long currentMillis) {
|
|||
if (bButtonUpChanged) {
|
||||
// Compare with the last interrupt time to ensure debounce delay
|
||||
if (currentMillis - buttonUpChangeTime > DEBOUNCE_DELAY) {
|
||||
if (digitalRead(PIN_SW_UP) == LOW) {
|
||||
if (gpio_get_level((gpio_num_t)PIN_SW_UP) == LOW) {
|
||||
// Button pressed
|
||||
buttonUpDownTime = buttonUpChangeTime;
|
||||
bButtonUpDown = true;
|
||||
|
|
@ -1113,7 +1100,7 @@ void CUI::checkButtonStates(unsigned long currentMillis) {
|
|||
if (bButtonDownChanged) {
|
||||
// Compare with the last interrupt time to ensure debounce delay
|
||||
if (currentMillis - buttonDownChangeTime > DEBOUNCE_DELAY) {
|
||||
if (digitalRead(PIN_SW_DOWN) == LOW) {
|
||||
if (gpio_get_level((gpio_num_t)PIN_SW_DOWN) == LOW) {
|
||||
// Button pressed
|
||||
buttonDownDownTime = buttonDownChangeTime;
|
||||
bButtonDownDown = true;
|
||||
|
|
@ -1133,20 +1120,20 @@ void CUI::checkButtonStates(unsigned long currentMillis) {
|
|||
}
|
||||
|
||||
// ISR for the Set button handling
|
||||
ARDUINO_ISR_ATTR void buttonSetISR() {
|
||||
void IRAM_ATTR buttonSetISR(void *) {
|
||||
// Record the time of the button interrupt and set a flag
|
||||
ui.buttonSetChangeTime = millis();
|
||||
ui.bButtonSetChanged = true; // Flag for main loop to process
|
||||
}
|
||||
|
||||
// ISR for the Up button handling
|
||||
ARDUINO_ISR_ATTR void buttonUpISR() {
|
||||
void IRAM_ATTR buttonUpISR(void *) {
|
||||
ui.buttonUpChangeTime = millis();
|
||||
ui.bButtonUpChanged = true; // Flag for main loop to process
|
||||
}
|
||||
|
||||
// ISR for the Down button handling
|
||||
ARDUINO_ISR_ATTR void buttonDownISR() {
|
||||
void IRAM_ATTR buttonDownISR(void *) {
|
||||
ui.buttonDownChangeTime = millis();
|
||||
ui.bButtonDownChanged = true; // Flag for main loop to process
|
||||
}
|
||||
10
UI.h
10
UI.h
|
|
@ -98,6 +98,14 @@ private:
|
|||
void checkButtonStates(unsigned long tickMillis);
|
||||
|
||||
};
|
||||
#endif
|
||||
|
||||
//
|
||||
// Button ISR's
|
||||
//
|
||||
void IRAM_ATTR buttonSetISR(void *);
|
||||
void IRAM_ATTR buttonUpISR(void *);
|
||||
void IRAM_ATTR buttonDownISR(void *);
|
||||
|
||||
extern CUI ui;
|
||||
#endif
|
||||
|
||||
|
|
|
|||
|
|
@ -773,9 +773,6 @@ size_t CWiFiHost::ReceiveData(uint8_t* data, size_t size)
|
|||
m_pDataReceive_data = (char *) data;
|
||||
m_nDataReceive_size = size;
|
||||
m_nDataReceive_received = 0;
|
||||
#ifdef ESP8266
|
||||
digitalWrite(PIN_EXTRA, LED_ON);
|
||||
#endif
|
||||
return size;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -27,6 +27,8 @@
|
|||
#include "mbedtls/aes.h"
|
||||
#include <WiFi.h>
|
||||
#define TAG_FW "FW Update"
|
||||
// GPIO Headers
|
||||
#include "driver/gpio.h"
|
||||
#elif defined(ESP8266)
|
||||
#include <ESP8266WiFi.h>
|
||||
#include <WiFiClient.h>
|
||||
|
|
@ -348,7 +350,7 @@ void ESPUpdateClass::_reset() {
|
|||
_command = U_FLASH;
|
||||
|
||||
if (_ledPin != -1) {
|
||||
digitalWrite(_ledPin, !_ledOn);
|
||||
gpio_set_level((gpio_num_t)_ledPin, !_ledOn);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -775,12 +777,12 @@ size_t ESPUpdateClass::writeStream(Stream &data) {
|
|||
}
|
||||
|
||||
if (_ledPin != -1) {
|
||||
pinMode(_ledPin, OUTPUT);
|
||||
gpio_set_direction((gpio_num_t)_ledPin, GPIO_MODE_OUTPUT);
|
||||
}
|
||||
|
||||
while (remaining()) {
|
||||
if (_ledPin != -1) {
|
||||
digitalWrite(_ledPin, _ledOn);
|
||||
gpio_set_level((gpio_num_t)_ledPin, !_ledOn);
|
||||
}
|
||||
size_t bytesToRead = SPI_FLASH_SEC_SIZE - _bufferLen;
|
||||
if (bytesToRead > remaining()) {
|
||||
|
|
@ -802,7 +804,7 @@ size_t ESPUpdateClass::writeStream(Stream &data) {
|
|||
}
|
||||
|
||||
if (_ledPin != -1) {
|
||||
digitalWrite(_ledPin, !_ledOn);
|
||||
gpio_set_level((gpio_num_t)_ledPin, !_ledOn);
|
||||
}
|
||||
_bufferLen += toRead;
|
||||
if ((_bufferLen == remaining() || _bufferLen == SPI_FLASH_SEC_SIZE) && !_writeBuffer()) {
|
||||
|
|
|
|||
229
zcd.cpp
229
zcd.cpp
|
|
@ -8,48 +8,15 @@
|
|||
// Timer Headers
|
||||
#include "hal/timer_ll.h"
|
||||
#include "hal/timer_types.h"
|
||||
#include "driver/timer.h" // Needed for timer_isr_register
|
||||
#include "rom/ets_sys.h"
|
||||
|
||||
// GPIO Headers
|
||||
#include "driver/gpio.h"
|
||||
#include "driver/periph_ctrl.h"
|
||||
#include "driver/timer.h"
|
||||
|
||||
//#include "driver/timer_types_legacy.h"
|
||||
//#include "esp_intr_alloc.h"
|
||||
|
||||
timg_dev_t *tg0 = &TIMERG0;
|
||||
timg_dev_t *tg1 = &TIMERG1;
|
||||
|
||||
#define SET_TIMER_1_SAFE(duty) do { \
|
||||
timerWrite(timerHeater1, 0); \
|
||||
timerAlarm(timerHeater1, duty, false, 0); \
|
||||
} while(0)
|
||||
|
||||
#define SET_TIMER_2_SAFE(duty) do { \
|
||||
timerWrite(timerHeater2, 0); \
|
||||
timerAlarm(timerHeater2, duty, false, 0); \
|
||||
} while(0)
|
||||
|
||||
#define SET_TIMER_1(duty) do { \
|
||||
tg1->hw_timer[0].loadhi.val = 0; \
|
||||
tg1->hw_timer[0].loadlo.val = 0; \
|
||||
tg1->hw_timer[0].load.val = 1; \
|
||||
\
|
||||
timer_ll_set_alarm_value(tg1, 0, duty); \
|
||||
\
|
||||
tg1->int_clr_timers.t0_int_clr = 1; \
|
||||
\
|
||||
tg1->hw_timer[0].update.val = 1; \
|
||||
} while(0)
|
||||
|
||||
#define SET_TIMER_2(duty) do { \
|
||||
tg1->hw_timer[1].loadhi.val = 0; \
|
||||
tg1->hw_timer[1].loadlo.val = 0; \
|
||||
tg1->hw_timer[1].load.val = 1; \
|
||||
\
|
||||
timer_ll_set_alarm_value(tg1, 1, duty); \
|
||||
\
|
||||
tg1->int_clr_timers.t1_int_clr = 1; \
|
||||
\
|
||||
tg1->hw_timer[1].update.val = 1; \
|
||||
} while(0)
|
||||
|
||||
#define ESP_INTR_FLAG_LEVEL3 (1<<3)
|
||||
#define ESP_INTR_FLAG_LEVEL1 (1<<1)
|
||||
|
|
@ -75,17 +42,19 @@ volatile uint32_t dutyHeater2; // Calculated timerZCD count for TRIAC firing
|
|||
volatile uint8_t zcdACCount;
|
||||
volatile uint8_t zcdLoadCount;
|
||||
|
||||
volatile uint8_t ac1ControlMode = PHASE_CONTROL;
|
||||
volatile uint8_t ac2ControlMode = PHASE_CONTROL;
|
||||
volatile uint8_t ac1ControlMode;
|
||||
volatile uint8_t ac2ControlMode;
|
||||
|
||||
volatile uint8_t fireStatusTimer1 = 0;
|
||||
volatile uint8_t fireStatusTimer2 = 0;
|
||||
volatile uint8_t fireStatusTimer0;
|
||||
volatile uint8_t fireStatusTimer1;
|
||||
|
||||
timg_dev_t *tg0;
|
||||
timg_dev_t *tg1;
|
||||
|
||||
hw_timer_t *timer10K;
|
||||
hw_timer_t *timerDummy;
|
||||
hw_timer_t *timerHeater1;
|
||||
hw_timer_t *timerHeater2;
|
||||
//hw_timer_t *timer10K;
|
||||
//hw_timer_t *timerDummy;
|
||||
//hw_timer_t *timerHeater1;
|
||||
//hw_timer_t *timerHeater2;
|
||||
|
||||
const char fireTable[17][16] {
|
||||
{0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0}, // 0 0%
|
||||
|
|
@ -115,6 +84,9 @@ volatile uint8_t dutyAC2TableIndex = 0;
|
|||
volatile uint8_t zcdACISRCount = 0;
|
||||
volatile uint8_t zcdLoadISRCount = 0;
|
||||
|
||||
volatile bool fire_enable_1 = false;
|
||||
volatile bool fire_enable_2 = false;
|
||||
|
||||
void setAC1ControlMode(uint8_t mode) { ac1ControlMode = mode; }
|
||||
void setAC2ControlMode(uint8_t mode) { ac2ControlMode = mode; }
|
||||
|
||||
|
|
@ -131,7 +103,7 @@ short getHeater2Duty() {
|
|||
}
|
||||
|
||||
// Function to set the duty based on percentage (0 to 10000)
|
||||
ARDUINO_ISR_ATTR void setHeater1Duty(short duty) {
|
||||
void IRAM_ATTR setHeater1Duty(short duty) {
|
||||
if (ac1ControlMode == ZCD_CONTROL) {
|
||||
if (duty > 10000) duty = 10000;
|
||||
dutyAC1TableIndex = (uint8_t)((duty + 10000/32)/625);
|
||||
|
|
@ -162,16 +134,15 @@ ARDUINO_ISR_ATTR void setHeater1Duty(short duty) {
|
|||
}
|
||||
|
||||
// Function to set the duty based on percentage (0 to 10000)
|
||||
ARDUINO_ISR_ATTR void setHeater2Duty(short duty) {
|
||||
void IRAM_ATTR setHeater2Duty(short duty) {
|
||||
if (config.bAC2_OnOff) {
|
||||
if (duty >= 10000) {
|
||||
digitalWrite(PIN_HEATER2, HEATER_ON);
|
||||
duty = 10000;
|
||||
dutyHeater2 = LEADING_PULSE_COUNT;
|
||||
} else {
|
||||
digitalWrite(PIN_HEATER2, HEATER_OFF);
|
||||
duty = 0;
|
||||
dutyHeater2 = 0; // If 0% duty, no pulse (turn off TRIAC)
|
||||
}
|
||||
dutyHeater2 = 0;
|
||||
} else {
|
||||
if (ac2ControlMode == ZCD_CONTROL) {
|
||||
if (duty > 10000) duty = 10000;
|
||||
|
|
@ -203,124 +174,128 @@ ARDUINO_ISR_ATTR void setHeater2Duty(short duty) {
|
|||
ESP_LOGD(TAG_ZCD,"Set Duty: %.2f%%, Timer Count: %u clock cycles\n", duty, dutyHeater2);
|
||||
}
|
||||
|
||||
#define SET_TIMER_0_SAFE(duty) do { \
|
||||
timerWrite(timerHeater1, 0); \
|
||||
timerAlarm(timerHeater1, duty, false, 0); \
|
||||
} while(0)
|
||||
|
||||
void ARDUINO_ISR_ATTR onTimer1() {
|
||||
if (fireStatusTimer1 == 0) {
|
||||
// First Trigger: Turn ON
|
||||
REG_WRITE(GPIO_OUT1_W1TS_REG, (1UL << (PIN_HEATER1 - 32)));
|
||||
fireStatusTimer1 = 1;
|
||||
SET_TIMER_1_SAFE(18); // Schedule OFF pulse 8us later
|
||||
#define SET_TIMER_1_SAFE(duty) do { \
|
||||
timerWrite(timerHeater2, 0); \
|
||||
timerAlarm(timerHeater2, duty, false, 0); \
|
||||
} while(0)
|
||||
|
||||
void IRAM_ATTR timer0ISR(void *) {
|
||||
#ifdef DEBUG_ZCD
|
||||
zcdLoadISRCount++;
|
||||
#endif
|
||||
//timer_group_clr_intr_status_in_isr(TIMER_GROUP_1, TIMER_0);
|
||||
TIMERG1.int_clr_timers.t0_int_clr = 1;
|
||||
if (fire_enable_1) {
|
||||
if (fireStatusTimer0 == 0) {
|
||||
gpio_set_level((gpio_num_t)PIN_HEATER1, 1);
|
||||
fireStatusTimer0 = 1;
|
||||
|
||||
// Set next timer
|
||||
timer_set_counter_value(TIMER_GROUP_1, TIMER_0, 0);
|
||||
timer_set_alarm_value(TIMER_GROUP_1, TIMER_0, 18);
|
||||
timer_set_alarm(TIMER_GROUP_1, TIMER_0, TIMER_ALARM_EN);
|
||||
} else {
|
||||
// Second Trigger: Turn OFF
|
||||
REG_WRITE(GPIO_OUT1_W1TC_REG, (1UL << (PIN_HEATER1 - 32)));
|
||||
gpio_set_level((gpio_num_t)PIN_HEATER1, 0);
|
||||
|
||||
// Suspend Timer until next zcdACISR
|
||||
fire_enable_1 = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void ARDUINO_ISR_ATTR onTimer2() {
|
||||
if (fireStatusTimer2 == 0) {
|
||||
REG_WRITE(GPIO_OUT1_W1TS_REG, (1UL << (PIN_HEATER2 - 32)));
|
||||
fireStatusTimer2 = 1;
|
||||
SET_TIMER_2_SAFE(18);
|
||||
void IRAM_ATTR timer1ISR(void *)
|
||||
{
|
||||
//timer_group_clr_intr_status_in_isr(TIMER_GROUP_1, TIMER_1);
|
||||
TIMERG1.int_clr_timers.t1_int_clr = 1;
|
||||
if (fire_enable_2) {
|
||||
if (fireStatusTimer1 == 0) {
|
||||
gpio_set_level((gpio_num_t)PIN_HEATER2, 1);
|
||||
fireStatusTimer1 = 1;
|
||||
|
||||
// Set next timer
|
||||
timer_set_counter_value(TIMER_GROUP_1, TIMER_1, 0);
|
||||
timer_set_alarm_value(TIMER_GROUP_1, TIMER_1, 18);
|
||||
timer_set_alarm(TIMER_GROUP_1, TIMER_1, TIMER_ALARM_EN);
|
||||
} else {
|
||||
REG_WRITE(GPIO_OUT1_W1TC_REG, (1UL << (PIN_HEATER2 - 32)));
|
||||
gpio_set_level((gpio_num_t)PIN_HEATER2, 0);
|
||||
|
||||
// Suspend Timer until next zcdACISR
|
||||
fire_enable_2 = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Zero-Cross Detection Interrupt Service Routine
|
||||
void ARDUINO_ISR_ATTR zcdACISR() {
|
||||
void IRAM_ATTR zcdACISR(void *) {
|
||||
// 1. Power side AC ZCD Count
|
||||
zcdACISRCount++;
|
||||
|
||||
fireStatusTimer0 = 0;
|
||||
fireStatusTimer1 = 0;
|
||||
fireStatusTimer2 = 0;
|
||||
|
||||
// 3. Heater 1
|
||||
if (ac1ControlMode == ZCD_CONTROL) {
|
||||
if (fireTable[dutyAC1TableIndex][seqStep]) SET_TIMER_1_SAFE(LEADING_ZCD_COUNT);
|
||||
if (fireTable[dutyAC1TableIndex][seqStep]) {
|
||||
timer_set_counter_value(TIMER_GROUP_1, TIMER_0, 0);
|
||||
timer_set_alarm_value(TIMER_GROUP_1, TIMER_0, (uint64_t) LEADING_ZCD_COUNT);
|
||||
timer_set_alarm(TIMER_GROUP_1, TIMER_0, TIMER_ALARM_EN);
|
||||
fire_enable_1 = true;
|
||||
}
|
||||
} else if ( dutyHeater1 >= LEADING_PULSE_COUNT){
|
||||
SET_TIMER_1_SAFE(dutyHeater1);
|
||||
timer_set_counter_value(TIMER_GROUP_1, TIMER_0, 0);
|
||||
timer_set_alarm_value(TIMER_GROUP_1, TIMER_0, (uint64_t) dutyHeater1);
|
||||
timer_set_alarm(TIMER_GROUP_1, TIMER_0, TIMER_ALARM_EN);
|
||||
fire_enable_1 = true;
|
||||
}
|
||||
|
||||
// 4. Heater 2
|
||||
if (ac2ControlMode == ZCD_CONTROL) {
|
||||
if (fireTable[dutyAC2TableIndex][seqStep]) SET_TIMER_2_SAFE(LEADING_ZCD_COUNT);
|
||||
} else if (dutyHeater2 >= LEADING_PULSE_COUNT) {
|
||||
SET_TIMER_2_SAFE(dutyHeater2);
|
||||
if (fireTable[dutyAC2TableIndex][seqStep]) {
|
||||
timer_set_counter_value(TIMER_GROUP_1, TIMER_1, 0);
|
||||
timer_set_alarm_value(TIMER_GROUP_1, TIMER_1, (uint64_t)LEADING_ZCD_COUNT);
|
||||
timer_set_alarm(TIMER_GROUP_1, TIMER_1, TIMER_ALARM_EN);
|
||||
fire_enable_2 = true;
|
||||
}
|
||||
} else if (dutyHeater2 >= LEADING_PULSE_COUNT) {
|
||||
timer_set_counter_value(TIMER_GROUP_1, TIMER_1, 0);
|
||||
timer_set_alarm_value(TIMER_GROUP_1, TIMER_1, (uint64_t)dutyHeater2);
|
||||
timer_set_alarm(TIMER_GROUP_1, TIMER_1, TIMER_ALARM_EN);
|
||||
fire_enable_2 = true;
|
||||
}
|
||||
|
||||
seqStep = ++seqStep & 0x0F;
|
||||
}
|
||||
|
||||
void ARDUINO_ISR_ATTR zcdLoadISR() {
|
||||
void IRAM_ATTR zcdLoadISR(void *) {
|
||||
// Load side AC ZCD Count
|
||||
#ifndef DEBUG_ZCD
|
||||
zcdLoadISRCount++;
|
||||
#endif
|
||||
}
|
||||
|
||||
void setupZCD() {
|
||||
periph_module_enable(PERIPH_TIMG0_MODULE);
|
||||
periph_module_enable(PERIPH_TIMG1_MODULE);
|
||||
pinMode(PIN_ZCD_AC, INPUT);
|
||||
pinMode(PIN_ZCD_LOAD, INPUT);
|
||||
pinMode(PIN_HEATER1, OUTPUT);
|
||||
pinMode(PIN_HEATER2, OUTPUT);
|
||||
digitalWrite(PIN_HEATER1, HEATER_OFF);
|
||||
digitalWrite(PIN_HEATER2, HEATER_OFF);
|
||||
|
||||
//===============================================================================
|
||||
// Initialize variables
|
||||
dutyHeater1 = 0; // Calculated timerHeater1 count for TRIAC firing
|
||||
dutyHeater2 = 0; // Calculated timerZCD count for TRIAC firing
|
||||
zcdACCount = 0;
|
||||
zcdLoadCount = 0;
|
||||
timerHeater1 = NULL;
|
||||
|
||||
// Test
|
||||
config.ac1ControlMode = PHASE_CONTROL;
|
||||
config.ac2ControlMode = PHASE_CONTROL;
|
||||
|
||||
fireStatusTimer0 = 0;
|
||||
fireStatusTimer1 = 0;
|
||||
|
||||
tg0 = &TIMERG0;
|
||||
tg1 = &TIMERG1;
|
||||
ac1ControlMode = config.ac1ControlMode;
|
||||
ac2ControlMode = config.ac2ControlMode;
|
||||
|
||||
//===============================================================================
|
||||
|
||||
// --- 0. Hardware Config for TG0-Timer0 (g_millis)
|
||||
timer_ll_set_clock_prescale(tg0, 0, 8000); // 10KHz
|
||||
timer_ll_set_count_direction(tg0, 0, GPTIMER_COUNT_UP);
|
||||
tg0->hw_timer[0].loadhi.val = 0UL;
|
||||
tg0->hw_timer[0].loadlo.val = 0UL;
|
||||
tg0->hw_timer[0].load.val = 1UL;
|
||||
timer_ll_enable_alarm(tg0, 0, false); // No ISR needed for g_millis
|
||||
timer_ll_enable_counter(tg0, 0, true);
|
||||
|
||||
attachInterrupt(PIN_ZCD_AC, zcdACISR, CHANGE); // Attach zero-cross detection ISR
|
||||
attachInterrupt(PIN_ZCD_LOAD, zcdLoadISR, CHANGE); // Attach zero-cross detection ISR
|
||||
|
||||
// Initialize and configure the timer
|
||||
if ((timer10K = timerBegin(10000)) != NULL) {
|
||||
// TG0-Timer0
|
||||
timerStop(timer10K); // Ensure timer is stopped initially
|
||||
timerStart(timer10K); // Explicitly start the timer after setup
|
||||
|
||||
}
|
||||
|
||||
if ((timerDummy = timerBegin(1000000)) != NULL) {
|
||||
// TG0-Timer1
|
||||
timerStop(timerDummy); // Ensure timer is stopped initially
|
||||
timerStart(timerDummy); // Explicitly start the timer after setup
|
||||
}
|
||||
|
||||
if ((timerHeater1 = timerBegin(1000000)) != NULL) {
|
||||
// TG1-Timer0
|
||||
timerAttachInterrupt(timerHeater1, &onTimer1); // Attach TRIAC firing routine
|
||||
timerStop(timerHeater1); // Ensure timer is stopped initially
|
||||
timerStart(timerHeater1); // Explicitly start the timer after setup
|
||||
|
||||
}
|
||||
|
||||
if ((timerHeater2 = timerBegin(1000000)) != NULL) {
|
||||
// TG1-Timer1
|
||||
timerAttachInterrupt(timerHeater2, &onTimer2); // Attach TRIAC firing routine
|
||||
timerStop(timerHeater2); // Ensure timer is stopped initially
|
||||
timerStart(timerHeater2); // Explicitly start the timer after setup
|
||||
}
|
||||
}
|
||||
|
||||
void setACLoadStatus(uint32_t tNow) {
|
||||
|
|
|
|||
10
zcd.h
10
zcd.h
|
|
@ -6,7 +6,17 @@ void setupZCD();
|
|||
void setHeater1Duty(short duty);
|
||||
void setHeater2Duty(short duty);
|
||||
short getHeater1Duty();
|
||||
|
||||
void IRAM_ATTR zcdACISR(void *);
|
||||
void IRAM_ATTR zcdLoadISR(void *);
|
||||
void IRAM_ATTR timer0ISR(void *);
|
||||
void IRAM_ATTR timer1ISR(void *);
|
||||
|
||||
#define DEBUG_ZCD
|
||||
#define ENABLE_TIMERS
|
||||
|
||||
#if defined(ESP8266)
|
||||
void setMistDuty(short duty);
|
||||
#endif
|
||||
|
||||
#endif
|
||||
Loading…
Reference in New Issue
Block a user