📄 usbdrv.c
字号:
UCONbits.SUSPND = 0;
UIEbits.ACTVIE = 0;
while(UIRbits.ACTVIF){UIRbits.ACTVIF = 0;} // Added
}
/******************************************************************************
* Function: void USBRemoteWakeup(void)
*
* PreCondition: None
*
* Input: None
*
* Output: None
*
* Side Effects: None
*
* Overview: This function should be called by user when the device
* is waken up by an external stimulus other than ACTIVIF.
* Please read the note below to understand the limitations.
*
* Note: The modifiable section in this routine should be changed
* to meet the application needs. Current implementation
* temporary blocks other functions from executing for a
* period of 1-13 ms depending on the core frequency.
*
* According to USB 2.0 specification section 7.1.7.7,
* "The remote wakeup device must hold the resume signaling
* for at lest 1 ms but for no more than 15 ms."
* The idea here is to use a delay counter loop, using a
* common value that would work over a wide range of core
* frequencies.
* That value selected is 1800. See table below:
* ==========================================================
* Core Freq(MHz) MIP RESUME Signal Period (ms)
* ==========================================================
* 48 12 1.05
* 4 1 12.6
* ==========================================================
* * These timing could be incorrect when using code
* optimization or extended instruction mode,
* or when having other interrupts enabled.
* Make sure to verify using the MPLAB SIM's Stopwatch
*****************************************************************************/
void USBRemoteWakeup(void)
{
static word delay_count;
if(usb_stat.RemoteWakeup == 1) // Check if RemoteWakeup function
{ // has been enabled by the host.
UCONbits.SUSPND = 0; // Added
/*******************************************************************/
UCONbits.RESUME = 1; // Start RESUME signaling
delay_count = 1800U; // Set RESUME line for 1-13 ms
do
{
delay_count--;
}while(delay_count);
UCONbits.RESUME = 0;
}
}
/******************************************************************************
* Function: void USB_SOF_Handler(void)
* PreCondition: None
* Input: None
* Output: None
* Side Effects: None
* Overview: The USB host sends out a SOF packet to full-speed devices
* every 1 ms. This interrupt may be useful for isochronous
* pipes. End designers should implement callback routine
* as necessary.
*****************************************************************************/
void USB_SOF_Handler(void)
{
UIRbits.SOFIF = 0;
}
/******************************************************************************
* Function: void USBStallHandler(void)
*
* PreCondition: A STALL packet is sent to the host by the SIE.
*
* Input: None
*
* Output: None
*
* Side Effects: None
*
* Overview: The STALLIF is set anytime the SIE sends out a STALL
* packet regardless of which endpoint causes it.
* A Setup transaction overrides the STALL function. A stalled
* endpoint stops stalling once it receives a setup packet.
* In this case, the SIE will accepts the Setup packet and
* set the TRNIF flag to notify the firmware. STALL function
* for that particular endpoint pipe will be automatically
* disabled (direction specific).
*
* There are a few reasons for an endpoint to be stalled.
* 1. When a non-supported USB request is received.
* Example: GET_DESCRIPTOR(DEVICE_QUALIFIER)
* 2. When an endpoint is currently halted.
* 3. When the device class specifies that an endpoint must
* stall in response to a specific event.
* Example: Mass Storage Device Class
* If the CBW is not valid, the device shall
* STALL the Bulk-In pipe.
* See USB Mass Storage Class Bulk-only Transport
* Specification for more details.
*
* Note: UEPn.EPSTALL can be scanned to see which endpoint causes
* the stall event.
*****************************************************************************/
void USBStallHandler(void)
{
if(UEP0bits.EPSTALL == 1)
{
if((ep0Bo.Stat._byte == _USIE) && (ep0Bi.Stat._byte == (_USIE|_BSTALL)))
{
ep0Bo.Stat._byte = _USIE|_DAT0|_DTSEN|_BSTALL;
}
UEP0bits.EPSTALL = 0; // Clear STALL status
}
UIRbits.STALLIF = 0;
}
/******************************************************************************
* Function: void USBErrorHandler(void)
*
* PreCondition: None
*
* Input: None
*
* Output: None
*
* Side Effects: None
*
* Overview: The purpose of this interrupt is mainly for debugging
* during development. Check UEIR to see which error causes
* the interrupt.
*
* Note: None
*****************************************************************************/
void USBErrorHandler(void)
{
UEIR = 0; // Added
}
/******************************************************************************
* Function: void USBProtocolResetHandler(void)
*
* PreCondition: A USB bus reset is received from the host.
*
* Input: None
*
* Output: None
*
* Side Effects: Currently, this routine flushes any pending USB
* transactions. It empties out the USTAT FIFO. This action
* might not be desirable in some applications.
*
* Overview: Once a USB bus reset is received from the host, this
* routine should be called. It resets the device address to
* zero, disables all non-EP0 endpoints, initializes EP0 to
* be ready for default communication, clears all USB
* interrupt flags, unmasks applicable USB interrupts, and
* reinitializes internal state-machine variables.
*
* Note: None
*****************************************************************************/
void USBProtocolResetHandler(void)
{
UEIR = 0; // Clear all USB error flags
UIR = 0; // Clears all USB interrupts
UEIE = 0b10011111; // Unmask all USB error interrupts
UIE = 0b01111011; // Enable all interrupts except ACTVIE
UADDR = 0x00; // Reset to default address
mDisableEP1to15(); // Reset all non-EP0 UEPn registers
UEP0 = EP_CTRL|HSHK_EN; // Init EP0 as a Ctrl EP, see usbdrv.h
while(UIRbits.TRNIF == 1) // Flush any pending transactions
{
UIRbits.TRNIF = 0;
Nop(); Nop(); Nop();
Nop(); Nop(); Nop();
}
UCONbits.PKTDIS = 0; // Make sure packet processing is enabled
USBPrepareForNextSetupTrf(); // Declared in usbctrltrf.c
usb_stat.RemoteWakeup = 0; // Default status flag to disable
usb_active_cfg = 0; // Clear active configuration
usb_device_state = DEFAULT_STATE;
}
void ClearArray(byte* startAdr,byte count)
{
*startAdr;
while(count)
{
_asm
clrf POSTINC0,0
_endasm
count--;
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -