📄 usbdrv.c
字号:
/*********************************************************************
*
* Microchip USB C18 Firmware Version 1.0
*
*********************************************************************
* FileName: usbdrv.c
* Dependencies: See INCLUDES section below
* Processor: PIC18
* Compiler: C18 2.30.01+
* Company: Microchip Technology, Inc.
*
* Software License Agreement
*
* The software supplied herewith by Microchip Technology Incorporated
* (the 揅ompany? for its PICmicro?Microcontroller is intended and
* supplied to you, the Company抯 customer, for use solely and
* exclusively on Microchip PICmicro Microcontroller products. The
* software is owned by the Company and/or its supplier, and is
* protected under applicable copyright laws. All rights are reserved.
* Any use in violation of the foregoing restrictions may subject the
* user to criminal sanctions under applicable laws, as well as to
* civil liability for the breach of the terms and conditions of this
* license.
*
* THIS SOFTWARE IS PROVIDED IN AN 揂S IS?CONDITION. NO WARRANTIES,
* WHETHER EXPRESS, IMPLIED OR STATUTORY, INCLUDING, BUT NOT LIMITED
* TO, IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
* PARTICULAR PURPOSE APPLY TO THIS SOFTWARE. THE COMPANY SHALL NOT,
* IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL OR
* CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER.
*
* Author Date Comment
*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
* Rawin Rojvanit 11/19/04 Original.
********************************************************************/
/** I N C L U D E S **********************************************************/
#include <p18cxxx.h>
#include "system\typedefs.h"
#include "system\usb\usb.h"
#include "io_cfg.h" // Required for USBCheckBusStatus()
/** V A R I A B L E S ********************************************************/
#pragma udata
/** P R I V A T E P R O T O T Y P E S ***************************************/
void USBModuleEnable(void);
void USBModuleDisable(void);
void USBSuspend(void);
void USBWakeFromSuspend(void);
void USBProtocolResetHandler(void);
void USB_SOF_Handler(void);
void USBStallHandler(void);
void USBErrorHandler(void);
/** D E C L A R A T I O N S **************************************************/
#pragma code
/******************************************************************************
* Function: void USBCheckBusStatus(void)
*
* PreCondition: None
*
* Input: None
*
* Output: None
*
* Side Effects: None
*
* Overview: This routine enables/disables the USB module by monitoring
* the USB power signal.
*
* Note: None
*****************************************************************************/
void USBCheckBusStatus(void)
{
/**************************************************************************
* Bus Attachment & Detachment Detection
* usb_bus_sense is an i/o pin defined in io_cfg.h
*************************************************************************/
#define USB_BUS_ATTACHED 1
#define USB_BUS_DETACHED 0
if(usb_bus_sense == USB_BUS_ATTACHED) // Is USB bus attached?
{
if(UCONbits.USBEN == 0) // Is the module off?
USBModuleEnable(); // Is off, enable it
}
else
{
if(UCONbits.USBEN == 1) // Is the module on?
USBModuleDisable(); // Is on, disable it
}//end if(usb_bus_sense...)
/*
* After enabling the USB module, it takes some time for the voltage
* on the D+ or D- line to rise high enough to get out of the SE0 condition.
* The USB Reset interrupt should not be unmasked until the SE0 condition is
* cleared. This helps preventing the firmware from misinterpreting this
* unique event as a USB bus reset from the USB host.
*/
if(usb_device_state == ATTACHED_STATE)
{
if(!UCONbits.SE0)
{
UIR = 0; // Clear all USB interrupts
UIE = 0; // Mask all USB interrupts
UIEbits.URSTIE = 1; // Unmask RESET interrupt
UIEbits.IDLEIE = 1; // Unmask IDLE interrupt
usb_device_state = POWERED_STATE;
}//end if // else wait until SE0 is cleared
}//end if(usb_device_state == ATTACHED_STATE)
}//end USBCheckBusStatus
/******************************************************************************
* Function: void USBModuleEnable(void)
*
* PreCondition: None
*
* Input: None
*
* Output: None
*
* Side Effects: None
*
* Overview: This routine enables the USB module.
* An end designer should never have to call this routine
* manually. This routine should only be called from
* USBCheckBusStatus().
*
* Note: See USBCheckBusStatus() for more information.
*****************************************************************************/
void USBModuleEnable(void)
{
UCON = 0;
UIE = 0; // Mask all USB interrupts
UCONbits.USBEN = 1; // Enable module & attach to bus
usb_device_state = ATTACHED_STATE; // Defined in usbmmap.c & .h
}//end USBModuleEnable
/******************************************************************************
* Function: void USBModuleDisable(void)
*
* PreCondition: None
*
* Input: None
*
* Output: None
*
* Side Effects: None
*
* Overview: This routine disables the USB module.
* An end designer should never have to call this routine
* manually. This routine should only be called from
* USBCheckBusStatus().
*
* Note: See USBCheckBusStatus() for more information.
*****************************************************************************/
void USBModuleDisable(void)
{
UCON = 0; // Disable module & detach from bus
UIE = 0; // Mask all USB interrupts
usb_device_state = DETACHED_STATE; // Defined in usbmmap.c & .h
}//end USBModuleDisable
/******************************************************************************
* Function: void USBSoftDetach(void)
*
* PreCondition: None
*
* Input: None
*
* Output: None
*
* Side Effects: The device will have to be re-enumerated to function again.
*
* Overview: USBSoftDetach electrically disconnects the device from
* the bus. This is done by stop supplying Vusb voltage to
* pull-up resistor. The pull-down resistors on the host
* side will pull both differential signal lines low and
* the host registers the event as a disconnect.
*
* Since the USB cable is not physically disconnected, the
* power supply through the cable can still be sensed by
* the device. The next time USBCheckBusStatus() function
* is called, it will reconnect the device back to the bus.
*
* Note: None
*****************************************************************************/
void USBSoftDetach(void)
{
USBModuleDisable();
}//end USBSoftDetach
/******************************************************************************
* Function: void USBDriverService(void)
*
* PreCondition: None
*
* Input: None
*
* Output: None
*
* Side Effects: None
*
* Overview: This routine is the heart of this firmware. It manages
* all USB interrupts.
*
* Note: Device state transitions through the following stages:
* DETACHED -> ATTACHED -> POWERED -> DEFAULT ->
* ADDRESS_PENDING -> ADDRESSED -> CONFIGURED -> READY
*****************************************************************************/
void USBDriverService(void)
{
/*
* Pointless to continue servicing if USB cable is not even attached.
*未连接状态
*/
if(usb_device_state == DETACHED_STATE) return;
/*
* Task A: Service USB Activity Interrupt
*作业A:USB活动中断产生,从挂起状态唤醒;
*/
if(UIRbits.ACTVIF && UIEbits.ACTVIE) USBWakeFromSuspend();
/*
* Pointless to continue servicing if the device is in suspend mode.
*挂起状态
*/
if(UCONbits.SUSPND==1) return;
/*
* Task B: Service USB Bus Reset Interrupt.
* When bus reset is received during suspend, ACTVIF will be set first,
* once the UCONbits.SUSPND is clear, then the URSTIF bit will be asserted.
* This is why URSTIF is checked after ACTVIF.
*/
if(UIRbits.URSTIF && UIEbits.URSTIE) USBProtocolResetHandler();
/*
* Task C: Service other USB interrupts
*/
if(UIRbits.IDLEIF && UIEbits.IDLEIE) USBSuspend();
if(UIRbits.SOFIF && UIEbits.SOFIE) USB_SOF_Handler();
if(UIRbits.STALLIF && UIEbits.STALLIE) USBStallHandler();
if(UIRbits.UERRIF && UIEbits.UERRIE) USBErrorHandler();
/*
* Pointless to continue servicing if the host has not sent a bus reset.
* Once bus reset is received, the device transitions into the DEFAULT
* state and is ready for communication.
*/
if(usb_device_state < DEFAULT_STATE) return;
/*
* Task D: Servicing USB Transaction Complete Interrupt
*/
if(UIRbits.TRNIF && UIEbits.TRNIE)
{
/*
* USBCtrlEPService only services transactions over EP0.
* It ignores all other EP transactions.
*/
USBCtrlEPService();
/*
* Other EP can be serviced later by responsible device class firmware.
* Each device driver knows when an OUT or IN transaction is ready by
* checking the buffer ownership bit.
* An OUT EP should always be owned by SIE until the data is ready.
* An IN EP should always be owned by CPU until the data is ready.
*
* Because of this logic, it is not necessary to save the USTAT value
* of non-EP0 transactions.
*/
UIRbits.TRNIF = 0;
}//end if(UIRbits.TRNIF && UIEbits.TRNIE)
}//end USBDriverService
/******************************************************************************
* Function: void USBSuspend(void)
*
* PreCondition: None
*
* Input: None
*
* Output: None
*
* Side Effects: None
*
* Overview:
*
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -