1 /* 2 * Copyright (c) 2015-2019, Texas Instruments Incorporated 3 * All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions 7 * are met: 8 * 9 * * Redistributions of source code must retain the above copyright 10 * notice, this list of conditions and the following disclaimer. 11 * 12 * * Redistributions in binary form must reproduce the above copyright 13 * notice, this list of conditions and the following disclaimer in the 14 * documentation and/or other materials provided with the distribution. 15 * 16 * * Neither the name of Texas Instruments Incorporated nor the names of 17 * its contributors may be used to endorse or promote products derived 18 * from this software without specific prior written permission. 19 * 20 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 21 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 22 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 23 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR 24 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 25 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 26 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 27 * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 28 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 29 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, 30 * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 31 */ 32 /*! ============================================================================ 33 * @file PWMTimerCC32XX.h 34 * 35 * @brief PWM driver implementation using CC32XX General Purpose Timers. 36 * 37 * The PWM header file should be included in an application as follows: 38 * @code 39 * #include <ti/drivers/PWM.h> 40 * #include <ti/drivers/pwm/PWMTimerCC32XX.h> 41 * @endcode 42 * 43 * Refer to @ref PWM.h for a complete description of the PWM 44 * driver APIs provided and examples of their use. 45 * 46 * ## Overview # 47 * This driver configures a CC32XX General Purpose Timer (GPT) in PWM mode. 48 * When in PWM mode, each GPT is divided into 2 PWM outputs. This driver 49 * manages each output as an independent PWM instance. The timer is 50 * automatically configured in count-down mode using the system clock as 51 * the source. 52 * 53 * The timers operate at the system clock frequency (80 MHz). So each timer 54 * tick is 12.5 ns. The period and duty registers are 16 bits wide; thus 55 * 8-bit prescalars are used to extend period and duty registers. The 56 * maximum value supported is 16777215 timer counts ((2^24) - 1) or 57 * 209715 microseconds. Updates to a PWM's period or duty will occur 58 * instantaneously (GPT peripherals do not have shadow registers). 59 * 60 * When stopped, the driver will configure the pin in GPIO mode & set the 61 * output to the PWM_IdleLevel specified in the params used during open. Users 62 * need be aware that while PIN 19 can be used for PWM it is not GPIO capable, 63 * so it cannot be set to the PWM_IdleLevel. Output voltage will be PWM output 64 * at the moment it is stopped. 65 * 66 * Finally, when this driver is opened, it automatically changes the 67 * PWM pin's parking configuration (used when entering low power modes) to 68 * correspond with the PWM_IDLE_LEVEL set in the PWM_params. However, this 69 * setting is not reverted once the driver is closed, it is the users 70 * responsibility to change the parking configuration if necessary. 71 * 72 * ### CC32xx PWM Driver Configuration # 73 * 74 * In order to use the PWM APIs, the application is required 75 * to define 4 configuration items in the application ti_drivers_config.c file: 76 * 77 * 1. An array of PWMTimerCC32XX_Object elements, which will be used by 78 * by the driver to maintain instance state. 79 * Below is an example PWMTimerCC32XX_Object array appropriate for the CC3220SF LaunchPad 80 * board: 81 * @code 82 * #include <ti/drivers/PWM.h> 83 * #include <ti/drivers/pwm/PWMTimerCC32XX.h> 84 * 85 * PWMTimerCC32XX_Object pwmTimerCC3220SObjects[CC3220SF_LAUNCHXL_PWMCOUNT]; 86 * @endcode 87 * 88 * 2. An array of PWMTimerCC32XX_HWAttrsV2 elements that defines which 89 * pin will be used by the corresponding PWM instance 90 * (see @ref pwmPinIdentifiersCC32XX). 91 * Below is an example PWMTimerCC32XX_HWAttrsV2 array appropriate for the CC3220SF LaunchPad 92 * board: 93 * @code 94 * const PWMTimerCC32XX_HWAttrsV2 pwmTimerCC3220SHWAttrs[CC3220SF_LAUNCHXL_PWMCOUNT] = { 95 * { 96 * .pwmPin = PWMTimerCC32XX_PIN_01 97 * }, 98 * { 99 * .pwmPin = PWMTimerCC32XX_PIN_02 100 * } 101 * }; 102 * @endcode 103 * 104 * 3. An array of @ref PWM_Config elements, one for each PWM instance. Each 105 * element of this array identifies the device-specific API function table, 106 * the device specific PWM object instance, and the device specific Hardware 107 * Attributes to be used for each PWM channel. 108 * Below is an example @ref PWM_Config array appropriate for the CC3220SF LaunchPad 109 * board: 110 * @code 111 * const PWM_Config PWM_config[CC3220SF_LAUNCHXL_PWMCOUNT] = { 112 * { 113 * .fxnTablePtr = &PWMTimerCC32XX_fxnTable, 114 * .object = &pwmTimerCC3220SObjects[CC3220SF_LAUNCHXL_PWM6], 115 * .hwAttrs = &pwmTimerCC3220SHWAttrs[CC3220SF_LAUNCHXL_PWM6] 116 * }, 117 * { 118 * .fxnTablePtr = &PWMTimerCC32XX_fxnTable, 119 * .object = &pwmTimerCC3220SObjects[CC3220SF_LAUNCHXL_PWM7], 120 * .hwAttrs = &pwmTimerCC3220SHWAttrs[CC3220SF_LAUNCHXL_PWM7] 121 * } 122 * }; 123 * @endcode 124 * 125 * 4. A global variable, PWM_count, that informs the driver how many PWM 126 * instances are defined: 127 * @code 128 * const uint_least8_t PWM_count = CC3220SF_LAUNCHXL_PWMCOUNT; 129 * @endcode 130 * 131 * ### Power Management # 132 * The TI-RTOS power management framework will try to put the device into the most 133 * power efficient mode whenever possible. Please see the technical reference 134 * manual for further details on each power mode. 135 * 136 * The PWMTimerCC32XX driver explicitly sets a power constraint when the 137 * PWM is running to prevent LPDS. 138 * The following statements are valid: 139 * - After PWM_open(): Clocks are enabled to the timer resource and the 140 * configured pwmPin. The device is still allowed 141 * to enter LPDS. 142 * - After PWM_start(): LPDS is disabled when PWM is running. 143 * - After PWM_stop(): Conditions are equal as for after PWM_open 144 * - After PWM_close(): The underlying GPTimer is turned off, and the clocks 145 * to the timer and pin are disabled.. 146 * 147 * ============================================================================= 148 */ 149 150 #ifndef ti_driver_pwm_PWMTimerCC32XX__include 151 #define ti_driver_pwm_PWMTimerCC32XX__include 152 153 #include <stdbool.h> 154 #include <ti/drivers/Power.h> 155 #include <ti/drivers/PWM.h> 156 157 #ifdef __cplusplus 158 extern "C" { 159 #endif 160 161 /*! \cond */ 162 /* 163 * PWMTimer port/pin defines for pin configuration. 164 * 165 * The timer id (0, 1, 2, or 3) is stored in bits 31 - 28 166 * The timer half (0 = A, 1 = B) is stored in bits 27 - 24 167 * The GPIO port (0, 1, 2, or 3) is stored in bits 23 - 20 168 * The GPIO pin index within the port (0 - 7) is stored in bits 19 - 16 169 * The pin mode is stored in bits 11 - 8 170 * The pin number is stored in bits 7 - 0 171 * 172 * 173 * 31 - 28 27 - 24 23 - 20 19 - 16 11 - 8 7 - 0 174 * ----------------------------------------------------------------------- 175 * | Timer id | Timer half | GPIO port | GPIO pin index | pin mode | pin | 176 * ----------------------------------------------------------------------- 177 * 178 * The CC32XX has fixed GPIO assignments and pin modes for a given pin. 179 * A PWM pin mode for a given pin has a fixed timer/timer-half. 180 */ 181 #define PWMTimerCC32XX_T0A (0x00 << 24) 182 #define PWMTimerCC32XX_T0B (0x01 << 24) 183 #define PWMTimerCC32XX_T1A (0x10 << 24) 184 #define PWMTimerCC32XX_T1B (0x11 << 24) 185 #define PWMTimerCC32XX_T2A (0x20 << 24) 186 #define PWMTimerCC32XX_T2B (0x21 << 24) 187 #define PWMTimerCC32XX_T3A (0x30 << 24) 188 #define PWMTimerCC32XX_T3B (0x31 << 24) 189 190 #define PWMTimerCC32XX_GPIO9 (0x11 << 16) 191 #define PWMTimerCC32XX_GPIO10 (0x12 << 16) 192 #define PWMTimerCC32XX_GPIO11 (0x13 << 16) 193 #define PWMTimerCC32XX_GPIO24 (0x30 << 16) 194 #define PWMTimerCC32XX_GPIO25 (0x31 << 16) 195 196 #define PWMTimerCC32XX_GPIONONE (0xFF << 16) 197 /*! \endcond */ 198 199 /*! 200 * \defgroup pwmPinIdentifiersCC32XX PWMTimerCC32XX_HWAttrs 'pwmPin' field options 201 * @{ 202 */ 203 /*! 204 * @name PIN 01, GPIO10, uses Timer3A for PWM. 205 * @{ 206 */ 207 #define PWMTimerCC32XX_PIN_01 (PWMTimerCC32XX_T3A | PWMTimerCC32XX_GPIO10 | 0x0300) /*!< @hideinitializer */ 208 /*! @} */ 209 /*! 210 * @name PIN 02, GPIO11, uses Timer3B for PWM. 211 * @{ 212 */ 213 #define PWMTimerCC32XX_PIN_02 (PWMTimerCC32XX_T3B | PWMTimerCC32XX_GPIO11 | 0x0301) /*!< @hideinitializer */ 214 /*! @} */ 215 /*! 216 * @name PIN 17, GPIO24, uses Timer0A for PWM. 217 * @{ 218 */ 219 #define PWMTimerCC32XX_PIN_17 (PWMTimerCC32XX_T0A | PWMTimerCC32XX_GPIO24 | 0x0510) /*!< @hideinitializer */ 220 /*! @} */ 221 /*! 222 * @name PIN 19, uses Timer1B for PWM. 223 * @{ 224 */ 225 #define PWMTimerCC32XX_PIN_19 (PWMTimerCC32XX_T1B | PWMTimerCC32XX_GPIONONE | 0x0812) /*!< @hideinitializer */ 226 /*! @} */ 227 /*! 228 * @name PIN 21, GPIO25, uses Timer1A for PWM. 229 * @{ 230 */ 231 #define PWMTimerCC32XX_PIN_21 (PWMTimerCC32XX_T1A | PWMTimerCC32XX_GPIO25 | 0x0914) /*!< @hideinitializer */ 232 /*! @} */ 233 /*! 234 * @name PIN 64, GPIO9, uses Timer2B for PWM. 235 * @{ 236 */ 237 #define PWMTimerCC32XX_PIN_64 (PWMTimerCC32XX_T2B | PWMTimerCC32XX_GPIO9 | 0x033F) /*!< @hideinitializer */ 238 /*! @} */ 239 /*! @} */ 240 241 /** 242 * @addtogroup PWM_STATUS 243 * PWMTimerCC32XX_STATUS_* macros are command codes only defined in the 244 * PWMTimerCC32XX.h driver implementation and need to: 245 * @code 246 * #include <ti/drivers/pwm/PWMTimerCC32XX.h> 247 * @endcode 248 * @{ 249 */ 250 251 /* Add PWMTimerCC32XX_STATUS_* macros here */ 252 253 /** @}*/ 254 255 /** 256 * @addtogroup PWM_CMD 257 * PWMTimerCC32XX_CMD_* macros are command codes only defined in the 258 * PWMTimerCC32XX.h driver implementation and need to: 259 * @code 260 * #include <ti/drivers/pwm/PWMTimerCC32XX.h> 261 * @endcode 262 * @{ 263 */ 264 265 /* Add PWMTimerCC32XX_CMD_* macros here */ 266 267 /** @}*/ 268 269 /* PWM function table pointer */ 270 extern const PWM_FxnTable PWMTimerCC32XX_fxnTable; 271 272 /*! 273 * @brief PWMTimerCC32XX Hardware attributes 274 * 275 * The 'pwmPin' field identifies which physical pin to use for a 276 * particular PWM channel as well as the corresponding Timer resource used 277 * to source the PWM signal. The encoded pin identifier macros for 278 * initializing the 'pwmPin' field must be selected from the 279 * @ref pwmPinIdentifiersCC32XX macros. 280 * 281 * A sample structure is shown below: 282 * @code 283 * const PWMTimerCC32XX_HWAttrsV2 pwmTimerCC32XXHWAttrs[] = { 284 * { 285 * .pwmPin = PWMTimerCC32XX_PIN_01, 286 * }, 287 * { 288 * .pwmPin = PWMTimerCC32XX_PIN_02, 289 * } 290 * }; 291 * @endcode 292 */ 293 typedef struct { 294 uint32_t pwmPin; /*!< Pin to output PWM signal on 295 (see @ref pwmPinIdentifiersCC32XX) */ 296 } PWMTimerCC32XX_HWAttrsV2; 297 298 /*! 299 * @brief PWMTimerCC32XX Object 300 * 301 * The application must not access any member variables of this structure! 302 */ 303 typedef struct { 304 Power_NotifyObj postNotify; 305 uint32_t duty; /* Current duty cycle in Duty_Unites */ 306 uint32_t period; /* Current period PERIOD_Units */ 307 PWM_Duty_Units dutyUnits; /* Current duty cycle unit */ 308 PWM_Period_Units periodUnits; /* Current period unit */ 309 PWM_IdleLevel idleLevel; /* PWM idle level when stopped / not started */ 310 bool pwmStarted; /* Used to gate Power_set/releaseConstraint() calls */ 311 bool isOpen; /* open flag used to check if PWM is opened */ 312 } PWMTimerCC32XX_Object; 313 314 #ifdef __cplusplus 315 } 316 #endif 317 318 #endif /* ti_driver_pwm_PWMTimerCC32XX__include */ 319