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
@@ -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