I'm playing with mcpwm in order to use it later with a stepper motor. I made a very simple sketch (on arduino ide) where I setup a basic mcpwm to generate a pwm signal (first 1khz, then 10khz), stop and restart, etc... And I try to sort out how to manage interrupts.
And this is where I have a problem. For the moment, I just enable an interrupt when timer 0 stops.
The interrupt fire up as expected when I stop the mcpwm but then the system just hang, without any error message. And I don't understand what's happening then and how to fix that.
What's wrong with my code?
Any idea?
Test made with an esp32 dev board, and on oscilloscope to watch the output.
Code below
Thanks
Code: Select all
#include <driver/gpio.h>
#include "driver/mcpwm.h"
#include "soc/mcpwm_reg.h"
#include "soc/mcpwm_struct.h"
//Pins
#define DIR_PIN 14 //direction
#define STEP_PIN 27 //step
#define EN_PIN 26 //enable
// cannot be updated while timer is running => fix it to 0
#define TIMER_PRESCALER 0
static mcpwm_dev_t *mcpwm = &MCPWM0;
void breakpoint(String txt){
Serial.println(txt);
Serial.println("Press enter...");
while (!Serial.available()){delay(1);}
while (Serial.available()){Serial.read();}
}
volatile int count=0;
static void IRAM_ATTR toto(void *) {
count++;
}
void setup() {
Serial.begin(115200);
Serial.println("Hello!");
//pre-config
mcpwm->int_ena.val = 0; // disable all interrupts
mcpwm->int_clr.val = 0; // clear all interrupts
mcpwm_isr_register(MCPWM_UNIT_0, toto, NULL, ESP_INTR_FLAG_IRAM | ESP_INTR_FLAG_SHARED, NULL); //Set ISR Handler (active interrupts will be set later)
mcpwm_gpio_init(MCPWM_UNIT_0, MCPWM0A, STEP_PIN);
mcpwm_config_t pwm_config;
pwm_config.frequency = 1000; //frequency,
pwm_config.cmpr_a = 0; //duty cycle of PWMxA = 0
pwm_config.cmpr_b = 0; //duty cycle of PWMxb = 0
pwm_config.counter_mode = MCPWM_UP_COUNTER;
pwm_config.duty_mode = MCPWM_DUTY_MODE_0;
mcpwm_init(MCPWM_UNIT_0, MCPWM_TIMER_0, &pwm_config); //Configure PWM0A & PWM0B with above settings
//stop
mcpwm_set_signal_high(MCPWM_UNIT_0, MCPWM_TIMER_0, MCPWM_OPR_A);
Serial.println (mcpwm->int_raw.val,BIN);
mcpwm->int_ena.val = BIT(0); //Interrupt when timer 0 stops//
Serial.println (mcpwm->int_ena.val,BIN);
breakpoint("mcpwm ready, output should be HIGH");
//send 1kHz freq - duty80%
mcpwm_set_duty(MCPWM_UNIT_0, MCPWM_TIMER_0, MCPWM_OPR_A, 80);
mcpwm_set_duty_type(MCPWM_UNIT_0, MCPWM_TIMER_0, MCPWM_OPR_A, MCPWM_DUTY_MODE_0); //call this each time, if operator was previously in low/high state
Serial.println (mcpwm->int_raw.val,BIN);
breakpoint("1kHz - duty 80%");
mcpwm_set_frequency(MCPWM_UNIT_0, MCPWM_TIMER_0,10000);
Serial.println (mcpwm->int_raw.val,BIN);
breakpoint("10kHz - duty 80%");
mcpwm_stop(MCPWM_UNIT_0, MCPWM_TIMER_0);
Serial.println (mcpwm->int_raw.val,BIN);
breakpoint("stopped?");
mcpwm_start(MCPWM_UNIT_0, MCPWM_TIMER_0);
Serial.println (mcpwm->int_raw.val,BIN);
breakpoint("restarted?");
Serial.println (mcpwm->int_raw.val,BIN);
unsigned long t=micros();
Serial.println(String(count));
breakpoint("read again?");
t=micros()-t;
Serial.println(String(count)+":"+String(t));
}
void loop() {
// put your main code here, to run repeatedly:
}