• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright 2015-2019 Espressif Systems (Shanghai) PTE LTD
2 //
3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // you may not use this file except in compliance with the License.
5 // You may obtain a copy of the License at
6 //
7 //     http://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
14 
15 /*******************************************************************************
16  * NOTICE
17  * The hal is not public api, don't use in application code.
18  * See readme.md in hal/include/hal/readme.md
19  ******************************************************************************/
20 
21 // The HAL layer for MCPWM (common part)
22 
23 /*
24  * MCPWM HAL usages:
25  *
26  * Initialization:
27  *  1. Fill the parameters in `mcpwm_hal_context_t`.
28  *  2. Call `mcpwm_hal_init` to initialize the context.
29  *  3. Call `mcpwm_hal_hw_init` to initialize the hardware.
30  *
31  * Basic PWM:
32  *  1. Update parameters for the timers, comparators and generators.
33  *  2. Call `mcpwm_hal_timer_update_basic` to update the timer used.
34  *  3. Call `mcpwm_hal_operator_update_basic` to update all the parameters of a operator.
35  *
36  *     Alternatively, if only the comparator is updated (duty rate), call
37  *     `mcpwm_hal_operator_update_comparator` to update the comparator parameters; if only the
38  *     generator is updated (output style), call `mcpwm_hal_operator_update_generator` to update the
39  *     generator parameters.
40  *
41  *  4. At any time, call `mcpwm_hal_timer_start` to start the timer (so that PWM output will toggle
42  *    according to settings), or call `mcpwm_hal_timer_stop` to stop the timer (so that the PWM output
43  *    will be kept as called).
44  *
45  * Timer settings:
46  *  - Sync: Call `mcpwm_hal_timer_enable_sync` to enable the sync for the timer, and call
47  *  `mcpwm_hal_timer_disable_sync` to disable it.
48  *
49  * Operator settings:
50  *  - Carrier: Call `mcpwm_hal_operator_enable_carrier` to enable carrier for an operator, and call
51  *  `mcpwm_hal_operator_disable_carrier` to disable it.
52  *
53  *  - Deadzone: Call `mcpwm_hal_operator_update_deadzone` to update settings of deadzone for an operator.
54  *
55  * Fault handling settings:
56  *  1. Call `mcpwm_hal_fault_init` to initialize an fault signal to be detected.
57  *  2. Call `mcpwm_hal_operator_update_fault` to update the behavior of an operator when fault is
58  *     detected.
59  *  3. If the operator selects oneshot mode to handle the fault event, call
60  *     `mcpwm_hal_fault_oneshot_clear` to clear that fault event after the fault is handled properly.
61  *  4. Call `mcpwm_hal_fault_disable` to deinitialize the fault signal when it's no longer used.
62  *
63  * Capture:
64  *  1. Call `mcpwm_hal_capture_enable` to enable the capture for one capture signal.
65  *  2. Call `mcpwm_hal_capture_get_result` to get the last captured result.
66  *  3. Call `mcpwm_hal_capture_disable` to disable the capture for a signal.
67  */
68 
69 
70 #pragma once
71 
72 #include <esp_err.h>
73 #include "hal/mcpwm_ll.h"
74 
75 #define MCPWM_BASE_CLK (2 * APB_CLK_FREQ)   //2*APB_CLK_FREQ 160Mhz
76 
77 /// Configuration of HAL that used only once.
78 typedef struct {
79     int host_id;    ///< Which MCPWM peripheral to use, 0-1.
80 } mcpwm_hal_init_config_t;
81 
82 /// Configuration of each generator (output of operator)
83 typedef struct {
84     mcpwm_duty_type_t   duty_type;  ///< How the generator output
85     int comparator; ///< for mode `MCPWM_DUTY_MODE_*`, which comparator it refers to.
86 } mcpwm_hal_generator_config_t;
87 
88 /// Configuration of each operator
89 typedef struct {
90     mcpwm_hal_generator_config_t gen[SOC_MCPWM_GENERATOR_NUM];  ///< Configuration of the generators
91     float duty[SOC_MCPWM_COMPARATOR_NUM];   ///< Duty rate for each comparator, 10 means 10%.
92     int timer;      ///< The timer this operator is using
93 } mcpwm_hal_operator_config_t;
94 
95 /// Configuration of each timer
96 typedef struct {
97     uint32_t timer_prescale;    ///< The prescale from the MCPWM main clock to the timer clock, TIMER_FREQ=(MCPWM_FREQ/(timer_prescale+1))
98     uint32_t freq;              ///< Frequency desired, will be updated to actual value after the `mcpwm_hal_timer_update_freq` is called.
99     mcpwm_counter_type_t count_mode;    ///< Counting mode
100 } mcpwm_hal_timer_config_t;
101 
102 typedef struct {
103     mcpwm_dev_t *dev;           ///< Beginning address of the MCPWM peripheral registers. Call `mcpwm_hal_init` to initialize it.
104     uint32_t    prescale;       ///< Prescale from the 160M clock to MCPWM main clock.
105     mcpwm_hal_timer_config_t    timer[SOC_MCPWM_TIMER_NUM]; ///< Configuration of the timers
106     mcpwm_hal_operator_config_t op[SOC_MCPWM_OP_NUM];       ///< Configuration of the operators
107 } mcpwm_hal_context_t;
108 
109 /// Configuration of the carrier
110 typedef struct {
111     bool inverted;  ///< Whether to invert the output
112     uint8_t  duty;  ///< Duty of the carrier, 0-7. Duty rate = duty/8.
113     uint8_t oneshot_pulse_width;    ///< oneshot pulse width, in carrier periods. 0 to disable. 0-15.
114     uint32_t period; ///< Prescale from the MCPWM main clock to the carrier clock. CARRIER_FREQ=(MCPWM_FREQ/(period+1)/8.)
115 } mcpwm_hal_carrier_conf_t;
116 
117 /// Configuration of the deadzone
118 typedef struct {
119     mcpwm_deadtime_type_t mode; ///< Deadzone mode, `MCPWM_DEADTIME_BYPASS` to disable.
120     uint32_t fed;   ///< Delay on falling edge. By MCPWM main clock.
121     uint32_t red;   ///< Delay on rising edge. By MCPWM main clock.
122 } mcpwm_hal_deadzone_conf_t;
123 
124 /// Configuration of the fault handling for each operator
125 typedef struct {
126     uint32_t cbc_enabled_mask;  ///< Whether the cycle-by-cycle fault handling is enabled on each fault signal. BIT(n) stands for signal n.
127     uint32_t ost_enabled_mask;  ///< Whether the oneshot fault handling is enabled on each on each fault signal. BIT(n) stands for signal n.
128     mcpwm_output_action_t   action_on_fault[SOC_MCPWM_GENERATOR_NUM];   ///< Action to perform on each generator when any one of the fault signal triggers.
129 } mcpwm_hal_fault_conf_t;
130 
131 /// Configuration of the synchronization of each clock
132 typedef struct {
133     mcpwm_sync_signal_t sync_sig;   ///< Sync signal to use
134     uint32_t reload_permillage;     ///< Reload permillage when the sync is triggered. 100 means the timer will be reload to (period * 100)/1000=10% period value.
135 } mcpwm_hal_sync_config_t;
136 
137 /// Configuration of the capture feature on each capture signal
138 typedef struct {
139     mcpwm_capture_on_edge_t cap_edge;   ///< Whether the edges is captured, bitwise.
140     uint32_t prescale;          ///< Prescale of the input signal.
141 } mcpwm_hal_capture_config_t;
142 
143 /**
144  * @brief Initialize the internal state of the HAL. Call after settings are set and before other functions are called.
145  *
146  * @note Since There are several individual parts (timers + operators, captures), this funciton is
147  *  allowed to called several times.
148  *
149  * @param hal Context of the HAL layer.
150  * @param init_config Configuration for the HAL to be used only once.
151  */
152 void mcpwm_hal_init(mcpwm_hal_context_t *hal, const mcpwm_hal_init_config_t *init_config);
153 
154 /**
155  * @brief Initialize the hardware, call after `mcpwm_hal_init` and before other functions.
156  *
157  * @param hal Context of the HAL layer.
158  */
159 void mcpwm_hal_hw_init(mcpwm_hal_context_t *hal);
160 
161 /**
162  * @brief Start a timer
163  *
164  * @param hal Context of the HAL layer.
165  * @param timer Timer to start, 0-2.
166  */
167 void mcpwm_hal_timer_start(mcpwm_hal_context_t *hal, int timer);
168 
169 /**
170  * @brief Stop a timer.
171  *
172  * @param hal Context of the HAL layer.
173  * @param timer Timer to stop, 0-2.
174  */
175 void mcpwm_hal_timer_stop(mcpwm_hal_context_t *hal, int timer);
176 
177 /**
178  * @brief Update the basic parameters of a timer.
179  *
180  * @note This will influence the duty rate and count mode of each operator relies on this timer.
181  *       Call `mcpwm_hal_operator_update_basic` for each of the operator that relies on this timer after
182  *       to update the duty rate and generator output.
183  *
184  * @param hal Context of the HAL layer.
185  * @param timer Timer to update, 0-2.
186  */
187 void mcpwm_hal_timer_update_basic(mcpwm_hal_context_t *hal, int timer);
188 
189 /**
190  * @brief Start the synchronization for a timer.
191  *
192  * @param hal Context of the HAL layer.
193  * @param timer Timer to enable, 0-2.
194  * @param sync_conf Configuration of the sync operation.
195  */
196 void mcpwm_hal_timer_enable_sync(mcpwm_hal_context_t *hal, int timer, const mcpwm_hal_sync_config_t *sync_conf);
197 
198 /**
199  * @brief Stop the synchronization for a timer.
200  *
201  * @param hal Context of the HAL layer.
202  * @param timer Timer to disable sync, 0-2.
203  */
204 void mcpwm_hal_timer_disable_sync(mcpwm_hal_context_t *hal, int timer);
205 
206 /**
207  * @brief Update the basic settings (duty, output mode) for an operator.
208  *
209  * Will call `mcpwm_hal_operator_update_comparator` and `mcpwm_hal_operator_update_generator`
210  * recursively to update each of their duty and output mode.
211  *
212  * @param hal Context of the HAL layer.
213  * @param op Operator to update, 0-2.
214  */
215 void mcpwm_hal_operator_update_basic(mcpwm_hal_context_t *hal, int op);
216 
217 /**
218  * @brief Update a comparator (duty) for an operator.
219  *
220  * @param hal Context of the HAL layer.
221  * @param op Operator to update, 0-2.
222  * @param cmp Comparator to update, 0-1.
223  */
224 void mcpwm_hal_operator_update_comparator(mcpwm_hal_context_t *hal, int op, int cmp);
225 
226 /**
227  * @brief Update a generator (output mode) for an operator.
228  *
229  * @param hal Context of the HAL layer.
230  * @param op Operator to update, 0-2.
231  * @param cmp Comparator to update, 0-1.
232  */
233 void mcpwm_hal_operator_update_generator(mcpwm_hal_context_t *hal, int op, int gen_num);
234 
235 /**
236  * @brief Enable the carrier for an operator.
237  *
238  * @param hal Context of the HAL layer.
239  * @param op Operator to enable carrier, 0-2.
240  * @param carrier_conf Configuration of the carrier.
241  */
242 void mcpwm_hal_operator_enable_carrier(mcpwm_hal_context_t *hal, int op, const mcpwm_hal_carrier_conf_t *carrier_conf);
243 
244 /**
245  * @brief Disable the carrier for an operator.
246  *
247  * @param hal Context of the HAL layer.
248  * @param op  Operator to disable carrier, 0-2.
249  */
250 void mcpwm_hal_operator_disable_carrier(mcpwm_hal_context_t *hal, int op);
251 
252 /**
253  * @brief Update the deadzone for an operator.
254  *
255  * @param hal Context of the HAL layer.
256  * @param op Operator to update the deadzone, 0-2.
257  * @param deadzone Configuration of the deadzone. Set member `mode` to `MCPWM_DEADTIME_BYPASS` will bypass the deadzone.
258  */
259 void mcpwm_hal_operator_update_deadzone(mcpwm_hal_context_t *hal, int op, const mcpwm_hal_deadzone_conf_t *deadzone);
260 
261 /**
262  * @brief Enable one of the fault signal.
263  *
264  * @param hal Context of the HAL layer.
265  * @param fault_sig The signal to enable, 0-2.
266  * @param level The active level for the fault signal, true for high and false for low.
267  */
268 void mcpwm_hal_fault_init(mcpwm_hal_context_t *hal, int fault_sig, bool level);
269 
270 /**
271  * @brief Configure how the operator behave to the fault signals.
272  *
273  * Call after the fault signal is enabled by `mcpwm_hal_fault_init`.
274  *
275  * @param hal Context of the HAL layer.
276  * @param op Operator to configure, 0-2.
277  * @param fault_conf Configuration of the behavior of the operator when fault. Clear member `cbc_enabled_mask` and `ost_enabled_mask` will disable the fault detection of this operator.
278  */
279 void mcpwm_hal_operator_update_fault(mcpwm_hal_context_t *hal, int op, const mcpwm_hal_fault_conf_t *fault_conf);
280 
281 /**
282  * @brief Clear the oneshot fault status for an operator.
283  *
284  * @param hal Context of the HAL layer.
285  * @param op The operator to clear oneshot fault status, 0-2.
286  */
287 void mcpwm_hal_fault_oneshot_clear(mcpwm_hal_context_t *hal, int op);
288 
289 /**
290  * @brief Disable one of the fault signal.
291  *
292  * @param hal Context of the HAL layer.
293  * @param fault_sig The fault signal to disable, 0-2.
294  */
295 void mcpwm_hal_fault_disable(mcpwm_hal_context_t *hal, int fault_sig);
296 
297 /**
298  * @brief Enable one of the capture signal.
299  *
300  * @param hal Context of the HAL layer.
301  * @param cap_sig Capture signal to enable, 0-2.
302  * @param conf Configuration on how to capture the signal.
303  */
304 void mcpwm_hal_capture_enable(mcpwm_hal_context_t *hal, int cap_sig, const mcpwm_hal_capture_config_t *conf);
305 
306 /**
307  * @brief Get the capture result.
308  *
309  * @note The output value will always be updated with the register value, no matter event triggered or not.
310  *
311  * @param hal Context of the HAL layer.
312  * @param cap_sig Signal to get capture result, 0-2.
313  * @param out_count Output of the captured counter.
314  * @param out_edge  Output of the captured edge.
315  * @return
316  *  - ESP_OK: if a signal is captured
317  *  - ESP_ERR_NOT_FOUND: if no capture event happened.
318  */
319 esp_err_t mcpwm_hal_capture_get_result(mcpwm_hal_context_t *hal, int cap_sig, uint32_t *out_count,
320                                        mcpwm_capture_on_edge_t *out_edge);
321 
322 /**
323  * @brief Disable one of the capture signal.
324  *
325  * @param hal Context of the HAL layer.
326  * @param cap_sig The signal to capture, 0-2.
327  */
328 void mcpwm_hal_capture_disable(mcpwm_hal_context_t *hal, int cap_sig);
329