Files
kunlun/export/inc/bsp/iot_pwm_api.h
2024-09-28 14:24:04 +08:00

820 lines
33 KiB
C
Executable File

/****************************************************************************
Copyright(c) 2019 by Aerospace C.Power (Chongqing) Microelectronics. ALL RIGHTS RESERVED.
This Information is proprietary to Aerospace C.Power (Chongqing) Microelectronics and MAY NOT
be copied by any method or incorporated into another program without
the express written consent of Aerospace C.Power. This Information or any portion
thereof remains the property of Aerospace C.Power. The Information contained herein
is believed to be accurate and Aerospace C.Power assumes no responsibility or
liability for its use in any way and conveys no license or title under
any patent or copyright and makes no representation or warranty that this
Information is free from patent or copyright infringement.
****************************************************************************/
#ifndef _IOT_PWM_API_H_
#define _IOT_PWM_API_H_
#ifdef __cplusplus
extern "C" {
#endif
/* pwm api mode, working on either IOT_API_MODE_PWM or IOT_API_MODE_EPWM.
IOT_API_MODE_PWM is default. */
typedef enum {
/* working on pwm mode, use 'iot_pwm_xxx' api. */
IOT_API_MODE_PWM = 0,
/* working on epwm mode, use 'iot_epwm_xxx' api */
IOT_API_MODE_EPWM,
}iot_pwm_api_mode_e;
/* define pwm channel */
#define IOT_PWM_CHANNEL_0 0
#define IOT_PWM_CHANNEL_1 1
#define IOT_PWM_CHANNEL_2 2
#define IOT_PWM_CHANNEL_3 3
#define IOT_PWM_CHANNEL_4 4
#define IOT_PWM_CHANNEL_5 5
#define IOT_PWM_CHANNEL_INVAL 0xff
typedef uint32_t (*pwm_isr)();
/**
* @brief iot_pwm_start() - start PWM.
* @param ch: channel num, see IOT_PWM_CHANNEL_XXX.
*/
void iot_pwm_start(uint8_t ch);
/**
* @brief iot_pwm_stop() - stop PWM.
* @param ch: channel num, see IOT_PWM_CHANNEL_XXX.
*/
void iot_pwm_stop(uint8_t ch);
/**
* @brief iot_pwm_hw_init() - initialize the PWM module.
* @param ch: channel num, see IOT_PWM_CHANNEL_XXX.
* @retval: 0 - success
* otherwise - error code
*/
uint8_t iot_pwm_hw_init(uint8_t ch);
/**
* @brief iot_pwm_hw_deinit() - deinitialize the PWM module.
* @param ch: channel num, see IOT_PWM_CHANNEL_XXX.
*/
void iot_pwm_hw_deinit(uint8_t ch);
/**
* @brief iot_pwm_single_mode_init() - initialize the PWM single module.
* @param ch: channel num, see IOT_PWM_CHANNEL_XXX.
* @retval: 0 - for success case
* @retval: otherwise - error code
*/
uint8_t iot_pwm_single_mode_init(uint8_t ch);
/**
* @brief iot_pwm_get_clk() - get the time base clk of PWM.
* @return pwm time base clk frequence, unit is 1Hz.
*/
uint32_t iot_pwm_get_clk();
/** @brief iot_pwm_set_clk() - pwm src clk set.
* Notice: in one pwm, all channel use same clk_source ,
* so keep the clk_source and period the same as last.
* @param clk_source specifies the pwm timer clock source.
* This parameter can be one of the following values:
* @arg IOT_PWM_CLK_SRC_2M5 (KL1)
* @arg IOT_PWM_CLK_SRC_25M (KL1\KL2)
* @arg IOT_PWM_CLK_SRC_50M (KL1)
* @arg IOT_PWM_CLK_SRC_75M (KL2)
* @arg IOT_PWM_CLK_SRC_100M (KL2)
* @return 0 -- Operation Successful; others -- Operation failed.
*/
int iot_pwm_set_clk(uint8_t clk_src);
/**
* @brief iot_pwm_get_ch_clk() - get the PWM channel clock frequency.
* @param ch: channel num, see IOT_PWM_CHANNEL_XXX.
* @return pwm channel clock frequence, unit is 1Hz.
*/
uint32_t iot_pwm_get_ch_clk(uint8_t ch);
/**
* @brief iot_pwm_set_duty() - set the duty cycle of PWM.
* @param ch: channel num, see IOT_PWM_CHANNEL_XXX.
* @param duty: duty cycle 0~10000, stands for 0%~100%, unit:0.01%.
*/
void iot_pwm_set_duty(uint8_t ch, uint32_t duty);
/**
* @brief iot_pwm_set_period() - set the period of PWM.
* @param ch: channel num, see IOT_PWM_CHANNEL_XXX.
* @param period: pwm period.
*/
void iot_pwm_set_period(uint8_t ch, uint32_t period);
/**
* @brief iot_pwm_gpio_config() - config the GPIO for PWM output.
* @param ch: channel channel num, see IOT_PWM_CHANNEL_XXX .
* @param gpio_h: output gpio for PWM wave, can be 0xFF if no gpio for this.
* @param gpio_l: output gpio for PWM opposite wave, can be 0xFF if no gpio
* for this.
*/
void iot_pwm_gpio_config(uint8_t ch, uint8_t gpio_h, uint8_t gpio_l);
/**
* @brief iot_pwm_gpio_config_with_isr() - config the GPIO for PWM output.
* @param ch: channel channel num, see IOT_PWM_CHANNEL_XXX .
* @param gpio_h: output gpio for PWM wave, can be 0xFF if no gpio for this.
* @param gpio_l: output gpio for PWM opposite wave, can be 0xFF if no gpio
* @param isr: PWM interrupt callback function.
* for this.
*/
void iot_pwm_gpio_config_with_isr(uint8_t ch, uint8_t gpio_h,
uint8_t gpio_l, pwm_isr isr);
/**
* @brief iot_pwm_start_for_single() - start PWM in single mode.
* @param ch: channel channel num, see IOT_PWM_CHANNEL_XXX.
*/
void iot_pwm_start_for_single(uint8_t ch);
/**
* @brief iot_pwm_ch_init() - pwm channel init.
* @param ch: channel channel num, see IOT_PWM_CHANNEL_XXX.
*/
void iot_pwm_ch_init(uint8_t ch);
/** @brief iot_pwm_config() - pwm config.
* Notice: in one pwm, all channel use same clk_source and period,
* so keep the clk_source and period the same as last.
* @param ch channel num, see IOT_PWM_CHANNEL_XXX .
* @param clk_source specifies the pwm timer clock source.
* This parameter can be one of the following values:
* @arg IOT_PWM_CLK_SRC_2M5 (KL1)
* @arg IOT_PWM_CLK_SRC_25M (KL1\KL2)
* @arg IOT_PWM_CLK_SRC_50M (KL1)
* @param period 0 ~ (2^15 - 1), period counter.
* @param gpio_p specifies the pwm positive output gpio, set 0xFF if no use.
* @param gpio_n specifies the pwm negative output gpio, set 0xFF if no use.
* @return 0 -- Operation Successful; others -- Operation failed.
*/
int iot_pwm_config(uint8_t ch, uint8_t clk_source,
uint32_t period, uint8_t gpio_p, uint8_t gpio_n);
/** @brief iot_pwm_deconfig() - pwm default config.
* Notice: if pwm channel need iot_pwm_config() again, it first need
* iot_pwm_deconfig().
* @param ch channel num, see IOT_PWM_CHANNEL_XXX .
* @return 0 -- Operation Successful; others -- Operation failed.
*/
int iot_pwm_deconfig(uint8_t ch);
/**
* @brief iot_pwm_set_raw_duty() - set the duty counter of PWM.
* @param ch channel num, see IOT_PWM_CHANNEL_XXX .
* @param duty_cnt duty counter, 0 ~ period max value.
* 100% duty, if duty_cnt >= period cnt
* @return 0 -- Operation Successful; others -- Operation failed.
*/
int iot_pwm_set_raw_duty(uint8_t ch, uint32_t duty_cnt);
/**
* @brief iot_pwm_dead_band_config() - config the dead band of PWM.
* @param ch channel num, see IOT_PWM_CHANNEL_XXX .
* @param rising_db rising dead time, unit in ns.
* @param falling_db falling dead time, unit in ns.
* @param rising_actual return actual rising dead time, unit in ns.
* @param falling_actual return actual falling dead time, unit in ns.
* @return 0 -- Operation Successful; others -- Operation failed.
*/
int iot_pwm_dead_band_config(uint8_t ch, uint32_t rising_db,
uint32_t falling_db, uint32_t *rising_actual, uint32_t *falling_actual);
/**
* @brief iot_pwm_fault_config() - config the fault function of PWM.
* @param ch channel num, see IOT_PWM_CHANNEL_XXX .
* @param gpio gpio num for the fault event signal input, low active.
* @param h_state pwm output state when fault event is low.
* @param l_state pwm output state when fault event is low.
* @param cb fault interrupt hand call back function.
*/
void iot_pwm_fault_config(uint8_t ch, uint8_t gpio, uint8_t h_state,
uint8_t l_state,pwm_isr cb);
/* epwm channels.
IOT_EPWM_CHANNEL_0 ~ IOT_EPWM_CHANNEL_3, available on KL1
IOT_EPWM_CHANNEL_0 ~ IOT_EPWM_CHANNEL_5, available on KL2 \ KL3 */
typedef enum {
IOT_EPWM_CHANNEL_0 = 0,
IOT_EPWM_CHANNEL_1,
IOT_EPWM_CHANNEL_2,
IOT_EPWM_CHANNEL_3,
IOT_EPWM_CHANNEL_4,
IOT_EPWM_CHANNEL_5,
IOT_EPWM_CHANNEL_MAX
}iot_epwm_channel_e;
/* clock source of epwm */
typedef enum {
/* support: KL1 */
IOT_PWM_CLK_SRC_2M5 = 0,
/* support: KL1 \ KL2 \ KL3 */
IOT_PWM_CLK_SRC_25M,
/* support: KL1 */
IOT_PWM_CLK_SRC_50M,
/* support: KL2 */
IOT_PWM_CLK_SRC_75M,
/* support: KL2 */
IOT_PWM_CLK_SRC_100M,
/* support: KL3 */
IOT_PWM_CLK_SRC_150M,
}iot_epwm_clk_src_e;
/* trigger source for channel interrupt
Notice: only IOT_EPWM_INT_TRIG_CNT_EQU_PRD is supported on KL1. */
typedef enum {
/* reserved */
IOT_EPWM_INT_TRIG_RESERVED = 0,
/* counter equals 0 */
IOT_EPWM_INT_TRIG_CNT_EQU_ZERO = 1,
/* counter equals to period value */
IOT_EPWM_INT_TRIG_CNT_EQU_PRD = 2,
/* counter equals to 0 or period value, is useful in up-down count mode.*/
IOT_EPWM_INT_TRIG_CNT_EQU_ZERO_OR_PRD = 3,
/* counter incrementing, and equals compare A */
IOT_EPWM_INT_TRIG_CNT_UP_EQU_CMPA = 4,
/* counter decrementing, and equals compare A */
IOT_EPWM_INT_TRIG_CNT_DOWN_EQU_CMPA = 5,
/* counter incrementing, and equals compare B */
IOT_EPWM_INT_TRIG_CNT_UP_EQU_CMPB = 6,
/* counter decrementing, and equals compare B */
IOT_EPWM_INT_TRIG_CNT_DOWN_EQU_CMPB = 7
}iot_epwm_int_trigger_e;
/* trigger source for channel SOC(start of adc conversion) */
typedef enum {
/* event from epwm Digital-compare submodule */
IOT_EPWM_SOC_TRIG_DC_EVT = 0,
/* counter equals 0 */
IOT_EPWM_SOC_TRIG_CNT_EQU_ZERO = 1,
/* counter equals to period value */
IOT_EPWM_SOC_TRIG_CNT_EQU_PRD = 2,
/* counter equals to 0 or period value, is useful in up-down count mode.*/
IOT_EPWM_SOC_TRIG_CNT_EQU_ZERO_OR_PRD = 3,
/* counter incrementing, and equals compare A */
IOT_EPWM_SOC_TRIG_CNT_UP_EQU_CMPA = 4,
/* counter decrementing, and equals compare A */
IOT_EPWM_SOC_TRIG_CNT_DOWN_EQU_CMPA = 5,
/* counter incrementing, and equals compare B */
IOT_EPWM_SOC_TRIG_CNT_UP_EQU_CMPB = 6,
/* counter decrementing, and equals compare B */
IOT_EPWM_SOC_TRIG_CNT_DOWN_EQU_CMPB = 7
}iot_epwm_soc_trigger_e;
/* trip-zone input, total 3.
only IOT_EPWM_TZ_1 is supported on KL1. */
typedef enum {
IOT_EPWM_TZ_1 = 0,
IOT_EPWM_TZ_2,
IOT_EPWM_TZ_3,
IOT_EPWM_TZ_MAX
}iot_epwm_tz_e;
/* trip-zone action on epwm out pin. */
typedef enum {
/* set to high-impedance. unsupported on KL1.*/
IOT_EPWM_TZ_ACT_HIGH_IMPEDANCE = 0,
/* set to high level. */
IOT_EPWM_TZ_ACT_SET_HIGH = 1,
/* set to low level. */
IOT_EPWM_TZ_ACT_SET_LOW = 2,
/* no action is taken. */
IOT_EPWM_TZ_ACT_DO_NOTHING = 3
}iot_epwm_tz_action_e;
/* channel config updater, while epwm is running. */
typedef enum {
/* update frequency, enabled if 'ch_usage'=IOT_EPWM_CH_USEAGE_COMMON.
the effected time of new value specified by 'ch_period_load_mode'. */
IOT_EPWM_CH_UPDATER_FREQUENCY,
/* update duty, enabled if 'ch_usage'=IOT_EPWM_CH_USEAGE_COMMON.
the effected time of new value specified by 'ch_duty_load_mode'.*/
IOT_EPWM_CH_UPDATER_DUTY,
/* update frequency and duty, enabled if
'ch_usage'= IOT_EPWM_CH_USEAGE_COMMON. the effected time of new value
specified by 'ch_period_load_mode' and 'ch_duty_load_mode'.*/
IOT_EPWM_CH_UPDATER_FREQUENCY_DUTY,
/* update period count, enabled if 'ch_usage'=IOT_EPWM_CH_USEAGE_PRECISE.
the effected time of new value specified by 'ch_period_load_mode'. */
IOT_EPWM_CH_UPDATER_PERIOD_CNT,
/* update compare count, enabled if 'ch_usage'=IOT_EPWM_CH_USEAGE_PRECISE.
the effected time of new value specified by 'ch_duty_load_mode'. */
IOT_EPWM_CH_UPDATER_COMPARE_CNT,
/* update period and compare count, enabled if
'ch_usage'=IOT_EPWM_CH_USEAGE_PRECISE. the effected time of new value
specified by 'ch_period_load_mode' and 'ch_duty_load_mode'. */
IOT_EPWM_CH_UPDATER_PERIOD_COMPARE_CNT,
}iot_epwm_ch_updater_e;
/* channel software event force trigger */
typedef enum {
/* trigger a interrupt */
IOT_EPWM_CH_SW_EVENT_INNER_INT,
/* trigger a SOCA */
IOT_EPWM_CH_SW_EVENT_SOCA,
/* trigger a SOCB */
IOT_EPWM_CH_SW_EVENT_SOCB,
/* trigger a cycle-by-cycle trip-zone evnet */
IOT_EPWM_CH_SW_EVENT_TZ_CBC,
/* trigger an one-shut trip-zone evnet */
IOT_EPWM_CH_SW_EVENT_TZ_OSHT,
/* force outa to low one-time, resumed next period */
IOT_EPWM_CH_SW_EVENT_OUTA_LOW_OSHT,
/* force outa to high one-time, resumed next period */
IOT_EPWM_CH_SW_EVENT_OUTA_HIGH_OSHT,
/* force outa to toggle one-time, resumed next period */
IOT_EPWM_CH_SW_EVENT_OUTA_TOGG_OSHT,
/* force outb to low one-time, resumed next period */
IOT_EPWM_CH_SW_EVENT_OUTB_LOW_OSHT,
/* force outb to high one-time, resumed next period */
IOT_EPWM_CH_SW_EVENT_OUTB_HIGH_OSHT,
/* force outb to toggle one-time, resumed next period */
IOT_EPWM_CH_SW_EVENT_OUTB_TOGG_OSHT,
/* force outa to low continuously, until software resume it */
IOT_EPWM_CH_SW_EVENT_OUTA_LOW_CTNU,
/* force outa to high continuously, until software resume it */
IOT_EPWM_CH_SW_EVENT_OUTA_HIGH_CTNU,
/* resume outa from software control */
IOT_EPWM_CH_SW_EVENT_OUTA_RESUME,
/* force outb to low continuously, until software resume it */
IOT_EPWM_CH_SW_EVENT_OUTB_LOW_CTNU,
/* force outb to high continuously, until software resume it */
IOT_EPWM_CH_SW_EVENT_OUTB_HIGH_CTNU,
/* resume outb from software control */
IOT_EPWM_CH_SW_EVENT_OUTB_RESUME,
}iot_epwm_ch_event_e;
/* polarity of epwm output. */
typedef enum {
IOT_EPWM_POLARITY_NORMAL = 0,
IOT_EPWM_POLARITY_INVERTED,
}iot_epwm_polarity_e;
/* alignment of epwm output. */
typedef enum {
IOT_EPWM_ALIGN_EDGE = 0,
IOT_EPWM_ALIGN_CENTER,
}iot_epwm_align_e;
/* new period value load time. unsupported on KL1.*/
typedef enum {
IOT_EPWM_PERIOD_LOAD_CNT_EQU_ZERO = 0,
IOT_EPWM_PERIOD_LOAD_IMMEDIATELY,
}iot_epwm_period_load_e;
/* new duty value load time. */
typedef enum {
/* load immediately. */
IOT_EPWM_DUTY_LOAD_IMMEDIATELY = 0,
/* load when counter equal 0. */
IOT_EPWM_DUTY_LOAD_CNT_EQU_ZERO,
/* load when counter equal period. unsupported on KL1. */
IOT_EPWM_DUTY_LOAD_CNT_EQU_PRD,
/* load when counter equal zero or period. unsupported on KL1. */
IOT_EPWM_DUTY_LOAD_CNT_EQU_ZERO_OR_PRD,
}iot_epwm_duty_load_e;
/* channel synchronization mode (when to load epwm period, compa and compb). */
typedef enum {
/* depend on soc sync signal. */
IOT_EPWM_CH_SOC_SYNC = 0,
/* depend on inner_sync_load */
IOT_EPWM_CH_INNER_SYNC,
}iot_epwm_ch_sync_e;
/* channel usage, how to config channel frequency and duty. */
typedef enum {
/* common config, set the frequency and duty cycle, the actual effective
value may deviate from the set value. Get the actual value with
iot_epwm_ch_status_get(). */
IOT_EPWM_CH_USEAGE_COMMON = 0,
/* precise config, set the counting period value and comparator value,
suitable for applications with precise requirements. */
IOT_EPWM_CH_USEAGE_PRECISE,
}iot_epwm_ch_usage_e;
/* config for iot epwm module. Notice: [x], x is the default value */
typedef struct {
/* epwm clock source, enum in iot_epwm_clk_src_e. */
iot_epwm_clk_src_e clk_src;
/* (unsupported on KL1)
any gpio as input pin of extern synchronization: [0xFF], 0xFF means
not used.
NOTE: extern sync signal must be input to channel 0. it pass through
all channels.*/
uint8_t ext_sync_pin;
/* any gpio as input pins of trip-zone: [0xFF], 0xFF means not used
Notice: only tz_pins[IOT_EPWM_TZ_1] is used on KL1. */
uint8_t tz_pins[IOT_EPWM_TZ_MAX];
}iot_epwm_global_config_t;
#define IOT_EPWM_GLOBAL_CONFIG_DEFAULT \
{ \
.clk_src = IOT_PWM_CLK_SRC_25M, \
.ext_sync_pin = 0xFF, \
.tz_pins[IOT_EPWM_TZ_1] = 0xFF, \
.tz_pins[IOT_EPWM_TZ_2] = 0xFF, \
.tz_pins[IOT_EPWM_TZ_3] = 0xFF, \
}
/* config of epwm channel. Notice: [x], x is the default value. */
typedef struct {
/* channel clock divider, ch_clk = clk_src/ch_clk_div: [25],1~256. */
uint16_t ch_clk_div;
/* output pin of EPWMA: [0xFF], 0xFF means no output. */
uint8_t ch_pin_outa;
/* output pin of EPWMB: [0xFF], 0xFF means no output. */
uint8_t ch_pin_outb;
/* EPWMA polarity: [IOT_EPWM_POLARITY_NORMAL] or IOT_EPWM_POLARITY_INVERTED */
iot_epwm_polarity_e ch_polarity_outa;
/* EPWMB polarity: IOT_EPWM_POLARITY_NORMAL or [IOT_EPWM_POLARITY_INVERTED] */
iot_epwm_polarity_e ch_polarity_outb;
/* alignment of epwm output: [IOT_EPWM_ALIGN_EDGE] or IOT_EPWM_ALIGN_CENTER.
Notice: epwm period time will be twice in IOT_EPWM_ALIGN_CENTER. */
iot_epwm_align_e ch_align_mode;
/* new period value load time, unsupported on KL1:
[IOT_EPWM_PERIOD_LOAD_CNT_EQU_ZERO] or IOT_EPWM_PERIOD_LOAD_IMMEDIATELY. */
iot_epwm_period_load_e ch_period_load_mode;
/* new duty value load time: [IOT_EPWM_DUTY_LOAD_CNT_EQU_ZERO], enum in
iot_epwm_duty_load_e. */
iot_epwm_duty_load_e ch_duty_load_mode;
/* channel usage, how to config channel frequency and duty:
IOT_EPWM_CH_USEAGE_COMMON or [IOT_EPWM_CH_USEAGE_PRECISE]. */
iot_epwm_ch_usage_e ch_usage;
/* common config, active when ch_usage = IOT_EPWM_CH_USEAGE_COMMON. */
struct{
/* epwm frequency, unit is 1Hz: [0], 0 ~ channel_clock/2 */
uint32_t freq;
/* epwm duty cycle, unit is 0.01%: [0], 0~10000 */
uint32_t duty;
}ch_common_cfg;
/* precise config, active when ch_usage = IOT_EPWM_CH_USEAGE_PRECISE. */
struct {
/* KL1, counter period value: [1000], 1~0x8000(2^15) */
/* KL2/KL3, counter period value: [1000], 1~0x1000000(2^24) */
uint32_t period_cnt;
/* KL1, comparator value: [500], 0~0x7FFF */
/* KL2/KL3, comparator value: [500], 0~0xFFFFFF */
uint32_t compare_cnt;
}ch_precise_cfg;
/* (unsupported on KL1)
phase synchronization enables: [0],disable; 1,enable; */
uint8_t ch_phs_en;
/* (unsupported on KL1)
phase synchronization value: [0], 0~0xFFFFFF(2^24) */
uint32_t ch_phase;
/* (unsupported on KL1)
single-pulse mode enables, outputs only one cycle, and then the counter
stops: [0],disable; 1,enable;*/
uint8_t ch_single_pulse_en;
/* (KL3 only)
channel synchronization mode: IOT_EPWM_CH_SOC_SYNC or
[IOT_EPWM_CH_INNER_SYNC] */
iot_epwm_ch_sync_e ch_sync_mode;
/* (KL3 only)
duty cycle auto-adjust function. at the end of period, the comparator
value is automatically adjusted from cmp_start to cmp_end, and then
cycled back and forth. */
struct {
/* [0],disable; 1,enable; */
uint8_t enable;
/* start value of comparator: [0], 0~0xFFFFFF(2^24) */
uint32_t cmp_start;
/* end value of comparator: [0], 0~0xFFFFFF(2^24) */
uint32_t cmp_end;
/* adjust step of comparator : [0], 0~0xFF */
uint8_t cmp_step;
}ch_auto_duty;
/* dead band function. */
struct {
/* [0],disable; 1,enable; */
uint8_t enable;
/* delay before rising adge, unit is channel clock cycle time:
KL1: [0], 0~0x1FF
KL2/KL3: [0], 0~0x2FF */
uint16_t rising_delay;
/* delay after falling adge, unit is channel clock cycle time:
KL1: [0], 0~0x1FF
KL2/KL3: [0], 0~0x2FF */
uint16_t falling_delay;
}ch_dead_band;
/* (unsupported on KL1)
epwm chopper. a carrier wave of specific frequencies and duty cycles will
be superimposed on the output waveform of the epwm.*/
struct {
/* [0],disable; 1,enable; */
uint8_t enable;
/* clock divider of carrier wave: [1], 1~8.
Notice: clock source of carrier wave is division 8 of channel clock.
so, clk_carrier = (clk_channel/8)/divider. */
uint8_t divider;
/* duty cycle of carrier wave, unit is 12.5%: [1], 1~7. */
uint8_t duty;
/* width of first pulse. unit is 8x channel clock cycle: [1], 1~16. */
uint8_t osht_width;
}ch_chopper;
/* interrupt */
struct {
/* [0],disable; 1,enable; */
uint8_t enable;
/* trigger source for channel interrupt: [IOT_EPWM_INT_TRIG_CNT_EQU_PRD],
enum in iot_epwm_int_trigger_e. */
iot_epwm_int_trigger_e trigger;
/* (unsupported on KL1)
interrupt divider, i.e. how many times it is triggered to produce an
interrupt: [0], 0~255.
Notice: 0 means never produce an interrupt(software force trigger
is ignored too). */
uint8_t divider;
/* ISR for epwm interrupt: [null] */
uint32_t (*callback)(void);
}ch_interrupt;
/* (unsupported on KL1)
SOCA function. SOC, Start of ADC Conversion. */
struct {
/* [0],disable; 1,enable; */
uint8_t enable;
/* trigger source of soca: [IOT_EPWM_INT_TRIG_CNT_EQU_ZERO], eunm in
iot_epwm_soc_trigger_e */
iot_epwm_soc_trigger_e trigger;
/* soca divider, i.e. how many times it is triggered to produce a SOC:
[0], 0~15. Notice: 0 means never produce SOC. */
uint8_t divider;
/* ISR for soca: [null] */
uint32_t (*callback)(void);
}ch_soca;
/* (unsupported on KL1)
SOCB function, the same as SOCA. this means that each epwm cycle can
trigger SOC twice. */
struct {
/* [0],disable; 1,enable; */
uint8_t enable;
/* trigger source of socb: [IOT_EPWM_INT_TRIG_CNT_EQU_ZERO], eunm in
iot_epwm_soc_trigger_e */
iot_epwm_soc_trigger_e trigger;
/* socb divider, i.e. how many times it is triggered to produce a SOC:
[0], 0~15. Notice: 0 means never produce SOC. */
uint8_t divider;
/* ISR for socb: [null] */
uint32_t (*callback)(void);
}ch_socb;
/* the trip_zone function can be triggered in two ways:
OSHT: one-shot, tirgger status remained until cleared by software.
CBC: cycle-by-cycle trigger, tirgger status will be refreshed at every
epwm cycle begining(CNT=0).
Notice: these two way can coexist on KL2/KL3, but not coexist on KL1.*/
struct {
/* [0],disable; 1,enable; */
uint8_t enable;
/* TZ1-TZ3 for KL2/KL3, TZ1 for KL1, whether used as a trigger source
for OSHT(multiple select): [0],no; 1,yes; */
uint8_t tz_en_for_osht[IOT_EPWM_TZ_MAX];
/* TZ1-TZ3 for KL2/KL3, TZ1 for KL1, whether used as a trigger source
for CBC(multiple select): [0],no; 1,yes; */
uint8_t tz_en_for_cbc[IOT_EPWM_TZ_MAX];
/* action of outa: [IOT_EPWM_TZ_ACT_SET_HIGH],
eunm in iot_epwm_tz_action_e. */
iot_epwm_tz_action_e act_outa;
/* action of outb: [IOT_EPWM_TZ_ACT_SET_HIGH],
eunm in iot_epwm_tz_action_e. */
iot_epwm_tz_action_e act_outb;
/* ISR for OSHT interrupt: [null] */
uint32_t (*callback_osht)(void);
/* ISR for CBC interrupt: [null] */
uint32_t (*callback_cbc)(void);
}ch_trip_zone;
}iot_epwm_ch_config_t;
#define IOT_EPWM_CHANNEL_CONFIG_DEFAULT \
{ \
/* default clock source is 25M. so, channel clock = 25M/25 = 1M. */ \
.ch_clk_div = 25, \
.ch_pin_outa = 0xFF, \
.ch_pin_outb = 0xFF, \
/* complementary output, outa is normal, outb is inverted. */ \
.ch_polarity_outa = IOT_EPWM_POLARITY_NORMAL, \
.ch_polarity_outb = IOT_EPWM_POLARITY_INVERTED, \
.ch_align_mode = IOT_EPWM_ALIGN_EDGE, \
.ch_period_load_mode = IOT_EPWM_PERIOD_LOAD_CNT_EQU_ZERO, \
.ch_duty_load_mode = IOT_EPWM_DUTY_LOAD_CNT_EQU_ZERO, \
/* freq 1K Hz, duty 50%. */ \
.ch_usage = IOT_EPWM_CH_USEAGE_PRECISE, \
.ch_common_cfg.freq = 1000, \
.ch_common_cfg.duty = 5000, \
.ch_precise_cfg.period_cnt = 1000, \
.ch_precise_cfg.compare_cnt = 500, \
/* phase synchronization is disable. */ \
.ch_phs_en = 0, \
.ch_phase = 0, \
/* single pulse is disable. */ \
.ch_single_pulse_en = 0, \
.ch_sync_mode = IOT_EPWM_CH_INNER_SYNC, \
/* auto duty is disable. */ \
.ch_auto_duty.enable = 0, \
.ch_auto_duty.cmp_start = 0, \
.ch_auto_duty.cmp_end = 0, \
.ch_auto_duty.cmp_step = 0, \
/* dead band is disable. */ \
.ch_dead_band.enable = 0, \
.ch_dead_band.rising_delay = 0, \
.ch_dead_band.falling_delay = 0, \
/* chopper is disable. */ \
.ch_chopper.enable = 0, \
.ch_chopper.divider = 1, \
.ch_chopper.duty = 1, \
.ch_chopper.osht_width = 1, \
/* interrupt is disable. */ \
.ch_interrupt.enable = 0, \
.ch_interrupt.trigger = IOT_EPWM_INT_TRIG_CNT_EQU_PRD, \
.ch_interrupt.divider = 0, \
.ch_interrupt.callback = NULL, \
/* soca is disable. */ \
.ch_soca.enable = 0, \
.ch_soca.trigger = IOT_EPWM_INT_TRIG_CNT_EQU_ZERO, \
.ch_soca.divider = 0, \
.ch_soca.callback = NULL, \
/* socb is disable. */ \
.ch_socb.enable = 0, \
.ch_socb.trigger = IOT_EPWM_INT_TRIG_CNT_EQU_ZERO, \
.ch_socb.divider = 0, \
.ch_socb.callback = NULL, \
/* trip zone is disable. */ \
.ch_trip_zone.enable = 0, \
.ch_trip_zone.tz_en_for_osht[IOT_EPWM_TZ_1] = 0, \
.ch_trip_zone.tz_en_for_osht[IOT_EPWM_TZ_2] = 0, \
.ch_trip_zone.tz_en_for_osht[IOT_EPWM_TZ_3] = 0, \
.ch_trip_zone.tz_en_for_cbc[IOT_EPWM_TZ_1] = 0, \
.ch_trip_zone.tz_en_for_cbc[IOT_EPWM_TZ_2] = 0, \
.ch_trip_zone.tz_en_for_cbc[IOT_EPWM_TZ_3] = 0, \
.ch_trip_zone.act_outa = IOT_EPWM_TZ_ACT_SET_HIGH, \
.ch_trip_zone.act_outb = IOT_EPWM_TZ_ACT_SET_HIGH, \
.ch_trip_zone.callback_osht = NULL, \
.ch_trip_zone.callback_cbc = NULL, \
}
/* actual status of channel */
typedef struct {
/* actual channel clock */
uint32_t actual_ch_clk;
/* actual frequency, unit is Hz */
uint32_t actual_freq;
/* actual duty cycle, unit is 0.01% */
uint32_t actual_duty;
/* actual period value */
uint32_t actual_period;
/* actual compare value */
uint32_t actual_compare;
/* actual counter value */
uint32_t actual_counter;
}iot_epwm_ch_status_t;
/** @brief iot_pwm_api_mode_select() - select pwm api mode. can only be called
* once.
* @param api_mode IOT_API_MODE_PWM(default) or IOT_API_MODE_EPWM.
* @return 0 - successful; others - fail.
*/
int iot_pwm_api_mode_select(iot_pwm_api_mode_e api_mode);
/** @brief iot_pwm_api_mode_query() - query pwm api mode.
* @param none.
* @return iot_pwm_api_mode_e current pwm api mode.
*/
iot_pwm_api_mode_e iot_pwm_api_mode_query(void);
/** @brief iot_epwm_get_channel_count() - get available channel count.
* @param none.
* @return available channel count.
*/
uint8_t iot_epwm_get_channel_count(void);
/** @brief iot_epwm_global_config_set() - apply the epwm module config.
* Notice: should be called when all channels are stoped.
* @param cfg config of epwm module.
* @return 0 - successful; others - fail.
*/
int iot_epwm_global_config_set(iot_epwm_global_config_t *cfg);
/** @brief iot_epwm_global_config_get() - get the epwm module config.
* @param none.
* @return iot_epwm_global_config_t * epwm module config
*/
iot_epwm_global_config_t * iot_epwm_global_config_get(void);
/** @brief iot_epwm_global_start() - start all epwm channels. open the main clock
* gate of all channel.
* @param none.
* @return none.
*/
void iot_epwm_global_start(void);
/** @brief iot_epwm_global_stop() - stop all epwm channels. close the main clock
* gate of all channel.
* @param none.
* @return none.
*/
void iot_epwm_global_stop(void);
/** @brief iot_epwm_global_sync() - generate a soc sync signal, which make
* channel new period and compare value effective. works on all
* channels which configured 'ch_sync_mode'=IOT_EPWM_CH_SOC_SYNC.
* Notice: this api is unsupported on KL1.
* @param none.
* @return none.
*/
void iot_epwm_global_sync(void);
/** @brief iot_epwm_ch_start() - start epwm channel.
* @param ch channel num, see IOT_EPWM_CHANNEL_X .
* @return none.
*/
void iot_epwm_ch_start(uint8_t ch);
/** @brief iot_epwm_ch_stop() - stop epwm channel, counter is stoped.
* @param ch channel num, see IOT_EPWM_CHANNEL_X .
* @return none.
*/
void iot_epwm_ch_stop(uint8_t ch);
/** @brief iot_epwm_ch_close() - close epwm channel. all config of channel is
* set to default and release resource such as pin, interrupt.
* @param ch channel num, see IOT_EPWM_CHANNEL_X .
* @return none.
*/
void iot_epwm_ch_close(uint8_t ch);
/** @brief iot_epwm_ch_config_set() - apply channel config.
* Notice: should be called when channel is stoped.
* @param ch channel num, see IOT_EPWM_CHANNEL_X .
* @param cfg config of channel.
* @return 0 - successful; others - fail.
*/
int iot_epwm_ch_config_set(uint8_t ch, iot_epwm_ch_config_t *cfg);
/** @brief iot_epwm_ch_config_get() - get channel config.
* @param ch channel num, see IOT_EPWM_CHANNEL_X .
* @return iot_epwm_ch_config_t * channel config.
*/
iot_epwm_ch_config_t * iot_epwm_ch_config_get(uint8_t ch);
/** @brief iot_epwm_ch_update() - update the specified parameter, when channel
* is working.
* @param ch: channel num, see IOT_EPWM_CHANNEL_X .
* @param field parameter to be updated, enum in iot_epwm_ch_updater_e.
* @param val1 parameter1 value.
* @param val2 parameter2 value, set to 0 if not used. only used while
* 'field' = IOT_EPWM_CH_UPDATER_FREQUENCY_DUTY or
* IOT_EPWM_CH_UPDATER_PERIOD_COMPARE_CNT.
* @return 0 - successful; others - fail.
*/
int iot_epwm_ch_update(uint8_t ch, iot_epwm_ch_updater_e field, uint32_t val1,
uint32_t val2);
/** @brief iot_epwm_ch_sw_force() - software forced generate an event.
* Notice: this api is unsupported on KL1.
* @param ch channel num, see IOT_EPWM_CHANNEL_X .
* @param event event type, enum in iot_epwm_ch_event_e.
* @return none.
*/
void iot_epwm_ch_sw_force(uint8_t ch, iot_epwm_ch_event_e event);
/** @brief iot_epwm_ch_clear() - clear an event flag.
* Notice: this api is unsupported on KL1.
* @param ch channel num, see IOT_EPWM_CHANNEL_X .
* @param event event type, enum in iot_epwm_ch_event_e.
* @return none.
*/
void iot_epwm_ch_clear(uint8_t ch, iot_epwm_ch_event_e event);
/** @brief iot_epwm_ch_status_get() - get the actual status of channel.
* @param ch channel num, see IOT_EPWM_CHANNEL_X .
* @param status status returned.
* @return none.
*/
void iot_epwm_ch_status_get(uint8_t ch, iot_epwm_ch_status_t *status);
#endif