mirror of
https://github.com/thelsing/knx.git
synced 2025-10-12 11:15:54 +02:00
git-subtree-dir: examples/knx-cc1310/coresdk_cc13xx_cc26xx git-subtree-split: 0d78d3280357416a5c0388148cda13717c9ffaa5
223 lines
9.4 KiB
C
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(¶ms);
|
|
* 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, ¶ms);
|
|
* 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 */
|