knx/source/ti/drivers/pwm/PWMTimerCC26XX.h
Nanosonde e51b65f8c2 Squashed 'examples/knx-cc1310/coresdk_cc13xx_cc26xx/' content from commit 0d78d32
git-subtree-dir: examples/knx-cc1310/coresdk_cc13xx_cc26xx
git-subtree-split: 0d78d3280357416a5c0388148cda13717c9ffaa5
2020-10-21 10:00:49 +02:00

223 lines
9.4 KiB
C

/*
* Copyright (c) 2015-2019, Texas Instruments Incorporated
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* * Neither the name of Texas Instruments Incorporated nor the names of
* its contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
* THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
* EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
/*!*****************************************************************************
* @file PWMTimerCC26XX.h
* @brief PWM driver implementation for CC26XX/CC13XX
*
* # Overview #
* The general PWM API should be used in application code, i.e. PWM_open()
* should be used instead of PWMTimerCC26XX_open(). The board file will define the device
* specific config, and casting in the general API will ensure that the correct
* device specific functions are called.
*
* # General Behavior #
* Before using PWM on CC26XX:
* - The Timer HW is configured and system dependencies (for example IOs,
* power, etc.) are set by calling PWM_open().
*
* # Error handling #
* If unsupported arguments are provided to an API returning an error code, the
* PWM configuration will *not* be updated and PWM will stay in the mode it
* was already configured to.
*
* # Power Management #
* The TI-RTOS power management framework will try to put the device into the most
* power efficient mode whenever possible. Please see the technical reference
* manual for further details on each power mode.
*
* The PWMTimerCC26XX.h driver is not explicitly setting a power constraint when the
* PWM is running to prevent standby as this is assumed to be done in the
* underlying GPTimer driver.
* The following statements are valid:
* - After PWM_open(): The device is still allowed to enter Standby. When the
* device is active the underlying GPTimer peripheral will
* be enabled and clocked.
* - After PWM_start(): The device can only go to Idle power mode since the
* high-frequency clock is needed for PWM operation:
* - After PWM_stop(): Conditions are equal as for after PWM_open
* - After PWM_close(): The underlying GPTimer is turned off and the device
* is allowed to go to standby.
*
* # Accuracy #
* The PWM output period and duty cycle are limited by the underlying timer.
* In PWM mode the timer is effectively 24 bits which results in a minimum
* frequency of 48MHz / (2^24-1) = 2.86Hz (349.525ms)
* The driver will round off the configured duty and period to a value limited
* by the timer resolution and the application is responsible for selecting
* duty and period that works with the underlying timer if high accuracy is
* needed.
*
* The effect of this is most visible when using high output frequencies as the
* available duty cycle resolution is reduced correspondingly. For a 24MHz PWM
* only a 0%/50%/100% duty is available as the timer uses only counts 0 and 1.
* Similarly for a 12MHz period the duty cycle will be limited to a 12.5%
* resolution.
*
* @note The PWM signals are generated using the high-frequency clock as
* a source. The internal RC oscillator is the source of the high frequency
* clock, but may not be accurate enough for certain applications. If very
* high-accuracy outputs are needed, the application should request using
* the external HF crystal:
* @code
* #include <ti/drivers/Power.h>
* #include <ti/drivers/power/PowerCC26XX.h>
* Power_setDependency(PowerCC26XX_XOSC_HF);
* @endcode
*
* # Limitations #
* - The PWM output can currently not be synchronized with other PWM outputs
* - The PWM driver does not support updating duty and period using DMA.
* - Changes to the timer period are applied immediately, which can cause
* pulses to be too long or short unless period changes are applied close
* to a timeout. Does not apply to duty cycle, which is applied on timeout.
* # PWM usage #
*
* ## Basic PWM output ##
* The below example will output a 8MHz PWM signal with 50% duty cycle.
* @code
* PWM_Handle pwmHandle;
* PWM_Params params;
*
* PWM_Params_init(&params);
* params.idleLevel = PWM_IDLE_LOW;
* params.periodUnits = PWM_PERIOD_HZ;
* params.periodValue = 8e6;
* params.dutyUnits = PWM_DUTY_FRACTION;
* params.dutyValue = PWM_DUTY_FRACTION_MAX / 2;
*
* pwmHandle = PWM_open(Board_PWM0, &params);
* if(pwmHandle == NULL) {
* Log_error0("Failed to open PWM");
* Task_exit();
* }
* PWM_start(pwmHandle);
* @endcode
*
*
*******************************************************************************
*/
#ifndef ti_drivers_pwm__PWMTimerCC26XX_include
#define ti_drivers_pwm__PWMTimerCC26XX_include
#ifdef __cplusplus
extern "C" {
#endif
#include <stdint.h>
#include <stdbool.h>
#include <ti/drivers/PIN.h>
#include <ti/drivers/PWM.h>
#include <ti/drivers/timer/GPTimerCC26XX.h>
/*!
* @name PWMTimerCC26XX specific control commands and arguments
* @{
*/
/*! Timer debug stall mode (stop PWM output debugger halts CPU)
When enabled, PWM output will be HIGH when CPU is halted
*/
#define PWMTimerCC26XX_CMD_DEBUG_STALL PWM_CMD_RESERVED + 0 /*!< @hideinitializer */
/*!
* @name Arguments for PWMTimerCC26XX_CMD_DEBUG_STALL
* @{
*/
#define CMD_ARG_DEBUG_STALL_OFF (uint32_t)GPTimerCC26XX_DEBUG_STALL_OFF /*!< @hideinitializer */
#define CMD_ARG_DEBUG_STALL_ON (uint32_t)GPTimerCC26XX_DEBUG_STALL_ON /*!< @hideinitializer */
/* @} */
/* @} */
/* PWM function table pointer */
extern const PWM_FxnTable PWMTimerCC26XX_fxnTable;
/*!
* @brief PWMTimer26XX Hardware attributes
*
* These fields are used by the driver to set up underlying PIN and GPTimer
* driver statically. A sample structure is shown below:
*
* @code
* // PWM configuration, one per PWM output
* PWMTimerCC26XX_HwAttrs pwmtimerCC26xxHWAttrs[CC2650_PWMCOUNT] = {
* { .pwmPin = CC2650_LAUNCHXL_PWMPIN0, .gpTimerUnit = CC2650_LAUNCHXL_GPTIMER0A } ,
* { .pwmPin = CC2650_LAUNCHXL_PWMPIN1, .gpTimerUnit = CC2650_LAUNCHXL_GPTIMER0B } ,
* { .pwmPin = CC2650_LAUNCHXL_PWMPIN2, .gpTimerUnit = CC2650_LAUNCHXL_GPTIMER1A } ,
* { .pwmPin = CC2650_LAUNCHXL_PWMPIN3, .gpTimerUnit = CC2650_LAUNCHXL_GPTIMER1B } ,
* { .pwmPin = CC2650_LAUNCHXL_PWMPIN4, .gpTimerUnit = CC2650_LAUNCHXL_GPTIMER2A } ,
* { .pwmPin = CC2650_LAUNCHXL_PWMPIN5, .gpTimerUnit = CC2650_LAUNCHXL_GPTIMER2B } ,
* { .pwmPin = CC2650_LAUNCHXL_PWMPIN6, .gpTimerUnit = CC2650_LAUNCHXL_GPTIMER3A } ,
* { .pwmPin = CC2650_LAUNCHXL_PWMPIN7, .gpTimerUnit = CC2650_LAUNCHXL_GPTIMER3B } ,
* };
* @endcode
*/
typedef struct PWMTimerCC26XX_HwAttrs
{
PIN_Id pwmPin; /*!< PIN to output PWM signal on */
uint8_t gpTimerUnit; /*!< GPTimer unit index (0A, 0B, 1A..) */
} PWMTimerCC26XX_HwAttrs;
/*!
* @brief PWMTimer26XX Object
*
* These fields are used by the driver to store and modify PWM configuration
* during run-time.
* The application must not edit any member variables of this structure.
* Appplications should also not access member variables of this structure
* as backwards compatibility is not guaranteed.
* A sample structure is shown below:
* @code
* // PWM object, one per PWM output
* PWMTimerCC26XX_Object pwmtimerCC26xxObjects[CC2650_PWMCOUNT];
* @endcode
*/
typedef struct PWMTimerCC26XX_Object
{
bool isOpen; /*!< open flag used to check if PWM is opened */
bool isRunning; /*!< running flag, set if the output is active */
PWM_Period_Units periodUnit; /*!< Current period unit */
uint32_t periodValue; /*!< Current period value in unit */
uint32_t periodCounts; /*!< Current period in raw timer counts */
PWM_Duty_Units dutyUnit; /*!< Current duty cycle unit */
uint32_t dutyValue; /*!< Current duty cycle value in unit */
uint32_t dutyCounts; /*!< Current duty in raw timer counts */
PWM_IdleLevel idleLevel; /*!< PWM idle level when stopped / not started */
GPTimerCC26XX_Handle hTimer; /*!< Handle to underlying GPTimer peripheral */
} PWMTimerCC26XX_Object;
#ifdef __cplusplus
}
#endif
#endif /* ti_driver_pwm_PWMTimerCC26XX_include */