/***************************************************************************//** * \file cyhal_system.h * * \brief * Provides a high level interface for interacting with the Infineon power * management and system clock configuration. This interface abstracts out the * chip specific details. If any chip specific functionality is necessary, or * performance is critical the low level functions can be used directly. * ******************************************************************************** * \copyright * Copyright 2018-2022 Cypress Semiconductor Corporation (an Infineon company) or * an affiliate of Cypress Semiconductor Corporation * * SPDX-License-Identifier: Apache-2.0 * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. *******************************************************************************/ /** * \addtogroup group_hal_system System * \ingroup group_hal * \{ * High level interface for interacting with reset and delays. * * \section section_system_features Features * This driver provides three categories of functionality: * * Ability to get the last reset reason. * * Ability to delay for a period of time. * * The ability to disable interrupts during a critical section. * * \section subsection_system_quickstart Quick Start * * \ref cyhal_system_critical_section_enter and \ref * cyhal_system_critical_section_exit are used to enable/disable global interrupts * * \ref cyhal_system_delay_ms and \ref cyhal_system_delay_us are delay functions * used to halt the CPU exectution for a specified period of time * * \ref cyhal_system_get_reset_reason gets the cause of latest system reset and * \ref cyhal_system_clear_reset_reason clears the reset cause registers * * \section subsection_system_codesnippet Code Snippets * \subsection subsection_system_snippet1 Snippet 1: Critical Section * Critical section is a portion in the code where all active interrupts are * disabled. This is usually provided in places where the code execution must not * be disturbed by an interrupt. An example is a firmware controlled communication * protocol where timing of each byte must be maintained and any interrupt might * cause loss of data.
* \ref cyhal_system_critical_section_enter returns the current state of interrupts * which denote the active interrupts in the system. This must be passed as argument * to \ref cyhal_system_critical_section_exit while exiting the critical section. * \snippet hal_system.c snippet_cyhal_system_critical_section * * \subsection subsection_system_snippet2 Snippet 2: Reset reason * \ref cyhal_system_get_reset_reason must be called at the beginning of the main to * determine the reason for reset. The return parameters are present in \ref * cyhal_reset_reason_t. * \snippet hal_system.c snippet_cyhal_system_reset_reason */ #pragma once #include #include #include "cy_result.h" #include "cyhal_hw_types.h" #if defined(__cplusplus) extern "C" { #endif /** \addtogroup group_hal_results_system SYSTEM HAL Results * SYSTEM specific return codes * \ingroup group_hal_results * \{ *//** */ /** Functionality not supported on the current platform */ #define CYHAL_SYSTEM_RSLT_ERR_NOT_SUPPORTED \ (CY_RSLT_CREATE_EX(CY_RSLT_TYPE_ERROR, CY_RSLT_MODULE_ABSTRACTION_HAL, CYHAL_RSLT_MODULE_SYSTEM, 0)) /** Incorrect argument passed into a function */ #define CYHAL_SYSTEM_RSLT_BAD_ARGUMENT \ (CY_RSLT_CREATE_EX(CY_RSLT_TYPE_ERROR, CY_RSLT_MODULE_ABSTRACTION_HAL, CYHAL_RSLT_MODULE_SYSTEM, 1)) /** Failed to reset the device */ #define CYHAL_SYSTEM_RSLT_FAILED_RESET \ (CY_RSLT_CREATE_EX(CY_RSLT_TYPE_ERROR, CY_RSLT_MODULE_ABSTRACTION_HAL, CYHAL_RSLT_MODULE_SYSTEM, 2)) /** * \} */ /** Flags enum of possible system reset causes */ typedef enum { CYHAL_SYSTEM_RESET_NONE = 0, /**< No cause */ CYHAL_SYSTEM_RESET_WDT = 1 << 0, /**< A watchdog timer (WDT) reset has occurred */ CYHAL_SYSTEM_RESET_ACTIVE_FAULT = 1 << 1, /**< The fault logging system requested a reset from its Active logic. */ CYHAL_SYSTEM_RESET_DEEPSLEEP_FAULT = 1 << 2, /**< The fault logging system requested a reset from its Deep-Sleep logic. */ CYHAL_SYSTEM_RESET_SOFT = 1 << 3, /**< The CPU requested a system reset through it's SYSRESETREQ. */ CYHAL_SYSTEM_RESET_HIB_WAKEUP = 1 << 4, /**< A reset has occurred due to a a wakeup from hibernate power mode. */ CYHAL_SYSTEM_RESET_WCO_ERR = 1 << 5, /**< A reset has occurred due to a watch-crystal clock error */ CYHAL_SYSTEM_RESET_SYS_CLK_ERR = 1 << 6, /**< A reset has occurred due to a system clock error */ CYHAL_SYSTEM_RESET_PROTECTION = 1 << 7, /**< A reset has occurred due to a protection violation */ CYHAL_SYSTEM_RESET_WARMBOOT = 1 << 8, /**< A reset has occurred due wake up from DSRAM, which is a Warm Boot */ } cyhal_reset_reason_t; /** Function pointer for IRQ handlers ( \ref cyhal_system_set_isr). */ typedef void (* cyhal_irq_handler)(void); /** Enter a critical section * * Disables interrupts and returns a value indicating whether the interrupts were previously * enabled. * * @return Returns the state before entering the critical section. This value must be provided * to \ref cyhal_system_critical_section_exit() to properly restore the state * * See \ref subsection_system_snippet1 for code snippet on critical section */ uint32_t cyhal_system_critical_section_enter(void); /** Exit a critical section * * Re-enables the interrupts if they were enabled before * cyhal_system_critical_section_enter() was called. The argument should be the value * returned from \ref cyhal_system_critical_section_enter(). * * @param[in] old_state The state of interrupts from cyhal_system_critical_section_enter() * * See \ref subsection_system_snippet1 for code snippet on critical section */ void cyhal_system_critical_section_exit(uint32_t old_state); /** * Requests that the current operation delays for at least the specified length of time. * If this is running in an RTOS aware environment (COMPONENTS+=RTOS_AWARE) or * (DEFINES+=CY_RTOS_AWARE) it will attempt to have the RTOS suspend the current task * so others can continue to run. If this is not run under an RTOS it will then defer to * the standard system delay which is likely to be a busy loop. * If this is part of an application that is build with RTOS awareness, but the delay * should not depend on the RTOS for whatever reason, use cyhal_system_delay_us() with * the appropriate 1000x multiplier to the delay time. * * @param[in] milliseconds The number of milliseconds to delay for * @return Returns CY_RSLT_SUCCESS if the delay request was successful, otherwise error */ cy_rslt_t cyhal_system_delay_ms(uint32_t milliseconds); /** * Requests that the current operation delay for at least the specified number of * micro-seconds. This will generally keep the processor active in a loop for the * specified length of time. If this is running under an RTOS, it will NOT attempt to * run any other RTOS tasks, however if the scheduler or a high priority interrupt * comes it they can take over anyway. * * @param[in] microseconds The number of micro-seconds to delay for */ void cyhal_system_delay_us(uint16_t microseconds); /** Gets the cause of the latest reset or resets that occurred in the system. * * @return Returns an enum of flags with the cause of the last reset(s) * * Refer \ref subsection_system_snippet2 for code snippet on cyhal_system_get_reset_reason */ cyhal_reset_reason_t cyhal_system_get_reset_reason(void); /** Clears the reset cause registers. This should be done after calling * \ref cyhal_system_get_reset_reason to make sure the reason does not persist between resets. */ void cyhal_system_clear_reset_reason(void); /** Resets the device * * The mechanism used to reset the device is implementation-specific and the reset * behavior differs between devices. * * @return This function does not return if successful. Otherwise an error is returned. */ cy_rslt_t cyhal_system_reset_device(void); /** Registers the specified handler as the callback function for the specified irq_num with the * given priority. For devices that mux interrupt sources into mcu interrupts, the irq_src defines * the source of the interrupt. * * @param[in] irq_num The MCU interrupt number to register the handler for. * @param[in] irq_src The interrupt source that feeds the MCU interrupt. For devices that have a * 1:1 mapping between interrupt sources and MCU interrupts this should be the same as the irq_num. * @param[in] priority The MCU interrupt priority. * @param[in] handler The function pointer to call when the interrupt is triggered. * @return Returns CY_RSLT_SUCCESS if the set_isr request was successful, otherwise an error */ cy_rslt_t cyhal_system_set_isr(int32_t irq_num, int32_t irq_src, uint8_t priority, cyhal_irq_handler handler); #if defined(__cplusplus) } #endif #ifdef CYHAL_SYSTEM_IMPL_HEADER #include CYHAL_SYSTEM_IMPL_HEADER #endif /* CYHAL_SYSTEM_IMPL_HEADER */ /** \} group_hal_system */