📄 interrupt.c
字号:
/*******************************************************************
*
* DESCRIPTION: M30245 Mit_USB Demonstration Application
*
* AUTHOR: Mitsubishi DEC-E
*
* HISTORY: 0.5 5/30/02 Initial creation for NC30
* 1.0 6/18/02 First official release
* 1.1 6/27/02 Updated ISO routines
* 1.2 8/07/02 Updated for Rev B Starter Kit Board
*
*******************************************************************/
/** include files **/
#include "sfr245.h"
#include "extern.h"
// Function Prototypes
#pragma INTERRUPT USB_EP0_Interrupt
#pragma INTERRUPT USBSuspend
#pragma INTERRUPT USBResume
#pragma INTERRUPT USBReset
#pragma INTERRUPT UART1Receive
#pragma INTERRUPT VBUSDetectInterrupt
#pragma INTERRUPT USBFunction
#pragma INTERRUPT USBSOF
#pragma INTERRUPT TimerA1Int
#pragma INTERRUPT UART3Transmit
/*
** USB_EP0_Interrupt
*
* FILENAME: control_ep0.c
*
* PARAMETERS: None
*
* DESCRIPTION: Unloads EP0 OUT FIFO data packet (SETUP packet). If a previous STALL
* condition was set, then it is cleared since a new SETUP packet must
* be responded to.
*
* RETURNS: Nothing
*
*/
void USB_EP0_Interrupt(void){
if ( ep0csr0 && ep0csr2){ // Check is this is a SETUP packet
SetupPacket.bmRequestType = ep0ol; // If so, read the data out of the
SetupPacket.bRequest = ep0ol; // FIFO and place in this
SetupPacket.wValueLow = ep0ol; // structure
SetupPacket.wValueHigh = ep0ol;
SetupPacket.wIndexLow = ep0ol;
SetupPacket.wIndexHigh = ep0ol;
SetupPacket.wLengthLow = ep0ol;
SetupPacket.wLengthHigh = ep0ol;
if ( ep0csr12 ){ // If SEND_STALL is set, then clear it
ep0csr12 = 0; // Since this is a new SETUP packet
}
}
}
/*
** USBSuspend
*
* FILENAME: interrupt.c
*
* PARAMETERS: None
*
* DESCRIPTION: USB SUSPEND interrupt routine. When the D+/D- is idle for more than
* 3mS, the USB core will enter the SUSPEND state. This can also be caused
* if the USB cable is unplugged. Here all interrupts are disabled with
* the exception of the USB RESUME interrupt and the device enters STOP
* mode for low power.
*
* RETURNS: Nothing
*
*/
void USBSuspend(void){
ta1s = 0; // Stop the timer here
ta1ic = 0x00; // disable interrupt here
ta0s = 0; // Stop the timer here
ta0ic = 0x00; // disable interrupt here
prcr = 0x03; // Disable all protection here
usbc5 = 0; // Disable USB core clock
fse = 0; // Disable the PLL here
asm("FSET I");
rsmic = 0x04; // Ensure RESUME is higher priority
int0ic = 0x04; // Also test REMOTE_WAKEUP here too
cm10 = 1; // Stop clocks waiting here for resume....
asm("NOP");
asm("NOP");
asm("NOP");
asm("NOP");
asm("NOP");
}
/*
** USBResume
*
* FILENAME: interrupt.c
*
* PARAMETERS: None
*
* DESCRIPTION: After entering the SUSPEND state, when the USB core detects signalling
* on D+/D-, an interrupt is generated, waking the device from the STOP
* state. This interrupt routine starts up the USB core and re-enables
* the appropriate interrupts for other functions.
*
* RETURNS: Nothing
*
*/
void USBResume(void){
unsigned char DelayOne = 0xff; // Temporary delay variables
unsigned char DelayTwo = 0xff;
prcr = 0x03; // Disable protection
fse = 1; // Enable PLL
while ( DelayTwo != 0 ){ // Simple DO->WHILE to count while the
while ( DelayOne != 0 ){ // PLL comes online and stabilizes
DelayOne--; // These values should give us a delay of
} // Approxiamtely 3mS or so before we check
DelayOne = 0xff; // Reload small delay
DelayTwo--; // and one tick off large delay
}
DelayOne = 0x05; // Temporary delay variables
usbc = 0xe0; // Enable USB core clock & SOF output
for ( ; DelayOne; DelayOne--){ // Delay to allow USB core stabilization
asm("NOP");
}
}
/*
** TimerA1Int
*
* FILENAME: interrupt.c
*
* PARAMETERS: None
*
* DESCRIPTION: Driven by Timer A1, this interrupt polls the AD converter and
* onboard switches for changes in their state every 10mS. If a
* state change occurs then the buffer is loaded with the current
* value and a flag bit is set so that the MAIN loop can send out
* the new interrupt data with the next request. This function
* will not execute if the device is not configured, since writes
* to the FIFO would be blocked.
*
* RETURNS: Nothing
*
*/
void TimerA1Int(void){
if ( !USBFlags.Configured ){ // Don't update new data if not configured
DataTransferFlags.NewEP2Data = 0; // As this can cause errors. Just hold
return; // whatever data is here until EP is ready.
}
adst = 1; // Start an AD conversion
while ( adst ){} // wait till complete
if ( ad0l != EP2Buffer[0] ){ // Check to see if this is a new AD value
EP2Buffer[0] = ad0l; // If so then update the data to send to the HOST
DataTransferFlags.NewEP2Data = 1; // And flag MAIN to do so
}
if ( !p8_2 ){ // Has this switch been pressed
EP2Buffer[1] = 0x01; // If so update buffer
DataTransferFlags.NewEP2Data = 1; // And flag MAIN to send it
}
if ( !p10_6 ){ // Has this switch been pressed
EP2Buffer[2] = 0x01; // If so update buffer
DataTransferFlags.NewEP2Data = 1; // And flag MAIN to send it
}
if ( !p10_7 ){ // Has this switch been pressed
EP2Buffer[3] = 0x01; // If so update buffer
DataTransferFlags.NewEP2Data = 1; // And flag MAIN to send it
}
if ( !p8_3 ){ // Has this switch been pressed
EP2Buffer[4] = 0x01; // If so update buffer
DataTransferFlags.NewEP2Data = 1; // And flag MAIN to send it
}
}
/*
** VBUSDetectInterrupt
*
* FILENAME: interrupt.c
*
* PARAMETERS: None
*
* DESCRIPTION: Detects if the USB cable has been plugged in and
* signals MAIN if so to startup the USB core. Checks the USBA
* register and SUSPEND flag to determine whether to set
* the entire core up again or do nothing if the device has been
* SUSPEND. Otherwise this interrupt does nothing. Other user
* specific code could be inserted here if needed.
*
* RETURNS: Nothing
*
*/
void VBUSDetectInterrupt(void){
if ( ( !suspend ) && ( usba == 0x00 ) ){ // if not suspended and no address
USBFlags.Attached = 1; // Then we need to set global USB state bit
USBFlags.Powered = 1; // and signal to MAIN that the USB core
USBFlags.USBFirstStart = 1; // should be started up
}
}
/*
** USBReset
*
* FILENAME: interrupt.c
*
* PARAMETERS: None
*
* DESCRIPTION: When a USB RESET occurs this function restores the
* necessary variables and EP's to default values
*
* RETURNS: Nothing
*
*/
void USBReset(void){
USBFlags.Attached = 1; // Reset USB state bits. Incorrect for now
USBFlags.Powered = 1; // but usable until VBUS is corrected.
USBFlags.Default = 1;
USBFlags.Addressed = 0;
USBFlags.Configured = 0;
USBFlags.SetupEndFlag = 0;
ep0mp = 0x0008; // EP0 MAXP packet size = 8, no continuous mode
}
/*
** USBFunction
*
* FILENAME: interrupt.c
*
* PARAMETERS: None
*
* DESCRIPTION: USB functional interrupt occurs when data is sent
* or received. Various flags are set or cleared here
* depending on program flow for the starter kit
*
* RETURNS: Nothing
*
*/
void USBFunction(void){
if ( ep0csr5 ){ // Did the control transfer end early?
intcl8 = 1; // Clear the interrupt status flag
USBFlags.SetupEndFlag = 1; // And set a flag for other modules
}
if ( intst0 ){ // EP1 IN Interrupt
intcl0 = 1; // Send bulk data so clear
DataTransferFlags.EP1DataTransmit = 1; // Flag to let main service interrupt
}
if ( intst1 ){ // EP1 OUT Interrupt
intcl1 = 1; // Clear status flag
if ( out1csr1 ){ // Was data recieved
DataTransferFlags.BulkDataReceived = 1; // if data set flag so that it can be unloaded
}
}
if ( intst2 ){ // EP2 IN Interrupt
intcl2 = 1; // Data was sent so clear status...
}
if ( intst4 ){ // EP3 IN Interrupt
intcl4 = 1; // ISO data was sent, so ready to load another
DataTransferFlags.EP3INReady = 1;
}
if ( intst5 ){ // EP3 OUT Interrupt
intcl5 = 1; // ISO data was received, so send it out to UART3
DataTransferFlags.EP3DataReceived = 1;
}
if ( intst8 ){ // Error Interrupt
if ( in3csr2 ){ // EP3 IN under_run error?
in3csr4 = 1; // disregard for ISO transfer
intcl8 = 1; // clear status...
}
if ( out3csr2 ){ // EP3 OUT over_run error?
out3csr6 = 1; // disregard for ISO transfer
intcl8 = 1; // clear status...
}
}
}
/*
** USBSOF
*
* FILENAME: interrupt.c
*
* PARAMETERS: None
*
* DESCRIPTION: The 1mS frame marker causes this interrupt. It is used
* to synchronize the transfer of ISO data to and from
* the host over EP3.
*
* RETURNS: Nothing
*
*/
void USBSOF(void){
if ( !USBFlags.Configured ){ // If the device is not configured, then
return; // exit function as this might cause error
}
}
/*
** UART1Receive
*
* FILENAME: interrupt.c
*
* PARAMETERS: None
*
* DESCRIPTION: Used for the USB Monitor debugger. DO NOT MODIFY if debugging
* with USB monitor.
*
* RETURNS: Nothing
*
*/
void UART1Receive(void){
asm (" jmp.a 0FF900h ");
}
void UART3Transmit(void){
if ( !USBFlags.Configured ){ // If the device is not configured, then
return; // exit function as this might cause error
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -