knx/examples/knx-cc1310/coresdk_cc13xx_cc26xx/source/ti/drivers/PWM.h
nanosonde d90843ba45
Add support for CC1310 platform based on SimpleLink SDK (#94)
* Initial commit

* Clean up

* Remove display code

* Change cmake build

* Add SimpleLink SDK for CC13xx/CC26xx as submodule

* Remove commented line from build.sh

* Working build

* Remove SDK submodule

* Squashed 'examples/knx-cc1310/coresdk_cc13xx_cc26xx/' content from commit 0d78d32

git-subtree-dir: examples/knx-cc1310/coresdk_cc13xx_cc26xx
git-subtree-split: 0d78d3280357416a5c0388148cda13717c9ffaa5

* Add more comments and enable Power_idleFunc() for NoRTOS variant.
Internal SDK driver functions which have to wait for something
will cause Power_idleFunc to be called instead of doing busy wait.

* Move CC1310 platform init around

* Optimize a bit more in debug build config as the binary does not fit into 128Kb flash otherwise.

* Explicitly list each source/header file in build config. Use linker group to resolve circular dependencies.

* Ignore vscode settings.json

* Increase stacks size

* Only compile CC1310 source code if #define DeviceFamily_CC13X0

* initial commit of CC1310 RF driver with first working RX version

* Better handling of buttonUp() across platforms

* Start cleanup

* continue cleanup

* Fix bau2920 compilation

* Continue cleanup

* Fix compilation in other examples

* Fix compilation

* htons() and ntohs() only for SAMD and STM32, but not for Linux and ESP8266 and ESP32

* htons(9 and ntohs() needed for CC13x0

* Continue cleanup

* Add CC1310 platform to CI

* Fix CI

* Use more recent toolchain from ARM

* Fix travis

* Use Ubuntu Focal

* Fix toolchain for travis

* Fix package name

* Fix toolchain

* Add libstdc++-dev package

* Add newlib packages

* Remove commented commands from CI

* Fix travis

* Fix compilation of knxPython

* Clean up linefeeds

* Fix RX callback

* Move RF CRC16-DNP to bits.cpp

* Fix TX

* Optimization: do not calc CRC for block1 again in rf_data_link_layer

* Make newline optional in printHex

* Cleanup. First working version: ETS5 programming of individual address via KNX/RF coupler.

* Use LEDs and Buttons to control ProgMode and Flash Erase

* Remove settings.json (VScode)

* Add README.md

* Update README.md

* Update README.md

* Fix typo
2020-11-10 21:52:38 +01:00

624 lines
21 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 PWM.h
* @brief Pulse Width Modulation (PWM) driver
*
* @anchor ti_drivers_PWM_Overview
* # Overview #
* The PWM driver in TI-RTOS facilitates the generation of Pulse Width
* Modulated signals via simple and portable APIs.
*
* When a PWM instance is opened, the period, duty cycle and idle level are
* configured and the PWM is stopped (waveforms not generated until PWM_start()
* is called). The maximum period and duty supported is device dependent;
* refer to the implementation specific documentation for values.
*
* PWM outputs are active-high, meaning the duty will control the duration of
* high output on the pin (at 0% duty, the output is always low, at 100% duty,
* the output is always high).
*
* <hr>
* @anchor ti_drivers_PWM_Usage
* # Usage
*
* This documentation provides a basic @ref ti_drivers_PWM_Synopsis
* "usage summary" and a set of @ref ti_drivers_PWM_Examples "examples"
* in the form of commented code fragments. Detailed descriptions of the
* APIs are provided in subsequent sections.
*
* @anchor ti_drivers_PWM_Synopsis
* ## Synopsis
* @anchor ti_drivers_PWM_Synopsis_Code
* @code
* // Import PWM Driver definitions
* #include <ti/drivers/PWM.h>
*
* PWM_Handle pwm;
* PWM_Params pwmParams;
* uint32_t dutyValue;
*
* // Initialize the PWM driver.
* PWM_init();
*
* // Initialize the PWM parameters
* PWM_Params_init(&pwmParams);
* pwmParams.idleLevel = PWM_IDLE_LOW; // Output low when PWM is not running
* pwmParams.periodUnits = PWM_PERIOD_HZ; // Period is in Hz
* pwmParams.periodValue = 1e6; // 1MHz
* pwmParams.dutyUnits = PWM_DUTY_FRACTION; // Duty is in fractional percentage
* pwmParams.dutyValue = 0; // 0% initial duty cycle
*
* // Open the PWM instance
* pwm = PWM_open(Board_PWM0, &pwmParams);
*
* if (pwm == NULL) {
* // PWM_open() failed
* while (1);
* }
*
* PWM_start(pwm); // start PWM with 0% duty cycle
*
* dutyValue = (uint32_t) (((uint64_t) PWM_DUTY_FRACTION_MAX * 37) / 100);
* PWM_setDuty(pwm, dutyValue); // set duty cycle to 37%
* @endcode
*
* <hr>
* @anchor ti_drivers_PWM_Examples
* # Examples
*
* @li @ref ti_drivers_PWM_Examples_open "Opening a PWM instance"
* @li @ref ti_drivers_PWM_Examples_duty "Setting PWM duty"
* @li @ref ti_drivers_PWM_Examples_dutyperiod "Setting PWM Duty and Period"
*
* @anchor ti_drivers_PWM_Examples_open
* # Opening a PWM instance
*
* @code
*
* PWM_Handle pwm;
* PWM_Params pwmParams;
*
* PWM_init();
*
* PWM_Params_init(&pwmParams);
* pwmParams.idleLevel = PWM_IDLE_LOW;
* pwmParams.periodUnits = PWM_PERIOD_HZ;
* pwmParams.periodValue = 1e6;
* pwmParams.dutyUnits = PWM_DUTY_FRACTION;
* pwmParams.dutyValue = 0;
*
* pwm = PWM_open(Board_PWM0, &pwmParams);
*
* if (pwm == NULL) {
* // PWM_open() failed
* while (1);
* }
* @endcode
*
* @anchor ti_drivers_PWM_Examples_duty
* # Setting PWM duty
*
* Once the PWM instance has been opened and started, the primary API used
* by the application will be #PWM_setDuty() to control the duty cycle of a
* PWM pin:
*
* Below demonstrates setting the duty cycle to 45%.
*
* @code
* uint32_t dutyCycle;
*
* dutyCycle = (uint32_t) (((uint64_t) PWM_DUTY_FRACTION_MAX * 45) / 100);
* PWM_setDuty(pwm, dutyCycle);
* @endcode
*
* @anchor ti_drivers_PWM_Examples_dutyperiod
* # Setting PWM Duty and Period
*
* If an application needs to modify the duty and period of a running timer,
* an API is available to set both with as little interim time as possible.
* This minimises the possibility that a timeout will occur between one set
* call and the other. For low periods or for instances close to timeout, this
* API will pause the instance output briefly and must only be called when the
* PWM is already running.
*
* Below demonstrates setting the duty cycle to 75% of the new period (100us).
*
* @code
* uint32_t dutyCycle;
* uint32_t periodUs = 100;
*
* dutyCycle = (uint32_t) (((uint64_t) PWM_DUTY_FRACTION_MAX * 75) / 100);
* PWM_setDutyAndPeriod(pwm, dutyCycle, periodUs);
* @endcode
*
* ### Modes of Operation #
*
* A PWM instance can be configured to interpret the period as one of three
* units:
* - #PWM_PERIOD_US: The period is in microseconds.
* - #PWM_PERIOD_HZ: The period is in (reciprocal) Hertz.
* - #PWM_PERIOD_COUNTS: The period is in timer counts.
*
* A PWM instance can be configured to interpret the duty as one of three
* units:
* - #PWM_DUTY_US: The duty is in microseconds.
* - #PWM_DUTY_FRACTION: The duty is in a fractional part of the period
* where 0 is 0% and #PWM_DUTY_FRACTION_MAX is 100%.
* - #PWM_DUTY_COUNTS: The period is in timer counts and must be less than
* the period.
*
* The idle level parameter is used to set the output to high/low when the
* PWM is not running (stopped or not started). The idle level can be
* set to:
* - #PWM_IDLE_LOW
* - #PWM_IDLE_HIGH
*
* The default PWM configuration is to set a duty of 0% with a 1MHz frequency.
* The default period units are in #PWM_PERIOD_HZ and the default duty units
* are in #PWM_DUTY_FRACTION. Finally, the default output idle level is
* #PWM_IDLE_LOW. It is the application's responsibility to set the duty for
* each PWM output used.
*
* <hr>
* @anchor ti_drivers_PWM_Configuration
* # Configuration
*
* Refer to the @ref driver_configuration "Driver's Configuration" section
* for driver configuration information.
* <hr>
*****************************************************************************
*/
#ifndef ti_drivers_PWM__include
#define ti_drivers_PWM__include
#include <stdint.h>
#ifdef __cplusplus
extern "C" {
#endif
/*!
* @brief Maximum duty (100%) when configuring duty cycle as a fraction of
* period.
*/
#define PWM_DUTY_FRACTION_MAX ((uint32_t) ~0)
/*!
* Common PWM_control command code reservation offset.
* PWM driver implementations should offset command codes with #PWM_CMD_RESERVED
* growing positively.
*
* Example implementation specific command codes:
* @code
* #define PWMXYZ_COMMAND0 (PWM_CMD_RESERVED + 0)
* #define PWMXYZ_COMMAND1 (PWM_CMD_RESERVED + 1)
* @endcode
*/
#define PWM_CMD_RESERVED (32)
/*!
* Common PWM_control status code reservation offset.
* PWM driver implementations should offset status codes with
* #PWM_STATUS_RESERVED growing negatively.
*
* Example implementation specific status codes:
* @code
* #define PWMXYZ_STATUS_ERROR0 (PWM_STATUS_RESERVED - 0)
* #define PWMXYZ_STATUS_ERROR1 (PWM_STATUS_RESERVED - 1)
* #define PWMXYZ_STATUS_ERROR2 (PWM_STATUS_RESERVED - 2)
* @endcode
*/
#define PWM_STATUS_RESERVED (-32)
/*!
* @brief Success status code returned by:
* #PWM_control(), #PWM_setDuty(), #PWM_setPeriod().
*
* Functions return #PWM_STATUS_SUCCESS if the call was executed
* successfully.
*/
#define PWM_STATUS_SUCCESS (0)
/*!
* @brief Generic error status code returned by #PWM_control().
*
* #PWM_control() returns #PWM_STATUS_ERROR if the control code was not executed
* successfully.
*/
#define PWM_STATUS_ERROR (-1)
/*!
* @brief An error status code returned by #PWM_control() for undefined
* command codes.
*
* #PWM_control() returns #PWM_STATUS_UNDEFINEDCMD if the control code is not
* recognized by the driver implementation.
*/
#define PWM_STATUS_UNDEFINEDCMD (-2)
/*!
* @brief An error status code returned by #PWM_setPeriod().
*
* #PWM_setPeriod() returns #PWM_STATUS_INVALID_PERIOD if the period argument is
* invalid for the current configuration.
*/
#define PWM_STATUS_INVALID_PERIOD (-3)
/*!
* @brief An error status code returned by #PWM_setDuty().
*
* #PWM_setDuty() returns #PWM_STATUS_INVALID_DUTY if the duty cycle argument is
* invalid for the current configuration.
*/
#define PWM_STATUS_INVALID_DUTY (-4)
/*!
* @brief PWM period unit definitions. Refer to device specific
* implementation if using #PWM_PERIOD_COUNTS (raw PWM/Timer counts).
*/
typedef enum {
PWM_PERIOD_US, /*!< Period in microseconds */
PWM_PERIOD_HZ, /*!< Period in (reciprocal) Hertz
(for example 2MHz = 0.5us period) */
PWM_PERIOD_COUNTS /*!< Period in timer counts */
} PWM_Period_Units;
/*!
* @brief PWM duty cycle unit definitions. Refer to device specific
* implementation if using PWM_DUTY_COUNTS (raw PWM/Timer counts).
*/
typedef enum {
PWM_DUTY_US, /*!< Duty cycle in microseconds */
PWM_DUTY_FRACTION, /*!< Duty as a fractional part of #PWM_DUTY_FRACTION_MAX.
* A duty cycle value of 0 will yield a 0% duty cycle
* while a duty cycle value of #PWM_DUTY_FRACTION_MAX
* will yield a duty cycle value of 100%. */
PWM_DUTY_COUNTS /*!< Duty in timer counts */
} PWM_Duty_Units;
/*!
* @brief Idle output level when PWM is not running (stopped / not started).
*/
typedef enum {
PWM_IDLE_LOW = 0,
PWM_IDLE_HIGH = 1,
} PWM_IdleLevel;
/*!
* @brief PWM Parameters
*
* PWM Parameters are used to with the PWM_open() call. Default values for
* these parameters are set using PWM_Params_init().
*
* @sa PWM_Params_init()
*/
typedef struct {
PWM_Period_Units periodUnits; /*!< Units in which the period is specified */
uint32_t periodValue; /*!< PWM initial period */
PWM_Duty_Units dutyUnits; /*!< Units in which the duty is specified */
uint32_t dutyValue; /*!< PWM initial duty */
PWM_IdleLevel idleLevel; /*!< Pin output when PWM is stopped. */
void *custom; /*!< Custom argument used by driver
implementation */
} PWM_Params;
/*!
* @brief A handle that is returned from a PWM_open() call.
*/
typedef struct PWM_Config_ *PWM_Handle;
/*!
* @brief A function pointer to a driver specific implementation of
* PWM_close().
*/
typedef void (*PWM_CloseFxn) (PWM_Handle handle);
/*!
* @brief A function pointer to a driver specific implementation of
* PWM_control().
*/
typedef int_fast16_t (*PWM_ControlFxn) (PWM_Handle handle, uint_fast16_t cmd,
void *arg);
/*!
* @brief A function pointer to a driver specific implementation of
* PWM_init().
*/
typedef void (*PWM_InitFxn) (PWM_Handle handle);
/*!
* @brief A function pointer to a driver specific implementation of
* PWM_open().
*/
typedef PWM_Handle (*PWM_OpenFxn) (PWM_Handle handle, PWM_Params *params);
/*!
* @brief A function pointer to a driver specific implementation of
* PWM_setDuty().
*/
typedef int_fast16_t (*PWM_SetDutyFxn) (PWM_Handle handle,
uint32_t duty);
/*!
* @brief A function pointer to a driver specific implementation of
* PWM_setPeriod().
*/
typedef int_fast16_t (*PWM_SetPeriodFxn) (PWM_Handle handle,
uint32_t period);
/*!
* @brief A function pointer to a driver specific implementation of
* PWM_setDutyAndPeriod().
*/
typedef int_fast16_t (*PWM_SetDutyAndPeriodFxn) (PWM_Handle handle,
uint32_t duty, uint32_t period);
/*!
* @brief A function pointer to a driver specific implementation of
* PWM_start().
*/
typedef void (*PWM_StartFxn) (PWM_Handle handle);
/*!
* @brief A function pointer to a driver specific implementation of
* PWM_stop().
*/
typedef void (*PWM_StopFxn) (PWM_Handle handle);
/*!
* @brief The definition of a PWM function table that contains the
* required set of functions to control a specific PWM driver
* implementation.
*/
typedef struct PWM_FxnTable_ {
/*! Function to close the specified instance */
PWM_CloseFxn closeFxn;
/*! Function to driver implementation specific control function */
PWM_ControlFxn controlFxn;
/*! Function to initialize the given data object */
PWM_InitFxn initFxn;
/*! Function to open the specified instance */
PWM_OpenFxn openFxn;
/*! Function to set the duty cycle for a specific instance */
PWM_SetDutyFxn setDutyFxn;
/*! Function to set the period for a specific instance */
PWM_SetPeriodFxn setPeriodFxn;
/*! Function to set the duty and the period for a specific instance */
PWM_SetDutyAndPeriodFxn setDutyAndPeriodFxn;
/*! Function to start the PWM output for a specific instance */
PWM_StartFxn startFxn;
/*! Function to stop the PWM output for a specific instance */
PWM_StopFxn stopFxn;
} PWM_FxnTable;
/*!
* @brief PWM Global configuration.
*
* The PWM_Config structure contains a set of pointers used to characterize
* the PWM driver implementation.
*
*/
typedef struct PWM_Config_ {
/*! Pointer to a table of driver-specific implementations of PWM APIs */
PWM_FxnTable const *fxnTablePtr;
/*! Pointer to a driver specific data object */
void *object;
/*! Pointer to a driver specific hardware attributes structure */
void const *hwAttrs;
} PWM_Config;
/*!
* @brief Function to close a PWM instance specified by the PWM handle.
*
* @pre PWM_open() must have been called first.
* @pre PWM_stop() must have been called first if PWM was started.
*
* @param[in] handle A PWM handle returned from PWM_open().
*
* @sa PWM_open()
* @sa PWM_start()
* @sa PWM_stop()
*/
extern void PWM_close(PWM_Handle handle);
/*!
* @brief Function performs implementation specific features on a given
* PWM_Handle.
*
* @pre PWM_open() must have been called first.
*
* @param[in] handle A PWM handle returned from PWM_open().
*
* @param[in] cmd A command value defined by the driver specific
* implementation.
*
* @param[in] arg A pointer to an optional R/W (read/write) argument that
* is accompanied with cmd.
*
* @retval #PWM_STATUS_SUCCESS The control call was successful.
* @retval #PWM_STATUS_ERROR The control call failed.
*
* @sa PWM_open()
*/
extern int_fast16_t PWM_control(PWM_Handle handle, uint_fast16_t cmd,
void *arg);
/*!
* @brief This function initializes the PWM module.
*
* @pre The PWM_config structure must exist and be persistent before this
* function can be called. This function must be called before any
* other PWM driver APIs. This function does not modify any peripheral
* registers & should only be called once.
*/
extern void PWM_init(void);
/*!
* @brief This function opens a given PWM instance and sets the period,
* duty and idle level to those specified in the params argument.
*
* @param[in] index Logical instance number for the PWM indexed into
* the PWM_config table.
*
* @param[in] params Pointer to an parameter structure. If NULL default
* values are used.
*
* @return A #PWM_Handle if successful or NULL on an error or if it has been
* opened already. If NULL is returned further PWM API calls will
* result in undefined behavior.
*
* @sa PWM_close()
*/
extern PWM_Handle PWM_open(uint_least8_t index, PWM_Params *params);
/*!
* @brief Function to initialize the PWM_Params structure to default values.
*
* @param[in] params A pointer to PWM_Params structure for initialization.
*
* Defaults values are:
* Period units: PWM_PERIOD_HZ
* Period: 1e6 (1MHz)
* Duty cycle units: PWM_DUTY_FRACTION
* Duty cycle: 0%
* Idle level: PWM_IDLE_LOW
*/
extern void PWM_Params_init(PWM_Params *params);
/*!
* @brief Function to set the duty cycle of the specified PWM handle. PWM
* instances run in active high output mode; 0% is always low output,
* 100% is always high output. This API can be called while the PWM
* is running & duty must always be lower than or equal to the period.
* If an error occurs while calling the function the PWM duty cycle
* will remain unchanged.
*
* @pre PWM_open() must have been called first.
*
* @param[in] handle A PWM handle returned from PWM_open().
*
* @param[in] duty Duty cycle in the units specified by the params used
* in PWM_open().
*
* @retval #PWM_STATUS_SUCCESS The duty was set successfully.
* @retval #PWM_STATUS_ERROR The duty was not set and remains unchanged.
*
* @sa PWM_open()
*/
extern int_fast16_t PWM_setDuty(PWM_Handle handle, uint32_t duty);
/*!
* @brief Function to set the period of the specified PWM handle. This API
* can be called while the PWM is running & the period must always be
* larger than the duty cycle.
* If an error occurs while calling the function the PWM period
* will remain unchanged.
*
* @pre PWM_open() must have been called first.
*
* @param[in] handle A PWM handle returned from PWM_open().
*
* @param[in] period Period in the units specified by the params used
* in PWM_open().
*
* @retval #PWM_STATUS_SUCCESS The period was set successfully.
* @retval #PWM_STATUS_ERROR The period was not set and remains unchanged.
*
* @sa PWM_open()
*/
extern int_fast16_t PWM_setPeriod(PWM_Handle handle, uint32_t period);
/*!
* @brief Function to set both the period and the duty cycle of the specified PWM handle.
* This API must be called while the PWM is running & the period must always be
* larger than the duty cycle.
* If an error occurs while calling the function the period and duty
* will remain unchanged.
*
* @note This API should only be called while the PWM is running.
*
* @note If the period is lower than a certain platform-specific amount, the output of the
* PWM timer may be paused to set these values. Some implementations may also pause
* the PWM if the remaining time before the next timeout is less than this value. This
* is to guard against an edge case where a timeout happens in between setting period
* and duty.
*
* @pre PWM_open() must have been called first.
*
* @param[in] handle A PWM handle returned from PWM_open().
*
* @param[in] duty Duty cycle in the units specified by the params used
* in PWM_open().
*
* @param[in] period Period in the units specified by the params used
* in PWM_open().
*
* @retval #PWM_STATUS_SUCCESS The duty and period was set successfully.
* @retval #PWM_STATUS_ERROR The duty and period was not set and
remains unchanged.
*
* @sa PWM_open()
*/
extern int_fast16_t PWM_setDutyAndPeriod(PWM_Handle handle, uint32_t duty, uint32_t period);
/*!
* @brief Function to start the specified PWM handle with current settings.
*
* @pre PWM_open() has to have been called first.
*
* @param[in] handle A PWM handle returned from PWM_open().
*
* @sa PWM_open()
* @sa PWM_stop()
*/
extern void PWM_start(PWM_Handle handle);
/*!
* @brief Function to stop the specified PWM handle. Output will set to the
* idle level specified by params in PWM_open().
*
* @pre PWM_open() has to have been called first.
*
* @param[in] handle A PWM handle returned from PWM_open().
*
* @sa PWM_open()
* @sa PWM_start()
*/
extern void PWM_stop(PWM_Handle handle);
#ifdef __cplusplus
}
#endif
#endif /* ti_drivers_PWM__include */