PWM
PWM API Status
API |
BK7236 |
BK7236_cp1 |
---|---|---|
Y |
Y |
|
Y |
Y |
|
Y |
Y |
|
Y |
Y |
|
|
Y |
Y |
Y |
Y |
|
Y |
Y |
|
Y |
Y |
|
Y |
Y |
|
Y |
Y |
|
Y |
Y |
|
Y |
Y |
|
Y |
Y |
|
Y |
Y |
|
Y |
Y |
|
Y |
Y |
|
Y |
Y |
|
Y |
Y |
|
Y |
Y |
|
Y |
Y |
|
Y |
Y |
PWM Channel Number
Capability |
BK7236 |
BK7236_cp1 |
---|---|---|
Channel Number |
6 |
6 |
PWM Group Support
Capability |
BK7236 |
BK7236_cp1 |
---|---|---|
Software Group |
Y |
Y |
Hardware Group |
Y |
Y |
PWM Duty Support
Capability |
BK7236 |
BK7236_cp1 |
---|---|---|
period_cycle |
Y |
Y |
duty_cycle |
Y |
Y |
duty2_cycle |
Y |
Y |
duty3_cycle |
Y |
Y |
For unsupported duty fileds, we should set them to 0.
PWM Capture Edge Support Status
Capability |
BK7236 |
BK7236_cp1 |
---|---|---|
PWM_CAPTURE_POS |
Y |
Y |
PWM_CAPTURE_NEG |
Y |
Y |
PWM_CAPTURE_EDGE |
Y |
Y |
PWM Channel and GPIO Map
Channel Number |
BK7236 |
BK7236_cp1 |
---|---|---|
0 |
6 |
6 |
1 |
7 |
7 |
2 |
8 |
8 |
3 |
9 |
9 |
4 |
24 |
24 |
5 |
25 |
25 |
6 |
32 |
32 |
7 |
33 |
33 |
8 |
34 |
34 |
9 |
35 |
35 |
10 |
36 |
36 |
11 |
37 |
37 |
If the channel has more than one GPIO to map, the channel init API will choose the smallest GPIO port as the default value. We can call bk_pwm_set_gpio() to change it after the init API is called.
PWM API Reference
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)
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.
3. If D1 equals period, it indicates the duty ratio is 100% and the signal is always high.
4. The signal strengh between two successive duties is opposite, e.g. if signal of D1 is high, then signal of D2 is low.
5. The initial signal is the signal strengh of D1 if D1 is not 0.
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.
2. The chan2_duty_cycle is actually the 2nd signal wave for channel 2, as depicted in above picture.
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.
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
-
bk_err_t bk_pwm_set_mode_timer(pwm_chan_t chan)
Set pwm channel as timer mode.
- Attention
The caller need to make sure the parameter chan is correct!
- 参数
chan – PWM channel
- 返回
BK_OK: succeed
BK_ERR_PWM_CHAN_ID: invalid PWM channel
others: other errors.
PWM API Typedefs
Header File
Structures
-
struct pwm_init_config_t
Public Members
-
uint32_t period_cycle
PWM period cycle, unit is (1/clock_frequency)
-
uint32_t duty_cycle
PWM duty cycle, unit is (1/clock_frequency)
-
uint32_t duty2_cycle
PWM duty2 cycle, unit is (1/clock_frequency)
-
uint32_t duty3_cycle
PWM duty2 cycle, unit is (1/clock_frequency)
-
uint32_t reserved[4]
Reserved for future extend, must set to 0
-
uint32_t period_cycle
-
struct pwm_period_duty_config_t
-
struct pwm_capture_init_config_t
Public Members
-
pwm_capture_edge_t edge
PWM chan capture edge
-
pwm_capture_edge_t edge
-
struct pwm_group_init_config_t
Public Members
-
pwm_chan_t chan1
The first PWM channel ID in a group
-
pwm_chan_t chan2
The second PWM channel ID in a group
-
uint32_t period_cycle
PWM Group period cycle
-
uint32_t chan1_duty_cycle
Duty cycle of chan1
-
uint32_t chan2_duty_cycle
Duty cycle of chan2
-
pwm_chan_t chan1
-
struct pwm_group_config_t
Macros
-
BK_ERR_PWM_CLOCK
PWM global clock type not supported
-
BK_ERR_PWM_CHAN_CLOCK
PWM channel clock type not supported
-
BK_ERR_PWM_CHAN_ID
PWM channel number is invalid
-
BK_ERR_PWM_PERIOD_DUTY
PWM all duty cycle > period cycle
-
BK_ERR_PWM_CAPTURE_EDGE
PWM capture edge is invalid
-
BK_ERR_PWM_NOT_INIT
PWM driver not init
-
BK_ERR_PWM_CHAN_NOT_INIT
PWM channel not init
-
BK_ERR_PWM_CHAN_NOT_START
PWM channel not init
-
BK_ERR_PWM_GROUP_ID
PWM group ID is invalid
-
BK_ERR_PWM_GROUP_EXIST
PWM group already exists
-
BK_ERR_PWM_GROUP_CHAN_USED
PWM channel is used by other group
-
BK_ERR_PWM_GROUP_NOT_EXIST
PWM group doesn’t exist
-
BK_ERR_PWM_GROUP_DUTY
PWM group cycle invalid
-
BK_ERR_PWM_GROUP_SAME_CHAN
PWM group channel is same
-
BK_ERR_PWM_INVALID_GPIO_MODE
PWM invalid gpio mode
-
PWM_DEFAULT_PWM_CONFIG()
default PWM configuration
-
PWM_DEFAULT_PWM_CAPTURE_CONFIG()
default PWM capture configuration
-
PWM_GROUP_ID_INVALID
Invalid PWM group ID
Type Definitions
-
typedef void (*pwm_isr_t)(pwm_chan_t chan)
PWM interrupt service routine.
-
typedef uint8_t pwm_group_t
PWM group type.
Header File
Macros
-
BK_ERR_PWM_HAL_CLOCK
Type Definitions
-
typedef uint8_t pwm_unit_t
-
typedef uint8_t pwm_chan_t
Enumerations
-
enum pwm_mode_t
Values:
-
enumerator PWM_MODE_IDLE
-
enumerator PWM_MODE_PWM
-
enumerator PWM_MODE_CAPTUR
-
enumerator PWM_MODE_IDLE
-
enum pwm_id_t
Values:
-
enumerator PWM_ID_0
pwm id 0
-
enumerator PWM_ID_1
pwm id 1
-
enumerator PWM_ID_2
pwm id 2
-
enumerator PWM_ID_3
pwm id 3
-
enumerator PWM_ID_4
pwm id 4
-
enumerator PWM_ID_5
pwm id 5
-
enumerator PWM_ID_6
-
enumerator PWM_ID_7
-
enumerator PWM_ID_8
-
enumerator PWM_ID_9
-
enumerator PWM_ID_10
-
enumerator PWM_ID_11
-
enumerator PWM_ID_MAX
pwm id max
-
enumerator PWM_ID_0
-
enum pwm_ch_t
Values:
-
enumerator PWM_CH_0
-
enumerator PWM_CH_1
-
enumerator PWM_CH_2
-
enumerator PWM_CH_3
-
enumerator PWM_CH_4
-
enumerator PWM_CH_5
-
enumerator PWM_CH_MAX
-
enumerator PWM_CH_0
-
enum pwm_src_clk_t
Values:
-
enumerator PWM_SCLK_CLK32
PWM source clock dco
-
enumerator PWM_SCLK_XTAL
PWM source clock xtal 26M
-
enumerator PWM_SCLK_CLK32
-
enum pwm_capture_edge_t
Values:
-
enumerator PWM_CAPTURE_POS
Calculate cycles between two post edges
-
enumerator PWM_CAPTURE_NEG
Calculate cycles between two negtive edges
-
enumerator PWM_CAPTURE_EDGE
Calculate cycles between two edges (post or negative)
-
enumerator PWM_CAPTURE_MAX
Invalid capture mode
-
enumerator PWM_CAPTURE_POS