📄 hal_intr.h
字号:
: "er0" \
);
//==========================================================================
// ENABLE INTERRUPTS
// DESCRIPTION:
// Simply enables interrupts regardless of the current state of the
// mask.
//
// NOTES:
// If we ware working in interrupt control mode 2 then we have to
// then we have to set Bit 0 - Bit 2 of EXR to zero in order to
// unmask all interrupts.
//==========================================================================
#define HAL_ENABLE_INTERRUPTS() \
asm volatile ( \
"andc #0xf8,exr" \
);
//==========================================================================
// RESTORE INTERRUPTS
// DESCRIPTION:
// Restores the state of the interrupt mask to that recorded in old.
//
// PARAMETERS:
// '_old_' Interrupt mask to be restored
//
// NOTES:
// We are working in interrupt control mode 2 so we are going to modify
// the interrupt mask bits in EXR register (Bit 0 - 2)
//==========================================================================
#define HAL_RESTORE_INTERRUPTS(_old_) \
asm volatile ( \
"mov.l %0,er0\n\t" \
"and.b #0x07,r0l\n\t" \
"stc exr,r0h\n\t" \
"and.b #0xf8,r0h\n\t" \
"or.b r0h,r0l\n\t" \
"ldc r0l,exr" \
: \
: "r"(_old_) \
: "er0" \
);
//==========================================================================
// QUERY INTERRUPTS
// DESCRIPTION:
// stores the state of the interrupt mask in the variable passed in
// the state argument. The state stored here should also be capable of
// being passed to HAL_RESTORE_INTERRUPTS() at a later point.
//
// PARAMETERS:
// '_state_' Stores interrupt state
//
// NOTES:
// We are working in interrupt control mode 2 so we are going to
// query the EXR register
//==========================================================================
#define HAL_QUERY_INTERRUPTS(_state_) \
asm volatile ( \
"sub.l er0,er0\n\t" \
"stc exr,r0l\n\t" \
"and.b #0x07,r0l\n\t" \
"mov.l er0,%0" \
: "=r"(_state_) \
);
//==========================================================================
// TEST VECTOR STATE
// DESCRIPTION:
// Tests the state of the supplied interrupt vector and sets the value
// of the state parameter to either 1 or 0 depending on whether there
// is already an ISR attached to the vector. The HAL will only allow one
// ISR to be attached to each vector, so it is a good idea to use this
// function before using HAL_INTERRUPT_ATTACH().
//
// PARAMETERS:
// '_vector_' Vector number to be tested
// '_state_' State of the vector in _vector_
// 0 - Vector not in use, 1 - Vector in use
//==========================================================================
#define HAL_INTERRUPT_IN_USE(_vector_, _state_) \
CYG_MACRO_START \
cyg_uint32 _index_; \
HAL_TRANSLATE_VECTOR ((_vector_), _index_); \
\
if (hal_interrupt_handlers[_index_] == (CYG_ADDRESS)HAL_DEFAULT_ISR) \
{ \
(_state_) = 0; \
} \
else \
{ \
(_state_) = 1; \
} \
CYG_MACRO_END
//==========================================================================
// ATTACH ISR TO VECTOR
// DESCRIPTION:
// Attaches the ISR, data pointer and object pointer to the given
// vector. When an interrupt occurs on this vector the ISR is called
// using the C calling convention and the vector number and data pointer
// are passed to it as the first and second arguments respectively.
//
// PARAMETERS:
// '_vector_' Vector number of vector where VSR should be attached
// '_isr_' Points to interrupt service routine
// '_data_' Pointer to data
// '_object_' Pointer to interrupt object
//==========================================================================
#if !defined(HAL_INTERRUPT_ATTACH)
#define HAL_INTERRUPT_ATTACH(_vector_, _isr_, _data_, _object_) \
CYG_MACRO_START \
cyg_uint32 _index_; \
HAL_TRANSLATE_VECTOR(_vector_, _index_); \
\
if (hal_interrupt_handlers[_index_] == (CYG_ADDRESS)HAL_DEFAULT_ISR) \
{ \
hal_interrupt_handlers[_index_] = (CYG_ADDRESS)_isr_; \
hal_interrupt_data[_index_] = (CYG_ADDRWORD)_data_; \
hal_interrupt_objects[_index_] = (CYG_ADDRESS)_object_; \
} \
CYG_MACRO_END
#endif // #if !defined(HAL_INTERRUPT_ATTACH)
//==========================================================================
// DETACH ISR FROM VECTOR
// DESCRIPTION:
// Detaches the ISR from the vector.
//
// PARAMETERS:
// '_vector_' Vector number
// '_isr_' Points to interrupt service routine
//==========================================================================
#define HAL_INTERRUPT_DETACH( _vector_, _isr_ ) \
CYG_MACRO_START \
cyg_uint32 _index_; \
HAL_TRANSLATE_VECTOR(_vector_, _index_); \
\
if (hal_interrupt_handlers[_index_] == (CYG_ADDRESS)_isr_ ) \
{ \
hal_interrupt_handlers[_index_] = (CYG_ADDRESS)HAL_DEFAULT_ISR; \
hal_interrupt_data[_index_] = 0; \
hal_interrupt_objects[_index_] = 0; \
} \
CYG_MACRO_END
//==========================================================================
// GET COPY OF VSR
// DESCRIPTION:
// Assigns a copy of the VSR to the location pointed to by pvsr.
//
// PARAMETERS:
// '_vector_' Vector number
// '_pvsr_' Points to location of VSR
//==========================================================================
#define HAL_VSR_GET(_vector_, _pvsr_) \
*((CYG_ADDRESS *)_pvsr_) = hal_vsr_table[_vector_];
//==========================================================================
// REPLACE VSR
// DESCRIPTION:
// Replaces the VSR attached to the vector with the replacement supplied
// in vsr. The old VSR is returned in the location pointed to by pvsr.
//
// PARAMETERS:
// '_vector_' Vector number of VSR to be replaced
// '_vsr_' New VSR routine fro vector
// '_poldvsr_' Points to old VSR
//==========================================================================
#define HAL_VSR_SET( _vector_, _vsr_, _poldvsr_ ) \
CYG_MACRO_START \
if( (void*)_poldvsr_ != (void*)NULL ) \
{ \
*(CYG_ADDRESS *)_poldvsr_ = hal_vsr_table[_vector_]; \
} \
hal_vsr_table[_vector_] = (CYG_ADDRESS)_vsr_; \
CYG_MACRO_END
//==========================================================================
// SET VSR TO ECOS HANDLER
// DESCRIPTION:
// Ensures that the VSR for a specific exception is pointing to the eCos
// exception VSR and not one for RedBoot or some other ROM monitor. The
// default when running under RedBoot is for exceptions to be handled by
// RedBoot and passed to GDB. This macro diverts the exception to eCos so
// that it may be handled by application code. The arguments are the VSR
// vector to be replaced, and a location in which to store the old VSR
// pointer, so that it may be replaced at a later point.
//
// NOTES:
// This is an ugly name, but what it means is: grab the VSR back to eCos
// internal handling, or if you like, the default handler. But if
// cooperating with GDB and RedBoot, the default behaviour is to pass most
// exceptions to RedBoot. This macro undoes that so that eCos handles the
// exception. So use it with care.
//==========================================================================
///
/// The default interrupt vsr defined in vectors.S
///
externC void __default_interrupt_vsr( void );
///
/// The default exception vsr defined in vectors.S
///
externC void __default_exception_vsr( void );
#define HAL_VSR_SET_TO_ECOS_HANDLER( _vector_, _poldvsr_ ) \
CYG_MACRO_START \
if( (void*)_poldvsr_ != (void*)NULL ) \
*(CYG_ADDRESS *)_poldvsr_ = hal_vsr_table[_vector_]; \
hal_vsr_table[_vector_] = ( CYG_VECTOR_IS_INTERRUPT( _vector_ ) \
? (CYG_ADDRESS)__default_interrupt_vsr \
: (CYG_ADDRESS)__default_exception_vsr ); \
CYG_MACRO_END
//--------------------------------------------------------------------------
#endif // ifndef CYGONCE_HAL_HAL_INTR_H
// EOF hal_intr.h
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -