From a58a524d4c7e58d03a0fa3698f09fb17985a70bc Mon Sep 17 00:00:00 2001 From: gdisirio Date: Thu, 31 Mar 2011 10:21:52 +0000 Subject: Improvements to the PWM driver. git-svn-id: svn://svn.code.sf.net/p/chibios/svn/trunk@2853 35acf78f-673a-0410-8e92-d51de3d6d3f4 --- os/hal/templates/pwm_lld.c | 35 ++++++++++++++------ os/hal/templates/pwm_lld.h | 81 +++++++++++++--------------------------------- 2 files changed, 48 insertions(+), 68 deletions(-) (limited to 'os/hal/templates') diff --git a/os/hal/templates/pwm_lld.c b/os/hal/templates/pwm_lld.c index 507ba1294..295b0dcb4 100644 --- a/os/hal/templates/pwm_lld.c +++ b/os/hal/templates/pwm_lld.c @@ -87,23 +87,32 @@ void pwm_lld_stop(PWMDriver *pwmp) { } /** - * @brief Determines whatever the PWM channel is already enabled. + * @brief Changes the period the PWM peripheral. + * @details This function changes the period of a PWM unit that has already + * been activated using @p pwmStart(). + * @pre The PWM unit must have been activated using @p pwmStart(). + * @post The PWM unit period is changed to the new value. + * @post Any active channel is disabled by this function and must be + * activated explicitly using @p pwmEnableChannel(). + * @note Depending on the hardware implementation this function has + * effect starting on the next cycle (recommended implementation) + * or immediately (fallback implementation). * - * @param[in] pwmp pointer to the @p PWMDriver object - * @param[in] channel PWM channel identifier - * @return The PWM channel status. - * @retval FALSE the channel is not enabled. - * @retval TRUE the channel is enabled. + * @param[in] pwmp pointer to a @p PWMDriver object * - * @notapi + * @api */ -bool_t pwm_lld_is_enabled(PWMDriver *pwmp, pwmchannel_t channel) { +void pwm_lld_change_period(PWMDriver *pwmp, pwmcnt_t period) { - return FALSE; } /** * @brief Enables a PWM channel. + * @pre The PWM unit must have been activated using @p pwmStart(). + * @post The channel is active using the specified configuration. + * @note Depending on the hardware implementation this function has + * effect starting on the next cycle (recommended implementation) + * or immediately (fallback implementation). * * @param[in] pwmp pointer to a @p PWMDriver object * @param[in] channel PWM channel identifier (0...PWM_CHANNELS-1) @@ -119,11 +128,17 @@ void pwm_lld_enable_channel(PWMDriver *pwmp, /** * @brief Disables a PWM channel. - * @details The channel is disabled and its output line returned to the + * @pre The PWM unit must have been activated using @p pwmStart(). + * @post The channel is disabled and its output line returned to the * idle state. + * @note Depending on the hardware implementation this function has + * effect starting on the next cycle (recommended implementation) + * or immediately (fallback implementation). * * @param[in] pwmp pointer to a @p PWMDriver object * @param[in] channel PWM channel identifier (0...PWM_CHANNELS-1) + * + * @notapi */ void pwm_lld_disable_channel(PWMDriver *pwmp, pwmchannel_t channel) { diff --git a/os/hal/templates/pwm_lld.h b/os/hal/templates/pwm_lld.h index bee00c073..9ef7a9853 100644 --- a/os/hal/templates/pwm_lld.h +++ b/os/hal/templates/pwm_lld.h @@ -65,16 +65,13 @@ typedef uint8_t pwmchannel_t; typedef uint16_t pwmcnt_t; /** - * @brief Type of a structure representing an PWM driver. + * @brief PWM logic mode. */ -typedef struct PWMDriver PWMDriver; - -/** - * @brief PWM notification callback type. - * - * @param[in] pwmp pointer to a @p PWMDriver object - */ -typedef void (*pwmcallback_t)(PWMDriver *pwmp); +typedef enum { + PWM_OUTPUT_DISABLED = 0, /**< Output not driven, callback only. */ + PWM_OUTPUT_ACTIVE_HIGH = 1, /**< Idle is logic level 0. */ + PWM_OUTPUT_ACTIVE_LOW = 2 /**< Idle is logic level 1. */ +} pwmmode_t; /** * @brief PWM driver channel configuration structure. @@ -101,6 +98,18 @@ typedef struct { * architecture dependent, fields. */ typedef struct { + /** + * @brief Timer clock in Hz. + * @note The low level can use assertions in order to catch invalid + * frequency specifications. + */ + uint32_t frequency; + /** + * @brief PWM period in ticks. + * @note The low level can use assertions in order to catch invalid + * period specifications. + */ + pwmcnt_t period; /** * @brief Periodic callback pointer. * @note This callback is invoked on PWM counter reset. If set to @@ -128,6 +137,10 @@ struct PWMDriver { * @brief Current configuration data. */ const PWMConfig *config; + /** + * @brief Current PWM period in ticks. + */ + pwmcnt_t period; #if defined(PWM_DRIVER_EXT_FIELDS) PWM_DRIVER_EXT_FIELDS #endif @@ -138,54 +151,6 @@ struct PWMDriver { /* Driver macros. */ /*===========================================================================*/ -/** - * @brief Converts from fraction to pulse width. - * @note Be careful with rounding errors, this is integer math not magic. - * You can specify tenths of thousandth but make sure you have the - * proper hardware resolution by carefully choosing the clock source - * and prescaler settings, see @p PWM_COMPUTE_PSC. - * - * @param[in] pwmp pointer to a @p PWMDriver object - * @param[in] numerator numerator of the fraction - * @param[in] denominator percentage as an integer between 0 and numerator - * @return The pulse width to be passed to @p pwmEnableChannel(). - * - * @api - */ -#define PWM_FRACTION_TO_WIDTH(pwmp, numerator, denominator) 0 - -/** - * @brief Converts from degrees to pulse width. - * @note Be careful with rounding errors, this is integer math not magic. - * You can specify hundredths of degrees but make sure you have the - * proper hardware resolution by carefully choosing the clock source - * and prescaler settings, see @p PWM_COMPUTE_PSC. - * - * @param[in] pwmp pointer to a @p PWMDriver object - * @param[in] degrees degrees as an integer between 0 and 36000 - * @return The pulse width to be passed to @p pwmEnableChannel(). - * - * @api - */ -#define PWM_DEGREES_TO_WIDTH(pwmp, degrees) \ - PWM_FRACTION_TO_WIDTH(pwmp, 36000, degrees) - -/** - * @brief Converts from percentage to pulse width. - * @note Be careful with rounding errors, this is integer math not magic. - * You can specify tenths of thousandth but make sure you have the - * proper hardware resolution by carefully choosing the clock source - * and prescaler settings, see @p PWM_COMPUTE_PSC. - * - * @param[in] pwmp pointer to a @p PWMDriver object - * @param[in] percentage percentage as an integer between 0 and 10000 - * @return The pulse width to be passed to @p pwmEnableChannel(). - * - * @api - */ -#define PWM_PERCENTAGE_TO_WIDTH(pwmp, percentage) \ - PWM_FRACTION_TO_WIDTH(pwmp, 10000, percentage) - /*===========================================================================*/ /* External declarations. */ /*===========================================================================*/ @@ -196,7 +161,7 @@ extern "C" { void pwm_lld_init(void); void pwm_lld_start(PWMDriver *pwmp); void pwm_lld_stop(PWMDriver *pwmp); - bool_t pwm_lld_is_enabled(PWMDriver *pwmp, pwmchannel_t channel); + void pwm_lld_change_period(PWMDriver *pwmp, pwmcnt_t period); void pwm_lld_enable_channel(PWMDriver *pwmp, pwmchannel_t channel, pwmcnt_t width); -- cgit v1.2.3