Article Index

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);
  }
}