11#include " stepper_motor.h"
22#include " ../utils/timing.h"
33#include " ../utils/uart.h"
4- #include " esp32/ rom/gpio.h"
4+ #include " rom/gpio.h"
55#include " soc/gpio_sig_map.h"
66#include < algorithm>
77#include < driver/ledc.h>
8- #include < driver/pcnt.h>
9- #include < esp_rom_gpio.h>
10- #include < math.h>
11- #include < memory>
8+ #include < driver/pulse_cnt.h>
129#include < stdexcept>
1310
1411#define MIN_SPEED 490
1512
13+ static void check_error (esp_err_t err, const char *msg) {
14+ if (err != ESP_OK) {
15+ throw std::runtime_error (std::string (msg) + " : " + esp_err_to_name (err));
16+ }
17+ }
18+
1619#ifdef CONFIG_IDF_TARGET_ESP32S3
1720#define SPEED_MODE LEDC_LOW_SPEED_MODE
1821#define SPEED_OUT_IDX LEDC_LS_SIG_OUT0_IDX
22+ #define DUTY_RESOLUTION LEDC_TIMER_8_BIT
23+ #define DUTY_VALUE 128 // 50% of 256 with 8-bit resolution
1924#else
2025#define SPEED_MODE LEDC_HIGH_SPEED_MODE
2126#define SPEED_OUT_IDX LEDC_HS_SIG_OUT0_IDX
27+ #define DUTY_RESOLUTION LEDC_TIMER_1_BIT
28+ #define DUTY_VALUE 1 // 50% of max 1 with 1-bit resolution
2229#endif
2330
2431REGISTER_MODULE_DEFAULTS (StepperMotor)
@@ -35,48 +42,56 @@ const std::map<std::string, Variable_ptr> StepperMotor::get_defaults() {
3542StepperMotor::StepperMotor (const std::string name,
3643 const gpio_num_t step_pin,
3744 const gpio_num_t dir_pin,
38- const pcnt_unit_t pcnt_unit,
39- const pcnt_channel_t pcnt_channel,
4045 const ledc_timer_t ledc_timer,
4146 const ledc_channel_t ledc_channel)
4247 : Module(stepper_motor, name),
4348 step_pin(step_pin),
4449 dir_pin(dir_pin),
45- pcnt_unit(pcnt_unit),
46- pcnt_channel(pcnt_channel),
4750 ledc_timer(ledc_timer),
4851 ledc_channel(ledc_channel) {
4952 gpio_reset_pin (step_pin);
5053 gpio_reset_pin (dir_pin);
5154
5255 this ->properties = StepperMotor::get_defaults ();
5356
54- pcnt_config_t pcnt_config = {
55- .pulse_gpio_num = step_pin,
56- .ctrl_gpio_num = dir_pin,
57- .lctrl_mode = PCNT_MODE_REVERSE,
58- .hctrl_mode = PCNT_MODE_KEEP,
59- .pos_mode = PCNT_COUNT_INC,
60- .neg_mode = PCNT_COUNT_DIS,
61- .counter_h_lim = 30000 ,
62- .counter_l_lim = -30000 ,
63- .unit = this ->pcnt_unit ,
64- .channel = this ->pcnt_channel ,
57+ pcnt_unit_config_t unit_config = {
58+ .low_limit = -30000 ,
59+ .high_limit = 30000 ,
60+ .intr_priority = 0 ,
61+ .flags = {},
62+ };
63+ check_error (pcnt_new_unit (&unit_config, &this ->pcnt_unit ), " failed to create PCNT unit" );
64+
65+ pcnt_chan_config_t chan_config = {
66+ .edge_gpio_num = step_pin,
67+ .level_gpio_num = dir_pin,
68+ .flags = {},
6569 };
66- pcnt_unit_config (&pcnt_config);
67- pcnt_counter_pause (this ->pcnt_unit );
68- pcnt_counter_clear (this ->pcnt_unit );
69- pcnt_counter_resume (this ->pcnt_unit );
70+ check_error (pcnt_new_channel (this ->pcnt_unit , &chan_config, &this ->pcnt_channel ), " failed to create PCNT channel" );
71+
72+ check_error (pcnt_channel_set_edge_action (this ->pcnt_channel ,
73+ PCNT_CHANNEL_EDGE_ACTION_INCREASE,
74+ PCNT_CHANNEL_EDGE_ACTION_HOLD),
75+ " failed to set PCNT edge action" );
76+
77+ check_error (pcnt_channel_set_level_action (this ->pcnt_channel ,
78+ PCNT_CHANNEL_LEVEL_ACTION_KEEP,
79+ PCNT_CHANNEL_LEVEL_ACTION_INVERSE),
80+ " failed to set PCNT level action" );
81+
82+ check_error (pcnt_unit_enable (this ->pcnt_unit ), " failed to enable PCNT unit" );
83+ check_error (pcnt_unit_clear_count (this ->pcnt_unit ), " failed to clear PCNT count" );
84+ check_error (pcnt_unit_start (this ->pcnt_unit ), " failed to start PCNT unit" );
7085
7186 ledc_timer_config_t timer_config = {
7287 .speed_mode = SPEED_MODE,
73- .duty_resolution = LEDC_TIMER_1_BIT ,
88+ .duty_resolution = DUTY_RESOLUTION ,
7489 .timer_num = this ->ledc_timer ,
7590 .freq_hz = 1000 ,
7691 .clk_cfg = LEDC_AUTO_CLK,
7792 .deconfigure = false ,
7893 };
79- ledc_timer_config (&timer_config);
94+ check_error ( ledc_timer_config (&timer_config), " failed to configure LEDC timer " );
8095
8196 ledc_channel_config_t channel_config = {
8297 .gpio_num = step_pin,
@@ -88,16 +103,16 @@ StepperMotor::StepperMotor(const std::string name,
88103 .hpoint = 0 ,
89104 .flags = {},
90105 };
91- ledc_channel_config (&channel_config);
106+ check_error ( ledc_channel_config (&channel_config), " failed to configure LEDC channel " );
92107
93108 gpio_set_direction (step_pin, GPIO_MODE_INPUT_OUTPUT);
94109 gpio_set_direction (dir_pin, GPIO_MODE_INPUT_OUTPUT);
95110}
96111
97112void StepperMotor::read_position () {
98- int16_t count;
99- pcnt_get_counter_value (this ->pcnt_unit , &count);
100- int16_t d_count = count - this ->last_count ;
113+ int count;
114+ pcnt_unit_get_count (this ->pcnt_unit , &count);
115+ int d_count = count - this ->last_count ;
101116 if (d_count > 15000 ) {
102117 d_count -= 30000 ;
103118 }
@@ -113,7 +128,7 @@ void StepperMotor::set_state(StepperState new_state) {
113128 this ->properties .at (" idle" )->boolean_value = (new_state == Idle);
114129
115130 gpio_matrix_out (this ->step_pin , new_state == Idle ? SIG_GPIO_OUT_IDX : SPEED_OUT_IDX + this ->ledc_channel , 0 , 0 );
116- ledc_set_duty (SPEED_MODE, this ->ledc_channel , new_state == Idle ? 0 : 1 );
131+ ledc_set_duty (SPEED_MODE, this ->ledc_channel , new_state == Idle ? 0 : DUTY_VALUE );
117132 ledc_update_duty (SPEED_MODE, this ->ledc_channel );
118133}
119134
0 commit comments