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