Page 1 of 1

mcpwm interrupt hang

Posted: Tue Oct 19, 2021 10:19 pm
by shuptuu
Hi,
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:
}

Re: mcpwm interrupt hang

Posted: Wed Oct 20, 2021 1:34 am
by ESP_Sprite
Pretty sure you need to clear the interrupt after handling it, otherwise the ESP32 will jump straight back into the interrupt handler. Note that you set a bit (write 1) in int_clr to clear the corresponding interrupt.

Re: mcpwm interrupt hang

Posted: Wed Oct 20, 2021 7:59 am
by shuptuu
Oh yes!
Thanks a lot ESP_Sprite. You made my day!!!
Best regards

Re: mcpwm interrupt hang

Posted: Thu Oct 21, 2021 8:30 am
by ESP_Sprite
shuptuu wrote:
Wed Oct 20, 2021 7:59 am
Oh yes!
Thanks a lot ESP_Sprite. You made my day!!!
Best regards
Good to hear!