Преглед на файлове

Fix ESP32 i2s stream, add PWM to extended pins (#14592)

Ringel преди 4 години
родител
ревизия
e139c1d9d9

+ 54
- 11
Marlin/src/HAL/HAL_ESP32/HAL.cpp Целия файл

@@ -23,6 +23,7 @@
23 23
 #ifdef ARDUINO_ARCH_ESP32
24 24
 
25 25
 #include "HAL.h"
26
+#include "HAL_timers_ESP32.h"
26 27
 #include <rom/rtc.h>
27 28
 #include <driver/adc.h>
28 29
 #include <esp_adc_cal.h>
@@ -67,6 +68,9 @@ uint16_t HAL_adc_result;
67 68
 // ------------------------
68 69
 
69 70
 esp_adc_cal_characteristics_t characteristics;
71
+volatile int numPWMUsed = 0,
72
+             pwmPins[MAX_PWM_PINS],
73
+             pwmValues[MAX_PWM_PINS];
70 74
 
71 75
 // ------------------------
72 76
 // Public functions
@@ -168,25 +172,64 @@ void HAL_adc_init() {
168 172
 void HAL_adc_start_conversion(uint8_t adc_pin) {
169 173
   uint32_t mv;
170 174
   esp_adc_cal_get_voltage((adc_channel_t)get_channel(adc_pin), &characteristics, &mv);
171
-
172
-  HAL_adc_result = mv*1023.0/3300.0;
175
+  HAL_adc_result = mv * 1023.0 / 3300.0;
173 176
 }
174 177
 
175 178
 void analogWrite(pin_t pin, int value) {
179
+  // Use ledc hardware for internal pins
180
+  if (pin < 34) {
181
+    static int cnt_channel = 1, pin_to_channel[40] = { 0 };
182
+    if (pin_to_channel[pin] == 0) {
183
+      ledcAttachPin(pin, cnt_channel);
184
+      ledcSetup(cnt_channel, 490, 8);
185
+      ledcWrite(cnt_channel, value);
186
+      pin_to_channel[pin] = cnt_channel++;
187
+    }
188
+    ledcWrite(pin_to_channel[pin], value);
189
+    return;
190
+  }
191
+
192
+  int idx = -1;
176 193
 
177
-  if (!PWM_PIN(pin)) return;
194
+  // Search Pin
195
+  for (int i = 0; i < numPWMUsed; ++i)
196
+    if (pwmPins[i] == pin) { idx = i; break; }
178 197
 
179
-  static int cnt_channel = 1,
180
-             pin_to_channel[40] = {};
181
-  if (pin_to_channel[pin] == 0) {
182
-    ledcAttachPin(pin, cnt_channel);
183
-    ledcSetup(cnt_channel, 490, 8);
184
-    ledcWrite(cnt_channel, value);
198
+  // not found ?
199
+  if (idx < 0) {
200
+    // No slots remaining
201
+    if (numPWMUsed >= MAX_PWM_PINS) return;
185 202
 
186
-    pin_to_channel[pin] = cnt_channel++;
203
+    // Take new slot for pin
204
+    idx = numPWMUsed;
205
+    pwmPins[idx] = pin;
206
+    // Start timer on first use
207
+    if (idx == 0) HAL_timer_start(PWM_TIMER_NUM, PWM_TIMER_FREQUENCY);
208
+
209
+    ++numPWMUsed;
187 210
   }
188 211
 
189
-  ledcWrite(pin_to_channel[pin], value);
212
+  // Use 7bit internal value - add 1 to have 100% high at 255
213
+  pwmValues[idx] = (value + 1) / 2;
214
+}
215
+
216
+// Handle PWM timer interrupt
217
+HAL_PWM_TIMER_ISR() {
218
+  HAL_timer_isr_prologue(PWM_TIMER_NUM);
219
+
220
+  static uint8_t count = 0;
221
+
222
+  for (int i = 0; i < numPWMUsed; ++i) {
223
+    if (count == 0)                   // Start of interval
224
+      WRITE(pwmPins[i], pwmValues[i] ? HIGH : LOW);
225
+    else if (pwmValues[i] == count)   // End of duration
226
+      WRITE(pwmPins[i], LOW);
227
+  }
228
+
229
+  // 128 for 7 Bit resolution
230
+  count = (count + 1) & 0x7F;
231
+
232
+  HAL_timer_isr_epilogue(PWM_TIMER_NUM);
190 233
 }
191 234
 
192 235
 #endif // ARDUINO_ARCH_ESP32

+ 12
- 13
Marlin/src/HAL/HAL_ESP32/HAL_timers_ESP32.cpp Целия файл

@@ -47,7 +47,7 @@ static timg_dev_t *TG[2] = {&TIMERG0, &TIMERG1};
47 47
 const tTimerConfig TimerConfig [NUM_HARDWARE_TIMERS] = {
48 48
   { TIMER_GROUP_0, TIMER_0, STEPPER_TIMER_PRESCALE, stepTC_Handler }, // 0 - Stepper
49 49
   { TIMER_GROUP_0, TIMER_1,    TEMP_TIMER_PRESCALE, tempTC_Handler }, // 1 - Temperature
50
-  { TIMER_GROUP_1, TIMER_0,                      1, nullptr }, // 2
50
+  { TIMER_GROUP_1, TIMER_0,     PWM_TIMER_PRESCALE, pwmTC_Handler  }, // 2 - PWM
51 51
   { TIMER_GROUP_1, TIMER_1,                      1, nullptr }, // 3
52 52
 };
53 53
 
@@ -55,28 +55,28 @@ const tTimerConfig TimerConfig [NUM_HARDWARE_TIMERS] = {
55 55
 // Public functions
56 56
 // ------------------------
57 57
 
58
-void IRAM_ATTR timer_group0_isr(void *para) {
59
-  const int timer_idx = (int)para;
58
+void IRAM_ATTR timer_isr(void *para) {
59
+  const tTimerConfig& timer = TimerConfig[(int)para];
60 60
 
61 61
   // Retrieve the interrupt status and the counter value
62 62
   // from the timer that reported the interrupt
63
-  uint32_t intr_status = TIMERG0.int_st_timers.val;
64
-  TIMERG0.hw_timer[timer_idx].update = 1;
63
+  uint32_t intr_status = TG[timer.group]->int_st_timers.val;
64
+  TG[timer.group]->hw_timer[timer.idx].update = 1;
65 65
 
66 66
   // Clear the interrupt
67
-  if (intr_status & BIT(timer_idx)) {
68
-    switch (timer_idx) {
69
-      case TIMER_0: TIMERG0.int_clr_timers.t0 = 1; break;
70
-      case TIMER_1: TIMERG0.int_clr_timers.t1 = 1; break;
67
+  if (intr_status & BIT(timer.idx)) {
68
+    switch (timer.idx) {
69
+      case TIMER_0: TG[timer.group]->int_clr_timers.t0 = 1; break;
70
+      case TIMER_1: TG[timer.group]->int_clr_timers.t1 = 1; break;
71
+      case TIMER_MAX: break;
71 72
     }
72 73
   }
73 74
 
74
-  const tTimerConfig timer = TimerConfig[timer_idx];
75 75
   timer.fn();
76 76
 
77 77
   // After the alarm has been triggered
78 78
   // Enable it again so it gets triggered the next time
79
-  TIMERG0.hw_timer[timer_idx].config.alarm_en = TIMER_ALARM_EN;
79
+  TG[timer.group]->hw_timer[timer.idx].config.alarm_en = TIMER_ALARM_EN;
80 80
 }
81 81
 
82 82
 /**
@@ -106,8 +106,7 @@ void HAL_timer_start(const uint8_t timer_num, uint32_t frequency) {
106 106
 
107 107
   timer_enable_intr(timer.group, timer.idx);
108 108
 
109
-  // TODO need to deal with timer_group1_isr
110
-  timer_isr_register(timer.group, timer.idx, timer_group0_isr, (void*)timer.idx, 0, nullptr);
109
+  timer_isr_register(timer.group, timer.idx, timer_isr, (void*)timer_num, 0, nullptr);
111 110
 
112 111
   timer_start(timer.group, timer.idx);
113 112
 }

+ 11
- 1
Marlin/src/HAL/HAL_ESP32/HAL_timers_ESP32.h Целия файл

@@ -40,6 +40,7 @@ typedef uint64_t hal_timer_t;
40 40
 
41 41
 #define STEP_TIMER_NUM 0  // index of timer to use for stepper
42 42
 #define TEMP_TIMER_NUM 1  // index of timer to use for temperature
43
+#define PWM_TIMER_NUM  2  // index of timer to use for PWM outputs
43 44
 #define PULSE_TIMER_NUM STEP_TIMER_NUM
44 45
 
45 46
 #define HAL_TIMER_RATE APB_CLK_FREQ // frequency of timer peripherals
@@ -59,6 +60,14 @@ typedef uint64_t hal_timer_t;
59 60
 #define TEMP_TIMER_PRESCALE    1000 // prescaler for setting Temp timer, 72Khz
60 61
 #define TEMP_TIMER_FREQUENCY   1000 // temperature interrupt frequency
61 62
 
63
+#define PWM_TIMER_PRESCALE       10
64
+#if ENABLED(FAST_PWM_FAN)
65
+  #define PWM_TIMER_FREQUENCY  FAST_PWM_FAN_FREQUENCY
66
+#else
67
+  #define PWM_TIMER_FREQUENCY  (50*128) // 50Hz and 7bit resolution
68
+#endif
69
+#define MAX_PWM_PINS             32 // Number of PWM pin-slots
70
+
62 71
 #define PULSE_TIMER_RATE         STEPPER_TIMER_RATE   // frequency of pulse timer
63 72
 #define PULSE_TIMER_PRESCALE     STEPPER_TIMER_PRESCALE
64 73
 #define PULSE_TIMER_TICKS_PER_US STEPPER_TIMER_TICKS_PER_US
@@ -72,10 +81,11 @@ typedef uint64_t hal_timer_t;
72 81
 
73 82
 #define HAL_TEMP_TIMER_ISR() extern "C" void tempTC_Handler(void)
74 83
 #define HAL_STEP_TIMER_ISR() extern "C" void stepTC_Handler(void)
84
+#define HAL_PWM_TIMER_ISR() extern "C" void pwmTC_Handler(void)
75 85
 
76 86
 extern "C" void tempTC_Handler(void);
77 87
 extern "C" void stepTC_Handler(void);
78
-
88
+extern "C" void pwmTC_Handler(void);
79 89
 
80 90
 // ------------------------
81 91
 // Types

+ 1
- 1
Marlin/src/HAL/HAL_ESP32/fastio_ESP32.h Целия файл

@@ -66,7 +66,7 @@
66 66
 #define extDigitalWrite(IO,V)   digitalWrite(IO,V)
67 67
 
68 68
 // PWM outputs
69
-#define PWM_PIN(P)              (P < 34) // NOTE Pins >= 34 are input only on ESP32, so they can't be used for output.
69
+#define PWM_PIN(P)              (P < 34 || P > 127) // NOTE Pins >= 34 are input only on ESP32, so they can't be used for output.
70 70
 
71 71
 // Toggle pin value
72 72
 #define TOGGLE(IO)              WRITE(IO, !READ(IO))

+ 19
- 4
Marlin/src/HAL/HAL_ESP32/i2s.cpp Целия файл

@@ -56,7 +56,7 @@ static i2s_dev_t* I2S[I2S_NUM_MAX] = {&I2S0, &I2S1};
56 56
 static i2s_dma_t dma;
57 57
 
58 58
 // output value
59
-uint32_t i2s_port_data;
59
+uint32_t i2s_port_data = 0;
60 60
 
61 61
 #define I2S_ENTER_CRITICAL()  portENTER_CRITICAL(&i2s_spinlock[i2s_num])
62 62
 #define I2S_EXIT_CRITICAL()   portEXIT_CRITICAL(&i2s_spinlock[i2s_num])
@@ -140,13 +140,13 @@ static void IRAM_ATTR i2s_intr_handler_default(void *arg) {
140 140
 }
141 141
 
142 142
 void stepperTask(void* parameter) {
143
-  uint32_t i, remaining = 0;
143
+  uint32_t remaining = 0;
144 144
 
145 145
   while (1) {
146 146
     xQueueReceive(dma.queue, &dma.current, portMAX_DELAY);
147 147
     dma.rw_pos = 0;
148 148
 
149
-    for (i = 0; i < DMA_SAMPLE_COUNT; i++) {
149
+    while (dma.rw_pos < DMA_SAMPLE_COUNT) {
150 150
       // Fill with the port data post pulse_phase until the next step
151 151
       if (remaining) {
152 152
         i2s_push_sample();
@@ -254,7 +254,13 @@ int i2s_init() {
254 254
 
255 255
   I2S0.fifo_conf.dscr_en = 0;
256 256
 
257
-  I2S0.conf_chan.tx_chan_mod = 0;
257
+  I2S0.conf_chan.tx_chan_mod = (
258
+    #if ENABLED(I2S_STEPPER_SPLIT_STREAM)
259
+      4
260
+    #else
261
+      0
262
+    #endif
263
+  );
258 264
   I2S0.fifo_conf.tx_fifo_mod = 0;
259 265
   I2S0.conf.tx_mono = 0;
260 266
 
@@ -314,10 +320,19 @@ int i2s_init() {
314 320
 }
315 321
 
316 322
 void i2s_write(uint8_t pin, uint8_t val) {
323
+  #if ENABLED(I2S_STEPPER_SPLIT_STREAM)
324
+    if (pin >= 16) {
325
+      SET_BIT_TO(I2S0.conf_single_data, pin, val);
326
+      return;
327
+    }
328
+  #endif
317 329
   SET_BIT_TO(i2s_port_data, pin, val);
318 330
 }
319 331
 
320 332
 uint8_t i2s_state(uint8_t pin) {
333
+  #if ENABLED(I2S_STEPPER_SPLIT_STREAM)
334
+    if (pin >= 16) return TEST(I2S0.conf_single_data, pin);
335
+  #endif
321 336
   return TEST(i2s_port_data, pin);
322 337
 }
323 338
 

Loading…
Отказ
Запис