// Copyright 2015-2019 Espressif Systems (Shanghai) PTE LTD // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. /******************************************************************************* * NOTICE * The hal is not public api, don't use in application code. * See readme.md in soc/include/hal/readme.md ******************************************************************************/ // The HAL layer for MCPWM (common part) /* * MCPWM HAL usages: * * Initialization: * 1. Fill the parameters in `mcpwm_hal_context_t`. * 2. Call `mcpwm_hal_init` to initialize the context. * 3. Call `mcpwm_hal_hw_init` to initialize the hardware. * * Basic PWM: * 1. Update parameters for the timers, comparators and generators. * 2. Call `mcpwm_hal_timer_update_basic` to update the timer used. * 3. Call `mcpwm_hal_operator_update_basic` to update all the parameters of a operator. * * Alternatively, if only the comparator is updated (duty rate), call * `mcpwm_hal_operator_update_comparator` to update the comparator parameters; if only the * generator is updated (output style), call `mcpwm_hal_operator_update_generator` to update the * generator parameters. * * 4. At any time, call `mcpwm_hal_timer_start` to start the timer (so that PWM output will toggle * according to settings), or call `mcpwm_hal_timer_stop` to stop the timer (so that the PWM output * will be kept as called). * * Timer settings: * - Sync: Call `mcpwm_hal_timer_enable_sync` to enable the sync for the timer, and call * `mcpwm_hal_timer_disable_sync` to disable it. * * Operator settings: * - Carrier: Call `mcpwm_hal_operator_enable_carrier` to enable carrier for an operator, and call * `mcpwm_hal_operator_disable_carrier` to disable it. * * - Deadzone: Call `mcpwm_hal_operator_update_deadzone` to update settings of deadzone for an operator. * * Fault handling settings: * 1. Call `mcpwm_hal_fault_init` to initialize an fault signal to be detected. * 2. Call `mcpwm_hal_operator_update_fault` to update the behavior of an operator when fault is * detected. * 3. If the operator selects oneshot mode to handle the fault event, call * `mcpwm_hal_fault_oneshot_clear` to clear that fault event after the fault is handled properly. * 4. Call `mcpwm_hal_fault_disable` to deinitialize the fault signal when it's no longer used. * * Capture: * 1. Call `mcpwm_hal_capture_enable` to enable the capture for one capture signal. * 2. Call `mcpwm_hal_capture_get_result` to get the last captured result. * 3. Call `mcpwm_hal_capture_disable` to disable the capture for a signal. */ #pragma once #include #include "hal/mcpwm_ll.h" #define MCPWM_BASE_CLK (2 * APB_CLK_FREQ) //2*APB_CLK_FREQ 160Mhz /// Configuration of HAL that used only once. typedef struct { int host_id; ///< Which MCPWM peripheral to use, 0-1. } mcpwm_hal_init_config_t; /// Configuration of each generator (output of operator) typedef struct { mcpwm_duty_type_t duty_type; ///< How the generator output int comparator; ///< for mode `MCPWM_DUTY_MODE_*`, which comparator it refers to. } mcpwm_hal_generator_config_t; /// Configuration of each operator typedef struct { mcpwm_hal_generator_config_t gen[SOC_MCPWM_GENERATOR_NUM]; ///< Configuration of the generators float duty[SOC_MCPWM_COMPARATOR_NUM]; ///< Duty rate for each comparator, 10 means 10%. int timer; ///< The timer this operator is using } mcpwm_hal_operator_config_t; /// Configuration of each timer typedef struct { uint32_t timer_prescale; ///< The prescale from the MCPWM main clock to the timer clock, TIMER_FREQ=(MCPWM_FREQ/(timer_prescale+1)) uint32_t freq; ///< Frequency desired, will be updated to actual value after the `mcpwm_hal_timer_update_freq` is called. mcpwm_counter_type_t count_mode; ///< Counting mode } mcpwm_hal_timer_config_t; typedef struct { mcpwm_dev_t *dev; ///< Beginning address of the MCPWM peripheral registers. Call `mcpwm_hal_init` to initialize it. uint32_t prescale; ///< Prescale from the 160M clock to MCPWM main clock. mcpwm_hal_timer_config_t timer[SOC_MCPWM_TIMER_NUM]; ///< Configuration of the timers mcpwm_hal_operator_config_t op[SOC_MCPWM_OP_NUM]; ///< Configuration of the operators } mcpwm_hal_context_t; /// Configuration of the carrier typedef struct { bool inverted; ///< Whether to invert the output uint8_t duty; ///< Duty of the carrier, 0-7. Duty rate = duty/8. uint8_t oneshot_pulse_width; ///< oneshot pulse width, in carrier periods. 0 to disable. 0-15. uint32_t period; ///< Prescale from the MCPWM main clock to the carrier clock. CARRIER_FREQ=(MCPWM_FREQ/(period+1)/8.) } mcpwm_hal_carrier_conf_t; /// Configuration of the deadzone typedef struct { mcpwm_deadtime_type_t mode; ///< Deadzone mode, `MCPWM_DEADTIME_BYPASS` to disable. uint32_t fed; ///< Delay on falling edge. By MCPWM main clock. uint32_t red; ///< Delay on rising edge. By MCPWM main clock. } mcpwm_hal_deadzone_conf_t; /// Configuration of the fault handling for each operator typedef struct { uint32_t cbc_enabled_mask; ///< Whether the cycle-by-cycle fault handling is enabled on each fault signal. BIT(n) stands for signal n. uint32_t ost_enabled_mask; ///< Whether the oneshot fault handling is enabled on each on each fault signal. BIT(n) stands for signal n. 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. } mcpwm_hal_fault_conf_t; /// Configuration of the synchronization of each clock typedef struct { mcpwm_sync_signal_t sync_sig; ///< Sync signal to use 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. } mcpwm_hal_sync_config_t; /// Configuration of the capture feature on each capture signal typedef struct { mcpwm_capture_on_edge_t cap_edge; ///< Whether the edges is captured, bitwise. uint32_t prescale; ///< Prescale of the input signal. } mcpwm_hal_capture_config_t; /** * @brief Initialize the internal state of the HAL. Call after settings are set and before other functions are called. * * @note Since There are several individual parts (timers + operators, captures), this funciton is * allowed to called several times. * * @param hal Context of the HAL layer. * @param init_config Configuration for the HAL to be used only once. */ void mcpwm_hal_init(mcpwm_hal_context_t *hal, const mcpwm_hal_init_config_t *init_config); /** * @brief Initialize the hardware, call after `mcpwm_hal_init` and before other functions. * * @param hal Context of the HAL layer. */ void mcpwm_hal_hw_init(mcpwm_hal_context_t *hal); /** * @brief Start a timer * * @param hal Context of the HAL layer. * @param timer Timer to start, 0-2. */ void mcpwm_hal_timer_start(mcpwm_hal_context_t *hal, int timer); /** * @brief Stop a timer. * * @param hal Context of the HAL layer. * @param timer Timer to stop, 0-2. */ void mcpwm_hal_timer_stop(mcpwm_hal_context_t *hal, int timer); /** * @brief Update the basic parameters of a timer. * * @note This will influence the duty rate and count mode of each operator relies on this timer. * Call `mcpwm_hal_operator_update_basic` for each of the operator that relies on this timer after * to update the duty rate and generator output. * * @param hal Context of the HAL layer. * @param timer Timer to update, 0-2. */ void mcpwm_hal_timer_update_basic(mcpwm_hal_context_t *hal, int timer); /** * @brief Start the synchronization for a timer. * * @param hal Context of the HAL layer. * @param timer Timer to enable, 0-2. * @param sync_conf Configuration of the sync operation. */ void mcpwm_hal_timer_enable_sync(mcpwm_hal_context_t *hal, int timer, const mcpwm_hal_sync_config_t *sync_conf); /** * @brief Stop the synchronization for a timer. * * @param hal Context of the HAL layer. * @param timer Timer to disable sync, 0-2. */ void mcpwm_hal_timer_disable_sync(mcpwm_hal_context_t *hal, int timer); /** * @brief Update the basic settings (duty, output mode) for an operator. * * Will call `mcpwm_hal_operator_update_comparator` and `mcpwm_hal_operator_update_generator` * recursively to update each of their duty and output mode. * * @param hal Context of the HAL layer. * @param op Operator to update, 0-2. */ void mcpwm_hal_operator_update_basic(mcpwm_hal_context_t *hal, int op); /** * @brief Update a comparator (duty) for an operator. * * @param hal Context of the HAL layer. * @param op Operator to update, 0-2. * @param cmp Comparator to update, 0-1. */ void mcpwm_hal_operator_update_comparator(mcpwm_hal_context_t *hal, int op, int cmp); /** * @brief Update a generator (output mode) for an operator. * * @param hal Context of the HAL layer. * @param op Operator to update, 0-2. * @param cmp Comparator to update, 0-1. */ void mcpwm_hal_operator_update_generator(mcpwm_hal_context_t *hal, int op, int gen_num); /** * @brief Enable the carrier for an operator. * * @param hal Context of the HAL layer. * @param op Operator to enable carrier, 0-2. * @param carrier_conf Configuration of the carrier. */ void mcpwm_hal_operator_enable_carrier(mcpwm_hal_context_t *hal, int op, const mcpwm_hal_carrier_conf_t *carrier_conf); /** * @brief Disable the carrier for an operator. * * @param hal Context of the HAL layer. * @param op Operator to disable carrier, 0-2. */ void mcpwm_hal_operator_disable_carrier(mcpwm_hal_context_t *hal, int op); /** * @brief Update the deadzone for an operator. * * @param hal Context of the HAL layer. * @param op Operator to update the deadzone, 0-2. * @param deadzone Configuration of the deadzone. Set member `mode` to `MCPWM_DEADTIME_BYPASS` will bypass the deadzone. */ void mcpwm_hal_operator_update_deadzone(mcpwm_hal_context_t *hal, int op, const mcpwm_hal_deadzone_conf_t *deadzone); /** * @brief Enable one of the fault signal. * * @param hal Context of the HAL layer. * @param fault_sig The signal to enable, 0-2. * @param level The active level for the fault signal, true for high and false for low. */ void mcpwm_hal_fault_init(mcpwm_hal_context_t *hal, int fault_sig, bool level); /** * @brief Configure how the operator behave to the fault signals. * * Call after the fault signal is enabled by `mcpwm_hal_fault_init`. * * @param hal Context of the HAL layer. * @param op Operator to configure, 0-2. * @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. */ void mcpwm_hal_operator_update_fault(mcpwm_hal_context_t *hal, int op, const mcpwm_hal_fault_conf_t *fault_conf); /** * @brief Clear the oneshot fault status for an operator. * * @param hal Context of the HAL layer. * @param op The operator to clear oneshot fault status, 0-2. */ void mcpwm_hal_fault_oneshot_clear(mcpwm_hal_context_t *hal, int op); /** * @brief Disable one of the fault signal. * * @param hal Context of the HAL layer. * @param fault_sig The fault signal to disable, 0-2. */ void mcpwm_hal_fault_disable(mcpwm_hal_context_t *hal, int fault_sig); /** * @brief Enable one of the capture signal. * * @param hal Context of the HAL layer. * @param cap_sig Capture signal to enable, 0-2. * @param conf Configuration on how to capture the signal. */ void mcpwm_hal_capture_enable(mcpwm_hal_context_t *hal, int cap_sig, const mcpwm_hal_capture_config_t *conf); /** * @brief Get the capture result. * * @note The output value will always be updated with the register value, no matter event triggered or not. * * @param hal Context of the HAL layer. * @param cap_sig Signal to get capture result, 0-2. * @param out_count Output of the captured counter. * @param out_edge Output of the captured edge. * @return * - ESP_OK: if a signal is captured * - ESP_ERR_NOT_FOUND: if no capture event happened. */ esp_err_t mcpwm_hal_capture_get_result(mcpwm_hal_context_t *hal, int cap_sig, uint32_t *out_count, mcpwm_capture_on_edge_t *out_edge); /** * @brief Disable one of the capture signal. * * @param hal Context of the HAL layer. * @param cap_sig The signal to capture, 0-2. */ void mcpwm_hal_capture_disable(mcpwm_hal_context_t *hal, int cap_sig);