📄 usb_int.c
字号:
/**************** (c) 2000 STMicroelectronics *******************************
NAME: usb_poll.c
PROJECT: USB - ST7 FULL SPEED
VERSION: v 1.10
CREATION: 03/01/2002
AUTHOR: MICROCONTROLLER DIVISION / ST Rousset
-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-
Functions for handling USB interrupts in POLLING model
-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-
MODIFICATIONS :
******************************************************************************/
#include "mcu_conf.h"
#include "usb_libs.h"
#include "usb_reg.h"
#include "usb_def.h"
#include "usb_lib.h"
#include "usb_app.h"
#pragma DATA_SEG SHORT USB_RAM0 // Map USB variables into page 0 (short addressing RAM)
extern char _vUSB_Data_OUT_Len; // Save the packet length of data OUT stage
char _EP_RxTx_Flag; // Bitmap variable to flag free or busy of non-control endpoint
static char _Non_EP0_Events; // Bitmap variable to flag the event on non-control endpoint
static char _Token_Index;
unsigned char _Token_OverRun; // export to "usb_lib.c"
#ifdef SETUP_PREEMPTIVE
static char Token_Stack;
#endif
///////////////////////////////////////////////////////////////////////////////
#pragma CODE_SEG USB_CODE
extern void USB_SETUP_Stage(void);
extern void USB_Data_IN_Stage(void);
extern void USB_Data_OUT_Stage(void);
extern void USB_Status_IN_Stage(void);
extern void USB_Status_OUT_Stage(void);
extern void Change_EP0_State(void);
#pragma CONST_SEG USB_CONST
const struct Token_Jump {
unsigned char No_Function;
char JP0; void (*USB_SETUP_Stage)(void);
char JP1; void (*USB_Data_IN_Stage)(void);
char JP2; void (*USB_Data_OUT_Stage)(void);
char JP3; void (*USB_Status_IN_Stage)(void);
char JP4; void (*USB_Status_OUT_Stage)(void);
} Token_Routines = {
0x8E, // HALT instruction
0xCC, USB_SETUP_Stage,
0xCC, USB_Data_IN_Stage,
0xCC, USB_Data_OUT_Stage,
0xCC, USB_Status_IN_Stage,
0xCC, USB_Status_OUT_Stage
};
// Index of the above jump table
#define NULL_INDEX 0
#define SETUP_INDEX 1
#define DATA_IN_INDEX 4
#define DATA_OUT_INDEX 7
#define STATUS_IN_INDEX 10
#define STATUS_OUT_INDEX 13
void _Check_Non_EP0_Events(void)
{
if (_Non_EP0_Events == 0)
return;
#ifdef DECLARE_EP1
if (ValBit(_Non_EP0_Events, EV_EP1_IN)) {
ClrBit(_Non_EP0_Events, EV_EP1_IN);
_USB_EP1_XEvent();
}
#ifdef MCU_ST7265
if (ValBit(_Non_EP0_Events, EV_EP1_OUT)) {
ClrBit(_Non_EP0_Events, EV_EP1_OUT);
_USB_EP1_REvent();
}
#endif
#endif
#ifdef DECLARE_EP2
if (ValBit(_Non_EP0_Events, EV_EP2_IN)) {
ClrBit(_Non_EP0_Events, EV_EP2_IN);
_USB_EP2_XEvent();
}
if (ValBit(_Non_EP0_Events, EV_EP2_OUT)) {
ClrBit(_Non_EP0_Events, EV_EP2_OUT);
_USB_EP2_REvent();
}
#endif
#ifdef MCU_ST7SCR
#ifdef DECLARE_EP3
if (ValBit(_Non_EP0_Events, EV_EP3_IN)) {
ClrBit(_Non_EP0_Events, EV_EP3_IN);
_USB_EP3_XEvent();
}
#endif
#ifdef DECLARE_EP4
if (ValBit(_Non_EP0_Events, EV_EP4_IN)) {
ClrBit(_Non_EP0_Events, EV_EP4_IN);
_USB_EP4_XEvent();
}
#endif
#ifdef DECLARE_EP5
if (ValBit(_Non_EP0_Events, EV_EP5_IN)) {
ClrBit(_Non_EP0_Events, EV_EP5_IN);
_USB_EP5_XEvent();
}
#endif
#endif // MCU_ST7SCR
}
// This function is part of the interrupt routine
// Checks endpoint interrupt of non EP0
#pragma TRAP_PROC
void _Non_EP0_Interrupt(void)
{
// unsigned char EPx = USBSR & 0x27;
// if (EPx == 0x21) {
if (ValBit(EP1TXR, 3)) {
ClrBit(EP1TXR, 3);
#ifdef DECLARE_EP1
SetBit(_Non_EP0_Events, EV_EP1_IN);
#endif
}
#ifdef MCU_ST7265
// else if (EPx == 0x01) {
else if (ValBit(EP1RXR, 3)) {
ClrBit(EP1RXR, 3);
#ifdef DECLARE_EP1
SetBit(_Non_EP0_Events, EV_EP1_OUT);
#endif
}
#endif
// else if (EPx == 0x22) {
else if (ValBit(EP2TXR, 3)) {
ClrBit(EP2TXR, 3);
#ifdef DECLARE_EP2
SetBit(_Non_EP0_Events, EV_EP2_IN);
#endif
}
// else if (EPx == 0x02) {
else if (ValBit(EP2RXR, 3)) {
ClrBit(EP2RXR, 3);
#ifdef DECLARE_EP2
SetBit(_Non_EP0_Events, EV_EP2_OUT);
#endif
}
#ifdef MCU_ST7SCR
// else if (EPx == 0x23) {
else if (ValBit(EP3TXR, 3)) {
ClrBit(EP3TXR, 3);
#ifdef DECLARE_EP3
SetBit(_Non_EP0_Events, EV_EP3_IN);
#endif
}
// else if (EPx == 0x24) {
else if (ValBit(EP4TXR, 3)) {
ClrBit(EP4TXR, 3);
#ifdef DECLARE_EP4
SetBit(_Non_EP0_Events, EV_EP4_IN);
#endif
}
// else if (EPx == 0x25) {
else if (ValBit(EP5TXR, 3)) {
ClrBit(EP5TXR, 3);
#ifdef DECLARE_EP5
SetBit(_Non_EP0_Events, EV_EP5_IN);
#endif
}
#endif // MCU_ST7SCR
}
#ifdef USB_POLLING_MODEL
/*-----------------------------------------------------------------------------
ROUTINE NAME : INT_USB - Polling model
DESCRIPTION : Comes from the USB cell.
-----------------------------------------------------------------------------*/
#pragma TRAP_PROC
void INT_USB(void)
{
asm {
BTJF USBISTR, #ISTR_SOVR, _No_Setup_OverRun
// Process SETUP overrun interrupt
BRES USBISTR,#ISTR_SOVR // clear SOVR bit
_Mark_Overrun:
#ifdef CUT09
////////These 2 lines are done by H/W
LD X, #MAX_PACKET_SIZE
LD CNT0RXR, X
#endif
LD X, #SETUP_INDEX
LD _Token_OverRun, X
IRET
_No_Setup_OverRun:
BTJF EP0R, #7, _Non_EP0_INT
LD A, _Token_Index // check USB state machine is in idle
JREQ _Normal_Token
BRES EP0R, #7 // Clear CTR0 bit
JRT _Mark_Overrun // Not in idle, this is a overrun token
_Normal_Token:
LD A, USBSR // identify the Status Stage as earlier as here
CP A, #$0C0
JREQ _SETUP_Stage // a SETUP token, can not be a Status Stage
XOR A, sUSB_vSetup
JRPL _Data_Stage // Same direction, not a Stagus Stage
// This is a status stage
BTJF USBSR, #7, _Status_OUT_Stage
_Status_IN_Stage:
LD A, #$0B1
LD EP0R, A // STALL Recv and Enable Xmit
LD X, #STATUS_IN_INDEX
JRT _Token_Branch
_Status_OUT_Stage:
LD A, #$093
LD EP0R, A // STALL Xmit and Enable Recv
LD X, #STATUS_OUT_INDEX
JRT _Token_Branch
_SETUP_Stage:
LD X, #SETUP_INDEX
JRT _Token_Branch
_Data_Stage:
LD A, USBSR
JRMI _Data_In_Stage
_Data_Out_Stage:
LD X, #DATA_OUT_INDEX
LD A, #MAX_PACKET_SIZE // Since we have to set the CNT0RXR in _Token_Branch
SUB A, CNT0RXR // in order to allow a SETUP comes in after clear CTR0
LD _vUSB_Data_OUT_Len, A // read the length of data out stage here
JRT _Token_Branch
_Data_In_Stage:
LD X, #DATA_IN_INDEX
_Token_Branch:
BRES EP0R, #7 // Clear CTR0 bit
#ifdef CUT09
////////These 2 lines will be done by H/W
LD A, #MAX_PACKET_SIZE
LD CNT0RXR, A
#endif
LD _Token_Index, X
IRET
_Non_EP0_INT:
BTJF USBISTR, #ISTR_CTR, _Non_CTR_Int
JP _Non_EP0_Interrupt // Mark down CTR interrupt from non-control pipe
_Non_CTR_Int:
}
if (USBISTR & USBIMR & IMR_ERR) { // ERROR IT
ClrBit(USBISTR, ISTR_ERR); // Clear ERR bit
return; // Just clear the status and do nothing
}
// For all other non-CTR interrupt source
// Save compiler registers first
asm {
PUSH Y
LD A, _R_Z
PUSH A
LD A, _LEX:1
PUSH A
LD A, _LEX
PUSH A
LD A, _SEX:1
PUSH A
LD A, _SEX
PUSH A
}
if (USBISTR & USBIMR & IMR_SUSP) { // SUSPEND IT
ClrBit(USBISTR, ISTR_SUSP); // clear SUSP bit
USBCTLR |= 0x02; // set FSUSP bit
USERIT(USER_Suspend);
}
if (USBISTR & USBIMR & IMR_RESET) { // RESET IT
USBISTR = 0x00; // Clear ISTR register
USB_Reset();
}
if (USBISTR & USBIMR & IMR_SOF) { // SOF IT
USERIT(USER_SOF);
ClrBit(USBISTR, ISTR_SOF); // clear RESET bit
}
asm {
POP A
LD _SEX, A
POP A
LD _SEX:1, A
POP A
LD _LEX, A
POP A
LD _LEX:1, A
POP A
LD _R_Z, A
POP Y
}
}
///////////////////////////////////////////////////////////////////////////////
// Following codes are used to implement USB polling and to dispatch processing
///////////////////////////////////////////////////////////////////////////////
/*-----------------------------------------------------------------------------
ROUTINE NAME : USB_Polling
DESCRIPTION : Called from the main loop to perform USB processing
-----------------------------------------------------------------------------*/
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -