blob: a2c64cef117ecde4be0141758c85a273924f6d96 [file] [log] [blame]
/**
*******************************************************************************
*
* @file ll.h
*
* @brief Declaration of low level functions.
*
* Copyright (C) RivieraWaves 2009-2015
* Copyright (C) Atmosic 2017-2021
*
*******************************************************************************
*/
#pragma once
/**
* @defgroup LL Low level
* @ingroup ATM2x
* @brief Low level functions
* @{
*/
#if !defined(__GNUC__) && !defined(__ICCARM__)
#error "File only included with ARM GCC or IAR ANSI C/C++ Compiler for ARM"
#endif
#ifdef CORTEX_M0
#pragma push_macro("__INLINE")
#undef __INLINE
#include "CMSDK_CM0.h"
#include "core_cm0.h"
#pragma pop_macro("__INLINE")
#endif
#ifdef __ICCARM__
#include <intrinsics.h>
#endif
#include <stdbool.h>
#include <stdint.h>
#ifdef __cplusplus
extern "C" {
#endif
/// Interrupt priorities
#define IRQ_PRI_RT 0 // Real time - highest priority
#define IRQ_PRI_HIGH 1
#define IRQ_PRI_NORMAL 2
#define IRQ_PRI_UI 3 // User interface - lowest priority
/** @brief Enable interrupts globally in the system.
* This macro must be used when the initialization phase is over and the interrupts
* can start being handled by the system.
*/
#define GLOBAL_INT_START() \
do { \
__enable_irq(); \
} while(0)
/** @brief Disable interrupts globally in the system.
* This macro must be used when the system wants to disable all the interrupt
* it could handle.
*/
#define GLOBAL_INT_STOP() \
do { \
__disable_irq(); \
} while(0)
/** @brief Disable interrupts globally in the system.
* This macro must be used in conjunction with the @ref GLOBAL_INT_RESTORE macro since this
* last one will close the brace that the current macro opens. This means that both
* macros must be located at the same scope level.
*/
#define GLOBAL_INT_DISABLE() \
do { \
uint32_t __PRIMASK_save = __get_PRIMASK(); \
__disable_irq()
#define STATIC_GLOBAL_INT_DISABLE() \
do { \
static uint32_t __PRIMASK_save; \
__PRIMASK_save = __get_PRIMASK(); \
__disable_irq()
/** @brief Restore interrupts from the previous global disable.
* @sa GLOBAL_INT_DISABLE
*/
#define GLOBAL_INT_RESTORE() \
__set_PRIMASK(__PRIMASK_save); \
} while(0)
/** @brief Invoke the wait for interrupt procedure of the processor.
*
* @warning It is suggested that this macro is called while the interrupts are disabled
* to have performed the checks necessary to decide to move to sleep mode.
*
*/
#define WFI() __WFI()
/**
* @brief Wait for a condition to be made true by an interrupt handler.
*/
#define WFI_COND(__c) do { \
bool done = false; \
do { \
GLOBAL_INT_DISABLE(); \
if (__c) { \
done = true; \
} else { \
WFI(); \
} \
GLOBAL_INT_RESTORE(); \
} while (!done); \
} while(0)
/**
* @brief Relax the running CPU thread, especially when spinning.
*/
#define YIELD() __ASM volatile ("yield")
#ifdef __cplusplus
}
#endif
/// @} LL