MediaTek-Labs / mt3620_m4_software

mt3620_m4_driver
Other
32 stars 29 forks source link

PWM with two independent channels output same wave after start #36

Closed m4tto closed 3 years ago

m4tto commented 3 years ago

Hi,

I'm seeing strange behavior in the configuration of a PWM controller. Even If I configure two channels with different freq and duty, at start they both have the same period and duty equal to the last set.

This is the example code:

    int ret = 0;

printf("PWM Task Start\n");

/* Init PWM */
ret |= mtk_os_hal_pwm_ctlr_init(PWM_CTRL_GROUP,
                                PWM_EN_MASK);
if (ret) {
    printf("mtk_os_hal_pwm_ctlr_init failed\n");
    goto err_exit;
}

printf("enable feature 1\n");
/* Configure PWM */
ret |= mtk_os_hal_pwm_feature_enable(PWM_CTRL_GROUP,
                     PWM_ON_OFF_CH,
                     PWM_GLOBAL_KICK,
                     PWM_IO_CTRL,
                     PWM_POLARITY_SET);
printf("enable feature 2\n");
ret |= mtk_os_hal_pwm_feature_enable(PWM_CTRL_GROUP,
                     PWM_TACH_SET_CH,
                     PWM_GLOBAL_KICK,
                     PWM_IO_CTRL,
                     PWM_POLARITY_SET);
if (ret) {
    printf("mtk_os_hal_pwm_feature_enable failed\n");
    goto err_exit;
}

/* Set PWM Frequency & Duty */
printf("set duty 1\n");
ret |= mtk_os_hal_pwm_config_freq_duty_normal(PWM_CTRL_GROUP,
    PWM_ON_OFF_CH,
    1000,
    500);
printf("set duty 2\n");
ret |= mtk_os_hal_pwm_config_freq_duty_normal(PWM_CTRL_GROUP,
    PWM_TACH_SET_CH,
    2500,
    500);

// /* Start PWM */
 printf("start 1\n");
 ret |= mtk_os_hal_pwm_start_normal(PWM_CTRL_GROUP,
                                    PWM_ON_OFF_CH);
 printf("start 2\n");
 ret |= mtk_os_hal_pwm_start_normal(PWM_CTRL_GROUP,
                                    PWM_TACH_SET_CH);
 if (ret) {
    printf("mtk_os_hal_pwm_start_normal failed\n");
    goto err_exit;
 }

After start, both pwm have 2.5KHz frequency and 50% duty. If I call mtk_os_hal_pwm_config_freq_duty_normal after start, on each channel, I can configure them as I want. I suspect this is not the intended behaviour. Probably the cause is here (mhal_pwm.c lines 369,370):

    _mtk_mhal_pwm_group_get(ctlr->base,
    pwm_num,
    &frequency,
    &duty_cycle,
    &pwm_enable);

pwm_enable = 1;

pwm_debug("frequency is =%d,duty =%d.\n", frequency, duty_cycle);
_mtk_mhal_pwm_group_set(ctlr->base,
    pwm_num,
    ctlr->data->current_frequency,
    ctlr->data->current_duty_cycle,
    pwm_enable
    );

frequency and duty are not set using those get from _mtk_mhal_pwm_group_get

kevinwh-chou commented 3 years ago

Hi,

The duty_cycle got from _mtk_mhal_pwm_group_get(...) will be 0 due to certain design reason, which makes this duty_cycle unable to be directly applied.

Actually I've checked that the current API functions were initially designed to be:

  1. Call mtk_os_hal_pwm_config_freq_duty_normal(...) first for one channel
  2. Call mtk_os_hal_pwm_start_normal(...) to start right after configuration for this channel is done in the step 1

So your example code will become the following:

printf("set`` duty 1\n");
ret |= mtk_os_hal_pwm_config_freq_duty_normal(PWM_CTRL_GROUP, PWM_ON_OFF_CH, 1000, 500);

printf("start 1\n");
ret |= mtk_os_hal_pwm_start_normal(PWM_CTRL_GROUP, PWM_ON_OFF_CH);

printf("set duty 2\n");
ret |= mtk_os_hal_pwm_config_freq_duty_normal(PWM_CTRL_GROUP, PWM_TACH_SET_CH, 2500, 500);

printf("start 2\n");
ret |= mtk_os_hal_pwm_start_normal(PWM_CTRL_GROUP, PWM_TACH_SET_CH);

The PWM sample code may also be misleading, we will modify them in the future update.

m4tto commented 3 years ago

I see, thank you for your prompt reply.