Newer
Older
mbed-os / targets / TARGET_Cypress / TARGET_PSOC6 / mtb-hal-cat1 / include / cyhal_system.h
@Dustin Crossman Dustin Crossman on 4 Jun 2021 7 KB Fix file modes.
/***************************************************************************//**
* \file cyhal_system.h
*
* \brief
* Provides a high level interface for interacting with the Cypress 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-2021 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. <br>
* \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 <stdint.h>
#include <stdbool.h>
#include "cy_result.h"
#include "cyhal_hw_types.h"

#if defined(__cplusplus)
extern "C" {
#endif

/** 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_reset_reason_t;

/** 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 */
void cyhal_system_clear_reset_reason(void);

#if defined(__cplusplus)
}
#endif

#ifdef CYHAL_SYSTEM_IMPL_HEADER
#include CYHAL_SYSTEM_IMPL_HEADER
#endif /* CYHAL_SYSTEM_IMPL_HEADER */

/** \} group_hal_system */