Page 8 of 16
Page 184 -186 uses MCPWM.h given earlier
#include <stdio.h>
#include "freertos/FreeRTOS.h"
#include "driver/mcpwm_prelude.h"
#include "MCPWM.h"
typedef struct{
mcpwm_timer_handle_t timer;
mcpwm_oper_handle_t oper;
mcpwm_gen_handle_t generator1;
mcpwm_cmpr_handle_t comparator1;
}PWM;
PWM makePWM(int gpio, uint32_t res, uint32_t ticksperiod,
uint32_t duty) {
PWM pwm;
pwm.timer = makeTimer(res, ticksperiod);
pwm.oper = makeOper();
mcpwm_operator_connect_timer(pwm.oper, pwm.timer);
pwm.generator1 = makeGen(pwm.oper, gpio);
pwm.comparator1 = makeComp(pwm.oper);
mcpwm_comparator_set_compare_value(pwm.comparator1, duty);
mcpwm_generator_set_action_on_timer_event(pwm.generator1,
MCPWM_GEN_TIMER_EVENT_ACTION(MCPWM_TIMER_DIRECTION_UP,
MCPWM_TIMER_EVENT_EMPTY, MCPWM_GEN_ACTION_HIGH));
mcpwm_generator_set_action_on_compare_event(pwm.generator1,
MCPWM_GEN_COMPARE_EVENT_ACTION(MCPWM_TIMER_DIRECTION_UP,
pwm.comparator1, MCPWM_GEN_ACTION_LOW));
mcpwm_timer_enable(pwm.timer);
mcpwm_timer_start_stop(pwm.timer, MCPWM_TIMER_START_NO_STOP);
return pwm;
}
typedef struct
{
PWM pwm;
uint32_t gpio;
uint32_t duty;
uint32_t freq;
uint32_t resolution;
float speed;
} Motor;
Motor makeUniMotor(int32_t gpio) {
int32_t res = 1000000;
int32_t freq = 500;
Motor motor;
motor.gpio = gpio;
motor.pwm = makePWM(gpio, res, freq, 0);
motor.freq = freq;
motor.speed = 0;
motor.duty = 0;
return motor;
}
void setUniMotorSpeed(Motor motor, float speed) {
motor.speed = speed;
motor.duty = speed * (float)(motor.freq);
mcpwm_comparator_set_compare_value(motor.pwm.comparator1,
motor.duty);
}
void app_main(void)
{
Motor motor = makeUniMotor(2);
setUniMotorSpeed(motor, 0.1);
}
Page 191-192 uses MCPWM.h given earlier
#include <stdio.h>
#include "freertos/FreeRTOS.h"
#include "driver/mcpwm_prelude.h"
#include "MCPWM.h"
typedef struct{
mcpwm_timer_handle_t timer;
mcpwm_oper_handle_t oper;
mcpwm_gen_handle_t generator1;
mcpwm_cmpr_handle_t comparator1;
}PWM;
PWM makePWM(int gpio, uint32_t res, uint32_t ticksperiod,
uint32_t duty) {
PWM pwm;
pwm.timer = makeTimer(res, ticksperiod);
pwm.oper = makeOper();
mcpwm_operator_connect_timer(pwm.oper, pwm.timer);
pwm.generator1 = makeGen(pwm.oper, gpio);
pwm.comparator1 = makeComp(pwm.oper);
mcpwm_comparator_set_compare_value(pwm.comparator1, duty);
mcpwm_generator_set_action_on_timer_event(pwm.generator1,
MCPWM_GEN_TIMER_EVENT_ACTION(MCPWM_TIMER_DIRECTION_UP,
MCPWM_TIMER_EVENT_EMPTY, MCPWM_GEN_ACTION_HIGH));
mcpwm_generator_set_action_on_compare_event(pwm.generator1,
MCPWM_GEN_COMPARE_EVENT_ACTION(MCPWM_TIMER_DIRECTION_UP,
pwm.comparator1, MCPWM_GEN_ACTION_LOW));
mcpwm_timer_enable(pwm.timer);
mcpwm_timer_start_stop(pwm.timer, MCPWM_TIMER_START_NO_STOP);
return pwm;
}
typedef struct
{
PWM pwm;
PWM pwm2;
uint32_t gpio;
uint32_t gpio2;
uint32_t duty;
uint32_t freq;
uint32_t resolution;
float speed;
bool forward;
} Motor;
Motor makeBiMotor(int32_t gpio1,int32_t gpio2) {
int32_t res = 1000000;
int32_t freq = 500;
Motor motor;
motor.gpio = gpio1;
motor.gpio2 = gpio2;
motor.pwm = makePWM(gpio1, res, freq, 0);
motor.pwm2 = makePWM(gpio2, res, freq, 0);
motor.freq = freq;
motor.speed = 0;
motor.duty = 0;
motor.forward=true;
return motor;
}
void setBiMotorSpeedDirection(Motor motor, float speed,
bool forward) {
motor.speed = speed;
motor.duty = speed * (float)(motor.freq);
motor.forward=forward;
if(forward){
mcpwm_comparator_set_compare_value(motor.pwm2.comparator1,0);
mcpwm_comparator_set_compare_value(motor.pwm.comparator1,
motor.duty);
}else{
mcpwm_comparator_set_compare_value(motor.pwm.comparator1, 0);
mcpwm_comparator_set_compare_value(motor.pwm2.comparator1,
motor.duty);
}
}
void app_main(void)
{
Motor motor = makeBiMotor(2,4);
setBiMotorSpeedDirection(motor, 0.1,false);
}
Page 194 -195 uses MCPWM.h given earlier and only partially listed on page
#include <stdio.h>
#include "freertos/FreeRTOS.h"
#include "driver/mcpwm_prelude.h"
#include "MCPWM.h"
typedef struct
{
mcpwm_timer_handle_t timer;
mcpwm_oper_handle_t oper;
mcpwm_gen_handle_t generator1;
mcpwm_gen_handle_t generator2;
mcpwm_cmpr_handle_t comparator1;
} PWM;
PWM makePWM(int gpio, uint32_t res, uint32_t ticksperiod,
uint32_t duty)
{
PWM pwm;
pwm.timer = makeTimer(res, ticksperiod);
pwm.oper = makeOper();
mcpwm_operator_connect_timer(pwm.oper, pwm.timer);
pwm.generator1 = makeGen(pwm.oper, gpio);
pwm.comparator1 = makeComp(pwm.oper);
mcpwm_comparator_set_compare_value(pwm.comparator1, duty);
mcpwm_generator_set_action_on_timer_event(pwm.generator1,
MCPWM_GEN_TIMER_EVENT_ACTION(MCPWM_TIMER_DIRECTION_UP,
MCPWM_TIMER_EVENT_EMPTY, MCPWM_GEN_ACTION_HIGH));
mcpwm_generator_set_action_on_compare_event(pwm.generator1,
MCPWM_GEN_COMPARE_EVENT_ACTION(MCPWM_TIMER_DIRECTION_UP,
pwm.comparator1, MCPWM_GEN_ACTION_LOW));
mcpwm_timer_enable(pwm.timer);
mcpwm_timer_start_stop(pwm.timer, MCPWM_TIMER_START_NO_STOP);
return pwm;
}
void makeDCAC(int32_t gpio1, int32_t gpio2)
{
int32_t res = 1000000;
int32_t freq = 20000;
PWM pwm = makePWM(gpio1, res, freq, 10000);
pwm.generator2 = makeGen(pwm.oper, gpio2);
int deadtime = 200;
mcpwm_dead_time_config_t dtconfig = {
.posedge_delay_ticks = deadtime,
.negedge_delay_ticks = 0,
.flags.invert_output = false};
mcpwm_generator_set_dead_time(pwm.generator1,
pwm.generator1, &dtconfig);
dtconfig.posedge_delay_ticks = 0;
dtconfig.negedge_delay_ticks = deadtime;
dtconfig.flags.invert_output = true;
mcpwm_generator_set_dead_time(pwm.generator1, pwm.generator2,
&dtconfig);
}
void app_main(void)
{
makeDCAC(2,4);
}
Page 197-198 uses MCPWM.h given earlier
#include <stdio.h>
#include "freertos/FreeRTOS.h"
#include "driver/mcpwm_prelude.h"
#include "MCPWM.h"
void delay_ms(int t) {
vTaskDelay(t / portTICK_PERIOD_MS);
}
typedef struct {
mcpwm_timer_handle_t timer;
mcpwm_oper_handle_t oper;
mcpwm_gen_handle_t generator1;
mcpwm_gen_handle_t generator2;
mcpwm_cmpr_handle_t comparator1;
int32_t freq;
}PWM;
PWM makePWM(int gpio, uint32_t res, uint32_t ticksperiod,
uint32_t duty) {
PWM pwm;
pwm.timer = makeTimer(res, ticksperiod);
pwm.oper = makeOper();
mcpwm_operator_connect_timer(pwm.oper, pwm.timer);
pwm.generator1 = makeGen(pwm.oper, gpio);
pwm.comparator1 = makeComp(pwm.oper);
mcpwm_comparator_set_compare_value(pwm.comparator1, duty);
mcpwm_generator_set_action_on_timer_event(pwm.generator1,
MCPWM_GEN_TIMER_EVENT_ACTION(MCPWM_TIMER_DIRECTION_UP,
MCPWM_TIMER_EVENT_EMPTY, MCPWM_GEN_ACTION_HIGH));
mcpwm_generator_set_action_on_compare_event(pwm.generator1,
MCPWM_GEN_COMPARE_EVENT_ACTION(MCPWM_TIMER_DIRECTION_UP,
pwm.comparator1, MCPWM_GEN_ACTION_LOW));
mcpwm_timer_enable(pwm.timer);
mcpwm_timer_start_stop(pwm.timer, MCPWM_TIMER_START_NO_STOP);
return pwm;
}
PWM makeServo(int gpio) {
int32_t res = 1000000;
int32_t freq = 20000;
return makePWM(gpio, res, freq, 500);
}
void setAngle(PWM pwm, float angle) {
int32_t max = 2500;
int32_t min = 500;
int32_t duty = (float)(max - min) * angle + min;
mcpwm_comparator_set_compare_value(pwm.comparator1, duty);
}
void app_main(void)
{
PWM pwm = makeServo(2);
setAngle(pwm, 1.0);
delay_ms(100);
fflush(stdout);
setAngle(pwm, 0.5);
delay_ms(100);
setAngle(pwm, 0.0);
}
Page199 uses MCPWM.h given earlier and only partially listed on page
#include <stdio.h>
#include "freertos/FreeRTOS.h"
#include "driver/mcpwm_prelude.h"
#include "MCPWM.h"
void delay_ms(int t) {
vTaskDelay(t / portTICK_PERIOD_MS);
}
typedef struct {
mcpwm_timer_handle_t timer;
mcpwm_oper_handle_t oper;
mcpwm_gen_handle_t generator1;
mcpwm_gen_handle_t generator2;
mcpwm_cmpr_handle_t comparator1;
int32_t freq;
}PWM;
PWM makePWM(int gpio, uint32_t res, uint32_t ticksperiod,
uint32_t duty) {
PWM pwm;
pwm.timer = makeTimer(res, ticksperiod);
pwm.oper = makeOper();
mcpwm_operator_connect_timer(pwm.oper, pwm.timer);
pwm.generator1 = makeGen(pwm.oper, gpio);
pwm.comparator1 = makeComp(pwm.oper);
mcpwm_comparator_set_compare_value(pwm.comparator1, duty);
mcpwm_generator_set_action_on_timer_event(pwm.generator1,
MCPWM_GEN_TIMER_EVENT_ACTION(MCPWM_TIMER_DIRECTION_UP,
MCPWM_TIMER_EVENT_EMPTY, MCPWM_GEN_ACTION_HIGH));
mcpwm_generator_set_action_on_compare_event(pwm.generator1,
MCPWM_GEN_COMPARE_EVENT_ACTION(MCPWM_TIMER_DIRECTION_UP,
pwm.comparator1, MCPWM_GEN_ACTION_LOW));
mcpwm_timer_enable(pwm.timer);
mcpwm_timer_start_stop(pwm.timer, MCPWM_TIMER_START_NO_STOP);
return pwm;
}
PWM makeServo(int gpio) {
int32_t res = 1000000;
int32_t freq = 20000;
return makePWM(gpio, res, freq, 500);
}
void setAngle(PWM pwm, float angle) {
int32_t max = 2500;
int32_t min = 500;
int32_t duty = (float)(max - min) * angle + min;
mcpwm_comparator_set_compare_value(pwm.comparator1, duty);
}
void app_main(void)
{
PWM pwm = makeServo(2);
setAngle(pwm, 1.0);
delay_ms(100);
fflush(stdout);
setAngle(pwm, 0.5);
delay_ms(100);
setAngle(pwm, 0.0);
}
Page 208
#include <stdio.h>
#include "freertos/FreeRTOS.h"
#include "driver/gpio.h"
#include "soc/gpio_reg.h"
#include <unistd.h>
void gpio_set(int32_t value, int32_t mask) {
int32_t* OutAdd = (int32_t*)GPIO_OUT_REG;
*OutAdd = (*OutAdd & ~mask) | (value & mask);;
}
void delay_us(int t) {
usleep(t);
}
typedef struct
{
int gpio;
int speed;
bool forward;
uint32_t gpiomask;
int phase;
} StepperBi;
uint32_t stepTable[8] = (uint32_t[8]){ 0x8, 0xC, 0x4, 0x6, 0x2, 0x3, 0x1, 0x9 };
/*
{1, 0, 0, 0},
{1, 1, 0, 0},
{0, 1, 0, 0},
{0, 1, 1, 0},
{0, 0, 1, 0},
{0, 0, 1, 1},
{0, 0, 0, 1},
{1, 0, 0, 1}
*/
void StepperBiInit(StepperBi* s, int gpio)
{
s->gpio = gpio;
for (int i = 0; i < 4; i++) {
gpio_reset_pin((s->gpio) + i);
gpio_set_direction((s->gpio) + i, GPIO_MODE_OUTPUT);
}
s->gpiomask = 0x0F << gpio;
volatile uint32_t mask = stepTable[0] << gpio;
gpio_set(mask, s->gpiomask);
s->phase = 0;
s->speed = 0;
s->forward = true;
}
void setPhase(StepperBi* s, int p)
{
uint32_t mask = stepTable[p] << (s->gpio);
gpio_set(mask, s->gpiomask);
}
void stepForward(StepperBi* s)
{
s->phase = (s->phase + 1) % 8;
setPhase(s, s->phase);
}
void stepReverse(StepperBi* s)
{
s->phase = (s->phase - 1) % 8;
setPhase(s, s->phase);
}
void rotate(StepperBi* s, bool dir, int speed)
{
s->forward = dir;
s->speed = speed;
}
void app_main(void)
{
StepperBi s1;
StepperBiInit(&s1, 15);
while (true)
{
stepForward(&s1);
delay_us(1000);
}
}
Page 213
#include <stdio.h>
#include "freertos/FreeRTOS.h"
#include "driver/gpio.h"
#include "soc/gpio_reg.h"
#include <unistd.h>
#include "driver/gptimer.h"
void gpio_set(int32_t value, int32_t mask) {
int32_t* OutAdd = (int32_t*)GPIO_OUT_REG;
*OutAdd = (*OutAdd & ~mask) | (value & mask);;
}
void delay_ms(int t) {
vTaskDelay(t / portTICK_PERIOD_MS);
}
void delay_us(int t) {
usleep(t);
}
typedef struct
{
int gpio;
int speed;
bool forward;
uint32_t gpiomask;
int phase;
} StepperBi;
uint32_t stepTable[8] = (uint32_t[8]){ 0x8, 0xC, 0x4, 0x6, 0x2, 0x3, 0x1, 0x9 };
/*
{1, 0, 0, 0},
{1, 1, 0, 0},
{0, 1, 0, 0},
{0, 1, 1, 0},
{0, 0, 1, 0},
{0, 0, 1, 1},
{0, 0, 0, 1},
{1, 0, 0, 1}
*/
void StepperBiInit(StepperBi* s, int gpio)
{
s->gpio = gpio;
for (int i = 0; i < 4; i++) {
gpio_reset_pin((s->gpio) + i);
gpio_set_direction((s->gpio) + i, GPIO_MODE_OUTPUT);
}
s->gpiomask = 0x0F << gpio;
volatile uint32_t mask = stepTable[0] << gpio;
gpio_set(mask, s->gpiomask);
s->phase = 0;
s->speed = 0;
s->forward = true;
}
void setPhase(StepperBi* s, int p)
{
uint32_t mask = stepTable[p] << (s->gpio);
gpio_set(mask, s->gpiomask);
}
void stepForward(StepperBi* s)
{
s->phase = (s->phase + 1) % 8;
setPhase(s, s->phase);
}
void stepReverse(StepperBi* s)
{
s->phase = (s->phase - 1) % 8;
setPhase(s, s->phase);
}
bool step(gptimer_handle_t gptimer, const gptimer_alarm_event_data_t* edata, void* user_data)
{
StepperBi* s = (StepperBi*)(user_data);
if (s->forward)
{
stepForward(s);
}
else
{
stepReverse(s);
}
return false;
}
void rotate(StepperBi* s, bool dir, int speed)
{
static gptimer_handle_t gptimer = NULL;
if (gptimer == NULL) {
gptimer_config_t timer_config = {
.clk_src = GPTIMER_CLK_SRC_DEFAULT,
.direction = GPTIMER_COUNT_UP,
.resolution_hz = 1000000,
};
gptimer_new_timer(&timer_config, &gptimer);
gptimer_alarm_config_t alarm_config = {
.flags.auto_reload_on_alarm = true,
.alarm_count = 1000,
.reload_count = 0 };
gptimer_set_alarm_action(gptimer, &alarm_config);
gptimer_event_callbacks_t cbs = {
.on_alarm = step,
};
gptimer_register_event_callbacks(gptimer, &cbs, (void*)s);
gptimer_enable(gptimer);
gptimer_start(gptimer);
};
s->forward = dir;
if (speed == 0)
{
gptimer_stop(gptimer);
gptimer_disable(gptimer);
gptimer_del_timer(gptimer);
gptimer = NULL;
s->speed = 0;
return;
}
gptimer_alarm_config_t alarm_config = {
.flags.auto_reload_on_alarm = true,
.alarm_count = 2000,
.reload_count = 0 };
alarm_config.alarm_count = speed / 150.0 * 1000.0;
s->speed = speed;
gptimer_set_alarm_action(gptimer, &alarm_config);
}
void app_main(void)
{
StepperBi s1;
StepperBiInit(&s1, 15);
while (true)
{
rotate(&s1, true, 150);
delay_ms(100);
rotate(&s1, true, 00);
delay_ms(100);
}
}