• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2021 HPMicro
3  *
4  * SPDX-License-Identifier: BSD-3-Clause
5  *
6  */
7 
8 #include "hpm_soc_feature.h"
9 #include "hpm_pwm_drv.h"
10 
pwm_load_cmp_shadow_on_match(PWM_Type * pwm_x,uint8_t index,pwm_cmp_config_t * config)11 hpm_stat_t pwm_load_cmp_shadow_on_match(PWM_Type *pwm_x,
12                                          uint8_t index,
13                                          pwm_cmp_config_t *config)
14 {
15     if (config->mode != pwm_cmp_mode_output_compare) {
16         return status_invalid_argument;
17     }
18     pwm_config_cmp(pwm_x, index, config);
19     pwm_issue_shadow_register_lock_event(pwm_x);
20     pwm_x->GCR = ((pwm_x->GCR & ~(PWM_GCR_CMPSHDWSEL_MASK)) | PWM_GCR_CMPSHDWSEL_SET(index));
21     return status_success;
22 }
23 
pwm_get_captured_count(PWM_Type * pwm_x,uint32_t * buf,pwm_counter_type_t counter,uint8_t start_index,uint8_t num)24 void pwm_get_captured_count(PWM_Type *pwm_x, uint32_t *buf, pwm_counter_type_t counter, uint8_t start_index, uint8_t num)
25 {
26     uint32_t i;
27     if (counter == pwm_counter_type_capture_falling_edge) {
28         for (i = start_index; i < start_index + num; i++) {
29             *buf = pwm_x->CAPNEG[i];
30         }
31     } else {
32         for (i = start_index; i < start_index + num; i++) {
33             *buf = pwm_x->CAPPOS[i];
34         }
35     }
36 }
37 
pwm_get_default_cmp_config(PWM_Type * pwm_x,pwm_cmp_config_t * config)38 void pwm_get_default_cmp_config(PWM_Type *pwm_x, pwm_cmp_config_t *config)
39 {
40     (void) pwm_x;
41     config->mode = pwm_cmp_mode_output_compare;
42     config->update_trigger = pwm_shadow_register_update_on_modify;
43     config->enable_ex_cmp = false;
44 #if defined(PWM_SOC_HRPWM_SUPPORT) && PWM_SOC_HRPWM_SUPPORT
45     config->enable_hrcmp = false;
46     config->hrcmp = 0;
47 #endif
48     config->cmp = 0;
49     config->ex_cmp = 0;
50     config->half_clock_cmp = 0;
51     config->jitter_cmp = 0;
52 }
53 
pwm_get_default_output_channel_config(PWM_Type * pwm_x,pwm_output_channel_t * config)54 void pwm_get_default_output_channel_config(PWM_Type *pwm_x, pwm_output_channel_t *config)
55 {
56     (void) pwm_x;
57     config->cmp_start_index = 0;
58     config->cmp_end_index = 0;
59     config->invert_output = false;
60 }
61 
pwm_get_default_pwm_config(PWM_Type * pwm_x,pwm_config_t * config)62 void pwm_get_default_pwm_config(PWM_Type *pwm_x, pwm_config_t *config)
63 {
64     (void) pwm_x;
65     config->enable_output = false;
66     config->update_trigger = pwm_shadow_register_update_on_modify;
67     config->fault_mode = pwm_fault_mode_force_output_highz;
68     config->fault_recovery_trigger = pwm_fault_recovery_on_fault_clear;
69     config->force_source = pwm_force_source_software;
70     config->dead_zone_in_half_cycle = 0;
71 }
72 
pwm_get_default_pwm_pair_config(PWM_Type * pwm_x,pwm_pair_config_t * config)73 void pwm_get_default_pwm_pair_config(PWM_Type *pwm_x, pwm_pair_config_t *config)
74 {
75     pwm_get_default_pwm_config(pwm_x, &config->pwm[0]);
76     pwm_get_default_pwm_config(pwm_x, &config->pwm[1]);
77 }
78 
pwm_setup_waveform_in_pair(PWM_Type * pwm_x,uint8_t pwm_index,pwm_pair_config_t * pwm_pair_config,uint8_t cmp_start_index,pwm_cmp_config_t * cmp,uint8_t cmp_num)79 hpm_stat_t pwm_setup_waveform_in_pair(PWM_Type *pwm_x, uint8_t pwm_index,
80                         pwm_pair_config_t *pwm_pair_config, uint8_t cmp_start_index,
81                         pwm_cmp_config_t *cmp, uint8_t cmp_num)
82 {
83     uint8_t i;
84     pwm_output_channel_t ch_config;
85 
86     if ((pwm_index > PWM_SOC_PWM_MAX_COUNT)
87         || !cmp_num
88         || (cmp_start_index > PWM_SOC_CMP_MAX_COUNT)
89         || (cmp_start_index + cmp_num > PWM_SOC_CMP_MAX_COUNT)
90         || ((pwm_index > (PWM_SOC_PWM_MAX_COUNT - 1))
91                     || (pwm_index & 0x1))) {
92         return status_invalid_argument;
93     }
94 
95     pwm_x->PWMCFG[pwm_index] &= ~PWM_PWMCFG_OEN_MASK;
96     pwm_x->PWMCFG[pwm_index + 1] &= ~PWM_PWMCFG_OEN_MASK;
97 
98     for (i =  0; i < cmp_num; i++) {
99         pwm_config_cmp(pwm_x, cmp_start_index + i, &cmp[i]);
100     }
101     ch_config.cmp_start_index = cmp_start_index;
102     ch_config.cmp_end_index = cmp_start_index + cmp_num - 1;
103     ch_config.invert_output = pwm_pair_config->pwm[0].invert_output;
104     pwm_config_output_channel(pwm_x, pwm_index, &ch_config);
105 
106     ch_config.invert_output = pwm_pair_config->pwm[1].invert_output;
107     pwm_config_output_channel(pwm_x, pwm_index + 1, &ch_config);
108 
109     pwm_config_pwm(pwm_x, pwm_index, &pwm_pair_config->pwm[0], true);
110     pwm_config_pwm(pwm_x, pwm_index + 1, &pwm_pair_config->pwm[1], true);
111 
112     return status_success;
113 }
114 
pwm_setup_waveform(PWM_Type * pwm_x,uint8_t pwm_index,pwm_config_t * pwm_config,uint8_t cmp_start_index,pwm_cmp_config_t * cmp,uint8_t cmp_num)115 hpm_stat_t pwm_setup_waveform(PWM_Type *pwm_x,
116                         uint8_t pwm_index, pwm_config_t *pwm_config,
117                         uint8_t cmp_start_index, pwm_cmp_config_t *cmp, uint8_t cmp_num)
118 {
119     uint8_t i;
120     pwm_output_channel_t ch_config;
121     if (!cmp_num
122         || (cmp_start_index > PWM_SOC_CMP_MAX_COUNT)
123         || (cmp_start_index + cmp_num > PWM_SOC_CMP_MAX_COUNT)) {
124         return status_invalid_argument;
125     }
126 
127     for (i =  0; i < cmp_num; i++) {
128         pwm_config_cmp(pwm_x, cmp_start_index + i, &cmp[i]);
129     }
130     ch_config.cmp_start_index = cmp_start_index;
131     ch_config.cmp_end_index = cmp_start_index + cmp_num - 1;
132     ch_config.invert_output = pwm_config->invert_output;
133     pwm_config_output_channel(pwm_x, pwm_index, &ch_config);
134     if (pwm_index < PWM_SOC_PWM_MAX_COUNT) {
135         pwm_config_pwm(pwm_x, pwm_index, pwm_config, false);
136     }
137     return status_success;
138 }
139 
pwm_update_raw_cmp_edge_aligned(PWM_Type * pwm_x,uint8_t cmp_index,uint32_t target_cmp)140 hpm_stat_t pwm_update_raw_cmp_edge_aligned(PWM_Type *pwm_x, uint8_t cmp_index, uint32_t target_cmp)
141 {
142     pwm_shadow_register_unlock(pwm_x);
143     pwm_cmp_update_cmp_value(pwm_x, cmp_index, target_cmp, 0);
144     return status_success;
145 }
146 
pwm_update_raw_cmp_central_aligned(PWM_Type * pwm_x,uint8_t cmp1_index,uint8_t cmp2_index,uint32_t target_cmp1,uint32_t target_cmp2)147 hpm_stat_t pwm_update_raw_cmp_central_aligned(PWM_Type *pwm_x, uint8_t cmp1_index,
148                                        uint8_t cmp2_index, uint32_t target_cmp1, uint32_t target_cmp2)
149 {
150     uint32_t reload = PWM_RLD_RLD_GET(pwm_x->RLD);
151     if (!target_cmp1) {
152         target_cmp1 = reload + 1;
153     }
154     if (!target_cmp2) {
155         target_cmp2 = reload + 1;
156     }
157     pwm_shadow_register_unlock(pwm_x);
158     pwm_cmp_update_cmp_value(pwm_x, cmp1_index, target_cmp1, 0);
159     pwm_cmp_update_cmp_value(pwm_x, cmp2_index, target_cmp2, 0);
160     return status_success;
161 }
162 #if defined(PWM_SOC_HRPWM_SUPPORT) && PWM_SOC_HRPWM_SUPPORT
163 
pwm_update_raw_hrcmp_edge_aligned(PWM_Type * pwm_x,uint8_t cmp_index,uint32_t target_cmp,uint16_t target_hrcmp)164 hpm_stat_t pwm_update_raw_hrcmp_edge_aligned(PWM_Type *pwm_x, uint8_t cmp_index, uint32_t target_cmp,
165             uint16_t target_hrcmp)
166 {
167     pwm_shadow_register_unlock(pwm_x);
168     pwm_cmp_update_hrcmp_value(pwm_x, cmp_index, target_cmp, target_hrcmp);
169     return status_success;
170 }
171 
pwm_update_raw_hrcmp_central_aligned(PWM_Type * pwm_x,uint8_t cmp1_index,uint8_t cmp2_index,uint32_t target_cmp1,uint32_t target_cmp2,uint16_t target_hrcmp1,uint16_t target_hrcmp2)172 hpm_stat_t pwm_update_raw_hrcmp_central_aligned(PWM_Type *pwm_x, uint8_t cmp1_index,
173                                        uint8_t cmp2_index, uint32_t target_cmp1, uint32_t target_cmp2,
174                                         uint16_t target_hrcmp1, uint16_t target_hrcmp2)
175 {
176     uint32_t reload = PWM_RLD_RLD_GET(pwm_x->RLD);
177     if (!target_cmp1) {
178         target_cmp1 = reload + 1;
179     }
180     if (!target_cmp2) {
181         target_cmp2 = reload + 1;
182     }
183     pwm_shadow_register_unlock(pwm_x);
184     pwm_cmp_update_hrcmp_value(pwm_x, cmp1_index, target_cmp1, target_hrcmp1);
185     pwm_cmp_update_hrcmp_value(pwm_x, cmp2_index, target_cmp2, target_hrcmp2);
186     return status_success;
187 }
188 #endif
189