#ifndef __PAN_UTILITY_H__
#define __PAN_UTILITY_H__

#include <stdint.h>
#include <stdbool.h>
#include <cmsis_compiler.h>

/**
 * @brief Lock interrupts.
 *
 * This routine disables all interrupts on the CPU. It returns an unsigned
 * integer "lock-out key", which is an indicator of whether interrupts were
 * locked prior to the call. The lock-out key must be passed to irq_unlock()
 * to re-enable interrupts.
 *
 * @warning
 * The lock-out key should never be used to manually re-enable interrupts
 * or to inspect or manipulate the contents of the CPU's interrupt bits.
 *
 * @return A lock-out key representing the
 *         "interrupt disable state" prior to the call.
 */
__STATIC_FORCEINLINE uint32_t irq_lock(void)
{
    uint32_t primask = __get_PRIMASK();
    __disable_irq();
    return primask;
}

/**
 * @brief Unlock interrupts.
 *
 * This routine reverses the effect of a previous call to irq_lock() using
 * the associated lock-out key. The caller must call the routine once for
 * each time it called irq_lock(), supplying the keys in the reverse order
 * they were acquired, before interrupts are enabled.
 *
 * @note Can be called by ISRs.
 *
 * @param key Lock-out key generated by irq_lock().
 *
 * @return N/A
 */
__STATIC_FORCEINLINE void irq_unlock(uint32_t key)
{
    __set_PRIMASK(key);
}

/**
 * @brief : Verify that the current program is in interrupt.
 */
__STATIC_FORCEINLINE bool IN_ISR(void)
{
    return __get_IPSR() ? true : false;
}

#endif // __PAN_UTILITY_H__
