blob: 90de0ee4b3e343ecb6a72b1e19ccd83390535d2d [file] [log] [blame]
/*
* Copyright (c) 2016, Freescale Semiconductor, Inc.
* Copyright 2016-2017 NXP
* All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#include "fsl_pwm.h"
/*******************************************************************************
* Definitions
******************************************************************************/
/* Component ID definition, used by tools. */
#ifndef FSL_COMPONENT_ID
#define FSL_COMPONENT_ID "platform.drivers.ipwm"
#endif
/*******************************************************************************
* Prototypes
******************************************************************************/
/*!
* @brief Get the instance from the base address
*
* @param base PWM peripheral base address
*
* @return The PWM module instance
*/
static uint32_t PWM_GetInstance(PWM_Type *base);
/*******************************************************************************
* Variables
******************************************************************************/
/*! @brief Pointers to PWM bases for each instance. */
static PWM_Type *const s_pwmBases[] = PWM_BASE_PTRS;
#if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL)
/* Array of PWM clock name. */
static const clock_ip_name_t s_pwmClock[] = PWM_CLOCKS;
#endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */
/*******************************************************************************
* Code
******************************************************************************/
static uint32_t PWM_GetInstance(PWM_Type *base)
{
uint32_t instance;
uint32_t pwmArrayCount = (sizeof(s_pwmBases) / sizeof(s_pwmBases[0]));
/* Find the instance index from base address mappings. */
for (instance = 0; instance < pwmArrayCount; instance++)
{
if (s_pwmBases[instance] == base)
{
break;
}
}
assert(instance < pwmArrayCount);
return instance;
}
/*!
* brief Ungates the PWM clock and configures the peripheral for basic operation.
*
* note This API should be called at the beginning of the application using the PWM driver.
*
* param base PWM peripheral base address
* param config Pointer to user's PWM config structure.
*
* return kStatus_Success means success; else failed.
*/
status_t PWM_Init(PWM_Type *base, const pwm_config_t *config)
{
assert(config);
#if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL)
/* Ungate PWM clock */
CLOCK_EnableClock(s_pwmClock[PWM_GetInstance(base)]);
#endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */
/* Setup the PWM operation */
base->PWMCR = (PWM_PWMCR_REPEAT(config->sampleRepeat) | PWM_PWMCR_PRESCALER(config->prescale) |
PWM_PWMCR_CLKSRC(config->clockSource) | PWM_PWMCR_POUTC(config->outputConfig) |
PWM_PWMCR_HCTR(config->halfWordSwap) | PWM_PWMCR_BCTR(config->byteSwap) |
PWM_PWMCR_STOPEN(config->enableStopMode) | PWM_PWMCR_DBGEN(config->enableDebugMode) |
PWM_PWMCR_WAITEN(config->enableWaitMode) | PWM_PWMCR_DOZEN(config->enableDozeMode) |
PWM_PWMCR_FWM(config->fifoWater));
return kStatus_Success;
}
/*!
* brief Gate the PWM submodule clock
*
* param base PWM peripheral base address
*/
void PWM_Deinit(PWM_Type *base)
{
/* Set clock source to none to disable counter */
base->PWMCR &= ~(PWM_PWMCR_CLKSRC_MASK);
#if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL)
/* Gate the PWM clock */
CLOCK_DisableClock(s_pwmClock[PWM_GetInstance(base)]);
#endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */
}
/*!
* brief Fill in the PWM config struct with the default settings
*
* The default values are:
* code
* config->enableStopMode = false;
* config->enableDozeMode = false;
* config->enableWaitMode = false;
* config->enableDozeMode = false;
* config->clockSource = kPWM_LowFrequencyClock;
* config->prescale = 0U;
* config->outputConfig = kPWM_SetAtRolloverAndClearAtcomparison;
* config->fifoWater = kPWM_FIFOWaterMark_2;
* config->sampleRepeat = kPWM_EachSampleOnce;
* config->byteSwap = kPWM_ByteNoSwap;
* config->halfWordSwap = kPWM_HalfWordNoSwap;
* endcode
* param config Pointer to user's PWM config structure.
*/
void PWM_GetDefaultConfig(pwm_config_t *config)
{
assert(config);
/* Initializes the configure structure to zero. */
(void)memset(config, 0, sizeof(*config));
/* Stop mode disabled */
config->enableStopMode = false;
/* Doze mode disabled */
config->enableDozeMode = false;
/* Wait mode disabled */
config->enableWaitMode = false;
/* Debug mode disabled */
config->enableDebugMode = false;
/* Choose low frequency clock to control counter operation */
config->clockSource = kPWM_LowFrequencyClock;
/* PWM clock devide by (config->prescale + 1) */
config->prescale = 0U;
/* Output pin is set at rollover and cleared at comparison */
config->outputConfig = kPWM_SetAtRolloverAndClearAtcomparison;
/* FIFO empty flag is set when there are more than or equal to 2 empty slots in FIFO */
config->fifoWater = kPWM_FIFOWaterMark_2;
/* Use each sample once */
config->sampleRepeat = kPWM_EachSampleOnce;
/* byte ordering remains the same */
config->byteSwap = kPWM_ByteNoSwap;
/* Half word swapping does not take place */
config->halfWordSwap = kPWM_HalfWordNoSwap;
}