Skip to content

Commit 72cbf0d

Browse files
committed
bugfix(pwm): support fractional phase
* Supports fractional phase, making the phase function produce higher precision waveforms. * Enhanced stability
1 parent ac10b42 commit 72cbf0d

File tree

4 files changed

+17
-17
lines changed

4 files changed

+17
-17
lines changed

components/esp8266/driver/ledc.c

+2-2
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,7 @@ typedef struct {
5151
uint32_t step_01duty; // 0.1 of the duty value
5252
uint32_t step_001duty; // 0.01 of the duty value
5353
uint32_t gpio_num;//gpio pins
54-
int16_t phase; //init phase
54+
float phase; //init phase
5555
int fade_time; // Time to duty by fade
5656
} ledc_obj_t;
5757

@@ -277,7 +277,7 @@ static void ledc_task(void* pvParameters)
277277

278278
esp_err_t ledc_fade_func_install(int intr_alloc_flags)
279279
{
280-
int16_t ledc_phase[LEDC_CHANNEL_MAX] = {0};
280+
float ledc_phase[LEDC_CHANNEL_MAX] = {0};
281281
uint32_t ledc_duty[LEDC_CHANNEL_MAX] = {0};
282282
uint32_t ledc_gpio_num[LEDC_CHANNEL_MAX] = {0};
283283

components/esp8266/driver/pwm.c

+9-8
Original file line numberDiff line numberDiff line change
@@ -59,7 +59,7 @@ static const char *TAG = "pwm";
5959

6060
typedef struct {
6161
uint32_t duty; /*!< pwm duty for each channel */
62-
int16_t phase; /*!< pwm phase for each channel */
62+
float phase; /*!< pwm phase for each channel */
6363
uint8_t io_num; /*!< pwm io_num for each channel */
6464
} pwm_info_t;
6565

@@ -113,13 +113,13 @@ static void pwm_phase_init(void)
113113

114114
for (i = 0; i < pwm_obj->channel_num; i++) {
115115
if (-180 < pwm_obj->pwm_info[i].phase && pwm_obj->pwm_info[i].phase < 0) {
116-
time_delay = 0 - ((0 - pwm_obj->pwm_info[i].phase) * pwm_obj->depth / 360);
116+
time_delay = (int32_t)(0 - ((0 - pwm_obj->pwm_info[i].phase) * pwm_obj->depth / 360.0));
117117
} else if (pwm_obj->pwm_info[i].phase == 0) {
118118
continue;
119-
} else if (180 > pwm_obj->pwm_info[i].phase && pwm_obj->pwm_info[i].phase > 0) {
120-
time_delay = pwm_obj->pwm_info[i].phase * pwm_obj->depth / 360;
119+
} else if (180 >= pwm_obj->pwm_info[i].phase && pwm_obj->pwm_info[i].phase > 0) {
120+
time_delay = (int32_t)(pwm_obj->pwm_info[i].phase * pwm_obj->depth / 360.0);
121121
} else {
122-
ESP_LOGE(TAG, "channel[%d] phase error %d, valid ramge from (-180,180)\n", i, pwm_obj->pwm_info[i].phase);
122+
ESP_LOGE(TAG, "channel[%d] phase error %f, valid ramge from (-180,180]\n", i, pwm_obj->pwm_info[i].phase);
123123
continue;
124124
}
125125

@@ -224,7 +224,7 @@ esp_err_t pwm_set_period_duties(uint32_t period, uint32_t *duties)
224224
return ESP_OK;
225225
}
226226

227-
esp_err_t pwm_set_phase(uint8_t channel_num, int16_t phase)
227+
esp_err_t pwm_set_phase(uint8_t channel_num, float phase)
228228
{
229229
PWM_CHECK(channel_num < pwm_obj->channel_num, "Channel num error", ESP_ERR_INVALID_ARG);
230230

@@ -233,7 +233,7 @@ esp_err_t pwm_set_phase(uint8_t channel_num, int16_t phase)
233233
return ESP_OK;
234234
}
235235

236-
esp_err_t pwm_set_phases(int16_t *phases)
236+
esp_err_t pwm_set_phases(float *phases)
237237
{
238238
uint8_t i;
239239
PWM_CHECK(NULL != phases, "Pointer is empty", ESP_ERR_INVALID_ARG);
@@ -246,7 +246,7 @@ esp_err_t pwm_set_phases(int16_t *phases)
246246
return ESP_OK;
247247
}
248248

249-
esp_err_t pwm_get_phase(uint8_t channel_num, uint16_t *phase_p)
249+
esp_err_t pwm_get_phase(uint8_t channel_num, float *phase_p)
250250
{
251251
PWM_CHECK(channel_num < pwm_obj->channel_num, "Channel num error", ESP_ERR_INVALID_ARG);
252252
PWM_CHECK(NULL != phase_p, "Pointer is empty", ESP_ERR_INVALID_ARG);
@@ -310,6 +310,7 @@ static void IRAM_ATTR pwm_timer_intr_handler(void)
310310
pwm_obj->this_target = AHEAD_TICKS1 + AHEAD_TICKS3;
311311
}
312312

313+
REG_WRITE(WDEVTSF0TIMER_ENA, 0);
313314
REG_WRITE(WDEVTSFSW0_LO, 0);
314315
//WARNING, pwm_obj->this_target - AHEAD_TICKS1 should be bigger than 2
315316
REG_WRITE(WDEVTSF0_TIMER_LO, pwm_obj->this_target - AHEAD_TICKS1);

components/esp8266/include/driver/pwm.h

+4-4
Original file line numberDiff line numberDiff line change
@@ -145,13 +145,13 @@ esp_err_t pwm_set_duties(uint32_t *duties);
145145
*
146146
* @param channel_num PWM channel number
147147
* the channel_num cannot exceed the value initialized by pwm_init.
148-
* @param phase The phase of this PWM channel, the phase range is (-180 ~ 180).
148+
* @param phase The phase of this PWM channel, the phase range is (-180 ~ 180].
149149
*
150150
* @return
151151
* - ESP_OK Success
152152
* - ESP_ERR_INVALID_ARG Parameter error
153153
*/
154-
esp_err_t pwm_set_phase(uint8_t channel_num, int16_t phase);
154+
esp_err_t pwm_set_phase(uint8_t channel_num, float phase);
155155

156156
/**
157157
* @brief Set the phase of all channels.
@@ -164,7 +164,7 @@ esp_err_t pwm_set_phase(uint8_t channel_num, int16_t phase);
164164
* - ESP_OK Success
165165
* - ESP_ERR_INVALID_ARG Parameter error
166166
*/
167-
esp_err_t pwm_set_phases(int16_t *phases);
167+
esp_err_t pwm_set_phases(float *phases);
168168

169169
/**
170170
* @brief Get the phase of a PWM channel.
@@ -177,7 +177,7 @@ esp_err_t pwm_set_phases(int16_t *phases);
177177
* - ESP_OK Success
178178
* - ESP_ERR_INVALID_ARG Parameter error
179179
*/
180-
esp_err_t pwm_get_phase(uint8_t channel_num, uint16_t *phase_p);
180+
esp_err_t pwm_get_phase(uint8_t channel_num, float *phase_p);
181181

182182
/**
183183
* @brief Set PWM period and duty of each PWM channel.

examples/peripherals/pwm/main/pwm_example_main.c

+2-3
Original file line numberDiff line numberDiff line change
@@ -49,14 +49,13 @@ uint32_t duties[4] = {
4949
};
5050

5151
// phase table, delay = (phase[x]/360)*PERIOD
52-
int16_t phase[4] = {
53-
0, 0, 90, -90,
52+
float phase[4] = {
53+
0, 0, 90.0, -90.0,
5454
};
5555

5656
void app_main()
5757
{
5858
pwm_init(PWM_PERIOD, duties, 4, pin_num);
59-
pwm_set_channel_invert(0x1 << 0);
6059
pwm_set_phases(phase);
6160
pwm_start();
6261
int16_t count = 0;

0 commit comments

Comments
 (0)