[SOLVED] MCPWM does not want to start
Posted: Wed Jul 21, 2021 5:12 pm
Hello, here is the deal: I have made a simple C environment where I can run bare-metal code. I wanted to configure mcpwm peripheral to control an H-Bridge for 2 coils stepper motor.
Used Chip is ESP32-D0WDQ6 (revision 1).
The problem is that when I call two_phase_init();, the registers hold their values, but when I read PWM_TIMER0_STATUS_REG, I see zeros, as if the CLK_160M timer was not enabled.
Please assume that this is a single core application, so no synchronization is required, and I have unlocked the watchdog so the core does not reset every x-miliseconds.
Did I forget something, such as some clock init? Or is some configuration in a wrong order? Relevant MEM dump is as follows:
0x3FF5E000 0b 00000000 00000000 00000000 11111010 // PWM_CLK_CFG_REG
0x3FF5E004 0b 00000000 00000000 00000111 11111010 // PWM_TIMER0_CFG0_REG
0x3FF5E008 0b 00000000 00000000 00000000 00010010 // PWM_TIMER0_CFG1_REG (Timer start holds value 2 - start & run on)
0x3FF5E00C 0b 00000000 00000000 00000000 01000100 // PWM_TIMER0_SYNC_REG
0x3FF5E010 0b 00000000 00000000 00000000 00000000 // PWM_TIMER0_STATUS_REG (Value = 0, Direction = Increment(wrong))
This is pretty much what would run in the PRO CPU entry function called from the ROM code.
Used Chip is ESP32-D0WDQ6 (revision 1).
The problem is that when I call two_phase_init();, the registers hold their values, but when I read PWM_TIMER0_STATUS_REG, I see zeros, as if the CLK_160M timer was not enabled.
Please assume that this is a single core application, so no synchronization is required, and I have unlocked the watchdog so the core does not reset every x-miliseconds.
Did I forget something, such as some clock init? Or is some configuration in a wrong order? Relevant MEM dump is as follows:
0x3FF5E000 0b 00000000 00000000 00000000 11111010 // PWM_CLK_CFG_REG
0x3FF5E004 0b 00000000 00000000 00000111 11111010 // PWM_TIMER0_CFG0_REG
0x3FF5E008 0b 00000000 00000000 00000000 00010010 // PWM_TIMER0_CFG1_REG (Timer start holds value 2 - start & run on)
0x3FF5E00C 0b 00000000 00000000 00000000 01000100 // PWM_TIMER0_SYNC_REG
0x3FF5E010 0b 00000000 00000000 00000000 00000000 // PWM_TIMER0_STATUS_REG (Value = 0, Direction = Increment(wrong))
This is pretty much what would run in the PRO CPU entry function called from the ROM code.
Code: Select all
#include <motor_control_reg.h>
#include "GPIO.h"
#include <control_reg.h>
/**
* Initializes the required cables and registers.
**/
void two_phase_init(){
//Enable peripheral
DREG->PERIP_CLK_EN.DPORT_PWM0_CLK_EN = 1;
DREG->PERIP_RST_EN.DPORT_PWM0_RST = 1;
DREG->PERIP_RST_EN.DPORT_PWM0_RST = 0;
DREG->AHBLITE_MPU_TABLE_PWM0 = 1;
//We will use Channel0.
//==PRESCALER SUBMODULE==
//Input to this prescaler is 160Mhz
MOT_CTRL0->CLK_CFG.PWM_CLK_PRESCALE = 250; //Out is 640Khz
//==SHADOW REGISTERS CONFIG==
MOT_CTRL0->UPDATE_CFG.PWM_GLOBAL_UP_EN = 1;
MOT_CTRL0->UPDATE_CFG.PWM_OP0_UP_EN = 1;
MOT_CTRL0->UPDATE_CFG.PWM_OP1_UP_EN = 1;
MOT_CTRL0->UPDATE_CFG.PWM_OP2_UP_EN = 1;
MOT_CTRL0->UPDATE_CFG.PWM_GLOBAL_FORCE_UP ^= (1u << 1u); //Flush Shadow
//==TIMER SUBMODULE 0,1,2==
MOT_CTRL0->SUBMODULE_TIMER[0].CFG0.PRESCALE = 250; //Out is 2.560Khz
MOT_CTRL0->SUBMODULE_TIMER[0].CFG1.MODE = PWM_TIMER_MODE_DECREASE;
MOT_CTRL0->SUBMODULE_TIMER[0].CFG0.PERIOD_UPDATEMETHOD = PWM_TIMER_UPDATEMETHOD_IMMEDIATELY;
MOT_CTRL0->SUBMODULE_TIMER[0].CFG0.PERIOD = 7;
MOT_CTRL0->SUBMODULE_TIMER[0].SYNC.PHASE = 4;
MOT_CTRL0->SUBMODULE_TIMER[0].SYNC.OUT_SEL = PWM_TIMER_SYNC_OUT_TIME_ZERO; //Does not really matter
MOT_CTRL0->SUBMODULE_TIMER[0].SYNC.IN_EN = 0;
MOT_CTRL0->TIMER_SYNCI_CFG.TIMER0_SYNCISEL = PWM_TIMER_SYNC_IN_NOT_CONNECTED;
MOT_CTRL0->TIMER_SYNCI_CFG.EXTERNAL_SYNCI0_INVERT = 0;
//==OPERATOR SUBMODULE==
MOT_CTRL0->OPERATOR_TIMERSEL.OPERATOR0_TIMERSEL = PWM_TIMER_TIMERSEL_TIMER0;
MOT_CTRL0->SUBMODULE_OPERATOR[0].GEN_A.UTEZ = PWM_ACTION_HIGH;
MOT_CTRL0->SUBMODULE_OPERATOR[0].GEN_A.UTEA = PWM_ACTION_LOW;
MOT_CTRL0->SUBMODULE_OPERATOR[0].GEN_A.UTEB = PWM_ACTION_NO_CHANGE;
MOT_CTRL0->SUBMODULE_OPERATOR[0].GEN_EVENT_A.VALUE = 3;
GPIO_set_pin_as_output(33, 32, 2); //GPIO 33 will have connected signal no. 32 at drive strength 2
MOT_CTRL0->UPDATE_CFG.PWM_GLOBAL_FORCE_UP ^= (1u << 1u); //Flush Shadow
//MOT_CTRL0->SUBMODULE_TIMER[0].SYNC.SOFTWARE_SYNC = 1;
MOT_CTRL0->SUBMODULE_TIMER[0].CFG1.START = PWM_TIMER_START_RUN;
//DUMP PERFORMED HERE
}