328 lines
13 KiB
C
328 lines
13 KiB
C
// 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 <esp_err.h>
|
|
#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);
|