182 lines
6.7 KiB
Plaintext
182 lines
6.7 KiB
Plaintext
|
//------------------------------------------------------------------------------
|
||
|
// @file hal/micro/cortexm3/spmr.s79
|
||
|
// @brief SPMR (Special Purpose Mask Registers) manipulation routines.
|
||
|
//
|
||
|
// Since the compiler does not provide low level intrinsic functions for some
|
||
|
// required operations, this file maintains the small set of assembly code
|
||
|
// needed to manipulate the Special Purpose Mask Registers.
|
||
|
//
|
||
|
// While it is possible to add this functionality as inline assembly in C files,
|
||
|
// IAR highly recommends against this due to not only code being fragile in its
|
||
|
// surroundings, but it also negates the possibility of size optimization.
|
||
|
//
|
||
|
// NOTE: This file looks more complicated than it really is. It was originally
|
||
|
// generated by writing a C file and having the compiler generate the
|
||
|
// corresponding assembly file. This is where all the CFI (Call Frame
|
||
|
// Information) expressions came from. The CFI information enables proper debug
|
||
|
// backtrace ability. The pieces to pay attention to are the actual funtions
|
||
|
// near the end.
|
||
|
//
|
||
|
// * <!--(C) COPYRIGHT 2010 STMicroelectronics. All rights reserved. -->
|
||
|
//------------------------------------------------------------------------------
|
||
|
|
||
|
#include "compiler/asm.h"
|
||
|
|
||
|
// NOTE!! IF THIS VALUE IS CHANGED, NVIC-CONFIG.H MUST ALSO BE UPDATED
|
||
|
#define INTERRUPTS_DISABLED_PRIORITY (12 << 3)
|
||
|
|
||
|
__EXPORT__ _readBasePri
|
||
|
__EXPORT__ _writeBasePri
|
||
|
__EXPORT__ _disableBasePri
|
||
|
__EXPORT__ _basePriIsDisabled
|
||
|
__EXPORT__ _enableBasePri
|
||
|
__EXPORT__ _setPriMask
|
||
|
__EXPORT__ _clearPriMask
|
||
|
__EXPORT__ _executeBarrierInstructions
|
||
|
|
||
|
//------------------------------------------------------------------------------
|
||
|
// int8u _readBasePri(void)
|
||
|
//
|
||
|
// Read and return the BASEPRI value.
|
||
|
//
|
||
|
//------------------------------------------------------------------------------
|
||
|
__CODE__
|
||
|
__THUMB__
|
||
|
__CFI__(Block cfiBlock0 Using cfiCommon0)
|
||
|
__CFI__(Function _readBasePri)
|
||
|
_readBasePri:
|
||
|
MRS R0, BASEPRI // read current BASEPRI
|
||
|
BX LR
|
||
|
__CFI__(EndBlock cfiBlock0)
|
||
|
|
||
|
//------------------------------------------------------------------------------
|
||
|
// void _writeBasePri(int8u priority)
|
||
|
//
|
||
|
// Write BASEPRI with the passed value to obtain the proper preemptive priority
|
||
|
// group masking. Note that the value passed must have been left shifted by 3
|
||
|
// to be properly aligned in the BASEPRI register.
|
||
|
// (Refer to nvic-config.h for the PRIGROUP table.)
|
||
|
//
|
||
|
//------------------------------------------------------------------------------
|
||
|
__CODE__
|
||
|
__THUMB__
|
||
|
__CFI__(Block cfiBlock1 Using cfiCommon0)
|
||
|
__CFI__(Function _writeBasePri)
|
||
|
_writeBasePri:
|
||
|
MSR BASEPRI, R0 // load BASEPRI from variable (R0)
|
||
|
BX LR
|
||
|
__CFI__(EndBlock cfiBlock1)
|
||
|
|
||
|
//------------------------------------------------------------------------------
|
||
|
// int8u _disableBasePri(void)
|
||
|
//
|
||
|
// Set BASEPRI to mask out interrupts but allow faults. It returns the value
|
||
|
// BASEPRI had when it was called.
|
||
|
//
|
||
|
//------------------------------------------------------------------------------
|
||
|
__CODE__
|
||
|
__THUMB__
|
||
|
__CFI__(Block cfiBlock2 Using cfiCommon0)
|
||
|
__CFI__(Function _disableBasePri)
|
||
|
_disableBasePri:
|
||
|
MRS R0, BASEPRI // read current BASEPRI
|
||
|
LDR R1, =INTERRUPTS_DISABLED_PRIORITY // disable ints, allow faults
|
||
|
MSR BASEPRI, R1
|
||
|
BX LR
|
||
|
__CFI__(EndBlock cfiBlock2)
|
||
|
|
||
|
//------------------------------------------------------------------------------
|
||
|
// boolean _basePriIsDisabled(void)
|
||
|
//
|
||
|
// Compare BASEPRI to the priority used to disable interrupts (but not faults).
|
||
|
// Return TRUE if the priority is higher or equal to that.
|
||
|
//
|
||
|
//------------------------------------------------------------------------------
|
||
|
__CODE__
|
||
|
__THUMB__
|
||
|
__CFI__(Block cfiBlock3 Using cfiCommon0)
|
||
|
__CFI__(Function _basePriIsDisabled)
|
||
|
_basePriIsDisabled:
|
||
|
MRS R0, BASEPRI // read current BASEPRI
|
||
|
CMP R0, #INTERRUPTS_DISABLED_PRIORITY
|
||
|
ITE le
|
||
|
LDRLE R0, =1
|
||
|
LDRGT R0, =0
|
||
|
BX LR
|
||
|
__CFI__(EndBlock cfiBlock3)
|
||
|
|
||
|
//------------------------------------------------------------------------------
|
||
|
// void _enableBasePri(void)
|
||
|
//
|
||
|
// Set BASEPRI to 0, which disables it from masking any interrupts.
|
||
|
//
|
||
|
//------------------------------------------------------------------------------
|
||
|
__CODE__
|
||
|
__THUMB__
|
||
|
__CFI__(Block cfiBlock4 Using cfiCommon0)
|
||
|
__CFI__(Function _enableBasePri)
|
||
|
_enableBasePri:
|
||
|
LDR R1, = 0 // zero disables BASEPRI masking
|
||
|
MSR BASEPRI, R1
|
||
|
BX LR
|
||
|
__CFI__(EndBlock cfiBlock4)
|
||
|
|
||
|
//------------------------------------------------------------------------------
|
||
|
// void _setPriMask(void)
|
||
|
//
|
||
|
// Set the 1-bit PRIMASK register, which sets the base priority to 0. This
|
||
|
// locks out all interrupts and configurable faults (usage, memory management
|
||
|
// and bus faults).
|
||
|
//
|
||
|
// Note: generally speaking PRIMASK should not be set because faults should
|
||
|
// be enabled even when interrupts are disabled. If they are not enabled,
|
||
|
// a fault will immediately escalate to a hard fault.
|
||
|
//
|
||
|
//------------------------------------------------------------------------------
|
||
|
__CODE__
|
||
|
__THUMB__
|
||
|
__CFI__(Block cfiBlock5 Using cfiCommon0)
|
||
|
__CFI__(Function _setPriMask)
|
||
|
_setPriMask:
|
||
|
CPSID i
|
||
|
BX LR
|
||
|
__CFI__(EndBlock cfiBlock5)
|
||
|
|
||
|
//------------------------------------------------------------------------------
|
||
|
// void _clearPriMask(void)
|
||
|
//
|
||
|
// Clears the 1-bit PRIMASK register, which allows the BASEPRI value to
|
||
|
// mask interrupts (if non-zero).
|
||
|
//
|
||
|
//------------------------------------------------------------------------------
|
||
|
__CODE__
|
||
|
__THUMB__
|
||
|
__CFI__(Block cfiBlock6 Using cfiCommon0)
|
||
|
__CFI__(Function _clearPriMask)
|
||
|
_clearPriMask:
|
||
|
CPSIE i
|
||
|
BX LR
|
||
|
__CFI__(EndBlock cfiBlock6)
|
||
|
|
||
|
//------------------------------------------------------------------------------
|
||
|
// void _executeBarrierInstructions(void)
|
||
|
//
|
||
|
//A utility function for inserting barrier instructions. These
|
||
|
//instructions should be used whenever the MPU is enabled or disabled so
|
||
|
//that all memory/instruction accesses can complete before the MPU changes
|
||
|
//state.
|
||
|
//
|
||
|
//------------------------------------------------------------------------------
|
||
|
__CODE__
|
||
|
__THUMB__
|
||
|
__CFI__(Block cfiBlock7 Using cfiCommon0)
|
||
|
__CFI__(Function _executeBarrierInstructions)
|
||
|
_executeBarrierInstructions:
|
||
|
DMB
|
||
|
DSB
|
||
|
ISB
|
||
|
BX LR
|
||
|
__CFI__(EndBlock cfiBlock7)
|
||
|
|
||
|
__END__
|