1 /***************************************************************************//**
2 * \file cyhal_system.h
3 *
4 * \brief
5 * Provides a high level interface for interacting with the Infineon power
6 * management and system clock configuration. This interface abstracts out the
7 * chip specific details. If any chip specific functionality is necessary, or
8 * performance is critical the low level functions can be used directly.
9 *
10 ********************************************************************************
11 * \copyright
12 * Copyright 2018-2021 Cypress Semiconductor Corporation (an Infineon company) or
13 * an affiliate of Cypress Semiconductor Corporation
14 *
15 * SPDX-License-Identifier: Apache-2.0
16 *
17 * Licensed under the Apache License, Version 2.0 (the "License");
18 * you may not use this file except in compliance with the License.
19 * You may obtain a copy of the License at
20 *
21 *     http://www.apache.org/licenses/LICENSE-2.0
22 *
23 * Unless required by applicable law or agreed to in writing, software
24 * distributed under the License is distributed on an "AS IS" BASIS,
25 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
26 * See the License for the specific language governing permissions and
27 * limitations under the License.
28 *******************************************************************************/
29 
30 /**
31 * \addtogroup group_hal_system System
32 * \ingroup group_hal
33 * \{
34 * High level interface for interacting with reset and delays.
35 *
36 * \section section_system_features Features
37 * This driver provides three categories of functionality:
38 * * Ability to get the last reset reason.
39 * * Ability to delay for a period of time.
40 * * The ability to disable interrupts during a critical section.
41 *
42 * \section subsection_system_quickstart Quick Start
43 * * \ref cyhal_system_critical_section_enter and \ref
44 * cyhal_system_critical_section_exit are used to enable/disable global interrupts
45 * * \ref cyhal_system_delay_ms and \ref cyhal_system_delay_us are delay functions
46 * used to halt the CPU exectution for a specified period of time
47 * * \ref cyhal_system_get_reset_reason gets the cause of latest system reset and
48 * \ref cyhal_system_clear_reset_reason clears the reset cause registers
49 *
50 * \section subsection_system_codesnippet Code Snippets
51 * \subsection subsection_system_snippet1 Snippet 1: Critical Section
52 * Critical section is a portion in the code where all active interrupts are
53 * disabled. This is usually provided in places where the code execution must not
54 * be disturbed by an interrupt. An example is a firmware controlled communication
55 * protocol where timing of each byte must be maintained and any interrupt might
56 * cause loss of data. <br>
57 * \ref cyhal_system_critical_section_enter returns the current state of interrupts
58 * which denote the active interrupts in the system. This must be passed as argument
59 * to \ref cyhal_system_critical_section_exit while exiting the critical section.
60 * \snippet hal_system.c snippet_cyhal_system_critical_section
61 *
62 * \subsection subsection_system_snippet2 Snippet 2: Reset reason
63 * \ref cyhal_system_get_reset_reason must be called at the beginning of the main to
64 * determine the reason for reset. The return parameters are present in \ref
65 * cyhal_reset_reason_t.
66 * \snippet hal_system.c snippet_cyhal_system_reset_reason
67 */
68 
69 #pragma once
70 
71 #include <stdint.h>
72 #include <stdbool.h>
73 #include "cy_result.h"
74 #include "cyhal_hw_types.h"
75 
76 #if defined(__cplusplus)
77 extern "C" {
78 #endif
79 
80 /** Flags enum of possible system reset causes */
81 typedef enum
82 {
83     CYHAL_SYSTEM_RESET_NONE            = 0,      /**< No cause */
84     CYHAL_SYSTEM_RESET_WDT             = 1 << 0, /**< A watchdog timer (WDT) reset has occurred */
85     CYHAL_SYSTEM_RESET_ACTIVE_FAULT    = 1 << 1, /**< The fault logging system requested a reset from its Active logic. */
86     CYHAL_SYSTEM_RESET_DEEPSLEEP_FAULT = 1 << 2, /**< The fault logging system requested a reset from its Deep-Sleep logic. */
87     CYHAL_SYSTEM_RESET_SOFT            = 1 << 3, /**< The CPU requested a system reset through it's SYSRESETREQ. */
88     CYHAL_SYSTEM_RESET_HIB_WAKEUP      = 1 << 4, /**< A reset has occurred due to a a wakeup from hibernate power mode. */
89     CYHAL_SYSTEM_RESET_WCO_ERR         = 1 << 5, /**< A reset has occurred due to a watch-crystal clock error */
90     CYHAL_SYSTEM_RESET_SYS_CLK_ERR     = 1 << 6, /**< A reset has occurred due to a system clock error */
91     CYHAL_SYSTEM_RESET_PROTECTION      = 1 << 7, /**< A reset has occurred due to a protection violation */
92 } cyhal_reset_reason_t;
93 
94 /** Function pointer for IRQ handlers ( \ref cyhal_system_set_isr). */
95 typedef void (* cyhal_irq_handler)(void);
96 
97 /** Enter a critical section
98  *
99  * Disables interrupts and returns a value indicating whether the interrupts were previously
100  * enabled.
101  *
102  * @return Returns the state before entering the critical section. This value must be provided
103  * to \ref cyhal_system_critical_section_exit() to properly restore the state
104  *
105  * See \ref subsection_system_snippet1 for code snippet on critical section
106  */
107 uint32_t cyhal_system_critical_section_enter(void);
108 
109 /** Exit a critical section
110  *
111  * Re-enables the interrupts if they were enabled before
112  *  cyhal_system_critical_section_enter() was called. The argument should be the value
113  *  returned from \ref cyhal_system_critical_section_enter().
114  *
115  * @param[in] old_state The state of interrupts from cyhal_system_critical_section_enter()
116  *
117  * See \ref subsection_system_snippet1 for code snippet on critical section
118  */
119 void cyhal_system_critical_section_exit(uint32_t old_state);
120 
121 /**
122  * Requests that the current operation delays for at least the specified length of time.
123  * If this is running in an RTOS aware environment (COMPONENTS+=RTOS_AWARE) or
124  * (DEFINES+=CY_RTOS_AWARE) it will attempt to have the RTOS suspend the current task
125  * so others can continue to run. If this is not run under an RTOS it will then defer to
126  * the standard system delay which is likely to be a busy loop.
127  * If this is part of an application that is build with RTOS awareness, but the delay
128  * should not depend on the RTOS for whatever reason, use cyhal_system_delay_us() with
129  * the appropriate 1000x multiplier to the delay time.
130  *
131  * @param[in] milliseconds The number of milliseconds to delay for
132  * @return Returns CY_RSLT_SUCCESS if the delay request was successful, otherwise error
133  */
134 cy_rslt_t cyhal_system_delay_ms(uint32_t milliseconds);
135 
136 /**
137  * Requests that the current operation delay for at least the specified number of
138  * micro-seconds. This will generally keep the processor active in a loop for the
139  * specified length of time. If this is running under an RTOS, it will NOT attempt to
140  * run any other RTOS tasks, however if the scheduler or a high priority interrupt
141  * comes it they can take over anyway.
142  *
143  * @param[in] microseconds The number of micro-seconds to delay for
144  */
145 void cyhal_system_delay_us(uint16_t microseconds);
146 
147 /** Gets the cause of the latest reset or resets that occurred in the system.
148  *
149  * @return Returns an enum of flags with the cause of the last reset(s)
150  *
151  * Refer \ref subsection_system_snippet2 for code snippet on cyhal_system_get_reset_reason
152  */
153 cyhal_reset_reason_t cyhal_system_get_reset_reason(void);
154 
155 /** Clears the reset cause registers. This should be done after calling
156  * \ref cyhal_system_get_reset_reason to make sure the reason does not persist between resets.
157  */
158 void cyhal_system_clear_reset_reason(void);
159 
160 /** Registers the specified handler as the callback function for the specififed irq_num with the
161  * given priority. For devices that mux interrupt sources into mcu interrupts, the irq_src defines
162  * the source of the interrupt.
163  *
164  * @param[in] irq_num   The MCU interrupt number to register the handler for.
165  * @param[in] irq_src   The interrupt source that feeds the MCU interrupt. For devices that have a
166  * 1:1 mapping between interrupt sources and MCU interrupts this should be the same as the irq_num.
167  * @param[in] priority  The MCU interrupt priority.
168  * @param[in] handler   The function pointer to call when the interrupt is triggered.
169  * @return Returns CY_RSLT_SUCCESS if the set_isr request was successful, otherwise an error
170  */
171 cy_rslt_t cyhal_system_set_isr(int32_t irq_num, int32_t irq_src, uint8_t priority, cyhal_irq_handler handler);
172 
173 #if defined(__cplusplus)
174 }
175 #endif
176 
177 #ifdef CYHAL_SYSTEM_IMPL_HEADER
178 #include CYHAL_SYSTEM_IMPL_HEADER
179 #endif /* CYHAL_SYSTEM_IMPL_HEADER */
180 
181 /** \} group_hal_system */
182