ChibiOS/RT Architecture - Reference Manual - Guides |
00001 /* 00002 ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010 Giovanni Di Sirio. 00003 00004 This file is part of ChibiOS/RT. 00005 00006 ChibiOS/RT is free software; you can redistribute it and/or modify 00007 it under the terms of the GNU General Public License as published by 00008 the Free Software Foundation; either version 3 of the License, or 00009 (at your option) any later version. 00010 00011 ChibiOS/RT is distributed in the hope that it will be useful, 00012 but WITHOUT ANY WARRANTY; without even the implied warranty of 00013 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00014 GNU General Public License for more details. 00015 00016 You should have received a copy of the GNU General Public License 00017 along with this program. If not, see <http://www.gnu.org/licenses/>. 00018 00019 --- 00020 00021 A special exception to the GPL can be applied should you wish to distribute 00022 a combined work that includes ChibiOS/RT, without being obliged to provide 00023 the source code for any proprietary components. See the file exception.txt 00024 for full details of how and when the exception can be applied. 00025 */ 00026 00027 /** 00028 * @file templates/pwm_lld.h 00029 * @brief PWM Driver subsystem low level driver header template. 00030 * 00031 * @addtogroup PWM_LLD 00032 * @{ 00033 */ 00034 00035 #ifndef _PWM_LLD_H_ 00036 #define _PWM_LLD_H_ 00037 00038 #if CH_HAL_USE_PWM || defined(__DOXYGEN__) 00039 00040 /*===========================================================================*/ 00041 /* Driver constants. */ 00042 /*===========================================================================*/ 00043 00044 /*===========================================================================*/ 00045 /* Driver pre-compile time settings. */ 00046 /*===========================================================================*/ 00047 00048 /** 00049 * @brief Number of PWM channels per PWM driver. 00050 */ 00051 #if !defined(PWM_CHANNELS) || defined(__DOXYGEN__) 00052 #define PWM_CHANNELS 1 00053 #endif 00054 00055 /*===========================================================================*/ 00056 /* Derived constants and error checks. */ 00057 /*===========================================================================*/ 00058 00059 /*===========================================================================*/ 00060 /* Driver data structures and types. */ 00061 /*===========================================================================*/ 00062 00063 /** 00064 * @brief PWM channel type. 00065 */ 00066 typedef uint8_t pwmchannel_t; 00067 00068 /** 00069 * @brief PWM counter type. 00070 */ 00071 typedef uint16_t pwmcnt_t; 00072 00073 /** 00074 * @brief Type of a structure representing an PWM driver. 00075 */ 00076 typedef struct PWMDriver PWMDriver; 00077 00078 /** 00079 * @brief PWM notification callback type. 00080 * 00081 * @param[in] pwmp pointer to a @p PWMDriver object 00082 */ 00083 typedef void (*pwmcallback_t)(PWMDriver *pwmp); 00084 00085 /** 00086 * @brief PWM driver channel configuration structure. 00087 * @note Some architectures may not be able to support the channel mode 00088 * or the callback, in this case the fields are ignored. 00089 */ 00090 typedef struct { 00091 /** 00092 * @brief Channel active logic level. 00093 */ 00094 pwmmode_t pcc_mode; 00095 /** 00096 * @brief Channel callback pointer. 00097 * @note This callback is invoked on the channel compare event. If set to 00098 * @p NULL then the callback is disabled. 00099 */ 00100 pwmcallback_t pcc_callback; 00101 /* End of the mandatory fields.*/ 00102 } PWMChannelConfig; 00103 00104 /** 00105 * @brief Driver configuration structure. 00106 * @note Implementations may extend this structure to contain more, 00107 * architecture dependent, fields. 00108 */ 00109 typedef struct { 00110 /** 00111 * @brief Periodic callback pointer. 00112 * @note This callback is invoked on PWM counter reset. If set to 00113 * @p NULL then the callback is disabled. 00114 */ 00115 pwmcallback_t pc_callback; 00116 /** 00117 * @brief Channels configurations. 00118 */ 00119 PWMChannelConfig pc_channels[PWM_CHANNELS]; 00120 /* End of the mandatory fields.*/ 00121 } PWMConfig; 00122 00123 /** 00124 * @brief Structure representing an PWM driver. 00125 * @note Implementations may extend this structure to contain more, 00126 * architecture dependent, fields. 00127 */ 00128 struct PWMDriver { 00129 /** 00130 * @brief Driver state. 00131 */ 00132 pwmstate_t pd_state; 00133 /** 00134 * @brief Current configuration data. 00135 */ 00136 const PWMConfig *pd_config; 00137 #if defined(PWM_DRIVER_EXT_FIELDS) 00138 PWM_DRIVER_EXT_FIELDS 00139 #endif 00140 /* End of the mandatory fields.*/ 00141 }; 00142 00143 /*===========================================================================*/ 00144 /* Driver macros. */ 00145 /*===========================================================================*/ 00146 00147 /** 00148 * @brief Converts from fraction to pulse width. 00149 * @note Be careful with rounding errors, this is integer math not magic. 00150 * You can specify tenths of thousandth but make sure you have the 00151 * proper hardware resolution by carefully choosing the clock source 00152 * and prescaler settings, see @p PWM_COMPUTE_PSC. 00153 * 00154 * @param[in] numerator numerator of the fraction 00155 * @param[in] denominator percentage as an integer between 0 and numerator 00156 * @return The pulse width to be passed to @p pwmEnableChannel(). 00157 * 00158 * @api 00159 */ 00160 #define PWM_FRACTION_TO_WIDTH(pwmp, numerator, denominator) 0 00161 00162 /** 00163 * @brief Converts from degrees to pulse width. 00164 * @note Be careful with rounding errors, this is integer math not magic. 00165 * You can specify hundredths of degrees but make sure you have the 00166 * proper hardware resolution by carefully choosing the clock source 00167 * and prescaler settings, see @p PWM_COMPUTE_PSC. 00168 * 00169 * @param[in] pwmp pointer to a @p PWMDriver object 00170 * @param[in] degrees degrees as an integer between 0 and 36000 00171 * @return The pulse width to be passed to @p pwmEnableChannel(). 00172 * 00173 * @api 00174 */ 00175 #define PWM_DEGREES_TO_WIDTH(pwmp, degrees) \ 00176 PWM_FRACTION_TO_WIDTH(pwmp, 36000, degrees) 00177 00178 /** 00179 * @brief Converts from percentage to pulse width. 00180 * @note Be careful with rounding errors, this is integer math not magic. 00181 * You can specify tenths of thousandth but make sure you have the 00182 * proper hardware resolution by carefully choosing the clock source 00183 * and prescaler settings, see @p PWM_COMPUTE_PSC. 00184 * 00185 * @param[in] pwmp pointer to a @p PWMDriver object 00186 * @param[in] percentage percentage as an integer between 0 and 10000 00187 * @return The pulse width to be passed to @p pwmEnableChannel(). 00188 * 00189 * @api 00190 */ 00191 #define PWM_PERCENTAGE_TO_WIDTH(pwmp, percentage) \ 00192 PWM_FRACTION_TO_WIDTH(pwmp, 10000, percentage) 00193 00194 /*===========================================================================*/ 00195 /* External declarations. */ 00196 /*===========================================================================*/ 00197 00198 #ifdef __cplusplus 00199 extern "C" { 00200 #endif 00201 void pwm_lld_init(void); 00202 void pwm_lld_start(PWMDriver *pwmp); 00203 void pwm_lld_stop(PWMDriver *pwmp); 00204 bool_t pwm_lld_is_enabled(PWMDriver *pwmp, pwmchannel_t channel); 00205 void pwm_lld_enable_channel(PWMDriver *pwmp, 00206 pwmchannel_t channel, 00207 pwmcnt_t width); 00208 void pwm_lld_disable_channel(PWMDriver *pwmp, pwmchannel_t channel); 00209 #ifdef __cplusplus 00210 } 00211 #endif 00212 00213 #endif /* CH_HAL_USE_PWM */ 00214 00215 #endif /* _PWM_LLD_H_ */ 00216 00217 /** @} */