From ad61b62feb860e56b83a895bfa55bf197ced5ebd Mon Sep 17 00:00:00 2001 From: Wolfgang Villing Date: Mon, 8 Jul 2019 22:19:13 +0200 Subject: [PATCH 1/7] Fixed samplecount to completely fill i2s DMA --- Marlin/src/HAL/HAL_ESP32/i2s.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Marlin/src/HAL/HAL_ESP32/i2s.cpp b/Marlin/src/HAL/HAL_ESP32/i2s.cpp index 557714f870f8..47e95f118f1d 100644 --- a/Marlin/src/HAL/HAL_ESP32/i2s.cpp +++ b/Marlin/src/HAL/HAL_ESP32/i2s.cpp @@ -146,7 +146,7 @@ void stepperTask(void* parameter) { xQueueReceive(dma.queue, &dma.current, portMAX_DELAY); dma.rw_pos = 0; - for (i = 0; i < DMA_SAMPLE_COUNT; i++) { + while (dma.rw_pos < DMA_SAMPLE_COUNT) { // Fill with the port data post pulse_phase until the next step if (remaining) { i2s_push_sample(); From c521fc4485e646b614dd28180c4554baa986e7a6 Mon Sep 17 00:00:00 2001 From: Wolfgang Villing Date: Tue, 9 Jul 2019 23:27:05 +0200 Subject: [PATCH 2/7] Using split i2s - first 16bits from DMA - other 16bits from direct register. --- Marlin/src/HAL/HAL_ESP32/i2s.cpp | 16 +++++++++++----- 1 file changed, 11 insertions(+), 5 deletions(-) diff --git a/Marlin/src/HAL/HAL_ESP32/i2s.cpp b/Marlin/src/HAL/HAL_ESP32/i2s.cpp index 47e95f118f1d..1ad96ac61353 100644 --- a/Marlin/src/HAL/HAL_ESP32/i2s.cpp +++ b/Marlin/src/HAL/HAL_ESP32/i2s.cpp @@ -56,7 +56,7 @@ static i2s_dev_t* I2S[I2S_NUM_MAX] = {&I2S0, &I2S1}; static i2s_dma_t dma; // output value -uint32_t i2s_port_data; +uint32_t i2s_port_data = 0; #define I2S_ENTER_CRITICAL() portENTER_CRITICAL(&i2s_spinlock[i2s_num]) #define I2S_EXIT_CRITICAL() portEXIT_CRITICAL(&i2s_spinlock[i2s_num]) @@ -140,7 +140,7 @@ static void IRAM_ATTR i2s_intr_handler_default(void *arg) { } void stepperTask(void* parameter) { - uint32_t i, remaining = 0; + uint32_t remaining = 0; while (1) { xQueueReceive(dma.queue, &dma.current, portMAX_DELAY); @@ -254,7 +254,7 @@ int i2s_init() { I2S0.fifo_conf.dscr_en = 0; - I2S0.conf_chan.tx_chan_mod = 0; + I2S0.conf_chan.tx_chan_mod = 4; I2S0.fifo_conf.tx_fifo_mod = 0; I2S0.conf.tx_mono = 0; @@ -314,11 +314,17 @@ int i2s_init() { } void i2s_write(uint8_t pin, uint8_t val) { - SET_BIT_TO(i2s_port_data, pin, val); + if (pin < 16) + SET_BIT_TO(i2s_port_data, pin, val); + else + SET_BIT_TO(I2S0.conf_single_data, pin, val); } uint8_t i2s_state(uint8_t pin) { - return TEST(i2s_port_data, pin); + if (pin < 16) + return TEST(i2s_port_data, pin); + + return TEST(I2S0.conf_single_data, pin); } void i2s_push_sample() { From e7b64ee5e502e3617ad16bea98b91ead13dffec3 Mon Sep 17 00:00:00 2001 From: Wolfgang Villing Date: Thu, 11 Jul 2019 17:37:56 +0200 Subject: [PATCH 3/7] Handle PWM via timer. Even handle PWM for i2s register-outputs, leave ledc system to servos --- Marlin/src/HAL/HAL_ESP32/HAL.cpp | 60 ++++++++++++++++--- Marlin/src/HAL/HAL_ESP32/HAL_timers_ESP32.cpp | 25 ++++---- Marlin/src/HAL/HAL_ESP32/HAL_timers_ESP32.h | 12 +++- Marlin/src/HAL/HAL_ESP32/fastio_ESP32.h | 2 +- 4 files changed, 75 insertions(+), 24 deletions(-) diff --git a/Marlin/src/HAL/HAL_ESP32/HAL.cpp b/Marlin/src/HAL/HAL_ESP32/HAL.cpp index f37a3a4ef83d..36403e15d2e7 100644 --- a/Marlin/src/HAL/HAL_ESP32/HAL.cpp +++ b/Marlin/src/HAL/HAL_ESP32/HAL.cpp @@ -23,6 +23,7 @@ #ifdef ARDUINO_ARCH_ESP32 #include "HAL.h" +#include "HAL_timers_ESP32.h" #include #include #include @@ -67,6 +68,9 @@ uint16_t HAL_adc_result; // ------------------------ esp_adc_cal_characteristics_t characteristics; +volatile int numPWMUsed=0; +volatile int pwmPins[MAX_PWM_PINS]; +volatile int pwmValues[MAX_PWM_PINS]; // ------------------------ // Public functions @@ -91,6 +95,9 @@ void HAL_init_board(void) { #endif server.begin(); #endif + + HAL_timer_start(PWM_TIMER_NUM, PWM_TIMER_FREQUENCY); + } void HAL_idletask(void) { @@ -173,20 +180,55 @@ void HAL_adc_start_conversion(uint8_t adc_pin) { } void analogWrite(pin_t pin, int value) { + int idx=-1; + + // Search Pin + for (int i=0; i= MAX_PWM_PINS-1) + return; + + // take new slot for pin + idx = numPWMUsed; + pwmPins[idx] = pin; + ++numPWMUsed; + } + + // Use 7bit internal value - add 1 to have 100% high at 255 + pwmValues[idx] = (value + 1) / 2; +} - if (!PWM_PIN(pin)) return; +// Handle PWM timer interrupt +HAL_PWM_TIMER_ISR(){ + HAL_timer_isr_prologue(PWM_TIMER_NUM); - static int cnt_channel = 1, - pin_to_channel[40] = {}; - if (pin_to_channel[pin] == 0) { - ledcAttachPin(pin, cnt_channel); - ledcSetup(cnt_channel, 490, 8); - ledcWrite(cnt_channel, value); + static unsigned int count = 0; - pin_to_channel[pin] = cnt_channel++; + for (int i=0; i127) + count=0; + + HAL_timer_isr_epilogue(PWM_TIMER_NUM); } + #endif // ARDUINO_ARCH_ESP32 diff --git a/Marlin/src/HAL/HAL_ESP32/HAL_timers_ESP32.cpp b/Marlin/src/HAL/HAL_ESP32/HAL_timers_ESP32.cpp index 27bd42bdf886..fc90af4b8fd5 100644 --- a/Marlin/src/HAL/HAL_ESP32/HAL_timers_ESP32.cpp +++ b/Marlin/src/HAL/HAL_ESP32/HAL_timers_ESP32.cpp @@ -47,7 +47,7 @@ static timg_dev_t *TG[2] = {&TIMERG0, &TIMERG1}; const tTimerConfig TimerConfig [NUM_HARDWARE_TIMERS] = { { TIMER_GROUP_0, TIMER_0, STEPPER_TIMER_PRESCALE, stepTC_Handler }, // 0 - Stepper { TIMER_GROUP_0, TIMER_1, TEMP_TIMER_PRESCALE, tempTC_Handler }, // 1 - Temperature - { TIMER_GROUP_1, TIMER_0, 1, nullptr }, // 2 + { TIMER_GROUP_1, TIMER_0, PWM_TIMER_PRESCALE, pwmTC_Handler }, // 2 - PWM { TIMER_GROUP_1, TIMER_1, 1, nullptr }, // 3 }; @@ -55,28 +55,28 @@ const tTimerConfig TimerConfig [NUM_HARDWARE_TIMERS] = { // Public functions // ------------------------ -void IRAM_ATTR timer_group0_isr(void *para) { - const int timer_idx = (int)para; +void IRAM_ATTR timer_isr(void *para) { + const tTimerConfig& timer = TimerConfig[(int)para]; // Retrieve the interrupt status and the counter value // from the timer that reported the interrupt - uint32_t intr_status = TIMERG0.int_st_timers.val; - TIMERG0.hw_timer[timer_idx].update = 1; + uint32_t intr_status = TG[timer.group]->int_st_timers.val; + TG[timer.group]->hw_timer[timer.idx].update = 1; // Clear the interrupt - if (intr_status & BIT(timer_idx)) { - switch (timer_idx) { - case TIMER_0: TIMERG0.int_clr_timers.t0 = 1; break; - case TIMER_1: TIMERG0.int_clr_timers.t1 = 1; break; + if (intr_status & BIT(timer.idx)) { + switch (timer.idx) { + case TIMER_0: TG[timer.group]->int_clr_timers.t0 = 1; break; + case TIMER_1: TG[timer.group]->int_clr_timers.t1 = 1; break; + case TIMER_MAX: break; } } - const tTimerConfig timer = TimerConfig[timer_idx]; timer.fn(); // After the alarm has been triggered // Enable it again so it gets triggered the next time - TIMERG0.hw_timer[timer_idx].config.alarm_en = TIMER_ALARM_EN; + TG[timer.group]->hw_timer[timer.idx].config.alarm_en = TIMER_ALARM_EN; } /** @@ -106,8 +106,7 @@ void HAL_timer_start(const uint8_t timer_num, uint32_t frequency) { timer_enable_intr(timer.group, timer.idx); - // TODO need to deal with timer_group1_isr - timer_isr_register(timer.group, timer.idx, timer_group0_isr, (void*)timer.idx, 0, nullptr); + timer_isr_register(timer.group, timer.idx, timer_isr, (void*)timer_num, 0, nullptr); timer_start(timer.group, timer.idx); } diff --git a/Marlin/src/HAL/HAL_ESP32/HAL_timers_ESP32.h b/Marlin/src/HAL/HAL_ESP32/HAL_timers_ESP32.h index d3da0aef8001..0806fd2c776e 100644 --- a/Marlin/src/HAL/HAL_ESP32/HAL_timers_ESP32.h +++ b/Marlin/src/HAL/HAL_ESP32/HAL_timers_ESP32.h @@ -40,6 +40,7 @@ typedef uint64_t hal_timer_t; #define STEP_TIMER_NUM 0 // index of timer to use for stepper #define TEMP_TIMER_NUM 1 // index of timer to use for temperature +#define PWM_TIMER_NUM 2 // index of timer to use for PWM outputs #define PULSE_TIMER_NUM STEP_TIMER_NUM #define HAL_TIMER_RATE APB_CLK_FREQ // frequency of timer peripherals @@ -59,6 +60,14 @@ typedef uint64_t hal_timer_t; #define TEMP_TIMER_PRESCALE 1000 // prescaler for setting Temp timer, 72Khz #define TEMP_TIMER_FREQUENCY 1000 // temperature interrupt frequency +#define PWM_TIMER_PRESCALE 10 +#if ENABLED(FAST_PWM_FAN) + #define PWM_TIMER_FREQUENCY FAST_PWM_FAN_FREQUENCY +#else + #define PWM_TIMER_FREQUENCY (50*128) // 50Hz and 7bit resolution +#endif +#define MAX_PWM_PINS 32 // Number of PWM pin-slots + #define PULSE_TIMER_RATE STEPPER_TIMER_RATE // frequency of pulse timer #define PULSE_TIMER_PRESCALE STEPPER_TIMER_PRESCALE #define PULSE_TIMER_TICKS_PER_US STEPPER_TIMER_TICKS_PER_US @@ -72,10 +81,11 @@ typedef uint64_t hal_timer_t; #define HAL_TEMP_TIMER_ISR() extern "C" void tempTC_Handler(void) #define HAL_STEP_TIMER_ISR() extern "C" void stepTC_Handler(void) +#define HAL_PWM_TIMER_ISR() extern "C" void pwmTC_Handler(void) extern "C" void tempTC_Handler(void); extern "C" void stepTC_Handler(void); - +extern "C" void pwmTC_Handler(void); // ------------------------ // Types diff --git a/Marlin/src/HAL/HAL_ESP32/fastio_ESP32.h b/Marlin/src/HAL/HAL_ESP32/fastio_ESP32.h index 364777409587..1641116b9023 100644 --- a/Marlin/src/HAL/HAL_ESP32/fastio_ESP32.h +++ b/Marlin/src/HAL/HAL_ESP32/fastio_ESP32.h @@ -66,7 +66,7 @@ #define extDigitalWrite(IO,V) digitalWrite(IO,V) // PWM outputs -#define PWM_PIN(P) (P < 34) // NOTE Pins >= 34 are input only on ESP32, so they can't be used for output. +#define PWM_PIN(P) (P < 34 || P > 127) // NOTE Pins >= 34 are input only on ESP32, so they can't be used for output. // Toggle pin value #define TOGGLE(IO) WRITE(IO, !READ(IO)) From 43a2405537e45cdf19390f8848a39d846bb2a246 Mon Sep 17 00:00:00 2001 From: Wolfgang Villing Date: Fri, 12 Jul 2019 13:09:37 +0200 Subject: [PATCH 4/7] Use Split i2s mode only when I2S_STEPPER_SPLIT_STREAM is defined --- Marlin/src/HAL/HAL_ESP32/i2s.cpp | 26 +++++++++++++++++--------- 1 file changed, 17 insertions(+), 9 deletions(-) diff --git a/Marlin/src/HAL/HAL_ESP32/i2s.cpp b/Marlin/src/HAL/HAL_ESP32/i2s.cpp index 1ad96ac61353..cdf0c3f1aa5b 100644 --- a/Marlin/src/HAL/HAL_ESP32/i2s.cpp +++ b/Marlin/src/HAL/HAL_ESP32/i2s.cpp @@ -254,7 +254,11 @@ int i2s_init() { I2S0.fifo_conf.dscr_en = 0; - I2S0.conf_chan.tx_chan_mod = 4; + #if ENABLED(I2S_STEPPER_SPLIT_STREAM) + I2S0.conf_chan.tx_chan_mod = 4; + #else + I2S0.conf_chan.tx_chan_mod = 0; + #endif I2S0.fifo_conf.tx_fifo_mod = 0; I2S0.conf.tx_mono = 0; @@ -314,17 +318,21 @@ int i2s_init() { } void i2s_write(uint8_t pin, uint8_t val) { - if (pin < 16) - SET_BIT_TO(i2s_port_data, pin, val); - else - SET_BIT_TO(I2S0.conf_single_data, pin, val); + #if ENABLED(I2S_STEPPER_SPLIT_STREAM) + if (pin >= 16) { + SET_BIT_TO(I2S0.conf_single_data, pin, val); + return; + } + #endif + SET_BIT_TO(i2s_port_data, pin, val); } uint8_t i2s_state(uint8_t pin) { - if (pin < 16) - return TEST(i2s_port_data, pin); - - return TEST(I2S0.conf_single_data, pin); + #if ENABLED(I2S_STEPPER_SPLIT_STREAM) + if (pin >= 16) + return TEST(I2S0.conf_single_data, pin); + #endif + return TEST(i2s_port_data, pin); } void i2s_push_sample() { From 2ee5878a6a5a08b0a6cbc1b0aa0c4eb29cae810e Mon Sep 17 00:00:00 2001 From: Wolfgang Villing Date: Sun, 14 Jul 2019 13:20:53 +0200 Subject: [PATCH 5/7] Use ledc for internal pins, PWM Timer for external only --- Marlin/src/HAL/HAL_ESP32/HAL.cpp | 23 ++++++++++++++++++++--- 1 file changed, 20 insertions(+), 3 deletions(-) diff --git a/Marlin/src/HAL/HAL_ESP32/HAL.cpp b/Marlin/src/HAL/HAL_ESP32/HAL.cpp index 36403e15d2e7..b068b7204d40 100644 --- a/Marlin/src/HAL/HAL_ESP32/HAL.cpp +++ b/Marlin/src/HAL/HAL_ESP32/HAL.cpp @@ -95,9 +95,6 @@ void HAL_init_board(void) { #endif server.begin(); #endif - - HAL_timer_start(PWM_TIMER_NUM, PWM_TIMER_FREQUENCY); - } void HAL_idletask(void) { @@ -180,6 +177,22 @@ void HAL_adc_start_conversion(uint8_t adc_pin) { } void analogWrite(pin_t pin, int value) { + // Use ledc hardware for internal pins + if (pin < 34){ + static int cnt_channel = 1, + pin_to_channel[40] = {}; + if (pin_to_channel[pin] == 0) { + ledcAttachPin(pin, cnt_channel); + ledcSetup(cnt_channel, 490, 8); + ledcWrite(cnt_channel, value); + + pin_to_channel[pin] = cnt_channel++; + } + + ledcWrite(pin_to_channel[pin], value); + return; + } + int idx=-1; // Search Pin @@ -200,6 +213,10 @@ void analogWrite(pin_t pin, int value) { // take new slot for pin idx = numPWMUsed; pwmPins[idx] = pin; + // Start timer on first use + if (numPWMUsed == 0) + HAL_timer_start(PWM_TIMER_NUM, PWM_TIMER_FREQUENCY); + ++numPWMUsed; } From f93fca840b7ce7af50d3dad156c04efdabe7ae6d Mon Sep 17 00:00:00 2001 From: Scott Lahteine Date: Sun, 14 Jul 2019 10:00:24 -0500 Subject: [PATCH 6/7] Update HAL.cpp --- Marlin/src/HAL/HAL_ESP32/HAL.cpp | 60 ++++++++++++-------------------- 1 file changed, 22 insertions(+), 38 deletions(-) diff --git a/Marlin/src/HAL/HAL_ESP32/HAL.cpp b/Marlin/src/HAL/HAL_ESP32/HAL.cpp index b068b7204d40..37bba692603a 100644 --- a/Marlin/src/HAL/HAL_ESP32/HAL.cpp +++ b/Marlin/src/HAL/HAL_ESP32/HAL.cpp @@ -68,9 +68,9 @@ uint16_t HAL_adc_result; // ------------------------ esp_adc_cal_characteristics_t characteristics; -volatile int numPWMUsed=0; -volatile int pwmPins[MAX_PWM_PINS]; -volatile int pwmValues[MAX_PWM_PINS]; +volatile int numPWMUsed = 0, + pwmPins[MAX_PWM_PINS], + pwmValues[MAX_PWM_PINS]; // ------------------------ // Public functions @@ -172,50 +172,39 @@ void HAL_adc_init() { void HAL_adc_start_conversion(uint8_t adc_pin) { uint32_t mv; esp_adc_cal_get_voltage((adc_channel_t)get_channel(adc_pin), &characteristics, &mv); - - HAL_adc_result = mv*1023.0/3300.0; + HAL_adc_result = mv * 1023.0 / 3300.0; } void analogWrite(pin_t pin, int value) { // Use ledc hardware for internal pins - if (pin < 34){ - static int cnt_channel = 1, - pin_to_channel[40] = {}; + if (pin < 34) { + static int cnt_channel = 1, pin_to_channel[40] = { 0 }; if (pin_to_channel[pin] == 0) { ledcAttachPin(pin, cnt_channel); ledcSetup(cnt_channel, 490, 8); ledcWrite(cnt_channel, value); - pin_to_channel[pin] = cnt_channel++; } - - ledcWrite(pin_to_channel[pin], value); - return; + ledcWrite(pin_to_channel[pin], value); + return; } - int idx=-1; + int idx = -1; // Search Pin - for (int i=0; i= MAX_PWM_PINS-1) - return; + if (numPWMUsed >= MAX_PWM_PINS) return; - // take new slot for pin + // Take new slot for pin idx = numPWMUsed; pwmPins[idx] = pin; // Start timer on first use - if (numPWMUsed == 0) - HAL_timer_start(PWM_TIMER_NUM, PWM_TIMER_FREQUENCY); + if (idx == 0) HAL_timer_start(PWM_TIMER_NUM, PWM_TIMER_FREQUENCY); ++numPWMUsed; } @@ -225,27 +214,22 @@ void analogWrite(pin_t pin, int value) { } // Handle PWM timer interrupt -HAL_PWM_TIMER_ISR(){ +HAL_PWM_TIMER_ISR() { HAL_timer_isr_prologue(PWM_TIMER_NUM); - static unsigned int count = 0; + static uint8_t count = 0; - for (int i=0; i127) - count=0; + count = (count + 1) & 0x7F; HAL_timer_isr_epilogue(PWM_TIMER_NUM); } - #endif // ARDUINO_ARCH_ESP32 From 1a05b39783a3566c9e3d1ffbd92a45bf2cb58aa9 Mon Sep 17 00:00:00 2001 From: Scott Lahteine Date: Sun, 14 Jul 2019 10:02:37 -0500 Subject: [PATCH 7/7] Update i2s.cpp --- Marlin/src/HAL/HAL_ESP32/i2s.cpp | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/Marlin/src/HAL/HAL_ESP32/i2s.cpp b/Marlin/src/HAL/HAL_ESP32/i2s.cpp index cdf0c3f1aa5b..1f7c508cf1c4 100644 --- a/Marlin/src/HAL/HAL_ESP32/i2s.cpp +++ b/Marlin/src/HAL/HAL_ESP32/i2s.cpp @@ -254,11 +254,13 @@ int i2s_init() { I2S0.fifo_conf.dscr_en = 0; - #if ENABLED(I2S_STEPPER_SPLIT_STREAM) - I2S0.conf_chan.tx_chan_mod = 4; - #else - I2S0.conf_chan.tx_chan_mod = 0; - #endif + I2S0.conf_chan.tx_chan_mod = ( + #if ENABLED(I2S_STEPPER_SPLIT_STREAM) + 4 + #else + 0 + #endif + ); I2S0.fifo_conf.tx_fifo_mod = 0; I2S0.conf.tx_mono = 0; @@ -329,8 +331,7 @@ void i2s_write(uint8_t pin, uint8_t val) { uint8_t i2s_state(uint8_t pin) { #if ENABLED(I2S_STEPPER_SPLIT_STREAM) - if (pin >= 16) - return TEST(I2S0.conf_single_data, pin); + if (pin >= 16) return TEST(I2S0.conf_single_data, pin); #endif return TEST(i2s_port_data, pin); }