Skip to content

Commit 94905dd

Browse files
committed
Merge branch 'bugfix/pwm_support_fractional_phase' into 'master'
bugfix(pwm): support fractional phase See merge request sdk/ESP8266_RTOS_SDK!1424
2 parents c972ccc + 8ba4058 commit 94905dd

File tree

5 files changed

+31
-21
lines changed

5 files changed

+31
-21
lines changed

components/esp8266/driver/ledc.c

Lines changed: 2 additions & 2 deletions
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

Lines changed: 21 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -55,11 +55,11 @@ static const char *TAG = "pwm";
5555
#define AHEAD_TICKS3 2
5656
#define MAX_TICKS 10000000ul
5757

58-
#define PWM_VERSION "PWM v3.2"
58+
#define PWM_VERSION "PWM v3.4"
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);
@@ -259,9 +259,7 @@ esp_err_t pwm_get_phase(uint8_t channel_num, uint16_t *phase_p)
259259
static void pwm_timer_enable(uint8_t enable)
260260
{
261261
if (0 == enable) {
262-
ENTER_CRITICAL();
263262
REG_WRITE(WDEVTSF0TIMER_ENA, REG_READ(WDEVTSF0TIMER_ENA) & (~WDEV_TSF0TIMER_ENA));
264-
EXIT_CRITICAL();
265263
} else {
266264
REG_WRITE(WDEVTSF0TIMER_ENA, WDEV_TSF0TIMER_ENA);
267265
}
@@ -310,14 +308,20 @@ static void IRAM_ATTR pwm_timer_intr_handler(void)
310308
pwm_obj->this_target = AHEAD_TICKS1 + AHEAD_TICKS3;
311309
}
312310

311+
REG_WRITE(WDEVSLEEP0_CONF, REG_READ(WDEVSLEEP0_CONF) & (~WDEV_TSFUP0_ENA));
312+
REG_WRITE(WDEVTSF0TIMER_ENA, REG_READ(WDEVTSF0TIMER_ENA) & (~WDEV_TSF0TIMER_ENA));
313313
REG_WRITE(WDEVTSFSW0_LO, 0);
314314
//WARNING, pwm_obj->this_target - AHEAD_TICKS1 should be bigger than 2
315315
REG_WRITE(WDEVTSF0_TIMER_LO, pwm_obj->this_target - AHEAD_TICKS1);
316316
REG_WRITE(WDEVTSF0TIMER_ENA, WDEV_TSF0TIMER_ENA);
317+
REG_WRITE(WDEVSLEEP0_CONF, REG_READ(WDEVSLEEP0_CONF) | WDEV_TSFUP0_ENA);
317318
}
318319

319320
static void pwm_timer_start(uint32_t period)
320321
{
322+
ENTER_CRITICAL();
323+
REG_WRITE(WDEVSLEEP0_CONF, REG_READ(WDEVSLEEP0_CONF) & (~WDEV_TSFUP0_ENA));
324+
REG_WRITE(WDEVTSF0TIMER_ENA, REG_READ(WDEVTSF0TIMER_ENA) & (~WDEV_TSF0TIMER_ENA));
321325
// suspend all task to void timer interrupt missed
322326
// TODO, do we need lock interrupt here, I think interrupt context will not take 1ms long
323327
// time low field to 0
@@ -334,8 +338,11 @@ static void pwm_timer_start(uint32_t period)
334338
pwm_obj->this_target = US_TO_TICKS(period);
335339
// WARNING: pwm_obj->this_target should bigger than AHEAD_TICKS1
336340
REG_WRITE(WDEVTSF0_TIMER_LO, pwm_obj->this_target - AHEAD_TICKS1);
337-
// enable timer
341+
REG_WRITE(WDEVTSF0TIMER_ENA, WDEV_TSF0TIMER_ENA);
342+
REG_WRITE(WDEVSLEEP0_CONF, REG_READ(WDEVSLEEP0_CONF) | WDEV_TSFUP0_ENA);
343+
//enable timer
338344
pwm_timer_enable(1);
345+
EXIT_CRITICAL();
339346
}
340347

341348
static void pwm_timer_register(void (*handle)(void))
@@ -573,7 +580,9 @@ esp_err_t pwm_stop(uint32_t stop_level_mask)
573580
{
574581
int16_t i = 0;
575582

583+
ENTER_CRITICAL();
576584
pwm_timer_enable(0);
585+
EXIT_CRITICAL();
577586
uint32_t level_set = REG_READ(PERIPHS_GPIO_BASEADDR + GPIO_OUT_ADDRESS);
578587

579588
for (i = 0; i < pwm_obj->channel_num; i++) {

components/esp8266/include/driver/pwm.h

Lines changed: 4 additions & 4 deletions
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.

components/esp8266/include/esp8266/eagle_soc.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -148,12 +148,14 @@
148148

149149
#define WDEVTSF0_TIME_LO 0x3ff21004
150150
#define WDEVTSF0_TIME_HI 0x3ff21008
151+
#define WDEVSLEEP0_CONF 0x3ff21014
151152
#define WDEVTSFSW0_LO 0x3ff21018
152153
#define WDEVTSFSW0_HI 0x3ff2101C
153154
#define WDEVTSF0_TIMER_LO 0x3ff2109c
154155
#define WDEVTSF0_TIMER_HI 0x3ff210a0
155156
#define WDEVTSF0TIMER_ENA 0x3ff21098
156157
#define WDEV_TSF0TIMER_ENA BIT(31)
158+
#define WDEV_TSFUP0_ENA BIT(31)
157159

158160
//Watch dog reg {{
159161
#define PERIPHS_WDT_BASEADDR 0x60000900

examples/peripherals/pwm/main/pwm_example_main.c

Lines changed: 2 additions & 3 deletions
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)