David Kester / nRF51822

Dependents:   GonioTrainer

Fork of nRF51822 by Nordic Semiconductor

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers app_util_platform.h Source File

app_util_platform.h

Go to the documentation of this file.
00001 /* Copyright (c) 2014 Nordic Semiconductor. All Rights Reserved.
00002  *
00003  * The information contained herein is property of Nordic Semiconductor ASA.
00004  * Terms and conditions of usage are described in detail in NORDIC
00005  * SEMICONDUCTOR STANDARD SOFTWARE LICENSE AGREEMENT.
00006  *
00007  * Licensees are granted free, non-transferable use of the information. NO
00008  * WARRANTY of ANY KIND is provided. This heading must NOT be removed from
00009  * the file.
00010  *
00011  */
00012 
00013 /**@file
00014  *
00015  * @defgroup app_util_platform Utility Functions and Definitions (Platform)
00016  * @{
00017  * @ingroup app_common
00018  *
00019  * @brief Various types and definitions available to all applications when using SoftDevice.
00020  */
00021 
00022 #ifndef APP_UTIL_PLATFORM_H__
00023 #define APP_UTIL_PLATFORM_H__
00024 
00025 #include <stdint.h>
00026 #include "compiler_abstraction.h"
00027 #include "nrf51.h"
00028 #ifdef SOFTDEVICE_PRESENT
00029 #include "nrf_soc.h"
00030 #include "app_error.h"
00031 #endif
00032 /**@brief The interrupt priorities available to the application while the SoftDevice is active. */
00033 typedef enum
00034 {
00035 #ifndef SOFTDEVICE_PRESENT
00036     APP_IRQ_PRIORITY_HIGHEST = 0,
00037 #endif
00038     APP_IRQ_PRIORITY_HIGH    = 1,
00039 #ifndef SOFTDEVICE_PRESENT
00040     APP_IRQ_PRIORITY_MID     = 2,
00041 #endif
00042     APP_IRQ_PRIORITY_LOW     = 3
00043 } app_irq_priority_t;
00044 
00045 #define NRF_APP_PRIORITY_THREAD    4                    /**< "Interrupt level" when running in Thread Mode. */
00046 
00047 /**@cond NO_DOXYGEN */
00048 #define EXTERNAL_INT_VECTOR_OFFSET 16
00049 /**@endcond */
00050 
00051 #define PACKED(TYPE) __packed TYPE
00052 
00053 void critical_region_enter (void);
00054 void critical_region_exit (void);
00055 
00056 /**@brief Macro for entering a critical region.
00057  *
00058  * @note Due to implementation details, there must exist one and only one call to
00059  *       CRITICAL_REGION_EXIT() for each call to CRITICAL_REGION_ENTER(), and they must be located
00060  *       in the same scope.
00061  */
00062 #ifdef SOFTDEVICE_PRESENT
00063 #define CRITICAL_REGION_ENTER()                                                             \
00064     {                                                                                       \
00065         uint8_t IS_NESTED_CRITICAL_REGION = 0;                                              \
00066         uint32_t CURRENT_INT_PRI = current_int_priority_get();                              \
00067         if (CURRENT_INT_PRI != APP_IRQ_PRIORITY_HIGH)                                       \
00068         {                                                                                   \
00069             uint32_t ERR_CODE = sd_nvic_critical_region_enter(&IS_NESTED_CRITICAL_REGION);  \
00070             if (ERR_CODE == NRF_ERROR_SOFTDEVICE_NOT_ENABLED)                               \
00071             {                                                                               \
00072                 __disable_irq();                                                            \
00073             }                                                                               \
00074             else                                                                            \
00075             {                                                                               \
00076                 APP_ERROR_CHECK(ERR_CODE);                                                  \
00077             }                                                                               \
00078         }        
00079 #else
00080 #define CRITICAL_REGION_ENTER() critical_region_enter()
00081 #endif
00082 
00083 /**@brief Macro for leaving a critical region.
00084  *
00085  * @note Due to implementation details, there must exist one and only one call to
00086  *       CRITICAL_REGION_EXIT() for each call to CRITICAL_REGION_ENTER(), and they must be located
00087  *       in the same scope.
00088  */
00089 #ifdef SOFTDEVICE_PRESENT
00090 #define CRITICAL_REGION_EXIT()                                                              \
00091         if (CURRENT_INT_PRI != APP_IRQ_PRIORITY_HIGH)                                       \
00092         {                                                                                   \
00093             uint32_t ERR_CODE;                                                              \
00094             __enable_irq();                                                                 \
00095             ERR_CODE = sd_nvic_critical_region_exit(IS_NESTED_CRITICAL_REGION);             \
00096             if (ERR_CODE != NRF_ERROR_SOFTDEVICE_NOT_ENABLED)                               \
00097             {                                                                               \
00098                 APP_ERROR_CHECK(ERR_CODE);                                                  \
00099             }                                                                               \
00100         }                                                                                   \
00101     }
00102 #else
00103 #define CRITICAL_REGION_EXIT() critical_region_exit()
00104 #endif 
00105        
00106 /**@brief Function for finding the current interrupt level.
00107  *
00108  * @return   Current interrupt level.
00109  * @retval   APP_IRQ_PRIORITY_HIGH    We are running in Application High interrupt level.
00110  * @retval   APP_IRQ_PRIORITY_LOW     We are running in Application Low interrupt level.
00111  * @retval   APP_IRQ_PRIORITY_THREAD  We are running in Thread Mode.
00112  */
00113 static __INLINE uint8_t current_int_priority_get(void)
00114 {
00115     uint32_t isr_vector_num = (SCB->ICSR & SCB_ICSR_VECTACTIVE_Msk);
00116     if (isr_vector_num > 0)
00117     {
00118         int32_t irq_type = ((int32_t)isr_vector_num - EXTERNAL_INT_VECTOR_OFFSET);
00119         return (NVIC_GetPriority((IRQn_Type )irq_type) & 0xFF);
00120     }
00121     else
00122     {
00123         return NRF_APP_PRIORITY_THREAD;
00124     }
00125 }
00126 
00127 #endif // APP_UTIL_PLATFORM_H__
00128 
00129 /** @} */