📄 usb_interrupt.h
字号:
#ifndef USBINTERRUPT_H
#define USBINTERRUPT_H
/** \addtogroup module_usb_interrupt USB Interrupt (usbirq)
* \brief This module contains the USB interrupt handler, which converts USB interrupts to USBIRQ events.
*
* This module contains two interrupt service routines.
* \li P0 ISR
* \li P2 ISR
* Both these are used by the USB part of the CC2511.
* Hence it is recommended to only use P1 for interrupts from any peripherals connected to the CC2511.
* Unless running low on GPIO pins, one should generally avoid using the P0 and P2 pins at all.
*
* The CC2511 contains three interrupt flag registers, USBCIE, USBIIE and USBOIE, which are all cleared
* upon read access. The \ref module_usb_interrupt module encapsulates the USB interrupts, and saves the
* three flag registers in a single 16-bit word. By doing that it becomes possible to process
* high-priority events in the interrupt context, and low-priority events in the main loop.
*
* \section section_usbirq_initialization Initialization
* After initializing the \ref module_usb_framework module, \c main() must call \ref usbirqInit(). The
* \c irqMask parameter of this function shall contain all \c USBIRQ_EVENT bits that will be handled
* either in the interrupt or in \c main(). Note, however, that the event reporting may not always be
* necessary. For instance, there is usually no reason to enable \c USBIRQ_EVENT_EPxIN or
* \c USBIRQ_EVENT_EPxOUT events when handling low-priority transfers in the \c main() loop. In these
* cases it is simpler and more efficient to check the arming condition of the endpoint in question.
*
* The following example enables the setup and reset events (which must always be enabled!), and turns on
* global interrupts:
* \code
* void main(void) {
*
* ... Initialize the crystal oscillator and USB Framework first ...
*
* // Initialize the USB Interrupt module
* usbirqInit(USBIRQ_EVENT_RESET | USBIRQ_EVENT_SETUP);
*
* // Turn on interrupts
* INT_GLOBAL_ENABLE();
*
* // Main loop
* while (1) {
* ...
* }
* \endcode
*
* \section section_usbirq_event_processing Event Processing
* Regardless of whether the interrupt event is processed in the interrupt or in the main loop, the code
* piece for doing it is the same (this example illustrates the processing of \ref USBIRQ_EVENT_RESET
* events):
* \code
* // Let the framework handle reset events :)
* if (USBIRQ_GET_EVENT_MASK() & USBIRQ_EVENT_RESET) {
* USBIRQ_CLEAR_EVENTS(USBIRQ_EVENT_RESET);
* usbfwResetHandler();
* }
* \endcode
*
* \section Hooks
* The following hook is called from the USB interrupt, and allows for event processing in the interrupt
* context:
* \code
* void usbirqHookProcessEvents(void) {
* // Process high-priority events here, or simply return if there are none
* }
* \endcode
* @{
*/
#ifdef EXTERN
#undef EXTERN
#endif
#ifdef USBINTERRUPT_C
#define EXTERN
#else
#define EXTERN extern
#endif
//-------------------------------------------------------------------------------------------------------
/// USBIRQ internal module data
typedef struct {
WORD eventMask; ///< Bit mask containing all pending events (see the \c USBIRQ_EVENT definitions)
BOOL inSuspend; ///< Is currently in suspend?
} USBIRQ_DATA;
EXTERN USBIRQ_DATA __data usbirqData; ///< USBIRQ internal module data
//-------------------------------------------------------------------------------------------------------
//-------------------------------------------------------------------------------------------------------
/// \name USB Interrupt Events
//@{
/// Suspend signaling detected on the USB bus
/// Note that the chip should not enter PM1 while still in the interrupt routine (inside the usbirqHookProcessEvents() function )
#define USBIRQ_EVENT_SUSPEND 0x0001
/// Resume signaling detected on the USB bus
#define USBIRQ_EVENT_RESUME 0x0002
/// Reset signaling detected on the USB bus (call \ref usbfwResetHandler() for processing)
#define USBIRQ_EVENT_RESET 0x0004
/// Start of frame token received (synthesized by hardware when the next SOF token is expected, so that missing or corrupted tokens have no effect)
#define USBIRQ_EVENT_START_OF_FRAME 0x0008
/// Endpoint 0 IN/OUT setup/data transfer complete / stall sent / premature completion (call \ref usbfwSetupHandler() for processing)
#define USBIRQ_EVENT_SETUP 0x0010
/// Endpoint 1 IN data successfully transmitted to host (FIFO disarmed) / FIFO flushed / stall sent
#define USBIRQ_EVENT_EP1IN 0x0020
/// Endpoint 2 IN data successfully transmitted to host (FIFO disarmed) / FIFO flushed / stall sent
#define USBIRQ_EVENT_EP2IN 0x0040
/// Endpoint 3 IN data successfully transmitted to host (FIFO disarmed) / FIFO flushed / stall sent
#define USBIRQ_EVENT_EP3IN 0x0080
/// Endpoint 4 IN data successfully transmitted to host (FIFO disarmed) / FIFO flushed / stall sent
#define USBIRQ_EVENT_EP4IN 0x0100
/// Endpoint 5 IN data successfully transmitted to host (FIFO disarmed) / FIFO flushed / stall sent
#define USBIRQ_EVENT_EP5IN 0x0200
/// Endpoint 1 OUT data received from host (FIFO disarmed) / stall sent
#define USBIRQ_EVENT_EP1OUT 0x0400
/// Endpoint 2 OUT data received from host (FIFO disarmed) / stall sent
#define USBIRQ_EVENT_EP2OUT 0x0800
/// Endpoint 3 OUT data received from host (FIFO disarmed) / stall sent
#define USBIRQ_EVENT_EP3OUT 0x1000
/// Endpoint 4 OUT data received from host (FIFO disarmed) / stall sent
#define USBIRQ_EVENT_EP4OUT 0x2000
/// Endpoint 5 OUT data received from host (FIFO disarmed) / stall sent
#define USBIRQ_EVENT_EP5OUT 0x4000
//@}
//-------------------------------------------------------------------------------------------------------
//-------------------------------------------------------------------------------------------------------
/// \name Interrupt Mask Access Macros
//@{
/// Clears one or more events (use one or more \c USBIRQ_EVENT bits OR'ed together)
#define USBIRQ_CLEAR_EVENTS(mask) (usbirqData.eventMask &= ~(mask))
/// Get the bit mask containing all pending events
#define USBIRQ_GET_EVENT_MASK() (usbirqData.eventMask)
//@}
//-------------------------------------------------------------------------------------------------------
//-------------------------------------------------------------------------------------------------------
/// \name Resume Interrupt
//@{
/// Enables the resume interrupt (P0 vector), must be called before entering Power meode 1
#define USBIRQ_ENABLE_RESUME_INT() (PICTL |= 0x10; INT_ENABLE(INUM_P0INT, INT_ON);)
/// Disables the resume interrupt (P0 vector), must be called after receiving a \ref USBIRQ_EVENT_RESUME
#define USBIRQ_DISABLE_RESUME_INT() (INT_ENABLE(INUM_P0INT, INT_OFF);)
//@}
//-------------------------------------------------------------------------------------------------------
//-------------------------------------------------------------------------------------------------------
/// \name Interrupt Event Hooks
//@{
/// Called upon all USB interrupts for high-priority event processing
void usbirqHookProcessEvents(void);
//@}
//-------------------------------------------------------------------------------------------------------
//-------------------------------------------------------------------------------------------------------
// Function prototypes
void usbirqInit(WORD irqMask);
__near_func __interrupt void usbirqHandler(void);
//-------------------------------------------------------------------------------------------------------
//@}
#endif
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -