1 /*
2 * Copyright (c) 2023 HPMicro
3 *
4 * SPDX-License-Identifier: BSD-3-Clause
5 *
6 */
7
8 #include "hpm_soc_feature.h"
9 #include "hpm_pwmv2_drv.h"
10
pwmv2_deinit(PWMV2_Type * pwm_x)11 void pwmv2_deinit(PWMV2_Type *pwm_x)
12 {
13 pwm_x->IRQ_EN_CMP = 0;
14 pwm_x->IRQ_EN_RELOAD = 0;
15 pwm_x->IRQ_EN_CAP_POS = 0;
16 pwm_x->IRQ_EN_CAP_NEG = 0;
17 pwm_x->IRQ_EN_FAULT = 0;
18 pwm_x->IRQ_EN_BURSTEND = 0;
19 pwm_x->IRQ_EN = 0;
20 pwm_x->DMA_EN = 0;
21 pwm_x->IRQ_STS |= pwm_x->IRQ_STS;
22 pwm_x->IRQ_STS_CMP = 0;
23 pwm_x->IRQ_STS_RELOAD = 0;
24 pwm_x->IRQ_STS_CAP_POS = 0;
25 pwm_x->IRQ_STS_CAP_NEG = 0;
26 pwm_x->IRQ_STS_FAULT = 0;
27 pwm_x->IRQ_STS_BURSTEND = 0;
28 for (uint8_t i = 0; i < PWM_SOC_CMP_MAX_COUNT; i++) {
29 pwm_x->CMP[i].CFG = 0;
30 }
31 for (uint8_t i = 0; i < PWM_SOC_OUTPUT_TO_PWM_MAX_COUNT; i++) {
32 pwm_x->PWM[i].CFG0 = 0;
33 pwm_x->PWM[i].CFG1 = 0;
34 pwm_x->PWM[i].DEAD_AREA = 0;
35 }
36 for (uint8_t i = 0; i < PWMV2_SOC_CAL_COUNT_MAX; i++) {
37 pwm_x->CAL[i].CFG0 = 0;
38 pwm_x->CAL[i].CFG1 = 0;
39 }
40 }
41
pwmv2_config_cmp(PWMV2_Type * pwm_x,uint8_t index,pwmv2_cmp_config_t * config)42 void pwmv2_config_cmp(PWMV2_Type *pwm_x, uint8_t index, pwmv2_cmp_config_t *config)
43 {
44 pwmv2_select_cmp_source(pwm_x, index, config->cmp_source, config->cmp_source_index);
45 pwmv2_cmp_update_trig_time(pwm_x, index, config->update_trigger);
46 if (config->update_trigger == pwm_shadow_register_update_on_trigmux) {
47 pwmv2_select_cmp_trigmux(pwm_x, index, config->update_trigger_index);
48 }
49 if (index >= PWM_CMP_UNABLE_OUTPUT_INDEX) {
50 pwmv2_cmp_select_counter(pwm_x, index, config->cmp_source_index);
51 }
52 if (config->cmp_source == cmp_value_from_shadow_val) {
53 pwmv2_shadow_register_unlock(pwm_x);
54 if (config->enable_hrcmp) {
55 pwmv2_set_shadow_val(pwm_x, config->cmp_source_index, config->cmp, config->hrcmp, config->enable_half_cmp);
56 } else {
57 pwmv2_set_shadow_val(pwm_x, config->cmp_source_index, config->cmp, 0, config->enable_half_cmp);
58 }
59 pwmv2_shadow_register_lock(pwm_x);
60 }
61 }
62
pwmv2_config_async_fault_source(PWMV2_Type * pwm_x,pwm_channel_t index,pwmv2_async_fault_source_config_t * config)63 void pwmv2_config_async_fault_source(PWMV2_Type *pwm_x, pwm_channel_t index, pwmv2_async_fault_source_config_t *config)
64 {
65 pwm_x->PWM[index].CFG0 = (pwm_x->PWM[index].CFG0 & ~(PWMV2_PWM_CFG0_FAULT_SEL_ASYNC_MASK | PWMV2_PWM_CFG0_FAULT_POL_ASYNC_MASK))
66 | PWMV2_PWM_CFG0_FAULT_SEL_ASYNC_SET(config->async_signal_from_pad_index)
67 | PWMV2_PWM_CFG0_FAULT_POL_ASYNC_SET(config->fault_async_pad_level);
68 }
69
pwmv2_config_pwm(PWMV2_Type * pwm_x,pwm_channel_t index,pwmv2_config_t * config,bool enable_pair_mode)70 void pwmv2_config_pwm(PWMV2_Type *pwm_x, pwm_channel_t index,
71 pwmv2_config_t *config, bool enable_pair_mode)
72 {
73 pwm_x->PWM[index].CFG0 = PWMV2_PWM_CFG0_TRIG_SEL4_SET(config->enable_four_cmp) |
74 PWMV2_PWM_CFG0_OUT_POLARITY_SET(config->invert_output) |
75 PWMV2_PWM_CFG0_POL_UPDATE_SEL_SET(config->update_polarity_time);
76 pwm_x->PWM[index].CFG1 = PWMV2_PWM_CFG1_HIGHZ_EN_N_SET(config->enable_output) |
77 PWMV2_PWM_CFG1_FORCE_UPDATE_TIME_SET(config->force_shadow_trigger) |
78 PWMV2_PWM_CFG1_FAULT_MODE_SET(config->fault_mode) |
79 PWMV2_PWM_CFG1_FAULT_REC_TIME_SET(config->fault_recovery_trigger) |
80 PWMV2_PWM_CFG1_PAIR_MODE_SET(enable_pair_mode) |
81 PWMV2_PWM_CFG1_PWM_LOGIC_SET(config->logic) |
82 PWMV2_PWM_CFG1_FORCE_TIME_SET(config->force_trigger) |
83 PWMV2_PWM_CFG1_FORCE_TRIG_SEL_SET(config->force_shadow_trigmux_index) |
84 PWMV2_PWM_CFG1_FORCE_ACT_SEL_SET(config->force_trigmux_index) |
85 PWMV2_PWM_CFG1_PWM_FORCE_SEL_SET(config->fault_recovery_trigmux_index);
86 pwmv2_config_async_fault_source(pwm_x, index, &config->async_fault_source);
87 if (enable_pair_mode) {
88 pwmv2_set_dead_area(pwm_x, index, config->dead_zone_in_half_cycle);
89 }
90 }
91
pwmv2_setup_waveform(PWMV2_Type * pwm_x,pwm_channel_t chn,pwmv2_config_t * pwm_config,uint8_t cmp_start_index,pwmv2_cmp_config_t * cmp,uint8_t cmp_num)92 hpm_stat_t pwmv2_setup_waveform(PWMV2_Type *pwm_x,
93 pwm_channel_t chn, pwmv2_config_t *pwm_config,
94 uint8_t cmp_start_index, pwmv2_cmp_config_t *cmp, uint8_t cmp_num)
95 {
96 uint8_t i;
97
98 for (i = 0; i < cmp_num; i++) {
99 pwmv2_config_cmp(pwm_x, cmp_start_index + i, &cmp[i]);
100 }
101 pwmv2_config_pwm(pwm_x, chn, pwm_config, false);
102
103 return status_success;
104 }
105
pwmv2_setup_waveform_in_pair(PWMV2_Type * pwm_x,pwm_channel_t chn,pwmv2_pair_config_t * pwm_pair_config,uint8_t cmp_start_index,pwmv2_cmp_config_t * cmp,uint8_t cmp_num)106 hpm_stat_t pwmv2_setup_waveform_in_pair(PWMV2_Type *pwm_x, pwm_channel_t chn,
107 pwmv2_pair_config_t *pwm_pair_config, uint8_t cmp_start_index,
108 pwmv2_cmp_config_t *cmp, uint8_t cmp_num)
109 {
110 uint8_t i;
111
112 for (i = 0; i < cmp_num; i++) {
113 pwmv2_config_cmp(pwm_x, cmp_start_index + i, &cmp[i]);
114 }
115 pwmv2_config_pwm(pwm_x, chn, &pwm_pair_config->pwm[0], true);
116 pwmv2_config_pwm(pwm_x, chn + 1, &pwm_pair_config->pwm[1], true);
117
118 return status_success;
119 }
120
pwmv2_setup_cmp_calculate(PWMV2_Type * pwm_x,uint8_t cal_index,pwmv2_cmp_calculate_cfg_t * cal)121 void pwmv2_setup_cmp_calculate(PWMV2_Type *pwm_x, uint8_t cal_index, pwmv2_cmp_calculate_cfg_t *cal)
122 {
123 pwm_x->CAL[cal_index].CFG0 = PWMV2_CAL_CFG0_CAL_LU_PARAM_SET(cal->up_limit_param) |
124 PWMV2_CAL_CFG0_CAL_LL_PARAM_SET(cal->low_limit_param) |
125 PWMV2_CAL_CFG0_CAL_T_PARAM_SET(cal->t_param) |
126 PWMV2_CAL_CFG0_CAL_D_PARAM_SET(cal->d_param);
127 pwm_x->CAL[cal_index].CFG1 = PWMV2_CAL_CFG1_CAL_T_INDEX_SET(cal->counter_index) |
128 PWMV2_CAL_CFG1_CAL_IN_INDEX_SET(cal->in_index) |
129 PWMV2_CAL_CFG1_CAL_LU_EN_SET(cal->enable_up_limit) |
130 PWMV2_CAL_CFG1_CAL_LIM_UP_SET(cal->up_limit_offset_index) |
131 PWMV2_CAL_CFG1_CAL_LL_EN_SET(cal->enbale_low_limit) |
132 PWMV2_CAL_CFG1_CAL_LIM_LO_SET (cal->low_limit_offset_index) |
133 PWMV2_CAL_CFG1_CAL_IN_OFF_SET(cal->in_offset_index);
134 }
135