nes-proj/cpu/stm32w108/hal/micro/cortexm3/spmr.s79
2011-03-22 19:35:49 +01:00

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 lt
LDRLT R0, =0
LDRGE R0, =1
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__