Browse Source

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

Ringel 6 years ago
parent
commit
e139c1d9d9

+ 54
- 11
Marlin/src/HAL/HAL_ESP32/HAL.cpp View File

23
 #ifdef ARDUINO_ARCH_ESP32
23
 #ifdef ARDUINO_ARCH_ESP32
24
 
24
 
25
 #include "HAL.h"
25
 #include "HAL.h"
26
+#include "HAL_timers_ESP32.h"
26
 #include <rom/rtc.h>
27
 #include <rom/rtc.h>
27
 #include <driver/adc.h>
28
 #include <driver/adc.h>
28
 #include <esp_adc_cal.h>
29
 #include <esp_adc_cal.h>
67
 // ------------------------
68
 // ------------------------
68
 
69
 
69
 esp_adc_cal_characteristics_t characteristics;
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
 // Public functions
76
 // Public functions
168
 void HAL_adc_start_conversion(uint8_t adc_pin) {
172
 void HAL_adc_start_conversion(uint8_t adc_pin) {
169
   uint32_t mv;
173
   uint32_t mv;
170
   esp_adc_cal_get_voltage((adc_channel_t)get_channel(adc_pin), &characteristics, &mv);
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
 void analogWrite(pin_t pin, int value) {
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
 #endif // ARDUINO_ARCH_ESP32
235
 #endif // ARDUINO_ARCH_ESP32

+ 12
- 13
Marlin/src/HAL/HAL_ESP32/HAL_timers_ESP32.cpp View File

47
 const tTimerConfig TimerConfig [NUM_HARDWARE_TIMERS] = {
47
 const tTimerConfig TimerConfig [NUM_HARDWARE_TIMERS] = {
48
   { TIMER_GROUP_0, TIMER_0, STEPPER_TIMER_PRESCALE, stepTC_Handler }, // 0 - Stepper
48
   { TIMER_GROUP_0, TIMER_0, STEPPER_TIMER_PRESCALE, stepTC_Handler }, // 0 - Stepper
49
   { TIMER_GROUP_0, TIMER_1,    TEMP_TIMER_PRESCALE, tempTC_Handler }, // 1 - Temperature
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
   { TIMER_GROUP_1, TIMER_1,                      1, nullptr }, // 3
51
   { TIMER_GROUP_1, TIMER_1,                      1, nullptr }, // 3
52
 };
52
 };
53
 
53
 
55
 // Public functions
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
   // Retrieve the interrupt status and the counter value
61
   // Retrieve the interrupt status and the counter value
62
   // from the timer that reported the interrupt
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
   // Clear the interrupt
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
   timer.fn();
75
   timer.fn();
76
 
76
 
77
   // After the alarm has been triggered
77
   // After the alarm has been triggered
78
   // Enable it again so it gets triggered the next time
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
 
106
 
107
   timer_enable_intr(timer.group, timer.idx);
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
   timer_start(timer.group, timer.idx);
111
   timer_start(timer.group, timer.idx);
113
 }
112
 }

+ 11
- 1
Marlin/src/HAL/HAL_ESP32/HAL_timers_ESP32.h View File

40
 
40
 
41
 #define STEP_TIMER_NUM 0  // index of timer to use for stepper
41
 #define STEP_TIMER_NUM 0  // index of timer to use for stepper
42
 #define TEMP_TIMER_NUM 1  // index of timer to use for temperature
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
 #define PULSE_TIMER_NUM STEP_TIMER_NUM
44
 #define PULSE_TIMER_NUM STEP_TIMER_NUM
44
 
45
 
45
 #define HAL_TIMER_RATE APB_CLK_FREQ // frequency of timer peripherals
46
 #define HAL_TIMER_RATE APB_CLK_FREQ // frequency of timer peripherals
59
 #define TEMP_TIMER_PRESCALE    1000 // prescaler for setting Temp timer, 72Khz
60
 #define TEMP_TIMER_PRESCALE    1000 // prescaler for setting Temp timer, 72Khz
60
 #define TEMP_TIMER_FREQUENCY   1000 // temperature interrupt frequency
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
 #define PULSE_TIMER_RATE         STEPPER_TIMER_RATE   // frequency of pulse timer
71
 #define PULSE_TIMER_RATE         STEPPER_TIMER_RATE   // frequency of pulse timer
63
 #define PULSE_TIMER_PRESCALE     STEPPER_TIMER_PRESCALE
72
 #define PULSE_TIMER_PRESCALE     STEPPER_TIMER_PRESCALE
64
 #define PULSE_TIMER_TICKS_PER_US STEPPER_TIMER_TICKS_PER_US
73
 #define PULSE_TIMER_TICKS_PER_US STEPPER_TIMER_TICKS_PER_US
72
 
81
 
73
 #define HAL_TEMP_TIMER_ISR() extern "C" void tempTC_Handler(void)
82
 #define HAL_TEMP_TIMER_ISR() extern "C" void tempTC_Handler(void)
74
 #define HAL_STEP_TIMER_ISR() extern "C" void stepTC_Handler(void)
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
 extern "C" void tempTC_Handler(void);
86
 extern "C" void tempTC_Handler(void);
77
 extern "C" void stepTC_Handler(void);
87
 extern "C" void stepTC_Handler(void);
78
-
88
+extern "C" void pwmTC_Handler(void);
79
 
89
 
80
 // ------------------------
90
 // ------------------------
81
 // Types
91
 // Types

+ 1
- 1
Marlin/src/HAL/HAL_ESP32/fastio_ESP32.h View File

66
 #define extDigitalWrite(IO,V)   digitalWrite(IO,V)
66
 #define extDigitalWrite(IO,V)   digitalWrite(IO,V)
67
 
67
 
68
 // PWM outputs
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
 // Toggle pin value
71
 // Toggle pin value
72
 #define TOGGLE(IO)              WRITE(IO, !READ(IO))
72
 #define TOGGLE(IO)              WRITE(IO, !READ(IO))

+ 19
- 4
Marlin/src/HAL/HAL_ESP32/i2s.cpp View File

56
 static i2s_dma_t dma;
56
 static i2s_dma_t dma;
57
 
57
 
58
 // output value
58
 // output value
59
-uint32_t i2s_port_data;
59
+uint32_t i2s_port_data = 0;
60
 
60
 
61
 #define I2S_ENTER_CRITICAL()  portENTER_CRITICAL(&i2s_spinlock[i2s_num])
61
 #define I2S_ENTER_CRITICAL()  portENTER_CRITICAL(&i2s_spinlock[i2s_num])
62
 #define I2S_EXIT_CRITICAL()   portEXIT_CRITICAL(&i2s_spinlock[i2s_num])
62
 #define I2S_EXIT_CRITICAL()   portEXIT_CRITICAL(&i2s_spinlock[i2s_num])
140
 }
140
 }
141
 
141
 
142
 void stepperTask(void* parameter) {
142
 void stepperTask(void* parameter) {
143
-  uint32_t i, remaining = 0;
143
+  uint32_t remaining = 0;
144
 
144
 
145
   while (1) {
145
   while (1) {
146
     xQueueReceive(dma.queue, &dma.current, portMAX_DELAY);
146
     xQueueReceive(dma.queue, &dma.current, portMAX_DELAY);
147
     dma.rw_pos = 0;
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
       // Fill with the port data post pulse_phase until the next step
150
       // Fill with the port data post pulse_phase until the next step
151
       if (remaining) {
151
       if (remaining) {
152
         i2s_push_sample();
152
         i2s_push_sample();
254
 
254
 
255
   I2S0.fifo_conf.dscr_en = 0;
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
   I2S0.fifo_conf.tx_fifo_mod = 0;
264
   I2S0.fifo_conf.tx_fifo_mod = 0;
259
   I2S0.conf.tx_mono = 0;
265
   I2S0.conf.tx_mono = 0;
260
 
266
 
314
 }
320
 }
315
 
321
 
316
 void i2s_write(uint8_t pin, uint8_t val) {
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
   SET_BIT_TO(i2s_port_data, pin, val);
329
   SET_BIT_TO(i2s_port_data, pin, val);
318
 }
330
 }
319
 
331
 
320
 uint8_t i2s_state(uint8_t pin) {
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
   return TEST(i2s_port_data, pin);
336
   return TEST(i2s_port_data, pin);
322
 }
337
 }
323
 
338
 

Loading…
Cancel
Save