I am beginning to play with MCPWM and I would change on the fly some values such as the prescaler which are in MCPWM_CLK_CFG_REG and in MCPWM_TIMER0_CFG0_REG. For the moment I have no oscillo and I test with leds.
- For the prescaler in MCPWM_CLK_CFG_REG register, I see a change when I modify its value.
- But for the one in MCPWM_TIMER0_CFG0_REG, it seems to me that there is no change when I modify its value. what am I doing wrong in the following program ?
pwm_config.frequency = 20;
by
pwm_config.frequency = 10;
without executing the lines 92-101, I see a strange value in the MCPWM_TIMER0_PERIOD part of the PWM_TIMER0_CFG0_REG :
I find there 34464 = 0x86A0 when the right value would be 100000 = 0x186A0.
Obviously it is impossible to put this value into the 16 bits provided and it looks like the extra digit was cut.
Thank you very much for any clue
Best regards
J.M. CORNIL
Code: Select all
#include <stdio.h>
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "freertos/queue.h"
#include "esp_attr.h"
#include "soc/rtc.h"
#include "driver/mcpwm.h"
#include "soc/mcpwm_periph.h"
#define GPIO_PWM0A_OUT 17 //Set GPIO 17 as PWM0A
#define GPIO_PWM0B_OUT 21 //Set GPIO 21 as PWM0B
static void mcpwm_example_gpio_initialize(void)
{
mcpwm_gpio_init(MCPWM_UNIT_0, MCPWM0A, GPIO_PWM0A_OUT);
mcpwm_gpio_init(MCPWM_UNIT_0, MCPWM0B, GPIO_PWM0B_OUT);
}
// general prescaler
uint8_t get_MCPWM_CLK_CFG_REG(){
return *((uint32_t *) MCPWM_CLK_CFG_REG(0)) & 0xFF;
}
void set_MCPWM_CLK_CFG_REG(uint8_t val){
*((uint32_t *) MCPWM_CLK_CFG_REG(0)) = (MCPWM_CLK_CFG_REG(0) & 0xFFFFFF00) | val ;
}
// Timer0 prescaler
uint8_t get_MCPWM_TIMER0_PRESCALE(){
return *((uint32_t *) MCPWM_TIMER0_CFG0_REG(0)) & 0xFF;
}
void set_MCPWM_TIMER0_PRESCALE(uint8_t val){
uint32_t* p = (uint32_t *) MCPWM_TIMER0_CFG0_REG(0);
*p = (*p & 0xFFFFFF00) | val;
}
// Timer0 period
uint16_t get_MCPWM_TIMER0_PERIOD(){
return ((*((uint32_t *) MCPWM_TIMER0_CFG0_REG(0))) >>8) & 0xFFFF;
}
void set_MCPWM_TIMER0_PERIOD(uint16_t val){
uint32_t* p = (uint32_t *) MCPWM_TIMER0_CFG0_REG(0);
*p = (*p & 0xFF0000FF) | (val<<8);
}
// A cmpr register
uint16_t get_MCPWM_GEN0_TSTMP_A_REG(){
return (*(uint32_t *)MCPWM_GEN0_TSTMP_A_REG(0)) & 0xFFFF;
}
void set_MCPWM_GEN0_TSTMP_A_REG(uint16_t val){
uint32_t* p = (uint32_t *)MCPWM_GEN0_TSTMP_A_REG(0);
*p = (*p & 0xFFFF0000) | val;
}
// B cmpr register
uint16_t get_MCPWM_GEN0_TSTMP_B_REG(){
return (*(uint32_t *)MCPWM_GEN0_TSTMP_B_REG(0)) & 0xFFFF;
}
void set_MCPWM_GEN0_TSTMP_B_REG(uint16_t val){
uint32_t* p = (uint32_t *)MCPWM_GEN0_TSTMP_B_REG(0);
*p = (*p & 0xFFFF0000) | val;
}
void timer_Start(){
uint32_t* p = (uint32_t *) MCPWM_TIMER0_CFG1_REG(0);
*p = (*p & ~0b111) | 0b10;
}
void timer_Stop(){
uint32_t* p = (uint32_t *) MCPWM_TIMER0_CFG1_REG(0);
*p = *p & ~0b111;
}
void app_main(void)
{
//1. mcpwm gpio initialization
mcpwm_example_gpio_initialize();
//2. initial mcpwm configuration
mcpwm_config_t pwm_config;
pwm_config.frequency = 20; // frequency
pwm_config.cmpr_a = 50.0; // duty cycle of PWMxA = 50.0%
pwm_config.cmpr_b = 50.0; // duty cycle of PWMxb = 50.0%
pwm_config.counter_mode = MCPWM_UP_COUNTER;
pwm_config.duty_mode = MCPWM_DUTY_MODE_1;
mcpwm_init(MCPWM_UNIT_0, MCPWM_TIMER_0, &pwm_config); //Configure PWM0A & PWM0B with above settings
// Then I try playing with the two prescaler
timer_Stop();
// For this one I see that it operates on the result
set_MCPWM_CLK_CFG_REG(255);
// But for the following, I don't see any change, whatever the value
set_MCPWM_TIMER0_PRESCALE(4);
set_MCPWM_TIMER0_PERIOD(60000);
set_MCPWM_GEN0_TSTMP_B_REG(50000);
set_MCPWM_GEN0_TSTMP_A_REG(50000);
timer_Start();
printf("MCPWM_CLK_CFG_REG adr = %d \r\n",get_MCPWM_CLK_CFG_REG());
printf("MCPWM_TIMER0_CFG0_REG presc = %d period = %d \r\n",get_MCPWM_TIMER0_PRESCALE(),get_MCPWM_TIMER0_PERIOD());
printf("MCPWM_GEN0_TSTMP_A_REG val = %d \r\n",get_MCPWM_GEN0_TSTMP_A_REG());
printf("MCPWM_GEN0_TSTMP_B_REG val = %d \r\n",get_MCPWM_GEN0_TSTMP_B_REG());
}