1 /* 2 * Copyright (c) 2016, Freescale Semiconductor, Inc. 3 * Copyright 2016-2017 NXP 4 * All rights reserved. 5 * 6 * SPDX-License-Identifier: BSD-3-Clause 7 */ 8 9 #include "fsl_pwm.h" 10 11 /******************************************************************************* 12 * Definitions 13 ******************************************************************************/ 14 15 /* Component ID definition, used by tools. */ 16 #ifndef FSL_COMPONENT_ID 17 #define FSL_COMPONENT_ID "platform.drivers.ipwm" 18 #endif 19 20 /******************************************************************************* 21 * Prototypes 22 ******************************************************************************/ 23 /*! 24 * @brief Get the instance from the base address 25 * 26 * @param base PWM peripheral base address 27 * 28 * @return The PWM module instance 29 */ 30 static uint32_t PWM_GetInstance(PWM_Type *base); 31 32 /******************************************************************************* 33 * Variables 34 ******************************************************************************/ 35 /*! @brief Pointers to PWM bases for each instance. */ 36 static PWM_Type *const s_pwmBases[] = PWM_BASE_PTRS; 37 38 #if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) 39 /* Array of PWM clock name. */ 40 static const clock_ip_name_t s_pwmClock[] = PWM_CLOCKS; 41 #endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */ 42 43 /******************************************************************************* 44 * Code 45 ******************************************************************************/ PWM_GetInstance(PWM_Type * base)46static uint32_t PWM_GetInstance(PWM_Type *base) 47 { 48 uint32_t instance; 49 uint32_t pwmArrayCount = (sizeof(s_pwmBases) / sizeof(s_pwmBases[0])); 50 51 /* Find the instance index from base address mappings. */ 52 for (instance = 0; instance < pwmArrayCount; instance++) 53 { 54 if (s_pwmBases[instance] == base) 55 { 56 break; 57 } 58 } 59 60 assert(instance < pwmArrayCount); 61 62 return instance; 63 } 64 65 /*! 66 * brief Ungates the PWM clock and configures the peripheral for basic operation. 67 * 68 * note This API should be called at the beginning of the application using the PWM driver. 69 * 70 * param base PWM peripheral base address 71 * param config Pointer to user's PWM config structure. 72 * 73 * return kStatus_Success means success; else failed. 74 */ PWM_Init(PWM_Type * base,const pwm_config_t * config)75status_t PWM_Init(PWM_Type *base, const pwm_config_t *config) 76 { 77 assert(config); 78 79 #if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) 80 /* Ungate PWM clock */ 81 CLOCK_EnableClock(s_pwmClock[PWM_GetInstance(base)]); 82 #endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */ 83 84 /* Setup the PWM operation */ 85 base->PWMCR = (PWM_PWMCR_REPEAT(config->sampleRepeat) | PWM_PWMCR_PRESCALER(config->prescale) | 86 PWM_PWMCR_CLKSRC(config->clockSource) | PWM_PWMCR_POUTC(config->outputConfig) | 87 PWM_PWMCR_HCTR(config->halfWordSwap) | PWM_PWMCR_BCTR(config->byteSwap) | 88 PWM_PWMCR_STOPEN(config->enableStopMode) | PWM_PWMCR_DBGEN(config->enableDebugMode) | 89 PWM_PWMCR_WAITEN(config->enableWaitMode) | PWM_PWMCR_DOZEN(config->enableDozeMode) | 90 PWM_PWMCR_FWM(config->fifoWater)); 91 92 return kStatus_Success; 93 } 94 95 /*! 96 * brief Gate the PWM submodule clock 97 * 98 * param base PWM peripheral base address 99 */ PWM_Deinit(PWM_Type * base)100void PWM_Deinit(PWM_Type *base) 101 { 102 /* Set clock source to none to disable counter */ 103 base->PWMCR &= ~(PWM_PWMCR_CLKSRC_MASK); 104 105 #if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) 106 /* Gate the PWM clock */ 107 CLOCK_DisableClock(s_pwmClock[PWM_GetInstance(base)]); 108 #endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */ 109 } 110 111 /*! 112 * brief Fill in the PWM config struct with the default settings 113 * 114 * The default values are: 115 * code 116 * config->enableStopMode = false; 117 * config->enableDozeMode = false; 118 * config->enableWaitMode = false; 119 * config->enableDozeMode = false; 120 * config->clockSource = kPWM_LowFrequencyClock; 121 * config->prescale = 0U; 122 * config->outputConfig = kPWM_SetAtRolloverAndClearAtcomparison; 123 * config->fifoWater = kPWM_FIFOWaterMark_2; 124 * config->sampleRepeat = kPWM_EachSampleOnce; 125 * config->byteSwap = kPWM_ByteNoSwap; 126 * config->halfWordSwap = kPWM_HalfWordNoSwap; 127 * endcode 128 * param config Pointer to user's PWM config structure. 129 */ PWM_GetDefaultConfig(pwm_config_t * config)130void PWM_GetDefaultConfig(pwm_config_t *config) 131 { 132 assert(config); 133 134 /* Initializes the configure structure to zero. */ 135 (void)memset(config, 0, sizeof(*config)); 136 137 /* Stop mode disabled */ 138 config->enableStopMode = false; 139 /* Doze mode disabled */ 140 config->enableDozeMode = false; 141 /* Wait mode disabled */ 142 config->enableWaitMode = false; 143 /* Debug mode disabled */ 144 config->enableDebugMode = false; 145 /* Choose low frequency clock to control counter operation */ 146 config->clockSource = kPWM_LowFrequencyClock; 147 /* PWM clock devide by (config->prescale + 1) */ 148 config->prescale = 0U; 149 /* Output pin is set at rollover and cleared at comparison */ 150 config->outputConfig = kPWM_SetAtRolloverAndClearAtcomparison; 151 /* FIFO empty flag is set when there are more than or equal to 2 empty slots in FIFO */ 152 config->fifoWater = kPWM_FIFOWaterMark_2; 153 /* Use each sample once */ 154 config->sampleRepeat = kPWM_EachSampleOnce; 155 /* byte ordering remains the same */ 156 config->byteSwap = kPWM_ByteNoSwap; 157 /* Half word swapping does not take place */ 158 config->halfWordSwap = kPWM_HalfWordNoSwap; 159 } 160