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-2022 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 /** \addtogroup group_hal_results_system SYSTEM HAL Results
81  *  SYSTEM specific return codes
82  *  \ingroup group_hal_results
83  *  \{ *//**
84  */
85 
86 /** Functionality not supported on the current platform */
87 #define CYHAL_SYSTEM_RSLT_ERR_NOT_SUPPORTED           \
88     (CY_RSLT_CREATE_EX(CY_RSLT_TYPE_ERROR, CY_RSLT_MODULE_ABSTRACTION_HAL, CYHAL_RSLT_MODULE_SYSTEM, 0))
89 /** Incorrect argument passed into a function */
90 #define CYHAL_SYSTEM_RSLT_BAD_ARGUMENT           \
91     (CY_RSLT_CREATE_EX(CY_RSLT_TYPE_ERROR, CY_RSLT_MODULE_ABSTRACTION_HAL, CYHAL_RSLT_MODULE_SYSTEM, 1))
92 /** Failed to reset the device */
93 #define CYHAL_SYSTEM_RSLT_FAILED_RESET           \
94     (CY_RSLT_CREATE_EX(CY_RSLT_TYPE_ERROR, CY_RSLT_MODULE_ABSTRACTION_HAL, CYHAL_RSLT_MODULE_SYSTEM, 2))
95 
96 /**
97  * \}
98  */
99 
100 /** Flags enum of possible system reset causes */
101 typedef enum
102 {
103     CYHAL_SYSTEM_RESET_NONE            = 0,      /**< No cause */
104     CYHAL_SYSTEM_RESET_WDT             = 1 << 0, /**< A watchdog timer (WDT) reset has occurred */
105     CYHAL_SYSTEM_RESET_ACTIVE_FAULT    = 1 << 1, /**< The fault logging system requested a reset from its Active logic. */
106     CYHAL_SYSTEM_RESET_DEEPSLEEP_FAULT = 1 << 2, /**< The fault logging system requested a reset from its Deep-Sleep logic. */
107     CYHAL_SYSTEM_RESET_SOFT            = 1 << 3, /**< The CPU requested a system reset through it's SYSRESETREQ. */
108     CYHAL_SYSTEM_RESET_HIB_WAKEUP      = 1 << 4, /**< A reset has occurred due to a a wakeup from hibernate power mode. */
109     CYHAL_SYSTEM_RESET_WCO_ERR         = 1 << 5, /**< A reset has occurred due to a watch-crystal clock error */
110     CYHAL_SYSTEM_RESET_SYS_CLK_ERR     = 1 << 6, /**< A reset has occurred due to a system clock error */
111     CYHAL_SYSTEM_RESET_PROTECTION      = 1 << 7, /**< A reset has occurred due to a protection violation */
112 	CYHAL_SYSTEM_RESET_WARMBOOT        = 1 << 8, /**< A reset has occurred due wake up from DSRAM, which is a Warm Boot */
113 } cyhal_reset_reason_t;
114 
115 /** Function pointer for IRQ handlers ( \ref cyhal_system_set_isr). */
116 typedef void (* cyhal_irq_handler)(void);
117 
118 /** Enter a critical section
119  *
120  * Disables interrupts and returns a value indicating whether the interrupts were previously
121  * enabled.
122  *
123  * @return Returns the state before entering the critical section. This value must be provided
124  * to \ref cyhal_system_critical_section_exit() to properly restore the state
125  *
126  * See \ref subsection_system_snippet1 for code snippet on critical section
127  */
128 uint32_t cyhal_system_critical_section_enter(void);
129 
130 /** Exit a critical section
131  *
132  * Re-enables the interrupts if they were enabled before
133  *  cyhal_system_critical_section_enter() was called. The argument should be the value
134  *  returned from \ref cyhal_system_critical_section_enter().
135  *
136  * @param[in] old_state The state of interrupts from cyhal_system_critical_section_enter()
137  *
138  * See \ref subsection_system_snippet1 for code snippet on critical section
139  */
140 void cyhal_system_critical_section_exit(uint32_t old_state);
141 
142 /**
143  * Requests that the current operation delays for at least the specified length of time.
144  * If this is running in an RTOS aware environment (COMPONENTS+=RTOS_AWARE) or
145  * (DEFINES+=CY_RTOS_AWARE) it will attempt to have the RTOS suspend the current task
146  * so others can continue to run. If this is not run under an RTOS it will then defer to
147  * the standard system delay which is likely to be a busy loop.
148  * If this is part of an application that is build with RTOS awareness, but the delay
149  * should not depend on the RTOS for whatever reason, use cyhal_system_delay_us() with
150  * the appropriate 1000x multiplier to the delay time.
151  *
152  * @param[in] milliseconds The number of milliseconds to delay for
153  * @return Returns CY_RSLT_SUCCESS if the delay request was successful, otherwise error
154  */
155 cy_rslt_t cyhal_system_delay_ms(uint32_t milliseconds);
156 
157 /**
158  * Requests that the current operation delay for at least the specified number of
159  * micro-seconds. This will generally keep the processor active in a loop for the
160  * specified length of time. If this is running under an RTOS, it will NOT attempt to
161  * run any other RTOS tasks, however if the scheduler or a high priority interrupt
162  * comes it they can take over anyway.
163  *
164  * @param[in] microseconds The number of micro-seconds to delay for
165  */
166 void cyhal_system_delay_us(uint16_t microseconds);
167 
168 /** Gets the cause of the latest reset or resets that occurred in the system.
169  *
170  * @return Returns an enum of flags with the cause of the last reset(s)
171  *
172  * Refer \ref subsection_system_snippet2 for code snippet on cyhal_system_get_reset_reason
173  */
174 cyhal_reset_reason_t cyhal_system_get_reset_reason(void);
175 
176 /** Clears the reset cause registers. This should be done after calling
177  * \ref cyhal_system_get_reset_reason to make sure the reason does not persist between resets.
178  */
179 void cyhal_system_clear_reset_reason(void);
180 
181 /** Resets the device
182  *
183  * The mechanism used to reset the device is implementation-specific and the reset
184  * behavior differs between devices.
185  *
186  * @return This function does not return if successful. Otherwise an error is returned.
187  */
188 cy_rslt_t cyhal_system_reset_device(void);
189 
190 /** Registers the specified handler as the callback function for the specified irq_num with the
191  * given priority. For devices that mux interrupt sources into mcu interrupts, the irq_src defines
192  * the source of the interrupt.
193  *
194  * @param[in] irq_num   The MCU interrupt number to register the handler for.
195  * @param[in] irq_src   The interrupt source that feeds the MCU interrupt. For devices that have a
196  * 1:1 mapping between interrupt sources and MCU interrupts this should be the same as the irq_num.
197  * @param[in] priority  The MCU interrupt priority.
198  * @param[in] handler   The function pointer to call when the interrupt is triggered.
199  * @return Returns CY_RSLT_SUCCESS if the set_isr request was successful, otherwise an error
200  */
201 cy_rslt_t cyhal_system_set_isr(int32_t irq_num, int32_t irq_src, uint8_t priority, cyhal_irq_handler handler);
202 
203 #if defined(__cplusplus)
204 }
205 #endif
206 
207 #ifdef CYHAL_SYSTEM_IMPL_HEADER
208 #include CYHAL_SYSTEM_IMPL_HEADER
209 #endif /* CYHAL_SYSTEM_IMPL_HEADER */
210 
211 /** \} group_hal_system */
212