feat: update CAN integration and T2G seat firmware

This commit is contained in:
vee
2026-08-01 15:55:21 +08:00
parent 8cda026ac2
commit 4aded5c21d
1443 changed files with 1007122 additions and 4978 deletions
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,524 @@
/***************************************************************************//**
* \file cy_adc.h
* \version 1.0
*
* \brief
* Provides an API declaration of the Adc driver
*
********************************************************************************
* \copyright
* Copyright 2016-2017, Cypress Semiconductor Corporation. All rights reserved.
* You may use this file only in accordance with the license, terms, conditions,
* disclaimers, and limitations in the end user license agreement accompanying
* the software package with which this file was provided.
*******************************************************************************/
/**
* \defgroup group_adc Analog to Digital Converter (ADC)
* \{
* The ADC driver provides an API to configure the ADC.
* The ADC has upto 4 ADC and upto 32 channel for each ADC module. About actual
* supported # or modules and channels, please refer to the technical reference
* manual (TRM) and device datasheet.
*
* \section group_adc_configuration Configuration Considerations
* Typical usage as is follows:
* - Call Cy_Adc_Init to initialize ADC module
* - Call Cy_Adc_Channel_Init to initialize a channel
* - Call Cy_Adc_Channel_SetInterruptMask if you need to use interrupt.
* After initialize channel(s) call Cy_Adc_Channel_Enable function then
* trigger by software (calling Cy_Adc_Channel_SoftwareTrigger) or start
* a peripheral that is configured for HW trigger.
* Note that if you use interrupt for ADC, you have to make interrupt handler
* and register it by using sysint module. In the handler, you can check
* which interrupt is occurred by Cy_Adc_Channel_GetInterruptMaskedStatus
* and can get conversion result by Cy_Adc_Channel_GetResult.
* If you don't use interrupt, you can poll conversion status by
* Cy_Adc_Channel_GetInterruptStatus.
* For both of polling and interrupt, clear interrupt flags by
* Cy_Adc_Channel_ClearInterruptStatus after handling data.
*
* \section group_adc_more_information More Information
*
* Refer to the technical reference manual (TRM) and the device datasheet.
*
* \section group_adc_changelog Changelog
* <table class="doxtable">
* <tr><th>Version</th><th>Changes</th><th>Reason for Change</th></tr>
* <tr>
* <td>1.0</td>
* <td>Initial version</td>
* <td></td>
* </tr>
* </table>
*
* \defgroup group_adc_macro Macro
* \defgroup group_adc_interrupt_sources Interrupt Sources
* \defgroup group_adc_ch_status Channel Status
* \defgroup group_adc_grp_status Group Status
* \defgroup group_adc_functions Functions
* \defgroup group_adc_data_structures Data structures
* \defgroup group_adc_enums Enumerated Types
* \defgroup group_adc_globals Global variables
*/
#if !defined(CY_ADC_H)
#define CY_ADC_H
#include <stdint.h>
#include <stdbool.h>
#include <stddef.h>
#include "syslib/cy_syslib.h"
#include "syspm/cy_syspm.h"
#include "cy_device_headers.h"
#if defined(__cplusplus)
extern "C" {
#endif
/***************************************
* Macro definitions
***************************************/
/**
* \addtogroup group_adc_macro
* \{
*/
/** Driver major version */
#define CY_ADC_DRV_VERSION_MAJOR 1
/** Driver minor version */
#define CY_ADC_DRV_VERSION_MINOR 0
/** Adc driver ID */
#define CY_ADC_ID CY_PDL_DRV_ID(0x36u)
/** \} group_adc_macro */
/***************************************
* Enumeration
***************************************/
/**
* \addtogroup group_adc_enums
* \{
*/
/**
* Adc Driver error codes
*/
typedef enum {
CY_ADC_SUCCESS = 0x00u, /**< Returned successful */
CY_ADC_BAD_PARAM = CY_ADC_ID | CY_PDL_STATUS_ERROR | 0x01u, /**< Bad parameter was passed */
} cy_en_adc_status_t;
/** When set use 2 cycles for the Most Significant Bit (MSB) */
typedef enum {
CY_ADC_MSB_STRETCH_MODE_1CYCLE = 0u, /**< Use 1 clock cycles per conversion. */
CY_ADC_MSB_STRETCH_MODE_2CYCLE = 1u /**< Use 2 clock cycles per conversion. */
} cy_en_adc_msb_stretch_mode_t;
/** Select Diagnostic Reference function. */
typedef enum {
CY_ADC_DIAG_REFERENCE_SELECT_VREFL = 0u, /**< DiagOut = VrefL */
CY_ADC_DIAG_REFERENCE_SELECT_VREFH_1DIV8 = 1u, /**< DiagOut = VrefH * 1/8 */
CY_ADC_DIAG_REFERENCE_SELECT_VREFH_2DIV8 = 2u, /**< DiagOut = VrefH * 2/8 */
CY_ADC_DIAG_REFERENCE_SELECT_VREFH_3DIV8 = 3u, /**< DiagOut = VrefH * 3/8 */
CY_ADC_DIAG_REFERENCE_SELECT_VREFH_4DIV8 = 4u, /**< DiagOut = VrefH * 4/8 */
CY_ADC_DIAG_REFERENCE_SELECT_VREFH_5DIV8 = 5u, /**< DiagOut = VrefH * 5/8 */
CY_ADC_DIAG_REFERENCE_SELECT_VREFH_6DIV8 = 6u, /**< DiagOut = VrefH * 6/8 */
CY_ADC_DIAG_REFERENCE_SELECT_VREFH_7DIV8 = 7u, /**< DiagOut = VrefH * 7/8 */
CY_ADC_DIAG_REFERENCE_SELECT_VREFH = 8u, /**< DiagOut = VrefH */
CY_ADC_DIAG_REFERENCE_SELECT_VREFX = 9u, /**< DiagOut = VrefX = VrefH * 199/200 */
CY_ADC_DIAG_REFERENCE_SELECT_VBG = 10u, /**< DiagOut = Vbg from SRSS */
CY_ADC_DIAG_REFERENCE_SELECT_VIN1 = 11u, /**< DiagOut = Vin1 */
CY_ADC_DIAG_REFERENCE_SELECT_VIN2 = 12u, /**< DiagOut = Vin2 */
CY_ADC_DIAG_REFERENCE_SELECT_VIN3 = 13u, /**< DiagOut = Vin3 */
CY_ADC_DIAG_REFERENCE_SELECT_I_SOURCE = 14u, /**< DiagOut = Isource (10uA) */
CY_ADC_DIAG_REFERENCE_SELECT_I_SINK = 15u /**< DiagOut = Isink (10uA) */
} cy_en_adc_diag_reference_select_t;
/** The ADC trigger mode selection. */
typedef enum {
CY_ADC_TRIGGER_OFF = 0u, /**< Use for channels in group, except the first channel */
CY_ADC_TRIGGER_TCPWM = 1u, /**< Trigger from corresponding TCPWM channel */
CY_ADC_TRIGGER_GENERIC0 = 2u, /**< Generic trigger input 0 */
CY_ADC_TRIGGER_GENERIC1 = 3u, /**< Generic trigger input 1 */
CY_ADC_TRIGGER_GENERIC2 = 4u, /**< Generic trigger input 2 */
CY_ADC_TRIGGER_GENERIC3 = 5u, /**< Generic trigger input 3 */
CY_ADC_TRIGGER_GENERIC4 = 6u, /**< Generic trigger input 4 */
CY_ADC_TRIGGER_CONTINUOUS = 7u /**< Always triggered (also called idle), can only be used for at most 1 channel */
} cy_en_adc_trigger_selection_t;
/** The ADC preemption type selection. */
typedef enum {
CY_ADC_PREEMPTION_ABORT_CANCEL = 0u, /**< Abort ongoing acquisition, do not return. */
CY_ADC_PREEMPTION_ABORT_RESTART = 1u, /**< Abort ongoing acquisition, up on return Restart group from first channel. */
CY_ADC_PREEMPTION_ABORT_RESUME = 2u, /**< Abort ongoing acquisition, up on return Resume group from aborted channel. */
CY_ADC_PREEMPTION_FINISH_RESUME = 3u /**< Complete ongoing acquisition (including averaging), up on return Resume group from next channel. */
} cy_en_adc_preemption_type_t;
/** Conversion done trigger output selection. */
typedef enum {
CY_ADC_DONE_LEVEL_PULSE = 0u, /**< Conversion done signal for other IPs is a 2 cycle pulse (clk_sys), no need to read the result regisgter.
Typically used for triggering another IPs other than DW. */
CY_ADC_DONE_LEVEL_LEVEL = 1u /**< Conversion done signal for other IPs is level output until result register is read.
Typically used for DW and also overflow detection. */
} cy_en_adc_done_level_t;
/** Address of the analog signal (pin) to be sampled by corresponding channel. */
typedef enum {
CY_ADC_PIN_ADDRESS_AN0 = 0u, /**< Vout = AN0, select corresponding analog input. */
CY_ADC_PIN_ADDRESS_AN1 = 1u,
CY_ADC_PIN_ADDRESS_AN2 = 2u,
CY_ADC_PIN_ADDRESS_AN3 = 3u,
CY_ADC_PIN_ADDRESS_AN4 = 4u,
CY_ADC_PIN_ADDRESS_AN5 = 5u,
CY_ADC_PIN_ADDRESS_AN6 = 6u,
CY_ADC_PIN_ADDRESS_AN7 = 7u,
CY_ADC_PIN_ADDRESS_AN8 = 8u,
CY_ADC_PIN_ADDRESS_AN9 = 9u,
CY_ADC_PIN_ADDRESS_AN10 = 10u,
CY_ADC_PIN_ADDRESS_AN11 = 11u,
CY_ADC_PIN_ADDRESS_AN12 = 12u,
CY_ADC_PIN_ADDRESS_AN13 = 13u,
CY_ADC_PIN_ADDRESS_AN14 = 14u,
CY_ADC_PIN_ADDRESS_AN15 = 15u,
CY_ADC_PIN_ADDRESS_AN16 = 16u,
CY_ADC_PIN_ADDRESS_AN17 = 17u,
CY_ADC_PIN_ADDRESS_AN18 = 18u,
CY_ADC_PIN_ADDRESS_AN19 = 19u,
CY_ADC_PIN_ADDRESS_AN20 = 20u,
CY_ADC_PIN_ADDRESS_AN21 = 21u,
CY_ADC_PIN_ADDRESS_AN22 = 22u,
CY_ADC_PIN_ADDRESS_AN23 = 23u,
CY_ADC_PIN_ADDRESS_AN24 = 24u,
CY_ADC_PIN_ADDRESS_AN25 = 25u,
CY_ADC_PIN_ADDRESS_AN26 = 26u,
CY_ADC_PIN_ADDRESS_AN27 = 27u,
CY_ADC_PIN_ADDRESS_AN28 = 28u,
CY_ADC_PIN_ADDRESS_AN29 = 29u,
CY_ADC_PIN_ADDRESS_AN30 = 30u,
CY_ADC_PIN_ADDRESS_AN31 = 31u,
CY_ADC_PIN_ADDRESS_VMOTOR = 32u, /**< Vout = Vmotor, select motor input. */
CY_ADC_PIN_ADDRESS_VAUX = 33u, /**< Vout = Vaux, select auxiliarly input. */
CY_ADC_PIN_ADDRESS_AMUXBUS_A = 34u, /**< Vout = AmuxbusA. */
CY_ADC_PIN_ADDRESS_AMUXBUS_B = 35u, /**< Vout = AmuxbusB. */
CY_ADC_PIN_ADDRESS_VCCD = 36u, /**< Vout = Vccd. */
CY_ADC_PIN_ADDRESS_VDDA = 37u, /**< Vout = Vdda. */
CY_ADC_PIN_ADDRESS_VBG = 38u, /**< Vout = Vbg, Bandgap voltage from SRSS. */
CY_ADC_PIN_ADDRESS_VTEMP = 39u, /**< Vout = Vtemp, select temperature sensor. Make sure that only 1 ADC is allowed to use this.. */
CY_ADC_PIN_ADDRESS_VREF_L = 62u, /**< Vout = VrefL (VrefL actually bypasses the SARMUX (XSL)). */
CY_ADC_PIN_ADDRESS_VREF_H = 63u /**< Vout = VrefH (VrefH actually bypasses the SARMUX (XSH)) */
} cy_en_adc_pin_address_t;
/** Select the physical port. This field is only valid for ADC0. */
typedef enum {
CY_ADC_PORT_ADDRESS_SARMUX0 = 0u, /**< ADC uses it's own SARMUX. */
CY_ADC_PORT_ADDRESS_SARMUX1 = 1u, /**< ADC0 uses SARMUX1 (only valid for ADC0, undefined result if used for ADC1-3). */
CY_ADC_PORT_ADDRESS_SARMUX2 = 2u, /**< ADC0 uses SARMUX2 (only valid for ADC0, undefined result if used for ADC1-3). */
CY_ADC_PORT_ADDRESS_SARMUX3 = 3u /**< ADC0 uses SARMUX3 (only valid for ADC0, undefined result if used for ADC1-3). */
} cy_en_adc_port_address_t;
/** Select preconditioning mode.
Preconditioning (dis)charges the SAR sample capacitor to the selected reference voltage for precondition time (global) cycles,
a break before make cycle will be inserted before sampling starts sample time.
See also \ref cy_stc_adc_config_t */
typedef enum {
CY_ADC_PRECONDITION_MODE_OFF = 0u, /**< No preconditioning. */
CY_ADC_PRECONDITION_MODE_VREFL = 1u, /**< Discharge to VREFL. */
CY_ADC_PRECONDITION_MODE_VREFH = 2u, /**< Charge to VREFH. */
CY_ADC_PRECONDITION_MODE_DIAG = 3u /**< Connect the Diagnostic reference output during preconditioning.
The Diagnostic reference should be configured to output a reference voltage. */
} cy_en_adc_precondition_mode_t;
/** Select Overlap mode or SARMUX Diagnostics, in both cases the Diagnostic reference is used. */
typedef enum {
CY_ADC_OVERLAP_DIAG_MODE_OFF = 0u, /**< No overlap or SARMUX Diagnostics. */
CY_ADC_OVERLAP_DIAG_MODE_HALF = 1u, /**< Sample the selected analog input for 2 sample time periods.
During the first period use overlap sampling,
i.e. connect both the analog input and Diagnostic reference.
During second period only connect the analog input */
CY_ADC_OVERLAP_DIAG_MODE_FULL = 2u, /**< Like normal sample the selected analog input for a single sample time period
but use overlap sampling, i.e. connect both the analog input and Diagnostic reference. */
CY_ADC_OVERLAP_DIAG_MODE_MUX_DIAG = 3u /**< Select Diagnostic reference instead of analog signal at the input of the SARMUX.
This enables a functional safety check of the SARMUX analog connections. */
} cy_en_adc_overlap_diag_mode_t;
/** Select calibration values. */
typedef enum {
CY_ADC_CALIBRATION_VALUE_REGULAR = 0u, /**< use regular calibration values */
CY_ADC_CALIBRATION_VALUE_ALTERNATE = 1u /**< use alternate calibration values */
} cy_en_adc_calibration_value_select_t;
/** Select post processing mode. */
typedef enum {
CY_ADC_POST_PROCESSING_MODE_NONE = 0u, /**< No postprocessing. */
CY_ADC_POST_PROCESSING_MODE_AVG = 1u, /**< Averaging. */
CY_ADC_POST_PROCESSING_MODE_AVG_RANGE = 2u, /**< Averaging followed by Range detect. */
CY_ADC_POST_PROCESSING_MODE_RANGE = 3u, /**< Range detect. */
CY_ADC_POST_PROCESSING_MODE_RANGE_PULSE = 4u, /**< Range detect followed by pulse detect. */
} cy_en_adc_post_processing_mode_t;
/** Select result data alignment. */
typedef enum {
CY_ADC_RESULT_ALIGNMENT_RIGHT = 0u, /**< the data is right aligned in result[11:0], with sign extension to 16 bits if enabled. */
CY_ADC_RESULT_ALIGNMENT_LEFT = 1u, /**< the data is left aligned in result[15:4] with the lower nibble 0.
Caveat if the result was more than 12 bits (e.g. after averaging)
then the bits above 12 will be discarded. */
} cy_en_adc_result_alignment_t;
/** Select whether result data is signed or unsigned. */
typedef enum {
CY_ADC_SIGN_EXTENTION_UNSIGNED = 0u, /**< Result data is unsigned (zero extended if needed). */
CY_ADC_SIGN_EXTENTION_SIGNED = 1u, /**< Result data is signed (sign extended if needed). */
} cy_en_adc_sign_extention_t;
/** Select range detection mode. */
typedef enum {
CY_ADC_RANGE_DETECTION_MODE_BELOW_LO = 0u, /**< Below Low threshold (result < Lo) */
CY_ADC_RANGE_DETECTION_MODE_INSIDE_RANGE = 1u, /**< Inside range (Lo <= result < Hi) */
CY_ADC_RANGE_DETECTION_MODE_ABOVE_HI = 2u, /**< Above high threshold (Hi <= result) */
CY_ADC_RANGE_DETECTION_MODE_OUTSIDE_RANGE = 3u /**< Outside range (result < Lo || Hi <= result) */
} cy_en_adc_range_detection_mode_t;
/** Select reference buffer mode. */
typedef enum {
CY_ADC_REF_BUF_MODE_OFF = 0u, /**< No reference mode selected */
CY_ADC_REF_BUF_MODE_ON = 1u, /**< Reference buffered Vbg from SRSS */
CY_ADC_REF_BUF_MODE_BYPASS = 3u, /**< Reference unbuffered Vbg from SRSS */
} cy_en_adc_ref_buf_mode_t;
/** \} group_adc_enums */
/***************************************
* Configuration Structure
***************************************/
/** Channel conversion status */
typedef struct
{
bool aboveHi; /**< If true out of range was detected and the value was above the Hi threshold */
bool rangeIntr; /**< If true range detected. */
bool pulseIntr; /**< If true pulse detected. */
bool valid; /**< If true result data is valid. */
} cy_stc_adc_ch_status_t;
/** Interrupt sources */
typedef struct
{
bool grpDone; /**< (Group) Done interrupt */
bool grpCancelled; /**< (Group) Cancelled Interrupt */
bool grpOverflow; /**< (Group) Overflow Interrupt */
bool chRange; /**< Range detect Interrupt */
bool chPulse; /**< Pulse detect Interrupt */
bool chOverflow; /**< Channel overflow Interrupt */
} cy_stc_adc_interrupt_source_t;
/** Group sources */
typedef struct
{
bool grpComplete; /**< Group acquisition complete. */
bool grpCancelled; /**< Group Cancelled. */
bool grpOverflow; /**< Group Overflow. */
bool chRangeComplete; /**< Channel Range complete. */
bool chPulseComplete; /**< Channel Pulse complete. */
bool chOverflow; /**< Channel Overflow. */
bool grpBusy; /**< Group acquisition busy. */
} cy_stc_adc_group_status_t;
/**
* \addtogroup group_adc_data_structures
* \{
*/
/** Configuration structure of a ADC */
typedef struct {
uint8_t preconditionTime; /**< Number ADC clock cycles that Preconditioning is done before the sample window starts. */
uint8_t powerupTime; /**< Number cycles to wait to power up after IDLE_PWRDWN. */
bool enableIdlePowerDown; /**< When idle automatically power down the analog if true. */
cy_en_adc_msb_stretch_mode_t msbStretchMode; /**< When set use 2 cycles for the Most Significant Bit (MSB), see \ref cy_en_adc_msb_stretch_mode_t */
bool enableHalfLsbConv; /**< When true take an extra cycle to convert the half LSB and add it to 12-bit result for Missing Code Recovery */
bool sarMuxEnable; /**< Enable the SARMUX (only valid if sarIpEnable = true). */
bool adcEnable; /**< Enable the SAR ADC and SAR sequencer (only valid if sarIpEnable = true). */
bool sarIpEnable; /**< Enable the SAR IP. */
} cy_stc_adc_config_t;
/** Configuration structure of a ADC channel */
typedef struct {
cy_en_adc_trigger_selection_t triggerSelection; /**< The ADC trigger mode selection, see \ref cy_en_adc_trigger_selection_t */
uint8_t channelPriority; /**< Channel priority. 0=highest, 7=lowest. Valid range = [0..7].*/
cy_en_adc_preemption_type_t preenptionType; /**< The ADC preemption type selection, see \ref cy_en_adc_preemption_type_t */
bool isGroupEnd; /**< This value indicates that this channel is the last channel of a group or not */
cy_en_adc_done_level_t doneLevel; /**< Conversion done trigger output selection, see \ref cy_en_adc_done_level_t */
cy_en_adc_pin_address_t pinAddress; /**< Address of the analog signal (pin) to be sampled by corresponding channel,
* see \ref cy_en_adc_pin_address_t
*/
cy_en_adc_port_address_t portAddress; /**< Select the physical port, see \ref cy_en_adc_port_address_t */
uint8_t extMuxSelect; /**< External analog mux select. */
bool extMuxEnable; /**< External analog mux enable. */
cy_en_adc_precondition_mode_t preconditionMode; /**< Select preconditioning mode, see \ref cy_en_adc_precondition_mode_t */
cy_en_adc_overlap_diag_mode_t overlapDiagMode; /**< Select Overlap mode or SARMUX Diagnostics, see \ref cy_en_adc_overlap_diag_mode_t */
uint16_t sampleTime; /**< Sample time (aperture) in ADC clock cycles. Minimum is 1 (0 gives the same result as 1),
* minimum time needed for proper settling is at least 300ns,
* i.e. 6 clock cycles at the max frequency of 20MHz.
*/
cy_en_adc_calibration_value_select_t calibrationValueSelect; /**< Select calibration values, see \ref cy_en_adc_calibration_value_select_t */
cy_en_adc_post_processing_mode_t postProcessingMode; /**< Select post processing mode, see \ref cy_en_adc_post_processing_mode_t */
cy_en_adc_result_alignment_t resultAlignment; /**< Select result data alignment, see \ref cy_en_adc_result_alignment_t */
cy_en_adc_sign_extention_t signExtention; /**< Select whether result data is signed or unsigned, see \ref cy_en_adc_sign_extention_t */
uint8_t averageCount; /**< Either averaging count (minus 1) or Pulse positive reload value. */
uint8_t rightShift; /**< Either Shift Right (no pulse detection) or Pulse nagative reload value (if pulse detection is enabled).
* When using other than pulse detection, setting value is used for right shift value of the
* conversion result. Typically it is used for the averaging. Averaging data may be over 12bits,
* therefore user must ensure conversion result not to over 12bits by using this value.
* This value is also used to fit the 12-bit result in 8bits.
* When using other than pulse detection, valid range is [0..12].
* In pulse detection mode this value is used as negative reload value.
*/
cy_en_adc_range_detection_mode_t rangeDetectionMode; /**< Select range detection mode, see \ref cy_en_adc_range_detection_mode_t */
uint16_t rangeDetectionLoThreshold; /**< Range detect low threshold (Lo) */
uint16_t rangeDetectionHiThreshold; /**< Range detect high threshold (Hi) */
cy_stc_adc_interrupt_source_t mask; /**< Select the interrupt sources. \ref cy_stc_adc_interrupt_source_t */
} cy_stc_adc_channel_config_t;
/** Digital calibration values. */
typedef struct {
uint16_t offset; /**< Digital offset correction. Valid range is [0..4096] */
uint8_t gain; /**< Digital gain correction. Valid range is [0..63] */
} cy_stc_adc_digital_calibration_conifg_t;
/** Analog calibration values. */
typedef struct {
int8_t offset; /**< Analog offset correction. Valid range is [0..255] */
int8_t gain; /**< Analog gain correction. Valid range is [0..31] */
} cy_stc_adc_analog_calibration_conifg_t;
/** Configuration structure of diagnosis function. */
typedef struct {
cy_en_adc_diag_reference_select_t referenceSelect; /**< Select Diagnostic Reference function, see \ref cy_en_adc_diag_reference_select_t */
} cy_stc_adc_diag_config_t;
/** Control freeze feature for debugging. */
typedef struct {
bool enableFreezeAdc0; /**< If true, freeze ADC0 in debug mode. */
bool enableFreezeAdc1; /**< If true, freeze ADC1 in debug mode. */
bool enableFreezeAdc2; /**< If true, freeze ADC2 in debug mode. */
bool enableFreezeAdc3; /**< If true, freeze ADC3 in debug mode. */
} cy_stc_adc_debug_freeze_config_t;
/** ADC temp sensor data values structure read form SFLASH */
typedef struct {
double hotValue; /**< Pass the hot temperature reading */
double roomValue; /**< Pass the room temperature reading */
double coldValue; /**< Pass the cold temperature reading */
} cy_en_adc_temp_sflash_data_t;
/** ADC ref data values structure read form SFLASH */
typedef struct {
cy_en_adc_temp_sflash_data_t adcVbgValues; /**< Pass the Vbg read value from SFLASH */
cy_en_adc_temp_sflash_data_t adcTempValues; /**< Pass the sort data values from SFLASH */
cy_en_adc_temp_sflash_data_t adcDiodeValues; /**< Pass the class data values from SFLASH */
} cy_stc_adc_temp_ref_t;
/** ADC raw data values structure of a temperature calculation */
typedef struct {
uint16_t adcVtempRawValue; /**< Enable the SAR Channel VTEMP, and update the value */
uint16_t adcVbgRawValue; /**< Enable the SAR Channel VBG, and update the value */
} cy_stc_adc_temp_raw_t;
/** \} group_adc_data_structures */
/***************************************
* Global Variable
***************************************/
/* N/A */
/***************************************
* Constants
***************************************/
/** \cond INTERNAL */
/** \endcond */
/***************************************
* Function Prototypes
***************************************/
/**
* \addtogroup group_adc_functions
* \{
*/
/* For each ADC */
cy_en_adc_status_t Cy_Adc_Init(volatile stc_PASS_SAR_t * base, const cy_stc_adc_config_t * config);
void Cy_Adc_DeInit(volatile stc_PASS_SAR_t * base);
uint32_t Cy_Adc_GetPendingStatus(const volatile stc_PASS_SAR_t * base);
uint32_t Cy_Adc_GetWorkValidStatus(const volatile stc_PASS_SAR_t * base);
uint32_t Cy_Adc_GetWorkRangeStatus(const volatile stc_PASS_SAR_t * base);
uint32_t Cy_Adc_GetWorkRangeHiStatus(const volatile stc_PASS_SAR_t * base);
uint32_t Cy_Adc_GetWorkPulseStatus(const volatile stc_PASS_SAR_t * base);
uint32_t Cy_Adc_GetResultValidStatus(const volatile stc_PASS_SAR_t * base);
uint32_t Cy_Adc_GetResultRangeHiStatus(const volatile stc_PASS_SAR_t * base);
/* For each channels */
cy_en_adc_status_t Cy_Adc_Channel_Init(volatile stc_PASS_SAR_CH_t * base, const cy_stc_adc_channel_config_t * config);
void Cy_Adc_Channel_DeInit(volatile stc_PASS_SAR_CH_t * base);
void Cy_Adc_Channel_Enable(volatile stc_PASS_SAR_CH_t * base);
void Cy_Adc_Channel_Disable(volatile stc_PASS_SAR_CH_t * base);
void Cy_Adc_Channel_SoftwareTrigger(volatile stc_PASS_SAR_CH_t * base);
cy_en_adc_status_t Cy_Adc_Channel_GetResult(const volatile stc_PASS_SAR_CH_t * base, uint16_t * result, cy_stc_adc_ch_status_t * status);
cy_en_adc_status_t Cy_Adc_Channel_GetWorkingData(const volatile stc_PASS_SAR_CH_t * base, uint16_t * result, cy_stc_adc_ch_status_t * status);
cy_en_adc_status_t Cy_Adc_Channel_GetGroupStatus(const volatile stc_PASS_SAR_CH_t * base, cy_stc_adc_group_status_t * status);
cy_en_adc_status_t Cy_Adc_Channel_SetInterruptMask(volatile stc_PASS_SAR_CH_t * base, const cy_stc_adc_interrupt_source_t * mask);
cy_en_adc_status_t Cy_Adc_Channel_GetInterruptMask(const volatile stc_PASS_SAR_CH_t * base, cy_stc_adc_interrupt_source_t * mask);
cy_en_adc_status_t Cy_Adc_Channel_ClearInterruptStatus(volatile stc_PASS_SAR_CH_t * base, const cy_stc_adc_interrupt_source_t * source);
cy_en_adc_status_t Cy_Adc_Channel_GetInterruptStatus(const volatile stc_PASS_SAR_CH_t * base, cy_stc_adc_interrupt_source_t * status);
cy_en_adc_status_t Cy_Adc_Channel_GetInterruptMaskedStatus(const volatile stc_PASS_SAR_CH_t * base, cy_stc_adc_interrupt_source_t * status);
/* For diagnosis function */
cy_en_adc_status_t Cy_Adc_Diag_Init(volatile stc_PASS_SAR_t * base, const cy_stc_adc_diag_config_t * config);
void Cy_Adc_Diag_Enable(volatile stc_PASS_SAR_t * base);
void Cy_Adc_Diag_Disable(volatile stc_PASS_SAR_t * base);
/* For calibration */
void Cy_Adc_TriggerCalibrationUpdate(volatile stc_PASS_SAR_t * base);
bool Cy_Adc_IsCalibrationUpdateDone(const volatile stc_PASS_SAR_t * base);
cy_en_adc_status_t Cy_Adc_SetDigitalCalibrationValue(volatile stc_PASS_SAR_t * base, const cy_stc_adc_digital_calibration_conifg_t * config);
cy_en_adc_status_t Cy_Adc_GetDigitalCalibrationValue(const volatile stc_PASS_SAR_t * base, cy_stc_adc_digital_calibration_conifg_t * config);
cy_en_adc_status_t Cy_Adc_SetAltDigitalCalibrationValue(volatile stc_PASS_SAR_t * base, const cy_stc_adc_digital_calibration_conifg_t * config);
cy_en_adc_status_t Cy_Adc_GetAltDigitalCalibrationValue(const volatile stc_PASS_SAR_t * base, cy_stc_adc_digital_calibration_conifg_t * config);
cy_en_adc_status_t Cy_Adc_SetAnalogCalibrationValue(volatile stc_PASS_SAR_t * base, cy_stc_adc_analog_calibration_conifg_t * config);
cy_en_adc_status_t Cy_Adc_GetAnalogCalibrationValue(const volatile stc_PASS_SAR_t * base, cy_stc_adc_analog_calibration_conifg_t * config);
cy_en_adc_status_t Cy_Adc_SetAltAnalogCalibrationValue(volatile stc_PASS_SAR_t * base, cy_stc_adc_analog_calibration_conifg_t * config);
cy_en_adc_status_t Cy_Adc_GetAltAnalogCalibrationValue(const volatile stc_PASS_SAR_t * base, cy_stc_adc_analog_calibration_conifg_t * config);
/* For debugging */
cy_en_adc_ref_buf_mode_t Cy_Adc_GetReferenceBufferMode(volatile stc_PASS_EPASS_MMIO_t * base);
void Cy_Adc_SetReferenceBufferMode(volatile stc_PASS_EPASS_MMIO_t * base, cy_en_adc_ref_buf_mode_t mode);
cy_en_adc_status_t Cy_Adc_SetDebugFreezeMode(volatile stc_PASS_EPASS_MMIO_t * base, const cy_stc_adc_debug_freeze_config_t * config);
/* For SAR general trigger input / output trigger setting */
cy_en_adc_status_t Cy_Adc_SetGenericTriggerInput(volatile stc_PASS_EPASS_MMIO_t * base, uint8_t numOfAdc, uint8_t triggerInputNumber, uint8_t genericTriggerValue);
cy_en_adc_status_t Cy_Adc_SetGenericOutpuTrigger(volatile stc_PASS_EPASS_MMIO_t * base, uint8_t numOfAdc, uint8_t outputTriggerNumber, uint8_t genericTriggerValue);
/* For temperature measurements */
double Cy_Adc_CalculateDieTemperature(cy_stc_adc_temp_ref_t *refValue, cy_stc_adc_temp_raw_t *rawValue);
/** \} group_adc_functions */
#if defined(__cplusplus)
}
#endif
#endif /* CY_ADC_H */
/** \} group_adc */
/* [] END OF FILE */
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,915 @@
/***************************************************************************//**
* \file cy_canfd.h
* \version 1.0
*
* \brief
* Provides an API declaration of the CAN FD driver
*
********************************************************************************
* \copyright
* Copyright 2016-2017, Cypress Semiconductor Corporation. All rights reserved.
* You may use this file only in accordance with the license, terms, conditions,
* disclaimers, and limitations in the end user license agreement accompanying
* the software package with which this file was provided.
*******************************************************************************/
/**
* \defgroup CanFDGroup CAN with Flexible Data rate (CAN FD)
* \{
* \brief This section describes the interface for the CAN with Flexible Data rate.
*
* Provided functions of CAN FD module:
* - Cy_CANFD_Init() (Initialization of CAN FD module)
* - Cy_CANFD_UpdateAndTransmitMsgBuffer() (Used to update the data in a message buffer and to transmit a message)
* - Cy_CANFD_DeInit() (Deinitialization of CAN FD module)
* - Cy_CANFD_GetTxBufferStatus() (Used to retreive the Tx message buffer status)
*
* \brief How to use the CAN FD module:
* First, to initialise a CAN FD module, Cy_CANFD_Init() must be called.
* Initialize the CAN FD module with the configuration parameters, and start
* the CAN FD communication.
* The callback functions are optional, but recommended, otherwise there is no
* report to the API in case of any error and transmission/reception.
*
* For transmitting CAN FD messages the function CanFD_UpdateAndTransmitMsgBuffer()
* has to be used. The buffer status can be retreived by Cy_CANFD_GetTxBufferStatus().
* It is possible to set a callback function which will be notified whenever a
* message has been received.
*
* \description
* Specification of sample software is as follows:
* - Selectable CAN-FD mode or CAN mode.
* - Configurable CAN clock
* - Configurable CAN Bit rate
* - Configurable CAN-FD Bit rate
* - Configurable Standard ID filter/s
* - Configurable Extended Message ID Filter/s
* - Tx/Rx Element Size : 8 byte (CAN mode)
* Tx/Rx Element Size : 64 byte (CAN-FD mode)
* - Tx/Rx FIFO : Not used
* - Interrupt : DRXE=1 (Message stored to Dedicated Rx Buffer)
* (Inactive other)
*
* Send data of ID:0x200 periodically in the main().
* Echoback by incrementing the ID of the Rx data received by
* the receiving interrupt.(CanFDIrqHandler() --- CanFDCallbackRx())
*
* \note Following settings are not implemented.
* - Using Tx/warning/error interrupt
* - Using Tx/Rx FIFO
*
*/
#if !defined(CY_CANFD_H)
#define CY_CANFD_H
#include <stddef.h>
#include "syslib/cy_syslib.h"
#include "cy_device_headers.h"
#include "canfd/cy_canfd_config.h"
#if defined(__cplusplus)
extern "C" {
#endif
/** \addtogroup group_canfd_macro
* \{
*/
/** Driver major version */
#define CY_CANFD_DRV_VERSION_MAJOR 1
/** Driver minor version */
#define CY_CANFD_DRV_VERSION_MINOR 0
/** CANFD driver ID */
#define CY_CANFD_ID CY_PDL_DRV_ID(0x18u)
/** \} group_canfd_macro */
/***************************************
* Constants
***************************************/
/** Size of Word data bytes in a receive or transmit operation (16word = 64byte) */
#define CY_CANFD_MESSAGE_DATA_BUFFER_SIZE 16
/** Rx FIFO Numbers */
#define CY_CANFD_RX_FIFO0 0
#define CY_CANFD_RX_FIFO1 1
#define CY_CANFD_MSGRAM_START (0x00010000ul)
/**
******************************************************************************
** \brief The macro for configuration the standard ID filter to store RX buffer.
** If RxId fulfills the following condition, RxId matches in this filter.
** Id == RxId
** When the RxId matches the condition, the message will be store into a rx buffer
** that specified by RxBuffIdx.
******************************************************************************/
#define CANFD_CONFIG_STD_ID_FILTER_CLASSIC_RXBUFF(Id, RxBuffIdx) \
{ \
.sfid2 = (0u << 9u) | (uint32_t)(RxBuffIdx), \
.sfid1 = (uint32_t)(Id), \
.sfec = (uint32_t)CY_CANFD_ID_FILTER_ELEMNT_CONFIG_STORE_RXBUFF_OR_DEBUGMSG, \
.sft = (uint32_t)CY_CANFD_STD_ID_FILTER_TYPE_CLASSIC, \
}
/**
******************************************************************************
** \brief The macro for configuration the standard ID filter as the classic filter.
** If RxId fulfills the following condition, RxId matches in this filter.
** (Id & IdMask) == (RxId & IdMask)
** When the RxId matches the condition, the message will be treated in accordance
** with ElementConfig.
** ElementConfig can be selected from following definitions:
** - CY_CANFD_ID_FILTER_ELEMNT_CONFIG_STORE_RXFIFO0
** - CY_CANFD_ID_FILTER_ELEMNT_CONFIG_STORE_RXFIFO1
** - CY_CANFD_ID_FILTER_ELEMNT_CONFIG_REJECT_ID
** - CY_CANFD_ID_FILTER_ELEMNT_CONFIG_SET_PRIORIY
** - CY_CANFD_ID_FILTER_ELEMNT_CONFIG_SET_PIORITY_STORE_RXFIFO0
** - CY_CANFD_ID_FILTER_ELEMNT_CONFIG_SET_PIORITY_STORE_RXFIFO1
******************************************************************************/
#define CANFD_CONFIG_STD_ID_FILTER_CLASSIC(Id, IdMask, ElementConfig) \
{ \
.sfid2 = (uint32_t)(IdMask), \
.sfid1 = (uint32_t)(Id), \
.sfec = (uint32_t)(ElementConfig), \
.sft = (uint32_t)CY_CANFD_STD_ID_FILTER_TYPE_CLASSIC, \
}
/**
******************************************************************************
** \brief The macro for configuration the standard ID filter as the range filter.
** If RxId fulfills the following condition, RxId matches in this filter.
** MinId <= RxId <= MaxId
** When the RxId matches the condition, the message will be treated in accordance
** with ElementConfig.
** ElementConfig can be selected from following definitions:
** - CY_CANFD_ID_FILTER_ELEMNT_CONFIG_STORE_RXFIFO0
** - CY_CANFD_ID_FILTER_ELEMNT_CONFIG_STORE_RXFIFO1
** - CY_CANFD_ID_FILTER_ELEMNT_CONFIG_REJECT_ID
** - CY_CANFD_ID_FILTER_ELEMNT_CONFIG_SET_PRIORIY
** - CY_CANFD_ID_FILTER_ELEMNT_CONFIG_SET_PIORITY_STORE_RXFIFO0
** - CY_CANFD_ID_FILTER_ELEMNT_CONFIG_SET_PIORITY_STORE_RXFIFO1
******************************************************************************/
#define CANFD_CONFIG_STD_ID_FILTER_RANGE(MinId, MaxId, ElementConfig) \
{ \
.sfid2 = (uint32_t)(MaxId), \
.sfid1 = (uint32_t)(MinId), \
.sfec = (uint32_t)(ElementConfig), \
.sft = (uint32_t)CY_CANFD_STD_ID_FILTER_TYPE_RANGE, \
}
/**
******************************************************************************
** \brief The macro for configuration the standard ID filter as the dual filter.
** If RxId fulfills the following condition, RxId matches in this filter.
** Id1 == RxId
** OR
** Id2 == RxId
** When the RxId matches the condition, the message will be treated in accordance
** with ElementConfig.
** ElementConfig can be selected from following definitions:
** - CY_CANFD_ID_FILTER_ELEMNT_CONFIG_STORE_RXFIFO0
** - CY_CANFD_ID_FILTER_ELEMNT_CONFIG_STORE_RXFIFO1
** - CY_CANFD_ID_FILTER_ELEMNT_CONFIG_REJECT_ID
** - CY_CANFD_ID_FILTER_ELEMNT_CONFIG_SET_PRIORIY
** - CY_CANFD_ID_FILTER_ELEMNT_CONFIG_SET_PIORITY_STORE_RXFIFO0
** - CY_CANFD_ID_FILTER_ELEMNT_CONFIG_SET_PIORITY_STORE_RXFIFO1
******************************************************************************/
#define CANFD_CONFIG_STD_ID_FILTER_DUAL(Id1, Id2, ElementConfig) \
{ \
.sfid2 = (uint32_t)(Id2), \
.sfid1 = (uint32_t)(Id1), \
.sfec = (uint32_t)(ElementConfig), \
.sft = (uint32_t)CY_CANFD_STD_ID_FILTER_TYPE_DUAL, \
}
/**
******************************************************************************
** \brief The macro for configuration the extended ID filter to store RX buffer.
** If RxId fulfills the following condition, RxId matches in this filter.
** Id == (RxId & extIDANDMask)
** When the RxId matches the condition, the message will be store into a rx buffer
** that specified by RxBuffIdx.
******************************************************************************/
#define CANFD_CONFIG_EXT_ID_FILTER_CLASSIC_RXBUFF(Id, RxBuffIdx) \
{ \
.f0_f = \
{ \
.efid1 = (uint32_t)(Id), \
.efec = (uint32_t)CY_CANFD_ID_FILTER_ELEMNT_CONFIG_STORE_RXBUFF_OR_DEBUGMSG, \
}, \
.f1_f = \
{ \
.efid2 = (0u << 9u) | (uint32_t)(RxBuffIdx), \
.eft = (uint32_t)CY_CANFD_EXT_ID_FILTER_TYPE_CLASSIC, \
}, \
}
/**
******************************************************************************
** \brief The macro for configuration the extended ID filter as the classic filter.
** If RxId fulfills the following condition, RxId matches in this filter.
** (Id & IdMask) == ((RxId & extIDANDMask) & IdMask)
** When the RxId matches the condition, the message will be treated in accordance
** with ElementConfig.
** ElementConfig can be selected from following definitions:
** - CY_CANFD_ID_FILTER_ELEMNT_CONFIG_STORE_RXFIFO0
** - CY_CANFD_ID_FILTER_ELEMNT_CONFIG_STORE_RXFIFO1
** - CY_CANFD_ID_FILTER_ELEMNT_CONFIG_REJECT_ID
** - CY_CANFD_ID_FILTER_ELEMNT_CONFIG_SET_PRIORIY
** - CY_CANFD_ID_FILTER_ELEMNT_CONFIG_SET_PIORITY_STORE_RXFIFO0
** - CY_CANFD_ID_FILTER_ELEMNT_CONFIG_SET_PIORITY_STORE_RXFIFO1
******************************************************************************/
#define CANFD_CONFIG_EXT_ID_FILTER_CLASSIC(Id, IdMask, ElementConfig) \
{ \
.f0_f = \
{ \
.efid1 = (uint32_t)(Id), \
.efec = (uint32_t)(ElementConfig), \
}, \
.f1_f = \
{ \
.efid2 = (uint32_t)(IdMask), \
.eft = (uint32_t)CY_CANFD_EXT_ID_FILTER_TYPE_CLASSIC, \
}, \
}
/**
******************************************************************************
** \brief The macro for configuration the extended ID filter as the range filter.
** If RxId fulfills the following condition, RxId matches in this filter.
** MinId <= RxId <= MaxId
** When the RxId matches the condition, the message will be treated in accordance
** with ElementConfig.
** ElementConfig can be selected from following definitions:
** - CY_CANFD_ID_FILTER_ELEMNT_CONFIG_STORE_RXFIFO0
** - CY_CANFD_ID_FILTER_ELEMNT_CONFIG_STORE_RXFIFO1
** - CY_CANFD_ID_FILTER_ELEMNT_CONFIG_REJECT_ID
** - CY_CANFD_ID_FILTER_ELEMNT_CONFIG_SET_PRIORIY
** - CY_CANFD_ID_FILTER_ELEMNT_CONFIG_SET_PIORITY_STORE_RXFIFO0
** - CY_CANFD_ID_FILTER_ELEMNT_CONFIG_SET_PIORITY_STORE_RXFIFO1
******************************************************************************/
#define CANFD_CONFIG_EXT_ID_FILTER_RANGE(MinId, MaxId, ElementConfig) \
{ \
.f0_f = \
{ \
.efid1 = (uint32_t)(MinId), \
.efec = (uint32_t)(ElementConfig), \
}, \
.f1_f = \
{ \
.efid2 = (uint32_t)(MaxId), \
.eft = (uint32_t)CY_CANFD_EXT_ID_FILTER_TYPE_RANGE \
}, \
}
/**
******************************************************************************
** \brief The macro for configuration the extended ID filter as the range and mask filter.
** If RxId fulfills the following condition, RxId matches in this filter.
** MinId <= (RxId & extIDANDMask) <= MaxId
** When the RxId matches the condition, the message will be treated in accordance
** with ElementConfig.
** ElementConfig can be selected from following definitions:
** - CY_CANFD_ID_FILTER_ELEMNT_CONFIG_STORE_RXFIFO0
** - CY_CANFD_ID_FILTER_ELEMNT_CONFIG_STORE_RXFIFO1
** - CY_CANFD_ID_FILTER_ELEMNT_CONFIG_REJECT_ID
** - CY_CANFD_ID_FILTER_ELEMNT_CONFIG_SET_PRIORIY
** - CY_CANFD_ID_FILTER_ELEMNT_CONFIG_SET_PIORITY_STORE_RXFIFO0
** - CY_CANFD_ID_FILTER_ELEMNT_CONFIG_SET_PIORITY_STORE_RXFIFO1
******************************************************************************/
#define CANFD_CONFIG_EXT_ID_FILTER_RANGE_AND_MASK(MinId, MaxId, ElementConfig) \
{ \
.f0_f = \
{ \
.efid1 = (uint32_t)(MinId), \
.efec = (uint32_t)(ElementConfig), \
}, \
.f1_f = \
{ \
.efid2 = (uint32_t)(MaxId), \
.eft = (uint32_t)CY_CANFD_EXT_ID_FILTER_TYPE_RANGE_AND_MASK \
}, \
}
/**
******************************************************************************
** \brief The macro for configuration the extended ID filter as the dual filter.
** If RxId fulfills the following condition, RxId matches in this filter.
** Id1 == (RxId & extIDANDMask)
** OR
** Id2 == (RxId & extIDANDMask)
** When the RxId matches the condition, the message will be treated in accordance
** with ElementConfig.
** ElementConfig can be selected from following definitions:
** - CY_CANFD_ID_FILTER_ELEMNT_CONFIG_STORE_RXFIFO0
** - CY_CANFD_ID_FILTER_ELEMNT_CONFIG_STORE_RXFIFO1
** - CY_CANFD_ID_FILTER_ELEMNT_CONFIG_REJECT_ID
** - CY_CANFD_ID_FILTER_ELEMNT_CONFIG_SET_PRIORIY
** - CY_CANFD_ID_FILTER_ELEMNT_CONFIG_SET_PIORITY_STORE_RXFIFO0
** - CY_CANFD_ID_FILTER_ELEMNT_CONFIG_SET_PIORITY_STORE_RXFIFO1
******************************************************************************/
#define CANFD_CONFIG_EXT_ID_FILTER_DUAL(Id1, Id2, ElementConfig) \
{ \
.f0_f = \
{ \
.efid1 = (uint32_t)(Id1), \
.efec = (uint32_t)(ElementConfig), \
}, \
.f1_f = \
{ \
.efid2 = (uint32_t)(Id2), \
.eft = (uint32_t)CY_CANFD_EXT_ID_FILTER_TYPE_DUAL \
}, \
}
/***************************************
* Enumerations
***************************************/
/**
* \addtogroup group_canfd_enums
* \{
*/
/**
*****************************************************************************
** \brief CAN FD driver error codes.
**
*****************************************************************************/
typedef enum
{
CY_CANFD_SUCCESS = 0x00u, /**< Returned successful */
CY_CANFD_BAD_PARAM = CY_CANFD_ID | CY_PDL_STATUS_ERROR | 0x01u, /**< Bad parameter was passed */
} cy_en_canfd_status_t;
/**
*****************************************************************************
** \brief CAN FD Tx Buffer status.
**
*****************************************************************************/
typedef enum
{
CY_CANFD_TX_BUFFER_IDLE = 0u,
CY_CANFD_TX_BUFFER_PENDING = 1u, /**< Pending transmission> */
CY_CANFD_TX_BUFFER_TRANSMIT_OCCURRED = 2u, /**< Transmission occurred> */
CY_CANFD_TX_BUFFER_CANCEL_REQUESTED = 3u, /**< Cancellation requested> */
CY_CANFD_TX_BUFFER_CANCEL_FINISHED = 4u, /**< Cancellation finished> */
} cy_en_canfd_tx_buffer_status_t;
/**
*****************************************************************************
** \brief CAN FD error.
**
** These error values are used to report any CAN FD related error to the API via
** the CAN FD error callback function (canfd_error_func_ptr_t).
*****************************************************************************/
typedef enum
{
CY_CANFD_BUSOFF = 0, /*!< The CAN FD module is in busoff state. */
CY_CANFD_WARNING = 1 /*!< At least one error counter has reached error warning. */
} cy_en_canfd_bus_error_t;
/**
*****************************************************************************
** \brief CAN FD instance Clock source.
**
** These values are used to specify the clock source for the CAN FD instance
*****************************************************************************/
typedef enum
{
CY_CANFD_CLOCK_SOURCE_MAIN = 0, // TODO: DENA. Clocks SAS still not finalized. Will be done later
} cy_en_canfd_clock_source_t;
/**
*****************************************************************************
** \brief CAN FD Bus status.
**
** These state values represent the current CAN FD state, and are used in the
** CAN FD status changed callback function (canfd_status_chg_func_ptr_t).
*****************************************************************************/
typedef enum
{
CY_CANFD_NO_ERROR = 0, /*!< No error pending. */
CY_CANFD_STUFF_ERROR = 1, /*!< More than 5 equal bits in a sequence have occurred in a part of a received message. */
CY_CANFD_FORM_ERROR = 2, /*!< A fixed format part of a received frame has the wrong format. */
CY_CANFD_ACK_ERROR = 3, /*!< The message this CAN FD Core transmitted was not acknowledged by another node. */
CY_CANFD_BIT1_ERROR = 4, /*!< While trying to send a recessive bit (1) a dominant level (0) was sampled. */
CY_CANFD_BIT0_ERROR = 5, /*!< While trying to send a dominant bit (0) a recessive level (1) was sampled. */
CY_CANFD_CRC_ERROR = 6 /*!< The CRC checksum was incorrect. */
} cy_en_canfd_bus_error_status_t;
/**
*****************************************************************************
** \brief CAN FD TX/RX buffer element size.
**
** The number of data bytes belonging to an Rx, Tx Buffer / Rx FIFO element.
*****************************************************************************/
typedef enum
{
CY_CANFD_BUFFER_DATA_SIZE_8 = 0, /*!< 8 byte data field. */
CY_CANFD_BUFFER_DATA_SIZE_12 = 1, /*!< 12 byte data field. */
CY_CANFD_BUFFER_DATA_SIZE_16 = 2, /*!< 16 byte data field. */
CY_CANFD_BUFFER_DATA_SIZE_20 = 3, /*!< 20 byte data field. */
CY_CANFD_BUFFER_DATA_SIZE_24 = 4, /*!< 24 byte data field. */
CY_CANFD_BUFFER_DATA_SIZE_32 = 5, /*!< 32 byte data field. */
CY_CANFD_BUFFER_DATA_SIZE_48 = 6, /*!< 48 byte data field. */
CY_CANFD_BUFFER_DATA_SIZE_64 = 7 /*!< 64 byte data field. */
} cy_en_canfd_buffer_data_size_t;
/**
*****************************************************************************
** \brief CAN FD RX FIFO operating mode.
*****************************************************************************/
typedef enum
{
CY_CANFD_FIFO_MODE_BLOCKING = 0, /*!< FIFO blocking mode. */
CY_CANFD_FIFO_MODE_OVERWRITE = 1 /*!< FIFO overwrite mode. */
} cy_en_canfd_fifo_mode_t;
/**
*****************************************************************************
** \brief CAN FD accept non matching frames.
*****************************************************************************/
typedef enum
{
CY_CANFD_ACCEPT_IN_RXFIFO_0 = 0,
CY_CANFD_ACCEPT_IN_RXFIFO_1 = 1,
CY_CANFD_REJECT_NON_MATCHING = 2
} cy_en_accept_non_matching_frames_t;
/**
******************************************************************************
** \brief ID Filter Element Configuration Type
******************************************************************************/
typedef enum
{
CY_CANFD_ID_FILTER_ELEMNT_CONFIG_DISABLE_FILETER_ELEMENT = 0x00u,
CY_CANFD_ID_FILTER_ELEMNT_CONFIG_STORE_RXFIFO0 = 0x01u,
CY_CANFD_ID_FILTER_ELEMNT_CONFIG_STORE_RXFIFO1 = 0x02u,
CY_CANFD_ID_FILTER_ELEMNT_CONFIG_REJECT_ID = 0x03u,
CY_CANFD_ID_FILTER_ELEMNT_CONFIG_SET_PRIORIY = 0x04u,
CY_CANFD_ID_FILTER_ELEMNT_CONFIG_SET_PIORITY_STORE_RXFIFO0 = 0x05u,
CY_CANFD_ID_FILTER_ELEMNT_CONFIG_SET_PIORITY_STORE_RXFIFO1 = 0x06u,
CY_CANFD_ID_FILTER_ELEMNT_CONFIG_STORE_RXBUFF_OR_DEBUGMSG = 0x07u,
}cy_en_canfd_id_filter_element_confifg_t;
/**
******************************************************************************
** \brief Standard ID Filter Type
******************************************************************************/
typedef enum
{
CY_CANFD_STD_ID_FILTER_TYPE_RANGE = 0x00u,
CY_CANFD_STD_ID_FILTER_TYPE_DUAL = 0x01u,
CY_CANFD_STD_ID_FILTER_TYPE_CLASSIC = 0x02u,
}cy_en_canfd_std_id_filter_type_t;
/**
******************************************************************************
** \brief Extended ID Filter Type
******************************************************************************/
typedef enum
{
CY_CANFD_EXT_ID_FILTER_TYPE_RANGE_AND_MASK = 0x00u,
CY_CANFD_EXT_ID_FILTER_TYPE_DUAL = 0x01u,
CY_CANFD_EXT_ID_FILTER_TYPE_CLASSIC = 0x02u,
CY_CANFD_EXT_ID_FILTER_TYPE_RANGE = 0x03u,
}cy_en_canfd_ext_id_filter_type_t;
/**
******************************************************************************
** \brief Method of receiving the message
******************************************************************************/
typedef enum
{
CY_CANFD_RECEIVED_IN_DEDICATED_BUFFER = 0x00u,
CY_CANFD_RECEIVED_IN_FIFO_TOP_POINTER_NOT_USED = 0x01u,
CY_CANFD_RECEIVED_IN_FIFO_TOP_POINTER_USED = 0x02u,
}cy_en_canfd_rx_received_type_t;
/** \} group_canfd_enums */
/***************************************
* Configuration Structures
***************************************/
/**
* \addtogroup group_canfd_data_structures
* \{
*/
/**
******************************************************************************
** \brief Redefinition of R0 register bitfields
******************************************************************************/
typedef struct
{
volatile uint32_t id :29; /*!< Identifier */
volatile uint32_t rtr : 1; /*!< Remote Transmission Request. 0:data frame, 1:remote frame */
volatile uint32_t xtd : 1; /*!< Extended Identifier. 0:11-bit standard identifier, 1:29-bit extended identifier */
volatile uint32_t esi : 1; /*!< Error State Indicator. 0:error active, 1:error passive */
} cy_stc_canfd_r0_t;
/**
******************************************************************************
** \brief Redefinition of R1 register bitfields
******************************************************************************/
typedef struct
{
volatile uint32_t rxts :16; /*!< Rx Timestamp */
volatile uint32_t dlc : 4; /*!< Data Length Code */
volatile uint32_t brs : 1; /*!< Bit Rate Switch. 0:without bit rate switching, 1:with bit rate switching */
volatile uint32_t fdf : 1; /*!< Extended Data Length. 0:Classic CAN frame format, 1:CAN FD frame format */
uint32_t reserved1 : 2; /*!< Reserved bits */
volatile uint32_t fidx : 7; /*!< Filter Index */
volatile uint32_t anmf : 1; /*!< Accepted Non-matching Frame. 0:matching filter index FIDX, 1:did not match any Rx filter element */
} cy_stc_canfd_r1_t;
/**
******************************************************************************
** \brief Redefinition of Rx Buffer Register
******************************************************************************/
typedef struct
{
cy_stc_canfd_r0_t r0_f; /*!< Rx buffer element for R0. See #cy_stc_canfd_r0_t. */
cy_stc_canfd_r1_t r1_f; /*!< Rx buffer element for R1. See #cy_stc_canfd_r1_t. */
uint32_t data_area_f[16]; /*!< Rx buffer element for Rn */
} cy_stc_canfd_rx_buffer_t;
/**
******************************************************************************
** \brief Redefinition of T0 register bitfields
******************************************************************************/
typedef struct
{
volatile uint32_t id :29; /*!< Identifier */
volatile uint32_t rtr : 1; /*!< Remote Transmission Request. 0:data frame, 1:remote frame */
volatile uint32_t xtd : 1; /*!< Extended Identifier. 0:11-bit standard identifier, 1:29-bit extended identifier */
volatile uint32_t esi : 1; /*!< Error State Indicator. 0:ESI bit in CAN FD format depends only on error passive flag, 1:ESI bit in CAN FD format transmitted recessive. */
} cy_stc_canfd_t0_t;
/**
******************************************************************************
** \brief Redefinition of T1 register bitfields
******************************************************************************/
typedef struct
{
uint32_t reserved1 :16; /*!< Reserved bits */
volatile uint32_t dlc : 4; /*!< Data Length Code */
volatile uint32_t brs : 1; /*!< Bit Rate Switching. 0:CAN FD frames transmitted without bit rate switching, CAN FD frames transmitted with bit rate switching */
volatile uint32_t fdf : 1; /*!< FD Format. 0:Frame transmitted in Classic CAN format, 1:Frame transmitted in CAN FD format */
volatile uint32_t reserved2 : 1; /*!< Reserved bit*/ // Added by DENA
volatile uint32_t efc : 1; /*!< Event FIFO Control. 0:Tx events not stored, 1:Store Tx events */
volatile uint32_t mm : 8; /*!< Message Marker */
} cy_stc_canfd_t1_t;
/**
******************************************************************************
** \brief Redefinition of Tx Buffer Register
******************************************************************************/
typedef struct
{
cy_stc_canfd_t0_t t0_f; /*!< Tx buffer element for T0. See #cy_stc_canfd_t0_t. */
cy_stc_canfd_t1_t t1_f; /*!< Tx buffer element for T1. See #cy_stc_canfd_t1_t. */
uint32_t data_area_f[16]; /*!< Tx buffer element for Tn */
} cy_stc_canfd_tx_buffer_t;
/**
******************************************************************************
** \brief Redefinition of Message ID Filter register
** This filter can be configured with CANFD_CONFIG_STD_ID_FILTER_* macros.
******************************************************************************/
typedef struct
{
volatile uint32_t sfid2 :11; /*!< Standard Filter ID 2 */
uint32_t reserved4 : 5; /*!< Reserved bits */
volatile uint32_t sfid1 :11; /*!< Standard Filter ID 1 */
volatile uint32_t sfec : 3; /*!< Standard Filter Element Configuration */
volatile uint32_t sft : 2; /*!< Standard Filter Type */
} cy_stc_id_filter_t;
/**
******************************************************************************
** \brief Redefinition of F0 register bitfields
******************************************************************************/
typedef struct
{
volatile uint32_t efid1 :29; /*!< Extended Filter ID 1 */
volatile uint32_t efec : 3; /*!< Extended Filter Element Configuration */
} cy_stc_canfd_f0_t;
/**
******************************************************************************
** \brief Redefinition of F1 register bitfields
******************************************************************************/
typedef struct
{
volatile uint32_t efid2 :29; /*!< Extended Filter ID 2 */
uint32_t reserved1 : 1; /*!< Reserved bits */
volatile uint32_t eft : 2; /*!< Extended Filter Type */
} cy_stc_canfd_f1_t;
/**
******************************************************************************
** \brief Redefinition of Extended Message ID Filter register
** This filter can be configured with CANFD_CONFIG_EXT_ID_FILTER_* macros.
******************************************************************************/
typedef struct
{
cy_stc_canfd_f0_t f0_f; /*!< Extended Message ID Filter Element for F0. See #stc_canfd_f0_t. */
cy_stc_canfd_f1_t f1_f; /*!< Extended Message ID Filter Element for F1. See #stc_canfd_f1_t. */
} cy_stc_extid_filter_t;
/**
*****************************************************************************
** \brief CAN FD bitrate.
**
** This structure is used to set the bitrate register.
*****************************************************************************/
typedef struct
{
uint16_t prescaler; /*!< Baud Rate Prescaler */
uint8_t timeSegment1; /*!< Time segment before sample point */
uint8_t timeSegment2; /*!< Time segment after sample point */
uint8_t syncJumpWidth; /*!< Synchronization Jump Width */
} cy_stc_canfd_bitrate_t;
/**
*****************************************************************************
** \brief CAN FD transceiver delay compensation offset configuration.
*****************************************************************************/
typedef struct
{
bool tdcEnabled;
uint8_t tdcOffset;
uint8_t tdcFilterWindow;
} cy_stc_canfd_transceiver_delay_compensation_t;
/**
*****************************************************************************
** \brief CAN FD message identifier
**
** This structure is used to set the CAN FD message identifier for transmit and
** receive operations.
*****************************************************************************/
typedef struct
{
uint32_t identifier; /*!< 11- or 29-bit identifier. The valid bit length depends on bExtended. */
bool extended; /*!< TRUE: 29-bit identifier, FALSE: 11-bit identifier. */
} cy_stc_canfd_msg_id_t;
/**
*****************************************************************************
** \brief CAN FD message data.
**
** Data structure for transmit and receive operations
*****************************************************************************/
typedef struct
{
uint32_t data[CY_CANFD_MESSAGE_DATA_BUFFER_SIZE]; /*!< Data of CAN FD message. */
uint8_t dataLengthCode; /*!< Number of valid bytes in data and DLC of CAN FD message. */
} cy_stc_canfd_msg_data_t;
/**
*****************************************************************************
** \brief CAN FD message.
**
** This structure stores a CAN FD message, including the identifier, data
** and data length code (DLC).
*****************************************************************************/
typedef struct
{
bool canFDFormat; /*!< TRUE:CAN FD format, FALSE:Classic CAN format. */
cy_stc_canfd_msg_id_t idConfig; /*!< 11- or 29-bit identifier (ID) */
cy_stc_canfd_msg_data_t dataConfig; /*!< Data and DLC */
} cy_stc_canfd_msg_t;
/**
*****************************************************************************
** \brief Standard ID filter configuration.
**
** Data structure for SID flter configuration.
*****************************************************************************/
typedef struct
{
uint8_t numberOfSIDFilters;
const cy_stc_id_filter_t* sidFilter;
} cy_stc_canfd_sid_filter_config_t;
/**
*****************************************************************************
** \brief Extended ID filter configuration.
**
** Data structure for EXTID flter configuration.
*****************************************************************************/
typedef struct
{
uint8_t numberOfEXTIDFilters;
const cy_stc_extid_filter_t* extidFilter;
uint32_t extIDANDMask;
} cy_stc_canfd_extid_filter_config_t;
/**
*****************************************************************************
** \brief Global filter configuration.
**
** Data structure for Global flter configuration.
*****************************************************************************/
typedef struct
{
cy_en_accept_non_matching_frames_t nonMatchingFramesStandard;
cy_en_accept_non_matching_frames_t nonMatchingFramesExtended;
bool rejectRemoteFramesStandard;
bool rejectRemoteFramesExtended;
} cy_stc_canfd_global_filter_config_t;
/**
*****************************************************************************
** \brief Rx Fifo configuration.
**
** Data structure for Rx Fifo configuration.
*****************************************************************************/
typedef struct
{
cy_en_canfd_fifo_mode_t mode;
uint8_t watermark;
uint8_t numberOfFifoElements;
bool topPointerLogicEnabled;
}cy_en_canfd_fifo_config_t;
/**
*****************************************************************************
** \brief Message transmission complete callback function (cy_canfd_tx_msg_func_ptr_t).
**
** Signals a successful completed transmission.
*****************************************************************************/
typedef void (*cy_canfd_tx_msg_func_ptr_t)( void );
/**
*****************************************************************************
** \brief Message reception callback function for message received in dedicated
** Rx Buffer or in Rx Fifo when Rx Fifo top pointer is not used (cy_canfd_rx_msg_func_ptr_t)
**
** Signals that CAN FD has received a new message.
** -- If Message was received in dedicated Rx Buffer (0 - 63) then bRxFifoMsg is False
** and u8MsgBufOrFifoNum indicates the Rx Buffer number
** -- If Message was received in Rx Fifo (0/1 and Rx Fifo top pointer is not used)
** then bRxFifoMsg is True and u8MsgBufOrFifoNum indicates the FIFO number.
*****************************************************************************/
typedef void (*cy_canfd_rx_msg_func_ptr_t)(bool bRxFifoMsg,
uint8_t u8MsgBufOrRxFifoNum,
cy_stc_canfd_msg_t* pstcCanFDmsg
);
/**
*****************************************************************************
** \brief Message reception callback function for message received in Rx Fifo
** when Rx Fifo Top pointer is used (cy_canfd_rx_msg_func_ptr_t).
**
*****************************************************************************/
typedef void (*cy_canfd_rx_fifo_msg_with_top_func_ptr_t)(uint8_t u8FifoNum,
uint8_t u8BufferSizeInWord,
uint32_t* pu32RxBuf
);
/**
*****************************************************************************
** \brief Status changed callback function (cy_canfd_status_chg_func_ptr_t).
**
** Any status change will be reported to the API (see #cy_en_canfd_bus_error_status_t for
** possible status change codes).
*****************************************************************************/
typedef void (*cy_canfd_status_chg_func_ptr_t)(cy_en_canfd_bus_error_status_t enCanFDStatus);
/**
*****************************************************************************
** \brief Error callback function (cy_canfd_error_func_ptr_t).
**
** Any error will be reported to the API (see #cy_en_canfd_bus_error_t for
** possible error codes).
*****************************************************************************/
typedef void (*cy_canfd_error_func_ptr_t)(cy_en_canfd_bus_error_t enCanFDError);
/**
*****************************************************************************
** \brief CAN FD configuration.
**
** Is used to set the bitrate and select CAN mode or CAN FD mode.
** Optionally Callbacks notification can be set.
*****************************************************************************/
typedef struct
{
cy_canfd_tx_msg_func_ptr_t txCallback; /*!< Callback function for transmit completed, can be NULL. */
cy_canfd_rx_msg_func_ptr_t rxCallback; /*!< Callback function for receive completed, can be NULL. */
cy_canfd_rx_fifo_msg_with_top_func_ptr_t rxFifoWithTopCallback; /*!< Callback function for receive in Fifo completed with Fifo Top pointer logic enabled */
cy_canfd_status_chg_func_ptr_t statusCallback; /*!< Callback function for CAN status changes, can be NULL. */
cy_canfd_error_func_ptr_t errorCallback; /*!< Callback function for CAN related errors, can be NULL. */
bool canFDMode; /*!< TRUE:CAN FD mode, FALSE:Classic CAN mode. */
cy_stc_canfd_bitrate_t bitrate; /*!< CAN bitrate setting. */
cy_stc_canfd_bitrate_t fastBitrate; /*!< CAN Fast bitrate setting. */
cy_stc_canfd_transceiver_delay_compensation_t tdcConfig; /*!< CAN transceiver delay compensation setting. */
cy_stc_canfd_sid_filter_config_t sidFilterConfig; /*!< CAN Standard ID filter setting. */
cy_stc_canfd_extid_filter_config_t extidFilterConfig; /*!< CAN Extended ID filter setting. */
cy_stc_canfd_global_filter_config_t globalFilterConfig; /*!< CAN global filter setting. */
cy_en_canfd_buffer_data_size_t rxBufferDataSize;
cy_en_canfd_buffer_data_size_t rxFifo1DataSize;
cy_en_canfd_buffer_data_size_t rxFifo0DataSize;
cy_en_canfd_buffer_data_size_t txBufferDataSize;
cy_en_canfd_fifo_config_t rxFifo0Config;
cy_en_canfd_fifo_config_t rxFifo1Config;
uint8_t noOfRxBuffers; /*!< Max 64> */
uint8_t noOfTxBuffers; /*!< Max 32> */
} cy_stc_canfd_config_t;
/**
*****************************************************************************
** \brief CAN FD interrupt pointer structure
**
** Holds some pointers to callback functions and buffer
*****************************************************************************/
typedef struct
{
cy_canfd_tx_msg_func_ptr_t canFDTxInterruptFunction; /*!< pointer to transmit interrupt callback */
cy_canfd_rx_msg_func_ptr_t canFDRxInterruptFunction; /*!< pointer to receive interrupt callback (dedicated Rx Buffer or RxFifo without Top pointer logic)*/
cy_canfd_rx_fifo_msg_with_top_func_ptr_t canFDRxWithTopPtrInterruptFunction; /*!< pointer to receive interrupt callback (RxFifo when Top pointer logic used)*/
} cy_stc_canfd_interrupt_handling_t;
/**
*****************************************************************************
** \brief CAN FD notification pointer structure
**
** Holds some pointers to callback functions for status and error notification
*****************************************************************************/
typedef struct
{
cy_canfd_status_chg_func_ptr_t canFDStatusInterruptFunction ; /*!< pointer to status interrupt callback */
cy_canfd_error_func_ptr_t canFDErrorInterruptFunction ; /*!< pointer to error interrupt callback */
} cy_stc_canfd_notification_t;
/**
*****************************************************************************
** \brief CAN FD internal data structure
**
** Pointer to callback function interrupt handler
*****************************************************************************/
typedef struct
{
cy_stc_canfd_interrupt_handling_t canFDInterruptHandling; /*!< Interrupt callback. See #stc_canfd_interrupt_handling_t. */
cy_stc_canfd_notification_t canFDNotificationCb; /*!< Interrupt callback. See #stc_canfd_notification_t. */
} cy_stc_canfd_context_t;
/** \} group_canfd_data_structures */
/**
*****************************************************************************
** \brief CAN FD Unit Type
*****************************************************************************/
typedef volatile stc_CANFD_CH_t* cy_pstc_canfd_type_t;
/***************************************
* Function Prototypes
***************************************/
/**
* \addtogroup group_canfd_functions
* \{
*/
void Cy_CANFD_IrqHandler( cy_pstc_canfd_type_t pstcCanFD );
cy_en_canfd_status_t Cy_CANFD_Init( cy_pstc_canfd_type_t pstcCanFD, const cy_stc_canfd_config_t* pstcConfig) ;
cy_en_canfd_status_t Cy_CANFD_DeInit(cy_pstc_canfd_type_t pstcCanFD);
cy_en_canfd_status_t Cy_CANFD_UpdateAndTransmitMsgBuffer( cy_pstc_canfd_type_t pstcCanFD, uint8_t u8MsgBuf, cy_stc_canfd_msg_t* pstcMsg ) ;
cy_en_canfd_tx_buffer_status_t Cy_CANFD_GetTxBufferStatus( cy_pstc_canfd_type_t pstcCanFD, uint8_t u8MsgBuf);
void Cy_CANFD_ExtractMsgFromRXBuffer(cy_stc_canfd_rx_buffer_t *pstcRxBufferAddr, cy_stc_canfd_msg_t *pstcCanFDmsg);
cy_en_canfd_status_t Cy_CANFD_ClockInit( cy_pstc_canfd_type_t pstcCanFD,
uint8_t u8CanFDPrescaler, // TODO: DENA. Clock SAS still not finalized. Will be done later
cy_en_canfd_clock_source_t enCanFDClockSource // TODO: DENA. Clock SAS still not finalized. Will be done later
) ;
/** \} group_canfd_functions */
#if defined(__cplusplus)
}
#endif
#endif /* CY_CANFD_H */
/** \} group_canfd */
/* [] END OF FILE */
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,717 @@
/***************************************************************************//**
* \file cy_crypto_common.h
* \version 1.0
*
* \brief
* This file provides common constants and parameters
* for the Crypto driver.
*
********************************************************************************
* \copyright
* Copyright 2016-2017, Cypress Semiconductor Corporation. All rights reserved.
* You may use this file only in accordance with the license, terms, conditions,
* disclaimers, and limitations in the end user license agreement accompanying
* the software package with which this file was provided.
*******************************************************************************/
#if !defined(CY_CRYPTO_COMMON_H)
#define CY_CRYPTO_COMMON_H
#include <stddef.h>
#include <stdbool.h>
#include "cy_device_headers.h"
#include "sysint/cy_sysint.h"
#include "syslib/cy_syslib.h"
#ifndef CY_IP_MXCRYPTO
#error "The CRYPTO driver is not supported on this device"
#endif
#if (CPUSS_CRYPTO_PRESENT == 1)
/** Driver major version */
#define CY_CRYPTO_DRV_VERSION_MAJOR (1)
/** Driver minor version */
#define CY_CRYPTO_DRV_VERSION_MINOR (0)
/**
* \addtogroup group_crypto_macros
* \{
*/
/** Defines Crypto_Sync blocking execution type parameter */
#define CY_CRYPTO_SYNC_BLOCKING (true)
/** Defines Crypto_Sync non-blocking execution type parameter */
#define CY_CRYPTO_SYNC_NON_BLOCKING (false)
/** Defines the Crypto DES key size (in bytes) */
#define CY_CRYPTO_DES_KEY_SIZE (8u)
/** Defines the Crypto TDES key size (in bytes) */
#define CY_CRYPTO_TDES_KEY_SIZE (24u)
/** Defines the Crypto AES block size (in bytes) */
#define CY_CRYPTO_AES_BLOCK_SIZE (16u)
/** Defines the Crypto AES key maximum size (in bytes) */
#define CY_CRYPTO_AES_128_KEY_SIZE (16u)
/** Defines the Crypto AES key maximum size (in bytes) */
#define CY_CRYPTO_AES_192_KEY_SIZE (24u)
/** Defines the Crypto AES key maximum size (in bytes) */
#define CY_CRYPTO_AES_256_KEY_SIZE (32u)
/** Defines size of the AES block, in four-byte words */
#define CY_CRYPTO_AES_BLOCK_SIZE_U32 (4UL)
#if ((CPUSS_CRYPTO_SHA1 == 1) || \
(CPUSS_CRYPTO_SHA2 == 1) || \
(CPUSS_CRYPTO_SHA3 == 1))
#define CPUSS_CRYPTO_SHA (1u)
#endif
#if (CPUSS_CRYPTO_SHA == 1)
/** Hash size for the SHA1 mode (in bytes) */
#define CY_CRYPTO_SHA1_DIGEST_SIZE (20u)
/** Hash size for the SHA224 mode (in bytes) */
#define CY_CRYPTO_SHA224_DIGEST_SIZE (28u)
/** Hash size for the SHA256 mode (in bytes) */
#define CY_CRYPTO_SHA256_DIGEST_SIZE (32u)
/** Hash size for the SHA384 mode (in bytes) */
#define CY_CRYPTO_SHA384_DIGEST_SIZE (48u)
/** Hash size for the SHA512 mode (in bytes) */
#define CY_CRYPTO_SHA512_DIGEST_SIZE (64u)
/** Hash size for the SHA512_224 mode (in bytes) */
#define CY_CRYPTO_SHA512_224_DIGEST_SIZE (28u)
/** Hash size for the SHA512_256 mode (in bytes) */
#define CY_CRYPTO_SHA512_256_DIGEST_SIZE (32u)
/** Hash size for the SHA3_224 mode (in bytes) */
#define CY_CRYPTO_SHA3_224_DIGEST_SIZE (224u/8u)
/** Hash size for the SHA3_256 mode (in bytes) */
#define CY_CRYPTO_SHA3_256_DIGEST_SIZE (256u/8u)
/** Hash size for the SHA3_384 mode (in bytes) */
#define CY_CRYPTO_SHA3_384_DIGEST_SIZE (384u/8u)
/** Hash size for the SHA3_512 mode (in bytes) */
#define CY_CRYPTO_SHA3_512_DIGEST_SIZE (512u/8u)
/** Hash size for the SHAKE128 mode (in bytes)
* SHAKE128 can generate variable size of the digest, but in the driver implementation
* only fixed length 256bits is supported.
*/
#define CY_CRYPTO_SHAKE128_DIGEST_SIZE (256u/8u)
/** Hash size for the SHAKE256 mode (in bytes)
* SHAKE256 can generate variable size of the digest, but in the driver implementation
* only fixed length 512bits is supported.
*/
#define CY_CRYPTO_SHAKE256_DIGEST_SIZE (512u/8u)
#endif /* #if (CPUSS_CRYPTO_SHA == 1) */
#if (CPUSS_CRYPTO_VU == 1)
/** Processed message size for the RSA 1024Bit mode (in bytes) */
#define CY_CRYPTO_RSA1024_MESSAGE_SIZE (128)
/** Processed message size for the RSA 1536Bit mode (in bytes) */
#define CY_CRYPTO_RSA1536_MESSAGE_SIZE (192)
/** Processed message size for the RSA 2048Bit mode (in bytes) */
#define CY_CRYPTO_RSA2048_MESSAGE_SIZE (256)
#endif /* #if (CPUSS_CRYPTO_VU == 1) */
/** Crypto Driver PDL ID */
#define CY_CRYPTO_ID CY_PDL_DRV_ID(0x0Cu)
/** \} group_crypto_macros */
/**
* \addtogroup group_crypto_config_structure
* \{
*/
/** The Crypto user callback function type.
Callback is called at the end of Crypto calculation. */
typedef void (*cy_crypto_callback_ptr_t)(void);
/** The Crypto configuration structure. */
typedef struct
{
/** Defines the IPC channel used for client-server data exchange */
uint32_t ipcChannel;
/** Specifies the IPC notifier channel (IPC interrupt structure number)
to notify server that data for the operation is prepared */
uint32_t acquireNotifierChannel;
/** Specifies the IPC notifier channel (IPC interrupt structure number)
to notify client that operation is complete and data is valid */
uint32_t releaseNotifierChannel;
/** Specifies the release notifier interrupt configuration. */
cy_stc_sysint_irq_t releaseNotifierConfig;
/** User callback function.
If this field is NOT NULL, it called when Crypto operation
is complete. */
cy_crypto_callback_ptr_t userCompleteCallback;
#if (CY_CPU_CORTEX_M0P)
/** Server-side user IRQ handler function, called when data for the
operation is prepared to process.
- This field cannot work because IRQ handler cannot change in operation.
If needed user IRQ handler, please update the Cy_Crypto_Server_GetDataHandler.
- If this field is NULL, server will use own interrupt handler
to get data.
- If this field is not NULL, server will call this interrupt handler.
This interrupt handler must call the
\ref Cy_Crypto_Server_GetDataHandler to get data to process.
Note: In the second case user should process data separately and
clear interrupt by calling \ref Cy_Crypto_Server_Process.
This model is used in the
multitasking environment (e.g. CyOS). */
cy_israddress userGetDataHandler;
/** Server-side user IRQ handler function, called when a Crypto hardware
error occurs (interrupt was raised).
- This field cannot work because IRQ handler cannot change in operation.
If needed user IRQ handler, please update the Cy_Crypto_Server_ErrorHandler.
- If this field is NULL - server will use own interrupt handler
for error processing.
- If this field is not NULL - server will call this interrupt handler.
This interrupt handler must call the
\ref Cy_Crypto_Server_ErrorHandler to clear the interrupt. */
cy_israddress userErrorHandler;
/** Specifies the prepared data notifier interrupt configuration. */
cy_stc_sysint_irq_t acquireNotifierConfig;
/** Specifies the hardware error processing interrupt configuration. */
cy_stc_sysint_irq_t cryptoErrorIntrConfig;
#endif
} cy_stc_crypto_config_t;
/** \} group_crypto_config_structure */
/**
* \addtogroup group_crypto_cli_data_structures
* \{
*/
#if (CPUSS_CRYPTO_VU == 1)
/** Structure for storing the RSA public key and additional coefficients to
accelerate RSA calculation.
RSA key contained from two fields:
- n - modulus part of the key
- e - exponent part of the key.
Other fields are accelerating coefficients and can be calculated by
\ref Cy_Crypto_Rsa_CalcCoefs.
*/
typedef struct
{
/** The pointer to the modulus part of public key. */
void const *moduloPtr;
/** The modulus length, in bits, maximum supported size is 2048Bit */
uint32_t moduloLength;
/** The pointer to the exponent part of public key */
void const *pubExpPtr;
/** The exponent length, in bits, maximum supported size is 256Bit */
uint32_t pubExpLength;
/** The pointer to the Barrett coefficient. Memory for it should be
allocated by user with size moduloLength + 1. */
void *barretCoefPtr;
/** The pointer to the binary inverse of the modulo. Memory for it
should be allocated by user with size moduloLength. */
void *inverseModuloPtr;
/** The pointer to the (2^moduloLength mod modulo). Memory for it should
be allocated by user with size moduloLength */
void *rBarPtr;
} cy_stc_crypto_rsa_pub_key_t;
#endif /* #if (CPUSS_CRYPTO_VU == 1) */
/** Structure for storing a description of a Crypto hardware error */
typedef struct
{
/**
Captures error description information:
for INSTR_OPC_ERROR: - Violating instruction (from instruction FIFO).
for INSTR_CC_ERROR : - Violating instruction (from instruction FIFO).
for BUS_ERROR : - violating the transfer address. */
uint32_t errorStatus0;
/**
[31] - Specifies if ERROR_STATUS0 and ERROR_STATUS1 capture valid
error-information.
[26..24] - The error source:
"0": INSTR_OPC_ERROR (instuction FIFO decoder error).
"1": INSTR_CC_ERROR (instruction FIFO decoder, VU CC error).
"2": BUS_ERROR (bus master interface AHB-Lite bus error).
"3": TR_AP_DETECT_ERROR.
"4": TR_RC_DETECT_ERROR.
[23..0] - Captures error description information.
For BUS_ERROR:
- violating the transfer, read the attribute (DATA23[0]).
- violating the transfer, the size attribute (DATA23[5:4]).
"0": an 8-bit transfer;
"1": 16 bits transfer;
"2": 32-bit transfer. */
uint32_t errorStatus1;
} cy_stc_crypto_hw_error_t;
/** \} group_crypto_cli_data_structures */
/** The Crypto library functionality level. */
typedef enum
{
CY_CRYPTO_NO_LIBRARY = 0x00u,
CY_CRYPTO_BASE_LIBRARY = 0x01u,
CY_CRYPTO_EXTRA_LIBRARY = 0x02u,
CY_CRYPTO_FULL_LIBRARY = 0x03u,
} cy_en_crypto_lib_info_t;
/**
* \addtogroup group_crypto_enums
* \{
*/
#if (CPUSS_CRYPTO_AES == 1)
/** The key length options for the AES method. */
typedef enum
{
CY_CRYPTO_KEY_AES_128 = 0x00u, /**< The AES key size is 128 bits */
CY_CRYPTO_KEY_AES_192 = 0x01u, /**< The AES key size is 192 bits */
CY_CRYPTO_KEY_AES_256 = 0x02u /**< The AES key size is 256 bits */
} cy_en_crypto_aes_key_length_t;
#endif /* #if (CPUSS_CRYPTO_AES == 1) */
/** Defines the direction of the Crypto methods */
typedef enum
{
/** The forward mode, plain text will be encrypted into cipher text */
CY_CRYPTO_ENCRYPT = 0x00u,
/** The reverse mode, cipher text will be decrypted into plain text */
CY_CRYPTO_DECRYPT = 0x01u
} cy_en_crypto_dir_mode_t;
#if (CPUSS_CRYPTO_SHA == 1)
/** Defines modes of SHA method */
typedef enum
{
#if (CPUSS_CRYPTO_SHA1 == 1)
CY_CRYPTO_MODE_SHA1 = 0x00u, /**< Sets the SHA1 mode */
#endif /* #if (CPUSS_CRYPTO_SHA1 == 1) */
#if (CPUSS_CRYPTO_SHA2 == 1)
CY_CRYPTO_MODE_SHA224 = 0x11u, /**< Sets the SHA224 mode */
CY_CRYPTO_MODE_SHA256 = 0x01u, /**< Sets the SHA256 mode */
CY_CRYPTO_MODE_SHA384 = 0x12u, /**< Sets the SHA384 mode */
CY_CRYPTO_MODE_SHA512 = 0x02u, /**< Sets the SHA512 mode */
CY_CRYPTO_MODE_SHA512_256 = 0x22u, /**< Sets the SHA512/256 mode */
CY_CRYPTO_MODE_SHA512_224 = 0x32u, /**< Sets the SHA512/224 mode */
#endif /* #if (CPUSS_CRYPTO_SHA2 == 1) */
#if (CPUSS_CRYPTO_SHA3 == 1)
CY_CRYPTO_MODE_SHA3_224 = 0x81u, /**< Sets the SHA3_224 mode */
CY_CRYPTO_MODE_SHA3_256 = 0x82u, /**< Sets the SHA3_256 mode */
CY_CRYPTO_MODE_SHA3_384 = 0x83u, /**< Sets the SHA3_384 mode */
CY_CRYPTO_MODE_SHA3_512 = 0x84u, /**< Sets the SHA3_512 mode */
CY_CRYPTO_MODE_SHAKE128 = 0x85u, /**< Sets the SHAKE128 mode */
CY_CRYPTO_MODE_SHAKE256 = 0x86u /**< Sets the SHAKE256 mode */
#endif /* #if (CPUSS_CRYPTO_SHA3 == 1) */
} cy_en_crypto_sha_mode_t;
#endif /* #if (CPUSS_CRYPTO_SHA == 1) */
/** Signature verification status */
typedef enum
{
CY_CRYPTO_RSA_VERIFY_SUCCESS = 0x00u, /**< PKCS1-v1.5 verify SUCCESS */
CY_CRYPTO_RSA_VERIFY_FAIL = 0x01u /**< PKCS1-v1.5 verify FAILED */
} cy_en_crypto_rsa_ver_result_t;
#if (CPUSS_CRYPTO_CHACHA == 1)
/** ChaCha round number selection */
typedef enum
{
CY_CRYPTO_CHACHA8 = 8u / 2u, /**< CHACHA8 */
CY_CRYPTO_CHACHA12 = 12u / 2u, /**< CHACHA12 */
CY_CRYPTO_CHACHA20 = 20u / 2u /**< CHACHA20 */
} cy_en_crypto_chacha_round_t;
#endif /* #if (CPUSS_CRYPTO_CHACHA == 1) */
/** Errors of the Crypto block */
typedef enum
{
/** Operation completed successfully. */
CY_CRYPTO_SUCCESS = 0x00u,
/** A hardware error occurred, detailed information is in stc_crypto_hw_error_t. */
CY_CRYPTO_HW_ERROR = CY_CRYPTO_ID | CY_PDL_STATUS_ERROR | 0x01u,
/** The size of input data is not multiple of 16. */
CY_CRYPTO_SIZE_NOT_X16 = CY_CRYPTO_ID | CY_PDL_STATUS_ERROR | 0x02u,
/** The key for the DES method is weak. */
CY_CRYPTO_DES_WEAK_KEY = CY_CRYPTO_ID | CY_PDL_STATUS_WARNING | 0x03u,
/** Communication between the client and server via IPC is broken. */
CY_CRYPTO_COMM_FAIL = CY_CRYPTO_ID | CY_PDL_STATUS_ERROR | 0x04u,
/** The Crypto server is not started. */
CY_CRYPTO_SERVER_NOT_STARTED = CY_CRYPTO_ID | CY_PDL_STATUS_ERROR | 0x06u,
/** The Crypto server in process state. */
CY_CRYPTO_SERVER_BUSY = CY_CRYPTO_ID | CY_PDL_STATUS_INFO | 0x07u,
/** The Crypto driver is not initialized. */
CY_CRYPTO_NOT_INITIALIZED = CY_CRYPTO_ID | CY_PDL_STATUS_ERROR | 0x08u,
/** The Crypto hardware is not enabled. */
CY_CRYPTO_HW_NOT_ENABLED = CY_CRYPTO_ID | CY_PDL_STATUS_ERROR | 0x09u,
/** The Crypto operation is not supported. */
CY_CRYPTO_NOT_SUPPORTED = CY_CRYPTO_ID | CY_PDL_STATUS_ERROR | 0x0Au,
/** Invalid parameter is passed */
CY_CRYPTO_BAD_PARAM = CY_CRYPTO_ID | CY_PDL_STATUS_ERROR | 0x0Bu
} cy_en_crypto_status_t;
/** \} group_crypto_enums */
/** \cond INTERNAL */
/** Instruction to communicate between Client and Server */
typedef enum
{
CY_CRYPTO_INSTR_UNKNOWN = 0x00u,
CY_CRYPTO_INSTR_ENABLE = 0x01u,
CY_CRYPTO_INSTR_DISABLE = 0x02u,
#if (CPUSS_CRYPTO_PR == 1)
CY_CRYPTO_INSTR_PRNG_INIT = 0x03u,
CY_CRYPTO_INSTR_PRNG = 0x04u,
#endif /* #if (CPUSS_CRYPTO_PR == 1) */
#if (CPUSS_CRYPTO_TR == 1)
CY_CRYPTO_INSTR_TRNG_INIT = 0x05u,
CY_CRYPTO_INSTR_TRNG = 0x06u,
#endif /* #if (CPUSS_CRYPTO_PR == 1) */
#if (CPUSS_CRYPTO_AES == 1)
CY_CRYPTO_INSTR_AES_ECB = 0x08u,
CY_CRYPTO_INSTR_AES_CBC = 0x09u,
CY_CRYPTO_INSTR_AES_CFB = 0x0Au,
CY_CRYPTO_INSTR_AES_CTR = 0x0Bu,
CY_CRYPTO_INSTR_CMAC = 0x0Cu,
#endif /* #if (CPUSS_CRYPTO_AES == 1) */
#if (CPUSS_CRYPTO_SHA == 1)
CY_CRYPTO_INSTR_SHA = 0x0Du,
#endif /* #if (CPUSS_CRYPTO_SHA == 1) */
#if (CPUSS_CRYPTO_SHA == 1)
CY_CRYPTO_INSTR_HMAC = 0x0Eu,
#endif /* #if (CPUSS_CRYPTO_SHA == 1) */
#if (CPUSS_CRYPTO_CRC == 1)
CY_CRYPTO_INSTR_CRC_INIT = 0x13u,
CY_CRYPTO_INSTR_CRC = 0x14u,
#endif /* #if (CPUSS_CRYPTO_CRC == 1) */
#if (CPUSS_CRYPTO_DES == 1)
CY_CRYPTO_INSTR_DES = 0x15u,
CY_CRYPTO_INSTR_3DES = 0x16u,
#endif /* #if (CPUSS_CRYPTO_DES == 1) */
#if (CPUSS_CRYPTO_VU == 1)
CY_CRYPTO_INSTR_RSA_PROC = 0x17u,
CY_CRYPTO_INSTR_RSA_COEF = 0x18u,
#endif /* #if (CPUSS_CRYPTO_VU == 1)*/
#if (CPUSS_CRYPTO_SHA == 1)
CY_CRYPTO_INSTR_RSA_VER = 0x19u,
#endif /* #if (CPUSS_CRYPTO_SHA == 1) */
#if (CPUSS_CRYPTO_CHACHA == 1)
CY_CRYPTO_INSTR_CHACHA = 0x1Au,
#endif /* #if (CPUSS_CRYPTO_CHACHA == 1) */
CY_CRYPTO_INSTR_SRV_INFO = 0x55u
} cy_en_crypto_comm_instr_t;
/** \endcond */
/**
* \addtogroup group_crypto_cli_data_structures
* \{
*/
#if (CPUSS_CRYPTO_AES == 1)
/** Structure for storing the AES state */
typedef struct
{
/** Pointer to AES key */
void const *keyPtr;
/** AES key length */
cy_en_crypto_aes_key_length_t keyLength;
/** AES processed block index (for CMAC operations) */
uint32_t blockIdx;
} cy_stc_crypto_aes_state_t;
#endif /* #if (CPUSS_CRYPTO_AES == 1) */
/** \} group_crypto_cli_data_structures */
/*************************************************************
* Structures used for communication between Client and Server
***************************************************************/
/**
* \addtogroup group_crypto_srv_data_structures
* \{
*/
/** Structure for storing the server context */
typedef struct
{
/** IPC communication channel number */
uint32_t ipcChannel;
/** IPC acquire interrupt channel number */
uint32_t acquireNotifierChannel;
/** IPC release interrupt channel number */
uint32_t releaseNotifierChannel;
/** Interrupt handler to get processing data */
cy_israddress getDataHandlerPtr;
/** Crypto hardware errors interrupt handler */
cy_israddress errorHandlerPtr;
/** Acquire notifier interrupt configuration */
cy_stc_sysint_irq_t acquireNotifierConfig;
/** Crypto hardware errors interrupt configuration */
cy_stc_sysint_irq_t cryptoErrorIntrConfig;
/** Hardware error occurrence flag */
bool isHwErrorOccured;
} cy_stc_crypto_server_context_t;
/** \} group_crypto_srv_data_structures */
/**
* \addtogroup group_crypto_cli_data_structures
* \{
*/
/** Structure for storing the global context */
typedef struct
{
/** Operation instruction code */
cy_en_crypto_comm_instr_t instr;
/** Response from executed crypto function */
cy_en_crypto_status_t resp;
/** Hardware processing errors */
cy_stc_crypto_hw_error_t hwErrorStatus;
/** IPC communication channel number */
uint32_t ipcChannel;
/** IPC acquire interrupt channel number */
uint32_t acquireNotifierChannel;
/** IPC release interrupt channel number */
uint32_t releaseNotifierChannel;
/** User callback for Crypto HW calculation complete event */
cy_crypto_callback_ptr_t userCompleteCallback;
/** Release notifier interrupt configuration */
cy_stc_sysint_irq_t releaseNotifierConfig;
/** Pointer to the crypto function specific context data */
void *xdata;
} cy_stc_crypto_context_t;
#if (CPUSS_CRYPTO_DES == 1)
/** Structure for storing the DES context */
typedef struct
{
/** Operation direction (Encrypt / Decrypt) */
cy_en_crypto_dir_mode_t dirMode;
/** Pointer to key data */
void const *keyPtr;
/** Pointer to data destination block */
void *dstPtr;
/** Pointer to data source block */
void const *srcPtr;
} cy_stc_crypto_context_des_t;
#endif /* #if (CPUSS_CRYPTO_DES == 1) */
#if (CPUSS_CRYPTO_AES == 1)
/** Structure for storing the AES context */
typedef struct
{
/** AES state data */
cy_stc_crypto_aes_state_t aesState;
/** Operation direction (Encrypt / Decrypt) */
cy_en_crypto_dir_mode_t dirMode;
/** Operation data size */
uint32_t srcSize;
/** Size of the last non-complete block (for CTR mode only)
* Other than CTR mode can be set to NULL.
* For the first sequence, *srcOffset value should be 0.
* This parameter is updated by CRYPTO module.
* For the first call for a sequence, this field shall be initialized
* to '0'. For the trailing call for the sequence,
* it shall not be initialized.
*/
uint32_t *srcOffset;
/** Initialization vector, in the CTR mode is used as nonceCounter
* In the CTR mode, counter value is incremented by the API.
* For the first call for a sequence, this field shall be initialized
* required nonceCounter value. For the trailing call for the sequence,
* it shall not be initialized.
*/
void *ivPtr;
/** Pointer to data destination block */
void *dstPtr;
/** Pointer to data source block */
void const *srcPtr;
} cy_stc_crypto_context_aes_t;
#endif /* #if (CPUSS_CRYPTO_AES == 1) */
#if (CPUSS_CRYPTO_SHA == 1)
/** Structure for storing the SHA context */
typedef struct
{
/** Pointer to data source block */
void const *messagePtr;
/** Operation data size */
uint32_t messageSize;
/** Pointer to data destination block */
void *dstPtr;
/** SHA mode */
cy_en_crypto_sha_mode_t mode;
/** Pointer to key data (for HMAC only) */
void const *keyPtr;
/** Key data length (for HMAC only) */
uint32_t keyLength;
} cy_stc_crypto_context_sha_t;
#endif /* #if (CPUSS_CRYPTO_SHA == 1) */
#if (CPUSS_CRYPTO_PR == 1)
/** Structure for storing the PRNG context */
typedef struct
{
uint32_t lfsr32InitState; /**< lfsr32 initialization data (must be none zero) */
uint32_t lfsr31InitState; /**< lfsr31 initialization data (must be none zero) */
uint32_t lfsr29InitState; /**< lfsr29 initialization data (must be none zero) */
uint32_t max; /**< Maximum of the generated value */
uint32_t *prngNumPtr; /**< Pointer to generated value */
} cy_stc_crypto_context_prng_t;
#endif /* #if (CPUSS_CRYPTO_PR == 1) */
#if (CPUSS_CRYPTO_TR == 1)
/** Structure for storing the TRNG context */
typedef struct
{
/**
The polynomial for the programmable Galois ring oscillator (TR_GARO_CTL).
The polynomial is represented WITHOUT the high order bit (this bit is
always assumed '1').
The polynomial should be aligned so that more significant bits
(bit 30 and down) contain the polynomial and less significant bits
(bit 0 and up) contain padding '0's. */
uint32_t GAROPol;
/**
The polynomial for the programmable Fibonacci ring oscillator(TR_FIRO_CTL).
The polynomial is represented WITHOUT the high order bit (this bit is
always assumed '1').
The polynomial should be aligned so that more significant bits
(bit 30 and down) contain the polynomial and less significant bits
(bit 0 and up) contain padding '0's. */
uint32_t FIROPol;
/** Bit size of the generated value. Valid range is [0,32] */
uint8_t bitSize;
/** Pointer to generated value */
uint32_t *trngNumPtr;
} cy_stc_crypto_context_trng_t;
#endif /* #if (CPUSS_CRYPTO_TR == 1) */
#if (CPUSS_CRYPTO_CRC == 1)
/** Structure for storing the CRC context */
typedef struct
{
void const *srcDataPtr; /**< Pointer to data source block */
uint32_t dataSize; /**< operation data size */
uint32_t *crcPtr; /**< Pointer to CRC destination variable */
uint32_t polynomial; /**< Polynomial for CRC calculate */
uint32_t lfsrInitState; /**< CRC calculation initial value */
uint32_t dataReverse; /**< Input data reverse flag */
uint32_t dataXor; /**< Input data XOR flag */
uint32_t remReverse; /**< Output data reverse flag */
uint32_t remXor; /**< Output data XOR flag */
} cy_stc_crypto_context_crc_t;
#endif /* #if (CPUSS_CRYPTO_CRC == 1) */
/** Structure for storing the RSA verify context */
typedef struct
{
/** Pointer to verification result /ref cy_en_crypto_rsa_ver_result_t */
cy_en_crypto_rsa_ver_result_t *verResult;
/** SHA digest type, used with SHA calculation of the message */
cy_en_crypto_sha_mode_t digestType;
/** SHA digest of the message, calculated with digestType */
void const *hashPtr;
/** Previously decrypted RSA signature */
void const *decryptedSignaturePtr;
/** Length of the decrypted RSA signature */
uint32_t decryptedSignatureLength;
} cy_stc_crypto_context_rsa_ver_t;
#if (CPUSS_CRYPTO_VU == 1)
/** Structure for storing the RSA process context */
typedef struct
{
/** Pointer to key data */
cy_stc_crypto_rsa_pub_key_t const *keyPtr;
/** Pointer to data source block */
void const *messagePtr;
/** Operation data size */
uint32_t messageLength;
/** Pointer to data destination block */
void *resultPtr;
} cy_stc_crypto_context_rsa_t;
#endif /* #if (CPUSS_CRYPTO_VU == 1)*/
#if (CPUSS_CRYPTO_CHACHA == 1)
/** Structure for storing the CHACHA context */
typedef struct
{
/** Operation data size */
uint32_t srcSize;
/** Pointer to data destination block */
void *dstPtr;
/** Pointer to data source block */
void const *srcPtr;
/** Initial nonce value (only 96bits is supported in the driver.) */
void const *noncePtr;
/** Initial counter value */
uint32_t counter;
/** Pointer to CHACHA key (Only 256bits is supported in the driver). */
void const *keyPtr;
/** half of a round number. Refer \ref cy_en_crypto_chacha_round_t */
cy_en_crypto_chacha_round_t roundNum;
} cy_stc_crypto_context_chacha_t;
#endif /* #if (CPUSS_CRYPTO_CHACHA == 1) */
/** \} group_crypto_data_structures */
/** \} group_crypto_cli_data_structures */
#endif /* (CPUSS_CRYPTO_PRESENT == 1) */
#endif /* #if !defined(CY_CRYPTO_COMMON_H) */
/* [] END OF FILE */
@@ -0,0 +1,59 @@
/***************************************************************************//**
* \file
* \version `$CY_MAJOR_VERSION`.`$CY_MINOR_VERSION`
*
* Description:
* This C file is not intended to be part of the Crypto driver. It is the code
* required to configure the crypto driver by user.
*
********************************************************************************
* Copyright 2016-2017, Cypress Semiconductor Corporation. All rights reserved.
* You may use this file only in accordance with the license, terms, conditions,
* disclaimers, and limitations in the end user license agreement accompanying
* the software package with which this file was provided.
*******************************************************************************/
#include "cy_crypto_config.h"
#include "ipc/cy_ipc_drv.h"
#include "sysint/cy_sysint.h"
/** The Crypto configuration structure. (default example)*/
const cy_stc_crypto_config_t cryptoConfig =
{
.ipcChannel = CY_IPC_CHAN_CRYPTO,
.acquireNotifierChannel = CY_CRYPTO_IPC_INTR_NOTIFY_NUM,
.releaseNotifierChannel = CY_CRYPTO_IPC_INTR_RELEASE_NUM,
.userCompleteCallback = NULL,
.releaseNotifierConfig = {
.sysIntSrc = (cy_en_intr_t)((uint32_t)cpuss_interrupts_ipc_0_IRQn + CY_CRYPTO_IPC_INTR_RELEASE_NUM),
.intIdx = CY_CRYPTO_RELEASE_CPU_INT_IDX,
.isEnabled = true
}
#if (CY_CPU_CORTEX_M0P)
,
.userGetDataHandler = NULL,
.userErrorHandler = NULL,
.acquireNotifierConfig = {
.sysIntSrc = (cy_en_intr_t)((uint32_t)cpuss_interrupts_ipc_0_IRQn + CY_CRYPTO_IPC_INTR_NOTIFY_NUM),
.intIdx = CY_CRYPTO_NOTIFY_CPU_INT_IDX,
.isEnabled = true
},
.cryptoErrorIntrConfig = {
.sysIntSrc = cpuss_interrupt_crypto_IRQn,
.intIdx = CY_CRYPTO_ERROR_CPU_INT_IDX,
.isEnabled = true
}
#endif
};
/* [] END OF FILE */
@@ -0,0 +1,59 @@
/***************************************************************************//**
* \file cy_crypto_config.h
* \version 1.0
*
* \brief
* This file provides user parameters for the Crypto driver.
*
********************************************************************************
* \copyright
* Copyright 2016-2017, Cypress Semiconductor Corporation. All rights reserved.
* You may use this file only in accordance with the license, terms, conditions,
* disclaimers, and limitations in the end user license agreement accompanying
* the software package with which this file was provided.
*******************************************************************************/
#if !defined(CY_CRYPTO_CONFIG_H)
#define CY_CRYPTO_CONFIG_H
#include <stddef.h>
#include <stdbool.h>
#include "cy_device_headers.h"
#include "crypto/cy_crypto_common.h"
/* Defines to configure Crypto driver */
extern const cy_stc_crypto_config_t cryptoConfig;
/**
* \addtogroup group_crypto_config_macros
* \{
*
* These constants defines an interrupts settings for IPC channel used for the
* client-server communication, and the Crypto Error IRQ
*
* Both the CM4/CM7_x and CM0+ uses IPC hardware depended interrupt sources
* through SYSINT structure.
*/
/** Defines the Crypto notify IPC interrupt number */
#define CY_CRYPTO_IPC_INTR_NOTIFY_NUM CY_IPC_INTR_CRYPTO_SRV
/** Defines the Crypto release IPC interrupt number */
#define CY_CRYPTO_IPC_INTR_RELEASE_NUM CY_IPC_INTR_CRYPTO_CLI
/** Defines the CPU Interrupt Index for the Crypto IPC server notify interrupt */
#define CY_CRYPTO_NOTIFY_CPU_INT_IDX (CPUIntIdx3_IRQn)
/** Defines the CPU Interrupt Index for the Crypto IPC client release interrupt */
#define CY_CRYPTO_RELEASE_CPU_INT_IDX (CPUIntIdx3_IRQn)
/** Defines the CPU Interrupt Index for the Crypto Error interrupt */
#define CY_CRYPTO_ERROR_CPU_INT_IDX (CPUIntIdx3_IRQn)
/** \} group_crypto_config_macros */
#endif /* #if !defined(CY_CRYPTO_CONFIG_H) */
/* [] END OF FILE */
@@ -0,0 +1,117 @@
/***************************************************************************//**
* \file cy_crypto_server.h
* \version 1.0
*
* \brief
* This file provides the prototypes for common API
* in the Crypto driver.
*
********************************************************************************
* \copyright
* Copyright 2016-2017, Cypress Semiconductor Corporation. All rights reserved.
* You may use this file only in accordance with the license, terms, conditions,
* disclaimers, and limitations in the end user license agreement accompanying
* the software package with which this file was provided.
*******************************************************************************/
#if !defined(CY_CRYPTO_SERVER_H)
#define CY_CRYPTO_SERVER_H
#include "crypto/cy_crypto_common.h"
#include "syslib/cy_syslib.h"
#if (CY_CPU_CORTEX_M0P)
#if (CPUSS_CRYPTO_PRESENT == 1)
/**
* \addtogroup group_crypto_srv_functions
* \{
*/
/*******************************************************************************
* Function Name: Cy_Crypto_Server_Start
****************************************************************************//**
*
* This function starts the Crypto server on the CM0+ core, sets up an interrupt
* for the IPC Crypto channel on the CM0+ core, sets up an interrupt
* to catch Crypto HW errors. Should be invoked only on CM0.
*
* This function available for CM0+ core only.
*
* \param config
* The Crypto configuration structure.
*
* \param context
* The pointer to the \ref cy_stc_crypto_server_context_t structure that stores
* the Crypto server context.
*
* \return
* A Crypto status \ref cy_en_crypto_status_t.
*
*******************************************************************************/
cy_en_crypto_status_t Cy_Crypto_Server_Start(cy_stc_crypto_config_t const *config,
cy_stc_crypto_server_context_t *context);
/*******************************************************************************
* Function Name: Cy_Crypto_Server_Stop
****************************************************************************//**
*
* This function stops the Crypto server by disabling the IPC notify interrupt
* and Crypto error interrupt. Should be invoked only on CM0.
*
* This function available for CM0+ core only.
*
* \return
* A Crypto status \ref cy_en_crypto_status_t.
*
*******************************************************************************/
cy_en_crypto_status_t Cy_Crypto_Server_Stop(void);
/*******************************************************************************
* Function Name: Cy_Crypto_Server_Process
****************************************************************************//**
*
* This function parses input data received from the Crypto Client,
* runs the appropriate Crypto function and releases the Crypto IPC channel.
*
* This function available for CM0+ core only.
*
*******************************************************************************/
void Cy_Crypto_Server_Process(void);
/*******************************************************************************
* Function Name: Cy_Crypto_Server_GetDataHandler
****************************************************************************//**
*
* This function is a IPC Crypto channel notify interrupt-routine.
* It receives information from the Crypto client,
* runs the process if user not setup own handler.
*
* This function available for CM0+ core only.
*
*******************************************************************************/
void Cy_Crypto_Server_GetDataHandler(void);
/*******************************************************************************
* Function Name: Cy_Crypto_Server_ErrorHandler
****************************************************************************//**
*
* This function is a routine to handle an interrupt caused by the Crypto hardware error.
*
* This function available for CM0+ core only.
*
*******************************************************************************/
void Cy_Crypto_Server_ErrorHandler(void);
/** \} group_crypto_srv_functions */
#endif /* #if (CPUSS_CRYPTO_PRESENT == 1) */
#endif /* #if (CY_CPU_CORTEX_M0P) */
#endif /* #if !defined(CY_CRYPTO_SERVER_H) */
/* [] END OF FILE */
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,521 @@
/***************************************************************************//**
* \file cxpi.h
* \version 1.0
*
* \brief
* Provides an API declaration of the CXPI driver
*
* \note
* Generator version: draft verision
* Database revision: https://svn.design.cypress.com:18080/svn/chips/trunk/s40/MXS40/Platform/MXS40-SAS/Configuration/MXS40-IP-CXPI.xlsm
[rev.185188]
*
********************************************************************************
* \copyright
* Copyright 2017-2018, Cypress Semiconductor Corporation. All rights reserved.
* You may use this file only in accordance with the license, terms, conditions,
* disclaimers, and limitations in the end user license agreement accompanying
* the software package with which this file was provided.
*******************************************************************************/
/**
* \defgroup group_cxpi Clock eXtension Peripheral Interface (CXPI)
* \{
* This driver provides global CXPI defines and API function definitions.
*
* \defgroup group_cxpi_macros Macro
* \defgroup group_cxpi_functions Functions
* \defgroup group_cxpi_data_structures Data structures
* \defgroup group_cxpi_enums Enumerated types
*/
#if !defined(CY_CXPI_H)
#define CY_CXPI_H
/*****************************************************************************/
/* Include files */
/*****************************************************************************/
#include <stddef.h>
#include "syslib/cy_syslib.h"
#include "cy_device_headers.h"
#if defined(__cplusplus)
extern "C" {
#endif
/**
* \addtogroup group_cxpi_macros
* \{
*/
/*****************************************************************************/
/* Global pre-processor symbols/macros ('#define') */
/*****************************************************************************/
/** Driver major version */
#define CY_CXPI_DRV_VERSION_MAJOR 1
/** Driver minor version */
#define CY_CXPI_DRV_VERSION_MINOR 0
/** CXPI driver ID */
#define CY_CXPI_ID CY_PDL_DRV_ID(0x37u) //need modified
/** \} group_cxpi_macros */
/**
* \addtogroup group_cxpi_enums
* \{
*/
/** CXPI API status definition */
typedef enum
{
CY_CXPI_SUCCESS = 0x00u, /**< Returned successful */
//CY_CXPI_BAD_PARAM = CY_CXPI_ID | CY_PDL_STATUS_ERROR | 0x01u, /**< Bad parameter was passed */
CY_CXPI_BAD_PARAM = 0x01u,
//CY_CXPI_BUSY = CY_CXPI_ID | CY_PDL_STATUS_ERROR | 0x02u, /**< Change settings while tx/rx on-going */
CY_CXPI_BUSY = 0x02u,
//CY_CXPI_FRAME_NOT_RECEIVED = CY_CXPI_ID | CY_PDL_STATUS_ERROR | 0x03u, /**< No frame received */
CY_CXPI_FRAME_NOT_RECEIVED = 0x03u,
} cy_en_cxpi_status_t;
/** \} group_cxpi_enums */
/**
* \addtogroup group_cxpi_macros
* \{
*/
/** Maximum reversed ID */
#define CXPI_REV_ID_MAX (0x79)
/** Maximum data length */
#define CXPI_DATA_LENGTH_MAX (255u)
/** Minimum data length */
#define CXPI_DATA_LENGTH_MIN (1u)
/** Maximum counter = 3 */
#define CXPI_COUNTER_MAX (3u)
/** Maximum time out = 10Tbits*/
#define CXPI_TIMEOUT_MAX (10u)
/** Maximum wake up pulse low period = 50Tbits*/
#define CXPI_T_WAKEUP_LENGTH_MAX (50u)
/** Minimum wake up pulse low period = 1Tbits*/
#define CXPI_T_WAKEUP_LENGTH_MIN (1u)
/** Maximum low count for logic "1" = 400 Tbits*/
#define CXPI_T_LOW1_MAX (400u)
/** Minimum low count for logic "1" = 1 Tbits*/
#define CXPI_T_LOW1_MIN (1u)
/** Maximim low count for logic "0" = 400 Tbits*/
#define CXPI_T_LOW0_MAX (400u)
/** Minimum low count for logic "0" = 1 Tbits*/
#define CXPI_T_LOW0_MIN (1u)
/** Maximim offset value = 400 Tbits*/
#define CXPI_T_OFFSET_MAX (400u)
/** Minimum offset value = 1 Tbits*/
#define CXPI_T_OFFSET_MIN (1u)
/** Maximum retries after arbitration lost = 3 times */
#define CXPI_RETRY_MAX (3u)
/**Maximum number of entries of TX_FIFO */
#define CXPI_TX_FIFO_ENTRIESNUM_MAX (16u)
/**Maximum number of entries of RX_FIFO */
#define CXPI_RX_FIFO_ENTRIESNUM_MAX (16u)
/** Hardware TX_FIFO size */
#define CXPI_TX_FIFO_SIZE (16u)
/** Hardware RX_FIFO size */
#define CXPI_RX_FIFO_SIZE (16u)
#define CXPI_PTYPE (0x0)
#define CXPI_SLEEP_MODE (0x0)
#define CXPI_STANDBY_MODE (0x1)
#define CXPI_NORMAL_MODE (0x2)
/**
* Specifies the parameter values passed to CXPI command API
*/
#define CXPI_CMD_TX_HEADER (CXPI_CH_CMD_TX_HEADER_Msk)
#define CXPI_CMD_RX_HEADER (CXPI_CH_CMD_RX_HEADER_Msk)
#define CXPI_CMD_TX_HEADER_RX_HEADER (CXPI_CH_CMD_TX_HEADER_Msk | CXPI_CH_CMD_RX_HEADER_Msk)
#define CXPI_CMD_TX_RESPONSE (CXPI_CH_CMD_TX_RESPONSE_Msk)
#define CXPI_CMD_RX_RESPONSE (CXPI_CH_CMD_RX_RESPONSE_Msk)
#define CXPI_CMD_TX_HEADER_TX_RESPONSE (CXPI_CH_CMD_TX_HEADER_Msk | CXPI_CH_CMD_TX_RESPONSE_Msk)
#define CXPI_CMD_TX_HEADER_RX_RESPONSE (CXPI_CH_CMD_TX_HEADER_Msk | CXPI_CH_CMD_RX_RESPONSE_Msk)
#define CXPI_CMD_RX_HEADER_RX_RESPONSE (CXPI_CH_CMD_RX_HEADER_Msk | CXPI_CH_CMD_RX_RESPONSE_Msk)
#define CXPI_CMD_TX_WAKEUP_PULSE (CXPI_CH_CMD_TX_WAKEUP_PULSE_Msk)
#define CXPI_CMD_SLEEP (CXPI_CH_CMD_SLEEP_Msk)
#define CXPI_CMD_WAKE_TO_STANDBY (CXPI_CH_CMD_WAKE_TO_STANDBY_Msk)
#define CXPI_CMD_IFS_WAIT (CXPI_CH_CMD_IFS_WAIT_Msk)
/** \} group_cxpi_cmd_macro */
/**
* Specifies the mask value for interrupt status/mask
*/
#define CXPI_INTR_TX_HEADER_DONE (CXPI_CH_INTR_TX_HEADER_DONE_Msk)
#define CXPI_INTR_TX_RESPONSE_DONE (CXPI_CH_INTR_TX_RESPONSE_DONE_Msk)
#define CXPI_INTR_TX_WAKEUP_DONE (CXPI_CH_INTR_TX_WAKEUP_DONE_Msk)
#define CXPI_INTR_TX_FIFO_TRIGGER (CXPI_CH_INTR_TX_FIFO_TRIGGER_Msk)
#define CXPI_INTR_RX_HEADER_DONE (CXPI_CH_INTR_RX_HEADER_DONE_Msk)
#define CXPI_INTR_RX_RESPONSE_DONE (CXPI_CH_INTR_RX_RESPONSE_DONE_Msk)
#define CXPI_INTR_RX_WAKEUP_DETECT (CXPI_CH_INTR_RX_WAKEUP_DETECT_Msk)
#define CXPI_INTR_RX_FIFO_TRIGGER (CXPI_CH_INTR_RX_FIFO_TRIGGER_Msk)
#define CXPI_INTR_RX_HEADER_PID_DONE (CXPI_CH_INTR_RX_HEADER_PID_DONE_Msk)
#define CXPI_INTR_TXRX_COMPLETE (CXPI_CH_INTR_TXRX_COMPLETE_Msk)
#define CXPI_INTR_TIMEOUT (CXPI_CH_INTR_TIMEOUT_Msk)
#define CXPI_INTR_TX_HEADER_ARB_LOST (CXPI_CH_INTR_TX_HEADER_ARB_LOST_Msk)
#define CXPI_INTR_TX_BIT_ERROR (CXPI_CH_INTR_TX_BIT_ERROR_Msk)
#define CXPI_INTR_RX_CRC_ERROR (CXPI_CH_INTR_RX_CRC_ERROR_Msk)
#define CXPI_INTR_RX_HEADER_PARITY_ERROR (CXPI_CH_INTR_RX_HEADER_PARITY_ERROR_Msk)
#define CXPI_INTR_RX_DATA_LENGTH_ERROR (CXPI_CH_INTR_RX_DATA_LENGTH_ERROR_Msk)
#define CXPI_INTR_TX_DATA_LENGTH_ERROR (CXPI_CH_INTR_TX_DATA_LENGTH_ERROR_Msk)
#define CXPI_INTR_RX_OVERFLOW_ERROR (CXPI_CH_INTR_RX_OVERFLOW_ERROR_Msk)
#define CXPI_INTR_TX_OVERFLOW_ERROR (CXPI_CH_INTR_TX_OVERFLOW_ERROR_Msk)
#define CXPI_INTR_RX_UNDERFLOW_ERROR (CXPI_CH_INTR_RX_UNDERFLOW_ERROR_Msk)
#define CXPI_INTR_TX_UNDERFLOW_ERROR (CXPI_CH_INTR_TX_UNDERFLOW_ERROR_Msk)
#define CXPI_INTR_RX_FRAME_ERROR (CXPI_CH_INTR_RX_FRAME_ERROR_Msk)
#define CXPI_INTR_TX_FRAME_ERROR (CXPI_CH_INTR_TX_FRAME_ERROR_Msk)
#define CXPI_INTR_ALL_ERROR_MASK (CXPI_CH_INTR_TX_BIT_ERROR_Msk |\
CXPI_CH_INTR_RX_CRC_ERROR_Msk |\
CXPI_CH_INTR_RX_HEADER_PARITY_ERROR_Msk |\
CXPI_CH_INTR_RX_DATA_LENGTH_ERROR_Msk |\
CXPI_CH_INTR_TX_DATA_LENGTH_ERROR_Msk |\
CXPI_CH_INTR_RX_OVERFLOW_ERROR_Msk |\
CXPI_CH_INTR_TX_OVERFLOW_ERROR_Msk |\
CXPI_CH_INTR_RX_UNDERFLOW_ERROR_Msk |\
CXPI_CH_INTR_TX_UNDERFLOW_ERROR_Msk |\
CXPI_CH_INTR_RX_FRAME_ERROR_Msk |\
CXPI_CH_INTR_TX_FRAME_ERROR_Msk)
/** \} group_cxpi_macros */
/*****************************************************************************/
/* Global type definitions ('typedef') */
/*****************************************************************************/
/**
* \addtogroup group_cxpi_enums
* \{
*/
/**
*****************************************************************************
** \brief CXPI mode of operation
**
** This configuration is effective only when corresponding channel = master mode.
*****************************************************************************/
typedef enum en_cxpi_mode{
CXPI_NRZ_Mode = 0, /*!< NRZ mode */
CXPI_PWM_Mode = 1, /*!< PWM mode */
}en_cxpi_mode_t;
typedef enum en_bit_error_ignore{
MESSAGE_TRANFER_ABORTED = 0, /*!< Message transfer is aborted. */
MESSAGE_TRANFER_NOT_ABORTED = 1, /*!< Message transfer is NOT aborted. */
}en_bit_error_ignore_t;
typedef enum en_master_mode{
CXPI_SLAVE_MODE = 0, /*!< Indicates CXPI as slave node. */
CXPI_MASTER_MODE = 1, /*!< Indicates CXPI as master node. */
}en_master_mode_t;
/**
*****************************************************************************
** \brief number of retries after arbitration lost
**
*****************************************************************************/
typedef enum en_cxpi_retries
{
CxpiNoRetries = 0, /*!< no retries */
CxpiRetriesOneTime = 1, /*!< 1 retries */
CxpiRetriesTwoTime = 2, /*!< 2 retries */
CxpiRetriesThreeTime = 3 /*!< 3 retries */
}en_cxpi_retries_t;
/**
*****************************************************************************
** \brief timeout selection.
**
*****************************************************************************/
typedef enum en_cxpi_timeout_sel
{
CxpiTimeoutDisabled = 0, /*!< Timeout check is disabled */
CxpiTimeoutCheckHdrRes = 1, /*!< Timeout check is enabled and HW will refer to TIMEOUT_LENGTH as number of Tbits allowed between header and response */
CxpiTimeoutCheckAllByte = 2, /*!< Timeout check is enabled to check all bytes within a message frame to be space within TIMEOUT_LENGTH bit time */
}en_cxpi_timeout_sel_t;
/* CXPI state type */
typedef enum
{
CXPI_STATE_TXRX_PENDING,
CXPI_STATE_TX_PTYPE,
CXPI_STATE_TX_HDR_RX_RESP,
CXPI_STATE_TX_HDR_TX_RESP,
CXPI_STATE_RX_HDR_TX_RESP,
CXPI_STATE_RX_HDR_RX_RESP,
} en_cxpi_state_t;
/* Arbitration state type */
typedef enum
{
CXPI_ARB_PENDING,
CXPI_ARB_LOST_TX_RESP,
CXPI_ARB_LOST_RX_RESP,
} en_cxpi_arb_state_t;
/** \} group_cxpi_enums */
/**
* \addtogroup group_cxpi_data_structures
* \{
*/
/**
*****************************************************************************
** \brief CXPI_CH_CLT0 configuration for modes, offset, or master/slave
**
*****************************************************************************/
typedef struct stc_cxpi_ch_ctl0_config
{
/** Mode of operation */
en_cxpi_mode_t enMode;
/** If TRUE, corresponding CXPI channel transceiver is enabled automatically,
* the TX_RX_STATUS.EN_OUT field is controlled by HW.
* If FALSE, firmware has to handle the transceiver enable signal manually
*/
bool bCxpiTransceiverAutoEnable;
/** Receive PID Zero Check Enable
* If TRUE, If received PID[6:0] = 0 and PID[7]=1'b1, HW does not clear CMD.RX_HEADER
* and will anticipate receiving header again. Should be TRUE where polling is enabled
* and CXPI controller is configured as slave.
* If FALSE, no action if received PID[6:0] = 0 and PID[7]=1'b1.
*/
bool bRxPIDZeroAutoCheckEnable;
/** If TRUE, cxpi_rx_in filter operates.
* Median 3 operates on the last three "cxpi_rx_in" values.
* The sequences '000', '001', '010' and '100' result in a filtered value '0'.
* The sequences '111', '110', '101' and '011' result in a filtered value '1'.
*/
bool bFilterEnable;
/** Inter Frame Space in bit periods */
uint8_t u8IFS;
/** Inter Byte Space in bit periods */
uint8_t u8IBS;
/** Specifies behavior on a detected bit error during header or response transmission.
* If TRUE, message transfer is NOT aborted.
* If FALSE, message transfer is NOT aborted.
*/
en_bit_error_ignore_t enBitErrorIgnore;
/** CXPI master mode.
* If TRUE, use CXPI as master node.
* If FALSE, use CXPI as slave node.
*/
en_master_mode_t enCxpiMasterMode;
}stc_cxpi_ch_ctl0_config_t;
/**
*****************************************************************************
** \brief CXPI_CH_CLT1 configuration for timing controls at Data link layer.
**
*****************************************************************************/
typedef struct stc_cxpi_ch_ctl1_config
{
/** Low count for logic 1.
* The count value here indicates the number of clocks per clk_cxpi_ch
* to drive a '0' at CXPI bus before releasing it to indicate a logical '1'. */
uint16_t u16TLow1;
/** Low count for logic 0.
* The count value here indicates the number of clocks per clk_cxpi_ch
* to drive a '0' at CXPI bus before releasing it to indicate a logical '1'. */
uint16_t u16TLow0;
/** The value of offset that is used for sampling the 'rx'. */
uint16_t u16TOffset;
}stc_cxpi_ch_ctl1_config_t;
/**
*****************************************************************************
** \brief CXPI_CH_CLT2 configuration for retry, wakeup pulse length, time out.
**
*****************************************************************************/
typedef struct stc_cxpi_ch_ctl2_config
{
/** Number of retries after arbitration lost. */
en_cxpi_retries_t enRetriesNumber;
/** Specifies the wake up pulse low period in Tbits that is transmitted during Standby mode. */
uint8_t u8TWakeUpLength;
/** Timeout Length (in Tbits). Specifies the number of Tbits to exceed timeout between frame bytes
* within a message frame. CXPI spec states that the maximum allowed inter byte space (IBS) is 9Tbits
*/
uint8_t u8TimeoutLength;
/** Timeout Select */
en_cxpi_timeout_sel_t enTimeoutSel;
}stc_cxpi_ch_ctl2_config_t;
typedef struct stc_cxpi_frame_info{
uint8_t datalength;
uint8_t SleepInd;
uint8_t WakeupInd;
uint8_t counter;
} stc_cxpi_frame_info_t;
/* CXPI frame configuration */
typedef struct cxpi_response
{
stc_cxpi_frame_info_t frameIF;
uint8_t dataBuffer[CXPI_DATA_LENGTH_MAX];
} cxpi_response_t;
typedef struct cxpi_frame_context
{
uint8_t id;
cxpi_response_t response;
} cxpi_frame_context_t;
typedef struct stc_CXPI_context
{
volatile stc_CXPI_CH_t *pstcInstanceCxpi;
uint8_t* pAcceptedPIDList;
uint32_t numberOfAcceptedPID;
uint8_t *rxBuf; /**< The pointer to the receive buffer */
uint8_t volatile rxBuffCount; /**< The receive buffer size */
uint8_t volatile rxBufIdx; /**< The current location in the receive buffer */
uint8_t *txBuf; /**< The pointer to the transmit buffer */
uint8_t volatile txBuffCount; /**< The transmit buffer size */
uint8_t volatile txBufIdx; /**< The current location in the transmit buffer */
en_cxpi_state_t volatile state;
en_cxpi_arb_state_t volatile arbState;
uint8_t maximumRetries;
uint8_t volatile retriesCount;
uint8_t transmittingFrameId;
cxpi_response_t* pTransmittingFrameResponse;
cxpi_frame_context_t transmittingFrame;
cxpi_frame_context_t receivedFrame;
void (*pNotifyTrasmittedWakeupPulse)(void);
void (*pNotifyRXFallingEdgeDetected)(void);
void (*pNotifyError)(uint32_t);
void (*pNotifySentPTYPE)(void);
void (*pNotifyReceivedPTYPE)(void);
void (*pNotifyReceivedPID)(uint8_t);
void (*pNotifyReceivedResponse)(cxpi_frame_context_t*);
void (*pNotifyArbitrationLost)(void);
}stc_CXPI_context_t;
/**
*****************************************************************************
** \brief CXPI configuration
** This settings are per CXPI instance.
*****************************************************************************/
typedef struct stc_cxpi_config
{
stc_cxpi_ch_ctl0_config_t stcCxpiChCtl0Config;
stc_cxpi_ch_ctl1_config_t stcCxpiChCtl1Config;
stc_cxpi_ch_ctl2_config_t stcCxpiChCtl2Config;
uint8_t* pAcceptedPIDList;
uint32_t numberOfAcceptedPID;
uint32_t maximumRetries;
void (*pNotifyTrasmittedWakeupPulse)(void);
void (*pNotifyRXFallingEdgeDetected)(void);
void (*pNotifyError)(uint32_t);
void (*pNotifySentPTYPE)(void);
void (*pNotifyReceivedPTYPE)(void);
void (*pNotifyReceivedPID)(uint8_t);
void (*pNotifyReceivedResponse)(cxpi_frame_context_t*);
void (*pNotifyArbitrationLost)(void);
}stc_cxpi_config_t;
/** \} group_cxpi_data_structures */
/**
*****************************************************************************
** \brief CXPI context structure
**
*****************************************************************************/
/*****************************************************************************/
/* Global variable declarations ('extern', definition in C source) */
/*****************************************************************************/
/*****************************************************************************/
/* Global function prototypes ('extern', definition in C source) */
/*****************************************************************************/
/**
* \addtogroup group_cxpi_functions
* \{
*/
cy_en_cxpi_status_t Cy_CXPI_DeInit( volatile stc_CXPI_CH_t *pstcCXPI ); //done
cy_en_cxpi_status_t Cy_CXPI_Init( volatile stc_CXPI_CH_t *pstcCXPI, const stc_cxpi_config_t *pstcConfig, stc_CXPI_context_t *pCxpiCtx); //done w/o comment
cy_en_cxpi_status_t Cy_CXPI_Enable(volatile stc_CXPI_CH_t *pstcCXPI); //done
cy_en_cxpi_status_t Cy_CXPI_Disable(volatile stc_CXPI_CH_t *pstcCXPI); //done
cy_en_cxpi_status_t Cy_CXPI_SetCmd(volatile stc_CXPI_CH_t *pstcCXPI, uint32_t command);
cy_en_cxpi_status_t Cy_CXPI_GetStatus(volatile stc_CXPI_CH_t *pstcCXPI, uint32_t *status); //done
cy_en_cxpi_status_t Cy_CXPI_SetPID(volatile stc_CXPI_CH_t *pstcCXPI, uint8_t id); //done
cy_en_cxpi_status_t Cy_CXPI_GetPID(volatile stc_CXPI_CH_t *pstcCXPI, uint8_t* id, uint8_t* parity); //done
cy_en_cxpi_status_t Cy_CXPI_SetFI(volatile stc_CXPI_CH_t *pstcCXPI, stc_cxpi_frame_info_t fi); //done
cy_en_cxpi_status_t Cy_CXPI_GetFI(volatile stc_CXPI_CH_t *pstcCXPI, stc_cxpi_frame_info_t *fi); //done
cy_en_cxpi_status_t Cy_CXPI_GetCRC(volatile stc_CXPI_CH_t *pstcCXPI, uint32_t *CRCdata); //done
cy_en_cxpi_status_t Cy_CXPI_SetTriggerLevelTxFIFO(volatile stc_CXPI_CH_t *pstcCXPI, uint8_t triggerLevel); //done w/o comment
cy_en_cxpi_status_t Cy_CXPI_ClearTxFIFO(volatile stc_CXPI_CH_t *pstcCXPI); //done w/o comment
cy_en_cxpi_status_t Cy_CXPI_FreezeTxFIFO(volatile stc_CXPI_CH_t *pstcCXPI); //done w/o comment
cy_en_cxpi_status_t Cy_CXPI_UnfreezeTxFIFO(volatile stc_CXPI_CH_t *pstcCXPI); //done w/o comment
cy_en_cxpi_status_t Cy_CXPI_GetTxFIFOStatus(volatile stc_CXPI_CH_t *pstcCXPI, uint32_t *usedEnntries, uint32_t *availEntries); //done w/o comment
cy_en_cxpi_status_t Cy_CXPI_WriteTxFIFO( volatile stc_CXPI_CH_t *pstcCXPI, const uint8_t data);
cy_en_cxpi_status_t Cy_CXPI_SetTriggerLevelRxFIFO(volatile stc_CXPI_CH_t *pstcCXPI, uint8_t triggerLevel); //done w/o comment
cy_en_cxpi_status_t Cy_CXPI_ClearRxFIFO(volatile stc_CXPI_CH_t *pstcCXPI); //done w/o comment
cy_en_cxpi_status_t Cy_CXPI_FreezeRxFIFO(volatile stc_CXPI_CH_t *pstcCXPI); //done w/o comment
cy_en_cxpi_status_t Cy_CXPI_UnfreezeRxFIFO(volatile stc_CXPI_CH_t *pstcCXPI); //done w/o comment
cy_en_cxpi_status_t Cy_CXPI_GetRxFIFOStatus(volatile stc_CXPI_CH_t *pstcCXPI, uint32_t *usedEnntries, uint32_t *availEntries); //done w/o comment
cy_en_cxpi_status_t Cy_CXPI_ReadRxFIFO( volatile stc_CXPI_CH_t *pstcCXPI, uint8_t *data); //done w/o comment
cy_en_cxpi_status_t Cy_CXPI_SilentReadRxFIFO(volatile stc_CXPI_CH_t *pstcCXPI, uint8_t *data); //done w/o comment
cy_en_cxpi_status_t Cy_CXPI_SetInterruptMask(volatile stc_CXPI_CH_t *pstcCXPI, uint32_t mask); //done
cy_en_cxpi_status_t Cy_CXPI_GetInterruptMask(volatile stc_CXPI_CH_t *pstcCXPI, uint32_t *mask); //done
cy_en_cxpi_status_t Cy_CXPI_GetInterruptMaskedStatus(volatile stc_CXPI_CH_t *pstcCXPI, uint32_t *status); //done
cy_en_cxpi_status_t Cy_CXPI_GetInterruptStatus(volatile stc_CXPI_CH_t *pstcCXPI, uint32_t *status); //done
cy_en_cxpi_status_t Cy_CXPI_ClearInterrupt(volatile stc_CXPI_CH_t *pstcCXPI, uint32_t mask); //done
cy_en_cxpi_status_t Cy_CXPI_SendWakeupPulse(volatile stc_CXPI_CH_t *pstcCXPI, uint32_t tWakeupLength);
cy_en_cxpi_status_t Cy_CXPI_IFSWait(volatile stc_CXPI_CH_t *pstcCXPI);
cy_en_cxpi_status_t Cy_CXPI_SetMode(volatile stc_CXPI_CH_t *pstcCXPI, stc_CXPI_context_t *cxpiCtx, uint32_t mode);
cy_en_cxpi_status_t Cy_CXPI_SendPTYPE(volatile stc_CXPI_CH_t *pstcCXPI, stc_CXPI_context_t *cxpiCtx);
cy_en_cxpi_status_t Cy_CXPI_SendPID(volatile stc_CXPI_CH_t *pstcCXPI, stc_CXPI_context_t *cxpiCtx, uint8_t frameID, bool withResponse, cxpi_response_t *pResponse, bool IFSwait);
cy_en_cxpi_status_t Cy_CXPI_SendResp(volatile stc_CXPI_CH_t *pstcCXPI, stc_CXPI_context_t *cxpiCtx, cxpi_response_t *pResponse);
cy_en_cxpi_status_t Cy_CXPI_Interrupt(volatile stc_CXPI_CH_t *pstcCXPI, stc_CXPI_context_t *cxpiCtx);
void HeaderReceptionOperation(volatile stc_CXPI_CH_t* pstcCXPI, stc_CXPI_context_t* pCxpiCtx);
void TXRXCompletionOperation(volatile stc_CXPI_CH_t* pstcCXPI, stc_CXPI_context_t* pCxpiCtx);
void TXHandler(volatile stc_CXPI_CH_t* pstcCXPI, stc_CXPI_context_t* pCxpiCtx);
void RXHandler(volatile stc_CXPI_CH_t* pstcCXPI, stc_CXPI_context_t* pCxpiCtx);
void RXResponseDoneHandler(volatile stc_CXPI_CH_t* pstcCXPI, stc_CXPI_context_t* pCxpiCtx);
/** \} group_cxpi_functions */
#ifdef __cplusplus
}
#endif
#endif /* __CY_CXPI_H__ */
/*****************************************************************************/
/* EOF (not truncated) */
/*****************************************************************************/
@@ -0,0 +1,428 @@
/***************************************************************************//**
* \file cy_mdma.c
* \version 1.0
*
* \brief
* The MDMA driver.
*
********************************************************************************
* \copyright
* Copyright 2016-2017, Cypress Semiconductor Corporation. All rights reserved.
* You may use this file only in accordance with the license, terms, conditions,
* disclaimers, and limitations in the end user license agreement accompanying
* the software package with which this file was provided.
*******************************************************************************/
#include "cy_mdma.h"
#if defined(__cplusplus)
extern "C" {
#endif
/*******************************************************************************
* Function Name: Cy_MDMA_Descr_Init
****************************************************************************//**
*
* This function initializes descriptor structure in SRAM from a pre-initialized
* configuration structure.
* This function initializes only the descriptor and not the channel.
* This function will operate on the descriptor only if it was defined as a RAM
* variable.
* If the descriptor is defined in Flash, then the user must use the
* configuration defines to initialize it.
*
* \param descriptor
* This is an instance of the descriptor structure declared by the user and
* initialized by this function.
*
* \param config
* This is a configuration structure that has all initialization information for
* the descriptor.
*
* \return
* This function returns /ref cy_en_mdma_status_t.
*
*******************************************************************************/
cy_en_mdma_status_t Cy_MDMA_Descr_Init(cy_stc_mdma_descr_t* descriptor, const cy_stc_mdma_descr_config_t* config)
{
cy_en_mdma_status_t retVal = CY_MDMA_ERR_UNC;
if ((descriptor != NULL) && (config != NULL))
{
/* Descriptor[0] */
descriptor->unMDMA_DESCR_CTL.stcField.u2WAIT_FOR_DEACT = config->deact;
descriptor->unMDMA_DESCR_CTL.stcField.u2INTR_TYPE = config->intrType;
descriptor->unMDMA_DESCR_CTL.stcField.u2TR_OUT_TYPE = config->trigoutType;
descriptor->unMDMA_DESCR_CTL.stcField.u2TR_IN_TYPE = config->triginType;
descriptor->unMDMA_DESCR_CTL.stcField.u1DATA_PREFETCH = config->dataPrefetch;
descriptor->unMDMA_DESCR_CTL.stcField.u2DATA_SIZE = config->dataSize;
descriptor->unMDMA_DESCR_CTL.stcField.u1CH_DISABLE = config->chStateAtCmplt;
descriptor->unMDMA_DESCR_CTL.stcField.u1SRC_TRANSFER_SIZE = config->srcTxfrSize;
descriptor->unMDMA_DESCR_CTL.stcField.u1DST_TRANSFER_SIZE = config->destTxfrSize;
descriptor->unMDMA_DESCR_CTL.stcField.u3DESCR_TYPE = config->descrType;
/* Descriptor[1] */
descriptor->u32MDMA_DESCR_SRC = (uint32_t)config->srcAddr;
/* after 3rd word of descriptor depends on descriptor type */
switch(config->descrType)
{
case (uint32_t)CY_MDMA_SINGLE_TRANSFER:
{
/* Descriptor[2] */
descriptor->u32MDMA_DESCR_DST = (uint32_t)config->destAddr;
/* Descriptor[3] -> NEXT_PTR */
descriptor->unMDMA_DESCR_X_SIZE.u32Register = (uint32_t)config->descrNext;
break;
}
case (uint32_t)CY_MDMA_1D_TRANSFER:
{
/* Descriptor[2] */
descriptor->u32MDMA_DESCR_DST = (uint32_t)config->destAddr;
/* Descriptor[3] */
descriptor->unMDMA_DESCR_X_SIZE.stcField.u16X_COUNT = (uint32_t)((config->xCount) - 1ul);
/* Descriptor[4] */
descriptor->unMDMA_DESCR_X_INCR.stcField.u16SRC_X_INCR = (uint32_t)config->srcXincr;
descriptor->unMDMA_DESCR_X_INCR.stcField.u16DST_X_INCR = (uint32_t)config->destXincr;
/* Descriptor[5] -> NEXT_PTR */
descriptor->unMDMA_DESCR_Y_SIZE.u32Register = (uint32_t)config->descrNext;
break;
}
case (uint32_t)CY_MDMA_2D_TRANSFER:
{
/* Descriptor[2] */
descriptor->u32MDMA_DESCR_DST = (uint32_t)config->destAddr;
/* Descriptor[3] */
descriptor->unMDMA_DESCR_X_SIZE.stcField.u16X_COUNT = (uint32_t)((config->xCount) - 1ul);
/* Descriptor[4] */
descriptor->unMDMA_DESCR_X_INCR.stcField.u16SRC_X_INCR = (uint32_t)config->srcXincr;
descriptor->unMDMA_DESCR_X_INCR.stcField.u16DST_X_INCR = (uint32_t)config->destXincr;
/* Descriptor[5] */
descriptor->unMDMA_DESCR_Y_SIZE.stcField.u16Y_COUNT = (uint32_t)((config->yCount) - 1ul);
/* Descriptor[6] */
descriptor->unMDMA_DESCR_Y_INCR.stcField.u16SRC_Y_INCR = (uint32_t)config->srcYincr;
descriptor->unMDMA_DESCR_Y_INCR.stcField.u16DST_Y_INCR = (uint32_t)config->destYincr;
/* Descriptor[7] */
descriptor->u32MDMA_DESCR_NEXT_PTR = (uint32_t)config->descrNext;
break;
}
case (uint32_t)CY_MDMA_MEMORY_COPY_TRANSFER:
{
/* Descriptor[2] */
descriptor->u32MDMA_DESCR_DST = (uint32_t)config->destAddr;
/* Descriptor[3] */
descriptor->unMDMA_DESCR_X_SIZE.stcField.u16X_COUNT = (uint32_t)((config->xCount) - 1ul);
/* Descriptor[4] -> NEXT_PTR */
descriptor->unMDMA_DESCR_X_INCR.u32Register = (uint32_t)config->descrNext;
break;
}
case (uint32_t)CY_MDMA_SCATTER_TRANSFER:
{
/* Descriptor[2] -> X_SIZE */
descriptor->u32MDMA_DESCR_DST = (uint32_t)((config->xCount) - 1ul);
/* Descriptor[3] -> NEXT_PTR */
descriptor->unMDMA_DESCR_X_SIZE.u32Register = (uint32_t)config->descrNext;
break;
}
default:
{
/* Unsupported type of descriptor */
break;
}
}
retVal = CY_MDMA_SUCCESS;
}
else
{
retVal = CY_MDMA_INVALID_INPUT_PARAMETERS;
}
return retVal;
}
/*******************************************************************************
* Function Name: Cy_MDMA_Descr_DeInit
****************************************************************************//**
*
* This function clears all the content of the descriptor structure.
* This function will operate in the descriptor only if it was defined as a RAM
* variable.
* If the descriptor is being defined in Flash, then the user can't use this
* function to deinitialize it.
*
* \param descriptor
* This is an instance of the descriptor structure to be cleared.
*
*******************************************************************************/
void Cy_MDMA_Descr_DeInit(cy_stc_mdma_descr_t* descriptor)
{
descriptor->unMDMA_DESCR_CTL.u32Register = 0ul;
descriptor->u32MDMA_DESCR_SRC = 0ul;
descriptor->u32MDMA_DESCR_DST = 0ul;
descriptor->unMDMA_DESCR_X_SIZE.u32Register = 0ul;
descriptor->unMDMA_DESCR_X_INCR.u32Register = 0ul;
descriptor->unMDMA_DESCR_Y_SIZE.u32Register = 0ul;
descriptor->unMDMA_DESCR_Y_INCR.u32Register = 0ul;
descriptor->u32MDMA_DESCR_NEXT_PTR = 0ul;
}
/*******************************************************************************
* Function Name: Cy_MDMA_Descr_SetTxfrWidth
****************************************************************************//**
*
* This function sets the transfer widths for for the descriptor structure.
* This function will operate in the descriptor only if it was defined as a RAM
* variable.
* If the descriptor is defined in Flash, then the user must use the
* configuration defines to initialize it.
*
* \param descriptor
* This is a descriptor-structure instance declared by the user. This is the
* descriptor being modified.
*
* \param dataElementSize
* This parameter provides the data element size of the descriptor.
* \ref cy_en_mdma_datasize_t
*
* \param srcTxfrWidth
* This parameter provides the source transfer size parameters of the descriptor.
* \ref cy_en_mdma_txfrsize_t
*
* \param dstTxfrWidth
* This parameter provides the destination transfer size parameters of the
* descriptor.
* \ref cy_en_mdma_txfrsize_t
*
*******************************************************************************/
void Cy_MDMA_Descr_SetTxfrWidth(cy_stc_mdma_descr_t* descriptor,
uint32_t dataElementSize,
uint32_t srcTxfrWidth,
uint32_t dstTxfrWidth)
{
descriptor->unMDMA_DESCR_CTL.stcField.u2DATA_SIZE = dataElementSize;
descriptor->unMDMA_DESCR_CTL.stcField.u1SRC_TRANSFER_SIZE = srcTxfrWidth;
descriptor->unMDMA_DESCR_CTL.stcField.u1DST_TRANSFER_SIZE = dstTxfrWidth;
}
/*******************************************************************************
* Function Name: Cy_MDMA_Chnl_Init
****************************************************************************//**
*
* Initializes the MDMA channel with a descriptor and other parameters.
*
* \param ptscMDMA
* Pointer to the hardware MDMA block.
*
* \param chNum
* Channel number of the MDMA.
*
* \param chnlConfig
* This parameter is a structure that has the initialization information for the
* channel.
*
* \return
* This function returns /ref cy_en_mdma_status_t.
*
*******************************************************************************/
cy_en_mdma_status_t Cy_MDMA_Chnl_Init(volatile stc_DMAC_t *pstcMDMA, uint32_t chNum, const cy_stc_mdma_chnl_config_t* chnlConfig)
{
cy_en_mdma_status_t retVal = CY_MDMA_ERR_UNC;
if ((pstcMDMA != NULL) && (chnlConfig != NULL))
{
/* Initialize the X/Y indices (which are undefined after reset) */
pstcMDMA->CH[chNum].unIDX.u32Register = 0;
/* Set current descriptor */
pstcMDMA->CH[chNum].unCURR.u32Register = (uint32_t)chnlConfig->MDMA_Descriptor;
/* Set if the channel is preemptable */
/* There is no the parameter in MDMA */
/* Set channel priority */
pstcMDMA->CH[chNum].unCTL.stcField.u2PRIO = chnlConfig->priority;
/* Set enabled status */
pstcMDMA->CH[chNum].unCTL.stcField.u1ENABLED = chnlConfig->enable;
retVal = CY_MDMA_SUCCESS;
}
else
{
retVal = CY_MDMA_INVALID_INPUT_PARAMETERS;
}
return (retVal);
}
/*******************************************************************************
* Function Name: Cy_MDMA_Chnl_DeInit
****************************************************************************//**
*
* Clears all the content of registers corresponding to the channel.
*
* \param ptscMDMA
* Pointer to the hardware MDMA block.
*
* \param chNum
* Channel number of the MDMA.
*
*******************************************************************************/
void Cy_MDMA_Chnl_DeInit(volatile stc_DMAC_t *pstcMDMA, uint32_t chNum)
{
pstcMDMA->CH[chNum].unCTL.u32Register = 0ul;
pstcMDMA->CH[chNum].unIDX.u32Register = 0ul;
pstcMDMA->CH[chNum].unCURR.u32Register = 0ul;
pstcMDMA->CH[chNum].unINTR_MASK.u32Register = 0ul;
pstcMDMA->CH[chNum].unINTR_SET.u32Register = 0ul;
}
/*******************************************************************************
* Function Name: Cy_MDMA_Enable
****************************************************************************//**
*
* This function enables the MDMA block.
*
* \param ptscMDMA
* Pointer to the hardware MDMA block.
*
*******************************************************************************/
void Cy_MDMA_Enable(volatile stc_DMAC_t *pstcMDMA)
{
pstcMDMA->unCTL.stcField.u1ENABLED = 1ul;
}
/*******************************************************************************
* Function Name: Cy_MDMA_Disable
****************************************************************************//**
*
* This function disables the MDMA block.
*
* \param ptscMDMA
* Pointer to the hardware MDMA block.
*
*******************************************************************************/
void Cy_MDMA_Disable(volatile stc_DMAC_t *pstcMDMA)
{
pstcMDMA->unCTL.stcField.u1ENABLED = 0ul;
}
/*******************************************************************************
* Function Name: Cy_MDMA_GetActiveChnl
****************************************************************************//**
*
* This function used to determine the channels that are active/pending in
* the MDMA block.
*
* \param ptscMDMA
* Pointer to the hardware MDMA block.
*
* \return
* Returns a bit-field with all of the currently active/pending channels in the
* MDMA block.
*
*******************************************************************************/
uint32_t Cy_MDMA_GetActiveChnl(const volatile stc_DMAC_t *pstcMDMA)
{
return pstcMDMA->unACTIVE.u32Register;
}
/*******************************************************************************
* Function Name: Cy_MDMA_Chnl_ClearInterrupt
****************************************************************************//**
*
* This function clears the interrupt status.
*
* \param ptscMDMA
* Pointer to the hardware MDMA block.
*
* \param chNum
* Channel number of the MDMA.
*
*******************************************************************************/
void Cy_MDMA_Chnl_ClearInterrupt(volatile stc_DMAC_t *pstcMDMA, uint32_t chNum)
{
pstcMDMA->CH[chNum].unINTR.u32Register = CY_MDMA_INTR_BIT_MASK;
/* Readback of the register is required by hardware. */
(void) pstcMDMA->CH[chNum].unINTR.u32Register;
}
/*******************************************************************************
* Function Name: Cy_MDMA_Descr_SetNxtDescr
****************************************************************************//**
*
* Sets a next descriptor parameter for the descriptor structure.
* This function will operate in the descriptor only if it was defined as a RAM
* variable.
* If the descriptor is defined in Flash, then the user must use the
* configuration defines to initialize it.
* Based on descriptor type the offset of address for the next descriptor may
* vary. For a single transfer descriptor type, this register is at offset 0x0c.
* For a 1D transfer descriptor type, this register is at offset 0x10. For a 2D
* transfer descriptor type, this register is at offset 0x14.
*
* \param descriptor
* This is the descriptor-structure instance declared by the user. The function
* modifies the destination-address parameter in this descriptor.
*
* \param nxtDescriptor
* The pointer to the next descriptor.
*
*******************************************************************************/
void Cy_MDMA_Descr_SetNxtDescr(cy_stc_mdma_descr_t* descriptor, const cy_stc_mdma_descr_t* nxtDescriptor)
{
if (descriptor->unMDMA_DESCR_CTL.stcField.u3DESCR_TYPE == (uint32_t)CY_MDMA_SINGLE_TRANSFER)
{
descriptor->unMDMA_DESCR_X_SIZE.u32Register = (uint32_t)nxtDescriptor;
}
else if (descriptor->unMDMA_DESCR_CTL.stcField.u3DESCR_TYPE == (uint32_t)CY_MDMA_1D_TRANSFER)
{
descriptor->unMDMA_DESCR_Y_SIZE.u32Register = (uint32_t)nxtDescriptor;
}
else if (descriptor->unMDMA_DESCR_CTL.stcField.u3DESCR_TYPE == (uint32_t)CY_MDMA_2D_TRANSFER)
{
descriptor->u32MDMA_DESCR_NEXT_PTR = (uint32_t)nxtDescriptor;
}
else if (descriptor->unMDMA_DESCR_CTL.stcField.u3DESCR_TYPE == (uint32_t)CY_MDMA_MEMORY_COPY_TRANSFER)
{
descriptor->unMDMA_DESCR_X_INCR.u32Register = (uint32_t)nxtDescriptor;
}
else if (descriptor->unMDMA_DESCR_CTL.stcField.u3DESCR_TYPE == (uint32_t)CY_MDMA_SCATTER_TRANSFER)
{
descriptor->unMDMA_DESCR_X_SIZE.u32Register = (uint32_t)nxtDescriptor;
}
else
{
/* Unsupported type of descriptor */
}
}
#if defined(__cplusplus)
}
#endif
/* [] END OF FILE */
@@ -0,0 +1,866 @@
/***************************************************************************//**
* \file cy_mdma.h
* \version 1.0
*
* \brief
* The header file of the MDMA driver.
*
********************************************************************************
* \copyright
* Copyright 2016-2017, Cypress Semiconductor Corporation. All rights reserved.
* You may use this file only in accordance with the license, terms, conditions,
* disclaimers, and limitations in the end user license agreement accompanying
* the software package with which this file was provided.
*******************************************************************************/
/**
* \defgroup group_mdma Memory DMA (M-DMA)
* \{
* Configures a MDMA channel and its descriptor(s).
*
* The MDMA Channel component can be used in any project that needs to transfer data
* without CPU intervention, based on a hardware trigger signal from another component.
*
* A device may support more than one MDMA hardware block. Each block has a set of
* registers, and a base hardware address. Each block also supports multiple channels.
* Many API functions for the MDMA driver require the base hardware address and the
* channel number. Ensure that you use the correct hardware address for the MDMA block in use.
*
* Features:
* * Devices support one MDMA hardware block
* * Each MDMA block supports up to 16 MDMA channels
* * Supports channel descriptors in SRAM
* * Four Priority Levels for each channel
* * Byte, Half-word (2 byte), and Word (4 byte) transfers
* * Configurable source and destination addresses
*
* A simplified diagram of the M-DMA block is shown below:
* \image html dma.png
*
* \section group_mdma_configuration Configuration Considerations
*
* To set up a MDMA driver you initialize a descriptor,
* initialize and enable a channel, and enable the MDMA block.
*
* To set up the descriptor, provide the configuration parameters for the
* descriptor in the \ref cy_stc_mdma_descr_config_t structure. Then call the
* \ref Cy_MDMA_Descr_Init function to initialize the descriptor in SRAM. You can
* modify the source and destination addresses dynamically by calling
* \ref Cy_MDMA_Descr_SetSrcAddr and \ref Cy_MDMA_Descr_SetDestAddr.
*
* To set up the MDMA channel, provide a filled \ref cy_stc_mdma_chnl_config_t
* structure. Call the \ref Cy_MDMA_Chnl_Init function, specifying the channel
* number. Use \ref Cy_MDMA_Chnl_Enable to enable the configured MDMA channel.
*
* Call \ref Cy_MDMA_Chnl_Enable for each MDMA channel in use.
*
* <B>NOTE:</B> Even if a MDMA channel is enabled, it is not operational until
* the MDMA block is enabled using function \ref Cy_MDMA_Enable.\n
* <B>NOTE:</B> If the MDMA descriptor is configured to generate an interrupt,
* the interrupt must be enabled using the \ref Cy_MDMA_Chnl_SetInterruptMask
* function for each MDMA channel.
*
* \section group_mdma_more_information More Information.
*
* See the MDMA Component datasheet.
* See also the MDMA chapter of the device technical reference manual (TRM).
*
*
* \section group_mdma_changelog Changelog
*
* <table class="doxtable">
* <tr><th>Version</th><th>Changes</th><th>Reason for Change</th></tr>
* <tr>
* <td>1.0</td>
* <td>Initial version</td>
* <td></td>
* </tr>
* </table>
*
* \defgroup group_mdma_macro Macro
* \{
* \defgroup group_mdma_common_macro_MDMAIntrCauses MDMA Interrupt Causes
* \}
*
* \defgroup group_mdma_functions Functions
* \defgroup group_mdma_data_structures Data structures
* \defgroup group_mdma_enums Enumerated types
*/
#if !defined(CY_MDMA_H)
#define CY_MDMA_H
#include <stdint.h>
#include <stdbool.h>
#include <stddef.h>
#include "syslib/cy_syslib.h"
#include "cy_device_headers.h"
/*
#ifndef CY_IP_M4CPUSS_MDMA
#error "The MDMA driver is not supported on this device"
#endif
*/
#if defined(__cplusplus)
extern "C" {
#endif
/******************************************************************************
* Macro definitions *
******************************************************************************/
/**
* \addtogroup group_mdma_macro
* \{
*/
/** Driver major version */
#define CY_MDMA_DRV_VERSION_MAJOR 1
/** Driver minor version */
#define CY_MDMA_DRV_VERSION_MINOR 0
/** \cond INTERNAL */
#define CY_MDMA_INTR_BIT_MASK (0x01UL)
/** \endcond */
/**
* \addtogroup group_mdma_common_macro_MDMAIntrCauses
* \{
*/
#define CY_MDMA_INTRCAUSE_NO_INTR (0x00u) /**< No interrupt */
#define CY_MDMA_INTRCAUSE_COMPLETION (0x01u) /**< Completion */
#define CY_MDMA_INTRCAUSE_SRC_BUS_ERROR (0x02u) /**< Source bus error */
#define CY_MDMA_INTRCAUSE_DST_BUS_ERROR (0x04u) /**< Destination bus error */
#define CY_MDMA_INTRCAUSE_SRC_MISAL (0x08u) /**< Source address is not aligned */
#define CY_MDMA_INTRCAUSE_DST_MISAL (0x10u) /**< Destination address is not aligned */
#define CY_MDMA_INTRCAUSE_CURR_PTR_NULL (0x20u) /**< Current descriptor pointer is NULL */
#define CY_MDMA_INTRCAUSE_ACTIVE_CH_DISABLED (0x40u) /**< Active channel is disabled */
#define CY_MDMA_INTRCAUSE_DESCR_BUS_ERROR (0x80u) /**< Descriptor bus error */
/** \} group_mdma_common_macro_MDMAIntrCauses */
#define CY_MDMA_ID (CY_PDL_DRV_ID(0x13u)) /**< MDMA PDL ID */
#define CY_MDMA_ID_INFO (uint32_t)( CY_MDMA_ID | CY_PDL_STATUS_INFO ) /**< Return prefix for MDMA driver function status codes */
#define CY_MDMA_ID_WARNING (uint32_t)( CY_MDMA_ID | CY_PDL_STATUS_WARNING) /**< Return prefix for MDMA driver function warning return values */
#define CY_MDMA_ID_ERROR (uint32_t)( CY_MDMA_ID | CY_PDL_STATUS_ERROR) /**< Return prefix for MDMA driver function error return values */
/** \} group_mdma_macro */
/**
* \addtogroup group_mdma_data_structures
* \{
*/
/* MDMA descriptor structure type. This is a redefinition of the descriptor structure in the driver.
* The user will use this descriptor type in his descriptor configuration functions.
*/
/**
* \brief MDMA descriptor structure
*/
typedef struct stc_MDMA_DESCR_CTL_field {
uint32_t u2WAIT_FOR_DEACT:2;
uint32_t u2INTR_TYPE:2;
uint32_t u2TR_OUT_TYPE:2;
uint32_t u2TR_IN_TYPE:2;
uint32_t u1DATA_PREFETCH:1;
uint32_t :7;
uint32_t u2DATA_SIZE:2;
uint32_t :6;
uint32_t u1CH_DISABLE:1;
uint32_t :1;
uint32_t u1SRC_TRANSFER_SIZE:1;
uint32_t u1DST_TRANSFER_SIZE:1;
uint32_t u3DESCR_TYPE:3;
uint32_t :1;
} stc_MDMA_DESCR_CTL_field_t;
typedef union un_MDMA_DESCR_CTL {
uint32_t u32Register;
stc_MDMA_DESCR_CTL_field_t stcField;
uint8_t au8Byte[4];
uint16_t au16Halfword[2];
} un_MDMA_DESCR_CTL_t;
typedef struct stc_MDMA_DESCR_X_SIZE_field {
uint32_t u16X_COUNT:16;
uint32_t :16;
} stc_MDMA_DESCR_X_SIZE_field_t;
typedef union un_MDMA_DESCR_X_SIZE {
uint32_t u32Register;
stc_MDMA_DESCR_X_SIZE_field_t stcField;
uint8_t au8Byte[4];
uint16_t au16Halfword[2];
} un_MDMA_DESCR_X_SIZE_t;
typedef struct stc_MDMA_DESCR_X_INCR_field {
uint32_t u16SRC_X_INCR:16;
uint32_t u16DST_X_INCR:16;
} stc_MDMA_DESCR_X_INCR_field_t;
typedef union un_MDMA_DESCR_X_INCR {
uint32_t u32Register;
stc_MDMA_DESCR_X_INCR_field_t stcField;
uint8_t au8Byte[4];
uint16_t au16Halfword[2];
} un_MDMA_DESCR_X_INCR_t;
typedef struct stc_MDMA_DESCR_Y_SIZE_field {
uint32_t u16Y_COUNT:16;
uint32_t :16;
} stc_MDMA_DESCR_Y_SIZE_field_t;
typedef union un_MDMA_DESCR_Y_SIZE {
uint32_t u32Register;
stc_MDMA_DESCR_Y_SIZE_field_t stcField;
uint8_t au8Byte[4];
uint16_t au16Halfword[2];
} un_MDMA_DESCR_Y_SIZE_t;
typedef struct stc_MDMA_DESCR_Y_INCR_field {
uint32_t u16SRC_Y_INCR:16;
uint32_t u16DST_Y_INCR:16;
} stc_MDMA_DESCR_Y_INCR_field_t;
typedef union un_MDMA_DESCR_Y_INCR {
uint32_t u32Register;
stc_MDMA_DESCR_Y_INCR_field_t stcField;
uint8_t au8Byte[4];
uint16_t au16Halfword[2];
} un_MDMA_DESCR_Y_INCR_t;
typedef struct {
un_MDMA_DESCR_CTL_t unMDMA_DESCR_CTL;
uint32_t u32MDMA_DESCR_SRC;
uint32_t u32MDMA_DESCR_DST;
un_MDMA_DESCR_X_SIZE_t unMDMA_DESCR_X_SIZE;
un_MDMA_DESCR_X_INCR_t unMDMA_DESCR_X_INCR;
un_MDMA_DESCR_Y_SIZE_t unMDMA_DESCR_Y_SIZE;
un_MDMA_DESCR_Y_INCR_t unMDMA_DESCR_Y_INCR;
uint32_t u32MDMA_DESCR_NEXT_PTR;
} cy_stc_mdma_descr_t;
/**
* This structure is a configuration structure pre-initialized by the user and
* passed as a parameter to the Cy_MDMA_InitDescr(). This structure has all the parameters
* of the descriptor as separate parameters. Some of these parameters are represented in the
* stc_Descr_t data structure as bit fields.
*/
typedef struct {
uint32_t deact; /**< Specifies whether the MDMA controller should wait for the input trigger to be deactivated */
uint32_t intrType; /**< Sets the event that triggers an interrupt, see \ref cy_en_mdma_inttype_t */
uint32_t trigoutType; /**< Sets the event that triggers an output, see \ref cy_en_mdma_trigouttype_t */
uint32_t chStateAtCmplt; /**< Specifies if the channel is enabled or disabled on completion of descriptor see \ref cy_en_mdma_chdesccmpl_t */
uint32_t triginType; /**< Sets what type of transfer is triggered, see \ref cy_en_mdma_trigintype_t */
uint32_t dataPrefetch; /**< Source data prefetch */
uint32_t dataSize; /**< The size of the data bus for transfer, see \ref cy_en_mdma_datasize_t */
uint32_t srcTxfrSize; /**< The source transfer size */
uint32_t destTxfrSize; /**< The destination transfer size */
uint32_t descrType; /**< The type of the descriptor see \ref cy_en_mdma_descrtype_t*/
void * srcAddr; /**< The source address of the transfer */
void * destAddr; /**< The destination address of the transfer */
int16_t srcXincr; /**< The address increment of the source after each X-loop transfer */
int16_t destXincr; /**< The address increment of the destination after each X-loop transfer */
uint32_t xCount; /**< The number of transfers in an X-loop */
int16_t srcYincr; /**< The address increment of the source after each Y-loop transfer */
int16_t destYincr; /**< The address increment of the destination after each Y-loop transfer */
uint32_t yCount; /**< The number of transfers in the Y-loop */
cy_stc_mdma_descr_t* descrNext; /**< The next descriptor to chain after completion, a NULL value will signify no chaining */
} cy_stc_mdma_descr_config_t;
/** This structure holds the initialization values for the MDMA channel */
typedef struct {
cy_stc_mdma_descr_t* MDMA_Descriptor; /**< The MDMA descriptor associated with the channel being initialized */
uint32_t preemptable; /**< Specifies if the channel is preemptable by another higher-priority channel */
uint32_t priority; /**< This parameter specifies the channel's priority */
uint32_t enable; /**< This parameter specifies if the channel is enabled after initializing */
uint32_t priviledge;
uint32_t non_secure;
uint32_t bufferable;
uint32_t protection_context;
} cy_stc_mdma_chnl_config_t;
/** \} group_mdma_data_structures */
/**
* \addtogroup group_mdma_enums
* \{
*/
/** Contains the options for the trigger input deactivation parameter type */
enum cy_en_mdma_deactivate_t {
CY_MDMA_TRIG_DEACT_NO_WAIT, /**< Don't wait for deactivation (for pulse sensitive triggers)*/
CY_MDMA_TRIG_DEACT_4CYC, /**< Wait for up to 4 cycles */
CY_MDMA_TRIG_DEACT_16CYC, /**< Wait for up to 16 cycles */
CY_MDMA_TRIG_DEACT_WAIT_INDEFINITELY /**< Wait indefinitely. This option may result in controller lockup if the trigger is not de-activated */
} ;
/** Contains the options for the descriptor type */
enum cy_en_mdma_descrtype_t {
CY_MDMA_SINGLE_TRANSFER, /**< Single transfer */
CY_MDMA_1D_TRANSFER, /**< 1D transfer */
CY_MDMA_2D_TRANSFER, /**< 2D transfer */
CY_MDMA_MEMORY_COPY_TRANSFER, /**< Memory copy transfer */
CY_MDMA_SCATTER_TRANSFER /**< Scatter transfer */
} ;
/** Contains the options for the interrupt-type parameter of the descriptor */
enum cy_en_mdma_inttype_t {
CY_MDMA_INTR_1ELEMENT_CMPLT, /**< Triggers on every element transfer completion */
CY_MDMA_INTR_X_LOOP_CMPLT, /**< Triggers on every X loop transfer completion */
CY_MDMA_INTR_DESCR_CMPLT, /**< Triggers on descriptor completion */
CY_MDMA_INTR_DESCRCHAIN_CMPLT /**< Triggers on completion of the entire descriptor chain */
} ;
/** This enum has the options for the trigger in the type parameter of the descriptor */
enum cy_en_mdma_trigouttype_t {
CY_MDMA_TRIGOUT_1ELEMENT_CMPLT, /**< Triggers on every element transfer completion */
CY_MDMA_TRIGOUT_X_LOOP_CMPLT, /**< Triggers on every X loop transfer completion */
CY_MDMA_TRIGOUT_DESCR_CMPLT, /**< Triggers on descriptor completion */
CY_MDMA_TRIGOUT_DESCRCHAIN_CMPLT /**< Triggers on completion of the entire descriptor chain */
} ;
/** This enum has the options for the trigger-in-type parameter of the descriptor */
enum cy_en_mdma_trigintype_t {
CY_MDMA_TRIGIN_1ELEMENT, /**< One transfer per trigger */
CY_MDMA_TRIGIN_XLOOP, /**< One X loop transfer per trigger */
CY_MDMA_TRIGIN_DESCR, /**< The entire descriptor transfer per trigger */
CY_MDMA_TRIGIN_DESCRCHAIN /**< The entire descriptor chain per trigger */
} ;
/** This enum has the options for the data size */
enum cy_en_mdma_datasize_t {
CY_MDMA_BYTE, /**< One byte */
CY_MDMA_HALFWORD, /**< Half word (two bytes) */
CY_MDMA_WORD /**< Full word (four bytes) */
} ;
/** This enum has the options for descriptor retriggering */
enum cy_en_mdma_retrigger_t {
CY_MDMA_RETDIG_IM, /**< Retrigger immediately */
CY_MDMA_RETDIG_4CYC, /**< Retrigger after 4 SYSCLK */
CY_MDMA_RETDIG_16CYC, /**< Retrigger after 16 SYSCLK */
CY_MDMA_WAIT_FOR_REACT /**< Wait for trigger reactivation */
};
/** This enum has the options for the transfer size */
enum cy_en_mdma_txfrsize_t {
CY_MDMA_TXFR_SIZE_DATA_SIZE, /**< As per data size register */
CY_MDMA_TXFR_SIZE_WORD /**< A full word (four bytes) */
};
/** This enum has the options for the state of the channel when the descriptor is completed */
enum cy_en_mdma_chdesccmpl_t {
CY_MDMA_CH_ENABLED, /**< Channel stays enabled */
CY_MDMA_CH_DISABLED /**< Channel is disabled */
};
/** This enum has the return values of the MDMA driver */
typedef enum
{
CY_MDMA_SUCCESS = 0x00ul, /**< Success */
CY_MDMA_INVALID_INPUT_PARAMETERS = ( CY_MDMA_ID_ERROR + 1ul), /**< Input parameters passed to MDMA API are not valid */
CY_MDMA_ERR_UNC = ( CY_MDMA_ID_ERROR + 0xFul),/**< Unknown error */
} cy_en_mdma_status_t;
/** \} group_mdma_enums */
/**
* \addtogroup group_mdma_functions
* \{
*/
//IP functions
void Cy_MDMA_Enable ( volatile stc_DMAC_t * pstcMDMA);
void Cy_MDMA_Disable ( volatile stc_DMAC_t * pstcMDMA);
uint32_t Cy_MDMA_GetActiveChnl ( const volatile stc_DMAC_t * pstcMDMA);
//Descriptor functions
cy_en_mdma_status_t Cy_MDMA_Descr_Init ( cy_stc_mdma_descr_t* descriptor,
const cy_stc_mdma_descr_config_t* config);
void Cy_MDMA_Descr_DeInit ( cy_stc_mdma_descr_t* descriptor);
__STATIC_INLINE void Cy_MDMA_Descr_SetSrcAddr ( cy_stc_mdma_descr_t* descriptor,
const void * srcAddr);
__STATIC_INLINE void Cy_MDMA_Descr_SetDestAddr ( cy_stc_mdma_descr_t* descriptor,
const void * dstAddr);
void Cy_MDMA_Descr_SetNxtDescr ( cy_stc_mdma_descr_t* descriptor,
const cy_stc_mdma_descr_t* nxtDescriptor);
__STATIC_INLINE void Cy_MDMA_Descr_SetIntrType ( cy_stc_mdma_descr_t* descriptor,
uint32_t interruptType);
__STATIC_INLINE void Cy_MDMA_Descr_SetTrigInType ( cy_stc_mdma_descr_t* descriptor,
uint32_t trigInType);
__STATIC_INLINE void Cy_MDMA_Descr_SetTrigOutType ( cy_stc_mdma_descr_t* descriptor,
uint32_t trigOutType);
void Cy_MDMA_Descr_SetTxfrWidth ( cy_stc_mdma_descr_t* descriptor,
uint32_t dataElementSize,
uint32_t srcTxfrWidth,
uint32_t dstTxfrWidth);
//Channel functions
cy_en_mdma_status_t Cy_MDMA_Chnl_Init ( volatile stc_DMAC_t * pstcMDMA,
uint32_t chNum,
const cy_stc_mdma_chnl_config_t* chnlConfig);
void Cy_MDMA_Chnl_DeInit ( volatile stc_DMAC_t * pstcMDMA,
uint32_t chNum);
__STATIC_INLINE void Cy_MDMA_Chnl_SetDescr ( volatile stc_DMAC_t * pstcMDMA,
uint32_t chNum,
const cy_stc_mdma_descr_t* descriptor);
__STATIC_INLINE void Cy_MDMA_Chnl_Enable ( volatile stc_DMAC_t * pstcMDMA,
uint32_t chNum);
__STATIC_INLINE void Cy_MDMA_Chnl_Disable ( volatile stc_DMAC_t * pstcMDMA,
uint32_t chNum);
__STATIC_INLINE void Cy_MDMA_Chnl_SetPriority ( volatile stc_DMAC_t * pstcMDMA,
uint32_t chNum,
uint32_t priority);
__STATIC_INLINE uint32_t Cy_MDMA_Chnl_GetPriority ( const volatile stc_DMAC_t * pstcMDMA,
uint32_t chNum);
__STATIC_INLINE cy_stc_mdma_descr_t* Cy_MDMA_Chnl_GetCurrentDescr ( const volatile stc_DMAC_t * pstcMDMA,
uint32_t chNum);
__STATIC_INLINE uint32_t Cy_MDMA_Chnl_GetInterruptStatus ( const volatile stc_DMAC_t * pstcMDMA,
uint32_t chNum);
__STATIC_INLINE uint32_t Cy_MDMA_Chnl_GetInterruptCause ( const volatile stc_DMAC_t * pstcMDMA,
uint32_t chNum);
void Cy_MDMA_Chnl_ClearInterrupt ( volatile stc_DMAC_t * pstcMDMA,
uint32_t chNum);
__STATIC_INLINE void Cy_MDMA_Chnl_SetInterrupt ( volatile stc_DMAC_t * pstcMDMA,
uint32_t chNum,
uint32_t intMask);
__STATIC_INLINE uint32_t Cy_MDMA_Chnl_GetInterruptMask ( const volatile stc_DMAC_t * pstcMDMA,
uint32_t chNum);
__STATIC_INLINE void Cy_MDMA_Chnl_SetInterruptMask ( volatile stc_DMAC_t * pstcMDMA,
uint32_t chNum,
uint32_t intMask);
__STATIC_INLINE uint32_t Cy_MDMA_Chnl_GetInterruptStatusMasked ( const volatile stc_DMAC_t * pstcMDMA,
uint32_t chNum);
#if defined(CPUSS_SW_TR_PRESENT) && (CPUSS_SW_TR_PRESENT == 1)
__STATIC_INLINE void Cy_MDMA_Chnl_SetSwTrigger ( volatile stc_DMAC_t * pstcMDMA,
uint32_t chNum);
#endif
/***************************************
* In-line Function Implementation
***************************************/
/*******************************************************************************
* Function Name: Cy_MDMA_Descr_SetSrcAddr
****************************************************************************//**
*
* \brief Sets the source address parameter for the descriptor structure.
*
* This function will operate on the descriptor only if it was defined as a RAM
* variable.
* If the descriptor is being defined in Flash, then the user has to use the
* configuration defines to initialize it.
*
* \param descriptor
* This is a descriptor-structure instance declared by the user. The function
* modifies the source-address parameter in this descriptor.
*
* \param srcAddr
* The source address value for the descriptor.
*
*******************************************************************************/
__STATIC_INLINE void Cy_MDMA_Descr_SetSrcAddr(cy_stc_mdma_descr_t* descriptor, const void * srcAddr)
{
descriptor->u32MDMA_DESCR_SRC = (uint32_t)srcAddr;
}
/*******************************************************************************
* Function Name: Cy_MDMA_Descr_SetDestAddr
****************************************************************************//**
*
* \brief Sets the destination address parameter for the descriptor structure.
*
* This function will operate in the descriptor only if it was defined as a RAM
* variable.
* If the descriptor is being defined in Flash, then the user has to use the
* configuration defines to initialize it.
*
* \param descriptor
* This is a descriptor-structure instance declared by the user. The function
* modifies the destination-address parameter in this descriptor.
*
* \param dstAddr
* The destination address value for the descriptor.
*
*******************************************************************************/
__STATIC_INLINE void Cy_MDMA_Descr_SetDestAddr(cy_stc_mdma_descr_t* descriptor, const void * dstAddr)
{
descriptor->u32MDMA_DESCR_DST = (uint32_t)dstAddr;
}
/*******************************************************************************
* Function Name: Cy_MDMA_Chnl_SetDescr
****************************************************************************//**
*
* \brief Sets a descriptor as current for specified MDMA channel.
*
* \param pstcMDMA
* Pointer to the hardware MDMA block.
*
* \param chNum
* Channel number of the MDMA.
*
* \param descriptor
* This is the descriptor which will be associated with the channel.
*
*******************************************************************************/
__STATIC_INLINE void Cy_MDMA_Chnl_SetDescr(volatile stc_DMAC_t *pstcMDMA, uint32_t chNum, const cy_stc_mdma_descr_t* descriptor)
{
pstcMDMA->CH[chNum].unCURR.u32Register = (uint32_t)descriptor;
}
/*******************************************************************************
* Function Name: Cy_MDMA_Chnl_Enable
****************************************************************************//**
*
* The function is used to enable a MDMA channel.
*
* \param pstcMDMA
* Pointer to the hardware MDMA block.
*
* \param chNum
* Channel number of the MDMA.
*
*******************************************************************************/
__STATIC_INLINE void Cy_MDMA_Chnl_Enable(volatile stc_DMAC_t *pstcMDMA, uint32_t chNum)
{
pstcMDMA->CH[chNum].unCTL.stcField.u1ENABLED = 1ul;
}
/*******************************************************************************
* Function Name: Cy_MDMA_Chnl_Disable
****************************************************************************//**
*
* The function is used to disable a MDMA channel.
*
* \param pstcMDMA
* Pointer to the hardware MDMA block.
*
* \param chNum
* Channel number of the MDMA.
*
*******************************************************************************/
__STATIC_INLINE void Cy_MDMA_Chnl_Disable(volatile stc_DMAC_t *pstcMDMA, uint32_t chNum)
{
pstcMDMA->CH[chNum].unCTL.stcField.u1ENABLED = 0ul;
}
/*******************************************************************************
* Function Name: Cy_MDMA_Chnl_SetPriority
****************************************************************************//**
*
* The function is used to set a priority for the MDMA channel.
*
* \param pstcMDMA
* Pointer to the hardware MDMA block.
*
* \param chNum
* Channel number of the MDMA.
*
* \param priority
* The priority to be set for the MDMA channel. The allowed values are 0,1,2,3.
*
*******************************************************************************/
__STATIC_INLINE void Cy_MDMA_Chnl_SetPriority(volatile stc_DMAC_t *pstcMDMA, uint32_t chNum, uint32_t priority)
{
pstcMDMA->CH[chNum].unCTL.stcField.u2PRIO = priority;
}
/*******************************************************************************
* Function Name: Cy_MDMA_Chnl_GetPriority
****************************************************************************//**
*
* Returns the priority of MDMA channel.
*
* \param pstcMDMA
* Pointer to the hardware MDMA block.
*
* \param chNum
* Channel number of the MDMA.
*
* \return
* The priority of the channel.
*
*******************************************************************************/
__STATIC_INLINE uint32_t Cy_MDMA_Chnl_GetPriority(const volatile stc_DMAC_t *pstcMDMA, uint32_t chNum)
{
return pstcMDMA->CH[chNum].unCTL.stcField.u2PRIO;
}
/*******************************************************************************
* Function Name: Cy_MDMA_Chnl_GetCurrentDescr
****************************************************************************//**
*
* This function returns the descriptor that is active in the channel.
*
* \param pstcMDMA
* Pointer to the hardware MDMA block.
*
* \param chNum
* Channel number of the MDMA.
*
* \return
* The pointer to the descriptor associated with the channel.
*
*******************************************************************************/
__STATIC_INLINE cy_stc_mdma_descr_t* Cy_MDMA_Chnl_GetCurrentDescr(const volatile stc_DMAC_t *pstcMDMA, uint32_t chNum)
{
return (cy_stc_mdma_descr_t*) pstcMDMA->CH[chNum].unCURR.u32Register;
}
/*******************************************************************************
* Function Name: Cy_MDMA_Descr_SetIntrType
****************************************************************************//**
*
* Sets the interrupt type parameter for the descriptor structure.
* This function will operate in the descriptor only if it was defined as a RAM
* variable.
* If the descriptor is being defined in Flash, then the user has to use the
* configuration defines to initialize it.
*
* \param descriptor
* This is the descriptor-structure instance declared by the user. This is the
* descriptor being modified.
*
* \param interruptType
* The interrupt type set for the descriptor.
*
*******************************************************************************/
__STATIC_INLINE void Cy_MDMA_Descr_SetIntrType(cy_stc_mdma_descr_t* descriptor, uint32_t interruptType)
{
descriptor->unMDMA_DESCR_CTL.stcField.u2INTR_TYPE = interruptType;
}
/*******************************************************************************
* Function Name: Cy_MDMA_Descr_SetTrigInType
****************************************************************************//**
*
* Sets the trigger-in-type parameter for the descriptor structure.
* This function will operate in the descriptor only if it was defined as a RAM
* variable.
* If the descriptor is being defined in Flash, then the user has to use the
* configuration defines to initialize it.
*
* \param descriptor
* This is a descriptor structure instance declared by the user. This is the
* descriptor being modified.
*
* \param trigInType
* The trigger-in-type set for the descriptor. \ref cy_en_pdma_trigintype_t
*
*******************************************************************************/
__STATIC_INLINE void Cy_MDMA_Descr_SetTrigInType(cy_stc_mdma_descr_t* descriptor, uint32_t trigInType)
{
descriptor->unMDMA_DESCR_CTL.stcField.u2TR_IN_TYPE = trigInType;
}
/*******************************************************************************
* Function Name: Cy_MDMA_Descr_SetTrigOutType
****************************************************************************//**
*
* This function sets the trigger-out-type parameter for for the descriptor
* structure.
* This function will operate in the descriptor only if it was defined as a RAM
* variable.
* If the descriptor is being defined in Flash, then the user has to use the
* configuration defines to initialize it.
*
* \param descriptor
* This is a descriptor-structure instance declared by the user. This is the
* descriptor being modified.
*
* \param trigOutType
* The trigger-out-type set for the descriptor. \ref cy_en_pdma_trigouttype_t
*
*******************************************************************************/
__STATIC_INLINE void Cy_MDMA_Descr_SetTrigOutType(cy_stc_mdma_descr_t* descriptor, uint32_t trigOutType)
{
descriptor->unMDMA_DESCR_CTL.stcField.u2TR_OUT_TYPE = trigOutType;
}
/*******************************************************************************
* Function Name: Cy_MDMA_Chnl_GetInterruptStatus
****************************************************************************//**
*
* This function can be used to determine the interrupt status of the
* MDMA channel.
*
* \param pstcMDMA
* Pointer to the hardware MDMA block.
*
* \param chNum
* Channel number of the MDMA.
*
* \return
* Returns a status of an interrupt for specified channel.
*
*******************************************************************************/
__STATIC_INLINE uint32_t Cy_MDMA_Chnl_GetInterruptStatus(const volatile stc_DMAC_t *pstcMDMA, uint32_t chNum)
{
return (pstcMDMA->CH[chNum].unINTR.u32Register);
}
/*******************************************************************************
* Function Name: Cy_MDMA_Chnl_GetInterruptCause
****************************************************************************//**
*
* This function can be used to determine the interrupt reason of the
* MDMA channel.
*
* \param pstcMDMA
* Pointer to the hardware MDMA block.
*
* \param chNum
* Channel number of the MDMA.
*
* \return
* Returns a status of an interrupt for specified channel.
* (see \ref group_pdma_common_macro_MDMAIntrCauses for return values).
* For error related interrupt causes (INTR_CAUSE is "1", "2", "3", ..., "8"),
* the channel is disabled (HW sets CH_CTL.ENABLED to '0').
*
*******************************************************************************/
__STATIC_INLINE uint32_t Cy_MDMA_Chnl_GetInterruptCause(const volatile stc_DMAC_t *pstcMDMA, uint32_t chNum)
{
return (pstcMDMA->CH[chNum].unINTR.u32Register & 0xFFul);
}
/*******************************************************************************
* Function Name: Cy_MDMA_Chnl_SetInterrupt
****************************************************************************//**
*
* This function sets the interrupt.
*
* \param pstcMDMA
* Pointer to the hardware MDMA block.
*
* \param chNum
* Channel number of the MDMA.
* intMask Interrupt to be enabled
*
*******************************************************************************/
__STATIC_INLINE void Cy_MDMA_Chnl_SetInterrupt(volatile stc_DMAC_t *pstcMDMA, uint32_t chNum, uint32_t intMask)
{
pstcMDMA->CH[chNum].unINTR_SET.u32Register = intMask;
}
/*******************************************************************************
* Function Name: Cy_MDMA_Chnl_GetInterruptMask
****************************************************************************//**
*
* This function gets interrupt mask value.
*
* \param pstcMDMA
* Pointer to the hardware MDMA block.
*
* \param chNum
* Channel number of the MDMA.
*
* \return
* Returns an interrupt mask value.
*
*******************************************************************************/
__STATIC_INLINE uint32_t Cy_MDMA_Chnl_GetInterruptMask(const volatile stc_DMAC_t *pstcMDMA, uint32_t chNum)
{
return (pstcMDMA->CH[chNum].unINTR_MASK.u32Register);
}
/*******************************************************************************
* Function Name: Cy_MDMA_Chnl_SetInterruptMask
****************************************************************************//**
*
* This function sets interrupt mask value.
*
* \param pstcMDMA
* Pointer to the hardware MDMA block.
*
* \param chNum
* Channel number of the MDMA.
* intMask Interrupt mask to be enabled
*
*******************************************************************************/
__STATIC_INLINE void Cy_MDMA_Chnl_SetInterruptMask(volatile stc_DMAC_t *pstcMDMA, uint32_t chNum, uint32_t intMask)
{
pstcMDMA->CH[chNum].unINTR_MASK.u32Register = intMask;
}
/*******************************************************************************
* Function Name: Cy_MDMA_Chnl_GetInterruptStatusMasked
****************************************************************************//**
*
* This function returns logical and of corresponding INTR and INTR_MASK fields
* in a single load operation.
*
* \param pstcMDMA
* Pointer to the hardware MDMA block.
*
* \param chNum
* Channel number of the MDMA.
*
*******************************************************************************/
__STATIC_INLINE uint32_t Cy_MDMA_Chnl_GetInterruptStatusMasked(const volatile stc_DMAC_t *pstcMDMA, uint32_t chNum)
{
return (pstcMDMA->CH[chNum].unINTR_MASKED.u32Register);
}
#if defined(CPUSS_SW_TR_PRESENT) && (CPUSS_SW_TR_PRESENT == 1)
/*******************************************************************************
* Function Name: Cy_MDMA_Chnl_SetSwTrigger
****************************************************************************//**
*
* This function sets the SW trigger for a channel.
*
* \param pstcMDMA
* Pointer to the hardware MDMA block.
*
* \param chNum
* Channel number of the MDMA.
*
* \return
* Returns an interrupt mask value.
*
*******************************************************************************/
__STATIC_INLINE void Cy_MDMA_Chnl_SetSwTrigger(volatile stc_DMAC_t *pstcMDMA, uint32_t chNum)
{
pstcMDMA->CH[chNum].unTR_CMD.stcField.u1ACTIVATE = 1ul;
}
#endif
/** \} group_mdma_functions */
#if defined(__cplusplus)
}
#endif
#endif /* (CY_MDMA_H) */
/** \} group_mdma */
/* [] END OF FILE */
@@ -0,0 +1,454 @@
/***************************************************************************//**
* \file cy_pdma.c
* \version 1.0
*
* \brief
* The PDMA driver.
*
********************************************************************************
* \copyright
* Copyright 2016-2017, Cypress Semiconductor Corporation. All rights reserved.
* You may use this file only in accordance with the license, terms, conditions,
* disclaimers, and limitations in the end user license agreement accompanying
* the software package with which this file was provided.
*******************************************************************************/
#include "cy_pdma.h"
#if defined(__cplusplus)
extern "C" {
#endif
/*******************************************************************************
* Function Name: Cy_PDMA_Descr_Init
****************************************************************************//**
*
* This function initializes descriptor structure in SRAM from a pre-initialized
* configuration structure.
* This function initializes only the descriptor and not the channel.
* This function will operate on the descriptor only if it was defined as a RAM
* variable.
* If the descriptor is defined in Flash, then the user must use the
* configuration defines to initialize it.
*
* \param descriptor
* This is an instance of the descriptor structure declared by the user and
* initialized by this function.
*
* \param config
* This is a configuration structure that has all initialization information for
* the descriptor.
*
* \return
* This function returns /ref cy_en_pdma_status_t.
*
*******************************************************************************/
cy_en_pdma_status_t Cy_PDMA_Descr_Init(cy_stc_pdma_descr_t* descriptor, const cy_stc_pdma_descr_config_t* config)
{
cy_en_pdma_status_t retVal = CY_PDMA_ERR_UNC;
if ((descriptor != NULL) && (config != NULL))
{
descriptor->unPDMA_DESCR_CTL.stcField.u2WAIT_FOR_DEACT = config->deact;
descriptor->unPDMA_DESCR_CTL.stcField.u2INTR_TYPE = config->intrType;
descriptor->unPDMA_DESCR_CTL.stcField.u2TR_OUT_TYPE = config->trigoutType;
descriptor->unPDMA_DESCR_CTL.stcField.u2TR_IN_TYPE = config->triginType;
descriptor->unPDMA_DESCR_CTL.stcField.u1SRC_TRANSFER_SIZE = config->srcTxfrSize;
descriptor->unPDMA_DESCR_CTL.stcField.u1DST_TRANSFER_SIZE = config->destTxfrSize;
descriptor->unPDMA_DESCR_CTL.stcField.u1CH_DISABLE = config->chStateAtCmplt;
descriptor->unPDMA_DESCR_CTL.stcField.u2DATA_SIZE = config->dataSize;
descriptor->unPDMA_DESCR_CTL.stcField.u2DESCR_TYPE = config->descrType;
descriptor->u32PDMA_DESCR_SRC = (uint32_t)config->srcAddr;
descriptor->u32PDMA_DESCR_DST = (uint32_t)config->destAddr;
switch(config->descrType)
{
case (uint32_t)CY_PDMA_SINGLE_TRANSFER:
{
descriptor->unPDMA_DESCR_X_CTL.u32Register = (uint32_t)config->descrNext;
break;
}
case (uint32_t)CY_PDMA_1D_TRANSFER:
{
descriptor->unPDMA_DESCR_X_CTL.stcField.u12SRC_X_INCR = (uint32_t)config->srcXincr;
descriptor->unPDMA_DESCR_X_CTL.stcField.u12DST_X_INCR = (uint32_t)config->destXincr;
descriptor->unPDMA_DESCR_X_CTL.stcField.u8X_COUNT = (uint32_t)((config->xCount) - 1ul);
descriptor->unPDMA_DESCR_Y_CTL.u32Register = (uint32_t)config->descrNext;
break;
}
case (uint32_t)CY_PDMA_CRC_TRANSFER:
{
descriptor->unPDMA_DESCR_X_CTL.stcField.u12SRC_X_INCR = (uint32_t)config->srcXincr;
descriptor->unPDMA_DESCR_X_CTL.stcField.u12DST_X_INCR = 0ul;
descriptor->unPDMA_DESCR_X_CTL.stcField.u8X_COUNT = (uint32_t)((config->xCount) - 1ul);
descriptor->unPDMA_DESCR_Y_CTL.u32Register = (uint32_t)config->descrNext;
break;
}
case (uint32_t)CY_PDMA_2D_TRANSFER:
{
descriptor->unPDMA_DESCR_X_CTL.stcField.u12SRC_X_INCR = (uint32_t)config->srcXincr;
descriptor->unPDMA_DESCR_X_CTL.stcField.u12DST_X_INCR = (uint32_t)config->destXincr;
descriptor->unPDMA_DESCR_X_CTL.stcField.u8X_COUNT = (uint32_t)((config->xCount) - 1ul);
descriptor->unPDMA_DESCR_Y_CTL.stcField.u12SRC_Y_INCR = (uint32_t)config->srcYincr;
descriptor->unPDMA_DESCR_Y_CTL.stcField.u12DST_Y_INCR = (uint32_t)config->destYincr;
descriptor->unPDMA_DESCR_Y_CTL.stcField.u8Y_COUNT = (uint32_t)((config->yCount) - 1ul);
descriptor->u32PDMA_DESCR_NEXT_PTR = (uint32_t)config->descrNext;
break;
}
default:
{
/* Unsupported type of descriptor */
break;
}
}
retVal = CY_PDMA_SUCCESS;
}
else
{
retVal = CY_PDMA_INVALID_INPUT_PARAMETERS;
}
return retVal;
}
/*******************************************************************************
* Function Name: Cy_PDMA_Descr_DeInit
****************************************************************************//**
*
* This function clears all the content of the descriptor structure.
* This function will operate in the descriptor only if it was defined as a RAM
* variable.
* If the descriptor is being defined in Flash, then the user can't use this
* function to deinitialize it.
*
* \param descriptor
* This is an instance of the descriptor structure to be cleared.
*
*******************************************************************************/
void Cy_PDMA_Descr_DeInit(cy_stc_pdma_descr_t* descriptor)
{
descriptor->unPDMA_DESCR_CTL.u32Register = 0ul;
descriptor->u32PDMA_DESCR_SRC = 0ul;
descriptor->u32PDMA_DESCR_DST = 0ul;
descriptor->unPDMA_DESCR_X_CTL.u32Register = 0ul;
descriptor->unPDMA_DESCR_Y_CTL.u32Register = 0ul;
descriptor->u32PDMA_DESCR_NEXT_PTR = 0ul;
}
/*******************************************************************************
* Function Name: Cy_PDMA_Descr_SetTxfrWidth
****************************************************************************//**
*
* This function sets the transfer widths for for the descriptor structure.
* This function will operate in the descriptor only if it was defined as a RAM
* variable.
* If the descriptor is defined in Flash, then the user must use the
* configuration defines to initialize it.
*
* \param descriptor
* This is a descriptor-structure instance declared by the user. This is the
* descriptor being modified.
*
* \param dataElementSize
* This parameter provides the data element size of the descriptor.
* \ref cy_en_pdma_datasize_t
*
* \param srcTxfrWidth
* This parameter provides the source transfer size parameters of the descriptor.
* \ref cy_en_pdma_txfrsize_t
*
* \param dstTxfrWidth
* This parameter provides the destination transfer size parameters of the
* descriptor.
* \ref cy_en_pdma_txfrsize_t
*
*******************************************************************************/
void Cy_PDMA_Descr_SetTxfrWidth(cy_stc_pdma_descr_t* descriptor,
uint32_t dataElementSize,
uint32_t srcTxfrWidth,
uint32_t dstTxfrWidth)
{
descriptor->unPDMA_DESCR_CTL.stcField.u2DATA_SIZE = dataElementSize;
descriptor->unPDMA_DESCR_CTL.stcField.u1SRC_TRANSFER_SIZE = srcTxfrWidth;
descriptor->unPDMA_DESCR_CTL.stcField.u1DST_TRANSFER_SIZE = dstTxfrWidth;
}
/*******************************************************************************
* Function Name: Cy_PDMA_Chnl_Init
****************************************************************************//**
*
* Initializes the PDMA channel with a descriptor and other parameters.
*
* \param ptscPDMA
* Pointer to the hardware PDMA block.
*
* \param chNum
* Channel number of the PDMA.
*
* \param chnlConfig
* This parameter is a structure that has the initialization information for the
* channel.
*
* \return
* This function returns /ref cy_en_pdma_status_t.
*
*******************************************************************************/
cy_en_pdma_status_t Cy_PDMA_Chnl_Init(volatile stc_DW_t *pstcPDMA, uint32_t chNum, const cy_stc_pdma_chnl_config_t* chnlConfig)
{
cy_en_pdma_status_t retVal = CY_PDMA_ERR_UNC;
if ((pstcPDMA != NULL) && (chnlConfig != NULL))
{
/* Write this channel's SRAM data to initialize ECC properly */
pstcPDMA->CH_STRUCT[chNum].unSRAM_DATA0.u32Register = 0;
pstcPDMA->CH_STRUCT[chNum].unSRAM_DATA1.u32Register = 0;
/* Initialize the X/Y indices (which are undefined after reset) */
pstcPDMA->CH_STRUCT[chNum].unCH_IDX.u32Register = 0;
/* Set current descriptor */
pstcPDMA->CH_STRUCT[chNum].unCH_CURR_PTR.u32Register = (uint32_t)chnlConfig->PDMA_Descriptor;
/* Set if the channel is preemtable */
pstcPDMA->CH_STRUCT[chNum].unCH_CTL.stcField.u1PREEMPTABLE = chnlConfig->preemptable;
/* Set channel priority */
pstcPDMA->CH_STRUCT[chNum].unCH_CTL.stcField.u2PRIO = chnlConfig->priority;
/* Set enabled status */
pstcPDMA->CH_STRUCT[chNum].unCH_CTL.stcField.u1ENABLED = chnlConfig->enable;
retVal = CY_PDMA_SUCCESS;
}
else
{
retVal = CY_PDMA_INVALID_INPUT_PARAMETERS;
}
return (retVal);
}
/*******************************************************************************
* Function Name: Cy_PDMA_Chnl_DeInit
****************************************************************************//**
*
* Clears all the content of registers corresponding to the channel.
*
* \param ptscPDMA
* Pointer to the hardware PDMA block.
*
* \param chNum
* Channel number of the PDMA.
*
*******************************************************************************/
void Cy_PDMA_Chnl_DeInit(volatile stc_DW_t *pstcPDMA, uint32_t chNum)
{
pstcPDMA->CH_STRUCT[chNum].unCH_CTL.u32Register = 0ul;
pstcPDMA->CH_STRUCT[chNum].unCH_IDX.u32Register = 0ul;
pstcPDMA->CH_STRUCT[chNum].unCH_CURR_PTR.u32Register = 0ul;
pstcPDMA->CH_STRUCT[chNum].unINTR_MASK.u32Register = 0ul;
pstcPDMA->CH_STRUCT[chNum].unINTR_SET.u32Register = 0ul;
}
/*******************************************************************************
* Function Name: Cy_PDMA_Enable
****************************************************************************//**
*
* This function enables the PDMA block.
*
* \param ptscPDMA
* Pointer to the hardware PDMA block.
*
*******************************************************************************/
void Cy_PDMA_Enable(volatile stc_DW_t *pstcPDMA)
{
pstcPDMA->unCTL.stcField.u1ENABLED = 1ul;
}
/*******************************************************************************
* Function Name: Cy_PDMA_Disable
****************************************************************************//**
*
* This function disables the PDMA block.
*
* \param ptscPDMA
* Pointer to the hardware PDMA block.
*
*******************************************************************************/
void Cy_PDMA_Disable(volatile stc_DW_t *pstcPDMA)
{
pstcPDMA->unCTL.stcField.u1ENABLED = 0ul;
}
/*******************************************************************************
* Function Name: Cy_PDMA_GetActiveChnl
****************************************************************************//**
*
* This function used to determine the channels that are active/pending in
* the PDMA block.
*
* \param ptscPDMA
* Pointer to the hardware PDMA block.
*
* \return
* Returns a bit-field with all of the currently active/pending channels in the
* PDMA block.
*
*******************************************************************************/
uint32_t Cy_PDMA_GetActiveChnl(const volatile stc_DW_t *pstcPDMA)
{
return pstcPDMA->unSTATUS.stcField.u9CH_IDX;
}
/*******************************************************************************
* Function Name: Cy_PDMA_GetActiveSrcAddr
****************************************************************************//**
*
* Returns the source address that is being used for current transfer.
*
* \param ptscPDMA
* Pointer to the hardware PDMA block.
*
* \return
* Returns a pointer to the source of transfer.
*
*******************************************************************************/
void * Cy_PDMA_GetActiveSrcAddr(const volatile stc_DW_t *pstcPDMA)
{
return ((void *)pstcPDMA->unACT_DESCR_SRC.u32Register);
}
/*******************************************************************************
* Function Name: Cy_PDMA_GetActiveDstAddr
****************************************************************************//**
*
* Returns the destination address that is being used for the current transfer.
*
* \param ptscPDMA
* Pointer to the hardware PDMA block.
*
* \return
* Returns a pointer to the destination of transfer.
*
*******************************************************************************/
void * Cy_PDMA_GetActiveDstAddr(const volatile stc_DW_t *pstcPDMA)
{
return ((void *)pstcPDMA->unACT_DESCR_DST.u32Register);
}
/*******************************************************************************
* Function Name: Cy_PDMA_Chnl_ClearInterrupt
****************************************************************************//**
*
* This function clears the interrupt status.
*
* \param ptscPDMA
* Pointer to the hardware PDMA block.
*
* \param chNum
* Channel number of the PDMA.
*
*******************************************************************************/
void Cy_PDMA_Chnl_ClearInterrupt(volatile stc_DW_t *pstcPDMA, uint32_t chNum)
{
pstcPDMA->CH_STRUCT[chNum].unINTR.u32Register = CY_PDMA_INTR_BIT_MASK;
/* Readback of the register is required by hardware. */
(void) pstcPDMA->CH_STRUCT[chNum].unINTR.u32Register;
}
/*******************************************************************************
* Function Name: Cy_PDMA_Descr_SetNxtDescr
****************************************************************************//**
*
* Sets a next descriptor parameter for the descriptor structure.
* This function will operate in the descriptor only if it was defined as a RAM
* variable.
* If the descriptor is defined in Flash, then the user must use the
* configuration defines to initialize it.
* Based on descriptor type the offset of address for the next descriptor may
* vary. For a single transfer descriptor type, this register is at offset 0x0c.
* For a 1D transfer descriptor type, this register is at offset 0x10. For a 2D
* transfer descriptor type, this register is at offset 0x14.
*
* \param descriptor
* This is the descriptor-structure instance declared by the user. The function
* modifies the destination-address parameter in this descriptor.
*
* \param nxtDescriptor
* The pointer to the next descriptor.
*
*******************************************************************************/
void Cy_PDMA_Descr_SetNxtDescr(cy_stc_pdma_descr_t* descriptor, const cy_stc_pdma_descr_t* nxtDescriptor)
{
switch(descriptor->unPDMA_DESCR_CTL.stcField.u2DESCR_TYPE)
{
case (uint32_t)CY_PDMA_SINGLE_TRANSFER:
{
descriptor->unPDMA_DESCR_X_CTL.u32Register = (uint32_t)nxtDescriptor;
break;
}
case (uint32_t)CY_PDMA_1D_TRANSFER:
case (uint32_t)CY_PDMA_CRC_TRANSFER:
{
descriptor->unPDMA_DESCR_Y_CTL.u32Register = (uint32_t)nxtDescriptor;
break;
}
case (uint32_t)CY_PDMA_2D_TRANSFER:
{
descriptor->u32PDMA_DESCR_NEXT_PTR = (uint32_t)nxtDescriptor;
break;
}
default:
{
/* Unsupported type of descriptor */
break;
}
}
}
/*******************************************************************************
* Function Name: Cy_PDMA_CRC_Config
****************************************************************************//**
*******************************************************************************/
void Cy_PDMA_CRC_Config ( volatile stc_DW_t * pstcPDMA,
const cy_stc_pdma_crc_config_t* pstcCrcConfig)
{
pstcPDMA->unCRC_CTL.stcField.u1DATA_REVERSE = pstcCrcConfig->data_reverse;
pstcPDMA->unCRC_CTL.stcField.u1REM_REVERSE = pstcCrcConfig->rem_reverse;
pstcPDMA->unCRC_DATA_CTL.stcField.u8DATA_XOR = pstcCrcConfig->data_xor;
pstcPDMA->unCRC_LFSR_CTL.stcField.u32LFSR32 = pstcCrcConfig->lfsr32;
pstcPDMA->unCRC_POL_CTL.stcField.u32POLYNOMIAL = pstcCrcConfig->polynomial;
pstcPDMA->unCRC_REM_CTL.stcField.u32REM_XOR = pstcCrcConfig->rem_xor;
}
/*******************************************************************************
* Function Name: Cy_PDMA_CRC_Config
****************************************************************************//**
*******************************************************************************/
uint32_t Cy_PDMA_GetCrcRemainderResult ( volatile stc_DW_t * pstcPDMA)
{
return pstcPDMA->unCRC_REM_RESULT.u32Register;
}
#if defined(__cplusplus)
}
#endif
/* [] END OF FILE */
@@ -0,0 +1,853 @@
/***************************************************************************//**
* \file cy_pdma.h
* \version 1.0
*
* \brief
* The header file of the PDMA driver.
*
********************************************************************************
* \copyright
* Copyright 2016-2017, Cypress Semiconductor Corporation. All rights reserved.
* You may use this file only in accordance with the license, terms, conditions,
* disclaimers, and limitations in the end user license agreement accompanying
* the software package with which this file was provided.
*******************************************************************************/
/**
* \defgroup group_pdma Peripheral DMA (P-DMA)
* \{
* Configures a PDMA channel and its descriptor(s).
*
* The PDMA Channel component can be used in any project that needs to transfer data
* without CPU intervention, based on a hardware trigger signal from another component.
*
* A device may support more than one PDMA hardware block. Each block has a set of
* registers, and a base hardware address. Each block also supports multiple channels.
* Many API functions for the PDMA driver require the base hardware address and the
* channel number. Ensure that you use the correct hardware address for the PDMA block in use.
*
* Features:
* * Devices support up to two PDMA hardware blocks
* * Each PDMA block supports up to 16 PDMA channels
* * Supports channel descriptors in SRAM
* * Four Priority Levels for each channel
* * Byte, Half-word (2 byte), and Word (4 byte) transfers
* * Configurable source and destination addresses
*
* \section group_pdma_configuration Configuration Considerations
*
* To set up a PDMA driver you initialize a descriptor,
* intialize and enable a channel, and enable the PDMA block.
*
* To set up the descriptor, provide the configuration parameters for the
* descriptor in the \ref cy_stc_pdma_descr_config_t structure. Then call the
* \ref Cy_PDMA_Descr_Init function to initialize the descriptor in SRAM. You can
* modify the source and destination addresses dynamically by calling
* \ref Cy_PDMA_Descr_SetSrcAddr and \ref Cy_PDMA_Descr_SetDestAddr.
*
* To set up the PDMA channel, provide a filled \ref cy_stc_pdma_chnl_config_t
* structure. Call the \ref Cy_PDMA_Chnl_Init function, specifying the channel
* number. Use \ref Cy_PDMA_Chnl_Enable to enable the configured PDMA channel.
*
* Call \ref Cy_PDMA_Chnl_Enable for each PDMA channel in use.
*
* <B>NOTE:</B> Even if a PDMA channel is enabled, it is not operational until
* the PDMA block is enabled using function \ref Cy_PDMA_Enable.\n
* <B>NOTE:</B> If the PDMA descriptor is configured to generate an interrupt,
* the interrupt must be enabled using the \ref Cy_PDMA_Chnl_SetInterruptMask
* function for each PDMA channel.
*
* \section group_pdma_more_information More Information.
*
* See the PDMA Component datasheet.
* See also the PDMA chapter of the device technical reference manual (TRM).
*
*
* \section group_pdma_changelog Changelog
*
* <table class="doxtable">
* <tr><th>Version</th><th>Changes</th><th>Reason for Change</th></tr>
* <tr>
* <td>7.3.0</td>
* <td>group_pdma_common_macro_PDMAIntrCauses corrections </td>
* <td>Status alignment with design</td>
* </tr>
* </table>
*
* <table class="doxtable">
* <tr><th>Version</th><th>Changes</th><th>Reason for Change</th></tr>
* <tr>
* <td>1.0</td>
* <td>Initial version</td>
* <td></td>
* </tr>
* </table>
*
* \defgroup group_pdma_macro Macro
* \{
* \defgroup group_pdma_common_macro_PDMAIntrCauses PDMA Interrupt Causes
* \}
*
* \defgroup group_pdma_functions Functions
* \defgroup group_pdma_data_structures Data structures
* \defgroup group_pdma_enums Enumerated types
*/
#if !defined(CY_PDMA_H)
#define CY_PDMA_H
#include <stdint.h>
#include <stdbool.h>
#include <stddef.h>
#include "syslib/cy_syslib.h"
#include "cy_device_headers.h"
/*
#ifndef CY_IP_M4CPUSS_PDMA
#error "The PDMA driver is not supported on this device"
#endif
*/
#if defined(__cplusplus)
extern "C" {
#endif
/******************************************************************************
* Macro definitions *
******************************************************************************/
/**
* \addtogroup group_pdma_macro
* \{
*/
/** Driver major version */
#define CY_PDMA_DRV_VERSION_MAJOR 1
/** Driver minor version */
#define CY_PDMA_DRV_VERSION_MINOR 0
/** \cond INTERNAL */
#define CY_PDMA_INTR_BIT_MASK (0x01UL)
/** \endcond */
/**
* \addtogroup group_pdma_common_macro_PDMAIntrCauses
* \{
*/
#define CY_PDMA_INTRCAUSE_NO_INTR (0x00u) /**< No interrupt generated */
#define CY_PDMA_INTRCAUSE_COMPLETION (0x01u) /**< Interrupt based on transfer completion configuration based on INTR_TYPE */
#define CY_PDMA_INTRCAUSE_SRC_BUS_ERROR (0x02u) /**< Source transfer bus error */
#define CY_PDMA_INTRCAUSE_DST_BUS_ERROR (0x03u) /**< Destination transfer bus error */
#define CY_PDMA_INTRCAUSE_SRC_MISAL (0x04u) /**< Source address misalignment */
#define CY_PDMA_INTRCAUSE_DST_MISAL (0x05u) /**< Destination address misalignment */
#define CY_PDMA_INTRCAUSE_CURR_PTR_NULL (0x06u) /**< Current descriptor pointer is null */
#define CY_PDMA_INTRCAUSE_ACTIVE_CH_DISABLED (0x07u) /**< Active channel is disabled */
#define CY_PDMA_INTRCAUSE_DESCR_BUS_ERROR (0x08u) /**< Descriptor bus error */
/** \} group_pdma_common_macro_PDMAIntrCauses */
#define CY_PDMA_ID (CY_PDL_DRV_ID(0x13u)) /**< PDMA PDL ID */
#define CY_PDMA_ID_INFO (uint32_t)( CY_PDMA_ID | CY_PDL_STATUS_INFO ) /**< Return prefix for PDMA driver function status codes */
#define CY_PDMA_ID_WARNING (uint32_t)( CY_PDMA_ID | CY_PDL_STATUS_WARNING) /**< Return prefix for PDMA driver function warning return values */
#define CY_PDMA_ID_ERROR (uint32_t)( CY_PDMA_ID | CY_PDL_STATUS_ERROR) /**< Return prefix for PDMA driver function error return values */
/** \} group_pdma_macro */
/**
* \addtogroup group_pdma_data_structures
* \{
*/
/* PDMA descriptor structure type. This is a redefinition of the descriptor structure in the driver.
* The user will use this descriptor type in his descriptor configuration functions.
*/
/**
* \brief PDMA descriptor structure
*/
typedef struct stc_PDMA_DESCR_CTL_field {
uint32_t u2WAIT_FOR_DEACT:2;
uint32_t u2INTR_TYPE:2;
uint32_t u2TR_OUT_TYPE:2;
uint32_t u2TR_IN_TYPE:2;
uint32_t :16;
uint32_t u1CH_DISABLE:1;
uint32_t :1;
uint32_t u1SRC_TRANSFER_SIZE:1;
uint32_t u1DST_TRANSFER_SIZE:1;
uint32_t u2DATA_SIZE:2;
uint32_t u2DESCR_TYPE:2;
} stc_PDMA_DESCR_CTL_field_t;
typedef union un_PDMA_DESCR_CTL {
uint32_t u32Register;
stc_PDMA_DESCR_CTL_field_t stcField;
uint8_t au8Byte[4];
uint16_t au16Halfword[2];
} un_PDMA_DESCR_CTL_t;
typedef struct stc_PDMA_DESCR_X_CTL_field {
uint32_t u12SRC_X_INCR:12;
uint32_t u12DST_X_INCR:12;
uint32_t u8X_COUNT:8;
} stc_PDMA_DESCR_X_CTL_field_t;
typedef union un_PDMA_DESCR_X_CTL {
uint32_t u32Register;
stc_PDMA_DESCR_X_CTL_field_t stcField;
uint8_t au8Byte[4];
uint16_t au16Halfword[2];
} un_PDMA_DESCR_X_CTL_t;
typedef struct stc_PDMA_DESCR_Y_CTL_field {
uint32_t u12SRC_Y_INCR:12;
uint32_t u12DST_Y_INCR:12;
uint32_t u8Y_COUNT:8;
} stc_PDMA_DESCR_Y_CTL_field_t;
typedef union un_PDMA_DESCR_Y_CTL {
uint32_t u32Register;
stc_PDMA_DESCR_Y_CTL_field_t stcField;
uint8_t au8Byte[4];
uint16_t au16Halfword[2];
} un_PDMA_DESCR_Y_CTL_t;
typedef struct {
un_PDMA_DESCR_CTL_t unPDMA_DESCR_CTL;
uint32_t u32PDMA_DESCR_SRC;
uint32_t u32PDMA_DESCR_DST;
un_PDMA_DESCR_X_CTL_t unPDMA_DESCR_X_CTL;
un_PDMA_DESCR_Y_CTL_t unPDMA_DESCR_Y_CTL;
uint32_t u32PDMA_DESCR_NEXT_PTR;
} cy_stc_pdma_descr_t;
/**
* This structure is a configuration structure pre-initialized by the user and
* passed as a parameter to the CY_PDMA_InitDescr(). This structure has all the parameters
* of the descriptor as separate parameters. Some of these parameters are represented in the
* stc_Descr_t data structure as bit fields.
*/
typedef struct {
uint32_t deact; /**< Specifies whether the PDMA controller should wait for the input trigger to be deactivated */
uint32_t intrType; /**< Sets the event that triggers an interrupt, see \ref cy_en_pdma_inttype_t */
uint32_t trigoutType; /**< Sets the event that triggers an output, see \ref cy_en_pdma_trigouttype_t */
uint32_t chStateAtCmplt; /**< Specifies if the channel is enabled or disabled on completion of descriptor see \ref cy_en_pdma_chdesccmpl_t */
uint32_t triginType; /**< Sets what type of transfer is triggered, see \ref cy_en_pdma_trigintype_t */
uint32_t dataSize; /**< The size of the data bus for transfer, see \ref cy_en_pdma_datasize_t */
uint32_t srcTxfrSize; /**< The source transfer size */
uint32_t destTxfrSize; /**< The destination transfer size */
uint32_t descrType; /**< The type of the descriptor see \ref cy_en_pdma_descrtype_t*/
void * srcAddr; /**< The source address of the transfer */
void * destAddr; /**< The destination address of the transfer */
int32_t srcXincr; /**< The address increment of the source after each X-loop transfer */
int32_t destXincr; /**< The address increment of the destination after each X-loop transfer */
uint32_t xCount; /**< The number of transfers in an X-loop */
int32_t srcYincr; /**< The address increment of the source after each Y-loop transfer */
int32_t destYincr; /**< The address increment of the destination after each Y-loop transfer */
uint32_t yCount; /**< The number of transfers in the Y-loop */
cy_stc_pdma_descr_t* descrNext; /**< The next descriptor to chain after completion, a NULL value will signify no chaining */
} cy_stc_pdma_descr_config_t;
/** This structure holds the initialization values for the PDMA channel */
typedef struct {
cy_stc_pdma_descr_t* PDMA_Descriptor;/**< The PDMA descriptor associated with the channel being initialized */
uint32_t preemptable; /**< Specifies if the channel is preemptable by another higher-priority channel */
uint32_t priority; /**< This parameter specifies the channel's priority */
uint32_t enable; /**< This parameter specifies if the channel is enabled after initializing */
uint32_t priviledge;
uint32_t non_secure;
uint32_t bufferable;
uint32_t protection_context;
} cy_stc_pdma_chnl_config_t;
/** This structure holds the initialization values for the CRC feature on PDMA */
typedef struct {
uint32_t data_reverse;
uint32_t rem_reverse;
uint8_t data_xor;
uint32_t polynomial;
uint32_t lfsr32;
uint32_t rem_xor;
} cy_stc_pdma_crc_config_t;
/** \} group_pdma_data_structures */
/**
* \addtogroup group_pdma_enums
* \{
*/
/** Contains the options for the trigger input deactivation parameter type */
enum cy_en_pdma_deactivate_t {
CY_PDMA_TRIG_DEACT_NO_WAIT, /**< Don't wait for deactivation (for pulse sensitive triggers)*/
CY_PDMA_TRIG_DEACT_4CYC, /**< Wait for up to 4 cycles */
CY_PDMA_TRIG_DEACT_16CYC, /**< Wait for up to 16 cycles */
CY_PDMA_TRIG_DEACT_WAIT_INDEFINITELY, /**< Wait indefinitely. This option may result in controller lockup if the trigger is not de-activated */
} ;
/** Contains the options for the descriptor type */
enum cy_en_pdma_descrtype_t {
CY_PDMA_SINGLE_TRANSFER, /**< Single transfer */
CY_PDMA_1D_TRANSFER, /**< 1D transfer */
CY_PDMA_2D_TRANSFER, /**< 2D transfer */
CY_PDMA_CRC_TRANSFER /**< CRC transfer */
} ;
/** Contains the options for the interrupt-type parameter of the descriptor */
enum cy_en_pdma_inttype_t {
CY_PDMA_INTR_1ELEMENT_CMPLT, /**< Triggers on every element transfer completion */
CY_PDMA_INTR_X_LOOP_CMPLT, /**< Triggers on every X loop transfer completion */
CY_PDMA_INTR_DESCR_CMPLT, /**< Triggers on descriptor completion */
CY_PDMA_INTR_DESCRCHAIN_CMPLT /**< Triggers on completion of the entire descriptor chain */
} ;
/** This enum has the options for the trigger in the type parameter of the descriptor */
enum cy_en_pdma_trigouttype_t {
CY_PDMA_TRIGOUT_1ELEMENT_CMPLT, /**< Triggers on every element transfer completion */
CY_PDMA_TRIGOUT_X_LOOP_CMPLT, /**< Triggers on every X loop transfer completion */
CY_PDMA_TRIGOUT_DESCR_CMPLT, /**< Triggers on descriptor completion */
CY_PDMA_TRIGOUT_DESCRCHAIN_CMPLT /**< Triggers on completion of the entire descriptor chain */
} ;
/** This enum has the options for the trigger-in-type parameter of the descriptor */
enum cy_en_pdma_trigintype_t {
CY_PDMA_TRIGIN_1ELEMENT, /**< One transfer per trigger */
CY_PDMA_TRIGIN_XLOOP, /**< One X loop transfer per trigger */
CY_PDMA_TRIGIN_DESCR, /**< The entire descriptor transfer per trigger */
CY_PDMA_TRIGIN_DESCRCHAIN /**< The entire descriptor chain per trigger */
} ;
/** This enum has the options for the data size */
enum cy_en_pdma_datasize_t {
CY_PDMA_BYTE, /**< One byte */
CY_PDMA_HALFWORD, /**< Half word (two bytes) */
CY_PDMA_WORD /**< Full word (four bytes) */
} ;
/** This enum has the options for descriptor retriggering */
enum cy_en_pdma_retrigger_t {
CY_PDMA_RETDIG_IM, /**< Retrigger immediately */
CY_PDMA_RETDIG_4CYC, /**< Retrigger after 4 SYSCLK */
CY_PDMA_RETDIG_16CYC, /**< Retrigger after 16 SYSCLK */
CY_PDMA_WAIT_FOR_REACT /**< Wait for trigger reactivation */
};
/** This enum has the options for the transfer size */
enum cy_en_pdma_txfrsize_t {
CY_PDMA_TXFR_SIZE_DATA_SIZE, /**< As per data size register */
CY_PDMA_TXFR_SIZE_WORD /**< A full word (four bytes) */
};
/** This enum has the options for the state of the channel when the descriptor is completed */
enum cy_en_pdma_chdesccmpl_t {
CY_PDMA_CH_ENABLED, /**< Channel stays enabled */
CY_PDMA_CH_DISABLED /**< Channel is disabled */
};
/** This enum has the return values of the PDMA driver */
typedef enum
{
CY_PDMA_SUCCESS = 0x00ul, /**< Success */
CY_PDMA_INVALID_INPUT_PARAMETERS = ( CY_PDMA_ID_ERROR + 1ul), /**< Input parameters passed to PDMA API are not valid */
CY_PDMA_ERR_UNC = ( CY_PDMA_ID_ERROR + 0xFul),/**< Unknown error */
} cy_en_pdma_status_t;
/** \} group_pdma_enums */
/**
* \addtogroup group_pdma_functions
* \{
*/
//IP functions
void Cy_PDMA_Enable ( volatile stc_DW_t * pstcPDMA);
void Cy_PDMA_Disable ( volatile stc_DW_t * pstcPDMA);
uint32_t Cy_PDMA_GetActiveChnl ( const volatile stc_DW_t * pstcPDMA);
void* Cy_PDMA_GetActiveSrcAddr ( const volatile stc_DW_t * pstcPDMA);
void* Cy_PDMA_GetActiveDstAddr ( const volatile stc_DW_t * pstcPDMA);
void Cy_PDMA_CRC_Config ( volatile stc_DW_t * pstcPDMA,
const cy_stc_pdma_crc_config_t* pstcCrcConfig);
uint32_t Cy_PDMA_GetCrcRemainderResult ( volatile stc_DW_t * pstcPDMA);
//Descriptor functions
cy_en_pdma_status_t Cy_PDMA_Descr_Init ( cy_stc_pdma_descr_t* descriptor,
const cy_stc_pdma_descr_config_t* config);
void Cy_PDMA_Descr_DeInit ( cy_stc_pdma_descr_t* descriptor);
__STATIC_INLINE void Cy_PDMA_Descr_SetSrcAddr ( cy_stc_pdma_descr_t* descriptor,
const void * srcAddr);
__STATIC_INLINE void Cy_PDMA_Descr_SetDestAddr ( cy_stc_pdma_descr_t* descriptor,
const void * dstAddr);
void Cy_PDMA_Descr_SetNxtDescr ( cy_stc_pdma_descr_t* descriptor,
const cy_stc_pdma_descr_t* nxtDescriptor);
__STATIC_INLINE void Cy_PDMA_Descr_SetIntrType ( cy_stc_pdma_descr_t* descriptor,
uint32_t interruptType);
__STATIC_INLINE void Cy_PDMA_Descr_SetTrigInType ( cy_stc_pdma_descr_t* descriptor,
uint32_t trigInType);
__STATIC_INLINE void Cy_PDMA_Descr_SetTrigOutType ( cy_stc_pdma_descr_t* descriptor,
uint32_t trigOutType);
void Cy_PDMA_Descr_SetTxfrWidth ( cy_stc_pdma_descr_t* descriptor,
uint32_t dataElementSize,
uint32_t srcTxfrWidth,
uint32_t dstTxfrWidth);
//Channel functions
cy_en_pdma_status_t Cy_PDMA_Chnl_Init ( volatile stc_DW_t * pstcPDMA,
uint32_t chNum,
const cy_stc_pdma_chnl_config_t* chnlConfig);
void Cy_PDMA_Chnl_DeInit ( volatile stc_DW_t * pstcPDMA,
uint32_t chNum);
__STATIC_INLINE void Cy_PDMA_Chnl_SetDescr ( volatile stc_DW_t * pstcPDMA,
uint32_t chNum,
const cy_stc_pdma_descr_t* descriptor);
__STATIC_INLINE void Cy_PDMA_Chnl_Enable ( volatile stc_DW_t * pstcPDMA,
uint32_t chNum);
__STATIC_INLINE void Cy_PDMA_Chnl_Disable ( volatile stc_DW_t * pstcPDMA,
uint32_t chNum);
__STATIC_INLINE void Cy_PDMA_Chnl_SetPriority ( volatile stc_DW_t * pstcPDMA,
uint32_t chNum,
uint32_t priority);
__STATIC_INLINE uint32_t Cy_PDMA_Chnl_GetPriority ( const volatile stc_DW_t * pstcPDMA,
uint32_t chNum);
__STATIC_INLINE cy_stc_pdma_descr_t* Cy_PDMA_Chnl_GetCurrentDescr ( const volatile stc_DW_t * pstcPDMA,
uint32_t chNum);
__STATIC_INLINE uint32_t Cy_PDMA_Chnl_GetInterruptStatus ( const volatile stc_DW_t * pstcPDMA,
uint32_t chNum);
__STATIC_INLINE uint32_t Cy_PDMA_Chnl_GetInterruptCause ( const volatile stc_DW_t * pstcPDMA,
uint32_t chNum);
void Cy_PDMA_Chnl_ClearInterrupt ( volatile stc_DW_t * pstcPDMA,
uint32_t chNum);
__STATIC_INLINE void Cy_PDMA_Chnl_SetInterrupt ( volatile stc_DW_t * pstcPDMA,
uint32_t chNum);
__STATIC_INLINE uint32_t Cy_PDMA_Chnl_GetInterruptMask ( const volatile stc_DW_t * pstcPDMA,
uint32_t chNum);
__STATIC_INLINE void Cy_PDMA_Chnl_SetInterruptMask ( volatile stc_DW_t * pstcPDMA,
uint32_t chNum);
__STATIC_INLINE uint32_t Cy_PDMA_Chnl_GetInterruptStatusMasked ( const volatile stc_DW_t * pstcPDMA,
uint32_t chNum);
#if defined(CPUSS_SW_TR_PRESENT) && (CPUSS_SW_TR_PRESENT == 1)
__STATIC_INLINE void Cy_PDMA_Chnl_SetSwTrigger ( volatile stc_DW_t * pstcPDMA,
uint32_t chNum);
#endif
/***************************************
* In-line Function Implementation
***************************************/
/*******************************************************************************
* Function Name: Cy_PDMA_Descr_SetSrcAddr
****************************************************************************//**
*
* \brief Sets the source address parameter for the descriptor structure.
*
* This function will operate on the descriptor only if it was defined as a RAM
* variable.
* If the descriptor is being defined in Flash, then the user has to use the
* configuration defines to initialize it.
*
* \param descriptor
* This is a descriptor-structure instance declared by the user. The function
* modifies the source-address parameter in this descriptor.
*
* \param srcAddr
* The source address value for the descriptor.
*
*******************************************************************************/
__STATIC_INLINE void Cy_PDMA_Descr_SetSrcAddr(cy_stc_pdma_descr_t* descriptor, const void * srcAddr)
{
descriptor->u32PDMA_DESCR_SRC = (uint32_t)srcAddr;
}
/*******************************************************************************
* Function Name: Cy_PDMA_Descr_SetDestAddr
****************************************************************************//**
*
* \brief Sets the destination address parameter for the descriptor structure.
*
* This function will operate in the descriptor only if it was defined as a RAM
* variable.
* If the descriptor is being defined in Flash, then the user has to use the
* configuration defines to initialize it.
*
* \param descriptor
* This is a descriptor-structure instance declared by the user. The function
* modifies the destination-address parameter in this descriptor.
*
* \param dstAddr
* The destination address value for the descriptor.
*
*******************************************************************************/
__STATIC_INLINE void Cy_PDMA_Descr_SetDestAddr(cy_stc_pdma_descr_t* descriptor, const void * dstAddr)
{
descriptor->u32PDMA_DESCR_DST = (uint32_t)dstAddr;
}
/*******************************************************************************
* Function Name: Cy_PDMA_Chnl_SetDescr
****************************************************************************//**
*
* \brief Sets a descriptor as current for specified PDMA channel.
*
* \param pstcPDMA
* Pointer to the hardware PDMA block.
*
* \param chNum
* Channel number of the PDMA.
*
* \param descriptor
* This is the descriptor which will be associated with the channel.
*
*******************************************************************************/
__STATIC_INLINE void Cy_PDMA_Chnl_SetDescr(volatile stc_DW_t *pstcPDMA, uint32_t chNum, const cy_stc_pdma_descr_t* descriptor)
{
pstcPDMA->CH_STRUCT[chNum].unCH_CURR_PTR.u32Register = (uint32_t)descriptor;
}
/*******************************************************************************
* Function Name: Cy_PDMA_Chnl_Enable
****************************************************************************//**
*
* The function is used to enable a PDMA channel.
*
* \param pstcPDMA
* Pointer to the hardware PDMA block.
*
* \param chNum
* Channel number of the PDMA.
*
*******************************************************************************/
__STATIC_INLINE void Cy_PDMA_Chnl_Enable(volatile stc_DW_t *pstcPDMA, uint32_t chNum)
{
pstcPDMA->CH_STRUCT[chNum].unCH_CTL.stcField.u1ENABLED = 1ul;
}
/*******************************************************************************
* Function Name: Cy_PDMA_Chnl_Disable
****************************************************************************//**
*
* The function is used to disable a PDMA channel.
*
* \param pstcPDMA
* Pointer to the hardware PDMA block.
*
* \param chNum
* Channel number of the PDMA.
*
*******************************************************************************/
__STATIC_INLINE void Cy_PDMA_Chnl_Disable(volatile stc_DW_t *pstcPDMA, uint32_t chNum)
{
pstcPDMA->CH_STRUCT[chNum].unCH_CTL.stcField.u1ENABLED = 0ul;
}
/*******************************************************************************
* Function Name: Cy_PDMA_Chnl_SetPriority
****************************************************************************//**
*
* The function is used to set a priority for the PDMA channel.
*
* \param pstcPDMA
* Pointer to the hardware PDMA block.
*
* \param chNum
* Channel number of the PDMA.
*
* \param priority
* The priority to be set for the PDMA channel. The allowed values are 0,1,2,3.
*
*******************************************************************************/
__STATIC_INLINE void Cy_PDMA_Chnl_SetPriority(volatile stc_DW_t *pstcPDMA, uint32_t chNum, uint32_t priority)
{
pstcPDMA->CH_STRUCT[chNum].unCH_CTL.stcField.u2PRIO = priority;
}
/*******************************************************************************
* Function Name: Cy_PDMA_Chnl_GetPriority
****************************************************************************//**
*
* Returns the priority of PDMA channel.
*
* \param pstcPDMA
* Pointer to the hardware PDMA block.
*
* \param chNum
* Channel number of the PDMA.
*
* \return
* The priority of the channel.
*
*******************************************************************************/
__STATIC_INLINE uint32_t Cy_PDMA_Chnl_GetPriority(const volatile stc_DW_t *pstcPDMA, uint32_t chNum)
{
return pstcPDMA->CH_STRUCT[chNum].unCH_CTL.stcField.u2PRIO;
}
/*******************************************************************************
* Function Name: Cy_PDMA_Chnl_GetCurrentDescr
****************************************************************************//**
*
* This function returns the descriptor that is active in the channel.
*
* \param pstcPDMA
* Pointer to the hardware PDMA block.
*
* \param chNum
* Channel number of the PDMA.
*
* \return
* The pointer to the descriptor associated with the channel.
*
*******************************************************************************/
__STATIC_INLINE cy_stc_pdma_descr_t* Cy_PDMA_Chnl_GetCurrentDescr(const volatile stc_DW_t *pstcPDMA, uint32_t chNum)
{
return (cy_stc_pdma_descr_t*) pstcPDMA->CH_STRUCT[chNum].unCH_CURR_PTR.u32Register;
}
/*******************************************************************************
* Function Name: Cy_PDMA_Descr_SetIntrType
****************************************************************************//**
*
* Sets the interrupt type parameter for the descriptor structure.
* This function will operate in the descriptor only if it was defined as a RAM
* variable.
* If the descriptor is being defined in Flash, then the user has to use the
* configuration defines to initialize it.
*
* \param descriptor
* This is the descriptor-structure instance declared by the user. This is the
* descriptor being modified.
*
* \param interruptType
* The interrupt type set for the descriptor.
*
*******************************************************************************/
__STATIC_INLINE void Cy_PDMA_Descr_SetIntrType(cy_stc_pdma_descr_t* descriptor, uint32_t interruptType)
{
descriptor->unPDMA_DESCR_CTL.stcField.u2INTR_TYPE = interruptType;
}
/*******************************************************************************
* Function Name: Cy_PDMA_Descr_SetTrigInType
****************************************************************************//**
*
* Sets the trigger-in-type parameter for the descriptor structure.
* This function will operate in the descriptor only if it was defined as a RAM
* variable.
* If the descriptor is being defined in Flash, then the user has to use the
* configuration defines to initialize it.
*
* \param descriptor
* This is a descriptor structure instance declared by the user. This is the
* descriptor being modified.
*
* \param trigInType
* The trigger-in-type set for the descriptor. \ref cy_en_pdma_trigintype_t
*
*******************************************************************************/
__STATIC_INLINE void Cy_PDMA_Descr_SetTrigInType(cy_stc_pdma_descr_t* descriptor, uint32_t trigInType)
{
descriptor->unPDMA_DESCR_CTL.stcField.u2TR_IN_TYPE = trigInType;
}
/*******************************************************************************
* Function Name: Cy_PDMA_Descr_SetTrigOutType
****************************************************************************//**
*
* This function sets the trigger-out-type parameter for for the descriptor
* structure.
* This function will operate in the descriptor only if it was defined as a RAM
* variable.
* If the descriptor is being defined in Flash, then the user has to use the
* configuration defines to initialize it.
*
* \param descriptor
* This is a descriptor-structure instance declared by the user. This is the
* descriptor being modified.
*
* \param trigOutType
* The trigger-out-type set for the descriptor. \ref cy_en_pdma_trigouttype_t
*
*******************************************************************************/
__STATIC_INLINE void Cy_PDMA_Descr_SetTrigOutType(cy_stc_pdma_descr_t* descriptor, uint32_t trigOutType)
{
descriptor->unPDMA_DESCR_CTL.stcField.u2TR_OUT_TYPE = trigOutType;
}
/*******************************************************************************
* Function Name: Cy_PDMA_Chnl_GetInterruptStatus
****************************************************************************//**
*
* This function can be used to determine the interrupt status of the
* PDMA channel.
*
* \param pstcPDMA
* Pointer to the hardware PDMA block.
*
* \param chNum
* Channel number of the PDMA.
*
* \return
* Returns a status of an interrupt for specified channel.
*
*******************************************************************************/
__STATIC_INLINE uint32_t Cy_PDMA_Chnl_GetInterruptStatus(const volatile stc_DW_t *pstcPDMA, uint32_t chNum)
{
return (pstcPDMA->CH_STRUCT[chNum].unINTR.u32Register);
}
/*******************************************************************************
* Function Name: Cy_PDMA_Chnl_GetInterruptCause
****************************************************************************//**
*
* This function can be used to determine the interrupt reason of the
* PDMA channel.
*
* \param pstcPDMA
* Pointer to the hardware PDMA block.
*
* \param chNum
* Channel number of the PDMA.
*
* \return
* Returns a status of an interrupt for specified channel.
* (see \ref group_pdma_common_macro_PDMAIntrCauses for return values).
* For error related interrupt causes (INTR_CAUSE is "1", "2", "3", ..., "8"),
* the channel is disabled (HW sets CH_CTL.ENABLED to '0').
*
*******************************************************************************/
__STATIC_INLINE uint32_t Cy_PDMA_Chnl_GetInterruptCause(const volatile stc_DW_t *pstcPDMA, uint32_t chNum)
{
return (pstcPDMA->CH_STRUCT[chNum].unCH_STATUS.stcField.u4INTR_CAUSE);
}
/*******************************************************************************
* Function Name: Cy_PDMA_Chnl_SetInterrupt
****************************************************************************//**
*
* This function sets the interrupt.
*
* \param pstcPDMA
* Pointer to the hardware PDMA block.
*
* \param chNum
* Channel number of the PDMA.
*
*******************************************************************************/
__STATIC_INLINE void Cy_PDMA_Chnl_SetInterrupt(volatile stc_DW_t *pstcPDMA, uint32_t chNum)
{
pstcPDMA->CH_STRUCT[chNum].unINTR_SET.u32Register = CY_PDMA_INTR_BIT_MASK;
}
/*******************************************************************************
* Function Name: Cy_PDMA_Chnl_GetInterruptMask
****************************************************************************//**
*
* This function gets interrupt mask value.
*
* \param pstcPDMA
* Pointer to the hardware PDMA block.
*
* \param chNum
* Channel number of the PDMA.
*
* \return
* Returns an interrupt mask value.
*
*******************************************************************************/
__STATIC_INLINE uint32_t Cy_PDMA_Chnl_GetInterruptMask(const volatile stc_DW_t *pstcPDMA, uint32_t chNum)
{
return (pstcPDMA->CH_STRUCT[chNum].unINTR_MASK.u32Register);
}
/*******************************************************************************
* Function Name: Cy_PDMA_Chnl_SetInterruptMask
****************************************************************************//**
*
* This function sets interrupt mask value.
*
* \param pstcPDMA
* Pointer to the hardware PDMA block.
*
* \param chNum
* Channel number of the PDMA.
*
*******************************************************************************/
__STATIC_INLINE void Cy_PDMA_Chnl_SetInterruptMask(volatile stc_DW_t *pstcPDMA, uint32_t chNum)
{
pstcPDMA->CH_STRUCT[chNum].unINTR_MASK.u32Register = CY_PDMA_INTR_BIT_MASK;
}
/*******************************************************************************
* Function Name: Cy_PDMA_Chnl_GetInterruptStatusMasked
****************************************************************************//**
*
* This function returns logical and of corresponding INTR and INTR_MASK fields
* in a single load operation.
*
* \param pstcPDMA
* Pointer to the hardware PDMA block.
*
* \param chNum
* Channel number of the PDMA.
*
*******************************************************************************/
__STATIC_INLINE uint32_t Cy_PDMA_Chnl_GetInterruptStatusMasked(const volatile stc_DW_t *pstcPDMA, uint32_t chNum)
{
return (pstcPDMA->CH_STRUCT[chNum].unINTR_MASKED.u32Register);
}
#if defined(CPUSS_SW_TR_PRESENT) && (CPUSS_SW_TR_PRESENT == 1)
/*******************************************************************************
* Function Name: Cy_PDMA_Chnl_SetSwTrigger
****************************************************************************//**
*
* This function sets the SW trigger for a channel.
*
* \param pstcPDMA
* Pointer to the hardware PDMA block.
*
* \param chNum
* Channel number of the PDMA.
*
* \return
* Returns an interrupt mask value.
*
*******************************************************************************/
__STATIC_INLINE void Cy_PDMA_Chnl_SetSwTrigger(volatile stc_DW_t *pstcPDMA, uint32_t chNum)
{
pstcPDMA->CH_STRUCT[chNum].unTR_CMD.stcField.u1ACTIVATE = 1ul;
}
#endif
/** \} group_pdma_functions */
#if defined(__cplusplus)
}
#endif
#endif /* (CY_PDMA_H) */
/** \} group_pdma */
/* [] END OF FILE */
@@ -0,0 +1,283 @@
/***************************************************************************//**
* \file cy_evtgen.c
* \version 1.0
*
* \brief
* Provides the public functions for the API for the Traveo II Event generator Driver.
*
********************************************************************************
* \copyright
* Copyright 2016-2017, Cypress Semiconductor Corporation. All rights reserved.
* You may use this file only in accordance with the license, terms, conditions,
* disclaimers, and limitations in the end user license agreement accompanying
* the software package with which this file was provided.
*******************************************************************************/
#include "cy_evtgen.h"
#include "syslib/cy_syslib.h"
static cy_stc_evtgen_struct_context_t *evtgenContext[EVTGEN_COMP_STRUCT_NR];
uint32_t mapUsed;
/*******************************************************************************
* Function Name: Cy_Evtgen_Initialize
****************************************************************************//**
*
* \brief Initialize the event generator
*
* \param config
* Pointer to the event generator config structure base address
*
* \return
* Event generator initialization status
*
*******************************************************************************/
cy_en_evtgendrv_status_t Cy_Evtgen_Initialize(volatile stc_EVTGEN_t *base, const cy_stc_evtgen_config_t* config)
{
uint16_t refDiv;
un_EVTGEN_RATIO_CTL_t ratioCtl;
/* 1. Checking input parameter valid */
if(config == NULL)
{
return CY_EVTGEN_ERR;
}
/* 2. Initialize internal variable */
for(uint32_t i = 0; i < EVTGEN_COMP_STRUCT_NR; i++)
{
evtgenContext[i] = NULL;
}
mapUsed = 0;
Cy_Evtgen_Enable(base);
/* 2. Setting divider value of clk_ref */
refDiv = config->frequencyRef / config->frequencyTick;
if(config->frequencyRef % config->frequencyTick != 0)
{
return CY_EVTGEN_ERR;
}
else if(refDiv > 256 || refDiv < 1)
{
return CY_EVTGEN_ERR;
}
else
{
base->unREF_CLOCK_CTL.stcField.u8INT_DIV = refDiv - 1u;
}
/* 3. Setting ratio operation */
if(config->ratioControlMode == CY_EVTGEN_RATIO_CONTROL_SW)
{
/* SW controll: setting value for ratio value should be ratio between tick_ref_div and clk_lf. */
uint64_t temp = (uint64_t)(config->frequencyRef / refDiv) << EVTGEN_RATIO_INT16_Pos;
temp = temp / (uint64_t)(config->frequencyLf);
base->unRATIO.u32Register = ((uint32_t)temp) & (EVTGEN_RATIO_INT16_Msk | EVTGEN_RATIO_FRAC8_Msk);
base->unRATIO_CTL.stcField.u1DYNAMIC = 0u;
/* SW controll: valid bit should be set manually. */
base->unRATIO_CTL.stcField.u1VALID = 1u; /* Set VALID bit */
}
else
{
/* HW controll: */
ratioCtl.u32Register = base->unRATIO_CTL.u32Register;
ratioCtl.stcField.u1DYNAMIC = 1u; /* Set Dynamic bit */
ratioCtl.stcField.u3DYNAMIC_MODE = config->ratioValueDynamicMode; /* Set Dynamic bit */
base->unRATIO_CTL.u32Register = ratioCtl.u32Register;
/* Waiting until valid bit is set. */
while(base->unRATIO_CTL.stcField.u1VALID == 0u);
}
/* Waiting until counter become ready. */
while(base->unCOUNTER_STATUS.stcField.u1VALID == 0u);
return CY_EVTGEN_OK;
}
/*******************************************************************************
* Function Name: Cy_Evtgen_Deinitialize
****************************************************************************//**
*
* \brief Deinitialize event generator
*
*******************************************************************************/
void Cy_Evtgen_Deinitialize(volatile stc_EVTGEN_t *base)
{
base->unCTL.u32Register = 0;
base->unREF_CLOCK_CTL.u32Register = 0;
base->unRATIO.u32Register = 0;
base->unRATIO_CTL.u32Register = 0;
base->unINTR_MASK.u32Register = 0;
base->unINTR_DPSLP_MASK.u32Register = 0;
}
/*******************************************************************************
* Function Name: Cy_Evtgen_InitializeCompStruct
****************************************************************************//**
*
* \brief Initialize a comparator structure
*
* \param config
* Number of structure to be initilized
*
* \param configStruct
* Pointer to the event generator structure config structure base address
*
* \param context
* Pointer to internal context
*
* \return
* Event generator initialization status
*
*******************************************************************************/
cy_en_evtgendrv_status_t Cy_Evtgen_InitializeCompStruct(volatile stc_EVTGEN_t *base,
uint8_t structNum,
const cy_stc_evtgen_struct_config_t* configStruct,
cy_stc_evtgen_struct_context_t* context)
{
un_EVTGEN_COMP_STRUCT_COMP_CTL_t compCtr;
uint64_t tempCounterValue;
uint32_t savedIntrStatus;
/* Checking input parameter valid */
if(configStruct == NULL)
{
return CY_EVTGEN_ERR;
}
if(structNum >= EVTGEN_COMP_STRUCT_NR)
{
return CY_EVTGEN_ERR;
}
if(configStruct->functionalitySelection != CY_EVTGEN_DEEPSLEEP_FUNCTIONALITY)
{
if(context == NULL)
{
return CY_EVTGEN_ERR;
}
evtgenContext[structNum] = context;
evtgenContext[structNum]->addValueForCOMP0 = configStruct->valueActiveComparator;
evtgenContext[structNum]->userIsr = configStruct->userIsr;
mapUsed |= 1 << structNum;
}
compCtr.u32Register = base->COMP_STRUCT[structNum].unCOMP_CTL.u32Register;
if(configStruct->functionalitySelection == CY_EVTGEN_DEEPSLEEP_FUNCTIONALITY)
{
compCtr.stcField.u1COMP1_EN = 1u;
}
compCtr.stcField.u1COMP0_EN = 1u;
compCtr.stcField.u1TR_OUT_EDGE = configStruct->triggerOutEdge;
compCtr.stcField.u1ENABLED = 1u;
savedIntrStatus = Cy_SysLib_EnterCriticalSection();
tempCounterValue = (uint64_t)Cy_Evtgen_GetCounterValue(base);
/* Setting active comparator value */
base->COMP_STRUCT[structNum].unCOMP0.stcField.u32INT32 = (uint32_t)(tempCounterValue + (uint64_t)configStruct->valueActiveComparator);
/* Setting deep sleep comparator value */
if(configStruct->functionalitySelection == CY_EVTGEN_DEEPSLEEP_FUNCTIONALITY)
{
base->COMP_STRUCT[structNum].unCOMP1.stcField.u32INT32 = (uint32_t)(tempCounterValue + (uint64_t)configStruct->valueDeepSleepComparator);
}
Cy_SysLib_ExitCriticalSection(savedIntrStatus);
/* Setting comparator struct controll parameter */
base->COMP_STRUCT[structNum].unCOMP_CTL.u32Register = compCtr.u32Register;
Cy_Evtgen_SetInterruptMask(base, structNum);
if(configStruct->functionalitySelection == CY_EVTGEN_DEEPSLEEP_FUNCTIONALITY)
{
Cy_Evtgen_SetInterruptDeepSleepMask(base, structNum);
}
return CY_EVTGEN_OK;
}
/*******************************************************************************
* Function Name: Cy_Evtgen_DeinitializeCompStruct
****************************************************************************//**
*
* \brief Deinitialize event generator struct
*
* \param structNum
* Number of structure to be de-initilized
*
*******************************************************************************/
void Cy_Evtgen_DeinitializeCompStruct(volatile stc_EVTGEN_t *base, uint8_t structNum)
{
base->COMP_STRUCT[structNum].unCOMP_CTL.u32Register = 0;
base->COMP_STRUCT[structNum].unCOMP0.stcField.u32INT32 = 0;
base->COMP_STRUCT[structNum].unCOMP1.stcField.u32INT32 = 0;
evtgenContext[structNum] = NULL;
}
/*******************************************************************************
* Function Name: Cy_Evtgen_Interrupt
****************************************************************************//**
*
* \brief Interrupt handler for event generator
*
* \note Please call this function in the interrupt handler of event generator.
* This function can clear interrupt factors multiple time therefore the user
* needs to clear pending status of NVIC at the end of the handler to avoid
* hard fault exception.
*
*******************************************************************************/
void Cy_Evtgen_Interrupt(volatile stc_EVTGEN_t *base)
{
uint64_t tempCompValue;
uint32_t masked = base->unINTR_MASKED.u32Register;
uint32_t temp_masked;
uint32_t operatingStructNum = 0;
masked &= mapUsed;
temp_masked = masked;
// Clear all interrupt flags used in active functionality.
Cy_Evtgen_ClearInterrupt(base, temp_masked);
while (temp_masked != 0)
{
if (temp_masked & 0x01)
{
tempCompValue = (uint64_t)base->COMP_STRUCT[operatingStructNum].unCOMP0.stcField.u32INT32;
tempCompValue += (uint64_t)evtgenContext[operatingStructNum]->addValueForCOMP0;
base->COMP_STRUCT[operatingStructNum].unCOMP_CTL.stcField.u1COMP0_EN = 0u;
base->COMP_STRUCT[operatingStructNum].unCOMP0.stcField.u32INT32 = (uint32_t)tempCompValue;
base->COMP_STRUCT[operatingStructNum].unCOMP_CTL.stcField.u1COMP0_EN = 1u;
}
temp_masked >>= 1;
operatingStructNum++;
}
operatingStructNum = 0;
temp_masked = masked;
while(temp_masked != 0)
{
if(temp_masked & 0x01)
{
if(evtgenContext[operatingStructNum]->userIsr != NULL)
{
evtgenContext[operatingStructNum]->userIsr();
}
}
temp_masked >>= 1;
operatingStructNum++;
}
}
/* [] END OF FILE */
@@ -0,0 +1,542 @@
/***************************************************************************//**
* \file cy_evtgen.h
* \version 1.0
*
* Provides the API declarations of the Event generator driver.
*
********************************************************************************
* \copyright
* Copyright 2016-2017, Cypress Semiconductor Corporation. All rights reserved.
* You may use this file only in accordance with the license, terms, conditions,
* disclaimers, and limitations in the end user license agreement accompanying
* the software package with which this file was provided.
*******************************************************************************/
#if !defined(CY_EVTGEN_H)
#define CY_EVTGEN_H
/**
* \defgroup group_evtgen Event Generator (EVTGEN)
* \{
* This driver provides global EVTGEN defines and API function definitions.
*
* \defgroup group_evtgen_macros Macro
* \defgroup group_evtgen_functions Functions
* \defgroup group_evtgen_data_structures Data structures
* \defgroup group_evtgen_enums Enumerated types
*/
#include <stdint.h>
#include <stdbool.h>
#include <stddef.h>
#include "cy_device_headers.h"
/***************************************
* Macro definitions
***************************************/
/**
* \addtogroup group_evtgen_macros
* \{
*/
/** Driver major version */
#define CY_EVTGEN_DRV_VERSION_MAJOR 1
/** Driver minor version */
#define CY_EVTGEN_DRV_VERSION_MINOR 0
/** \} group_evtgen_macros */
/**
* \addtogroup group_evtgen_enums
* \{
*/
/**
* Specifies return values meaning
*/
/** This enum has the return values of the Event generator driver */
typedef enum
{
CY_EVTGEN_OK = 0u,
CY_EVTGEN_ERR,
} cy_en_evtgendrv_status_t;
typedef enum
{
CY_EVTGEN_DISABLE = 0u,
CY_EVTGEN_ENABLE = 1u,
} cy_en_evtgendrv_enable_t;
typedef enum
{
CY_EVTGEN_RATIO_INVALID = 0u,
CY_EVTGEN_RATIO_VALID = 1u,
} cy_en_evtgendrv_ratio_valid_t;
typedef enum
{
CY_EVTGEN_RATIO_STATIC = 0u,
CY_EVTGEN_RATIO_DYNAMIC = 1u,
} cy_en_evtgendrv_ratio_dynamic_t;
typedef enum
{
CY_EVTGEN_COUNTER_STATUS_INVALID = 0u,
CY_EVTGEN_COUNTER_STATUS_VALID = 1u,
} cy_en_evtgen_counter_status_t;
typedef enum
{
CY_EVTGEN_RATIO_DYNAMIC_MODE0 = 0u, // new RATIO value = (RATIO + measurement + 1) / 2.
CY_EVTGEN_RATIO_DYNAMIC_MODE1 = 1u, // new RATIO value = (3*RATIO + measurement + 2) / 4.
CY_EVTGEN_RATIO_DYNAMIC_MODE2 = 2u, // new RATIO value = (7*RATIO + measurement + 4) / 8.
CY_EVTGEN_RATIO_DYNAMIC_MODE3 = 3u, // new RATIO value = (15*RATIO + measurement + 8) / 16.
CY_EVTGEN_RATIO_DYNAMIC_MODE4 = 4u, // new RATIO value = (31*RATIO + measurement + 16) / 32.
CY_EVTGEN_RATIO_DYNAMIC_MODE5 = 5u, // new RATIO value = (63*RATIO + measurement + 32) / 64.
CY_EVTGEN_RATIO_DYNAMIC_MODE6 = 6u, // new RATIO value = (127*RATIO + measurement + 64) / 128.
CY_EVTGEN_RATIO_DYNAMIC_MODE7 = 7u, // new RATIO value = (255*RATIO + measurement + 128) / 256.
} cy_en_evtgendrv_ratio_dynamic_mode_t;
typedef enum
{
CY_EVTGEN_RATIO_CONTROL_SW = 0u,
CY_EVTGEN_RATIO_CONTROL_HW,
} cy_en_evtgendrv_ratio_control;
typedef enum
{
CY_EVTGEN_STRUCT_DISABLE = 0u,
CY_EVTGEN_STRUCT_ENABLE,
} cy_en_evtgendrv_struct_enable_t;
typedef enum
{
CY_EVTGEN_ACTIVE_COMP_DISABLE = 0u,
CY_EVTGEN_ACTIVE_COMP_ENABLE,
} cy_en_evtgendrv_enable_active_cmp_t;
typedef enum
{
CY_EVTGEN_DSLEEP_COMP_DISABLE = 0u,
CY_EVTGEN_DSLEEP_COMP_ENABLE,
} cy_en_evtgendrv_enable_dsleep_cmp_t;
typedef enum
{
CY_EVTGEN_LEVEL_SENSITIVE = 0u,
CY_EVTGEN_EDGE_SENSITIVE,
} cy_en_evtgendrv_struct_trg_edge_t;
typedef enum
{
CY_EVTGEN_ACTIVE_FUNCTIONALITY = 0u,
CY_EVTGEN_DEEPSLEEP_FUNCTIONALITY,
} cy_en_evtgendrv_struct_functionality;
/** \} group_evtgen_enums */
#if defined(__cplusplus)
extern "C" {
#endif
/***************************************
* Data Structure definitions
***************************************/
/**
* \addtogroup group_evtgen_data_structures
* \{
*/
/** Event generator driver context */
typedef struct
{
uint32_t frequencyRef;
uint32_t frequencyLf;
uint32_t frequencyTick;
cy_en_evtgendrv_ratio_control ratioControlMode;
cy_en_evtgendrv_ratio_dynamic_mode_t ratioValueDynamicMode; /**< Specifies the configuration of evtgen operation */
}cy_stc_evtgen_config_t;
typedef void (* cy_evtgen_handler)(void); /**< Type of ISR callbacks */
typedef struct
{
cy_en_evtgendrv_struct_functionality functionalitySelection;
cy_en_evtgendrv_struct_trg_edge_t triggerOutEdge; /**< Specifies the code of evtgen operation */
uint32_t valueActiveComparator; /**< Specifies the configuration of evtgen operation */
uint32_t valueDeepSleepComparator; /**< Specifies the configuration of evtgen operation */
cy_evtgen_handler userIsr;
}cy_stc_evtgen_struct_config_t;
typedef struct
{
uint32_t addValueForCOMP0; /**< Specifies the configuration of evtgen operation */
cy_evtgen_handler userIsr;
}cy_stc_evtgen_struct_context_t;
/** \} group_evtgen_data_structures */
/***************************************
* Function Prototypes
***************************************/
/**
* \addtogroup group_evtgen_functions
* \{
*/
/*******************************************************************************
* Function Name: Cy_Evtgen_Enable
****************************************************************************//**
*
* \brief Enable event generator
*
* \return
* void
*
*******************************************************************************/
__STATIC_INLINE void Cy_Evtgen_Enable(volatile stc_EVTGEN_t *base)
{
base->unCTL.stcField.u1ENABLED = 1u; /* Set ENABLED bit */
}
/*******************************************************************************
* Function Name: Cy_Evtgen_SetInterrupt
****************************************************************************//**
*
* \brief Set interrupt factor of corresponding structure
*
* \param [in] structNumber
* Number of structure. The interrupt factor of that is to be set
*
* \return
* void
*
*******************************************************************************/
__STATIC_INLINE void Cy_Evtgen_SetInterrupt(volatile stc_EVTGEN_t *base, uint8_t structNumber)
{
base->unINTR_SET.u32Register = ((uint32_t)1 << structNumber);
}
/*******************************************************************************
* Function Name: Cy_Evtgen_ClearInterrupt
****************************************************************************//**
*
* \brief Clear the interrupt factor
*
* \param [in] mask
* Each bit of this parameter corresponds to each structure factor to be clear
*
* \return
* void
*
*******************************************************************************/
__STATIC_INLINE void Cy_Evtgen_ClearInterrupt(volatile stc_EVTGEN_t *base, uint32_t mask)
{
base->unINTR.u32Register = mask;
// Dummy read. This is to wait for reflection above write operation.
base->unINTR.u32Register;
}
/*******************************************************************************
* Function Name: Cy_Evtgen_ClearStructInterrupt
****************************************************************************//**
*
* \brief Clear interrupt factor of corresponding structure
*
* \param [in] structNumber
* Number of structure. The factor of that is to be clear
*
* \return
* void
*
*******************************************************************************/
__STATIC_INLINE void Cy_Evtgen_ClearStructInterrupt(volatile stc_EVTGEN_t *base, uint8_t structNumber)
{
base->unINTR.u32Register = ((uint32_t)1 << structNumber);
// Dummy read. This is to wait for reflection above write operation.
base->unINTR.u32Register;
}
/*******************************************************************************
* Function Name: Cy_Evtgen_SetInterruptMask
****************************************************************************//**
*
* \brief Set interrupt mask bit of a corresponding structure
*
* \param [in] structNumber
* Number of structure. The mask bit of that is to be set
*
* \return
* void
*
*******************************************************************************/
__STATIC_INLINE void Cy_Evtgen_SetInterruptMask(volatile stc_EVTGEN_t *base, uint8_t structNumber)
{
base->unINTR_MASK.u32Register |= ((uint32_t)1 << structNumber);
}
/*******************************************************************************
* Function Name: Cy_Evtgen_GetInterrupt
****************************************************************************//**
*
* \brief Get interrupt bit of corresponding structure
*
* \param [in] structNumber
* Number of structure. The interrupt factor of the structure is to be returned
*
* \return
* The interrupt bit
*
*******************************************************************************/
__STATIC_INLINE bool Cy_Evtgen_GetInterrupt(volatile stc_EVTGEN_t *base, uint8_t structNumber)
{
return ((base->unINTR.u32Register & ((uint32_t)1 << structNumber)) == 0u) ? false : true;
}
/*******************************************************************************
* Function Name: Cy_Evtgen_GetInterruptMasked
****************************************************************************//**
*
* \brief Get interrupt masked bit of corresponding structure
*
* \param [in] structNumber
* Number of structure. The masked bit of the structure is to be returned
*
* \return
* The interrupt masked bit
*
*******************************************************************************/
__STATIC_INLINE bool Cy_Evtgen_GetInterruptMasked(volatile stc_EVTGEN_t *base, uint8_t structNumber)
{
return ((base->unINTR_MASKED.u32Register & ((uint32_t)1 << structNumber)) == 0u) ? false : true;
}
/*******************************************************************************
* Function Name: Cy_Evtgen_SetInterruptDeepSleep
****************************************************************************//**
*
* \brief Set deep sleep interrupt factor of corresponding structure
*
* \param [in] structNumber
* Number of structure. The interrupt factor of that is to be set
*
* \return
* void
*
*******************************************************************************/
__STATIC_INLINE void Cy_Evtgen_SetInterruptDeepSleep(volatile stc_EVTGEN_t *base, uint8_t structNumber)
{
base->unINTR_DPSLP_SET.u32Register |= ((uint32_t)1 << structNumber);
}
/*******************************************************************************
* Function Name: Cy_Evtgen_ClearInterruptDeepSleep
****************************************************************************//**
*
* \brief Clear the deep sleep interrupt factor
*
* \param [in] mask
* Each bit of this parameter corresponds to each structure factor to be clear
*
* \return
* void
*
*******************************************************************************/
__STATIC_INLINE void Cy_Evtgen_ClearInterruptDeepSleep(volatile stc_EVTGEN_t *base, uint32_t mask)
{
base->unINTR_DPSLP.u32Register = mask;
// Dummy read. This is to wait for reflection above write operation.
base->unINTR_DPSLP.u32Register;
}
/*******************************************************************************
* Function Name: Cy_Evtgen_ClearStructInterruptDeepSleep
****************************************************************************//**
*
* \brief Clear deep sleep interrupt factor of corresponding structure
*
* \param [in] structNumber
* Number of structure. The factor of that is to be clear
*
* \return
* void
*
*******************************************************************************/
__STATIC_INLINE void Cy_Evtgen_ClearStructInterruptDeepSleep(volatile stc_EVTGEN_t *base, uint8_t structNumber)
{
base->unINTR_DPSLP.u32Register = ((uint32_t)1 << structNumber);
// Dummy read. This is to wait for reflection above write operation.
base->unINTR_DPSLP.u32Register;
}
/*******************************************************************************
* Function Name: Cy_Evtgen_SetInterruptDeepSleepMask
****************************************************************************//**
*
* \brief Set deep sleep interrupt mask bit of a corresponding structure
*
* \param [in] structNumber
* Number of structure. The deep sleep mask bit of that is to be set
*
* \return
* void
*
*******************************************************************************/
__STATIC_INLINE void Cy_Evtgen_SetInterruptDeepSleepMask(volatile stc_EVTGEN_t *base, uint8_t structNumber)
{
base->unINTR_DPSLP_MASK.u32Register |= ((uint32_t)1 << structNumber);
}
/*******************************************************************************
* Function Name: Cy_Evtgen_GetInterruptDeepSleep
****************************************************************************//**
*
* \brief Get deep sleep interrupt bit of corresponding structure
*
* \param [in] structNumber
* Number of structure. The deep sleep interrupt factor of the structure is to be returned
*
* \return
* The interrupt bit
*
*******************************************************************************/
__STATIC_INLINE bool Cy_Evtgen_GetInterruptDeepSleep(volatile stc_EVTGEN_t *base, uint8_t structNumber)
{
return ((base->unINTR_DPSLP.u32Register & ((uint32_t)1 << structNumber)) == 0) ? false : true;
}
/*******************************************************************************
* Function Name: Cy_Evtgen_GetInterruptDeepSleepMasked
****************************************************************************//**
*
* \brief Get deep sleep interrupt masked bit of corresponding structure
*
* \param [in] structNumber
* Number of structure. The deep sleep masked bit of the structure is to be returned
*
* \return
* The interrupt masked bit
*
*******************************************************************************/
__STATIC_INLINE bool Cy_Evtgen_GetInterruptDeepSleepMasked(volatile stc_EVTGEN_t *base, uint8_t structNumber)
{
return ((base->unINTR_DPSLP_MASKED.u32Register & ((uint32_t)1 << structNumber)) == 0) ? false : true;
}
/*******************************************************************************
* Function Name: Cy_Evtgen_GetComp0Status
****************************************************************************//**
*
* \brief Get comparator 0 status
*
* \return
* Comparator 0 Status
*
*******************************************************************************/
__STATIC_INLINE uint32_t Cy_Evtgen_GetComp0Status(volatile stc_EVTGEN_t *base)
{
return base->unCOMP0_STATUS.u32Register;
}
/*******************************************************************************
* Function Name: Cy_Evtgen_GetComp1Status
****************************************************************************//**
*
* \brief Get comparator 1 status
*
* \return
* Comparator 1 Status
*
*******************************************************************************/
__STATIC_INLINE uint32_t Cy_Evtgen_GetComp1Status(volatile stc_EVTGEN_t *base)
{
return base->unCOMP1_STATUS.u32Register;
}
/*******************************************************************************
* Function Name: Cy_Evtgen_GetCounterStatus
****************************************************************************//**
*
* \brief Get counter status
*
* \return
* counter status
*
* \Note
* If this status is "1", the counter completed initialization
* and is ready to be read
*
*******************************************************************************/
__STATIC_INLINE cy_en_evtgen_counter_status_t Cy_Evtgen_GetCounterStatus(volatile stc_EVTGEN_t *base)
{
return (cy_en_evtgen_counter_status_t)base->unCOUNTER_STATUS.stcField.u1VALID;
}
/*******************************************************************************
* Function Name: Cy_Evtgen_GetCounterValue
****************************************************************************//**
*
* \brief Get counter value
*
* \return
* counter value
*
*******************************************************************************/
__STATIC_INLINE uint32_t Cy_Evtgen_GetCounterValue(volatile stc_EVTGEN_t *base)
{
return base->unCOUNTER.u32Register;
}
void Cy_Evtgen_Enable(volatile stc_EVTGEN_t *base);
cy_en_evtgendrv_status_t Cy_Evtgen_Initialize(volatile stc_EVTGEN_t *base, const cy_stc_evtgen_config_t* config);
void Cy_Evtgen_Deinitialize(volatile stc_EVTGEN_t *base);
uint32_t Cy_Evtgen_GetComp0Status(volatile stc_EVTGEN_t *base);
uint32_t Cy_Evtgen_GetComp1Status(volatile stc_EVTGEN_t *base);
cy_en_evtgen_counter_status_t Cy_Evtgen_GetCounterStatus(volatile stc_EVTGEN_t *base);
uint32_t Cy_Evtgen_GetCounterValue(volatile stc_EVTGEN_t *base);
cy_en_evtgendrv_status_t Cy_Evtgen_InitializeCompStruct(volatile stc_EVTGEN_t *base,
uint8_t structNum,
const cy_stc_evtgen_struct_config_t* configStruct,
cy_stc_evtgen_struct_context_t* context);
void Cy_Evtgen_DeinitializeCompStruct(volatile stc_EVTGEN_t *base, uint8_t structNum);
void Cy_Evtgen_Interrupt(volatile stc_EVTGEN_t *base);
/** \cond INTERNAL */
/** \endcond */
/** \} group_evtgen_functions */
#if defined(__cplusplus)
}
#endif
#endif /* #if !defined(CY_EVTGEN_H) */
/** \endcond */
/** \} group_evtgen */
/* [] END OF FILE */
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,159 @@
/***************************************************************************//**
* \file cy_gpio.c
* \version 1.0
*
* \brief
* Provides an API implementation of the GPIO driver
*
********************************************************************************
* \copyright
* Copyright 2016-2017, Cypress Semiconductor Corporation. All rights reserved.
* You may use this file only in accordance with the license, terms, conditions,
* disclaimers, and limitations in the end user license agreement accompanying
* the software package with which this file was provided.
*******************************************************************************/
#include "cy_gpio.h"
#if defined(__cplusplus)
extern "C" {
#endif
/*******************************************************************************
* Function Name: Cy_GPIO_Pin_Init
****************************************************************************//**
*
* \brief Initialize all pin configuration setting for the pin.
*
* \param base
* Pointer to the pin's port register base address
*
* \param pinNum
* Position of the pin bit-field within the port register
*
* \param config
* Pointer to the pin config structure base address
*
* \return
* void
*
* \note
* This function modifies port registers in read-modify-write operations. It is
* not thread safe as the resource is shared among multiple pins on a port.
*
*******************************************************************************/
cy_en_gpio_status_t Cy_GPIO_Pin_Init(volatile stc_GPIO_PRT_t *base, uint32_t pinNum, const cy_stc_gpio_pin_config_t *config)
{
cy_en_gpio_status_t status = CY_GPIO_SUCCESS;
if((NULL != base) && (NULL != config))
{
Cy_GPIO_Write(base, pinNum, config->outVal);
Cy_GPIO_SetHSIOM(base, pinNum, config->hsiom);
Cy_GPIO_SetVtrip(base, pinNum, config->vtrip);
Cy_GPIO_SetSlewRate(base, pinNum, config->slewRate);
Cy_GPIO_SetDriveSel(base, pinNum, config->driveSel);
Cy_GPIO_SetDrivemode(base, pinNum, config->driveMode);
Cy_GPIO_SetInterruptEdge(base, pinNum, config->intEdge);
Cy_GPIO_ClearInterrupt(base, pinNum);
Cy_GPIO_SetInterruptMask(base, pinNum, config->intMask);
}
else
{
status = CY_GPIO_BAD_PARAM;
}
return(status);
}
/*******************************************************************************
* Function Name: Cy_GPIO_Multi_Pin_Init
****************************************************************************//**
*
* \brief Initialize pin configuration setting for multiple pin.
* This will return CY_GPIO_BAD_PARAM, only if configuration paramter does not
* contain any pin configuration.
*
* \param config
* Pointer to top of array of pin configuration structure.
*
* \param pinAmount
* Pin number (amount) to be set.
*
* \return
* cy_en_gpio_status_t
*
*******************************************************************************/
cy_en_gpio_status_t Cy_GPIO_Multi_Pin_Init(const cy_stc_gpio_pin_prt_config_t *config, uint32_t pinAmount)
{
cy_en_gpio_status_t status = CY_GPIO_SUCCESS;
if((NULL != config))
{
for(uint32_t i = 0ul; i < pinAmount; i++)
{
status = Cy_GPIO_Pin_Init(config[i].portReg, config[i].pinNum, &config[i].cfg);
}
}
else
{
status = CY_GPIO_BAD_PARAM;
}
return(status);
}
/*******************************************************************************
* Function Name: Cy_GPIO_Port_Init
****************************************************************************//**
*
* \brief Initialize a complete port of pins from a single init structure.
*
* \param base
* Pointer to the pin's port register base address
*
* \param config
* Pointer to the pin config structure base address
*
* \return
* void
*
*******************************************************************************/
cy_en_gpio_status_t Cy_GPIO_Port_Init(volatile stc_GPIO_PRT_t* base, const cy_stc_gpio_prt_config_t *config)
{
cy_en_gpio_status_t status = CY_GPIO_SUCCESS;
uint32_t portNum;
stc_HSIOM_PRT_t* baseHSIOM;
if((NULL != base) && (NULL != config))
{
portNum = ((uint32_t)(base) - GPIO_BASE) / GPIO_PRT_SECTION_SIZE;
baseHSIOM = (stc_HSIOM_PRT_t*)(HSIOM_BASE + (HSIOM_PRT_SECTION_SIZE * portNum));
baseHSIOM->unPORT_SEL0.u32Register = config->sel0Active;
baseHSIOM->unPORT_SEL1.u32Register = config->sel1Active;
base->unOUT.u32Register = config->out;
base->unCFG_IN.u32Register = config->cfgIn;
base->unCFG_OUT.u32Register = config->cfgOut;
base->unCFG.u32Register = config->cfg;
base->unINTR_CFG.u32Register = config->intrCfg;
base->unINTR.u32Register = 0x1fful;
base->unINTR_MASK.u32Register = config->intrMask;
}
else
{
status = CY_GPIO_BAD_PARAM;
}
return(status);
}
#if defined(__cplusplus)
}
#endif
/* [] END OF FILE */
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,103 @@
/***************************************************************************//**
* \file cy_ipc_config.h
* \version 1.10
*
* \brief
* This header file is not intended to be part of the IPC driver since it defines
* a device specific configuration for the IPC channels and pipes.
*
********************************************************************************
* \copyright
* Copyright 2016-2017, Cypress Semiconductor Corporation. All rights reserved.
* You may use this file only in accordance with the license, terms, conditions,
* disclaimers, and limitations in the end user license agreement accompanying
* the software package with which this file was provided.
*******************************************************************************/
#ifndef CY_IPC_CONFIG_H
#define CY_IPC_CONFIG_H
/* IPC Resources */
#define CY_IPC_CHANNELS CPUSS_IPC_IPC_NR /**< Max number of IPC channels in this device */
#define CY_IPC_INTERRUPTS CPUSS_IPC_IPC_IRQ_NR /**< Max number of IPC interrupt structures in this device */
/* IPC channel definitions */
#define CY_IPC_CHAN_SYSCALL_CM0 0 /**< System calls for the CM0+ processor */
#define CY_IPC_CHAN_SYSCALL_CM4_CM7_0 1 /**< System calls for the 1st non-CM0+ processor */
#define CY_IPC_CHAN_SYSCALL_CM7_1 2 /**< System calls for the 2nd non-CM0+ processor */
#define CY_IPC_CHAN_SYSCALL_CM7_2 3 /**< System calls for the 3rd non-CM0+ processor */
#define CY_IPC_CHAN_SYSCALL_CM7_3 4 /**< System calls for the 4th non-CM0+ processor */
#ifdef tviibh16m
/* Channel is determined during runtime (-> allows generic library) */
#define CY_IPC_CHAN_SYSCALL ( (CPUSS->unIDENTITY.stcField.u4MS == 0) ? CY_IPC_CHAN_SYSCALL_CM0 : \
(CPUSS->unIDENTITY.stcField.u4MS == 14) ? CY_IPC_CHAN_SYSCALL_CM4_CM7_0 : \
(CPUSS->unIDENTITY.stcField.u4MS == 13) ? CY_IPC_CHAN_SYSCALL_CM7_1 : \
(CPUSS->unIDENTITY.stcField.u4MS == 7) ? CY_IPC_CHAN_SYSCALL_CM7_2 : \
CY_IPC_CHAN_SYSCALL_CM7_3 )
#define CY_IPC_CHAN_CRYPTO 8 /**< IPC data channel for the Crypto */
#else
/* Channel is determined during runtime (-> allows generic library) */
#define CY_IPC_CHAN_SYSCALL ( (CPUSS->unIDENTITY.stcField.u4MS == 0) ? CY_IPC_CHAN_SYSCALL_CM0 : \
(CPUSS->unIDENTITY.stcField.u4MS == 14) ? CY_IPC_CHAN_SYSCALL_CM4_CM7_0 : \
CY_IPC_CHAN_SYSCALL_CM7_1 )
#define CY_IPC_CHAN_CRYPTO 4 /**< IPC data channel for the Crypto */
#endif
#define CY_IPC_CHAN_SEMA 5 /**< IPC data channel for the Semaphores (just a proposal, can be used as parameter when calling Cy_IPC_Sema_Init() */
#define CY_IPC_CHAN_PIPE_EP0 6 /**< IPC data channel for PIPE EP0 */
#define CY_IPC_CHAN_PIPE_EP1 7 /**< IPC data channel for PIPE EP1 */
/* IPC Notify interrupts definitions */
#define CY_IPC_INTR_CRYPTO_SRV 4 /**< IPC interrupt structure for the notification of the Crypto server */
#define CY_IPC_INTR_CRYPTO_CLI 5 /**< IPC interrupt structure for the release notification of the Crypto client */
/* IPC Pipe definitions */
#define CY_IPC_PIPE_MAX_ENDPOINTS 2 /**< Number of pipe endpoints (each endpoint needs its own IPC channel and IPC Intr. struct */
#define CY_IPC_PIPE_MAX_CLIENTS 8 /**< Defines max. number of client IDs (which are part of the pipe message and used to index the callback array) */
/*******************************************************************************
** CY IPC PIPE default/example configuration
*******************************************************************************/
/* The pipe endpoint configuration must be identical on all CPUs.
Below is a default/example configuration which can be used as config struct
initializer by the user or they can define their own configuration here
or somewhere else
*/
#define CY_IPC_INTR_PIPE_CPU_INT_IDX_EP0 CPUIntIdx2_IRQn /**< CPU Interrupt Index, used in the EP0 CPU */
#define CY_IPC_INTR_PIPE_EP0 6 /**< IPC Interrupt Structure Index, used as notifier for EP0 */
#define CY_IPC_INTR_PIPE_CPU_INT_IDX_EP1 CPUIntIdx2_IRQn /**< CPU Interrupt Index, used in the EP1 CPU */
#define CY_IPC_INTR_PIPE_EP1 7 /**< IPC Interrupt Structure Index, used as notifier for EP1 */
#define CY_IPC_PIPE_ENDPOINTS_DEFAULT_CONFIG \
{ \
{ \
.ipcStructNr = CY_IPC_CHAN_PIPE_EP0, \
.ipcIntrStructNr = CY_IPC_INTR_PIPE_EP0, \
.ipcCpuIntIdx = CY_IPC_INTR_PIPE_CPU_INT_IDX_EP0, \
}, \
{ \
.ipcStructNr = CY_IPC_CHAN_PIPE_EP1, \
.ipcIntrStructNr = CY_IPC_INTR_PIPE_EP1, \
.ipcCpuIntIdx = CY_IPC_INTR_PIPE_CPU_INT_IDX_EP1, \
}, \
}
/******************************************************************************/
#endif /* CY_IPC_CONFIG_H */
/* [] END OF FILE */
@@ -0,0 +1,306 @@
/***************************************************************************//**
* \file cy_ipc_drv.c
* \version 1.10
*
* \breif
* IPC Driver - This source file contains the low-level driver code for
* the IPC hardware.
*
********************************************************************************
* Copyright 2016-2017, Cypress Semiconductor Corporation. All rights reserved.
* You may use this file only in accordance with the license, terms, conditions,
* disclaimers, and limitations in the end user license agreement accompanying
* the software package with which this file was provided.
*******************************************************************************/
#include "cy_ipc_drv.h"
/*******************************************************************************
* Function Name: Cy_IPC_Drv_LockAcquire
****************************************************************************//**
*
* This function is used to acquire the IPC channel.
*
* This function is internal and should not be called directly by user software
*
* \param base
* This parameter is a handle that represents the base address of the registers
* of the IPC channel.
* The parameter is generally returned from a call to the \ref
* Cy_IPC_Drv_GetIpcBaseAddress
*
* \return Status of the operation
* \retval CY_IPC_DRV_SUCCESS: The IPC was successfully acquired
* \retval CY_IPC_DRV_ERROR: The IPC was not acquired because it was already acquired
* by another master
*
*******************************************************************************/
cy_en_ipcdrv_status_t Cy_IPC_Drv_LockAcquire (volatile stc_IPC_STRUCT_t const * base)
{
cy_en_ipcdrv_status_t retStatus;
if( 0ul != base->unACQUIRE.stcField.u1SUCCESS )
{
retStatus = CY_IPC_DRV_SUCCESS;
}
else
{
retStatus = CY_IPC_DRV_ERROR;
}
return(retStatus);
}
/*******************************************************************************
* Function Name: Cy_IPC_Drv_LockRelease
****************************************************************************//**
*
* The function is used to release an IPC channel from the locked state.
* The function also has a way to specify through a parameter which IPC
* interrupts must be notified during the release event.
*
* This function is internal and should not be called directly by user software.
*
* \param base
* This parameter is a handle that represents the base address of the registers
* of the IPC channel.
* The parameter is generally returned from a call to the \ref
* Cy_IPC_Drv_GetIpcBaseAddress.
*
* \param releaseEventIntr
* Bit encoded list of IPC interrupt lines that are triggered by a release event.
*
* \return Status of the operation
* \retval CY_IPC_DRV_SUCCESS: The function executed successfully and the IPC channel
* was released.
* \retval CY_IPC_DRV_ERROR: The IPC channel was not acquired before the
* function call.
*
*******************************************************************************/
cy_en_ipcdrv_status_t Cy_IPC_Drv_LockRelease (volatile stc_IPC_STRUCT_t* base, uint32_t releaseEventIntr)
{
cy_en_ipcdrv_status_t retStatus;
/* Check to make sure the IPC is Acquired */
if( Cy_IPC_Drv_IsLockAcquired(base) )
{
/* The IPC was acquired, release the IPC channel */
Cy_IPC_Drv_ReleaseNotify(base, releaseEventIntr);
retStatus = CY_IPC_DRV_SUCCESS;
}
else /* The IPC channel was already released (not acquired) */
{
retStatus = CY_IPC_DRV_ERROR;
}
return(retStatus);
}
/*******************************************************************************
* Function Name: Cy_IPC_Drv_SendMsgWord
****************************************************************************//**
*
* This function is used to send a 32-bit word message through an IPC channel.
* The function also has an associated notification field that will let the
* message notify one or multiple IPC interrupts. The IPC channel is locked and
* remains locked after the function returns. The receiver of the message should
* release the channel.
*
* This function is internal and should not be called directly by user software.
*
* \param base
* This parameter is a handle that represents the base address of the registers
* of the IPC channel.
* The parameter is generally returned from a call to the \ref
* Cy_IPC_Drv_GetIpcBaseAddress.
*
* \param notifyEventIntr
* Bit encoded list of IPC interrupt lines that are triggered by a notification.
*
* \param message
* The message word that is the data placed in the IPC data register.
*
* \return Status of the operation:
* \retval CY_IPC_DRV_SUCCESS: The send operation was successful.
* \retval CY_IPC_DRV_ERROR: The IPC channel is unavailable because it is already locked.
*
*******************************************************************************/
cy_en_ipcdrv_status_t Cy_IPC_Drv_SendMsgWord (volatile stc_IPC_STRUCT_t* base, uint32_t notifyEventIntr, uint32_t message)
{
cy_en_ipcdrv_status_t retStatus;
if( CY_IPC_DRV_SUCCESS == Cy_IPC_Drv_LockAcquire(base) )
{
/* If the channel was acquired, send the message. */
Cy_IPC_Drv_WriteDataValue(base, message);
Cy_IPC_Drv_AcquireNotify(base, notifyEventIntr);
retStatus = CY_IPC_DRV_SUCCESS;
}
else
{
/* Channel was already acquired, return Error */
retStatus = CY_IPC_DRV_ERROR;
}
return(retStatus);
}
/*******************************************************************************
* Function Name: Cy_IPC_Drv_SendMsgWord_2
****************************************************************************//**
*
* This function is used to send two 32-bit word message through an IPC channel.
* The function also has an associated notification field that will let the
* message notify one or multiple IPC interrupts. The IPC channel is locked and
* remains locked after the function returns. The receiver of the message should
* release the channel.
*
* This function is internal and should not be called directly by user software.
*
* \param base
* This parameter is a handle that represents the base address of the registers
* of the IPC channel.
* The parameter is generally returned from a call to the \ref
* Cy_IPC_Drv_GetIpcBaseAddress.
*
* \param notifyEventIntr
* Bit encoded list of IPC interrupt lines that are triggered by a notification.
*
* \param message
* The message word that is the data placed in the IPC data register.
* \param message2
* The message word that is the data placed in the IPC data1 register.
*
* \return Status of the operation:
* \retval CY_IPC_DRV_SUCCESS: The send operation was successful.
* \retval CY_IPC_DRV_ERROR: The IPC channel is unavailable because it is already locked.
*
*******************************************************************************/
cy_en_ipcdrv_status_t Cy_IPC_Drv_SendMsgWord_2 (volatile stc_IPC_STRUCT_t* base, uint32_t notifyEventIntr, uint32_t message, uint32_t message2)
{
cy_en_ipcdrv_status_t retStatus;
if( CY_IPC_DRV_SUCCESS == Cy_IPC_Drv_LockAcquire(base) )
{
/* If the channel was acquired, send the message. */
Cy_IPC_Drv_WriteDataValue(base, message);
Cy_IPC_Drv_WriteData1Value(base, message2);
Cy_IPC_Drv_AcquireNotify(base, notifyEventIntr);
retStatus = CY_IPC_DRV_SUCCESS;
}
else
{
/* Channel was already acquired, return Error */
retStatus = CY_IPC_DRV_ERROR;
}
return(retStatus);
}
/*******************************************************************************
* Function Name: Cy_IPC_Drv_ReadMsgWord
****************************************************************************//**
*
* This function is used to read a 32-bit word message through an IPC channel.
* This function assumes that the channel is locked (for a valid message).
* If the channel is not locked, the message is invalid. The user must call
* Cy_IPC_Drv_Release() function after reading the message to release the
* IPC channel.
*
* This function is internal and should not be called directly by user software.
*
* \param base
* This parameter is a handle that represents the base address of the registers
* of the IPC channel.
* The parameter is generally returned from a call to the \ref
* Cy_IPC_Drv_GetIpcBaseAddress.
*
* \param message
* A variable where the read data is copied.
*
* \return Status of the operation
* \retval CY_IPC_DRV_SUCCESS: The function executed successfully and the IPC
* was acquired.
* \retval CY_IPC_DRV_ERROR: The function encountered an error because the IPC
* channel was already in a released state, meaning the data
* may be invalid.
*
*******************************************************************************/
cy_en_ipcdrv_status_t Cy_IPC_Drv_ReadMsgWord (volatile stc_IPC_STRUCT_t const * base, uint32_t * message)
{
cy_en_ipcdrv_status_t retStatus;
if ( Cy_IPC_Drv_IsLockAcquired(base) )
{
/* The channel is locked; message is valid. */
*message = Cy_IPC_Drv_ReadDataValue(base);
retStatus = CY_IPC_DRV_SUCCESS;
}
else
{
/* The channel is not locked so channel is invalid. */
retStatus = CY_IPC_DRV_ERROR;
}
return(retStatus);
}
/*******************************************************************************
* Function Name: Cy_IPC_Drv_ReadMsgWord_2
****************************************************************************//**
*
* This function is used to read two 32-bit word messages through an IPC channel.
* This function assumes that the channel is locked (for a valid message).
* If the channel is not locked, the message is invalid. The user must call
* Cy_IPC_Drv_Release() function after reading the message to release the
* IPC channel.
*
* This function is internal and should not be called directly by user software.
*
* \param base
* This parameter is a handle that represents the base address of the registers
* of the IPC channel.
* The parameter is generally returned from a call to the \ref
* Cy_IPC_Drv_GetIpcBaseAddress.
*
* \param message
* A variable where the read data is copied.
*
* \param message
* A variable where the read data1 is copied.
*
* \return Status of the operation
* \retval CY_IPC_DRV_SUCCESS: The function executed successfully and the IPC
* was acquired.
* \retval CY_IPC_DRV_ERROR: The function encountered an error because the IPC
* channel was already in a released state, meaning the data
* may be invalid.
*
*******************************************************************************/
cy_en_ipcdrv_status_t Cy_IPC_Drv_ReadMsgWord_2 (volatile stc_IPC_STRUCT_t const * base, uint32_t * message, uint32_t* message2)
{
cy_en_ipcdrv_status_t retStatus;
if ( Cy_IPC_Drv_IsLockAcquired(base) )
{
/* The channel is locked; message is valid. */
*message = Cy_IPC_Drv_ReadDataValue(base);
*message2 = Cy_IPC_Drv_ReadData1Value(base);
retStatus = CY_IPC_DRV_SUCCESS;
}
else
{
/* The channel is not locked so channel is invalid. */
retStatus = CY_IPC_DRV_ERROR;
}
return(retStatus);
}
/* [] END OF FILE */
@@ -0,0 +1,744 @@
/***************************************************************************//**
* \file cy_ipc_drv.h
* \version 1.10
*
* Provides an API declaration of the IPC driver.
*
********************************************************************************
* \copyright
* Copyright 2016-2017, Cypress Semiconductor Corporation. All rights reserved.
* You may use this file only in accordance with the license, terms, conditions,
* disclaimers, and limitations in the end user license agreement accompanying
* the software package with which this file was provided.
*******************************************************************************/
#ifndef CY_IPC_DRV_H
#define CY_IPC_DRV_H
/**
* \defgroup group_ipc Inter Process Communication (IPC)
* \{
* Contains the driver API for the low-level IPC interface as well as Semaphores and
* Pipe upper-level interfaces.
*
* The IPC driver provides a safe and reliable method to transfer data between
* CPUs or processes in a single device. Hardware locking provides a reliable
* method to ensure that only one device can acquire and transfer data at one
* time so no data is lost or over written by asynchronous processes or CPUs.
*
* The Semaphores functions make use of a single IPC channel to allow multiple
* semaphores that can be used by system or user function calls.
*
* The Pipe functions provide a method to transfer data between CPUs or tasks.
* The data can be defined as an array of data or a user defined structure.
* The only limitation is that the first element of the data must be a 32-bit
* unsigned word as service field in which a client ID number is passed.
* The client ID dictates the callback function that will be called by the
* receiver of the message. After the callback function is returned by the receiver,
* it invokes a release callback function defined by the sender of the
* message.
*
* \section group_ipc_configuration Configuration Considerations
*
* The usage of the IPC channels is partially fixed (system call channels for the
* various CPUs, DAP) other could be changed by the user
*
* \section group_ipc_more_information More Information
*
* See the technical reference manual(TRM) for more information on the IPC.
*
* \defgroup group_ipc_drv IPC driver layer (IPC_DRV)
* \defgroup group_ipc_sema IPC semaphores layer (IPC_SEMA)
* \defgroup group_ipc_pipe IPC pipes layer (IPC_PIPE)
* \} */
/**
* \addtogroup group_ipc_drv
* \{
* The functions of this layer are used in the higher IPC levels
* (Semaphores and Pipes).
*
* \defgroup group_ipc_macros Macros
* Macro definitions are used in the driver
*
* \defgroup group_ipc_functions Functions
* Functions are used in the driver
*
* \defgroup group_ipc_data_structures Data Structures
* Data structures are used in the driver
*
* \defgroup group_ipc_enums Enumerated Types
* Enumerations are used in the driver
*
*/
/******************************************************************************/
/* Include files */
/******************************************************************************/
#include "syslib/cy_syslib.h"
#include "cy_device_headers.h"
#include "cy_ipc_config.h"
/**
* \addtogroup group_ipc_macros
* \{
*/
/** Driver major version */
#define CY_IPC_DRV_VERSION_MAJOR 1
/** Driver minor version */
#define CY_IPC_DRV_VERSION_MINOR 10
/** Defines a value to indicate that no notification events are needed */
#define CY_IPC_NO_NOTIFICATION (uint32_t)(0x00000000ul)
/* Error Code constants */
#define CY_IPC_ID CY_PDL_DRV_ID(0x22u) /**< Software PDL driver ID for IPC */
/** Return prefix for IPC driver function status codes */
#define CY_IPC_ID_INFO (uint32_t)( CY_IPC_ID | CY_PDL_STATUS_INFO )
/** Return prefix for IPC driver function warning return values */
#define CY_IPC_ID_WARNING (uint32_t)( CY_IPC_ID | CY_PDL_STATUS_WARNING)
/** Return prefix for IPC driver function error return values */
#define CY_IPC_ID_ERROR (uint32_t)( CY_IPC_ID | CY_PDL_STATUS_ERROR)
/** Converts the IPC interrupt channel number to interrupt vector */
#define CY_IPC_INTR_NUM_TO_VECT(x) ((int32_t)cpuss_interrupts_ipc_0_IRQn + (x))
/** \} group_ipc_macros */
/* end of definition in device.h */
/**
* \addtogroup group_ipc_enums
* \{
*/
/**
* This is a list of ENUMs used for function return status.
*/
typedef enum
{
/** Function was successfully executed */
CY_IPC_DRV_SUCCESS = (0x00u),
/** Function was not executed due to an error.
Typical conditions for the error explained
in the function description */
CY_IPC_DRV_ERROR = ( CY_IPC_ID_ERROR + 1ul),
} cy_en_ipcdrv_status_t;
/** \} group_ipc_enums */
#ifdef __cplusplus
extern "C" {
#endif
/** \cond INTERNAL */
__STATIC_INLINE void Cy_IPC_Drv_WriteDataValue (volatile stc_IPC_STRUCT_t* base, uint32_t dataValue);
__STATIC_INLINE uint32_t Cy_IPC_Drv_ReadDataValue (volatile stc_IPC_STRUCT_t const * base);
__STATIC_INLINE void Cy_IPC_Drv_ReleaseNotify (volatile stc_IPC_STRUCT_t* base, uint32_t notifyEventIntr);
__STATIC_INLINE uint32_t Cy_IPC_Drv_ExtractAcquireMask (uint32_t intMask);
__STATIC_INLINE uint32_t Cy_IPC_Drv_ExtractReleaseMask (uint32_t intMask);
/** \endcond */
/**
* \addtogroup group_ipc_functions
* \{
*/
__STATIC_INLINE volatile stc_IPC_STRUCT_t* Cy_IPC_Drv_GetIpcBaseAddress (uint32_t ipcIndex);
__STATIC_INLINE volatile stc_IPC_INTR_STRUCT_t* Cy_IPC_Drv_GetIntrBaseAddr (uint32_t ipcIntrIndex);
__STATIC_INLINE void Cy_IPC_Drv_AcquireNotify (volatile stc_IPC_STRUCT_t * base, uint32_t notifyEventIntr);
cy_en_ipcdrv_status_t Cy_IPC_Drv_LockAcquire (volatile stc_IPC_STRUCT_t const * base);
cy_en_ipcdrv_status_t Cy_IPC_Drv_LockRelease (volatile stc_IPC_STRUCT_t * base, uint32_t releaseEventIntr);
__STATIC_INLINE bool Cy_IPC_Drv_IsLockAcquired (volatile stc_IPC_STRUCT_t const * base);
__STATIC_INLINE uint32_t Cy_IPC_Drv_GetLockStatus (volatile stc_IPC_STRUCT_t const * base);
cy_en_ipcdrv_status_t Cy_IPC_Drv_SendMsgWord (volatile stc_IPC_STRUCT_t * base, uint32_t notifyEventIntr, uint32_t message);
cy_en_ipcdrv_status_t Cy_IPC_Drv_SendMsgWord_2 (volatile stc_IPC_STRUCT_t* base, uint32_t notifyEventIntr, uint32_t message, uint32_t message2);
cy_en_ipcdrv_status_t Cy_IPC_Drv_ReadMsgWord (volatile stc_IPC_STRUCT_t const * base, uint32_t * message);
cy_en_ipcdrv_status_t Cy_IPC_Drv_ReadMsgWord_2 (volatile stc_IPC_STRUCT_t const * base, uint32_t * message, uint32_t* message2);
__STATIC_INLINE void Cy_IPC_Drv_SetInterruptMask (volatile stc_IPC_INTR_STRUCT_t * base,
uint32_t ipcReleaseMask, uint32_t ipcNotifyMask);
__STATIC_INLINE uint32_t Cy_IPC_Drv_GetInterruptMask (volatile stc_IPC_INTR_STRUCT_t const * base);
__STATIC_INLINE uint32_t Cy_IPC_Drv_GetInterruptStatusMasked (volatile stc_IPC_INTR_STRUCT_t const * base);
__STATIC_INLINE uint32_t Cy_IPC_Drv_GetInterruptStatus (volatile stc_IPC_INTR_STRUCT_t const * base);
__STATIC_INLINE void Cy_IPC_Drv_SetInterrupt (volatile stc_IPC_INTR_STRUCT_t * base,
uint32_t ipcReleaseMask, uint32_t ipcNotifyMask);
__STATIC_INLINE void Cy_IPC_Drv_ClearInterrupt (volatile stc_IPC_INTR_STRUCT_t * base,
uint32_t ipcReleaseMask, uint32_t ipcNotifyMask);
/*******************************************************************************
* Function Name: Cy_IPC_Drv_GetIpcBaseAddress
****************************************************************************//**
*
* This function takes an IPC channel index as a parameter and returns the base
* address the IPC registers corresponding to the IPC channel.
*
* This function is internal and should not be called directly by user
* software.
*
* \note The user is responsible for ensuring that ipcIndex does not exceed the
* limits.
*
* \param ipcIndex
* Represents the number of IPC structure. This is converted to the base address of
* the IPC channel registers.
*
* \return
* Returns a pointer to the base of the IPC registers.
*
*******************************************************************************/
__STATIC_INLINE volatile stc_IPC_STRUCT_t* Cy_IPC_Drv_GetIpcBaseAddress (uint32_t ipcIndex)
{
CY_ASSERT((uint32_t)CPUSS_IPC_IPC_NR > ipcIndex);
return ( (volatile stc_IPC_STRUCT_t*) ( &IPC->STRUCT[ipcIndex] ) );
}
/*******************************************************************************
* Function Name: Cy_IPC_Drv_GetIntrBaseAddr
****************************************************************************//**
*
* This function takes an IPC interrupt structure index and returns the base
* address of the IPC interrupt registers corresponding to the IPC Interrupt.
*
* This function is internal and should not be called directly by user
* software.
*
* \note The user is responsible for ensuring that ipcIntrIndex does not exceed the
* limits.
*
* \param ipcIntrIndex
* Represents the number of IPC interrupt structure. This is converted to the
* base address of the IPC interrupt registers.
*
* \return
* Returns a pointer to the base of the IPC interrupt registers.
*
*******************************************************************************/
__STATIC_INLINE volatile stc_IPC_INTR_STRUCT_t* Cy_IPC_Drv_GetIntrBaseAddr (uint32_t ipcIntrIndex)
{
CY_ASSERT((uint32_t)CPUSS_IPC_IPC_IRQ_NR > ipcIntrIndex);
return ( (volatile stc_IPC_INTR_STRUCT_t*) ( &IPC->INTR_STRUCT[ipcIntrIndex] ) );
}
/*******************************************************************************
* Function Name: Cy_IPC_Drv_SetInterruptMask
****************************************************************************//**
*
* This function is used to set the interrupt mask for an IPC Interrupt.
* The mask sets release or acquire notification events for all IPC channels.
*
* This function is internal and should not be called directly by user
* software.
*
* \param base
* This is a handle to the IPC interrupt. This handle can be calculated from the
* IPC interrupt number using \ref Cy_IPC_Drv_GetIntrBaseAddr.
*
* \param ipcReleaseMask
* An encoded list of all IPC channels that can trigger the interrupt on a
* release event.
*
* \param ipcNotifyMask
* An encoded list of all IPC channels that can trigger the interrupt on a
* notify event.
*
*******************************************************************************/
__STATIC_INLINE void Cy_IPC_Drv_SetInterruptMask (volatile stc_IPC_INTR_STRUCT_t* base,
uint32_t ipcReleaseMask, uint32_t ipcNotifyMask)
{
un_IPC_INTR_STRUCT_INTR_MASK_t reg = { 0 };
reg.stcField.u16NOTIFY = ipcNotifyMask;
reg.stcField.u16RELEASE = ipcReleaseMask;
base->unINTR_MASK.u32Register = reg.u32Register;
}
/*******************************************************************************
* Function Name: Cy_IPC_Drv_GetInterruptMask
****************************************************************************//**
*
* This function is used to read the interrupt mask.
*
* This function is internal and should not be called directly by user
* software.
*
* \param base
* This is a handle to the IPC interrupt. This handle can be calculated from
* the IPC interrupt number using \ref Cy_IPC_Drv_GetIntrBaseAddr.
*
* \return
* The return value is encoded as follows
* <table>
* <tr><th>Interrupt sources <th>Value
* <tr><td>Ipc_PORTX_RELEASE <td>Xth bit set
* <tr><td>Ipc_PORTX_NOTIFY <td>X+16th bit set
* </table>
*
*******************************************************************************/
__STATIC_INLINE uint32_t Cy_IPC_Drv_GetInterruptMask(volatile stc_IPC_INTR_STRUCT_t const * base)
{
return (base->unINTR_MASK.u32Register);
}
/*******************************************************************************
* Function Name: Cy_IPC_Drv_GetInterruptStatusMasked
****************************************************************************//**
*
* This function is used to read the active unmasked interrupt. This function
* can be used in the interrupt service routine to find which source triggered
* the interrupt.
*
* This function is internal and should not be called directly by user
* software.
*
* \param base
* This is a handle to the IPC interrupt. This handle can be calculated from the
* IPC interrupt number using \ref Cy_IPC_Drv_GetIntrBaseAddr.
*
* \return
* The return value is encoded as follows
* <table>
* <tr><th>Interrupt sources <th>Value
* <tr><td>Ipc_PORTX_RELEASE <td>Xth bit set
* <tr><td>Ipc_PORTX_NOTIFY <td>X+16th bit set
* </table>
*
*******************************************************************************/
__STATIC_INLINE uint32_t Cy_IPC_Drv_GetInterruptStatusMasked (volatile stc_IPC_INTR_STRUCT_t const * base)
{
return (base->unINTR_MASKED.u32Register);
}
/*******************************************************************************
* Function Name: Cy_IPC_Drv_GetInterruptStatus
****************************************************************************//**
*
* This function is used to read the pending interrupts. Note that this read is
* an unmasked read of the interrupt status. Interrupt sources read as active by
* this function would generate interrupts only if they were not masked.
* This function is internal and should not be called directly by user
* software.
*
* \param base
* This is a handle to the IPC interrupt. This handle can be calculated from the
* IPC interrupt number using \ref Cy_IPC_Drv_GetIntrBaseAddr.
*
* \return
* The return value is encoded as follows
* <table>
* <tr><th>Interrupt sources <th>Value
* <tr><td>Ipc_PORTX_RELEASE <td>Xth bit set
* <tr><td>Ipc_PORTX_NOTIFY <td>X+16th bit set
* </table>
*
*******************************************************************************/
__STATIC_INLINE uint32_t Cy_IPC_Drv_GetInterruptStatus(volatile stc_IPC_INTR_STRUCT_t const * base)
{
return (base->unINTR.u32Register);
}
/*******************************************************************************
* Function Name: Cy_IPC_Drv_SetInterrupt
****************************************************************************//**
*
* This function is used to set the interrupt source. This function can be used
* to activate interrupts through software.
* \note That interrupt sources set using this interrupt would generate interrupts
* only if they are not masked.
*
* This function is internal and should not be called directly by user
* software.
*
* \param base
* This is a handle to the IPC interrupt. This handle can be calculated from the
* IPC interrupt number using \ref Cy_IPC_Drv_GetIntrBaseAddr.
*
* \param ipcReleaseMask
* An encoded list of all IPC channels that can trigger the interrupt on a
* release event.
*
* \param ipcNotifyMask
* An encoded list of all IPC channels that can trigger the interrupt on a
* notify event.
*
*******************************************************************************/
__STATIC_INLINE void Cy_IPC_Drv_SetInterrupt(volatile stc_IPC_INTR_STRUCT_t* base, uint32_t ipcReleaseMask, uint32_t ipcNotifyMask)
{
un_IPC_INTR_STRUCT_INTR_SET_t reg = { 0 };
reg.stcField.u16NOTIFY = ipcNotifyMask;
reg.stcField.u16RELEASE = ipcReleaseMask;
base->unINTR_SET.u32Register = reg.u32Register;
}
/*******************************************************************************
* Function Name: Cy_IPC_Drv_ClearInterrupt
****************************************************************************//**
*
* This function is used to clear the interrupt source. Use this function to clear
* a pending interrupt source in the interrupt status.
*
* This function is internal and should not be called directly by user
* software.
*
* \param base
* This is a handle to the IPC interrupt. This handle can be calculated from the
* IPC interrupt number using \ref Cy_IPC_Drv_GetIntrBaseAddr.
*
* \param ipcReleaseMask
* An encoded list of all IPC channels that can trigger the interrupt on a
* release event.
*
* \param ipcNotifyMask
* An encoded list of all IPC channels that can trigger the interrupt on a
* notify event.
*
*******************************************************************************/
__STATIC_INLINE void Cy_IPC_Drv_ClearInterrupt(volatile stc_IPC_INTR_STRUCT_t* base, uint32_t ipcReleaseMask, uint32_t ipcNotifyMask)
{
un_IPC_INTR_STRUCT_INTR_t reg = { 0 };
reg.stcField.u16NOTIFY = ipcNotifyMask;
reg.stcField.u16RELEASE = ipcReleaseMask;
base->unINTR.u32Register = reg.u32Register;
(void)base->unINTR.u32Register; /* Read the register to flush the cache */
}
/** \} group_ipc_functions */
/** \} group_ipc */
/*******************************************************************************
* Function Name: Cy_IPC_Drv_AcquireNotify
****************************************************************************//**
*
* The function generates a notify event by IPC interrupt structures.
*
* This function is internal and should not be called directly by user
* software.
*
* \param base
* This parameter is a handle that represents the base address of the registers
* of the IPC channel.
* The parameter is generally returned from a call to the \ref
* Cy_IPC_Drv_GetIpcBaseAddress.
*
* \param notifyEventIntr
* Bit encoded list of IPC interrupt structures that are triggered
* by a notification. Bit number correspond to number of the IPC interrupt
* structure.
*
*******************************************************************************/
__STATIC_INLINE void Cy_IPC_Drv_AcquireNotify (volatile stc_IPC_STRUCT_t* base, uint32_t notifyEventIntr)
{
un_IPC_STRUCT_NOTIFY_t reg = { 0 };
reg.stcField.u16INTR_NOTIFY = notifyEventIntr;
base->unNOTIFY.u32Register = reg.u32Register;
}
/*******************************************************************************
* Function Name: Cy_IPC_Drv_ReleaseNotify
****************************************************************************//**
*
* The function generates a notify event to an IPC interrupt structure.
*
* This function is internal and should not be called directly by user
* software.
*
* \param base
* This parameter is a handle that represents the base address of the registers
* of the IPC channel.
* The parameter is generally returned from a call to the \ref
* Cy_IPC_Drv_GetIpcBaseAddress.
*
* \param notifyEventIntr
* Bit encoded list of IPC interrupt lines that are triggered by a notification.
*
*******************************************************************************/
__STATIC_INLINE void Cy_IPC_Drv_ReleaseNotify (volatile stc_IPC_STRUCT_t* base, uint32_t notifyEventIntr)
{
un_IPC_STRUCT_RELEASE_t reg = { 0 };
reg.stcField.u16INTR_RELEASE = notifyEventIntr;
base->unRELEASE.u32Register = reg.u32Register;
}
/*******************************************************************************
* Function Name: Cy_IPC_Drv_WriteDataValue
****************************************************************************//**
*
* The function writes a value to the DATA register of the IPC channel.
*
* This function is internal and should not be called directly by user
* software.
*
* \param base
* This parameter is a handle that represents the base address of the registers
* of the IPC channel.
* The parameter is generally returned from a call to the \ref
* Cy_IPC_Drv_GetIpcBaseAddress.
*
* \param dataValue
* Value to be written.
*
*******************************************************************************/
__STATIC_INLINE void Cy_IPC_Drv_WriteDataValue (volatile stc_IPC_STRUCT_t* base, uint32_t dataValue)
{
base->unDATA0.u32Register = dataValue;
}
/*******************************************************************************
* Function Name: Cy_IPC_Drv_WriteData1Value
****************************************************************************//**
*
* The function writes a value to the DATA1 register of the IPC channel.
*
* This function is internal and should not be called directly by user
* software.
*
* \param base
* This parameter is a handle that represents the base address of the registers
* of the IPC channel.
* The parameter is generally returned from a call to the \ref
* Cy_IPC_Drv_GetIpcBaseAddress.
*
* \param dataValue
* Value to be written.
*
*******************************************************************************/
__STATIC_INLINE void Cy_IPC_Drv_WriteData1Value (volatile stc_IPC_STRUCT_t* base, uint32_t dataValue)
{
base->unDATA1.u32Register = dataValue;
}
/*******************************************************************************
* Function Name: Cy_IPC_Drv_ReadDataValue
****************************************************************************//**
*
* The function reads a value from the DATA register of the IPC channel.
*
* This function is internal and should not be called directly by user
* software.
*
* \param base
* This parameter is a handle that represents the base address of the registers
* of the IPC channel.
* The parameter is generally returned from a call to the \ref
* Cy_IPC_Drv_GetIpcBaseAddress.
*
* \return
* Value from DATA register.
*
*******************************************************************************/
__STATIC_INLINE uint32_t Cy_IPC_Drv_ReadDataValue (volatile stc_IPC_STRUCT_t const * base)
{
return (base->unDATA0.u32Register);
}
/*******************************************************************************
* Function Name: Cy_IPC_Drv_ReadData1Value
****************************************************************************//**
*
* The function reads a value from the DATA1 register of the IPC channel.
*
* This function is internal and should not be called directly by user
* software.
*
* \param base
* This parameter is a handle that represents the base address of the registers
* of the IPC channel.
* The parameter is generally returned from a call to the \ref
* Cy_IPC_Drv_GetIpcBaseAddress.
*
* \return
* Value from DATA register.
*
*******************************************************************************/
__STATIC_INLINE uint32_t Cy_IPC_Drv_ReadData1Value (volatile stc_IPC_STRUCT_t const * base)
{
return (base->unDATA1.u32Register);
}
/*******************************************************************************
* Function Name: Cy_IPC_Drv_IsLockAcquired
****************************************************************************//**
*
* The function is used to test the status of an IPC channel. The function
* tells the reader if the IPC channel was in the locked or released state.
*
* This function is internal and should not be called directly by user
* software.
*
* \param base
* This parameter is a handle that represents the base address of the registers
* of the IPC channel.
* The parameter is generally returned from a call to the \ref
* Cy_IPC_Drv_GetIpcBaseAddress.
*
* \return
* Status for the function:
* true: The IPC channel is in the Locked state.
* false: The IPC channel is in the Released state.
*
*******************************************************************************/
__STATIC_INLINE bool Cy_IPC_Drv_IsLockAcquired (volatile stc_IPC_STRUCT_t const * base)
{
return ( 0u != base->unLOCK_STATUS.stcField.u1ACQUIRED );
}
/*******************************************************************************
* Function Name: Cy_IPC_Drv_GetLockStatus
****************************************************************************//**
*
* The function is used to get the status of an IPC channel.
*
* This function is internal and should not be called directly by user
* software.
*
* \param base
* This parameter is a handle that represents the base address of the registers
* of the IPC channel.
* The parameter is generally returned from a call to the \ref
* Cy_IPC_Drv_GetIpcBaseAddress.
*
* \return
* Value from LOCK_STATUS register.
*
*******************************************************************************/
__STATIC_INLINE uint32_t Cy_IPC_Drv_GetLockStatus (volatile stc_IPC_STRUCT_t const * base)
{
return (base->unLOCK_STATUS.u32Register);
}
/*******************************************************************************
* Function Name: Cy_IPC_Drv_ExtractAcquireMask
****************************************************************************//**
*
* The function extracts an Acquire mask part from full interrupt mask value.
*
* This function is internal and should not be called directly by user
* software.
*
* \param intMask
* Interrupt mask value to be processed.
*
* \return
* Acquire mask value.
*
*******************************************************************************/
__STATIC_INLINE uint32_t Cy_IPC_Drv_ExtractAcquireMask (uint32_t intMask)
{
return _FLD2VAL(IPC_INTR_STRUCT_INTR_MASK_NOTIFY, intMask);
}
/*******************************************************************************
* Function Name: Cy_IPC_Drv_ExtractReleaseMask
****************************************************************************//**
*
* The function extracts a Release mask part from full interrupt mask value.
*
* This function is internal and should not be called directly by user
* software.
*
* \param intMask
* Interrupt mask value to be processed.
*
* \return
* Release mask value.
*
*******************************************************************************/
__STATIC_INLINE uint32_t Cy_IPC_Drv_ExtractReleaseMask (uint32_t intMask)
{
return _FLD2VAL(IPC_INTR_STRUCT_INTR_MASK_RELEASE, intMask);
}
/*******************************************************************************
* Function Name: Cy_IPC_Drv_SendMsgPtr
****************************************************************************//**
*
* This function is used to send a message pointer through an IPC channel.
* The message structure may hold a generic pointer that may contain the address
* of any user data type or structure. This parameter could be a pointer to a 32-bit
* integer, an array, or even a data structure defined in the user code. This
* function acts as a transfer engine for sending the pointer. Any memory
* management of the pointer allocation and deallocation is up to the application
* code.
* The function also has an associated notification field that will let the
* message notify one or multiple interrupts.
*
* This function is internal and should not be called directly by user software.
*
* \param base
* This parameter is a handle that represents the base address of the registers
* of the IPC channel.
* The parameter is generally returned from a call to the \ref
* Cy_IPC_Drv_GetIpcBaseAddress.
*
* \param notifyEventIntr
* Bit encoded list of IPC interrupt lines that are triggered during the release
* action.
*
* \param msgPtr
* The message pointer that is being sent over the IPC channel.
*
* \return Status of the operation:
* \retval CY_IPC_DRV_SUCCESS: The send operation was successful.
* \retval CY_IPC_DRV_ERROR: The IPC channel is unavailable because
* it is already locked.
*
*******************************************************************************/
__STATIC_INLINE cy_en_ipcdrv_status_t Cy_IPC_Drv_SendMsgPtr(volatile stc_IPC_STRUCT_t* base, uint32_t notifyEventIntr, void const * msgPtr)
{
return Cy_IPC_Drv_SendMsgWord(base, notifyEventIntr, (uint32_t)msgPtr);
}
/*******************************************************************************
* Function Name: Cy_IPC_Drv_ReadMsgPtr
****************************************************************************//**
*
* This function is used to read a 32-bit pointer message through an IPC channel.
*
* This function is internal and should not be called directly by user software.
*
* \param base
* This parameter is a handle that represents the base address of the registers
* of the IPC channel.
* The parameter is generally returned from a call to the \ref
* Cy_IPC_Drv_GetIpcBaseAddress.
*
* \param msgPtr
* Pointer variable to hold the data pointer that is being read from the IPC
* channel.
*
*
* \return Status of the operation
* \retval CY_IPC_DRV_SUCCESS: The function executed successfully and the IPC
* was acquired.
* \retval CY_IPC_DRV_ERROR: The function encountered an error because the IPC
* channel was already in a released state meaning the data
* in it is invalid.
*
*******************************************************************************/
__STATIC_INLINE cy_en_ipcdrv_status_t Cy_IPC_Drv_ReadMsgPtr (volatile stc_IPC_STRUCT_t const * base, void ** msgPtr)
{
return Cy_IPC_Drv_ReadMsgWord(base, (uint32_t *)msgPtr);
}
#ifdef __cplusplus
}
#endif
#endif /* !defined(CY_IPC_DRV_H) */
/* [] END OF FILE */
@@ -0,0 +1,488 @@
/***************************************************************************//**
* \file cy_ipc_pipe.c
* \version 1.10
*
* Description:
* IPC Pipe Driver - This source file includes code for the Pipe layer on top
* of the IPC driver.
*
********************************************************************************
* Copyright 2016-2017, Cypress Semiconductor Corporation. All rights reserved.
* You may use this file only in accordance with the license, terms, conditions,
* disclaimers, and limitations in the end user license agreement accompanying
* the software package with which this file was provided.
*******************************************************************************/
#include "cy_ipc_pipe.h"
/**
* This is the definition of the configuration and status of a pipe endpoint.
* There is one endpoint structure for each CPU in a pipe. It contains all
* the information to process a message send to other CPUs in the pipe.
*/
typedef struct
{
uint32_t ipcChan; /**< IPC channel number used for this endpoint to receive messages */
uint32_t intrChan; /**< IPC interrupt channel number used for this endpoint to receive interrupts */
uint32_t pipeIntMask; /**< Release/Notify interrupt mask that includes all endpoints on pipe */
cy_en_intr_t pipeIntrSrc; /**< System interrupt number that includes all endpoints on pipe */
volatile stc_IPC_STRUCT_t * ipcPtr; /**< Pointer to receive IPC channel ( If ipcPtr == NULL, cannot receive ) */
volatile stc_IPC_INTR_STRUCT_t * ipcIntrPtr; /**< Pointer to IPC interrupt, needed to clear the interrupt */
uint32_t busy; /**< Endpoint busy flag. If set no messages can be sent from this endpoint */
cy_ipc_pipe_relcallback_ptr_t releaseCallbackPtr; /**< Pointer to release callback function */
cy_ipc_pipe_relcallback_ptr_t defaultReleaseCallbackPtr; /**< Pointer to default release callback function */
} cy_stc_ipc_pipe_internal_cfg_status_t;
/** Create an array of endpoint structures */
static cy_stc_ipc_pipe_internal_cfg_status_t cy_ipc_pipe_epCfgStatus[CY_IPC_PIPE_MAX_ENDPOINTS];
/** Remember this CPU's endpoint */
static uint8_t cy_ipc_pipe_epForThisCpu;
/** Create an array of callback functions */
static cy_ipc_pipe_callback_ptr_t cy_ipc_pipe_callbackArray[CY_IPC_PIPE_MAX_CLIENTS];
/** Remember "driver initialized" state, for checking in the various APIs */
static bool cy_ipc_pipe_drvInitialized = false;
static void InitEndpoint(uint32_t epAddr, cy_stc_ipc_pipe_ep_config_t const * epConfig, uint32_t intMask, cy_en_intr_t epSysInt);
static void ExecCallback(cy_stc_ipc_pipe_internal_cfg_status_t * endpoint);
/*******************************************************************************
* Function Name: Cy_IPC_Pipe_Init
****************************************************************************//**
*
* Initializes the system pipes.
* \note The function should be called on all CPUs.
*
* After this function is called, the callback array needs to be populated
* with the callback functions for this endpoint using the
* Cy_IPC_Pipe_RegisterCallback() function.
*
* \param config
* This is the pointer to the pipe configuration structure
*
*******************************************************************************/
void Cy_IPC_Pipe_Init(cy_stc_ipc_pipe_config_t const * config)
{
cy_stc_sysint_irq_t irqCfg;
uint32_t ipcIrqMaskSuperset = 0;
// Store index of this CPU's endpoint
cy_ipc_pipe_epForThisCpu = config->epIndexForThisCpu;
// Prepare IRQ configuration
irqCfg.sysIntSrc = (cy_en_intr_t) CY_IPC_INTR_NUM_TO_VECT(config->epConfigData[cy_ipc_pipe_epForThisCpu].ipcIntrStructNr);
irqCfg.intIdx = config->epConfigData[cy_ipc_pipe_epForThisCpu].ipcCpuIntIdx;
irqCfg.isEnabled = true;
// Calculate IRQ Mask (superset of all endpoints' IPC structure number)
for(uint8_t curEndpoint = 0; curEndpoint < CY_IPC_PIPE_MAX_ENDPOINTS; curEndpoint++)
{
ipcIrqMaskSuperset |= (0x1ul << config->epConfigData[curEndpoint].ipcStructNr);
}
// Initialize the internal config/status for all endpoints
for(uint8_t curEndpoint = 0; curEndpoint < CY_IPC_PIPE_MAX_ENDPOINTS; curEndpoint++)
{
cy_en_intr_t sys_int = (curEndpoint == cy_ipc_pipe_epForThisCpu) ? irqCfg.sysIntSrc : disconnected_IRQn;
InitEndpoint(curEndpoint, &config->epConfigData[curEndpoint], ipcIrqMaskSuperset, sys_int);
}
// Configure interrupt
(void)Cy_SysInt_InitIRQ(&irqCfg);
Cy_SysInt_SetSystemIrqVector(irqCfg.sysIntSrc, Cy_IPC_Pipe_Isr);
cy_ipc_pipe_drvInitialized = true;
}
/*******************************************************************************
* Function Name: InitEndpoint
****************************************************************************//**
*
* This function initializes an endpoint of a pipe for the current CPU. It needs
* to be called for all endpoints in a pipe so that their respective config/status
* structs are populated with the necessary data.
*
* \param epAddr
* This parameter is the address (or index in the array of endpoint structures)
* that designates the endpoint you want to initialize.
*
* \param epConfig
* Configuration of this endpoint
*
* \param intMask
* Superset bitmask of all IPC channels used by all endpoints
*
* \param epSysInt
* This is the system interrupt number of the IPC interrupt structure used by this endpoint.
*
*******************************************************************************/
static void InitEndpoint(uint32_t epAddr, cy_stc_ipc_pipe_ep_config_t const * epConfig, uint32_t intMask, cy_en_intr_t epSysInt)
{
cy_stc_ipc_pipe_internal_cfg_status_t * endpoint;
endpoint = &cy_ipc_pipe_epCfgStatus[epAddr];
endpoint->ipcChan = epConfig->ipcStructNr;
endpoint->intrChan = epConfig->ipcIntrStructNr;
endpoint->pipeIntMask = intMask;
/* Assign IPC channel to this endpoint */
endpoint->ipcPtr = Cy_IPC_Drv_GetIpcBaseAddress(endpoint->ipcChan);
/* Assign interrupt structure to endpoint and Initialize the interrupt mask for this endpoint */
endpoint->ipcIntrPtr = Cy_IPC_Drv_GetIntrBaseAddr(endpoint->intrChan);
/* Only allow notify and release interrupts from endpoints in this pipe. */
Cy_IPC_Drv_SetInterruptMask(endpoint->ipcIntrPtr, endpoint->pipeIntMask, endpoint->pipeIntMask);
/* Save the Client count and the callback array pointer */
endpoint->busy = CY_IPC_PIPE_ENDPOINT_NOTBUSY;
endpoint->pipeIntrSrc = epSysInt;
}
/*******************************************************************************
* Function Name: Cy_IPC_Pipe_SendMessage
****************************************************************************//**
*
* This function is used to send a message from one endpoint to another. It
* generates an interrupt on the endpoint that receives the message and a
* release interrupt to the sender to acknowledge the message has been processed.
*
* \param toEpIndex
* This parameter is the address (or index in the array of endpoint structures)
* of the endpoint to which you are sending the message.
*
* \param msgPtr
* Pointer to the message structure to be sent.
*
* \param callBackPtr
* Pointer to the Release callback function.
*
* \return
* CY_IPC_PIPE_SUCCESS: Message was sent to the other end of the pipe
* CY_IPC_PIPE_ERROR_BAD_HANDLE: The handle provided for the pipe was not valid
* CY_IPC_PIPE_ERROR_SEND_BUSY: The pipe is already busy sending a message
* CY_IPC_PIPE_ERROR_UNINIT: Driver init function has not yet been called
*
*******************************************************************************/
cy_en_ipc_pipe_status_t Cy_IPC_Pipe_SendMessage(uint32_t toEpIndex, void * msgPtr, cy_ipc_pipe_relcallback_ptr_t callBackPtr)
{
cy_en_ipc_pipe_status_t returnStatus;
uint32_t releaseMask;
uint32_t notifyMask;
cy_stc_ipc_pipe_internal_cfg_status_t * fromEp;
cy_stc_ipc_pipe_internal_cfg_status_t * toEp;
if(cy_ipc_pipe_drvInitialized == false)
{
return CY_IPC_PIPE_ERROR_UNINIT;
}
toEp = &cy_ipc_pipe_epCfgStatus[toEpIndex];
fromEp = &cy_ipc_pipe_epCfgStatus[cy_ipc_pipe_epForThisCpu];
/* Create the release mask for the "fromEp" channel's interrupt channel */
releaseMask = (uint32_t)(1ul << (fromEp->intrChan));
/* Shift into position */
releaseMask = _VAL2FLD(CY_IPC_PIPE_MSG_RELEASE, releaseMask);
/* Create the notify mask for the "toEp" channel's interrupt channel */
notifyMask = (uint32_t)(1ul << (toEp->intrChan));
/* Check if IPC channel valid */
if( toEp->ipcPtr != (void *)0u)
{
if(fromEp->busy == CY_IPC_PIPE_ENDPOINT_NOTBUSY)
{
/* Attempt to acquire the channel */
if( CY_IPC_DRV_SUCCESS == Cy_IPC_Drv_LockAcquire(toEp->ipcPtr) )
{
__DSB();
/* Mask out the release mask area */
*((uint32_t *) msgPtr) &= ~(CY_IPC_PIPE_MSG_RELEASE_Msk);
*((uint32_t *) msgPtr) |= releaseMask;
/* If the channel was acquired, write the message. */
Cy_IPC_Drv_WriteDataValue(toEp->ipcPtr, (uint32_t) msgPtr);
/* Set the busy flag. The ISR clears this after the release */
fromEp->busy = CY_IPC_PIPE_ENDPOINT_BUSY;
/* Setup release callback function */
fromEp->releaseCallbackPtr = callBackPtr;
__DSB();
/* Cause notify event/interrupt */
Cy_IPC_Drv_AcquireNotify(toEp->ipcPtr, notifyMask);
returnStatus = CY_IPC_PIPE_SUCCESS;
}
else
{
/* Channel was already acquired, return Error */
returnStatus = CY_IPC_PIPE_ERROR_SEND_BUSY;
}
}
else
{
/* Channel may not be acquired, but the release interrupt has not executed yet */
returnStatus = CY_IPC_PIPE_ERROR_SEND_BUSY;
}
}
else
{
/* Null pipe handle. */
returnStatus = CY_IPC_PIPE_ERROR_BAD_HANDLE;
}
return (returnStatus);
}
/*******************************************************************************
* Function Name: Cy_IPC_Pipe_RegisterCallback
****************************************************************************//**
*
* This function registers a callback that is called when a message is received on a pipe.
* The client_ID is the same as the index of the callback function array. The callback
* may be a real function pointer or NULL if no callback is required.
*
* \param callBackPtr
* Pointer to the callback function called when the endpoint has received a message.
*
* \param clientId
* The index in the callback array (Client ID) where the function pointer is saved.
*
* \return
* CY_IPC_PIPE_SUCCESS: Callback registered successfully
* CY_IPC_PIPE_ERROR_BAD_CLIENT: Client ID out of range, callback not registered.
*******************************************************************************/
cy_en_ipc_pipe_status_t Cy_IPC_Pipe_RegisterCallback(cy_ipc_pipe_callback_ptr_t callBackPtr, uint32_t clientId)
{
cy_en_ipc_pipe_status_t returnStatus;
/* Check if clientId is between 0 and less than client count */
if (clientId < CY_IPC_PIPE_MAX_CLIENTS)
{
/* Copy callback function into callback function pointer array */
cy_ipc_pipe_callbackArray[clientId] = callBackPtr;
returnStatus = CY_IPC_PIPE_SUCCESS;
}
else
{
returnStatus = CY_IPC_PIPE_ERROR_BAD_CLIENT;
}
return (returnStatus);
}
/*******************************************************************************
* Function Name: Cy_IPC_Pipe_RegisterCallbackRel
****************************************************************************//**
*
* This function registers a default callback if a release interrupt
* is generated but the current release callback function is null.
*
*
* \param callBackPtr
* Pointer to the callback executed when the endpoint has received a message.
*
* \return
* CY_IPC_PIPE_SUCCESS: Callback registered successfully
* CY_IPC_PIPE_ERROR_UNINIT: Driver init function has not yet been called
*******************************************************************************/
cy_en_ipc_pipe_status_t Cy_IPC_Pipe_RegisterCallbackRel(cy_ipc_pipe_relcallback_ptr_t callBackPtr)
{
cy_stc_ipc_pipe_internal_cfg_status_t * endpoint;
if(cy_ipc_pipe_drvInitialized == false)
{
return CY_IPC_PIPE_ERROR_UNINIT;
}
endpoint = &cy_ipc_pipe_epCfgStatus[cy_ipc_pipe_epForThisCpu];
/* Copy callback function into callback function pointer array */
endpoint->defaultReleaseCallbackPtr = callBackPtr;
return CY_IPC_PIPE_SUCCESS;
}
/*******************************************************************************
* Function Name: Cy_IPC_Pipe_Isr
****************************************************************************//**
*
* This is the interrupt service routine for the pipe.
*
*******************************************************************************/
void Cy_IPC_Pipe_Isr(void)
{
if(cy_ipc_pipe_drvInitialized != false)
{
ExecCallback(&cy_ipc_pipe_epCfgStatus[cy_ipc_pipe_epForThisCpu]);
}
}
/*******************************************************************************
* Function Name: ExecCallback
****************************************************************************//**
*
* This function is called by the ISR for a given pipe endpoint to dispatch
* the appropriate callback function based on the client ID for that endpoint.
*
* \param endpoint
* Pointer to endpoint structure.
*
* \return
* None
*******************************************************************************/
static void ExecCallback(cy_stc_ipc_pipe_internal_cfg_status_t * endpoint)
{
uint32_t *msgPtr = (void *)0uL;
uint32_t clientID;
uint32_t shadowIntr;
uint32_t releaseMask = (uint32_t)0;
cy_ipc_pipe_callback_ptr_t callbackPtr;
/* Check to make sure the interrupt was a notify interrupt */
shadowIntr = Cy_IPC_Drv_GetInterruptStatusMasked(endpoint->ipcIntrPtr);
if( 0ul != (shadowIntr & IPC_INTR_STRUCT_INTR_MASK_NOTIFY_Msk))
{
/* Clear the notify interrupt. */
endpoint->ipcIntrPtr->unINTR.u32Register = (shadowIntr & IPC_INTR_STRUCT_INTR_MASK_NOTIFY_Msk);
if( Cy_IPC_Drv_IsLockAcquired (endpoint->ipcPtr) )
{
__DSB();
/* Extract Client ID */
if( CY_IPC_DRV_SUCCESS == Cy_IPC_Drv_ReadMsgPtr (endpoint->ipcPtr, (void **)&msgPtr))
{
/* Get release mask */
releaseMask = _FLD2VAL(CY_IPC_PIPE_MSG_RELEASE, *msgPtr);
clientID = _FLD2VAL(CY_IPC_PIPE_MSG_CLIENT, *msgPtr);
/* Make sure client ID is within valid range */
if (clientID < CY_IPC_PIPE_MAX_CLIENTS)
{
callbackPtr = cy_ipc_pipe_callbackArray[clientID]; /* Get the callback function */
if (callbackPtr != NULL)
{
callbackPtr(msgPtr); /* Call the function pointer for "clientID" */
}
}
}
__DSB();
/* Must always release the IPC channel */
(void)Cy_IPC_Drv_LockRelease (endpoint->ipcPtr, releaseMask);
}
}
/* Check to make sure the interrupt was a release interrupt */
if( 0ul != (shadowIntr & IPC_INTR_STRUCT_INTR_MASK_RELEASE_Msk)) /* Check for a Release interrupt */
{
/* Clear the release interrupt */
endpoint->ipcIntrPtr->unINTR.u32Register = (shadowIntr & IPC_INTR_STRUCT_INTR_MASK_RELEASE_Msk);
if (endpoint->releaseCallbackPtr != NULL)
{
endpoint->releaseCallbackPtr();
/* Clear the pointer after it was called */
endpoint->releaseCallbackPtr = NULL;
}
else
{
if (endpoint->defaultReleaseCallbackPtr != NULL)
{
endpoint->defaultReleaseCallbackPtr();
}
}
/* Clear the busy flag when release is detected */
endpoint->busy = CY_IPC_PIPE_ENDPOINT_NOTBUSY;
}
(void)Cy_IPC_Drv_GetInterruptStatus(endpoint->ipcIntrPtr);
}
/*******************************************************************************
* Function Name: Cy_IPC_Pipe_EndpointPause
****************************************************************************//**
*
* This function sets the receiver endpoint to paused state.
*
*
* \return
* CY_IPC_PIPE_SUCCESS: Endpoint paused successfully
* CY_IPC_PIPE_ERROR_UNINIT: Driver init function has not yet been called
*
*******************************************************************************/
cy_en_ipc_pipe_status_t Cy_IPC_Pipe_EndpointPause(void)
{
cy_stc_ipc_pipe_internal_cfg_status_t * endpoint;
if(cy_ipc_pipe_drvInitialized == false)
{
return CY_IPC_PIPE_ERROR_UNINIT;
}
endpoint = &cy_ipc_pipe_epCfgStatus[cy_ipc_pipe_epForThisCpu];
/* Disable the interrupts */
Cy_SysInt_DisableIRQ(endpoint->pipeIntrSrc);
return (CY_IPC_PIPE_SUCCESS);
}
/*******************************************************************************
* Function Name: Cy_IPC_Pipe_EndpointResume
****************************************************************************//**
*
* This function sets the receiver endpoint to active state.
*
*
* \return
* CY_IPC_PIPE_SUCCESS: Endpoint resumed successfully
* CY_IPC_PIPE_ERROR_UNINIT: Driver init function has not yet been called
*
*******************************************************************************/
cy_en_ipc_pipe_status_t Cy_IPC_Pipe_EndpointResume(void)
{
cy_stc_ipc_pipe_internal_cfg_status_t * endpoint;
if(cy_ipc_pipe_drvInitialized == false)
{
return CY_IPC_PIPE_ERROR_UNINIT;
}
endpoint = &cy_ipc_pipe_epCfgStatus[cy_ipc_pipe_epForThisCpu];
/* Enable the interrupts */
Cy_SysInt_EnableIRQ(endpoint->pipeIntrSrc);
return (CY_IPC_PIPE_SUCCESS);
}
/* [] END OF FILE */
@@ -0,0 +1,206 @@
/***************************************************************************//**
* \file cy_ipc_pipe.h
* \version 1.10
*
* Description:
* IPC Pipe Driver - This header file contains all the function prototypes,
* structure definitions, pipe constants, and pipe endpoint address definitions.
*
********************************************************************************
* Copyright 2016-2017, Cypress Semiconductor Corporation. All rights reserved.
* You may use this file only in accordance with the license, terms, conditions,
* disclaimers, and limitations in the end user license agreement accompanying
* the software package with which this file was provided.
*******************************************************************************/
#ifndef CY_IPC_PIPE_H
#define CY_IPC_PIPE_H
/******************************************************************************/
/* Include files */
/******************************************************************************/
#include "ipc/cy_ipc_drv.h"
#include "syslib/cy_syslib.h"
#include "sysint/cy_sysint.h"
/**
* \addtogroup group_ipc_pipe IPC pipes layer (IPC_PIPE)
* \{
* The Pipe functions provide a method to transfer one or more words of data
* between CPUs or tasks. The data can be defined as a single 32-bit unsigned
* word, an array of data, or a user-defined structure. The only limitation is
* that the first word in the array or structure must be a 32-bit unsigned word
* in which a client ID number is passed. The client ID dictates the callback
* function that will be called by the receiver of the message. After the
* callback function returns by the receiver, it will invoke a release callback
* function defined by the sender of the message.
*
* A User Pipe is provided for the user to transfer data between CPUs and
* tasks.
*
* \defgroup group_ipc_pipe_macros Macros
* Macro definitions are used in the driver
*
* \defgroup group_ipc_pipe_functions Functions
* Functions are used in the driver
*
* \defgroup group_ipc_pipe_data_structures Data Structures
* Data structures are used in the driver
*
* \defgroup group_ipc_pipe_enums Enumerated Types
* Enumerations are used in the driver
*
*/
/*
* This section defines the system level constants required to define
* callback arrays for the Cypress pipe and the user pipe. These defines
* are used for both the max callback count and maximum clients.
*/
/** Typedef for pipe callback function pointer */
typedef void (* cy_ipc_pipe_callback_ptr_t)(uint32_t * msgPtr);
/** Typedef for a pipe release callback function pointer */
typedef void (* cy_ipc_pipe_relcallback_ptr_t)(void);
/** Typedef for array of callback function pointers */
typedef void (** cy_ipc_pipe_callback_array_ptr_t)(uint32_t * msgPtr);
/**
* \addtogroup group_ipc_pipe_macros
* \{
*/
#define CY_IPC_PIPE_MSG_CLIENT_Msk (0x000000FFul) /**< Client mask for first word of Pipe message */
#define CY_IPC_PIPE_MSG_CLIENT_Pos (0ul) /**< Client shift for first word of Pipe message */
#define CY_IPC_PIPE_MSG_USR_Msk (0x0000FF00ul) /**< User data mask for first word of Pipe message */
#define CY_IPC_PIPE_MSG_USR_Pos (8ul) /**< User data shift for first word of Pipe message */
#define CY_IPC_PIPE_MSG_RELEASE_Msk (0xFFFF0000ul) /**< Mask for message release mask */
#define CY_IPC_PIPE_MSG_RELEASE_Pos (16UL) /**< Shift require to line up mask to LSb */
/** Use to set the busy flag when waiting for a release interrupt */
#define CY_IPC_PIPE_ENDPOINT_BUSY (1UL)
/** Denotes that a release interrupt is not pending */
#define CY_IPC_PIPE_ENDPOINT_NOTBUSY (0UL)
/** \} group_ipc_pipe_macros */
/**
* \addtogroup group_ipc_pipe_data_structures
* \{
*/
/** The Pipe endpoint configuration structure. */
typedef struct
{
uint8_t ipcStructNr; /**< IPC Channel used by this endpoint */
uint8_t ipcIntrStructNr; /**< IPC Interrupt Structure used by this endpoint */
IRQn_Type ipcCpuIntIdx; /**< CPU interrupt index used by this endpoint */
} cy_stc_ipc_pipe_ep_config_t;
/** The Pipe configuration structure. */
typedef struct
{
uint8_t epIndexForThisCpu; /**< The current CPU's endpoint index in the #epConfigData array */
cy_stc_ipc_pipe_ep_config_t epConfigData[CY_IPC_PIPE_MAX_ENDPOINTS]; /**< Configuration of all endpoints of this pipe (system-wide identical) */
} cy_stc_ipc_pipe_config_t;
/** \} goup_ipc_pipe_data_structures */
/**
* \addtogroup group_ipc_pipe_macros
* \{
*/
/* Status and error types */
#define CY_IPC_PIPE_RTN (0x0200ul) /**< Software PDL driver ID for IPC pipe functions */
#define CY_IPC_PIPE_ID_INFO (uint32_t)( CY_IPC_ID_INFO | CY_IPC_PIPE_RTN) /**< Return prefix for IPC pipe function status codes */
#define CY_IPC_PIPE_ID_WARNING (uint32_t)( CY_IPC_ID_WARNING | CY_IPC_PIPE_RTN) /**< Return prefix for IPC pipe function warning return values */
#define CY_IPC_PIPE_ID_ERROR (uint32_t)( CY_IPC_ID_ERROR | CY_IPC_PIPE_RTN) /**< Return prefix for IPC pipe function error return values */
/** \} group_ipc_pipe_macros */
/**
* \addtogroup group_ipc_pipe_enums
* \{
*/
/** Return constants for IPC pipe functions. */
typedef enum
{
CY_IPC_PIPE_SUCCESS =(uint32_t)(0x00u), /**< Pipe API return for no error */
CY_IPC_PIPE_ERROR_NO_IPC =(uint32_t)(CY_IPC_PIPE_ID_ERROR | 1ul), /**< Pipe API return for no valid IPC channel */
CY_IPC_PIPE_ERROR_NO_INTR =(uint32_t)(CY_IPC_PIPE_ID_ERROR | 2ul), /**< Pipe API return for no valid interrupt */
CY_IPC_PIPE_ERROR_BAD_PRIORITY =(uint32_t)(CY_IPC_PIPE_ID_ERROR | 3ul), /**< Pipe API return for bad priority parameter */
CY_IPC_PIPE_ERROR_BAD_HANDLE =(uint32_t)(CY_IPC_PIPE_ID_ERROR | 4ul), /**< Pipe API return for bad pipe handle */
CY_IPC_PIPE_ERROR_BAD_ID =(uint32_t)(CY_IPC_PIPE_ID_ERROR | 5ul), /**< Pipe API return for bad pipe ID */
CY_IPC_PIPE_ERROR_DIR_ERROR =(uint32_t)(CY_IPC_PIPE_ID_ERROR | 6ul), /**< Pipe API return for invalid direction (Not used at this time) */
CY_IPC_PIPE_ERROR_SEND_BUSY =(uint32_t)(CY_IPC_PIPE_ID_ERROR | 7ul), /**< Pipe API return for pipe is currently busy */
CY_IPC_PIPE_ERROR_NO_MESSAGE =(uint32_t)(CY_IPC_PIPE_ID_ERROR | 8ul), /**< Pipe API return for no message indicated */
CY_IPC_PIPE_ERROR_BAD_CPU =(uint32_t)(CY_IPC_PIPE_ID_ERROR | 9ul), /**< Pipe API return for invalid CPU value */
CY_IPC_PIPE_ERROR_BAD_CLIENT =(uint32_t)(CY_IPC_PIPE_ID_ERROR | 10ul), /**< Pipe API return for client out of range */
CY_IPC_PIPE_ERROR_UNINIT =(uint32_t)(CY_IPC_PIPE_ID_ERROR | 11ul), /**< Pipe API return if driver has not been initialized yet*/
} cy_en_ipc_pipe_status_t;
/** \} group_ipc_pipe_enums */
/**
* \addtogroup group_ipc_pipe_data_structures
* \{
*/
/** \cond
*
* Client identifier for a message.
* For a given pipe, traffic across the pipe can be multiplexed with multiple
* senders on one end and multiple receivers on the other end.
*
* The first 32-bit word of the message is used to identify the client that owns
* the message.
*
* The upper 16 bits are the client ID.
*
* The lower 16 bits are for use by the client in any way desired.
*
* The lower 16 bits are preserved (not modified) and not interpreted in any way.
* \endcond
*/
/** \} group_ipc_pipe_data_structures */
/******************************************************************************/
/* Global function prototypes (definition in C source) */
/******************************************************************************/
/**
* \addtogroup group_ipc_pipe_functions
* \{
*/
#ifdef __cplusplus
extern "C" {
#endif
void Cy_IPC_Pipe_Init(cy_stc_ipc_pipe_config_t const * config);
cy_en_ipc_pipe_status_t Cy_IPC_Pipe_SendMessage(uint32_t toEpIndex, void * msgPtr, cy_ipc_pipe_relcallback_ptr_t callBackPtr);
cy_en_ipc_pipe_status_t Cy_IPC_Pipe_RegisterCallback(cy_ipc_pipe_callback_ptr_t callBackPtr, uint32_t clientId);
cy_en_ipc_pipe_status_t Cy_IPC_Pipe_RegisterCallbackRel(cy_ipc_pipe_relcallback_ptr_t callBackPtr);
cy_en_ipc_pipe_status_t Cy_IPC_Pipe_EndpointPause(void);
cy_en_ipc_pipe_status_t Cy_IPC_Pipe_EndpointResume(void);
void Cy_IPC_Pipe_Isr(void);
#ifdef __cplusplus
}
#endif
/** \} group_ipc_pipe_functions */
#endif /* CY_IPC_PIPE_H */
/* [] END OF FILE */
@@ -0,0 +1,451 @@
/***************************************************************************//**
* \file cy_ipc_sema.c
* \version 1.10
*
* Description:
* IPC Semaphore Driver - This source file contains the source code for the
* semaphore level APIs for the IPC interface.
*
********************************************************************************
* Copyright 2016-2017, Cypress Semiconductor Corporation. All rights reserved.
* You may use this file only in accordance with the license, terms, conditions,
* disclaimers, and limitations in the end user license agreement accompanying
* the software package with which this file was provided.
*******************************************************************************/
#include "ipc/cy_ipc_drv.h"
#include "ipc/cy_ipc_sema.h"
#include "syslib/cy_syslib.h"
#include <string.h> /* The memset() definition */
/* Defines a mask to Check if semaphore count is a multiple of 32 */
#define CY_IPC_SEMA_PER_WORD_MASK (CY_IPC_SEMA_PER_WORD - 1ul)
/* Pointer to IPC structure used for semaphores */
static volatile stc_IPC_STRUCT_t* cy_semaIpcStruct = NULL;
/*
* Internal IPC semaphore control data structure.
*/
typedef struct {
uint32_t maxSema; /* Maximum semaphores in system */
uint32_t *arrayPtr; /* Pointer to semaphores array */
} cy_stc_ipc_sema_t;
/*******************************************************************************
* Function Name: Cy_IPC_Sema_Init
****************************************************************************//**
*
* This function initializes the semaphores subsystem. The user must create an
* array of unsigned 32-bit words to hold the semaphore bits. The number
* of semaphores will be the size of the array * 32. The total semaphores count
* will always be a multiple of 32.
*
* \note In a multi-CPU system this init function should be called with all
* initialized parameters on one CPU only to provide a pointer to SRAM that can
* be shared between all the CPUs in the system that will use semaphores.
* On other CPUs user must specify the IPC semaphores channel and pass 0 / NULL
* to count and memPtr parameters correspondingly.
*
* \param ipcChannel
* The IPC channel number used for semaphores
*
* \param count
* The maximum number of semaphores to be supported (multiple of 32).
*
* \param memPtr
* This points to the array of (count/32) words that contain the semaphore data.
*
* \return
* \retval CY_IPC_SEMA_SUCCESS: Successfully initialized
* \retval CY_IPC_SEMA_BAD_PARAM: Memory pointer is NULL and count is not zero,
* or count not multiple of 32
* \retval CY_IPC_SEMA_ERROR_LOCKED: Could not acquire semaphores IPC channel
*
*******************************************************************************/
cy_en_ipcsema_status_t Cy_IPC_Sema_Init(uint32_t ipcChannel,
uint32_t count, uint32_t memPtr[])
{
/* Structure containing semaphores control data */
static cy_stc_ipc_sema_t cy_semaData;
cy_en_ipcsema_status_t retStatus = CY_IPC_SEMA_BAD_PARAM;
if (ipcChannel >= CY_IPC_CHANNELS)
{
retStatus = CY_IPC_SEMA_BAD_PARAM;
}
else
{
if( (NULL == memPtr) && (0u == count))
{
cy_semaIpcStruct = Cy_IPC_Drv_GetIpcBaseAddress(ipcChannel);
retStatus = CY_IPC_SEMA_SUCCESS;
}
/* Check for non Null pointers and count value */
else if ((NULL != memPtr) && (0u != count))
{
/* Check if semaphore count is a multiple of 32 */
if( 0ul == (count & CY_IPC_SEMA_PER_WORD_MASK))
{
cy_semaIpcStruct = Cy_IPC_Drv_GetIpcBaseAddress(ipcChannel);
cy_semaData.maxSema = count;
cy_semaData.arrayPtr = memPtr;
/* Initialize all semaphores to released */
(void)memset(cy_semaData.arrayPtr, 0, (count /8u));
__DSB();
/* Make sure semaphores start out released. */
/* Ignore the return value since it is OK if it was already released. */
(void) Cy_IPC_Drv_LockRelease (cy_semaIpcStruct, CY_IPC_NO_NOTIFICATION);
/* Set the IPC Data with the pointer to the array. */
if( CY_IPC_DRV_SUCCESS == Cy_IPC_Drv_SendMsgPtr (cy_semaIpcStruct, CY_IPC_NO_NOTIFICATION, &cy_semaData))
{
if(CY_IPC_DRV_SUCCESS == Cy_IPC_Drv_LockRelease (cy_semaIpcStruct, CY_IPC_NO_NOTIFICATION))
{
retStatus = CY_IPC_SEMA_SUCCESS;
}
else
{
/* IPC channel not released, still semaphored */
retStatus = CY_IPC_SEMA_ERROR_LOCKED;
}
}
else
{
/* Could not acquire semaphore channel */
retStatus = CY_IPC_SEMA_ERROR_LOCKED;
}
}
else
{
retStatus = CY_IPC_SEMA_BAD_PARAM;
}
}
else
{
retStatus = CY_IPC_SEMA_BAD_PARAM;
}
}
return(retStatus);
}
/*******************************************************************************
* Function Name: Cy_IPC_Sema_Set
****************************************************************************//**
*
* This function tries to acquire a semaphore. If the
* semaphore is not available, this function returns immediately with
* CY_IPC_SEMA_LOCKED.
*
* It first acquires the IPC channel that is used for all the semaphores, sets
* the semaphore if it is cleared, then releases the IPC channel used for the semaphore.
*
* \param semaNumber
* The semaphore number to acquire.
*
* \param preemptable
* When this parameter is enabled the function can be preempted by another
* task or other forms of context switching in an RTOS environment.
*
* \return
* \retval CY_IPC_SEMA_SUCCESS: The semaphore was set successfully
* \retval CY_IPC_SEMA_LOCKED: The semaphore channel is busy or locked
* by another process
* \retval CY_IPC_SEMA_NOT_ACQUIRED: Semaphore was already set
* \retval CY_IPC_SEMA_OUT_OF_RANGE: The semaphore number is not valid
* \retval CY_IPC_SEMA_ERROR_UNINIT: Driver has not been initialized yet
*
*
*******************************************************************************/
cy_en_ipcsema_status_t Cy_IPC_Sema_Set(uint32_t semaNumber, bool preemptable)
{
uint32_t semaIndex;
uint32_t semaMask;
uint32_t interruptState = 0ul;
cy_stc_ipc_sema_t *semaStruct;
cy_en_ipcsema_status_t retStatus = CY_IPC_SEMA_LOCKED;
if(cy_semaIpcStruct == NULL)
{
retStatus = CY_IPC_SEMA_ERROR_UNINIT;
}
else
{
/* Get pointer to structure */
semaStruct = (cy_stc_ipc_sema_t *)Cy_IPC_Drv_ReadDataValue(cy_semaIpcStruct);
if (semaNumber < semaStruct->maxSema)
{
semaIndex = semaNumber / CY_IPC_SEMA_PER_WORD;
semaMask = (uint32_t)(1ul << (semaNumber - (semaIndex * CY_IPC_SEMA_PER_WORD) ));
if (!preemptable)
{
interruptState = Cy_SysLib_EnterCriticalSection();
}
/* Check to make sure the IPC channel is released
If so, check if specific channel can be locked. */
if(CY_IPC_DRV_SUCCESS == Cy_IPC_Drv_LockAcquire (cy_semaIpcStruct))
{
__DSB();
if((semaStruct->arrayPtr[semaIndex] & semaMask) == 0ul)
{
semaStruct->arrayPtr[semaIndex] |= semaMask;
retStatus = CY_IPC_SEMA_SUCCESS;
}
else
{
retStatus = CY_IPC_SEMA_NOT_ACQUIRED;
}
__DSB();
/* Release, but do not trigger a release event */
(void) Cy_IPC_Drv_LockRelease (cy_semaIpcStruct, CY_IPC_NO_NOTIFICATION);
}
if (!preemptable)
{
Cy_SysLib_ExitCriticalSection(interruptState);
}
}
else
{
retStatus = CY_IPC_SEMA_OUT_OF_RANGE;
}
}
return(retStatus);
}
/*******************************************************************************
* Function Name: Cy_IPC_Sema_Clear
****************************************************************************//**
*
* This functions tries to releases a semaphore.
*
* It first acquires the IPC channel that is used for all the semaphores, clears
* the semaphore if it is set, then releases the IPC channel used for the semaphores.
*
* \param semaNumber
* The index of the semaphore to release.
*
* \param preemptable
* When this parameter is enabled the function can be preempted by another
* task or other forms of context switching in an RTOS environment.
*
* \return
* \retval CY_IPC_SEMA_SUCCESS: The semaphore was cleared successfully
* \retval CY_IPC_SEMA_NOT_ACQUIRED: The semaphore was already cleared
* \retval CY_IPC_SEMA_LOCKED: The semaphore channel was semaphored or busy
* \retval CY_IPC_SEMA_OUT_OF_RANGE: The semaphore number is not valid
* \retval CY_IPC_SEMA_ERROR_UNINIT: Driver has not been initialized yet
*
*
*******************************************************************************/
cy_en_ipcsema_status_t Cy_IPC_Sema_Clear(uint32_t semaNumber, bool preemptable)
{
uint32_t semaIndex;
uint32_t semaMask;
uint32_t interruptState = 0ul;
cy_stc_ipc_sema_t *semaStruct;
cy_en_ipcsema_status_t retStatus = CY_IPC_SEMA_LOCKED;
if(cy_semaIpcStruct == NULL)
{
retStatus = CY_IPC_SEMA_ERROR_UNINIT;
}
else
{
/* Get pointer to structure */
semaStruct = (cy_stc_ipc_sema_t *)Cy_IPC_Drv_ReadDataValue(cy_semaIpcStruct);
if (semaNumber < semaStruct->maxSema)
{
semaIndex = semaNumber / CY_IPC_SEMA_PER_WORD;
semaMask = (uint32_t)(1ul << (semaNumber - (semaIndex * CY_IPC_SEMA_PER_WORD) ));
if (!preemptable)
{
interruptState = Cy_SysLib_EnterCriticalSection();
}
/* Check to make sure the IPC channel is released
If so, check if specific channel can be locked. */
if(CY_IPC_DRV_SUCCESS == Cy_IPC_Drv_LockAcquire (cy_semaIpcStruct))
{
__DSB();
if((semaStruct->arrayPtr[semaIndex] & semaMask) != 0ul)
{
semaStruct->arrayPtr[semaIndex] &= ~semaMask;
retStatus = CY_IPC_SEMA_SUCCESS;
}
else
{
retStatus = CY_IPC_SEMA_NOT_ACQUIRED;
}
__DSB();
/* Release, but do not trigger a release event */
(void) Cy_IPC_Drv_LockRelease (cy_semaIpcStruct, CY_IPC_NO_NOTIFICATION);
}
if (!preemptable)
{
Cy_SysLib_ExitCriticalSection(interruptState);
}
}
else
{
retStatus = CY_IPC_SEMA_OUT_OF_RANGE;
}
}
return(retStatus);
}
/*******************************************************************************
* Function Name: Cy_IPC_Sema_Status
****************************************************************************//**
*
* This function returns the status of the semaphore.
*
* \param semaNumber
* The index of the semaphore to return status.
*
* \return
* \retval CY_IPC_SEMA_STATUS_LOCKED: The semaphore is in the set state.
* \retval CY_IPC_SEMA_STATUS_UNLOCKED: The semaphore is in the cleared state.
* \retval CY_IPC_SEMA_OUT_OF_RANGE: The semaphore number is not valid
* \retval CY_IPC_SEMA_ERROR_UNINIT: Driver has not been initialized yet
*
*
*******************************************************************************/
cy_en_ipcsema_status_t Cy_IPC_Sema_Status(uint32_t semaNumber)
{
cy_en_ipcsema_status_t retStatus;
uint32_t semaIndex;
uint32_t semaMask;
cy_stc_ipc_sema_t *semaStruct;
if(cy_semaIpcStruct == NULL)
{
retStatus = CY_IPC_SEMA_ERROR_UNINIT;
}
else
{
/* Get pointer to structure */
semaStruct = (cy_stc_ipc_sema_t *)Cy_IPC_Drv_ReadDataValue(cy_semaIpcStruct);
if (semaNumber < semaStruct->maxSema)
{
/* Get the index into the semaphore array and calculate the mask */
semaIndex = semaNumber / CY_IPC_SEMA_PER_WORD;
semaMask = (uint32_t)(1ul << (semaNumber - (semaIndex * CY_IPC_SEMA_PER_WORD) ));
if((semaStruct->arrayPtr[semaIndex] & semaMask) != 0ul)
{
retStatus = CY_IPC_SEMA_STATUS_LOCKED;
}
else
{
retStatus = CY_IPC_SEMA_STATUS_UNLOCKED;
}
}
else
{
retStatus = CY_IPC_SEMA_OUT_OF_RANGE;
}
}
return(retStatus);
}
/*******************************************************************************
* Function Name: Cy_IPC_Sema_GetMaxSems
****************************************************************************//**
*
* This function returns the number of semaphores in the semaphores subsystem.
*
* \param maxSema
* Pointer to where the max semaphore number will be stored
*
* \return
* \retval CY_IPC_SEMA_SUCCESS: #maxSema will contain valid number
* \retval CY_IPC_SEMA_ERROR_UNINIT: Driver has not been initialized yet
*
*******************************************************************************/
cy_en_ipcsema_status_t Cy_IPC_Sema_GetMaxSems (uint32_t *maxSema)
{
cy_stc_ipc_sema_t *semaStruct;
cy_en_ipcsema_status_t retStatus = CY_IPC_SEMA_SUCCESS;
if(cy_semaIpcStruct == NULL)
{
*maxSema = 0;
retStatus = CY_IPC_SEMA_ERROR_UNINIT;
}
else
{
/* Get pointer to structure */
semaStruct = (cy_stc_ipc_sema_t *)Cy_IPC_Drv_ReadDataValue(cy_semaIpcStruct);
*maxSema = semaStruct->maxSema;
}
return retStatus;
}
/*******************************************************************************
* Function Name: Cy_IPC_Sema_IsReady
****************************************************************************//**
*
* This function checks whether the IPC Sema "master" (the core for which
* Cy_IPC_Sema_Init is called with 'count' != 0 and 'memPtr' != NULL) has completed
* its Cy_IPC_Sema_Init call. The decision is made by checking whether the IPC data
* register of the semaphore IPC struct has changed its value from its default 0.
*
*
* \return
* \retval true: IPC sema "master" is ready
* \retval false: IPC sema "master" has not yet finished initialization or
* driver on this core has not yet been initialized
*
*******************************************************************************/
bool Cy_IPC_Sema_IsReady (void)
{
cy_stc_ipc_sema_t *semaStruct;
// Check first if Cy_IPC_Sema_Init has been called on this core at all...
if(cy_semaIpcStruct != NULL)
{
/* Get pointer to structure */
semaStruct = (cy_stc_ipc_sema_t *)Cy_IPC_Drv_ReadDataValue(cy_semaIpcStruct);
if(semaStruct != NULL)
{
return true;
}
}
return false;
}
/* [] END OF FILE */
@@ -0,0 +1,118 @@
/***************************************************************************//**
* \file cy_ipc_sema.h
* \version 1.10
*
* \brief
* Header file for IPC SEM functions
*
********************************************************************************
* \copyright
* Copyright 2016-2017, Cypress Semiconductor Corporation. All rights reserved.
* You may use this file only in accordance with the license, terms, conditions,
* disclaimers, and limitations in the end user license agreement accompanying
* the software package with which this file was provided.
*******************************************************************************/
#ifndef CY_IPC_SEMA_H
#define CY_IPC_SEMA_H
/******************************************************************************/
/* Include files */
/******************************************************************************/
#include "cy_ipc_drv.h"
#include <stdbool.h>
/**
* \addtogroup group_ipc_sema
* \{
* The semaphores layer functions made use of a single IPC channel to allow
* multiple semaphores that can be used by system or user function calls.
*
* \defgroup group_ipc_sema_macros Macros
* Macro definitions are used in the driver
*
* \defgroup group_ipc_sema_functions Functions
* Functions are used in the driver
*
* \defgroup group_ipc_sema_enums Enumerated Types
* Enumerations are used in the driver
*
*/
/**
* \addtogroup group_ipc_sema_macros
* \{
*/
/** Software PDL driver ID for IPC semaphore functions */
#define CY_IPC_SEMA_RTN (0x0100ul)
/** Return prefix for IPC semaphore function status codes */
#define CY_IPC_SEMA_ID_INFO (uint32_t)( CY_IPC_ID_INFO | CY_IPC_SEMA_RTN)
/** Return prefix for IPC semaphore function warning return values */
#define CY_IPC_SEMA_ID_WARNING (uint32_t)( CY_IPC_ID_WARNING | CY_IPC_SEMA_RTN)
/** Return prefix for IPC semaphore function error return values */
#define CY_IPC_SEMA_ID_ERROR (uint32_t)( CY_IPC_ID_ERROR | CY_IPC_SEMA_RTN)
#define CY_IPC_SEMA_PER_WORD (uint32_t)32u /**< 32 semaphores per word */
/** \} group_ipc_sema_macros */
/**
* \addtogroup group_ipc_sema_enums
* \{
*/
/** Return constants for IPC semaphores functions. */
typedef enum
{
/** No error has occurred */
CY_IPC_SEMA_SUCCESS = (uint32_t)(0ul),
/** Semaphores IPC channel has already been locked */
CY_IPC_SEMA_ERROR_LOCKED = (uint32_t)(CY_IPC_SEMA_ID_ERROR | 1ul),
/** Semaphores IPC channel is unlocked */
CY_IPC_SEMA_ERROR_UNLOCKED = (uint32_t)(CY_IPC_SEMA_ID_ERROR | 2ul),
/** Semaphore API bad parameter */
CY_IPC_SEMA_BAD_PARAM = (uint32_t)(CY_IPC_SEMA_ID_ERROR | 3ul),
/** Semaphore API return when semaphore number is out of the range */
CY_IPC_SEMA_OUT_OF_RANGE = (uint32_t)(CY_IPC_SEMA_ID_ERROR | 4ul),
/** Semaphore API return when driver is not yet initialized */
CY_IPC_SEMA_ERROR_UNINIT = (uint32_t)(CY_IPC_SEMA_ID_ERROR | 5ul),
/** Semaphore API return when IPC channel was not acquired */
CY_IPC_SEMA_NOT_ACQUIRED = (uint32_t)(CY_IPC_SEMA_ID_INFO | 2ul),
/** Semaphore API return status when semaphore channel is busy or locked by another process */
CY_IPC_SEMA_LOCKED = (uint32_t)(CY_IPC_SEMA_ID_INFO | 3ul),
/** Semaphore status return that the semaphore is set */
CY_IPC_SEMA_STATUS_LOCKED = (uint32_t)(CY_IPC_SEMA_ID_INFO | 1ul),
/** Semaphore status return that the semaphore is cleared */
CY_IPC_SEMA_STATUS_UNLOCKED = (uint32_t)(CY_IPC_SEMA_ID_INFO | 0ul)
} cy_en_ipcsema_status_t;
/** \} group_ipc_sema_enums */
/**
* \addtogroup group_ipc_sema_functions
* \{
*/
#ifdef __cplusplus
extern "C" {
#endif
cy_en_ipcsema_status_t Cy_IPC_Sema_Init (uint32_t ipcChannel, uint32_t count, uint32_t memPtr[]);
cy_en_ipcsema_status_t Cy_IPC_Sema_Set (uint32_t semaNumber, bool preemptable);
cy_en_ipcsema_status_t Cy_IPC_Sema_Clear (uint32_t semaNumber, bool preemptable);
cy_en_ipcsema_status_t Cy_IPC_Sema_Status (uint32_t semaNumber);
cy_en_ipcsema_status_t Cy_IPC_Sema_GetMaxSems (uint32_t *maxSema);
bool Cy_IPC_Sema_IsReady (void);
#ifdef __cplusplus
}
#endif
/** \} group_ipc_sema_functions */
#endif /* CY_IPC_SEMA_H */
/* [] END OF FILE */
@@ -0,0 +1,716 @@
/***************************************************************************//**
* \file cy_lin.c
* \version 1.0
*
* \brief
* Provides an API declaration of the LIN driver
*
********************************************************************************
* \copyright
* Copyright 2016-2017, Cypress Semiconductor Corporation. All rights reserved.
* You may use this file only in accordance with the license, terms, conditions,
* disclaimers, and limitations in the end user license agreement accompanying
* the software package with which this file was provided.
*******************************************************************************/
/*****************************************************************************/
/* Include files */
/*****************************************************************************/
#include "cy_lin.h"
/*****************************************************************************/
/* Local pre-processor symbols/macros ('#define') */
/*****************************************************************************/
/*****************************************************************************/
/* Global variable definitions (declared in header file with 'extern') */
/*****************************************************************************/
/*****************************************************************************/
/* Local type definitions ('typedef') */
/*****************************************************************************/
/*****************************************************************************/
/* Local variable definitions ('static') */
/*****************************************************************************/
/*****************************************************************************/
/* Local function prototypes ('static') */
/*****************************************************************************/
/*****************************************************************************/
/* Function implementation - global ('extern') and local ('static') */
/*****************************************************************************/
/**
*****************************************************************************
** \brief DeInitialisation of a LIN module.
** This Function deinitialises the selected LIN channel.
**
** \param [in] pstcLin Pointer to LIN instance register area
**
** \retval Refer \ref cy_en_lin_status_t
**
*****************************************************************************/
cy_en_lin_status_t Cy_Lin_DeInit( volatile stc_LIN_CH_t* pstcLin )
{
cy_en_lin_status_t status = CY_LIN_SUCCESS;
un_LIN_CH_CTL0_t ctl0 = { 0u };
/* Check if pointers are valid */
if ( NULL == pstcLin )
{
return CY_LIN_BAD_PARAM;
}
/* Disable the LIN Channel */
pstcLin->unCTL0.stcField.u1ENABLED = 0u;
/* Clear the data registers */
pstcLin->unDATA0.u32Register = 0uL;
pstcLin->unDATA1.u32Register = 0uL;
/* Clear the PID filed */
pstcLin->unPID_CHECKSUM.stcField.u8CHECKSUM = 0u;
ctl0.stcField.u1ENABLED = 0u;
/* Assign the default value for Stop bit length */
ctl0.stcField.u2STOP_BITS = LinOneStopBit;
/* Assign the default value for LIN Transceiver Auto Enable */
ctl0.stcField.u1AUTO_EN = 1u;
/* Default Break Delimiter Length: 1 */
ctl0.stcField.u2BREAK_DELIMITER_LENGTH = 1u;
/* Default Break field length: 12 */
ctl0.stcField.u5BREAK_WAKEUP_LENGTH = 12u;
/* Filter setting */
ctl0.stcField.u1FILTER_EN= 1u;
pstcLin->unCTL0.u32Register = ctl0.u32Register;
return status;
}
/**
*****************************************************************************
** \brief Initialisation of a LIN module.
** This Function initialises the LIN according the Options setup in the
** passed Config Struct. Several Checkings are done before that and an error
** is returned if invalid Modes are requested.
**
** \pre The Application must configure corresponding LIN pins (SIN, SOT)
** according to requirements and settings of LIN instance.
** And must set baudrate using SysClk. LIN I/F has internal fixed
** oversampling value (16). Therefore LIN clock / 16 is actual
** baudrate.
**
** \param [in] pstcLin Pointer to LIN instance register area
** \param [in] pstcConfig LIN module configuration. See #stc_lin_config_t.
**
** \retval Refer \ref cy_en_lin_status_t
**
*****************************************************************************/
cy_en_lin_status_t Cy_Lin_Init( volatile stc_LIN_CH_t* pstcLin, const stc_lin_config_t *pstcConfig)
{
cy_en_lin_status_t status = CY_LIN_SUCCESS;
/* Check if pointers are valid */
if ( ( NULL == pstcLin ) ||
( NULL == pstcConfig ) )
{
status = CY_LIN_BAD_PARAM;
}
else if (pstcConfig->bMasterMode &&
((CY_LIN_MASTER_BREAK_FILED_LENGTH_MIN > pstcConfig->u8BreakFieldLength) ||
(CY_LIN_BREAK_WAKEUP_LENGTH_BITS_MAX < pstcConfig->u8BreakFieldLength)))
{
status = CY_LIN_BAD_PARAM;
}
else if (CY_LIN_BREAK_WAKEUP_LENGTH_BITS_MAX < pstcConfig->u8BreakFieldLength)
{
status = CY_LIN_BAD_PARAM;
}
else
{
un_LIN_CH_CTL0_t ctl0 = { 0u };
/* Stop bit length */
ctl0.stcField.u2STOP_BITS = pstcConfig->enStopBit;
/* LIN Transceiver Auto Enable by Hardware */
ctl0.stcField.u1AUTO_EN = pstcConfig->bLinTransceiverAutoEnable;
/* Break field length */
ctl0.stcField.u5BREAK_WAKEUP_LENGTH = pstcConfig->u8BreakFieldLength - 1u;
/* Break Delimiter Length: Bit8-9 */
/* This field effect only master node header transmission. */
ctl0.stcField.u2BREAK_DELIMITER_LENGTH = pstcConfig->enBreakDelimiterLength;
/* Mode of Operation: Bit 24: 0 -> LIN Mode, 1 -> UART Mode */
ctl0.stcField.u1MODE = 0u;
/* Enable the LIN Channel */
ctl0.stcField.u1ENABLED = 1u;
/* Filter setting */
ctl0.stcField.u1FILTER_EN = pstcConfig->bFilterEnable;
/* Other settings are set to default */
ctl0.stcField.u1BIT_ERROR_IGNORE = 0u;
ctl0.stcField.u1PARITY = 0u;
ctl0.stcField.u1PARITY_EN = 0u;
pstcLin->unCTL0.u32Register = ctl0.u32Register;
}
return status;
}
/**
*****************************************************************************
** \brief Read response data.
**
** \pre Must be run after RX_RESPONSE_DONE.
**
** \note This function return last received data set.
**
** \param pstcLin [in] Pointer to LIN instance register area.
** \param u8Data [out] Pointer to received data.
** Must have enough space for current Rx data.
**
** \retval Refer \ref cy_en_lin_status_t
**
*****************************************************************************/
cy_en_lin_status_t Cy_Lin_ReadData( volatile stc_LIN_CH_t* pstcLin, uint8_t *u8Data )
{
cy_en_lin_status_t status = CY_LIN_SUCCESS;
uint8_t u8Cnt;
uint8_t u8Length;
/* Check if pointers are valid */
if( ( NULL == pstcLin ) ||
( NULL == u8Data ))
{
status = CY_LIN_BAD_PARAM;
}
/* Check if the response is received successfully */
else if( ( 0u == pstcLin->unCMD.stcField.u1RX_RESPONSE ) &&
( 0u == pstcLin->unSTATUS.stcField.u1RX_BUSY ) )
{
u8Length = pstcLin->unCTL1.stcField.u3DATA_NR + 1u;
/* Copy the data in to u8Data array */
un_LIN_CH_DATA0_t data0;
un_LIN_CH_DATA1_t data1;
data0.u32Register = pstcLin->unDATA0.u32Register;
data1.u32Register = pstcLin->unDATA1.u32Register;
for ( u8Cnt = 0; u8Cnt < u8Length; u8Cnt++ )
{
if( 4u > u8Cnt )
{
u8Data[u8Cnt] = data0.au8Byte[u8Cnt];
}
else
{
u8Data[u8Cnt] = data1.au8Byte[u8Cnt - 4u];
}
}
}
else
{
status = CY_LIN_BUSY;
}
return status;
}
/**
*****************************************************************************
** \brief Write response data.
**
** \param pstcLin [in] Pointer to LIN instance register area.
** \param au8Data [in] Pointer to response data.
** \param u8DataLength [in] Data length in bytes.
** \retval Refer \ref cy_en_lin_status_t
**
*****************************************************************************/
cy_en_lin_status_t Cy_Lin_WriteData( volatile stc_LIN_CH_t* pstcLin, const uint8_t *au8Data,
uint8_t u8DataLength )
{
cy_en_lin_status_t status = CY_LIN_SUCCESS;
un_LIN_CH_DATA0_t data0 = { 0 };
un_LIN_CH_DATA1_t data1 = { 0 };
uint8_t u8Cnt;
/* Check if NULL pointer */
if( ( NULL == pstcLin ) ||
( NULL == au8Data ) )
{
status = CY_LIN_BAD_PARAM;
}
/* Check if data length is valid */
else if( CY_LIN_DATA_LENGTH_MAX < u8DataLength )
{
status = CY_LIN_BAD_PARAM;
}
/* Check if the bus is free */
else if( 0u == pstcLin->unSTATUS.stcField.u1TX_BUSY )
{
/* Write data in to the temp variables */
for( u8Cnt = 0; u8Cnt < u8DataLength; u8Cnt++ )
{
if( 4u > u8Cnt )
{
data0.au8Byte[u8Cnt] = au8Data[u8Cnt];
}
else
{
data1.au8Byte[u8Cnt - 4u] = au8Data[u8Cnt];
}
}
/* Write data to HW FIFO */
pstcLin->unDATA0.u32Register = data0.u32Register;
pstcLin->unDATA1.u32Register = data1.u32Register;
}
else
{
status = CY_LIN_BUSY;
/* A requested operation could not be completed */
}
return status;
}
/**
*****************************************************************************
** \brief Enable LIN channel.
**
** \param pstcLin [in] Pointer to LIN instance register area.
**
** \retval Refer \ref cy_en_lin_status_t
**
*****************************************************************************/
cy_en_lin_status_t Cy_Lin_Enable(volatile stc_LIN_CH_t* pstcLin)
{
cy_en_lin_status_t ret = CY_LIN_SUCCESS;
if (NULL == pstcLin)
{
ret = CY_LIN_BAD_PARAM;
}
else
{
pstcLin->unCTL0.stcField.u1ENABLED = 1u;
}
return ret;
}
/**
*****************************************************************************
** \brief Disable LIN channel.
** Disabling LIN channel causes clearing none retained registers.
** e.g) CMD register, INTR register, STATUS regiser.
** This behavior can be uses re-initialization after error,
** abort RX operation.
**
** \param pstcLin [in] Pointer to LIN instance register area.
**
** \retval Refer \ref cy_en_lin_status_t
**
*****************************************************************************/
cy_en_lin_status_t Cy_Lin_Disable(volatile stc_LIN_CH_t* pstcLin)
{
cy_en_lin_status_t ret = CY_LIN_SUCCESS;
if (NULL == pstcLin)
{
ret = CY_LIN_BAD_PARAM;
}
else
{
pstcLin->unCTL0.stcField.u1ENABLED = 0u;
}
return ret;
}
/**
*****************************************************************************
** \brief Setup LIN break/wakeup field length.
** Normaly this I/F is used for detection of the wakeup pulse.
**
** \param pstcLin [in] Pointer to LIN instance register area.
** \param length [in] Bit length of the break/wakeup field.
**
** \retval Refer \ref cy_en_lin_status_t
**
*****************************************************************************/
cy_en_lin_status_t Cy_Lin_SetBreakWakeupFieldLength(volatile stc_LIN_CH_t* pstcLin, uint8_t length)
{
cy_en_lin_status_t ret = CY_LIN_SUCCESS;
if (NULL == pstcLin)
{
ret = CY_LIN_BAD_PARAM;
}
else if (CY_LIN_BREAK_WAKEUP_LENGTH_BITS_MAX < length)
{
ret = CY_LIN_BAD_PARAM;
}
else
{
pstcLin->unCTL0.stcField.u5BREAK_WAKEUP_LENGTH = length - 1u;
}
return ret;
}
/**
*****************************************************************************
** \brief Setup LIN checksum type setting
**
** \param pstcLin [in] Pointer to LIN instance register area.
** \param type [in] Checksum type. Refer \ref en_lin_checksum_type_t
**
** \retval Refer \ref cy_en_lin_status_t
**
*****************************************************************************/
cy_en_lin_status_t Cy_Lin_SetChecksumType(volatile stc_LIN_CH_t* pstcLin, en_lin_checksum_type_t type)
{
cy_en_lin_status_t ret = CY_LIN_SUCCESS;
if (NULL == pstcLin)
{
ret = CY_LIN_BAD_PARAM;
}
else
{
pstcLin->unCTL1.stcField.u1CHECKSUM_ENHANCED = type;
}
return ret;
}
/**
*****************************************************************************
** \brief Setup LIN response field data length
**
** \param pstcLin [in] Pointer to LIN instance register area.
** \param length [in] Data length in byte
**
** \retval Refer \ref cy_en_lin_status_t
**
*****************************************************************************/
cy_en_lin_status_t Cy_Lin_SetDataLength(volatile stc_LIN_CH_t* pstcLin, uint8_t length)
{
cy_en_lin_status_t ret = CY_LIN_SUCCESS;
if ((NULL == pstcLin) ||
(length > CY_LIN_DATA_LENGTH_MAX) ||
(length < CY_LIN_DATA_LENGTH_MIN))
{
ret = CY_LIN_BAD_PARAM;
}
else
{
pstcLin->unCTL1.stcField.u3DATA_NR = length - 1u;
}
return ret;
}
/**
*****************************************************************************
** \brief Setup LIN operation command
**
** \note As a normal usage, following comobinations are used.
** - Master
** Header TX only : LIN_CMD_TX_HEADER
** Header TX & TX response : LIN_CMD_TX_HEADER_TX_RESPONSE
** Header TX & RX response : LIN_CMD_TX_HEADER_RX_RESPONSE
** - Slave
** Header RX : LIN_CMD_RX_HEADER_RX_RESPONSE
** TX response : LIN_CMD_TX_RESPONSE
** RX response : Already set when header RX
** As a typical usage, RX response is always set at header RX phase.
** - Wakeup frame : LIN_CMD_TX_WAKEUP
** Instead of above macro, you can use raw definition LIN_CH_CMD_*_Msk defined in IO header file.
**
** \param pstcLin [in] Pointer to LIN instance register area.
** \param command [in] Required operation command. Refer \ref group_lin_cmd_macro
**
** \retval Refer \ref cy_en_lin_status_t
**
*****************************************************************************/
cy_en_lin_status_t Cy_Lin_SetCmd(volatile stc_LIN_CH_t* pstcLin, uint32_t command)
{
cy_en_lin_status_t ret = CY_LIN_SUCCESS;
un_LIN_CH_CMD_t cmdReg;
cmdReg.u32Register = pstcLin->unCMD.u32Register;
if (NULL == pstcLin)
{
ret = CY_LIN_BAD_PARAM;
}
else if (((command & (LIN_CH_CMD_TX_HEADER_Msk | LIN_CH_CMD_RX_HEADER_Msk))
== (LIN_CH_CMD_TX_HEADER_Msk | LIN_CH_CMD_RX_HEADER_Msk)) ||
(((command & LIN_CH_CMD_TX_WAKEUP_Msk) != 0) &&
((command & (LIN_CH_CMD_TX_HEADER_Msk |
LIN_CH_CMD_TX_RESPONSE_Msk |
LIN_CH_CMD_RX_HEADER_Msk |
LIN_CH_CMD_RX_RESPONSE_Msk)) != 0)))
{
ret = CY_LIN_BAD_PARAM;
}
else if (((cmdReg.stcField.u1TX_HEADER != 0) && (command & LIN_CH_CMD_RX_HEADER_Msk) != 0) ||
((cmdReg.stcField.u1RX_HEADER != 0) && (command & LIN_CH_CMD_TX_HEADER_Msk) != 0) ||
((cmdReg.stcField.u1TX_WAKEUP != 0) &&
((command & (LIN_CH_CMD_TX_HEADER_Msk |
LIN_CH_CMD_TX_RESPONSE_Msk |
LIN_CH_CMD_RX_HEADER_Msk |
LIN_CH_CMD_RX_RESPONSE_Msk)) != 0)))
{
ret = CY_LIN_BUSY;
}
else
{
pstcLin->unCMD.u32Register = command;
}
return ret;
}
/**
*****************************************************************************
** \brief Setup LIN header for master tx header operation
**
** \param pstcLin [in] Pointer to LIN instance register area.
** \param id [in] ID value
**
** \retval Refer \ref cy_en_lin_status_t
**
*****************************************************************************/
cy_en_lin_status_t Cy_Lin_SetHeader(volatile stc_LIN_CH_t* pstcLin, uint8_t id)
{
cy_en_lin_status_t ret = CY_LIN_SUCCESS;
uint8_t TempPID;
uint8_t Parity_P1, Parity_P0;
if ((NULL == pstcLin) ||
(CY_LIN_ID_MAX < id))
{
ret = CY_LIN_BAD_PARAM;
}
else
{
/* Calculate the Parity bits P0 & P1 */
Parity_P0 = ((id) ^ (id>>1u) ^
(id>>2u) ^ (id>>4u)) & 0x01u;
Parity_P1 = (~((id>>1u) ^ (id>>3u) ^
(id>>4u) ^ (id>>5u))) & 0x01u;
/* Assign the Parity bits and the header values in to the TempPID */
TempPID = id | ((uint8_t) Parity_P0<<6u) | ((uint8_t) Parity_P1<<7u);
/* Write the TempID value in to the TX_HEADER register */
pstcLin->unPID_CHECKSUM.stcField.u8PID = TempPID;
}
return ret;
}
/**
*****************************************************************************
** \brief Return received LIN header
**
** \param pstcLin [in] Pointer to LIN instance register area.
** \param id [out] Received ID value.
** \param parity [out] Received parity value.
** Note that parity check is always done by HW automatically.
**
** \retval Refer \ref cy_en_lin_status_t
**
*****************************************************************************/
cy_en_lin_status_t Cy_Lin_GetHeader(volatile stc_LIN_CH_t* pstcLin, uint8_t *id, uint8_t *parity)
{
cy_en_lin_status_t ret = CY_LIN_SUCCESS;
if ((NULL == pstcLin) ||
(NULL == id) ||
(NULL == parity))
{
ret = CY_LIN_BAD_PARAM;
}
else
{
/* Store received ID and parity bits */
uint8_t temp = pstcLin->unPID_CHECKSUM.stcField.u8PID;
*parity = (temp >> 6u);
*id = (temp & CY_LIN_ID_MAX);
}
return ret;
}
/**
*****************************************************************************
** \brief Setup interrupt source to be accepted.
**
** \param pstcLin [in] Pointer to LIN instance register area.
** \param mask [in] The mask with the OR of the interrupt source to be accepted.
** See \ref group_lin_intr_mask_macro for the set of constants.
**
** \retval Refer \ref cy_en_lin_status_t
**
*****************************************************************************/
cy_en_lin_status_t Cy_Lin_SetInterruptMask(volatile stc_LIN_CH_t* pstcLin, uint32_t mask)
{
cy_en_lin_status_t ret = CY_LIN_SUCCESS;
if (NULL == pstcLin)
{
ret = CY_LIN_BAD_PARAM;
}
else
{
pstcLin->unINTR_MASK.u32Register = mask;
}
return ret;
}
/**
*****************************************************************************
** \brief Return interupt mask setting.
**
** \param pstcLin [in] Pointer to LIN instance register area.
** \param status [out] The mask with the OR of the interrupt source which is masked.
** See \ref group_lin_intr_mask_macro for the set of constants.
**
** \retval Refer \ref cy_en_lin_status_t
**
*****************************************************************************/
cy_en_lin_status_t Cy_Lin_GetInterruptMask(volatile stc_LIN_CH_t* pstcLin, uint32_t *mask)
{
cy_en_lin_status_t ret = CY_LIN_SUCCESS;
if ((NULL == pstcLin) ||
(NULL == mask))
{
ret = CY_LIN_BAD_PARAM;
}
else
{
*mask = pstcLin->unINTR_MASK.u32Register;
}
return ret;
}
/**
*****************************************************************************
** \brief Return interupt masked status.
**
** \param pstcLin [in] Pointer to LIN instance register area.
** \param status [out] The mask with the OR of the interrupt source which occurs.
** See \ref group_lin_intr_mask_macro for the set of constants.
**
** \retval Refer \ref cy_en_lin_status_t
**
*****************************************************************************/
cy_en_lin_status_t Cy_Lin_GetInterruptMaskedStatus(volatile stc_LIN_CH_t* pstcLin, uint32_t *status)
{
cy_en_lin_status_t ret = CY_LIN_SUCCESS;
if ((NULL == pstcLin) ||
(NULL == status))
{
ret = CY_LIN_BAD_PARAM;
}
else
{
*status = pstcLin->unINTR_MASKED.u32Register;
}
return ret;
}
/**
*****************************************************************************
** \brief Return interupt raw status.
**
** \param pstcLin [in] Pointer to LIN instance register area.
** \param status [out] The mask with the OR of the interrupt source which occurs.
** See \ref group_lin_intr_mask_macro for the set of constants.
**
** \retval Refer \ref cy_en_lin_status_t
**
*****************************************************************************/
cy_en_lin_status_t Cy_Lin_GetInterruptStatus(volatile stc_LIN_CH_t* pstcLin, uint32_t *status)
{
cy_en_lin_status_t ret = CY_LIN_SUCCESS;
if ((NULL == pstcLin) ||
(NULL == status))
{
ret = CY_LIN_BAD_PARAM;
}
else
{
*status = pstcLin->unINTR.u32Register;
}
return ret;
}
/**
*****************************************************************************
** \brief Clear interupt status.
**
** \param pstcLin [in] Pointer to LIN instance register area.
** \param mask [in] The mask with the OR of the interrupt source to be cleared.
** See \ref group_lin_intr_mask_macro for the set of constants.
**
** \retval Refer \ref cy_en_lin_status_t
**
*****************************************************************************/
cy_en_lin_status_t Cy_Lin_ClearInterrupt(volatile stc_LIN_CH_t* pstcLin, uint32_t mask)
{
cy_en_lin_status_t ret = CY_LIN_SUCCESS;
if (NULL == pstcLin)
{
ret = CY_LIN_BAD_PARAM;
}
else
{
pstcLin->unINTR.u32Register = mask;
}
return ret;
}
/**
*****************************************************************************
** \brief Return LIN module status
**
** \param pstcLin [in] Pointer to LIN instance register area.
** \param status [out] LIN module status.
**
** \retval Refer \ref cy_en_lin_status_t
**
*****************************************************************************/
cy_en_lin_status_t Cy_Lin_GetStatus(volatile stc_LIN_CH_t* pstcLin, uint32_t *status)
{
cy_en_lin_status_t ret = CY_LIN_SUCCESS;
if ((NULL == pstcLin) ||
(NULL == status))
{
ret = CY_LIN_BAD_PARAM;
}
else
{
*status = pstcLin->unSTATUS.u32Register;
}
return ret;
}
/*****************************************************************************/
/* EOF (not truncated) */
/*****************************************************************************/
@@ -0,0 +1,275 @@
/***************************************************************************//**
* \file lin.h
* \version 1.0
*
* \brief
* Provides an API declaration of the LIN driver
*
********************************************************************************
* \copyright
* Copyright 2016-2017, Cypress Semiconductor Corporation. All rights reserved.
* You may use this file only in accordance with the license, terms, conditions,
* disclaimers, and limitations in the end user license agreement accompanying
* the software package with which this file was provided.
*******************************************************************************/
/**
* \defgroup group_lin Local Interconnect Network (LIN)
* \{
* The Local Interconnect Network (LIN) block of TVII supports the
* autonomous transfer of the LIN frame to reduce CPU processing. Supports
* master and slave functionality.
*
* One LIN bit length corresponds to 16 clock cycles; that is, 16 oversample
* counters are executed.
*
* This driver provides global LIN defines and API function definitions.
*
* \section group_lin_more_information More Information
* Refer to the technical reference manual (TRM) and the device datasheet.
*
* \section group_lin_changelog Changelog
* <table class="doxtable">
* <tr><th>Version</th><th>Changes</th><th>Reason for Change</th></tr>
* <tr>
* <td>6.6.0</td>
* <td>API prototype correction, prefixed Cy_ for APIs.
* Global macros prefixed with CY_LIN </td>
* <td>Proto type alignment with other modules</td>
* </tr>
* </table>
*
* \defgroup group_lin_macro Macro
* \defgroup group_lin_functions Functions
* \defgroup group_lin_data_structures Data structures
* \defgroup group_lin_enums Enumerated types
*/
#if !defined(CY_LIN_H)
#define CY_LIN_H
/*****************************************************************************/
/* Include files */
/*****************************************************************************/
#include <stddef.h>
#include "syslib/cy_syslib.h"
#include "cy_device_headers.h"
#if defined(__cplusplus)
extern "C" {
#endif
/**
* \addtogroup group_lin_macros
* \{
*/
/*****************************************************************************/
/* Global pre-processor symbols/macros ('#define') */
/*****************************************************************************/
/** Driver major version */
#define CY_LIN_DRV_VERSION_MAJOR 1
/** Driver minor version */
#define CY_LIN_DRV_VERSION_MINOR 0
/** LIN driver ID */
#define CY_LIN_ID CY_PDL_DRV_ID(0x37u)
/** Maximum ID */
#define CY_LIN_ID_MAX (0x3Fu)
/** Maximum data length */
#define CY_LIN_DATA_LENGTH_MAX (8u)
/** Minimum data length */
#define CY_LIN_DATA_LENGTH_MIN (1u)
/** Maximum time out length */
#define CY_LIN_TIMEOUT_LENGTH_MAX (255u)
/** Minimum wakeup peroid value = 250usec*/
#define CY_LIN_WAKEUP_PERIOD_MIN (250u)
/** Maximum break_wakeup period bit length */
#define CY_LIN_BREAK_WAKEUP_LENGTH_BITS_MAX (31u)
/** LIN Master minimum break filed detection length */
#define CY_LIN_MASTER_BREAK_FILED_LENGTH_MIN (13u)
/**
* LIN command type: Specifies the parameter values passed to LIN command API
*/
#define CY_LIN_CMD_TX_HEADER (LIN_CH_CMD_TX_HEADER_Msk)
#define CY_LIN_CMD_TX_RESPONSE (LIN_CH_CMD_TX_RESPONSE_Msk)
#define CY_LIN_CMD_RX_RESPONSE (LIN_CH_CMD_RX_RESPONSE_Msk)
#define CY_LIN_CMD_TX_HEADER_TX_RESPONSE (LIN_CH_CMD_TX_HEADER_Msk | LIN_CH_CMD_TX_RESPONSE_Msk)
#define CY_LIN_CMD_TX_HEADER_RX_RESPONSE (LIN_CH_CMD_TX_HEADER_Msk | LIN_CH_CMD_RX_RESPONSE_Msk)
#define CY_LIN_CMD_RX_HEADER_RX_RESPONSE (LIN_CH_CMD_RX_HEADER_Msk | LIN_CH_CMD_RX_RESPONSE_Msk)
#define CY_LIN_CMD_TX_WAKEUP (LIN_CH_CMD_TX_WAKEUP_Msk)
/** \} group_lin_cmd_macro */
/**
* LIN ALL error mask: Specifies the mask value for interrupt status/mask
*/
#define CY_LIN_INTR_TX_HEADER_DONE (LIN_CH_INTR_TX_HEADER_DONE_Msk)
#define CY_LIN_INTR_TX_RESPONSE_DONE (LIN_CH_INTR_TX_RESPONSE_DONE_Msk)
#define CY_LIN_INTR_TX_WAKEUP_DONE (LIN_CH_INTR_TX_WAKEUP_DONE_Msk)
#define CY_LIN_INTR_RX_HEADER_DONE (LIN_CH_INTR_RX_HEADER_DONE_Msk)
#define CY_LIN_INTR_RX_RESPONSE_DONE (LIN_CH_INTR_RX_RESPONSE_DONE_Msk)
#define CY_LIN_INTR_RX_WAKEUP_DONE (LIN_CH_INTR_RX_WAKEUP_DONE_Msk)
#define CY_LIN_INTR_RX_HEADER_SYNC_DONE (LIN_CH_INTR_RX_HEADER_SYNC_DONE_Msk)
#define CY_LIN_INTR_RX_NOISE_DETECT (LIN_CH_INTR_RX_NOISE_DETECT_Msk)
#define CY_LIN_INTR_TIMEOUT (LIN_CH_INTR_TIMEOUT_Msk)
#define CY_LIN_INTR_TX_HEADER_BIT_ERROR (LIN_CH_INTR_TX_HEADER_BIT_ERROR_Msk)
#define CY_LIN_INTR_TX_RESPONSE_BIT_ERROR (LIN_CH_INTR_TX_RESPONSE_BIT_ERROR_Msk)
#define CY_LIN_INTR_RX_HEADER_FRAME_ERROR (LIN_CH_INTR_RX_HEADER_FRAME_ERROR_Msk)
#define CY_LIN_INTR_RX_HEADER_SYNC_ERROR (LIN_CH_INTR_RX_HEADER_SYNC_ERROR_Msk)
#define CY_LIN_INTR_RX_HEADER_PARITY_ERROR (LIN_CH_INTR_RX_HEADER_PARITY_ERROR_Msk)
#define CY_LIN_INTR_RX_RESPONSE_FRAME_ERROR (LIN_CH_INTR_RX_RESPONSE_FRAME_ERROR_Msk)
#define CY_LIN_INTR_RX_RESPONSE_CHECKSUM_ERROR (LIN_CH_INTR_RX_RESPONSE_CHECKSUM_ERROR_Msk)
#define CY_LIN_INTR_ALL_ERROR_MASK_SLAVE (LIN_CH_INTR_RX_NOISE_DETECT_Msk |\
LIN_CH_INTR_TIMEOUT_Msk |\
LIN_CH_INTR_TX_RESPONSE_BIT_ERROR_Msk |\
LIN_CH_INTR_RX_HEADER_FRAME_ERROR_Msk |\
LIN_CH_INTR_RX_HEADER_SYNC_ERROR_Msk |\
LIN_CH_INTR_RX_HEADER_PARITY_ERROR_Msk |\
LIN_CH_INTR_RX_RESPONSE_FRAME_ERROR_Msk |\
LIN_CH_INTR_RX_RESPONSE_CHECKSUM_ERROR_Msk)
#define CY_LIN_INTR_ALL_ERROR_MASK_MASTER (CY_LIN_INTR_ALL_ERROR_MASK_SLAVE | LIN_CH_INTR_TX_HEADER_BIT_ERROR_Msk)
/** \} group_lin_macros */
/*****************************************************************************/
/* Global type definitions ('typedef') */
/*****************************************************************************/
/**
* \addtogroup group_lin_enums
* \{
*/
/** LIN API status definition */
typedef enum
{
CY_LIN_SUCCESS = 0x00u, /**< Returned successful */
CY_LIN_BAD_PARAM = CY_LIN_ID | CY_PDL_STATUS_ERROR | 0x01u, /**< Bad parameter was passed */
CY_LIN_BUSY = CY_LIN_ID | CY_PDL_STATUS_ERROR | 0x02u, /**< Change settings while tx/rx on-going */
CY_LIN_FRAME_NOT_RECEIVED = CY_LIN_ID | CY_PDL_STATUS_ERROR | 0x03u, /**< No frame received */
} cy_en_lin_status_t;
/**
* LIN break delimiter length.
* This configuration is effective only when corresponding channel = master mode.
*/
typedef enum {
LinBreakDelimiterLength1bits = 0, /**< 1-bit length */
LinBreakDelimiterLength2bits = 1, /**< 2-bit length */
LinBreakDelimiterLength3bits = 2, /**< 3-bit length */
LinBreakDelimiterLength4bits = 3 /**< 4-bit length */
} en_lin_break_delimiter_length_t;
/**
* Stop bit selection.
*/
typedef enum
{
LinOneStopBit = 1, /**< 1 stop bit */
LinTwoStopBit = 3 /**< 2 stop bits */
} en_lin_stopbit_t;
/**
* Checksum type selection.
*/
typedef enum
{
LinChecksumTypeNormal = 0, /**< Normal (classic) checksum */
LinChecksumTypeExtended = 1 /**< Extended (enhanced) checksum */
} en_lin_checksum_type_t;
/**
* Timeout type selection.
*/
typedef enum
{
LinTimeoutNone = 0, /**< No timeout */
LinTimeoutFromBreakToChecksum = 1, /**< Frame mode: from the start of break field to checksum field STOP bits */
LinTimeoutFromBreakToPID = 2, /**< Frame header mode: detects timeout from the start of break field to PID field STOP bits */
LinTimeoutFromResponseToChecksum = 3 /**< Frame response mode: detects timeout from the first data field START bit to checksum field STOP bits. */
} en_lin_timeout_sel_type_t;
/** \} group_lin_enums */
/**
* \addtogroup group_lin_data_structures
* \{
*/
/**
*****************************************************************************
** \brief LIN configuration
** This settings are per LIN instance.
*****************************************************************************/
typedef struct stc_lin_config
{
/**< If TRUE, corresponding channel = master mode, If FALSE, slave mode. */
bool bMasterMode;
/**< If TRUE, corresponding LIN channel transceiver is enabled automatically,
** If FALSE, firmware has to handle the transceiver enable signal manually */
bool bLinTransceiverAutoEnable;
/**< Break field length. */
uint8_t u8BreakFieldLength;
/**< Break delimiter length. See #en_lin_break_delimiter_length_t */
en_lin_break_delimiter_length_t enBreakDelimiterLength;
/**< Stop bit length. See #en_lin_stopbit_t. */
en_lin_stopbit_t enStopBit;
/**< If TRUE, lin_rx_in filter operates.
* Median 3 operates on the last three "lin_rx_in" values.
* The sequences '000', '001', '010' and '100' result in a filtered value '0'.
* The sequences '111', '110', '101' and '011' result in a filtered value '1'.
*/
bool bFilterEnable;
}stc_lin_config_t;
/** \} group_lin_data_structures */
/**
* \addtogroup group_lin_functions
* \{
*/
/*****************************************************************************/
/* Global variable declarations ('extern', definition in C source) */
/*****************************************************************************/
/*****************************************************************************/
/* Global function prototypes ('extern', definition in C source) */
/*****************************************************************************/
cy_en_lin_status_t Cy_Lin_DeInit( volatile stc_LIN_CH_t* pstcLin );
cy_en_lin_status_t Cy_Lin_Init( volatile stc_LIN_CH_t* pstcLin, const stc_lin_config_t *pstcConfig);
cy_en_lin_status_t Cy_Lin_ReadData( volatile stc_LIN_CH_t* pstcLin, uint8_t *u8Data);
cy_en_lin_status_t Cy_Lin_WriteData( volatile stc_LIN_CH_t* pstcLin, const uint8_t *au8Data,
uint8_t u8DataLength );
cy_en_lin_status_t Cy_Lin_Enable(volatile stc_LIN_CH_t* pstcLin);
cy_en_lin_status_t Cy_Lin_Disable(volatile stc_LIN_CH_t* pstcLin);
cy_en_lin_status_t Cy_Lin_SetBreakWakeupFieldLength(volatile stc_LIN_CH_t* pstcLin, uint8_t length);
cy_en_lin_status_t Cy_Lin_SetDataLength(volatile stc_LIN_CH_t* pstcLin, uint8_t length);
cy_en_lin_status_t Cy_Lin_SetChecksumType(volatile stc_LIN_CH_t* pstcLin, en_lin_checksum_type_t type);
cy_en_lin_status_t Cy_Lin_SetCmd(volatile stc_LIN_CH_t* pstcLin, uint32_t command);
cy_en_lin_status_t Cy_Lin_SetHeader(volatile stc_LIN_CH_t* pstcLin, uint8_t id);
cy_en_lin_status_t Cy_Lin_GetHeader(volatile stc_LIN_CH_t* pstcLin, uint8_t *id, uint8_t *parity);
cy_en_lin_status_t Cy_Lin_SetInterruptMask(volatile stc_LIN_CH_t* pstcLin, uint32_t mask);
cy_en_lin_status_t Cy_Lin_GetInterruptMask(volatile stc_LIN_CH_t* pstcLin, uint32_t *mask);
cy_en_lin_status_t Cy_Lin_GetInterruptMaskedStatus(volatile stc_LIN_CH_t* pstcLin, uint32_t *status);
cy_en_lin_status_t Cy_Lin_GetInterruptStatus(volatile stc_LIN_CH_t* pstcLin, uint32_t *status);
cy_en_lin_status_t Cy_Lin_ClearInterrupt(volatile stc_LIN_CH_t* pstcLin, uint32_t mask);
cy_en_lin_status_t Cy_Lin_GetStatus(volatile stc_LIN_CH_t* pstcLin, uint32_t *status);
/** \} group_lin_functions */
#ifdef __cplusplus
}
#endif
#endif /* __CY_LIN_H__ */
/*****************************************************************************/
/* EOF (not truncated) */
/*****************************************************************************/
@@ -0,0 +1,64 @@
/***************************************************************************//**
* \file cy_lvd.c
* \version 1.0
*
* The source code file for the LVD driver.
*
********************************************************************************
* \copyright
* Copyright 2017, Cypress Semiconductor Corporation. All rights reserved.
* You may use this file only in accordance with the license, terms, conditions,
* disclaimers, and limitations in the end user license agreement accompanying
* the software package with which this file was provided.
*******************************************************************************/
#include "cy_lvd.h"
#ifdef __cplusplus
extern "C" {
#endif
/*******************************************************************************
* Function Name: Cy_LVD_DeepSleepCallback
****************************************************************************//**
*
* When this function is registered by \ref Cy_SysPm_RegisterCallback - it
* automatically enables the LVD after wake up from DeepSleep mode.
*
* \param callbackParams a pointer to the callback parameters structure,
* see \ref cy_stc_syspm_callback_params_t.
*
* \return the SysPm callback status \ref cy_en_syspm_status_t.
*
*******************************************************************************/
cy_en_syspm_status_t Cy_LVD_DeepSleepCallback(cy_en_lvd_type_select_t lvdType, cy_stc_syspm_callback_params_t * callbackParams)
{
cy_en_syspm_status_t ret = CY_SYSPM_SUCCESS;
switch(callbackParams->mode)
{
case CY_SYSPM_CHECK_READY:
case CY_SYSPM_CHECK_FAIL:
case CY_SYSPM_BEFORE_ENTER:
break;
case CY_SYSPM_AFTER_EXIT:
Cy_LVD_Enable(lvdType);
break;
default:
ret = CY_SYSPM_FAIL;
break;
}
return(ret);
}
#ifdef __cplusplus
}
#endif
/* [] END OF FILE */
@@ -0,0 +1,540 @@
/***************************************************************************//**
* \file cy_lvd.h
* \version 1.0
*
* The header file of the LVD driver.
*
********************************************************************************
* \copyright
* Copyright 2017, Cypress Semiconductor Corporation. All rights reserved.
* You may use this file only in accordance with the license, terms, conditions,
* disclaimers, and limitations in the end user license agreement accompanying
* the software package with which this file was provided.
*******************************************************************************/
/**
* \addtogroup group_lvd Low Voltage Detector (LVD)
* \{
* The LVD driver provides an API to manage the Low Voltage Detection block.
* The LVD block provides a status of currently observed VDDD voltage
* and triggers an interrupt when the observed voltage crosses an adjusted
* threshold.
*
* \section group_lvd_configuration_considerations Configuration Considerations
* To set up an LVD, configure the voltage threshold by the
* \ref Cy_LVD_SetThreshold function, ensure that the LVD block itself and LVD
* interrupt are disabled (by the \ref Cy_LVD_Disable and
* \ref Cy_LVD_ClearInterruptMask functions correspondingly) before changing the
* threshold to prevent propagating a false interrupt.
* Then configure interrupts by the \ref Cy_LVD_SetInterruptConfig function, do
* not forget to initialize an interrupt handler (the interrupt source number
* is srss_interrupt_IRQn).
* Then enable LVD by the \ref Cy_LVD_Enable function, then wait for at least 8us
* to get the circuit stabilized and clear the possible false interrupts by the
* \ref Cy_LVD_ClearInterrupt, and finally the LVD interrupt can be enabled by
* the \ref Cy_LVD_SetInterruptMask function.
*
* Note that the LVD circuit is available only in Active, LPACTIVE, Sleep, and
* LPSLEEP power modes. If an LVD is required in DeepSleep mode, then the device
* should be configured to periodically wake up from deep sleep using a
* Deep-Sleep wakeup source. This makes sure a LVD check is performed during
* Active/LPACTIVE mode.
*
* \section group_lvd_more_information More Information
* See the LVD chapter of the device technical reference manual (TRM).
*
* \section group_lvd_changelog Changelog
* <table class="doxtable">
* <tr><th>Version</th><th>Changes</th><th>Reason of Change</th></tr>
* <tr>
* <td>1.0</td>
* <td>Initial Version</td>
* <td></td>
* </tr>
* </table>
*
* \defgroup group_lvd_macros Macros
* \defgroup group_lvd_functions Functions
* \defgroup group_lvd_enums Enumerated types
*/
#if !defined CY_LVD_H
#define CY_LVD_H
#include "syspm/cy_syspm.h"
#ifdef __cplusplus
extern "C" {
#endif
/** \addtogroup group_lvd_macros
* \{
*/
/** Driver major version */
#define CY_LVD_DRV_VERSION_MAJOR 1
/** Driver minor version */
#define CY_LVD_DRV_VERSION_MINOR 0
/** LVD driver identifier */
#define CY_LVD_ID (CY_PDL_DRV_ID(0x39u))
/** Interrupt mask for \ref Cy_LVD_GetInterruptStatus(),
\ref Cy_LVD_GetInterruptMask() and
\ref Cy_LVD_GetInterruptStatusMasked() */
#define CY_LVD_INTR (SRSS_SRSS_INTR_HVLVD1_Msk)
/** \} group_lvd_macros */
/** \addtogroup group_lvd_enums
* \{
*/
/**
* LVD Type Selection.
*/
typedef enum
{
CY_LVD_TYPE_1 = 0x0u, /**<Select LVD Type 1 */
CY_LVD_TYPE_2 = 0x1u, /**<Select LVD Type 2 */
} cy_en_lvd_type_select_t;
/**
* LVD reference voltage select.
*/
typedef enum
{
CY_LVD_THRESHOLD_2_8_V = 0x00u, /**<Select LVD reference voltage: 2.8V */
CY_LVD_THRESHOLD_2_9_V = 0x01u, /**<Select LVD reference voltage: 2.9V */
CY_LVD_THRESHOLD_3_0_V = 0x02u, /**<Select LVD reference voltage: 3.0V */
CY_LVD_THRESHOLD_3_1_V = 0x03u, /**<Select LVD reference voltage: 3.1V */
CY_LVD_THRESHOLD_3_2_V = 0x04u, /**<Select LVD reference voltage: 3.2V */
CY_LVD_THRESHOLD_3_3_V = 0x05u, /**<Select LVD reference voltage: 3.3V */
CY_LVD_THRESHOLD_3_4_V = 0x06u, /**<Select LVD reference voltage: 3.4V */
CY_LVD_THRESHOLD_3_5_V = 0x07u, /**<Select LVD reference voltage: 3.5V */
CY_LVD_THRESHOLD_3_6_V = 0x08u, /**<Select LVD reference voltage: 3.6V */
CY_LVD_THRESHOLD_3_7_V = 0x09u, /**<Select LVD reference voltage: 3.7V */
CY_LVD_THRESHOLD_3_8_V = 0x0Au, /**<Select LVD reference voltage: 3.8V */
CY_LVD_THRESHOLD_3_9_V = 0x0Bu, /**<Select LVD reference voltage: 3.9V */
CY_LVD_THRESHOLD_4_0_V = 0x0Cu, /**<Select LVD reference voltage: 4.0V */
CY_LVD_THRESHOLD_4_1_V = 0x0Du, /**<Select LVD reference voltage: 4.1V */
CY_LVD_THRESHOLD_4_2_V = 0x0Eu, /**<Select LVD reference voltage: 4.2V */
CY_LVD_THRESHOLD_4_3_V = 0x0Fu, /**<Select LVD reference voltage: 4.3V */
CY_LVD_THRESHOLD_4_4_V = 0x10u, /**<Select LVD reference voltage: 4.4V */
CY_LVD_THRESHOLD_4_5_V = 0x11u, /**<Select LVD reference voltage: 4.5V */
CY_LVD_THRESHOLD_4_6_V = 0x12u, /**<Select LVD reference voltage: 4.6V */
CY_LVD_THRESHOLD_4_7_V = 0x13u, /**<Select LVD reference voltage: 4.7V */
CY_LVD_THRESHOLD_4_8_V = 0x14u, /**<Select LVD reference voltage: 4.8V */
CY_LVD_THRESHOLD_4_9_V = 0x15u, /**<Select LVD reference voltage: 4.9V */
CY_LVD_THRESHOLD_5_0_V = 0x16u, /**<Select LVD reference voltage: 5.0V */
CY_LVD_THRESHOLD_5_1_V = 0x17u, /**<Select LVD reference voltage: 5.1V */
CY_LVD_THRESHOLD_5_2_V = 0x18u, /**<Select LVD reference voltage: 5.2V */
CY_LVD_THRESHOLD_5_3_V = 0x19u /**<Select LVD reference voltage: 5.3V */
} cy_en_lvd_tripsel_t;
/**
* LVD edge select configuration.
*/
typedef enum
{
CY_LVD_EDGE_DISABLE = 0x0u, /**<Select LVD edge select: disabled */
CY_LVD_EDGE_RISING = 0x1u, /**<Select LVD edge select: rising edge */
CY_LVD_EDGE_FALLING = 0x2u, /**<Select LVD edge select: falling edge */
CY_LVD_EDGE_BOTH = 0x3u, /**<Select LVD edge select: both edges */
} cy_en_lvd_edge_select_t;
/**
* LVD action select configuration.
*/
typedef enum
{
CY_LVD_ACTION_INTR = 0x0u, /**<Select LVD action select: interrupt */
CY_LVD_ACTION_FAULT = 0x1u, /**<Select LVD action select: fault */
} cy_en_lvd_action_select_t;
/**
* LVD output status.
*/
typedef enum
{
CY_LVD_STATUS_BELOW = 0x0u, /**<The voltage is below the threshold */
CY_LVD_STATUS_ABOVE = 0x1u, /**<The voltage is above the threshold */
} cy_en_lvd_status_t;
/** \} group_lvd_enums */
/** \cond internal */
/* Macros for conditions used by CY_ASSERT calls */
#define CY_LVD_CHECK_TRIPSEL(threshold) (((threshold) == CY_LVD_THRESHOLD_2_8_V) || \
((threshold) == CY_LVD_THRESHOLD_2_9_V) || \
((threshold) == CY_LVD_THRESHOLD_3_0_V) || \
((threshold) == CY_LVD_THRESHOLD_3_1_V) || \
((threshold) == CY_LVD_THRESHOLD_3_2_V) || \
((threshold) == CY_LVD_THRESHOLD_3_3_V) || \
((threshold) == CY_LVD_THRESHOLD_3_4_V) || \
((threshold) == CY_LVD_THRESHOLD_3_5_V) || \
((threshold) == CY_LVD_THRESHOLD_3_6_V) || \
((threshold) == CY_LVD_THRESHOLD_3_7_V) || \
((threshold) == CY_LVD_THRESHOLD_3_8_V) || \
((threshold) == CY_LVD_THRESHOLD_3_9_V) || \
((threshold) == CY_LVD_THRESHOLD_4_0_V) || \
((threshold) == CY_LVD_THRESHOLD_4_1_V) || \
((threshold) == CY_LVD_THRESHOLD_4_2_V) || \
((threshold) == CY_LVD_THRESHOLD_4_3_V) || \
((threshold) == CY_LVD_THRESHOLD_4_4_V) || \
((threshold) == CY_LVD_THRESHOLD_4_5_V) || \
((threshold) == CY_LVD_THRESHOLD_4_6_V) || \
((threshold) == CY_LVD_THRESHOLD_4_7_V) || \
((threshold) == CY_LVD_THRESHOLD_4_8_V) || \
((threshold) == CY_LVD_THRESHOLD_4_9_V) || \
((threshold) == CY_LVD_THRESHOLD_5_0_V) || \
((threshold) == CY_LVD_THRESHOLD_5_1_V) || \
((threshold) == CY_LVD_THRESHOLD_5_2_V) || \
((threshold) == CY_LVD_THRESHOLD_5_3_V))
#define CY_LVD_CHECK_EDGE_CFG(edgeCfg) (((edgeCfg) == CY_LVD_EDGE_DISABLE) || \
((edgeCfg) == CY_LVD_EDGE_RISING) || \
((edgeCfg) == CY_LVD_EDGE_FALLING) || \
((edgeCfg) == CY_LVD_EDGE_BOTH))
#define CY_LVD_CHECK_ACTION_CFG(actCfg) (((actCfg) == CY_LVD_ACTION_INTR) || \
((actCfg) == CY_LVD_ACTION_FAULT))
/** \endcond */
/**
* \addtogroup group_lvd_functions
* \{
*/
__STATIC_INLINE void Cy_LVD_Enable(cy_en_lvd_type_select_t lvdType);
__STATIC_INLINE void Cy_LVD_Disable(cy_en_lvd_type_select_t lvdType);
__STATIC_INLINE void Cy_LVD_SetThreshold(cy_en_lvd_type_select_t lvdType, cy_en_lvd_tripsel_t threshold);
__STATIC_INLINE cy_en_lvd_status_t Cy_LVD_GetStatus(cy_en_lvd_type_select_t lvdType);
__STATIC_INLINE uint32_t Cy_LVD_GetInterruptStatus(cy_en_lvd_type_select_t lvdType);
__STATIC_INLINE void Cy_LVD_ClearInterrupt(cy_en_lvd_type_select_t lvdType);
__STATIC_INLINE void Cy_LVD_SetInterrupt(cy_en_lvd_type_select_t lvdType);
__STATIC_INLINE uint32_t Cy_LVD_GetInterruptMask(cy_en_lvd_type_select_t lvdType);
__STATIC_INLINE void Cy_LVD_SetInterruptMask(cy_en_lvd_type_select_t lvdType);
__STATIC_INLINE void Cy_LVD_ClearInterruptMask(cy_en_lvd_type_select_t lvdType);
__STATIC_INLINE uint32_t Cy_LVD_GetInterruptStatusMasked(cy_en_lvd_type_select_t lvdType);
__STATIC_INLINE void Cy_LVD_SetEdgeSelect(cy_en_lvd_type_select_t lvdType, cy_en_lvd_edge_select_t lvdEdgeSelect);
__STATIC_INLINE void Cy_LVD_SetActionSelect(cy_en_lvd_type_select_t lvdType, cy_en_lvd_action_select_t lvdActionSelect);
cy_en_syspm_status_t Cy_LVD_DeepSleepCallback(cy_en_lvd_type_select_t lvdType, cy_stc_syspm_callback_params_t * callbackParams);
/*******************************************************************************
* Function Name: Cy_LVD_Enable
****************************************************************************//**
*
* Enables the output of the LVD block when the VDDD voltage is
* at or below the threshold.
* See the Configuration Considerations section for details.
*
*******************************************************************************/
__STATIC_INLINE void Cy_LVD_Enable(cy_en_lvd_type_select_t lvdType)
{
if(lvdType == CY_LVD_TYPE_1)
{
SRSS->unPWR_LVD_CTL.u32Register |= SRSS_PWR_LVD_CTL_HVLVD1_EN_HT_Msk;
}
else
{
SRSS->unPWR_LVD_CTL2.u32Register |= SRSS_PWR_LVD_CTL2_HVLVD2_EN_HT_Msk;
}
}
/*******************************************************************************
* Function Name: Cy_LVD_Disable
****************************************************************************//**
*
* Disables the LVD block. A low voltage detection interrupt is disabled.
*
*******************************************************************************/
__STATIC_INLINE void Cy_LVD_Disable(cy_en_lvd_type_select_t lvdType)
{
if(lvdType == CY_LVD_TYPE_1)
{
SRSS->unPWR_LVD_CTL.u32Register &= (uint32_t) ~SRSS_PWR_LVD_CTL_HVLVD1_EN_HT_Msk;
}
else
{
SRSS->unPWR_LVD_CTL2.u32Register &= (uint32_t) ~SRSS_PWR_LVD_CTL2_HVLVD2_EN_HT_Msk;
}
}
/*******************************************************************************
* Function Name: Cy_LVD_SetThreshold
****************************************************************************//**
*
* Sets a threshold for monitoring the VDDD voltage.
* To prevent propagating a false interrupt, before changing the threshold
* ensure that the LVD block itself and LVD interrupt are disabled by the
* \ref Cy_LVD_Disable and \ref Cy_LVD_ClearInterruptMask functions
* correspondingly.
*
* \param threshold
* Threshold selection for Low Voltage Detect circuit, \ref cy_en_lvd_tripsel_t.
*
*******************************************************************************/
__STATIC_INLINE void Cy_LVD_SetThreshold(cy_en_lvd_type_select_t lvdType, cy_en_lvd_tripsel_t threshold)
{
CY_ASSERT(CY_LVD_CHECK_TRIPSEL(threshold));
if(lvdType == CY_LVD_TYPE_1)
{
SRSS->unPWR_LVD_CTL.u32Register = _CLR_SET_FLD32U(SRSS->unPWR_LVD_CTL.u32Register, SRSS_PWR_LVD_CTL_HVLVD1_TRIPSEL_HT, threshold);
}
else
{
SRSS->unPWR_LVD_CTL2.u32Register = _CLR_SET_FLD32U(SRSS->unPWR_LVD_CTL2.u32Register, SRSS_PWR_LVD_CTL2_HVLVD2_TRIPSEL_HT, threshold);
}
}
/*******************************************************************************
* Function Name: Cy_LVD_GetStatus
****************************************************************************//**
*
* Returns the status of LVD.
* SRSS LVD Status Register (PWR_LVD_STATUS).
*
* \return LVD status, \ref cy_en_lvd_status_t.
*
*******************************************************************************/
__STATIC_INLINE cy_en_lvd_status_t Cy_LVD_GetStatus(cy_en_lvd_type_select_t lvdType)
{
if(lvdType == CY_LVD_TYPE_1)
{
return ((cy_en_lvd_status_t) _FLD2VAL(SRSS_PWR_LVD_STATUS_HVLVD1_OUT, SRSS->unPWR_LVD_STATUS.u32Register));
}
else
{
return ((cy_en_lvd_status_t) _FLD2VAL(SRSS_PWR_LVD_STATUS2_HVLVD2_OUT, SRSS->unPWR_LVD_STATUS2.u32Register));
}
}
/*******************************************************************************
* Function Name: Cy_LVD_GetInterruptStatus
****************************************************************************//**
*
* Returns the status of LVD interrupt.
* SRSS Interrupt Register (SRSS_INTR).
*
* \return SRSS Interrupt status, \ref CY_LVD_INTR.
*
*******************************************************************************/
__STATIC_INLINE uint32_t Cy_LVD_GetInterruptStatus(cy_en_lvd_type_select_t lvdType)
{
if(lvdType == CY_LVD_TYPE_1)
{
return (SRSS->unSRSS_INTR.u32Register & SRSS_SRSS_INTR_HVLVD1_Msk);
}
else
{
return (SRSS->unSRSS_INTR.u32Register & SRSS_SRSS_INTR_HVLVD2_Msk);
}
}
/*******************************************************************************
* Function Name: Cy_LVD_ClearInterrupt
****************************************************************************//**
*
* Clears LVD interrupt.
* SRSS Interrupt Register (SRSS_INTR).
*
*******************************************************************************/
__STATIC_INLINE void Cy_LVD_ClearInterrupt(cy_en_lvd_type_select_t lvdType)
{
if(lvdType == CY_LVD_TYPE_1)
{
SRSS->unSRSS_INTR.u32Register = SRSS_SRSS_INTR_HVLVD1_Msk;
}
else
{
SRSS->unSRSS_INTR.u32Register = SRSS_SRSS_INTR_HVLVD2_Msk;
}
(void) SRSS->unSRSS_INTR.u32Register;
}
/*******************************************************************************
* Function Name: Cy_LVD_SetInterrupt
****************************************************************************//**
*
* Triggers the device to generate interrupt for LVD.
* SRSS Interrupt Set Register (SRSS_INTR_SET).
*
*******************************************************************************/
__STATIC_INLINE void Cy_LVD_SetInterrupt(cy_en_lvd_type_select_t lvdType)
{
if(lvdType == CY_LVD_TYPE_1)
{
SRSS->unSRSS_INTR_SET.u32Register = SRSS_SRSS_INTR_SET_HVLVD1_Msk;
}
else
{
SRSS->unSRSS_INTR_SET.u32Register = SRSS_SRSS_INTR_SET_HVLVD2_Msk;
}
}
/*******************************************************************************
* Function Name: Cy_LVD_GetInterruptMask
****************************************************************************//**
*
* Returns the mask value of LVD interrupts.
* SRSS Interrupt Mask Register (SRSS_INTR_MASK).
*
* \return SRSS Interrupt Mask value, \ref CY_LVD_INTR.
*
*******************************************************************************/
__STATIC_INLINE uint32_t Cy_LVD_GetInterruptMask(cy_en_lvd_type_select_t lvdType)
{
if(lvdType == CY_LVD_TYPE_1)
{
return (SRSS->unSRSS_INTR_MASK.u32Register & SRSS_SRSS_INTR_MASK_HVLVD1_Msk);
}
else
{
return (SRSS->unSRSS_INTR_MASK.u32Register & SRSS_SRSS_INTR_MASK_HVLVD2_Msk);
}
}
/*******************************************************************************
* Function Name: Cy_LVD_SetInterruptMask
****************************************************************************//**
*
* Enables LVD interrupts.
* Sets the LVD interrupt mask in the SRSS_INTR_MASK register.
*
*******************************************************************************/
__STATIC_INLINE void Cy_LVD_SetInterruptMask(cy_en_lvd_type_select_t lvdType)
{
if(lvdType == CY_LVD_TYPE_1)
{
SRSS->unSRSS_INTR_MASK.u32Register |= SRSS_SRSS_INTR_MASK_HVLVD1_Msk;
}
else
{
SRSS->unSRSS_INTR_MASK.u32Register |= SRSS_SRSS_INTR_MASK_HVLVD2_Msk;
}
}
/*******************************************************************************
* Function Name: Cy_LVD_ClearInterruptMask
****************************************************************************//**
*
* Disables LVD interrupts.
* Clears the LVD interrupt mask in the SRSS_INTR_MASK register.
*
*******************************************************************************/
__STATIC_INLINE void Cy_LVD_ClearInterruptMask(cy_en_lvd_type_select_t lvdType)
{
if(lvdType == CY_LVD_TYPE_1)
{
SRSS->unSRSS_INTR_MASK.u32Register &= (uint32_t) ~SRSS_SRSS_INTR_MASK_HVLVD1_Msk;
}
else
{
SRSS->unSRSS_INTR_MASK.u32Register &= (uint32_t) ~SRSS_SRSS_INTR_MASK_HVLVD2_Msk;
}
}
/*******************************************************************************
* Function Name: Cy_LVD_GetInterruptStatusMasked
****************************************************************************//**
*
* Returns the masked interrupt status which is a bitwise AND between the
* interrupt status and interrupt mask registers.
* SRSS Interrupt Masked Register (SRSS_INTR_MASKED).
*
* \return SRSS Interrupt Masked value, \ref CY_LVD_INTR.
*
*******************************************************************************/
__STATIC_INLINE uint32_t Cy_LVD_GetInterruptStatusMasked(cy_en_lvd_type_select_t lvdType)
{
if(lvdType == CY_LVD_TYPE_1)
{
return (SRSS->unSRSS_INTR_MASKED.u32Register & SRSS_SRSS_INTR_MASKED_HVLVD1_Msk);
}
else
{
return (SRSS->unSRSS_INTR_MASKED.u32Register & SRSS_SRSS_INTR_MASKED_HVLVD2_Msk);
}
}
/*******************************************************************************
* Function Name: Cy_LVD_SetEdgeSelect
****************************************************************************//**
*
* Sets which edge(s) will trigger as action when the threshold is crossed.
* Note: Before calling this function ensure that the LVD block itself and LVD interrupts
* are disabled
*
* \param lvdSelect \ref cy_en_lvd_edge_select_t.
*
*******************************************************************************/
__STATIC_INLINE void Cy_LVD_SetEdgeSelect(cy_en_lvd_type_select_t lvdType, cy_en_lvd_edge_select_t lvdEdgeSelect)
{
CY_ASSERT(CY_LVD_CHECK_EDGE_CFG(lvdEdgeSelect));
if(lvdType == CY_LVD_TYPE_1)
{
SRSS->unPWR_LVD_CTL.u32Register = _CLR_SET_FLD32U(SRSS->unPWR_LVD_CTL.u32Register, SRSS_PWR_LVD_CTL_HVLVD1_EDGE_SEL, lvdEdgeSelect);
}
else
{
SRSS->unPWR_LVD_CTL2.u32Register = _CLR_SET_FLD32U(SRSS->unPWR_LVD_CTL2.u32Register, SRSS_PWR_LVD_CTL2_HVLVD2_EDGE_SEL, lvdEdgeSelect);
}
}
/*******************************************************************************
* Function Name: Cy_LVD_SetActionSelect
****************************************************************************//**
*
* Sets the action taken when the threshold is crossed in the programmed directions(s).
*
* \param lvdActionSelect \ref cy_en_lvd_action_select_t.
*
*******************************************************************************/
__STATIC_INLINE void Cy_LVD_SetActionSelect(cy_en_lvd_type_select_t lvdType, cy_en_lvd_action_select_t lvdActionSelect)
{
CY_ASSERT(CY_LVD_CHECK_ACTION_CFG(lvdActionSelect));
if(lvdType == CY_LVD_TYPE_1)
{
SRSS->unPWR_LVD_CTL.u32Register = _CLR_SET_FLD32U(SRSS->unPWR_LVD_CTL.u32Register, SRSS_PWR_LVD_CTL_HVLVD1_ACTION, lvdActionSelect);
}
else
{
SRSS->unPWR_LVD_CTL2.u32Register = _CLR_SET_FLD32U(SRSS->unPWR_LVD_CTL2.u32Register, SRSS_PWR_LVD_CTL2_HVLVD2_ACTION, lvdActionSelect);
}
}
/** \} group_lvd_functions */
#ifdef __cplusplus
}
#endif
#endif /* CY_LVD_H */
/** \} group_lvd */
/* [] END OF FILE */
@@ -0,0 +1,163 @@
/***************************************************************************//**
* \file cy_mcwdt.c
* \version 1.0
*
* Description:
* Provides a system API for the MCWDT driver.
*
********************************************************************************
* Copyright 2016-2017, Cypress Semiconductor Corporation. All rights reserved.
* You may use this file only in accordance with the license, terms, conditions,
* disclaimers, and limitations in the end user license agreement accompanying
* the software package with which this file was provided.
*******************************************************************************/
#include "cy_mcwdt.h"
#if defined(__cplusplus)
extern "C" {
#endif
/*******************************************************************************
* Function Name: Cy_MCWDT_Init
****************************************************************************//**
*
* Initializes the MCWDT block.
*
* \param base
* The base pointer to a structure that describes the registers.
*
* \param config
* The pointer to a structure that contains component configuration data.
*
* \return cy_en_mcwdt_status_t
* *base checking result. If the pointer is NULL, returns error.
*
* \note
* This API should not be called when the counters are running. Prior to calling
* this API the counter should be disabled.
*
*******************************************************************************/
cy_en_mcwdt_status_t Cy_MCWDT_Init(volatile stc_MCWDT_t *base, cy_stc_mcwdt_config_t const *config)
{
cy_en_mcwdt_status_t ret = CY_MCWDT_BAD_PARAM;
if ((base != NULL) && (config != NULL))
{
Cy_MCWDT_Unlock(base);
un_MCWDT_CTR_CONFIG_t tempConfigParams = { 0ul };
un_MCWDT_CTR2_CONFIG_t tempCNT2ConfigParams = { 0ul };
base->unCPU_SELECT.u32Register = config->coreSelect;
base->CTR[0].unLOWER_LIMIT.stcField.u16LOWER_LIMIT = config->c0LowerLimit;
base->CTR[0].unUPPER_LIMIT.stcField.u16UPPER_LIMIT = config->c0UpperLimit;
base->CTR[0].unWARN_LIMIT.stcField.u16WARN_LIMIT = config->c0WarnLimit;
tempConfigParams.stcField.u2LOWER_ACTION = config->c0LowerAction;
tempConfigParams.stcField.u2UPPER_ACTION = config->c0UpperAction;
tempConfigParams.stcField.u1WARN_ACTION = config->c0WarnAction;
tempConfigParams.stcField.u1AUTO_SERVICE = config->c0AutoService;
tempConfigParams.stcField.u1SLEEPDEEP_PAUSE = config->c0SleepDeepPause;
tempConfigParams.stcField.u1DEBUG_RUN = config->c0DebugRun;
base->CTR[0].unCONFIG.u32Register = tempConfigParams.u32Register;
base->CTR[1].unLOWER_LIMIT.stcField.u16LOWER_LIMIT = config->c1LowerLimit;
base->CTR[1].unUPPER_LIMIT.stcField.u16UPPER_LIMIT = config->c1UpperLimit;
base->CTR[1].unWARN_LIMIT.stcField.u16WARN_LIMIT = config->c1WarnLimit;
tempConfigParams.stcField.u2LOWER_ACTION = config->c1LowerAction;
tempConfigParams.stcField.u2UPPER_ACTION = config->c1UpperAction;
tempConfigParams.stcField.u1WARN_ACTION = config->c1WarnAction;
tempConfigParams.stcField.u1AUTO_SERVICE = config->c1AutoService;
tempConfigParams.stcField.u1SLEEPDEEP_PAUSE = config->c1SleepDeepPause;
tempConfigParams.stcField.u1DEBUG_RUN = config->c1DebugRun;
base->CTR[1].unCONFIG.u32Register = tempConfigParams.u32Register;
tempCNT2ConfigParams.stcField.u5BITS = config->c2ToggleBit;
tempCNT2ConfigParams.stcField.u1ACTION = config->c2Action;
tempCNT2ConfigParams.stcField.u1SLEEPDEEP_PAUSE = config->c2SleepDeepPause;
tempCNT2ConfigParams.stcField.u1DEBUG_RUN = config->c2DebugRun;
base->unCTR2_CONFIG.u32Register = tempCNT2ConfigParams.u32Register;
Cy_MCWDT_Lock(base);
ret = CY_MCWDT_SUCCESS;
}
return (ret);
}
/*******************************************************************************
* Function Name: Cy_MCWDT_DeInit
****************************************************************************//**
*
* De-initializes the MCWDT block, returns register values to their default state.
*
* \param base
* The base pointer to a structure that describes the registers.
*
* \note
* This API should not be called when the counters are running. Prior to calling
* this API the counter should be disabled.
*
* \note
* This API waits all counter are actually disabled after disables all counters,
* And then start initializing other registers.
*
*******************************************************************************/
void Cy_MCWDT_DeInit(volatile stc_MCWDT_t *base)
{
Cy_MCWDT_Unlock(base);
// disable all counter
for(uint32_t loop = 0ul; loop < CY_MCWDT_NUM_OF_SUBCOUNTER; loop++)
{
base->CTR[loop].unCTL.u32Register = 0ul;
}
base->unCTR2_CTL.u32Register = 0ul;
for(uint32_t loop = 0ul; loop < CY_MCWDT_NUM_OF_SUBCOUNTER; loop++)
{
while(base->CTR[loop].unCTL.u32Register != 0x0ul); // wait until enabled bit become 1
base->CTR[loop].unLOWER_LIMIT.u32Register = 0x0ul;
base->CTR[loop].unUPPER_LIMIT.u32Register = 0x0ul;
base->CTR[loop].unWARN_LIMIT.u32Register = 0x0ul;
base->CTR[loop].unCONFIG.u32Register = 0x0ul;
base->CTR[loop].unCNT.u32Register = 0x0ul;
}
while(base->unCTR2_CNT.u32Register != 0ul); // wait until enabled bit become 1
base->unCPU_SELECT.u32Register = 0ul;
base->unCTR2_CONFIG.u32Register = 0ul;
base->unSERVICE.u32Register = 0x00000003ul;
base->unINTR.u32Register = 0xFFFFFFFFul;
base->unINTR_MASK.u32Register = 0ul;
Cy_MCWDT_Lock(base);
}
/*******************************************************************************
* Function Name: Cy_MCWDT_ClearWatchdog
****************************************************************************//**
*
* Clears the MC watchdog counter, to prevent a XRES device reset or fault.
*
* \param base
* The base pointer to a structure that describes the registers.
*
* \param counter
* The number of the MCWDT counter. The valid range is [0-1].
*
*******************************************************************************/
void Cy_MCWDT_ClearWatchdog(volatile stc_MCWDT_t *base, cy_en_mcwdtctr_t counter)
{
Cy_MCWDT_Unlock(base);
Cy_MCWDT_ResetCounters(base, (1u << (uint8_t)counter), 0u);
Cy_MCWDT_Lock(base);
}
#if defined(__cplusplus)
}
#endif
/* [] END OF FILE */
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,301 @@
/***************************************************************************//**
* \file cy_mpu.c
* \version 1.0
*
* Provides the API definitions of the Cortex-M MPU driver.
*
********************************************************************************
* \copyright
* Copyright 2016, Cypress Semiconductor Corporation. All rights reserved.
* You may use this file only in accordance with the license, terms, conditions,
* disclaimers, and limitations in the end user license agreement accompanying
* the software package with which this file was provided.
*******************************************************************************/
#include "mpu/cy_mpu.h"
#include "cy_device_headers.h"
/*******************************************************************************
* Function Name: Cy_MPU_Setup
****************************************************************************//**
*
* This function setups Core MPU region and enables the MPU.
*
* \param cfg : Array of settings for each MPU region.
* \ref cy_stc_mpu_region_cfg_t
* \param cfgSize: Length of 'cfg' array. If this value is larger than
* maximum value of implemented MPU region. this function
* will return immediately.
* \param privDefMapEn : \ref cy_en_mpu_privdefena_t
* \param faultNmiEn : \ref cy_en_mpu_hfnmiena_t
*
* \return \cy_en_mpu_status_t
*
*******************************************************************************/
cy_en_mpu_status_t Cy_MPU_Setup(const cy_stc_mpu_region_cfg_t cfg[], uint8_t cfgSize, cy_en_mpu_privdefena_t privDefMapEn, cy_en_mpu_hfnmiena_t faultNmiEn)
{
// Check if MPU is implemented or not
if (MPU->TYPE == 0ul)
{
// MPU is not implemented
return CY_MPU_FAILURE;
}
// Check for NULL ptr
if (cfg == NULL)
{
return CY_MPU_FAILURE;
}
// Check if input configuration array number is not larger than MPU region implemented
if(cfgSize > CY_MPU_MAX_NUM)
{
// input parameter invalid
return CY_MPU_FAILURE;
}
// Ensure all memory accesses are completed before new memory access is committed
__DMB();
// Disable the MPU
MPU->CTRL = 0ul;
uint32_t i_mpuRegionNo;
for(i_mpuRegionNo = 0ul; i_mpuRegionNo < CY_MPU_MAX_NUM; i_mpuRegionNo++)
{
// Select which MPU region to configure
MPU->RNR = i_mpuRegionNo;
if(i_mpuRegionNo < cfgSize)
{
// Configure region base address register
// VALID and REGION field of RBAR register will be 0 since this function sets RNR register manually.
MPU->RBAR = (cfg[i_mpuRegionNo].addr & MPU_RBAR_ADDR_Msk);
uint32_t srd;
if(cfg[i_mpuRegionNo].size < CY_MPU_SIZE_256B)
{
srd = 0ul;
}
else
{
srd = (cfg[i_mpuRegionNo].srd << MPU_RASR_SRD_Pos);
}
// Configure region attribute and size register
MPU->RASR = ((uint32_t)cfg[i_mpuRegionNo].size |
(uint32_t)cfg[i_mpuRegionNo].permission |
(uint32_t)cfg[i_mpuRegionNo].attribute |
(uint32_t)cfg[i_mpuRegionNo].execute |
srd |
(uint32_t)cfg[i_mpuRegionNo].enable);
}
else // Disables unused regions
{
// Configure region base address register
MPU->RBAR = 0ul;
// Configure region attribute and size register
MPU->RASR = 0ul;
}
}
// Enable the MPU
MPU->CTRL = ((uint32_t)privDefMapEn | (uint32_t)faultNmiEn | MPU_CTRL_ENABLE_Msk);
// Ensure all memory accesses are completed before next instruction is executed
__DSB();
// Flush the pipeline and ensure all previous instructions are completed before executing new instructions
__ISB();
return CY_MPU_SUCCESS;
}
/*******************************************************************************
* Function Name: Cy_MPU_SetRegion
****************************************************************************//**
*
* This function sets a single region.
* Enabling/Disabling of MPU would need to be done by user
*
* \param cfg : Settings for MPU region.
* \ref cy_stc_mpu_region_cfg_t
* \param regionNr: Region number to be configured
*
* \return \cy_en_mpu_status_t
*
*******************************************************************************/
cy_en_mpu_status_t Cy_MPU_SetRegion(const cy_stc_mpu_region_cfg_t * cfg, uint8_t regionNr)
{
// Check if MPU is implemented or not
if (MPU->TYPE == 0ul)
{
// MPU is not implemented
return CY_MPU_FAILURE;
}
// Check for NULL ptr
if (cfg == NULL)
{
return CY_MPU_FAILURE;
}
// Check if region number is not larger than MPU region implemented
if(regionNr > CY_MPU_MAX_NUM)
{
// input parameter invalid
return CY_MPU_FAILURE;
}
// Ensure all memory accesses are completed before new memory access is committed
__DMB();
// Select which MPU region to configure
MPU->RNR = regionNr;
// Configure region base address register
// VALID and REGION field of RBAR register will be 0 since this function sets RNR register manually.
MPU->RBAR = (cfg->addr & MPU_RBAR_ADDR_Msk);
uint32_t srd;
if(cfg->size < CY_MPU_SIZE_256B)
{
srd = 0ul;
}
else
{
srd = (cfg->srd << MPU_RASR_SRD_Pos);
}
// Configure region attribute and size register
MPU->RASR = ((uint32_t)cfg->size |
(uint32_t)cfg->permission |
(uint32_t)cfg->attribute |
(uint32_t)cfg->execute |
srd |
(uint32_t)cfg->enable);
// Ensure all memory accesses are completed before next instruction is executed
__DSB();
// Flush the pipeline and ensure all previous instructions are completed before executing new instructions
__ISB();
return CY_MPU_SUCCESS;
}
/*******************************************************************************
* Function Name: Cy_MPU_GetRegion
****************************************************************************//**
*
* This function gets the settings of a single region.
*
* \param cfg : Settings of the selected MPU region.
* \ref cy_stc_mpu_region_cfg_t
* \param regionNr: Region number for which the settings shall be retrieved
*
* \return \cy_en_mpu_status_t
*
*******************************************************************************/
cy_en_mpu_status_t Cy_MPU_GetRegion(cy_stc_mpu_region_cfg_t * cfg, uint8_t regionNr)
{
// Check if MPU is implemented or not
if (MPU->TYPE == 0ul)
{
// MPU is not implemented
return CY_MPU_FAILURE;
}
// Check for NULL ptr
if (cfg == NULL)
{
return CY_MPU_FAILURE;
}
// Check if region number is not larger than MPU region implemented
if(regionNr > CY_MPU_MAX_NUM)
{
// input parameter invalid
return CY_MPU_FAILURE;
}
// Select which MPU region to configure
MPU->RNR = regionNr;
// Configure region base address register
// VALID and REGION field of RBAR register will be 0 since this function sets RNR register manually.
cfg->addr = MPU->RBAR & MPU_RBAR_ADDR_Msk;
uint32_t rasr = MPU->RASR;
cfg->srd = (uint8_t) ((rasr & MPU_RASR_SRD_Msk) >> MPU_RASR_SRD_Pos);
cfg->size = (cy_en_mpu_region_size_t) (rasr & MPU_RASR_SIZE_Msk);
cfg->permission = (cy_en_mpu_access_p_t) (rasr & MPU_RASR_AP_Msk);
cfg->attribute = (cy_en_mpu_attr_t) (rasr & (MPU_RASR_TEX_Msk | MPU_RASR_B_Msk | MPU_RASR_C_Msk | MPU_RASR_S_Msk));
cfg->execute = (cy_en_mpu_execute_n_t) (rasr & MPU_RASR_XN_Msk);
cfg->enable = (cy_en_mpu_region_en_t) (rasr & MPU_RASR_ENABLE_Msk);
return CY_MPU_SUCCESS;
}
void Cy_MPU_Enable(void)
{
// Ensure all memory accesses are completed before new memory access is committed
__DSB();
// Enable the MPU
MPU->CTRL |= MPU_CTRL_ENABLE_Msk;
// Ensure all memory accesses are completed before next instruction is executed
__DSB();
// Flush the pipeline and ensure all previous instructions are completed before executing new instructions
__ISB();
}
void Cy_MPU_Disable(void)
{
// Ensure all memory accesses are completed before new memory access is committed
__DSB();
// Disable the MPU
MPU->CTRL &= (~MPU_CTRL_ENABLE_Msk);
// Ensure all memory accesses are completed before next instruction is executed
__DSB();
// Flush the pipeline and ensure all previous instructions are completed before executing new instructions
__ISB();
}
void Cy_MPU_GetGlobalControlBits(cy_stc_mpu_global_ctrl_bits_t * mpuGlobalCtrl)
{
uint32_t mpuCtrl = MPU->CTRL;
mpuGlobalCtrl->privDefMapEn = (cy_en_mpu_privdefena_t)(mpuCtrl & MPU_CTRL_PRIVDEFENA_Msk);
mpuGlobalCtrl->faultNmiEn = (cy_en_mpu_hfnmiena_t) (mpuCtrl & MPU_CTRL_HFNMIENA_Msk);
mpuGlobalCtrl->mpuGlobalEnable = (cy_en_mpu_global_en_t) (mpuCtrl & MPU_CTRL_ENABLE_Msk);
}
void Cy_MPU_SetGlobalControlBits(const cy_stc_mpu_global_ctrl_bits_t * mpuGlobalCtrl)
{
// Ensure all memory accesses are completed before new memory access is committed
__DSB();
// Set the MPU global control bits
MPU->CTRL = (uint32_t)mpuGlobalCtrl->mpuGlobalEnable | (uint32_t)mpuGlobalCtrl->privDefMapEn | (uint32_t)mpuGlobalCtrl->faultNmiEn;
// Ensure all memory accesses are completed before next instruction is executed
__DSB();
// Flush the pipeline and ensure all previous instructions are completed before executing new instructions
__ISB();
}
/* [] END OF FILE */
@@ -0,0 +1,252 @@
/***************************************************************************//**
* \file cy_mpu.h
* \version `$CY_MAJOR_VERSION`.`$CY_MINOR_VERSION`
* \platform Microcontroller family or derivative or all platforms
* \brief Provides an API declaration of the Cortex-M MPU driver
*
*******************************************************************************/
/*******************************************************************************
* Copyright 2017, Cypress Semiconductor Corporation. All Rights Reserved.
********************************************************************************
* This software is owned by Cypress Semiconductor Corporation (Cypress)
* and is protected by and subject to worldwide patent protection (United
* States and foreign), United States copyright laws and international treaty
* provisions. Cypress hereby grants to licensee a personal, non-exclusive,
* non-transferable license to copy, use, modify, create derivative works of,
* and compile the Cypress Source Code and derivative works for the sole
* purpose of creating custom software in support of licensee product to be
* used only in conjunction with a Cypress integrated circuit as specified in
* the applicable agreement. Any reproduction, modification, translation,
* compilation, or representation of this software except as specified above
* is prohibited without the express written permission of Cypress.
*
* Disclaimer: CYPRESS MAKES NO WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, WITH
* REGARD TO THIS MATERIAL, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
* Cypress reserves the right to make changes without further notice to the
* materials described herein. Cypress does not assume any liability arising out
* of the application or use of any product or circuit described herein. Cypress
* does not authorize its products for use as critical components in life-support
* systems where a malfunction or failure may reasonably be expected to result in
* significant injury to the user. The inclusion of Cypress' product in a life-
* support systems application implies that the manufacturer assumes all risk of
* such use and in doing so indemnifies Cypress against all charges.
*
* Use of this Software may be limited by and subject to the applicable Cypress
* software license agreement.
*******************************************************************************/
/******************************************************************************/
/* Version History: */
/******************************************************************************/
/* $Log:$ 2019-07-27 YOTS Setup and disable functions are available. */
#ifndef _CY_MPU_H_
#define _CY_MPU_H_
#include <stdint.h>
#include <stdbool.h>
#include "cy_device_headers.h"
#include "syslib/cy_syslib.h"
#ifdef __cplusplus
extern "C" {
#endif
#define CY_MPU_MAX_NUM ((MPU->TYPE & MPU_TYPE_DREGION_Msk) >> MPU_TYPE_DREGION_Pos)
/** Specifies region size of the MPU region */
typedef enum
{
#if (~CY_CPU_CORTEX_M0P)
CY_MPU_SIZE_32B = (0x04ul << MPU_RASR_SIZE_Pos), /**< 32 Byte (Only for M4/M7) */
CY_MPU_SIZE_64B = (0x05ul << MPU_RASR_SIZE_Pos), /**< 64 Byte (Only for M4/M7) */
CY_MPU_SIZE_128B = (0x06ul << MPU_RASR_SIZE_Pos), /**< 128 Byte (Only for M4/M7) */
#endif
CY_MPU_SIZE_256B = (0x07ul << MPU_RASR_SIZE_Pos), /**< 256 Byte */
CY_MPU_SIZE_512B = (0x08ul << MPU_RASR_SIZE_Pos), /**< 512 Byte */
CY_MPU_SIZE_1KB = (0x09ul << MPU_RASR_SIZE_Pos), /**< 1K Byte */
CY_MPU_SIZE_2KB = (0x0Aul << MPU_RASR_SIZE_Pos), /**< 2K Byte */
CY_MPU_SIZE_4KB = (0x0Bul << MPU_RASR_SIZE_Pos), /**< 4K Byte */
CY_MPU_SIZE_8KB = (0x0Cul << MPU_RASR_SIZE_Pos), /**< 8K Byte */
CY_MPU_SIZE_16KB = (0x0Dul << MPU_RASR_SIZE_Pos), /**< 16K Byte */
CY_MPU_SIZE_32KB = (0x0Eul << MPU_RASR_SIZE_Pos), /**< 32K Byte */
CY_MPU_SIZE_64KB = (0x0Ful << MPU_RASR_SIZE_Pos), /**< 64K Byte */
CY_MPU_SIZE_128KB = (0x10ul << MPU_RASR_SIZE_Pos), /**< 128K Byte */
CY_MPU_SIZE_256KB = (0x11ul << MPU_RASR_SIZE_Pos), /**< 256K Byte */
CY_MPU_SIZE_512KB = (0x12ul << MPU_RASR_SIZE_Pos), /**< 512K Byte */
CY_MPU_SIZE_1MB = (0x13ul << MPU_RASR_SIZE_Pos), /**< 1M Byte */
CY_MPU_SIZE_2MB = (0x14ul << MPU_RASR_SIZE_Pos), /**< 2M Byte */
CY_MPU_SIZE_4MB = (0x15ul << MPU_RASR_SIZE_Pos), /**< 4M Byte */
CY_MPU_SIZE_8MB = (0x16ul << MPU_RASR_SIZE_Pos), /**< 8M Byte */
CY_MPU_SIZE_16MB = (0x17ul << MPU_RASR_SIZE_Pos), /**< 16M Byte */
CY_MPU_SIZE_32MB = (0x18ul << MPU_RASR_SIZE_Pos), /**< 32M Byte */
CY_MPU_SIZE_64MB = (0x19ul << MPU_RASR_SIZE_Pos), /**< 64M Byte */
CY_MPU_SIZE_128MB = (0x1Aul << MPU_RASR_SIZE_Pos), /**< 128M Byte */
CY_MPU_SIZE_256MB = (0x1Bul << MPU_RASR_SIZE_Pos), /**< 256M Byte */
CY_MPU_SIZE_512MB = (0x1Cul << MPU_RASR_SIZE_Pos), /**< 512M Byte */
CY_MPU_SIZE_1GB = (0x1Dul << MPU_RASR_SIZE_Pos), /**< 1G Byte */
CY_MPU_SIZE_2GB = (0x1Eul << MPU_RASR_SIZE_Pos), /**< 2G Byte */
CY_MPU_SIZE_4GB = (0x1Ful << MPU_RASR_SIZE_Pos), /**< 4G Byte */
} cy_en_mpu_region_size_t;
/** Specifies access permission of the MPU region */
typedef enum
{
CY_MPU_ACCESS_P_NO_ACCESS = (0x0ul << MPU_RASR_AP_Pos), /**< All accesses generate a permission fault */
CY_MPU_ACCESS_P_PRIV_RW = (0x1ul << MPU_RASR_AP_Pos), /**< Access from privileged software only */
CY_MPU_ACCESS_P_PRIV_RW_USER_RO = (0x2ul << MPU_RASR_AP_Pos), /**< Writes by unprivileged software generate a permission fault */
CY_MPU_ACCESS_P_FULL_ACCESS = (0x3ul << MPU_RASR_AP_Pos), /**< Full access */
CY_MPU_ACCESS_P_PRIV_RO = (0x5ul << MPU_RASR_AP_Pos), /**< Reads by privileged software only */
CY_MPU_ACCESS_P_RO = (0x6ul << MPU_RASR_AP_Pos), /**< Read only, by privileged or unprivileged software */
} cy_en_mpu_access_p_t;
/** Specifies attribute of the MPU region */
typedef enum
{
CY_MPU_ATTR_STR_ORD_DEV = ((0x0ul << MPU_RASR_TEX_Pos) ), /**< Strongly-ordered, shareable. */
CY_MPU_ATTR_SHR_DEV = ((0x0ul << MPU_RASR_TEX_Pos) | MPU_RASR_B_Msk ), /**< Device, shareable. */
CY_MPU_ATTR_NORM_MEM_WT = ((0x0ul << MPU_RASR_TEX_Pos) | MPU_RASR_C_Msk ), /**< Normal, Not shareable, Outer and inner write-through. No write allocate. */
CY_MPU_ATTR_NORM_SHR_MEM_WT = ((0x0ul << MPU_RASR_TEX_Pos) | MPU_RASR_C_Msk | MPU_RASR_S_Msk), /**< Normal, shareable, Outer and inner write-through. No write allocate. */
CY_MPU_ATTR_NORM_MEM_WB = ((0x0ul << MPU_RASR_TEX_Pos) | MPU_RASR_C_Msk | MPU_RASR_B_Msk ), /**< Normal, Not shareable, Outer and inner write-back. No write allocate. */
CY_MPU_ATTR_NORM_SHR_MEM_WB = ((0x0ul << MPU_RASR_TEX_Pos) | MPU_RASR_C_Msk | MPU_RASR_B_Msk | MPU_RASR_S_Msk), /**< Normal, shareable, Outer and inner write-back. No write allocate. */
CY_MPU_ATTR_NORM_MEM_NC = ((0x1ul << MPU_RASR_TEX_Pos) ), /**< Normal, Not shareable, Outer and inner non-cacheable. */
CY_MPU_ATTR_NORM_SHR_MEM_NC = ((0x1ul << MPU_RASR_TEX_Pos) | MPU_RASR_S_Msk), /**< Normal, shareable, Outer and inner non-cacheable. */
CY_MPU_ATTR_NORM_MEM_WA = ((0x1ul << MPU_RASR_TEX_Pos) | MPU_RASR_C_Msk | MPU_RASR_B_Msk ), /**< Normal, Not shareable, Outer and inner Write-Back. Write and read allocate */
CY_MPU_ATTR_NORM_SHR_MEM_WA = ((0x1ul << MPU_RASR_TEX_Pos) | MPU_RASR_C_Msk | MPU_RASR_B_Msk | MPU_RASR_S_Msk), /**< Normal, shareable, Outer and inner Write-Back. Write and read allocate */
CY_MPU_ATTR_DEV = ((0x2ul << MPU_RASR_TEX_Pos) ), /**< Device, Not-shareable, */
// Attribute for different policy for outer and inter cache.
CY_MPU_ATTR_NORM_MEM_IN_NC_OUT_NC = ((0x4ul << MPU_RASR_TEX_Pos) ), /**< Normal, Not-shareable. inner policy: Non-cachealbe, outer policy: Non-cacheable */
CY_MPU_ATTR_NORM_MEM_IN_WA_OUT_NC = ((0x4ul << MPU_RASR_TEX_Pos) | MPU_RASR_B_Msk ), /**< Normal, Not-shareable. inner policy: Write back, write and read-Allocate outer policy: Non-cacheable */
CY_MPU_ATTR_NORM_MEM_IN_WT_OUT_NC = ((0x4ul << MPU_RASR_TEX_Pos) | MPU_RASR_C_Msk ), /**< Normal, Not-shareable. inner policy: Write through, no Write-Allocate, outer policy: Non-cacheable */
CY_MPU_ATTR_NORM_MEM_IN_WB_OUT_NC = ((0x4ul << MPU_RASR_TEX_Pos) | MPU_RASR_C_Msk | MPU_RASR_B_Msk ), /**< Normal, Not-shareable. inner policy: Write back, no Write-Allocate, outer policy: Non-cacheable */
CY_MPU_ATTR_NORM_SHR_MEM_IN_NC_OUT_NC = ((0x4ul << MPU_RASR_TEX_Pos) | MPU_RASR_S_Msk), /**< Normal, shareable. inner policy: Non-cachealbe, outer policy: Non-cacheable */
CY_MPU_ATTR_NORM_SHR_MEM_IN_WA_OUT_NC = ((0x4ul << MPU_RASR_TEX_Pos) | MPU_RASR_B_Msk | MPU_RASR_S_Msk), /**< Normal, shareable. inner policy: Write back, write and read-Allocate outer policy: Non-cacheable */
CY_MPU_ATTR_NORM_SHR_MEM_IN_WT_OUT_NC = ((0x4ul << MPU_RASR_TEX_Pos) | MPU_RASR_C_Msk | MPU_RASR_S_Msk), /**< Normal, shareable. inner policy: Write through, no Write-Allocate, outer policy: Non-cacheable */
CY_MPU_ATTR_NORM_SHR_MEM_IN_WB_OUT_NC = ((0x4ul << MPU_RASR_TEX_Pos) | MPU_RASR_C_Msk | MPU_RASR_B_Msk | MPU_RASR_S_Msk), /**< Normal, shareable. inner policy: Write back, no Write-Allocate, outer policy: Non-cacheable */
CY_MPU_ATTR_NORM_MEM_IN_NC_OUT_WA = ((0x5ul << MPU_RASR_TEX_Pos) ), /**< Normal, Not-shareable. inner policy: Non-cachealbe, outer policy: Write back, write and read-Allocate */
CY_MPU_ATTR_NORM_MEM_IN_WA_OUT_WA = ((0x5ul << MPU_RASR_TEX_Pos) | MPU_RASR_B_Msk ), /**< Normal, Not-shareable. inner policy: Write back, write and read-Allocate outer policy: Write back, write and read-Allocate */
CY_MPU_ATTR_NORM_MEM_IN_WT_OUT_WA = ((0x5ul << MPU_RASR_TEX_Pos) | MPU_RASR_C_Msk ), /**< Normal, Not-shareable. inner policy: Write through, no Write-Allocate, outer policy: Write back, write and read-Allocate */
CY_MPU_ATTR_NORM_MEM_IN_WB_OUT_WA = ((0x5ul << MPU_RASR_TEX_Pos) | MPU_RASR_C_Msk | MPU_RASR_B_Msk ), /**< Normal, Not-shareable. inner policy: Write back, no Write-Allocate, outer policy: Write back, write and read-Allocate */
CY_MPU_ATTR_NORM_SHR_MEM_IN_NC_OUT_WA = ((0x5ul << MPU_RASR_TEX_Pos) | MPU_RASR_S_Msk), /**< Normal, shareable. inner policy: Non-cachealbe, outer policy: Write back, write and read-Allocate */
CY_MPU_ATTR_NORM_SHR_MEM_IN_WA_OUT_WA = ((0x5ul << MPU_RASR_TEX_Pos) | MPU_RASR_B_Msk | MPU_RASR_S_Msk), /**< Normal, shareable. inner policy: Write back, write and read-Allocate outer policy: Write back, write and read-Allocate */
CY_MPU_ATTR_NORM_SHR_MEM_IN_WT_OUT_WA = ((0x5ul << MPU_RASR_TEX_Pos) | MPU_RASR_C_Msk | MPU_RASR_S_Msk), /**< Normal, shareable. inner policy: Write through, no Write-Allocate, outer policy: Write back, write and read-Allocate */
CY_MPU_ATTR_NORM_SHR_MEM_IN_WB_OUT_WA = ((0x5ul << MPU_RASR_TEX_Pos) | MPU_RASR_C_Msk | MPU_RASR_B_Msk | MPU_RASR_S_Msk), /**< Normal, shareable. inner policy: Write back, no Write-Allocate, outer policy: Write back, write and read-Allocate */
CY_MPU_ATTR_NORM_MEM_IN_NC_OUT_WT = ((0x6ul << MPU_RASR_TEX_Pos) ), /**< Normal, Not-shareable. inner policy: Non-cachealbe, outer policy: Write through, no Write-Allocate */
CY_MPU_ATTR_NORM_MEM_IN_WA_OUT_WT = ((0x6ul << MPU_RASR_TEX_Pos) | MPU_RASR_B_Msk ), /**< Normal, Not-shareable. inner policy: Write back, write and read-Allocate outer policy: Write through, no Write-Allocate */
CY_MPU_ATTR_NORM_MEM_IN_WT_OUT_WT = ((0x6ul << MPU_RASR_TEX_Pos) | MPU_RASR_C_Msk ), /**< Normal, Not-shareable. inner policy: Write through, no Write-Allocate, outer policy: Write through, no Write-Allocate */
CY_MPU_ATTR_NORM_MEM_IN_WB_OUT_WT = ((0x6ul << MPU_RASR_TEX_Pos) | MPU_RASR_C_Msk | MPU_RASR_B_Msk ), /**< Normal, Not-shareable. inner policy: Write back, no Write-Allocate, outer policy: Write through, no Write-Allocate */
CY_MPU_ATTR_NORM_SHR_MEM_IN_NC_OUT_WT = ((0x6ul << MPU_RASR_TEX_Pos) | MPU_RASR_S_Msk), /**< Normal, shareable. inner policy: Non-cachealbe, outer policy: Write through, no Write-Allocate */
CY_MPU_ATTR_NORM_SHR_MEM_IN_WA_OUT_WT = ((0x6ul << MPU_RASR_TEX_Pos) | MPU_RASR_B_Msk | MPU_RASR_S_Msk), /**< Normal, shareable. inner policy: Write back, write and read-Allocate outer policy: Write through, no Write-Allocate */
CY_MPU_ATTR_NORM_SHR_MEM_IN_WT_OUT_WT = ((0x6ul << MPU_RASR_TEX_Pos) | MPU_RASR_C_Msk | MPU_RASR_S_Msk), /**< Normal, shareable. inner policy: Write through, no Write-Allocate, outer policy: Write through, no Write-Allocate */
CY_MPU_ATTR_NORM_SHR_MEM_IN_WB_OUT_WT = ((0x6ul << MPU_RASR_TEX_Pos) | MPU_RASR_C_Msk | MPU_RASR_B_Msk | MPU_RASR_S_Msk), /**< Normal, shareable. inner policy: Write back, no Write-Allocate, outer policy: Write through, no Write-Allocate */
CY_MPU_ATTR_NORM_MEM_IN_NC_OUT_WB = ((0x7ul << MPU_RASR_TEX_Pos) ), /**< Normal, Not-shareable. inner policy: Non-cachealbe, outer policy: Write back, no Write-Allocate */
CY_MPU_ATTR_NORM_MEM_IN_WA_OUT_WB = ((0x7ul << MPU_RASR_TEX_Pos) | MPU_RASR_B_Msk ), /**< Normal, Not-shareable. inner policy: Write back, write and read-Allocate outer policy: Write back, no Write-Allocate */
CY_MPU_ATTR_NORM_MEM_IN_WT_OUT_WB = ((0x7ul << MPU_RASR_TEX_Pos) | MPU_RASR_C_Msk ), /**< Normal, Not-shareable. inner policy: Write through, no Write-Allocate, outer policy: Write back, no Write-Allocate */
CY_MPU_ATTR_NORM_MEM_IN_WB_OUT_WB = ((0x7ul << MPU_RASR_TEX_Pos) | MPU_RASR_C_Msk | MPU_RASR_B_Msk ), /**< Normal, Not-shareable. inner policy: Write back, no Write-Allocate, outer policy: Write back, no Write-Allocate */
CY_MPU_ATTR_NORM_SHR_MEM_IN_NC_OUT_WB = ((0x7ul << MPU_RASR_TEX_Pos) | MPU_RASR_S_Msk), /**< Normal, shareable. inner policy: Non-cachealbe, outer policy: Write back, no Write-Allocate */
CY_MPU_ATTR_NORM_SHR_MEM_IN_WA_OUT_WB = ((0x7ul << MPU_RASR_TEX_Pos) | MPU_RASR_B_Msk | MPU_RASR_S_Msk), /**< Normal, shareable. inner policy: Write back, write and read-Allocate outer policy: Write back, no Write-Allocate */
CY_MPU_ATTR_NORM_SHR_MEM_IN_WT_OUT_WB = ((0x7ul << MPU_RASR_TEX_Pos) | MPU_RASR_C_Msk | MPU_RASR_S_Msk), /**< Normal, shareable. inner policy: Write through, no Write-Allocate, outer policy: Write back, no Write-Allocate */
CY_MPU_ATTR_NORM_SHR_MEM_IN_WB_OUT_WB = ((0x7ul << MPU_RASR_TEX_Pos) | MPU_RASR_C_Msk | MPU_RASR_B_Msk | MPU_RASR_S_Msk), /**< Normal, shareable. inner policy: Write back, no Write-Allocate, outer policy: Write back, no Write-Allocate */
} cy_en_mpu_attr_t;
/** Specifies enable/disable of instruction access of the MPU region */
typedef enum
{
CY_MPU_INST_ACCESS_EN = (0ul), /**< Instruction fetches enabled */
CY_MPU_INST_ACCESS_DIS = (MPU_RASR_XN_Msk), /**< Instruction fetches disabled */
} cy_en_mpu_execute_n_t;
/** Specifies enable/disable of the MPU region */
typedef enum
{
CY_MPU_DISABLE = (0ul), /**< Disable */
CY_MPU_ENABLE = (MPU_RASR_ENABLE_Msk), /**< Enable */
} cy_en_mpu_region_en_t;
/** Specifies structure of configuration parameter of Cortex-M MPU */
typedef struct
{
uint32_t addr; /**< The base address of the MPU region.
The base address is aligned to the size of the region.
For example, a 64KB region must be aligned on a multiple of 64KB,
for example, at 0x00010000 or 0x00020000. */
cy_en_mpu_region_size_t size; /**< The size of the MPU region \ref cy_en_mpu_region_size_t */
cy_en_mpu_access_p_t permission; /**< The access permission of the MPU region \ref cy_en_mpu_access_p_t */
cy_en_mpu_attr_t attribute; /**< The attribute of the MPU region \ref cy_en_mpu_attr_t */
cy_en_mpu_execute_n_t execute; /**< Instruction access disable/enable select \ref cy_en_mpu_region_xn_t */
uint8_t srd; /**< Subregion disable bits. For each bit in this field.
Regions of 256 bytes or more are divided into eight equal-sized subregions. Set the
corresponding bit in this parameter to disable a subregion.
0: Corresponding sub-region is enabled.
1: Corresponding sub-region is disabled.
If MPU region size is less than 256 byte, this value will be ignored. */
cy_en_mpu_region_en_t enable; /**< enable/disable the MPU region \ref cy_en_mpu_region_en_t */
} cy_stc_mpu_region_cfg_t;
/** Specifies enable/disable privileged software access to the default memory map */
typedef enum
{
CY_MPU_DISABLE_USE_DEFAULT_MAP = (0ul), /**< If the MPU is enabled, disables use of the default memory map.
Any memory access to a location not covered by any enabled
region causes a fault. */
CY_MPU_USE_DEFAULT_MAP_AS_BG = (MPU_CTRL_PRIVDEFENA_Msk), /**< If the MPU is enabled, enables use of the default memory map
as a background region for privileged software accesses. */
} cy_en_mpu_privdefena_t;
/** Specifies enable/disable the operation of MPU during hard fault, NMI, and FAULTMASK handlers. */
typedef enum
{
CY_MPU_DISABLED_DURING_FAULT_NMI = (0ul), /**< MPU is disabled during hard fault, NMI, and FAULTMASK handlers,
regardless of the value of the ENABLE bit. */
CY_MPU_ENABLED_DURING_FAULT_NMI = (MPU_CTRL_HFNMIENA_Msk), /**< The MPU is enabled during hard fault, NMI, and FAULTMASK handlers. */
} cy_en_mpu_hfnmiena_t;
/** Specifies enable/disable of the MPU */
typedef enum
{
CY_MPU_GLOBAL_DISABLE = (0ul), /**< Disable */
CY_MPU_GLOBAL_ENABLE = (MPU_CTRL_ENABLE_Msk), /**< Enable */
} cy_en_mpu_global_en_t;
/** Contains the 3 global MPU control bits */
typedef struct
{
cy_en_mpu_global_en_t mpuGlobalEnable; /**< Global MPU enable */
cy_en_mpu_privdefena_t privDefMapEn; /**< MPU default memory map for privileged accesses enabled */
cy_en_mpu_hfnmiena_t faultNmiEn; /**< MPU enabled or disabled during Hard Faults and NMIs */
} cy_stc_mpu_global_ctrl_bits_t;
/** Specifies status of APIs of this driver */
typedef enum
{
CY_MPU_SUCCESS = 0ul, /**< The API completed in success */
CY_MPU_FAILURE, /**< The API finished in failure */
} cy_en_mpu_status_t;
extern cy_en_mpu_status_t Cy_MPU_Setup(const cy_stc_mpu_region_cfg_t cfg[], uint8_t cfgSize, cy_en_mpu_privdefena_t privDefMapEn, cy_en_mpu_hfnmiena_t faultNmiEn);
extern void Cy_MPU_Enable(void);
extern void Cy_MPU_Disable(void);
extern cy_en_mpu_status_t Cy_MPU_SetRegion(const cy_stc_mpu_region_cfg_t * cfg, uint8_t regionNr);
extern cy_en_mpu_status_t Cy_MPU_GetRegion(cy_stc_mpu_region_cfg_t * cfg, uint8_t regionNr);
extern void Cy_MPU_GetGlobalControlBits(cy_stc_mpu_global_ctrl_bits_t * mpuGlobalCtrl);
extern void Cy_MPU_SetGlobalControlBits(const cy_stc_mpu_global_ctrl_bits_t * mpuGlobalCtrl);
#ifdef __cplusplus
}
#endif
#endif /* _CY_MPU_H_ */
/* [] END OF FILE */
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,567 @@
/***************************************************************************//**
* \file cy_prot.h
* \version 1.0
*
* \brief
* Provides an API declaration of the Protection Unit driver
*
********************************************************************************
* \copyright
* Copyright 2016-2017, Cypress Semiconductor Corporation. All rights reserved.
* You may use this file only in accordance with the license, terms, conditions,
* disclaimers, and limitations in the end user license agreement accompanying
* the software package with which this file was provided.
*******************************************************************************/
/**
* \defgroup group_prot Protection Unit (PROT)
* \{
*
* The Protection Unit driver provides an API to configure the Memory Protection
* Units (MPU), Shared Memory Protection Units (SMPU), and Peripheral Protection
* Units (PPU). These are separate from the ARM Core MPUs and provide additional
* mechanisms for securing resource accesses. The Protection units address the
* following concerns in an embedded design:
* - Security requirements. This includes the prevention of malicious attacks
* to access secure memory or peripherals.
* - Safety requirements. This includes detection of accidental (non-malicious)
* SW errors and random HW errors. It is important to enable failure analysis
* to investigate the root cause of a safety violation.
*
* \n
* <b> Memory Protection </b>
*
* Memory protection is provided by MPUs and SMPUs and allows control of
* memory accesses by bus masters (e.g., CM0+, CM4, Crypto):
* - MPUs are used to distinguish user and privileged accesses from a single bus
* master such as task switching in an OS/kernel. For ARM core MPUs, the
* assigned Cypress MPUs for those cores provide additional functionality
* such as protection contexts (PC) and security attributes.
* - SMPUs are used to distinguish memory accesses between bus masters. This is
* achieved by using protection contexts and secure-/non-secure attributes.
*
* \n
* <b> Peripheral Protection </b>
*
* Peripheral protection is provided by PPUs and allows control of peripheral
* register accesses by bus masters. Four types of PPUs are available.
* - Programmable (PROG) PPUs are used to protect any peripheral memory region
* in a device from invalid bus master accesses. It is the most versatile
* type of peripheral protection unit.
* - Fixed Group (GR) PPUs are used to protect an entire peripheral MMIO group
* from invalid bus master accesses. The MMIO grouping information and which
* resource belongs to which group is device specific and can be obtained
* from the device technical reference manual (TRM).
* - Fixed Region (RG) PPUs are used to protect an entire peripheral slave
* instance from invalid bus master accesses. For example, TCPWM0, TCPWM1,
* SCB0, and SCB1, etc.
* - Fixed Slave (SL) PPUs are used to protect specified regions of peripheral
* instances. For example, individual DW channel structs, SMPU structs, and
* IPC structs, etc.
*
* \n
* <b> External Memory Protection </b>
*
* The External (SDRAM) Memory Protection Unit (EMPU) guards the external LPDDR4
* SDRAM against unauthorized accesses via the AXI ports. As the external SDRAM
* can only be accessed via the AXI ports, there is no need for protecting the
* SDRAM against accesses via the AHB port.
* - The functionality and register model are based on the Shared Memory
* Protection Unit (SMPU).
* - Unauthorized accesses cause a bus error and are reported as a fault.
*
* \n
* <b> Driver Usage </b>
*
* Each protection unit is distinguished by its type (e.g.
* stc_PROT_MPU_MPU_STRUCT_t). The list of supported protection units can be
* obtained from the device header file. Choose a protection unit of interest,
* and call its corresponding Cy_Prot_Config<X>Struct() function with its
* software protection unit configuration structure populated. Then enable the
* protection unit by calling the Cy_Prot_Enable<X>Struct() function.
*
* Each bus master can be configured to allow/disallow certain types of accesses
* by calling the Cy_Prot_ConfigBusMaster() function. For example, CM0+ core
* is a bus master. By configuring it to allow only protection contexts (PC)
* 2 and 3, the bus master will be able to set its protection context only to
* 2 or 3. In a thread execution, the CM0+ core can set its protection context
* to 2 by calling Cy_Prot_SetActivePC() and access all regions of memory that
* allow PC=2. A fault will be triggered if a resource is protected with different
* protection settings.
*
* \section group_prot_configuration Configuration Considerations
*
* With the exception of MPUs, Protection structures are implemented in
* hardware as master and slave pairs. The master protection structure protects
* the slave protection structure. The slave protection structure protects the
* memory region that is to be protected.
* For example, a slave protection structure is configured to allow protection
* contexts 3 and 4 to access a set of peripheral registers. The corresponding
* master protection structure can then be used to protect the slave structure
* configuration and allow only protection context 1 to make modifications.
* Any bus master attempting to change the slave protection structure must then
* have a protection context 1. Otherwise an access fault will occur.
*
* \section group_prot_more_information More Information
*
* Refer to Technical Reference Manual (TRM) and the device datasheet.
*
* \section group_prot_changelog Changelog
* <table class="doxtable">
* <tr><th>Version</th><th>Changes</th><th>Reason for Change</th></tr>
* <tr>
* <td>1.0</td>
* <td>Initial version</td>
* <td></td>
* </tr>
* <tr>
* <td>1.1</td>
* <td>Remove old commented code</td>
* <td>Added ISB instruction after enable/disable SMPU structure</td>
* <td></td>
* </tr>
* <tr>
* <td>1.2</td>
* <td>Remove pc_save accessing code</td>
* <td></td>
* </tr>
* <tr>
* <td>1.3</td>
* <td>Added comments for cy_en_prot_pc_t</td>
* <td></td>
* </tr>
* <tr>
* <td>1.4</td>
* <td>Added functions and code for empu</td>
* <td></td>
* </tr>
* </table>
*
* \defgroup group_prot_macro Macro
* \defgroup group_prot_functions Functions
* \{
* \defgroup group_prot_functions_busmaster Bus Master and PC Functions
* \defgroup group_prot_functions_mpu MPU Functions
* \defgroup group_prot_functions_smpu SMPU Functions
* \defgroup group_prot_functions_ppu_prog PPU Programmable (PROG) Functions
* \defgroup group_prot_functions_ppu_gr PPU Group (GR) Functions
* \defgroup group_prot_functions_ppu_sl PPU Slave (SL) Functions
* \defgroup group_prot_functions_ppu_rg PPU Region (RG) Functions
* \defgroup group_prot_functions_empu EMPU Functions
* \}
* \defgroup group_prot_data_structures Data structures
* \defgroup group_prot_enums Enumerated types
*/
#if !defined(__CY_PROT_H__)
#define __CY_PROT_H__
#include <stdbool.h>
#include "syslib/cy_syslib.h"
#include "cy_device_headers.h"
#if defined(__cplusplus)
extern "C" {
#endif
/** \addtogroup group_prot_macro
* \{
*/
/** Driver major version */
#define CY_PROT_DRV_VERSION_MAJOR 1
/** Driver minor version */
#define CY_PROT_DRV_VERSION_MINOR 0
/** Prot driver ID */
#define CY_PROT_ID CY_PDL_DRV_ID(0x30u)
/** \} group_prot_macro */
/**
* \addtogroup group_prot_enums
* \{
*/
/**
* Prot Driver error codes
*/
typedef enum
{
CY_PROT_SUCCESS = 0x00u, /**< Returned successful */
CY_PROT_BAD_PARAM = CY_PROT_ID | CY_PDL_STATUS_ERROR | 0x01u, /**< Bad parameter was passed */
CY_PROT_FAILURE = CY_PROT_ID | CY_PDL_STATUS_ERROR | 0x03u /**< The resource is locked */
} cy_en_prot_status_t;
/**
* User/Privileged permission
*/
typedef enum
{
CY_PROT_PERM_DISABLED = 0x00u, /**< Read, Write and Execute disabled */
CY_PROT_PERM_R = 0x01u, /**< Read enabled */
CY_PROT_PERM_W = 0x02u, /**< Write enabled */
CY_PROT_PERM_RW = 0x03u, /**< Read and Write enabled */
CY_PROT_PERM_X = 0x04u, /**< Execute enabled */
CY_PROT_PERM_RX = 0x05u, /**< Read and Execute enabled */
CY_PROT_PERM_WX = 0x06u, /**< Write and Execute enabled */
CY_PROT_PERM_RWX = 0x07u /**< Read, Write and Execute enabled */
}cy_en_prot_perm_t;
/**
* Memory region size
*/
typedef enum
{
CY_PROT_SIZE_4B = 1u, /**< 4 bytes */
CY_PROT_SIZE_8B = 2u, /**< 8 bytes */
CY_PROT_SIZE_16B = 3u, /**< 16 bytes */
CY_PROT_SIZE_32B = 4u, /**< 32 bytes */
CY_PROT_SIZE_64B = 5u, /**< 64 bytes */
CY_PROT_SIZE_128B = 6u, /**< 128 bytes */
CY_PROT_SIZE_256B = 7u, /**< 256 bytes */
CY_PROT_SIZE_512B = 8u, /**< 512 bytes */
CY_PROT_SIZE_1KB = 9u, /**< 1 Kilobyte */
CY_PROT_SIZE_2KB = 10u, /**< 2 Kilobytes */
CY_PROT_SIZE_4KB = 11u, /**< 4 Kilobytes */
CY_PROT_SIZE_8KB = 12u, /**< 8 Kilobytes */
CY_PROT_SIZE_16KB = 13u, /**< 16 Kilobytes */
CY_PROT_SIZE_32KB = 14u, /**< 32 Kilobytes */
CY_PROT_SIZE_64KB = 15u, /**< 64 Kilobytes */
CY_PROT_SIZE_128KB = 16u, /**< 128 Kilobytes */
CY_PROT_SIZE_256KB = 17u, /**< 256 Kilobytes */
CY_PROT_SIZE_512KB = 18u, /**< 512 Kilobytes */
CY_PROT_SIZE_1MB = 19u, /**< 1 Megabyte */
CY_PROT_SIZE_2MB = 20u, /**< 2 Megabytes */
CY_PROT_SIZE_4MB = 21u, /**< 4 Megabytes */
CY_PROT_SIZE_8MB = 22u, /**< 8 Megabytes */
CY_PROT_SIZE_16MB = 23u, /**< 16 Megabytes */
CY_PROT_SIZE_32MB = 24u, /**< 32 Megabytes */
CY_PROT_SIZE_64MB = 25u, /**< 64 Megabytes */
CY_PROT_SIZE_128MB = 26u, /**< 128 Megabytes */
CY_PROT_SIZE_256MB = 27u, /**< 256 Megabytes */
CY_PROT_SIZE_512MB = 28u, /**< 512 Megabytes */
CY_PROT_SIZE_1GB = 29u, /**< 1 Gigabyte */
CY_PROT_SIZE_2GB = 30u /**< 2 Gigabytes */
}cy_en_prot_size_t;
/**
* Protection Context (PC)
*/
typedef enum
{
CY_PROT_PC0 = 0u, /**< PC = 0, which cannot be configured */
CY_PROT_PC1 = 1u, /**< PC = 1 */
CY_PROT_PC2 = 2u, /**< PC = 2 */
CY_PROT_PC3 = 3u, /**< PC = 3 */
CY_PROT_PC4 = 4u, /**< PC = 4 */
CY_PROT_PC5 = 5u, /**< PC = 5 */
CY_PROT_PC6 = 6u, /**< PC = 6 */
CY_PROT_PC7 = 7u, /**< PC = 7 */
CY_PROT_PC8 = 8u, /**< PC = 8 */
CY_PROT_PC9 = 9u, /**< PC = 9 */
CY_PROT_PC10 = 10u, /**< PC = 10 */
CY_PROT_PC11 = 11u, /**< PC = 11 */
CY_PROT_PC12 = 12u, /**< PC = 12 */
CY_PROT_PC13 = 13u, /**< PC = 13 */
CY_PROT_PC14 = 14u, /**< PC = 14 */
CY_PROT_PC15 = 15u, /**< PC = 15 */
CY_PROT_PC_NUM
} cy_en_prot_pc_t;
/***************************************
* Constants
***************************************/
/** \cond INTERNAL */
/* Helper function for finding max */
#define CY_PROT_MAX(x,y) (((x)>(y))?(x):(y))
/* General Masks and shifts */
#define CY_PROT_MSX_CTL_SHIFT (0x02UL) /**< Shift for MSx_CTL register */
#define CY_PROT_STRUCT_ENABLE (0x01UL) /**< Enable protection unit struct */
#define CY_PROT_ADDR_SHIFT (8UL) /**< Address shift for MPU, SMPU and PROG PPU structs */
#define CY_PROT_ADDR_SHIFT_PPU (2UL) /**< Address shift for PROG PPU structs */
/* Permission masks and shifts */
#define CY_PROT_ATT_PERMISSION_MASK (0x07UL) /**< Protection Unit attribute permission mask */
#define CY_PROT_ATT_USER_PERMISSION_SHIFT (0x00UL) /**< Protection Unit user attribute permission shift */
#define CY_PROT_ATT_PRIV_PERMISSION_SHIFT (0x03UL) /**< Protection Unit priliged attribute permission shift */
/* Maximum Master Protection Context */
#define CY_PROT_MS_PC_NR_MAX CY_PROT_MAX(CPUSS_PROT_SMPU_MS0_PC_NR_MINUS1, \
CY_PROT_MAX(CPUSS_PROT_SMPU_MS1_PC_NR_MINUS1, \
CY_PROT_MAX(CPUSS_PROT_SMPU_MS2_PC_NR_MINUS1, \
CY_PROT_MAX(CPUSS_PROT_SMPU_MS3_PC_NR_MINUS1, \
CY_PROT_MAX(CPUSS_PROT_SMPU_MS4_PC_NR_MINUS1, \
CY_PROT_MAX(CPUSS_PROT_SMPU_MS5_PC_NR_MINUS1, \
CY_PROT_MAX(CPUSS_PROT_SMPU_MS6_PC_NR_MINUS1, \
CY_PROT_MAX(CPUSS_PROT_SMPU_MS7_PC_NR_MINUS1, \
CY_PROT_MAX(CPUSS_PROT_SMPU_MS8_PC_NR_MINUS1, \
CY_PROT_MAX(CPUSS_PROT_SMPU_MS9_PC_NR_MINUS1, \
CY_PROT_MAX(CPUSS_PROT_SMPU_MS10_PC_NR_MINUS1, \
CY_PROT_MAX(CPUSS_PROT_SMPU_MS11_PC_NR_MINUS1, \
CY_PROT_MAX(CPUSS_PROT_SMPU_MS12_PC_NR_MINUS1, \
CY_PROT_MAX(CPUSS_PROT_SMPU_MS13_PC_NR_MINUS1, \
CY_PROT_MAX(CPUSS_PROT_SMPU_MS14_PC_NR_MINUS1, \
CPUSS_PROT_SMPU_MS15_PC_NR_MINUS1)))))))))))))))
/* Protection Context limit masks */
#define CY_PROT_MPU_PC_LIMIT_MASK (0xFFFFFFFFUL << CY_PROT_MS_PC_NR_MAX)
#define CY_PROT_SMPU_PC_LIMIT_MASK (0xFFFFFFFFUL << CPUSS_PROT_SMPU_MS15_PC_NR_MINUS1) //RMKN CPUSS_SMPU_STRUCT_PC_NR_MINUS1)
#define CY_PROT_PPU_PROG_PC_LIMIT_MASK (0xFFFFFFFFUL << PERI_PPU_PROG_STRUCT_PC_NR_MINUS1)
#define CY_PROT_PPU_FIXED_PC_LIMIT_MASK (0xFFFFFFFFUL << PERI_PPU_FIXED_STRUCT_PC_NR_MINUS1)
/* Parameter validation masks to check for read-only values */
#define CY_PROT_SMPU_ATT0_MASK ((uint32_t)~(PROT_SMPU_SMPU_STRUCT_ATT0_PC_MASK_0_Msk))
#define CY_PROT_SMPU_ATT1_MASK ((uint32_t)~(PROT_SMPU_SMPU_STRUCT_ATT1_UR_Msk \
| PROT_SMPU_SMPU_STRUCT_ATT1_UX_Msk \
| PROT_SMPU_SMPU_STRUCT_ATT1_PR_Msk \
| PROT_SMPU_SMPU_STRUCT_ATT1_PX_Msk \
| PROT_SMPU_SMPU_STRUCT_ATT1_PC_MASK_0_Msk \
| PROT_SMPU_SMPU_STRUCT_ATT1_REGION_SIZE_Msk \
))
#define CY_PROT_PPU_PROG_ATT0_MASK ((uint32_t)~(PERI_PPU_GR_ATT1_UX_Msk \
| PERI_PPU_GR_ATT1_PX_Msk \
|PERI_PPU_PR_ATT0_PC_MASK_0_Msk \
))
#define CY_PROT_PPU_PROG_ATT1_MASK ((uint32_t)~(PERI_PPU_PR_ATT1_UR_Msk \
| PERI_PPU_PR_ATT1_UX_Msk \
| PERI_PPU_PR_ATT1_PR_Msk \
| PERI_PPU_PR_ATT1_PX_Msk \
| PERI_PPU_PR_ATT1_PC_MASK_0_Msk \
| PERI_PPU_PR_ATT1_REGION_SIZE_Msk \
))
#define CY_PROT_PPU_GR_ATT0_MASK ((uint32_t)~(PERI_PPU_GR_ATT0_UX_Msk \
| PERI_PPU_GR_ATT0_PX_Msk \
| PERI_PPU_GR_ATT0_PC_MASK_0_Msk \
| PERI_PPU_GR_ATT0_REGION_SIZE_Msk \
))
#define CY_PROT_PPU_GR_ATT1_MASK ((uint32_t)~(PERI_PPU_GR_ATT1_UR_Msk \
| PERI_PPU_GR_ATT1_UX_Msk \
| PERI_PPU_GR_ATT1_PR_Msk \
| PERI_PPU_GR_ATT1_PX_Msk \
| PERI_PPU_GR_ATT1_PC_MASK_0_Msk \
| PERI_PPU_GR_ATT1_REGION_SIZE_Msk \
))
#define CY_PROT_PPU_SL_ATT0_MASK ((uint32_t)~(PERI_GR_PPU_SL_ATT0_UX_Msk \
| PERI_GR_PPU_SL_ATT0_PX_Msk \
| PERI_GR_PPU_SL_ATT0_PC_MASK_0_Msk \
| PERI_GR_PPU_SL_ATT0_REGION_SIZE_Msk \
))
#define CY_PROT_PPU_SL_ATT1_MASK ((uint32_t)~(PERI_GR_PPU_SL_ATT1_UR_Msk \
| PERI_GR_PPU_SL_ATT1_UX_Msk \
| PERI_GR_PPU_SL_ATT1_PR_Msk \
| PERI_GR_PPU_SL_ATT1_PX_Msk \
| PERI_GR_PPU_SL_ATT1_PC_MASK_0_Msk \
| PERI_GR_PPU_SL_ATT1_REGION_SIZE_Msk \
))
#define CY_PROT_PPU_RG_ATT0_MASK ((uint32_t)~(PERI_GR_PPU_RG_ATT0_UX_Msk \
| PERI_GR_PPU_RG_ATT0_PX_Msk \
| PERI_GR_PPU_RG_ATT0_PC_MASK_0_Msk \
| PERI_GR_PPU_RG_ATT0_REGION_SIZE_Msk \
))
#define CY_PROT_PPU_RG_ATT1_MASK ((uint32_t)~(PERI_GR_PPU_RG_ATT1_UR_Msk \
| PERI_GR_PPU_RG_ATT1_UX_Msk \
| PERI_GR_PPU_RG_ATT1_PR_Msk \
| PERI_GR_PPU_RG_ATT1_PX_Msk \
| PERI_GR_PPU_RG_ATT1_PC_MASK_0_Msk \
| PERI_GR_PPU_RG_ATT1_REGION_SIZE_Msk \
))
#if defined(LPDDR4_EMPU_EMPU_STRUCT_NR) && (LPDDR4_EMPU_EMPU_STRUCT_NR >= 0)
#define CY_PROT_EMPU_PC_LIMIT_MASK (0xFFFFFFFFUL << LPDDR4_EMPU_STRUCT_PC_NR_MINUS1)
#define CY_PROT_EMPU_ATT0_MASK ((uint32_t)~(LPDDR4_EMPU_EMPU_STRUCT_ATT0_PC_MASK_0_Msk))
#define CY_PROT_EMPU_ATT1_MASK ((uint32_t)~(LPDDR4_EMPU_EMPU_STRUCT_ATT1_UR_Msk \
| LPDDR4_EMPU_EMPU_STRUCT_ATT1_UX_Msk \
| LPDDR4_EMPU_EMPU_STRUCT_ATT1_PR_Msk \
| LPDDR4_EMPU_EMPU_STRUCT_ATT1_PX_Msk \
| LPDDR4_EMPU_EMPU_STRUCT_ATT1_PC_MASK_0_Msk \
| LPDDR4_EMPU_EMPU_STRUCT_ATT1_REGION_SIZE_Msk \
))
#endif
/** \endcond */
/***************************************
* Configuration Structures
***************************************/
/**
* \addtogroup group_prot_data_structures
* \{
*/
/** Configuration structure for MPU Struct initialization */
typedef struct
{
uint32_t* address; /**< Base address of the memory region */
cy_en_prot_size_t regionSize; /**< Size of the memory region */
uint8_t subregions; /**< Mask of the 8 subregions to disable */
cy_en_prot_perm_t userPermission; /**< User permissions for the region */
cy_en_prot_perm_t privPermission; /**< Privileged permissions for the region */
bool secure; /**< Non Secure = 0, Secure = 1 */
} cy_stc_mpu_cfg_t;
/** Configuration structure for SMPU struct initialization */
typedef struct
{
uint32_t* address; /**< Base address of the memory region (Only applicable to slave) */
cy_en_prot_size_t regionSize; /**< Size of the memory region (Only applicable to slave) */
uint8_t subregions; /**< Mask of the 8 subregions to disable (Only applicable to slave) */
cy_en_prot_perm_t userPermission; /**< User permissions for the region */
cy_en_prot_perm_t privPermission; /**< Privileged permissions for the region */
bool secure; /**< Non Secure = 0, Secure = 1 */
bool pcMatch; /**< Access evaluation = 0, Matching = 1 */
uint16_t pcMask; /**< Mask of allowed protection context(s) */
} cy_stc_smpu_cfg_t;
/** Configuration structure for Programmable (PROG) PPU (PPU_PR) struct initialization */
typedef struct
{
uint32_t* address; /**< Base address of the memory region (Only applicable to slave) */
cy_en_prot_size_t regionSize; /**< Size of the memory region (Only applicable to slave) */
} cy_stc_ppu_prog_region_cfg_t;
typedef struct
{
cy_en_prot_perm_t userPermission; /**< User permissions for the region */
cy_en_prot_perm_t privPermission; /**< Privileged permissions for the region */
bool secure; /**< Non Secure = 0, Secure = 1 */
} cy_stc_ppu_prog_attr_cfg_t;
/** Configuration structure for Fixed Group (GR) PPU (PPU_GR) struct initialization */
typedef struct
{
cy_en_prot_perm_t userPermission; /**< User permissions for the region */
cy_en_prot_perm_t privPermission; /**< Privileged permissions for the region */
bool secure; /**< Non Secure = 0, Secure = 1 */
} cy_stc_ppu_gr_cfg_t;
#if defined(LPDDR4_EMPU_EMPU_STRUCT_NR) && (LPDDR4_EMPU_EMPU_STRUCT_NR >= 0)
/** Configuration structure for EMPU struct initialization */
typedef struct
{
uint32_t* address; /**< Base address of the memory region (Only applicable to slave) */
cy_en_prot_size_t regionSize; /**< Size of the memory region (Only applicable to slave) */
uint8_t subregions; /**< Mask of the 8 subregions to disable (Only applicable to slave) */
cy_en_prot_perm_t userPermission; /**< User permissions for the region */
cy_en_prot_perm_t privPermission; /**< Privileged permissions for the region */
bool secure; /**< Non Secure = 0, Secure = 1 */
bool pcMatch; /**< Access evaluation = 0, Matching = 1 */
uint16_t pcMask; /**< Mask of allowed protection context(s) */
} cy_stc_empu_cfg_t;
#endif
/** \} group_prot_data_structures */
/***************************************
* Function Prototypes
***************************************/
/**
* \addtogroup group_prot_functions
* \{
*/
/**
* \addtogroup group_prot_functions_busmaster
* \{
*/
cy_en_prot_status_t Cy_Prot_ConfigBusMaster(en_prot_master_t busMaster, bool privileged, bool secure, uint32_t pcMask);
cy_en_prot_status_t Cy_Prot_SetActivePC(en_prot_master_t busMaster, uint32_t pc);
uint32_t Cy_Prot_GetActivePC(en_prot_master_t busMaster);
/** \} group_prot_functions_busmaster */
/**
* \addtogroup group_prot_functions_mpu
* \{
*/
cy_en_prot_status_t Cy_Prot_ConfigMpuStruct(volatile stc_PROT_MPU_MPU_STRUCT_t* base, const cy_stc_mpu_cfg_t* config);
cy_en_prot_status_t Cy_Prot_EnableMpuStruct(volatile stc_PROT_MPU_MPU_STRUCT_t* base);
cy_en_prot_status_t Cy_Prot_DisableMpuStruct(volatile stc_PROT_MPU_MPU_STRUCT_t* base);
/** \} group_prot_functions_mpu */
/**
* \addtogroup group_prot_functions_smpu
* \{
*/
cy_en_prot_status_t Cy_Prot_ConfigSmpuMasterStruct(volatile stc_PROT_SMPU_SMPU_STRUCT_t* base, const cy_stc_smpu_cfg_t* config);
cy_en_prot_status_t Cy_Prot_ConfigSmpuSlaveStruct(volatile stc_PROT_SMPU_SMPU_STRUCT_t* base, const cy_stc_smpu_cfg_t* config);
cy_en_prot_status_t Cy_Prot_EnableSmpuMasterStruct(volatile stc_PROT_SMPU_SMPU_STRUCT_t* base);
cy_en_prot_status_t Cy_Prot_DisableSmpuMasterStruct(volatile stc_PROT_SMPU_SMPU_STRUCT_t* base);
cy_en_prot_status_t Cy_Prot_EnableSmpuSlaveStruct(volatile stc_PROT_SMPU_SMPU_STRUCT_t* base);
cy_en_prot_status_t Cy_Prot_DisableSmpuSlaveStruct(volatile stc_PROT_SMPU_SMPU_STRUCT_t* base);
/** \} group_prot_functions_smpu */
/**
* \addtogroup group_prot_functions_ppu_prog
* \{
*/
cy_en_prot_status_t Cy_Prot_ConfigPpuProgMasterStructAttr(volatile stc_PERI_MS_PPU_PR_t* base, cy_en_prot_pc_t setPC, const cy_stc_ppu_prog_attr_cfg_t* config);
cy_en_prot_status_t Cy_Prot_ConfigPpuProgSlaveStructAttr(volatile stc_PERI_MS_PPU_PR_t* base, cy_en_prot_pc_t setPC, const cy_stc_ppu_prog_attr_cfg_t* config);
cy_en_prot_status_t Cy_Prot_ConfigPpuProgSlaveStructReg(volatile stc_PERI_MS_PPU_PR_t* base, const cy_stc_ppu_prog_region_cfg_t* config);
cy_en_prot_status_t Cy_Prot_EnablePpuProgMasterStruct(volatile stc_PERI_MS_PPU_PR_t* base);
cy_en_prot_status_t Cy_Prot_DisablePpuProgMasterStruct(volatile stc_PERI_MS_PPU_PR_t* base);
cy_en_prot_status_t Cy_Prot_EnablePpuProgSlaveStruct(volatile stc_PERI_MS_PPU_PR_t* base);
cy_en_prot_status_t Cy_Prot_DisablePpuProgSlaveStruct(volatile stc_PERI_MS_PPU_PR_t* base);
/** \} group_prot_functions_ppu_prog */
/**
* \addtogroup group_prot_functions_ppu_fixed
* \{
*/
cy_en_prot_status_t Cy_Prot_ConfigPpuFixedMasterStruct(volatile stc_PERI_MS_PPU_FX_t* base, cy_en_prot_pc_t setPC, const cy_stc_ppu_gr_cfg_t* config);
cy_en_prot_status_t Cy_Prot_ConfigPpuFixedSlaveStruct(volatile stc_PERI_MS_PPU_FX_t* base, cy_en_prot_pc_t setPC, const cy_stc_ppu_gr_cfg_t* config);
cy_en_prot_status_t Cy_Prot_EnablePpuFixedMasterStruct(volatile stc_PERI_MS_PPU_FX_t* base);
cy_en_prot_status_t Cy_Prot_DisablePpuFixedMasterStruct(volatile stc_PERI_MS_PPU_FX_t* base);
cy_en_prot_status_t Cy_Prot_EnablePpuFixedSlaveStruct(volatile stc_PERI_MS_PPU_FX_t* base);
cy_en_prot_status_t Cy_Prot_DisablePpuFixedSlaveStruct(volatile stc_PERI_MS_PPU_FX_t* base);
/** \} group_prot_functions_ppu_fixed */
#if defined(LPDDR4_EMPU_EMPU_STRUCT_NR) && (LPDDR4_EMPU_EMPU_STRUCT_NR >= 0)
/**
* \addtogroup group_prot_functions_empu
* \{
*/
cy_en_prot_status_t Cy_Prot_ConfigEmpuMasterStruct(volatile stc_LPDDR4_EMPU_EMPU_STRUCT_t* base, const cy_stc_empu_cfg_t* config);
cy_en_prot_status_t Cy_Prot_ConfigEmpuSlaveStruct(volatile stc_LPDDR4_EMPU_EMPU_STRUCT_t* base, const cy_stc_empu_cfg_t* config);
cy_en_prot_status_t Cy_Prot_EnableEmpuMasterStruct(volatile stc_LPDDR4_EMPU_EMPU_STRUCT_t* base);
cy_en_prot_status_t Cy_Prot_DisableEmpuMasterStruct(volatile stc_LPDDR4_EMPU_EMPU_STRUCT_t* base);
cy_en_prot_status_t Cy_Prot_EnableEmpuSlaveStruct(volatile stc_LPDDR4_EMPU_EMPU_STRUCT_t* base);
cy_en_prot_status_t Cy_Prot_DisableEmpuSlaveStruct(volatile stc_LPDDR4_EMPU_EMPU_STRUCT_t* base);
/** \} group_prot_functions_empu */
#endif
/** \} group_prot_functions */
/** \} group_prot */
#if defined(__cplusplus)
}
#endif
#endif /* CY_PROT_H */
@@ -0,0 +1,412 @@
/***************************************************************************//**
* \file cy_scb_common.c
* \version 1.0
*
* Provides common API implementation of the SCB driver.
*
********************************************************************************
* \copyright
* Copyright 2016-2017, Cypress Semiconductor Corporation. All rights reserved.
* You may use this file only in accordance with the license, terms, conditions,
* disclaimers, and limitations in the end user license agreement accompanying
* the software package with which this file was provided.
*******************************************************************************/
#include "cy_scb_common.h"
#if defined(__cplusplus)
extern "C" {
#endif
/*******************************************************************************
* Function Name: Cy_SCB_ReadArrayNoCheck
****************************************************************************//**
*
* Reads an array of data out of the SCB receive FIFO without checking if the
* receive FIFO has enough data elements.
* Before calling this function, make sure that the receive FIFO has enough data
* elements to be read.
*
* \param base
* The pointer to the SCB instance.
*
* \param rxBuf
* The pointer to location to place data read from the receive FIFO.
* The size of the data element defined by the configured data width.
*
* \param size
* The number of data elements read from the receive FIFO.
*
*******************************************************************************/
void Cy_SCB_ReadArrayNoCheck(volatile stc_SCB_t const *base, void *rxBuf, uint32_t size)
{
uint32_t idx;
if (Cy_SCB_IsRxDataWidthByte(base))
{
uint8_t *buf = (uint8_t *) rxBuf;
/* Get data available in RX FIFO */
for (idx = 0ul; idx < size; ++idx)
{
buf[idx] = (uint8_t) Cy_SCB_ReadRxFifo(base);
}
}
else
{
uint16_t *buf = (uint16_t *) rxBuf;
/* Get data available in RX FIFO */
for (idx = 0ul; idx < size; ++idx)
{
buf[idx] = (uint16_t) Cy_SCB_ReadRxFifo(base);
}
}
}
/*******************************************************************************
* Function Name: Cy_SCB_ReadArray
****************************************************************************//**
*
* Reads an array of data out of the SCB receive FIFO.
* This function does not block, it returns how many data elements were
* read from the receive FIFO.
*
* \param base
* The pointer to the SCB instance.
*
* \param rxBuf
* The pointer to location to place data read from receive FIFO.
* The item size is defined by the data type which depends on the configured
* data width.
*
* \param size
* The number of data elements to read from the receive FIFO.
*
* \return
* The number of data elements read from the receive FIFO.
*
*******************************************************************************/
uint32_t Cy_SCB_ReadArray(volatile stc_SCB_t const *base, void *rxBuf, uint32_t size)
{
/* Get available items in RX FIFO */
uint32_t numToCopy = Cy_SCB_GetNumInRxFifo(base);
/* Adjust items which will be read */
if (numToCopy > size)
{
numToCopy = size;
}
/* Get data available in RX FIFO */
Cy_SCB_ReadArrayNoCheck(base, rxBuf, numToCopy);
return (numToCopy);
}
/*******************************************************************************
* Function Name: Cy_SCB_ReadArrayBlocking
****************************************************************************//**
*
* Reads an array of data out of the SCB receive FIFO.
* This function blocks until the number of data elements specified by the
* size has been read from the receive FIFO.
*
* \param base
* The pointer to the SCB instance.
*
* \param rxBuf
* The pointer to location to place data read from receive FIFO.
* The item size is defined by the data type which depends on the configured
* data width.
*
* \param size
* The number of data elements to read from receive FIFO.
*
*******************************************************************************/
void Cy_SCB_ReadArrayBlocking(volatile stc_SCB_t const *base, void *rxBuf, uint32_t size)
{
uint32_t numCopied;
uint8_t *buf = (uint8_t *) rxBuf;
/* Get data from RX FIFO. Stop when the requested size is read. */
while (size > 0ul)
{
numCopied = Cy_SCB_ReadArray(base, (void *) buf, size);
buf = &buf[(Cy_SCB_IsRxDataWidthByte(base) ? (numCopied) : (2ul * numCopied))];
size -= numCopied;
}
}
/*******************************************************************************
* Function Name: Cy_SCB_Write
****************************************************************************//**
*
* Places a single data element in the SCB transmit FIFO.
* This function does not block and returns how many data elements were placed
* in the transmit FIFO.
*
* \param base
* The pointer to the SCB instance.
*
* \param data
* Data to put in the transmit FIFO.
* The item size is defined by the data type which depends on the configured
* data width.
*
* \return
* The number of data elements placed in the transmit FIFO: 0 or 1.
*
*******************************************************************************/
uint32_t Cy_SCB_Write(volatile stc_SCB_t *base, uint32_t data)
{
uint32_t numCopied = 0ul;
if (Cy_SCB_GetFifoSize(base) != Cy_SCB_GetNumInTxFifo(base))
{
Cy_SCB_WriteTxFifo(base, data);
numCopied = 1ul;
}
return (numCopied);
}
/*******************************************************************************
* Function Name: Cy_SCB_WriteArrayNoCheck
****************************************************************************//**
*
* Places an array of data in the SCB transmit FIFO without checking if the
* transmit FIFO has enough space.
* Before calling this function, make sure that the transmit FIFO has enough
* space to put all requested data elements.
*
* \param base
* The pointer to the SCB instance.
*
* \param txBuf
* The pointer to data to place in the transmit FIFO.
* The item size is defined by the data type which depends on the configured
* TX data width.
*
* \param size
* The number of data elements to transmit.
*
* \return
* The number of data elements placed in the transmit FIFO.
*
*******************************************************************************/
void Cy_SCB_WriteArrayNoCheck(volatile stc_SCB_t *base, void *txBuf, uint32_t size)
{
uint32_t idx;
if (Cy_SCB_IsTxDataWidthByte(base))
{
uint8_t *buf = (uint8_t *) txBuf;
/* Put data into TX FIFO */
for (idx = 0ul; idx < size; ++idx)
{
Cy_SCB_WriteTxFifo(base, (uint32_t) buf[idx]);
}
}
else
{
uint16_t *buf = (uint16_t *) txBuf;
/* Put data into TX FIFO */
for (idx = 0ul; idx < size; ++idx)
{
Cy_SCB_WriteTxFifo(base, (uint32_t) buf[idx]);
}
}
}
/*******************************************************************************
* Function Name: Cy_SCB_WriteArray
****************************************************************************//**
*
* Places an array of data in the SCB transmit FIFO.
* This function does not block and it returns how many data elements were
* placed in the transmit FIFO.
*
* \param base
* The pointer to the SCB instance.
*
* \param txBuf
* The pointer to data to place in the transmit FIFO.
* The item size is defined by the data type which depends on the configured
* TX data width.
*
* \param size
* The number of data elements to transmit.
*
* \return
* The number of data elements placed in the transmit FIFO.
*
*******************************************************************************/
uint32_t Cy_SCB_WriteArray(volatile stc_SCB_t *base, void *txBuf, uint32_t size)
{
/* Get free entries in TX FIFO */
uint32_t numToCopy = Cy_SCB_GetFifoSize(base) - Cy_SCB_GetNumInTxFifo(base);
/* Adjust the data elements to write */
if (numToCopy > size)
{
numToCopy = size;
}
Cy_SCB_WriteArrayNoCheck(base, txBuf, numToCopy);
return (numToCopy);
}
/*******************************************************************************
* Function Name: Cy_SCB_WriteArrayBlocking
****************************************************************************//**
*
* Places an array of data in the transmit FIFO.
* This function blocks until the number of data elements specified by the size
* is placed in the transmit FIFO.
*
* \param base
* The pointer to the SCB instance.
*
* \param txBuf
* The pointer to data to place in transmit FIFO.
* The item size is defined by the data type which depends on the configured
* data width.
*
* \param size
* The number of data elements to write into the transmit FIFO.
*
*******************************************************************************/
void Cy_SCB_WriteArrayBlocking(volatile stc_SCB_t *base, void *txBuf, uint32_t size)
{
uint32_t numCopied;
uint8_t *buf = (uint8_t *) txBuf;
/* Get data from RX FIFO. Stop when the requested size is read. */
while (size > 0ul)
{
numCopied = Cy_SCB_WriteArray(base, (void *) buf, size);
buf = &buf[(Cy_SCB_IsTxDataWidthByte(base) ? (numCopied) : (2ul * numCopied))];
size -= numCopied;
}
}
/*******************************************************************************
* Function Name: Cy_SCB_WriteString
****************************************************************************//**
*
* Places a NULL terminated string in the transmit FIFO.
* This function blocks until the entire string is placed in the transmit FIFO.
*
* \param base
* The pointer to the SCB instance.
*
* \param string
* The pointer to the null terminated string array.
*
*******************************************************************************/
void Cy_SCB_WriteString(volatile stc_SCB_t *base, char_t const string[])
{
uint32_t idx = 0ul;
uint32_t fifoSize = Cy_SCB_GetFifoSize(base);
/* Put data from TX FIFO. Stop when string is terminated */
while (((char_t) 0) != string[idx])
{
/* Wait for free space to be available */
while (fifoSize == Cy_SCB_GetNumInTxFifo(base))
{
}
Cy_SCB_WriteTxFifo(base, (uint32_t) string[idx]);
++idx;
}
}
/*******************************************************************************
* Function Name: Cy_SCB_WriteDefaultArrayNoCheck
****************************************************************************//**
*
* Places a number of the same data elements in the SCB transmit FIFO without
* checking if the transmit FIFO has enough space. The data elements is equal
* to txData parameter.
* Before calling this function make sure that transmit FIFO has enough space
* to put all requested data elements.
*
* \param base
* The pointer to the SCB instance.
*
* \param txData
* The data element to transmit repeatedly.
*
* \param size
* The number of data elements to transmit.
*
*******************************************************************************/
void Cy_SCB_WriteDefaultArrayNoCheck(volatile stc_SCB_t *base, uint32_t txData, uint32_t size)
{
while (size > 0ul)
{
Cy_SCB_WriteTxFifo(base, txData);
--size;
}
}
/*******************************************************************************
* Function Name: Cy_SCB_WriteDefaultArray
****************************************************************************//**
*
* Places a number of the same data elements in the SCB transmit FIFO.
* The data elements is equal to the txData parameter.
*
* \param base
* The pointer to the SCB instance.
*
* \param txData
* The data element to transmit repeatedly.
*
* \param size
* The number of data elements to transmit.
*
* \return
* The number of data elements placed in the transmit FIFO.
*
*******************************************************************************/
uint32_t Cy_SCB_WriteDefaultArray(volatile stc_SCB_t *base, uint32_t txData, uint32_t size)
{
/* Get free entries in TX FIFO */
uint32_t numToCopy = Cy_SCB_GetFifoSize(base) - Cy_SCB_GetNumInTxFifo(base);
/* Adjust data elements to write */
if (numToCopy > size)
{
numToCopy = size;
}
Cy_SCB_WriteDefaultArrayNoCheck(base, txData, numToCopy);
return (numToCopy);
}
#if defined(__cplusplus)
}
#endif
/* [] END OF FILE */
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,422 @@
/***************************************************************************//**
* \file cy_scb_ezi2c.h
* \version 1.0
*
* Provides EZI2C API declarations of the SCB driver.
*
********************************************************************************
* \copyright
* Copyright 2016-2017, Cypress Semiconductor Corporation. All rights reserved.
* You may use this file only in accordance with the license, terms, conditions,
* disclaimers, and limitations in the end user license agreement accompanying
* the software package with which this file was provided.
*******************************************************************************/
/**
* \addtogroup group_scb_ezi2c
* \{
* Driver API for EZI2C slave Peripheral
*
* I2C - The Inter-Integrated Circuit (I2C) bus is an industry-standard.
* The two-wire hardware interface was developed by Philips Semiconductors
* (now NXP Semiconductors).
*
* The EZI2C slave peripheral driver provides an API to implement the I2C slave
* device based on the SCB hardware block. This slave device emulates a common
* I2C EEPROM interface that acts like dual-port memory between the external
* master and your code. I2C devices based on the SCB hardware are compatible
* with the I2C Standard mode, Fast mode, and Fast mode Plus specifications as
* defined in the I2C bus specification.
*
* Features:
* * An industry-standard I2C bus interface
* * Supports standard data rates of 100/400/1000 kbps
* * Emulates a common I2C EEPROM Interface
* * Acts like dual-port memory between the external master and your code
* * Supports Hardware Address Match
* * Supports two hardware addresses with separate buffers
* * Supports Wake from Deep Sleep on address match
* * Simple to set up and use, does not require calling EZI2C API
* at run time.
*
* \section group_scb_ezi2c_configuration Configuration Considerations
*
* To set up the EZI2C slave driver, provide the configuration parameters in the
* \ref cy_stc_scb_ezi2c_config_t structure. For the slave, the primary slave
* address slaveAddress1 must be provided. The other parameters are optional
* for operation.
* To get EZI2C slave operate with desired data rate the SCB clock frequency
* must be configured. Use the SysClk driver API to do that. Refer to the
* technical reference manual (TRM) to get information how to select SCB
* frequency in I2C mode to support desired data rate.
* To initialize the driver, call the \ref Cy_SCB_EZI2C_Init function providing
* a pointer to the filled \ref cy_stc_scb_ezi2c_config_t structure and
* allocated \ref cy_stc_scb_ezi2c_context_t. The \ref Cy_SCB_EZI2C_Interrupt
* function must be called in the interrupt handler for the selected
* SCB instance and this interrupt must be enabled in the NVIC. Set up the
* EZI2C slave buffers before calling \ref Cy_SCB_EZI2C_Enable using
* \ref Cy_SCB_EZI2C_SetBuffer1 for the primary slave address and
* \ref Cy_SCB_EZI2C_SetBuffer2 for the secondary if it is enabled. Finally,
* enable the EZI2C slave operation calling \ref Cy_SCB_EZI2C_Enable.
*
* The following operation might not require calling any EZI2C slave function
* because the I2C master is able to access the slave buffer and the application
* can directly access it as well. Note that this is an application level task
* to ensure the buffer content integrity.
*
* The master can access the buffer:
* * Master Write operation starts with sending a base address which is 1
* or 2 bytes depending on the sub-address size configuration. This base
* address is retained and will be used for later read operations. Following
* the base address, there is a sequence of bytes written into the buffer
* starting from the base address location. The buffer index is incremented
* for each written byte, but this does not affect the base address which is
* retained. The length of a write operation is limited by the maximum buffer
* read/write region size.\n
* When a master attempts to write outside the read/write region or past the
* end of the buffer, the last byte is NACKed.
* * Master Read operation always starts from the base address set by the most
* recent Write operation. The buffer index is incremented for each read byte.
* Two sequential read operations start from the same base address no matter
* how many bytes were read. The length of a read operation is not limited by
* the maximum size of the data buffer. The EZI2C slave returns 0xFF bytes
* if the read operation passes the end of the buffer.\n
* Typically, a read operation requires the base address to be updated before
* starting the read. In this case, the write and read operations must be
* combined together. The I2C master may use the ReStart or Stop/Start
* conditions to combine the operations. The write operation sets only the
* base address and the following read operation will start from the new base
* address. In cases where the base address remains the same, there is no need
* for a write operation.
*
* \section group_scb_ezi2c_more_information More Information
*
* For more information on the SCB peripheral, refer to the technical reference
* manual (TRM).
*
* \section group_scb_ezi2c_changelog Changelog
* <table class="doxtable">
* <tr><th>Version</th><th>Changes</th><th>Reason for Change</th></tr>
* <tr>
* <td>1.0</td>
* <td>Initial version</td>
* <td></td>
* </tr>
* </table>
*
* \defgroup group_scb_ezi2c_macro Macro
* \defgroup group_scb_ezi2c_functions Functions
* \{
* \defgroup group_scb_ezi2c_general_functions General
* \defgroup group_scb_ezi2c_slave_functions Slave
* \defgroup group_scb_ezi2c_low_power_functions Low Power Callbacks
* \}
* \defgroup group_scb_ezi2c_data_structures Data Structures
* \defgroup group_scb_ezi2c_enums Enumerated Types
*/
#if !defined(CY_SCB_EZI2C_H)
#define CY_SCB_EZI2C_H
#include "cy_scb_common.h"
#if defined(__cplusplus)
extern "C" {
#endif
/***************************************
* Enumerated Types
***************************************/
/**
* \addtogroup group_scb_ezi2c_enums
* \{
*/
/** EZI2C slave status codes */
typedef enum
{
/** Operation completed successfully */
CY_SCB_EZI2C_SUCCESS = 0u,
/** One or more of input parameters are invalid */
CY_SCB_EZI2C_BAD_PARAM = (CY_SCB_ID | CY_PDL_STATUS_ERROR | CY_SCB_EZI2C_ID | 1u),
} cy_en_scb_ezi2c_status_t;
/** \cond INTERNAL */
/** EZI2C slave FSM states */
typedef enum
{
CY_SCB_EZI2C_STATE_IDLE,
CY_SCB_EZI2C_STATE_RX_OFFSET_MSB,
CY_SCB_EZI2C_STATE_RX_OFFSET_LSB,
CY_SCB_EZI2C_STATE_RX_DATA0,
CY_SCB_EZI2C_STATE_RX_DATA1,
CY_SCB_EZI2C_STATE_TX_DATA
} cy_en_scb_ezi2c_state_t;
/** \endcond */
/** \} group_scb_ezi2c_enums */
/***************************************
* Type Definitions
***************************************/
/**
* \addtogroup group_scb_ezi2c_data_structures
* \{
*/
/** EZI2C slave configuration structure */
typedef struct cy_stc_scb_ezi2c_config
{
/**
* The number of supported addresses either (See
* \ref group_scb_ezi2c_macro_num_of_addr for the set of constants)
*/
uint32_t numberOfAddresses;
/** The 7-bit right justified primary slave address */
uint8_t slaveAddress1;
/** The 7-bit right justified secondary slave address */
uint8_t slaveAddress2;
/** The size of the sub-address, can either be 8 or 16 bits (See
* \ref group_scb_ezi2c_macro_sub_addr_size for the set of constants)
*/
uint32_t subAddressSize;
/**
* When set, the slave will wake the device from deep sleep on an address
* match (The device datasheet must be consulted to determine which SCBs
* support this mode)
*/
bool enableWakeFromSleep;
} cy_stc_scb_ezi2c_config_t;
/** EZI2C slave context structure */
typedef struct cy_stc_scb_ezi2c_context
{
cy_en_scb_ezi2c_state_t state; /**< The driver state */
uint32_t status; /**< The slave status */
uint8_t address1; /**< The primary slave address (7-bits right justified) */
uint8_t address2; /**< The secondary slave address (7-bits right justified) */
uint32_t subAddrSize; /**< The sub-address size */
uint32_t idx; /**< The index within the buffer during operation */
uint32_t baseAddr1; /**< The valid base address for the primary slave address */
uint32_t baseAddr2; /**< The valid base address for the secondary slave address */
bool addr1Active; /**< Defines whether the request is intended for the primary slave address */
uint8_t *curBuf; /**< The pointer to the current location in the buffer (while it is accessed) */
uint32_t bufSize; /**< Specifies how many bytes are left in the current buffer */
uint8_t *buf1; /**< The pointer to the buffer exposed on the request intended for the primary slave address */
uint32_t buf1Size; /**< The buffer size assigned to the primary slave address */
uint32_t buf1rwBondary; /**< The Read/Write boundary within the buffer assigned to the primary slave address */
uint8_t *buf2; /**< The pointer to the buffer exposed on the request intended for the secondary slave address */
uint32_t buf2Size; /**< The buffer size assigned to the secondary slave address */
uint32_t buf2rwBondary; /**< The Read/Write boundary within the buffer assigned for the secondary slave address */
} cy_stc_scb_ezi2c_context_t;
/** \} group_scb_ezi2c_data_structures */
/***************************************
* Function Prototypes
***************************************/
/**
* \addtogroup group_scb_ezi2c_general_functions
* \{
*/
cy_en_scb_ezi2c_status_t Cy_SCB_EZI2C_Init(volatile stc_SCB_t *base, cy_stc_scb_ezi2c_config_t const *config,
cy_stc_scb_ezi2c_context_t *context);
void Cy_SCB_EZI2C_DeInit(volatile stc_SCB_t *base);
__STATIC_INLINE void Cy_SCB_EZI2C_Enable(volatile stc_SCB_t *base);
void Cy_SCB_EZI2C_Disable(volatile stc_SCB_t *base, cy_stc_scb_ezi2c_context_t *context);
void Cy_SCB_EZI2C_SetAddress1(volatile stc_SCB_t *base, uint8_t addr, cy_stc_scb_ezi2c_context_t *context);
uint32_t Cy_SCB_EZI2C_GetAddress1(volatile stc_SCB_t const *base, cy_stc_scb_ezi2c_context_t const *context);
void Cy_SCB_EZI2C_SetAddress2(volatile stc_SCB_t *base, uint8_t addr, cy_stc_scb_ezi2c_context_t *context);
uint32_t Cy_SCB_EZI2C_GetAddress2(volatile stc_SCB_t const *base, cy_stc_scb_ezi2c_context_t const *context);
/** \} group_scb_ezi2c_general_functions */
/**
* \addtogroup group_scb_ezi2c_slave_functions
* \{
*/
void Cy_SCB_EZI2C_SetBuffer1(volatile stc_SCB_t const *base, uint8_t *buf, uint32_t bufSize, uint32_t rwBoundary,
cy_stc_scb_ezi2c_context_t *context);
void Cy_SCB_EZI2C_SetBuffer2(volatile stc_SCB_t const *base, uint8_t *buf, uint32_t bufSize, uint32_t rwBoundary,
cy_stc_scb_ezi2c_context_t *context);
uint32_t Cy_SCB_EZI2C_GetActivity(volatile stc_SCB_t const *base, cy_stc_scb_ezi2c_context_t *context);
void Cy_SCB_EZI2C_Interrupt(volatile stc_SCB_t *base, cy_stc_scb_ezi2c_context_t *context);
/** \} group_scb_ezi2c_slave_functions */
/**
* \addtogroup group_scb_ezi2c_low_power_functions
* \{
*/
cy_en_syspm_status_t Cy_EZI2C_DeepSleepCallback(void *base, void *context, cy_en_syspm_callback_mode_t mode);
cy_en_syspm_status_t Cy_EZI2C_HibernateCallback(void *base, void *context, cy_en_syspm_callback_mode_t mode);
/** \} group_scb_ezi2c_low_power_functions */
/***************************************
* API Constants
***************************************/
/**
* \addtogroup group_scb_ezi2c_macro
* \{
*/
/**
* \defgroup group_scb_ezi2c_macro_num_of_addr Number of Addresses
* \{
*/
#define CY_SCB_EZI2C_ONE_ADDRESS (0ul) /**< Only one address */
#define CY_SCB_EZI2C_TWO_ADDRESSES (1ul) /**< Two addresses */
/** \} group_scb_ezi2c_macro_num_of_addr */
/**
* \defgroup group_scb_ezi2c_macro_sub_addr_size Size of Sub-Address
* \{
*/
#define CY_SCB_EZI2C_SUB_ADDR8_BITS (0ul) /**< Sub-address is 8 bits */
#define CY_SCB_EZI2C_SUB_ADDR16_BITS (1ul) /**< Sub-address is 16 bits */
/** \} group_scb_ezi2c_macro_sub_addr_size */
/**
* \defgroup group_scb_ezi2c_macro_get_activity EZI2C Activity Status
* Each EZI2C slave status is encoded in a separate bit, therefore multiple bits
* may be set to indicate the current status.
* \{
*/
/**
* The Read transfer intended for the primary slave address is complete.
* The error condition status bit must be checked to ensure that the Read
* transfer was completed successfully.
*/
#define CY_SCB_EZI2C_STATUS_READ1 (0x01ul)
/**
* The Write transfer intended for the primary slave address is complete.
* The buffer content was modified.
* The error condition status bit must be checked to ensure that the Write
* transfer was completed successfully.
*/
#define CY_SCB_EZI2C_STATUS_WRITE1 (0x02ul)
/**
* The Read transfer intended for the secondary slave address is complete.
* The error condition status bit must be checked to ensure that the Read
* transfer was completed successfully.
*/
#define CY_SCB_EZI2C_STATUS_READ2 (0x04ul)
/**
* The Write transfer intended for the secondary slave address is complete.
* The buffer content was modified.
* The error condition status bit must be checked to ensure that the Write
* transfer was completed successfully.
*/
#define CY_SCB_EZI2C_STATUS_WRITE2 (0x08ul)
/**
* A transfer intended for the primary address or secondary address is in
* progress. The status bit is set after an address match and cleared
* on a Stop or ReStart condition.
*/
#define CY_SCB_EZI2C_STATUS_BUSY (0x10ul)
/**
* An error occurred during a transfer intended for the primary or secondary
* slave address. The sources of the error are: a misplaced Start or Stop
* condition or lost arbitration while the slave drives SDA.
* When CY_SCB_EZI2C_STATUS_ERR is set, the slave buffer may contain an
* invalid byte. It is recommended to discard the buffer content in this case.
*/
#define CY_SCB_EZI2C_STATUS_ERR (0x20ul)
/** \} group_scb_ezi2c_macro_get_activity */
/**
* This value is returned by the slave when the buffer is not configured or
* the master requests more bytes than available in the buffer.
*/
#define CY_SCB_EZI2C_DEFAULT_TX (0xFFul)
/***************************************
* Internal Constants
***************************************/
/** \cond INTERNAL */
/* Default registers values */
#define CY_SCB_EZI2C_I2C_CTRL (SCB_I2C_CTRL_S_GENERAL_IGNORE_Msk | SCB_I2C_CTRL_SLAVE_MODE_Msk)
#define CY_SCB_EZI2C_RX_CTRL (CY_SCB_I2C_RX_CTRL)
#define CY_SCB_EZI2C_TX_CTRL (CY_SCB_I2C_TX_CTRL)
#define CY_SCB_EZI2C_SLAVE_INTR (CY_SCB_SLAVE_INTR_I2C_ADDR_MATCH | CY_SCB_SLAVE_INTR_I2C_STOP | \
CY_SCB_SLAVE_INTR_I2C_BUS_ERROR | CY_SCB_SLAVE_INTR_I2C_ARB_LOST)
/* Error interrupt sources */
#define CY_SCB_EZI2C_SLAVE_INTR_ERROR (CY_SCB_SLAVE_INTR_I2C_BUS_ERROR | CY_SCB_SLAVE_INTR_I2C_ARB_LOST)
/* Disables Stop interrupt source */
#define CY_SCB_EZI2C_SLAVE_INTR_NO_STOP (CY_SCB_EZI2C_SLAVE_INTR & ((uint32_t) ~CY_SCB_SLAVE_INTR_I2C_STOP))
/* Disable Address interrupt source */
#define CY_SCB_EZI2C_SLAVE_INTR_NO_ADDR (CY_SCB_EZI2C_SLAVE_INTR & ((uint32_t) ~CY_SCB_SLAVE_INTR_I2C_ADDR_MATCH))
/* FIFO size */
#define CY_SCB_EZI2C_FIFO_SIZE (CY_SCB_FIFO_SIZE)
#define CY_SCB_EZI2C_HALF_FIFO_SIZE (CY_SCB_FIFO_SIZE / 2ul)
#define CY_SCB_EZI2C_ONE_ADDRESS_MASK (0xFFul)
/** \endcond */
/** \} group_scb_ezi2c_macro */
/***************************************
* Inline Function Implementation
***************************************/
/**
* \addtogroup group_scb_ezi2c_general_functions
* \{
*/
/*******************************************************************************
* Function Name: Cy_SCB_EZI2C_Enable
****************************************************************************//**
*
* Enables the SCB block for the EZI2C operation
*
* \param base
* The pointer to the EZI2C SCB instance.
*
*******************************************************************************/
__STATIC_INLINE void Cy_SCB_EZI2C_Enable(volatile stc_SCB_t *base)
{
base->unCTRL.stcField.u1ENABLED = 1ul;
}
/** \} group_scb_ezi2c_general_functions */
#if defined(__cplusplus)
}
#endif
/** \} group_scb_ezi2c */
#endif /* (CY_SCB_EZI2C_H) */
/* [] END OF FILE */
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,521 @@
/***************************************************************************//**
* \file cy_smartio.h
* \version `$CY_MAJOR_VERSION`.`$CY_MINOR_VERSION`
*
* \brief
* Provides an API declaration of the Smart I/O driver
*
********************************************************************************
* \copyright
* Copyright 2017, Cypress Semiconductor Corporation. All rights reserved.
* You may use this file only in accordance with the license, terms, conditions,
* disclaimers, and limitations in the end user license agreement accompanying
* the software package with which this file was provided.
*******************************************************************************/
/**
* \defgroup group_smartio Smart I/O (SmartIO)
* \{
* The Smart I/O driver provides an API to configure and access the Smart I/O hardware
* present between the GPIOs (pins) and HSIOMs (pin muxes) on select device ports. It
* can be used to perform simple logic operations on peripheral and GPIO signals at
* the GPIO port. Features include,
*
* 1. Purely combinatorial logic using 8 Look-Up Tables (LUT).
* 2. Mixed sequential and combinatorial logic using 8 LUTs and 1 Data Unit (DU).
* 3. Counters and shift registers using 8-bit multi-function DU (simplified ALU).
* 4. Operational in device active, sleep and deep-sleep power modes.
*
* \section group_smartio_configuration Configuration Considerations
*
* \subsection group_smartio_routing_fabric Routing Fabric
*
* The Smart I/O routing fabric is divided into two portions, where each portion is capable
* of accepting half of the data or GPIO signals. The LUTs have the following structure.
*
* - LUT 7...4 are capable of accepting signals from io/chip 7...4 as inputs.
* - LUT 3...0 are capable of accepting signals from io/chip 3...0 as inputs.
* - The LUTs can accept any LUT output as an input.
* - Each LUT output is dedicated to the corresponding output io/chip terminal. For
* example, LUT 0 can go to either io0 terminal output or chip0 terminal output or both.
*
* \subsection group_smartio_single_lut Single Source LUT Input
*
* If a LUT is used, all three inputs to the LUT must be designated. For example, even If a LUT is
* used to accept a single source as its input, all three inputs must accept that same signal. The
* lookup table should then be designed such that it only changes the output value when all
* three inputs satisfy the same condition. For example, consider the case where the signal on
* data0 must be inverted before being passed to io0. LUT0 accepts chip0 as input 0, 1 and 2.
* The truth table is defined such that it outputs a logic 1 only when the inputs are all 0.
*
* \subsection group_smartio_clk_rst Clock and Reset Behavior
*
* The Smart I/O hardware drives its synchronous elements using a single clock source.
* Depending on the clock source, the Smart I/O will have different reset behaviors, which
* will reset all the flip-flops in the LUTs and synchronizers to logic 0. The configuration
* registers will retain their values unless coming out of Power on Reset (POR). Notes:
*
* - If the block is only disabled, the values in the LUT flip-flips and I/O synchronizers are
* held as long as the chip remains in a valid power mode.
* - The selected clock for the fabric's synchronous logic is not phase aligned with other
* synchronous logic on the chip operating on the same clock. Therefore, communication between
* the Smart I/O and other synchronous logic should be treated as asynchronous (just as the
* communication between I/O input signals and other synchronous logic should be treated as
* asynchronous)
*
* <table class="doxtable">
* <tr>
* <th>Clock Source</th>
* <th>Reset Behavior</th>
* <th>Enable Delay</th>
* <th>Description</th>
* </tr>
* <tr>
* <td>io/chip 7...0</td>
* <td>Reset on POR</td>
* <td>2 clock edges</td>
* <td>If chosen as the clock source, that particular signal cannot also be used as an input
* to a LUT as it may cause a race condition. The fabric will be enabled after 2 clock
* edges of the signal on the gpio terminal.</td>
* </tr>
* <tr>
* <td>Divided Clock (Active)</td>
* <td>Reset when going to Deep Sleep, Hibernate or POR</td>
* <td>2 clock edges</td>
* <td>The fabric will be enabled after 2 clock edges of the divided clock. Any synchronous
* logic in the LUTs will be reset to 0 when in chip deep-sleep or hibernate modes.</td>
* </tr>
* <tr>
* <td>Divided Clock (Deep-Sleep)</td>
* <td>Reset when going to Hibernate or POR</td>
* <td>2 clock edges</td>
* <td>The fabric will be enabled after 2 clock edges of the divided clock. Any synchronous
* logic in the LUTs will be reset to 0 when in hibernate mode.</td>
* </tr>
* <tr>
* <td>Divided Clock (Hibernate)</td>
* <td>Reset on POR</td>
* <td>2 clock edges</td>
* <td>The fabric will be enabled after 2 clock edges of the divided clock.</td>
* </tr>
* <tr>
* <td>LFCLK</td>
* <td>Reset when going to Hibernate and POR</td>
* <td>2 clock edges</td>
* <td>The fabric will be enabled after 2 clock edges of the low frequency clock (LFCLK).
* Any synchronous logic in the LUTs will be reset to 0 when in hibernate mode.</td>
* </tr>
* <tr>
* <td>Asynchronous</td>
* <td>Reset on POR</td>
* <td>3 clock edges of SYSCLK</td>
* <td>The fabric will be enabled after 3 clock edges of the clk_peri source.</td>
* </tr>
* </table>
*
* \subsection group_smartio_sync_req Signal Synchronization Requirement
*
* If any of the signals coming in through the Smart I/O terminals are meant to be used
* in sequential elements in the LUTs, the terminal synchronizer must first be used to synchronize
* that signal to the Component clock. For example, if the signal on io0 must be used in LUT0 in
* Sequential output mode, the synchronization for io0 terminal should be enabled for reliable
* operation.
*
* \subsection group_smartio_comb_feedback LUT Combinatorial Feedback
*
* Since the LUTs can be configured as purely (or partially) combinatorial elements and since they
* can chain to each other in any fashion, combinatorial timing loops can occur. This causes
* oscillations that burn power and create unpredictable behavior. If a feedback is required, the
* signals should always go through a flip-flop before feeding back. For example, the following is a
* potentially problematic design; LUT1 and LUT2 are configured in combinatorial mode, where their
* respective outputs feed into the inputs of the other. This will result in oscillations.
* To prevent it, one of the LUTs should be configured to Gated Output mode.
*
* \subsection group_smartio_lpm Low Power Mode
*
* The Smart I/O hardware is capable of operating during chip Deep-Sleep mode. The block has
* the following requirements when operating in this mode:
*
* - All sequential elements must be clocked by a valid clock in these power domains. Refer to
* \ref group_smartio_clk_rst for more details.
* - All signals in the block (including the clock) must be less than 1 MHz when in Deep-Sleep
* mode.
* - The hold override functionality should be enabled when entering Deep-Sleep mode.
* This functionality should then be disabled when the chip is not in this mode.
*
* \section group_smartio_more_information More Information
*
* Refer to the technical reference manual (TRM) and the device datasheet.
*
* \defgroup group_smartio_macros Macros
* \defgroup group_smartio_functions Functions
* \{
* \defgroup group_smartio_functions_init Initialization Functions
* \defgroup group_smartio_functions_general General Functions
* \defgroup group_smartio_functions_lut LUT Functions
* \defgroup group_smartio_functions_du Data Unit Functions
* \}
* \defgroup group_smartio_data_structures Data Structures
* \defgroup group_smartio_enums Enumerated Types
*/
#if !defined(CY_SMARTIO_H)
#define CY_SMARTIO_H
#include <stdbool.h>
#include <stddef.h>
#include "syslib/cy_syslib.h"
#include "cy_device_headers.h"
#if defined(__cplusplus)
extern "C" {
#endif
/** \addtogroup group_smartio_macros
* \{
*/
/** Driver major version */
//#define CY_SMARTIO_DRV_VERSION_MAJOR `$CY_MAJOR_VERSION`
#define CY_SMARTIO_DRV_VERSION_MAJOR 1
/** Driver minor version */
//#define CY_SMARTIO_DRV_VERSION_MINOR `$CY_MINOR_VERSION`
#define CY_SMARTIO_DRV_VERSION_MINOR 0
/** SmartIO driver ID */
#define CY_SMARTIO_ID CY_PDL_DRV_ID (0x48u) /* Needs update */
/**
* \defgroup group_smartio_channels Smart I/O channel selection
* \{
* Constants for selecting the Smart I/O channels
*/
#define CY_SMARTIO_CHANNEL_NONE 0x00u /**< No channels */
#define CY_SMARTIO_CHANNEL0 0x01u /**< Channel 0 (chip0 <-> io0) */
#define CY_SMARTIO_CHANNEL1 0x02u /**< Channel 1 (chip1 <-> io1) */
#define CY_SMARTIO_CHANNEL2 0x04u /**< Channel 2 (chip2 <-> io2) */
#define CY_SMARTIO_CHANNEL3 0x08u /**< Channel 3 (chip3 <-> io3) */
#define CY_SMARTIO_CHANNEL4 0x10u /**< Channel 4 (chip4 <-> io4) */
#define CY_SMARTIO_CHANNEL5 0x20u /**< Channel 5 (chip5 <-> io5) */
#define CY_SMARTIO_CHANNEL6 0x40u /**< Channel 6 (chip6 <-> io6) */
#define CY_SMARTIO_CHANNEL7 0x80u /**< Channel 7 (chip7 <-> io7) */
#define CY_SMARTIO_CHANNEL_ALL 0xffu /**< All channels */
/** \} */
/** \} group_smartio_macros */
/***************************************
* Constants
***************************************/
/** \cond INTERNAL */
#define CY_SMARTIO_ENABLE 1ul
#define CY_SMARTIO_DISABLE 0ul
#define CY_SMARTIO_DEINIT 0ul
#define CY_SMARTIO_LUTMAX 8u
#define CY_SMARTIO_LUTMIN 0u
/** \endcond */
/***************************************
* Enumerations
***************************************/
/**
* \addtogroup group_smartio_enums
* \{
*/
/**
* Smart I/O driver error codes
*/
typedef enum
{
CY_SMARTIO_SUCCESS = 0x00u, /**< Returned successful */
CY_SMARTIO_BAD_PARAM = CY_SMARTIO_ID | CY_PDL_STATUS_ERROR | 0x01u, /**< Bad parameter was passed */
CY_SMARTIO_LOCKED = CY_SMARTIO_ID | CY_PDL_STATUS_ERROR | 0x02u, /**< Smart I/O is not disabled */
} cy_en_smartio_status_t;
/**
* Smart I/O clock selection
*/
typedef enum {
CY_SMARTIO_CLK_IO0 = 0, /**< Clock source is signal on io0 */
CY_SMARTIO_CLK_IO1 = 1, /**< Clock source is signal on io1 */
CY_SMARTIO_CLK_IO2 = 2, /**< Clock source is signal on io2 */
CY_SMARTIO_CLK_IO3 = 3, /**< Clock source is signal on io3 */
CY_SMARTIO_CLK_IO4 = 4, /**< Clock source is signal on io4 */
CY_SMARTIO_CLK_IO5 = 5, /**< Clock source is signal on io5 */
CY_SMARTIO_CLK_IO6 = 6, /**< Clock source is signal on io6 */
CY_SMARTIO_CLK_IO7 = 7, /**< Clock source is signal on io7 */
CY_SMARTIO_CLK_CHIP0 = 8, /**< Clock source is signal on chip0 */
CY_SMARTIO_CLK_CHIP1 = 9, /**< Clock source is signal on chip1 */
CY_SMARTIO_CLK_CHIP2 = 10, /**< Clock source is signal on chip2 */
CY_SMARTIO_CLK_CHIP3 = 11, /**< Clock source is signal on chip3 */
CY_SMARTIO_CLK_CHIP4 = 12, /**< Clock source is signal on chip4 */
CY_SMARTIO_CLK_CHIP5 = 13, /**< Clock source is signal on chip5 */
CY_SMARTIO_CLK_CHIP6 = 14, /**< Clock source is signal on chip6 */
CY_SMARTIO_CLK_CHIP7 = 15, /**< Clock source is signal on chip7 */
CY_SMARTIO_CLK_DIVACT = 16, /**< Clock source is a peripheral clock divider (Active) */
CY_SMARTIO_CLK_DIVDS = 17, /**< Clock source is a peripheral clock divider (Deep-Sleep) */
CY_SMARTIO_CLK_DIVHIB = 18, /**< Clock source is a peripheral clock divider (Hibernate) */
CY_SMARTIO_CLK_LFCLK = 19, /**< Clock source is LFCLK */
CY_SMARTIO_CLK_GATED = 20, /**< Disables the clock. Used when turning off the block */
CY_SMARTIO_CLK_ASYNC = 31, /**< Asynchronous operation (only allow combinatorial logic) */
}cy_en_smartio_clksrc_t;
/**
* Smart I/O LUT number
*/
typedef enum {
CY_SMARTIO_LUT0 = 0, /**< Look-Up-Table #0 */
CY_SMARTIO_LUT1 = 1, /**< Look-Up-Table #1 */
CY_SMARTIO_LUT2 = 2, /**< Look-Up-Table #2 */
CY_SMARTIO_LUT3 = 3, /**< Look-Up-Table #3 */
CY_SMARTIO_LUT4 = 4, /**< Look-Up-Table #4 */
CY_SMARTIO_LUT5 = 5, /**< Look-Up-Table #5 */
CY_SMARTIO_LUT6 = 6, /**< Look-Up-Table #6 */
CY_SMARTIO_LUT7 = 7, /**< Look-Up-Table #7 */
}cy_en_smartio_lutnum_t;
/**
* Smart I/O input trigger number
*/
typedef enum {
CY_SMARTIO_TR0 = 0, /**< Input trigger #0 */
CY_SMARTIO_TR1 = 1, /**< Input trigger #1 */
CY_SMARTIO_TR2 = 2, /**< Input trigger #2 */
}cy_en_smartio_trnum_t;
/**
* Smart I/O Data Unit's input "DATA" number
*/
typedef enum {
CY_SMARTIO_DATA0 = 0, /**< Input DATA #0 */
CY_SMARTIO_DATA1 = 1, /**< Input DATA #1 */
}cy_en_smartio_datanum_t;
/**
* Smart I/O LUT input trigger source
*/
typedef enum {
CY_SMARTIO_LUTTR_DU_OUT = 0, /**< Data Unit output */
CY_SMARTIO_LUTTR_LUT0_OUT = 0, /**< LUT0 output */
CY_SMARTIO_LUTTR_LUT1_OUT = 1, /**< LUT1 output */
CY_SMARTIO_LUTTR_LUT2_OUT = 2, /**< LUT2 output */
CY_SMARTIO_LUTTR_LUT3_OUT = 3, /**< LUT3 output */
CY_SMARTIO_LUTTR_LUT4_OUT = 4, /**< LUT4 output */
CY_SMARTIO_LUTTR_LUT5_OUT = 5, /**< LUT5 output */
CY_SMARTIO_LUTTR_LUT6_OUT = 6, /**< LUT6 output */
CY_SMARTIO_LUTTR_LUT7_OUT = 7, /**< LUT7 output */
CY_SMARTIO_LUTTR_CHIP0 = 8, /**< Chip signal 0 (for LUT 0,1,2,3) */
CY_SMARTIO_LUTTR_CHIP4 = 8, /**< Chip signal 4 (for LUT 4,5,6,7) */
CY_SMARTIO_LUTTR_CHIP1 = 9, /**< Chip signal 1 (for LUT 0,1,2,3) */
CY_SMARTIO_LUTTR_CHIP5 = 9, /**< Chip signal 5 (for LUT 4,5,6,7) */
CY_SMARTIO_LUTTR_CHIP2 = 10, /**< Chip signal 2 (for LUT 0,1,2,3) */
CY_SMARTIO_LUTTR_CHIP6 = 10, /**< Chip signal 6 (for LUT 4,5,6,7) */
CY_SMARTIO_LUTTR_CHIP3 = 11, /**< Chip signal 3 (for LUT 0,1,2,3) */
CY_SMARTIO_LUTTR_CHIP7 = 11, /**< Chip signal 7 (for LUT 4,5,6,7) */
CY_SMARTIO_LUTTR_IO0 = 12, /**< I/O signal 0 (for LUT 0,1,2,3) */
CY_SMARTIO_LUTTR_IO4 = 12, /**< I/O signal 4 (for LUT 4,5,6,7) */
CY_SMARTIO_LUTTR_IO1 = 13, /**< I/O signal 1 (for LUT 0,1,2,3) */
CY_SMARTIO_LUTTR_IO5 = 13, /**< I/O signal 5 (for LUT 4,5,6,7) */
CY_SMARTIO_LUTTR_IO2 = 14, /**< I/O signal 2 (for LUT 0,1,2,3) */
CY_SMARTIO_LUTTR_IO6 = 14, /**< I/O signal 6 (for LUT 4,5,6,7) */
CY_SMARTIO_LUTTR_IO3 = 15, /**< I/O signal 3 (for LUT 0,1,2,3) */
CY_SMARTIO_LUTTR_IO7 = 15, /**< I/O signal 7 (for LUT 4,5,6,7) */
CY_SMARTIO_LUTTR_INVALID = 255, /**< Invalid input trigger selection */
}cy_en_smartio_luttr_t;
/**
* Smart I/O LUT opcode
*/
typedef enum {
CY_SMARTIO_LUTOPC_COMB = 0, /**< Combinatorial output */
CY_SMARTIO_LUTOPC_GATED_TR2 = 1, /**< TR2 gated, Combinatorial output */
CY_SMARTIO_LUTOPC_GATED_OUT = 2, /**< Sequential (gated) output */
CY_SMARTIO_LUTOPC_ASYNC_SR = 3, /**< Asynchronous Set/Reset mode */
}cy_en_smartio_lutopc_t;
/**
* Smart I/O Data Unit input trigger source
*/
typedef enum {
CY_SMARTIO_DUTR_ZERO = 0, /**< Constant 0 */
CY_SMARTIO_DUTR_ONE = 1, /**< Constant 1 */
CY_SMARTIO_DUTR_DU_OUT = 2, /**< Data Unit output */
CY_SMARTIO_DUTR_LUT0_OUT = 3, /**< LUT0 output */
CY_SMARTIO_DUTR_LUT1_OUT = 4, /**< LUT1 output */
CY_SMARTIO_DUTR_LUT2_OUT = 5, /**< LUT2 output */
CY_SMARTIO_DUTR_LUT3_OUT = 6, /**< LUT3 output */
CY_SMARTIO_DUTR_LUT4_OUT = 7, /**< LUT4 output */
CY_SMARTIO_DUTR_LUT5_OUT = 8, /**< LUT5 output */
CY_SMARTIO_DUTR_LUT6_OUT = 9, /**< LUT6 output */
CY_SMARTIO_DUTR_LUT7_OUT = 10, /**< LUT7 output */
CY_SMARTIO_DUTR_INVALID = 255, /**< Invalid input trigger selected */
}cy_en_smartio_dutr_t;
/**
* Smart I/O Data Unit input "DATA" source
*/
typedef enum {
CY_SMARTIO_DUDATA_ZERO = 0, /**< Constant 0 */
CY_SMARTIO_DUDATA_CHIP = 1, /**< Chip signal [7:0] */
CY_SMARTIO_DUDATA_IO = 2, /**< I/O signal [7:0] */
CY_SMARTIO_DUDATA_DATAREG = 3, /**< SMARTIO.DATA register */
}cy_en_smartio_dudata_t;
/**
* Smart I/O Data Unit opcode
*/
typedef enum {
CY_SMARTIO_DUOPC_INCR = 1, /**< Increment (Count up) */
CY_SMARTIO_DUOPC_DECR = 2, /**< Decrement (Count down) */
CY_SMARTIO_DUOPC_INCR_WRAP = 3, /**< Increment and wrap-around (Count up and wrap) */
CY_SMARTIO_DUOPC_DECR_WRAP = 4, /**< Decrement and wrap-around (Count down and wrap) */
CY_SMARTIO_DUOPC_INCR_DECR = 5, /**< Increment or decrement (Count up/down) */
CY_SMARTIO_DUOPC_INCR_DECR_WRAP = 6, /**< Increment or decrement with wrap-around (Count up/down and wrap) */
CY_SMARTIO_DUOPC_ROR = 7, /**< Rotate right (shift right and wrap) */
CY_SMARTIO_DUOPC_SHR = 8, /**< Shift right and shift data in through MSB */
CY_SMARTIO_DUOPC_AND_OR = 9, /**< out = ((DATA0 & DATA1) == 0) ? 0 : 1 */
CY_SMARTIO_DUOPC_SHR_MAJ3 = 10, /**< Majority 3 (Check if 2 out of 3 LSB bits are logic 1) */
CY_SMARTIO_DUOPC_SHR_EQL = 11, /**< Check for equality against DATA1. Also perform Shift right */
}cy_en_smartio_duopc_t;
/**
* Smart I/O Data Unit operation bit size
*/
typedef enum {
CY_SMARTIO_DUSIZE_1 = 0, /**< 1-bit size/width operand */
CY_SMARTIO_DUSIZE_2 = 1, /**< 2-bits size/width operand */
CY_SMARTIO_DUSIZE_3 = 2, /**< 3-bits size/width operand */
CY_SMARTIO_DUSIZE_4 = 3, /**< 4-bits size/width operand */
CY_SMARTIO_DUSIZE_5 = 4, /**< 5-bits size/width operand */
CY_SMARTIO_DUSIZE_6 = 5, /**< 6-bits size/width operand */
CY_SMARTIO_DUSIZE_7 = 6, /**< 7-bits size/width operand */
CY_SMARTIO_DUSIZE_8 = 7, /**< 8-bits size/width operand */
}cy_en_smartio_dusize_t;
/** \} group_smartio_enums */
/***************************************
* Configuration Structures
***************************************/
/**
* \addtogroup group_smartio_data_structures
* \{
*/
/** LUT configuration structure */
typedef struct {
cy_en_smartio_luttr_t tr0; /**< LUT input trigger 0 source selection */
cy_en_smartio_luttr_t tr1; /**< LUT input trigger 1 source selection */
cy_en_smartio_luttr_t tr2; /**< LUT input trigger 2 source selection */
cy_en_smartio_lutopc_t opcode; /**< LUT Opcode */
uint8_t lutMap; /**< LUT output mapping */
}cy_stc_smartio_lutcfg_t;
/** Data Unit (DU) configuration structure */
typedef struct {
cy_en_smartio_dutr_t tr0; /**< DU input trigger 0 source selection */
cy_en_smartio_dutr_t tr1; /**< DU input trigger 1 source selection */
cy_en_smartio_dutr_t tr2; /**< DU input trigger 2 source selection */
cy_en_smartio_dudata_t data0; /**< DU input DATA0 source selection */
cy_en_smartio_dudata_t data1; /**< DU input DATA1 source selection */
cy_en_smartio_duopc_t opcode; /**< DU op-code */
cy_en_smartio_dusize_t size; /**< DU operation bit size */
uint8_t dataReg; /**< DU DATA register value */
}cy_stc_smartio_ducfg_t;
/** Smart I/O configuration structure */
typedef struct {
cy_en_smartio_clksrc_t clkSrc; /**< Smart I/O instance clock source */
uint8_t bypassMask; /**< Smart I/O io<->chip channel bypass mask */
uint8_t ioSyncEn; /**< Synchronization enable/disable for I/O terminals */
uint8_t chipSyncEn; /**< Synchronization enable/disable for Chip terminals */
const cy_stc_smartio_lutcfg_t* lutCfg[CY_SMARTIO_LUTMAX]; /**< Pointer to LUT configuration (NULL if not used) */
const cy_stc_smartio_ducfg_t* duCfg; /**< Pointer to Data Unit configuration (NULL if not used) */
bool hldOvr; /**< Hold override enable (true) / disable (false) */
}cy_stc_smartio_config_t;
/** \} group_smartio_data_structures */
/***************************************
* Function Prototypes
***************************************/
/**
* \addtogroup group_smartio_functions
* \{
*/
/**
* \addtogroup group_smartio_functions_init
* \{
*/
extern cy_en_smartio_status_t Cy_SmartIO_Init(volatile stc_SMARTIO_PRT_t* base, const cy_stc_smartio_config_t* config);
extern void Cy_SmartIO_Deinit(volatile stc_SMARTIO_PRT_t* base);
extern void Cy_SmartIO_Enable(volatile stc_SMARTIO_PRT_t* base);
extern void Cy_SmartIO_Disable(volatile stc_SMARTIO_PRT_t* base);
/** \} group_smartio_functions_init */
/**
* \addtogroup group_smartio_functions_general
* \{
*/
extern uint8_t Cy_SmartIO_GetChBypass(volatile stc_SMARTIO_PRT_t* base);
extern cy_en_smartio_status_t Cy_SmartIO_SetChBypass(volatile stc_SMARTIO_PRT_t* base, uint8_t channelEn);
extern cy_en_smartio_clksrc_t Cy_SmartIO_GetClock(volatile stc_SMARTIO_PRT_t* base);
extern cy_en_smartio_status_t Cy_SmartIO_SetClock(volatile stc_SMARTIO_PRT_t* base, cy_en_smartio_clksrc_t clkSrc);
extern uint8_t Cy_SmartIO_GetIoSync(volatile stc_SMARTIO_PRT_t* base);
extern cy_en_smartio_status_t Cy_SmartIO_SetIoSync(volatile stc_SMARTIO_PRT_t* base, uint8_t ioSyncEn);
extern uint8_t Cy_SmartIO_GetChipSync(volatile stc_SMARTIO_PRT_t* base);
extern cy_en_smartio_status_t Cy_SmartIO_SetChipSync(volatile stc_SMARTIO_PRT_t* base, uint8_t chipSyncEn);
extern cy_en_smartio_status_t Cy_SmartIO_HoldOverride(volatile stc_SMARTIO_PRT_t* base, bool hldOvr);
/** \} group_smartio_functions_general */
/**
* \addtogroup group_smartio_functions_lut
* \{
*/
extern cy_en_smartio_luttr_t Cy_SmartIO_GetLutTr(volatile stc_SMARTIO_PRT_t* base, cy_en_smartio_lutnum_t lutNum, cy_en_smartio_trnum_t trNum);
extern cy_en_smartio_status_t Cy_SmartIO_SetLutTr(volatile stc_SMARTIO_PRT_t* base, cy_en_smartio_lutnum_t lutNum, cy_en_smartio_trnum_t trNum, cy_en_smartio_luttr_t trSrc);
extern cy_en_smartio_status_t Cy_SmartIO_SetLutTrAll(volatile stc_SMARTIO_PRT_t* base, cy_en_smartio_lutnum_t lutNum, cy_en_smartio_luttr_t trSrc);
extern cy_en_smartio_lutopc_t Cy_SmartIO_GetLutOpcode(volatile stc_SMARTIO_PRT_t* base, cy_en_smartio_lutnum_t lutNum);
extern cy_en_smartio_status_t Cy_SmartIO_SetLutOpcode(volatile stc_SMARTIO_PRT_t* base, cy_en_smartio_lutnum_t lutNum, cy_en_smartio_lutopc_t opcode);
extern uint8_t Cy_SmartIO_GetLutMap(volatile stc_SMARTIO_PRT_t* base, cy_en_smartio_lutnum_t lutNum);
extern cy_en_smartio_status_t Cy_SmartIO_SetLutMap(volatile stc_SMARTIO_PRT_t* base, cy_en_smartio_lutnum_t lutNum, uint8_t lutMap);
/** \} group_smartio_functions_lut */
/**
* \addtogroup group_smartio_functions_du
* \{
*/
extern cy_en_smartio_dutr_t Cy_SmartIO_GetDuTr(volatile stc_SMARTIO_PRT_t* base, cy_en_smartio_trnum_t trNum);
extern cy_en_smartio_status_t Cy_SmartIO_SetDuTr(volatile stc_SMARTIO_PRT_t* base, cy_en_smartio_trnum_t trNum, cy_en_smartio_dutr_t trSrc);
extern cy_en_smartio_status_t Cy_SmartIO_SetDuTrAll(volatile stc_SMARTIO_PRT_t* base, cy_en_smartio_dutr_t trSrc);
extern cy_en_smartio_dudata_t Cy_SmartIO_GetDuData(volatile stc_SMARTIO_PRT_t* base, cy_en_smartio_datanum_t dataNum);
extern cy_en_smartio_status_t Cy_SmartIO_SetDuData(volatile stc_SMARTIO_PRT_t* base, cy_en_smartio_datanum_t dataNum, cy_en_smartio_dudata_t dataSrc);
extern cy_en_smartio_duopc_t Cy_SmartIO_GetDuOpc(volatile stc_SMARTIO_PRT_t* base);
extern cy_en_smartio_dusize_t Cy_SmartIO_GetDuSize(volatile stc_SMARTIO_PRT_t* base);
extern cy_en_smartio_status_t Cy_SmartIO_SetDuOperation(volatile stc_SMARTIO_PRT_t* base, cy_en_smartio_duopc_t opcode, cy_en_smartio_dusize_t size);
extern uint8_t Cy_SmartIO_GetDataReg(volatile stc_SMARTIO_PRT_t* base);
extern cy_en_smartio_status_t Cy_SmartIO_SetDataReg(volatile stc_SMARTIO_PRT_t* base, uint8_t dataReg);
/** \} group_smartio_functions_du */
/** \} group_smartio_functions */
#if defined(__cplusplus)
}
#endif
#endif /* CY_SMARTIO_H */
/** \} group_smartio */
/* [] END OF FILE */
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,962 @@
/***************************************************************************//**
* \file cy_smif.h
* \version `$CY_MAJOR_VERSION`.`$CY_MINOR_VERSION`
*
* Provides an API declaration of the Cypress SMIF driver.
*
********************************************************************************
* \copyright
* Copyright 2016-2018, Cypress Semiconductor Corporation. All rights reserved.
* You may use this file only in accordance with the license, terms, conditions,
* disclaimers, and limitations in the end user license agreement accompanying
* the software package with which this file was provided.
*******************************************************************************/
/**
* \defgroup group_smif Serial Memory Interface (SMIF)
* \{
* The SPI-based communication interface for external memory devices.
*
* SMIF: Serial Memory Interface: This IP block implements an SPI-based
* communication interface for interfacing external memory devices to TVII. The SMIF
* supports Octal-SPI, Dual Quad-SPI, Quad-SPI, DSPI, and SPI.
*
* Features
* - Standard SPI Master interface
* - Supports Single/Dual/Quad/Octal SPI Memories
* - Supports Dual-Quad SPI mode
* - Design-time configurable support for multiple (up to 4) external serial
* memory devices
* - eXecute-In-Place (XIP) operation mode for both read and write accesses
* with 4KB XIP read cache and on-the-fly encryption and decryption
* - Supports external serial memory initialization via Serial Flash
* Discoverable Parameters (SFDP) standard
* - Support for SPI clock frequencies up to 80 MHz
*
* The primary usage model for the SMIF is that of an external memory interface.
* The SMIF is capable of interfacing with different types of memory, up to four
* types.
*
* \b SMIF driver is divided in next layers
* - cy_smif.h APIs
* - cy_smif_memslot.h APIs
* - SMIF version specific support APIs
*
* The SMIF API is divided into the low-level functions and memory-slot functions. Use
* the low level API for the SMIF block initialization and for implementing a generic
* SPI communication interface using the SMIF block.
*
* The memory slot API has functions to implement the basic memory operations such as
* program, read, erase etc. These functions are implemented using the memory
* parameters in the memory device configuration data structure. The memory-slot
* initialization API initializes all the memory slots based on the settings in the
* array.
*
* \warning The driver is not responsible for external memory persistence. You cannot edit
* a buffer during the Read/Write operations. If there is a memory error, the SMIF ip block
* can require a reset. To determine if this has happened, check the SMIF
* busy status using Cy_SMIF_IsBusy() and implement a timeout. Reset the SMIF
* block by toggling CTL.ENABLED. Then reconfigure the SMIF block.
*
* For the Write operation, check that the SMIF driver has completed
* transferring by calling Cy_SMIF_IsBusy(). Also, check that the memory is
* available with Cy_SMIF_Memslot_IsBusy() before proceeding.
*
* Simple example of external flash memory programming using low level SMIF API.
* All steps mentioned in example below are incorporated in
* \ref Cy_SMIF_Memslot_CmdWriteEnable(), \ref Cy_SMIF_Memslot_CmdProgram(), and
* \ref Cy_SMIF_Memslot_IsBusy() of the
* \ref group_smif_mem_slot_functions "memory slot level API".
* \warning Example is simplified, without checks of error conditions.
* \note Flash memories need erase operation before programming. Refer to
* external memory datasheet for specific memory commands.
*
* For the Read operation, before accessing the read buffer, check that it is ready
* by calling Cy_SMIF_GetTxFifoStatus().
*
* Simple example of external flash memory read using low level SMIF API. All
* steps mentioned in example below are incorporated in
* \ref Cy_SMIF_Memslot_CmdRead() of the
* \ref group_smif_mem_slot_functions "memory slot level API".
* \warning Example is simplified, without checks of error conditions.
* \note Refer to external memory datasheet for specific memory commands.
*
* The user should invalidate the cache by calling Cy_SMIF_CacheInvalidate() when
* switching from the MMIO mode to XIP mode.
*
* \section group_smif_configuration Configuration Considerations
*
* See the documentation for Cy_SMIF_Init() and Cy_SMIF_Memslot_Init() for details
* on the required configuration structures and other initialization topics.
*
* The normal (MMIO) mode is used for implementing a generic SPI/DSPI/QSPI/Dual
* Quad-SPI/Octal-SPI communication interface using the SMIF block. This
* interface can be used to implement special commands like Program/Erase of
* flash, memory device configuration, sleep mode entry for memory devices or
* other special commands specific to the memory device. The transfer width
* (SPI/DSP/Quad-SPI/Octal-SPI) of a transmission is a parameter set for each
* transmit/receive operation. So these can be changed at run time.
*
* In a typical memory interface with flash memory, the SMIF is used in the
* memory mode when reading from the memory and it switches to the normal mode when
* writing to flash memory.
* A typical memory device has multiple types of commands.
*
* The SMIF interface can be used to transmit different types of commands. Each
* command has different phases: command, dummy cycles, and transmit and receive
* data which require separate APIs.
*
* \subsection group_smif_init SMIF Initialization
* Create interrupt function and allocate memory for SMIF context
* structure
*
* SMIF driver initialization for low level API usage (cy_smif.h)
* Additional steps to initialize SMIF driver for memory slot level API usage
* (cy_smif_memslot.h).
*
* \note Example does not include initialization of all needed configuration
* structures (\ref cy_stc_smif_mem_device_cfg_t, \ref cy_stc_smif_mem_cmd_t).
*
* \subsection group_smif_xip_init SMIF XIP Initialization
* The eXecute In Place (XIP) is a mode of operation where read or write commands
* to the memory device are directed through the SMIF without any use of API
* function calls. In this mode the SMIF block maps the AHB bus-accesses to
* external memory device addresses to make it behave similar to internal memory.
* This allows the CPU to execute code directly from external memory. This mode
* is not limited to code and is suitable also for data read and write accesses.
*
* \note Example of input parameters initialization is in \ref group_smif_init
* section.
* \warning Functions that called from external memory should be declared with
* long call attribute.
*
* \section group_smif_more_information More Information
*
* More information regarding the Serial Memory Interface can be found in the Technical
* Reference Manual (TRM).
*
* \section group_smif_changelog Changelog
* <table class="doxtable">
* <tr><th>Version</th><th>Changes</th><th>Reason for Change</th></tr>
* <tr>
* <td>1.0</td>
* <td>Initial version</td>
* <td></td>
* </tr>
* </table>
*
* \defgroup group_smif_macros Macros
* \{
* \defgroup group_smif_macros_status Status Macros
* \defgroup group_smif_macros_cmd Command Macros
* \defgroup group_smif_macros_flags External Memory Flags
* \}
* \defgroup group_smif_functions Functions
* \{
* \defgroup group_smif_low_level_functions Low Level Functions
* \{
* Basic flow for read/write commands using \ref Cy_SMIF_TransmitCommand
* \ref Cy_SMIF_TransmitData \ref Cy_SMIF_ReceiveData
* \ref Cy_SMIF_SendDummyCycles
*
* \}
* \defgroup group_smif_mem_slot_functions Memory Slot Functions
* \defgroup group_smif_version_specific_functions SMIF version specific Functions
* \}
* \defgroup group_smif_data_structures Data Structures
* \{
* \defgroup group_smif_data_structures_memslot SMIF Memory Description Structures
* General hierarchy of memory structures are:
* Top structure is \ref cy_stc_smif_block_config_t, which could have links up to
* 4 \ref cy_stc_smif_mem_config_t which describes each connected to the SMIF
* external memory.
* \}
* \defgroup group_smif_enums Enumerated Types
*/
#if !defined(CY_SMIF_H)
#define CY_SMIF_H
#include <stdint.h>
#include <stdbool.h>
#include <stddef.h>
#include "syslib/cy_syslib.h"
#include "syspm/cy_syspm.h"
#include "cy_device_headers.h"
#ifdef CY_IP_MXSMIF
#if defined(__cplusplus)
extern "C" {
#endif
/***************************************
* Constants
****************************************/
/**
* \addtogroup group_smif_macros
* \{
*/
/** The driver major version */
#define CY_SMIF_DRV_VERSION_MAJOR `$CY_MAJOR_VERSION`
/** The driver minor version */
#define CY_SMIF_DRV_VERSION_MINOR `$CY_MINOR_VERSION`
/** One microsecond timeout for Cy_SMIF_TimeoutRun() */
#define CY_SMIF_WAIT_1_UNIT (1U)
/** The SMIF driver ID, reported as part of an unsuccessful API return status
* \ref cy_en_smif_status_t */
#define CY_SMIF_ID CY_PDL_DRV_ID (0x2CU)
/** Number of SMIF core */
#define CY_SMIF_CORE_MAX (2U)
/**
* \addtogroup group_smif_macros_isr
* \{
*/
/** \} group_smif_macros_isr */
/** \cond INTERNAL */
/* Devices with a single SMIF instance use a different generated define name (w/o instance suffix), so make it common */
// For device count definitions
#if defined(SMIF0_DEVICE_NR)
#define CY_SMIF_DRV_SMIF0_DEVICE_NR SMIF0_DEVICE_NR
#elif defined(SMIF_DEVICE_NR)
#define CY_SMIF_DRV_SMIF0_DEVICE_NR SMIF_DEVICE_NR
#endif
#if defined(CY_SMIF_CORE1_EXISTS)
#if defined(SMIF1_DEVICE_NR)
#define CY_SMIF_DRV_SMIF1_DEVICE_NR SMIF1_DEVICE_NR
#elif defined(SMIF_DEVICE_NR)
#define CY_SMIF_DRV_SMIF1_DEVICE_NR SMIF_DEVICE_NR
#endif
#endif
// For delay tap number definitions
#if defined(SMIF_DELAY_TAPS_NR)
#define CY_SMIF_DRV_SMIF0_DELAY_TAPS_NR SMIF_DELAY_TAPS_NR
#elif defined(SMIF0_DELAY_TAPS_NR)
#define CY_SMIF_DRV_SMIF0_DELAY_TAPS_NR SMIF0_DELAY_TAPS_NR
#endif
#if defined(SMIF1_DELAY_TAPS_NR)
#define CY_SMIF_DRV_SMIF1_DELAY_TAPS_NR SMIF1_DELAY_TAPS_NR
#endif
// For delay line number definitions
#if defined(SMIF_DELAY_LINES_NR)
#define CY_SMIF_DRV_SMIF0_DELAY_LINES_NR SMIF_DELAY_LINES_NR
#elif defined(SMIF0_DELAY_LINES_NR)
#define CY_SMIF_DRV_SMIF0_DELAY_LINES_NR SMIF0_DELAY_LINES_NR
#endif
#if defined(SMIF1_DELAY_LINES_NR)
#define CY_SMIF_DRV_SMIF1_DELAY_LINES_NR SMIF1_DELAY_LINES_NR
#endif
// For XIP MASK definitions
#if defined(SMIF_SMIF_XIP_MASK)
#define CY_SMIF_DRV_SMIF0_SMIF_XIP_MASK SMIF_SMIF_XIP_MASK
#elif defined(SMIF0_SMIF_XIP_MASK)
#define CY_SMIF_DRV_SMIF0_SMIF_XIP_MASK SMIF0_SMIF_XIP_MASK
#elif defined(SMIF_SMIF0_XIP_MASK)
#define CY_SMIF_DRV_SMIF0_SMIF_XIP_MASK SMIF_SMIF0_XIP_MASK
#endif
#if defined(SMIF1_SMIF_XIP_MASK)
#define CY_SMIF_DRV_SMIF1_SMIF_XIP_MASK SMIF1_SMIF_XIP_MASK
#elif defined(SMIF_SMIF1_XIP_MASK)
#define CY_SMIF_DRV_SMIF1_SMIF_XIP_MASK SMIF_SMIF1_XIP_MASK
#endif
// For XIP ADDR definitions
#if defined(SMIF_SMIF_XIP_ADDR)
#define CY_SMIF_DRV_SMIF0_SMIF_XIP_ADDR SMIF_SMIF_XIP_ADDR
#elif defined(SMIF0_SMIF_XIP_ADDR)
#define CY_SMIF_DRV_SMIF0_SMIF_XIP_ADDR SMIF0_SMIF_XIP_ADDR
#elif defined(SMIF_SMIF0_XIP_ADDR)
#define CY_SMIF_DRV_SMIF0_SMIF_XIP_ADDR SMIF_SMIF0_XIP_ADDR
#endif
#if defined(SMIF1_SMIF_XIP_ADDR)
#define CY_SMIF_DRV_SMIF1_SMIF_XIP_ADDR SMIF1_SMIF_XIP_ADDR
#elif defined(SMIF_SMIF1_XIP_ADDR)
#define CY_SMIF_DRV_SMIF1_SMIF_XIP_ADDR SMIF_SMIF1_XIP_ADDR
#endif
#define CY_SMIF_CMD_FIFO_TX_MODE (0UL)
#define CY_SMIF_CMD_FIFO_TX_COUNT_MODE (1UL)
#define CY_SMIF_CMD_FIFO_RX_COUNT_MODE (2UL)
#define CY_SMIF_CMD_FIFO_DUMMY_COUNT_MODE (3UL)
#define CY_SMIF_CMD_FIFO_DESELECT_MODE (4UL)
#define CY_SMIF_TX_CMD_FIFO_STATUS_RANGE (8U)
#define CY_SMIF_TX_DATA_FIFO_STATUS_RANGE (8U)
#define CY_SMIF_RX_DATA_FIFO_STATUS_RANGE (8U)
#define CY_SMIF_MAX_TX_TR_LEVEL (8U)
#define CY_SMIF_MAX_RX_TR_LEVEL (8U)
#define CY_SMIF_CRYPTO_START (1UL)
#define CY_SMIF_CRYPTO_COMPLETED (0UL)
#define CY_SMIF_CRYPTO_ADDR_MASK (0xFFFFFFF0UL)
#define CY_SMIF_AES128_BYTES (16U)
#define CY_SMIF_CTL_REG_DEFAULT (0x00000300U) /* 3 - [13:12] CLOCK_IF_RX_SEL */
#define CY_SMIF_CTL2_REG_DEFAULT (0x00000000U)
/** \endcond*/
/** \} group_smif_macros */
/**
* \addtogroup group_smif_enums
* \{
*/
/** The Transfer width options for the command, data, the address and the mode. */
typedef enum
{
CY_SMIF_WIDTH_SINGLE = 0U, /**< Normal SPI mode. */
CY_SMIF_WIDTH_DUAL = 1U, /**< Dual SPI mode. */
CY_SMIF_WIDTH_QUAD = 2U, /**< Quad SPI mode. */
CY_SMIF_WIDTH_OCTAL = 3U /**< Octal SPI mode. */
} cy_en_smif_txfr_width_t;
/* Specifies what happens for MMIO interface read accesses to an */
/* empty RX data FIFO or to a full TX format/data FIFO. */
typedef enum
{
/**< Generates a bus error. */
CY_SMIF_BUS_ERROR = 0UL,
/** Stalls the bus with the wait states. This option will increase the
* interrupt latency.
*/
CY_SMIF_WAIT_STATES = 1UL
} cy_en_smif_error_event_t;
/** The data line-selection options for a slave device. */
typedef enum
{
/**
* smif.spi_data[0] = DATA0, smif.spi_data[1] = DATA1, ..., smif.spi_data[7] = DATA7.
* This value is allowed for the SPI, DSPI, quad-SPI, dual quad-SPI, and octal-SPI modes.
*/
CY_SMIF_DATA_SEL0 = 0,
/**
* smif.spi_data[2] = DATA0, smif.spi_data[3] = DATA1.
* This value is only allowed for the SPI and DSPI modes.
*/
CY_SMIF_DATA_SEL1 = 1,
/**
* smif.spi_data[4] = DATA0, smif.spi_data[5] = DATA1, ..., smif.spi_data[7] = DATA3.
* This value is only allowed for the SPI, DSPI, quad-SPI and dual quad-SPI modes.
*/
CY_SMIF_DATA_SEL2 = 2,
/**
* smif.spi_data[6] = DATA0, smif.spi_data[7] = DATA1.
* This value is only allowed for the SPI and DSPI modes.
*/
CY_SMIF_DATA_SEL3 = 3
} cy_en_smif_data_select_t;
/** The SMIF modes to work with an external memory. */
typedef enum
{
CY_SMIF_NORMAL = 0, /**< Command mode (MMIO mode). */
CY_SMIF_MEMORY = 1 /**< XIP (eXecute In Place) mode. or ARB mode for smif_3*/
} cy_en_smif_mode_t;
/** Device interface transmitter clock source */
typedef enum
{
CY_SMIF_DIV_INV_FOR_SDR = 0, /**< transmitter clock clk_if */
CY_SMIF_INV_FOR_DDR = 1 /**< transmitter clock clk_if_inv */
} cy_en_smif_clk_tx_t;
/** Specifies the delay line used for RX data capturing with */
typedef enum
{
CY_SMIF_1_NEW_SEL_PER_TAP = 0, /**< 1 of these new delay cells per tap providing:
granularity of max. ~0.22ns */
CY_SMIF_1_SEN_SEL_PER_TAP = 1, /**< 1 SEN_DEL_L4_1 cell per tap providing:
granularity of max. ~0.4ns */
CY_SMIF_2_SEN_SEL_PER_TAP = 2, /**< 2 SEN_DEL_L4_1 cells per tap providing:
granularity of max. ~0.8ns */
CY_SMIF_4_SEN_SEL_PER_TAP = 3, /**< 4 SEN_DEL_L4_1 cells per tap providing:
granularity of max. ~1.6ns */
CY_SMIF_NO_DELAY_SEL = 0xFF,/**< No delay line (disabled) */
} cy_en_smif_delay_line_t;
/** Specifies use HW DLP calibration or SW DLP calibration */
typedef enum
{
CY_SMIF_DLP_UPDATE_MANUAL = 0, /**< SW will calibrates and sets DLP */
CY_SMIF_DLP_UPDATE_AUTO = 1, /**< Use HW DLP calibration scheme */
} cy_en_smif_dlp_auto_t;
/* Specifies the read data capture cycle for internal clocking. Only applies when receiver clock source is internal clock.*/
typedef enum
{
CY_SMIF_CAPTURE_DELAY_0_CYCLE = 0, /**< Cycle 0 */
CY_SMIF_CAPTURE_DELAY_1_CYCLE = 1, /**< Cycle 1 */
CY_SMIF_CAPTURE_DELAY_2_CYCLE = 2, /**< Cycle 2 */
} cy_en_smif_ddr_capture_delay_t;
/** The SMIF transfer status return values. */
typedef enum
{
CY_SMIF_STARTED, /**< The SMIF started. */
CY_SMIF_SEND_CMPLT, /**< The data transmission is complete. */
CY_SMIF_SEND_BUSY, /**< The data transmission is in progress. */
CY_SMIF_REC_CMPLT, /**< The data reception is completed. */
CY_SMIF_REC_BUSY, /**< The data reception is in progress. */
CY_SMIF_XIP_ERROR, /**< An XIP alignment error. */
CY_SMIF_CMD_ERROR, /**< A TX CMD FIFO overflow. */
CY_SMIF_TX_ERROR, /**< A TX DATA FIFO overflow. */
CY_SMIF_RX_ERROR /**< An RX DATA FIFO underflow. */
} cy_en_smif_txfr_status_t;
/** The SMIF API return values. */
typedef enum
{
CY_SMIF_SUCCESS = 0x00U, /**< Successful SMIF operation. */
CY_SMIF_CMD_FIFO_FULL = CY_SMIF_ID |CY_PDL_STATUS_ERROR | 0x01U, /**< The command is cancelled. The command FIFO is full. */
CY_SMIF_EXCEED_TIMEOUT = CY_SMIF_ID |CY_PDL_STATUS_ERROR | 0x02U, /**< The SMIF operation timeout exceeded. */
/**
* The device does not have a QE bit. The device detects
* 1-1-4 and 1-4-4 Reads based on the instruction.
*/
CY_SMIF_NO_QE_BIT = CY_SMIF_ID |CY_PDL_STATUS_ERROR | 0x03U,
CY_SMIF_BAD_PARAM = CY_SMIF_ID |CY_PDL_STATUS_ERROR | 0x04U, /**< The SMIF API received the wrong parameter */
CY_SMIF_NO_SFDP_SUPPORT = CY_SMIF_ID |CY_PDL_STATUS_ERROR | 0x05U, /**< The external memory does not support SFDP (JESD216B). */
CY_SMIF_BAD_STATUS = CY_SMIF_ID |CY_PDL_STATUS_ERROR | 0x06U, /**< The SMIF API received the wrong parameter */
CY_SMIF_GENERAL_ERROR = CY_SMIF_ID |CY_PDL_STATUS_ERROR | 0x07U, /**< Some general error */
} cy_en_smif_status_t;
/** The SMIF slave select definitions for the driver API. Each slave select is
* represented by an enumeration that has the bit corresponding to the slave
* select number set. */
typedef enum
{
CY_SMIF_SLAVE_SELECT_0 = 1U, /**< The SMIF slave select 0 */
#if (CY_SMIF_DRV_SMIF0_DEVICE_NR >= 2) || (defined(CY_SMIF_DRV_SMIF1_DEVICE_NR) && (CY_SMIF_DRV_SMIF1_DEVICE_NR >= 2))
CY_SMIF_SLAVE_SELECT_1 = 2U, /**< The SMIF slave select 1 */
#endif
#if (CY_SMIF_DRV_SMIF0_DEVICE_NR >= 3) || (defined(CY_SMIF_DRV_SMIF1_DEVICE_NR) && (CY_SMIF_DRV_SMIF1_DEVICE_NR >= 3))
CY_SMIF_SLAVE_SELECT_2 = 4U, /**< The SMIF slave select 2 */
#endif
#if (CY_SMIF_DRV_SMIF0_DEVICE_NR >= 4) || (defined(CY_SMIF_DRV_SMIF1_DEVICE_NR) && (CY_SMIF_DRV_SMIF1_DEVICE_NR >= 4))
CY_SMIF_SLAVE_SELECT_3 = 8U /**< The SMIF slave select 3 */
#endif
} cy_en_smif_slave_select_t;
/** Specifies the clock source for the receiver clock. */
typedef enum
{
CY_SMIF_OUTPUT_CLK = 0U, /**< The SMIF output clock */
CY_SMIF_INV_OUTPUT_CLK = 1U, /**< The SMIF output inverted clock */
CY_SMIF_FEEDBACK_CLK = 2U, /**< The SMIF feedback clock */
CY_SMIF_INV_FEEDBACK_CLK = 3U, /**< The SMIF feedback inverted clock */
CY_SMIF_INTERNAL_CLK = 4U, /**< The SMIF internal clock */
CY_SMIF_INV_INTERNAL_CLK = 5U, /**< The SMIF internal inverted clock */
CY_SMIF_INV_RWDS = 6U, /**< The SMIF inverted rwds */
CY_SMIF_RWDS = 7U, /**< The SMIF rwds */
} cy_en_smif_clk_rx_t;
/* Specifies the minimum duration of SPI deselection in between SPI transfers: */
typedef enum
{
CY_SMIF_MIN_DESELECT_1_CLK = 0U, /**< 1 memory interface clock cycle */
CY_SMIF_MIN_DESELECT_2_CLK = 1U, /**< 2 memory interface clock cycles */
CY_SMIF_MIN_DESELECT_3_CLK = 2U, /**< 3 memory interface clock cycles */
CY_SMIF_MIN_DESELECT_4_CLK = 3U, /**< 4 memory interface clock cycles */
CY_SMIF_MIN_DESELECT_5_CLK = 4U, /**< 5 memory interface clock cycles */
CY_SMIF_MIN_DESELECT_6_CLK = 5U, /**< 6 memory interface clock cycles */
CY_SMIF_MIN_DESELECT_7_CLK = 6U, /**< 7 memory interface clock cycles */
CY_SMIF_MIN_DESELECT_8_CLK = 7U /**< 8 memory interface clock cycles */
} cy_en_smif_deselection_t;
/* Specifies the duration between spi_select becomes low to 1st spi_clk edge */
/* min = 1 memory interface clock cycles when SDR, 1/4 memory interface clock cycles when DDR */
typedef enum
{
CY_SMIF_SETUP_0_CLK_PULUS_MIN = 0U, /**< 0 memory interface clock cycles + min duration */
CY_SMIF_SETUP_1_CLK_PULUS_MIN = 1U, /**< 1 memory interface clock cycles + min duration */
CY_SMIF_SETUP_2_CLK_PULUS_MIN = 2U, /**< 2 memory interface clock cycles + min duration */
CY_SMIF_SETUP_3_CLK_PULUS_MIN = 3U, /**< 3 memory interface clock cycles + min duration */
} cy_en_smif_setup_delay_t;
/* Specifies the duration between last spi_clk edge to spi_select becomes high */
/* min = 1 memory interface clock cycles when SDR, 1/4 memory interface clock cycles when DDR */
typedef enum
{
CY_SMIF_HOLD_0_CLK_PULUS_MIN = 0U, /**< 0 memory interface clock cycles + min duration */
CY_SMIF_HOLD_1_CLK_PULUS_MIN = 1U, /**< 1 memory interface clock cycles + min duration */
CY_SMIF_HOLD_2_CLK_PULUS_MIN = 2U, /**< 2 memory interface clock cycles + min duration */
CY_SMIF_HOLD_3_CLK_PULUS_MIN = 3U, /**< 3 memory interface clock cycles + min duration */
} cy_en_smif_hold_delay_t;
/** Specifies enabled type of SMIF cache. */
typedef enum
{
CY_SMIF_CACHE_SLOW = 1U, /**< The SMIF slow cache (in the clk_slow domain) see TRM for details */
CY_SMIF_CACHE_FAST = 2U, /**< The SMIF fast cache (in the clk_fast domain) see TRM for details */
CY_SMIF_CACHE_BOTH = 3U /**< The SMIF both caches */
} cy_en_smif_cache_en_t;
/** Specifies Data Rate. single data rate (SDR) or double data rate (DDR) */
typedef enum
{
CY_SMIF_SDR = 0, /**< Single data rate */
CY_SMIF_DDR = 1, /**< Double data rate */
} cy_en_smif_data_rate_t;
/** The size of the device region specified by DEVICE_MASK register */
typedef enum // casting int32_t is to avoid compiler error.
{
CY_SMIF_DEVICE_1M_BYTE = (int32_t)(0xFFF00000UL), /**< for 1M size device */
CY_SMIF_DEVICE_2M_BYTE = (int32_t)(0xFFE00000UL), /**< for 2M size device */
CY_SMIF_DEVICE_4M_BYTE = (int32_t)(0xFFC00000UL), /**< for 4M size device */
CY_SMIF_DEVICE_8M_BYTE = (int32_t)(0xFF800000UL), /**< for 8M size device */
CY_SMIF_DEVICE_16M_BYTE = (int32_t)(0xFF000000UL), /**< for 16M size device */
CY_SMIF_DEVICE_32M_BYTE = (int32_t)(0xFE000000UL), /**< for 32M size device */
CY_SMIF_DEVICE_64M_BYTE = (int32_t)(0xFC000000UL), /**< for 64M size device */
CY_SMIF_DEVICE_128M_BYTE = (int32_t)(0xF8000000UL), /**< for 128M size device */
CY_SMIF_DEVICE_256M_BYTE = (int32_t)(0xF0000000UL), /**< for 256M size device */
CY_SMIF_DEVICE_512M_BYTE = (int32_t)(0xE0000000UL), /**< for 512M size device */
CY_SMIF_DEVICE_1G_BYTE = (int32_t)(0xC0000000UL), /**< for 1G size device */
CY_SMIF_DEVICE_2G_BYTE = (int32_t)(0x80000000UL), /**< for 2G size device */
CY_SMIF_DEVICE_4G_BYTE = (int32_t)(0x00000000UL), /**< for 4G size device */
} cy_en_device_size_t;
/** Specifies the size of the XIP device address in Bytes */
typedef enum
{
CY_SMIF_XIP_ADDRESS_1_BYTE = 0, /**< 1 Byte address */
CY_SMIF_XIP_ADDRESS_2_BYTE = 1, /**< 2 Byte address */
CY_SMIF_XIP_ADDRESS_3_BYTE = 2, /**< 3 Byte address */
CY_SMIF_XIP_ADDRESS_4_BYTE = 3, /**< 4 Byte address */
CY_SMIF_XIP_ADDRESS_5_BYTE = 7, /**< 4 Byte address (spread over 5 bytes) according to Hyperbus protocol */
} cy_en_smif_xip_addr_byte_t;
/** Continuous transfer merge timeout in clk_mem cycles */
typedef enum
{
CY_SMIF_MER_TIMEOUT_1_CYCLE = 0, /**< Timeout after 1 clk_mem cycle */
CY_SMIF_MER_TIMEOUT_16_CYCLE = 1, /**< Timeout after 16 clk_mem cycle */
CY_SMIF_MER_TIMEOUT_256_CYCLE = 2, /**< Timeout after 256 clk_mem cycle */
CY_SMIF_MER_TIMEOUT_4096_CYCLE = 3, /**< Timeout after 4096 clk_mem cycle */
CY_SMIF_MER_TIMEOUT_65536_CYCLE = 4, /**< Timeout after 65536 clk_mem cycle */
} cy_en_smif_dev_merge_timeout_t;
/** Specify mode/dummy presence */
typedef enum
{
CY_SMIF_NOT_PRESENT = 0, /**< mode/dummy not present */
CY_SMIF_PRESENT_1BYTE = 1, /**< mode/dummy 1 byte present */
CY_SMIF_PRESENT_2BYTE = 2, /**< mode/dummy 2 byte present */
} cy_en_smif_field_presence_t;
/** Specify whether command to be transmitted is last one or not */
typedef enum
{
NOT_LAST_COMMAND = 0, /**< not last command */
LAST_COMMAND_BYTE = 1,/**< last command */
} cy_en_smif_cmd_last_t;
/** Specifies which of the Functional Safety Status field bits are checked */
typedef enum
{
CY_SMIF_CHECK_FUNC_SAFETY = 0, /**< The associated Functional Safety Status bit is checked */
CY_SMIF_DONT_CHECK_FUNC_SAFETY = 1, /**< The associated Functional Safety Status bit is not checked
If the received Functional Safety Status bit = Functional Safety Status Error Polarity (STATUS_ERROR_POLARITY),
then a Functional Safety Status error interrupt and a XIP bus error response is generated. */
} cy_en_smif_crc_ctl_status_check_t;
/** Specifies the polarity of the Functional Safety Status field bits */
typedef enum
{
CY_SMIF_ERROR_POL_ACTIVE_LOW = 0, /**< The associated Functional Safety Status bit is active-low */
CY_SMIF_ERROR_POL_ACTIVE_HIGH = 1, /**< The associated Functional Safety Status bit is active-high */
} cy_en_smif_crc_ctl_error_pol_t;
/** Specifies which fields are included in the command / address CRC generation */
typedef enum
{
CY_SMIF_INC_ADDR_MODE = 0, /**< The command / address CRC field is generated over the address and (if present) mode fields only.*/
CY_SMIF_INC_CMD_ADDR_MODE = 1, /**< The command / address CRC field is generated over the command, address and (if present) mode fields.*/
} cy_en_smif_crc_input_scope_t;
/** Specifies the size of a memory sub page */
typedef enum
{
SUB_PAGE_SIZE_8BYTE = 0, /**< sub_page_size = 8 words = 16 bytes (default) */
SUB_PAGE_SIZE_16BYTE = 1, /**< sub_page_size = 16 words = 32 bytes */
SUB_PAGE_SIZE_32BYTE = 2, /**< sub_page_size = 32 words = 64 bytes */
SUB_PAGE_SIZE_64BYTE = 3,/**< sub_page_size = 64 words = 128 bytes */
} en_cy_sub_page_size_t;
/** Specifies the number of sub pages per page */
typedef enum
{
SUB_PAGE_1_PER_PAGE = 0, /**< 1 sub pages per page, i.e. page_size = sub_page_size */
SUB_PAGE_2_PER_PAGE = 1, /**< 2 sub pages per page, i.e. page_size = 2 x sub_page_size */
SUB_PAGE_4_PER_PAGE = 2, /**< 4 sub pages per page, i.e. page_size = 4 x sub_page_size */
SUB_PAGE_8_PER_PAGE = 3, /**< 8 sub pages per page, i.e. page_size = 8 x sub_page_size */
} en_cy_sub_page_nr_t;
/** Specifies the DLL speed mode */
typedef enum
{
CY_SMIF_DLL_SPEED_160_TO_180_MHZ = 0, /**< 160 MHz to 180 MHz PLL clock frequency for DLL */
CY_SMIF_DLL_SPEED_180_TO_266_MHZ = 1, /**< 181 MHz to 266 MHz PLL clock frequency for DLL */
CY_SMIF_DLL_SPEED_266_TO_333_MHZ = 2, /**< 267 MHz to 333 MHz PLL clock frequency for DLL */
CY_SMIF_DLL_SPEED_333_TO_400_MHZ = 3, /**< 334 MHz to 400 MHz PLL clock frequency for DLL */
} cy_en_smif_dll_clk_mode_t;
/** Specifies the RX capture mode */
typedef enum
{
CY_SMIF_RX_CAPTURE_MODE_SPI = 0, /**< Receive capture scheme - normal SPI without DLP */
CY_SMIF_RX_CAPTURE_MODE_SPI_DLP = 1, /**< Receive capture scheme - normal SPI with DLP */
CY_SMIF_RX_CAPTURE_MODE_XSPI_HB = 2, /**< Receive capture scheme - Hyperbus or xSPI */
} cy_en_smif_cap_mode_t;
/** \} group_smif_enums */
/**
* \addtogroup group_smif_data_structures
* \{
*/
/***************************************************************************//**
*
* The SMIF user callback function type called at the end of a transfer.
*
* \param event
* The event which caused a callback call.
*
*******************************************************************************/
typedef void (*cy_smif_event_cb_t)(uint32_t event);
/** Specifies the bit field of TX_CMD_FIFO_WR when cmd = "TX" command */
typedef struct
{
uint32_t firstByte : 8; /**< Specifies the transmitted Byte */
uint32_t secondByte : 8; /**< Specifies the second transmitted Byte. This is only used for octal data transfer with DDR mode */
uint32_t width : 2; /**< Specifies the width of the data transfer */
uint32_t dataRate : 1; /**< Specifies the mode of transfer rate */
uint32_t last : 1; /**< Specifies whether this is the last TX Byte */
uint32_t selectDev : 4; /**< Specifies which of the four devices are selected */
uint32_t cmd : 3; /**< Specifies the specific command */
uint32_t reserved0 : 5; /**< Reserved */
} cy_stc_smif_cmd_fifo_tx_t;
/** Specifies the bit field of TX_CMD_FIFO_WR when cmd = "TX_COUNT" command */
typedef struct
{
uint32_t dataNum : 16;/**< Specifies the number of to be transmitted memory data units */
uint32_t width : 2; /**< Specifies the width of the data transfer */
uint32_t dataRate : 1; /**< Specifies the mode of transfer rate */
uint32_t last : 1; /**< Specifies whether this is the last TX Byte */
uint32_t selectDev : 4; /**< Specifies which of the four devices are selected */
uint32_t cmd : 3; /**< Specifies the specific command */
uint32_t reserved0 : 5; /**< Reserved */
} cy_stc_smif_cmd_fifo_tx_count_t;
/** Specifies the bit field of TX_CMD_FIFO_WR when cmd = "RX_COUNT" command */
typedef struct
{
uint32_t dataNum : 16;/**< Specifies the number of to be received memory data units */
uint32_t width : 2; /**< Specifies the width of the data transfer */
uint32_t dataRate : 1; /**< Specifies the mode of transfer rate */
uint32_t last : 1; /**< Specifies whether this is the last TX Byte */
uint32_t selectDev : 4; /**< Specifies which of the four devices are selected */
uint32_t cmd : 3; /**< Specifies the specific command */
uint32_t reserved0 : 5; /**< Reserved */
} cy_stc_smif_cmd_fifo_rx_count_t;
/** Specifies the bit field of TX_CMD_FIFO_WR when cmd = "DUMMY_COUNT" command */
typedef struct
{
uint32_t cycleNum : 16;
uint32_t width : 2; /**< Specifies the width of the data transfer */
uint32_t dataRate : 1; /**< Specifies the mode of transfer rate */
uint32_t last : 1; /**< Specifies whether this is the last TX Byte */
uint32_t doubleDm : 1; /**< specifies whether an active RWDS refresh indicator (captured with the previous rising memory clock output) causes to double the number of dummy cycles. This is used for the variable latency in HyperRAM. */
uint32_t rwdsInDm : 1; /**< specifies whether the RWDS output signal should be driven starting in the last dummy cycle until DESELECT. This is needed for write transactions with RWDS (e.g. Hyperbus) before a TX_COUNT command. */
uint32_t dlpEn : 1; /**< specifies whether data learning is enabled. In XIP mode this field is set for read transactions when CTL.INT_CLOCK_DL_ENABLED is "1"). */
uint32_t capEn : 1; /**< specifies whether RWDS / DQS based capturing is enabled in the last dummy cycle, i.e. this needs to be set to '1' for read transactions to memory device using RWDS / DQS capturing scheme. */
uint32_t cmd : 3; /**< Specifies the specific command */
uint32_t reserved0 : 5; /**< Reserved */
} cy_stc_smif_cmd_fifo_dm_t;
/** Specifies the bit field of TX_CMD_FIFO_WR when cmd = "DESELECT" command */
typedef struct
{
uint32_t reserved1 : 24; /**< Reserved */
uint32_t cmd : 3; /**< Specifies the specific command */
uint32_t reserved0 : 5; /**< Reserved */
} cy_stc_smif_cmd_fifo_deselect_t;
/** union for TX_CMD_FIFO_WR as per it's commands */
typedef union
{
cy_stc_smif_cmd_fifo_tx_t fieldTx; /**< Bit field when cmd = "TX" command \ref cy_stc_smif_cmd_fifo_tx_t */
cy_stc_smif_cmd_fifo_tx_count_t fieldTxCount; /**< Bit field when cmd = "TX_COUNT" command \ref cy_stc_smif_cmd_fifo_tx_count_t */
cy_stc_smif_cmd_fifo_rx_count_t fieldRxCount; /**< Bit field when cmd = "RX_COUNT" command \ref cy_stc_smif_cmd_fifo_rx_count_t */
cy_stc_smif_cmd_fifo_dm_t fieldDummy; /**< Bit field when cmd = "DUMMY_COUNT" command \ref cy_stc_smif_cmd_fifo_dm_t */
cy_stc_smif_cmd_fifo_deselect_t fieldDeselect; /**< Bit field when cmd = "DESELECT" command \ref cy_stc_smif_cmd_fifo_deselect_t */
uint32_t u32; /**< 32-bit access */
} cy_un_smif_cmd_fifo_t;
/** The SMIF configuration structure. */
typedef struct
{
cy_en_smif_clk_tx_t txClk; /**< TX clock source selection \ref cy_en_smif_clk_tx_t (ignored from SMIF_4) */
cy_en_smif_clk_rx_t rxClk; /**< RX clock source selection \ref cy_en_smif_clk_rx_t (ignored from SMIF_4) */
cy_en_smif_delay_line_t delaySel; /**< Delay line selection for RX clock \ref cy_en_smif_delay_line_t (ignored from SMIF_4) */
cy_en_smif_dlp_auto_t dlpAuto; /**< Use SW calibration or HW calibration \ref cy_en_smif_dlp_auto_t (ignored from SMIF_4) */
cy_en_smif_ddr_capture_delay_t capDelay; /**< Selection for capture delay \ref cy_en_smif_ddr_capture_delay_t (ignored from SMIF_4) */
cy_en_smif_deselection_t deselectDelay; /**< \ref cy_en_smif_deselection_t */
cy_en_smif_setup_delay_t setupDelay; /**< \ref cy_en_smif_setup_delay_t */
cy_en_smif_hold_delay_t holdDelay; /**< \ref cy_en_smif_hold_delay_t */
cy_en_smif_mode_t mode; /**< Specifies the mode of operation \ref cy_en_smif_mode_t. */
cy_en_smif_error_event_t blockEvent; /**< Specifies what happens when there is a Read
* from an empty RX FIFO or a Write to a full
* TX FIFO. \ref cy_en_smif_error_event_t. */
cy_en_cy_clkif_source_t clkIfSrc; /**< \ref cy_en_cy_clkif_source_t */
void* pDllCfg; /**< Pointer to configuration parameter structure for DLL. This is ignored for smif driver versions other than SMIF_4
Set pointer to \ref cy_stc_smif_dll_config_t for SMIF_4 */
} cy_stc_smif_config_t;
/** The SMIF internal context data. The user must not modify it. */
typedef struct
{
uint8_t volatile * volatile txBufferAddress; /**< The pointer to the data to transfer */
/**
* The transfer counter.
*/
uint32_t volatile txBufferCounter;
uint8_t volatile * volatile rxBufferAddress; /**< The pointer to the variable where the received data is stored */
/**
* The transfer counter.
*/
uint32_t volatile rxBufferCounter;
/**
* The status of the transfer. The transmitting / receiving is completed / in progress
*/
cy_en_smif_txfr_status_t volatile transferStatus;
cy_smif_event_cb_t volatile txCmpltCb; /**< The user-defined callback executed at the completion of a transmission */
cy_smif_event_cb_t volatile rxCmpltCb; /**< The user-defined callback executed at the completion of a reception */
/**
* The timeout in microseconds for the blocking functions. This timeout value applies to all blocking APIs.
*/
uint32_t timeout;
cy_en_smif_data_rate_t preCmdDataRate;
cy_en_smif_txfr_width_t preCmdWidth;
uint32_t volatile txCmdBufCounter;
} cy_stc_smif_context_t;
/** TX/RX CMD/MODE control in XIP mode */
typedef struct
{
uint16_t cmd; /**< Command byte code. If presence = CY_SMIF_PRESENT_1BYTE, only lower 8bit is active. */
cy_en_smif_txfr_width_t width; /**< Width of data transfer \ref cy_en_smif_txfr_width_t */
cy_en_smif_data_rate_t dataRate; /**< Mode of transfer rate \ref cy_en_smif_data_rate_t */
cy_en_smif_field_presence_t presence; /**< Presence of command field \ref cy_en_smif_field_presence_t */
} stc_cy_smif_cmd_mode_ctl_t;
/** TX/RX ADDR/DATA control in XIP mode */
typedef struct
{
cy_en_smif_txfr_width_t width; /**< Width of data transfer \ref cy_en_smif_txfr_width_t */
cy_en_smif_data_rate_t dataRate; /**< Mode of transfer rate \ref cy_en_smif_data_rate_t */
} stc_cy_smif_addr_data_ctl_t;
/** RX DUMMY control in XIP mode */
typedef struct
{
uint8_t numOfDummy; /**< Number of dummy cycles */
cy_en_smif_field_presence_t presence; /**< Presence of dummy cycles. If presence == CY_SMIF_PRESENT_2BYTE, Dummy cycles are doubled
when RWDS refresh indicator is high during CA cycle. (HyperRAM variable latency mode) */
} stc_cy_smif_rd_dummy_ctl_t;
/** TX DUMMY control in XIP mode */
typedef struct
{
uint8_t numOfDummy; /**< Number of dummy cycles */
bool rwdsEn; /**< Read-Write-Data-Strobe Enable. Specifies whether the RWDS output signal
should be driven starting in the last dummy cycle until DESELECT.
This is needed for write transactions with byte masking via RWDS (e.g. Hyperbus).
'0': do not drive RWDS output
'1': drive RWDS output starting in last dummy cycle until DESELECT */
cy_en_smif_field_presence_t presence; /**< Presence of dummy cycles. If presence == CY_SMIF_PRESENT_2BYTE, Dummy cycles are doubled
when RWDS refresh indicator is high during CA cycle. (HyperRAM variable latency mode) */
} stc_cy_smif_wr_dummy_ctl_t;
/** RX CRC control in XIP mode */
typedef struct
{
uint8_t inputSize; /**< Number of input data bytes for CRC generation */
cy_en_smif_crc_ctl_status_check_t funcSafeChecked; /**< Specifies which of the Functional Safety Status field bits are checked.
There is 1 mask bit for each Functional Safety Status bit.
\ref cy_en_smif_crc_ctl_status_check_t */
cy_en_smif_crc_ctl_error_pol_t errPol; /**< Specifies the polarity of the Functional Safety Status field bits.
There is 1 polarity bit for each Functional Safety Status bit.
\ref cy_en_smif_crc_ctl_status_check_t */
cy_en_smif_txfr_width_t width; /**< Width of command / address CRC field. \ref cy_en_smif_txfr_width_t */
cy_en_smif_data_rate_t dataRate; /**< Mode of transfer rate of command / address CRC field \ref cy_en_smif_data_rate_t */
cy_en_smif_crc_input_scope_t inputScope; /**< Specifies which fields are included in the command / address CRC generation \ref cy_en_smif_crc_input_scope_t */
bool crcChecked; /**< Specifies whether or not the read data CRC field is checked.
'0': Read data CRC field is reserved in RX data stream, but not checked.
'1': Read data CRC field is checked in RX data stream. If CRC does not match an CRC error interrupt and a XIP bus error response is generated. */
bool cmd_addrCrcPresent; /**< Presence of command / address CRC field */
bool dataCrcPresent; /**< Presence of data CRC field */
} stc_cy_smif_rd_crc_ctl_t;
/** TX CRC control in XIP mode */
typedef struct
{
uint8_t inputSize; /**< Number of input data bytes for CRC generation */
cy_en_smif_txfr_width_t width; /**< Width of command / address CRC field \ref cy_en_smif_txfr_width_t */
cy_en_smif_data_rate_t dataRate; /**< Mode of transfer rate of command / address CRC field \ref cy_en_smif_data_rate_t */
cy_en_smif_crc_input_scope_t inputScope; /**< Specifies which fields are included in the command / address CRC generation \ref cy_en_smif_crc_input_scope_t*/
bool cmd_addrCrcPresent; /**< Presence of command / address CRC field */
bool dataCrcPresent; /**< Presence of data CRC field */
} stc_cy_smif_wr_crc_ctl_t;
/** RX BOUND control in XIP mode */
typedef struct
{
uint8_t numOfCycle; /**< Number of base latency cycles used for calculating the number of fist page boundary crossing latency cycles */
en_cy_sub_page_size_t subPageSize; /**< Specifies the size of a memory sub page \ref en_cy_sub_page_size_t */
en_cy_sub_page_nr_t subPageNr; /**< Specifies the number of sub pages per page \ref en_cy_sub_page_nr_t */
bool subsqBndEn; /**< Enable subsequent page boundary latency cycles */
bool bdLPresent; /**< Presence of first page boundary latency cycles */
} stc_cy_smif_rd_bound_ctl_t;
/** \} group_smif_data_structures */
/**
* \addtogroup group_smif_low_level_functions
* \{
*/
extern cy_en_smif_mode_t Cy_SMIF_GetMode(volatile cy_stc_smif_reg_t *base);
extern void Cy_SMIF_DeviceSetDataSelect(volatile cy_stc_smif_reg_device_t *device, cy_en_smif_data_select_t sel);
extern void Cy_SMIF_DeviceEnable(volatile cy_stc_smif_reg_device_t *device);
extern void Cy_SMIF_DeviceDisable(volatile cy_stc_smif_reg_device_t *device);
extern void Cy_SMIF_DeviceWriteEnable(volatile cy_stc_smif_reg_device_t *device);
extern void Cy_SMIF_DeviceWriteDisable(volatile cy_stc_smif_reg_device_t *device);
extern void Cy_SMIF_DeviceCryptoEnable(volatile cy_stc_smif_reg_device_t *device);
extern void Cy_SMIF_DeviceCryptoDisable(volatile cy_stc_smif_reg_device_t *device);
extern void Cy_SMIF_DeviceTransferMergingEnable(volatile cy_stc_smif_reg_device_t *device, cy_en_smif_dev_merge_timeout_t timeout);
extern void Cy_SMIF_DeviceTransferMergingDisable(volatile cy_stc_smif_reg_device_t *device);
extern void Cy_SMIF_DeviceTotalTimeoutEnable(volatile cy_stc_smif_reg_device_t *device, uint16_t timeout);
extern void Cy_SMIF_DeviceTotalTimeoutDisable(volatile cy_stc_smif_reg_device_t *device);
extern uint8_t Cy_SMIF_GetReadStatus(volatile cy_stc_smif_reg_device_t *device);
extern void Cy_SMIF_SetXIPBaseAddress(volatile cy_stc_smif_reg_device_t *device, uint32_t addr);
extern void Cy_SMIF_SetXIPAddressSize(volatile cy_stc_smif_reg_device_t *device, cy_en_device_size_t size);
extern void Cy_SMIF_SetXIPAddrCtl(volatile cy_stc_smif_reg_device_t *device, cy_en_smif_xip_addr_byte_t addrSize, bool divForDualQuad);
extern void Cy_SMIF_SetReadCmdCtl(volatile cy_stc_smif_reg_device_t *device, const stc_cy_smif_cmd_mode_ctl_t *config);
extern void Cy_SMIF_SetWriteCmdCtl(volatile cy_stc_smif_reg_device_t *device, const stc_cy_smif_cmd_mode_ctl_t *config);
extern void Cy_SMIF_SetReadAddrCtl(volatile cy_stc_smif_reg_device_t *device, const stc_cy_smif_addr_data_ctl_t *config);
extern void Cy_SMIF_SetWriteAddrCtl(volatile cy_stc_smif_reg_device_t *device, const stc_cy_smif_addr_data_ctl_t *config);
extern void Cy_SMIF_SetReadModeCtl(volatile cy_stc_smif_reg_device_t *device, const stc_cy_smif_cmd_mode_ctl_t *config);
extern void Cy_SMIF_SetWriteModeCtl(volatile cy_stc_smif_reg_device_t *device, const stc_cy_smif_cmd_mode_ctl_t *config);
extern void Cy_SMIF_SetReadDummyCtl(volatile cy_stc_smif_reg_device_t *device, const stc_cy_smif_rd_dummy_ctl_t *config);
extern void Cy_SMIF_SetWriteDummyCtl(volatile cy_stc_smif_reg_device_t *device, const stc_cy_smif_wr_dummy_ctl_t *config);
extern void Cy_SMIF_SetReadDataCtl(volatile cy_stc_smif_reg_device_t *device, const stc_cy_smif_addr_data_ctl_t *config);
extern void Cy_SMIF_SetWriteDataCtl(volatile cy_stc_smif_reg_device_t *device, const stc_cy_smif_addr_data_ctl_t *config);
extern void Cy_SMIF_SetReadCrcCtl(volatile cy_stc_smif_reg_device_t *device, const stc_cy_smif_rd_crc_ctl_t *config);
extern void Cy_SMIF_SetWriteCrcCtl(volatile cy_stc_smif_reg_device_t *device, const stc_cy_smif_wr_crc_ctl_t *config);
extern void Cy_SMIF_SetReadBoundCtl(volatile cy_stc_smif_reg_device_t *device, const stc_cy_smif_rd_bound_ctl_t *config);
extern void Cy_SMIF_Disable(volatile cy_stc_smif_reg_t *base);
extern void Cy_SMIF_SetInterruptMask(volatile cy_stc_smif_reg_t *base, uint32_t interrupt);
extern uint32_t Cy_SMIF_GetInterruptMask(volatile cy_stc_smif_reg_t *base);
extern uint32_t Cy_SMIF_GetInterruptStatusMasked(volatile cy_stc_smif_reg_t *base);
extern uint32_t Cy_SMIF_GetInterruptStatus(volatile cy_stc_smif_reg_t *base);
extern void Cy_SMIF_SetInterrupt(volatile cy_stc_smif_reg_t *base, uint32_t interrupt);
extern void Cy_SMIF_ClearInterrupt(volatile cy_stc_smif_reg_t *base, uint32_t interrupt);
extern void Cy_SMIF_SetRxFifoTriggerLevel(volatile cy_stc_smif_reg_t *base, uint32_t level);
extern uint32_t Cy_SMIF_GetCmdFifoStatus(volatile cy_stc_smif_reg_t *base);
extern uint32_t Cy_SMIF_GetRxFifoStatus(volatile cy_stc_smif_reg_t *base);
extern bool Cy_SMIF_IsBusy(volatile cy_stc_smif_reg_t *base);
extern void Cy_SMIF_Interrupt(volatile cy_stc_smif_reg_t *base, cy_stc_smif_context_t *context);
extern void Cy_SMIF_PopRxFifo(volatile cy_stc_smif_reg_t *baseaddr, cy_stc_smif_context_t *context);
extern uint8_t Cy_SMIF_CheckRxFifoContents(volatile cy_stc_smif_reg_t *baseaddr);
extern uint32_t Cy_SMIF_PackBytesArray(uint8_t const buff[], bool fourBytes);
extern void Cy_SMIF_UnPackByteArray(uint32_t inValue, uint8_t outBuff[], bool fourBytes);
extern cy_en_smif_status_t Cy_SMIF_TimeoutRun(uint32_t *timeoutUnits);
extern uint32_t CY_SMIF_GetDeviceNumber(volatile void *base);
extern uint32_t CY_SMIF_GetDelayTapsNumber(volatile void *base);
extern uint32_t CY_SMIF_GetDelayLinesNumber(volatile void *base);
extern uint32_t CY_SMIF_GetXIP_Mask(volatile void *base);
extern uint32_t CY_SMIF_GetXIP_Address(volatile void *base);
extern uint32_t Cy_SMIF_MaskValueToSizeInByte(cy_en_device_size_t mask);
extern uint32_t Cy_SMIF_Reverse4ByteEndian(uint32_t in);
extern cy_en_smif_status_t Cy_SMIF_TransmitCommand(volatile cy_stc_smif_reg_t *base, uint16_t cmd, bool isCommand2Byte, cy_en_smif_txfr_width_t cmdTxfrWidth, cy_en_smif_data_rate_t cmdDataRate, uint8_t const cmdParam[], uint32_t paramSize, cy_en_smif_txfr_width_t paramTxfrWidth, cy_en_smif_data_rate_t paramDataRate, cy_en_smif_slave_select_t slaveSelect, cy_en_smif_cmd_last_t cmpltTxfr, cy_stc_smif_context_t *context);
extern cy_en_smif_status_t Cy_SMIF_TransmitData(volatile cy_stc_smif_reg_t *base, const uint8_t *txBuffer, uint32_t size, cy_en_smif_txfr_width_t transferWidth, cy_en_smif_data_rate_t dataDataRate, cy_en_smif_slave_select_t slaveSelect, cy_smif_event_cb_t TxCmpltCb, cy_stc_smif_context_t *context);
extern cy_en_smif_status_t Cy_SMIF_TransmitDataBlocking(volatile cy_stc_smif_reg_t *base, const uint8_t *txBuffer, uint32_t size, cy_en_smif_txfr_width_t transferWidth, cy_en_smif_data_rate_t dataDataRate, cy_en_smif_slave_select_t slaveSelect, cy_stc_smif_context_t *context);
extern cy_en_smif_status_t Cy_SMIF_ReceiveDataCmd(volatile cy_stc_smif_reg_t *base, uint8_t *rxBuffer, uint32_t size, cy_en_smif_txfr_width_t transferWidth, cy_en_smif_data_rate_t dataRate, cy_en_smif_slave_select_t slaveSelect, cy_smif_event_cb_t RxCmpltCb, cy_stc_smif_context_t *context);
extern cy_en_smif_status_t Cy_SMIF_ReceiveData(volatile cy_stc_smif_reg_t *base, uint8_t *rxBuffer, uint32_t size, cy_en_smif_txfr_width_t transferWidth, cy_en_smif_data_rate_t dataRate, cy_en_smif_slave_select_t slaveSelect, cy_smif_event_cb_t RxCmpltCb, cy_stc_smif_context_t *context);
extern cy_en_smif_status_t Cy_SMIF_ReceiveDataBlocking(volatile cy_stc_smif_reg_t *base, uint8_t *rxBuffer, uint32_t size, cy_en_smif_txfr_width_t transferWidth, cy_en_smif_data_rate_t dataRate, cy_en_smif_slave_select_t slaveSelect, cy_stc_smif_context_t *context);
extern cy_en_smif_status_t Cy_SMIF_SendDummyCycles(volatile cy_stc_smif_reg_t *base, cy_en_smif_txfr_width_t transferWidth, cy_en_smif_data_rate_t dataRate, bool doubleDm, bool rwdsInDm, bool dlpEn, bool capEn, uint32_t cycles, cy_stc_smif_context_t *context);
extern cy_en_smif_status_t Cy_SMIF_Deselect(volatile cy_stc_smif_reg_t *base, cy_stc_smif_context_t *context);
extern cy_en_smif_txfr_status_t Cy_SMIF_GetTxfrStatus(volatile cy_stc_smif_reg_t *base, cy_stc_smif_context_t const *context);
extern void Cy_SMIF_Enable(volatile cy_stc_smif_reg_t *base, cy_stc_smif_context_t *context);
extern cy_en_smif_status_t Cy_SMIF_CacheEnable(volatile cy_stc_smif_reg_t *base, cy_en_smif_cache_en_t cacheType);
extern cy_en_smif_status_t Cy_SMIF_CacheDisable(volatile cy_stc_smif_reg_t *base, cy_en_smif_cache_en_t cacheType);
extern cy_en_smif_status_t Cy_SMIF_CachePrefetchingEnable(volatile cy_stc_smif_reg_t *base, cy_en_smif_cache_en_t cacheType);
extern cy_en_smif_status_t Cy_SMIF_CachePrefetchingDisable(volatile cy_stc_smif_reg_t *base, cy_en_smif_cache_en_t cacheType);
extern cy_en_smif_status_t Cy_SMIF_CacheInvalidate(volatile cy_stc_smif_reg_t *base, cy_en_smif_cache_en_t cacheType);
extern cy_en_smif_status_t Cy_SMIF_SetMode(volatile cy_stc_smif_reg_t *base, cy_en_smif_mode_t mode);
extern cy_en_smif_status_t Cy_SMIF_CRC_Calibration(volatile cy_stc_smif_reg_t *base, uint8_t inData[], uint32_t sizeInByte, uint8_t *result);
extern volatile cy_stc_smif_reg_t * Cy_SMIF_GetSmifBasePtrFromAnySmifPtr(volatile void *any_smif_address);
extern cy_en_smif_slave_select_t Cy_SMIF_GetSlaveSelectFromDeviceBasePtr(volatile cy_stc_smif_reg_device_t *device);
extern cy_en_smif_slave_select_t Cy_SMIF_GetSlaveSelectFromDeviceNumber(uint8_t device_number);
extern volatile cy_stc_smif_reg_device_t * Cy_SMIF_GetDeviceBasePtrFromSmifBasePtrAndSlaveSelect(volatile cy_stc_smif_reg_t *base, cy_en_smif_slave_select_t slave);
extern volatile cy_stc_smif_reg_device_t * Cy_SMIF_GetDeviceBasePtrFromSmifBasePtrAndDeviceNumber(volatile cy_stc_smif_reg_t *base, uint8_t device_number);
extern cy_en_syspm_status_t Cy_SMIF_DeepSleepCallback(cy_stc_syspm_callback_params_t *callbackParams);
extern cy_en_syspm_status_t Cy_SMIF_HibernateCallback(cy_stc_syspm_callback_params_t *callbackParams);
/** \} group_smif_low_level_functions */
#if defined(__cplusplus)
}
#endif
#endif /* CY_IP_MXSMIF */
#endif /* (CY_SMIF_H) */
/** \} group_smif */
/* [] END OF FILE */
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,296 @@
/***************************************************************************//**
* \file cy_smif_memslot.h
* \version `$CY_MAJOR_VERSION`.`$CY_MINOR_VERSION`.1
*
* \brief
* This file provides the constants and parameter values for the memory-level
* APIs of the SMIF driver.
*
* Note:
*
********************************************************************************
* \copyright
* Copyright 2016-2018, Cypress Semiconductor Corporation. All rights reserved.
* You may use this file only in accordance with the license, terms, conditions,
* disclaimers, and limitations in the end user license agreement accompanying
* the software package with which this file was provided.
*******************************************************************************/
#if !defined(CY_SMIF_MEMORYSLOT_H)
#define CY_SMIF_MEMORYSLOT_H
#include <stdint.h>
#include <stdbool.h>
#include "syslib/cy_syslib.h"
#include "cy_device_headers.h"
#include "cy_project.h"
#if defined(__cplusplus)
extern "C" {
#endif
/**
* \addtogroup group_smif_macros_status
* \{
*/
/***************************************
* Constants
****************************************/
#define CY_SMIF_DEVICE_BUSY (1U) /**< The external memory is busy */
#define CY_SMIF_DEVICE_READY (0U) /**< The external memory is ready */
/** \} group_smif_macros_status */
/**
* \addtogroup group_smif_macros_cmd
* \{
*/
#define CY_SMIF_CMD_WITHOUT_PARAM (0U) /**< No parameter */
#define CY_SMIF_TX_LAST_BYTE (1U) /**< The last byte in the command transmission
* (SS is set high after the transmission)
*/
#define CY_SMIF_TX_NOT_LAST_BYTE (0U) /**< Not the last byte in the command transmission
* (SS remains low after the transmission)
*/
#define CY_SMIF_READ_ONE_BYTE (1U) /**< Read 1 byte */
#define CY_SMIF_WRITE_ONE_BYTE (1U) /**< Write 1 byte */
#define CY_SMIF_WRITE_TWO_BYTES (2U) /**< Write 2 bytes */
#define CY_SMIF_ONE_WORD (4U) /**< 4 bytes */
#define CY_SMIF_DUAL_QUAD_DISABLED (0U) /**< The dual quad transmission mode is disabled */
#define CY_SMIF_DUAL_QUAD_ENABLED (1U) /**< The dual quad transmission mode is enabled */
/** \} group_smif_macros_status */
/**
* \addtogroup group_smif_macros_flags
* \{
*/
#define CY_SMIF_FLAG_ALL_DISABLED (0U) /**< All memory configuration flags are disabled */
/** Enables the write capability for the memory slave in the memory-mapped
* mode. Valid when the memory-mapped mode is enabled */
#define CY_SMIF_FLAG_WR_EN (SMIF_DEVICE_CTL_WR_EN_Msk)
/** Determines if the device is memory-mapped. If enabled, this memory slot will
* be initialized in System init */
#define CY_SMIF_FLAG_MEMORY_MAPPED (2U)
#define CY_SMIF_FLAG_DETECT_SFDP (4U) /**< Enables the Autodetect using the SFDP */
/** Enables the crypto support for this memory slave. All access to the
* memory device goes through the encryption/decryption
* Valid when the memory-mapped mode is enabled */
#define CY_SMIF_FLAG_CRYPTO_EN (SMIF_DEVICE_CTL_CRYPTO_EN_Msk)
/** \} group_smif_macros_flags */
/**
* \addtogroup group_smif_data_structures_memslot
* \{
*/
/** This structure is used to store the read dummy configuration. */
typedef struct
{
stc_cy_smif_rd_dummy_ctl_t dummyCtl; /**< specifies existence of dummy and the number */
bool doubleDm; /**< specifies whether an active RWDS refresh indicator (captured with the previous rising memory clock output) causes to double the number of dummy cycles. This is used for the variable latency in HyperRAM. */
bool rwdsInDm; /**< specifies whether the RWDS output signal should be driven starting in the last dummy cycle until DESELECT. This is needed for write transactions with RWDS (e.g. Hyperbus) before a TX_COUNT command. */
bool dlpEn; /**< specifies whether data learning is enabled. In XIP mode this field is set for read transactions when CTL.INT_CLOCK_DL_ENABLED is "1"). */
bool capEn; /**< specifies whether RWDS / DQS based capturing is enabled in the last dummy cycle, i.e. this needs to be set to '1' for read transactions to memory device using RWDS / DQS capturing scheme. */
} stc_smif_mem_rd_dm_ctl_t;
/** This structure is used to store the write dummy configuration. */
typedef struct
{
stc_cy_smif_wr_dummy_ctl_t dummyCtl; /**< specifies existence of dummy and the number */
bool doubleDm; /**< specifies whether an active RWDS refresh indicator (captured with the previous rising memory clock output) causes to double the number of dummy cycles. This is used for the variable latency in HyperRAM. */
bool rwdsInDm; /**< specifies whether the RWDS output signal should be driven starting in the last dummy cycle until DESELECT. This is needed for write transactions with RWDS (e.g. Hyperbus) before a TX_COUNT command. */
bool dlpEn; /**< specifies whether data learning is enabled. In XIP mode this field is set for read transactions when CTL.INT_CLOCK_DL_ENABLED is "1"). */
bool capEn; /**< specifies whether RWDS / DQS based capturing is enabled in the last dummy cycle, i.e. this needs to be set to '1' for read transactions to memory device using RWDS / DQS capturing scheme. */
} stc_smif_mem_wr_dm_ctl_t;
/** This structure stores sequence for one read command specified by external device. */
typedef struct
{
stc_cy_smif_cmd_mode_ctl_t cmdCtl; /**< RX CMD control in XIP mode */
stc_cy_smif_addr_data_ctl_t addrCtl; /**< RX ADDR control in XIP mode */
stc_cy_smif_cmd_mode_ctl_t modeCtl; /**< RX MODE control in XIP mode */
stc_smif_mem_rd_dm_ctl_t memDummyCtl; /**< RX DUMMY control in XIP mode */
stc_cy_smif_addr_data_ctl_t dataCtl; /**< RX DATA control in XIP mode */
stc_cy_smif_rd_crc_ctl_t crcCtl; /**< RX CRC control in XIP mode */
stc_cy_smif_rd_bound_ctl_t boundCtl; /**< RX BOUND control in XIP mode */
} cy_stc_smif_mem_rd_cmd_t;
/** This structure stores sequence for one write command specified by external device. */
typedef struct
{
stc_cy_smif_cmd_mode_ctl_t cmdCtl; /**< TX CMD control in XIP mode */
stc_cy_smif_addr_data_ctl_t addrCtl; /**< TX ADDR control in XIP mode */
stc_cy_smif_cmd_mode_ctl_t modeCtl; /**< TX MODE control in XIP mode */
stc_smif_mem_wr_dm_ctl_t memDummyCtl;/**< TX DUMMY control in XIP mode */
stc_cy_smif_addr_data_ctl_t dataCtl; /**< TX DATA control in XIP mode */
stc_cy_smif_wr_crc_ctl_t crcCtl; /**< TX CRC control in XIP mode */
} cy_stc_smif_mem_wr_cmd_t;
/** This structure stores sequence for one command specified by external device. */
typedef struct
{
stc_cy_smif_cmd_mode_ctl_t cmdCtl; /**< TX CMD control */
} cy_stc_smif_mem_cmd_t;
/**
*
* This configuration structure of the SMIF memory device is used to store
* device-specific parameters.
* These parameters are used to set up the memory mode initialization and the
* memory API.
*/
typedef struct
{
bool isCommand2Byte;
cy_en_smif_xip_addr_byte_t numOfAddrBytes; /**< This specifies the number of address bytes used by the
* memory slave device, valid values 1-4 */
cy_stc_smif_mem_rd_cmd_t* readCmd; /**< This specifies the Read command */
cy_stc_smif_mem_cmd_t* writeEnCmd; /**< This specifies the Write Enable command */
cy_stc_smif_mem_cmd_t* writeDisCmd; /**< This specifies the Write Disable command */
cy_stc_smif_mem_cmd_t* eraseCmd; /**< This specifies the Erase command */
cy_stc_smif_mem_cmd_t* chipEraseCmd; /**< This specifies the Chip Erase command */
cy_stc_smif_mem_wr_cmd_t* programCmd; /**< This specifies the Program command */
uint32_t programSize; /**< This specifies the page size for programming */
cy_stc_smif_mem_cmd_t* readStsRegWipCmd; /**< This specifies the command to read the WIP-containing status register */
cy_stc_smif_mem_cmd_t* readStsRegQeCmd; /**< This specifies the command to read the QE-containing status register */
cy_stc_smif_mem_cmd_t* writeStsRegQeCmd; /**< This specifies the command to write into the QE-containing status register */
uint32_t stsRegBusyMask; /**< The Busy mask for the status registers */
uint32_t stsRegQuadEnableMask; /**< The QE mask for the status registers */
uint32_t stsRegProtectionMask;
} cy_stc_smif_mem_device_cfg_t;
/**
*
* This SMIF memory configuration structure is used to store the memory configuration for the memory mode of operation.
* This data structure is stored in a fixed location in the flash. The data structure is required
* for the initialization of the SMIF in the SystemInit.
*/
typedef struct
{
/** Determines the slave select where the memory device is placed */
cy_en_smif_slave_select_t slaveSelect;
/** Determines if the device is memory-mapped, enables the Autodetect
* using the SFDP, enables the write capability, or enables the crypto
* support for this memory slave */
bool writeEn;
bool crypteEn;
bool XIPSettingEn;
/** The data-line selection options for a slave device */
cy_en_smif_data_select_t dataSelect;
/** The base address the memory slave is mapped to in the PSoC memory map.
* This address must be a multiple of the SMIF XIP memory size/capacity. The
* SMIF XIP memory region should NOT overlap with other memory regions
* (with exception to dual quad mode). Valid when the memory-mapped mode is
* enabled.
*/
uint32_t baseAddress;
/** The size/capacity allocated in the PSoC memory map for the memory slave
* device. The capacity is allocated from the base address. The capacity
* must be a power of 2 and greater or equal than 64 KB. Valid when
* memory-mapped mode is enabled
*/
cy_en_device_size_t memMappedSize;
/** Defines if this memory device is one of the devices in the dual quad SPI
* configuration. Equals the sum of the slave-slot numbers. */
uint32_t dualQuadSlots;
cy_stc_smif_mem_device_cfg_t *deviceCfg; /**< The configuration of the device */
} cy_stc_smif_mem_config_t;
/**
*
* This SMIF memory configuration structure is used to store the memory configuration for the memory mode of operation.
* This data structure is stored in a fixed location in the flash. The data structure is required
* for the initialization of the SMIF in the SystemInit.
*/
typedef struct
{
uint32_t memCount; /**< The number of SMIF memory defined */
cy_stc_smif_mem_config_t **memConfig; /**< The pointer to the array of the memory configuration structures of size Memory_count */
uint32_t majorVersion; /**< The version of the SMIF driver */
uint32_t minorVersion; /**< The version of the SMIF driver */
} cy_stc_smif_block_config_t;
/** \} group_smif_data_structures_memslot */
/**
* \addtogroup group_smif_mem_slot_functions
* \{
*/
cy_en_smif_status_t Cy_SMIF_Memslot_Init(cy_stc_smif_reg_t volatile *base,
const cy_stc_smif_block_config_t* blockConfig,
cy_stc_smif_context_t *context);
void Cy_SMIF_Memslot_DeInit(cy_stc_smif_reg_t volatile *base);
cy_en_smif_status_t Cy_SMIF_Memslot_CmdWriteEnable(cy_stc_smif_reg_t volatile *base,
cy_stc_smif_mem_config_t const *memDevice,
cy_stc_smif_context_t *context);
cy_en_smif_status_t Cy_SMIF_Memslot_CmdWriteDisable(cy_stc_smif_reg_t volatile *base,
cy_stc_smif_mem_config_t const *memDevice,
cy_stc_smif_context_t *context);
bool Cy_SMIF_Memslot_IsBusy(cy_stc_smif_reg_t volatile *base, cy_stc_smif_mem_config_t *memDevice,
cy_stc_smif_context_t *context);
cy_en_smif_status_t Cy_SMIF_Memslot_QuadEnable(cy_stc_smif_reg_t volatile *base,
cy_stc_smif_mem_config_t *memDevice,
cy_stc_smif_context_t *context);
cy_en_smif_status_t Cy_SMIF_Memslot_BlockProtNone(cy_stc_smif_reg_t volatile *base,
cy_stc_smif_mem_config_t *memDevice,
cy_stc_smif_context_t *context);
cy_en_smif_status_t Cy_SMIF_Memslot_CmdReadSts(cy_stc_smif_reg_t volatile *base,
cy_stc_smif_mem_config_t const *memDevice,
uint8_t *status,
uint16_t command,
cy_en_smif_txfr_width_t dataWidth,
cy_en_smif_data_rate_t dataRate,
cy_stc_smif_context_t *context);
cy_en_smif_status_t Cy_SMIF_Memslot_CmdWriteSts(cy_stc_smif_reg_t volatile *base,
cy_stc_smif_mem_config_t const *memDevice,
void const *status,
uint8_t command,
cy_en_smif_txfr_width_t dataWidth,
cy_en_smif_data_rate_t dataRate,
cy_stc_smif_context_t *context);
cy_en_smif_status_t Cy_SMIF_Memslot_CmdChipErase(cy_stc_smif_reg_t volatile *base,
cy_stc_smif_mem_config_t const *memDevice,
cy_stc_smif_context_t *context);
cy_en_smif_status_t Cy_SMIF_Memslot_CmdSectorErase(cy_stc_smif_reg_t volatile *base,
cy_stc_smif_mem_config_t *memDevice,
uint32_t sectorAddr,
cy_stc_smif_context_t *context);
cy_en_smif_status_t Cy_SMIF_Memslot_CmdProgram(cy_stc_smif_reg_t volatile *base,
cy_stc_smif_mem_config_t const *memDevice,
uint32_t deviceAddr,
uint8_t* writeBuff,
uint32_t size,
cy_smif_event_cb_t cmdCmpltCb,
cy_stc_smif_context_t *context);
cy_en_smif_status_t Cy_SMIF_Memslot_CmdRead(cy_stc_smif_reg_t volatile *base,
cy_stc_smif_mem_config_t const *memDevice,
uint32_t deviceAddr,
uint8_t* readBuff,
uint32_t size,
cy_smif_event_cb_t cmdCmpltCb,
cy_stc_smif_context_t *context);
/** \} group_smif_mem_slot_functions */
#if defined(__cplusplus)
}
#endif
#endif /* (CY_SMIF_MEMORYSLOT_H) */
/* [] END OF FILE */
@@ -0,0 +1,4 @@
V2_0 for BH4M and BH8M devices.
V2_0 represents SMIF_ver2
@@ -0,0 +1,824 @@
/***************************************************************************//**
* \file cy_smif_ver_specific.c
* \version `$CY_MAJOR_VERSION`.`$CY_MINOR_VERSION`
*
* \brief
* This file provides the source code for the SMIF driver APIs.
*
* Note:
*
********************************************************************************
* \copyright
* Copyright 2016-2018, Cypress Semiconductor Corporation. All rights reserved.
* You may use this file only in accordance with the license, terms, conditions,
* disclaimers, and limitations in the end user license agreement accompanying
* the software package with which this file was provided.
*******************************************************************************/
#include "smif/ver2/cy_smif_ver_specific.h"
#ifdef CY_IP_MXSMIF
#if defined(__cplusplus)
extern "C" {
#endif
/*******************************************************************************
* Function Name: Cy_SMIF_Init
****************************************************************************//**
*
* This function initializes the SMIF block as a communication block. The user
* must ensure that the SMIF interrupt is disabled while this function
* is called. Enabling the interrupts can lead to triggering in the middle
* of the initialization operation, which can lead to erroneous initialization.
*
* As parameters, this function takes the SMIF register base address and a
* context structure along with the configuration needed for the SMIF block,
* stored in a config
*
* \param base
* Holds the base address of the SMIF block registers.
*
* \param config
* Passes a configuration structure that configures the SMIF block for operation.
*
* \param context
* Passes a configuration structure that contains the transfer parameters of the
* SMIF block.
*
* \param timeout
* A timeout in microseconds for blocking APIs in use.
*
*
* \note Make sure that the interrupts are initialized and disabled.
*
* \return
* - \ref CY_SMIF_BAD_PARAM
* - \ref CY_SMIF_SUCCESS
*
*******************************************************************************/
cy_en_smif_status_t Cy_SMIF_Init(volatile cy_stc_smif_reg_t *base,
cy_stc_smif_config_t const *config,
uint32_t timeout,
cy_stc_smif_context_t *context)
{
if((NULL == base) || (NULL == config) || (NULL == context))
{
return CY_SMIF_BAD_PARAM;
}
if(config->dlpAuto == CY_SMIF_DLP_UPDATE_AUTO)
{
if((config->rxClk != CY_SMIF_INTERNAL_CLK) && (config->rxClk != CY_SMIF_INV_INTERNAL_CLK))
{
return CY_SMIF_BAD_PARAM;
}
if(config->delaySel == CY_SMIF_NO_DELAY_SEL)
{
return CY_SMIF_BAD_PARAM;
}
}
/* Global variables initialization */
context->txBufferAddress = NULL;
context->txBufferCounter = 0;
context->rxBufferAddress = NULL;
context->rxBufferCounter = 0;
context->transferStatus = CY_SMIF_STARTED;
context->txCmpltCb = NULL;
context->rxCmpltCb = NULL;
context->preCmdDataRate = CY_SMIF_SDR;
context->preCmdWidth = CY_SMIF_WIDTH_SINGLE;
context->txCmdBufCounter = 0;
/* Configure the initial interrupt mask */
/* Disable the TR_TX_REQ and TR_RX_REQ interrupts */
cy_un_smif_reg_intr_mask_t tempIntrMask;
tempIntrMask.u32Register = base->unINTR_MASK.u32Register;
tempIntrMask.stcField.u1TR_TX_REQ = 0u;
tempIntrMask.stcField.u1TR_RX_REQ = 0u;
base->unINTR_MASK.u32Register = tempIntrMask.u32Register;
/* Configure the SMIF interface */
cy_un_smif_reg_ctl_t tempCtl;
tempCtl.u32Register = base->unCTL.u32Register;
tempCtl.stcField.u1CLOCK_IF_TX_SEL = config->txClk;
tempCtl.stcField.u3CLOCK_IF_RX_SEL = config->rxClk;
if(config->delaySel == CY_SMIF_NO_DELAY_SEL)
{
tempCtl.stcField.u1DELAY_TAP_ENABLED = 0u;
}
else
{
tempCtl.stcField.u1DELAY_TAP_ENABLED = 1u;
tempCtl.stcField.u3DELAY_LINE_SEL = config->delaySel;
}
//rmkn: not supported tempCtl.stcField.u1INT_CLOCK_DL_ENABLED = (uint8_t)config->dlpAuto;
tempCtl.stcField.u1XIP_MODE = config->mode;
//rmkn: not supported tempCtl.stcField.u2INT_CLOCK_CAPTURE_CYCLE = config->capDelay;
tempCtl.stcField.u3DESELECT_DELAY = config->deselectDelay;
tempCtl.stcField.u2SELECT_SETUP_DELAY = config->setupDelay;
tempCtl.stcField.u2SELECT_HOLD_DELAY = config->holdDelay;
tempCtl.stcField.u1BLOCK = config->blockEvent;
base->unCTL.u32Register = tempCtl.u32Register;
/* Read the register to flush the buffer */
(void) base->unCTL.u32Register;
return CY_SMIF_SUCCESS;
}
/*******************************************************************************
* Function Name: Cy_SMIF_DeInit
****************************************************************************//**
*
* This function de-initializes the SMIF block to default values.
*
* \param base
* Holds the base address of the SMIF block registers.
*
* \note The SMIF must be disabled before calling the function. Call
* \ref Cy_SMIF_Disable
*
*******************************************************************************/
void Cy_SMIF_DeInit(volatile cy_stc_smif_reg_t *base)
{
/* Configure the SMIF interface to default values.
* The default value is 0.
*/
base->unCTL.u32Register = CY_SMIF_CTL_REG_DEFAULT;
base->unTX_DATA_FIFO_CTL.u32Register = 0U;
base->unRX_DATA_MMIO_FIFO_CTL.u32Register = 0U;
base->unINTR_MASK.u32Register = 0U;
for(uint32_t idx = 0UL; idx < CY_SMIF_GetDeviceNumber(base); idx++)
{
base->DEVICE[idx].unCTL.u32Register = 0U;
/* Read the register to flush the buffer */
(void) base->DEVICE[idx].unCTL.u32Register;
}
}
/*******************************************************************************
* Function Name: Cy_SMIF_Encrypt()
****************************************************************************//**
*
* Uses the Encryption engine to create an encrypted result when the input, key
* and data arrays are provided. The AES-128 encryption of the address with the
* key, fetching the result and XOR with the data array are all done in the
* function. The operational scheme is the following:
* data = XOR(AES128(address, key), data)
* Decryption is done using the input data-array identically to the encryption.
* In the XIP mode, encryption and decryption are done without calling this
* function. The operational scheme in the XIP mode is the same. The address
* parameter in the XIP mode equals the actual address in the TVII memory map.
* The SMIF encryption engine is designed for code storage.
* For data storage, the encryption key can be changed.
* For sensitive data, the Crypto block is used.
*
* \note The API does not have access to the encryption key. The key must be
* placed in the register before calling this API. The crypto routine
* that can access the key storage area is recommended. This crypto routine is
* typically a protection context 0 function.
*
* \note This is a blocking API. The API waits for encryption completion. Will
* exit if a timeout is set (not equal to 0) and expired.
*
* \param base
* Holds the base address of the SMIF block registers.
*
* \param address
* The address that gets encrypted is a masked 16-byte block address. The 32-bit
* address with the last 4 bits masked is placed as the last 4 bytes in the
* 128-bit input. The rest of the higher bit for the 128 bits are padded zeros.
* PA[127:0]:
* PA[3:0] = 0
* PA[7:4] = ADDR[7:4].
* PA[15:8] = ADDR[15:8].
* PA[23:16] = ADDR[23:16].
* PA[31:24] = ADDR[31:24].
* The other twelve of the sixteen plain text address bytes of PA[127:0] are "0":
* PA[127:32] = "0".
*
* \param dataInOut
* This is the location where the input data-array is passed while the function
* is called. This array gets populated with the result after encryption is
* completed.
*
* \param sizeInByte
* Provides a size of the array.
*
* \param context
* Passes a configuration structure that contains the transfer parameters of the
* SMIF block.
*
* \return A status of the command transmit.
* - \ref CY_SMIF_SUCCESS
* - \ref CY_SMIF_EXCEED_TIMEOUT
* - \ref CY_SMIF_BAD_PARAM
*
*******************************************************************************/
cy_en_smif_status_t Cy_SMIF_Encrypt(volatile cy_stc_smif_reg_t *base,
uint32_t address,
uint8_t dataInOut[],
uint32_t sizeInByte,
cy_stc_smif_context_t const *context)
{
if((sizeInByte == 0UL) ||
(sizeInByte % CY_SMIF_AES128_BYTES) != 0UL) // The user needs to do padding in application.
{
return CY_SMIF_BAD_PARAM;
}
if(dataInOut == NULL)
{
return CY_SMIF_BAD_PARAM;
}
if(base->unCRYPTO_CMD.stcField.u1START != CY_SMIF_CRYPTO_COMPLETED)
{
return CY_SMIF_BAD_STATUS;
}
/* Fill the output array */
cy_en_smif_status_t status = CY_SMIF_SUCCESS;
uint32_t blockNum = (sizeInByte / CY_SMIF_AES128_BYTES);
for(uint32_t i_AES_Block = 0U; i_AES_Block < blockNum; i_AES_Block++)
{
uint32_t timeoutUnits = context->timeout;
uint32_t addrOffset = i_AES_Block * CY_SMIF_AES128_BYTES;
/* Fill the input field */
uint32_t validPosOfINPUT0 = base->unCRYPTO_INPUT0.u32Register & (~CY_SMIF_CRYPTO_ADDR_MASK);
base->unCRYPTO_INPUT0.u32Register = ((address + addrOffset) & CY_SMIF_CRYPTO_ADDR_MASK) + validPosOfINPUT0;
/* Start the encryption */
base->unCRYPTO_CMD.stcField.u1START = CY_SMIF_CRYPTO_START;
while((base->unCRYPTO_CMD.stcField.u1START != CY_SMIF_CRYPTO_COMPLETED) && (CY_SMIF_EXCEED_TIMEOUT != status))
{
/* Wait until the encryption is completed and check the
* timeout
*/
status = Cy_SMIF_TimeoutRun(&timeoutUnits);
}
if (status == CY_SMIF_EXCEED_TIMEOUT)
{
break;
}
*(uint32_t*)&dataInOut[addrOffset] ^= base->unCRYPTO_OUTPUT0.u32Register;
*(uint32_t*)&dataInOut[addrOffset + 4ul] ^= base->unCRYPTO_OUTPUT1.u32Register;
*(uint32_t*)&dataInOut[addrOffset + 8ul] ^= base->unCRYPTO_OUTPUT2.u32Register;
*(uint32_t*)&dataInOut[addrOffset + 12ul] ^= base->unCRYPTO_OUTPUT3.u32Register;
}
return (status);
}
/*******************************************************************************
* Function Name: Cy_SMIF_SetDelayLineForFreq
****************************************************************************//**
*
* Selects the right delay line for the specified frequency, so that the taps of
* that delay line should give enough possibilities to fine tune the delay in a
* subsequent calibration step.
*
* \note Expects that SMIF is not busy!
*
* \param base
* Holds the base address of the SMIF block registers.
*
* \param freqMhz
* The frequency of the SMIF clock (external)
*
* \param isDDR
* If the protocol has double data rate (e.g. in case of HyperBus)
*
* \param calculatedTap
* Caller can optionally retrieve the tap number index that was calculated by this
* function (value: 0 .. (SMIFn_DELAY_TAPS_NR - 1)). Pass NULL if value is not needed
*
* \return \ref cy_en_smif_status_t
*
*******************************************************************************/
cy_en_smif_status_t Cy_SMIF_SetDelayLineForFreq(volatile cy_stc_smif_reg_t *base, uint8_t freqMhz, bool isDDR, uint8_t *calculatedTap)
{
// TODO: Device dependent delays (and number of delay lines)
static const float32_t minDelayPerTapInNs[CY_SMIF_DRV_SMIF0_DELAY_LINES_NR] = {0.0559, 0.1197, 0.1935, 0.3973};
cy_en_smif_status_t status = CY_SMIF_SUCCESS;
uint8_t tapNumCalculated;
uint8_t delayLine;
uint8_t maxTaps = CY_SMIF_GetDelayTapsNumber(base);
// Calculate the offset to the nominal center of the data eye
float32_t clockPeriodNs = 1000.0 / freqMhz;
float32_t dataPeriodNs = clockPeriodNs / ((isDDR == true) ? 2.0 : 1.0);
float32_t dataPeriodCenterNs = dataPeriodNs / 2.0;
// Check all scan lines whether the number of taps required to hit the nominal center of the data eye are below the actual number of taps per delay line
for(delayLine = 0; delayLine < CY_SMIF_DRV_SMIF0_DELAY_LINES_NR; delayLine++)
{
tapNumCalculated = (uint8_t) ((dataPeriodCenterNs / minDelayPerTapInNs[delayLine]) + 0.5);
if(tapNumCalculated <= maxTaps)
{
break;
}
}
// No matching delay line found, use the one with the largest delays and return error...
if(delayLine == 4)
{
delayLine = 3;
status = CY_SMIF_BAD_PARAM;
}
Cy_SMIF_Set_DelayLineSel(base, (cy_en_smif_delay_line_t)delayLine);
if(calculatedTap != NULL)
{
// If no matching delay line has been found, return the maximum number of taps
*calculatedTap = ((tapNumCalculated < maxTaps) ? tapNumCalculated : maxTaps) - 1;
}
return status;
}
/*******************************************************************************
* Function Name: Cy_SMIF_SetMasterDLP
****************************************************************************//**
*
* This function sets Data Learning Pattern to be compared.
* DLP width is constant 8bits. Although input value is 16bit integer, upper 8bits
* will be ignored.
*
* \param base
* Holds the base address of the SMIF block registers.
*
* \param dlp
* DLP value to be set.
*
*******************************************************************************/
void Cy_SMIF_SetMasterDLP(volatile cy_stc_smif_reg_t *base, uint16_t dlp)
{
base->unDLP.stcField.u8DLP = (uint8_t)dlp;
}
/*******************************************************************************
* Function Name: Cy_SMIF_GetMasterDLP
****************************************************************************//**
*
* This function reads Data Learning Pattern which have been set.
*
* \param base
* Holds the base address of the SMIF block registers.
*
* \return Master DLP value.
*
*******************************************************************************/
uint16_t Cy_SMIF_GetMasterDLP(volatile cy_stc_smif_reg_t *base)
{
return (uint16_t)(base->unDLP.stcField.u8DLP);
}
/*******************************************************************************
* Function Name: Cy_SMIF_SetMasterDLP_Size
****************************************************************************//**
*
* This function writes DLP size to the register.
* The size of DLP is contstant 8bits, thus this function has no effect.
* If 8 is input as a size, this function returns status of success. otherwise,
* returns of status of failure.
*
* \param base
* Holds the base address of the SMIF block registers.
*
* \param size
* DLP size value to be set to the register. Can be only 8.
*
* \return \ref cy_en_smif_status_t
*
*******************************************************************************/
cy_en_smif_status_t Cy_SMIF_SetMasterDLP_Size(volatile cy_stc_smif_reg_t *base, uint32_t size)
{
if(size == 8ul)
{
return CY_SMIF_SUCCESS;
}
else
{
return CY_SMIF_BAD_PARAM;
}
}
/*******************************************************************************
* Function Name: Cy_SMIF_GetMasterDLP_Size
****************************************************************************//**
*
* This function reads DLP size which have been set.
* The size of DLP is contstant 8bits, thus this function returns 8.
*
* \param base
* Holds the base address of the SMIF block registers.
*
* \return Master DLP size value.
*
*******************************************************************************/
uint8_t Cy_SMIF_GetMasterDLP_Size(volatile cy_stc_smif_reg_t *base)
{
return (uint8_t)(8u);
}
/*******************************************************************************
* Function Name: Cy_SMIF_SetMasterDLP_WarnLevel
****************************************************************************//**
*
* This function does not anything and returns status of success.
*
* \param base
* Holds the base address of the SMIF block registers.
*
* \param warnLevel
* Warning level value to be set to the resister.
*
* \return \ref cy_en_smif_status_t
*
*******************************************************************************/
cy_en_smif_status_t Cy_SMIF_SetMasterDLP_WarnLevel(volatile cy_stc_smif_reg_t *base, uint32_t warnLevel)
{
return CY_SMIF_SUCCESS;
}
/*******************************************************************************
* Function Name: Cy_SMIF_GetMasterDLP_WarnLevel
****************************************************************************//**
*
* This function returns 0.
*
* \param base
* Holds the base address of the SMIF block registers.
*
* \return Master DLP warning level value.
*
*******************************************************************************/
uint8_t Cy_SMIF_GetMasterDLP_WarnLevel(volatile cy_stc_smif_reg_t *base)
{
return (uint8_t)0u;
}
/*******************************************************************************
* Function Name: Cy_SMIF_GetTapNumCapturedCorrectDLP
****************************************************************************//**
*
* This function return tap number indicated by input bit number.
* \note not tested yet. this function may cause hardfault.
*
* \param base
* Holds the base address of the SMIF block registers.
*
* \param bit
* The tap number of the bit will be read.
*
* \return tap number
*
*******************************************************************************/
uint8_t Cy_SMIF_GetTapNumCapturedCorrectDLP(volatile cy_stc_smif_reg_t *base, uint8_t bit)
{
CY_ASSERT_L2(bit < 8u);
if(bit < 4u)
{
return(base->unDL_STATUS0.au8Byte[bit]);
}
else
{
return(base->unDL_STATUS1.au8Byte[bit - 4u]);
}
}
/*******************************************************************************
* Function Name: Cy_SMIF_Set_DelayLineSel
****************************************************************************//**
*
* This function enable delay line, and set line selection which is input.
*
* \param base
* Holds the base address of the SMIF block registers.
*
* \param lineSel
* delay line selection to be set
*
* \return status (see \ref cy_en_smif_status_t).
*
*******************************************************************************/
cy_en_smif_status_t Cy_SMIF_Set_DelayLineSel(volatile cy_stc_smif_reg_t *base, cy_en_smif_delay_line_t lineSel)
{
if(lineSel == CY_SMIF_NO_DELAY_SEL)
{
base->unCTL.stcField.u1DELAY_TAP_ENABLED = 0;
return CY_SMIF_SUCCESS;
}
cy_un_smif_reg_ctl_t tempCTL;
tempCTL.u32Register = base->unCTL.u32Register;
tempCTL.stcField.u1DELAY_TAP_ENABLED = 1;
tempCTL.stcField.u3DELAY_LINE_SEL = lineSel;
base->unCTL.u32Register = tempCTL.u32Register;
return CY_SMIF_SUCCESS;
}
/*******************************************************************************
* Function Name: Cy_SMIF_Get_DelayLineSel
****************************************************************************//**
*
* This function returns the currently selected delay line
*
* \param base
* Holds the base address of the SMIF block registers.
*
* \return delay line (see \ref cy_en_smif_delay_line_t).
*
*******************************************************************************/
cy_en_smif_delay_line_t Cy_SMIF_Get_DelayLineSel(volatile cy_stc_smif_reg_t *base)
{
if(base->unCTL.stcField.u1DELAY_TAP_ENABLED == 0)
{
return CY_SMIF_NO_DELAY_SEL;
}
else
{
return (cy_en_smif_delay_line_t) base->unCTL.stcField.u3DELAY_LINE_SEL;
}
}
/*******************************************************************************
* Function Name: Cy_SMIF_Set_DelayTapSel
****************************************************************************//**
*
* This function sets delay tap number for the SMIF (common for all its devices).
* To ensure compatibility with users of this API independent of the current
* SMIF IP version, it accepts any SMIF pointer as parameter, e.g. a SMIF base
* pointer or a SMIF_DEVICE base pointer. This means this API can be called with
* a SMIF_DEVICE base pointer.
*
* \param smif_or_device_base
* Holds the base address of the SMIF block or SMIF_DEVICE block registers.
*
* \param tapSel
* delay tap selection to be set
*
* \return status (see \ref cy_en_smif_status_t).
*
*******************************************************************************/
cy_en_smif_status_t Cy_SMIF_Set_DelayTapSel(volatile void *smif_or_device_base, uint8_t tapSel)
{
// Ensure that if a device pointer has been passed, it is converted to a SMIF base pointer
volatile stc_SMIF_t * base = Cy_SMIF_GetSmifBasePtrFromAnySmifPtr(smif_or_device_base);
if(tapSel > (CY_SMIF_GetDelayTapsNumber(base) - 1))
{
return CY_SMIF_BAD_PARAM;
}
base->unDELAY_TAP_SEL.stcField.u8SEL = tapSel;
return CY_SMIF_SUCCESS;
}
/*******************************************************************************
* Function Name: Cy_SMIF_Get_DelayTapSel
****************************************************************************//**
*
* This function returns delay tap number which has been set for the SMIF (common for all its devices).
* To ensure compatibility with users of this API independent of the current
* SMIF IP version, it accepts any SMIF pointer as parameter, e.g. a SMIF base
* pointer or a SMIF_DEVICE base pointer. This means this API can be called with
* a SMIF_DEVICE base pointer.
*
* \param smif_or_device_base
* Holds the base address of the SMIF block or SMIF_DEVICE block registers.
*
* \return read tap selection
*
*******************************************************************************/
uint8_t Cy_SMIF_Get_DelayTapSel(volatile void *smif_or_device_base)
{
// Ensure that if a device pointer has been passed, it is converted to a SMIF base pointer
volatile stc_SMIF_t * base = Cy_SMIF_GetSmifBasePtrFromAnySmifPtr(smif_or_device_base);
return (uint8_t)(base->unDELAY_TAP_SEL.stcField.u8SEL);
}
/*******************************************************************************
* Function Name: Cy_SMIF_SetTxFifoTriggerLevel()
****************************************************************************//**
*
* This function is used to set a trigger level for the TX FIFO. This value must
* be an integer between 0 and 7. For the normal mode only.
* The triggering is active when TX_DATA_FIFO_STATUS <= level.
*
* \param base
* Holds the base address of the SMIF block registers.
*
* \param level
* The trigger level to set (0-8).
*
*******************************************************************************/
void Cy_SMIF_SetTxFifoTriggerLevel(volatile cy_stc_smif_reg_t *base, uint32_t level)
{
CY_ASSERT_L2(level < CY_SMIF_MAX_TX_TR_LEVEL);
base->unTX_DATA_FIFO_CTL.u32Register = level;
}
/*******************************************************************************
* Function Name: Cy_SMIF_SetCryptoInput128
****************************************************************************//**
*
* This function sets 128 bit data of crypto input (plain text).
*
* \param device
* Holds the base address of the SMIF Device registers.
*
* \param inData Address of input 16 byte input data to be crypted
*
*******************************************************************************/
void Cy_SMIF_SetCryptoInput128(volatile cy_stc_smif_reg_t *base, const uint8_t inData[])
{
base->unCRYPTO_INPUT0.u32Register = *(uint32_t*)&inData[0u];
base->unCRYPTO_INPUT1.u32Register = *(uint32_t*)&inData[4u];
base->unCRYPTO_INPUT2.u32Register = *(uint32_t*)&inData[8u];
base->unCRYPTO_INPUT3.u32Register = *(uint32_t*)&inData[12u];
}
/*******************************************************************************
* Function Name: Cy_SMIF_SetCryptoKey128
****************************************************************************//**
*
* This function sets 128 bit data of crypto key.
*
* \param device
* Holds the base address of the SMIF Device registers.
*
* \param key Address of 16 byte AES key data
*
*******************************************************************************/
void Cy_SMIF_SetCryptoKey128(volatile cy_stc_smif_reg_t *base, const uint8_t key[])
{
base->unCRYPTO_KEY0.u32Register = *(uint32_t*)&key[0u];
base->unCRYPTO_KEY1.u32Register = *(uint32_t*)&key[4u];
base->unCRYPTO_KEY2.u32Register = *(uint32_t*)&key[8u];
base->unCRYPTO_KEY3.u32Register = *(uint32_t*)&key[12u];
}
/*******************************************************************************
* Function Name: Cy_SMIF_GetTxFifoStatus()
****************************************************************************//**
*
* This function is used to read the status of the TX FIFO.
*
* \param base
* Holds the base address of the SMIF block registers.
*
* \return Returns the number of the entries in the TX FIFO.
*
*******************************************************************************/
uint32_t Cy_SMIF_GetTxFifoStatus(volatile cy_stc_smif_reg_t *base)
{
return (base->unTX_DATA_FIFO_STATUS.stcField.u4USED4);
}
/*******************************************************************************
* Function Name: Cy_SMIF_PushCmdFifo()
****************************************************************************//**
*
* Push input data to SMIF tx command fifo.
*
* \param base
* Holds the base address of the SMIF block registers.
*
* \param data
* The data to be pushed.
*
* \param sizeInWord
* The size of the data to be pushed in words.
*
*******************************************************************************/
void Cy_SMIF_PushCmdFifo(volatile cy_stc_smif_reg_t *base, uint32_t data[], uint32_t sizeInWord)
{
for(uint32_t idx = 0ul; idx < sizeInWord; idx++)
{
base->unTX_CMD_FIFO_WR.u32Register = data[idx];
}
}
/*******************************************************************************
* Function Name: Cy_SMIF_PushTxFifo
***************************************************************************//***
*
* \internal
*
* \param baseaddr
* Holds the base address of the SMIF block registers.
*
* \param context
* Passes a configuration structure that contains the transfer parameters of the
* SMIF block.
*
* This function writes data in the TX FIFO SMIF buffer by 4, 2, or 1 bytes based
* on the residual number of bytes and the available space in the TX FIFO.
*
*******************************************************************************/
void Cy_SMIF_PushTxFifo(volatile cy_stc_smif_reg_t *baseaddr, cy_stc_smif_context_t *context)
{
/* The variable that shows which is smaller: the free FIFO size or amount of bytes to be sent */
uint32_t freeFifoBytes = CY_SMIF_TX_DATA_FIFO_STATUS_RANGE - Cy_SMIF_GetTxFifoStatus(baseaddr);;
uint32_t buffCounter = context->txBufferCounter;
// writeBytes = MIN(freeFifoBytes, buffCounter);
uint32_t writeBytes = (freeFifoBytes > buffCounter)? buffCounter: freeFifoBytes;
// If it sends 2 byte per one clock, then it needs using TX_DATA_FIFO_WR1ODD when sending one byte.
// Save proper one byte sending fifo address into ptr1ByteFifo accordingly.
uint32_t* ptr1ByteFifo;
if((context->preCmdDataRate == CY_SMIF_DDR) &&(context->preCmdWidth == CY_SMIF_WIDTH_OCTAL))
{
ptr1ByteFifo = (uint32_t*)&(baseaddr->unTX_DATA_FIFO_WR1ODD);
}
else
{
ptr1ByteFifo = (uint32_t*)&(baseaddr->unTX_DATA_FIFO_WR1);
}
/* Check that after a FIFO Write, no data/FIFO space remains */
uint8_t *buff = (uint8_t*)context->txBufferAddress;
while (writeBytes != 0U)
{
// Even if writeBytes == 1, do not send it. Wait more space becoming available.
// Because 1 byte fifo (TX_DATA_FIFO_WR1) should be used only last 1 byte.
// If bufferCounter == 1, it means it is the last byte. then send it.
if((writeBytes >= 2U) || (buffCounter == 1))
{
if(writeBytes == 1)
{
// Enter here only when this is the last sending.
*ptr1ByteFifo = buff[0U];
}
else if((writeBytes == 2u) || (writeBytes == 3u))
{
baseaddr->unTX_DATA_FIFO_WR2.u32Register = Cy_SMIF_PackBytesArray(&buff[0U], false);
writeBytes = 2u;
}
else if((writeBytes == 4u) || (writeBytes == 5u))
{
baseaddr->unTX_DATA_FIFO_WR4.u32Register = Cy_SMIF_PackBytesArray(&buff[0U], true);
writeBytes = 4u;
}
else if((writeBytes == 6u) || (writeBytes == 7u))
{
baseaddr->unTX_DATA_FIFO_WR4.u32Register = Cy_SMIF_PackBytesArray(&buff[0U], true);
baseaddr->unTX_DATA_FIFO_WR2.u32Register = Cy_SMIF_PackBytesArray(&buff[4U], false);
writeBytes = 6u;
}
else /* writeBytes => 8*/
{
baseaddr->unTX_DATA_FIFO_WR4.u32Register = Cy_SMIF_PackBytesArray(&buff[0U], true);
baseaddr->unTX_DATA_FIFO_WR4.u32Register = Cy_SMIF_PackBytesArray(&buff[4U], true);
writeBytes = 8u;
}
buff = &buff[writeBytes];
buffCounter -= writeBytes;
}
/* Check if we already got new data in TX_FIFO*/
freeFifoBytes = CY_SMIF_TX_DATA_FIFO_STATUS_RANGE - Cy_SMIF_GetTxFifoStatus(baseaddr);
writeBytes = (freeFifoBytes > buffCounter)? buffCounter: freeFifoBytes;
}
/* Save changes in the context */
context->txBufferAddress = buff;
context->txBufferCounter = buffCounter;
/* Check if all bytes are sent */
if (buffCounter == 0u)
{
/* Disable the TR_TX_REQ interrupt */
baseaddr->unINTR_MASK.stcField.u1TR_TX_REQ = 0u;
context->transferStatus = CY_SMIF_SEND_CMPLT;
if (NULL != context->txCmpltCb)
{
context->txCmpltCb((uint32_t) CY_SMIF_SEND_CMPLT);
}
}
}
#if defined(__cplusplus)
}
#endif
#endif /* CY_IP_MXSMIF */
/* [] END OF FILE */
@@ -0,0 +1,209 @@
/***************************************************************************//**
* \file cy_smif_ver_specific.h
* \version `$CY_MAJOR_VERSION`.`$CY_MINOR_VERSION`
*
* Provides an API declaration of the Cypress SMIF v2.0 driver.
*
********************************************************************************
* \copyright
* Copyright 2016-2018, Cypress Semiconductor Corporation. All rights reserved.
* You may use this file only in accordance with the license, terms, conditions,
* disclaimers, and limitations in the end user license agreement accompanying
* the software package with which this file was provided.
*******************************************************************************/
/**
* \section group_smif_ver_specific_changelog Changelog
* <table class="doxtable">
* <tr><th>Version</th><th>Changes</th><th>Reason for Change</th></tr>
* <tr>
* <td>1.0</td>
* <td>Initial version</td>
* <td></td>
* </tr>
* </table>
*
*/
#if !defined(CY_SMIF_VER_SPECIFIC_H)
#define CY_SMIF_VER_SPECIFIC_H
#include <stdint.h>
#include <stdbool.h>
#include <stddef.h>
#include "cy_device_headers.h"
#ifdef CY_IP_MXSMIF
#if defined(__cplusplus)
extern "C" {
#endif
/* Typedef for smif driver, so make it common */
typedef stc_SMIF_t cy_stc_smif_reg_t;
typedef un_SMIF_CTL_t cy_un_smif_reg_ctl_t;
typedef un_SMIF_STATUS_t cy_un_smif_reg_status_t;
typedef un_SMIF_INT_CLOCK_DELAY_TAP_SEL0_t cy_un_smif_reg_dlp_delay_tap_sel0_t;
typedef un_SMIF_INT_CLOCK_DELAY_TAP_SEL1_t cy_un_smif_reg_dlp_delay_tap_sel1_t;
typedef un_SMIF_DLP_t cy_un_smif_reg_dlp_ctl_t;
typedef un_SMIF_DL_STATUS0_t cy_un_smif_reg_dlp_status0_t;
typedef un_SMIF_DL_STATUS1_t cy_un_smif_reg_dlp_status1_t;
typedef un_SMIF_DELAY_TAP_SEL_t cy_un_smif_reg_delay_tap_sel_t;
typedef un_SMIF_TX_CMD_FIFO_STATUS_t cy_un_smif_reg_tx_cmd_fifo_status_t;
typedef un_SMIF_TX_CMD_FIFO_WR_t cy_un_smif_reg_tx_cmd_fifo_wr_t;
typedef un_SMIF_TX_DATA_FIFO_CTL_t cy_un_smif_reg_tx_data_fifo_ctl_t;
typedef un_SMIF_TX_DATA_FIFO_STATUS_t cy_un_smif_reg_tx_data_fifo_status_t;
typedef un_SMIF_TX_DATA_FIFO_WR1_t cy_un_smif_reg_tx_data_fifo_wr1_t;
typedef un_SMIF_TX_DATA_FIFO_WR2_t cy_un_smif_reg_tx_data_fifo_wr2_t;
typedef un_SMIF_TX_DATA_FIFO_WR4_t cy_un_smif_reg_tx_data_fifo_wr4_t;
typedef un_SMIF_TX_DATA_FIFO_WR1ODD_t cy_un_smif_reg_tx_data_fifo_wr1odd_t;
typedef un_SMIF_RX_DATA_MMIO_FIFO_CTL_t cy_un_smif_reg_rx_data_mmio_fifo_ctl_t;
typedef un_SMIF_RX_DATA_MMIO_FIFO_STATUS_t cy_un_smif_reg_rx_data_mmio_fifo_status_t;
typedef un_SMIF_RX_DATA_FIFO_STATUS_t cy_un_smif_reg_rx_data_fifo_status_t;
typedef un_SMIF_RX_DATA_MMIO_FIFO_RD1_t cy_un_smif_reg_rx_data_mmio_fifo_rd1_t;
typedef un_SMIF_RX_DATA_MMIO_FIFO_RD2_t cy_un_smif_reg_rx_data_mmio_fifo_rd2_t;
typedef un_SMIF_RX_DATA_MMIO_FIFO_RD4_t cy_un_smif_reg_rx_data_mmio_fifo_rd4_t;
typedef un_SMIF_RX_DATA_MMIO_FIFO_RD1_SILENT_t cy_un_smif_reg_rx_data_mmio_fifo_rd1_silent_t;
typedef un_SMIF_SLOW_CA_CTL_t cy_un_smif_reg_slow_ca_ctl_t;
typedef un_SMIF_SLOW_CA_CMD_t cy_un_smif_reg_slow_ca_cmd_t;
typedef un_SMIF_FAST_CA_CTL_t cy_un_smif_reg_fast_ca_ctl_t;
typedef un_SMIF_FAST_CA_CMD_t cy_un_smif_reg_fast_ca_cmd_t;
typedef un_SMIF_CRYPTO_CMD_t cy_un_smif_reg_crypto_cmd_t;
typedef un_SMIF_CRYPTO_INPUT0_t cy_un_smif_reg_crypto_input0_t;
typedef un_SMIF_CRYPTO_INPUT1_t cy_un_smif_reg_crypto_input1_t;
typedef un_SMIF_CRYPTO_INPUT2_t cy_un_smif_reg_crypto_input2_t;
typedef un_SMIF_CRYPTO_INPUT3_t cy_un_smif_reg_crypto_input3_t;
typedef un_SMIF_CRYPTO_KEY0_t cy_un_smif_reg_crypto_key0_t;
typedef un_SMIF_CRYPTO_KEY1_t cy_un_smif_reg_crypto_key1_t;
typedef un_SMIF_CRYPTO_KEY2_t cy_un_smif_reg_crypto_key2_t;
typedef un_SMIF_CRYPTO_KEY3_t cy_un_smif_reg_crypto_key3_t;
typedef un_SMIF_CRYPTO_OUTPUT0_t cy_un_smif_reg_crypto_output0_t;
typedef un_SMIF_CRYPTO_OUTPUT1_t cy_un_smif_reg_crypto_output1_t;
typedef un_SMIF_CRYPTO_OUTPUT2_t cy_un_smif_reg_crypto_output2_t;
typedef un_SMIF_CRYPTO_OUTPUT3_t cy_un_smif_reg_crypto_output3_t;
typedef un_SMIF_CRC_CMD_t cy_un_smif_reg_crc_cmd_t;
typedef un_SMIF_CRC_INPUT0_t cy_un_smif_reg_crc_input0_t;
typedef un_SMIF_CRC_INPUT1_t cy_un_smif_reg_crc_input1_t;
typedef un_SMIF_CRC_OUTPUT_t cy_un_smif_reg_crc_output_t;
typedef un_SMIF_INTR_t cy_un_smif_reg_intr_t;
typedef un_SMIF_INTR_SET_t cy_un_smif_reg_intr_set_t;
typedef un_SMIF_INTR_MASK_t cy_un_smif_reg_intr_mask_t;
typedef un_SMIF_INTR_MASKED_t cy_un_smif_reg_intr_masked_t;
typedef stc_SMIF_DEVICE_t cy_stc_smif_reg_device_t;
typedef un_SMIF_DEVICE_CTL_t cy_un_smif_reg_device_ctl_t;
typedef un_SMIF_DEVICE_ADDR_t cy_un_smif_reg_device_addr_t;
typedef un_SMIF_DEVICE_MASK_t cy_un_smif_reg_device_mask_t;
typedef un_SMIF_DEVICE_ADDR_CTL_t cy_un_smif_reg_device_addr_ctl_t;
typedef un_SMIF_DEVICE_RD_STATUS_t cy_un_smif_reg_device_rd_status_t;
typedef un_SMIF_DEVICE_RD_CMD_CTL_t cy_un_smif_reg_device_rd_cmd_ctl_t;
typedef un_SMIF_DEVICE_RD_ADDR_CTL_t cy_un_smif_reg_device_rd_addr_ctl_t;
typedef un_SMIF_DEVICE_RD_MODE_CTL_t cy_un_smif_reg_device_rd_mode_ctl_t;
typedef un_SMIF_DEVICE_RD_DUMMY_CTL_t cy_un_smif_reg_device_rd_dummy_t;
typedef un_SMIF_DEVICE_RD_DATA_CTL_t cy_un_smif_reg_device_rd_data_ctl_t;
typedef un_SMIF_DEVICE_RD_CRC_CTL_t cy_un_smif_reg_device_rd_crc_ctl_t;
typedef un_SMIF_DEVICE_RD_BOUND_CTL_t cy_un_smif_reg_device_rd_bound_ctl_t;
typedef un_SMIF_DEVICE_WR_CMD_CTL_t cy_un_smif_reg_device_wr_cmd_t;
typedef un_SMIF_DEVICE_WR_ADDR_CTL_t cy_un_smif_reg_device_wr_addr_t;
typedef un_SMIF_DEVICE_WR_MODE_CTL_t cy_un_smif_reg_device_wr_mode_ctl_t;
typedef un_SMIF_DEVICE_WR_DUMMY_CTL_t cy_un_smif_reg_device_wr_dummy_ctl_t;
typedef un_SMIF_DEVICE_WR_DATA_CTL_t cy_un_smif_reg_device_wr_data_ctl_t;
typedef un_SMIF_DEVICE_WR_CRC_CTL_t cy_un_smif_reg_device_wr_crc_ctl_t;
/* Definitions for smif register masks, so make it common (only for required entities) */
#define CY_SMIF_DRV_DEVICE_ADDR_MSK SMIF_DEVICE_ADDR_ADDR_Msk
#define CY_SMIF_DRV_INTR_TR_TX_REQ_MSK SMIF_INTR_TR_TX_REQ_Msk
#define CY_SMIF_DRV_INTR_TR_RX_REQ_MSK SMIF_INTR_TR_RX_REQ_Msk
#define CY_SMIF_DRV_INTR_XIP_ALIGNMENT_ERROR_MSK SMIF_INTR_XIP_ALIGNMENT_ERROR_Msk
#define CY_SMIF_DRV_INTR_TX_CMD_FIFO_OVERFLOW_MSK SMIF_INTR_TX_CMD_FIFO_OVERFLOW_Msk
#define CY_SMIF_DRV_INTR_TX_DATA_FIFO_OVERFLOW_MSK SMIF_INTR_TX_DATA_FIFO_OVERFLOW_Msk
#define CY_SMIF_DRV_INTR_RX_DATA_MMIO_FIFO_UNDERFLOW_MSK SMIF_INTR_RX_DATA_MMIO_FIFO_UNDERFLOW_Msk
/* Definitions for smif register top address, so make it common */
#if defined(SMIF0)
#define CY_SMIF_DRV_SMIF0_CORE0 SMIF0
#endif
#if defined(SMIF1)
#define CY_SMIF_CORE1_EXISTS
#define CY_SMIF_DRV_SMIF0_CORE1 SMIF1
#endif
#if defined(SMIF0_DEVICE0)
#define CY_SMIF_DRV_SMIF0_CORE0_DEVICE0 SMIF0_DEVICE0
#endif
#if defined(SMIF0_DEVICE1)
#define CY_SMIF_DRV_SMIF0_CORE0_DEVICE1 SMIF0_DEVICE1
#endif
#if defined(SMIF1_DEVICE0)
#define CY_SMIF_DRV_SMIF0_CORE1_DEVICE0 SMIF1_DEVICE0
#endif
#if defined(SMIF1_DEVICE1)
#define CY_SMIF_DRV_SMIF0_CORE1_DEVICE1 SMIF1_DEVICE1
#endif
#if defined(SMIF_DEVICE_SECTION_SIZE)
#define CY_SMIF_DRV_DEVICE_SECTION_SIZE SMIF_DEVICE_SECTION_SIZE
#endif
#define CY_SMIF_DRV_SMIF0_IRQN smif_0_interrupt_IRQn
#if defined(CY_SMIF_CORE1_EXISTS)
#define CY_SMIF_DRV_SMIF1_IRQN smif_1_interrupt_IRQn
#endif
/* Specifies the clock source for "clk_if". Must be 0 (clk_hf) */
/* before entering DeepSleep; can be returned to 1 (clk_pll) afterwards. */
typedef enum
{
CY_SMIF_CLKIF_SRC_CLK_HF = 0, /**< Clock source clk_hf */
CY_SMIF_CLKIF_SRC_CLK_PLL = 1 /**< Clock source clk_pll */
} cy_en_cy_clkif_source_t;
#include "smif/common/cy_smif.h"
/**
* \addtogroup group_smif_version_specific_functions
* This device uses SMIF revision 2.0
* \{
*/
extern cy_en_smif_status_t Cy_SMIF_Init(volatile cy_stc_smif_reg_t *base, cy_stc_smif_config_t const *config, uint32_t timeout, cy_stc_smif_context_t *context);
extern void Cy_SMIF_DeInit(volatile cy_stc_smif_reg_t *base);
extern cy_en_smif_status_t Cy_SMIF_Encrypt(volatile cy_stc_smif_reg_t *base, uint32_t address, uint8_t dataInOut[], uint32_t sizeInByte, cy_stc_smif_context_t const *context);
extern cy_en_smif_status_t Cy_SMIF_SetDelayLineForFreq(volatile cy_stc_smif_reg_t *base, uint8_t freqMhz, bool isDDR, uint8_t *calculatedTap);
extern void Cy_SMIF_SetMasterDLP(volatile cy_stc_smif_reg_t *base, uint16_t dlp);
extern uint16_t Cy_SMIF_GetMasterDLP(volatile cy_stc_smif_reg_t *base);
extern cy_en_smif_status_t Cy_SMIF_SetMasterDLP_Size(volatile cy_stc_smif_reg_t *base, uint32_t size);
extern uint8_t Cy_SMIF_GetMasterDLP_Size(volatile cy_stc_smif_reg_t *base);
extern cy_en_smif_status_t Cy_SMIF_SetMasterDLP_WarnLevel(volatile cy_stc_smif_reg_t *base, uint32_t warnLevel);
extern uint8_t Cy_SMIF_GetMasterDLP_WarnLevel(volatile cy_stc_smif_reg_t *base);
extern uint8_t Cy_SMIF_GetTapNumCapturedCorrectDLP(volatile cy_stc_smif_reg_t *base, uint8_t bit);
extern cy_en_smif_status_t Cy_SMIF_Set_DelayLineSel(volatile cy_stc_smif_reg_t *base, cy_en_smif_delay_line_t lineSel);
extern cy_en_smif_delay_line_t Cy_SMIF_Get_DelayLineSel(volatile cy_stc_smif_reg_t *base);
extern cy_en_smif_status_t Cy_SMIF_Set_DelayTapSel(volatile void *smif_or_device_base, uint8_t tapSel);
extern uint8_t Cy_SMIF_Get_DelayTapSel(volatile void *smif_or_device_base);
extern void Cy_SMIF_SetTxFifoTriggerLevel(volatile cy_stc_smif_reg_t *base, uint32_t level);
extern void Cy_SMIF_SetCryptoInput128(volatile cy_stc_smif_reg_t *base, const uint8_t inData[]);
extern void Cy_SMIF_SetCryptoKey128(volatile cy_stc_smif_reg_t *base, const uint8_t key[]);
extern uint32_t Cy_SMIF_GetTxFifoStatus(volatile cy_stc_smif_reg_t *base);
extern void Cy_SMIF_PushCmdFifo(volatile cy_stc_smif_reg_t *base, uint32_t data[], uint32_t sizeInWord);
extern void Cy_SMIF_PushTxFifo(volatile cy_stc_smif_reg_t *baseaddr, cy_stc_smif_context_t *context);
/** \} group_smif_version_specific_functions */
#if defined(__cplusplus)
}
#endif
#endif /* CY_IP_MXSMIF */
#endif /* (CY_SMIF_H) */
/** \} group_smif */
/* [] END OF FILE */
@@ -0,0 +1,5 @@
V3_1 C2D4M, CE4M rev_a.
V3_1 represents SMIF_3_0
@@ -0,0 +1,835 @@
/***************************************************************************//**
* \file cy_smif_ver_specific.c
* \version `$CY_MAJOR_VERSION`.`$CY_MINOR_VERSION`
*
* \brief
* This file provides the source code for the SMIF driver APIs.
*
* Note:
*
********************************************************************************
* \copyright
* Copyright 2016-2018, Cypress Semiconductor Corporation. All rights reserved.
* You may use this file only in accordance with the license, terms, conditions,
* disclaimers, and limitations in the end user license agreement accompanying
* the software package with which this file was provided.
*******************************************************************************/
#include "smif/ver3_1/cy_smif_ver_specific.h"
#ifdef CY_IP_MXSMIF
#if defined(__cplusplus)
extern "C" {
#endif
/*******************************************************************************
* Function Name: Cy_SMIF_Init
****************************************************************************//**
*
* This function initializes the SMIF block as a communication block. The user
* must ensure that the SMIF interrupt is disabled while this function
* is called. Enabling the interrupts can lead to triggering in the middle
* of the initialization operation, which can lead to erroneous initialization.
*
* As parameters, this function takes the SMIF register base address and a
* context structure along with the configuration needed for the SMIF block,
* stored in a config
*
* \param base
* Holds the base address of the SMIF block registers.
*
* \param config
* Passes a configuration structure that configures the SMIF block for operation.
*
* \param context
* Passes a configuration structure that contains the transfer parameters of the
* SMIF block.
*
* \param timeout
* A timeout in microseconds for blocking APIs in use.
*
*
* \note Make sure that the interrupts are initialized and disabled.
*
* \return
* - \ref CY_SMIF_BAD_PARAM
* - \ref CY_SMIF_SUCCESS
*
*******************************************************************************/
cy_en_smif_status_t Cy_SMIF_Init(volatile cy_stc_smif_reg_t *base,
cy_stc_smif_config_t const *config,
uint32_t timeout,
cy_stc_smif_context_t *context)
{
if((NULL == base) || (NULL == config) || (NULL == context))
{
return CY_SMIF_BAD_PARAM;
}
if(config->dlpAuto == CY_SMIF_DLP_UPDATE_AUTO)
{
if((config->rxClk != CY_SMIF_INTERNAL_CLK) && (config->rxClk != CY_SMIF_INV_INTERNAL_CLK))
{
return CY_SMIF_BAD_PARAM;
}
if(config->delaySel == CY_SMIF_NO_DELAY_SEL)
{
return CY_SMIF_BAD_PARAM;
}
}
/* Global variables initialization */
context->txBufferAddress = NULL;
context->txBufferCounter = 0;
context->rxBufferAddress = NULL;
context->rxBufferCounter = 0;
context->transferStatus = CY_SMIF_STARTED;
context->txCmpltCb = NULL;
context->rxCmpltCb = NULL;
context->preCmdDataRate = CY_SMIF_SDR;
context->preCmdWidth = CY_SMIF_WIDTH_SINGLE;
context->txCmdBufCounter = 0;
/* Configure the initial interrupt mask */
/* Disable the TR_TX_REQ and TR_RX_REQ interrupts */
cy_un_smif_reg_intr_mask_t tempIntrMask;
tempIntrMask.u32Register = base->unINTR_MASK.u32Register;
tempIntrMask.stcField.u1TR_TX_REQ = 0u;
tempIntrMask.stcField.u1TR_RX_REQ = 0u;
base->unINTR_MASK.u32Register = tempIntrMask.u32Register;
/* Configure the SMIF interface */
cy_un_smif_reg_ctl_t tempCtl;
tempCtl.u32Register = base->unCTL.u32Register;
tempCtl.stcField.u1CLOCK_IF_TX_SEL = config->txClk;
tempCtl.stcField.u3CLOCK_IF_RX_SEL = config->rxClk;
if(config->delaySel == CY_SMIF_NO_DELAY_SEL)
{
tempCtl.stcField.u1DELAY_TAP_ENABLED = 0u;
}
else
{
tempCtl.stcField.u1DELAY_TAP_ENABLED = 1u;
tempCtl.stcField.u3DELAY_LINE_SEL = config->delaySel;
}
tempCtl.stcField.u1INT_CLOCK_DL_ENABLED = (uint8_t)config->dlpAuto;
tempCtl.stcField.u1XIP_MODE = config->mode;
tempCtl.stcField.u2INT_CLOCK_CAPTURE_CYCLE = config->capDelay;
tempCtl.stcField.u3DESELECT_DELAY = config->deselectDelay;
tempCtl.stcField.u2SELECT_SETUP_DELAY = config->setupDelay;
tempCtl.stcField.u2SELECT_HOLD_DELAY = config->holdDelay;
tempCtl.stcField.u1BLOCK = config->blockEvent;
tempCtl.stcField.u1CLOCK_IF_SEL = config->clkIfSrc;
base->unCTL.u32Register = tempCtl.u32Register;
/* Read the register to flush the buffer */
(void) base->unCTL.u32Register;
return CY_SMIF_SUCCESS;
}
/*******************************************************************************
* Function Name: Cy_SMIF_DeInit
****************************************************************************//**
*
* This function de-initializes the SMIF block to default values.
*
* \param base
* Holds the base address of the SMIF block registers.
*
* \note The SMIF must be disabled before calling the function. Call
* \ref Cy_SMIF_Disable
*
*******************************************************************************/
void Cy_SMIF_DeInit(volatile cy_stc_smif_reg_t *base)
{
/* Configure the SMIF interface to default values.
* The default value is 0.
*/
base->unCTL.u32Register = CY_SMIF_CTL_REG_DEFAULT;
base->unTX_DATA_MMIO_FIFO_CTL.u32Register = 0U;
base->unRX_DATA_MMIO_FIFO_CTL.u32Register = 0U;
base->unINTR_MASK.u32Register = 0U;
for(uint32_t idx = 0UL; idx < CY_SMIF_GetDeviceNumber(base); idx++)
{
base->DEVICE[idx].unCTL.u32Register = 0U;
/* Read the register to flush the buffer */
(void) base->DEVICE[idx].unCTL.u32Register;
}
}
/*******************************************************************************
* Function Name: Cy_SMIF_Encrypt()
****************************************************************************//**
*
* Uses the Encryption engine to create an encrypted result when the input, key
* and data arrays are provided. The AES-128 encryption of the address with the
* key, fetching the result and XOR with the data array are all done in the
* function. The operational scheme is the following:
* data = XOR(AES128(address, key), data)
* Decryption is done using the input data-array identically to the encryption.
* In the XIP mode, encryption and decryption are done without calling this
* function. The operational scheme in the XIP mode is the same. The address
* parameter in the XIP mode equals the actual address in the TVII memory map.
* The SMIF encryption engine is designed for code storage.
* For data storage, the encryption key can be changed.
* For sensitive data, the Crypto block is used.
*
* \note The API does not have access to the encryption key. The key must be
* placed in the register before calling this API. The crypto routine
* that can access the key storage area is recommended. This crypto routine is
* typically a protection context 0 function.
*
* \note This is a blocking API. The API waits for encryption completion. Will
* exit if a timeout is set (not equal to 0) and expired.
*
* \param base
* Holds the base address of the SMIF block registers.
*
* \param address
* The address that gets encrypted is a masked 16-byte block address. The 32-bit
* address with the last 4 bits masked is placed as the last 4 bytes in the
* 128-bit input. The rest of the higher bit for the 128 bits are padded zeros.
* PA[127:0]:
* PA[3:0] = 0
* PA[7:4] = ADDR[7:4].
* PA[15:8] = ADDR[15:8].
* PA[23:16] = ADDR[23:16].
* PA[31:24] = ADDR[31:24].
* The other twelve of the sixteen plain text address bytes of PA[127:0] are "0":
* PA[127:32] = "0".
*
* \param dataInOut
* This is the location where the input data-array is passed while the function
* is called. This array gets populated with the result after encryption is
* completed.
*
* \param sizeInByte
* Provides a size of the array.
*
* \param context
* Passes a configuration structure that contains the transfer parameters of the
* SMIF block.
*
* \return A status of the command transmit.
* - \ref CY_SMIF_SUCCESS
* - \ref CY_SMIF_EXCEED_TIMEOUT
* - \ref CY_SMIF_BAD_PARAM
*
*******************************************************************************/
cy_en_smif_status_t Cy_SMIF_Encrypt(volatile cy_stc_smif_reg_t *base,
uint32_t address,
uint8_t dataInOut[],
uint32_t sizeInByte,
cy_stc_smif_context_t const *context)
{
if((sizeInByte == 0UL) ||
(sizeInByte % CY_SMIF_AES128_BYTES) != 0UL) // The user needs to do padding in application.
{
return CY_SMIF_BAD_PARAM;
}
if(dataInOut == NULL)
{
return CY_SMIF_BAD_PARAM;
}
if(base->SMIF_CRYPTO[0].unCRYPTO_CMD.stcField.u1START != CY_SMIF_CRYPTO_COMPLETED)
{
return CY_SMIF_BAD_STATUS;
}
/* Fill the output array */
cy_en_smif_status_t status = CY_SMIF_SUCCESS;
uint32_t blockNum = (sizeInByte / CY_SMIF_AES128_BYTES);
for(uint32_t i_AES_Block = 0U; i_AES_Block < blockNum; i_AES_Block++)
{
uint32_t timeoutUnits = context->timeout;
uint32_t addrOffset = i_AES_Block * CY_SMIF_AES128_BYTES;
/* Fill the input field */
uint32_t validPosOfINPUT0 = base->SMIF_CRYPTO[0].unCRYPTO_INPUT0.u32Register & (~CY_SMIF_CRYPTO_ADDR_MASK);
base->SMIF_CRYPTO[0].unCRYPTO_INPUT0.u32Register = ((address + addrOffset) & CY_SMIF_CRYPTO_ADDR_MASK) + validPosOfINPUT0;
/* Start the encryption */
base->SMIF_CRYPTO[0].unCRYPTO_CMD.stcField.u1START = CY_SMIF_CRYPTO_START;
while((base->SMIF_CRYPTO[0].unCRYPTO_CMD.stcField.u1START != CY_SMIF_CRYPTO_COMPLETED) && (CY_SMIF_EXCEED_TIMEOUT != status))
{
/* Wait until the encryption is completed and check the
* timeout
*/
status = Cy_SMIF_TimeoutRun(&timeoutUnits);
}
if (status == CY_SMIF_EXCEED_TIMEOUT)
{
break;
}
*(uint32_t*)&dataInOut[addrOffset] ^= base->SMIF_CRYPTO[0].unCRYPTO_OUTPUT0.u32Register;
*(uint32_t*)&dataInOut[addrOffset + 4ul] ^= base->SMIF_CRYPTO[0].unCRYPTO_OUTPUT1.u32Register;
*(uint32_t*)&dataInOut[addrOffset + 8ul] ^= base->SMIF_CRYPTO[0].unCRYPTO_OUTPUT2.u32Register;
*(uint32_t*)&dataInOut[addrOffset + 12ul] ^= base->SMIF_CRYPTO[0].unCRYPTO_OUTPUT3.u32Register;
}
return (status);
}
/*******************************************************************************
* Function Name: Cy_SMIF_SetDelayLineForFreq
****************************************************************************//**
*
* Selects the right delay line for the specified frequency, so that the taps of
* that delay line should give enough possibilities to fine tune the delay in a
* subsequent calibration step.
*
* \note Expects that SMIF is not busy!
*
* \param base
* Holds the base address of the SMIF block registers.
*
* \param freqMhz
* The frequency of the SMIF clock (external)
*
* \param isDDR
* If the protocol has double data rate (e.g. in case of HyperBus)
*
* \param calculatedTap
* Caller can optionally retrieve the tap number index that was calculated by this
* function (value: 0 .. (SMIFn_DELAY_TAPS_NR - 1)). Pass NULL if value is not needed
*
* \return \ref cy_en_smif_status_t
*
*******************************************************************************/
cy_en_smif_status_t Cy_SMIF_SetDelayLineForFreq(volatile cy_stc_smif_reg_t *base, uint8_t freqMhz, bool isDDR, uint8_t *calculatedTap)
{
// TODO: Device dependent delays (and number of delay lines)
static const float32_t minDelayPerTapInNs[CY_SMIF_DRV_SMIF0_DELAY_LINES_NR] = {0.0559, 0.1197, 0.1935, 0.3973};
cy_en_smif_status_t status = CY_SMIF_SUCCESS;
uint8_t tapNumCalculated;
uint8_t delayLine;
uint8_t maxTaps = CY_SMIF_GetDelayTapsNumber(base);
// Calculate the offset to the nominal center of the data eye
float32_t clockPeriodNs = 1000.0 / freqMhz;
float32_t dataPeriodNs = clockPeriodNs / ((isDDR == true) ? 2.0 : 1.0);
float32_t dataPeriodCenterNs = dataPeriodNs / 2.0;
// Check all scan lines whether the number of taps required to hit the nominal center of the data eye are below the actual number of taps per delay line
for(delayLine = 0; delayLine < CY_SMIF_DRV_SMIF0_DELAY_LINES_NR; delayLine++)
{
tapNumCalculated = (uint8_t) ((dataPeriodCenterNs / minDelayPerTapInNs[delayLine]) + 0.5f);
if(tapNumCalculated <= maxTaps)
{
break;
}
}
// No matching delay line found, use the one with the largest delays and return error...
if(delayLine == 4)
{
delayLine = 3;
status = CY_SMIF_BAD_PARAM;
}
Cy_SMIF_Set_DelayLineSel(base, (cy_en_smif_delay_line_t)delayLine);
if(calculatedTap != NULL)
{
// If no matching delay line has been found, return the maximum number of taps
*calculatedTap = ((tapNumCalculated < maxTaps) ? tapNumCalculated : maxTaps) - 1;
}
return status;
}
/*******************************************************************************
* Function Name: Cy_SMIF_SetMasterDLP
****************************************************************************//**
*
* This function sets Data Learning Pattern to be compared.
*
* \param base
* Holds the base address of the SMIF block registers.
*
* \param dlp
* DLP value to be set.
*
*******************************************************************************/
void Cy_SMIF_SetMasterDLP(volatile cy_stc_smif_reg_t *base, uint16_t dlp)
{
base->unDL_CTL.stcField.u16DLP = dlp;
}
/*******************************************************************************
* Function Name: Cy_SMIF_GetMasterDLP
****************************************************************************//**
*
* This function reads Data Learning Pattern which have been set.
*
* \param base
* Holds the base address of the SMIF block registers.
*
* \return Master DLP value.
*
*******************************************************************************/
uint16_t Cy_SMIF_GetMasterDLP(volatile cy_stc_smif_reg_t *base)
{
return (uint16_t)(base->unDL_CTL.stcField.u16DLP);
}
/*******************************************************************************
* Function Name: Cy_SMIF_SetMasterDLP_Size
****************************************************************************//**
*
* This function writes DLP size to the register.
*
* \param base
* Holds the base address of the SMIF block registers.
*
* \param size
* DLP size value to be set to the register. Can be 1 ~ 16.
*
* \return \ref cy_en_smif_status_t
*
*******************************************************************************/
cy_en_smif_status_t Cy_SMIF_SetMasterDLP_Size(volatile cy_stc_smif_reg_t *base, uint32_t size)
{
if((size == 0) || (16 < size))
{
return CY_SMIF_BAD_PARAM;
}
base->unDL_CTL.stcField.u4DLP_SIZE = size - 1ul;
return CY_SMIF_SUCCESS;
}
/*******************************************************************************
* Function Name: Cy_SMIF_GetMasterDLP_Size
****************************************************************************//**
*
* This function reads DLP size which have been set.
*
* \param base
* Holds the base address of the SMIF block registers.
*
* \return Master DLP size value.
*
*******************************************************************************/
uint8_t Cy_SMIF_GetMasterDLP_Size(volatile cy_stc_smif_reg_t *base)
{
return (uint8_t)(base->unDL_CTL.stcField.u4DLP_SIZE);
}
/*******************************************************************************
* Function Name: Cy_SMIF_SetMasterDLP_WarnLevel
****************************************************************************//**
*
* This function writes DLP warning level to the register.
*
* \param base
* Holds the base address of the SMIF block registers.
*
* \param warnLevel
* Warning level value to be set to the resister.
*
* \return \ref cy_en_smif_status_t
*
*******************************************************************************/
cy_en_smif_status_t Cy_SMIF_SetMasterDLP_WarnLevel(volatile cy_stc_smif_reg_t *base, uint32_t warnLevel)
{
if(15 < warnLevel)
{
return CY_SMIF_BAD_PARAM;
}
base->unDL_CTL.stcField.u4DL_WARNING_LEVEL = warnLevel;
return CY_SMIF_SUCCESS;
}
/*******************************************************************************
* Function Name: Cy_SMIF_GetMasterDLP_WarnLevel
****************************************************************************//**
*
* This function reads DLP warning level which have been set.
*
* \param base
* Holds the base address of the SMIF block registers.
*
* \return Master DLP warning level value.
*
*******************************************************************************/
uint8_t Cy_SMIF_GetMasterDLP_WarnLevel(volatile cy_stc_smif_reg_t *base)
{
return (uint8_t)(base->unDL_CTL.stcField.u4DL_WARNING_LEVEL);
}
/*******************************************************************************
* Function Name: Cy_SMIF_GetTapNumCapturedCorrectDLP
****************************************************************************//**
*
* This function return tap number indicated by input bit number.
* \note not tested yet. this function may cause hardfault.
*
* \param base
* Holds the base address of the SMIF block registers.
*
* \param bit
* The tap number of the bit will be read.
*
* \return tap number
*
*******************************************************************************/
uint8_t Cy_SMIF_GetTapNumCapturedCorrectDLP(volatile cy_stc_smif_reg_t *base, uint8_t bit)
{
CY_ASSERT_L2(bit < 8u);
if(bit < 4u)
{
return(base->unDL_STATUS0.au8Byte[bit]);
}
else
{
return(base->unDL_STATUS1.au8Byte[bit - 4u]);
}
}
/*******************************************************************************
* Function Name: Cy_SMIF_Set_DelayLineSel
****************************************************************************//**
*
* This function enable delay line, and set line selection which is input.
*
* \param base
* Holds the base address of the SMIF block registers.
*
* \param lineSel
* delay line selection to be set
*
* \return status (see \ref cy_en_smif_status_t).
*
*******************************************************************************/
cy_en_smif_status_t Cy_SMIF_Set_DelayLineSel(volatile cy_stc_smif_reg_t *base, cy_en_smif_delay_line_t lineSel)
{
if(lineSel == CY_SMIF_NO_DELAY_SEL)
{
base->unCTL.stcField.u1DELAY_TAP_ENABLED = 0;
return CY_SMIF_SUCCESS;
}
cy_un_smif_reg_ctl_t tempCTL;
tempCTL.u32Register = base->unCTL.u32Register;
tempCTL.stcField.u1DELAY_TAP_ENABLED = 1;
tempCTL.stcField.u3DELAY_LINE_SEL = lineSel;
base->unCTL.u32Register = tempCTL.u32Register;
return CY_SMIF_SUCCESS;
}
/*******************************************************************************
* Function Name: Cy_SMIF_Get_DelayLineSel
****************************************************************************//**
*
* This function returns the currently selected delay line
*
* \param base
* Holds the base address of the SMIF block registers.
*
* \return delay line (see \ref cy_en_smif_delay_line_t).
*
*******************************************************************************/
cy_en_smif_delay_line_t Cy_SMIF_Get_DelayLineSel(volatile cy_stc_smif_reg_t *base)
{
if(base->unCTL.stcField.u1DELAY_TAP_ENABLED == 0)
{
return CY_SMIF_NO_DELAY_SEL;
}
else
{
return (cy_en_smif_delay_line_t) base->unCTL.stcField.u3DELAY_LINE_SEL;
}
}
/*******************************************************************************
* Function Name: Cy_SMIF_Set_DelayTapSel
****************************************************************************//**
*
* This function sets delay tap number for the SMIF (common for all its devices).
* To ensure compatibility with users of this API independent of the current
* SMIF IP version, it accepts any SMIF pointer as parameter, e.g. a SMIF base
* pointer or a SMIF_DEVICE base pointer. This means this API can be called with
* a SMIF_DEVICE base pointer and the calling code will work with CY_SMIF_NEW_VERSION
* or CY_SMIF_OLD_VERSION
*
* \param smif_or_device_base
* Holds the base address of the SMIF block or SMIF_DEVICE block registers.
*
* \param tapSel
* delay tap selection to be set
*
* \return status (see \ref cy_en_smif_status_t).
*
*******************************************************************************/
cy_en_smif_status_t Cy_SMIF_Set_DelayTapSel(volatile void *smif_or_device_base, uint8_t tapSel)
{
if(tapSel > (CY_SMIF_GetDelayTapsNumber(smif_or_device_base) - 1))
{
return CY_SMIF_BAD_PARAM;
}
if((smif_or_device_base != CY_SMIF_DRV_SMIF0_CORE0_DEVICE0) && (smif_or_device_base != CY_SMIF_DRV_SMIF0_CORE0_DEVICE1))
{
return CY_SMIF_BAD_PARAM;
}
((volatile cy_stc_smif_reg_device_t*)smif_or_device_base)->unDELAY_TAP_SEL.stcField.u8SEL = tapSel;
return CY_SMIF_SUCCESS;
}
/*******************************************************************************
* Function Name: Cy_SMIF_Get_DelayTapSel
****************************************************************************//**
*
* This function returns delay tap number which has been set for the SMIF (common for all its devices).
* To ensure compatibility with users of this API independent of the current
* SMIF IP version, it accepts any SMIF pointer as parameter, e.g. a SMIF base
* pointer or a SMIF_DEVICE base pointer. This means this API can be called with
* a SMIF_DEVICE base pointer and the calling code will work with CY_SMIF_NEW_VERSION
* or CY_SMIF_OLD_VERSION
*
* \param smif_or_device_base
* Holds the base address of the SMIF block or SMIF_DEVICE block registers.
*
* \return read tap selection
*
*******************************************************************************/
uint8_t Cy_SMIF_Get_DelayTapSel(volatile void *smif_or_device_base)
{
if((smif_or_device_base == CY_SMIF_DRV_SMIF0_CORE0_DEVICE0) || (smif_or_device_base == CY_SMIF_DRV_SMIF0_CORE0_DEVICE1))
{
return (uint8_t)(((volatile cy_stc_smif_reg_device_t*)smif_or_device_base)->unDELAY_TAP_SEL.stcField.u8SEL);
}
else
{
// Bad parameter input.
return 0u;
}
}
/*******************************************************************************
* Function Name: Cy_SMIF_SetTxFifoTriggerLevel()
****************************************************************************//**
*
* This function is used to set a trigger level for the TX FIFO. This value must
* be an integer between 0 and 7. For the normal mode only.
* The triggering is active when TX_DATA_FIFO_STATUS <= level.
*
* \param base
* Holds the base address of the SMIF block registers.
*
* \param level
* The trigger level to set (0-8).
*
*******************************************************************************/
void Cy_SMIF_SetTxFifoTriggerLevel(volatile cy_stc_smif_reg_t *base, uint32_t level)
{
CY_ASSERT_L2(level < CY_SMIF_MAX_TX_TR_LEVEL);
base->unTX_DATA_MMIO_FIFO_CTL.u32Register = level;
}
/*******************************************************************************
* Function Name: Cy_SMIF_SetCryptoInput128
****************************************************************************//**
*
* This function sets 128 bit data of crypto input (plain text).
*
* \param device
* Holds the base address of the SMIF Device registers.
*
* \param inData Address of input 16 byte input data to be crypted
*
*******************************************************************************/
void Cy_SMIF_SetCryptoInput128(volatile cy_stc_smif_reg_t *base, const uint8_t inData[])
{
base->SMIF_CRYPTO[0].unCRYPTO_INPUT0.u32Register = *(uint32_t*)&inData[0u];
base->SMIF_CRYPTO[0].unCRYPTO_INPUT1.u32Register = *(uint32_t*)&inData[4u];
base->SMIF_CRYPTO[0].unCRYPTO_INPUT2.u32Register = *(uint32_t*)&inData[8u];
base->SMIF_CRYPTO[0].unCRYPTO_INPUT3.u32Register = *(uint32_t*)&inData[12u];
}
/*******************************************************************************
* Function Name: Cy_SMIF_SetCryptoKey128
****************************************************************************//**
*
* This function sets 128 bit data of crypto key.
*
* \param device
* Holds the base address of the SMIF Device registers.
*
* \param key Address of 16 byte AES key data
*
*******************************************************************************/
void Cy_SMIF_SetCryptoKey128(volatile cy_stc_smif_reg_t *base, const uint8_t key[])
{
base->SMIF_CRYPTO[0].unCRYPTO_KEY0.u32Register = *(uint32_t*)&key[0u];
base->SMIF_CRYPTO[0].unCRYPTO_KEY1.u32Register = *(uint32_t*)&key[4u];
base->SMIF_CRYPTO[0].unCRYPTO_KEY2.u32Register = *(uint32_t*)&key[8u];
base->SMIF_CRYPTO[0].unCRYPTO_KEY3.u32Register = *(uint32_t*)&key[12u];
}
/*******************************************************************************
* Function Name: Cy_SMIF_GetTxFifoStatus()
****************************************************************************//**
*
* This function is used to read the status of the TX FIFO.
*
* \param base
* Holds the base address of the SMIF block registers.
*
* \return Returns the number of the entries in the TX FIFO.
*
*******************************************************************************/
uint32_t Cy_SMIF_GetTxFifoStatus(volatile cy_stc_smif_reg_t *base)
{
return (base->unTX_DATA_MMIO_FIFO_STATUS.stcField.u4USED4);
}
/*******************************************************************************
* Function Name: Cy_SMIF_PushCmdFifo()
****************************************************************************//**
*
* Push input data to SMIF tx command fifo.
*
* \param base
* Holds the base address of the SMIF block registers.
*
* \param data
* The data to be pushed.
*
* \param sizeInWord
* The size of the data to be pushed in words.
*
*******************************************************************************/
void Cy_SMIF_PushCmdFifo(volatile cy_stc_smif_reg_t *base, uint32_t data[], uint32_t sizeInWord)
{
for(uint32_t idx = 0ul; idx < sizeInWord; idx++)
{
base->unTX_CMD_MMIO_FIFO_WR.u32Register = data[idx];
}
}
/*******************************************************************************
* Function Name: Cy_SMIF_PushTxFifo
***************************************************************************//***
*
* \internal
*
* \param baseaddr
* Holds the base address of the SMIF block registers.
*
* \param context
* Passes a configuration structure that contains the transfer parameters of the
* SMIF block.
*
* This function writes data in the TX FIFO SMIF buffer by 4, 2, or 1 bytes based
* on the residual number of bytes and the available space in the TX FIFO.
*
*******************************************************************************/
void Cy_SMIF_PushTxFifo(volatile cy_stc_smif_reg_t *baseaddr, cy_stc_smif_context_t *context)
{
/* The variable that shows which is smaller: the free FIFO size or amount of bytes to be sent */
uint32_t freeFifoBytes = CY_SMIF_TX_DATA_FIFO_STATUS_RANGE - Cy_SMIF_GetTxFifoStatus(baseaddr);;
uint32_t buffCounter = context->txBufferCounter;
// writeBytes = MIN(freeFifoBytes, buffCounter);
uint32_t writeBytes = (freeFifoBytes > buffCounter)? buffCounter: freeFifoBytes;
// If it sends 2 byte per one clock, then it needs using TX_DATA_FIFO_WR1ODD when sending one byte.
// Save proper one byte sending fifo address into ptr1ByteFifo accordingly.
uint32_t* ptr1ByteFifo;
if((context->preCmdDataRate == CY_SMIF_DDR) &&(context->preCmdWidth == CY_SMIF_WIDTH_OCTAL))
{
ptr1ByteFifo = (uint32_t*)&(baseaddr->unTX_DATA_MMIO_FIFO_WR1ODD);
}
else
{
ptr1ByteFifo = (uint32_t*)&(baseaddr->unTX_DATA_MMIO_FIFO_WR1);
}
/* Check that after a FIFO Write, no data/FIFO space remains */
uint8_t *buff = (uint8_t*)context->txBufferAddress;
while (writeBytes != 0U)
{
// Even if writeBytes == 1, do not send it. Wait more space becoming available.
// Because 1 byte fifo (TX_DATA_FIFO_WR1) should be used only last 1 byte.
// If bufferCounter == 1, it means it is the last byte. then send it.
if((writeBytes >= 2U) || (buffCounter == 1))
{
if(writeBytes == 1)
{
// Enter here only when this is the last sending.
*ptr1ByteFifo = buff[0U];
}
else if((writeBytes == 2u) || (writeBytes == 3u))
{
baseaddr->unTX_DATA_MMIO_FIFO_WR2.u32Register = Cy_SMIF_PackBytesArray(&buff[0U], false);
writeBytes = 2u;
}
else if((writeBytes == 4u) || (writeBytes == 5u))
{
baseaddr->unTX_DATA_MMIO_FIFO_WR4.u32Register = Cy_SMIF_PackBytesArray(&buff[0U], true);
writeBytes = 4u;
}
else if((writeBytes == 6u) || (writeBytes == 7u))
{
baseaddr->unTX_DATA_MMIO_FIFO_WR4.u32Register = Cy_SMIF_PackBytesArray(&buff[0U], true);
baseaddr->unTX_DATA_MMIO_FIFO_WR2.u32Register = Cy_SMIF_PackBytesArray(&buff[4U], false);
writeBytes = 6u;
}
else /* writeBytes => 8*/
{
baseaddr->unTX_DATA_MMIO_FIFO_WR4.u32Register = Cy_SMIF_PackBytesArray(&buff[0U], true);
baseaddr->unTX_DATA_MMIO_FIFO_WR4.u32Register = Cy_SMIF_PackBytesArray(&buff[4U], true);
writeBytes = 8u;
}
buff = &buff[writeBytes];
buffCounter -= writeBytes;
}
/* Check if we already got new data in TX_FIFO*/
freeFifoBytes = CY_SMIF_TX_DATA_FIFO_STATUS_RANGE - Cy_SMIF_GetTxFifoStatus(baseaddr);
writeBytes = (freeFifoBytes > buffCounter)? buffCounter: freeFifoBytes;
}
/* Save changes in the context */
context->txBufferAddress = buff;
context->txBufferCounter = buffCounter;
/* Check if all bytes are sent */
if (buffCounter == 0u)
{
/* Disable the TR_TX_REQ interrupt */
baseaddr->unINTR_MASK.stcField.u1TR_TX_REQ = 0u;
context->transferStatus = CY_SMIF_SEND_CMPLT;
if (NULL != context->txCmpltCb)
{
context->txCmpltCb((uint32_t) CY_SMIF_SEND_CMPLT);
}
}
}
#if defined(__cplusplus)
}
#endif
#endif /* CY_IP_MXSMIF */
/* [] END OF FILE */
@@ -0,0 +1,217 @@
/***************************************************************************//**
* \file cy_smif_ver_specific.h
* \version `$CY_MAJOR_VERSION`.`$CY_MINOR_VERSION`
*
* Provides an API declaration of the Cypress SMIF v3.1 driver.
*
********************************************************************************
* \copyright
* Copyright 2016-2018, Cypress Semiconductor Corporation. All rights reserved.
* You may use this file only in accordance with the license, terms, conditions,
* disclaimers, and limitations in the end user license agreement accompanying
* the software package with which this file was provided.
*******************************************************************************/
/**
* \section group_smif_ver_specific_changelog Changelog
* <table class="doxtable">
* <tr><th>Version</th><th>Changes</th><th>Reason for Change</th></tr>
* <tr>
* <td>1.0</td>
* <td>Initial version</td>
* <td></td>
* </tr>
* </table>
*
*/
#if !defined(CY_SMIF_VER_SPECIFIC_H)
#define CY_SMIF_VER_SPECIFIC_H
#include <stdint.h>
#include <stdbool.h>
#include <stddef.h>
#include "cy_device_headers.h"
#ifdef CY_IP_MXSMIF
#if defined(__cplusplus)
extern "C" {
#endif
/* Typedef for smif driver, so make it common */
typedef stc_SMIF_t cy_stc_smif_reg_t;
typedef un_SMIF_CTL_t cy_un_smif_reg_ctl_t;
typedef un_SMIF_STATUS_t cy_un_smif_reg_status_t;
typedef un_SMIF_INT_CLOCK_DELAY_TAP_SEL0_t cy_un_smif_reg_dlp_delay_tap_sel0_t;
typedef un_SMIF_INT_CLOCK_DELAY_TAP_SEL1_t cy_un_smif_reg_dlp_delay_tap_sel1_t;
typedef un_SMIF_DL_CTL_t cy_un_smif_reg_dlp_ctl_t;
typedef un_SMIF_DL_STATUS0_t cy_un_smif_reg_dlp_status0_t;
typedef un_SMIF_DL_STATUS1_t cy_un_smif_reg_dlp_status1_t;
typedef un_SMIF_TX_CMD_FIFO_STATUS_t cy_un_smif_reg_tx_cmd_fifo_status_t;
typedef un_SMIF_TX_CMD_MMIO_FIFO_STATUS_t cy_un_smif_reg_tx_cmd_mmio_fifo_status_t;
typedef un_SMIF_TX_CMD_MMIO_FIFO_WR_t cy_un_smif_reg_tx_cmd_mmio_fifo_wr_t;
typedef un_SMIF_TX_DATA_MMIO_FIFO_CTL_t cy_un_smif_reg_tx_data_mmio_fifo_ctl_t;
typedef un_SMIF_TX_DATA_FIFO_STATUS_t cy_un_smif_reg_tx_data_fifo_status_t;
typedef un_SMIF_TX_DATA_MMIO_FIFO_STATUS_t cy_un_smif_reg_tx_data_mmio_fifo_status_t;
typedef un_SMIF_TX_DATA_MMIO_FIFO_WR1_t cy_un_smif_reg_tx_data_mmio_fifo_wr1_t;
typedef un_SMIF_TX_DATA_MMIO_FIFO_WR2_t cy_un_smif_reg_tx_data_mmio_fifo_wr2_t;
typedef un_SMIF_TX_DATA_MMIO_FIFO_WR4_t cy_un_smif_reg_tx_data_mmio_fifo_wr4_t;
typedef un_SMIF_TX_DATA_MMIO_FIFO_WR1ODD_t cy_un_smif_reg_tx_data_mmio_fifo_wr1odd_t;
typedef un_SMIF_RX_DATA_MMIO_FIFO_CTL_t cy_un_smif_reg_rx_data_mmio_fifo_ctl_t;
typedef un_SMIF_RX_DATA_MMIO_FIFO_STATUS_t cy_un_smif_reg_rx_data_mmio_fifo_status_t;
typedef un_SMIF_RX_DATA_FIFO_STATUS_t cy_un_smif_reg_rx_data_fifo_status_t;
typedef un_SMIF_RX_DATA_MMIO_FIFO_RD1_t cy_un_smif_reg_rx_data_mmio_fifo_rd1_t;
typedef un_SMIF_RX_DATA_MMIO_FIFO_RD2_t cy_un_smif_reg_rx_data_mmio_fifo_rd2_t;
typedef un_SMIF_RX_DATA_MMIO_FIFO_RD4_t cy_un_smif_reg_rx_data_mmio_fifo_rd4_t;
typedef un_SMIF_RX_DATA_MMIO_FIFO_RD1_SILENT_t cy_un_smif_reg_rx_data_mmio_fifo_rd1_silent_t;
typedef un_SMIF_SLOW_CA_CTL_t cy_un_smif_reg_slow_ca_ctl_t;
typedef un_SMIF_SLOW_CA_CMD_t cy_un_smif_reg_slow_ca_cmd_t;
typedef un_SMIF_FAST_CA_CTL_t cy_un_smif_reg_fast_ca_ctl_t;
typedef un_SMIF_FAST_CA_CMD_t cy_un_smif_reg_fast_ca_cmd_t;
typedef un_SMIF_CRC_CMD_t cy_un_smif_reg_crc_cmd_t;
typedef un_SMIF_CRC_INPUT0_t cy_un_smif_reg_crc_input0_t;
typedef un_SMIF_CRC_INPUT1_t cy_un_smif_reg_crc_input1_t;
typedef un_SMIF_CRC_OUTPUT_t cy_un_smif_reg_crc_output_t;
typedef un_SMIF_INTR_t cy_un_smif_reg_intr_t;
typedef un_SMIF_INTR_SET_t cy_un_smif_reg_intr_set_t;
typedef un_SMIF_INTR_MASK_t cy_un_smif_reg_intr_mask_t;
typedef un_SMIF_INTR_MASKED_t cy_un_smif_reg_intr_masked_t;
typedef un_SMIF_INTR_CAUSE_t cy_un_smif_reg_cause_t;
typedef stc_SMIF_DEVICE_t cy_stc_smif_reg_device_t;
typedef un_SMIF_DEVICE_CTL_t cy_un_smif_reg_device_ctl_t;
typedef un_SMIF_DEVICE_ADDR_t cy_un_smif_reg_device_addr_t;
typedef un_SMIF_DEVICE_MASK_t cy_un_smif_reg_device_mask_t;
typedef un_SMIF_DEVICE_ADDR_CTL_t cy_un_smif_reg_device_addr_ctl_t;
typedef un_SMIF_DEVICE_DELAY_TAP_SEL_t cy_un_smif_reg_device_capture_config_t;
typedef un_SMIF_DEVICE_RD_STATUS_t cy_un_smif_reg_device_rd_status_t;
typedef un_SMIF_DEVICE_RD_CMD_CTL_t cy_un_smif_reg_device_rd_cmd_ctl_t;
typedef un_SMIF_DEVICE_RD_ADDR_CTL_t cy_un_smif_reg_device_rd_addr_ctl_t;
typedef un_SMIF_DEVICE_RD_MODE_CTL_t cy_un_smif_reg_device_rd_mode_ctl_t;
typedef un_SMIF_DEVICE_RD_DUMMY_CTL_t cy_un_smif_reg_device_rd_dummy_t;
typedef un_SMIF_DEVICE_RD_DATA_CTL_t cy_un_smif_reg_device_rd_data_ctl_t;
typedef un_SMIF_DEVICE_RD_CRC_CTL_t cy_un_smif_reg_device_rd_crc_ctl_t;
typedef un_SMIF_DEVICE_RD_BOUND_CTL_t cy_un_smif_reg_device_rd_bound_ctl_t;
typedef un_SMIF_DEVICE_WR_CMD_CTL_t cy_un_smif_reg_device_wr_cmd_t;
typedef un_SMIF_DEVICE_WR_ADDR_CTL_t cy_un_smif_reg_device_wr_addr_t;
typedef un_SMIF_DEVICE_WR_MODE_CTL_t cy_un_smif_reg_device_wr_mode_ctl_t;
typedef un_SMIF_DEVICE_WR_DUMMY_CTL_t cy_un_smif_reg_device_wr_dummy_ctl_t;
typedef un_SMIF_DEVICE_WR_DATA_CTL_t cy_un_smif_reg_device_wr_data_ctl_t;
typedef un_SMIF_DEVICE_WR_CRC_CTL_t cy_un_smif_reg_device_wr_crc_ctl_t;
typedef stc_SMIF_SMIF_CRYPTO_t cy_stc_smif_reg_crypto_t;
typedef un_SMIF_SMIF_CRYPTO_CRYPTO_CMD_t cy_un_smif_reg_crypto_cmd_t;
typedef un_SMIF_SMIF_CRYPTO_CRYPTO_ADDR_t cy_un_smif_reg_crypto_addr_t;
typedef un_SMIF_SMIF_CRYPTO_CRYPTO_MASK_t cy_un_smif_reg_crypto_mask_t;
typedef un_SMIF_SMIF_CRYPTO_CRYPTO_SUBREGION_t cy_un_smif_reg_crypto_subregion_t;
typedef un_SMIF_SMIF_CRYPTO_CRYPTO_INPUT0_t cy_un_smif_reg_crypto_input0_t;
typedef un_SMIF_SMIF_CRYPTO_CRYPTO_INPUT1_t cy_un_smif_reg_crypto_input1_t;
typedef un_SMIF_SMIF_CRYPTO_CRYPTO_INPUT2_t cy_un_smif_reg_crypto_input2_t;
typedef un_SMIF_SMIF_CRYPTO_CRYPTO_INPUT3_t cy_un_smif_reg_crypto_input3_t;
typedef un_SMIF_SMIF_CRYPTO_CRYPTO_KEY0_t cy_un_smif_reg_crypto_key0_t;
typedef un_SMIF_SMIF_CRYPTO_CRYPTO_KEY1_t cy_un_smif_reg_crypto_key1_t;
typedef un_SMIF_SMIF_CRYPTO_CRYPTO_KEY2_t cy_un_smif_reg_crypto_key2_t;
typedef un_SMIF_SMIF_CRYPTO_CRYPTO_KEY3_t cy_un_smif_reg_crypto_key3_t;
typedef un_SMIF_SMIF_CRYPTO_CRYPTO_OUTPUT0_t cy_un_smif_reg_crypto_output0_t;
typedef un_SMIF_SMIF_CRYPTO_CRYPTO_OUTPUT1_t cy_un_smif_reg_crypto_output1_t;
typedef un_SMIF_SMIF_CRYPTO_CRYPTO_OUTPUT2_t cy_un_smif_reg_crypto_output2_t;
typedef un_SMIF_SMIF_CRYPTO_CRYPTO_OUTPUT3_t cy_un_smif_reg_crypto_output3_t;
/* Definitions for smif register masks, so make it common (only for required entities) */
#define CY_SMIF_DRV_DEVICE_ADDR_MSK SMIF_DEVICE_ADDR_ADDR_Msk
#define CY_SMIF_DRV_INTR_TR_TX_REQ_MSK SMIF_INTR_TR_TX_REQ_Msk
#define CY_SMIF_DRV_INTR_TR_RX_REQ_MSK SMIF_INTR_TR_RX_REQ_Msk
#define CY_SMIF_DRV_INTR_XIP_ALIGNMENT_ERROR_MSK SMIF_INTR_XIP_ALIGNMENT_ERROR_Msk
#define CY_SMIF_DRV_INTR_TX_CMD_FIFO_OVERFLOW_MSK SMIF_INTR_TX_CMD_FIFO_OVERFLOW_Msk
#define CY_SMIF_DRV_INTR_TX_DATA_FIFO_OVERFLOW_MSK SMIF_INTR_TX_DATA_FIFO_OVERFLOW_Msk
#define CY_SMIF_DRV_INTR_RX_DATA_MMIO_FIFO_UNDERFLOW_MSK SMIF_INTR_RX_DATA_MMIO_FIFO_UNDERFLOW_Msk
/* Definitions for smif register top address, so make it common */
#if defined(SMIF0)
#define CY_SMIF_DRV_SMIF0_CORE0 SMIF0
#endif
#if defined(SMIF1)
#define CY_SMIF_CORE1_EXISTS
#define CY_SMIF_DRV_SMIF0_CORE1 SMIF1
#endif
#if defined(SMIF0_DEVICE0)
#define CY_SMIF_DRV_SMIF0_CORE0_DEVICE0 SMIF0_DEVICE0
#endif
#if defined(SMIF0_DEVICE1)
#define CY_SMIF_DRV_SMIF0_CORE0_DEVICE1 SMIF0_DEVICE1
#endif
#if defined(SMIF1_DEVICE0)
#define CY_SMIF_DRV_SMIF0_CORE1_DEVICE0 SMIF1_DEVICE0
#endif
#if defined(SMIF1_DEVICE1)
#define CY_SMIF_DRV_SMIF0_CORE1_DEVICE1 SMIF1_DEVICE1
#endif
#if defined(SMIF_DEVICE_SECTION_SIZE)
#define CY_SMIF_DRV_DEVICE_SECTION_SIZE SMIF_DEVICE_SECTION_SIZE
#endif
#define CY_SMIF_DRV_SMIF0_IRQN smif_0_interrupt_IRQn
#if defined(CY_SMIF_CORE1_EXISTS)
#define CY_SMIF_DRV_SMIF1_IRQN smif_1_interrupt_IRQn
#endif
/* Specifies the clock source for "clk_if". Must be 0 (clk_hf) */
/* before entering DeepSleep; can be returned to 1 (clk_pll) afterwards. */
typedef enum
{
CY_SMIF_CLKIF_SRC_CLK_HF = 0, /**< Clock source clk_hf */
CY_SMIF_CLKIF_SRC_CLK_PLL = 1 /**< Clock source clk_pll */
} cy_en_cy_clkif_source_t;
#include "smif/common/cy_smif.h"
/**
* \addtogroup group_smif_version_specific_functions
* This device uses SMIF revision 3.1
* \{
*/
extern cy_en_smif_status_t Cy_SMIF_Init(volatile cy_stc_smif_reg_t *base, cy_stc_smif_config_t const *config, uint32_t timeout, cy_stc_smif_context_t *context);
extern void Cy_SMIF_DeInit(volatile cy_stc_smif_reg_t *base);
extern cy_en_smif_status_t Cy_SMIF_Encrypt(volatile cy_stc_smif_reg_t *base, uint32_t address, uint8_t dataInOut[], uint32_t sizeInByte, cy_stc_smif_context_t const *context);
extern cy_en_smif_status_t Cy_SMIF_SetDelayLineForFreq(volatile cy_stc_smif_reg_t *base, uint8_t freqMhz, bool isDDR, uint8_t *calculatedTap);
extern void Cy_SMIF_SetMasterDLP(volatile cy_stc_smif_reg_t *base, uint16_t dlp);
extern uint16_t Cy_SMIF_GetMasterDLP(volatile cy_stc_smif_reg_t *base);
extern cy_en_smif_status_t Cy_SMIF_SetMasterDLP_Size(volatile cy_stc_smif_reg_t *base, uint32_t size);
extern uint8_t Cy_SMIF_GetMasterDLP_Size(volatile cy_stc_smif_reg_t *base);
extern cy_en_smif_status_t Cy_SMIF_SetMasterDLP_WarnLevel(volatile cy_stc_smif_reg_t *base, uint32_t warnLevel);
extern uint8_t Cy_SMIF_GetMasterDLP_WarnLevel(volatile cy_stc_smif_reg_t *base);
extern uint8_t Cy_SMIF_GetTapNumCapturedCorrectDLP(volatile cy_stc_smif_reg_t *base, uint8_t bit);
extern cy_en_smif_status_t Cy_SMIF_Set_DelayLineSel(volatile cy_stc_smif_reg_t *base, cy_en_smif_delay_line_t lineSel);
extern cy_en_smif_delay_line_t Cy_SMIF_Get_DelayLineSel(volatile cy_stc_smif_reg_t *base);
extern cy_en_smif_status_t Cy_SMIF_Set_DelayTapSel(volatile void *smif_or_device_base, uint8_t tapSel);
extern uint8_t Cy_SMIF_Get_DelayTapSel(volatile void *smif_or_device_base);
extern void Cy_SMIF_SetTxFifoTriggerLevel(volatile cy_stc_smif_reg_t *base, uint32_t level);
extern void Cy_SMIF_SetCryptoInput128(volatile cy_stc_smif_reg_t *base, const uint8_t inData[]);
extern void Cy_SMIF_SetCryptoKey128(volatile cy_stc_smif_reg_t *base, const uint8_t key[]);
extern uint32_t Cy_SMIF_GetTxFifoStatus(volatile cy_stc_smif_reg_t *base);
extern void Cy_SMIF_PushCmdFifo(volatile cy_stc_smif_reg_t *base, uint32_t data[], uint32_t sizeInWord);
extern void Cy_SMIF_PushTxFifo(volatile cy_stc_smif_reg_t *baseaddr, cy_stc_smif_context_t *context);
/** \} group_smif_version_specific_functions */
#if defined(__cplusplus)
}
#endif
#endif /* CY_IP_MXSMIF */
#endif /* (CY_SMIF_H) */
/** \} group_smif */
/* [] END OF FILE */
@@ -0,0 +1,4 @@
V4_0 for C2D6M rev_b (onwards) and C2D6MDDR rev_a.
V4_0 represents SMIF_4_0
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,389 @@
/***************************************************************************//**
* \file cy_smif_ver_specific.h
* \version `$CY_MAJOR_VERSION`.`$CY_MINOR_VERSION`
*
* Provides an API declaration of the Cypress SMIF v4.0 driver.
*
********************************************************************************
* \copyright
* Copyright 2016-2018, Cypress Semiconductor Corporation. All rights reserved.
* You may use this file only in accordance with the license, terms, conditions,
* disclaimers, and limitations in the end user license agreement accompanying
* the software package with which this file was provided.
*******************************************************************************/
/**
* \section group_smif_ver_specific_changelog Changelog
* <table class="doxtable">
* <tr><th>Version</th><th>Changes</th><th>Reason for Change</th></tr>
* <tr>
* <td>1.0</td>
* <td>Initial version</td>
* <td></td>
* </tr>
* </table>
*
*/
#if !defined(CY_SMIF_VER_SPECIFIC_H)
#define CY_SMIF_VER_SPECIFIC_H
#include <stdint.h>
#include <stdbool.h>
#include <stddef.h>
#include "cy_device_headers.h"
#ifdef CY_IP_MXSMIF
#if defined(__cplusplus)
extern "C" {
#endif
/* Typedef for smif driver, so make it common */
typedef stc_SMIF_t cy_stc_smif_base_reg_t;
typedef stc_SMIF_CORE_t cy_stc_smif_reg_t;
typedef un_SMIF_CORE_CTL_t cy_un_smif_reg_ctl_t;
typedef un_SMIF_CORE_STATUS_t cy_un_smif_reg_status_t;
typedef un_SMIF_CORE_CTL2_t cy_un_smif_reg_ctl2_t;
typedef un_SMIF_CORE_DLP_DELAY_TAP_SEL0_t cy_un_smif_reg_dlp_delay_tap_sel0_t;
typedef un_SMIF_CORE_DLP_DELAY_TAP_SEL1_t cy_un_smif_reg_dlp_delay_tap_sel1_t;
typedef un_SMIF_CORE_DLP_CTL_t cy_un_smif_reg_dlp_ctl_t;
typedef un_SMIF_CORE_DLP_STATUS0_t cy_un_smif_reg_dlp_status0_t;
typedef un_SMIF_CORE_DLP_STATUS1_t cy_un_smif_reg_dlp_status1_t;
typedef un_SMIF_CORE_TX_CMD_FIFO_STATUS_t cy_un_smif_reg_tx_cmd_fifo_status_t;
typedef un_SMIF_CORE_TX_CMD_MMIO_FIFO_STATUS_t cy_un_smif_reg_tx_cmd_mmio_fifo_status_t;
typedef un_SMIF_CORE_TX_CMD_MMIO_FIFO_WR_t cy_un_smif_reg_tx_cmd_mmio_fifo_wr_t;
typedef un_SMIF_CORE_TX_DATA_MMIO_FIFO_CTL_t cy_un_smif_reg_tx_data_mmio_fifo_ctl_t;
typedef un_SMIF_CORE_TX_DATA_FIFO_STATUS_t cy_un_smif_reg_tx_data_fifo_status_t;
typedef un_SMIF_CORE_TX_DATA_MMIO_FIFO_STATUS_t cy_un_smif_reg_tx_data_mmio_fifo_status_t;
typedef un_SMIF_CORE_TX_DATA_MMIO_FIFO_WR1_t cy_un_smif_reg_tx_data_mmio_fifo_wr1_t;
typedef un_SMIF_CORE_TX_DATA_MMIO_FIFO_WR2_t cy_un_smif_reg_tx_data_mmio_fifo_wr2_t;
typedef un_SMIF_CORE_TX_DATA_MMIO_FIFO_WR4_t cy_un_smif_reg_tx_data_mmio_fifo_wr4_t;
typedef un_SMIF_CORE_TX_DATA_MMIO_FIFO_WR1ODD_t cy_un_smif_reg_tx_data_mmio_fifo_wr1odd_t;
typedef un_SMIF_CORE_RX_DATA_MMIO_FIFO_CTL_t cy_un_smif_reg_rx_data_mmio_fifo_ctl_t;
typedef un_SMIF_CORE_RX_DATA_MMIO_FIFO_STATUS_t cy_un_smif_reg_rx_data_mmio_fifo_status_t;
typedef un_SMIF_CORE_RX_DATA_FIFO_STATUS_t cy_un_smif_reg_rx_data_fifo_status_t;
typedef un_SMIF_CORE_RX_DATA_MMIO_FIFO_RD1_t cy_un_smif_reg_rx_data_mmio_fifo_rd1_t;
typedef un_SMIF_CORE_RX_DATA_MMIO_FIFO_RD2_t cy_un_smif_reg_rx_data_mmio_fifo_rd2_t;
typedef un_SMIF_CORE_RX_DATA_MMIO_FIFO_RD4_t cy_un_smif_reg_rx_data_mmio_fifo_rd4_t;
typedef un_SMIF_CORE_RX_DATA_MMIO_FIFO_RD1_SILENT_t cy_un_smif_reg_rx_data_mmio_fifo_rd1_silent_t;
typedef un_SMIF_CORE_SLOW_CA_CTL_t cy_un_smif_reg_slow_ca_ctl_t;
typedef un_SMIF_CORE_SLOW_CA_CMD_t cy_un_smif_reg_slow_ca_cmd_t;
typedef un_SMIF_CORE_FAST_CA_CTL_t cy_un_smif_reg_fast_ca_ctl_t;
typedef un_SMIF_CORE_FAST_CA_CMD_t cy_un_smif_reg_fast_ca_cmd_t;
typedef un_SMIF_CORE_CRC_CMD_t cy_un_smif_reg_crc_cmd_t;
typedef un_SMIF_CORE_CRC_INPUT0_t cy_un_smif_reg_crc_input0_t;
typedef un_SMIF_CORE_CRC_INPUT1_t cy_un_smif_reg_crc_input1_t;
typedef un_SMIF_CORE_CRC_OUTPUT_t cy_un_smif_reg_crc_output_t;
typedef un_SMIF_CORE_INTR_t cy_un_smif_reg_intr_t;
typedef un_SMIF_CORE_INTR_SET_t cy_un_smif_reg_intr_set_t;
typedef un_SMIF_CORE_INTR_MASK_t cy_un_smif_reg_intr_mask_t;
typedef un_SMIF_CORE_INTR_MASKED_t cy_un_smif_reg_intr_masked_t;
typedef stc_SMIF_CORE_DEVICE_t cy_stc_smif_reg_device_t;
typedef un_SMIF_CORE_DEVICE_CTL_t cy_un_smif_reg_device_ctl_t;
typedef un_SMIF_CORE_DEVICE_ADDR_t cy_un_smif_reg_device_addr_t;
typedef un_SMIF_CORE_DEVICE_MASK_t cy_un_smif_reg_device_mask_t;
typedef un_SMIF_CORE_DEVICE_ADDR_CTL_t cy_un_smif_reg_device_addr_ctl_t;
typedef un_SMIF_CORE_DEVICE_RX_CAPTURE_CONFIG_t cy_un_smif_reg_device_capture_config_t;
typedef un_SMIF_CORE_DEVICE_RD_STATUS_t cy_un_smif_reg_device_rd_status_t;
typedef un_SMIF_CORE_DEVICE_RD_CMD_CTL_t cy_un_smif_reg_device_rd_cmd_ctl_t;
typedef un_SMIF_CORE_DEVICE_RD_ADDR_CTL_t cy_un_smif_reg_device_rd_addr_ctl_t;
typedef un_SMIF_CORE_DEVICE_RD_MODE_CTL_t cy_un_smif_reg_device_rd_mode_ctl_t;
typedef un_SMIF_CORE_DEVICE_RD_DUMMY_CTL_t cy_un_smif_reg_device_rd_dummy_t;
typedef un_SMIF_CORE_DEVICE_RD_DATA_CTL_t cy_un_smif_reg_device_rd_data_ctl_t;
typedef un_SMIF_CORE_DEVICE_RD_CRC_CTL_t cy_un_smif_reg_device_rd_crc_ctl_t;
typedef un_SMIF_CORE_DEVICE_RD_BOUND_CTL_t cy_un_smif_reg_device_rd_bound_ctl_t;
typedef un_SMIF_CORE_DEVICE_WR_CMD_CTL_t cy_un_smif_reg_device_wr_cmd_t;
typedef un_SMIF_CORE_DEVICE_WR_ADDR_CTL_t cy_un_smif_reg_device_wr_addr_t;
typedef un_SMIF_CORE_DEVICE_WR_MODE_CTL_t cy_un_smif_reg_device_wr_mode_ctl_t;
typedef un_SMIF_CORE_DEVICE_WR_DUMMY_CTL_t cy_un_smif_reg_device_wr_dummy_ctl_t;
typedef un_SMIF_CORE_DEVICE_WR_DATA_CTL_t cy_un_smif_reg_device_wr_data_ctl_t;
typedef un_SMIF_CORE_DEVICE_WR_CRC_CTL_t cy_un_smif_reg_device_wr_crc_ctl_t;
typedef stc_SMIF_CORE_SMIF_CRYPTO_t cy_stc_smif_reg_crypto_t;
typedef un_SMIF_CORE_SMIF_CRYPTO_CRYPTO_CMD_t cy_un_smif_reg_crypto_cmd_t;
typedef un_SMIF_CORE_SMIF_CRYPTO_CRYPTO_ADDR_t cy_un_smif_reg_crypto_addr_t;
typedef un_SMIF_CORE_SMIF_CRYPTO_CRYPTO_MASK_t cy_un_smif_reg_crypto_mask_t;
typedef un_SMIF_CORE_SMIF_CRYPTO_CRYPTO_SUBREGION_t cy_un_smif_reg_crypto_subregion_t;
typedef un_SMIF_CORE_SMIF_CRYPTO_CRYPTO_INPUT0_t cy_un_smif_reg_crypto_input0_t;
typedef un_SMIF_CORE_SMIF_CRYPTO_CRYPTO_INPUT1_t cy_un_smif_reg_crypto_input1_t;
typedef un_SMIF_CORE_SMIF_CRYPTO_CRYPTO_INPUT2_t cy_un_smif_reg_crypto_input2_t;
typedef un_SMIF_CORE_SMIF_CRYPTO_CRYPTO_INPUT3_t cy_un_smif_reg_crypto_input3_t;
typedef un_SMIF_CORE_SMIF_CRYPTO_CRYPTO_KEY0_t cy_un_smif_reg_crypto_key0_t;
typedef un_SMIF_CORE_SMIF_CRYPTO_CRYPTO_KEY1_t cy_un_smif_reg_crypto_key1_t;
typedef un_SMIF_CORE_SMIF_CRYPTO_CRYPTO_KEY2_t cy_un_smif_reg_crypto_key2_t;
typedef un_SMIF_CORE_SMIF_CRYPTO_CRYPTO_KEY3_t cy_un_smif_reg_crypto_key3_t;
typedef un_SMIF_CORE_SMIF_CRYPTO_CRYPTO_OUTPUT0_t cy_un_smif_reg_crypto_output0_t;
typedef un_SMIF_CORE_SMIF_CRYPTO_CRYPTO_OUTPUT1_t cy_un_smif_reg_crypto_output1_t;
typedef un_SMIF_CORE_SMIF_CRYPTO_CRYPTO_OUTPUT2_t cy_un_smif_reg_crypto_output2_t;
typedef un_SMIF_CORE_SMIF_CRYPTO_CRYPTO_OUTPUT3_t cy_un_smif_reg_crypto_output3_t;
typedef stc_SMIF_SMIF_BRIDGE_t cy_stc_smif_reg_bridge_t;
typedef un_SMIF_SMIF_BRIDGE_CTL_t cy_un_smif_reg_bridge_ctl_t;
typedef stc_SMIF_SMIF_BRIDGE_SMIF_REMAP_REGION_t cy_stc_smif_reg_bridge_region_t;
typedef un_SMIF_SMIF_BRIDGE_SMIF_REMAP_REGION_CTL_t cy_stc_smif_reg_bridge_region_ctl_t;
typedef un_SMIF_SMIF_BRIDGE_SMIF_REMAP_REGION_ADDR_t cy_stc_smif_reg_bridge_region_addr_t;
typedef un_SMIF_SMIF_BRIDGE_SMIF_REMAP_REGION_MASK_t cy_stc_smif_reg_bridge_region_mask_t;
typedef un_SMIF_SMIF_BRIDGE_SMIF_REMAP_REGION_SMIF0_REMAP_t cy_stc_smif_reg_bridge_region_smif0_remap_t;
typedef un_SMIF_SMIF_BRIDGE_SMIF_REMAP_REGION_SMIF1_REMAP_t cy_stc_smif_reg_bridge_region_smif1_remap_t;
/* Definitions for smif device parameters */
#define CY_SMIF_CORE_COUNT (2ul)
#define CY_SMIF_BRIGE_REMAP_REGION_COUNT (8ul)
/* Definitions for smif register masks, so make it common (only for required entities) */
#define CY_SMIF_DRV_DEVICE_ADDR_MSK SMIF_CORE_DEVICE_ADDR_ADDR_Msk
#define CY_SMIF_DRV_INTR_TR_TX_REQ_MSK SMIF_CORE_INTR_TR_TX_REQ_Msk
#define CY_SMIF_DRV_INTR_TR_RX_REQ_MSK SMIF_CORE_INTR_TR_RX_REQ_Msk
#define CY_SMIF_DRV_INTR_XIP_ALIGNMENT_ERROR_MSK SMIF_CORE_INTR_XIP_ALIGNMENT_ERROR_Msk
#define CY_SMIF_DRV_INTR_TX_CMD_FIFO_OVERFLOW_MSK SMIF_CORE_INTR_TX_CMD_FIFO_OVERFLOW_Msk
#define CY_SMIF_DRV_INTR_TX_DATA_FIFO_OVERFLOW_MSK SMIF_CORE_INTR_TX_DATA_FIFO_OVERFLOW_Msk
#define CY_SMIF_DRV_INTR_RX_DATA_MMIO_FIFO_UNDERFLOW_MSK SMIF_CORE_INTR_RX_DATA_MMIO_FIFO_UNDERFLOW_Msk
/* Definitions for smif register top address, so make it common */
#if defined(SMIF0_CORE0)
#define CY_SMIF_DRV_SMIF0_CORE0 SMIF0_CORE0
#endif
#if defined(SMIF0_CORE1)
#define CY_SMIF_CORE1_EXISTS
#define CY_SMIF_DRV_SMIF0_CORE1 SMIF0_CORE1
#endif
#if defined(SMIF0_CORE0_DEVICE0)
#define CY_SMIF_DRV_SMIF0_CORE0_DEVICE0 SMIF0_CORE0_DEVICE0
#endif
#if defined(SMIF0_CORE0_DEVICE1)
#define CY_SMIF_DRV_SMIF0_CORE0_DEVICE1 SMIF0_CORE0_DEVICE1
#endif
#if defined(SMIF0_CORE1_DEVICE0)
#define CY_SMIF_DRV_SMIF0_CORE1_DEVICE0 SMIF0_CORE1_DEVICE0
#endif
#if defined(SMIF0_CORE1_DEVICE1)
#define CY_SMIF_DRV_SMIF0_CORE1_DEVICE1 SMIF0_CORE1_DEVICE1
#endif
#if defined(SMIF_CORE_DEVICE_SECTION_SIZE)
#define CY_SMIF_DRV_DEVICE_SECTION_SIZE SMIF_CORE_DEVICE_SECTION_SIZE
#endif
#define CY_SMIF_DRV_SMIF0_IRQN smif_0_smif0_interrupt_IRQn
#if defined(CY_SMIF_CORE1_EXISTS)
#define CY_SMIF_DRV_SMIF1_IRQN smif_0_smif1_interrupt_IRQn
#endif
/* Set path of the PLL clock frequency that feeds the DLL */
typedef enum
{
CY_SMIF_CLKIF_SRC_CLK_PLL_NORMAL = 0, /**< clk_pll_normal is used to create clk_if */
//CY_SMIF_CLKIF_SRC_CLK_PLL_DIRECT = 1 /**< clk_pll_direct is used to create clk_if (not for customer use!) */
} cy_en_cy_clkif_source_t;
/** The SMIF configuration structure. */
/* Set according to the PLL clock frequency that feeds the DLL */
typedef enum
{
CY_SMIF_DLL_SRC_PLL_FREQ_160_To_180MHz = 0, /**< 160 to 180 MHz */
CY_SMIF_DLL_SRC_PLL_FREQ_180_To_266MHz = 1, /**< >180 to 266 MHz */
CY_SMIF_DLL_SRC_PLL_FREQ_266_To_333MHz = 2, /**< >266 to 333 MHz */
CY_SMIF_DLL_SRC_PLL_FREQ_333_To_400MHz = 3, /**< >333 to 400 MHz */
} cy_en_cy_smif_dll_speed_mode_t;
/* The clock out to the memory is a divided version of the MDL clock out */
typedef enum
{
CY_SMIF_MDL_CLK_OUT_DIV2 = 0, /**< Divided by 2 */
CY_SMIF_MDL_CLK_OUT_DIV4 = 1, /**< Divided by 4 */
CY_SMIF_MDL_CLK_OUT_DIV8 = 2, /**< Divided by 8 */
CY_SMIF_MDL_CLK_OUT_DIV16 = 3, /**< Divided by 16 */
} cy_en_cy_smif_mdl_clk_out_div_t;
/* Determines the relative amount of delay through the MDL/SDL(including neg and pos) for the reference clock in terms of the number of tap delays. */
typedef enum
{
CY_SMIF_DDL_1_TAP_DELAY = 0, /**< 1 tap delay */
CY_SMIF_DDL_2_TAP_DELAY = 1, /**< 2 tap delay */
CY_SMIF_DDL_3_TAP_DELAY = 2, /**< 3 tap delay */
CY_SMIF_DDL_4_TAP_DELAY = 3, /**< 4 tap delay */
CY_SMIF_DDL_5_TAP_DELAY = 4, /**< 5 tap delay */
CY_SMIF_DDL_6_TAP_DELAY = 5, /**< 6 tap delay */
CY_SMIF_DDL_7_TAP_DELAY = 6, /**< 7 tap delay */
CY_SMIF_DDL_8_TAP_DELAY = 7, /**< 8 tap delay */
CY_SMIF_DDL_9_TAP_DELAY = 8, /**< 9 tap delay */
CY_SMIF_DDL_10_TAP_DELAY = 9, /**< 10 tap delay */
CY_SMIF_DDL_11_TAP_DELAY = 10, /**< 11 tap delay */
CY_SMIF_DDL_12_TAP_DELAY = 11, /**< 12 tap delay */
CY_SMIF_DDL_13_TAP_DELAY = 12, /**< 13 tap delay */
CY_SMIF_DDL_14_TAP_DELAY = 13, /**< 14 tap delay */
CY_SMIF_DDL_15_TAP_DELAY = 14, /**< 15 tap delay */
CY_SMIF_DDL_16_TAP_DELAY = 15, /**< 16 tap delay */
CY_SMIF_DDL_TAP_NULMBER = 16, /**< Tap Count */
} cy_en_cy_smif_ddl_tap_sel_t;
#define CY_SMIF_DLL_TAP_MAX (CY_SMIF_DDL_TAP_NULMBER)
/* Determines the receive capture mode: */
typedef enum
{
CY_SMIF_CAP_MODE_SPI = 0, /**< SPI without RWDS, without DLP */
CY_SMIF_CAP_MODE_SPI_DLP = 1, /**< SPI without RWDS, with DLP */
CY_SMIF_CAP_MODE_RWDS = 2, /**< Hyperbus or SPI with RWDS */
} cy_en_cy_smif_rx_cap_mode_t;
/* This field is only applicable in SDR transmit mode. */
typedef enum
{
CY_SMIF_TX_ONE_PERIOD_AHEAD = 0, /**< transmit data is launched nominally 1 PLL clock period ahead of the rising edge of the clock out to the memory */
CY_SMIF_TX_TWO_PERIOD_AHEAD = 1, /**< transmit data is launched nominally 2 PLL clock periods ahead of the rising edge of the clock out to the memory */
} cy_en_cy_smif_tx_sdr_extra_t;
typedef struct
{
uint32_t pllFreq; /**< Input PLL frequency */
cy_en_cy_smif_mdl_clk_out_div_t mdlOutDiv; /**< \ref cy_en_cy_smif_mdl_clk_out_div_t */
cy_en_cy_smif_ddl_tap_sel_t mdlTapSel; /**< \ref cy_en_cy_smif_mdl_tap_sel_t */
cy_en_cy_smif_rx_cap_mode_t rxCapMode; /**< \ref cy_en_cy_smif_rx_cap_mode_t */
cy_en_cy_smif_tx_sdr_extra_t txSdrExtra; /**< \ref cy_en_cy_smif_tx_sdr_extra_t */
} cy_stc_smif_dll_config_t;
/* SMIF Bridge Remapping Entities */
typedef enum
{
CY_EN_BRIDGE_PRIO_SMIF0_XPI_SPACE = 0, // The master accessing through the SMIF0 XIP space has high priority.
CY_EN_BRIDGE_PRIO_SMIF1_XPI_SPACE = 1, // The master accessing through the SMIF1 XIP space has high priority.
} cy_en_smif_bridge_xip_space_pri_t;
typedef enum
{
CY_EN_BRIDGE_SMIF0_XPI_SPACE = 0,
CY_EN_BRIDGE_SMIF1_XPI_SPACE = 1,
} cy_en_smif_bridge_xip_space_t;
typedef enum
{
CY_EN_BRIGE_REMAP_TYPE_INACTIVE = 0,
CY_EN_BRIGE_REMAP_TYPE_TO_SMIF0 = 1,
CY_EN_BRIGE_REMAP_TYPE_TO_SMIF1 = 2,
CY_EN_BRIGE_REMAP_TYPE_INTERLEAVE = 3,
} cy_en_smif_bridge_remap_type_t;
typedef enum
{
CY_EN_BRIGE_INTERLEAVE_8BYTE = 0,
CY_EN_BRIGE_INTERLEAVE_16BYTE = 1,
CY_EN_BRIGE_INTERLEAVE_32BYTE = 2,
CY_EN_BRIGE_INTERLEAVE_64BYTE = 3,
CY_EN_BRIGE_INTERLEAVE_128BYTE = 4,
} cy_en_smif_bridge_interleave_step_t;
typedef enum
{
CY_EN_BRIGE_REMAP_SIZE_1MB = 0x1FF00000ul,
CY_EN_BRIGE_REMAP_SIZE_2MB = 0x1FE00000ul,
CY_EN_BRIGE_REMAP_SIZE_4MB = 0x1FC00000ul,
CY_EN_BRIGE_REMAP_SIZE_8MB = 0x1F800000ul,
CY_EN_BRIGE_REMAP_SIZE_16MB = 0x1F000000ul,
CY_EN_BRIGE_REMAP_SIZE_32MB = 0x1E000000ul,
CY_EN_BRIGE_REMAP_SIZE_64MB = 0x1C000000ul,
CY_EN_BRIGE_REMAP_SIZE_128MB = 0x18000000ul,
CY_EN_BRIGE_REMAP_SIZE_256MB = 0x10000000ul,
CY_EN_BRIGE_REMAP_SIZE_512MB = 0x00000000ul,
} cy_en_smif_bridge_remap_region_size_t;
typedef struct
{
uint32_t regionIdx;
cy_en_smif_bridge_remap_region_size_t regionSize;
uint32_t xipAddr;
uint32_t phyAddr;
} cy_stc_smif_bridge_remap_t;
typedef struct
{
uint32_t regionIdx;
cy_en_smif_bridge_remap_region_size_t regionSize;
uint32_t xipAddr;
uint32_t phyAddr0;
uint32_t phyAddr1;
} cy_stc_smif_bridge_interleave_remap_t;
typedef enum
{
CY_SMIF_RX_CAP_STYLE_SDR_POS = 0,
CY_SMIF_RX_CAP_STYLE_SDR_NEG_NORM = 1,
CY_SMIF_RX_CAP_STYLE_SDR_NEG_PIPED = 2,
} cy_en_sdr_cap_style_t;
typedef enum
{
CY_SMIF_RX_CAP_STYLE_DDR_NORM_SPI = 0, // For only normal SPI
CY_SMIF_RX_CAP_STYLE_DDR_HYPERBUS = 1, // For hyper bus
CY_SMIF_RX_CAP_STYLE_DDR_OCTAL = 2, // For Octal SPI mode. In case of using RWDS, bytes will swap: Byte captured by positive edge will go MSB
CY_SMIF_RX_CAP_STYLE_DDR_OCTAL_SWAP = 3, // For Octal SPI mode. Byte captured by positive edge will go MSB
CY_SMIF_RX_CAP_STYLE_DDR_xSPI = 4, // For other SPI modes.
} cy_en_ddr_cap_style_t;
#include "smif/common/cy_smif.h"
/**
* \addtogroup group_smif_version_specific_functions
* This device uses SMIF revision 4.0
* \{
*/
extern cy_en_smif_status_t Cy_SMIF_Init(volatile cy_stc_smif_reg_t *base, cy_stc_smif_config_t const *config, uint32_t timeout, cy_stc_smif_context_t *context);
extern cy_en_smif_status_t Cy_SMIF_DllConfig(volatile cy_stc_smif_reg_t *base, const cy_stc_smif_dll_config_t* pDllCfg);
extern void Cy_SMIF_SetDllOutDivider(volatile cy_stc_smif_reg_t *base, cy_en_cy_smif_mdl_clk_out_div_t div);
extern bool Cy_SMIF_IsDllLocked(volatile cy_stc_smif_reg_t *base);
extern void Cy_SMIF_DeInit(volatile cy_stc_smif_reg_t *base);
extern cy_en_smif_status_t Cy_SMIF_Encrypt(volatile cy_stc_smif_reg_t *base, uint32_t address, uint8_t dataInOut[], uint32_t sizeInByte, cy_stc_smif_context_t const *context);
extern cy_en_smif_status_t Cy_SMIF_SetDelayLineForFreq(volatile cy_stc_smif_reg_t *base, uint8_t freqMhz, bool isDDR, uint8_t *calculatedTap);
extern void Cy_SMIF_SetMasterDLP(volatile cy_stc_smif_reg_t *base, uint16_t dlp);
extern uint16_t Cy_SMIF_GetMasterDLP(volatile cy_stc_smif_reg_t *base);
extern cy_en_smif_status_t Cy_SMIF_SetMasterDLP_Size(volatile cy_stc_smif_reg_t *base, uint32_t size);
extern uint8_t Cy_SMIF_GetMasterDLP_Size(volatile cy_stc_smif_reg_t *base);
extern cy_en_smif_status_t Cy_SMIF_SetMasterDLP_WarnLevel(volatile cy_stc_smif_reg_t *base, uint32_t warnLevel);
extern uint8_t Cy_SMIF_GetMasterDLP_WarnLevel(volatile cy_stc_smif_reg_t *base);
extern uint8_t Cy_SMIF_GetTapNumCapturedCorrectDLP(volatile cy_stc_smif_reg_t *base, uint8_t bit);
extern cy_en_smif_status_t Cy_SMIF_Set_DelayLineSel(volatile cy_stc_smif_reg_t *base, cy_en_smif_delay_line_t lineSel);
extern cy_en_smif_delay_line_t Cy_SMIF_Get_DelayLineSel(volatile cy_stc_smif_reg_t *base);
extern cy_en_smif_status_t Cy_SMIF_Set_DelayTapSel(volatile void *smif_or_device_base, uint8_t tapSel);
extern uint8_t Cy_SMIF_Get_DelayTapSel(volatile void *smif_or_device_base);
extern void Cy_SMIF_SetTxFifoTriggerLevel(volatile cy_stc_smif_reg_t *base, uint32_t level);
extern void Cy_SMIF_SetCryptoInput128(volatile cy_stc_smif_reg_t *base, const uint8_t inData[]);
extern void Cy_SMIF_SetCryptoKey128(volatile cy_stc_smif_reg_t *base, const uint8_t key[]);
extern uint32_t Cy_SMIF_GetTxFifoStatus(volatile cy_stc_smif_reg_t *base);
extern void Cy_SMIF_PushCmdFifo(volatile cy_stc_smif_reg_t *base, uint32_t data[], uint32_t sizeInWord);
extern void Cy_SMIF_PushTxFifo(volatile cy_stc_smif_reg_t *baseaddr, cy_stc_smif_context_t *context);
extern cy_en_smif_status_t Cy_SMIF_SetCaptureConfig(volatile cy_stc_smif_reg_t *base, cy_en_smif_slave_select_t slave, bool isHyperBus);
void Cy_SMIF_DeviceSetRxCaptureDdr(volatile cy_stc_smif_reg_device_t *device, cy_en_ddr_cap_style_t capStyle);
extern void Cy_SMIF_DeviceSetRxCaptureSdr(volatile cy_stc_smif_reg_device_t *device, cy_en_sdr_cap_style_t capStyle);
extern cy_en_smif_status_t Cy_SMIF_SwitchBridge(volatile cy_stc_smif_base_reg_t *baseaddr, bool switchOn);
extern cy_en_smif_status_t Cy_SMIF_SetBridgePriority(volatile cy_stc_smif_base_reg_t *baseaddr, cy_en_smif_bridge_xip_space_pri_t pri_ahb_smif0, cy_en_smif_bridge_xip_space_pri_t pri_ahb_smif1, cy_en_smif_bridge_xip_space_pri_t pri_axi_smif0, cy_en_smif_bridge_xip_space_pri_t pri_axi_smif1);
extern cy_en_smif_status_t Cy_SMIF_SetSimpleRemapRegion(volatile cy_stc_smif_base_reg_t *baseaddr, const cy_stc_smif_bridge_remap_t* pCfg);
extern cy_en_smif_status_t Cy_SMIF_SetInterleavingRemapRegion(volatile cy_stc_smif_base_reg_t *baseaddr, const cy_stc_smif_bridge_interleave_remap_t* pCfg);
extern cy_en_smif_status_t Cy_SMIF_DeactivateRemapRegion(volatile cy_stc_smif_base_reg_t *baseaddr, uint32_t regionIdx);
/** \} group_smif_version_specific_functions */
#if defined(__cplusplus)
}
#endif
#endif /* CY_IP_MXSMIF */
#endif /* (CY_SMIF_H) */
/** \} group_smif */
/* [] END OF FILE */
@@ -0,0 +1,492 @@
#include "cy_srom.h"
static un_srom_api_scrach_sram_t g_scratch __ALIGNED(32); // This must locate on SRAM and align with cache line size (in case device has cache)
static un_srom_api_args_2_t g_scratch2 __ALIGNED(32); // This must locate on SRAM and align with cache line size (in case device has cache)
static cy_srom_handler gp_srom_resp_handler = NULL;
// Dummy var that might be needed as workaround
static uint32_t g_dummy = 0ul;
static void Cy_Srom_ISR_ResponseIPC(void);
/*******************************************************************************
* Function Name: Cy_Srom_CallApi
****************************************************************************//**
*
* This function calls SROM API. CPU will wait for API completed inside this
* function by checking IPC released. Even after checking 0x00FFFFFF times, if it
* is still not released, this function will return timeout status.
* If IPC was busy when this function was called, it would return busy status
* immediately.
* If SROM API returned error status, this function would return error status.
* But actual message is still in first word of memory pointed by second input
* parameter "resp" (if not NULL).
* All messages will be passed via SRAM pointed to scratch address. The SRAM area
* is reserved in this file as a variable named "g_scratch".
* This function is not re-entrant.
*
* \param params
* Pointer to memory which contains SROM API arguments. The contents of arguments
* will be copied to "g_scratch". \ref un_srom_api_args_t
*
* \param resp
* Pointer to memory which SROM API response message will be copied to. Even if
* this function return error status, response message will be copied to the
* memory. If pointer is NULL, response will not be copied \ref un_srom_api_resps_t
*
* \return
* \ref cy_en_srom_driver_status_t
*
*******************************************************************************/
cy_en_srom_driver_status_t Cy_Srom_CallApi(const un_srom_api_args_t* params, un_srom_api_resps_t* resp)
{
if(params == NULL)
{
return CY_SROM_DR_INVALID_INPUT;
}
volatile stc_IPC_STRUCT_t* syscall_ipc_struct = &IPC->STRUCT[CY_IPC_CHAN_SYSCALL];
uint32_t timeOut = 0x0FFFFFFFul;
// Copy input contents to SRAM reserved
g_scratch.args = *params;
// Make Bit[0] to 0, it indicates all arguments are passed through scratch address
g_scratch.u32[0] = g_scratch.u32[0] & 0xFFFFFFFEul;
// Clean scratch RAM in case current core has a D-Cache, so that CM0+ SROM handler reads correct data
Cy_SysLib_CleanCoreDCacheByAddr(&g_scratch, sizeof(g_scratch));
// Send a message by IPC
// Workaround: Because some SROM APIs read memory area pointed by IPC_DATA1 even if
// IPC_DATA0[0] == 0 (indicating the API arguments are passed through SRAM scratch),
// it's safe to set dummy readable address to the IPC_DATA1.
if (Cy_IPC_Drv_SendMsgWord_2(syscall_ipc_struct, CY_SROM_DR_IPC_NOTIFY_STRUCT, (uint32_t)&g_scratch, (uint32_t)&g_dummy) != CY_IPC_DRV_SUCCESS)
{
// The IPC structure is already locked by another process
return CY_SROM_DR_IPC_BUSY;
}
while(1)
{
// Checks if the IPC structure is not locked
if (Cy_IPC_Drv_IsLockAcquired(syscall_ipc_struct) == false)
{
// The result of SROM API calling is in the SRAM reserved.
// Copy the contents to the memory pointed by input pointer
if(resp != NULL)
{
// Invalidate scratch RAM in case current core has a D-Cache, so that updates from CM0+ SROM handler are read correctly
Cy_SysLib_InvalidateCoreDCacheByAddr(&g_scratch, sizeof(g_scratch));
*resp = g_scratch.resps;
}
break;
}
// Decrement time out counter value
timeOut--;
// If time out counter is "0" return time out status
if(timeOut == 0)
{
return CY_SROM_DR_TIMEOUT;
}
}
if(Cy_Srom_GetResponseType() == CY_SROM_RESPONSE_FAIL)
{
// If the SROM API returned an error in the scratch RAM, return error
return CY_SROM_DR_API_ERROR;
}
else if(Cy_Srom_GetResponseType() == CY_SROM_RESPONSE_SUCCESS)
{
// If the SROM API returned "OK", return success
return CY_SROM_DR_SUCCEEDED;
}
else
{
// Return unknown status
return CY_SROM_DR_API_UNKNOWN;
}
}
/*******************************************************************************
* Function Name: Cy_Srom_CallApi_NonBlock
****************************************************************************//**
*
* This function calls SROM API. CPU "won't" wait for API completed inside this
* function by checking IPC released.
* If IPC was busy when this function was called, it would return busy status
* immediately.
* Please call "Cy_Srom_Get_Api_Response" to retrieve API response.
* All messages will be passed via SRAM pointed to scratch address. The SRAM area
* is reserved in this file as a variable named "g_scratch".
* This function is not re-entrant.
* Once user called this function, this function and also "Cy_Srom_CallApi"
* must not called until SROM API finished.
*
* \param params
* Pointer to memory which contains SROM API arguments. The contents of arguments
* will be copied to "g_scratch". \ref un_srom_api_args_t
*
* \return
* \ref cy_en_srom_driver_status_t
*
*******************************************************************************/
cy_en_srom_driver_status_t Cy_Srom_CallApi_NonBlock(const un_srom_api_args_t* params)
{
if(params == NULL)
{
return CY_SROM_DR_INVALID_INPUT;
}
volatile stc_IPC_STRUCT_t* syscall_ipc_struct = &IPC->STRUCT[CY_IPC_CHAN_SYSCALL];
// Copy input contents to SRAM reserved
g_scratch.args = *params;
// Make Bit[0] to 0, it indicates all arguments are passed through scratch address
g_scratch.u32[0] = g_scratch.u32[0] & 0xFFFFFFFEul;
// Clean scratch RAM in case current core has a D-Cache, so that CM0+ SROM handler reads correct data
Cy_SysLib_CleanCoreDCacheByAddr(&g_scratch, sizeof(g_scratch));
// Send a message by IPC
// Workaround: Because some SROM APIs read memory area pointed by IPC_DATA1 even if
// IPC_DATA0[0] == 0 (indicating the API arguments are passed through SRAM scratch),
// it's safe to set dummy readable address to the IPC_DATA1.
if (Cy_IPC_Drv_SendMsgWord_2(syscall_ipc_struct, CY_SROM_DR_IPC_NOTIFY_STRUCT, (uint32_t)&g_scratch, (uint32_t)&g_dummy) != CY_IPC_DRV_SUCCESS)
{
// The IPC structure is already locked by another process
return CY_SROM_DR_IPC_BUSY;
}
// Return succeeded status
return CY_SROM_DR_SUCCEEDED;
}
/*******************************************************************************
* Function Name: Cy_Srom_CallApi_2
****************************************************************************//**
*
* This function calls SROM API which need also IPC DATA1. Other is same as
* "Cy_SROM_CallApi"
*
* \param params
* Pointer to memory which contains SROM API arguments. The contents of arguments
* will be copied to "g_scratch". \ref un_srom_api_args_t
*
* \param params
* Pointer to memory which contains SROM API arguments 2. The contents of arguments
* will be copied to "g_scratch2". \ref un_srom_api_args_2_t
*
* \param resp
* Pointer to memory which SROM API response message will be copied to. Even if
* this function return error status, response message will be copied to the
* memory. If pointer is NULL, response will not be copied \ref un_srom_api_resps_t
*
* \return
* \ref cy_en_srom_driver_status_t
*
*******************************************************************************/
cy_en_srom_driver_status_t Cy_Srom_CallApi_2(const un_srom_api_args_t* params, const un_srom_api_args_2_t* params2, un_srom_api_resps_t* resp)
{
if((params == NULL) || (params2 == NULL))
{
return CY_SROM_DR_INVALID_INPUT;
}
volatile stc_IPC_STRUCT_t* syscall_ipc_struct = &IPC->STRUCT[CY_IPC_CHAN_SYSCALL];
uint32_t timeOut = 0x00FFFFFFul;
// Copy input contents to SRAM reserved
g_scratch.args = *params;
g_scratch2 = *params2;
// Make Bit[0] to 0, it indicates all arguments are passed through scratch address
g_scratch.u32[0] = g_scratch.u32[0] & 0xFFFFFFFEul;
g_scratch2.arg[0] = g_scratch2.arg[0] & 0xFFFFFFFEul;
// Clean scratch RAM in case current core has a D-Cache, so that CM0+ SROM handler reads correct data
Cy_SysLib_CleanCoreDCacheByAddr(&g_scratch, sizeof(g_scratch));
Cy_SysLib_CleanCoreDCacheByAddr(&g_scratch2, sizeof(g_scratch2));
// Send message by IPC
if (Cy_IPC_Drv_SendMsgWord_2(syscall_ipc_struct, CY_SROM_DR_IPC_NOTIFY_STRUCT, (uint32_t)&g_scratch, (uint32_t)&g_scratch2) != CY_IPC_DRV_SUCCESS)
{
// The IPC structure is already locked by another process
return CY_SROM_DR_IPC_BUSY;
}
while(1)
{
// Checks if the IPC structure is not locked
if (Cy_IPC_Drv_IsLockAcquired(syscall_ipc_struct) == false)
{
// The result of SROM API calling is in the SRAM reserved.
// Copy the contents to the memory pointed by input pointer
if(resp != NULL)
{
// Invalidate scratch RAM in case current core has a D-Cache, so that updates from CM0+ SROM handler are read correctly
Cy_SysLib_InvalidateCoreDCacheByAddr(&g_scratch, sizeof(g_scratch));
*resp = g_scratch.resps;
}
break;
}
// Decrement time out counter value
timeOut--;
// If time out counter is "0" return time out status
if(timeOut == 0)
{
return CY_SROM_DR_TIMEOUT;
}
}
if(Cy_Srom_GetResponseType() == CY_SROM_RESPONSE_FAIL)
{
// If the SROM API returned an error in the scratch RAM, return error
return CY_SROM_DR_API_ERROR;
}
else if(Cy_Srom_GetResponseType() == CY_SROM_RESPONSE_SUCCESS)
{
// If the SROM API returned "OK", return success
return CY_SROM_DR_SUCCEEDED;
}
else
{
// Return unknown status
return CY_SROM_DR_API_UNKNOWN;
}
}
/*******************************************************************************
* Function Name: Cy_Srom_CallApi_NonBlock_2
****************************************************************************//**
*
* This function calls SROM API which need also IPC DATA1. Other is same as
* "Cy_SROM_CallApi_NonBlock_2"
*
* \param params
* Pointer to memory which contains SROM API arguments. The contents of arguments
* will be copied to "g_scratch". \ref un_srom_api_args_t
*
* \param params
* Pointer to memory which contains SROM API arguments 2. The contents of arguments
* will be copied to "g_scratch2". \ref un_srom_api_args_2_t
*
* \return
* \ref cy_en_srom_driver_status_t
*
*******************************************************************************/
cy_en_srom_driver_status_t Cy_Srom_CallApi_NonBlock_2(const un_srom_api_args_t* params, const un_srom_api_args_2_t* params2)
{
if((params == NULL) || (params2 == NULL))
{
return CY_SROM_DR_INVALID_INPUT;
}
volatile stc_IPC_STRUCT_t* syscall_ipc_struct = &IPC->STRUCT[CY_IPC_CHAN_SYSCALL];
// Copy input contents to SRAM reserved
g_scratch.args = *params;
g_scratch2 = *params2;
// Make Bit[0] to 0, it indicates all arguments are passed through scratch address
g_scratch.u32[0] = g_scratch.u32[0] & 0xFFFFFFFEul;
g_scratch2.arg[0] = g_scratch2.arg[0] & 0xFFFFFFFEul;
// Clean scratch RAM in case current core has a D-Cache, so that CM0+ SROM handler reads correct data
Cy_SysLib_CleanCoreDCacheByAddr(&g_scratch, sizeof(g_scratch));
Cy_SysLib_CleanCoreDCacheByAddr(&g_scratch2, sizeof(g_scratch2));
// Send message by IPC
if (Cy_IPC_Drv_SendMsgWord_2(syscall_ipc_struct, CY_SROM_DR_IPC_NOTIFY_STRUCT, (uint32_t)&g_scratch, (uint32_t)&g_scratch2) != CY_IPC_DRV_SUCCESS)
{
// The IPC structure is already locked by another process
return CY_SROM_DR_IPC_BUSY;
}
// Return succeeded status
return CY_SROM_DR_SUCCEEDED;
}
/*******************************************************************************
* Function Name: Cy_Srom_GetResponseType
****************************************************************************//**
*
* This function returns status of SROM API response defined by \ref
* cy_en_srom_response_type_t
* Please call this function after "Cy_Srom_CallApi_NonBlock" was called.
*
* \return
* \ref cy_en_srom_response_type_t
*
*******************************************************************************/
cy_en_srom_response_type_t Cy_Srom_GetResponseType(void)
{
// Invalidate scratch RAM in case current core has a D-Cache, so that updates from CM0+ SROM handler are read correctly
Cy_SysLib_InvalidateCoreDCacheByAddr(&g_scratch, sizeof(g_scratch));
if((g_scratch.u32[0] & 0xF0000000ul) == 0xA0000000ul)
{
return CY_SROM_RESPONSE_SUCCESS;
}
else if((g_scratch.u32[0] & 0xF0000000ul) == 0xF0000000ul)
{
return CY_SROM_RESPONSE_FAIL;
}
else
{
return CY_SROM_NOT_RESPONSE;
}
}
/*******************************************************************************
* Function Name: Cy_Srom_Get_Api_Response
****************************************************************************//**
*
* This function returns g_scratch value as a response of SROM API.
* Please call this function after "Cy_Srom_CallApi_NonBlock" was called.
* "resp" is raw response data from SROM API on the other hands, return value
* indicate status of the response data like as invalid, succeeded, or failed.
* (if failed return value is same as resp.u32[0])
*
* \param resp
* Pointer to memory into which SROM API response to be copied if not NULL.
* \ref un_srom_api_resps_t
*
* \return
* \ref cy_en_srom_api_status_t
*
*******************************************************************************/
cy_en_srom_api_status_t Cy_Srom_GetApiResponse(un_srom_api_resps_t* resp)
{
cy_en_srom_response_type_t type = Cy_Srom_GetResponseType();
if(type == CY_SROM_NOT_RESPONSE)
{
return CY_SROM_STATUS_INVALID;
}
else
{
if(resp != NULL)
{
*resp = g_scratch.resps;
}
if(type == CY_SROM_RESPONSE_SUCCESS)
{
return CY_SROM_STATUS_SUCCESS;
}
else // CY_SROM_RESPONSE_FAIL
{
// return error code.
return (cy_en_srom_api_status_t)g_scratch.u32[0];
}
}
}
/*******************************************************************************
* Function Name: Cy_Srom_ConvertRespToStatus
****************************************************************************//**
*
* This function returns g_scratch value as a response of SROM API.
* Please call this function after "Cy_Srom_CallApi_NonBlock" was called.
* "resp" is raw response data from SROM API on the other hands, return value
* indicate status of the response data like as invalid, succeeded, or failed.
* (if failed return value is same as resp.u32[0])
*
* \param resp
* Pointer to memory into which SROM API response to be copied if not NULL.
* \ref un_srom_api_resps_t
*
* \return
* \ref cy_en_srom_api_status_t
*
*******************************************************************************/
cy_en_srom_api_status_t Cy_Srom_ConvertRespToStatus(uint32_t resp0)
{
if((resp0 & 0xF0000000ul) == 0xA0000000ul)
{
return CY_SROM_STATUS_SUCCESS;
}
else if((resp0 & 0xF0000000ul) == 0xF0000000ul)
{
// Error Code
return (cy_en_srom_api_status_t)resp0;
}
else
{
return CY_SROM_STATUS_INVALID;
}
}
/*******************************************************************************
* Function Name: Cy_Srom_SetResponseHandler
****************************************************************************//**
*
* This function sets response handler which is supposed to be called when SROM
* API finished. This function does not set NVIC. NVIC settings including enabling
* interrupt, setting priority of interrupt, is a responsibility of the user
* code.
*
* \param handler
* This will be invoked when SROM API finished and the IPC released.
*
* \param intIdx
* Interrupt number of the ARM core. \ref IRQn_Type
*
*******************************************************************************/
void Cy_Srom_SetResponseHandler(cy_srom_handler handler, IRQn_Type intIdx)
{
cy_stc_sysint_irq_t irq_cfg =
{
.sysIntSrc = CY_SROM_DR_IPC_INTR_NO,
.intIdx = intIdx,
.isEnabled = true,
};
/* set response handler */
gp_srom_resp_handler = handler;
/* Set CPUSS interrupt */
Cy_SysInt_InitIRQ(&irq_cfg);
Cy_SysInt_SetSystemIrqVector(irq_cfg.sysIntSrc, Cy_Srom_ISR_ResponseIPC);
/* Set IPC interrupt mask */
volatile stc_IPC_INTR_STRUCT_t* sromRespIntrStr = Cy_IPC_Drv_GetIntrBaseAddr(CY_SROM_DR_IPC_INTR_STRUCT);
Cy_IPC_Drv_SetInterruptMask(sromRespIntrStr, (1u << CY_IPC_CHAN_SYSCALL), 0);
}
/*******************************************************************************
* Function Cy_Srom_ISR_ResponseIPC
****************************************************************************//**
*
* This is interrupt handler called when SROM API was finished by CM0+ via IPC
* This function will be assigned in "Cy_Srom_SetResponseHandler".
*
*******************************************************************************/
static void Cy_Srom_ISR_ResponseIPC(void)
{
uint32_t masked = 0;
volatile stc_IPC_INTR_STRUCT_t* sromRespIntrStr = Cy_IPC_Drv_GetIntrBaseAddr(CY_SROM_DR_IPC_INTR_STRUCT);
masked = Cy_IPC_Drv_GetInterruptStatusMasked(sromRespIntrStr);
if((masked & (1ul << CY_IPC_CHAN_SYSCALL)) != 0ul)
{
if(gp_srom_resp_handler != NULL)
{
gp_srom_resp_handler();
}
}
Cy_IPC_Drv_ClearInterrupt(
sromRespIntrStr,
(masked & 0x0000FFFFul),
(masked & 0xFFFF0000ul) >> 16ul
);
}
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,432 @@
/***************************************************************************//**
* \file
* \version 1.0
*
* \brief
* Provides an API implementation of the SysFault driver.
*
********************************************************************************
* \copyright
* Copyright 2016-2017, Cypress Semiconductor Corporation. All rights reserved.
* You may use this file only in accordance with the license, terms, conditions,
* disclaimers, and limitations in the end user license agreement accompanying
* the software package with which this file was provided.
*******************************************************************************/
#include "cy_sysflt.h"
#if defined(__cplusplus)
extern "C" {
#endif
/*******************************************************************************
* Function Name: Cy_SysFlt_Init
****************************************************************************//**
*
* \brief Initializes the SysFault for recording faults.
*
* \param ptscSYSFLT : The pointer to a structure instance.
*
* \return None
*
*******************************************************************************/
void Cy_SysFlt_Init(volatile stc_FAULT_STRUCT_t *ptscSYSFLT,const cy_stc_sysflt_t * config)
{
if (config->TriggerEnable)
{
ptscSYSFLT->unCTL.stcField.u1TR_EN = true;
}
else
{
ptscSYSFLT->unCTL.stcField.u1TR_EN = false;
}
if (config->OutputEnable)
{
ptscSYSFLT->unCTL.stcField.u1OUT_EN = true;
}
else
{
ptscSYSFLT->unCTL.stcField.u1OUT_EN = false;
}
if (config->ResetEnable)
{
ptscSYSFLT->unCTL.stcField.u1RESET_REQ_EN = true;
}
else
{
ptscSYSFLT->unCTL.stcField.u1RESET_REQ_EN = false;
}
}
/*******************************************************************************
* Function Name: Cy_SysFlt_ClearStatus
****************************************************************************//**
*
* \brief Clear fault status register
*
* \param ptscSYSFLT : The pointer to a structure instance.
*
*******************************************************************************/
void Cy_SysFlt_ClearStatus(volatile stc_FAULT_STRUCT_t *ptscSYSFLT)
{
ptscSYSFLT->unSTATUS.u32Register = 0x00000000UL;
}
/*******************************************************************************
* Function Name: Cy_SysFlt_GetErrorSource
****************************************************************************//**
*
* \brief Returns the source of error for the fault.
*
* \param ptscSYSFLT : The pointer to a structure instance.
*
* \return see sysflt source
*
*******************************************************************************/
cy_en_sysflt_source_t Cy_SysFlt_GetErrorSource(volatile stc_FAULT_STRUCT_t *ptscSYSFLT)
{
if(ptscSYSFLT->unSTATUS.stcField.u1VALID == 1u)
{
return((cy_en_sysflt_source_t)(ptscSYSFLT->unSTATUS.stcField.u7IDX));
}
else
{
return CY_SYSFLT_NO_FAULT;
}
}
/*******************************************************************************
* Function Name: Cy_SysFlt_GetData0
****************************************************************************//**
*
* \brief Returns the fault information.
*
* \param ptscSYSFLT : The pointer to a structure instance.
*
* \return Fault information
*
*******************************************************************************/
uint32_t Cy_SysFlt_GetData0(volatile stc_FAULT_STRUCT_t *ptscSYSFLT)
{
return(ptscSYSFLT->unDATA[0].u32Register);
}
/*******************************************************************************
* Function Name: Cy_SysFlt_GetData1
****************************************************************************//**
*
* \brief Returns the fault information.
*
* \param ptscSYSFLT : The pointer to a structure instance.
*
* \return Fault information
*
*******************************************************************************/
uint32_t Cy_SysFlt_GetData1(volatile stc_FAULT_STRUCT_t *ptscSYSFLT)
{
return(ptscSYSFLT->unDATA[1].u32Register);
}
/*******************************************************************************
* Function Name: Cy_SysFlt_GetData2
****************************************************************************//**
*
* \brief Returns the fault information.
*
* \param ptscSYSFLT : The pointer to a structure instance.
*
* \return Fault information
*
*******************************************************************************/
uint32_t Cy_SysFlt_GetData2(volatile stc_FAULT_STRUCT_t *ptscSYSFLT)
{
return(ptscSYSFLT->unDATA[2].u32Register);
}
/*******************************************************************************
* Function Name: Cy_SysFlt_GetData3
****************************************************************************//**
*
* \brief Returns the fault information.
*
* \param ptscSYSFLT : The pointer to a structure instance.
*
* \return Fault information
*
*******************************************************************************/
uint32_t Cy_SysFlt_GetData3(volatile stc_FAULT_STRUCT_t *ptscSYSFLT)
{
return(ptscSYSFLT->unDATA[3].u32Register);
}
/*******************************************************************************
* Function Name: Cy_SysFlt_Pending0
****************************************************************************//**
*
* \brief Returns the sources of pending fault which are not captured .
*
* \param ptscSYSFLT : The pointer to a structure instance.
*
* \return Source of pending fault.
*
*******************************************************************************/
uint32_t Cy_SysFlt_Pending0(volatile stc_FAULT_STRUCT_t *ptscSYSFLT)
{
return(ptscSYSFLT->unPENDING0.u32Register);
}
/*******************************************************************************
* Function Name: Cy_SysFlt_Pending1
****************************************************************************//**
*
* \brief Returns the sources of pending fault which are not captured .
*
* \param ptscSYSFLT : The pointer to a structure instance.
*
* \return Source of pending fault.
*
*******************************************************************************/
uint32_t Cy_SysFlt_Pending1(volatile stc_FAULT_STRUCT_t *ptscSYSFLT)
{
return(ptscSYSFLT->unPENDING1.u32Register);
}
/*******************************************************************************
* Function Name: Cy_SysFlt_Pending2
****************************************************************************//**
*
* \brief Returns the sources of pending fault which are not captured .
*
* \param ptscSYSFLT : The pointer to a structure instance.
*
* \return Source of pending fault.
*
*******************************************************************************/
uint32_t Cy_SysFlt_Pending2(volatile stc_FAULT_STRUCT_t *ptscSYSFLT)
{
return(ptscSYSFLT->unPENDING2.u32Register);
}
/*******************************************************************************
* Function Name: Cy_SysFlt_Mask0
****************************************************************************//**
*
* \brief Enable the faults to be captured.
*
* \param ptscSYSFLT : The pointer to a structure instance.
* enable : Faults capturing enable.
*
* \return None
*
*******************************************************************************/
void Cy_SysFlt_Mask0(volatile stc_FAULT_STRUCT_t *ptscSYSFLT, uint32_t enable)
{
ptscSYSFLT->unMASK0.stcField.u32SOURCE = enable;
}
/*******************************************************************************
* Function Name: Cy_SysFlt_Mask1
****************************************************************************//**
*
* \brief Enable the faults to be captured.
*
* \param ptscSYSFLT : The pointer to a structure instance.
* enable : Faults capturing enable.
*
* \return None
*
*******************************************************************************/
void Cy_SysFlt_Mask1(volatile stc_FAULT_STRUCT_t *ptscSYSFLT,uint32_t enable)
{
ptscSYSFLT->unMASK1.stcField.u32SOURCE = enable;
}
/*******************************************************************************
* Function Name: Cy_SysFlt_Mask2
****************************************************************************//**
*
* \brief Enable the faults to be captured.
*
* \param ptscSYSFLT : The pointer to a structure instance.
* enable : Faults capturing enable.
*
* \return None
*
*******************************************************************************/
void Cy_SysFlt_Mask2(volatile stc_FAULT_STRUCT_t *ptscSYSFLT,uint32_t enable)
{
ptscSYSFLT->unMASK2.stcField.u32SOURCE = enable;
}
/*******************************************************************************
* Function Name: Cy_SysFlt_SetMaskByIdx
****************************************************************************//**
*
* \brief Enable the faults to be captured by id.
*
* \param ptscSYSFLT : The pointer to a structure instance.
*
* \param idx : The fault id to be set in the mask register.
*
* \return None
*
*******************************************************************************/
void Cy_SysFlt_SetMaskByIdx(volatile stc_FAULT_STRUCT_t *ptscSYSFLT, cy_en_sysflt_source_t idx)
{
switch(idx / 32)
{
case 0:
ptscSYSFLT->unMASK0.u32Register |= (1UL << (uint32_t)idx);
break;
case 1:
ptscSYSFLT->unMASK1.u32Register |= (1UL << ((uint32_t)idx - 32UL));
break;
case 2:
ptscSYSFLT->unMASK2.u32Register |= (1UL << ((uint32_t)idx - 64UL));
break;
default:
break;
}
return;
}
/*******************************************************************************
* Function Name: Cy_SysFlt_ClearMaskByIdx
****************************************************************************//**
*
* \brief Disable the faults to be captured by id.
*
* \param ptscSYSFLT : The pointer to a structure instance.
*
* \param idx : The fault id to be clear in the mask register.
*
* \return None
*
*******************************************************************************/
void Cy_SysFlt_ClearMaskByIdx(volatile stc_FAULT_STRUCT_t *ptscSYSFLT, cy_en_sysflt_source_t idx)
{
switch(idx / 32)
{
case 0:
ptscSYSFLT->unMASK0.u32Register &= ~(1UL << (uint32_t)idx);
break;
case 1:
ptscSYSFLT->unMASK1.u32Register &= ~(1UL << ((uint32_t)idx - 32UL));
break;
case 2:
ptscSYSFLT->unMASK2.u32Register &= ~(1UL << ((uint32_t)idx - 64UL));
break;
default:
break;
}
return;
}
/*******************************************************************************
* Function Name: Cy_SysFlt_GetInterruptStatus
****************************************************************************//**
*
* \brief Returns the status of the interrupt.
*
* \param ptscSYSFLT : The pointer to a structure instance.
*
* \return Status
*
*******************************************************************************/
uint32_t Cy_SysFlt_GetInterruptStatus(volatile stc_FAULT_STRUCT_t *ptscSYSFLT)
{
return(ptscSYSFLT->unINTR.stcField.u1FAULT);
}
/*******************************************************************************
* Function Name: Cy_SysFlt_ClearInterrupt
****************************************************************************//**
*
* \brief Clears Active Interrupt Source
*
* \param ptscSYSFLT : The pointer to a structure instance.
*
* \return None
*
*******************************************************************************/
void Cy_SysFlt_ClearInterrupt(volatile stc_FAULT_STRUCT_t *ptscSYSFLT)
{
ptscSYSFLT->unINTR.stcField.u1FAULT = true;
(void)ptscSYSFLT->unINTR.u32Register;
}
/*******************************************************************************
* Function Name: Cy_SysFlt_SetInterrupt
****************************************************************************//**
*
* \brief Triggers an interrupt via a software write.
*
* \param ptscSYSFLT : The pointer to a structure instance.
*
* \return None
*
*******************************************************************************/
void Cy_SysFlt_SetInterrupt(volatile stc_FAULT_STRUCT_t *ptscSYSFLT)
{
ptscSYSFLT->unINTR_SET.stcField.u1FAULT = true;
}
/*******************************************************************************
* Function Name: Cy_SysFlt_SetInterruptMask
****************************************************************************//**
*
* \brief Sets an interrupt mask. A 1 means that when the event occurs, it will cause an interrupt;
* a 0 means no interrupt will be triggered.
*
* \param ptscSYSFLT : The pointer to a structure instance.
*
* \return None
*
*******************************************************************************/
void Cy_SysFlt_SetInterruptMask(volatile stc_FAULT_STRUCT_t *ptscSYSFLT)
{
ptscSYSFLT->unINTR_MASK.stcField.u1FAULT = true;
}
/*******************************************************************************
* Function Name: Cy_SysFlt_GetInterruptMask
****************************************************************************//**
*
* \brief Returns the interrupt mask.
*
* \param ptscSYSFLT : The pointer to a structure instance.
*
* \return Interrupt Mask
*
*******************************************************************************/
uint32_t Cy_SysFlt_GetInterruptMask(volatile stc_FAULT_STRUCT_t *ptscSYSFLT)
{
return(ptscSYSFLT->unINTR_MASK.u32Register);
}
/*******************************************************************************
* Function Name: Cy_SysFlt_GetInterruptStatusMasked
****************************************************************************//**
*
* \brief Returns which masked interrupt triggered the interrupt.
*
* \param ptscSYSFLT : The pointer to a structure instance.
*
* \return Interrupt Mask
*
*******************************************************************************/
uint32_t Cy_SysFlt_GetInterruptStatusMasked(volatile stc_FAULT_STRUCT_t *ptscSYSFLT)
{
return(ptscSYSFLT->unINTR_MASKED.u32Register);
}
#if defined(__cplusplus)
}
#endif
/* [] END OF FILE */
@@ -0,0 +1,384 @@
/***************************************************************************//**
* \file cy_sysflt.h
* \version 1.0
*
* \brief
* Provides an API declaration of the Sysfault driver
*
********************************************************************************
* \copyright
* Copyright 2016-2017, Cypress Semiconductor Corporation. All rights reserved.
* You may use this file only in accordance with the license, terms, conditions,
* disclaimers, and limitations in the end user license agreement accompanying
* the software package with which this file was provided.
*******************************************************************************/
/**
* \defgroup group_sysflt System Fault (SysFlt)
* \{
* The SysFault driver provides an API to configure the fault reporting structure.
*
* \section group_sysflt_more_information More Information
*
* Refer to the technical reference manual (TRM) and the device datasheet.
*
* \defgroup group_sysflt_enums Enumerated Types
*/
#if !defined(CY_SYSFLT_H)
#define CY_SYSFLT_H
#include <stddef.h>
#include "syslib/cy_syslib.h"
#include "cy_device_headers.h"
#include "sysflt/cy_sysflt_config.h"
#if defined(__cplusplus)
extern "C" {
#endif
/***************************************
* Enumeration
***************************************/
/**
* \addtogroup group_sysflt_enums
* \{
*/
typedef enum
{
CY_SYSFLT_SUCCESS = 0x00u, /**< Returned successful */
CY_SYSFLT_BAD_PARAM = 0x01u, /**< Bad parameter was passed */
} cy_en_sysflt_status_t;
/** \} group_sysint_enums */
/***************************************
* Configuration Structure
***************************************/
/**
* \addtogroup group_sysflt_data_structures
* \{
*/
/**
* Initialization configuration structure for a fault control register
*/
typedef struct {
bool TriggerEnable; /**< Enables the trigger output when it is True */
bool OutputEnable; /**< Enables the output signal when it is True */
bool ResetEnable; /**< Enables the Reset request when it is True */
} cy_stc_sysflt_t;
/** \} group_sysflt_data_structures */
/***************************************
* Function Prototypes
***************************************/
/**
* \addtogroup group_sysflt_functions
* \{
*/
/*******************************************************************************
* Function Name: Cy_SysFlt_Init
****************************************************************************//**
*
* \brief Initializes the SysFault for recording faults.
*
* \param ptscSYSFLT : The pointer to a structure instance.
*
* \return None
*
*******************************************************************************/
void Cy_SysFlt_Init(volatile stc_FAULT_STRUCT_t *ptscSYSFLT,const cy_stc_sysflt_t * config);
/*******************************************************************************
* Function Name: Cy_SysFlt_ClearStatus
****************************************************************************//**
*
* \brief Clear fault status register
*
* \param ptscSYSFLT : The pointer to a structure instance.
*
*******************************************************************************/
void Cy_SysFlt_ClearStatus(volatile stc_FAULT_STRUCT_t *ptscSYSFLT);
/*******************************************************************************
* Function Name: Cy_SysFlt_GetErrorSource
****************************************************************************//**
*
* \brief Returns the source of error for the fault.
*
* \param ptscSYSFLT : The pointer to a structure instance.
*
* \return see \ref cy_en_sysflt_source
*
*******************************************************************************/
cy_en_sysflt_source_t Cy_SysFlt_GetErrorSource(volatile stc_FAULT_STRUCT_t *ptscSYSFLT);
/*******************************************************************************
* Function Name: Cy_SysFlt_GetData0
****************************************************************************//**
*
* \brief Returns the fault information.
*
* \param ptscSYSFLT : The pointer to a structure instance.
*
* \return Fault information
*
*******************************************************************************/
uint32_t Cy_SysFlt_GetData0(volatile stc_FAULT_STRUCT_t *ptscSYSFLT);
/*******************************************************************************
* Function Name: Cy_SysFlt_GetData1
****************************************************************************//**
*
* \brief Returns the fault information.
*
* \param ptscSYSFLT : The pointer to a structure instance.
*
* \return Fault information
*
*******************************************************************************/
uint32_t Cy_SysFlt_GetData1(volatile stc_FAULT_STRUCT_t *ptscSYSFLT);
/*******************************************************************************
* Function Name: Cy_SysFlt_GetData2
****************************************************************************//**
*
* \brief Returns the fault information.
*
* \param ptscSYSFLT : The pointer to a structure instance.
*
* \return Fault information
*
*******************************************************************************/
uint32_t Cy_SysFlt_GetData2(volatile stc_FAULT_STRUCT_t *ptscSYSFLT);
/*******************************************************************************
* Function Name: Cy_SysFlt_GetData3
****************************************************************************//**
*
* \brief Returns the fault information.
*
* \param ptscSYSFLT : The pointer to a structure instance.
*
* \return Fault information
*
*******************************************************************************/
uint32_t Cy_SysFlt_GetData3(volatile stc_FAULT_STRUCT_t *ptscSYSFLT);
/*******************************************************************************
* Function Name: Cy_SysFlt_Pending0
****************************************************************************//**
*
* \brief Returns the sources of pending fault which are not captured .
*
* \param ptscSYSFLT : The pointer to a structure instance.
*
* \return Source of pending fault.
*
*******************************************************************************/
uint32_t Cy_SysFlt_Pending0(volatile stc_FAULT_STRUCT_t *ptscSYSFLT);
/*******************************************************************************
* Function Name: Cy_SysFlt_Pending1
****************************************************************************//**
*
* \brief Returns the sources of pending fault which are not captured .
*
* \param ptscSYSFLT : The pointer to a structure instance.
*
* \return Source of pending fault.
*
*******************************************************************************/
uint32_t Cy_SysFlt_Pending1(volatile stc_FAULT_STRUCT_t *ptscSYSFLT);
/*******************************************************************************
* Function Name: Cy_SysFlt_Pending2
****************************************************************************//**
*
* \brief Returns the sources of pending fault which are not captured .
*
* \param ptscSYSFLT : The pointer to a structure instance.
*
* \return Source of pending fault.
*
*******************************************************************************/
uint32_t Cy_SysFlt_Pending2(volatile stc_FAULT_STRUCT_t *ptscSYSFLT);
/*******************************************************************************
* Function Name: Cy_SysFlt_Mask0
****************************************************************************//**
*
* \brief Enable the faults to be captured.
*
* \param ptscSYSFLT : The pointer to a structure instance.
* enable : Faults capturing enable.
*
* \return None
*
*******************************************************************************/
void Cy_SysFlt_Mask0(volatile stc_FAULT_STRUCT_t *ptscSYSFLT,uint32_t enable);
/*******************************************************************************
* Function Name: Cy_SysFlt_Mask1
****************************************************************************//**
*
* \brief Enable the faults to be captured.
*
* \param ptscSYSFLT : The pointer to a structure instance.
* enable : Faults capturing enable.
*
* \return None
*
*******************************************************************************/
void Cy_SysFlt_Mask1(volatile stc_FAULT_STRUCT_t *ptscSYSFLT,uint32_t enable);
/*******************************************************************************
* Function Name: Cy_SysFlt_Mask2
****************************************************************************//**
*
* \brief Enable the faults to be captured.
*
* \param ptscSYSFLT : The pointer to a structure instance.
* enable : Faults capturing enable.
*
* \return None
*
*******************************************************************************/
void Cy_SysFlt_Mask2(volatile stc_FAULT_STRUCT_t *ptscSYSFLT,uint32_t enable);
/*******************************************************************************
* Function Name: Cy_SysFlt_SetMaskByIdx
****************************************************************************//**
*
* \brief Enable the faults to be captured by id.
*
* \param ptscSYSFLT : The pointer to a structure instance.
*
* \param idx : The fault id to be set in the mask register.
*
* \return None
*
*******************************************************************************/
void Cy_SysFlt_SetMaskByIdx(volatile stc_FAULT_STRUCT_t *ptscSYSFLT, cy_en_sysflt_source_t idx);
/*******************************************************************************
* Function Name: Cy_SysFlt_ClearMaskByIdx
****************************************************************************//**
*
* \brief Disable the faults to be captured by id.
*
* \param ptscSYSFLT : The pointer to a structure instance.
*
* \param idx : The fault id to be clear in the mask register.
*
* \return None
*
*******************************************************************************/
void Cy_SysFlt_ClearMaskByIdx(volatile stc_FAULT_STRUCT_t *ptscSYSFLT, cy_en_sysflt_source_t idx);
/*******************************************************************************
* Function Name: Cy_SysFlt_GetInterruptStatus
****************************************************************************//**
*
* \brief Returns the status of the interrupt.
*
* \param ptscSYSFLT : The pointer to a structure instance.
*
* \return Status
*
*******************************************************************************/
uint32_t Cy_SysFlt_GetInterruptStatus(volatile stc_FAULT_STRUCT_t *ptscSYSFLT);
/*******************************************************************************
* Function Name: Cy_SysFlt_ClearInterrupt
****************************************************************************//**
*
* \brief Clears Active Interrupt Source
*
* \param ptscSYSFLT : The pointer to a structure instance.
*
* \return None
*
*******************************************************************************/
void Cy_SysFlt_ClearInterrupt(volatile stc_FAULT_STRUCT_t *ptscSYSFLT);
/*******************************************************************************
* Function Name: Cy_SysFlt_SetInterrupt
****************************************************************************//**
*
* \brief Triggers an interrupt via a software write.
*
* \param ptscSYSFLT : The pointer to a structure instance.
*
* \return None
*
*******************************************************************************/
void Cy_SysFlt_SetInterrupt(volatile stc_FAULT_STRUCT_t *ptscSYSFLT);
/*******************************************************************************
* Function Name: Cy_SysFlt_SetInterruptMask
****************************************************************************//**
*
* \brief Sets an interrupt mask. A 1 means that when the event occurs, it will cause an interrupt;
* a 0 means no interrupt will be triggered.
*
* \param ptscSYSFLT : The pointer to a structure instance.
*
* \return None
*
*******************************************************************************/
void Cy_SysFlt_SetInterruptMask(volatile stc_FAULT_STRUCT_t *ptscSYSFLT);
/*******************************************************************************
* Function Name: Cy_SysFlt_GetInterruptMask
****************************************************************************//**
*
* \brief Returns the interrupt mask.
*
* \param ptscSYSFLT : The pointer to a structure instance.
*
* \return Interrupt Mask
*
*******************************************************************************/
uint32_t Cy_SysFlt_GetInterruptMask(volatile stc_FAULT_STRUCT_t *ptscSYSFLT);
/*******************************************************************************
* Function Name: Cy_SysFlt_GetInterruptStatusMasked
****************************************************************************//**
*
* \brief Returns which masked interrupt triggered the interrupt.
*
* \param ptscSYSFLT : The pointer to a structure instance.
*
* \return Interrupt Mask
*
*******************************************************************************/
uint32_t Cy_SysFlt_GetInterruptStatusMasked(volatile stc_FAULT_STRUCT_t *ptscSYSFLT);
/** \} group_sysflt_functions */
#if defined(__cplusplus)
}
#endif
#endif /* CY_SYSFLT_H */
/** \} group_sysflt */
/* [] END OF FILE */
@@ -0,0 +1,635 @@
/***************************************************************************//**
* \file
* \version 1.0
*
* \brief
* Provides an API implementation of the SysInt driver.
*
********************************************************************************
* \copyright
* Copyright 2016-2017, Cypress Semiconductor Corporation. All rights reserved.
* You may use this file only in accordance with the license, terms, conditions,
* disclaimers, and limitations in the end user license agreement accompanying
* the software package with which this file was provided.
*******************************************************************************/
#include "cy_sysint.h"
#if defined(__cplusplus)
extern "C" {
#endif
/*
If the System IRQ user table is linked to RAM in the project/core specific
cy_interrupt_map.c the following weak symbol is assigned the base address
of the System IRQ user table in RAM, otherwise it stays NULL and APIs can
use this information to allow/prevent their service */
CY_WEAK cy_systemIntr_Handler * Cy_SysInt_SystemIrqUserTableRamPointer = NULL;
/*******************************************************************************
* Function Name: Cy_SysInt_Init
****************************************************************************//**
*
* \brief Initializes the referenced CPU interrupt by setting the priority and the
* interrupt vector. Note that the interrupt vector will only be relocated if the
* vector table was moved to __ramVectors in SRAM. Otherwise it is ignored.
*
* Use the CMSIS core function NVIC_EnableIRQ(config.intrSrc) to enable it.
* And also for IRQs, use the Cy_SysInt_InitIRQ function to map and enable
* system interupt to CPU interrupt.
*
* \param config
* Interrupt configuration structure
*
* \param userIsr
* Address of the ISR. If 0 <= config->intrSrc < Internal0_IRQn userIsr has no meaning.
*
* \return
* Initialization status
*
*******************************************************************************/
cy_en_sysint_status_t Cy_SysInt_Init(const cy_stc_sysint_t * config, cy_israddress userIsr)
{
cy_en_sysint_status_t status = CY_SYSINT_SUCCESS;
if(NULL != config)
{
/* Only set the new vector if it is CPU interrupt (not internal SW interrupt) */
if ((config->intrSrc < CPUIntIdx0_IRQn) || (config->intrSrc >= Internal0_IRQn))
{
/* Only set the new vector if it was moved to __ramVectors */
if (SCB->VTOR == (uint32_t)&__ramVectors)
{
(void)Cy_SysInt_SetVector(config->intrSrc, userIsr);
}
}
else
{
return CY_SYSINT_BAD_PARAM; // Vector of system handler have to be set at ROM table.
}
NVIC_SetPriority(config->intrSrc, config->intrPriority);
}
else
{
status = CY_SYSINT_BAD_PARAM;
}
return(status);
}
/*******************************************************************************
* Function Name: Cy_SysInt_InitIRQ
****************************************************************************//**
*
* \brief Initializes the referenced system interrupt by setting the interrupt
* vector.
*
* \param config
* Interrupt configuration structure
*
* \param userIsr
* Address of the ISR
*
* \return
* Initialization status
*
*******************************************************************************/
cy_en_sysint_status_t Cy_SysInt_InitIRQ(const cy_stc_sysint_irq_t* config)
{
cy_en_sysint_status_t status = CY_SYSINT_SUCCESS;
#if (CY_CPU_CORTEX_M0P)
un_CPUSS_CM0_SYSTEM_INT_CTL_t unIntCtl = { 0ul };
#else
#if defined (tviibe512k) || defined (tviibe1m) || defined (tviibe2m)|| defined (tviibe4m) || defined (tviice4m)
un_CPUSS_CM4_SYSTEM_INT_CTL_t unIntCtl = { 0ul };
#elif defined (tviibh4m) || defined (tviibh8m) || defined (tviic2d6m) || defined (tviic2d4m) || defined (tviic2d6mddr) || defined (tviibh16m)
un_CPUSS_CM7_0_SYSTEM_INT_CTL_t unIntCtl0 = { 0ul };
#if defined(CPUSS_CM7_1_PRESENT) && (CPUSS_CM7_1_PRESENT == 1)
un_CPUSS_CM7_1_SYSTEM_INT_CTL_t unIntCtl1 = { 0ul };
#endif
#if defined(CPUSS_CM7_2_PRESENT) && (CPUSS_CM7_2_PRESENT == 1)
un_CPUSS_CM7_2_SYSTEM_INT_CTL_t unIntCtl2 = { 0ul };
#endif
#if defined(CPUSS_CM7_3_PRESENT) && (CPUSS_CM7_3_PRESENT == 1)
un_CPUSS_CM7_3_SYSTEM_INT_CTL_t unIntCtl3 = { 0ul };
#endif
#endif
#endif
if(NULL != config)
{
#if (CY_CPU_CORTEX_M0P) //rmkn u3CM0_CPU_INT_IDX->u3CPU_INT_IDX
#if defined (tviibe512k) || defined (tviibe1m) || defined (tviibe2m)|| defined (tviibe4m) || defined (tviice4m)
unIntCtl.stcField.u3CPU_INT_IDX = (uint8_t)config->intIdx;
#elif defined (tviibh4m) || defined (tviibh8m) || defined (tviic2d6m) || defined (tviic2d4m) || defined (tviic2d6mddr) || defined (tviibh16m)
unIntCtl.stcField.u3CM0_CPU_INT_IDX = (uint8_t)config->intIdx;
#endif
unIntCtl.stcField.u1CPU_INT_VALID = config->isEnabled ? 1ul : 0ul;
CPUSS->unCM0_SYSTEM_INT_CTL[config->sysIntSrc].u32Register = unIntCtl.u32Register;
#else
#if defined (tviibe512k) || defined (tviibe1m) || defined (tviibe2m)|| defined (tviibe4m) || defined (tviice4m)
unIntCtl.stcField.u3CPU_INT_IDX = (uint8_t)config->intIdx;
unIntCtl.stcField.u1CPU_INT_VALID = config->isEnabled ? 1ul : 0ul;
CPUSS->unCM4_SYSTEM_INT_CTL[config->sysIntSrc].u32Register = unIntCtl.u32Register;
#elif defined (tviibh4m) || defined (tviibh8m) || defined (tviic2d6m) || defined (tviic2d4m) || defined (tviic2d6mddr) || defined (tviibh16m)
if(CPUSS->unIDENTITY.stcField.u4MS == CPUSS_MS_ID_CM7_0)
{
unIntCtl0.stcField.u4CPU_INT_IDX = (uint8_t)config->intIdx;
unIntCtl0.stcField.u1CPU_INT_VALID = config->isEnabled ? 1ul : 0ul;
CPUSS->unCM7_0_SYSTEM_INT_CTL[config->sysIntSrc].u32Register = unIntCtl0.u32Register;
}
#if defined(CPUSS_CM7_1_PRESENT) && (CPUSS_CM7_1_PRESENT == 1)
else if(CPUSS->unIDENTITY.stcField.u4MS == CPUSS_MS_ID_CM7_1)
{
unIntCtl1.stcField.u4CPU_INT_IDX = (uint8_t)config->intIdx;
unIntCtl1.stcField.u1CPU_INT_VALID = config->isEnabled ? 1ul : 0ul;
CPUSS->unCM7_1_SYSTEM_INT_CTL[config->sysIntSrc].u32Register = unIntCtl1.u32Register;
}
#endif
#if defined(CPUSS_CM7_2_PRESENT) && (CPUSS_CM7_2_PRESENT == 1)
else if(CPUSS->unIDENTITY.stcField.u4MS == CPUSS_MS_ID_CM7_2)
{
unIntCtl2.stcField.u4CPU_INT_IDX = (uint8_t)config->intIdx;
unIntCtl2.stcField.u1CPU_INT_VALID = config->isEnabled ? 1ul : 0ul;
CPUSS->unCM7_2_SYSTEM_INT_CTL[config->sysIntSrc].u32Register = unIntCtl2.u32Register;
}
#endif
#if defined(CPUSS_CM7_3_PRESENT) && (CPUSS_CM7_3_PRESENT == 1)
else // if(CPUSS->unIDENTITY.stcField.u4MS == CPUSS_MS_ID_CM7_3)
{
unIntCtl3.stcField.u4CPU_INT_IDX = (uint8_t)config->intIdx;
unIntCtl3.stcField.u1CPU_INT_VALID = config->isEnabled ? 1ul : 0ul;
CPUSS->unCM7_3_SYSTEM_INT_CTL[config->sysIntSrc].u32Register = unIntCtl3.u32Register;
}
#endif
#endif
#endif
}
else
{
status = CY_SYSINT_BAD_PARAM;
}
return(status);
}
/*******************************************************************************
* Function Name: Cy_SysInt_SetVector
****************************************************************************//**
*
* \brief Changes the ISR vector for the Interrupt.
*
* Note that this function relies on the assumption that the vector table is
* relocated to __ramVectors[RAM_VECTORS_SIZE] in SRAM. Otherwise it will
* return the address of the default ISR location in Flash vector table.
*
* \param intrSrc
* Interrrupt source
*
* \param userIsr
* Address of the ISR to set in the interrupt vector table
*
* \return none
*
*******************************************************************************/
void Cy_SysInt_SetVector(IRQn_Type intrSrc, cy_israddress userIsr)
{
/* Only set the new vector if it was moved to __ramVectors */
if (SCB->VTOR == (uint32_t)&__ramVectors)
{
__ramVectors[CY_INT_IRQ_BASE + intrSrc] = userIsr;
#if CY_CPU_CORTEX_M7
// Ensure that above change in the vector table is cleaned from Data Cache,
// and Instruction Cache is invalidated, so that CPU fetches the correct address
SCB_CleanDCache_by_Addr((uint32_t*)&__ramVectors[CY_INT_IRQ_BASE + intrSrc], 4);
SCB_InvalidateICache();
#endif
}
}
/*******************************************************************************
* Function Name: Cy_SysInt_GetVector
****************************************************************************//**
*
* \brief Gets the address of the current ISR vector for the Interrupt.
*
* Note that this function relies on the assumption that the vector table is
* relocated to __ramVectors[RAM_VECTORS_SIZE] in SRAM.
*
* \param intrSrc
* Interrupt source
*
* \return
* Address of the ISR in the interrupt vector table
*
*******************************************************************************/
cy_israddress Cy_SysInt_GetVector(IRQn_Type intrSrc)
{
cy_israddress currIsr;
/* Only return the SRAM ISR address if it was moved to __ramVectors */
if (SCB->VTOR == (uint32_t)&__ramVectors)
{
currIsr = __ramVectors[CY_INT_IRQ_BASE + intrSrc];
}
else
{
currIsr = __Vectors[CY_INT_IRQ_BASE + intrSrc];
}
return currIsr;
}
/*******************************************************************************
* Function Name: Cy_SysInt_SetSystemIrqVector
****************************************************************************//**
*
* \brief Changes the User ISR vector for the System Interrupt.
*
* \param sysIntSrc
* Interrrupt source
*
* \param userIsr
* Address of the ISR to set in the interrupt vector table
*
* \return none
*
*******************************************************************************/
void Cy_SysInt_SetSystemIrqVector(cy_en_intr_t sysIntSrc, cy_systemIntr_Handler userIsr)
{
if (Cy_SysInt_SystemIrqUserTableRamPointer != NULL)
{
Cy_SysInt_SystemIrqUserTableRamPointer[sysIntSrc] = userIsr;
}
}
/*******************************************************************************
* Function Name: Cy_SysInt_GetSystemIrqVector
****************************************************************************//**
*
* \brief Gets the address of the current user ISR vector for the System Interrupt.
*
* \param sysIntSrc
* Interrupt source
*
* \return
* Address of the ISR in the interrupt vector table
*
*******************************************************************************/
cy_systemIntr_Handler Cy_SysInt_GetSystemIrqVector(cy_en_intr_t sysIntSrc)
{
if (Cy_SysInt_SystemIrqUserTableRamPointer != NULL)
{
return Cy_SysInt_SystemIrqUserTableRamPointer[sysIntSrc];
}
else
{
return NULL;
}
}
/*******************************************************************************
* Function Name: Cy_SysInt_EnableIRQ
****************************************************************************//**
*
* \brief Enable system inerurupt.
*
* \param sysintSrc
* System interrrupt source to be enabled.
*
* \return none
*
*******************************************************************************/
void Cy_SysInt_EnableIRQ(cy_en_intr_t sysIntSrc)
{
#if (CY_CPU_CORTEX_M0P)
CPUSS->unCM0_SYSTEM_INT_CTL[sysIntSrc].stcField.u1CPU_INT_VALID = 1ul;
#else
#if defined (tviibe512k) || defined (tviibe1m) || defined (tviibe2m)|| defined (tviibe4m) || defined (tviice4m)
CPUSS->unCM4_SYSTEM_INT_CTL[sysIntSrc].stcField.u1CPU_INT_VALID = 1ul;
#elif defined (tviibh4m) || defined (tviibh8m) || defined (tviic2d6m) ||defined (tviic2d4m) || defined (tviic2d6mddr) || defined (tviibh16m)
if(CPUSS->unIDENTITY.stcField.u4MS == CPUSS_MS_ID_CM7_0)
{
CPUSS->unCM7_0_SYSTEM_INT_CTL[sysIntSrc].stcField.u1CPU_INT_VALID = 1ul;
}
#if defined(CPUSS_CM7_1_PRESENT) && (CPUSS_CM7_1_PRESENT == 1)
else if(CPUSS->unIDENTITY.stcField.u4MS == CPUSS_MS_ID_CM7_1) // should be CPUSS_MS_ID_CM7_1
{
CPUSS->unCM7_1_SYSTEM_INT_CTL[sysIntSrc].stcField.u1CPU_INT_VALID = 0ul;
/* Read after write to ensure disabling the interrupt after returning from this function. */
(void)CPUSS->unCM7_1_SYSTEM_INT_CTL[sysIntSrc].stcField.u1CPU_INT_VALID;
}
#endif
#if defined(CPUSS_CM7_2_PRESENT) && (CPUSS_CM7_2_PRESENT == 1)
else if(CPUSS->unIDENTITY.stcField.u4MS == CPUSS_MS_ID_CM7_2) // should be CPUSS_MS_ID_CM7_2
{
CPUSS->unCM7_2_SYSTEM_INT_CTL[sysIntSrc].stcField.u1CPU_INT_VALID = 0ul;
/* Read after write to ensure disabling the interrupt after returning from this function. */
(void)CPUSS->unCM7_2_SYSTEM_INT_CTL[sysIntSrc].stcField.u1CPU_INT_VALID;
}
#endif
#if defined(CPUSS_CM7_3_PRESENT) && (CPUSS_CM7_3_PRESENT == 1)
else // should be CPUSS_MS_ID_CM7_3
{
CPUSS->unCM7_3_SYSTEM_INT_CTL[sysIntSrc].stcField.u1CPU_INT_VALID = 0ul;
/* Read after write to ensure disabling the interrupt after returning from this function. */
(void)CPUSS->unCM7_3_SYSTEM_INT_CTL[sysIntSrc].stcField.u1CPU_INT_VALID;
}
#endif
#endif
#endif
}
/*******************************************************************************
* Function Name: Cy_SysInt_DisableIRQ
****************************************************************************//**
*
* \brief Disable system inerurupt.
*
* \param sysintSrc
* System interrrupt source to be disabled.
*
* \return none
*
*******************************************************************************/
void Cy_SysInt_DisableIRQ(cy_en_intr_t sysIntSrc)
{
#if (CY_CPU_CORTEX_M0P)
CPUSS->unCM0_SYSTEM_INT_CTL[sysIntSrc].stcField.u1CPU_INT_VALID = 0ul;
/* Read after write to ensure disabling the interrupt after returning from this function. */
(void)CPUSS->unCM0_SYSTEM_INT_CTL[sysIntSrc].stcField.u1CPU_INT_VALID;
#else
#if defined (tviibe512k) || defined (tviibe1m) || defined (tviibe2m)|| defined (tviibe4m) || defined (tviice4m)
CPUSS->unCM4_SYSTEM_INT_CTL[sysIntSrc].stcField.u1CPU_INT_VALID = 0ul;
/* Read after write to ensure disabling the interrupt after returning from this function. */
(void)CPUSS->unCM4_SYSTEM_INT_CTL[sysIntSrc].stcField.u1CPU_INT_VALID;
#elif defined (tviibh4m) || defined (tviibh8m) || defined (tviic2d6m) || defined (tviic2d4m) || defined (tviic2d6mddr) || defined (tviibh16m)
if(CPUSS->unIDENTITY.stcField.u4MS == CPUSS_MS_ID_CM7_0)
{
CPUSS->unCM7_0_SYSTEM_INT_CTL[sysIntSrc].stcField.u1CPU_INT_VALID = 0ul;
/* Read after write to ensure disabling the interrupt after returning from this function. */
(void)CPUSS->unCM7_0_SYSTEM_INT_CTL[sysIntSrc].stcField.u1CPU_INT_VALID;
}
#if defined(CPUSS_CM7_1_PRESENT) && (CPUSS_CM7_1_PRESENT == 1)
else if(CPUSS->unIDENTITY.stcField.u4MS == CPUSS_MS_ID_CM7_1) // should be CPUSS_MS_ID_CM7_1
{
CPUSS->unCM7_1_SYSTEM_INT_CTL[sysIntSrc].stcField.u1CPU_INT_VALID = 0ul;
/* Read after write to ensure disabling the interrupt after returning from this function. */
(void)CPUSS->unCM7_1_SYSTEM_INT_CTL[sysIntSrc].stcField.u1CPU_INT_VALID;
}
#endif
#if defined(CPUSS_CM7_2_PRESENT) && (CPUSS_CM7_2_PRESENT == 1)
else if(CPUSS->unIDENTITY.stcField.u4MS == CPUSS_MS_ID_CM7_2) // should be CPUSS_MS_ID_CM7_2
{
CPUSS->unCM7_2_SYSTEM_INT_CTL[sysIntSrc].stcField.u1CPU_INT_VALID = 0ul;
/* Read after write to ensure disabling the interrupt after returning from this function. */
(void)CPUSS->unCM7_2_SYSTEM_INT_CTL[sysIntSrc].stcField.u1CPU_INT_VALID;
}
#endif
#if defined(CPUSS_CM7_3_PRESENT) && (CPUSS_CM7_3_PRESENT == 1)
else // should be CPUSS_MS_ID_CM7_3
{
CPUSS->unCM7_3_SYSTEM_INT_CTL[sysIntSrc].stcField.u1CPU_INT_VALID = 0ul;
/* Read after write to ensure disabling the interrupt after returning from this function. */
(void)CPUSS->unCM7_3_SYSTEM_INT_CTL[sysIntSrc].stcField.u1CPU_INT_VALID;
}
#endif
#endif
#endif
}
/*******************************************************************************
* Function Name: Cy_SysInt_GetIntStatus
****************************************************************************//**
*
* \brief This interface returns lowest activated system interrupt index for
* corresponding CPU interrupt index.
* Return value can be used to determine which system interrupt activated
* the interrupt handler.
* Typical usage:
* In case of one interrupt handler handles 2 or more system interrupts.
* In that case, user can determine which system interrupt should be handled
* in the handler with the retrun value by this I/F.
*
* \param intrSrc
* Number of CPU interrupt index. Only CPUIntIdx0_IRQn to CPUIntIdx7_IRQn
* are valid.
*
* \return
* System interrupt index that activated the interrupt handler.
* See \ref cy_en_intr_t.
* If invalid IRQ number is passed, then return disconnected_IRQn.
*
*******************************************************************************/
cy_en_intr_t Cy_SysInt_GetIntStatus(IRQn_Type intrSrc)
{
cy_en_intr_t ret = disconnected_IRQn;
#if CY_CPU_CORTEX_M0P
switch(intrSrc)
{
case CPUIntIdx0_IRQn:
ret = (cy_en_intr_t)CPUSS->unCM0_INT0_STATUS.stcField.u10SYSTEM_INT_IDX;
break;
case CPUIntIdx1_IRQn:
ret = (cy_en_intr_t)CPUSS->unCM0_INT1_STATUS.stcField.u10SYSTEM_INT_IDX;
break;
case CPUIntIdx2_IRQn:
ret = (cy_en_intr_t)CPUSS->unCM0_INT2_STATUS.stcField.u10SYSTEM_INT_IDX;
break;
case CPUIntIdx3_IRQn:
ret = (cy_en_intr_t)CPUSS->unCM0_INT3_STATUS.stcField.u10SYSTEM_INT_IDX;
break;
case CPUIntIdx4_IRQn:
ret = (cy_en_intr_t)CPUSS->unCM0_INT4_STATUS.stcField.u10SYSTEM_INT_IDX;
break;
case CPUIntIdx5_IRQn:
ret = (cy_en_intr_t)CPUSS->unCM0_INT5_STATUS.stcField.u10SYSTEM_INT_IDX;
break;
case CPUIntIdx6_IRQn:
ret = (cy_en_intr_t)CPUSS->unCM0_INT6_STATUS.stcField.u10SYSTEM_INT_IDX;
break;
case CPUIntIdx7_IRQn:
ret = (cy_en_intr_t)CPUSS->unCM0_INT7_STATUS.stcField.u10SYSTEM_INT_IDX;
break;
default:
break;
}
#else
#if defined (tviibe512k) || defined (tviibe1m) || defined (tviibe2m) || defined (tviibe4m) || defined (tviice4m)
switch(intrSrc)
{
case CPUIntIdx0_IRQn:
ret = (cy_en_intr_t)CPUSS->unCM4_INT0_STATUS.stcField.u10SYSTEM_INT_IDX;
break;
case CPUIntIdx1_IRQn:
ret = (cy_en_intr_t)CPUSS->unCM4_INT1_STATUS.stcField.u10SYSTEM_INT_IDX;
break;
case CPUIntIdx2_IRQn:
ret = (cy_en_intr_t)CPUSS->unCM4_INT2_STATUS.stcField.u10SYSTEM_INT_IDX;
break;
case CPUIntIdx3_IRQn:
ret = (cy_en_intr_t)CPUSS->unCM4_INT3_STATUS.stcField.u10SYSTEM_INT_IDX;
break;
case CPUIntIdx4_IRQn:
ret = (cy_en_intr_t)CPUSS->unCM4_INT4_STATUS.stcField.u10SYSTEM_INT_IDX;
break;
case CPUIntIdx5_IRQn:
ret = (cy_en_intr_t)CPUSS->unCM4_INT5_STATUS.stcField.u10SYSTEM_INT_IDX;
break;
case CPUIntIdx6_IRQn:
ret = (cy_en_intr_t)CPUSS->unCM4_INT6_STATUS.stcField.u10SYSTEM_INT_IDX;
break;
case CPUIntIdx7_IRQn:
ret = (cy_en_intr_t)CPUSS->unCM4_INT7_STATUS.stcField.u10SYSTEM_INT_IDX;
break;
default:
break;
}
#elif defined (tviibh4m) || defined (tviibh8m) || defined (tviic2d6m) || defined (tviic2d4m) || defined (tviic2d6mddr) || defined (tviibh16m)
if(CPUSS->unIDENTITY.stcField.u4MS == CPUSS_MS_ID_CM7_0)
{
ret = (cy_en_intr_t)CPUSS->unCM7_0_INT_STATUS[intrSrc].stcField.u10SYSTEM_INT_IDX;
}
#if defined(CPUSS_CM7_1_PRESENT) && (CPUSS_CM7_1_PRESENT == 1)
else if(CPUSS->unIDENTITY.stcField.u4MS == CPUSS_MS_ID_CM7_1) // should be CPUSS_MS_ID_CM7_1
{
ret = (cy_en_intr_t)CPUSS->unCM7_1_INT_STATUS[intrSrc].stcField.u10SYSTEM_INT_IDX;
}
#endif
#if defined(CPUSS_CM7_2_PRESENT) && (CPUSS_CM7_2_PRESENT == 1)
else if(CPUSS->unIDENTITY.stcField.u4MS == CPUSS_MS_ID_CM7_2) // should be CPUSS_MS_ID_CM7_2
{
ret = (cy_en_intr_t)CPUSS->unCM7_2_INT_STATUS[intrSrc].stcField.u10SYSTEM_INT_IDX;
}
#endif
#if defined(CPUSS_CM7_3_PRESENT) && (CPUSS_CM7_3_PRESENT == 1)
else // should be CPUSS_MS_ID_CM7_3
{
ret = (cy_en_intr_t)CPUSS->unCM7_3_INT_STATUS[intrSrc].stcField.u10SYSTEM_INT_IDX;
}
#endif
#endif
#endif
return ret;
}
/*******************************************************************************
* Function Name: Cy_SysInt_SetIntSourceNMI
****************************************************************************//**
*
* \brief Sets the interrupt source of NMI.
*
* Setting this value to 1023 disconnects the interrupt source from the NMI. The
* interrupt source must be a positive number.
*
* \param nmiNum
* Number of NMI (0 to 3).
*
* \param sysIntSrc
* System interrupt source. Refer \ref cy_en_intr_t.
* If you want to disconnect system interupt from the NMI, set disconnected_IRQn.
*
********************************************************************************/
void Cy_SysInt_SetIntSourceNMI(uint8_t nmiNum, cy_en_intr_t sysIntSrc)
{
#if (CY_CPU_CORTEX_M0P)
CPUSS->unCM0_NMI_CTL[nmiNum].stcField.u10SYSTEM_INT_IDX = sysIntSrc;
#else
#if defined (tviibe512k) || defined (tviibe1m) || defined (tviibe2m)|| defined (tviibe4m) || defined (tviice4m)
CPUSS->unCM4_NMI_CTL[nmiNum].stcField.u10SYSTEM_INT_IDX = sysIntSrc;
#elif defined (tviibh4m) || defined (tviibh8m) || defined (tviic2d6m) ||defined (tviic2d4m) || defined (tviic2d6mddr) || defined (tviibh16m)
if(CPUSS->unIDENTITY.stcField.u4MS == CPUSS_MS_ID_CM7_0)
{
CPUSS->unCM7_0_NMI_CTL[nmiNum].stcField.u10SYSTEM_INT_IDX = sysIntSrc;
}
#if defined(CPUSS_CM7_1_PRESENT) && (CPUSS_CM7_1_PRESENT == 1)
else if(CPUSS->unIDENTITY.stcField.u4MS == CPUSS_MS_ID_CM7_1) // should be CPUSS_MS_ID_CM7_1
{
CPUSS->unCM7_1_NMI_CTL[nmiNum].stcField.u10SYSTEM_INT_IDX = sysIntSrc;
}
#endif
#if defined(CPUSS_CM7_2_PRESENT) && (CPUSS_CM7_2_PRESENT == 1)
else if(CPUSS->unIDENTITY.stcField.u4MS == CPUSS_MS_ID_CM7_2) // should be CPUSS_MS_ID_CM7_2
{
CPUSS->unCM7_2_NMI_CTL[nmiNum].stcField.u10SYSTEM_INT_IDX = sysIntSrc;
}
#endif
#if defined(CPUSS_CM7_3_PRESENT) && (CPUSS_CM7_3_PRESENT == 1)
else // should be CPUSS_MS_ID_CM7_3
{
CPUSS->unCM7_3_NMI_CTL[nmiNum].stcField.u10SYSTEM_INT_IDX = sysIntSrc;
}
#endif
#endif
#endif
}
/*******************************************************************************
* Function Name: Cy_SysInt_GetIntSourceNMI
****************************************************************************//**
*
* \brief Gets the interrupt source of the NMI.
*
* \param nmiNum
* Number of NMI (0 to 3).
*
* \return
* Interrupt Source. A value of 1023 (disconnected_IRQn) means that there is no
* interrupt source for the NMI, and it can be only be triggered through software.
*
*******************************************************************************/
cy_en_intr_t Cy_SysInt_GetIntSourceNMI(uint8_t nmiNum)
{
#if (CY_CPU_CORTEX_M0P)
return (cy_en_intr_t) CPUSS->unCM0_NMI_CTL[nmiNum].stcField.u10SYSTEM_INT_IDX;
#else
#if defined (tviibe512k) || defined (tviibe1m) || defined (tviibe2m) || defined (tviibe4m) || defined (tviice4m)
return (cy_en_intr_t)CPUSS->unCM4_NMI_CTL[nmiNum].stcField.u10SYSTEM_INT_IDX;
#elif defined (tviibh4m) || defined (tviibh8m) || defined (tviic2d6m) ||defined (tviic2d4m) || defined (tviic2d6mddr) || defined (tviibh16m)
if(CPUSS->unIDENTITY.stcField.u4MS == CPUSS_MS_ID_CM7_0) // should be CPUSS_MS_ID_CM7_0
{
return (cy_en_intr_t) CPUSS->unCM7_0_NMI_CTL[nmiNum].stcField.u10SYSTEM_INT_IDX;
}
#if defined(CPUSS_CM7_1_PRESENT) && (CPUSS_CM7_1_PRESENT == 1)
else if(CPUSS->unIDENTITY.stcField.u4MS == CPUSS_MS_ID_CM7_1) // should be CPUSS_MS_ID_CM7_1
{
return (cy_en_intr_t) CPUSS->unCM7_1_NMI_CTL[nmiNum].stcField.u10SYSTEM_INT_IDX;
}
#endif
#if defined(CPUSS_CM7_2_PRESENT) && (CPUSS_CM7_2_PRESENT == 1)
else if(CPUSS->unIDENTITY.stcField.u4MS == CPUSS_MS_ID_CM7_2) // should be CPUSS_MS_ID_CM7_2
{
return (cy_en_intr_t) CPUSS->unCM7_2_NMI_CTL[nmiNum].stcField.u10SYSTEM_INT_IDX;
}
#endif
#if defined(CPUSS_CM7_3_PRESENT) && (CPUSS_CM7_3_PRESENT == 1)
else // should be CPUSS_MS_ID_CM7_3
{
return (cy_en_intr_t) CPUSS->unCM7_3_NMI_CTL[nmiNum].stcField.u10SYSTEM_INT_IDX;
}
#else
return disconnected_IRQn;
#endif
#endif
#endif
}
#if defined(__cplusplus)
}
#endif
/* [] END OF FILE */
@@ -0,0 +1,274 @@
/***************************************************************************//**
* \file cy_sysint.h
* \version 1.0
*
* \brief
* Provides an API declaration of the SysInt driver
*
********************************************************************************
* \copyright
* Copyright 2016-2017, Cypress Semiconductor Corporation. All rights reserved.
* You may use this file only in accordance with the license, terms, conditions,
* disclaimers, and limitations in the end user license agreement accompanying
* the software package with which this file was provided.
*******************************************************************************/
/**
* \defgroup group_sysint System Interrupt (SysInt)
* \{
* The SysInt driver provides an API to configure the device peripheral interrupts.
* It provides a lightweight interface to complement the CMSIS core NVIC API.
* The provided functions are applicable for all cores in a device and they can
* be used to configure and connect device peripheral interrupts to one or more
* cores.
*
* \n
* <b> Initialization </b>
*
* To configure an interrupt, call Cy_SysInt_Init().
* Populate the configuration structure (cy_stc_sysint_t) and pass it as a parameter
* along with the ISR address. This initializes the interrupt and
* instructs the CPU to jump to the specified ISR vector upon a valid trigger.
*
* Populating the interrupt configuration structure differs slightly for the system
* interrupt. Both of CM0+ and CM4 supports only up to 8 CPU interrupt and system
* (peripheral) interrupts are mapped to those.
* To allow all device interrupts to be routable to the NVIC of this core,
* there exists a 1023:1 multiplexer at each of the 8 NVIC channels.
* To configure system interrupt, call Cy_SysInt_InitIRQ().
*
* \n
* <b> Enable </b>
*
* After initializing an interrupt, use the CMSIS Core NVIC_EnableIRQ() function to
* enable it. Given an initialization structure named config, the function should be
* called as follows:
*
* NVIC_EnableIRQ(config.intIdx)
*
* \n
* <b>Writing an interrupt service routine</b>
*
* Servicing interrupts in the Peripheral Drivers should follow a prescribed
* recipe to ensure all interrupts are serviced and duplicate interrupts are not
* received. Any peripheral-specific register that must be written to clear the
* source of the interrupt should be written as soon as possible in the interrupt
* service routine. However, note that due to buffering on the output bus to the
* peripherals, the write clearing the interrupt may be delayed. After performing
* the normal interrupt service that should respond to the interrupting
* condition, the interrupt register that was initially written to clear the
* register should be read before returning from the interrupt service routine.
* This read ensures that the initial write has been flushed out to the hardware.
* Note, no additional processing should be performed based on the result of this
* read, as this read is just intended to ensure the write operation is flushed.
*
* This final read may indicate a pending interrupt. What this means is that in
* the interval between when the write actually happened at the peripheral and
* when the read actually happened at the peripheral, an interrupting condition
* occurred. This is ok and a return from the interrupt is still the correct
* action. As soon as conditions warrant, meaning interrupts are enabled and
* there are no higher priority interrupts pending, the interrupt will be
* triggered again to service the additional condition.
*
* \section group_sysint_more_information More Information
*
* Refer to the technical reference manual (TRM) and the device datasheet.
*
* \section group_sysint_changelog Changelog
* <table class="doxtable">
* <tr><th>Version</th><th>Changes</th><th>Reason for Change</th></tr>
* <tr>
* <td>1.0</td>
* <td>Initial version</td>
* <td></td>
* </tr>
* </table>
*
* \defgroup group_sysint_macro Macro
* \defgroup group_sysint_globals Global variables
* \defgroup group_sysint_functions Functions
* \defgroup group_sysint_data_structures Data structures
* \defgroup group_sysint_enums Enumerated Types
*/
#if !defined(CY_SYSINT_H)
#define CY_SYSINT_H
#include <stddef.h>
#include "syslib/cy_syslib.h"
#include "cy_device_headers.h"
#if defined(__cplusplus)
extern "C" {
#endif
typedef void (*cy_systemIntr_Handler)(void);
/***************************************
* Global Variable
***************************************/
/**
* \addtogroup group_sysint_globals
* \{
*/
extern const cy_israddress __Vectors[]; /**< Vector table in Flash */
extern cy_israddress __ramVectors[]; /**< Relocated vector table in SRAM */
/** \} group_sysint_globals */
/***************************************
* Global Interrupt
***************************************/
/**
* \addtogroup group_sysint_macro
* \{
*/
/** Driver major version */
#define CY_SYSINT_DRV_VERSION_MAJOR (0x01u)
/** Driver minor version */
#define CY_SYSINT_DRV_VERSION_MINOR (0x00u)
/** SysInt driver ID */
#define CY_SYSINT_ID CY_PDL_DRV_ID(0x15u)
/** \} group_sysint_macro */
/***************************************
* Enumeration
***************************************/
/**
* \addtogroup group_sysint_enums
* \{
*/
/**
* SysInt Driver error codes
*/
typedef enum
{
CY_SYSINT_SUCCESS = 0x00u, /**< Returned successful */
CY_SYSINT_BAD_PARAM = CY_SYSINT_ID | CY_PDL_STATUS_ERROR | 0x01u, /**< Bad parameter was passed */
} cy_en_sysint_status_t;
/** \} group_sysint_enums */
/***************************************
* Configuration Structure
***************************************/
/**
* \addtogroup group_sysint_data_structures
* \{
*/
/**
* Initialization configuration structure for a single core interrupt channel
*/
typedef struct {
IRQn_Type intrSrc; /**< Interrupt source */
uint32_t intrPriority; /**< Interrupt priority number (Refer to __NVIC_PRIO_BITS) */
} cy_stc_sysint_t;
/**
* Initialization configuration structure for a single system interrupt channel
*/
typedef struct {
cy_en_intr_t sysIntSrc; /**< System Interrupt source */
IRQn_Type intIdx; /**< CPU interrupt index whom system interrupt source is mapped to.
* Note: Only CPUIntIdxX_IRQn [X = 0..7] is valid.
*/
bool isEnabled; /**< Enabling/disabling system interruption */
} cy_stc_sysint_irq_t;
/** \} group_sysint_data_structures */
/***************************************
* Constants
***************************************/
/** \cond INTERNAL */
#define CY_INT_IRQ_BASE (0x10ul) /**< Start location of interrupts in the vector table */
#define CY_SYSINT_STATE_MASK (0x01ul) /**< Mask for interrupt state */
#define CY_SYSINT_STIR_MASK (0xfful) /**< Mask for software trigger interrupt register */
/** \endcond */
/***************************************
* Function Prototypes
***************************************/
/**
* \addtogroup group_sysint_functions
* \{
*/
cy_en_sysint_status_t Cy_SysInt_Init(const cy_stc_sysint_t * config, cy_israddress userIsr);
cy_en_sysint_status_t Cy_SysInt_InitIRQ(const cy_stc_sysint_irq_t* config);
void Cy_SysInt_SetVector(IRQn_Type intrSrc, cy_israddress userIsr);
cy_israddress Cy_SysInt_GetVector(IRQn_Type intrSrc);
void Cy_SysInt_SetVectorIRQ(IRQn_Type intIdx, cy_israddress userIsr);
cy_israddress Cy_SysInt_GetVectorIRQ(IRQn_Type intIdx);
void Cy_SysInt_SetSystemIrqVector(cy_en_intr_t sysIntSrc, cy_systemIntr_Handler userIsr);
cy_systemIntr_Handler Cy_SysInt_GetSystemIrqVector(cy_en_intr_t intrSrc);
void Cy_SysInt_EnableIRQ(cy_en_intr_t sysIntSrc);
void Cy_SysInt_DisableIRQ(cy_en_intr_t sysIntSrc);
cy_en_intr_t Cy_SysInt_GetIntStatus(IRQn_Type intrSrc);
void Cy_SysInt_SetIntSourceNMI(uint8_t nmiNum, cy_en_intr_t sysIntSrc);
cy_en_intr_t Cy_SysInt_GetIntSourceNMI(uint8_t nmiNum);
#if (CY_CPU_CORTEX_M0P)
#else
__STATIC_INLINE void Cy_SysInt_SoftwareTrig(IRQn_Type intrSrc);
#endif
#if (!CY_CPU_CORTEX_M0P) || defined (CY_DOXYGEN)
/*******************************************************************************
* Function Name: Cy_SysInt_SoftwareTrig
****************************************************************************//**
*
* \brief Triggers an interrupt using software (Not applicable for CM0+).
*
* <b>Note</b> Only privileged software can enable unprivileged access to the
* Software Trigger Interrupt Register (STIR).
*
* \param intrSrc
* Interrupt source
*
*******************************************************************************/
__STATIC_INLINE void Cy_SysInt_SoftwareTrig(IRQn_Type intrSrc)
{
NVIC->STIR = intrSrc & CY_SYSINT_STIR_MASK;
}
#endif
/** \} group_sysint_functions */
#if defined(__cplusplus)
}
#endif
#endif /* CY_SYSINT_H */
/** \} group_sysint */
/* [] END OF FILE */
@@ -0,0 +1,550 @@
/***************************************************************************//**
* \file cy_syslib.c
* \version 1.0
*
* Description:
* Provides an API declaration of the syslib driver
*
********************************************************************************
* Copyright 2016-2017, Cypress Semiconductor Corporation. All rights reserved.
* You may use this file only in accordance with the license, terms, conditions,
* disclaimers, and limitations in the end user license agreement accompanying
* the software package with which this file was provided.
*******************************************************************************/
#include "cy_syslib.h"
#include "ipc/cy_ipc_drv.h"
/* $TODO HXSH: Frequency threshold should be checked. */
/* Flash wait states (LP mode at 1.1v) */
#define CY_SYSLIB_FLASH_LP_WS_0_FREQ_MAX (100UL)
#define CY_SYSLIB_FLASH_LP_WS_1_FREQ_MAX (CY_HF_CLK_MAX_FREQ / 1000000UL)
/* Flash wait states (ULP mode at 0.9v) */
#define CY_SYSLIB_FLASH_ULP_WS_0_FREQ_MAX ( 16UL)
#define CY_SYSLIB_FLASH_ULP_WS_1_FREQ_MAX ( 33UL)
#define CY_SYSLIB_FLASH_ULP_WS_2_FREQ_MAX ( 50UL)
/* ROM wait states for the slow clock domain (LP mode at 1.1v) */
#define CY_SYSLIB_ROM_LP_SLOW_WS_0_FREQ_MAX (100UL)
#define CY_SYSLIB_ROM_LP_SLOW_WS_1_FREQ_MAX (120UL)
/* ROM wait states for the slow clock domain (ULP mode at 0.9v) */
#define CY_SYSLIB_ROM_ULP_SLOW_WS_0_FREQ_MAX ( 25UL)
#define CY_SYSLIB_ROM_ULP_SLOW_WS_1_FREQ_MAX ( 50UL)
/* ROM wait states for the fast clock domain (LP mode at 1.1v) */
#define CY_SYSLIB_ROM_LP_FAST_WS_0_FREQ_MAX (120UL)
/* ROM wait states for the slow clock domain (ULP mode at 0.9v) */
#define CY_SYSLIB_ROM_ULP_FAST_WS_0_FREQ_MAX ( 50UL)
/* SRAM wait states for the slow clock domain (LP mode at 1.1v) */
#define CY_SYSLIB_RAM_LP_SLOW_WS_0_FREQ_MAX (100UL)
#define CY_SYSLIB_RAM_LP_SLOW_WS_1_FREQ_MAX (120UL)
/* SRAM wait states for the slow clock domain (ULP mode at 0.9v) */
#define CY_SYSLIB_RAM_ULP_SLOW_WS_0_FREQ_MAX ( 25UL)
#define CY_SYSLIB_RAM_ULP_SLOW_WS_1_FREQ_MAX ( 50UL)
/* SRAM wait states for the fast clock domain (LP mode at 1.1v) */
#define CY_SYSLIB_RAM_LP_FAST_WS_0_FREQ_MAX (120UL)
/* SRAM wait states for the fast clock domain (ULP mode at 0.9v) */
#define CY_SYSLIB_RAM_ULP_FAST_WS_0_FREQ_MAX ( 50UL)
#if !defined(NDEBUG)
char_t cy_assertFileName[CY_MAX_FILE_NAME_SIZE];
uint32_t cy_assertLine;
#endif /* NDEBUG */
#if (CY_ARM_FAULT_DEBUG == CY_ARM_FAULT_DEBUG_ENABLED)
cy_stc_fault_frame_t cy_faultFrame;
#endif /* (CY_ARM_FAULT_DEBUG == CY_ARM_FAULT_DEBUG_ENABLED) */
static void Cy_SysLib_SetWaitStates_LP(uint32_t clkHfMHz);
/*******************************************************************************
* Function Name: Cy_SysLib_Delay
****************************************************************************//**
*
* The function delays by the specified number of milliseconds.
* By default, the number of cycles to delay is calculated based on the
* \ref SystemCoreClock.
*
* \param milliseconds The number of milliseconds to delay.
*
* \note The function calls \ref Cy_SysLib_DelayCycles() API to generate a delay.
* If the function parameter (milliseconds) is bigger than
* CY_DELAY_MS_OVERFLOW constant, then an additional loop runs to prevent
* an overflow in parameter passed to \ref Cy_SysLib_DelayCycles() API.
*
*******************************************************************************/
void Cy_SysLib_Delay(uint32_t milliseconds)
{
while(milliseconds > CY_DELAY_MS_OVERFLOW)
{
/* This loop prevents an overflow in value passed to Cy_SysLib_DelayCycles() API.
* At 100 MHz, (milliseconds * cy_delayFreqKhz) product overflows
* in case if milliseconds parameter is more than 42 seconds.
*/
Cy_SysLib_DelayCycles(cy_delay32kMs);
milliseconds -= CY_DELAY_MS_OVERFLOW;
}
Cy_SysLib_DelayCycles(milliseconds * cy_delayFreqKhz);
}
/*******************************************************************************
* Function Name: Cy_SysLib_DelayUs
****************************************************************************//**
*
* The function delays by the specified number of microseconds.
* By default, the number of cycles to delay is calculated based on the
* \ref SystemCoreClock.
*
* \param microseconds The number of microseconds to delay.
*
* \note If the CPU frequency is a small non-integer number, the actual delay
* can be up to twice as long as the nominal value. The actual delay
* cannot be shorter than the nominal one.
*
*******************************************************************************/
void Cy_SysLib_DelayUs(uint16_t microseconds)
{
Cy_SysLib_DelayCycles((uint32_t) microseconds * cy_delayFreqMhz);
}
/*******************************************************************************
* Function Name: Cy_SysLib_Halt
****************************************************************************//**
*
* This function halts the CPU but only the CPU which calls the function.
* It doesn't affect other CPUs.
*
* \param reason The value to be used during debugging.
*
* \note The function executes the BKPT instruction for halting CPU and is
* intended to be used for the debug purpose. A regular use case requires
* Debugger attachment before the function call.
* The BKPT instruction causes the CPU to enter the Debug state. Debug
* tools can use this to investigate the system state, when the
* instruction at a particular address is reached.
*
* \note Execution of a BKPT instruction without a debugger attached produces
* a fault. The fault results in the HardFault exception being taken
* or causes a Lockup state if it occurs in the NMI or HardFault handler.
* The default HardFault handler make a software reset if the build option
* is the release mode (NDEBUG). If the build option is the debug mode,
* the system will stay in the infinite loop of the
* \ref Cy_SysLib_ProcessingFault() function.
*
*******************************************************************************/
__NO_RETURN void Cy_SysLib_Halt(uint32_t reason)
{
if(0u != reason)
{
/* To remove an unreferenced local variable warning */
}
#if defined (__ARMCC_VERSION)
__breakpoint(0x0);
#elif defined(__GNUC__)
__asm(" bkpt 1");
__builtin_unreachable();
#elif defined (__ICCARM__)
__asm(" bkpt 1");
#elif defined (__ghs__)
__asm(" bkpt 1");
#elif defined (__DCC__)
__asm(" bkpt #1");
#else
#error "Unsupported toolchain"
#endif /* (__ARMCC_VERSION) */
while(1u) {}
}
/*******************************************************************************
* Function Name: Cy_SysLib_ClearFlashCacheAndBuffer
****************************************************************************//**
*
* This function invalidates the flash cache and buffer. It ensures the valid
* data is read from flash instead of using outdated data from the cache.
* The caches' LRU structure is also reset to their default state.
*
* \note The operation takes a maximum of three clock cycles on the slowest of
* the clk_slow and clk_fast clocks.
*
*******************************************************************************/
void Cy_SysLib_ClearFlashCacheAndBuffer(void)
{
#if !defined (tviibh16m)
FLASHC->unFLASH_CMD.u32Register = FLASHC_FLASH_CMD_INV_Msk;
#endif
}
/*******************************************************************************
* Function Name: Cy_SysLib_GetUniqueId
****************************************************************************//**
*
* This function returns the silicon unique ID.
* The ID includes Die lot[3]#, Die Wafer#, Die X, Die Y, DIE Sort# and
* Die Minor#
*
* \return
* A combined 64-bit unique ID.
* [63:56] - DIE_MINOR
* [55:48] - DIE_SORT
* [47:40] - DIE_Y
* [39:32] - DIE_X
* [31:24] - DIE_WAFER
* [23:16] - DIE_LOT[2]
* [15: 8] - DIE_LOT[1]
* [ 7: 0] - DIE_LOT[0]
*
*******************************************************************************/
uint64_t Cy_SysLib_GetUniqueId(void)
{
uint64_t uniqueId = 0u;
//rmkn: to be checked
#if (0) // !defined (tviibe2m)
uniqueId = ((uint64_t)((stc_SFLASH_t *)SFLASH_BASE)->unDIE_MINOR.u8Register << CY_UNIQUE_ID_DIE_MINOR_Pos) |
((uint64_t)((stc_SFLASH_t *)SFLASH_BASE)->unDIE_SORT.u8Register << CY_UNIQUE_ID_DIE_SORT_Pos) |
((uint64_t)((stc_SFLASH_t *)SFLASH_BASE)->unDIE_Y.u8Register << CY_UNIQUE_ID_DIE_Y_Pos) |
((uint64_t)((stc_SFLASH_t *)SFLASH_BASE)->unDIE_X.u8Register << CY_UNIQUE_ID_DIE_X_Pos) |
((uint64_t)((stc_SFLASH_t *)SFLASH_BASE)->unDIE_WAFER.u8Register << CY_UNIQUE_ID_DIE_WAFER_Pos) |
((uint64_t)((stc_SFLASH_t *)SFLASH_BASE)->unDIE_LOT[2u].u8Register << CY_UNIQUE_ID_DIE_LOT_2_Pos) |
((uint64_t)((stc_SFLASH_t *)SFLASH_BASE)->unDIE_LOT[1u].u8Register << CY_UNIQUE_ID_DIE_LOT_1_Pos) |
((uint64_t)((stc_SFLASH_t *)SFLASH_BASE)->unDIE_LOT[0u].u8Register << CY_UNIQUE_ID_DIE_LOT_0_Pos);
#endif
return (uniqueId);
}
#if (CY_ARM_FAULT_DEBUG == CY_ARM_FAULT_DEBUG_ENABLED) || defined(CY_DOXYGEN)
/*******************************************************************************
* Function Name: Cy_SysLib_FaultHandler
****************************************************************************//**
*
* This function stores the ARM Cortex registers into a non-zero init area for
* debugging. This function calls Cy_SysLib_ProcessingFault() after storing all
* the information.
*
* \param faultStackAddr The address of the stack pointer, indicates the lowest
* address in the fault stack frame to be stored.
* \note This function stores the fault stack frame only for the first occurred
* fault.
* \note This function sets two flags into the fault structure: one checks
* which core cause fault, another checks the type of fault for CM4 core.
* The flags should be cleared after analysis of the stored
* register values, to have possibility to distinguish the next fault.
* \note The PDL doesn't provide an API which can analyse the stored register
* values. A user has to add additional functions for the analysis,
* if necessary.
* \note The CY_ARM_FAULT_DEBUG macro defines if the Fault Handler is enabled.
* By default it is set to CY_ARM_FAULT_DEBUG_ENABLED and enables the
* Fault Handler.
* If there is a necessity to save memory or have some specific custom
* handler, etc. then CY_ARM_FAULT_DEBUG should be redefined as
* CY_ARM_FAULT_DEBUG_DISABLED. To do this the following definition should
* be added to the compiler Command Line (through the project Build
* Settings): "-D CY_ARM_FAULT_DEBUG=0".
*
*******************************************************************************/
void Cy_SysLib_FaultHandler(uint32_t const *faultStackAddr)
{
#if (CY_CPU_CORTEX_M0P)
if(CY_CM0P_FAULT_TYPE != cy_faultFrame.fault)
{
cy_faultFrame.fault = CY_CM0P_FAULT_TYPE; /* CM0P fault occurred. */
#else
#if (CY_CPU_CORTEX_M4)
if(CY_CM4_FAULT_TYPE != cy_faultFrame.fault)
{
cy_faultFrame.fault = CY_CM4_FAULT_TYPE; /* CM4 fault occurred. */
#elif (CY_CPU_CORTEX_M7)
if(CY_CM7_FAULT_TYPE != cy_faultFrame.fault)
{
cy_faultFrame.fault = CY_CM7_FAULT_TYPE; /* CM7 fault occurred. */
#endif
/* Stores the Configurable Fault Status Register state with the fault cause */
cy_faultFrame.cfsr = SCB->CFSR;
cy_faultFrame.faultType = CY_NON_FPU_FAULT_TYPE;
#endif /* CY_CPU_CORTEX_M0P */
/* Stores general registers */
cy_faultFrame.r0 = faultStackAddr[CY_R0_Pos];
cy_faultFrame.r1 = faultStackAddr[CY_R1_Pos];
cy_faultFrame.r2 = faultStackAddr[CY_R2_Pos];
cy_faultFrame.r3 = faultStackAddr[CY_R3_Pos];
cy_faultFrame.r12 = faultStackAddr[CY_R12_Pos];
cy_faultFrame.lr = faultStackAddr[CY_LR_Pos];
cy_faultFrame.pc = faultStackAddr[CY_PC_Pos];
cy_faultFrame.psr = faultStackAddr[CY_PSR_Pos];
#if ((CY_CPU_CORTEX_M7) || (CY_CPU_CORTEX_M4)) && ((defined (__FPU_PRESENT) && (__FPU_PRESENT == 1U)) && \
(defined (__FPU_USED ) && (__FPU_USED == 1U)))
/* Checks cumulative exception bits for floating-point exceptions */
if(0U != (__get_FPSCR() & (CY_FPSCR_IXC_Msk | CY_FPSCR_IDC_Msk)))
{
cy_faultFrame.faultType = CY_FPU_FAULT_TYPE;
cy_faultFrame.s0 = faultStackAddr[CY_S0_Pos];
cy_faultFrame.s1 = faultStackAddr[CY_S1_Pos];
cy_faultFrame.s2 = faultStackAddr[CY_S2_Pos];
cy_faultFrame.s3 = faultStackAddr[CY_S3_Pos];
cy_faultFrame.s4 = faultStackAddr[CY_S4_Pos];
cy_faultFrame.s5 = faultStackAddr[CY_S5_Pos];
cy_faultFrame.s6 = faultStackAddr[CY_S6_Pos];
cy_faultFrame.s7 = faultStackAddr[CY_S7_Pos];
cy_faultFrame.s8 = faultStackAddr[CY_S8_Pos];
cy_faultFrame.s9 = faultStackAddr[CY_S9_Pos];
cy_faultFrame.s10 = faultStackAddr[CY_S10_Pos];
cy_faultFrame.s11 = faultStackAddr[CY_S11_Pos];
cy_faultFrame.s12 = faultStackAddr[CY_S12_Pos];
cy_faultFrame.s13 = faultStackAddr[CY_S13_Pos];
cy_faultFrame.s14 = faultStackAddr[CY_S14_Pos];
cy_faultFrame.s15 = faultStackAddr[CY_S15_Pos];
cy_faultFrame.fpscr = faultStackAddr[CY_FPSCR_Pos];
}
#endif /* CY_CPU_CORTEX_M4 && __FPU_PRESENT */
}
Cy_SysLib_ProcessingFault();
}
/*******************************************************************************
* Function Name: Cy_SysLib_ProcessingFault
****************************************************************************//**
*
* This function determines how to process the current fault state. By default
* in case of exception the system will stay in the infinite loop of this
* function.
*
* \note This function has WEAK option, so the user can redefine the function
* for a custom processing.
* For example the function redefinition could be constructed from fault
* stack processing and NVIC_SystemReset() function call.
*
*******************************************************************************/
CY_WEAK void Cy_SysLib_ProcessingFault(void)
{
while(1u) {}
}
#endif /* (CY_ARM_FAULT_DEBUG == CY_ARM_FAULT_DEBUG_ENABLED) || defined(CY_DOXYGEN) */
/*******************************************************************************
* Function Name: Cy_SysLib_SvcHandler
****************************************************************************//**
*
* This function is called when SVC instruction executed with a pointer to top
* of the frame stack as a input parameter.
* By default, this function returns svc index which was input by user.
*
* \param pSvcArgs The address of the stack pointer. Note that first byte of
"PC" in the stack indicates SVC index.
*
*******************************************************************************/
CY_WEAK void Cy_SysLib_SvcHandler(uint32_t* pSvcArgs)
{
// Stack frame contains:
// r0, r1, r2, r3, r12, r14, the return address and xPSR
// - Stacked R0 = pSvcArgs[0]
// - Stacked R1 = pSvcArgs[1]
// - Stacked R2 = pSvcArgs[2]
// - Stacked R3 = pSvcArgs[3]
// - Stacked R12 = pSvcArgs[4]
// - Stacked LR = pSvcArgs[5]
// - Stacked PC = pSvcArgs[6]
// - Stacked xPSR= pSvcArgs[7]
uint8_t svcIdx = ((char*)pSvcArgs[6])[-2];
// return "svcIdx"
pSvcArgs[0] = svcIdx;
}
/*******************************************************************************
* Function Name: Cy_SysLib_SetWaitStates
****************************************************************************//**
*
* Sets the number of clock cycles the cache will wait for, before it samples
* data coming back from ROM, SRAM, and Flash.
*
* Call this function before increasing the HFClk0 High Frequency clock.
* Call this function optionally after lowering the HFClk0 High Frequency clock
* in order to improve the CPU performance.
*
* Also, call this function before switching core supply regulator voltage (LDO
* or SIMO Buck) from 1.1V to 0.9V.
* Call this function optionally after switching core supply regulator voltage
* from 0.9V to 1.1V in order to improve the CPU performance.
*
* \param ulpMode The device power mode.
* true, if the device should be switched to the ULP mode (nominal voltage of
* the core supply regulator should be switched to 0.9V);
* false, if the device should be switched to the LP mode (nominal voltage of
* the core supply regulator should be switched to 1.1V).
*
* \note Refer to the device TRM for low power modes description.
*
* \param clkHfMHz The HFClk0 clock frequency in MHz. Specifying frequency above
* maximum supported will set the wait states as for the maximum frequency.
*
*******************************************************************************/
void Cy_SysLib_SetWaitStates(uint32_t clkHfMHz)
{
Cy_SysLib_SetWaitStates_LP(clkHfMHz);
}
/*******************************************************************************
* Function Name: Cy_SysLib_SetWaitStates_LP
****************************************************************************//**
*
* Sets the ROM, SRAM, and Flash wait states for the low power mode.
* This function is called by \ref Cy_SysLib_SetWaitStates().
*
* \param clkHfMHz The HFClk0 clock frequency in MHz. Specifying frequency above
* maximum supported will set the wait states as for the maximum frequency.
*
*******************************************************************************/
static void Cy_SysLib_SetWaitStates_LP(uint32_t clkHfMHz)
{
uint32_t waitStates;
/* ROM */
if (clkHfMHz < CY_SYSLIB_ROM_LP_SLOW_WS_0_FREQ_MAX)
{
waitStates = 0UL;
} else
{
waitStates = 1UL;
}
CPUSS->unROM_CTL.stcField.u2SLOW_WS = waitStates;
waitStates = 0UL;
CPUSS->unROM_CTL.stcField.u2FAST_WS = waitStates;
/* SRAM */
if (clkHfMHz < CY_SYSLIB_RAM_LP_SLOW_WS_0_FREQ_MAX)
{
waitStates = 0UL;
} else
{
waitStates = 1UL;
}
CPUSS->unRAM0_CTL0.stcField.u2SLOW_WS = waitStates;
#if defined (CPUSS_RAMC1_PRESENT) && (CPUSS_RAMC1_PRESENT == 1UL)
CPUSS->unRAM1_CTL0.stcField.u2SLOW_WS = waitStates;
#endif /* defined (CPUSS_RAMC1_PRESENT) && (CPUSS_RAMC1_PRESENT == 1UL) */
#if defined (CPUSS_RAMC2_PRESENT) && (CPUSS_RAMC2_PRESENT == 1UL)
CPUSS->unRAM2_CTL0.stcField.u2SLOW_WS = waitStates;
#endif /* defined (CPUSS_RAMC2_PRESENT) && (CPUSS_RAMC2_PRESENT == 1UL) */
CPUSS->unRAM0_CTL0.stcField.u2FAST_WS = waitStates;
#if defined (CPUSS_RAMC1_PRESENT) && (CPUSS_RAMC1_PRESENT == 1UL)
CPUSS->unRAM1_CTL0.stcField.u2FAST_WS = waitStates;
#endif /* defined (CPUSS_RAMC1_PRESENT) && (CPUSS_RAMC1_PRESENT == 1UL) */
#if defined (CPUSS_RAMC2_PRESENT) && (CPUSS_RAMC2_PRESENT == 1UL)
CPUSS->unRAM2_CTL0.stcField.u2FAST_WS = waitStates;
#endif /* defined (CPUSS_RAMC2_PRESENT) && (CPUSS_RAMC2_PRESENT == 1UL) */
/* Flash */
if (clkHfMHz <= CY_SYSLIB_FLASH_LP_WS_0_FREQ_MAX)
{
waitStates = 0UL;
}
else
{
waitStates = 1UL;
}
#if defined (tviibe512k) || defined (tviibe1m) || defined (tviibe2m)|| defined (tviibe4m) || defined (tviice4m)
FLASHC->unFLASH_CTL.stcField.u4MAIN_WS = waitStates;
#elif defined (tviibh4m) || defined (tviibh8m) || defined (tviic2d6m) || defined (tviic2d4m) || defined (tviic2d6mddr) || defined (tviibh16m)
// rmkn: to be reworked FLASHC->unFLASH_CTL.stcField.u4WS = waitStates;
#endif
}
/*******************************************************************************
* Function Name: Cy_SysLib_InvalidateCoreDCacheByAddr
****************************************************************************//**
*
* Invalidates D-cache in the core for the given address.
* The D-cache memory blocks which are part of given address + given size are invalidated.
*
* \param addr address
* \param dsize size of memory block (in number of bytes)
*
* \note This function works only when called by the core with D-cache (e.g. CM7)
* and CY_SYSLIB_CORE_D_CACHE_MAINTENANCE == CY_SYSLIB_CORE_D_CACHE_MAINTENANCE_ON.
*
*******************************************************************************/
void Cy_SysLib_InvalidateCoreDCacheByAddr(void *addr, int32_t dsize)
{
#if (CY_CPU_CORTEX_M7) && (CY_SYSLIB_CORE_D_CACHE_MAINTENANCE == CY_SYSLIB_CORE_D_CACHE_MAINTENANCE_ON)
/** Call the ARM cache maintenance function. */
SCB_InvalidateDCache_by_Addr(addr, dsize);
#endif
}
/*******************************************************************************
* Function Name: Cy_SysLib_CleanCoreDCacheByAddr
****************************************************************************//**
*
* Cleans D-cache in the core for the given address
* The D-cache memory blocks which are part of given address + given size are cleaned.
*
* \param addr address
* \param dsize size of memory block (in number of bytes)
*
* \note This function works only when called by the core with D-cache (e.g. CM7)
* and CY_SYSLIB_CORE_D_CACHE_MAINTENANCE == CY_SYSLIB_CORE_D_CACHE_MAINTENANCE_ON.
*
*******************************************************************************/
void Cy_SysLib_CleanCoreDCacheByAddr(void *addr, int32_t dsize)
{
#if (CY_CPU_CORTEX_M7) && (CY_SYSLIB_CORE_D_CACHE_MAINTENANCE == CY_SYSLIB_CORE_D_CACHE_MAINTENANCE_ON)
/** Call the ARM cache maintenance function. */
SCB_CleanDCache_by_Addr(addr, dsize);
#endif
}
/*******************************************************************************
* Function Name: Cy_SysLib_CleanInvalidateCoreDCacheByAddr
****************************************************************************//**
*
* Cleans and invalidates D-cache in the core for the given address
* The D-cache memory blocks which are part of given address + given size are cleaned
* and invalidated.
*
* \param addr address
* \param dsize size of memory block (in number of bytes)
*
* \note This function works only when called by the core with D-cache (e.g. CM7)
* and CY_SYSLIB_CORE_D_CACHE_MAINTENANCE == CY_SYSLIB_CORE_D_CACHE_MAINTENANCE_ON.
*
*******************************************************************************/
void Cy_SysLib_CleanInvalidateCoreDCacheByAddr(void *addr, int32_t dsize)
{
#if (CY_CPU_CORTEX_M7) && (CY_SYSLIB_CORE_D_CACHE_MAINTENANCE == CY_SYSLIB_CORE_D_CACHE_MAINTENANCE_ON)
/** Call the ARM cache maintenance function. */
SCB_CleanInvalidateDCache_by_Addr(addr, dsize);
#endif
}
/* [] END OF FILE */
@@ -0,0 +1,941 @@
/***************************************************************************//**
* \file cy_syslib.h
* \version 1.0
*
* Provides an API declaration of the syslib driver.
*
********************************************************************************
* \copyright
* Copyright 2016-2017, Cypress Semiconductor Corporation. All rights reserved.
* You may use this file only in accordance with the license, terms, conditions,
* disclaimers, and limitations in the end user license agreement accompanying
* the software package with which this file was provided.
*******************************************************************************/
/**
* \defgroup group_syslib System Library (SysLib)
* \{
* The system libraries provide APIs that can be called in the user application
* to handle the timing, logical checking or register.
*
* SysLib driver contains a set of different system functions. These functions
* can be called in the application routine. Some features of the system library:
* * Delay functions
* * Register read/write macro
* * Assert and Halt
* * Software reset
* * Reading a reset cause
* * API to invalidate the flash cache and buffer
* * Data manipulation
* * A variable type definition from MISRA-C specifying signedness
* * Cross compiler compatible attributes
* * Get silicon unique ID API
*
* \section group_syslib_configuration Configuration Considerations
* There are no general SysLib configuration concerns.
*
* \section group_syslib_more_information More Information
* Refer to the technical reference manual (TRM).
*
* \section group_syslib_changelog Changelog
* <table class="doxtable">
* <tr><th>Version</th><th>Changes</th><th>Reason for Change</th></tr>
* <tr>
* <td>1.0</td>
* <td>Initial version</td>
* <td></td>
* </tr>
* </table>
*
* \defgroup group_syslib_macro Macro
* \defgroup group_syslib_functions Functions
* \defgroup group_syslib_data_structures Data Structures
*
*/
#if !defined(_CY_SYSLIB_H_)
#define _CY_SYSLIB_H_
#include <string.h>
#include <stdint.h>
#include <stdbool.h>
#include "cy_device_headers.h"
#if defined(__cplusplus)
extern "C" {
#endif /* defined(__cplusplus) */
#if defined( __ICCARM__ )
/* Suppress the warning for multiple volatile variables in an expression. */
/* This is common for drivers code and the usage is not order-dependent. */
#pragma diag_suppress=Pa082
#endif /* defined( __ICCARM__ ) */
/** \cond INTERNAL */
typedef uint32_t cy_status;
/* MISRA rule 6.3 recommends use specific-length typedef for the basic
* numerical types of signed and unsigned variants of char, float, and double.
*/
typedef char char_t; /**< Specific-length typedef for the basic numerical types of char */
typedef float float32_t; /**< Specific-length typedef for the basic numerical types of float */
typedef double float64_t; /**< Specific-length typedef for the basic numerical types of double */
/** \endcond */
/**
* \addtogroup group_syslib_macro
* \{
*/
/******************************************************************************
* Macros
*****************************************************************************/
#define CY_CPU_CORTEX_M0P (__CORTEX_M == 0) /**< CM0+ core CPU Code */
#define CY_CPU_CORTEX_M4 (__CORTEX_M == 4) /**< CM4 core CPU Code */
#define CY_CPU_CORTEX_M7 (__CORTEX_M == 7) /**< CM7 core CPU Code */
/** Macro to disable the Fault Handler */
#define CY_ARM_FAULT_DEBUG_DISABLED (0u)
/** Macro to enable the Fault Handler */
#define CY_ARM_FAULT_DEBUG_ENABLED (1u)
#if !defined(CY_ARM_FAULT_DEBUG)
/** Macro defines if the Fault Handler is enabled. Enabled by default. */
#define CY_ARM_FAULT_DEBUG (CY_ARM_FAULT_DEBUG_ENABLED)
#endif /* CY_ARM_FAULT_DEBUG */
/**
* \defgroup group_syslib_macro_status_codes Status codes
* \{
* Function status type codes
*/
#define CY_PDL_STATUS_CODE_Pos (0u) /**< The module status code position in the status code */
#define CY_PDL_STATUS_TYPE_Pos (16u) /**< The status type position in the status code */
#define CY_PDL_MODULE_ID_Pos (18u) /**< The software module ID position in the status code */
#define CY_PDL_STATUS_INFO (0UL << CY_PDL_STATUS_TYPE_Pos) /**< Information status type */
#define CY_PDL_STATUS_WARNING (1UL << CY_PDL_STATUS_TYPE_Pos) /**< Warning status type */
#define CY_PDL_STATUS_ERROR (2UL << CY_PDL_STATUS_TYPE_Pos) /**< Error status type */
#define CY_PDL_MODULE_ID_Msk (0x3FFFu) /**< The software module ID mask */
/** Get the software PDL module ID */
#define CY_PDL_DRV_ID(id) ((uint32_t)((uint32_t)((id) & CY_PDL_MODULE_ID_Msk) << CY_PDL_MODULE_ID_Pos))
#define CY_SYSLIB_ID CY_PDL_DRV_ID(0x11u) /**< SYSLIB PDL ID */
/** \} group_syslib_macro_status_codes */
/**
* \defgroup group_syslib_macro_function_config
* \{
* Function status type codes
*/
#define CY_SYSLIB_CORE_D_CACHE_MAINTENANCE_OFF (0) /**< Disable functions which maintains core cache */
#define CY_SYSLIB_CORE_D_CACHE_MAINTENANCE_ON (1) /**< Enable functions which maintains core cache */
#define CY_SYSLIB_CORE_D_CACHE_MAINTENANCE CY_SYSLIB_CORE_D_CACHE_MAINTENANCE_ON /**< Set CY_SYSLIB_CORE_D_CACHE_MAINTENANCE_OFF or CY_SYSLIB_CORE_D_CACHE_MAINTENANCE_ON */
/** \} group_syslib_macro_function_config */
/** \} group_syslib_macro */
/**
* \addtogroup group_syslib_data_structures
* \{
*/
/** The SysLib status code structure. */
typedef enum
{
CY_SYSLIB_SUCCESS = 0x00UL, /**< Success status code */
CY_SYSLIB_BAD_PARAM = CY_SYSLIB_ID | CY_PDL_STATUS_ERROR | 0x01UL, /**< Bad parameter status code */
CY_SYSLIB_TIMEOUT = CY_SYSLIB_ID | CY_PDL_STATUS_ERROR | 0x02UL, /**< Time out status code */
CY_SYSLIB_INVALID_STATE = CY_SYSLIB_ID | CY_PDL_STATUS_ERROR | 0x03UL, /**< Invalid state status code */
CY_SYSLIB_UNKNOWN = CY_SYSLIB_ID | CY_PDL_STATUS_ERROR | 0xFFUL /**< Unknown status code */
} cy_en_syslib_status_t;
#if (CY_ARM_FAULT_DEBUG == CY_ARM_FAULT_DEBUG_ENABLED)
/** The Fault configuration structure. */
typedef struct
{
uint32_t fault; /**< Indicates if the fault occurred */
uint32_t r0; /**< R0 register content */
uint32_t r1; /**< R1 register content */
uint32_t r2; /**< R2 register content */
uint32_t r3; /**< R3 register content */
uint32_t r12; /**< R12 register content */
uint32_t lr; /**< LR register content */
uint32_t pc; /**< PC register content */
uint32_t psr; /**< PSR register content */
#if (CY_CPU_CORTEX_M4) || (CY_CPU_CORTEX_M7)
uint32_t cfsr; /**< CFSR register content */
uint32_t faultType; /**< FPU or regular fault type */
#if ((defined (__FPU_PRESENT) && (__FPU_PRESENT == 1U)) && \
(defined (__FPU_USED ) && (__FPU_USED == 1U)))
uint32_t s0; /**< FPU S0 register content */
uint32_t s1; /**< FPU S1 register content */
uint32_t s2; /**< FPU S2 register content */
uint32_t s3; /**< FPU S3 register content */
uint32_t s4; /**< FPU S4 register content */
uint32_t s5; /**< FPU S5 register content */
uint32_t s6; /**< FPU S6 register content */
uint32_t s7; /**< FPU S7 register content */
uint32_t s8; /**< FPU S8 register content */
uint32_t s9; /**< FPU S9 register content */
uint32_t s10; /**< FPU S10 register content */
uint32_t s11; /**< FPU S11 register content */
uint32_t s12; /**< FPU S12 register content */
uint32_t s13; /**< FPU S13 register content */
uint32_t s14; /**< FPU S14 register content */
uint32_t s15; /**< FPU S15 register content */
uint32_t fpscr; /**< FPU FPSCR register content */
#endif /* __FPU_PRESENT */
#endif /* CY_CPU_CORTEX_M4 */
} cy_stc_fault_frame_t;
#endif /* (CY_ARM_FAULT_DEBUG == CY_ARM_FAULT_DEBUG_ENABLED) */
/** \} group_syslib_data_structures */
/**
* \addtogroup group_syslib_macro
* \{
*/
/** Driver major version */
#define CY_SYSLIB_DRV_VERSION_MAJOR 1
/** Driver minor version */
#define CY_SYSLIB_DRV_VERSION_MINOR 0
/** \cond INTERNAL */
/** ARM 32-bit Return error / status codes for backward compatibility.
* Do not use them in your code.
*/
#define CY_RET_SUCCESS (0x00u) /* Successful */
#define CY_RET_BAD_PARAM (0x01u) /* One or more invalid parameters */
/** \endcond */
/*******************************************************************************
* Data manipulation defines
*******************************************************************************/
/** Get the lower 8 bits of a 16-bit value. */
#define CY_LO8(x) ((uint8_t) ((x) & 0xFFu))
/** Get the upper 8 bits of a 16-bit value. */
#define CY_HI8(x) ((uint8_t) ((uint16_t)(x) >> 8u))
/** Get the lower 16 bits of a 32-bit value. */
#define CY_LO16(x) ((uint16_t) ((x) & 0xFFFFu))
/** Get the upper 16 bits of a 32-bit value. */
#define CY_HI16(x) ((uint16_t) ((uint32_t)(x) >> 16u))
/** Swap the byte ordering of a 16-bit value */
#define CY_SWAP_ENDIAN16(x) ((uint16_t)(((x) << 8u) | (((x) >> 8u) & 0x00FFu)))
/** Swap the byte ordering of a 32-bit value */
#define CY_SWAP_ENDIAN32(x) ((uint32_t)((((x) >> 24u) & 0x000000FFu) | (((x) & 0x00FF0000u) >> 8u) | \
(((x) & 0x0000FF00u) << 8u) | ((x) << 24u)))
/** Swap the byte ordering of a 64-bit value */
#define CY_SWAP_ENDIAN64(x) ((uint64_t) (((uint64_t) CY_SWAP_ENDIAN32((uint32_t)(x)) << 32u) | \
CY_SWAP_ENDIAN32((uint32_t)((x) >> 32u))))
/*******************************************************************************
* Memory model definitions
*******************************************************************************/
#if defined(__ARMCC_VERSION)
/** To create cross compiler compatible code, use the CY_SECTION, CY_UNUSED, CY_ALIGN
* attributes at the first place of declaration/definition.
* For example: CY_NOINIT uint32_t noinitVar;
*/
#define CY_SECTION(name) __attribute__ ((section(name)))
#define CY_UNUSED __attribute__ ((unused))
/* Specifies the minimum alignment (in bytes) for variables of the specified type. */
#define CY_ALIGN(align) __ALIGNED(align)
#define CY_WEAK __weak
#elif defined (__GNUC__)
#define CY_SECTION(name) __attribute__ ((section(name)))
#define CY_UNUSED __attribute__ ((unused))
#define CY_ALIGN(align) __ALIGNED(align)
#define CY_WEAK __attribute__ ((weak))
#elif defined (__ICCARM__)
#define CY_PRAGMA(x) _Pragma(#x)
#define CY_SECTION(name) CY_PRAGMA(location = name)
#define CY_UNUSED
#define CY_ALIGN(align) CY_PRAGMA(data_alignment = align)
#define CY_WEAK __weak
#elif defined (__ghs__)
#define CY_SECTION(name) __attribute__ ((section(name)))
#define CY_UNUSED __attribute__ ((unused))
#define CY_ALIGN(align) __ALIGNED(align)
#define CY_WEAK __WEAK
#elif defined (__DCC__)
#define CY_SECTION(name) __attribute__ ((section(name)))
#define CY_UNUSED __attribute__ ((unused))
#define CY_ALIGN(align) __ALIGNED(align)
#define CY_WEAK __WEAK
#else
#error "Unsupported toolchain"
#endif /* (__ARMCC_VERSION) */
typedef void (* cy_israddress)(void); /**< Type of ISR callbacks */
/** \cond INTERNAL */
/** Type of ISR callbacks for backward compatibility with the UDB components. Do not use it in your code. */
typedef void (* cyisraddress)(void);
/** \endcond */
#if defined (__ICCARM__)
typedef union { cy_israddress __fun; void * __ptr; } cy_intvec_elem;
/** \cond INTERNAL */
/** Type of ISR callbacks for backward compatibility with the UDB components. Do not use it in your code. */
typedef union { cyisraddress __fun; void * __ptr; } intvec_elem;
/** \endcond */
#endif /* defined (__ICCARM__) */
#if !defined(NDEBUG)
/** Max size of file name which stores the ASSERT location */
#define CY_MAX_FILE_NAME_SIZE (24u)
extern char_t cy_assertFileName[CY_MAX_FILE_NAME_SIZE]; /**< Assert buffer */
extern uint32_t cy_assertLine; /**< Assert line value */
#endif /* NDEBUG */
#if (CY_ARM_FAULT_DEBUG == CY_ARM_FAULT_DEBUG_ENABLED)
#define CY_R0_Pos (0u) /**< Position of R0 content in fault structure */
#define CY_R1_Pos (1u) /**< Position of R1 content in fault structure */
#define CY_R2_Pos (2u) /**< Position of R2 content in fault structure */
#define CY_R3_Pos (3u) /**< Position of R3 content in fault structure */
#define CY_R12_Pos (4u) /**< Position of R12 content in fault structure */
#define CY_LR_Pos (5u) /**< Position of LR content in fault structure */
#define CY_PC_Pos (6u) /**< Position of PC content in fault structure */
#define CY_PSR_Pos (7u) /**< Position of PSR content in fault structure */
#if (CY_CPU_CORTEX_M0P)
#define CY_CM0P_FAULT_TYPE (0xF0F1F2F3u) /**< Flag for indication CM0P core fault */
#else
#if (CY_CPU_CORTEX_M4)
#define CY_CM4_FAULT_TYPE (0xF4F5F6F7u) /**< Flag for indication CM4 core fault */
#elif (CY_CPU_CORTEX_M7)
#define CY_CM7_FAULT_TYPE (0xF7F8F9FAu) /**< Flag for indication CM7 core fault */
#endif
#define CY_NON_FPU_FAULT_TYPE (0xA1A2A3A4u) /**< Flag for indication CM4/7 non floating point fault type */
#if ((defined (__FPU_PRESENT) && (__FPU_PRESENT == 1U)) && \
(defined (__FPU_USED ) && (__FPU_USED == 1U)))
#define CY_FPU_FAULT_TYPE (0xA8A9AAABu) /**< Flag for indication CM4/7 core floating point fault type */
#define CY_FPSCR_IXC_Msk (0x00000010u) /**< Cumulative exception bit for floating-point exceptions */
#define CY_FPSCR_IDC_Msk (0x00000080u) /**< Cumulative exception bit for floating-point exceptions */
#define CY_S0_Pos (8u) /**< Position of FPU S0 content in fault structure */
#define CY_S1_Pos (9u) /**< Position of FPU S1 content in fault structure */
#define CY_S2_Pos (10u) /**< Position of FPU S2 content in fault structure */
#define CY_S3_Pos (11u) /**< Position of FPU S3 content in fault structure */
#define CY_S4_Pos (12u) /**< Position of FPU S4 content in fault structure */
#define CY_S5_Pos (13u) /**< Position of FPU S5 content in fault structure */
#define CY_S6_Pos (14u) /**< Position of FPU S6 content in fault structure */
#define CY_S7_Pos (15u) /**< Position of FPU S7 content in fault structure */
#define CY_S8_Pos (16u) /**< Position of FPU S8 content in fault structure */
#define CY_S9_Pos (17u) /**< Position of FPU S9 content in fault structure */
#define CY_S10_Pos (18u) /**< Position of FPU S10 content in fault structure */
#define CY_S11_Pos (19u) /**< Position of FPU S11 content in fault structure */
#define CY_S12_Pos (20u) /**< Position of FPU S12 content in fault structure */
#define CY_S13_Pos (21u) /**< Position of FPU S13 content in fault structure */
#define CY_S14_Pos (22u) /**< Position of FPU S14 content in fault structure */
#define CY_S15_Pos (23u) /**< Position of FPU S15 content in fault structure */
#define CY_FPSCR_Pos (24u) /**< Position of FPU FPSCR content in fault structure */
#endif /* __FPU_PRESENT */
#endif /* CY_CPU_CORTEX_M0P */
extern cy_stc_fault_frame_t cy_faultFrame; /**< Fault frame structure */
#endif /* (CY_ARM_FAULT_DEBUG == CY_ARM_FAULT_DEBUG_ENABLED) */
/*******************************************************************************
* Macro Name: CY_GET_REG8(addr)
****************************************************************************//**
*
* Reads the 8-bit value from the specified address. This function can't be
* used to access the Core register, otherwise a fault occurs.
*
* \param addr The register address.
*
* \return The read value.
*
*******************************************************************************/
#define CY_GET_REG8(addr) (*((const volatile uint8_t *)(addr)))
/*******************************************************************************
* Macro Name: CY_SET_REG8(addr, value)
****************************************************************************//**
*
* Writes an 8-bit value to the specified address. This function can't be
* used to access the Core register, otherwise a fault occurs.
*
* \param addr The register address.
*
* \param value The value to write.
*
*******************************************************************************/
#define CY_SET_REG8(addr, value) (*((volatile uint8_t *)(addr)) = (uint8_t)(value))
/*******************************************************************************
* Macro Name: CY_GET_REG16(addr)
****************************************************************************//**
*
* Reads the 16-bit value from the specified address.
*
* \param addr The register address.
*
* \return The read value.
*
*******************************************************************************/
#define CY_GET_REG16(addr) (*((const volatile uint16_t *)(addr)))
/*******************************************************************************
* Macro Name: CY_SET_REG16(addr, value)
****************************************************************************//**
*
* Writes the 16-bit value to the specified address.
*
* \param addr The register address.
*
* \param value The value to write.
*
*******************************************************************************/
#define CY_SET_REG16(addr, value) (*((volatile uint16_t *)(addr)) = (uint16_t)(value))
/*******************************************************************************
* Macro Name: CY_GET_REG24(addr)
****************************************************************************//**
*
* Reads the 24-bit value from the specified address.
*
* \param addr The register address.
*
* \return The read value.
*
*******************************************************************************/
#define CY_GET_REG24(addr) (((uint32_t) (*((const volatile uint8_t *)(addr)))) | \
(((uint32_t) (*((const volatile uint8_t *)(addr) + 1))) << 8U) | \
(((uint32_t) (*((const volatile uint8_t *)(addr) + 2))) << 16U))
/*******************************************************************************
* Macro Name: CY_SET_REG24(addr, value)
****************************************************************************//**
*
* Writes the 24-bit value to the specified address.
*
* \param addr The register address.
*
* \param value The value to write.
*
*******************************************************************************/
#define CY_SET_REG24(addr, value) do \
{ \
(*((volatile uint8_t *) (addr))) = (uint8_t)(value); \
(*((volatile uint8_t *) (addr) + 1)) = (uint8_t)((value) >> 8U); \
(*((volatile uint8_t *) (addr) + 2)) = (uint8_t)((value) >> 16U); \
} \
while(0)
/*******************************************************************************
* Macro Name: CY_GET_REG32(addr)
****************************************************************************//**
*
* Reads the 32-bit value from the specified register. The address is the little
* endian order (LSB in lowest address).
*
* \param addr The register address.
*
* \return The read value.
*
*******************************************************************************/
#define CY_GET_REG32(addr) (*((const volatile uint32_t *)(addr)))
/*******************************************************************************
* Macro Name: CY_SET_REG32(addr, value)
****************************************************************************//**
*
* Writes the 32-bit value to the specified register. The address is the little
* endian order (LSB in lowest address).
*
* \param addr The register address.
*
* \param value The value to write.
*
*******************************************************************************/
#define CY_SET_REG32(addr, value) (*((volatile uint32_t *)(addr)) = (uint32_t)(value))
/**
* \defgroup group_syslib_macros_assert Assert Classes and Levels
* \{
* Defines for the Assert Classes and Levels
*/
/**
* Class 1 - The highest class, safety-critical functions which rely on parameters that could be
* changed between different PSoC devices
*/
#define CY_ASSERT_CLASS_1 (1U)
/** Class 2 - Functions that have fixed limits such as counter periods (16-bits/32-bits etc.) */
#define CY_ASSERT_CLASS_2 (2U)
/** Class 3 - Functions that accept enums as constant parameters */
#define CY_ASSERT_CLASS_3 (3U)
#ifndef CY_ASSERT_LEVEL
/** The user-definable assert level from compiler command-line argument (similarly to DEBUG / NDEBUG) */
#define CY_ASSERT_LEVEL CY_ASSERT_CLASS_3
#endif /* CY_ASSERT_LEVEL */
#if (CY_ASSERT_LEVEL == CY_ASSERT_CLASS_1)
#define CY_ASSERT_L1(x) CY_ASSERT(x) /**< Assert Level 1 */
#define CY_ASSERT_L2(x) do{} while(0) /**< Assert Level 2 */
#define CY_ASSERT_L3(x) do{} while(0) /**< Assert Level 3 */
#elif (CY_ASSERT_LEVEL == CY_ASSERT_CLASS_2)
#define CY_ASSERT_L1(x) CY_ASSERT(x) /**< Assert Level 1 */
#define CY_ASSERT_L2(x) CY_ASSERT(x) /**< Assert Level 2 */
#define CY_ASSERT_L3(x) do{} while(0) /**< Assert Level 3 */
#else /* Default is Level 3 */
#define CY_ASSERT_L1(x) CY_ASSERT(x) /**< Assert Level 1 */
#define CY_ASSERT_L2(x) CY_ASSERT(x) /**< Assert Level 2 */
#define CY_ASSERT_L3(x) CY_ASSERT(x) /**< Assert Level 3 */
#endif /* CY_ASSERT_LEVEL == CY_ASSERT_CLASS_1 */
/** \} group_syslib_macros_assert */
/*******************************************************************************
* Macro Name: CY_ASSERT
****************************************************************************//**
*
* The macro that evaluates the expression and, if it is false (evaluates to 0),
* the processor is halted. Cy_Halt() is called when the logical expression is
* false to halt the processor.
* The ASSERT location of the file name (including path to file) and line number
* will be stored in a non-zero init area for debugging. They can be accessed
* by cy_assertFileName and assertLine global variables.
*
* \note This macro is evaluated unless NDEBUG is not defined.
* If NDEBUG is defined, just empty do while cycle is generated for this macro
* for the sake of consistency.
* NDEBUG is defined by default for a Release build setting and not defined for
* a Debug build setting.
*
* \param x The logical expression. Asserts if false.
*
*******************************************************************************/
#if !defined(NDEBUG)
#define CY_ASSERT(x) do \
{ \
if(0u == (uint32_t)(x)) \
{ \
(void) strncpy(cy_assertFileName, __FILE__, CY_MAX_FILE_NAME_SIZE); \
cy_assertFileName[CY_MAX_FILE_NAME_SIZE - 1] = '\0'; \
cy_assertLine = (uint32_t)(__LINE__); \
Cy_SysLib_Halt((uint32_t)0u); \
} \
} \
while(0u)
#else
#define CY_ASSERT(x) do \
{ \
} \
while(0u)
#endif /* !defined(NDEBUG) */
/*******************************************************************************
* Macro Name: _CLR_SET_FLD32U
****************************************************************************//**
*
* The macro for setting a register with a name field and value for providing
* get-clear-modify-write operations.
* Returns a resulting value to be assigned to the register.
*
*******************************************************************************/
#define _CLR_SET_FLD32U(reg, field, value) (((reg) & ((uint32_t)(~(field ## _Msk)))) | (_VAL2FLD(field, value)))
/*******************************************************************************
* Macro Name: CY_REG32_CLR_SET
****************************************************************************//**
*
* The macro for _CLR_SET_FLD32U usage simplification.
*
*******************************************************************************/
#define CY_REG32_CLR_SET(reg, field, value) (reg) = _CLR_SET_FLD32U((reg), field, (value))
/*******************************************************************************
* Macro Name: _CLR_SET_FLD16U
****************************************************************************//**
*
* The macro for setting a 16-bit register with a name field and value for providing
* get-clear-modify-write operations.
* Returns a resulting value to be assigned to the 16-bit register.
*
*******************************************************************************/
#define _CLR_SET_FLD16U(reg, field, value) ((uint16_t)(((reg) & ((uint16_t)(~(field ## _Msk)))) | \
((uint16_t)_VAL2FLD(field, value))))
/*******************************************************************************
* Macro Name: CY_REG16_CLR_SET
****************************************************************************//**
*
* The macro for _CLR_SET_FLD16U usage simplification.
*
*******************************************************************************/
#define CY_REG16_CLR_SET(reg, field, value) (reg) = _CLR_SET_FLD16U((reg), field, (value))
/*******************************************************************************
* Macro Name: _CLR_SET_FLD8U
****************************************************************************//**
*
* The macro for setting a 8-bit register with a name field and value for providing
* get-clear-modify-write operations.
* Returns a resulting value to be assigned to the 8-bit register.
*
*******************************************************************************/
#define _CLR_SET_FLD8U(reg, field, value) ((uint8_t)(((reg) & ((uint8_t)(~(field ## _Msk)))) | \
((uint8_t)_VAL2FLD(field, value))))
/*******************************************************************************
* Macro Name: CY_REG8_CLR_SET
****************************************************************************//**
*
* The macro for _CLR_SET_FLD8U usage simplification.
*
*******************************************************************************/
#define CY_REG8_CLR_SET(reg, field, value) (reg) = _CLR_SET_FLD8U((reg), field, (value))
/*******************************************************************************
* Macro Name: _BOOL2FLD
****************************************************************************//**
*
* Returns a field mask if the value is not false.
* Returns 0, if the value is false.
*
*******************************************************************************/
#define _BOOL2FLD(field, value) (((value) != false) ? (field ## _Msk) : 0UL)
/*******************************************************************************
* Macro Name: _FLD2BOOL
****************************************************************************//**
*
* Returns true, if the value includes the field mask.
* Returns false, if the value doesn't include the field mask.
*
*******************************************************************************/
#define _FLD2BOOL(field, value) (((value) & (field ## _Msk)) != 0UL)
/*******************************************************************************
* Macro Name: CY_MAX
****************************************************************************//**
*
* Returns the larger of both parameters
*
*******************************************************************************/
#define CY_MAX(x,y) ((x) > (y) ? (x) : (y))
/*******************************************************************************
* Macro Name: CY_MIN
****************************************************************************//**
*
* Returns the smaller of both parameters
*
*******************************************************************************/
#define CY_MIN(x,y) ((x) < (y) ? (x) : (y))
/*******************************************************************************
* Macro Name: CY_GET_ARRAY_LEN
****************************************************************************//**
*
* Returns the length of an array
*
*******************************************************************************/
#define CY_GET_ARRAY_LEN(array) (sizeof(array) / sizeof(array[0]))
/*******************************************************************************
* Macro Name: CY_IS_IN_ITCM
****************************************************************************//**
*
* Returns true, if the address is within the SELF_ITCM address space
* Returns false, if the address is outside the SELF_ITCM address space or the
* device does not have an M7 CPUSS
*
*******************************************************************************/
#ifdef CY_IP_M7CPUSS
// Assumes that ITCM size is identical for all CM7
#define CY_IS_IN_ITCM(addr) (((addr) < (0x00000000 + CY_CM7_0_ITCM_SIZE)) ? true : false)
#else
#define CY_IS_IN_ITCM(addr) (false)
#endif
/*******************************************************************************
* Macro Name: CY_IS_IN_DTCM
****************************************************************************//**
*
* Returns true, if the address is within the SELF_DTCM address space
* Returns false, if the address is outside the SELF_DTCM address space or the
* device does not have an M7 CPUSS
*
*******************************************************************************/
#ifdef CY_IP_M7CPUSS
// Assumes that DTCM size is identical for all CM7
#define CY_IS_IN_DTCM(addr) ((((addr) >= 0x20000000) && \
((addr) < (0x20000000 + CY_CM7_0_DTCM_SIZE)) ) ? true : false)
#else
#define CY_IS_IN_DTCM(addr) (false)
#endif
/*******************************************************************************
* Macro Name: CY_IS_IN_TCM
****************************************************************************//**
*
* Returns true, if the address is within the SELF_ITCM or SELF_DTCM address space
* Returns false, if the address is outside the SELF_ITCM and SELF_DTCM address space
* or the device does not have an M7 CPUSS
*
*******************************************************************************/
#define CY_IS_IN_TCM(addr) (CY_IS_IN_DTCM(addr) || CY_IS_IN_ITCM(addr))
/*******************************************************************************
* Macro Name: CY_GET_PUBLIC_ADDR_FROM_TCM
****************************************************************************//**
*
* Returns unchanged address for a device with M4 CPUSS, or if the address is not within the
* SELF_ITCM or SELF_DTCM address space.
* Returns translated address that can be used for access by external masters like DMA, if the address
* is within the SELF_ITCM and SELF_DTCM address space. The translated target address can be controlled
* with the second macro parameter (Master ID)
* Macro should be used when variables/buffers that might potentially be located in a TCM memory
* shall be accessed by other masters, e.g. descriptors for DMA, shared memory for IPC, ...
*
* addr : Address to be translated
* ms_id : Master ID, address will be translated to this master's public DTCM/ITCM address space mirror
* - CPUSS_MS_ID_CM0: Address will be returned unchanged, because CM0+ does not have DTCM/ITCM
* - CPUSS_MS_ID_CM4: Address will be returned unchanged, because CM4 does not have DTCM/ITCM
* - CPUSS_MS_ID_CM7_0: Address will be translated to CM7_0 public ITCM/DTCM if it is
* within SELF_ITCM or SELF_DTCM address space
* - CPUSS_MS_ID_CM7_1: Address will be translated to CM7_1 public ITCM/DTCM if it is
* within SELF_ITCM or SELF_DTCM address space
* Other master IDs are not supported, CPUSS_MS_ID_CM7_1 is only supported if device has an CM7_1!
*
* CPUSS->unIDENTITY.stcField.u4MS can be used to pass the current core's master ID at runtime:
*
* Example 1):
* CY_GET_PUBLIC_ADDR_FROM_TCM(0x20001234, CPUSS->unIDENTITY.stcField.u4MS) would return
* - 0xa0011234 if executed by CM7_0
* - 0xa0111234 if executed by CM7_1
* - 0x20001234 if executed by CM0+ or CM4
*
* Example 2):
* CY_GET_PUBLIC_ADDR_FROM_TCM(0x20001234, CPUSS_MS_ID_CM7_0) would always return
* - 0xa0011234, on a device that has an M7 CPUSS, independent on whether executed by CM0+, CM7_0 or CM7_1
* - 0x20001234 if executed by CM0+ of a device with M4 CPUSS, or by CM4
*
*
*******************************************************************************/
#ifdef CY_IP_M7CPUSS
#if (CPUSS_CM7_1_PRESENT == 1)
#define CY_GET_PUBLIC_ADDR_FROM_TCM(addr,ms_id) ( ((ms_id) == CPUSS_MS_ID_CM0) ? (addr) : \
(CY_IS_IN_DTCM(addr) != false) ? ((addr) - 0x20000000 + (((ms_id) == CPUSS_MS_ID_CM7_0) ? CY_CM7_0_DTCM_BASE : CY_CM7_1_DTCM_BASE)) : \
(CY_IS_IN_ITCM(addr) != false) ? ((addr) - 0x00000000 + (((ms_id) == CPUSS_MS_ID_CM7_0) ? CY_CM7_0_ITCM_BASE : CY_CM7_1_ITCM_BASE)) : \
(addr) )
#else
#define CY_GET_PUBLIC_ADDR_FROM_TCM(addr,ms_id) ( ((ms_id) == CPUSS_MS_ID_CM0) ? (addr) : \
(CY_IS_IN_DTCM(addr) != false) ? ((addr) - 0x20000000 + CY_CM7_0_DTCM_BASE) : \
(CY_IS_IN_ITCM(addr) != false) ? ((addr) - 0x00000000 + CY_CM7_0_ITCM_BASE) : \
(addr) )
#endif
#else
#define CY_GET_PUBLIC_ADDR_FROM_TCM(addr,ms_id) (addr)
#endif
/******************************************************************************
* Constants
*****************************************************************************/
/** Defines a 32-kHz clock delay */
#define CY_DELAY_MS_OVERFLOW (0x8000U)
/*******************************************************************************
* Macro Name: CY_SYSLIB_DIV_ROUND
****************************************************************************//**
*
* Calculates a / b with rounding to the nearest integer,
* a and b must have the same sign.
*
*******************************************************************************/
#define CY_SYSLIB_DIV_ROUND(a, b) (((a) + ((b) / 2U)) / (b))
/*******************************************************************************
* Macro Name: CY_SYSLIB_DIV_ROUNDUP
****************************************************************************//**
*
* Calculates a / b with rounding up if remainder != 0,
* both a and b must be positive.
*
*******************************************************************************/
#define CY_SYSLIB_DIV_ROUNDUP(a, b) ((((a) - 1U) / (b)) + 1U)
/** \} group_syslib_macro */
/******************************************************************************
* Function prototypes
******************************************************************************/
/**
* \addtogroup group_syslib_functions
* \{
*/
void Cy_SysLib_Delay(uint32_t milliseconds);
void Cy_SysLib_DelayUs(uint16_t microseconds);
/** Delays for the specified number of cycles.
* The function is implemented in assembler for each supported compiler.
* \param cycles The number of cycles to delay.
*/
void Cy_SysLib_DelayCycles(uint32_t cycles);
__NO_RETURN void Cy_SysLib_Halt(uint32_t reason);
void Cy_SysLib_ClearFlashCacheAndBuffer(void);
uint64_t Cy_SysLib_GetUniqueId(void);
#if (CY_ARM_FAULT_DEBUG == CY_ARM_FAULT_DEBUG_ENABLED) || defined(CY_DOXYGEN)
void Cy_SysLib_FaultHandler(uint32_t const *faultStackAddr);
CY_WEAK void Cy_SysLib_ProcessingFault(void);
#endif /* (CY_ARM_FAULT_DEBUG == CY_ARM_FAULT_DEBUG_ENABLED) */
void Cy_SysLib_SetWaitStates(uint32_t clkHfMHz);
/*******************************************************************************
* Function Name: Cy_SysLib_EnterCriticalSection
****************************************************************************//**
*
* Cy_SysLib_EnterCriticalSection disables interrupts and returns a value
* indicating whether interrupts were previously enabled.
*
* \note Implementation of Cy_SysLib_EnterCriticalSection manipulates the IRQ
* enable bit with interrupts still enabled.
*
* \return
* Returns the current interrupt status. Returns 0 if interrupts were
* previously enabled or 1 if interrupts were previously disabled.
*
*******************************************************************************/
uint32_t Cy_SysLib_EnterCriticalSection(void);
/*******************************************************************************
* Function Name: Cy_SysLib_ExitCriticalSection
****************************************************************************//**
*
* Re-enables interrupts if they were enabled before
* Cy_SysLib_EnterCriticalSection() was called. The argument should be the value
* returned from \ref Cy_SysLib_EnterCriticalSection().
*
* \param savedIntrStatus
* Puts the saved interrupts status returned by
* the \ref Cy_SysLib_EnterCriticalSection().
*
*******************************************************************************/
void Cy_SysLib_ExitCriticalSection(uint32_t savedIntrStatus);
/*******************************************************************************
* Function Name: Cy_SysLib_InvalidateCoreDCacheByAddr
****************************************************************************//**
*
* Invalidates D-cache in the core for the given address.
* The D-cache memory blocks which are part of given address + given size are invalidated.
*
* \param addr address
* \param dsize size of memory block (in number of bytes)
*
* \note This function works only when called by the core with D-cache (e.g. CM7)
* and CY_SYSLIB_CORE_D_CACHE_MAINTENANCE == CY_SYSLIB_CORE_D_CACHE_MAINTENANCE_ON.
*
*******************************************************************************/
void Cy_SysLib_InvalidateCoreDCacheByAddr(void *addr, int32_t dsize);
/*******************************************************************************
* Function Name: Cy_SysLib_CleanCoreDCacheByAddr
****************************************************************************//**
*
* Cleans D-cache in the core for the given address
* The D-cache memory blocks which are part of given address + given size are cleaned.
*
* \param addr address
* \param dsize size of memory block (in number of bytes)
*
* \note This function works only when called by the core with D-cache (e.g. CM7)
* and CY_SYSLIB_CORE_D_CACHE_MAINTENANCE == CY_SYSLIB_CORE_D_CACHE_MAINTENANCE_ON.
*
*******************************************************************************/
void Cy_SysLib_CleanCoreDCacheByAddr(void *addr, int32_t dsize);
/*******************************************************************************
* Function Name: Cy_SysLib_CleanInvalidateCoreDCacheByAddr
****************************************************************************//**
*
* Cleans and invalidates D-cache in the core for the given address
* The D-cache memory blocks which are part of given address + given size are cleaned
* and invalidated.
*
* \param addr address
* \param dsize size of memory block (in number of bytes)
*
* \note This function works only when called by the core with D-cache (e.g. CM7)
* and CY_SYSLIB_CORE_D_CACHE_MAINTENANCE == CY_SYSLIB_CORE_D_CACHE_MAINTENANCE_ON.
*
*******************************************************************************/
void Cy_SysLib_CleanInvalidateCoreDCacheByAddr(void *addr, int32_t dsize);
/** \} group_syslib_functions */
#if defined(__cplusplus)
}
#endif /* defined(__cplusplus) */
#endif /* _CY_SYSLIB_H_ */
/** \} group_syslib */
/* [] END OF FILE */
@@ -0,0 +1,89 @@
;/***************************************************************************//**
;* \file cy_syslib_diab.s
;* \version 2.0
;*
;* \brief Assembly routines for Windriver DIAB toolchain.
;*
;********************************************************************************
;* \copyright
;* Copyright 2016-2017, Cypress Semiconductor Corporation. All rights reserved.
;* You may use this file only in accordance with the license, terms, conditions,
;* disclaimers, and limitations in the end user license agreement accompanying
;* the software package with which this file was provided.
;*******************************************************************************/
.section ".text",4,c
.global Cy_SysLib_DelayCycles
.global Cy_SysLib_EnterCriticalSection
.global Cy_SysLib_ExitCriticalSection
THUMB
;/*******************************************************************************
;* Function Name: Cy_SysLib_DelayCycles
;****************************************************************************//**
;*
;* Delays for the specified number of cycles.
;*
;* \param uint32_t cycles: The number of cycles to delay.
;*
;*******************************************************************************/
;/* void Cy_SysLib_DelayCycles(uint32_t cycles) */
Cy_SysLib_DelayCycles:
ADDS r0, r0, #2
LSRS r0, r0, #2
BEQ Cy_DelayCycles_done
Cy_DelayCycles_loop:
ADDS r0, r0, #1
SUBS r0, r0, #2
BNE Cy_DelayCycles_loop
NOP
Cy_DelayCycles_done:
BX lr
;/*******************************************************************************
;* Function Name: Cy_SysLib_EnterCriticalSection
;****************************************************************************//**
;*
;* Cy_SysLib_EnterCriticalSection disables interrupts and returns a value
;* indicating whether interrupts were previously enabled.
;*
;* Note Implementation of Cy_SysLib_EnterCriticalSection manipulates the IRQ
;* enable bit with interrupts still enabled. The test and set of the interrupt
;* bits are not atomic. Therefore, to avoid corrupting processor state, it must
;* be the policy that all interrupt routines restore the interrupt enable bits
;* as they were found on entry.
;*
;* \return Returns 0 if interrupts were previously enabled or 1 if interrupts
;* were previously disabled.
;*
;*******************************************************************************/
;/* uint8_t Cy_SysLib_EnterCriticalSection(void) */
Cy_SysLib_EnterCriticalSection:
MRS r0, PRIMASK ; Save and return an interrupt state.
CPSID I ; Disable interrupts.
BX lr
;/*******************************************************************************
;* Function Name: Cy_SysLib_ExitCriticalSection
;****************************************************************************//**
;*
;* Cy_SysLib_ExitCriticalSection re-enables the interrupts if they were enabled
;* before Cy_SysLib_EnterCriticalSection was called. The argument should be the
;* value returned from Cy_SysLib_EnterCriticalSection.
;*
;* \param uint8_t savedIntrStatus:
;* The saved interrupt status returned by the
;* \ref Cy_SysLib_EnterCriticalSection().
;*
;*******************************************************************************/
;/* void Cy_SysLib_ExitCriticalSection(uint8_t savedIntrStatus) */
Cy_SysLib_ExitCriticalSection:
MSR PRIMASK, r0 ; Restore the interrupt state.
BX lr
END
@@ -0,0 +1,103 @@
@/***************************************************************************//**
@* \file cy_syslib_gcc.S
@* \version 2.0
@*
@* \brief Assembly routines for GNU Toolchain.
@*
@********************************************************************************
@* \copyright
@* Copyright 2016-2017, Cypress Semiconductor Corporation. All rights reserved.
@* You may use this file only in accordance with the license, terms, conditions,
@* disclaimers, and limitations in the end user license agreement accompanying
@* the software package with which this file was provided.
@*******************************************************************************/
.syntax unified
.global Cy_SysLib_DelayCycles
.global Cy_SysLib_EnterCriticalSection
.global Cy_SysLib_ExitCriticalSection
.text
.thumb
@/*******************************************************************************
@* Function Name: Cy_SysLib_DelayCycles
@****************************************************************************//**
@*
@* Delays for the specified number of cycles.
@*
@* \param uint32_t cycles: The number of cycles to delay.
@*
@*******************************************************************************/
@/* void Cy_SysLib_DelayCycles(uint32_t cycles) */
.type Cy_SysLib_DelayCycles, %function
Cy_SysLib_DelayCycles:
ADDS r0, r0, #2
LSRS r0, r0, #2
BEQ Cy_DelayCycles_done
Cy_DelayCycles_loop:
ADDS r0, r0, #1
SUBS r0, r0, #2
BNE Cy_DelayCycles_loop
NOP
Cy_DelayCycles_done:
BX lr
.size Cy_SysLib_DelayCycles, .-Cy_SysLib_DelayCycles
@/*******************************************************************************
@* Function Name: Cy_SysLib_EnterCriticalSection
@****************************************************************************//**
@*
@* Cy_SysLib_EnterCriticalSection disables interrupts and returns a value
@* indicating whether interrupts were previously enabled.
@*
@* Note Implementation of Cy_SysLib_EnterCriticalSection manipulates the IRQ
@* enable bit with interrupts still enabled. The test and set of the interrupt
@* bits are not atomic. Therefore, to avoid corrupting processor state, it must
@* be the policy that all interrupt routines restore the interrupt enable bits
@* as they were found on entry.
@*
@* \return Returns 0 if interrupts were previously enabled or 1 if interrupts
@* were previously disabled.
@*
@*******************************************************************************/
@/* uint8_t Cy_SysLib_EnterCriticalSection(void) */
.type Cy_SysLib_EnterCriticalSection, %function
Cy_SysLib_EnterCriticalSection:
MRS r0, PRIMASK @ Save and return an interrupt state.
CPSID I @ Disable interrupts.
BX lr
.size Cy_SysLib_EnterCriticalSection, .-Cy_SysLib_EnterCriticalSection
@/*******************************************************************************
@* Function Name: Cy_SysLib_ExitCriticalSection
@****************************************************************************//**
@*
@* Cy_SysLib_ExitCriticalSection re-enables the interrupts if they were enabled
@* before Cy_SysLib_EnterCriticalSection was called. The argument should be the
@* value returned from Cy_SysLib_EnterCriticalSection.
@*
@* \param uint8_t savedIntrStatus:
@* The saved interrupt status returned by the
@* \ref Cy_SysLib_EnterCriticalSection().
@*
@*******************************************************************************/
@/* void Cy_SysLib_ExitCriticalSection(uint8_t savedIntrStatus) */
.type Cy_SysLib_ExitCriticalSection, %function
Cy_SysLib_ExitCriticalSection:
MSR PRIMASK, r0 @ Restore the interrupt state.
BX lr
.size Cy_SysLib_ExitCriticalSection, .-Cy_SysLib_ExitCriticalSection
.end
@@ -0,0 +1,72 @@
/***************************************************************************//**
* \file cy_syslib_newlib_systemcalls.c
* \version 1.0
*
* Description:
* System Call implementations (mostly stubs) for GCC 'newlib'
*
********************************************************************************
* Copyright 2016-2017, Cypress Semiconductor Corporation. All rights reserved.
* You may use this file only in accordance with the license, terms, conditions,
* disclaimers, and limitations in the end user license agreement accompanying
* the software package with which this file was provided.
*******************************************************************************/
#include <sys/stat.h>
extern int __heap_start; // from linker file
__attribute__((weak)) void *_sbrk(int incr) {
static unsigned char *heap = NULL;
unsigned char *prev_heap;
if (heap == NULL) {
heap = (unsigned char *)&__heap_start;
}
prev_heap = heap;
heap += incr;
return prev_heap;
}
__attribute__((weak)) int _close(int file) {
return -1;
}
__attribute__((weak)) int _fstat(int file, struct stat *st) {
st->st_mode = S_IFCHR;
return 0;
}
__attribute__((weak)) int _isatty(int file) {
return 1;
}
__attribute__((weak)) int _lseek(int file, int ptr, int dir) {
return 0;
}
__attribute__((weak)) void _exit(int status) {
__asm("BKPT #0");
}
__attribute__((weak)) void _kill(int pid, int sig) {
return;
}
__attribute__((weak)) int _getpid(void) {
return -1;
}
__attribute__((weak)) int _write (int file, char * ptr, int len) {
return len;
}
__attribute__((weak)) int _read (int file, char * ptr, int len) {
return 0;
}
/* [] END OF FILE */
@@ -0,0 +1,93 @@
;/***************************************************************************//**
;* \file cy_syslib_ghs.arm
;* \version 2.0
;*
;* \brief Assembly routines for GreenHills.
;*
;********************************************************************************
;* \copyright
;* Copyright 2016-2017, Cypress Semiconductor Corporation. All rights reserved.
;* You may use this file only in accordance with the license, terms, conditions,
;* disclaimers, and limitations in the end user license agreement accompanying
;* the software package with which this file was provided.
;*******************************************************************************/
.export Cy_SysLib_DelayCycles
.export Cy_SysLib_EnterCriticalSection
.export Cy_SysLib_ExitCriticalSection
.text
.thumb
;/*******************************************************************************
;* Function Name: Cy_SysLib_DelayCycles
;****************************************************************************//**
;*
;* Delays for the specified number of cycles.
;*
;* \param uint32_t cycles: The number of cycles to delay.
;*
;*******************************************************************************/
;/* void Cy_SysLib_DelayCycles(uint32_t cycles) */
Cy_SysLib_DelayCycles:
ADDS r0, r0, #2
LSRS r0, r0, #2
BEQ Cy_DelayCycles_done
Cy_DelayCycles_loop:
ADDS r0, r0, #1
SUBS r0, r0, #2
BNE Cy_DelayCycles_loop
NOP
Cy_DelayCycles_done:
BX lr
.endf Cy_SysLib_DelayCycles
;/*******************************************************************************
;* Function Name: Cy_SysLib_EnterCriticalSection
;****************************************************************************//**
;*
;* Cy_SysLib_EnterCriticalSection disables interrupts and returns a value
;* indicating whether interrupts were previously enabled.
;*
;* Note Implementation of Cy_SysLib_EnterCriticalSection manipulates the IRQ
;* enable bit with interrupts still enabled. The test and set of the interrupt
;* bits are not atomic. Therefore, to avoid corrupting processor state, it must
;* be the policy that all interrupt routines restore the interrupt enable bits
;* as they were found on entry.
;*
;* \return Returns 0 if interrupts were previously enabled or 1 if interrupts
;* were previously disabled.
;*
;*******************************************************************************/
;/* uint8_t Cy_SysLib_EnterCriticalSection(void) */
Cy_SysLib_EnterCriticalSection:
MRS r0, PRIMASK ; Save and return an interrupt state.
CPSID I ; Disable interrupts.
BX lr
.endf Cy_SysLib_EnterCriticalSection
;/*******************************************************************************
;* Function Name: Cy_SysLib_ExitCriticalSection
;****************************************************************************//**
;*
;* Cy_SysLib_ExitCriticalSection re-enables the interrupts if they were enabled
;* before Cy_SysLib_EnterCriticalSection was called. The argument should be the
;* value returned from Cy_SysLib_EnterCriticalSection.
;*
;* \param uint8_t savedIntrStatus:
;* The saved interrupt status returned by the
;* \ref Cy_SysLib_EnterCriticalSection().
;*
;*******************************************************************************/
;/* void Cy_SysLib_ExitCriticalSection(uint8_t savedIntrStatus) */
Cy_SysLib_ExitCriticalSection:
MSR PRIMASK, r0 ; Restore the interrupt state.
BX lr
.endf Cy_SysLib_ExitCriticalSection
END
@@ -0,0 +1,89 @@
/***************************************************************************//**
* \file cy_syslib_iar.s
* \version 2.0
*
* \brief Assembly routines for IAR Embedded Workbench IDE.
*
********************************************************************************
* \copyright
* Copyright 2016-2017, Cypress Semiconductor Corporation. All rights reserved.
* You may use this file only in accordance with the license, terms, conditions,
* disclaimers, and limitations in the end user license agreement accompanying
* the software package with which this file was provided.
*******************************************************************************/
SECTION .text:CODE:ROOT(4)
PUBLIC Cy_SysLib_DelayCycles
PUBLIC Cy_SysLib_EnterCriticalSection
PUBLIC Cy_SysLib_ExitCriticalSection
THUMB
/*******************************************************************************
* Function Name: Cy_SysLib_DelayCycles
****************************************************************************//**
*
* Delays for the specified number of cycles.
*
* \param uint32_t cycles: The number of cycles to delay.
*
*******************************************************************************/
/* void Cy_SysLib_DelayCycles(uint32_t cycles) */
Cy_SysLib_DelayCycles:
ADDS r0, r0, #2
LSRS r0, r0, #2
BEQ Cy_DelayCycles_done
Cy_DelayCycles_loop:
ADDS r0, r0, #1
SUBS r0, r0, #2
BNE Cy_DelayCycles_loop
NOP
Cy_DelayCycles_done:
BX lr
/*******************************************************************************
* Function Name: Cy_SysLib_EnterCriticalSection
****************************************************************************//**
*
* Cy_SysLib_EnterCriticalSection disables interrupts and returns a value
* indicating whether interrupts were previously enabled.
*
* Note Implementation of Cy_SysLib_EnterCriticalSection manipulates the IRQ
* enable bit with interrupts still enabled. The test and set of the interrupt
* bits are not atomic. Therefore, to avoid corrupting processor state, it must
* be the policy that all interrupt routines restore the interrupt enable bits
* as they were found on entry.
*
* \return Returns 0 if interrupts were previously enabled or 1 if interrupts
* were previously disabled.
*
*******************************************************************************/
/* uint8_t Cy_SysLib_EnterCriticalSection(void) */
Cy_SysLib_EnterCriticalSection:
MRS r0, PRIMASK ; Save and return an interrupt state.
CPSID I ; Disable interrupts.
BX lr
/*******************************************************************************
* Function Name: Cy_SysLib_ExitCriticalSection
****************************************************************************//**
*
* Cy_SysLib_ExitCriticalSection re-enables the interrupts if they were enabled
* before Cy_SysLib_EnterCriticalSection was called. The argument should be the
* value returned from Cy_SysLib_EnterCriticalSection.
*
* \param uint8_t savedIntrStatus:
* The saved interrupt status returned by the
* \ref Cy_SysLib_EnterCriticalSection().
*
*******************************************************************************/
/* void Cy_SysLib_ExitCriticalSection(uint8_t savedIntrStatus) */
Cy_SysLib_ExitCriticalSection:
MSR PRIMASK, r0 ; Restore the interrupt state.
BX lr
END
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,159 @@
/***************************************************************************//**
* \file cy_sysreset.c
* \version 1.0
*
* Description:
* Provides an API definition of the sysreset driver
*
********************************************************************************
* Copyright 2016-2017, Cypress Semiconductor Corporation. All rights reserved.
* You may use this file only in accordance with the license, terms, conditions,
* disclaimers, and limitations in the end user license agreement accompanying
* the software package with which this file was provided.
*******************************************************************************/
#include "cy_sysreset.h"
#include "ipc/cy_ipc_drv.h"
/*******************************************************************************
* Function Name: Cy_SysReset_GetResetReason
****************************************************************************//**
*
* The function returns the cause for the latest consolidated reset(s) that occurred in
* the system. The reset causes include HFCLK error, system faults, and device
* reset on a wakeup from Hibernate mode.
*
* \param None
*
* \return 32-bit Contents of RES_CAUSE register
* | Name | Value
* |------------------------------------|--------------------
* | CY_SYSRESET_WDT | 0x00000001 (bit0)
* | CY_SYSRESET_ACT_FAULT | 0x00000002 (bit1)
* | CY_SYSRESET_DPSLP_FAULT | 0x00000004 (bit2)
* | CY_SYSRESET_TC_DBGRESET | 0x00000008 (bit3)
* | CY_SYSRESET_SOFT | 0x00000010 (bit4)
* | CY_SYSRESET_MCWDT0 | 0x00000020 (bit5)
* | CY_SYSRESET_MCWDT1 | 0x00000040 (bit6)
* | CY_SYSRESET_MCWDT2 | 0x00000080 (bit7)
* | CY_SYSRESET_MCWDT3 | 0x00000100 (bit8)
* | CY_SYSRESET_XRES | 0x00010000 (bit16)
* | CY_SYSRESET_BODVDDD | 0x00020000 (bit17)
* | CY_SYSRESET_BODVDDA | 0x00040000 (bit18)
* | CY_SYSRESET_BODVCCD | 0x00080000 (bit19)
* | CY_SYSRESET_OVDVDDD | 0x00100000 (bit20)
* | CY_SYSRESET_OVDVDDA | 0x00200000 (bit21)
* | CY_SYSRESET_OVDVCCD | 0x00400000 (bit22)
* | CY_SYSRESET_OCD_ACT_LINREG | 0x00800000 (bit23)
* | CY_SYSRESET_OCD_DPSLP_LINREG | 0x01000000 (bit24)
* | CY_SYSRESET_OCD_REGHC | 0x02000000 (bit25)
* | CY_SYSRESET_PMIC | 0x04000000 (bit26)
* | CY_SYSRESET_PXRES | 0x08000000 (bit27)
* | CY_SYSRESET_STRUCT_XRES | 0x20000000 (bit29)
* | CY_SYSRESET_PORVDDD | 0x40000000 (bit30)
*
*******************************************************************************/
uint32_t Cy_SysReset_GetResetReason(void)
{
return(SRSS->unRES_CAUSE.u32Register);
}
/*******************************************************************************
* Function Name: Cy_SysReset_GetNumHfclkResetCause
****************************************************************************//**
*
* This function returns the number of HF_CLK which is a reset cause (RES_CAUSE2)
* by a loss or an error of the high frequency clock.
*
* The Clock supervisors (CSV) can make a reset as CSV_FREQ_ACTION setting
* when a CSV frequency anomaly is detected. The function returns the index
* of HF_CLK, if a reset occurred due to an anomaly HF_CLK. There are two
* different options for monitoring on HF_CLK which are a frequency loss
* and a frequency error.
*
* \return
* - The number HF_CLK from Clock Supervisor High Frequency Loss: Bits[15:0]
* - The number HF_CLK from Clock Supervisor High Frequency error: Bits[31:16]
*
*******************************************************************************/
uint32_t Cy_SysReset_GetNumHfclkResetCause(void)
{
return (SRSS->unRES_CAUSE2.u32Register);
}
/*******************************************************************************
* Function Name: Cy_SysReset_IsResetDueToHibWakeup
****************************************************************************//**
*
* This function returns reset state if it is due to hibernate wakeup.
*
* \return
* true - Reset cause is due to hibernate wakeup
* false - Reset cause is not due to hibernate wakeup
*
*******************************************************************************/
bool Cy_SysReset_IsResetDueToHibWakeup(void)
{
bool retReason = false;
// Contains a 8-bit token that is retained through a HIBERNATE/WAKEUP sequence
// that can be used by firmware to differentiate WAKEUP from a general RESET event
// Value 0x1B into the TOKEN is added before jumping to HIBERNATE
if(0x1Bu == SRSS->unPWR_HIBERNATE.stcField.u8TOKEN)
{
retReason = true;
}
return retReason;
}
/*******************************************************************************
* Function Name: Cy_SysReset_ClearAllResetReasons
****************************************************************************//**
*
* This function clears the values of RES_CAUSE and RES_CAUSE2.
*
*******************************************************************************/
void Cy_SysReset_ClearAllResetReasons(void)
{
/* RES_CAUSE and RES_CAUSE2 register's bits are RW1C (every bit is cleared upon writing 1),
* so write all ones to clear all the reset reasons.
*/
SRSS->unRES_CAUSE.u32Register = 0xFFFFFFFFu;
SRSS->unRES_CAUSE2.u32Register = 0xFFFFFFFFu;
SRSS->unPWR_HIBERNATE.u32Register = 0u;
}
#if (CY_CPU_CORTEX_M0P) || defined(CY_DOXYGEN)
/*******************************************************************************
* Function Name: Cy_SysReset_SoftResetCM4
****************************************************************************//**
*
* This function performs a CM4 Core software reset using the CM4_PWR_CTL
* register.
*
* \note This function should be called only when the CM4 core is in Deep
* Sleep mode.
* \note This function will not reset CM0+ Core.
*
*******************************************************************************/
void Cy_SysReset_SoftResetCM4(void)
{
volatile uint32_t msg = CY_IPC_DATA_FOR_CM4_SOFT_RESET;
/* Tries to acquire the IPC structure and pass the arguments to SROM API.
* SROM API parameters:
* ipcPtr: IPC_STRUCT0 - IPC Structure 0 reserved for M0+ Secure Access.
* notifyEvent_Intr: 1u - IPC Interrupt Structure 1 is used for Releasing IPC 0 (M0+ NMI Handler).
* msgPtr: &msg - The address of SRAM with the API's parameters.
*/
if(CY_IPC_DRV_SUCCESS != Cy_IPC_Drv_SendMsgPtr(IPC_STRUCT0, 1u, (void *) &msg))
{
CY_ASSERT(0u != 0u);
}
}
#endif /* CY_CPU_CORTEX_M0P || defined(CY_DOXYGEN) */
/* [] END OF FILE */
@@ -0,0 +1,192 @@
/***************************************************************************//**
* \file cy_sysreset.h
* \version 1.0
*
* Provides an API declaration of the sysreset driver.
*
********************************************************************************
* \copyright
* Copyright 2016-2017, Cypress Semiconductor Corporation. All rights reserved.
* You may use this file only in accordance with the license, terms, conditions,
* disclaimers, and limitations in the end user license agreement accompanying
* the software package with which this file was provided.
*******************************************************************************/
/**
* \defgroup group_sysreset System RESET (SysReset)
* \{
* The system reset provide APIs that can be called in the user application
* to handle the system resets.
*
* sysreset driver contains a set of reset related system functions. These functions
* can be called in the application routine. Some features of the system reset:
* * Software reset
* * Reading a reset cause
*
* \section group_sysreset_configuration Configuration Considerations
* There are no general sysreset configuration concerns.
*
* \section group_sysreset_more_information More Information
* Refer to the technical reference manual (TRM).
*
* \section group_sysreset_changelog Changelog
* <table class="doxtable">
* <tr><th>Version</th><th>Changes</th><th>Reason for Change</th></tr>
* <tr>
* <td>1.0</td>
* <td>Initial version</td>
* <td></td>
* </tr>
* </table>
*
* \defgroup group_sysreset_macro Macro
* \defgroup group_sysreset_functions Functions
* \defgroup group_sysreset_data_structures Data Structures
*
*/
#if !defined(_CY_SYSRESET_H_)
#define _CY_SYSRESET_H_
#if !defined(NDEBUG)
#include <string.h>
#endif /* NDEBUG */
#include <stdint.h>
#include <stdbool.h>
#include "cy_device_headers.h"
#include "syslib/cy_syslib.h"
#if defined(__cplusplus)
extern "C" {
#endif /* defined(__cplusplus) */
/**
* \addtogroup group_sysreset_macro
* \{
*/
/******************************************************************************
* Macros
*****************************************************************************/
/** \} group_sysreset_macro */
/**
* \addtogroup group_sysreset_data_structures
* \{
*/
/** \} group_sysreset_data_structures */
/**
* \addtogroup group_sysreset_macro
* \{
*/
/******************************************************************************
* Constants
*****************************************************************************/
/**
* \defgroup group_sysreset_macro_reset_cause Reset cause
* \{
* Define RESET_CAUSE mask values
*/
/** A basic WatchDog Timer (WDT) reset has occurred since the last power cycle. */
#define CY_SYSRESET_WDT (0x00000001u)
/** The fault logging system requested a reset from its Active logic. */
#define CY_SYSRESET_ACT_FAULT (0x00000002u)
/** The fault logging system requested a reset from its DeepSleep logic. */
#define CY_SYSRESET_DPSLP_FAULT (0x00000004u)
/** Test controller or debugger asserted reset. */
#define CY_SYSRESET_TC_DBGRESET (0x00000008u)
/** The CPU requested a system reset through it's SYSRESETREQ. This can be done via a debugger probe or in firmware. */
#define CY_SYSRESET_SOFT (0x00000010u)
/** The Multi-Counter Watchdog timer #0 reset has occurred since last power cycle. */
#define CY_SYSRESET_MCWDT0 (0x00000020u)
/** The Multi-Counter Watchdog timer #1 reset has occurred since last power cycle. */
#define CY_SYSRESET_MCWDT1 (0x00000040u)
/** The Multi-Counter Watchdog timer #2 reset has occurred since last power cycle. */
#define CY_SYSRESET_MCWDT2 (0x00000080u)
/** The Multi-Counter Watchdog timer #3 reset has occurred since last power cycle. */
#define CY_SYSRESET_MCWDT3 (0x00000100u)
/** External XRES pin assertion. */
#define CY_SYSRESET_XRES (0x00010000u)
/** Reset due to external VDDD supply crossing brown-out limit. */
#define CY_SYSRESET_BODVDDD (0x00020000u)
/** Reset due to external VDDA supply crossed the brown-out limit. */
#define CY_SYSRESET_BODVDDA (0x00040000u)
/** Reset due to internal VCCD core supply crossed the brown-out limit. */
#define CY_SYSRESET_BODVCCD (0x00080000u)
/** Reset due to over voltage detection on the external VDDD supply. */
#define CY_SYSRESET_OVDVDDD (0x00100000u)
/** Reset due to over voltage detection on the external VDDA supply.. */
#define CY_SYSRESET_OVDVDDA (0x00200000u)
/** Reset due to over voltage detection on the internal core VCCD supply. */
#define CY_SYSRESET_OVDVCCD (0x00400000u)
/** Reset due to over current detection on the internal VCCD supply when supplied by the ACTIVE power mode linear regulator. */
#define CY_SYSRESET_OCD_ACT_LINREG (0x00800000u)
/** Reset due to over current detection on the internal VCCD supply when supplied by the DEEPSLEEP power mode linear regulator. */
#define CY_SYSRESET_OCD_DPSLP_LINREG (0x01000000u)
/** Reset due to over current detection from REGHC (if present). */
#define CY_SYSRESET_OCD_REGHC (0x02000000u)
/** PMIC status triggered a reset. */
#define CY_SYSRESET_PMIC (0x04000000u)
/** Programmable XRES triggered. */
#define CY_SYSRESET_PXRES (0x08000000u)
/** Structural reset was asserted. */
#define CY_SYSRESET_STRUCT_XRES (0x20000000u)
/** Indicator that a POR occurred. */
#define CY_SYSRESET_PORVDDD (0x40000000u)
/** Violation of a high-frequency clock has occurred since last power cycle. */
#define CY_SYSRESET_CSV_HF (0x00000200u)
/** Violation of a reference clock has occurred since last power cycle. */
#define CY_SYSRESET_CSV_REF (0x00000400u)
/** The reset has occurred on wakeup from a Hibernate power mode. */
#define CY_SYSRESET_HIB_WAKEUP (0x80000000u)
/** \} group_sysreset_macro_reset_cause */
/** Bit[31:24] Opcode = 0x1B (SoftReset)
* Bit[7:1] Type = 1 (Only CM4 reset)
*/
#define CY_IPC_DATA_FOR_CM4_SOFT_RESET (0x1B000002UL)
/** \} group_sysreset_macro */
/******************************************************************************
* Function prototypes
******************************************************************************/
/**
* \addtogroup group_sysreset_functions
* \{
*/
uint32_t Cy_SysReset_GetResetReason(void);
uint32_t Cy_SysReset_GetNumHfclkResetCause(void);
bool Cy_SysReset_IsResetDueToHibWakeup(void);
void Cy_SysReset_ClearAllResetReasons(void);
#if (CY_CPU_CORTEX_M0P)
void Cy_SysReset_SoftResetCM4(void);
#endif /* CY_CPU_CORTEX_M0P */
/** \} group_sysreset_functions */
#if defined(__cplusplus)
}
#endif /* defined(__cplusplus) */
#endif /* _CY_SYSRESET_H_ */
/** \} group_sysreset */
/* [] END OF FILE */
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,463 @@
/***************************************************************************//**
* \file cy_systick.c
* \version 1.0
*
* Provides the API definitions of the SisTick driver.
*
********************************************************************************
* \copyright
* Copyright 2016, Cypress Semiconductor Corporation. All rights reserved.
* You may use this file only in accordance with the license, terms, conditions,
* disclaimers, and limitations in the end user license agreement accompanying
* the software package with which this file was provided.
*******************************************************************************/
#include <stdint.h>
#include <stdbool.h>
#include "systick/cy_systick.h"
#include "syslib/cy_syslib.h"
#include "cy_device_headers.h"
static Cy_SysTick_Callback Cy_SysTick_Callbacks[CY_SYS_SYST_NUM_OF_CALLBACKS];
static void Cy_SysTick_ServiceCallbacks(void);
/*******************************************************************************
* Function Name: Cy_SysTick_Init
****************************************************************************//**
*
* \brief Initializes the callback addresses with pointers to NULL, associates the
* SysTick system vector with the function responsible for calling
* registered callback functions, configures the SysTick timer to generate an
* interrupt periodically.
*
* \param clockSource : The SysTick clock source \ref en_systick_clock_source_t
* \param interval : The SysTick reload value.
*
* \return None
*
* \note Clears the SysTick count flag if it was set.
*
*******************************************************************************/
void Cy_SysTick_Init(cy_en_systick_clock_source_t clockSource, uint32_t interval)
{
uint32_t i;
for (i = 0u; i<CY_SYS_SYST_NUM_OF_CALLBACKS; i++)
{
Cy_SysTick_Callbacks[i] = NULL;
}
__ramVectors[CY_SYSTICK_IRQ_NUM] = &Cy_SysTick_ServiceCallbacks;
#if CY_CPU_CORTEX_M7
// Ensure that above change in the vector table is cleaned from Data Cache, and Instruction Cache is invalidated
SCB_CleanDCache_by_Addr((uint32_t*)&__ramVectors[CY_SYSTICK_IRQ_NUM], 4);
SCB_InvalidateICache();
#endif
Cy_SysTick_SetClockSource(clockSource);
Cy_SysTick_SetReload(interval);
Cy_SysTick_Clear();
Cy_SysTick_Enable();
}
/*******************************************************************************
* Function Name: Cy_SysTick_Enable
****************************************************************************//**
*
* \brief Enables the SysTick timer and its interrupt.
*
* \param None
*
* \return None
*
* \note Clears the SysTick count flag if it was set
*
*******************************************************************************/
void Cy_SysTick_Enable(void)
{
Cy_SysTick_EnableInterrupt();
SysTick->CTRL |= SysTick_CTRL_ENABLE_Msk;
}
/*******************************************************************************
* Function Name: Cy_SysTick_Disable
****************************************************************************//**
*
* \brief Disables the SysTick timer and its interrupt.
*
* \param None
*
* \return None
*
* \note Clears the SysTick count flag if it was set
*
*******************************************************************************/
void Cy_SysTick_Disable(void)
{
Cy_SysTick_DisableInterrupt();
SysTick->CTRL &= ~SysTick_CTRL_ENABLE_Msk;
}
/*******************************************************************************
* Function Name: Cy_SysTick_EnableInterrupt
****************************************************************************//**
*
* \brief Enables the SysTick interrupt.
*
* \param None
*
* \return None
*
* \note Clears the SysTick count flag if it was set
*
*******************************************************************************/
void Cy_SysTick_EnableInterrupt(void)
{
SysTick->CTRL = SysTick->CTRL | SysTick_CTRL_TICKINT_Msk;
}
/*******************************************************************************
* Function Name: Cy_SysTick_DisableInterrupt
****************************************************************************//**
*
* \brief Cy_Disables the SysTick interrupt.
*
* \param None
*
* \return None
*
* \note Cy_Clears the SysTick count flag if it was set
*
*******************************************************************************/
void Cy_SysTick_DisableInterrupt(void)
{
SysTick->CTRL = SysTick->CTRL & ~SysTick_CTRL_TICKINT_Msk;
}
/*******************************************************************************
* Function Name: Cy_SysTick_SetReload
****************************************************************************//**
*
* \brief Sets the value the counter is set to on a startup and after it reaches zero.
* This function does not change or reset the current sysTick counter value, so
* it should be cleared using the SysTick_Clear() API.
*
* \param value: The valid range is [0x0-0x00FFFFFF]. The counter reset value.
*
*
* \return None
*******************************************************************************/
void Cy_SysTick_SetReload(uint32_t value)
{
SysTick->LOAD = (value & SysTick_LOAD_RELOAD_Msk);
}
/*******************************************************************************
* Function Name: Cy_SysTick_Set10msClockCycles
****************************************************************************//**
*
* \brief Sets the value that Specifies the number of clock source cycles
* (minus 1) that make up 10 ms for the selected clock source.
* It is SW's responsibility to provide the correct value to get 10 ms
* timeout for the selected clock source.
*
* \param value: The valid range is [0x0-0x00FFFFFF].
*
*
* \return None
*******************************************************************************/
void Cy_SysTick_Set10msCalibration(uint32_t value)
{
CPUSS->unSYSTICK_CTL.stcField.u24TENMS = (value-1);
}
/*******************************************************************************
* Function Name: Cy_SysTick_Get10msClockCycles
****************************************************************************//**
*
* \brief Sets the value that Specifies the number of clock source cycles
* (plus 1) that make up 10 ms for the selected clock source.
*
* \param None
*
* \return The clock source cycles to make up 10ms value.
*
*******************************************************************************/
uint32_t Cy_SysTick_Get10msCalibration(void)
{
// return (CPUSS->unSYSTICK_CTL.stcField.u24TENMS + 1);
return ((SysTick->CALIB & SysTick_CALIB_TENMS_Msk) + 1);
}
/*******************************************************************************
* Function Name: Cy_SysTick_GetReload
****************************************************************************//**
*
* \brief Gets the value the counter is set to on a startup and after it reaches zero.
*
* \param None
*
* \return The counter reset value.
*
*******************************************************************************/
uint32_t Cy_SysTick_GetReload(void)
{
return (SysTick->LOAD);
}
/*******************************************************************************
* Function Name: Cy_SysTick_GetValue
****************************************************************************//**
*
* \brief Gets the current SysTick counter value.
*
* \param None
*
* \return The current SysTick counter value.
*
*******************************************************************************/
uint32_t Cy_SysTick_GetValue(void)
{
return (SysTick->VAL);
}
/*******************************************************************************
* Function Name: Cy_SysTick_SetCallback
****************************************************************************//**
*
* \brief This function allows up to five user-defined interrupt service routine
* functions to be associated with the SysTick interrupt. These are specified
* through the use of pointers to the function.
*
* \param number : The number of the callback function addresses to be set.
* The valid range is from 0 to 4.
*
* \param function: The pointer to the function that will be associated with the
* SysTick ISR for the specified number.
*
* \return Returns the address of the previous callback function.
* The NULL is returned if the specified address in not set.
*
* \note The registered callback functions will be executed in the interrupt.
*
*******************************************************************************/
Cy_SysTick_Callback Cy_SysTick_SetCallback(uint32_t number, Cy_SysTick_Callback function)
{
Cy_SysTick_Callback retVal;
CY_ASSERT(number < CY_SYS_SYST_NUM_OF_CALLBACKS);
retVal = Cy_SysTick_Callbacks[number];
Cy_SysTick_Callbacks[number] = function;
return (retVal);
}
/*******************************************************************************
* Function Name: Cy_SysTick_GetCallback
****************************************************************************//**
*
* \brief The function gets the specified callback pointer.
*
* \param number : The number of the callback function address to get. The valid
* range is from 0 to 4.
*
* \return Returns the address of the specified callback function.
* The NULL is returned if the specified address in not initialized.
*
*******************************************************************************/
Cy_SysTick_Callback Cy_SysTick_GetCallback(uint32_t number)
{
return ((Cy_SysTick_Callback) Cy_SysTick_Callbacks[number]);
}
/*******************************************************************************
* Function Name: Cy_SysTick_SetClockSource
****************************************************************************//**
*
* \brief Sets the clock source for the SysTick counter.
*
* Clears the SysTick count flag if it was set. If the clock source is not ready
* this function call will have no effect. After changing the clock source to the
* low frequency clock, the counter and reload register values will remain
* unchanged so the time to the interrupt will be significantly longer and vice
* versa.
*
* Changing the SysTick clock source and/or its frequency will change
* the interrupt interval and that SysTick_SetReload() should be
* called to compensate this change.
*
* \param clockSource : \ref en_systick_clock_source_t Clock source.
*
*******************************************************************************/
void Cy_SysTick_SetClockSource(cy_en_systick_clock_source_t clockSource)
{
if (clockSource == CY_SYSTICK_CLOCK_SOURCE_CLK_CPU)
{
SysTick->CTRL |= SysTick_CTRL_CLKSOURCE_Msk;
CPUSS->unSYSTICK_CTL.stcField.u1NOREF = 1;
}
else
{
CPUSS->unSYSTICK_CTL.stcField.u2CLOCK_SOURCE = (uint32_t) clockSource;
CPUSS->unSYSTICK_CTL.stcField.u1NOREF = 0;
SysTick->CTRL &= ~SysTick_CTRL_CLKSOURCE_Msk;
}
}
/*******************************************************************************
* Function Name: Cy_SysTick_GetClockSource
****************************************************************************//**
*
* \brief Gets the clock source for the SysTick counter.
*
* \param None
*
* \returns \ref en_systick_clock_source_t Clock source
*
*******************************************************************************/
cy_en_systick_clock_source_t Cy_SysTick_GetClockSource(void)
{
cy_en_systick_clock_source_t returnValue;
if ((SysTick->CTRL & SysTick_CTRL_CLKSOURCE_Msk) != 0u)
{
returnValue = CY_SYSTICK_CLOCK_SOURCE_CLK_CPU;
}
else
{
returnValue = (cy_en_systick_clock_source_t)CPUSS->unSYSTICK_CTL.stcField.u2CLOCK_SOURCE;
}
return(returnValue);
}
/*******************************************************************************
* Function Name: Cy_SysTick_GetCountFlag
****************************************************************************//**
*
* \brief The count flag is set, once the SysTick counter reaches zero.
* The flag is cleared on read.
*
* \param None
*
* \return Returns a non-zero value if a flag is set, otherwise a zero is
* returned.
*
* \note Clears the SysTick count flag if it was set.
*
*******************************************************************************/
uint32_t Cy_SysTick_GetCountFlag(void)
{
return (SysTick->CTRL & SysTick_CTRL_COUNTFLAG_Msk);
}
/*******************************************************************************
* Function Name: Cy_SysTick_Clear
****************************************************************************//**
*
* \brief Clears the SysTick counter for a well-defined startup.
*
* \param None
*
* \return None
*
*******************************************************************************/
void Cy_SysTick_Clear(void)
{
SysTick->VAL = 0u;
}
/*******************************************************************************
* Function Name: Cy_SysTick_ServiceCallbacks
****************************************************************************//**
*
* The system Tick timer interrupt routine.
*
*******************************************************************************/
static void Cy_SysTick_ServiceCallbacks(void)
{
uint32_t i;
/* Verify that tick timer flag was set */
if (0u != Cy_SysTick_GetCountFlag())
{
for (i=0u; i < CY_SYS_SYST_NUM_OF_CALLBACKS; i++)
{
if (Cy_SysTick_Callbacks[i] != NULL)
{
(void)(Cy_SysTick_Callbacks[i])();
}
}
}
}
/*******************************************************************************
* Function Name: Cy_SysTick_DelayCoreCycle
****************************************************************************//**
*
* Delay input core cycle. This function can be input whole uint32_t value, while
* DELAY_CORE_CYCLE macro can be input only 24bit value.
* Note: This function is not re-entrant hand in glove with Cy_SysTick_DelayInUs.
*
* \param cycle core cycle to be delayed.
*
*******************************************************************************/
void Cy_SysTick_DelayCoreCycle(uint64_t cycle)
{
static bool isThisBeingCalled = false;
CY_ASSERT(isThisBeingCalled == false);
(void) isThisBeingCalled; // avoid "unused" compiler warning if NDEBUG is set
isThisBeingCalled = true;
uint64_t cycleRest = cycle;
uint32_t cyclePart;
do
{
if(cycleRest > SysTick_LOAD_RELOAD_Msk)
{
cyclePart = SysTick_LOAD_RELOAD_Msk;
cycleRest -= SysTick_LOAD_RELOAD_Msk;
}
else
{
cyclePart = (uint32_t)cycleRest;
cycleRest = 0ul;
}
SysTick->CTRL = 0;
SysTick->LOAD = cyclePart;
SysTick->VAL = 0;
SysTick->CTRL = (SysTick_CTRL_CLKSOURCE_Msk | SysTick_CTRL_ENABLE_Msk);
while((SysTick->CTRL & SysTick_CTRL_COUNTFLAG_Msk) == 0);
SysTick->CTRL = 0;
} while(cycleRest != 0);
isThisBeingCalled = false;
}
/*******************************************************************************
* Function Name: Cy_SysTick_DelayInUs
****************************************************************************//**
*
* Delay input value in micro second.
* Note: This function is not re-entrant hand in glove with Cy_SysTick_DelayCoreCycle.
* Note: Before calling this function SystemInit() have to be called.
*
* \param us micro second value to be delayed
*
*******************************************************************************/
void Cy_SysTick_DelayInUs(uint32_t us)
{
CY_ASSERT(SystemCoreClock != 0); // System not initialized
uint64_t cycle = SystemCoreClock / 1000000ull * us;
Cy_SysTick_DelayCoreCycle(cycle);
}
/* [] END OF FILE */
@@ -0,0 +1,446 @@
/***************************************************************************//**
* \file gpio.h
* \version `$CY_MAJOR_VERSION`.`$CY_MINOR_VERSION`
* \platform Microcontroller family or derivative or all platforms
* \brief Provides an API declaration of the GPIO driver
* \description The GPIO driver provides an API to configure and access device
* Input/Output pins. IO pins include all general purpose types
* such as GPIO, SIO, HSIO, AUXIO, and their variants.
* Once the pin/port initialization is complete, each pin can be
* accessed by specifying the port (GPIO_PRT_Type) and the pin
* (0-7) in the provided API functions.
*
*******************************************************************************/
/*******************************************************************************
* Copyright 2017, Cypress Semiconductor Corporation. All Rights Reserved.
********************************************************************************
* This software is owned by Cypress Semiconductor Corporation (Cypress)
* and is protected by and subject to worldwide patent protection (United
* States and foreign), United States copyright laws and international treaty
* provisions. Cypress hereby grants to licensee a personal, non-exclusive,
* non-transferable license to copy, use, modify, create derivative works of,
* and compile the Cypress Source Code and derivative works for the sole
* purpose of creating custom software in support of licensee product to be
* used only in conjunction with a Cypress integrated circuit as specified in
* the applicable agreement. Any reproduction, modification, translation,
* compilation, or representation of this software except as specified above
* is prohibited without the express written permission of Cypress.
*
* Disclaimer: CYPRESS MAKES NO WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, WITH
* REGARD TO THIS MATERIAL, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
* Cypress reserves the right to make changes without further notice to the
* materials described herein. Cypress does not assume any liability arising out
* of the application or use of any product or circuit described herein. Cypress
* does not authorize its products for use as critical components in life-support
* systems where a malfunction or failure may reasonably be expected to result in
* significant injury to the user. The inclusion of Cypress' product in a life-
* support systems application implies that the manufacturer assumes all risk of
* such use and in doing so indemnifies Cypress against all charges.
*
* Use of this Software may be limited by and subject to the applicable Cypress
* software license agreement.
*******************************************************************************/
/******************************************************************************/
/* Version History: */
/******************************************************************************/
/* $Log:$ */
#ifndef _CY_SYSTICK_H_
#define _CY_SYSTICK_H_
/**
* \defgroup group_systick Core System Tick Timer (SysTick)
* \{
* Provides SysTick APIs.
*
* \section group_systick_configuration Configuration Considerations
*
* The SysTick timer is part of the CPU. The timer is a down counter with a
* 24-bit reload/tick value that is clocked by the FastClk/SlowClk. The timer has
* the capability to generate an interrupt when the set number of ticks expires
* and the counter is reloaded. This interrupt is available as part of the Nested
* Vectored Interrupt Controller (NVIC) for service by the CPU and can be used
* for general purpose timing control in user code.
*
* Changing the SysTick clock source and/or its frequency will change the
* interrupt interval and therefore SysTick_SetReload() should be called to
* compensate for this change.
*
* Because the timer is independent of the CPU (except for the clock), this can be
* handy in applications requiring precise timing that do not have a dedicated
* timer/counter available for the job.
*
* \section group_systick_more_information More Information
*
* Refer to the SysTick section of the ARM reference guide for complete details
* on the registers and their use.
*
* \section group_systick_changelog Changelog
*
* <table class="doxtable">
* <tr><th>Version</th><th>Changes</th><th>Reason for Change</th></tr>
* <tr>
* <td>1.0</td>
* <td>Initial version</td>
* <td></td>
* </tr>
* </table>
*
* \defgroup group_systick_macro Macro
* \defgroup group_systick_functions Functions
* \defgroup group_systick_data_structures Data Structures
*/
#include <stdint.h>
#include <stdbool.h>
#include "syslib/cy_syslib.h"
#ifdef __cplusplus
extern "C" {
#endif
extern cy_israddress __ramVectors[];
/**
* \addtogroup group_systick_data_structures
* \{
*/
typedef void (*Cy_SysTick_Callback)(void);
typedef enum
{
/** The low frequency clock clk_lf is selected. The precision of this clock depends on whether the low frequency
clock source is a SRSS internal RC oscillator (imprecise) or a device external crystal oscillator (precise) */
CY_SYSTICK_CLOCK_SOURCE_CLK_LF = 0u,
/** The internal main oscillator (IMO) clock clk_imo is selected. */
CY_SYSTICK_CLOCK_SOURCE_CLK_IMO = 1u,
/** The external crystal oscillator (ECO) clock clk_eco is selected. */
CY_SYSTICK_CLOCK_SOURCE_CLK_ECO = 2u,
/** The SRSS clk_timer is selected. The clk_timer is a divided/gated version of clk_hf or clk_imo. */
CY_SYSTICK_CLOCK_SOURCE_CLK_TIMER = 3u,
/** The CPU clock is selected. */
CY_SYSTICK_CLOCK_SOURCE_CLK_CPU = 4u,
} cy_en_systick_clock_source_t;
/** \} group_systick_data_structures */
/**
* \addtogroup group_systick_functions
* \{
*/
/*******************************************************************************
* Function Name: Cy_SysTick_Init
****************************************************************************//**
*
* \brief Initializes the callback addresses with pointers to NULL, associates the
* SysTick system vector with the function responsible for calling
* registered callback functions, configures the SysTick timer to generate an
* interrupt periodically.
*
* \param clockSource : The SysTick clock source \ref en_systick_clock_source_t
* \param interval : The SysTick reload value.
*
* \return None
*
* \note Clears the SysTick count flag if it was set.
*
*******************************************************************************/
void Cy_SysTick_Init(cy_en_systick_clock_source_t clockSource, uint32_t interval);
/*******************************************************************************
* Function Name: Cy_SysTick_Enable
****************************************************************************//**
*
* \brief Enables the SysTick timer and its interrupt.
*
* \param None
*
* \return None
*
* \note Clears the SysTick count flag if it was set
*
*******************************************************************************/
void Cy_SysTick_Enable(void);
/*******************************************************************************
* Function Name: SysTick_Disable
****************************************************************************//**
*
* \brief Disables the SysTick timer and its interrupt.
*
* \param None
*
* \return None
*
* \note Clears the SysTick count flag if it was set
*
*******************************************************************************/
void Cy_SysTick_Disable(void);
/*******************************************************************************
* Function Name: Cy_SysTick_EnableInterrupt
****************************************************************************//**
*
* \brief Enables the SysTick interrupt.
*
* \param None
*
* \return None
*
* \note Clears the SysTick count flag if it was set
*
*******************************************************************************/
void Cy_SysTick_EnableInterrupt(void);
/*******************************************************************************
* Function Name: Cy_SysTick_DisableInterrupt
****************************************************************************//**
*
* \brief Disables the SysTick interrupt.
*
* \param None
*
* \return None
*
* \note Clears the SysTick count flag if it was set
*
*******************************************************************************/
void Cy_SysTick_DisableInterrupt(void);
/*******************************************************************************
* Function Name: Cy_SysTick_SetReload
****************************************************************************//**
*
* \brief Sets the value the counter is set to on a startup and after it reaches zero.
* This function does not change or reset the current sysTick counter value, so
* it should be cleared using the SysTick_Clear() API.
*
* \param value: The valid range is [0x0-0x00FFFFFF]. The counter reset value.
*
*
* \return None
*******************************************************************************/
void Cy_SysTick_SetReload(uint32_t value);
/*******************************************************************************
* Function Name: Cy_SysTick_Set10msCalibration
****************************************************************************//**
*
* \brief Sets the value that Specifies the number of clock source cycles
* (minus 1) that make up 10 ms for the selected clock source.
* It is SW's responsibility to provide the correct value to get 10 ms
* timeout for the selected clock source.
*
* \param value: The valid range is [0x0-0x00FFFFFF].
*
*
* \return None
*******************************************************************************/
void Cy_SysTick_Set10msCalibration(uint32_t value);
/*******************************************************************************
* Function Name: Cy_SysTick_Get10msCalibration
****************************************************************************//**
*
* \brief Sets the value that Specifies the number of clock source cycles
* (plus 1) that make up 10 ms for the selected clock source.
*
* \param None
*
* \return The clock source cycles to make up 10ms value.
*
*******************************************************************************/
uint32_t Cy_SysTick_Get10msCalibration(void);
/*******************************************************************************
* Function Name: Cy_SysTick_GetReload
****************************************************************************//**
*
* \brief Gets the value the counter is set to on a startup and after it reaches zero.
*
* \param None
*
* \return The counter reset value.
*
*******************************************************************************/
uint32_t Cy_SysTick_GetReload(void);
/*******************************************************************************
* Function Name: Cy_SysTick_GetValue
****************************************************************************//**
*
* \brief Gets the current SysTick counter value.
*
* \param None
*
* \return The current SysTick counter value.
*
*******************************************************************************/
uint32_t Cy_SysTick_GetValue(void);
/*******************************************************************************
* Function Name: Cy_SysTick_SetCallback
****************************************************************************//**
*
* \brief This function allows up to five user-defined interrupt service routine
* functions to be associated with the SysTick interrupt. These are specified
* through the use of pointers to the function.
*
* \param number : The number of the callback function addresses to be set.
* The valid range is from 0 to 4.
*
* \param function: The pointer to the function that will be associated with the
* SysTick ISR for the specified number.
*
* \return Returns the address of the previous callback function.
* The NULL is returned if the specified address in not set.
*
* \note The registered callback functions will be executed in the interrupt.
*
*******************************************************************************/
Cy_SysTick_Callback Cy_SysTick_SetCallback(uint32_t number, Cy_SysTick_Callback function);
/*******************************************************************************
* Function Name: Cy_SysTick_GetCallback
****************************************************************************//**
*
* \brief The function gets the specified callback pointer.
*
* \param number : The number of the callback function address to get. The valid
* range is from 0 to 4.
*
* \return Returns the address of the specified callback function.
* The NULL is returned if the specified address in not initialized.
*
*******************************************************************************/
Cy_SysTick_Callback SysTick_GetCallback(uint32_t number);
/*******************************************************************************
* Function Name: Cy_SysTick_SetClockSource
****************************************************************************//**
*
* \brief Sets the clock source for the SysTick counter.
*
* Clears the SysTick count flag if it was set. If the clock source is not ready
* this function call will have no effect. After changing the clock source to the
* low frequency clock, the counter and reload register values will remain
* unchanged so the time to the interrupt will be significantly longer and vice
* versa.
*
* Changing the SysTick clock source and/or its frequency will change
* the interrupt interval and that SysTick_SetReload() should be
* called to compensate this change.
*
* \param clockSource : \ref en_systick_clock_source_t Clock source.
*
*******************************************************************************/
void Cy_SysTick_SetClockSource(cy_en_systick_clock_source_t clockSource);
/*******************************************************************************
* Function Name: Cy_SysTick_GetClockSource
****************************************************************************//**
*
* \brief Gets the clock source for the SysTick counter.
*
* \param None
*
* \returns \ref en_systick_clock_source_t Clock source
*
*******************************************************************************/
cy_en_systick_clock_source_t Cy_SysTick_GetClockSource(void);
/*******************************************************************************
* Function Name: Cy_SysTick_GetCountFlag
****************************************************************************//**
*
* \brief The count flag is set, once the SysTick counter reaches zero.
* The flag is cleared on read.
*
* \param None
*
* \return Returns a non-zero value if a flag is set, otherwise a zero is
* returned.
*
* \note Clears the SysTick count flag if it was set.
*
*******************************************************************************/
uint32_t Cy_SysTick_GetCountFlag(void);
/*******************************************************************************
* Function Name: Cy_SysTick_Clear
****************************************************************************//**
*
* \brief Clears the SysTick counter for a well-defined startup.
*
* \param None
*
* \return None
*
*******************************************************************************/
void Cy_SysTick_Clear(void);
/*******************************************************************************
* Function Name: Cy_SysTick_DelayCoreCycle
****************************************************************************//**
*
* Delay input core cycle. This function can be input whole uint32_t value, while
* DELAY_CORE_CYCLE macro can be input only 24bit value.
* Note: This function is not re-entrant hand in glove with Cy_SysTick_DelayInUs.
*
* \param cycle core cycle to be delayed.
*
*******************************************************************************/
void Cy_SysTick_DelayCoreCycle(uint64_t cycle);
/*******************************************************************************
* Function Name: Cy_SysTick_DelayInUs
****************************************************************************//**
*
* Delay input value in micro second.
* Note: This function is not re-entrant hand in glove with Cy_SysTick_DelayCoreCycle.
* Note: Before calling this function SystemInit() have to be called.
*
* \param us micro second value to be delayed
*
*******************************************************************************/
void Cy_SysTick_DelayInUs(uint32_t us);
/** \} group_systick_functions */
/**
* \addtogroup group_systick_macro
* \{
*/
/** Driver major version */
#define SYSTICK_DRV_VERSION_MAJOR 1
/** Driver minor version */
#define SYSTICK_DRV_VERSION_MINOR 0
#define CY_SYS_SYST_NUM_OF_CALLBACKS (5u)
#define CY_SYSTICK_IRQ_NUM (15u)
/** \} group_systick_macro */
#ifdef __cplusplus
}
#endif
#endif /* _CY_SYSTICK_H_ */
/** \} group_systick */
/* [] END OF FILE */
@@ -0,0 +1,170 @@
/***************************************************************************//**
* \file cy_syswdt.c
* \version 1.0
*
* This file provides the source code to the API for the WDT driver.
*
********************************************************************************
* \copyright
* Copyright 2016-2017, Cypress Semiconductor Corporation. All rights reserved.
* You may use this file only in accordance with the license, terms, conditions,
* disclaimers, and limitations in the end user license agreement accompanying
* the software package with which this file was provided.
*******************************************************************************/
#include "syswdt/cy_syswdt.h"
#include "syslib/cy_syslib.h"
#if defined(__cplusplus)
extern "C" {
#endif
/*******************************************************************************
* Function Name: Cy_WDT_Init
****************************************************************************//**
*
* Initializes the Watchdog timer to its default state.
*
* The given default setting of the WDT:
*
* Before calling this function, WDT needs to be disable.
* This sets the upper limit and reset action.
*
*******************************************************************************/
void Cy_WDT_Init(void)
{
uint32_t interruptState;
interruptState = Cy_SysLib_EnterCriticalSection();
/* Unlock the WDT registers by two writes */
Cy_WDT_Unlock();
/* Set upper limit = 32000 (1sec) */
Cy_WDT_SetLowerLimit(0ul);
Cy_WDT_SetUpperLimit(CY_WDT_DEFAULT_MATCH_VALUE);
Cy_WDT_SetWarnLimit(0ul);
Cy_WDT_SetLowerAction(CY_WDT_LOW_UPP_ACTION_NONE);
Cy_WDT_SetUpperAction(CY_WDT_LOW_UPP_ACTION_RESET);
Cy_WDT_SetWarnAction(CY_WDT_WARN_ACTION_NONE);
/* Lock the WDT registers */
Cy_WDT_Lock();
Cy_SysLib_ExitCriticalSection(interruptState);
}
/*******************************************************************************
* Function Name: Cy_WDT_Lock
****************************************************************************//**
*
* Locks out configuration changes to the Watchdog Timer register.
*
* After this function is called, the WDT configuration cannot be changed until
* Cy_WDT_Unlock() is called.
*
*******************************************************************************/
void Cy_WDT_Lock(void)
{
uint32_t interruptState;
interruptState = Cy_SysLib_EnterCriticalSection();
WDT->unLOCK.stcField.u2WDT_LOCK = 3ul;
Cy_SysLib_ExitCriticalSection(interruptState);
}
/*******************************************************************************
* Function Name: Cy_WDT_Unlock
****************************************************************************//**
*
* Unlocks the Watchdog Timer configuration register.
*
*******************************************************************************/
void Cy_WDT_Unlock(void)
{
uint32_t interruptState;
interruptState = Cy_SysLib_EnterCriticalSection();
/* The WDT lock is to be removed by two writes */
WDT->unLOCK.stcField.u2WDT_LOCK = 1ul;
WDT->unLOCK.stcField.u2WDT_LOCK = 2ul;
Cy_SysLib_ExitCriticalSection(interruptState);
}
/*******************************************************************************
* Function Name: Cy_WDT_Enable
****************************************************************************//**
*
* Enables the Watchdog timer.
*
*******************************************************************************/
void Cy_WDT_Enable(void)
{
Cy_WDT_Unlock();
WDT->unCTL.stcField.u1ENABLE = 1ul;
Cy_WDT_Lock();
}
/*******************************************************************************
* Function Name: Cy_WDT_Disable
****************************************************************************//**
*
* Disables the Watchdog timer. The Watchdog timer should be unlocked before being
* disabled. Call the Cy_WDT_Unlock() API to unlock the WDT.
*
*******************************************************************************/
void Cy_WDT_Disable(void)
{
Cy_WDT_Unlock();
WDT->unCTL.stcField.u1ENABLE = 0ul;
Cy_WDT_Lock();
}
/*******************************************************************************
* Function Name: Cy_WDT_ClearInterrupt
****************************************************************************//**
*
* Clears the WDT match flag which is set every time the WDT counter reaches a
* WDT match value. Two unserviced interrupts lead to a system reset
* (i.e. at the third match).
*
*******************************************************************************/
void Cy_WDT_ClearInterrupt(void)
{
WDT->unINTR.stcField.u1WDT = 1ul;
/* Read the interrupt register to ensure that the initial clearing write has
* been flushed out to the hardware.
*/
(void) SRSS->unSRSS_INTR.u32Register;
}
/*******************************************************************************
* Function Name: Cy_WDT_ClearWatchdog
****************************************************************************//**
*
* Clears ("feeds") the watchdog, to prevent a XRES device reset.
* This function simply call Cy_WDT_ClearInterrupt() function.
*
*******************************************************************************/
void Cy_WDT_ClearWatchdog(void)
{
Cy_WDT_Unlock();
Cy_WDT_SetService();
Cy_WDT_Lock();
}
#if defined(__cplusplus)
}
#endif
/* [] END OF FILE */
@@ -0,0 +1,469 @@
/***************************************************************************//**
* \file cy_syswdt.h
* \version 1.0
*
* This file provides constants and parameter values for the WDT driver.
*
********************************************************************************
* \copyright
* Copyright 2016-2017, Cypress Semiconductor Corporation. All rights reserved.
* You may use this file only in accordance with the license, terms, conditions,
* disclaimers, and limitations in the end user license agreement accompanying
* the software package with which this file was provided.
*
*******************************************************************************/
/**
* \defgroup group_wdt Watchdog Timer (SysWdt)
* \{
*
* The Watchdog timer (WDT) has a 16-bit free-running up-counter. The WDT can
* issue counter match interrupts, and a device reset if its interrupts are not
* handled. Use the Watchdog timer for two main purposes.<br>
* The <b> First use case </b> is recovering from a CPU or firmware failure.
* A timeout period is set up in the Watchdog timer, and if a timeout occurs, the
* device is reset (WRES). <br>
* The <b>Second use case</b> is to generate periodic interrupts.
*
* A "reset cause" register exists, and the firmware should check this register
* at a start-up. An appropriate action can be taken if a WRES reset is detected.
*
* The user's firmware periodically resets the timeout period (clears or "feeds"
* the watchdog) before a timeout occurs. If the firmware fails to do so, that is
* considered to be a CPU crash or a firmware failure, and the reason for a
* device reset.
* The WDT can generate an interrupt instead of a device reset. The Interrupt
* Service Routine (ISR) can handle the interrupt either as a periodic interrupt,
* or as an early indication of a firmware failure and respond accordingly.
* However, it is not recommended to use the WDT for periodic interrupt
* generation. The Multi-counter Watchdog Timers (MCWDT) can be used to generate
* periodic interrupts if such are presented in the device.
*
* <b> Functional Description </b> <br>
* The WDT generates an interrupt when the count value in the counter equals the
* configured match value.
*
* Note that the counter is not reset on a match. In such case the WDT
* reset period is:
* WDT_Reset_Period = ILO_Period * (2*2^(16-IgnoreBits) + MatchValue);
* When the counter reaches a match value, it generates an interrupt and then
* keeps counting up until it overflows and rolls back to zero and reaches the
* match value again, at which point another interrupt is generated.
*
* To use a WDT to generate a periodic interrupt, the match value should be
* incremented in the ISR. As a result, the next WDT interrupt is generated when
* the counter reaches a new match value.
*
* You can also reduce the entire WDT counter period by
* specifying the number of most significant bits that are ignored in the WDT
* counter. For example, if the Cy_WDT_SetIgnoreBits() function is called with
* parameter 3, the WDT counter becomes a 13-bit free-running up-counter.
*
* <b> Power Modes </b> <br>
* WDT can operate in all possible low power modes.
* Operation during Hibernate mode is possible because the logic and
* high-voltage internal low oscillator (ILO) are supplied by the external
* high-voltage supply (Vddd). The WDT can be configured to wake the device from
* Hibernate mode.
*
* In Active or LPActive mode, an interrupt request from the WDT is sent to the
* CPU via IRQ 22. In Sleep, LPSleep or Deep Sleep power mode, the CPU subsystem
* is powered down, so the interrupt request from the WDT is sent directly to the
* WakeUp Interrupt Controller (WIC) which will then wake up the CPU. The
* CPU then acknowledges the interrupt request and executes the ISR.
*
* <b> Clock Source </b> <br>
* The WDT is clocked by the ILO. The WDT must be disabled before disabling
* the ILO. According to the device datasheet, the ILO accuracy is +/-30% over
* voltage and temperature. This means that the timeout period may vary by 30%
* from the configured value. Appropriate margins should be added while
* configuring WDT intervals to make sure that unwanted device resets do not
* occur on some devices.
*
* Refer to the device datasheet for more information on the oscillator accuracy.
*
* <b> Register Locking </b> <br>
* You can prevent accidental corruption of the WDT configuration by calling
* the Cy_WDT_Lock() function. When the WDT is locked, any writing to the WDT_*,
* CLK_ILO_CONFIG, CLK_SELECT.LFCLK_SEL, and CLK_TRIM_ILO_CTL registers is
* ignored.
* Call the Cy_WDT_Unlock() function to allow WDT registers modification.
*
* <b> Clearing WDT </b> <br>
* The ILO clock is asynchronous to the SysClk. Therefore it generally
* takes three ILO cycles for WDT register changes to come into effect. It is
* important to remember that a WDT should be cleared at least four cycles
* (3 + 1 for sure) before a timeout occurs, especially when small
* match values / low-toggle bit numbers are used.
*
* \warning It may happen that a WDT reset can be generated
* faster than a device start-up. To prevent this, calculate the
* start-up time and WDT reset time. The WDT reset time should be always smaller
* than device start-up time.
*
* <b> Reset Detection </b> <br>
* Use the Cy_SysReset_GetResetReason() function to detect whether the WDT has
* triggered a device reset.
*
* <b> Interrupt Configuration </b> <br>
* The Global Signal Reference and Interrupt components can be used for ISR
* configuration. If the WDT is configured to generate an interrupt, pending
* interrupts must be cleared within the ISR (otherwise, the interrupt will be
* generated continuously).
* A pending interrupt to the WDT block must be cleared by calling the
* Cy_WDT_ClearInterrupt() function. The call to the function will clear the
* unhandled WDT interrupt counter.
*
* Use the WDT ISR as a timer to trigger certain actions
* and to change a next WDT match value.
*
* Ensure that the interrupts from the WDT are passed to the CPU to avoid
* unregistered interrupts. Unregistered WDT interrupts result in a continuous
* device reset. To avoid this, call Cy_WDT_UnmaskInterrupt().
* After that, call the WDT API functions for interrupt
* handling/clearing.
*
* \section group_wdt_configuration Configuration Considerations
*
* To start the WDT, make sure that ILO is enabled.
* After the ILO is enabled, ensure that the WDT is unlocked and disabled by
* calling the Cy_WDT_Unlock() and Cy_WDT_Disable() functions. Set the WDT match
* value by calling Cy_WDT_SetMatch() with the required match value. If needed,
* set the ignore bits for reducing the WDT counter period by calling
* Cy_WDT_SetIgnoreBits() function. After the WDT configuration is set,
* call Cy_WDT_Enable().
*
* \note Enable a WDT if the power supply can produce
* sudden brownout events that may compromise the CPU functionality. This
* ensures that the system can recover after a brownout.
*
* When the WDT is used to protect against system crashes, the
* WDT interrupt should be cleared by a portion of the code that is not directly
* associated with the WDT interrupt.
* Otherwise, it is possible that the main firmware loop has crashed or is in an
* endless loop, but the WDT interrupt vector continues to operate and service
* the WDT. The user should:
* * Feed the watchdog by clearing the interrupt bit regularly in the main body
* of the firmware code.
*
* * Guarantee that the interrupt is cleared at least once every WDT period.
*
* * Use the WDT ISR only as a timer to trigger certain actions and to change the
* next match value.
*
* \section group_wdt_section_more_information More Information
*
* For more information on the WDT peripheral, refer to the technical reference
* manual (TRM).
*
* \section group_wdt_changelog Changelog
* <table class="doxtable">
* <tr><th>Version</th><th>Changes</th><th>Reason for Change</th></tr>
* <tr>
* <td>1.0</td>
* <td>Initial version</td>
* <td></td>
* </tr>
* </table>
*
* \defgroup group_wdt_macro Macro
* \defgroup group_wdt_functions Functions
*
*/
#if !defined(_WDT_H_)
#define _WDT_H_
#include <stdint.h>
#include <stdbool.h>
#include "cy_device_headers.h"
#if defined(__cplusplus)
extern "C" {
#endif
/*******************************************************************************
* Function Constants
*******************************************************************************/
/**
* \addtogroup group_wdt_macros
* \{
*/
/** The driver major version */
#define CY_WDT_DRV_VERSION_MAJOR (1ul)
/** The driver minor version */
#define CY_WDT_DRV_VERSION_MINOR (0ul)
/** The WDT default match value */
#define CY_WDT_DEFAULT_MATCH_VALUE (32000ul) // 1 sec when clk_lf = 32KHz
/** The WDT driver identifier */
#define CY_WDT_ID CY_PDL_DRV_ID(0x34u)
/** \} group_wdt_macros */
/**
* \addtogroup group_wdt_enums
* \{
*/
/** The wdt lower/upper limit actions. */
typedef enum
{
CY_WDT_LOW_UPP_ACTION_NONE,
CY_WDT_LOW_UPP_ACTION_RESET
} cy_en_wdt_lower_upper_action_t;
/** The wdt lower/upper limit actions. */
typedef enum
{
CY_WDT_WARN_ACTION_NONE,
CY_WDT_WARN_ACTION_INT
} cy_en_wdt_warn_action_t;
typedef enum
{
CY_WDT_DISABLE,
CY_WDT_ENABLE
} cy_en_wdt_enable_t;
/** \} group_wdt_enums */
/*******************************************************************************
* Function Prototypes
*******************************************************************************/
/**
* \addtogroup group_wdt_functions
* @{
*/
/* WDT API */
void Cy_WDT_Init(void);
void Cy_WDT_Lock(void);
void Cy_WDT_Unlock(void);
void Cy_WDT_Enable(void);
void Cy_WDT_Disable(void);
void Cy_WDT_ClearInterrupt(void);
void Cy_WDT_ClearWatchdog(void);
__STATIC_INLINE void Cy_WDT_SetLowerLimit(uint32_t match);
__STATIC_INLINE void Cy_WDT_SetUpperLimit(uint32_t match);
__STATIC_INLINE void Cy_WDT_SetWarnLimit(uint32_t match);
__STATIC_INLINE void Cy_WDT_SetLowerAction(cy_en_wdt_lower_upper_action_t action);
__STATIC_INLINE void Cy_WDT_SetUpperAction(cy_en_wdt_lower_upper_action_t action);
__STATIC_INLINE void Cy_WDT_SetWarnAction(cy_en_wdt_warn_action_t action);
__STATIC_INLINE void Cy_WDT_SetAutoService(cy_en_wdt_enable_t enable);
__STATIC_INLINE void Cy_WDT_SetDeepSleepPause(cy_en_wdt_enable_t enable);
__STATIC_INLINE void Cy_WDT_SetHibarnatePause(cy_en_wdt_enable_t enable);
__STATIC_INLINE void Cy_WDT_SetDebugRun(cy_en_wdt_enable_t enable);
__STATIC_INLINE uint32_t Cy_WDT_GetCount(void);
__STATIC_INLINE void Cy_WDT_SetService();
__STATIC_INLINE void Cy_WDT_MaskInterrupt(void);
__STATIC_INLINE void Cy_WDT_UnmaskInterrupt(void);
/*******************************************************************************
* Function Name: Cy_WDT_SetLowerLimit
****************************************************************************//**
*
* Set lower limit for watchdog.
*
*******************************************************************************/
__STATIC_INLINE void Cy_WDT_SetLowerLimit(uint32_t match)
{
WDT->unLOWER_LIMIT.stcField.u32LOWER_LIMIT = match;
}
/*******************************************************************************
* Function Name: Cy_WDT_SetUpperLimit
****************************************************************************//**
*
* Set upper limit for watchdog.
*
*******************************************************************************/
__STATIC_INLINE void Cy_WDT_SetUpperLimit(uint32_t match)
{
WDT->unUPPER_LIMIT.stcField.u32UPPER_LIMIT = match;
}
/*******************************************************************************
* Function Name: Cy_WDT_SetWarnLimit
****************************************************************************//**
*
* Set warn limit for watchdog.
*
*******************************************************************************/
__STATIC_INLINE void Cy_WDT_SetWarnLimit(uint32_t match)
{
WDT->unWARN_LIMIT.stcField.u32WARN_LIMIT = match;
}
/*******************************************************************************
* Function Name: Cy_WDT_SetLowerAction
****************************************************************************//**
*
* Set action taken if this watchdog is serviced before LOWER_LIMIT is reached.
*
*******************************************************************************/
__STATIC_INLINE void Cy_WDT_SetLowerAction(cy_en_wdt_lower_upper_action_t action)
{
WDT->unCONFIG.stcField.u1LOWER_ACTION = action;
}
/*******************************************************************************
* Function Name: Cy_WDT_SetUpperAction
****************************************************************************//**
*
* Set action taken if this watchdog is not serviced before UPPER_LIMIT is reached.
*
*******************************************************************************/
__STATIC_INLINE void Cy_WDT_SetUpperAction(cy_en_wdt_lower_upper_action_t action)
{
WDT->unCONFIG.stcField.u1UPPER_ACTION = action;
}
/*******************************************************************************
* Function Name: Cy_WDT_SetWarnAction
****************************************************************************//**
*
* Set action taken when the count value reaches WARN_LIMIT.
*
*******************************************************************************/
__STATIC_INLINE void Cy_WDT_SetWarnAction(cy_en_wdt_warn_action_t action)
{
WDT->unCONFIG.stcField.u1WARN_ACTION = action;
}
/*******************************************************************************
* Function Name: Cy_WDT_SetAutoService
****************************************************************************//**
*
* Set automatically service when the count value reaches WARN_LIMIT.
* This function is used for WARN_LIMIT.
*
*******************************************************************************/
__STATIC_INLINE void Cy_WDT_SetAutoService(cy_en_wdt_enable_t enable)
{
WDT->unCONFIG.stcField.u1AUTO_SERVICE = enable;
}
/*******************************************************************************
* Function Name: Cy_WDT_SetDeepSleepPause
****************************************************************************//**
*
* Set whether the WDT counter runs/pauses when the system is in DEEPSLEEP.
*
*******************************************************************************/
__STATIC_INLINE void Cy_WDT_SetDeepSleepPause(cy_en_wdt_enable_t enable)
{
WDT->unCONFIG.stcField.u1DPSLP_PAUSE = enable;
}
/*******************************************************************************
* Function Name: Cy_WDT_SetHibarnatePause
****************************************************************************//**
*
* Set whether the WDT counter runs/pauses when the system is in HIBERNATE.
*
*******************************************************************************/
__STATIC_INLINE void Cy_WDT_SetHibarnatePause(cy_en_wdt_enable_t enable)
{
WDT->unCONFIG.stcField.u1HIB_PAUSE = enable;
}
/*******************************************************************************
* Function Name: Cy_WDT_SetDebugRun
****************************************************************************//**
*
* Set the debug run value. It needs when using debugger.
*
*******************************************************************************/
__STATIC_INLINE void Cy_WDT_SetDebugRun(cy_en_wdt_enable_t enable)
{
WDT->unCONFIG.stcField.u1DEBUG_RUN = enable;
}
/*******************************************************************************
* Function Name: Cy_WDT_GetCount
****************************************************************************//**
*
* Reads the current WDT counter value.
*
* \return A live counter value.
*
*******************************************************************************/
__STATIC_INLINE uint32_t Cy_WDT_GetCount(void)
{
return WDT->unCNT.stcField.u32CNT;
}
/*******************************************************************************
* Function Name: Cy_WDT_SetService
****************************************************************************//**
*
* Set service of the watchdog. This resets the count value to zero.
*
*******************************************************************************/
__STATIC_INLINE void Cy_WDT_SetService()
{
WDT->unSERVICE.stcField.u1SERVICE = 1ul;
}
/*******************************************************************************
* Function Name: Cy_WDT_MaskInterrupt
****************************************************************************//**
*
* After masking interrupts from the WDT, they are passed to CPU.
* This function does not impact the reset generation.
*
*******************************************************************************/
__STATIC_INLINE void Cy_WDT_MaskInterrupt(void)
{
WDT->unINTR_MASK.stcField.u1WDT = 1ul;
}
/*******************************************************************************
* Function Name: Cy_WDT_UnmaskInterrupt
****************************************************************************//**
*
* After unmasking interrupts from the WDT, they are not passed to the CPU.
* This function does not disable the WDT-reset generation.
*
*******************************************************************************/
__STATIC_INLINE void Cy_WDT_UnmaskInterrupt(void)
{
WDT->unINTR_MASK.stcField.u1WDT = 0ul;
}
/** \} group_wdt_functions */
#if defined(__cplusplus)
}
#endif
#endif /* _WDT_H_ */
/** \} group_wdt */
/* [] END OF FILE */
@@ -0,0 +1,254 @@
/***************************************************************************//**
* \file cy_tcpwm.c
* \version 1.0
*
* \brief
* The source file of the tcpwm driver.
*
********************************************************************************
* \copyright
* Copyright 2016, Cypress Semiconductor Corporation. All rights reserved.
* You may use this file only in accordance with the license, terms, conditions,
* disclaimers, and limitations in the end user license agreement accompanying
* the software package with which this file was provided.
*******************************************************************************/
#include "cy_tcpwm.h"
#if defined(__cplusplus)
extern "C" {
#endif
/*******************************************************************************
* Function Name: Cy_Tcpwm_TriggerStart
****************************************************************************//**
*
* \brief Triggers a software start on the selected TCPWMs.
*
* \param ptscTCPWM : The pointer to a counter instance.
* Group0 - 16-bit timer(63 counters, 0-62)
* Group1 - 16-bit timer with motor control(12 counters, 0-11)
* Group2 - 32-bit timer(4 counters, 0-3)
*(Ex - TCPWM0_GRP0_CNT34 = Group0 is selected and its 34th counter is in use)
*
* \return None
*
*******************************************************************************/
void Cy_Tcpwm_TriggerStart(volatile stc_TCPWM_GRP_CNT_t *ptscTCPWM)
{
ptscTCPWM->unTR_CMD.stcField.u1START = 0x1ul;
}
/*******************************************************************************
* Function Name: Cy_Tcpwm_TriggerReloadOrIndex
****************************************************************************//**
*
* \brief Triggers a software reload event (or index in QuadDec mode).
*
* \param ptscTCPWM : The pointer to a counter instance.
* Group0 - 16-bit timer(63 counters, 0-62)
* Group1 - 16-bit timer with motor control(12 counters, 0-11)
* Group2 - 32-bit timer(4 counters, 0-3)
*(Ex - TCPWM0_GRP0_CNT34 = Group0 is selected and its 34th counter is in use)
*
* \return None
*
*******************************************************************************/
void Cy_Tcpwm_TriggerReloadOrIndex(volatile stc_TCPWM_GRP_CNT_t *ptscTCPWM)
{
ptscTCPWM->unTR_CMD.stcField.u1RELOAD = 0x1ul;
}
/*******************************************************************************
* Function Name: Cy_Tcpwm_TriggerStopOrKill
****************************************************************************//**
*
* \brief Triggers a stop in the Timer Counter mode, or a kill in the PWM mode.
*
* \param ptscTCPWM : The pointer to a counter instance.
* Group0 - 16-bit timer(63 counters, 0-62)
* Group1 - 16-bit timer with motor control(12 counters, 0-11)
* Group2 - 32-bit timer(4 counters, 0-3)
*(Ex - TCPWM0_GRP0_CNT34 = Group0 is selected and its 34th counter is in use)
*
* \return None
*
*******************************************************************************/
void Cy_Tcpwm_TriggerStopOrKill(volatile stc_TCPWM_GRP_CNT_t *ptscTCPWM)
{
ptscTCPWM->unTR_CMD.stcField.u1STOP = 0x1ul;
}
/*******************************************************************************
* Function Name: Cy_Tcpwm_TriggerCapture0
****************************************************************************//**
*
* \brief Triggers a Capture0 in the Timer Counter mode, and a Swap in the PWM mode.
*
* \param ptscTCPWM : The pointer to a counter instance.
* Group0 - 16-bit timer(63 counters, 0-62)
* Group1 - 16-bit timer with motor control(12 counters, 0-11)
* Group2 - 32-bit timer(4 counters, 0-3)
*(Ex - TCPWM0_GRP0_CNT34 = Group0 is selected and its 34th counter is in use)
*
* \return None
*
*******************************************************************************/
void Cy_Tcpwm_TriggerCapture0(volatile stc_TCPWM_GRP_CNT_t *ptscTCPWM)
{
ptscTCPWM->unTR_CMD.stcField.u1CAPTURE0 = 0x1ul;
}
/*******************************************************************************
* Function Name: Cy_Tcpwm_TriggerCapture1
****************************************************************************//**
*
* \brief Triggers a Capture1 in the Timer Counter mode, and a Swap in the PWM mode.
*
* \param ptscTCPWM : The pointer to a counter instance.
* Group0 - 16-bit timer(63 counters, 0-62)
* Group1 - 16-bit timer with motor control(12 counters, 0-11)
* Group2 - 32-bit timer(4 counters, 0-3)
*(Ex - TCPWM0_GRP0_CNT34 = Group0 is selected and its 34th counter is in use)
*
* \return None
*
*******************************************************************************/
void Cy_Tcpwm_TriggerCapture1(volatile stc_TCPWM_GRP_CNT_t *ptscTCPWM)
{
ptscTCPWM->unTR_CMD.stcField.u1CAPTURE1 = 0x1ul;
}
/*******************************************************************************
* Function Name: Cy_Tcpwm_GetInterruptStatus
****************************************************************************//**
*
* \brief Returns which event triggered the interrupt.
*
* \param ptscTCPWM : The pointer to a counter instance.
* Group0 - 16-bit timer(63 counters, 0-62)
* Group1 - 16-bit timer with motor control(12 counters, 0-11)
* Group2 - 32-bit timer(4 counters, 0-3)
*(Ex - TCPWM0_GRP0_CNT34 = Group0 is selected and its 34th counter is in use)
*
* \return see \ref cy_en_tcpwm_interrupt_sources
*
*******************************************************************************/
uint32_t Cy_Tcpwm_GetInterruptStatus(volatile stc_TCPWM_GRP_CNT_t *ptscTCPWM)
{
return(ptscTCPWM->unINTR.u32Register);
}
/*******************************************************************************
* Function Name: Cy_Tcpwm_ClearInterrupt
****************************************************************************//**
*
* \brief Clears Active Interrupt Source
*
* \param ptscTCPWM : The pointer to a counter instance.
* Group0 - 16-bit timer(63 counters, 0-62)
* Group1 - 16-bit timer with motor control(12 counters, 0-11)
* Group2 - 32-bit timer(4 counters, 0-3)
*(Ex - TCPWM0_GRP0_CNT34 = Group0 is selected and its 34th counter is in use)
* \param source : source to clear see \ref cy_en_tcpwm_interrupt_sources
*
*******************************************************************************/
void Cy_Tcpwm_ClearInterrupt(volatile stc_TCPWM_GRP_CNT_t *ptscTCPWM, uint32_t source)
{
ptscTCPWM->unINTR.u32Register = source;
(void)ptscTCPWM->unINTR.u32Register;
}
/*******************************************************************************
* Function Name: Cy_Tcpwm_SetInterrupt
****************************************************************************//**
*
* \brief Triggers an interrupt via a software write.
*
* \param ptscTCPWM : The pointer to a counter instance.
* Group0 - 16-bit timer(63 counters, 0-62)
* Group1 - 16-bit timer with motor control(12 counters, 0-11)
* Group2 - 32-bit timer(4 counters, 0-3)
*(Ex - TCPWM0_GRP0_CNT34 = Group0 is selected and its 34th counter is in use)
* \param source : The source to set an interrupt of see \ref group_tcpwm_interrupt_sources.
*
* \return None
*
*******************************************************************************/
void Cy_Tcpwm_SetInterrupt(volatile stc_TCPWM_GRP_CNT_t *ptscTCPWM, uint32_t source)
{
ptscTCPWM->unINTR_SET.u32Register = source;
}
/*******************************************************************************
* Function Name: Cy_Tcpwm_SetInterruptMask
****************************************************************************//**
*
* \brief Sets an interrupt mask. A 1 means that when the event occurs, it will cause an interrupt;
* a 0 means no interrupt will be triggered.
*
* \param ptscTCPWM : The pointer to a counter instance.
* Group0 - 16-bit timer(63 counters, 0-62)
* Group1 - 16-bit timer with motor control(12 counters, 0-11)
* Group2 - 32-bit timer(4 counters, 0-3)
*(Ex - TCPWM0_GRP0_CNT34 = Group0 is selected and its 34th counter is in use)
* \param mask : see \ref cy_en_tcpwm_interrupt_sources
*
* \return None
*
*******************************************************************************/
void Cy_Tcpwm_SetInterruptMask(volatile stc_TCPWM_GRP_CNT_t *ptscTCPWM, uint32_t mask)
{
ptscTCPWM->unINTR_MASK.u32Register = mask;
}
/*******************************************************************************
* Function Name: Cy_Tcpwm_GetInterruptMask
****************************************************************************//**
*
* \brief Returns the interrupt mask.
*
* \param ptscTCPWM : The pointer to a counter instance.
* Group0 - 16-bit timer(63 counters, 0-62)
* Group1 - 16-bit timer with motor control(12 counters, 0-11)
* Group2 - 32-bit timer(4 counters, 0-3)
*(Ex - TCPWM0_GRP0_CNT34 = Group0 is selected and its 34th counter is in use)
*
* \return Interrupt Mask, see \ref cy_en_tcpwm_interrupt_sources
*
*******************************************************************************/
uint32_t Cy_Tcpwm_GetInterruptMask(volatile stc_TCPWM_GRP_CNT_t *ptscTCPWM)
{
return(ptscTCPWM->unINTR_MASK.u32Register);
}
/*******************************************************************************
* Function Name: Cy_Tcpwm_GetInterruptStatusMasked
****************************************************************************//**
*
* \brief Returns which masked interrupt triggered the interrupt.
*
* \param ptscTCPWM : The pointer to a counter instance.
* Group0 - 16-bit timer(63 counters, 0-62)
* Group1 - 16-bit timer with motor control(12 counters, 0-11)
* Group2 - 32-bit timer(4 counters, 0-3)
*(Ex - TCPWM0_GRP0_CNT34 = Group0 is selected and its 34th counter is in use)
*
* \return Interrupt Mask, see \ref cy_en_tcpwm_interrupt_sources
*
*******************************************************************************/
uint32_t Cy_Tcpwm_GetInterruptStatusMasked(volatile stc_TCPWM_GRP_CNT_t *ptscTCPWM)
{
return(ptscTCPWM->unINTR_MASKED.u32Register);
}
#if defined(__cplusplus)
}
#endif
/* [] END OF FILE */
@@ -0,0 +1,326 @@
/***************************************************************************//**
* \file cy_tcpwm.h
* \version 1.0
*
* The header file of the TCPWM driver.
*
********************************************************************************
* \copyright
* Copyright 2016, Cypress Semiconductor Corporation. All rights reserved.
* You may use this file only in accordance with the license, terms, conditions,
* disclaimers, and limitations in the end user license agreement accompanying
* the software package with which this file was provided.
*******************************************************************************/
/**
* \defgroup group_tcpwm Timer Counter PWM (TCPWM)
* \{
*
* The TCPWM driver is a multifunction driver that implements the core
* microcontroller functionality, including Timer Counter, PWM, and
* Quadrature Decoder using the TCPWM block.
*
* \section group_tcpwm_configuration Configuration Considerations
*
* The component is based on a hardware structure designed to share the same
* hardware across all the various modes of operation. This structure
* allows the same hardware to provide a flexible set of functions with
* a little increase in the silicon use.
*
* The block is split into three functional modes. There is one overall tcpwm driver
* subdivided into the following:
*
* * The Timer/Counter has the following features:
* \li 16 or 32 bit Timer/Counter
* \li Programmable Period Register
* \li Output Compare, compare value can be swapped with a buffered compare value on comparison event
* \li Capture with buffer register
* \li Count Up, Count Down, or Count Up and Down Counting modes
* \li Continuous or One Shot Run modes
* \li Interrupt and Output on Overflow, Underflow, Capture, or Compare
* \li Start, Reload, Stop, Capture, and Count Inputs
*
* * The PWM has the following features:
* \li 16 or 32 bit Counter
* \li Two Programmable Period Registers that can be swapped on overflow
* \li Two Output Compare registers that can be swapped on overflow and/or underflow
* \li Left Aligned, Right Aligned, Center Aligned, and Asymmetric Aligned modes
* \li Continuous or One Shot Run modes
* \li Pseudo Random mode
* \li Two PWM outputs with Dead Time insertion
* \li Interrupt and Output on Overflow, Underflow, or Compare
* \li Start, Reload, Stop, Swap(Capture), and Count Inputs
*
* * The Quadrature Decoder has the following features:
* \li 16 or 32 bit Counter
* \li Counter Resolution of x1, x2, and x4 the frequency of the phiA(Count) and phiB(Start) inputs.
* \li Index(Reload) Input to determine absolute position.
* \li A positive edge on phiA increments the counter when phiB is 0 and decrements the counter when phiB is 1.
*
* \section group_tcpwm_more_information More Information
*
* For more information on the TCPWM peripheral, refer to the technical reference manual (TRM).
*
* \section group_tcpwm_changelog Changelog
* <table class="doxtable">
* <tr><th>Version</th><th>Changes</th><th>Reason for Change</th></tr>
* <tr>
* <td>1.1</td>
* <td>Config Struct \ref cy_stc_tcpwm_counter_config_t updated with correct members
* for trigger1/2, changed to trigger0EventCfg/trigger1EventCfg,
* Config Struct \ref cy_stc_tcpwm_pwm_config_t added
* with trigger0EventCfg/trigger1EventCfg, immediateKill, pwmOnDisable,
* Config Struct \ref cy_stc_tcpwm_quaddec_config_t added
* with trigger0EventCfg/trigger1EventCfg,
* Config Struct \ref cy_stc_tcpwm_sr_config_t added
* with trigger0EventCfg/trigger1EventCfg</td>
* <td>Corrections, and enhancements</td>
* <td></td>
* </tr>
* <tr>
* <td>1.0</td>
* <td>Initial version</td>
* <td></td>
* </tr>
* </table>
* \defgroup group_tcpwm_macro Macro
* \defgroup group_tcpwm_functions Functions
* \defgroup group_tcpwm_enum Enumerations
*
* \defgroup group_tcpwm_counter Counter (TCPWM)
* \defgroup group_tcpwm_pwm PWM (TCPWM)
* \defgroup group_tcpwm_quaddec Quadrature Decoder (TCPWM)
* \defgroup group_tcpwm_sr Shift Register (TCPWM)
*/
#if !defined(CY_TCPWM_H)
#define CY_TCPWM_H
#include <stdint.h>
#include <stdbool.h>
#include <stddef.h>
#include "cy_device_headers.h"
#include "ip/cyip_tcpwm_v2.h"
#include "syslib/cy_syslib.h"
#if defined(__cplusplus)
extern "C" {
#endif
/**
* \addtogroup group_tcpwm_macro
* \{
*/
/** Driver major version */
#define CY_TCPWM_DRV_VERSION_MAJOR 1
/** Driver minor version */
#define CY_TCPWM_DRV_VERSION_MINOR 0
/***************************************
* Registers Constants
***************************************/
/**
* \defgroup group_tcpwm_reg_const Default registers constants
* \{
* Default constants for CNT Registers
*/
#define CY_TCPWM_CNT_CTRL_DEFAULT (0x0ul) /**< Default value for CTRL register */
#define CY_TCPWM_CNT_COUNTER_DEFAULT (0x0ul) /**< Default value for COUNTER register */
#define CY_TCPWM_CNT_CC_DEFAULT (0xFFFFFFFFul) /**< Default value for CC register */
#define CY_TCPWM_CNT_CC_BUFF_DEFAULT (0xFFFFFFFFul) /**< Default value for CC_BUFF register */
#define CY_TCPWM_CNT_PERIOD_DEFAULT (0xFFFFFFFFul) /**< Default value for PERIOD register */
#define CY_TCPWM_CNT_PERIOD_BUFF_DEFAULT (0xFFFFFFFFul) /**< Default value for PERIOD_BUFF register */
#define CY_TCPWM_CNT_TR_CTRL0_DEFAULT (0x10ul) /**< Default value for TR_CTRL0 register */
#define CY_TCPWM_CNT_TR_CTRL1_DEFAULT (0x3FFul) /**< Default value for TR_CTRL1 register */
#define CY_TCPWM_CNT_TR_CTRL2_DEFAULT (0x3Ful) /**< Default value for TR_CTRL2 register */
#define CY_TCPWM_CNT_INTR_DEFAULT (0x3ul) /**< Default value for INTR register */
#define CY_TCPWM_CNT_INTR_SET_DEFAULT (0x0ul) /**< Default value for INTR_SET register */
#define CY_TCPWM_CNT_INTR_MASK_DEFAULT (0x0ul) /**< Default value for INTR_MASK register */
/** \} group_tcpwm_reg_const */
#define CY_TCPWM_CNT_STATUS_UP_POS (0x1ul) /**< Position of Up counting counter status */
#define CY_TCPWM_CNT_UP_INIT_VAL (0x0ul) /**< Initial value for the counter in the Up counting mode */
#define CY_TCPWM_CNT_UP_DOWN_INIT_VAL (0x1ul) /**< Initial value for the counter in the Up/Down counting modes */
/* Default value of TCPWM registers*/
#define CY_TCPWM_GRP_CNT_CTRL_DEFAULT (0x000000f0ul)
#define CY_TCPWM_GRP_CNT_COUNTER_DEFAULT (0x00000000ul)
#define CY_TCPWM_GRP_CNT_CC0_DEFAULT (0xfffffffful)
#define CY_TCPWM_GRP_CNT_CC0_BUFF_DEFAULT (0xfffffffful)
#define CY_TCPWM_GRP_CNT_CC1_DEFAULT (0xfffffffful)
#define CY_TCPWM_GRP_CNT_CC1_BUFF_DEFAULT (0xfffffffful)
#define CY_TCPWM_GRP_CNT_PERIOD_DEFAULT (0xfffffffful)
#define CY_TCPWM_GRP_CNT_PERIOD_BUFF_DEFAULT (0xfffffffful)
#define CY_TCPWM_GRP_CNT_DT_DEFAULT (0x00000000ul)
#define CY_TCPWM_GRP_CNT_TR_IN_SEL0_DEFAULT (0x00000100ul)
#define CY_TCPWM_GRP_CNT_TR_IN_SEL1_DEFAULT (0x00000000ul)
#define CY_TCPWM_GRP_CNT_TR_IN_EDGE_SEL_DEFAULT (0x0000fffful)
#define CY_TCPWM_GRP_CNT_TR_PWM_CTRL_DEFAULT (0x000000fful)
#define CY_TCPWM_GRP_CNT_TR_OUT_SEL_DEFAULT (0x00000032ul)
#define CY_TCPWM_GRP_CNT_INTR_DEFAULT (0x00000000ul)
#define CY_TCPWM_GRP_CNT_INTR_SET_DEFAULT (0x00000000ul)
#define CY_TCPWM_GRP_CNT_INTR_MASK_DEFAULT (0x00000000ul)
/** \} group_tcpwm_macro */
/**
* \addtogroup group_tcpwm_enum
* \{
*/
/**
* \defgroup group_tcpwm_input_selection Input Selection
* \{
* Configures TCPWM inputs triggers
*/
/**
*****************************************************************************
** \brief Selects which input to use
*****************************************************************************/
typedef enum cy_en_tcpwm_input_selection
{
CY_TCPWM_INPUT0 = 0u, /**< Input is tied to logic 0 */
CY_TCPWM_INPUT1 = 1u, /**< Input is tied to logic 1 */
CY_TCPWM_INPUT_TRIG0 = 2u, /**< Input is connected to the trigger input 0 */
CY_TCPWM_INPUT_TRIG1 = 3u, /**< Input is connected to the trigger input 1 */
CY_TCPWM_INPUT_TRIG2 = 4u, /**< Input is connected to the trigger input 2 */
CY_TCPWM_INPUT_TRIG3 = 5u, /**< Input is connected to the trigger input 3 */
CY_TCPWM_INPUT_TRIG4 = 6u, /**< Input is connected to the trigger input 4 */
CY_TCPWM_INPUT_TRIG5 = 7u, /**< Input is connected to the trigger input 5 */
CY_TCPWM_INPUT_TRIG6 = 8u, /**< Input is connected to the trigger input 6 */
CY_TCPWM_INPUT_TRIG7 = 9u, /**< Input is connected to the trigger input 7 */
CY_TCPWM_INPUT_TRIG8 = 10u, /**< Input is connected to the trigger input 8 */
CY_TCPWM_INPUT_TRIG9 = 11u, /**< Input is connected to the trigger input 9 */
CY_TCPWM_INPUT_TRIG10 = 12u, /**< Input is connected to the trigger input 10 */
CY_TCPWM_INPUT_TRIG11 = 13u, /**< Input is connected to the trigger input 11 */
CY_TCPWM_INPUT_TRIG12 = 14u, /**< Input is connected to the trigger input 12 */
CY_TCPWM_INPUT_TRIG13 = 15u /**< Input is connected to the trigger input 13 */
} cy_en_tcpwm_input_selection_t;
/** \} group_tcpwm_input_selection */
/**
* \defgroup group_tcpwm_input_modes Input Modes
* \{
* Configures how TCPWM inputs behave
*/
/**
*****************************************************************************
** \brief Configures how TCPWM inputs behave
*****************************************************************************/
typedef enum cy_en_tcpwm_input_modes
{
CY_TCPWM_INPUT_RISING_EDGE = 0u, /**< A rising edge triggers the event (Capture, Start, Reload, etc..) */
CY_TCPWM_INPUT_FALLING_EDGE = 1u, /**< A falling edge triggers the event (Capture, Start, Reload, etc..) */
CY_TCPWM_INPUT_BOTH_EDGES = 2u, /**< A rising edge or falling edge triggers the event (Capture, Start, Reload, etc..) */
CY_TCPWM_INPUT_LEVEL = 3u /**< The event is triggered each edge of the TCPWM clock if the input is high */
} cy_en_tcpwm_input_modes_t ;
/** \} group_tcpwm_input_modes */
/**
* \defgroup group_tcpwm_interrupt_sources Interrupt Sources
* \{
* Interrupt Sources
*/
/**
*****************************************************************************
** \brief Configures Interrupt Sources
*****************************************************************************/
typedef enum cy_en_tcpwm_interrupt_sources
{
CY_TCPWM_INT_NONE = 0u, /**< None of Interrupt */
CY_TCPWM_INT_ON_TC = 1u, /**< Interrupt on Terminal count(TC) */
CY_TCPWM_INT_ON_CC = 2u, /**< Interrupt on Compare/Capture(CC) */
CY_TCPWM_INT_ON_TC_OR_CC = 3u /**< Interrupt on TC or CC */
} cy_en_tcpwm_interrupt_sources_t ;
/** \} group_tcpwm_interrupt_sources */
/** \defgroup group_tcpwm_clk_prescalers Counter CLK Prescaler values
* \{
* Clock prescaler values.
*/
/**
*****************************************************************************
** \brief Configures Counter Clock Prescalar
*****************************************************************************/
typedef enum cy_en_tcpwm_clk_prescalers
{
CY_TCPWM_PRESCALER_DIVBY_1 = 0u, /**< Divide by 1 */
CY_TCPWM_PRESCALER_DIVBY_2 = 1u, /**< Divide by 2 */
CY_TCPWM_PRESCALER_DIVBY_4 = 2u, /**< Divide by 4 */
CY_TCPWM_PRESCALER_DIVBY_8 = 3u, /**< Divide by 8 */
CY_TCPWM_PRESCALER_DIVBY_16 = 4u, /**< Divide by 16 */
CY_TCPWM_PRESCALER_DIVBY_32 = 5u, /**< Divide by 32 */
CY_TCPWM_PRESCALER_DIVBY_64 = 6u, /**< Divide by 64 */
CY_TCPWM_PRESCALER_DIVBY_128 = 7u, /**< Divide by 128 */
} cy_en_tcpwm_clk_prescalers_t;
/** \} group_tcpwm_clk_prescalers */
/** \defgroup group_tcpwm_counter_output_trigger Counter CLK Prescalers
* \{
* The trig_output selection.
*/
/**
*****************************************************************************
** \brief Configures Counter Output Trigger
*****************************************************************************/
typedef enum cy_en_tcpwm_counter_trig_out_sel
{
CY_TCPWM_COUNTER_OVERFLOW = 0u, /**< An overflow event */
CY_TCPWM_COUNTER_UNDERFLOW = 1u, /**< An underflow event */
CY_TCPWM_COUNTER_TERMINAL_COUNT = 2u, /**< A terminal count event */
CY_TCPWM_COUNTER_CC0_MATCH = 3u, /**< A cc0_match event */
CY_TCPWM_COUNTER_CC1_MATCH = 4u, /**< A cc1_match event */
CY_TCPWM_COUNTER_LINE_OUT = 5u, /**< PWM output signal line_out */
CY_TCPWM_COUNTER_DISABLED = 7u, /**< Output trigger disabled */
} cy_en_tcpwm_counter_trig_out_sel_t;
/** \} group_tcpwm_counter_output_trigger */
/** \} group_tcpwm_enum */
/*******************************************************************************
* Function Prototypes
*******************************************************************************/
/**
* \addtogroup group_tcpwm_functions
* \{
*/
extern void Cy_Tcpwm_TriggerStart(volatile stc_TCPWM_GRP_CNT_t *ptscTCPWM);
extern void Cy_Tcpwm_TriggerReloadOrIndex(volatile stc_TCPWM_GRP_CNT_t *ptscTCPWM);
extern void Cy_Tcpwm_TriggerStopOrKill(volatile stc_TCPWM_GRP_CNT_t *ptscTCPWM);
extern void Cy_Tcpwm_TriggerCapture0(volatile stc_TCPWM_GRP_CNT_t *ptscTCPWM);
extern void Cy_Tcpwm_TriggerCapture1(volatile stc_TCPWM_GRP_CNT_t *ptscTCPWM);
extern uint32_t Cy_Tcpwm_GetInterruptStatus(volatile stc_TCPWM_GRP_CNT_t *ptscTCPWM);
extern void Cy_Tcpwm_ClearInterrupt(volatile stc_TCPWM_GRP_CNT_t *ptscTCPWM, uint32_t source);
extern void Cy_Tcpwm_SetInterrupt(volatile stc_TCPWM_GRP_CNT_t *ptscTCPWM, uint32_t source);
extern void Cy_Tcpwm_SetInterruptMask(volatile stc_TCPWM_GRP_CNT_t *ptscTCPWM, uint32_t mask);
extern uint32_t Cy_Tcpwm_GetInterruptMask(volatile stc_TCPWM_GRP_CNT_t *ptscTCPWM);
extern uint32_t Cy_Tcpwm_GetInterruptStatusMasked(volatile stc_TCPWM_GRP_CNT_t *ptscTCPWM);
/** \} group_tcpwm_functions */
/** \} group_tcpwm */
#if defined(__cplusplus)
}
#endif
#endif /* CY_TCPWM_H */
/* [] END OF FILE */
@@ -0,0 +1,816 @@
/***************************************************************************//**
* \file tcpwm_counter.c
* \version 1.0
*
* \brief
* The source file of the tcpwm driver.
*
********************************************************************************
* \copyright
* Copyright 2016, Cypress Semiconductor Corporation. All rights reserved.
* You may use this file only in accordance with the license, terms, conditions,
* disclaimers, and limitations in the end user license agreement accompanying
* the software package with which this file was provided.
*******************************************************************************/
#include "cy_tcpwm_counter.h"
#if defined(__cplusplus)
extern "C" {
#endif
/*******************************************************************************
* Function Name: Cy_Tcpwm_Counter_Init
****************************************************************************//**
*
* \brief Initializes the TCPWM for the Counter operation.
*
* \param ptscTCPWM : The pointer to a counter instance.
* Group0 - 16-bit timer(63 counters, 0-62)
* Group1 - 16-bit timer with motor control(12 counters, 0-11)
* Group2 - 32-bit timer(4 counters, 0-3)
*(Ex - TCPWM0_GRP0_CNT34 = Group0 is selected and its 34th counter is in use)
* \param config :The pointer to configuration structure see \ref cy_stc_tcpwm_counter_config_t.
*
* \return CY_RET_SUCCESS : Configuration completed successfully
* CY_RET_BAD_PARAM : One or more invalid parameters
*
*******************************************************************************/
uint32_t Cy_Tcpwm_Counter_Init(volatile stc_TCPWM_GRP_CNT_t *ptscTCPWM, cy_stc_tcpwm_counter_config_t const *config)
{
uint32_t status = CY_RET_BAD_PARAM;
if (config->trigger0EventCfg > 0x04ul || config->trigger1EventCfg > 0x04ul)
{
return status;
}
if ((NULL != ptscTCPWM) && (NULL != config))
{
un_TCPWM_GRP_CNT_CTRL_t workCTRL = { .u32Register = 0ul };
workCTRL.stcField.u1ONE_SHOT = config->runMode;
workCTRL.stcField.u2UP_DOWN_MODE = config->countDirection;
workCTRL.stcField.u3MODE = config->compareOrCapture;
workCTRL.stcField.u1DBG_FREEZE_EN = config->debug_pause;
workCTRL.stcField.u1AUTO_RELOAD_CC0 = config->enableCompare0Swap;
workCTRL.stcField.u1AUTO_RELOAD_CC1 = config->enableCompare1Swap;
ptscTCPWM->unCTRL.u32Register = workCTRL.u32Register;
ptscTCPWM->unDT.stcField.u8DT_LINE_OUT_L = config->clockPrescaler;
// Need to check (AKSF)
if (CY_TCPWM_COUNTER_ONESHOT == config->runMode)
{
if (CY_TCPWM_COUNTER_COUNT_UP == config->countDirection)
{
ptscTCPWM->unCOUNTER.u32Register = CY_TCPWM_CNT_UP_INIT_VAL;
}
else if (CY_TCPWM_COUNTER_COUNT_DOWN == config->countDirection)
{
ptscTCPWM->unCOUNTER.u32Register = config->period;
}
}
else
{
ptscTCPWM->unCOUNTER.u32Register = CY_TCPWM_CNT_UP_DOWN_INIT_VAL;
}
ptscTCPWM->unCC0.u32Register = config->compare0;
// Should not be set here (YOTS)
ptscTCPWM->unCC0_BUFF.u32Register = config->compare0_buff;
ptscTCPWM->unCC1.u32Register = config->compare1;
// Should not be set here (YOTS)
ptscTCPWM->unCC1_BUFF.u32Register = config->compare1_buff;
ptscTCPWM->unPERIOD.u32Register = config->period;
un_TCPWM_GRP_CNT_TR_IN_SEL0_t workTR_IN_SEL0 = {.u32Register = 0ul};
workTR_IN_SEL0.stcField.u8CAPTURE0_SEL = config->capture0Input;
workTR_IN_SEL0.stcField.u8RELOAD_SEL = config->reloadInput;
workTR_IN_SEL0.stcField.u8STOP_SEL = config->stopInput;
workTR_IN_SEL0.stcField.u8COUNT_SEL = config->countInput;
ptscTCPWM->unTR_IN_SEL0.u32Register = workTR_IN_SEL0.u32Register;
un_TCPWM_GRP_CNT_TR_IN_SEL1_t workTR_IN_SEL1 = {.u32Register = 0ul};
workTR_IN_SEL1.stcField.u8START_SEL = config->startInput;
workTR_IN_SEL1.stcField.u8CAPTURE1_SEL = config->capture1Input;
ptscTCPWM->unTR_IN_SEL1.u32Register = workTR_IN_SEL1.u32Register;
un_TCPWM_GRP_CNT_TR_IN_EDGE_SEL_t workTR_IN_EDGE_SEL = {.u32Register = 0ul};
workTR_IN_EDGE_SEL.stcField.u2CAPTURE0_EDGE = config->capture0InputMode;
workTR_IN_EDGE_SEL.stcField.u2CAPTURE1_EDGE = config->capture1InputMode;
workTR_IN_EDGE_SEL.stcField.u2RELOAD_EDGE = config->reloadInputMode;
workTR_IN_EDGE_SEL.stcField.u2START_EDGE = config->startInputMode;
workTR_IN_EDGE_SEL.stcField.u2STOP_EDGE = config->stopInputMode;
workTR_IN_EDGE_SEL.stcField.u2COUNT_EDGE = config->countInputMode;
ptscTCPWM->unTR_IN_EDGE_SEL.u32Register = workTR_IN_EDGE_SEL.u32Register;
un_TCPWM_GRP_CNT_TR_OUT_SEL_t workTR_OUT_SEL = {.u32Register = 0ul};
workTR_OUT_SEL.stcField.u3OUT0 = config->trigger0EventCfg;
workTR_OUT_SEL.stcField.u3OUT1 = config->trigger1EventCfg;
ptscTCPWM->unTR_OUT_SEL.u32Register = workTR_OUT_SEL.u32Register;
ptscTCPWM->unINTR_MASK.u32Register = config->interruptSources;
status = CY_RET_SUCCESS;
}
return(status);
}
/*******************************************************************************
* Function Name: Cy_Tcpwm_Counter_DeInit
****************************************************************************//**
*
* \breif De-initializes the TCPWM block, returns register values to default.
*
* \param ptscTCPWM : The pointer to a counter instance.
* Group0 - 16-bit timer(63 counters, 0-62)
* Group1 - 16-bit timer with motor control(12 counters, 0-11)
* Group2 - 32-bit timer(4 counters, 0-3)
*(Ex - TCPWM0_GRP0_CNT34 = Group0 is selected and its 34th counter is in use)
* \return None
*
*******************************************************************************/
void Cy_Tcpwm_Counter_DeInit(volatile stc_TCPWM_GRP_CNT_t *ptscTCPWM)
{
ptscTCPWM->unCTRL.u32Register = CY_TCPWM_GRP_CNT_CTRL_DEFAULT;
ptscTCPWM->unCOUNTER.u32Register = CY_TCPWM_GRP_CNT_COUNTER_DEFAULT;
ptscTCPWM->unCC0.u32Register = CY_TCPWM_GRP_CNT_CC0_DEFAULT;
ptscTCPWM->unCC0_BUFF.u32Register = CY_TCPWM_GRP_CNT_CC0_BUFF_DEFAULT;
ptscTCPWM->unCC1.u32Register = CY_TCPWM_GRP_CNT_CC1_DEFAULT;
ptscTCPWM->unCC1_BUFF.u32Register = CY_TCPWM_GRP_CNT_CC1_BUFF_DEFAULT;
ptscTCPWM->unPERIOD.u32Register = CY_TCPWM_GRP_CNT_PERIOD_DEFAULT;
ptscTCPWM->unPERIOD_BUFF.u32Register = CY_TCPWM_GRP_CNT_PERIOD_BUFF_DEFAULT;
ptscTCPWM->unTR_IN_SEL0.u32Register = CY_TCPWM_GRP_CNT_TR_IN_SEL0_DEFAULT;
ptscTCPWM->unTR_IN_SEL1.u32Register = CY_TCPWM_GRP_CNT_TR_IN_SEL1_DEFAULT;
ptscTCPWM->unTR_IN_EDGE_SEL.u32Register = CY_TCPWM_GRP_CNT_TR_IN_EDGE_SEL_DEFAULT;
ptscTCPWM->unTR_OUT_SEL.u32Register = CY_TCPWM_GRP_CNT_TR_OUT_SEL_DEFAULT;
ptscTCPWM->unTR_PWM_CTRL.u32Register = CY_TCPWM_GRP_CNT_TR_PWM_CTRL_DEFAULT;
ptscTCPWM->unINTR.u32Register = CY_TCPWM_GRP_CNT_INTR_DEFAULT;
ptscTCPWM->unINTR_SET.u32Register = CY_TCPWM_GRP_CNT_INTR_SET_DEFAULT;
ptscTCPWM->unINTR_MASK.u32Register = CY_TCPWM_GRP_CNT_INTR_MASK_DEFAULT;
}
/*******************************************************************************
* Function Name: Cy_Tcpwm_Counter_Enable
****************************************************************************//**
*
* \brief Enables the TCPWM block for the Counter operation.
*
* \param ptscTCPWM : The pointer to a counter instance.
* Group0 - 16-bit timer(63 counters, 0-62)
* Group1 - 16-bit timer with motor control(12 counters, 0-11)
* Group2 - 32-bit timer(4 counters, 0-3)
*(Ex - TCPWM0_GRP0_CNT34 = Group0 is selected and its 34th counter is in use)
*
* \return None
*
*******************************************************************************/
void Cy_Tcpwm_Counter_Enable(volatile stc_TCPWM_GRP_CNT_t *ptscTCPWM)
{
ptscTCPWM->unCTRL.stcField.u1ENABLED = 0x1ul;
}
/*******************************************************************************
* Function Name: Cy_Tcpwm_Counter_Disable
****************************************************************************//**
*
* \brief Disables the TCPWM block.
*
* \param ptscTCPWM : The pointer to a counter instance.
* Group0 - 16-bit timer(63 counters, 0-62)
* Group1 - 16-bit timer with motor control(12 counters, 0-11)
* Group2 - 32-bit timer(4 counters, 0-3)
*(Ex - TCPWM0_GRP0_CNT34 = Group0 is selected and its 34th counter is in use)
*
* \return None
*
*******************************************************************************/
void Cy_Tcpwm_Counter_Disable(volatile stc_TCPWM_GRP_CNT_t *ptscTCPWM)
{
ptscTCPWM->unCTRL.stcField.u1ENABLED = 0x0ul;
}
/*******************************************************************************
* Function Name: Cy_Tcpwm_Counter_GetStatus
****************************************************************************//**
*
* \brief Returns the status of the Counter Timer.
*
* \param ptscTCPWM : The pointer to a counter instance.
* Group0 - 16-bit timer(63 counters, 0-62)
* Group1 - 16-bit timer with motor control(12 counters, 0-11)
* Group2 - 32-bit timer(4 counters, 0-3)
*(Ex - TCPWM0_GRP0_CNT34 = Group0 is selected and its 34th counter is in use)
*
* \return The status, see \ref group_tcpwm_counter_status
*
*******************************************************************************/
uint32_t Cy_Tcpwm_Counter_GetStatus(volatile stc_TCPWM_GRP_CNT_t *ptscTCPWM)
{
return(ptscTCPWM->unSTATUS.u32Register);
}
/*******************************************************************************
* Function Name: Cy_Tcpwm_Counter_GetCapture0
****************************************************************************//**
*
* \brief Returns the capture0 value when the capture mode is enabled.
*
* \param ptscTCPWM : The pointer to a counter instance.
* Group0 - 16-bit timer(63 counters, 0-62)
* Group1 - 16-bit timer with motor control(12 counters, 0-11)
* Group2 - 32-bit timer(4 counters, 0-3)
*(Ex - TCPWM0_GRP0_CNT34 = Group0 is selected and its 34th counter is in use)
*
* \return The capture value.
*
*******************************************************************************/
uint32_t Cy_Tcpwm_Counter_GetCapture0(volatile stc_TCPWM_GRP_CNT_t *ptscTCPWM)
{
return(ptscTCPWM->unCC0.u32Register);
}
/*******************************************************************************
* Function Name: Cy_Tcpwm_Counter_GetCapture1
****************************************************************************//**
*
* \brief Returns the capture1 value when the capture mode is enabled.
*
* \param ptscTCPWM : The pointer to a counter instance.
* Group0 - 16-bit timer(63 counters, 0-62)
* Group1 - 16-bit timer with motor control(12 counters, 0-11)
* Group2 - 32-bit timer(4 counters, 0-3)
*(Ex - TCPWM0_GRP0_CNT34 = Group0 is selected and its 34th counter is in use)
* \return The capture value.
*
*******************************************************************************/
uint32_t Cy_Tcpwm_Counter_GetCapture1(volatile stc_TCPWM_GRP_CNT_t *ptscTCPWM)
{
return(ptscTCPWM->unCC1.u32Register);
}
/*******************************************************************************
* Function Name: Cy_Tcpwm_Counter_GetCapture0Buf
****************************************************************************//**
*
* \brief Returns the buffered capture0 value when the capture mode is enabled.
*
* \param ptscTCPWM : The pointer to a counter instance.
* Group0 - 16-bit timer(63 counters, 0-62)
* Group1 - 16-bit timer with motor control(12 counters, 0-11)
* Group2 - 32-bit timer(4 counters, 0-3)
*(Ex - TCPWM0_GRP0_CNT34 = Group0 is selected and its 34th counter is in use)
*
* \return The buffered capture value.
*
*******************************************************************************/
uint32_t Cy_Tcpwm_Counter_GetCapture0Buf(volatile stc_TCPWM_GRP_CNT_t *ptscTCPWM)
{
// Need to check this function makes sense (YOTS).
return(ptscTCPWM->unCC0_BUFF.u32Register);
}
/*******************************************************************************
* Function Name: Cy_Tcpwm_Counter_GetCapture1Buf
****************************************************************************//**
*
* \brief Returns the buffered capture1 value when the capture mode is enabled.
*
* \param ptscTCPWM : The pointer to a counter instance.
* Group0 - 16-bit timer(63 counters, 0-62)
* Group1 - 16-bit timer with motor control(12 counters, 0-11)
* Group2 - 32-bit timer(4 counters, 0-3)
*(Ex - TCPWM0_GRP0_CNT34 = Group0 is selected and its 34th counter is in use)
*
* \return The buffered capture value.
*
*******************************************************************************/
uint32_t Cy_Tcpwm_Counter_GetCapture1Buf(volatile stc_TCPWM_GRP_CNT_t *ptscTCPWM)
{
// Need to check this function makes sense (YOTS).
return(ptscTCPWM->unCC1_BUFF.u32Register);
}
/*******************************************************************************
* Function Name: Cy_Tcpwm_Counter_SetCompare0
****************************************************************************//**
*
* \brief Sets the compare0 value for Compare0 when the compare mode is enabled.
*
* \param ptscTCPWM : The pointer to a counter instance.
* Group0 - 16-bit timer(63 counters, 0-62)
* Group1 - 16-bit timer with motor control(12 counters, 0-11)
* Group2 - 32-bit timer(4 counters, 0-3)
*(Ex - TCPWM0_GRP0_CNT34 = Group0 is selected and its 34th counter is in use)
* compare0 : The compare value - 0 value.
*
* \return None
*
*******************************************************************************/
void Cy_Tcpwm_Counter_SetCompare0(volatile stc_TCPWM_GRP_CNT_t *ptscTCPWM, uint32_t compare0)
{
ptscTCPWM->unCC0.u32Register = compare0;
}
/*******************************************************************************
* Function Name: Cy_Tcpwm_Counter_GetCompare0
****************************************************************************//**
*
* \brief Returns compare0 value 0.
*
* \param ptscTCPWM : The pointer to a counter instance.
* Group0 - 16-bit timer(63 counters, 0-62)
* Group1 - 16-bit timer with motor control(12 counters, 0-11)
* Group2 - 32-bit timer(4 counters, 0-3)
*(Ex - TCPWM0_GRP0_CNT34 = Group0 is selected and its 34th counter is in use)
*
* \return Compare value 0.
*
*******************************************************************************/
uint32_t Cy_Tcpwm_Counter_GetCompare0(volatile stc_TCPWM_GRP_CNT_t *ptscTCPWM)
{
return(ptscTCPWM->unCC0.u32Register);
}
/*******************************************************************************
* Function Name: Cy_TCPWM_Counter_SetCompare0_Buff
****************************************************************************//**
*
* \brief Sets the compare value for Compare0_Buff when the compare mode is enabled.
*
* \param ptscTCPWM : The pointer to a counter instance.
* Group0 - 16-bit timer(63 counters, 0-62)
* Group1 - 16-bit timer with motor control(12 counters, 0-11)
* Group2 - 32-bit timer(4 counters, 0-3)
*(Ex - TCPWM0_GRP0_CNT34 = Group0 is selected and its 34th counter is in use)
* compare1 : The compare value - the 1 value.
*
* \return None
*
*******************************************************************************/
void Cy_Tcpwm_Counter_SetCompare0_Buff(volatile stc_TCPWM_GRP_CNT_t *ptscTCPWM, uint32_t compare1)
{
ptscTCPWM->unCC0_BUFF.u32Register = compare1;
}
/*******************************************************************************
* Function Name: Cy_Tcpwm_Counter_GetCompare0_Buff
****************************************************************************//**
*
* \brief Returns compare0_Buff value 1.
*
* \param ptscTCPWM : The pointer to a counter instance.
* Group0 - 16-bit timer(63 counters, 0-62)
* Group1 - 16-bit timer with motor control(12 counters, 0-11)
* Group2 - 32-bit timer(4 counters, 0-3)
*(Ex - TCPWM0_GRP0_CNT34 = Group0 is selcted and its 34th counter is in use)
*
* \return Compare value 1.
*
*******************************************************************************/
uint32_t Cy_Tcpwm_Counter_GetCompare0_Buff(volatile stc_TCPWM_GRP_CNT_t *ptscTCPWM)
{
return(ptscTCPWM->unCC0_BUFF.u32Register);
}
/*******************************************************************************
* Function Name: Cy_Tcpwm_Counter_SetCompare1
****************************************************************************//**
*
* \brief Sets the compare1 value for Compare0 when the compare mode is enabled.
*
* \param ptscTCPWM : The pointer to a counter instance.
* Group0 - 16-bit timer(63 counters, 0-62)
* Group1 - 16-bit timer with motor control(12 counters, 0-11)
* Group2 - 32-bit timer(4 counters, 0-3)
*(Ex - TCPWM0_GRP0_CNT34 = Group0 is selected and its 34th counter is in use)
* compare0 : The compare value - 0 value.
*
* \return None
*
*******************************************************************************/
void Cy_Tcpwm_Counter_SetCompare1(volatile stc_TCPWM_GRP_CNT_t *ptscTCPWM, uint32_t compare0)
{
ptscTCPWM->unCC1.u32Register = compare0;
}
/*******************************************************************************
* Function Name: Cy_Tcpwm_Counter_GetCompare1
****************************************************************************//**
*
* \brief Returns compare1 value 0.
*
* \param ptscTCPWM : The pointer to a counter instance.
* Group0 - 16-bit timer(63 counters, 0-62)
* Group1 - 16-bit timer with motor control(12 counters, 0-11)
* Group2 - 32-bit timer(4 counters, 0-3)
*(Ex - TCPWM0_GRP0_CNT34 = Group0 is selected and its 34th counter is in use)
*
* \return Compare value 0.
*
*******************************************************************************/
uint32_t Cy_Tcpwm_Counter_GetCompare1(volatile stc_TCPWM_GRP_CNT_t *ptscTCPWM)
{
return(ptscTCPWM->unCC1.u32Register);
}
/*******************************************************************************
* Function Name: Cy_TCPWM_Counter_SetCompare1_Buff
****************************************************************************//**
*
* \brief Sets the compare value for Compare1_Buff when the compare mode is enabled.
*
* \param ptscTCPWM : The pointer to a counter instance.
* Group0 - 16-bit timer(63 counters, 0-62)
* Group1 - 16-bit timer with motor control(12 counters, 0-11)
* Group2 - 32-bit timer(4 counters, 0-3)
*(Ex - TCPWM0_GRP0_CNT34 = Group0 is selected and its 34th counter is in use)
* compare1 : The compare value - the 1 value.
*
* \return None
*
*******************************************************************************/
void Cy_Tcpwm_Counter_SetCompare1_Buff(volatile stc_TCPWM_GRP_CNT_t *ptscTCPWM, uint32_t compare1)
{
ptscTCPWM->unCC1_BUFF.u32Register = compare1;
}
/*******************************************************************************
* Function Name: Cy_Tcpwm_Counter_GetCompare1_Buff
****************************************************************************//**
*
* \brief Returns compare1_Buff value 1.
*
* \param ptscTCPWM : The pointer to a counter instance.
* Group0 - 16-bit timer(63 counters, 0-62)
* Group1 - 16-bit timer with motor control(12 counters, 0-11)
* Group2 - 32-bit timer(4 counters, 0-3)
*(Ex - TCPWM0_GRP0_CNT34 = Group0 is selcted and its 34th counter is in use)
*
* \return Compare value 1.
*
*******************************************************************************/
uint32_t Cy_Tcpwm_Counter_GetCompare1_Buff(volatile stc_TCPWM_GRP_CNT_t *ptscTCPWM)
{
return(ptscTCPWM->unCC1_BUFF.u32Register);
}
/*******************************************************************************
* Function Name: Cy_Tcpwm_Counter_EnableCompare0Swap
****************************************************************************//**
*
* \brief Enables the comparison swap when the comparison value is true.
*
* \param ptscTCPWM : The pointer to a counter instance.
* Group0 - 16-bit timer(63 counters, 0-62)
* Group1 - 16-bit timer with motor control(12 counters, 0-11)
* Group2 - 32-bit timer(4 counters, 0-3)
*(Ex - TCPWM0_GRP0_CNT34 = Group0 is selected and its 34th counter is in use)
* \param enable : true = swap enabled, false = swap disabled
*
* \return None
*
*******************************************************************************/
void Cy_Tcpwm_Counter_EnableCompare0Swap(volatile stc_TCPWM_GRP_CNT_t *ptscTCPWM, bool enable)
{
if (enable)
{
ptscTCPWM->unCTRL.stcField.u1AUTO_RELOAD_CC0 = 0x1ul;
}
else
{
ptscTCPWM->unCTRL.stcField.u1AUTO_RELOAD_CC0 = 0x0ul;
}
}
/*******************************************************************************
* Function Name: Cy_Tcpwm_Counter_EnableCompare1Swap
****************************************************************************//**
*
* \brief Enables the comparison swap when the comparison value is true.
*
* \param ptscTCPWM : The pointer to a counter instance.
* Group0 - 16-bit timer(63 counters, 0-62)
* Group1 - 16-bit timer with motor control(12 counters, 0-11)
* Group2 - 32-bit timer(4 counters, 0-3)
*(Ex - TCPWM0_GRP0_CNT34 = Group0 is selected and its 34th counter is in use)
* \param enable : true = swap enabled, false = swap disabled
*
* \return None
*
*******************************************************************************/
void Cy_Tcpwm_Counter_EnableCompare1Swap(volatile stc_TCPWM_GRP_CNT_t *ptscTCPWM, bool enable)
{
if (enable)
{
ptscTCPWM->unCTRL.stcField.u1AUTO_RELOAD_CC1 = 0x1ul;
}
else
{
ptscTCPWM->unCTRL.stcField.u1AUTO_RELOAD_CC1 = 0x0ul;
}
}
/*******************************************************************************
* Function Name: Cy_Tcpwm_Counter_SetCounter
****************************************************************************//**
*
* \brief Sets the value of the counter.
*
* \param ptscTCPWM : The pointer to a counter instance.
* Group0 - 16-bit timer(63 counters, 0-62)
* Group1 - 16-bit timer with motor control(12 counters, 0-11)
* Group2 - 32-bit timer(4 counters, 0-3)
*(Ex - TCPWM0_GRP0_CNT34 = Group0 is selected and its 34th counter is in use)
* \param count : The value to write into the counter.
*
* \return None
*
*******************************************************************************/
void Cy_Tcpwm_Counter_SetCounter(volatile stc_TCPWM_GRP_CNT_t *ptscTCPWM, uint32_t count)
{
ptscTCPWM->unCOUNTER.u32Register = count;
}
/*******************************************************************************
* Function Name: Cy_Tcpwm_Counter_GetCounter
****************************************************************************//**
*
* \brief Returns the value in the counter.
*
* \param ptscTCPWM : The pointer to a counter instance.
* Group0 - 16-bit timer(63 counters, 0-62)
* Group1 - 16-bit timer with motor control(12 counters, 0-11)
* Group2 - 32-bit timer(4 counters, 0-3)
*(Ex - TCPWM0_GRP0_CNT34 = Group0 is selected and its 34th counter is in use)
*
* \return The current counter value.
*
*******************************************************************************/
uint32_t Cy_Tcpwm_Counter_GetCounter(volatile stc_TCPWM_GRP_CNT_t *ptscTCPWM)
{
return(ptscTCPWM->unCOUNTER.u32Register);
}
/*******************************************************************************
* Function Name: Cy_TCPWM_Counter_SetPeriod
****************************************************************************//**
*
* \brief Sets the value of the period register.
*
* \param ptscTCPWM : The pointer to a counter instance.
* Group0 - 16-bit timer(63 counters, 0-62)
* Group1 - 16-bit timer with motor control(12 counters, 0-11)
* Group2 - 32-bit timer(4 counters, 0-3)
*(Ex - TCPWM0_GRP0_CNT34 = Group0 is selected and its 34th counter is in use)
* \param period : The value to write into a period.
*
* \return None
*
*******************************************************************************/
void Cy_Tcpwm_Counter_SetPeriod(volatile stc_TCPWM_GRP_CNT_t *ptscTCPWM, uint32_t period)
{
ptscTCPWM->unPERIOD.u32Register = period;
}
/*******************************************************************************
* Function Name: Cy_Tcpwm_Counter_GetPeriod
****************************************************************************//**
*
* \brief Returns the value in the period register.
*
* \param ptscTCPWM : The pointer to a counter instance.
* Group0 - 16-bit timer(63 counters, 0-62)
* Group1 - 16-bit timer with motor control(12 counters, 0-11)
* Group2 - 32-bit timer(4 counters, 0-3)
*(Ex - TCPWM0_GRP0_CNT34 = Group0 is selected and its 34th counter is in use)
*
* \return The current period value.
*
*******************************************************************************/
uint32_t Cy_Tcpwm_Counter_GetPeriod(volatile stc_TCPWM_GRP_CNT_t *ptscTCPWM)
{
return(ptscTCPWM->unPERIOD.u32Register);
}
/*******************************************************************************
* Function Name: Cy_TCPWM_Counter_SetPeriod_Buff
****************************************************************************//**
*
* \brief Sets the value of the period register.
*
* \param ptscTCPWM : The pointer to a counter instance.
* Group0 - 16-bit timer(63 counters, 0-62)
* Group1 - 16-bit timer with motor control(12 counters, 0-11)
* Group2 - 32-bit timer(4 counters, 0-3)
*(Ex - TCPWM0_GRP0_CNT34 = Group0 is selected and its 34th counter is in use)
* period : The value to write into a period.
*
* \return None
*
*******************************************************************************/
void Cy_Tcpwm_Counter_SetPeriod_Buff(volatile stc_TCPWM_GRP_CNT_t *ptscTCPWM, uint32_t period)
{
ptscTCPWM->unPERIOD_BUFF.u32Register = period;
}
/*******************************************************************************
* Function Name: Cy_Tcpwm_Counter_GetPeriod_Buff
****************************************************************************//**
*
* \brief Returns the value in the period register.
*
* \param ptscTCPWM : The pointer to a counter instance.
* Group0 - 16-bit timer(63 counters, 0-62)
* Group1 - 16-bit timer with motor control(12 counters, 0-11)
* Group2 - 32-bit timer(4 counters, 0-3)
*(Ex - TCPWM0_GRP0_CNT34 = Group0 is selected and its 34th counter is in use)
*
* \return The current period value.
*
*******************************************************************************/
uint32_t Cy_Tcpwm_Counter_GetPeriod_Buff(volatile stc_TCPWM_GRP_CNT_t *ptscTCPWM)
{
return(ptscTCPWM->unPERIOD_BUFF.u32Register);
}
/*******************************************************************************
* Function Name: Cy_Tcpwm_Counter_SetTC_IntrMask
****************************************************************************//**
*
* \brief Set TC interrupt mask.
*
* \param ptscTCPWM : The pointer to a counter instance.
* Group0 - 16-bit timer(63 counters, 0-62)
* Group1 - 16-bit timer with motor control(12 counters, 0-11)
* Group2 - 32-bit timer(4 counters, 0-3)
*(Ex - TCPWM0_GRP0_CNT34 = Group0 is selected and its 34th counter is in use)
*
*******************************************************************************/
void Cy_Tcpwm_Counter_SetTC_IntrMask(volatile stc_TCPWM_GRP_CNT_t *ptscTCPWM)
{
ptscTCPWM->unINTR_MASK.stcField.u1TC = 1ul;
}
/*******************************************************************************
* Function Name: Cy_Tcpwm_Counter_SetCC0_IntrMask
****************************************************************************//**
*
* \brief Set CCO interrupt mask.
*
* \param ptscTCPWM : The pointer to a counter instance.
* Group0 - 16-bit timer(63 counters, 0-62)
* Group1 - 16-bit timer with motor control(12 counters, 0-11)
* Group2 - 32-bit timer(4 counters, 0-3)
*(Ex - TCPWM0_GRP0_CNT34 = Group0 is selcted and its 34th counter is in use)
*
*******************************************************************************/
void Cy_Tcpwm_Counter_SetCC0_IntrMask(volatile stc_TCPWM_GRP_CNT_t *ptscTCPWM)
{
ptscTCPWM->unINTR_MASK.stcField.u1CC0_MATCH = 0x1ul;
}
/*******************************************************************************
* Function Name: Cy_Tcpwm_Counter_SetCC1_IntrMask
****************************************************************************//**
*
* \brief Set CC1 interrupt mask.
*
* \param ptscTCPWM : The pointer to a counter instance.
* Group0 - 16-bit timer(63 counters, 0-62)
* Group1 - 16-bit timer with motor control(12 counters, 0-11)
* Group2 - 32-bit timer(4 counters, 0-3)
*(Ex - TCPWM0_GRP0_CNT34 = Group0 is selected and its 34th counter is in use)
*
*******************************************************************************/
void Cy_Tcpwm_Counter_SetCC1_IntrMask(volatile stc_TCPWM_GRP_CNT_t *ptscTCPWM)
{
ptscTCPWM->unINTR_MASK.stcField.u1CC1_MATCH = 0x1ul;
}
/*******************************************************************************
* Function Name: Cy_Tcpwm_Counter_GetTC_IntrMasked
****************************************************************************//**
*
* \brief Get TC interrupt masked.
*
* \param ptscTCPWM : The pointer to a counter instance.
* Group0 - 16-bit timer(63 counters, 0-62)
* Group1 - 16-bit timer with motor control(12 counters, 0-11)
* Group2 - 32-bit timer(4 counters, 0-3)
*(Ex - TCPWM0_GRP0_CNT34 = Group0 is selected and its 34th counter is in use)
*
*******************************************************************************/
uint8_t Cy_Tcpwm_Counter_GetTC_IntrMasked(volatile stc_TCPWM_GRP_CNT_t *ptscTCPWM)
{
return (uint8_t)(ptscTCPWM->unINTR_MASKED.stcField.u1TC);
}
/*******************************************************************************
* Function Name: Cy_Tcpwm_Counter_GetCC0_IntrMasked
****************************************************************************//**
*
* \brief Get CC0 interrupt masked.
*
* \param ptscTCPWM : The pointer to a counter instance.
* Group0 - 16-bit timer(63 counters, 0-62)
* Group1 - 16-bit timer with motor control(12 counters, 0-11)
* Group2 - 32-bit timer(4 counters, 0-3)
*(Ex - TCPWM0_GRP0_CNT34 = Group0 is selected and its 34th counter is in use)
*
*******************************************************************************/
uint8_t Cy_Tcpwm_Counter_GetCC0_IntrMasked(volatile stc_TCPWM_GRP_CNT_t *ptscTCPWM)
{
return (uint8_t)(ptscTCPWM->unINTR_MASKED.stcField.u1CC0_MATCH);
}
/*******************************************************************************
* Function Name: Cy_Tcpwm_Counter_GetCC1_IntrMasked
****************************************************************************//**
*
* \brief Get CC1 interrupt masked.
*
* \param ptscTCPWM : The pointer to a counter instance.
* Group0 - 16-bit timer(63 counters, 0-62)
* Group1 - 16-bit timer with motor control(12 counters, 0-11)
* Group2 - 32-bit timer(4 counters, 0-3)
*(Ex - TCPWM0_GRP0_CNT34 = Group0 is selected and its 34th counter is in use)
*
*******************************************************************************/
uint8_t Cy_Tcpwm_Counter_GetCC1_IntrMasked(volatile stc_TCPWM_GRP_CNT_t *ptscTCPWM)
{
return (uint8_t)(ptscTCPWM->unINTR_MASKED.stcField.u1CC1_MATCH);
}
/*******************************************************************************
* Function Name: Cy_Tcpwm_Counter_ClearTC_Intr
****************************************************************************//**
*
* \brief Clear TC interrupt.
*
* \param ptscTCPWM : The pointer to a counter instance.
* Group0 - 16-bit timer(63 counters, 0-62)
* Group1 - 16-bit timer with motor control(12 counters, 0-11)
* Group2 - 32-bit timer(4 counters, 0-3)
*(Ex - TCPWM0_GRP0_CNT34 = Group0 is selected and its 34th counter is in use)
*
*******************************************************************************/
void Cy_Tcpwm_Counter_ClearTC_Intr(volatile stc_TCPWM_GRP_CNT_t *ptscTCPWM)
{
ptscTCPWM->unINTR.stcField.u1TC = 1ul;
ptscTCPWM->unINTR.u32Register;
}
/*******************************************************************************
* Function Name: Cy_Tcpwm_Counter_ClearCC0_Intr
****************************************************************************//**
*
* \brief Clear CC0 interrupt.
*
* \param ptscTCPWM : The pointer to a counter instance.
* Group0 - 16-bit timer(63 counters, 0-62)
* Group1 - 16-bit timer with motor control(12 counters, 0-11)
* Group2 - 32-bit timer(4 counters, 0-3)
*(Ex - TCPWM0_GRP0_CNT34 = Group0 is selected and its 34th counter is in use)
*
*******************************************************************************/
void Cy_Tcpwm_Counter_ClearCC0_Intr(volatile stc_TCPWM_GRP_CNT_t *ptscTCPWM)
{
ptscTCPWM->unINTR.stcField.u1CC0_MATCH = 1ul;
ptscTCPWM->unINTR.u32Register;
}
/*******************************************************************************
* Function Name: Cy_Tcpwm_Counter_ClearCC1_Intr
****************************************************************************//**
*
* \brief Clear CC1 interrupt.
*
* \param ptscTCPWM : The pointer to a counter instance.
* Group0 - 16-bit timer(63 counters, 0-62)
* Group1 - 16-bit timer with motor control(12 counters, 0-11)
* Group2 - 32-bit timer(4 counters, 0-3)
*(Ex - TCPWM0_GRP0_CNT34 = Group0 is selected and its 34th counter is in use)
*
*******************************************************************************/
void Cy_Tcpwm_Counter_ClearCC1_Intr(volatile stc_TCPWM_GRP_CNT_t *ptscTCPWM)
{
ptscTCPWM->unINTR.stcField.u1CC1_MATCH = 1ul;
ptscTCPWM->unINTR.u32Register;
}
#if defined(__cplusplus)
}
#endif
/* [] END OF FILE */
@@ -0,0 +1,184 @@
/***************************************************************************//**
* \file tcpwm_counter.h
* \version 1.0
*
* \brief
* The header file of the TCPWM Timer Counter driver.
*
********************************************************************************
* \copyright
* Copyright 2016, Cypress Semiconductor Corporation. All rights reserved.
* You may use this file only in accordance with the license, terms, conditions,
* disclaimers, and limitations in the end user license agreement accompanying
* the software package with which this file was provided.
*******************************************************************************/
#if !defined(CY_TCPWM_COUNTER_H)
#define CY_TCPWM_COUNTER_H
#include "cy_tcpwm.h"
#if defined(__cplusplus)
extern "C" {
#endif
/**
* \addtogroup group_tcpwm_counter
* \{
*/
/**
* \addtogroup group_tcpwm_counter_macro
* \{
*/
/** \defgroup group_tcpwm_counter_status Counter Status
* \{
* The counter status.
*/
#define CY_TCPWM_COUNTER_STATUS_DOWN_COUNTING (0x1uL) /**< Timer/Counter is down counting */
#define CY_TCPWM_COUNTER_STATUS_UP_COUNTING (0x2uL) /**< Timer/Counter is up counting */
/**< Timer/Counter the counter is running */
#define CY_TCPWM_COUNTER_STATUS_COUNTER_RUNNING (TCPWM_CNT_STATUS_RUNNING_Msk)
/** \} group_tcpwm_counter_status */
/** \} group_tcpwm_counter_macro */
/**
* \addtogroup group_tcpwm_counter_enum
* \{
*/
/** \defgroup group_tcpwm_counter_run_modes Counter run modes
* \{
* Run modes for the counter.
*/
typedef enum cy_en_tcpwm_counter_run_modes
{
CY_TCPWM_COUNTER_CONTINUOUS = 0u, /**< Counter runs forever */
CY_TCPWM_COUNTER_ONESHOT = 1u, /**< Counter runs once and then stops */
} cy_en_tcpwm_counter_run_modes_t;
/** \} cy_en_tcpwm_counter_run_modes */
/** \defgroup group_tcpwm_counter_modes Counter modes
* \{
* Sets the counter modes.
*/
typedef enum group_tcpwm_counter_modes
{
CY_TCPWM_COUNTER_COUNT_UP = 0u, /**< Counter counts up */
CY_TCPWM_COUNTER_COUNT_DOWN = 1u, /**< Counter counts down */
CY_TCPWM_COUNTER_COUNT_UP_DOWN1 = 2u, /**< Counter counts up and down terminal count only occurs on underflow */
CY_TCPWM_COUNTER_COUNT_UP_DOWN2 = 3u, /**< Counter counts up and down terminal count occurs on both overflow and underflow */
} cy_en_tcpwm_counter_modes_t;
/** \} group_tcpwm_counter_modes */
/** \defgroup group_tcpwm_counter_compare_capture Counter Compare Capture
* \{
* A compare or capture mode.
*/
typedef enum cy_en_tcpwm_counter_cc_mode
{
CY_TCPWM_COUNTER_MODE_CAPTURE = 2u, /**< Timer/Counter is in Capture Mode */
CY_TCPWM_COUNTER_MODE_COMPARE = 0u, /**< Timer/Counter is in Compare Mode */
} cy_en_tcpwm_counter_cc_mode_t;
/** \} group_tcpwm_counter_compare_capture */
/** \} group_tcpwm_counter_enum */
/**
* \addtogroup group_tcpwm_counter_data_structures
* \{
*/
/** Counter Timer configuration structure */
typedef struct cy_stc_tcpwm_counter_config
{
uint32_t period; /**< Sets the period of the counter */
cy_en_tcpwm_clk_prescalers_t clockPrescaler; /**< Sets the clock prescaler inside the TCWPM block see \ref cy_en_tcpwm_clk_prescalers */
cy_en_tcpwm_counter_run_modes_t runMode; /**< Sets the Counter Timer Run mode see \ref cy_en_tcpwm_counter_run_modes_t */
cy_en_tcpwm_counter_modes_t countDirection; /**< Sets the counter direction see \ref cy_en_tcpwm_counter_modes_t */
bool debug_pause; /**< If enabled, the counter pauses in debug mode else it kept on running >*/
cy_en_tcpwm_counter_cc_mode_t compareOrCapture; /**< The counter can either compare or capture a value see \ref cy_en_tcpwm_counter_cc_mode_t */
uint32_t compare0; /**< Sets the value for Compare0 */
uint32_t compare0_buff; /**< Sets the value for Compare0_buff */
bool enableCompare0Swap; /**< If enabled, the compare values are swapped each time the comparison is true */
cy_en_tcpwm_interrupt_sources_t interruptSources; /**< Enabled an interrupt on the terminal count, capture or compare, see \ref cy_en_tcpwm_interrupt_sources_t */
cy_en_tcpwm_input_modes_t capture0InputMode; /**< Configures how the capture input behaves see \ref cy_en_tcpwm_input_modes_t */
uint32_t capture0Input; /**< Selects which input the capture uses, should be b/w 0x00 to 0xff */
uint32_t compare1; /**< Sets the value for Compare1 (Compare 1 will be active only for Group1 counters) */
uint32_t compare1_buff; /**< Sets the value for Compare1_buff (Compare 1 will be active only for Group1 counters) */
bool enableCompare1Swap; /**< If enabled, the compare1 values are swapped each time the comparison is true */
cy_en_tcpwm_input_modes_t capture1InputMode; /**< Configures how the capture input behaves see \ref cy_en_tcpwm_input_modes_t */
uint32_t capture1Input; /**< Selects which input the capture uses, should be b/w 0x00 to 0xff */
cy_en_tcpwm_input_modes_t reloadInputMode; /**< Configures how the reload input behaves see \ref cy_en_tcpwm_input_modes_t */
uint32_t reloadInput; /**< Selects which input the reload uses, should be b/w 0x00 to 0xff */
cy_en_tcpwm_input_modes_t startInputMode; /**< Configures how the start input behaves see \ref cy_en_tcpwm_input_modes_t */
uint32_t startInput; /**< Selects which input the start uses, should be b/w 0x00 to 0xff */
cy_en_tcpwm_input_modes_t stopInputMode; /**< Configures how the stop input behaves see \ref cy_en_tcpwm_input_modes_t */
uint32_t stopInput; /**< Selects which input the stop uses, should be b/w 0x00 to 0xff */
cy_en_tcpwm_input_modes_t countInputMode; /**< Configures how the count input behaves see \ref cy_en_tcpwm_input_modes_t */
uint32_t countInput; /**< Selects which input the count uses, should be b/w 0x00 to 0xff */
cy_en_tcpwm_counter_trig_out_sel_t trigger0EventCfg; /**< Configures which internal event generates on output trigger 0 see \ref cy_en_tcpwm_counter_trig_out_sel_t */
cy_en_tcpwm_counter_trig_out_sel_t trigger1EventCfg; /**< Configures which internal event generates on output trigger 1 see \ref cy_en_tcpwm_counter_trig_out_sel_t */
}cy_stc_tcpwm_counter_config_t;
/** \} group_tcpwm_counter_data_structures */
/*******************************************************************************
* Function Prototypes
*******************************************************************************/
/**
* \addtogroup group_tcpwm_counter_functions
* \{
*/
extern uint32_t Cy_Tcpwm_Counter_Init(volatile stc_TCPWM_GRP_CNT_t *ptscTCPWM, cy_stc_tcpwm_counter_config_t const *config);
extern void Cy_Tcpwm_Counter_DeInit(volatile stc_TCPWM_GRP_CNT_t *ptscTCPWM);
extern void Cy_Tcpwm_Counter_Enable(volatile stc_TCPWM_GRP_CNT_t *ptscTCPWM);
extern void Cy_Tcpwm_Counter_Disable(volatile stc_TCPWM_GRP_CNT_t *ptscTCPWM);
extern uint32_t Cy_Tcpwm_Counter_GetStatus(volatile stc_TCPWM_GRP_CNT_t *ptscTCPWM);
extern uint32_t Cy_Tcpwm_Counter_GetCapture0(volatile stc_TCPWM_GRP_CNT_t *ptscTCPWM);
extern uint32_t Cy_Tcpwm_Counter_GetCapture1(volatile stc_TCPWM_GRP_CNT_t *ptscTCPWM);
extern uint32_t Cy_Tcpwm_Counter_GetCapture0Buf(volatile stc_TCPWM_GRP_CNT_t *ptscTCPWM);
extern uint32_t Cy_Tcpwm_Counter_GetCapture1Buf(volatile stc_TCPWM_GRP_CNT_t *ptscTCPWM);
extern void Cy_Tcpwm_Counter_SetCompare0(volatile stc_TCPWM_GRP_CNT_t *ptscTCPWM, uint32_t compare0);
extern uint32_t Cy_Tcpwm_Counter_GetCompare0(volatile stc_TCPWM_GRP_CNT_t *ptscTCPWM);
extern void Cy_Tcpwm_Counter_SetCompare0_Buff(volatile stc_TCPWM_GRP_CNT_t *ptscTCPWM, uint32_t compare1);
extern uint32_t Cy_Tcpwm_Counter_GetCompare0_Buff(volatile stc_TCPWM_GRP_CNT_t *ptscTCPWM);
extern void Cy_Tcpwm_Counter_SetCompare1(volatile stc_TCPWM_GRP_CNT_t *ptscTCPWM, uint32_t compare0);
extern uint32_t Cy_Tcpwm_Counter_GetCompare1(volatile stc_TCPWM_GRP_CNT_t *ptscTCPWM);
extern void Cy_Tcpwm_Counter_SetCompare1_Buff(volatile stc_TCPWM_GRP_CNT_t *ptscTCPWM, uint32_t compare1);
extern uint32_t Cy_Tcpwm_Counter_GetCompare1_Buff(volatile stc_TCPWM_GRP_CNT_t *ptscTCPWM);
extern void Cy_Tcpwm_Counter_EnableCompare0Swap(volatile stc_TCPWM_GRP_CNT_t *ptscTCPWM, bool enable);
extern void Cy_Tcpwm_Counter_EnableCompare1Swap(volatile stc_TCPWM_GRP_CNT_t *ptscTCPWM, bool enable);
extern void Cy_Tcpwm_Counter_SetCounter(volatile stc_TCPWM_GRP_CNT_t *ptscTCPWM, uint32_t count);
extern uint32_t Cy_Tcpwm_Counter_GetCounter(volatile stc_TCPWM_GRP_CNT_t *ptscTCPWM);
extern void Cy_Tcpwm_Counter_SetPeriod(volatile stc_TCPWM_GRP_CNT_t *ptscTCPWM, uint32_t period);
extern uint32_t Cy_Tcpwm_Counter_GetPeriod(volatile stc_TCPWM_GRP_CNT_t *ptscTCPWM);
extern void Cy_Tcpwm_Counter_SetPeriod_Buff(volatile stc_TCPWM_GRP_CNT_t *ptscTCPWM, uint32_t period);
extern uint32_t Cy_Tcpwm_Counter_GetPeriod_Buff(volatile stc_TCPWM_GRP_CNT_t *ptscTCPWM);
extern void Cy_Tcpwm_Counter_SetTC_IntrMask(volatile stc_TCPWM_GRP_CNT_t *ptscTCPWM);
extern void Cy_Tcpwm_Counter_SetCC0_IntrMask(volatile stc_TCPWM_GRP_CNT_t *ptscTCPWM);
extern void Cy_Tcpwm_Counter_SetCC1_IntrMask(volatile stc_TCPWM_GRP_CNT_t *ptscTCPWM);
extern uint8_t Cy_Tcpwm_Counter_GetTC_IntrMasked(volatile stc_TCPWM_GRP_CNT_t *ptscTCPWM);
extern uint8_t Cy_Tcpwm_Counter_GetCC0_IntrMasked(volatile stc_TCPWM_GRP_CNT_t *ptscTCPWM);
extern uint8_t Cy_Tcpwm_Counter_GetCC1_IntrMasked(volatile stc_TCPWM_GRP_CNT_t *ptscTCPWM);
extern void Cy_Tcpwm_Counter_ClearTC_Intr(volatile stc_TCPWM_GRP_CNT_t *ptscTCPWM);
extern void Cy_Tcpwm_Counter_ClearCC0_Intr(volatile stc_TCPWM_GRP_CNT_t *ptscTCPWM);
extern void Cy_Tcpwm_Counter_ClearCC1_Intr(volatile stc_TCPWM_GRP_CNT_t *ptscTCPWM);
/** \} group_tcpwm_counter_functions */
/** \} group_tcpwm_counter */
#if defined(__cplusplus)
}
#endif
#endif /* TCPWM_COUNTER_H */
/* [] END OF FILE */
@@ -0,0 +1,701 @@
/***************************************************************************//**
* \file cy_tcpwm_pwm.c
* \version 1.0
*
* \brief
* The source file of the tcpwm driver.
*
********************************************************************************
* \copyright
* Copyright 2016, Cypress Semiconductor Corporation. All rights reserved.
* You may use this file only in accordance with the license, terms, conditions,
* disclaimers, and limitations in the end user license agreement accompanying
* the software package with which this file was provided.
*******************************************************************************/
#include "cy_tcpwm_pwm.h"
#if defined(__cplusplus)
extern "C" {
#endif
/*******************************************************************************
* Function Name: Cy_Tcpwm_Pwm_Init
****************************************************************************//**
*
* \brief Initializes the TCPWM for the PWM operation.
*
* \param ptscTCPWM The pointer to a counter instance.
* Group0 - 16-bit timer(63 counters, 0-62)
* Group1 - 16-bit timer with motor control(12 counters, 0-11)
* Group2 - 32-bit timer(4 counters, 0-3)
* (Ex - TCPWM0_GRP0_CNT34 = Group0 is selected and its 34th counter is in use)
* \param config The pointer to a configuration structure see \ref cy_stc_tcpwm_pwm_config_t.
*
* \return CY_RET_SUCCESS: configuration completed successfully
* CY_RET_BAD_PARAM: One or more invalid parameters
*
*******************************************************************************/
uint32_t Cy_Tcpwm_Pwm_Init(volatile stc_TCPWM_GRP_CNT_t* ptscTCPWM, cy_stc_tcpwm_pwm_config_t const* config)
{
uint32_t status = CY_RET_BAD_PARAM;
if((NULL != ptscTCPWM) && (NULL != config))
{
un_TCPWM_GRP_CNT_CTRL_t workCTRL = {.u32Register = 0ul};
workCTRL.stcField.u1ONE_SHOT = config->runMode;
workCTRL.stcField.u2UP_DOWN_MODE = config->countDirection;
workCTRL.stcField.u3MODE = config->pwmMode;
workCTRL.stcField.u1DBG_FREEZE_EN = config->debug_pause;
workCTRL.stcField.u1AUTO_RELOAD_CC0 = config->enableCompare0Swap;
workCTRL.stcField.u1AUTO_RELOAD_CC1 = config->enableCompare1Swap;
workCTRL.stcField.u1AUTO_RELOAD_PERIOD = config->enablePeriodSwap;
workCTRL.stcField.u1AUTO_RELOAD_LINE_SEL = config->enableLineSelSwap;
workCTRL.stcField.u1PWM_SYNC_KILL = config->killMode;
workCTRL.stcField.u1PWM_STOP_ON_KILL = (config->killMode>>1ul);
workCTRL.stcField.u1PWM_IMM_KILL = config->immediateKill;
workCTRL.stcField.u2PWM_DISABLE_MODE = config->pwmOnDisable;
ptscTCPWM->unCTRL.u32Register = workCTRL.u32Register;
if(CY_TCPWM_COUNTER_COUNT_UP == config->runMode)
{
ptscTCPWM->unCOUNTER.u32Register = CY_TCPWM_CNT_UP_INIT_VAL;
}
else if(CY_TCPWM_COUNTER_COUNT_DOWN == config->runMode)
{
ptscTCPWM->unCOUNTER.u32Register = config->period;
}
else
{
ptscTCPWM->unCOUNTER.u32Register = CY_TCPWM_CNT_UP_DOWN_INIT_VAL;
}
ptscTCPWM->unCC0.u32Register = config->compare0;
// Should not be set here (YOTS)
ptscTCPWM->unCC0_BUFF.u32Register = config->compare0_buff;
ptscTCPWM->unCC1.u32Register = config->compare1;
// Should not be set here (YOTS)
ptscTCPWM->unCC1_BUFF.u32Register = config->compare1_buff;
ptscTCPWM->unPERIOD.u32Register = config->period;
// Should not be set here (YOTS)
ptscTCPWM->unPERIOD_BUFF.u32Register = config->period_buff;
un_TCPWM_GRP_CNT_TR_IN_SEL0_t workTR_IN_SEL0 = {.u32Register = 0ul};
workTR_IN_SEL0.stcField.u8CAPTURE0_SEL = config->switchInput;
workTR_IN_SEL0.stcField.u8RELOAD_SEL = config->reloadInput;
workTR_IN_SEL0.stcField.u8STOP_SEL = config->kill0Input;
workTR_IN_SEL0.stcField.u8COUNT_SEL = config->countInput;
ptscTCPWM->unTR_IN_SEL0.u32Register = workTR_IN_SEL0.u32Register;
un_TCPWM_GRP_CNT_TR_IN_SEL1_t workTR_IN_SEL1 = {.u32Register = 0ul};
workTR_IN_SEL1.stcField.u8CAPTURE1_SEL = config->kill1Input;
workTR_IN_SEL1.stcField.u8START_SEL = config->startInput;
ptscTCPWM->unTR_IN_SEL1.u32Register = workTR_IN_SEL1.u32Register;
un_TCPWM_GRP_CNT_TR_IN_EDGE_SEL_t workTR_IN_EDGE_SEL = {.u32Register = 0ul};
workTR_IN_EDGE_SEL.stcField.u2CAPTURE0_EDGE = config->switchInputMode;
workTR_IN_EDGE_SEL.stcField.u2CAPTURE1_EDGE = config->kill1InputMode;
workTR_IN_EDGE_SEL.stcField.u2RELOAD_EDGE = config->reloadInputMode;
workTR_IN_EDGE_SEL.stcField.u2START_EDGE = config->startInputMode;
workTR_IN_EDGE_SEL.stcField.u2STOP_EDGE = config->kill0InputMode;
workTR_IN_EDGE_SEL.stcField.u2COUNT_EDGE = config->countInputMode;
ptscTCPWM->unTR_IN_EDGE_SEL.u32Register = workTR_IN_EDGE_SEL.u32Register;
un_TCPWM_GRP_CNT_TR_OUT_SEL_t workTR_OUT_SEL = {.u32Register = 0ul};
workTR_OUT_SEL.stcField.u3OUT0 = config->trigger0EventCfg;
workTR_OUT_SEL.stcField.u3OUT1 = config->trigger1EventCfg;
ptscTCPWM->unTR_OUT_SEL.u32Register = workTR_OUT_SEL.u32Register;
ptscTCPWM->unINTR_MASK.u32Register = config->interruptSources;
un_TCPWM_GRP_CNT_TR_PWM_CTRL_t workTR_PWM_CTRL = {.u32Register = 0ul};
workTR_PWM_CTRL.stcField.u2CC0_MATCH_MODE = config->cc0MatchMode;
workTR_PWM_CTRL.stcField.u2CC1_MATCH_MODE = config->cc1MatchMode;
workTR_PWM_CTRL.stcField.u2OVERFLOW_MODE = config->overflowMode;
workTR_PWM_CTRL.stcField.u2UNDERFLOW_MODE = config->underflowMode;
ptscTCPWM->unTR_PWM_CTRL.u32Register = workTR_PWM_CTRL.u32Register;
un_TCPWM_GRP_CNT_DT_t workDT = {.u32Register = 0ul};
workDT.stcField.u16DT_LINE_COMPL_OUT = config->deadTimeComp;
workDT.stcField.u8DT_LINE_OUT_H = (config->deadTime>>8ul);
if(config->pwmMode == CY_TCPWM_PWM_MODE_DEADTIME)
{
workDT.stcField.u8DT_LINE_OUT_L = config->deadTime;
}
else
{
workDT.stcField.u8DT_LINE_OUT_L = config->clockPrescaler;
}
ptscTCPWM->unDT.u32Register = workDT.u32Register;
status = CY_RET_SUCCESS;
}
return (status);
}
/*******************************************************************************
* Function Name: Cy_Tcpwm_Pwm_DeInit
****************************************************************************//**
*
* \brief De-initializes the TCPWM block, returns register values to default.
*
* \param ptscTCPWM : The pointer to a counter instance.
* Group0 - 16-bit timer(63 counters, 0-62)
* Group1 - 16-bit timer with motor control(12 counters, 0-11)
* Group2 - 32-bit timer(4 counters, 0-3)
*(Ex - TCPWM0_GRP0_CNT34 = Group0 is selected and its 34th counter is in use)
*
* \return None
*
*******************************************************************************/
void Cy_Tcpwm_Pwm_DeInit(volatile stc_TCPWM_GRP_CNT_t *ptscTCPWM)
{
ptscTCPWM->unCTRL.u32Register = CY_TCPWM_GRP_CNT_CTRL_DEFAULT;
ptscTCPWM->unCOUNTER.u32Register = CY_TCPWM_GRP_CNT_COUNTER_DEFAULT;
ptscTCPWM->unCC0.u32Register = CY_TCPWM_GRP_CNT_CC0_DEFAULT;
ptscTCPWM->unCC0_BUFF.u32Register = CY_TCPWM_GRP_CNT_CC0_BUFF_DEFAULT;
ptscTCPWM->unCC1.u32Register = CY_TCPWM_GRP_CNT_CC1_DEFAULT;
ptscTCPWM->unCC1_BUFF.u32Register = CY_TCPWM_GRP_CNT_CC1_BUFF_DEFAULT;
ptscTCPWM->unPERIOD.u32Register = CY_TCPWM_GRP_CNT_PERIOD_DEFAULT;
ptscTCPWM->unPERIOD_BUFF.u32Register = CY_TCPWM_GRP_CNT_PERIOD_BUFF_DEFAULT;
ptscTCPWM->unTR_IN_SEL0.u32Register = CY_TCPWM_GRP_CNT_TR_IN_SEL0_DEFAULT;
ptscTCPWM->unTR_IN_SEL1.u32Register = CY_TCPWM_GRP_CNT_TR_IN_SEL1_DEFAULT;
ptscTCPWM->unTR_IN_EDGE_SEL.u32Register = CY_TCPWM_GRP_CNT_TR_IN_EDGE_SEL_DEFAULT;
ptscTCPWM->unTR_OUT_SEL.u32Register = CY_TCPWM_GRP_CNT_TR_OUT_SEL_DEFAULT;
ptscTCPWM->unTR_PWM_CTRL.u32Register = CY_TCPWM_GRP_CNT_TR_PWM_CTRL_DEFAULT;
ptscTCPWM->unINTR.u32Register = CY_TCPWM_GRP_CNT_INTR_DEFAULT;
ptscTCPWM->unINTR_SET.u32Register = CY_TCPWM_GRP_CNT_INTR_SET_DEFAULT;
ptscTCPWM->unINTR_MASK.u32Register = CY_TCPWM_GRP_CNT_INTR_MASK_DEFAULT;
}
/*******************************************************************************
* Function Name: Cy_Tcpwm_Pwm_Enable
****************************************************************************//**
*
* \brief Enables the TCPWM block for the PWM operation.
*
* \param ptscTCPWM : The pointer to a counter instance.
* Group0 - 16-bit timer(63 counters, 0-62)
* Group1 - 16-bit timer with motor control(12 counters, 0-11)
* Group2 - 32-bit timer(4 counters, 0-3)
*(Ex - TCPWM0_GRP0_CNT34 = Group0 is selected and its 34th counter is in use)
*
* \return None
*
*******************************************************************************/
void Cy_Tcpwm_Pwm_Enable(volatile stc_TCPWM_GRP_CNT_t *ptscTCPWM)
{
ptscTCPWM->unCTRL.stcField.u1ENABLED = 0x1ul;
}
/*******************************************************************************
* Function Name: Cy_Tcpwm_Pwm_Disable
****************************************************************************//**
*
* \brief Disables the TCPWM block.
*
* \param ptscTCPWM : The pointer to a counter instance.
* Group0 - 16-bit timer(63 counters, 0-62)
* Group1 - 16-bit timer with motor control(12 counters, 0-11)
* Group2 - 32-bit timer(4 counters, 0-3)
*(Ex - TCPWM0_GRP0_CNT34 = Group0 is selected and its 34th counter is in use)
*
* \return None
*
*******************************************************************************/
void Cy_Tcpwm_Pwm_Disable(volatile stc_TCPWM_GRP_CNT_t *ptscTCPWM)
{
ptscTCPWM->unCTRL.stcField.u1ENABLED = 0x0ul;
}
/*******************************************************************************
* Function Name: Cy_Tcpwm_Pwm_GetStatus
****************************************************************************//**
*
* \brief Returns the status of the PWM.
*
* \param ptscTCPWM : The pointer to a counter instance.
* Group0 - 16-bit timer(63 counters, 0-62)
* Group1 - 16-bit timer with motor control(12 counters, 0-11)
* Group2 - 32-bit timer(4 counters, 0-3)
*(Ex - TCPWM0_GRP0_CNT34 = Group0 is selected and its 34th counter is in use)
*
* \return The status, see \ref group_tcpwm_pwm_status
*
*******************************************************************************/
uint32_t Cy_Tcpwm_Pwm_GetStatus(volatile stc_TCPWM_GRP_CNT_t *ptscTCPWM)
{
return(ptscTCPWM->unSTATUS.u32Register);
}
/*******************************************************************************
* Function Name: Cy_Tcpwm_Pwm_SetCompare0
****************************************************************************//**
*
* \brief Sets the compare value for Compare0 when the compare mode enabled.
*
* \param ptscTCPWM : The pointer to a counter instance.
* Group0 - 16-bit timer(63 counters, 0-62)
* Group1 - 16-bit timer with motor control(12 counters, 0-11)
* Group2 - 32-bit timer(4 counters, 0-3)
*(Ex - TCPWM0_GRP0_CNT34 = Group0 is selected and its 34th counter is in use)
* \param compare0 : The compare value - value 0.
*
* \return None
*
*******************************************************************************/
void Cy_Tcpwm_Pwm_SetCompare0(volatile stc_TCPWM_GRP_CNT_t *ptscTCPWM, uint32_t compare0)
{
ptscTCPWM->unCC0.u32Register = compare0;
}
/*******************************************************************************
* Function Name: Cy_Tcpwm_Pwm_GetCompare0
****************************************************************************//**
*
* \brief Returns compare value 0.
*
* \param ptscTCPWM : The pointer to a counter instance.
* Group0 - 16-bit timer(63 counters, 0-62)
* Group1 - 16-bit timer with motor control(12 counters, 0-11)
* Group2 - 32-bit timer(4 counters, 0-3)
*(Ex - TCPWM0_GRP0_CNT34 = Group0 is selected and its 34th counter is in use)
*
* \return Compare value 0.
*
*******************************************************************************/
uint32_t Cy_Tcpwm_Pwm_GetCompare0(volatile stc_TCPWM_GRP_CNT_t *ptscTCPWM)
{
return(ptscTCPWM->unCC0.u32Register);
}
/*******************************************************************************
* Function Name: Cy_Tcpwm_Pwm_SetCompare0_Buff
****************************************************************************//**
*
* \brief Sets the compare value for Compare1 when the compare mode is enabled.
*
* \param ptscTCPWM : The pointer to a counter instance.
* Group0 - 16-bit timer(63 counters, 0-62)
* Group1 - 16-bit timer with motor control(12 counters, 0-11)
* Group2 - 32-bit timer(4 counters, 0-3)
*(Ex - TCPWM0_GRP0_CNT34 = Group0 is selected and its 34th counter is in use)
* \param compare0 : The compare value - value 1.
*
* \return None
*
*******************************************************************************/
void Cy_Tcpwm_Pwm_SetCompare0_Buff(volatile stc_TCPWM_GRP_CNT_t *ptscTCPWM, uint32_t compare0)
{
ptscTCPWM->unCC0_BUFF.u32Register = compare0;
}
/*******************************************************************************
* Function Name: Cy_Tcpwm_Pwm_GetCompare0_Buff
****************************************************************************//**
*
* \brief Returns compare value 1.
*
* \param ptscTCPWM : The pointer to a counter instance.
* Group0 - 16-bit timer(63 counters, 0-62)
* Group1 - 16-bit timer with motor control(12 counters, 0-11)
* Group2 - 32-bit timer(4 counters, 0-3)
*(Ex - TCPWM0_GRP0_CNT34 = Group0 is selected and its 34th counter is in use)
* \return Compare value 1.
*
*******************************************************************************/
uint32_t Cy_Tcpwm_Pwm_GetCompare0_Buff(volatile stc_TCPWM_GRP_CNT_t *ptscTCPWM)
{
return(ptscTCPWM->unCC0_BUFF.u32Register);
}
/*******************************************************************************
* Function Name: Cy_Tcpwm_Pwm_EnableCompare0Swap
****************************************************************************//**
*
* \brief Enables the comparison swap when the comparison value is true.
*
* \param ptscTCPWM : The pointer to a counter instance.
* Group0 - 16-bit timer(63 counters, 0-62)
* Group1 - 16-bit timer with motor control(12 counters, 0-11)
* Group2 - 32-bit timer(4 counters, 0-3)
*(Ex - TCPWM0_GRP0_CNT34 = Group0 is selected and its 34th counter is in use)
* \param enable : true = swap enabled, false = swap disabled
*
* \return None
*
*******************************************************************************/
void Cy_Tcpwm_Pwm_EnableCompare0Swap(volatile stc_TCPWM_GRP_CNT_t *ptscTCPWM, bool enable)
{
if (enable)
{
ptscTCPWM->unCTRL.stcField.u1AUTO_RELOAD_CC0 = 0x1ul;
}
else
{
ptscTCPWM->unCTRL.stcField.u1AUTO_RELOAD_CC0 = 0x0ul;
}
}
/*******************************************************************************
* Function Name: Cy_Tcpwm_Pwm_SetCompare1
****************************************************************************//**
*
* \brief Sets the compare value for Compare0 when the compare mode enabled.
*
* \param ptscTCPWM : The pointer to a counter instance.
* Group0 - 16-bit timer(63 counters, 0-62)
* Group1 - 16-bit timer with motor control(12 counters, 0-11)
* Group2 - 32-bit timer(4 counters, 0-3)
*(Ex - TCPWM0_GRP0_CNT34 = Group0 is selected and its 34th counter is in use)
* \param param compare1 : The compare value - value 1.
*
* \return None
*
*******************************************************************************/
void Cy_Tcpwm_Pwm_SetCompare1(volatile stc_TCPWM_GRP_CNT_t *ptscTCPWM, uint32_t compare1)
{
ptscTCPWM->unCC1.u32Register = compare1;
}
/*******************************************************************************
* Function Name: Cy_Tcpwm_Pwm_GetCompare1
****************************************************************************//**
*
* \brief Returns compare value 1.
*
* \param ptscTCPWM : The pointer to a counter instance.
* Group0 - 16-bit timer(63 counters, 0-62)
* Group1 - 16-bit timer with motor control(12 counters, 0-11)
* Group2 - 32-bit timer(4 counters, 0-3)
*(Ex - TCPWM0_GRP0_CNT34 = Group0 is selected and its 34th counter is in use)
*
* \return Compare value 1.
*
*******************************************************************************/
uint32_t Cy_Tcpwm_Pwm_GetCompare1(volatile stc_TCPWM_GRP_CNT_t *ptscTCPWM)
{
return (ptscTCPWM->unCC1.u32Register);
}
/*******************************************************************************
* Function Name: Cy_Tcpwm_Pwm_SetCompare1_Buff
****************************************************************************//**
*
* \brief Sets the compare value for Compare1 when the compare mode is enabled.
*
* \param ptscTCPWM : The pointer to a counter instance.
* Group0 - 16-bit timer(63 counters, 0-62)
* Group1 - 16-bit timer with motor control(12 counters, 0-11)
* Group2 - 32-bit timer(4 counters, 0-3)
*(Ex - TCPWM0_GRP0_CNT34 = Group0 is selected and its 34th counter is in use)
* \param compare1 : The compare value - value 1.
*
* \return None
*
*******************************************************************************/
void Cy_Tcpwm_Pwm_SetCompare1_Buff(volatile stc_TCPWM_GRP_CNT_t *ptscTCPWM, uint32_t compare1)
{
ptscTCPWM->unCC1_BUFF.u32Register = compare1;
}
/*******************************************************************************
* Function Name: Cy_Tcpwm_Pwm_GetCompare1_Buff
****************************************************************************//**
*
* \brief Returns compare value 1.
*
* \param ptscTCPWM : The pointer to a counter instance.
* Group0 - 16-bit timer(63 counters, 0-62)
* Group1 - 16-bit timer with motor control(12 counters, 0-11)
* Group2 - 32-bit timer(4 counters, 0-3)
*(Ex - TCPWM0_GRP0_CNT34 = Group0 is selected and its 34th counter is in use)
*
* \return Compare value 1.
*
*******************************************************************************/
uint32_t Cy_Tcpwm_Pwm_GetCompare1_Buff(volatile stc_TCPWM_GRP_CNT_t *ptscTCPWM)
{
return (ptscTCPWM->unCC1_BUFF.u32Register);
}
/*******************************************************************************
* Function Name: Cy_Tcpwm_Pwm_EnableCompare1Swap
****************************************************************************//**
*
* \brief Enables the comparison swap when the comparison value is true.
*
* \param ptscTCPWM : The pointer to a counter instance.
* Group0 - 16-bit timer(63 counters, 0-62)
* Group1 - 16-bit timer with motor control(12 counters, 0-11)
* Group2 - 32-bit timer(4 counters, 0-3)
*(Ex - TCPWM0_GRP0_CNT34 = Group0 is selected and its 34th counter is in use)
* \param enable : true = swap enabled, false = swap disabled
*
* \return None
*
*******************************************************************************/
void Cy_Tcpwm_Pwm_EnableCompare1Swap(volatile stc_TCPWM_GRP_CNT_t *ptscTCPWM, bool enable)
{
if (enable)
{
ptscTCPWM->unCTRL.stcField.u1AUTO_RELOAD_CC1 = 0x1ul;
}
else
{
ptscTCPWM->unCTRL.stcField.u1AUTO_RELOAD_CC1 = 0x0ul;
}
}
/*******************************************************************************
* Function Name: Cy_Tcpwm_Pwm_SetCounter
****************************************************************************//**
*
* \brief Sets the value of the counter.
*
* \param ptscTCPWM : The pointer to a counter instance.
* Group0 - 16-bit timer(63 counters, 0-62)
* Group1 - 16-bit timer with motor control(12 counters, 0-11)
* Group2 - 32-bit timer(4 counters, 0-3)
*(Ex - TCPWM0_GRP0_CNT34 = Group0 is selected and its 34th counter is in use)
* \param count : The value to write into the counter.
*
* \return None
*
*******************************************************************************/
void Cy_Tcpwm_Pwm_SetCounter(volatile stc_TCPWM_GRP_CNT_t *ptscTCPWM, uint32_t count)
{
ptscTCPWM->unCOUNTER.u32Register = count;
}
/*******************************************************************************
* Function Name: Cy_Tcpwm_Pwm_GetCounter
****************************************************************************//**
*
* \brief Returns the value in the counter.
*
* \param ptscTCPWM : The pointer to a TCPWM instance.
*
* \return The current counter value.
*
*******************************************************************************/
uint32_t Cy_Tcpwm_Pwm_GetCounter(volatile stc_TCPWM_GRP_CNT_t *ptscTCPWM)
{
return(ptscTCPWM->unCOUNTER.u32Register);
}
/*******************************************************************************
* Function Name: Cy_Tcpwm_Pwm_SetPeriod
****************************************************************************//**
*
* \brief Sets the value of the period register.
*
* \param ptscTCPWM : The pointer to a counter instance.
* Group0 - 16-bit timer(63 counters, 0-62)
* Group1 - 16-bit timer with motor control(12 counters, 0-11)
* Group2 - 32-bit timer(4 counters, 0-3)
*(Ex - TCPWM0_GRP0_CNT34 = Group0 is selected and its 34th counter is in use)
* \param period : The value to write into a period.
*
* \return None
*
*******************************************************************************/
void Cy_Tcpwm_Pwm_SetPeriod(volatile stc_TCPWM_GRP_CNT_t *ptscTCPWM, uint32_t period)
{
ptscTCPWM->unPERIOD.u32Register = period;
}
/*******************************************************************************
* Function Name: Cy_Tcpwm_Pwm_GetPeriod
****************************************************************************//**
*
* \brief Returns the value in the period register.
*
* \param ptscTCPWM : The pointer to a counter instance.
* Group0 - 16-bit timer(63 counters, 0-62)
* Group1 - 16-bit timer with motor control(12 counters, 0-11)
* Group2 - 32-bit timer(4 counters, 0-3)
*(Ex - TCPWM0_GRP0_CNT34 = Group0 is selected and its 34th counter is in use)
*
* \return The current period value.
*
*******************************************************************************/
uint32_t Cy_Tcpwm_Pwm_GetPeriod(volatile stc_TCPWM_GRP_CNT_t *ptscTCPWM)
{
return(ptscTCPWM->unPERIOD.u32Register);
}
/*******************************************************************************
* Function Name: Cy_Tcpwm_Pwm_SetPeriodBuf
****************************************************************************//**
*
* \brief Sets the value of the period register.
*
* \param ptscTCPWM : The pointer to a counter instance.
* Group0 - 16-bit timer(63 counters, 0-62)
* Group1 - 16-bit timer with motor control(12 counters, 0-11)
* Group2 - 32-bit timer(4 counters, 0-3)
*(Ex - TCPWM0_GRP0_CNT34 = Group0 is selected and its 34th counter is in use)
* \param period1 : The value to write into a period1.
*
* \return None
*
*******************************************************************************/
void Cy_Tcpwm_Pwm_SetPeriodBuf(volatile stc_TCPWM_GRP_CNT_t *ptscTCPWM, uint32_t period1)
{
ptscTCPWM->unPERIOD_BUFF.u32Register = period1;
}
/*******************************************************************************
* Function Name: Cy_Tcpwm_Pwm_GetPeriodBuf
****************************************************************************//**
*
* \brief Returns the value in the period register.
*
* \param ptscTCPWM : The pointer to a counter instance.
* Group0 - 16-bit timer(63 counters, 0-62)
* Group1 - 16-bit timer with motor control(12 counters, 0-11)
* Group2 - 32-bit timer(4 counters, 0-3)
*(Ex - TCPWM0_GRP0_CNT34 = Group0 is selected and its 34th counter is in use)
*
* \return The current period value.
*
*******************************************************************************/
uint32_t Cy_Tcpwm_Pwm_GetPeriodBuf(volatile stc_TCPWM_GRP_CNT_t *ptscTCPWM)
{
return (ptscTCPWM->unPERIOD_BUFF.u32Register);
}
/*******************************************************************************
* Function Name: Cy_Tcpwm_Pwm_EnablePeriodSwap
****************************************************************************//**
*
* \brief Enables a period swap on OV and/or UN, depending on the PWM alignment
*
* \param ptscTCPWM : The pointer to a counter instance.
* Group0 - 16-bit timer(63 counters, 0-62)
* Group1 - 16-bit timer with motor control(12 counters, 0-11)
* Group2 - 32-bit timer(4 counters, 0-3)
*(Ex - TCPWM0_GRP0_CNT34 = Group0 is selected and its 34th counter is in use)
* \param enable : true: enable period swap. false: disable period swap.
*
* \return None
*
*******************************************************************************/
void Cy_Tcpwm_Pwm_EnablePeriodSwap(volatile stc_TCPWM_GRP_CNT_t *ptscTCPWM, bool enable)
{
if (enable)
{
ptscTCPWM->unCTRL.stcField.u1AUTO_RELOAD_PERIOD = 0x1ul;
}
else
{
ptscTCPWM->unCTRL.stcField.u1AUTO_RELOAD_PERIOD = 0x0ul;
}
}
/*******************************************************************************
* Function Name: Cy_Tcpwm_Pwm_LeftAlign
****************************************************************************//**
*
* \brief Set PWM alignment in Left aligned mode
*
* \param ptscTCPWM : The pointer to a counter instance.
* Group0 - 16-bit timer(63 counters, 0-62)
* Group1 - 16-bit timer with motor control(12 counters, 0-11)
* Group2 - 32-bit timer(4 counters, 0-3)
*(Ex - TCPWM0_GRP0_CNT34 = Group0 is selected and its 34th counter is in use)
*
* \return None
*
*******************************************************************************/
void Cy_Tcpwm_Pwm_LeftAlign(volatile stc_TCPWM_GRP_CNT_t *ptscTCPWM)
{
ptscTCPWM->unTR_PWM_CTRL.stcField.u2CC0_MATCH_MODE = CY_TCPWM_PWM_TR_CTRL2_CLEAR;
ptscTCPWM->unTR_PWM_CTRL.stcField.u2OVERFLOW_MODE = CY_TCPWM_PWM_TR_CTRL2_SET;
ptscTCPWM->unTR_PWM_CTRL.stcField.u2UNDERFLOW_MODE = CY_TCPWM_PWM_TR_CTRL2_NO_CHANGE;
}
/*******************************************************************************
* Function Name: Cy_Tcpwm_Pwm_RightAlign
****************************************************************************//**
*
* \brief Set PWM alignment in Right aligned mode
*
* \param ptscTCPWM : The pointer to a counter instance.
* Group0 - 16-bit timer(63 counters, 0-62)
* Group1 - 16-bit timer with motor control(12 counters, 0-11)
* Group2 - 32-bit timer(4 counters, 0-3)
*(Ex - TCPWM0_GRP0_CNT34 = Group0 is selected and its 34th counter is in use)
*
* \return None
*
*******************************************************************************/
void Cy_Tcpwm_Pwm_RightAlign(volatile stc_TCPWM_GRP_CNT_t *ptscTCPWM)
{
ptscTCPWM->unTR_PWM_CTRL.stcField.u2CC0_MATCH_MODE = CY_TCPWM_PWM_TR_CTRL2_SET;
ptscTCPWM->unTR_PWM_CTRL.stcField.u2OVERFLOW_MODE = CY_TCPWM_PWM_TR_CTRL2_NO_CHANGE;
ptscTCPWM->unTR_PWM_CTRL.stcField.u2UNDERFLOW_MODE = CY_TCPWM_PWM_TR_CTRL2_CLEAR;
}
/*******************************************************************************
* Function Name: Cy_Tcpwm_Pwm_CentreAlign
****************************************************************************//**
*
* \brief Set PWM alignment in Center aligned mode
*
* \param ptscTCPWM : The pointer to a counter instance.
* Group0 - 16-bit timer(63 counters, 0-62)
* Group1 - 16-bit timer with motor control(12 counters, 0-11)
* Group2 - 32-bit timer(4 counters, 0-3)
*(Ex - TCPWM0_GRP0_CNT34 = Group0 is selected and its 34th counter is in use)
*
* \return None
*
*******************************************************************************/
void Cy_Tcpwm_Pwm_CentreAlign(volatile stc_TCPWM_GRP_CNT_t *ptscTCPWM)
{
ptscTCPWM->unTR_PWM_CTRL.stcField.u2CC0_MATCH_MODE = CY_TCPWM_PWM_TR_CTRL2_INVERT;
ptscTCPWM->unTR_PWM_CTRL.stcField.u2OVERFLOW_MODE = CY_TCPWM_PWM_TR_CTRL2_SET;
ptscTCPWM->unTR_PWM_CTRL.stcField.u2UNDERFLOW_MODE = CY_TCPWM_PWM_TR_CTRL2_CLEAR;
}
/*******************************************************************************
* Function Name: Cy_Tcpwm_Pwm_LSFRConfig
****************************************************************************//**
*
* \brief Sets the length of LSFR i.e. GRP_CNT_WIDTH.
*
* \param ptscTCPWM : The pointer to a counter instance.
* Group0 - 16-bit timer(63 counters, 0-62)
* Group1 - 16-bit timer with motor control(12 counters, 0-11)
* Group2 - 32-bit timer(4 counters, 0-3)
*(Ex - TCPWM0_GRP0_CNT34 = Group0 is selected and its 34th counter is in use)
* \param tap_value : TAP value to be programmed to PERIOD_BUFF register
*
* \return None
*
*******************************************************************************/
void Cy_Tcpwm_Pwm_LSFRConfig(volatile stc_TCPWM_GRP_CNT_t *ptscTCPWM, uint32_t tap_value)
{
ptscTCPWM->unPERIOD_BUFF.u32Register = tap_value;
}
#if defined(__cplusplus)
}
#endif
/* [] END OF FILE */
@@ -0,0 +1,243 @@
/***************************************************************************//**
* \file cy_tcpwm_pwm.h
* \version 1.0
*
* \brief
* The header file of the TCPWM PWM driver.
*
********************************************************************************
* \copyright
* Copyright 2016, Cypress Semiconductor Corporation. All rights reserved.
* You may use this file only in accordance with the license, terms, conditions,
* disclaimers, and limitations in the end user license agreement accompanying
* the software package with which this file was provided.
*******************************************************************************/
#if !defined(CY_TCPWM_PWM_H)
#define CY_TCPWM_PWM_H
#include "cy_tcpwm.h"
#include "cy_tcpwm_counter.h"
#if defined(__cplusplus)
extern "C" {
#endif
/**
* \addtogroup group_tcpwm_pwm
* \{
*/
/**
* \addtogroup group_tcpwm_pwm_macro
* \{
*/
/** \defgroup group_tcpwm_pwm_status Counter Status
* \{
* The counter status.
*/
#define CY_TCPWM_PWM_STATUS_DOWN_COUNTING (0x1uL) /**< Timer/Counter is down counting */
#define CY_TCPWM_PWM_STATUS_UP_COUNTING (0x2uL) /**< Timer/Counter is up counting */
/**< Timer/Counter the counter is running */
#define CY_TCPWM_PWM_STATUS_COUNTER_RUNNING (TCPWM_CNT_STATUS_RUNNING_Msk)
/** \} group_tcpwm_pwm_status */
/** \} group_tcpwm_pwm_macro */
/**
* \addtogroup group_tcpwm_pwm_enum
* \{
*/
/** \defgroup group_tcpwm_pwm_run_modes PWM run modes
* \{
* Run modes for the pwm timer.
*/
typedef enum cy_en_tcpwm_pwm_run_modes
{
CY_TCPWM_PWM_CONTINUOUS = 0u, /**< Counter runs forever */
CY_TCPWM_PWM_ONESHOT = 1u, /**< Counter runs once and then stops */
} cy_en_tcpwm_pwm_run_modes_t;
/** \} group_tcpwm_pwm_run_modes */
/** \defgroup group_tcpwm_pwm_modes PWM modes
* \{
* Sets the PWM modes.
*/
typedef enum cy_en_tcpwm_pwm_modes
{
CY_TCPWM_PWM_MODE_PWM = 4u, /**< Standard PWM Mode*/
CY_TCPWM_PWM_MODE_DEADTIME = 5u, /**< PWM with deadtime mode*/
CY_TCPWM_PWM_MODE_PSEUDORANDOM = 6u, /**< Pseudo Random PWM */
} cy_en_tcpwm_pwm_modes_t;
/** \} group_tcpwm_pwm_modes */
/** \defgroup group_tcpwm_pwm_alignment PWM Alignment
* Sets the alignment of the PWM.
* \{
*/
typedef enum cy_en_tcpwm_pwm_alignment
{
CY_TCPWM_PWM_LEFT_ALIGN = 0u, /**< PWM is left aligned, meaning it starts high */
CY_TCPWM_PWM_RIGHT_ALIGN = 1u, /**< PWM is right aligned meaning it start low */
CY_TCPWM_PWM_CENTER_ALIGN = 2u, /**< PWM is centered aligned, terminal count only occurs on underflow */
CY_TCPWM_PWM_ASYMMETRIC_ALIGN = 3u, /**< PWM is asymmetrically aligned, terminal count occurs on overflow and underflow */
} cy_en_tcpwm_pwm_alignment_t;
/** \} group_tcpwm_pwm_alignment */
/** \defgroup group_tcpwm_pwm_kill_modes PWM kill modes
* Sets the kill mode for the PWM.
* \{
*/
typedef enum cy_en_tcpwm_pwm_kill_modes
{
CY_TCPWM_PWM_NOT_STOP_ON_KILL = 0u, /**< PWM output won't stop */
CY_TCPWM_PWM_STOP_ON_KILL = 2u, /**< PWM stops counting on kill */
CY_TCPWM_PWM_SYNCH_STOP_ON_KILL = 3u, /**< PWM output is killed after next TC */
} cy_en_tcpwm_pwm_kill_modes_t;
/** \} group_tcpwm_pwm_kill_modes */
/** \defgroup group_tcpwm_pwm_output_invert PWM output invert
* \{
* Output invert modes.
*/
typedef enum cy_en_tcpwm_pwm_output_invert
{
CY_TCPWM_PWM_INVERT_DISABLE = 0u, /**< Invert the output mode */
CY_TCPWM_PWM_INVERT_ENABLE = 1u, /**< Do not invert the output mode */
} cy_en_tcpwm_pwm_output_invert_t;
/** \} group_tcpwm_pwm_output_invert */
/** \defgroup group_tcpwm_pwm_output_configuration PWM output signal configuration
* \{
* The configuration of PWM output signal for PWM alignment.
*/
typedef enum cy_en_tcpwm_pwm_output_configuration
{
CY_TCPWM_PWM_TR_CTRL2_SET = 0u, /**< Set define for PWM output signal configuration */
CY_TCPWM_PWM_TR_CTRL2_CLEAR = 1u, /**< Clear define for PWM output signal configuration */
CY_TCPWM_PWM_TR_CTRL2_INVERT = 2u, /**< Invert define for PWM output signal configuration */
CY_TCPWM_PWM_TR_CTRL2_NO_CHANGE = 3u, /**< No change define for PWM output signal configuration */
} cy_en_tcpwm_pwm_output_configuration_t;
/** \} group_tcpwm_pwm_output_configuration */
/** \defgroup group_tcpwm_pwm_output_disable State of output signal on disabling PWM
* \{
* The configuration of PWM output signal after disable.
*/
typedef enum cy_en_tcpwm_pwm_output_disable_modes
{
CY_TCPWM_PWM_OUT_MODE_HIGHZ = 0u, /**< On counter disable, the PWM outputs level set to "Z" (high impedance). */
CY_TCPWM_PWM_OUT_MODE_RETAIN = 1u, /**< On counter disable, the PWM outputs are retained. */
CY_TCPWM_PWM_OUT_MODE_LOW = 2u, /**< On counter disable, the PWM outputs is driven to fixed 0. */
CY_TCPWM_PWM_OUT_MODE_HIGH = 3u, /**< On counter disable, the PWM outputs is driven to fixed 1. */
} cy_en_tcpwm_pwm_output_disable_modes_t;
/** \} group_tcpwm_pwm_output_disable */
/** \} group_tcpwm_pwm_enum */
/**
* \addtogroup group_tcpwm_pwm_data_structures
* \{
*/
/** PWM configuration structure */
typedef struct cy_stc_tcpwm_pwm_config
{
cy_en_tcpwm_pwm_modes_t pwmMode; /**< Sets the PWM mode, see \ref cy_en_tcpwm_pwm_modes_t */
cy_en_tcpwm_clk_prescalers_t clockPrescaler; /**< Sets the clock prescaler inside the TCWPM block see \ref cy_en_tcpwm_clk_prescalers */
bool debug_pause; /**< If enabled, the counter pauses in debug mode else it kept on running >*/
uint16_t deadTime; /**< The number of dead time-clocks in PWM in PWM_DT mode (8-bit for Grp0 and Grp2, 16-bit for Grp1)*/
uint16_t deadTimeComp; /**< The number of dead time-clocks in PWM_COMPL n PWM_DT mode (only for Grp1)*/
bool runMode; /**< Set the PWM Run Mode, TRUE: One shot, FALSE: Continuous */
uint32_t countDirection; /**< Sets the counter direction see \ref group_tcpwm_counter_direction */
cy_en_tcpwm_pwm_output_configuration_t cc0MatchMode; /**< Sets the effect of a compare match 0 event on the "line_out" output signals, see cy_en_tcpwm_pwm_output_configuration_t >*/
cy_en_tcpwm_pwm_output_configuration_t overflowMode; /**< Sets the effect of a compare overflow event on the "line_out" output signals, see cy_en_tcpwm_pwm_output_configuration_t >*/
cy_en_tcpwm_pwm_output_configuration_t underflowMode; /**< Sets the effect of a compare underflow event on the "line_out" output signals, see cy_en_tcpwm_pwm_output_configuration_t >*/
cy_en_tcpwm_pwm_output_configuration_t cc1MatchMode; /**< Sets the effect of a compare match 1 event on the "line_out" output signals, see cy_en_tcpwm_pwm_output_configuration_t >*/
uint32_t period; /**< Sets the period of the pwm */
uint32_t period_buff; /**< Sets the period_buff of the pwm */
bool enablePeriodSwap; /**< Enables swapping of period 0 and period 1 on terminal count */
bool enableLineSelSwap; /**< Enables swapping of LINE_SEL and LINE_SEL_BUFF on terminal count and Switch event */
int32_t compare0; /**< Sets the value for Compare0 */
uint32_t compare0_buff; /**< Sets the value for Compare0_buff */
bool enableCompare0Swap; /**< If enabled, the compare values are swapped each time the comparison is true */
uint32_t compare1; /**< Sets the value for Compare1 (Compare1 is available for Group 1 counter) */
uint32_t compare1_buff; /**< Sets the value for Compare1_buff (Compare1 is available for Group 1 counter) */
bool enableCompare1Swap; /**< If enabled, the compare1 values are swapped each time the comparison is true */
cy_en_tcpwm_interrupt_sources_t interruptSources; /**< Enables an interrupt on the terminal count, capture or compare, see \ref cy_en_tcpwm_interrupt_sources_t */
uint32_t invertPWMOut; /**< Inverts the PWM output */
uint32_t invertPWMOutN; /**< Inverts the PWM_n output */
cy_en_tcpwm_pwm_kill_modes_t killMode; /**< Configures the PWM kill modes, see \ref group_tcpwm_pwm_kill_modes */
cy_en_tcpwm_input_modes_t switchInputMode; /**< Configures how the switch input behaves see \ref cy_en_tcpwm_input_modes_t */
uint32_t switchInput; /**< Selects which input the switch uses, should be b/w 0x00 to 0xff */
cy_en_tcpwm_input_modes_t reloadInputMode; /**< Configures how the reload input behaves see \ref cy_en_tcpwm_input_modes_t */
uint32_t reloadInput; /**< Selects which input the reload uses, should be b/w 0x00 to 0xff */
cy_en_tcpwm_input_modes_t startInputMode; /**< Configures how the start input behaves see \ref cy_en_tcpwm_input_modes_t */
uint32_t startInput; /**< Selects which input the start uses, should be b/w 0x00 to 0xff */
cy_en_tcpwm_input_modes_t kill0InputMode; /**< Configures how the kill0 input behaves see \ref cy_en_tcpwm_input_modes_t */
uint32_t kill0Input; /**< Selects which input the kill0 uses, should be b/w 0x00 to 0xff */
cy_en_tcpwm_input_modes_t kill1InputMode; /**< Configures how the kill1 input behaves see \ref cy_en_tcpwm_input_modes_t */
uint32_t kill1Input; /**< Selects which input the kill1 uses, should be b/w 0x00 to 0xff */
cy_en_tcpwm_input_modes_t countInputMode; /**< Configures how the count input behaves see \ref cy_en_tcpwm_input_modes_t */
uint32_t countInput; /**< Selects which input the count uses, should be b/w 0x00 to 0xff */
bool immediateKill; /**< Specifies whether the kill event immediately deactivates the dt_line_out and dt_line_compl_out or with the next module clock */
cy_en_tcpwm_pwm_output_disable_modes_t pwmOnDisable; /**< Specifies the behavior of the PWM outputs line_out and line_compl_out see \ref cy_en_tcpwm_pwm_output_disable_modes_t */
cy_en_tcpwm_counter_trig_out_sel_t trigger0EventCfg; /**< Configures which internal event generates on output trigger 0 see \ref cy_en_tcpwm_counter_trig_out_sel_t */
cy_en_tcpwm_counter_trig_out_sel_t trigger1EventCfg; /**< Configures which internal event generates on output trigger 1 see \ref cy_en_tcpwm_counter_trig_out_sel_t */
}cy_stc_tcpwm_pwm_config_t;
/** \} group_tcpwm_pwm_data_structures */
/*******************************************************************************
* Function Prototypes
*******************************************************************************/
/**
* \addtogroup group_tcpwm_pwm_functions
* \{
*/
extern uint32_t Cy_Tcpwm_Pwm_Init(volatile stc_TCPWM_GRP_CNT_t *ptscTCPWM, cy_stc_tcpwm_pwm_config_t const *config);
extern void Cy_Tcpwm_Pwm_DeInit(volatile stc_TCPWM_GRP_CNT_t *ptscTCPWM);
extern void Cy_Tcpwm_Pwm_Enable(volatile stc_TCPWM_GRP_CNT_t *ptscTCPWM);
extern void Cy_Tcpwm_Pwm_Disable(volatile stc_TCPWM_GRP_CNT_t *ptscTCPWM);
extern uint32_t Cy_Tcpwm_Pwm_GetStatus(volatile stc_TCPWM_GRP_CNT_t *ptscTCPWM);
extern void Cy_Tcpwm_Pwm_SetCompare0(volatile stc_TCPWM_GRP_CNT_t *ptscTCPWM, uint32_t compare0);
extern uint32_t Cy_Tcpwm_Pwm_GetCompare0(volatile stc_TCPWM_GRP_CNT_t *ptscTCPWM);
extern void Cy_Tcpwm_Pwm_SetCompare0_Buff(volatile stc_TCPWM_GRP_CNT_t *ptscTCPWM, uint32_t compare0);
extern uint32_t Cy_Tcpwm_Pwm_GetCompare0_Buff(volatile stc_TCPWM_GRP_CNT_t *ptscTCPWM);
extern void Cy_Tcpwm_Pwm_EnableCompare0Swap(volatile stc_TCPWM_GRP_CNT_t *ptscTCPWM, bool enable);
extern void Cy_Tcpwm_Pwm_SetCompare1(volatile stc_TCPWM_GRP_CNT_t *ptscTCPWM, uint32_t compare1);
extern uint32_t Cy_Tcpwm_Pwm_GetCompare1(volatile stc_TCPWM_GRP_CNT_t *ptscTCPWM);
extern void Cy_Tcpwm_Pwm_SetCompare1_Buff(volatile stc_TCPWM_GRP_CNT_t *ptscTCPWM, uint32_t compare1);
extern uint32_t Cy_Tcpwm_Pwm_GetCompare1_Buff(volatile stc_TCPWM_GRP_CNT_t *ptscTCPWM);
extern void Cy_Tcpwm_Pwm_EnableCompare1Swap(volatile stc_TCPWM_GRP_CNT_t *ptscTCPWM, bool enable);
extern void Cy_Tcpwm_Pwm_SetCounter(volatile stc_TCPWM_GRP_CNT_t *ptscTCPWM, uint32_t count);
extern uint32_t Cy_Tcpwm_Pwm_GetCounter(volatile stc_TCPWM_GRP_CNT_t *ptscTCPWM);
extern void Cy_Tcpwm_Pwm_SetPeriod(volatile stc_TCPWM_GRP_CNT_t *ptscTCPWM, uint32_t period);
extern uint32_t Cy_Tcpwm_Pwm_GetPeriod(volatile stc_TCPWM_GRP_CNT_t *ptscTCPWM);
extern void Cy_Tcpwm_Pwm_SetPeriodBuf(volatile stc_TCPWM_GRP_CNT_t *ptscTCPWM, uint32_t period1);
extern uint32_t Cy_Tcpwm_Pwm_GetPeriodBuf(volatile stc_TCPWM_GRP_CNT_t *ptscTCPWM);
extern void Cy_Tcpwm_Pwm_EnablePeriodSwap(volatile stc_TCPWM_GRP_CNT_t *ptscTCPWM, bool enable);
extern void Cy_Tcpwm_Pwm_LeftAlign(volatile stc_TCPWM_GRP_CNT_t *ptscTCPWM);
extern void Cy_Tcpwm_Pwm_RightAlign(volatile stc_TCPWM_GRP_CNT_t *ptscTCPWM);
extern void Cy_Tcpwm_Pwm_CentreAlign(volatile stc_TCPWM_GRP_CNT_t *ptscTCPWM);
extern void Cy_Tcpwm_Pwm_LSFRConfig(volatile stc_TCPWM_GRP_CNT_t *ptscTCPWM, uint32_t tap_value);
/** \} group_tcpwm_pwm_functions */
/** \} group_tcpwm_pwm */
#if defined(__cplusplus)
}
#endif
#endif /* CY_TCPWM_PWM_H */
/* [] END OF FILE */
@@ -0,0 +1,540 @@
/***************************************************************************//**
* \file cy_tcpwm_quaddec.c
* \version 1.0
*
* \brief
* The source file of the quadrature decoder driver.
*
********************************************************************************
* \copyright
* Copyright 2016, Cypress Semiconductor Corporation. All rights reserved.
* You may use this file only in accordance with the license, terms, conditions,
* disclaimers, and limitations in the end user license agreement accompanying
* the software package with which this file was provided.
*******************************************************************************/
#include "cy_tcpwm_quaddec.h"
#if defined(__cplusplus)
extern "C" {
#endif
/*******************************************************************************
* Function Name: Cy_Tcpwm_QuadDec_Init
****************************************************************************//**
*
* \brief Initializes the TCPWM for the QuadDec operation.
*
* \param ptscTCPWM : The pointer to a counter instance.
* Group0 - 16-bit timer(63 counters, 0-62)
* Group1 - 16-bit timer with motor control(12 counters, 0-11)
* Group2 - 32-bit timer(4 counters, 0-3)
*(Ex - TCPWM0_GRP0_CNT34 = Group0 is selected and its 34th counter is in use)
* \param config : The pointer to a configuration structure see \ref cy_stc_tcpwm_quaddec_config_t.
*
* \return CYRET_SUCCESS : Configuration completed successfully
* CYRET_BAD_PARAM : One or more invalid parameters
*
*******************************************************************************/
uint32_t Cy_Tcpwm_QuadDec_Init(volatile stc_TCPWM_GRP_CNT_t *ptscTCPWM, cy_stc_tcpwm_quaddec_config_t const *config)
{
uint32_t status = CY_RET_BAD_PARAM;
if ((NULL != ptscTCPWM) && (NULL != config))
{
un_TCPWM_GRP_CNT_CTRL_t workCTRL = {.u32Register = 0ul};
workCTRL.stcField.u2QUAD_ENCODING_MODE = config->encoding_mode;
workCTRL.stcField.u2UP_DOWN_MODE = config->range_mode;
workCTRL.stcField.u3MODE = CY_TCPWM_QUADDEC_CTRL_QUADDEC_MODE;
workCTRL.stcField.u1DBG_FREEZE_EN = config->debug_pause;
if (CY_TCPWM_QUADDEC_RANGE_0_CMP == config->range_mode || CY_TCPWM_QUADDEC_RANGE_1_CMP == config->range_mode)
{
workCTRL.stcField.u1AUTO_RELOAD_CC0 = config->enableCompare0Swap;
workCTRL.stcField.u1AUTO_RELOAD_CC1 = config->enableCompare1Swap;
}
ptscTCPWM->unCTRL.u32Register = workCTRL.u32Register;
ptscTCPWM->unCC0.u32Register = config->compare0;
ptscTCPWM->unCC0_BUFF.u32Register = config->compare0_buff;
ptscTCPWM->unCC1.u32Register = config->compare1;
ptscTCPWM->unCC1_BUFF.u32Register = config->compare1_buff;
ptscTCPWM->unPERIOD.u32Register = config->period;
un_TCPWM_GRP_CNT_TR_IN_SEL0_t workTR_IN_SEL0 = {.u32Register = 0ul};
workTR_IN_SEL0.stcField.u8RELOAD_SEL = config->indexInput;
workTR_IN_SEL0.stcField.u8STOP_SEL = config->stopInput;
workTR_IN_SEL0.stcField.u8COUNT_SEL = config->phiAInput;
if (CY_TCPWM_QUADDEC_RANGE_1_CAPT == config->range_mode)
{
workTR_IN_SEL0.stcField.u8CAPTURE0_SEL = config->capture0Input;
}
ptscTCPWM->unTR_IN_SEL0.u32Register = workTR_IN_SEL0.u32Register;
un_TCPWM_GRP_CNT_TR_IN_SEL1_t workTR_IN_SEL1 = {.u32Register = 0ul};
workTR_IN_SEL1.stcField.u8START_SEL = config->phiBInput;
if (CY_TCPWM_QUADDEC_RANGE_1_CAPT == config->range_mode)
{
workTR_IN_SEL1.stcField.u8CAPTURE1_SEL = config->capture1Input;
}
ptscTCPWM->unTR_IN_SEL1.u32Register = workTR_IN_SEL1.u32Register;
un_TCPWM_GRP_CNT_TR_IN_EDGE_SEL_t workTR_IN_EDGE_SEL = {.u32Register = 0ul};
workTR_IN_EDGE_SEL.stcField.u2RELOAD_EDGE = config->indexInputMode;
workTR_IN_EDGE_SEL.stcField.u2STOP_EDGE = config->stopInputMode;
workTR_IN_EDGE_SEL.stcField.u2COUNT_EDGE = 0ul;
workTR_IN_EDGE_SEL.stcField.u2START_EDGE = 0ul;
if (CY_TCPWM_QUADDEC_RANGE_1_CAPT == config->range_mode)
{
workTR_IN_EDGE_SEL.stcField.u2CAPTURE0_EDGE = config->capture0InputMode;
workTR_IN_EDGE_SEL.stcField.u2CAPTURE1_EDGE = config->capture1InputMode;
}
ptscTCPWM->unTR_IN_EDGE_SEL.u32Register = workTR_IN_EDGE_SEL.u32Register;
un_TCPWM_GRP_CNT_TR_OUT_SEL_t workTR_OUT_SEL = {.u32Register = 0ul};
workTR_OUT_SEL.stcField.u3OUT0 = config->trigger0EventCfg;
workTR_OUT_SEL.stcField.u3OUT1 = config->trigger1EventCfg;
ptscTCPWM->unTR_OUT_SEL.u32Register = workTR_OUT_SEL.u32Register;
ptscTCPWM->unINTR_MASK.u32Register = config->interruptSources;
status = CY_RET_SUCCESS;
}
return(status);
}
/*******************************************************************************
* Function Name: Cy_Tcpwm_QuadDec_DeInit
****************************************************************************//**
*
* \brief De-initializes the TCPWM block, returns register values to default.
*
* \param ptscTCPWM : The pointer to a counter instance.
* Group0 - 16-bit timer(63 counters, 0-62)
* Group1 - 16-bit timer with motor control(12 counters, 0-11)
* Group2 - 32-bit timer(4 counters, 0-3)
*(Ex - TCPWM0_GRP0_CNT34 = Group0 is selected and its 34th counter is in use)
*
* \return None
*
*******************************************************************************/
void Cy_Tcpwm_QuadDec_DeInit(volatile stc_TCPWM_GRP_CNT_t *ptscTCPWM)
{
ptscTCPWM->unCTRL.u32Register = CY_TCPWM_GRP_CNT_CTRL_DEFAULT;
ptscTCPWM->unCOUNTER.u32Register = CY_TCPWM_GRP_CNT_COUNTER_DEFAULT;
ptscTCPWM->unCC0.u32Register = CY_TCPWM_GRP_CNT_CC0_DEFAULT;
ptscTCPWM->unCC0_BUFF.u32Register = CY_TCPWM_GRP_CNT_CC0_BUFF_DEFAULT;
ptscTCPWM->unCC1.u32Register = CY_TCPWM_GRP_CNT_CC1_DEFAULT;
ptscTCPWM->unCC1_BUFF.u32Register = CY_TCPWM_GRP_CNT_CC1_BUFF_DEFAULT;
ptscTCPWM->unPERIOD.u32Register = CY_TCPWM_GRP_CNT_PERIOD_DEFAULT;
ptscTCPWM->unPERIOD_BUFF.u32Register = CY_TCPWM_GRP_CNT_PERIOD_BUFF_DEFAULT;
ptscTCPWM->unTR_IN_SEL0.u32Register = CY_TCPWM_GRP_CNT_TR_IN_SEL0_DEFAULT;
ptscTCPWM->unTR_IN_SEL1.u32Register = CY_TCPWM_GRP_CNT_TR_IN_SEL1_DEFAULT;
ptscTCPWM->unTR_IN_EDGE_SEL.u32Register = CY_TCPWM_GRP_CNT_TR_IN_EDGE_SEL_DEFAULT;
ptscTCPWM->unTR_OUT_SEL.u32Register = CY_TCPWM_GRP_CNT_TR_OUT_SEL_DEFAULT;
ptscTCPWM->unTR_PWM_CTRL.u32Register = CY_TCPWM_GRP_CNT_TR_PWM_CTRL_DEFAULT;
ptscTCPWM->unINTR.u32Register = CY_TCPWM_GRP_CNT_INTR_DEFAULT;
ptscTCPWM->unINTR_SET.u32Register = CY_TCPWM_GRP_CNT_INTR_SET_DEFAULT;
ptscTCPWM->unINTR_MASK.u32Register = CY_TCPWM_GRP_CNT_INTR_MASK_DEFAULT;
}
/*******************************************************************************
* Function Name: Cy_Tcpwm_QuadDec_Enable
****************************************************************************//**
*
* \brief Enables the TCPWM block for the QuadDec operation.
*
* \param ptscTCPWM : The pointer to a counter instance.
* Group0 - 16-bit timer(63 counters, 0-62)
* Group1 - 16-bit timer with motor control(12 counters, 0-11)
* Group2 - 32-bit timer(4 counters, 0-3)
*(Ex - TCPWM0_GRP0_CNT34 = Group0 is selected and its 34th counter is in use)
*
* \return None
*
*******************************************************************************/
void Cy_Tcpwm_QuadDec_Enable(volatile stc_TCPWM_GRP_CNT_t *ptscTCPWM)
{
ptscTCPWM->unCTRL.stcField.u1ENABLED = 0x1ul;
}
/*******************************************************************************
* Function Name: Cy_Tcpwm_QuadDec_Disable
****************************************************************************//**
*
* \brief Disables the TCPWM block.
*
* \param ptscTCPWM : The pointer to a counter instance.
* Group0 - 16-bit timer(63 counters, 0-62)
* Group1 - 16-bit timer with motor control(12 counters, 0-11)
* Group2 - 32-bit timer(4 counters, 0-3)
*(Ex - TCPWM0_GRP0_CNT34 = Group0 is selected and its 34th counter is in use)
*
* \return None
*
*******************************************************************************/
void Cy_Tcpwm_QuadDec_Disable(volatile stc_TCPWM_GRP_CNT_t *ptscTCPWM)
{
ptscTCPWM->unCTRL.stcField.u1ENABLED = 0x0ul;
}
/*******************************************************************************
* Function Name: Cy_Tcpwm_QuadDec_GetStatus
****************************************************************************//**
*
* \brief Returns the status of the QuadDec.
*
* \param ptscTCPWM : The pointer to a counter instance.
* Group0 - 16-bit timer(63 counters, 0-62)
* Group1 - 16-bit timer with motor control(12 counters, 0-11)
* Group2 - 32-bit timer(4 counters, 0-3)
*(Ex - TCPWM0_GRP0_CNT34 = Group0 is selected and its 34th counter is in use)
*
* \return The status, see \ref group_tcpwm_quaddec_status
*
*******************************************************************************/
uint32_t Cy_Tcpwm_QuadDec_GetStatus(volatile stc_TCPWM_GRP_CNT_t *ptscTCPWM)
{
return(ptscTCPWM->unSTATUS.u32Register);
}
/*******************************************************************************
* Function Name: Cy_Tcpwm_QuadDec_GetCapture0
****************************************************************************//**
*
* \brief Returns the capture0 value.
*
* \param ptscTCPWM : The pointer to a counter instance.
* Group0 - 16-bit timer(63 counters, 0-62)
* Group1 - 16-bit timer with motor control(12 counters, 0-11)
* Group2 - 32-bit timer(4 counters, 0-3)
*(Ex - TCPWM0_GRP0_CNT34 = Group0 is selected and its 34th counter is in use)
*
* \return The capture value.
*
*******************************************************************************/
uint32_t Cy_Tcpwm_QuadDec_GetCapture0(volatile stc_TCPWM_GRP_CNT_t *ptscTCPWM)
{
return(ptscTCPWM->unCC0.u32Register);
}
/*******************************************************************************
* Function Name: Cy_Tcpwm_QuadDec_GetCaptureBuf0
****************************************************************************//**
*
* \brief Returns the buffered capture0 value.
*
* \param ptscTCPWM : The pointer to a counter instance.
* Group0 - 16-bit timer(63 counters, 0-62)
* Group1 - 16-bit timer with motor control(12 counters, 0-11)
* Group2 - 32-bit timer(4 counters, 0-3)
*(Ex - TCPWM0_GRP0_CNT34 = Group0 is selected and its 34th counter is in use)
*
* \return The buffered capture value.
*
*******************************************************************************/
uint32_t Cy_Tcpwm_QuadDec_GetCaptureBuf0(volatile stc_TCPWM_GRP_CNT_t *ptscTCPWM)
{
return(ptscTCPWM->unCC0_BUFF.u32Register);
}
/*******************************************************************************
* Function Name: Cy_Tcpwm_QuadDec_GetCapture1
****************************************************************************//**
*
* \brief Returns the capture1 value.
*
* \param ptscTCPWM : The pointer to a counter instance.
* Group0 - 16-bit timer(63 counters, 0-62)
* Group1 - 16-bit timer with motor control(12 counters, 0-11)
* Group2 - 32-bit timer(4 counters, 0-3)
*(Ex - TCPWM0_GRP0_CNT34 = Group0 is selected and its 34th counter is in use)
*
* \return The capture value.
*
*******************************************************************************/
uint32_t Cy_Tcpwm_QuadDec_GetCapture1(volatile stc_TCPWM_GRP_CNT_t *ptscTCPWM)
{
return(ptscTCPWM->unCC1.u32Register);
}
/*******************************************************************************
* Function Name: Cy_Tcpwm_QuadDec_GetCaptureBuf1
****************************************************************************//**
*
* \brief Returns the buffered capture1 value.
*
* \param ptscTCPWM : The pointer to a counter instance.
* Group0 - 16-bit timer(63 counters, 0-62)
* Group1 - 16-bit timer with motor control(12 counters, 0-11)
* Group2 - 32-bit timer(4 counters, 0-3)
*(Ex - TCPWM0_GRP0_CNT34 = Group0 is selected and its 34th counter is in use)
*
* \return The buffered capture value.
*
*******************************************************************************/
uint32_t Cy_Tcpwm_QuadDec_GetCaptureBuf1(volatile stc_TCPWM_GRP_CNT_t *ptscTCPWM)
{
return(ptscTCPWM->unCC1_BUFF.u32Register);
}
/*******************************************************************************
* Function Name: Cy_Tcpwm_QuadDec_SetCounter
****************************************************************************//**
*
* \brief Sets the value of the counter.
*
* \param ptscTCPWM : The pointer to a counter instance.
* Group0 - 16-bit timer(63 counters, 0-62)
* Group1 - 16-bit timer with motor control(12 counters, 0-11)
* Group2 - 32-bit timer(4 counters, 0-3)
*(Ex - TCPWM0_GRP0_CNT34 = Group0 is selected and its 34th counter is in use)
* \param count : The value to write into the counter.
*
* \return None
*
*******************************************************************************/
void Cy_Tcpwm_QuadDec_SetCounter(volatile stc_TCPWM_GRP_CNT_t *ptscTCPWM, uint32_t count)
{
ptscTCPWM->unCOUNTER.u32Register = count;
}
/*******************************************************************************
* Function Name: Cy_Tcpwm_QuadDec_GetCounter
****************************************************************************//**
*
* \brief Returns the value in the counter.
*
* \param ptscTCPWM : The pointer to a counter instance.
* Group0 - 16-bit timer(63 counters, 0-62)
* Group1 - 16-bit timer with motor control(12 counters, 0-11)
* Group2 - 32-bit timer(4 counters, 0-3)
*(Ex - TCPWM0_GRP0_CNT34 = Group0 is selected and its 34th counter is in use)
*
* \return The current counter value.
*
*******************************************************************************/
uint32_t Cy_Tcpwm_QuadDec_GetCounter(volatile stc_TCPWM_GRP_CNT_t *ptscTCPWM)
{
return(ptscTCPWM->unCOUNTER.u32Register);
}
/*******************************************************************************
* Function Name: Cy_Tcpwm_QuadDec_GetPeriod
****************************************************************************//**
*
* \brief Returns the period value.
*
* \param ptscTCPWM : The pointer to a counter instance.
return(ptscTCPWM->PERIOD);
* Group0 - 16-bit timer(63 counters, 0-62)
* Group1 - 16-bit timer with motor control(12 counters, 0-11)
* Group2 - 32-bit timer(4 counters, 0-3)
*(Ex - TCPWM0_GRP0_CNT34 = Group0 is selected and its 34th counter is in use)
*
* \return The capture value.
*
*******************************************************************************/
uint32_t Cy_Tcpwm_QuadDec_GetPeriod(volatile stc_TCPWM_GRP_CNT_t *ptscTCPWM)
{
return(ptscTCPWM->unPERIOD.u32Register);
}
/*******************************************************************************
* Function Name: Cy_Tcpwm_QuadDec_GetPeriodBuf
****************************************************************************//**
*
* \brief Returns the buffered period value.
*
* \param ptscTCPWM : The pointer to a counter instance.
* Group0 - 16-bit timer(63 counters, 0-62)
* Group1 - 16-bit timer with motor control(12 counters, 0-11)
* Group2 - 32-bit timer(4 counters, 0-3)
*(Ex - TCPWM0_GRP0_CNT34 = Group0 is selected and its 34th counter is in use)
*
* \return The buffered capture value.
*
*******************************************************************************/
uint32_t Cy_Tcpwm_QuadDec_GetPeriodBuf(volatile stc_TCPWM_GRP_CNT_t *ptscTCPWM)
{
return(ptscTCPWM->unPERIOD_BUFF.u32Register);
}
/*******************************************************************************
* Function Name: Cy_Tcpwm_QuadDec_SetTC_IntrMask
****************************************************************************//**
*
* \brief Set TC interrupt mask.
*
* \param ptscTCPWM : The pointer to a counter instance.
* Group0 - 16-bit timer(63 counters, 0-62)
* Group1 - 16-bit timer with motor control(12 counters, 0-11)
* Group2 - 32-bit timer(4 counters, 0-3)
*(Ex - TCPWM0_GRP0_CNT34 = Group0 is selected and its 34th counter is in use)
*
*******************************************************************************/
void Cy_Tcpwm_QuadDec_SetTC_IntrMask(volatile stc_TCPWM_GRP_CNT_t *ptscTCPWM)
{
ptscTCPWM->unINTR_MASK.stcField.u1TC = 1ul;
}
/*******************************************************************************
* Function Name: Cy_Tcpwm_QuadDec_SetCC0_IntrMask
****************************************************************************//**
*
* \brief Set CCO interrupt mask.
*
* \param ptscTCPWM : The pointer to a counter instance.
* Group0 - 16-bit timer(63 counters, 0-62)
* Group1 - 16-bit timer with motor control(12 counters, 0-11)
* Group2 - 32-bit timer(4 counters, 0-3)
*(Ex - TCPWM0_GRP0_CNT34 = Group0 is selected and its 34th counter is in use)
*
*******************************************************************************/
void Cy_Tcpwm_QuadDec_SetCC0_IntrMask(volatile stc_TCPWM_GRP_CNT_t *ptscTCPWM)
{
ptscTCPWM->unINTR_MASK.stcField.u1CC0_MATCH = 1ul;
}
/*******************************************************************************
* Function Name: Cy_Tcpwm_QuadDec_SetCC1_IntrMask
****************************************************************************//**
*
* \brief Set CC1 interrupt mask.
*
* \param ptscTCPWM : The pointer to a counter instance.
* Group0 - 16-bit timer(63 counters, 0-62)
* Group1 - 16-bit timer with motor control(12 counters, 0-11)
* Group2 - 32-bit timer(4 counters, 0-3)
*(Ex - TCPWM0_GRP0_CNT34 = Group0 is selected and its 34th counter is in use)
*
*******************************************************************************/
void Cy_Tcpwm_QuadDec_SetCC1_IntrMask(volatile stc_TCPWM_GRP_CNT_t *ptscTCPWM)
{
ptscTCPWM->unINTR_MASK.stcField.u1CC1_MATCH = 1ul;
}
/*******************************************************************************
* Function Name: Cy_Tcpwm_QuadDec_GetTC_IntrMasked
****************************************************************************//**
*
* \brief Get TC interrupt masked.
*
* \param ptscTCPWM : The pointer to a counter instance.
* Group0 - 16-bit timer(63 counters, 0-62)
* Group1 - 16-bit timer with motor control(12 counters, 0-11)
* Group2 - 32-bit timer(4 counters, 0-3)
*(Ex - TCPWM0_GRP0_CNT34 = Group0 is selected and its 34th counter is in use)
*
*******************************************************************************/
uint8_t Cy_Tcpwm_QuadDec_GetTC_IntrMasked(volatile stc_TCPWM_GRP_CNT_t *ptscTCPWM)
{
return(ptscTCPWM->unINTR_MASKED.stcField.u1TC);
}
/*******************************************************************************
* Function Name: Cy_Tcpwm_QuadDec_GetCC0_IntrMasked
****************************************************************************//**
*
* \brief Get CC0 interrupt masked.
*
* \param ptscTCPWM : The pointer to a counter instance.
* Group0 - 16-bit timer(63 counters, 0-62)
* Group1 - 16-bit timer with motor control(12 counters, 0-11)
* Group2 - 32-bit timer(4 counters, 0-3)
*(Ex - TCPWM0_GRP0_CNT34 = Group0 is selected and its 34th counter is in use)
*
*******************************************************************************/
uint8_t Cy_Tcpwm_QuadDec_GetCC0_IntrMasked(volatile stc_TCPWM_GRP_CNT_t *ptscTCPWM)
{
return(ptscTCPWM->unINTR_MASKED.stcField.u1CC0_MATCH);
}
/*******************************************************************************
* Function Name: Cy_Tcpwm_QuadDec_GetCC1_IntrMasked
****************************************************************************//**
*
* \brief Get CC1 interrupt masked.
*
* \param ptscTCPWM : The pointer to a counter instance.
* Group0 - 16-bit timer(63 counters, 0-62)
* Group1 - 16-bit timer with motor control(12 counters, 0-11)
* Group2 - 32-bit timer(4 counters, 0-3)
*(Ex - TCPWM0_GRP0_CNT34 = Group0 is selected and its 34th counter is in use)
*
*******************************************************************************/
uint8_t Cy_Tcpwm_QuadDec_GetCC1_IntrMasked(volatile stc_TCPWM_GRP_CNT_t *ptscTCPWM)
{
return(ptscTCPWM->unINTR_MASKED.stcField.u1CC1_MATCH);
}
/*******************************************************************************
* Function Name: Cy_Tcpwm_QuadDec_ClearTC_Intr
****************************************************************************//**
*
* \brief Clear TC interrupt.
*
* \param ptscTCPWM : The pointer to a counter instance.
* Group0 - 16-bit timer(63 counters, 0-62)
* Group1 - 16-bit timer with motor control(12 counters, 0-11)
* Group2 - 32-bit timer(4 counters, 0-3)
*(Ex - TCPWM0_GRP0_CNT34 = Group0 is selected and its 34th counter is in use)
*
*******************************************************************************/
void Cy_Tcpwm_QuadDec_ClearTC_Intr(volatile stc_TCPWM_GRP_CNT_t *ptscTCPWM)
{
ptscTCPWM->unINTR.stcField.u1TC = 1ul;
ptscTCPWM->unINTR.u32Register;
}
/*******************************************************************************
* Function Name: Cy_Tcpwm_QuadDec_ClearCC0_Intr
****************************************************************************//**
*
* \brief Clear CC0 interrupt.
*
* \param ptscTCPWM : The pointer to a counter instance.
* Group0 - 16-bit timer(63 counters, 0-62)
* Group1 - 16-bit timer with motor control(12 counters, 0-11)
* Group2 - 32-bit timer(4 counters, 0-3)
*(Ex - TCPWM0_GRP0_CNT34 = Group0 is selected and its 34th counter is in use)
*
*******************************************************************************/
void Cy_Tcpwm_QuadDec_ClearCC0_Intr(volatile stc_TCPWM_GRP_CNT_t *ptscTCPWM)
{
ptscTCPWM->unINTR.stcField.u1CC0_MATCH = 1ul;
ptscTCPWM->unINTR.u32Register;
}
/*******************************************************************************
* Function Name: Cy_Tcpwm_QuadDec_ClearCC1_Intr
****************************************************************************//**
*
* \brief Clear CC1 interrupt.
*
* \param ptscTCPWM : The pointer to a counter instance.
* Group0 - 16-bit timer(63 counters, 0-62)
* Group1 - 16-bit timer with motor control(12 counters, 0-11)
* Group2 - 32-bit timer(4 counters, 0-3)
*(Ex - TCPWM0_GRP0_CNT34 = Group0 is selected and its 34th counter is in use)
*
*******************************************************************************/
void Cy_Tcpwm_QuadDec_ClearCC1_Intr(volatile stc_TCPWM_GRP_CNT_t *ptscTCPWM)
{
ptscTCPWM->unINTR.stcField.u1CC1_MATCH = 1ul;
ptscTCPWM->unINTR.u32Register;
}
#if defined(__cplusplus)
}
#endif
/* [] END OF FILE */
@@ -0,0 +1,162 @@
/***************************************************************************//**
* \file tcpwm_quaddec.h
* \version 1.0
*
* \brief
* The header file of the TCPWM quadrature Decoder driver.
*
********************************************************************************
* \copyright
* Copyright 2016, Cypress Semiconductor Corporation. All rights reserved.
* You may use this file only in accordance with the license, terms, conditions,
* disclaimers, and limitations in the end user license agreement accompanying
* the software package with which this file was provided.
*******************************************************************************/
#if !defined(CY_TCPWM_QUADDEC_H)
#define CY_TCPWM_QUADDEC_H
#include "cy_tcpwm.h"
#if defined(__cplusplus)
extern "C" {
#endif
/**
* \addtogroup group_tcpwm_quaddec
* \{
*/
/**
* \addtogroup group_tcpwm_quaddec_macro
* \{
*/
/** \defgroup group_tcpwm_quaddec_status Counter Status
* \{
* The counter status.
*/
#define CY_TCPWM_QUADDEC_STATUS_DOWN_COUNTING (0x1uL) /**< QuadDec is down counting */
#define CY_TCPWM_QUADDEC_STATUS_UP_COUNTING (0x2uL) /**< QuadDec is up counting */
#define CY_TCPWM_QUADDEC_STATUS_COUNTER_RUNNING (TCPWM_CNT_STATUS_RUNNING_Msk) /** QuadDec the counter is running */
/** \} group_tcpwm_quaddec_status */
/** \cond INTERNAL */
#define CY_TCPWM_QUADDEC_CTRL_QUADDEC_MODE (0x3uL) /**< Quadrature encoding mode for CTRL register */
/** \endcond */
/** \} group_tcpwm_quaddec_macro */
/**
* \addtogroup group_tcpwm_quaddec_enum
* \{
*/
/** \defgroup group_tcpwm_quaddec_mode QuadDec operating modes
* \{
* The quadrature decoder operation.
*/
typedef enum cy_en_tcpwm_quaddec_modes
{
CY_TCPWM_QUADDEC_X1 = 0u, /**< X1 mode */
CY_TCPWM_QUADDEC_X2 = 1u, /**< X2 mode */
CY_TCPWM_QUADDEC_X4 = 2u, /**< X4 mode */
CY_TCPWM_QUADDEC_UP_DOWN_ROTARY_COUNT = 3u, /**< Up/down rotary count mode */
} cy_en_tcpwm_quaddec_modes_t;
/** \} group_tcpwm_quaddec_mode */
/** \defgroup group_tcpwm_quaddec_range_mode QuadDec range selection
* \{
* The quadrature decoder range selection.
*/
typedef enum cy_en_tcpwm_quaddec_range_sel
{
CY_TCPWM_QUADDEC_RANGE_0 = 0u, /**< QUAD_RANGE0 mode */
CY_TCPWM_QUADDEC_RANGE_0_CMP = 1u, /**< QUAD_RANGE0_CMP */
CY_TCPWM_QUADDEC_RANGE_1_CMP = 2u, /**< QUAD_RANGE1_CMP */
CY_TCPWM_QUADDEC_RANGE_1_CAPT = 3u, /**< QUAD_RANGE1_CAPT */
} cy_en_tcpwm_quaddec_range_sel_t;
/** \} group_tcpwm_quaddec_range_mode */
/** \} group_tcpwm_quaddec_enum */
/**
* \addtogroup group_tcpwm_quaddec_data_structures
* \{
*/
/** Quadrature Decoder configuration structure */
typedef struct cy_stc_tcpwm_quaddec_config
{
cy_en_tcpwm_quaddec_modes_t encoding_mode; /**< Selects the quadrature encoding mode, see \ref cy_en_tcpwm_quaddec_modes_t */
cy_en_tcpwm_quaddec_range_sel_t range_mode; /**< Selects the quadrature range mode, see \ref cy_en_tcpwm_quaddec_range_sel_t */
uint32_t period; /**< Sets the period of the counter */
bool debug_pause; /**< If enabled, the counter pauses in debug mode else it kept on running >*/
uint32_t compare0; /**< Sets the value for Compare0 */
uint32_t compare0_buff; /**< Sets the value for Compare0_buff */
bool enableCompare0Swap; /**< If enabled, the compare0 values are swapped each time the comparison is true */
cy_en_tcpwm_input_modes_t capture0InputMode; /**< Configures how the capture input behaves see \ref cy_en_tcpwm_input_modes_t */
uint32_t capture0Input; /**< Selects which input the capture uses, should be b/w 0x00 to 0xff */
uint32_t compare1; /**< Sets the value for Compare1 */
uint32_t compare1_buff; /**< Sets the value for Compare1_buff */
bool enableCompare1Swap; /**< If enabled, the compare1 values are swapped each time the comparison is true */
cy_en_tcpwm_input_modes_t capture1InputMode; /**< Configures how the capture input behaves see \ref cy_en_tcpwm_input_modes_t */
uint32_t capture1Input; /**< Selects which input the capture uses, should be b/w 0x00 to 0xff */
cy_en_tcpwm_interrupt_sources_t interruptSources; /**< Enables an interrupt on the terminal count, capture or compare, see \ref cy_en_tcpwm_interrupt_sources_t */
cy_en_tcpwm_input_modes_t indexInputMode; /**< Configures how the index input behaves, see \ref cy_en_tcpwm_input_modes_t */
cy_en_tcpwm_input_selection_t indexInput; /**< Selects which input the index uses, the inputs are device-specific see \ref cy_en_tcpwm_input_selection_t */
cy_en_tcpwm_input_modes_t stopInputMode; /**< Configures how the stop input behaves, see \ref cy_en_tcpwm_input_modes_t */
cy_en_tcpwm_input_selection_t stopInput; /**< Selects which input the stop uses, the inputs are device-specific see \ref cy_en_tcpwm_input_selection_t */
cy_en_tcpwm_input_selection_t phiAInput; /**< Selects which input the phiA uses, the inputs are device specific see \ref cy_en_tcpwm_input_selection_t */
cy_en_tcpwm_input_selection_t phiBInput; /**< Selects which input the phiB uses, the inputs are device specific see \ref cy_en_tcpwm_input_selection_t */
cy_en_tcpwm_counter_trig_out_sel_t trigger0EventCfg; /**< Configures which internal event generates on output trigger 0 see \ref cy_en_tcpwm_counter_trig_out_sel_t */
cy_en_tcpwm_counter_trig_out_sel_t trigger1EventCfg; /**< Configures which internal event generates on output trigger 1 see \ref cy_en_tcpwm_counter_trig_out_sel_t */
}cy_stc_tcpwm_quaddec_config_t;
/** \} group_tcpwm_quaddec_data_structures */
/*******************************************************************************
* Function Prototypes
*******************************************************************************/
/**
* \addtogroup group_tcpwm_quaddec_functions
* \{
*/
extern uint32_t Cy_Tcpwm_QuadDec_Init(volatile stc_TCPWM_GRP_CNT_t *ptscTCPWM, cy_stc_tcpwm_quaddec_config_t const *config);
extern void Cy_Tcpwm_QuadDec_DeInit(volatile stc_TCPWM_GRP_CNT_t *ptscTCPWM);
extern void Cy_Tcpwm_QuadDec_Enable(volatile stc_TCPWM_GRP_CNT_t *ptscTCPWM);
extern void Cy_Tcpwm_QuadDec_Disable(volatile stc_TCPWM_GRP_CNT_t *ptscTCPWM);
extern uint32_t Cy_Tcpwm_QuadDec_GetStatus(volatile stc_TCPWM_GRP_CNT_t *ptscTCPWM);
extern uint32_t Cy_Tcpwm_QuadDec_GetCapture0(volatile stc_TCPWM_GRP_CNT_t *ptscTCPWM);
extern uint32_t Cy_Tcpwm_QuadDec_GetCapture0Buf(volatile stc_TCPWM_GRP_CNT_t *ptscTCPWM);
extern uint32_t Cy_Tcpwm_QuadDec_GetCapture1(volatile stc_TCPWM_GRP_CNT_t *ptscTCPWM);
extern uint32_t Cy_Tcpwm_QuadDec_GetCapture1Buf(volatile stc_TCPWM_GRP_CNT_t *ptscTCPWM);
extern void Cy_Tcpwm_QuadDec_SetCounter(volatile stc_TCPWM_GRP_CNT_t *ptscTCPWM, uint32_t count);
extern uint32_t Cy_Tcpwm_QuadDec_GetCounter(volatile stc_TCPWM_GRP_CNT_t *ptscTCPWM);
extern uint32_t Cy_Tcpwm_QuadDec_GetPeriod(volatile stc_TCPWM_GRP_CNT_t *ptscTCPWM);
extern uint32_t Cy_Tcpwm_QuadDec_GetPeriodBuf(volatile stc_TCPWM_GRP_CNT_t *ptscTCPWM);
extern void Cy_Tcpwm_QuadDec_IntrMask(volatile stc_TCPWM_GRP_CNT_t *ptscTCPWM);
extern void Cy_Tcpwm_QuadDec_SetCC0_IntrMask(volatile stc_TCPWM_GRP_CNT_t *ptscTCPWM);
extern void Cy_Tcpwm_QuadDec_SetCC1_IntrMask(volatile stc_TCPWM_GRP_CNT_t *ptscTCPWM);
extern uint8_t Cy_Tcpwm_QuadDec_GetTC_IntrMasked(volatile stc_TCPWM_GRP_CNT_t *ptscTCPWM);
extern uint8_t Cy_Tcpwm_QuadDec_GetCC0_IntrMasked(volatile stc_TCPWM_GRP_CNT_t *ptscTCPWM);
extern uint8_t Cy_Tcpwm_QuadDec_GetCC1_IntrMasked(volatile stc_TCPWM_GRP_CNT_t *ptscTCPWM);
extern void Cy_Tcpwm_QuadDec_ClearTC_Intr(volatile stc_TCPWM_GRP_CNT_t *ptscTCPWM);
extern void Cy_Tcpwm_QuadDec_ClearCC0_Intr(volatile stc_TCPWM_GRP_CNT_t *ptscTCPWM);
extern void Cy_Tcpwm_QuadDec_ClearCC1_Intr(volatile stc_TCPWM_GRP_CNT_t *ptscTCPWM);
/** \} group_tcpwm_quaddec_functions */
/** \} group_tcpwm_quaddec */
#if defined(__cplusplus)
}
#endif
#endif /* TCPWM_QUADDEC_H */
/* [] END OF FILE */
@@ -0,0 +1,526 @@
/***************************************************************************//**
* \file cy_tcpwm_sr.c
* \version 1.0
*
* \brief
* The source file of the tcpwm driver.
*
********************************************************************************
* \copyright
* Copyright 2016, Cypress Semiconductor Corporation. All rights reserved.
* You may use this file only in accordance with the license, terms, conditions,
* disclaimers, and limitations in the end user license agreement accompanying
* the software package with which this file was provided.
*******************************************************************************/
#include "cy_tcpwm_sr.h"
#if defined(__cplusplus)
extern "C" {
#endif
/*******************************************************************************
* Function Name: Cy_Tcpwm_Sr_Init
****************************************************************************//**
*
* \brief Initializes the TCPWM for the Shift register mode operation.
*
* \param ptscTCPWM : The pointer to a counter instance.
* Group0 - 16-bit timer(63 counters, 0-62)
* Group1 - 16-bit timer with motor control(12 counters, 0-11)
* Group2 - 32-bit timer(4 counters, 0-3)
*(Ex - TCPWM0_GRP0_CNT34 = Group0 is selected and its 34th counter is in use)
* \param config :The pointer to configuration structure see \ref stc_tcpwm_counter_config_t.
*
* \return RET_SUCCESS : Configuration completed successfully
* RET_BAD_PARAM : One or more invalid parameters
*
*******************************************************************************/
uint32_t Cy_Tcpwm_Sr_Init(volatile stc_TCPWM_GRP_CNT_t *ptscTCPWM, cy_stc_tcpwm_sr_config_t const *config)
{
uint32_t status = CY_RET_BAD_PARAM;
if ((NULL != ptscTCPWM) && (NULL != config))
{
un_TCPWM_GRP_CNT_CTRL_t workCTRL = {.u32Register = 0ul};
workCTRL.stcField.u1ONE_SHOT = config->runMode;
workCTRL.stcField.u3MODE = CY_TCPWM_QUADDEC_CTRL_SR_MODE;
workCTRL.stcField.u1DBG_FREEZE_EN = config->debug_pause;
workCTRL.stcField.u1AUTO_RELOAD_CC0 = config->enableCompare0Swap;
workCTRL.stcField.u1AUTO_RELOAD_CC1 = config->enableCompare1Swap;
ptscTCPWM->unCTRL.u32Register = workCTRL.u32Register;
ptscTCPWM->unDT.stcField.u8DT_LINE_OUT_L = config->clockPrescaler;
ptscTCPWM->unCC0.u32Register = config->compare0;
ptscTCPWM->unCC0_BUFF.u32Register = config->compare0_buff;
ptscTCPWM->unCC1.u32Register = config->compare1;
ptscTCPWM->unCC1_BUFF.u32Register = config->compare1_buff;
ptscTCPWM->unPERIOD.u32Register = config->period;
ptscTCPWM->unPERIOD_BUFF.u32Register = config->period_buff;
un_TCPWM_GRP_CNT_TR_IN_SEL0_t workTR_IN_SEL0 = {.u32Register = 0ul};
workTR_IN_SEL0.stcField.u8CAPTURE0_SEL = config->serialInInput;
workTR_IN_SEL0.stcField.u8RELOAD_SEL = config->reloadInput;
workTR_IN_SEL0.stcField.u8STOP_SEL = config->stopInput;
workTR_IN_SEL0.stcField.u8COUNT_SEL = config->shiftInput;
ptscTCPWM->unTR_IN_SEL0.u32Register = workTR_IN_SEL0.u32Register;
ptscTCPWM->unTR_IN_SEL1.stcField.u8START_SEL = config->startInput;
un_TCPWM_GRP_CNT_TR_IN_EDGE_SEL_t workTR_IN_EDGE_SEL = {.u32Register = 0ul};
workTR_IN_EDGE_SEL.stcField.u2CAPTURE0_EDGE = config->serialInInputMode;
workTR_IN_EDGE_SEL.stcField.u2RELOAD_EDGE = config->reloadInputMode;
workTR_IN_EDGE_SEL.stcField.u2START_EDGE = config->startInputMode;
workTR_IN_EDGE_SEL.stcField.u2STOP_EDGE = config->stopInputMode;
workTR_IN_EDGE_SEL.stcField.u2COUNT_EDGE = config->shiftInputMode;
ptscTCPWM->unTR_IN_EDGE_SEL.u32Register = workTR_IN_EDGE_SEL.u32Register;
//un_TCPWM_GRP_CNT_TR_OUT_SEL_t workTR_OUT_SEL = {.u32Register = 0ul};
//workTR_OUT_SEL.stcField.u3OUT0 = 0x05ul;
//workTR_OUT_SEL.stcField.u3OUT1 = 0x05ul;
//ptscTCPWM->unTR_OUT_SEL.u32Register = workTR_OUT_SEL.u32Register;
un_TCPWM_GRP_CNT_TR_OUT_SEL_t workTR_OUT_SEL = {.u32Register = 0ul};
workTR_OUT_SEL.stcField.u3OUT0 = config->trigger0EventCfg;
workTR_OUT_SEL.stcField.u3OUT1 = config->trigger1EventCfg;
ptscTCPWM->unTR_OUT_SEL.u32Register = workTR_OUT_SEL.u32Register;
un_TCPWM_GRP_CNT_LINE_SEL_t workLINE_SEL = {.u32Register = 0ul};
workLINE_SEL.stcField.u3OUT_SEL = 0x02;
workLINE_SEL.stcField.u3COMPL_OUT_SEL = 0x03;
ptscTCPWM->unLINE_SEL.u32Register = workLINE_SEL.u32Register;
ptscTCPWM->unINTR_MASK.u32Register = config->interruptSources;
status = CY_RET_SUCCESS;
}
return(status);
}
/*******************************************************************************
* Function Name: Cy_Tcpwm_Sr_DeInit
****************************************************************************//**
*
* \breif De-initializes the TCPWM block, returns register values to default.
*
* \param ptscTCPWM : The pointer to a counter instance.
* Group0 - 16-bit timer(63 counters, 0-62)
* Group1 - 16-bit timer with motor control(12 counters, 0-11)
* Group2 - 32-bit timer(4 counters, 0-3)
*(Ex - TCPWM0_GRP0_CNT34 = Group0 is selected and its 34th counter is in use)
*
* \return None
*
*******************************************************************************/
void Cy_Tcpwm_Sr_DeInit(volatile stc_TCPWM_GRP_CNT_t *ptscTCPWM)
{
ptscTCPWM->unCTRL.u32Register = CY_TCPWM_GRP_CNT_CTRL_DEFAULT;
ptscTCPWM->unCOUNTER.u32Register = CY_TCPWM_GRP_CNT_COUNTER_DEFAULT;
ptscTCPWM->unCC0.u32Register = CY_TCPWM_GRP_CNT_CC0_DEFAULT;
ptscTCPWM->unCC0_BUFF.u32Register = CY_TCPWM_GRP_CNT_CC0_BUFF_DEFAULT;
ptscTCPWM->unCC1.u32Register = CY_TCPWM_GRP_CNT_CC1_DEFAULT;
ptscTCPWM->unCC1_BUFF.u32Register = CY_TCPWM_GRP_CNT_CC1_BUFF_DEFAULT;
ptscTCPWM->unPERIOD.u32Register = CY_TCPWM_GRP_CNT_PERIOD_DEFAULT;
ptscTCPWM->unPERIOD_BUFF.u32Register = CY_TCPWM_GRP_CNT_PERIOD_BUFF_DEFAULT;
ptscTCPWM->unTR_IN_SEL0.u32Register = CY_TCPWM_GRP_CNT_TR_IN_SEL0_DEFAULT;
ptscTCPWM->unTR_IN_SEL1.u32Register = CY_TCPWM_GRP_CNT_TR_IN_SEL1_DEFAULT;
ptscTCPWM->unTR_IN_EDGE_SEL.u32Register = CY_TCPWM_GRP_CNT_TR_IN_EDGE_SEL_DEFAULT;
ptscTCPWM->unTR_OUT_SEL.u32Register = CY_TCPWM_GRP_CNT_TR_OUT_SEL_DEFAULT;
ptscTCPWM->unTR_PWM_CTRL.u32Register = CY_TCPWM_GRP_CNT_TR_PWM_CTRL_DEFAULT;
ptscTCPWM->unINTR.u32Register = CY_TCPWM_GRP_CNT_INTR_DEFAULT;
ptscTCPWM->unINTR_SET.u32Register = CY_TCPWM_GRP_CNT_INTR_SET_DEFAULT;
ptscTCPWM->unINTR_MASK.u32Register = CY_TCPWM_GRP_CNT_INTR_MASK_DEFAULT;
}
/*******************************************************************************
* Function Name: Cy_Tcpwm_Sr_Enable
****************************************************************************//**
*
* \brief Enables the TCPWM block for the Counter operation.
*
* \param ptscTCPWM : The pointer to a counter instance.
* Group0 - 16-bit timer(63 counters, 0-62)
* Group1 - 16-bit timer with motor control(12 counters, 0-11)
* Group2 - 32-bit timer(4 counters, 0-3)
*(Ex - TCPWM0_GRP0_CNT34 = Group0 is selected and its 34th counter is in use)
*
* \return None
*
*******************************************************************************/
void Cy_Tcpwm_Sr_Enable(volatile stc_TCPWM_GRP_CNT_t *ptscTCPWM)
{
ptscTCPWM->unCTRL.stcField.u1ENABLED = 0x1ul;
}
/*******************************************************************************
* Function Name: Cy_Tcpwm_Sr_Disable
****************************************************************************//**
*
* \brief Disables the TCPWM block.
*
* \param ptscTCPWM : The pointer to a counter instance.
* Group0 - 16-bit timer(63 counters, 0-62)
* Group1 - 16-bit timer with motor control(12 counters, 0-11)
* Group2 - 32-bit timer(4 counters, 0-3)
*(Ex - TCPWM0_GRP0_CNT34 = Group0 is selected and its 34th counter is in use)
*
* \return None
*
*******************************************************************************/
void Cy_Tcpwm_Sr_Disable(volatile stc_TCPWM_GRP_CNT_t *ptscTCPWM)
{
ptscTCPWM->unCTRL.stcField.u1ENABLED = 0x0ul;
}
/*******************************************************************************
* Function Name: Cy_Tcpwm_Sr_GetStatus
****************************************************************************//**
*
* \brief Returns the status of the Shift Register.
*
* \param ptscTCPWM : The pointer to a counter instance.
* Group0 - 16-bit timer(63 counters, 0-62)
* Group1 - 16-bit timer with motor control(12 counters, 0-11)
* Group2 - 32-bit timer(4 counters, 0-3)
*(Ex - TCPWM0_GRP0_CNT34 = Group0 is selected and its 34th counter is in use)
*
* \return The status, see \ref group_tcpwm_counter_status
*
*******************************************************************************/
uint32_t Cy_Tcpwm_Sr_GetStatus(volatile stc_TCPWM_GRP_CNT_t *ptscTCPWM)
{
return(ptscTCPWM->unSTATUS.u32Register);
}
/*******************************************************************************
* Function Name: Cy_Tcpwm_Sr_GetCapture0
****************************************************************************//**
*
* \brief Returns the capture value when the capture mode is enabled.
*
* \param ptscTCPWM : The pointer to a counter instance.
* Group0 - 16-bit timer(63 counters, 0-62)
* Group1 - 16-bit timer with motor control(12 counters, 0-11)
* Group2 - 32-bit timer(4 counters, 0-3)
*(Ex - TCPWM0_GRP0_CNT34 = Group0 is selected and its 34th counter is in use)
*
* \return The capture value.
*
*******************************************************************************/
uint32_t Cy_Tcpwm_Sr_GetCapture0(volatile stc_TCPWM_GRP_CNT_t *ptscTCPWM)
{
return(ptscTCPWM->unCC0.u32Register);
}
/*******************************************************************************
* Function Name: Cy_Tcpwm_Sr_GetCapture0Buf
****************************************************************************//**
*
* \brief Returns the buffered capture value when the capture mode is enabled.
*
* \param ptscTCPWM : The pointer to a counter instance.
* Group0 - 16-bit timer(63 counters, 0-62)
* Group1 - 16-bit timer with motor control(12 counters, 0-11)
* Group2 - 32-bit timer(4 counters, 0-3)
*(Ex - TCPWM0_GRP0_CNT34 = Group0 is selected and its 34th counter is in use)
*
* \return The buffered capture value.
*
*******************************************************************************/
uint32_t Cy_Tcpwm_Sr_GetCapture0Buf(volatile stc_TCPWM_GRP_CNT_t *ptscTCPWM)
{
return(ptscTCPWM->unCC0_BUFF.u32Register);
}
/*******************************************************************************
* Function Name: Cy_Tcpwm_Sr_SetCompare0
****************************************************************************//**
*
* \brief Sets the compare value for Compare0 when the compare mode is enabled.
*
* \param ptscTCPWM : The pointer to a counter instance.
* Group0 - 16-bit timer(63 counters, 0-62)
* Group1 - 16-bit timer with motor control(12 counters, 0-11)
* Group2 - 32-bit timer(4 counters, 0-3)
*(Ex - TCPWM0_GRP0_CNT34 = Group0 is selected and its 34th counter is in use)
* \param compare0 : The compare value - 0 value.
*
* \return None
*
*******************************************************************************/
void Cy_Tcpwm_Sr_SetCompare0(volatile stc_TCPWM_GRP_CNT_t *ptscTCPWM, uint32_t compare0)
{
ptscTCPWM->unCC0.u32Register = compare0;
}
/*******************************************************************************
* Function Name: Cy_Tcpwm_Sr_GetCompare0
****************************************************************************//**
*
* \brief Returns compare value 0.
*
* \param ptscTCPWM : The pointer to a counter instance.
* Group0 - 16-bit timer(63 counters, 0-62)
* Group1 - 16-bit timer with motor control(12 counters, 0-11)
* Group2 - 32-bit timer(4 counters, 0-3)
*(Ex - TCPWM0_GRP0_CNT34 = Group0 is selected and its 34th counter is in use)
*
* \return Compare value 0.
*
*******************************************************************************/
uint32_t Cy_Tcpwm_Sr_GetCompare0(volatile stc_TCPWM_GRP_CNT_t *ptscTCPWM)
{
return(ptscTCPWM->unCC0.u32Register);
}
/*******************************************************************************
* Function Name: Cy_TCPWM_Counter_SetCompare0_Buff
****************************************************************************//**
*
* \brief Sets the compare value for Compare1 when the compare mode is enabled.
*
* \param ptscTCPWM : The pointer to a counter instance.
* Group0 - 16-bit timer(63 counters, 0-62)
* Group1 - 16-bit timer with motor control(12 counters, 0-11)
* Group2 - 32-bit timer(4 counters, 0-3)
*(Ex - TCPWM0_GRP0_CNT34 = Group0 is selected and its 34th counter is in use)
* \param compare1 : The compare value - the 1 value.
*
* \return None
*
*******************************************************************************/
void Cy_Tcpwm_Sr_SetCompare0_Buff(volatile stc_TCPWM_GRP_CNT_t *ptscTCPWM, uint32_t compare1)
{
ptscTCPWM->unCC0_BUFF.u32Register = compare1;
}
/*******************************************************************************
* Function Name: Cy_Tcpwm_Sr_GetCompare0_Buff
****************************************************************************//**
*
* \brief Returns compare value 1.
*
* \param ptscTCPWM : The pointer to a counter instance.
* Group0 - 16-bit timer(63 counters, 0-62)
* Group1 - 16-bit timer with motor control(12 counters, 0-11)
* Group2 - 32-bit timer(4 counters, 0-3)
*(Ex - TCPWM0_GRP0_CNT34 = Group0 is selected and its 34th counter is in use)
*
* \return Compare value 1.
*
*******************************************************************************/
uint32_t Cy_Tcpwm_Sr_GetCompare0_Buff(volatile stc_TCPWM_GRP_CNT_t *ptscTCPWM)
{
return(ptscTCPWM->unCC0_BUFF.u32Register);
}
/*******************************************************************************
* Function Name: Cy_Tcpwm_Sr_EnableCompare0Swap
****************************************************************************//**
*
* \brief Enables the comparison swap when the comparison value is true.
*
* \param ptscTCPWM : The pointer to a counter instance.
* Group0 - 16-bit timer(63 counters, 0-62)
* Group1 - 16-bit timer with motor control(12 counters, 0-11)
* Group2 - 32-bit timer(4 counters, 0-3)
*(Ex - TCPWM0_GRP0_CNT34 = Group0 is selected and its 34th counter is in use)
* \param enable : true = swap enabled, false = swap disabled
*
* \return None
*
*******************************************************************************/
void Cy_Tcpwm_Sr_EnableCompare0Swap(volatile stc_TCPWM_GRP_CNT_t *ptscTCPWM, bool enable)
{
if (enable)
{
ptscTCPWM->unCTRL.stcField.u1AUTO_RELOAD_CC0 = 0x1ul;
}
else
{
ptscTCPWM->unCTRL.stcField.u1AUTO_RELOAD_CC0 = 0x0ul;
}
}
/*******************************************************************************
* Function Name: Cy_Tcpwm_Sr_SetCompare1
****************************************************************************//**
*
* \brief Sets the compare value for Compare0 when the compare mode is enabled.
*
* \param ptscTCPWM : The pointer to a counter instance.
* Group0 - 16-bit timer(63 counters, 0-62)
* Group1 - 16-bit timer with motor control(12 counters, 0-11)
* Group2 - 32-bit timer(4 counters, 0-3)
*(Ex - TCPWM0_GRP0_CNT34 = Group0 is selected and its 34th counter is in use)
* \param compare0 : The compare value - 0 value.
*
* \return None
*
*******************************************************************************/
void Cy_Tcpwm_Sr_SetCompare1(volatile stc_TCPWM_GRP_CNT_t *ptscTCPWM, uint32_t compare0)
{
ptscTCPWM->unCC1.u32Register = compare0;
}
/*******************************************************************************
* Function Name: Cy_Tcpwm_Sr_GetCompare1
****************************************************************************//**
*
* \brief Returns compare value 0.
*
* \param ptscTCPWM : The pointer to a counter instance.
* Group0 - 16-bit timer(63 counters, 0-62)
* Group1 - 16-bit timer with motor control(12 counters, 0-11)
* Group2 - 32-bit timer(4 counters, 0-3)
*(Ex - TCPWM0_GRP0_CNT34 = Group0 is selected and its 34th counter is in use)
*
* \return Compare value 0.
*
*******************************************************************************/
uint32_t Cy_Tcpwm_Sr_GetCompare1(volatile stc_TCPWM_GRP_CNT_t *ptscTCPWM)
{
return (ptscTCPWM->unCC1.u32Register);
}
/*******************************************************************************
* Function Name: Cy_TCPWM_Sr_SetCompare1_Buff
****************************************************************************//**
*
* \brief Sets the compare value for Compare1 when the compare mode is enabled.
*
* \param ptscTCPWM : The pointer to a counter instance.
* Group0 - 16-bit timer(63 counters, 0-62)
* Group1 - 16-bit timer with motor control(12 counters, 0-11)
* Group2 - 32-bit timer(4 counters, 0-3)
*(Ex - TCPWM0_GRP0_CNT34 = Group0 is selected and its 34th counter is in use)
* \param compare1 : The compare value - the 1 value.
*
* \return None
*
*******************************************************************************/
void Cy_Tcpwm_Sr_SetCompare1_Buff(volatile stc_TCPWM_GRP_CNT_t *ptscTCPWM, uint32_t compare1)
{
ptscTCPWM->unCC1_BUFF.u32Register = compare1;
}
/*******************************************************************************
* Function Name: Cy_Tcpwm_Sr_GetCompare1_Buff
****************************************************************************//**
*
* \brief Returns compare value 1.
*
* \param ptscTCPWM : The pointer to a counter instance.
* Group0 - 16-bit timer(63 counters, 0-62)
* Group1 - 16-bit timer with motor control(12 counters, 0-11)
* Group2 - 32-bit timer(4 counters, 0-3)
*(Ex - TCPWM0_GRP0_CNT34 = Group0 is selected and its 34th counter is in use)
*
* \return Compare value 1.
*
*******************************************************************************/
uint32_t Cy_Tcpwm_Sr_GetCompare1_Buff(volatile stc_TCPWM_GRP_CNT_t *ptscTCPWM)
{
return(ptscTCPWM->unCC1_BUFF.u32Register);
}
/*******************************************************************************
* Function Name: Cy_Tcpwm_Sr_SetShiftRegister
****************************************************************************//**
*
* \brief Sets the value of the counter.
*
* \param ptscTCPWM : The pointer to a counter instance.
* Group0 - 16-bit timer(63 counters, 0-62)
* Group1 - 16-bit timer with motor control(12 counters, 0-11)
* Group2 - 32-bit timer(4 counters, 0-3)
*(Ex - TCPWM0_GRP0_CNT34 = Group0 is selected and its 34th counter is in use)
* \param sr : The value to write into the shift register.
*
* \return None
*
*******************************************************************************/
void Cy_Tcpwm_Sr_SetShiftRegister(volatile stc_TCPWM_GRP_CNT_t *ptscTCPWM, uint32_t sr)
{
ptscTCPWM->unCOUNTER.u32Register = sr;
}
/*******************************************************************************
* Function Name: Cy_Tcpwm_Sr_GetShiftRegister
****************************************************************************//**
*
* \brief Returns the value in the Shift Register.
*
* \param ptscTCPWM : The pointer to a counter instance.
* Group0 - 16-bit timer(63 counters, 0-62)
* Group1 - 16-bit timer with motor control(12 counters, 0-11)
* Group2 - 32-bit timer(4 counters, 0-3)
*(Ex - TCPWM0_GRP0_CNT34 = Group0 is selected and its 34th counter is in use)
*
* \return The current shift register value.
*
*******************************************************************************/
uint32_t Cy_Tcpwm_Sr_GetShiftRegister(volatile stc_TCPWM_GRP_CNT_t *ptscTCPWM)
{
return(ptscTCPWM->unCOUNTER.u32Register);
}
/*******************************************************************************
* Function Name: Cy_TCPWM_Sr_SetPeriod_Buff
****************************************************************************//**
*
* \brief Sets the value of the period buffer register which is used to know counter taps.
*
* \param ptscTCPWM : The pointer to a counter instance.
* Group0 - 16-bit timer(63 counters, 0-62)
* Group1 - 16-bit timer with motor control(12 counters, 0-11)
* Group2 - 32-bit timer(4 counters, 0-3)
*(Ex - TCPWM0_GRP0_CNT34 = Group0 is selected and its 34th counter is in use)
* \param period : The value to write into a period_buff.
*
* \return None
*
*******************************************************************************/
void Cy_Tcpwm_Sr_SetPeriod_Buff(volatile stc_TCPWM_GRP_CNT_t *ptscTCPWM, uint32_t period)
{
ptscTCPWM->unPERIOD_BUFF.u32Register = period;
}
/*******************************************************************************
* Function Name: Cy_Tcpwm_Sr_GetPeriod_Buff
****************************************************************************//**
*
* \brief Returns the value in the period register.
*
* \param ptscTCPWM : The pointer to a counter instance.
* Group0 - 16-bit timer(63 counters, 0-62)
* Group1 - 16-bit timer with motor control(12 counters, 0-11)
* Group2 - 32-bit timer(4 counters, 0-3)
*(Ex - TCPWM0_GRP0_CNT34 = Group0 is selected and its 34th counter is in use)
*
* \return The current period value.
*
*******************************************************************************/
uint32_t Cy_Tcpwm_Sr_GetPeriod_Buff(volatile stc_TCPWM_GRP_CNT_t *ptscTCPWM)
{
return(ptscTCPWM->unPERIOD_BUFF.u32Register);
}
#if defined(__cplusplus)
}
#endif
/* [] END OF FILE */
@@ -0,0 +1,150 @@
/***************************************************************************//**
* \file cy_tcpwm_sr.h
* \version 1.0
*
* \brief
* The header file of the TCPWM Shift Register driver.
*
********************************************************************************
* \copyright
* Copyright 2016, Cypress Semiconductor Corporation. All rights reserved.
* You may use this file only in accordance with the license, terms, conditions,
* disclaimers, and limitations in the end user license agreement accompanying
* the software package with which this file was provided.
*******************************************************************************/
#if !defined(CY_TCPWM_SR_H)
#define CY_TCPWM_SR_H
#include "cy_tcpwm.h"
#include "cy_tcpwm_counter.h"
#if defined(__cplusplus)
extern "C" {
#endif
/**
* \addtogroup group_tcpwm_sr
* \{
*/
/**
* \addtogroup group_tcpwm_sr_macro
* \{
*/
/** \cond INTERNAL */
#define CY_TCPWM_QUADDEC_CTRL_SR_MODE (0x7uL) /**< Shift Register mode for CTRL register */
/** \endcond */
/** \} group_tcpwm_sr_macro */
/**
* \addtogroup group_tcpwm_sr_enum
* \{
*/
/**
* \defgroup group_tcpwm_sr_run_modes Counter Run Modes
* \{
* Run modes for the shift register counter.
*/
typedef enum cy_en_tcpwm_sr_run_modes
{
CY_TCPWM_SR_CONTINUOUS = 0u, /**< Counter runs forever */
CY_TCPWM_SR_ONESHOT = 1u, /**< Counter runs once and then stops */
} cy_en_tcpwm_sr_run_modes_t;
/** \} group_tcpwm_sr_run_modes */
/** \defgroup group_tcpwm_sr_compare_capture Counter Compare Capture
* \{
* A compare or capture mode.
*/
typedef enum cy_en_tcpwm_sr_cc_mode
{
CY_TCPWM_SR_MODE_CAPTURE = 2u, /**< Timer/Counter is in Capture Mode */
CY_TCPWM_SR_MODE_COMPARE = 0u, /**< Timer/Counter is in Compare Mode */
} cy_en_tcpwm_sr_cc_mode_t;
/** \} group_tcpwm_sr_compare_capture */
/** \} group_tcpwm_sr_enum */
/**
* \addtogroup group_tcpwm_sr_data_structures
* \{
*/
/** Shift Register configuration structure */
typedef struct cy_stc_tcpwm_sr_config
{
uint32_t period; /**< Sets the period*/
uint32_t period_buff; /**< Sets the period_buff for the Shift Register to know taps for PWM */
cy_en_tcpwm_clk_prescalers_t clockPrescaler; /**< Sets the clock prescaler inside the TCWPM block see \ref cy_en_tcpwm_clk_prescalers */
uint32_t runMode; /** < Run Mode selection. TRUE: One shot, FALSE: Continuous */
bool debug_pause; /**< If enabled, the counter pauses in debug mode else it kept on running >*/
uint32_t compare0; /**< Sets the value for Compare0 */
uint32_t compare0_buff; /**< Sets the value for Compare0_buff */
bool enableCompare0Swap; /**< If enabled, the compare values are swapped each time the comparison is true */
uint32_t compare1; /**< Sets the value for Compare1 (Compare1 can only be used for counter in Group 1) */
uint32_t compare1_buff; /**< Sets the value for Compare1_buff (Compare1 can only be used for counter in Group 1) */
bool enableCompare1Swap; /**< If enabled, the compare1 values are swapped each time the comparison is true */
cy_en_tcpwm_interrupt_sources_t interruptSources; /**< Enabled an interrupt on the terminal count, capture or compare, see \ref cy_en_tcpwm_interrupt_sources_t */
cy_en_tcpwm_input_modes_t serialInInputMode; /**< Configures how the capture input behaves see \ref cy_en_tcpwm_input_modes_t */
uint32_t serialInInput; /**< Selects which input the capture uses, should be b/w 0x00 to 0xff */
cy_en_tcpwm_input_modes_t reloadInputMode; /**< Configures how the reload input behaves see \ref cy_en_tcpwm_input_modes_t */
uint32_t reloadInput; /**< Selects which input the reload uses, should be b/w 0x00 to 0xff */
cy_en_tcpwm_input_modes_t startInputMode; /**< Configures how the start input behaves see \ref cy_en_tcpwm_input_modes_t */
uint32_t startInput; /**< Selects which input the start uses, should be b/w 0x00 to 0xff */
cy_en_tcpwm_input_modes_t stopInputMode; /**< Configures how the stop input behaves see \ref cy_en_tcpwm_input_modes_t */
uint32_t stopInput; /**< Selects which input the stop uses, should be b/w 0x00 to 0xff */
cy_en_tcpwm_input_modes_t shiftInputMode; /**< Configures how the shift input behaves see \ref cy_en_tcpwm_input_modes_t */
uint32_t shiftInput; /**< Selects which shift the count uses, should be b/w 0x00 to 0xff */
cy_en_tcpwm_counter_trig_out_sel_t trigger0EventCfg; /**< Configures which internal event generates on output trigger 0 see \ref cy_en_tcpwm_counter_trig_out_sel_t */
cy_en_tcpwm_counter_trig_out_sel_t trigger1EventCfg; /**< Configures which internal event generates on output trigger 1 see \ref cy_en_tcpwm_counter_trig_out_sel_t */
}cy_stc_tcpwm_sr_config_t;
/** \} group_tcpwm_sr_data_structures */
/*******************************************************************************
* Function Prototypes
*******************************************************************************/
/**
* \addtogroup group_tcpwm_sr_functions
* \{
*/
extern uint32_t Cy_Tcpwm_Sr_Init(volatile stc_TCPWM_GRP_CNT_t *ptscTCPWM, cy_stc_tcpwm_sr_config_t const *config);
extern void Cy_Tcpwm_Sr_DeInit(volatile stc_TCPWM_GRP_CNT_t *ptscTCPWM);
extern void Cy_Tcpwm_Sr_Enable(volatile stc_TCPWM_GRP_CNT_t *ptscTCPWM);
extern void Cy_Tcpwm_Sr_Disable(volatile stc_TCPWM_GRP_CNT_t *ptscTCPWM);
extern uint32_t Cy_Tcpwm_Sr_GetStatus(volatile stc_TCPWM_GRP_CNT_t *ptscTCPWM);
extern uint32_t Cy_Tcpwm_Sr_GetCapture0(volatile stc_TCPWM_GRP_CNT_t *ptscTCPWM);
extern uint32_t Cy_Tcpwm_Sr_GetCapture0Buf(volatile stc_TCPWM_GRP_CNT_t *ptscTCPWM);
extern void Cy_Tcpwm_Sr_SetCompare0(volatile stc_TCPWM_GRP_CNT_t *ptscTCPWM, uint32_t compare0);
extern uint32_t Cy_Tcpwm_Sr_GetCompare0(volatile stc_TCPWM_GRP_CNT_t *ptscTCPWM);
extern void Cy_Tcpwm_Sr_SetCompare0_Buff(volatile stc_TCPWM_GRP_CNT_t *ptscTCPWM, uint32_t compare1);
extern uint32_t Cy_Tcpwm_Sr_GetCompare0_Buff(volatile stc_TCPWM_GRP_CNT_t *ptscTCPWM);
extern void Cy_Tcpwm_Sr_EnableCompare0Swap(volatile stc_TCPWM_GRP_CNT_t *ptscTCPWM, bool enable);
extern void Cy_Tcpwm_Sr_SetCompare1(volatile stc_TCPWM_GRP_CNT_t *ptscTCPWM, uint32_t compare0);
extern uint32_t Cy_Tcpwm_Sr_GetCompare1(volatile stc_TCPWM_GRP_CNT_t *ptscTCPWM);
extern void Cy_Tcpwm_Sr_SetCompare1_Buff(volatile stc_TCPWM_GRP_CNT_t *ptscTCPWM, uint32_t compare1);
extern uint32_t Cy_Tcpwm_Sr_GetCompare1_Buff(volatile stc_TCPWM_GRP_CNT_t *ptscTCPWM);
extern void Cy_Tcpwm_Sr_SetShiftRegister(volatile stc_TCPWM_GRP_CNT_t *ptscTCPWM, uint32_t sr);
extern uint32_t Cy_Tcpwm_Sr_GetShiftRegister(volatile stc_TCPWM_GRP_CNT_t *ptscTCPWM);
extern void Cy_Tcpwm_Sr_SetPeriod_Buff(volatile stc_TCPWM_GRP_CNT_t *ptscTCPWM, uint32_t period);
extern uint32_t Cy_Tcpwm_Sr_GetPeriod_Buff(volatile stc_TCPWM_GRP_CNT_t *ptscTCPWM);
/** \} group_tcpwm_sr_functions */
/** \} group_tcpwm_sr */
#if defined(__cplusplus)
}
#endif
#endif /* CY_TCPWM_SR_H */
/* [] END OF FILE */
@@ -0,0 +1,310 @@
/***************************************************************************//**
* \file
* \version 1.0
*
* \brief Trigger mux APIs.
*
********************************************************************************
* \copyright
* Copyright 2016-2017, Cypress Semiconductor Corporation. All rights reserved.
* You may use this file only in accordance with the license, terms, conditions,
* disclaimers, and limitations in the end user license agreement accompanying
* the software package with which this file was provided.
*******************************************************************************/
#include "cy_trigmux.h"
/*******************************************************************************
* Function Name: Cy_TrigMux_IsOutput
****************************************************************************//**
*
* This function checks whether trigger parameter is output type or input type.
*
* \param trig
* An input/output trigger parameter to be checked.
*
* \return
* - true : input trigger parameter is output type
* - false: input trigger parameter is input type
*
********************************************************************************/
static bool Cy_TrigMux_IsOutput(uint32_t trig)
{
// Check output bit field
if((trig & CY_TR_OUT_MASK) == 0)
{
// Input trigger parameter
return false;
}
else
{
// Output trigger parameter
return true;
}
}
/*******************************************************************************
* Function Name: Cy_TrigMux_IsOneToOne
****************************************************************************//**
*
* This function checks whether trigger parameter is for One-To-One trigger or not.
*
* \param trig
* An input/output trigger parameter to be checked.
*
* \return
* - true : input trigger parameter is for One-To-One
* - false: input trigger parameter is not for One-To-One
*
********************************************************************************/
static bool Cy_TrigMux_IsOneToOne(uint32_t trig)
{
// Check trigger type bit field
if((trig & CY_TR_TYPE_MASK) == 0)
{
// Trigger type normal (not one to one)
return false;
}
else
{
// Trigger type one to one
return true;
}
}
/*******************************************************************************
* Function Name: Cy_TrigMux_GetGroup
****************************************************************************//**
*
* This function distills group value from input trigger parameter.
*
* \param trig
* An input/output trigger parameter. group value of this parameter will be returned.
*
* \return
* group value of input trigger parameter.
*
********************************************************************************/
static uint8_t Cy_TrigMux_GetGroup(uint32_t trig)
{
// Distill group field of input parameter
return ((trig & CY_TR_GROUP_MASK) >> CY_TR_GROUP_SHIFT);
}
/*******************************************************************************
* Function Name: Cy_TrigMux_GetNo
****************************************************************************//**
*
* This function distills trigger No from input trigger parameter.
*
* \param trig
* An input/output trigger parameter. Trigger No of this parameter will be returned.
*
* \return
* Trigger No of input trigger parameter.
*
********************************************************************************/
static uint8_t Cy_TrigMux_GetNo(uint32_t trig)
{
// Distill trigger selection field of input parameter
return ((trig & CY_TR_MASK) >> CY_TR_SHIFT);
}
/*******************************************************************************
* Function Name: Cy_TrigMux_Connect
****************************************************************************//**
*
* This function connects an input trigger source and output trigger.
*
* \param inTrig
* An input selection for the trigger mux.
* - Bits 11:8 represent the trigger group selection.
* - Bits 7:0 select the input trigger number in the trigger group.
*
* \param outTrig
* The output of the trigger mux. This refers to the consumer of the trigger mux.
* - Bits 11:8 represent the trigger group selection.
* - Bits 7:0 select the output trigger number in the trigger group.
*
* \param invert
* - CY_TR_MUX_TR_INV_ENABLE: The output trigger is inverted.
* - CY_TR_MUX_TR_INV_DISABLE: The output trigger is not inverted.
*
* \param trigType
* - TRIGGER_TYPE_EDGE: The trigger is synchronized to the consumer blocks clock
* and a two-cycle pulse is generated on this clock.
* - TRIGGER_TYPE_LEVEL: The trigger is a simple level output.
*
* \param dbg_frz_en
* - 1: Output trigger is blocked in DBG mode
* - 0: Output trigger is not blocked in DBG mode
*
* \return
* A status
* - 0: Successful connection made.
* - 1: An invalid input selection corresponding to the output.
* Generally when the trigger groups do not match.
*
********************************************************************************/
cy_en_trigmux_status_t Cy_TrigMux_Connect(uint32_t inTrig, uint32_t outTrig, uint32_t invert, en_trig_type_t trigType, uint32_t dbg_frz_en)
{
cy_en_trigmux_status_t retVal = CY_TRIGMUX_BAD_PARAM;
/* Validate input trigger */
if(Cy_TrigMux_IsOutput(inTrig) == true)
{
/* Input trigger parameter is output type */
return retVal;
}
/* Validate output trigger */
if(Cy_TrigMux_IsOutput(outTrig) == false)
{
/* Output trigger parameter is input type */
return retVal;
}
/* Distill group and trigger No value from input parameters */
uint8_t inGroup = Cy_TrigMux_GetGroup(inTrig);
uint8_t outGroup = Cy_TrigMux_GetGroup(outTrig);
uint8_t inTrigNo = Cy_TrigMux_GetNo(inTrig);
uint8_t outTrigNo = Cy_TrigMux_GetNo(outTrig);
/* Check if output and input group is same */
if(inGroup != outGroup)
{
/* input group and output group mis-matched */
return retVal;
}
/* Get a pointer to target trigger setting register */
volatile stc_PERI_TR_GR_TR_CTL_field_t* pTR_CTL;
pTR_CTL = &(PERI->TR_GR[outGroup].unTR_CTL[outTrigNo].stcField);
/* Set input parameters to the register */
pTR_CTL->u8TR_SEL = inTrigNo;
pTR_CTL->u1TR_INV = invert;
pTR_CTL->u1TR_EDGE = trigType;
pTR_CTL->u1DBG_FREEZE_EN = dbg_frz_en;
/* Return success status */
retVal = CY_TRIGMUX_SUCCESS;
return retVal;
}
/*******************************************************************************
* Function Name: Cy_TrigMux_Connect1To1
****************************************************************************//**
*
* This function connects an input trigger source and output trigger.
*
* \param trig
* The output or input of the trigger mux.
* This refers to the consumer of the trigger mux.
* - Bits 11:8 represent the trigger group selection.
* - Bits 7:0 select the output trigger number in the trigger group.
*
* \param invert
* - CY_TR_MUX_TR_INV_ENABLE: The output trigger is inverted.
* - CY_MUX_TR_INV_DISABLE: The output trigger is not inverted.
*
* \param trigType
* - TRIGGER_TYPE_EDGE: The trigger is synchronized to the consumer blocks clock
* and a two-cycle pulse is generated on this clock.
* - TRIGGER_TYPE_LEVEL: The trigger is a simple level output.
*
* \param dbg_frz_en
* - 1: Output trigger is blocked in DBG mode
* 0: Output trigger is not blocked in DBG mode
*
* \return
* A status
* - 0: Successful connection made.
* - 1: An invalid input selection corresponding to the output.
* Generally when the trigger groups do not match.
*
*******************************************************************************/
cy_en_trigmux_status_t Cy_TrigMux_Connect1To1(uint32_t trig, uint32_t invert, en_trig_type_t trigType, uint32_t dbg_frz_en)
{
cy_en_trigmux_status_t retVal = CY_TRIGMUX_BAD_PARAM;
/* Validate output trigger */
if(Cy_TrigMux_IsOneToOne(trig) == false)
{
/* input trigger parameter is not One-To-One type */
return retVal;
}
/* Distill group and trigger No value from input trigger parameter */
uint8_t trigGroup = Cy_TrigMux_GetGroup(trig);
uint8_t trigNo = Cy_TrigMux_GetNo(trig);
/* Get a pointer to target trigger setting register */
volatile stc_PERI_TR_1TO1_GR_TR_CTL_field_t* pTR_CTL;
pTR_CTL = &(PERI->TR_1TO1_GR[trigGroup].unTR_CTL[trigNo].stcField);
/* Set input parameters to the register */
pTR_CTL->u1TR_SEL = true;
pTR_CTL->u1TR_INV = invert;
pTR_CTL->u1TR_EDGE = trigType;
pTR_CTL->u1DBG_FREEZE_EN = dbg_frz_en;
/* Return success status */
retVal = CY_TRIGMUX_SUCCESS;
return retVal;
}
/*******************************************************************************
* Function Name: Cy_TrigMux_SwTrigger
****************************************************************************//**
*
* This function generates a software trigger on an input trigger line.
* All output triggers connected to this input trigger will be triggered.
* The function also verifies that there is no activated trigger before
* generating another activation.
*
* \param trigLine
* The input of the trigger mux.
* - Bits 11:8 represent the trigger group selection.
* - Bits 7:0 select the output trigger number in the trigger group.
*
* \param trigType
* - TRIGGER_TYPE_EDGE: The trigger is synchronized to the consumer blocks clock
* and a two-cycle pulse is generated on this clock.
* - TRIGGER_TYPE_LEVEL: The trigger is a simple level output.
*
* \param outSel
* "Specifies whether trigger activation is for a specific input or ouput trigger
* of the trigger multiplexer. Activation of a specific input trigger,
* will result in activation of all output triggers that have the specific input
* trigger selected through their TR_OUT_CTL.TR_SEL field. Activation of a
* specific output trigger, will result in activation of the specified TR_SEL
* output trigger only.
* '0': TR_SEL selection and trigger activation is for an input trigger to the trigger multiplexer.
* '1': TR_SEL selection and trigger activation is for an output trigger from the trigger multiplexer.
* Note: this field is not used for trigger 1-to-1 groups."
*
* \return
* A status
* - 0: If there was not an already activated trigger.
* - 1: If there was an already activated trigger.
*
*******************************************************************************/
cy_en_trigmux_status_t Cy_TrigMux_SwTrigger(uint32_t trigLine, en_trig_type_t trigType, uint32_t outSel)
{
cy_en_trigmux_status_t retVal = CY_TRIGMUX_INVALID_STATE;
if (PERI->unTR_CMD.stcField.u1ACTIVATE == 0)
{
PERI->unTR_CMD.stcField.u8TR_SEL = Cy_TrigMux_GetNo(trigLine);
PERI->unTR_CMD.stcField.u5GROUP_SEL = Cy_TrigMux_GetGroup(trigLine);
PERI->unTR_CMD.stcField.u1TR_EDGE = trigType;
PERI->unTR_CMD.stcField.u1OUT_SEL = outSel;
PERI->unTR_CMD.stcField.u1ACTIVATE = 1; // Workaround: Rise ACTIVATE bit at last individually.
retVal = CY_TRIGMUX_SUCCESS;
}
return retVal;
}
/* [] END OF FILE */
@@ -0,0 +1,189 @@
/*******************************************************************************
* \file cy_trigmux.h
* \version 1.0
*
* This file provides constants and parameter values for the Trigger multiplexer driver.
*
********************************************************************************
* \copyright
* Copyright 2016-2017, Cypress Semiconductor Corporation. All rights reserved.
* You may use this file only in accordance with the license, terms, conditions,
* disclaimers, and limitations in the end user license agreement accompanying
* the software package with which this file was provided.
*******************************************************************************/
/**
* \defgroup group_trigmux Trigger multiplexer (TriggerMux)
* \{
* The trigger multiplexer provides access to the multiplexer that selects a set
* of trigger output signals from different peripheral blocks to route them to the
* specific trigger input of another peripheral block.
*
* The TrigMux driver is based on the trigger multiplexer's hardware block.
* The Trigger multiplexer block consists of multiple trigger multiplexers.
* These trigger multiplexers are grouped in trigger groups. All the trigger
* multiplexers in the trigger group share similar input options. The trigger
* multiplexer groups are either reduction multiplexers or distribution multiplexers.
* The reduction multiplexer groups have input options that are the trigger outputs
* coming from the different peripheral blocks and the reduction multiplexer groups
* route them to intermediate signals. The distribution multiplexer groups have input
* options from these intermediate signals and route them back to multiple peripheral
* blocks as their trigger inputs.
*
* The trigger architecture of the PSoC device is explained in the technical reference
* manual (TRM). Refer to the TRM to better understand the trigger multiplexer routing
* architecture available.
*
* \section group_trigmux_section_Configuration_Considerations Configuration Considerations
*
*
* To route a trigger signal from one peripheral in the PSoC
* to another, the user must configure a reduction multiplexer and a distribution
* multiplexer. The Cy_TrigMux_connect() is used to configure a trigger multiplexer connection.
* The user will need two calls of this API, one for the reduction multiplexer and another
* for the distribution multiplexer, to achieve the trigger connection from a source
* peripheral to a destination peripheral. The Cy_TrigMux_connect() function has two main
* parameters, inTrig and outTrig that refer to the input and output trigger signals
* connected using the multiplexer.
*
* In addition, the Cy_TrigMux_connect() function also has an invert and trigger type parameter.
* Refer to the API reference for a detailed description of this parameter.
* All the constants associated with the different trigger signals in the system
* (input and output) are defined as constants in the device configuration header file.
* The constants for TrigMux in the device configuration header file are divided into four
* types based on the signal being input/output and being part of a reduction/distribution
* trigger multiplexer.
*
* The four types of the input/output parameters are:
* 1) The parameters for the reduction multiplexer's inputs (input signals of TrigMux);
* 2) The parameters for the reduction multiplexer's outputs (intermediate signals);
* 3) The parameters for the distribution multiplexer's inputs (intermediate signals);
* 4) The parameters for the distribution multiplexer's outputs (output signals of TrigMux).
* Refer to the TRM for a more detailed description of this architecture and different options.
*
* The steps to connect one peripheral block to the other:
*
* Step 1. Find the trigger group number in the Trigger Group Inputs section of the device
* configuration header file that corresponds to the output of the first peripheral block.
* For example, TRIG10_IN_CPUSS_DW0_TR_OUT4 input of the reduction multiplexers belongs
* to Trigger Group 10.
*
* Step 2. Find the trigger group number in the Trigger Group Outputs section of the device
* configuration header file that corresponds to the input of the second peripheral block.
* For example, TRIG3_OUT_TCPWM1_TR_IN0 output of the distribution multiplexer belongs to
* Trigger Group 3.
*
* Step 3. Find the same trigger group number in the Trigger Group Inputs section of the
* device configuration header file that corresponds to the trigger group number found in
* Step 1. Select the reduction multiplexer output that can be connected to the trigger group
* found in Step 2. For example, TRIG3_IN_TR_GROUP10_OUTPUT5 means that Reduction Multiplexer
* Output 5 of Trigger Group 10 can be connected to Trigger Group 3.
*
* Step 4. Find the same trigger group number in the Trigger Group Outputs section of the
* device configuration header file that corresponds to the trigger group number found in Step 2.
* Select the distribution multiplexer input that can be connected to the trigger group found
* in Step 1. For example, TRIG10_OUT_TR_GROUP3_INPUT1 means that the Distribution Multiplexer
* Input 1 of Trigger Group 3 can be connected to the output of the reduction multiplexer
* in Trigger Group 10 found in Step 3.
*
* Step 5. Call Cy_TrigMux_Connect() API twice: the first call - with the constants for the
* inTrig and outTrig parameters found in Steps 1 and Step 4, the second call - with the
* constants for the inTrig and outTrig parameters found in Steps 2 and Step 3.
* For example,
* Cy_TrigMux_Connect(TRIG10_IN_CPUSS_DW0_TR_OUT4, TRIG10_OUT_TR_GROUP3_INPUT1,
* TR_MUX_TR_INV_DISABLE, TRIGGER_TYPE_LEVEL);
* Cy_TrigMux_Connect(TRIG3_IN_TR_GROUP10_OUTPUT5, TRIG3_OUT_TCPWM1_TR_IN0,
* TR_MUX_TR_INV_DISABLE, TRIGGER_TYPE_LEVEL);
*
* \section group_trigmux_more_information More Information
* For more information on the TrigMux peripheral, refer to the technical reference manual (TRM).
*
* \defgroup group_trigmux_macro Macro
* \defgroup group_trigmux_functions Functions
* \defgroup group_trigmux_enums Enumerated Types
*/
#if !defined(CY_TRIGMUX_H)
#define CY_TRIGMUX_H
#include "cy_device_headers.h"
#include "syslib/cy_syslib.h"
#if defined(__cplusplus)
extern "C" {
#endif
/**
* \addtogroup group_trigmux_macro
* \{
*/
/** The driver major version */
#define CY_TRIGMUX_DRV_VERSION_MAJOR 1
/** The driver minor version */
#define CY_TRIGMUX_DRV_VERSION_MINOR 0
/**< TRIGMUX PDL ID */
#define CY_TRIGMUX_ID CY_PDL_DRV_ID(0x33u) /**< The trigger multiplexer driver identifier */
#define CY_TR_MUX_TR_INV_ENABLE (0x01u) /**< Enable trigger invert */
#define CY_TR_MUX_TR_INV_DISABLE (0x00u) /**< Disable trigger invert */
/** \cond */
#define CY_TR_MASK (0x000000FFu) // 7:0 TR_SEL
#define CY_TR_SHIFT (0x0)
#define CY_TR_GROUP_MASK (0x00000F00u) // 11:8 GROUP_SEL
#define CY_TR_GROUP_SHIFT (0x08u)
#define CY_TR_OUT_MASK (0x40000000u) //New: Mask Trigger Output
#define CY_TR_TYPE_MASK (0x00001000u) //New: Mask 1-to-1 Trigger Input and Output
/** \endcond */
/** \} group_trigmux_macro */
/**
* \addtogroup group_trigmux_enums
* \{
*/
/******************************************************************************
* Enumerations
*****************************************************************************/
/** The TRIGMUX error codes. */
typedef enum
{
CY_TRIGMUX_SUCCESS = 0x00u, /**< Successful */
CY_TRIGMUX_BAD_PARAM = CY_TRIGMUX_ID | CY_PDL_STATUS_ERROR | 0x01u, /**< One or more invalid parameters */
CY_TRIGMUX_INVALID_STATE = CY_TRIGMUX_ID | CY_PDL_STATUS_ERROR | 0x02u /**< Operation not setup or is in an improper state */
} cy_en_trigmux_status_t;
/** \} group_trigmux_enums */
/**
* \addtogroup group_trigmux_functions
* \{
*/
cy_en_trigmux_status_t Cy_TrigMux_Connect(uint32_t inTrig, uint32_t outTrig, uint32_t invert, en_trig_type_t trigType, uint32_t dbg_frz_en);
cy_en_trigmux_status_t Cy_TrigMux_Connect1To1(uint32_t outTrig, uint32_t invert, en_trig_type_t trigType, uint32_t dbg_frz_en); //New
cy_en_trigmux_status_t Cy_TrigMux_SwTrigger(uint32_t trigLine, en_trig_type_t trigType, uint32_t outSel);
/** \} group_trigmux_functions */
#if defined(__cplusplus)
}
#endif
#endif /* CY_TRIGMUX_H */
/** \} group_lpcomp */
/* [] END OF FILE */