PWM API
PWM (Pulse Width Modulation) 脉宽调制API接口。
Header File
Functions
-
bk_err_t bk_pwm_driver_init(void)
Init the PWM driver.
This API init the resoure common to all PWM channels:
Init PWM driver control memory
Configure PWM common clock to 26M
This API should be called before any other PWM APIs.
- 返回
BK_OK: succeed
others: other errors.
-
bk_err_t bk_pwm_driver_deinit(void)
Deinit the PWM driver.
This API free all resource related to PWM and power down all PWM channels.
- 返回
BK_OK: succeed
others: other errors.
-
bk_err_t bk_pwm_init(pwm_chan_t chan, const pwm_init_config_t *config)
Init the PWM channel.
This API init the PWM channel:
Power up the PWM channel
Configure the PWM channel clock to 26M
Map the PWM channel to dedicated GPIO port
Set the period and duty cycle.
For duty/cycle relationship, refer to bk_pwm_set_period_duty()
- 返回
BK_OK: succeed
BK_ERR_PWM_NOT_INIT: PWM driver not init
BK_ERR_NULL_PARAM: config is NULL
BK_ERR_PWM_CHAN_ID: invalid PWM channel
BK_ERR_PWM_PERIOD_DUTY: PWM duty/period relationship is invalid
others: other errors.
-
bk_err_t bk_pwm_deinit(pwm_chan_t chan)
Deinit a PWM channel.
This API deinit the PWM channel:
Stop the PWM channel
Reset all configuration of PWM channel to default value
Power down the PWM channel
- 返回
BK_OK: succeed
others: other errors.
-
bk_err_t bk_pwm_start(pwm_chan_t chan)
Stop a PWM channel.
This API init the resoure common to all PWM channels:
Init PWM driver control memory
Configure PWM common clock to 26M
- 返回
BK_OK: succeed
others: other errors.
-
bk_err_t bk_pwm_stop(pwm_chan_t chan)
Stop a PWM channel.
This API init the resoure common to all PWM channels:
Init PWM driver control memory
Configure PWM common clock to 26M
- 返回
BK_OK: succeed
others: other errors.
-
bk_err_t bk_pwm_set_period_duty(pwm_chan_t chan, pwm_period_duty_config_t *config)
Configure the PWM period and duty cycle.
This API is used to configure the period and duty time. The unit is cycle of PWM channel clock, since the PWM channel clock is default to 26M, the unit is 1/26M (1/26 000 000) seconds.
The beken chip supports up to 3 duties, the exact duty numbers depends on the target type.
EXample1 - the simplest case::
Clock cycle = 1/26M Initial signal is High duty_cycle = D1 = 3 duty2_cycle = 0 duty3_cycle = 0 period_cycle = 3 + 2 = 5 |<-C->| __ __ __ __ __ __ __ __ __ __ __ __ Clock Signal: __| |__| |__| |__| |__| |__| |__| |__| |__| |__| |__| |__| |__ __________________ _________________ ___________ PWM Signal: __| |___________| |___________| Duty1: |<------- D1 ----->| Period: |<---------- Period1 --------->|<------ Period2 ------------>|
Example2 - 3 duty with initial signal high::
Clock cycle = 1/26M Duty_cycle = D1 = 1 Duty2_cycle = D2 = 2 Duty3_cycle = D3 = 3 period_cycle = D1 + D2 + D3 = 6 |<-C->| __ __ __ __ __ __ __ __ __ __ __ __ __ Clock Signal: __| |__| |__| |__| |__| |__| |__| |__| |__| |__| |__| |__| |__| ______ _________________ _____ _________________ PWM Signal: __| |___________| | |___________| |__ Duty1: |<-D1->|<----D2--->|<------D3------->| Period: |<--------------- Period1 ---------->|<------------ Period2 ------------>|
Example3 - 3 duty with initial signal low::
Clock cycle = 1/26M Duty_cycle = D1 = 1 Duty2_cycle = D2 = 2 Duty3_cycle = D3 = 3 period_cycle = D1 + D2 + D3 = 6 |<-C->| __ __ __ __ __ __ __ __ __ __ __ __ __ Clock Signal: __| |__| |__| |__| |__| |__| |__| |__| |__| |__| |__| |__| |__| __ ___________ ___________ PWM Signal: |_____| |_________________|_____| |_________________|__ Duty1: |<-D1->|<----D2--->|<------D3------->| Period: |<--------------- Period1 ---------->|<------------ Period2 -------------|
Example4 - 3 duty with initial signal low and period > (D1 + D2 + D3)::
Clock cycle = 1/26M Duty_cycle = D1 = 1 Duty2_cycle = D2 = 2 Duty3_cycle = D3 = 3 period_cycle = D1 + D2 + D3 + 1 = 7 |<-C->| __ __ __ __ __ __ __ __ __ __ __ __ __ Clock Signal: __| |__| |__| |__| |__| |__| |__| |__| |__| |__| |__| |__| |__| __ ___________ _____ ___________ PWM Signal: |_____| |_________________| |_____| |______________ Duty1: |<-D1->|<----D2--->|<------D3------->| Period: |<--------------- Period ----------------->|
- Attention
1. The period should great or equal to (D1 + D2 + D3)
- Attention
2. If the duty Dx is 0, then Dx+1 to D3 should also be 0. If D1 is 0, it indicates the duty ratio is 0% and the signal is always low.
- Attention
3. If D1 equals period, it indicates the duty ratio is 100% and the signal is always high.
- Attention
4. The signal strengh between two successive duties is opposite, e.g. if signal of D1 is high, then signal of D2 is low.
- Attention
5. The initial signal is the signal strengh of D1 if D1 is not 0.
- Attention
6. The duty/period configuration is very flexible, different configurations may have same result.
- 返回
BK_OK: succeed
BK_ERR_NULL_PARAM: config is NULL
BK_ERR_PWM_CHAN_NOT_INIT: PWM channel not init
BK_ERR_PWM_CHAN_ID: invalid PWM channel
BK_ERR_PWM_PERIOD_DUTY: PWM duty/period relationship is invalid
others: other errors.
-
bk_err_t bk_pwm_set_init_signal_low(pwm_chan_t chan)
Set the initial signal to low.
Set the initial signal level of the first duty which is indicated by duty_cycle.
- Attention
The signal will always be high if the duty_cycle equals period cycle (duty ratio is 100%), regardless whether this API is called or NOT.
- 返回
BK_OK: succeed
BK_ERR_PWM_CHAN_NOT_INIT: PWM channel not init
BK_ERR_PWM_CHAN_ID: invalid PWM channel
others: other errors.
-
bk_err_t bk_pwm_set_init_signal_high(pwm_chan_t chan)
Set the initial signal to high.
Set the initial signal level of the first duty which is indicated by duty_cycle.
- Attention
The signal will always be low if the duty_cycle is 0 (duty ratio is 0%), regardless whether this API is called or NOT.
- 返回
BK_OK: succeed
BK_ERR_PWM_CHAN_NOT_INIT: PWM channel not init
BK_ERR_PWM_CHAN_ID: invalid PWM channel
others: other errors.
-
bk_err_t bk_pwm_register_isr(pwm_chan_t chan, pwm_isr_t isr)
Register the interrupt service routine for PWM channel.
- Attention
1. Both bk_pwm_capture_init() and this API can set the ISR, the one called later makes sense.
- 返回
BK_OK: succeed
BK_ERR_PWM_NOT_INIT: PWM driver not init
BK_ERR_PWM_CHAN_ID: invalid PWM channel
others: other errors.
-
bk_err_t bk_pwm_enable_interrupt(pwm_chan_t chan)
Enable interrupt of PWM channel.
The PWM channel interrupt is disabled by default when starting the channel by bk_pwm_start() or bk_pwm_group_start(), while it’s enabled by default when starting the channel by bk_pwm_capture_start().
This API is designed mainly for debug purpose, we can use it to enable the interrupt of any PWM channel, regardless of whether the channel is started by bk_pwm_start() or bk_pwm_group_start() or bk_pwm_capture_start().
The bk_pwm_stop() and bk_pwm_group_stop() also disable the interrupt, but the bk_pwm_start() and bk_pwm_group_start will not enable the interrupt. So if the channel interrupt is enabled, and then stop and start the channel, we need to call this API to re-enable the interrupt.
- Attention
1. The interrupt can be enabled only after PWM channel is started by bk_pwm_start().
- 返回
BK_OK: succeed
BK_ERR_PWM_NOT_INIT: PWM driver not init
BK_ERR_PWM_CHAN_ID: invalid PWM channel
BK_ERR_PWM_CHAN_NOT_START: PWM channel is not started
others: other errors.
-
bk_err_t bk_pwm_disable_interrupt(pwm_chan_t chan)
Disable interrupt of PWM channel.
Stop the interrupt of any PWM channel, regardless whether the channel is in PWM mode, or PWM capture mode, or PWM group mode.
- Attention
1. bk_pwm_capture_start() will enable the interrupt anyway, so if we want to disable the interrupt of PWM capture channel, we need to call this API anytime bk_pwm_capture_start() is called.
- 参数
chan – the channel ID
- 返回
BK_OK: succeed
BK_ERR_PWM_NOT_INIT: PWM driver not init
BK_ERR_PWM_CHAN_ID: invalid PWM channel
others: other errors.
-
bk_err_t bk_pwm_group_init(const pwm_group_init_config_t *config, pwm_group_t *group)
Init the PWM group.
This API init the PWM group. The PWM group is a channel pair that has following attributes:
The period is same
The initial signal level is opposite
Start and stop at the same time
Below is a picture to demonstrate the relationship between duty and period::
|<------------------------ period_cycle ---------------------------->| |<--chan1_duty_cycle -->|<- D1 --|<--- chan2_duty_cycle --->|<- D2 ->| _______________________ channe1 1 | |____________________________________________| __________________________ channel 2 |________________________________| |________|
The D1/D2 indicates the dead time cycle, it’s calculated based on following formula: D1 = D2 = (period - chan1_duty_cycle - chan2_duty_cycle)/2
- Attention
1. This API doesn’t check whether the PWM channel is already used in other mode. e.g. If the API doesn’t returns error if config->chan1 is already used in capture mode, the application need to make sure the channel configured in the group is not used for other purpose.
- Attention
2. The chan2_duty_cycle is actually the 2nd signal wave for channel 2, as depicted in above picture.
- Attention
3. This API supports to group any two available channel into a PWM group, however, we recommend to group 0/1, 2/3, 4/5 into a group, because hardware can support these group directly and we can start the channels in the group at exactly same time.
- Attention
4. The chan1_duty_cycle and chan2_duty_cycle should be great than 0.
- 参数
config – configuration of PWM group
group – store the group ID if the API is succeed.
- 返回
BK_OK: succeed
BK_ERR_PWM_NOT_INIT: PWM driver not init
BK_ERR_NULL_PARAM: config or group is NULL
BK_ERR_PWM_CHAN_ID: channel 1 or 2 in the group is invalid
BK_ERR_PWM_GROUP_SAME_CHAN: channel 1 and 2 are same
BK_ERR_PWM_GROUP_EXIST: a group with channel 1 and 2 is already exists
BK_ERR_PWM_GROUP_CHAN_USED: a existing group has a channel equals to channel 1 or 2
BK_ERR_PWM_GROUP_DUTY: period cycle < (chan1_duty_cycle + chan2_duty_cycle)
BK_ERR_PWM_PERIOD_DUTY: PWM duty/period relationship is invalid
others: other errors.
-
bk_err_t bk_pwm_group_deinit(pwm_group_t group)
Deinit a PWM group.
This API stops and powers down channels in a PWM group.
- Attention
This API returns BK_OK directly if the group doesn’t exist.
- 参数
group – the group ID returned bk bk_pwm_group_init()
- 返回
BK_OK: succeed
others: other errors.
-
bk_err_t bk_pwm_group_set_config(pwm_group_t group, const pwm_group_config_t *config)
Configure the PWM group.
Configure the duty and period of a PWM group, for duty/period relationship refer to bk_pwm_group_init().
- Attention
The configuration can’t take effect until the current period is ended
- 参数
group – the group ID to be configured
config – configuration of PWM group
- 返回
BK_OK: succeed
BK_ERR_NULL_PARAM: config or group is NULL
BK_ERR_PWM_GROUP_NOT_EXIST: the group doesn’t exist
BK_ERR_PWM_GROUP_DUTY: period cycle < (chan1_duty_cycle + chan2_duty_cycle)
BK_ERR_PWM_PERIOD_DUTY: PWM duty/period relationship is invalid
others: other errors.
-
bk_err_t bk_pwm_group_start(pwm_group_t group)
Start the PWM group.
- 参数
group – the group ID to be started
- 返回
BK_OK: succeed
BK_ERR_PWM_GROUP_NOT_EXIST: the group doesn’t exist
others: other errors.
-
bk_err_t bk_pwm_group_stop(pwm_group_t group)
Stop the PWM group.
- 参数
group – the group ID to be stopped
- 返回
BK_OK: succeed
BK_ERR_PWM_GROUP_NOT_EXIST: the group doesn’t exist
others: other errors.
-
bk_err_t bk_pwm_capture_init(pwm_chan_t chan, const pwm_capture_init_config_t *config)
Init the PWM capture.
The PWM capture can calculate the cycles between two different edges, currently we support following mode:
PWM_CAPTURE_POS - calcualte cycles between two pos-edge, the interrupt trigger in post edge
PWM_CAPTURE_NEG - calcualte cycles between two neg-edge, the interrupt trigger in neg edge
PWM_CAPTURE_EDGE - calculate cycles between two edge (pos or neg), the interrupt trigger in post or neg edge.
Example 1 - init the capture in PWM_CAPTURE_POS mode::
|<------ C1 ---->|<------- C2 ------->| ______ ___________ ________________ _ PWM input _| |_________| |________| |__________| Capture value | C1 | C2 |
- 参数
chan – the capture channel
config – the configuration of capture
- 返回
BK_OK: succeed
BK_ERR_PWM_NOT_INIT: PWM driver not init
BK_ERR_NULL_PARAM: config is NULL
BK_ERR_PWM_CHAN_ID: invalid channel
BK_ERR_PWM_CAPTURE_EDGE: capture edge is invalid or not supported.
others: other errors.
-
bk_err_t bk_pwm_capture_deinit(pwm_chan_t chan)
Deinit the PWM capture.
- 参数
chan – the capture channel
- 返回
BK_OK: succeed
BK_ERR_PWM_NOT_INIT: PWM driver not init
BK_ERR_PWM_CHAN_ID: invalid channel
others: other errors.
-
bk_err_t bk_pwm_capture_start(pwm_chan_t chan)
Start the PWM capture.
- 参数
chan – channel to be started
- 返回
BK_OK: succeed
BK_ERR_PWM_NOT_INIT: PWM driver not init
BK_ERR_PWM_CHAN_ID: invalid PWM channel
others: other errors.
-
bk_err_t bk_pwm_capture_stop(pwm_chan_t chan)
Stop the PWM capture.
- 参数
chan – channel to be stopped
- 返回
BK_OK: succeed
BK_ERR_PWM_NOT_INIT: PWM driver not init
BK_ERR_PWM_CHAN_ID: invalid PWM channel
others: other errors.
-
uint32_t bk_pwm_capture_get_value(pwm_chan_t chan)
Get the capture value.
- Attention
The caller need to make sure the parameter chan is correct!
- 参数
chan – PWM channel
- 返回
capture value
-
uint32_t bk_pwm_capture_get_period_duty_cycle(pwm_chan_t chan, uint32_t timeout_ms)
Get the capture period and duty cycle.
- Attention
The caller need to make sure the parameter chan is correct!
- 参数
chan – PWM channel
timeout_ms – timeout ms
- 返回
period and duty cycle