Code/Resource
Windows Develop
Linux-Unix program
Internet-Socket-Network
Web Server
Browser Client
Ftp Server
Ftp Client
Browser Plugins
Proxy Server
Email Server
Email Client
WEB Mail
Firewall-Security
Telnet Server
Telnet Client
ICQ-IM-Chat
Search Engine
Sniffer Package capture
Remote Control
xml-soap-webservice
P2P
WEB(ASP,PHP,...)
TCP/IP Stack
SNMP
Grid Computing
SilverLight
DNS
Cluster Service
Network Security
Communication-Mobile
Game Program
Editor
Multimedia program
Graph program
Compiler program
Compress-Decompress algrithms
Crypt_Decrypt algrithms
Mathimatics-Numerical algorithms
MultiLanguage
Disk/Storage
Java Develop
assembly language
Applications
Other systems
Database system
Embeded-SCM Develop
FlashMX/Flex
source in ebook
Delphi VCL
OS Develop
MiddleWare
MPI
MacOS develop
LabView
ELanguage
Software/Tools
E-Books
Artical/Document
USB18.asm
Package: USBFM.zip [view]
Upload User: wang202020
Upload Date: 2021-02-07
Package Size: 182k
Code Size: 62k
Category:
SCM
Development Platform:
HTML/CSS
- ; USB18.ASM
- ; Put Address into source pointer
- mSetSourcePointer macro Address
- movlw low (Address)
- movwf pSrc
- movlw high (Address)
- movwf pSrc + 1
- endm
- ; Put Address into destination pointer
- mSetDestinationPointer macro Address
- movlw low (Address)
- movwf pDst
- movlw high (Address)
- movwf pDst + 1
- endm
- ; Get count from first location of ROM table pointed to by pSrc
- mGetRomTableCount macro
- movff pSrc, TBLPTRL ; Set source address
- movff pSrc + 1, TBLPTRH
- clrf TBLPTRU
- tblrd * ; Read count
- movff TABLAT, wCount
- clrf wCount + 1
- endm
- ; From usb9.c line 70
- ;/******************************************************************************
- ; * Function: void USBCheckStdRequest(void)
- ; *
- ; * PreCondition: None
- ; *
- ; * Input: None
- ; *
- ; * Output: None
- ; *
- ; * Side Effects: None
- ; *
- ; * Overview: This routine checks the setup data packet to see if it
- ; * knows how to handle it
- ; *
- ; * Note: None
- ; *****************************************************************************/
- USBCheckStdRequest
- movlb high 0x400 ; Point to proper bank
- movf SetupPkt, W ; RequestType = STANDARD?
- andlw 0x60 ; Mask to proper bits
- sublw (STANDARD) << 5
- bnz USBCheckStdRequestExit ; No
- movlw SET_ADR ; Handle request
- cpfseq SetupPkt + bRequest
- bra USBCheckStdRequest1
- movlw ADR_PENDING_STATE
- movwf usb_device_state
- bra USBStdSetSessionOwnerUSB9
- ; GET_DESCRIPTOR request?
- USBCheckStdRequest1
- movlw GET_DSC
- cpfseq SetupPkt + bRequest
- bra USBCheckStdRequest2
- bra USBStdGetDscHandler
- ; GET_CONFIGURATION request?
- USBCheckStdRequest2
- movlw GET_CFG
- cpfseq SetupPkt + bRequest
- bra USBCheckStdRequest3
- mSetSourcePointer usb_active_cfg
- movlw 1
- movwf wCount
- clrf wCount + 1
- bcf usb_stat, ctrl_trf_mem ; Indicate RAM
- bra USBStdSetSessionOwnerUSB9
- ; SET_CONFIGURATION request?
- USBCheckStdRequest3
- movlw SET_CFG
- cpfseq SetupPkt + bRequest
- bra USBCheckStdRequest4
- bra USBStdSetCfgHandler
- ; GET_STATUS request?
- USBCheckStdRequest4
- movlw GET_STATUS
- cpfseq SetupPkt + bRequest
- bra USBCheckStdRequest5
- bra USBStdGetStatusHandler
- ; CLEAR_FEATURE request?
- USBCheckStdRequest5
- movlw CLR_FEATURE
- cpfseq SetupPkt + bRequest
- bra USBCheckStdRequest6
- bra USBStdFeatureReqHandler
- ; SET_FEATURE request?
- USBCheckStdRequest6
- movlw SET_FEATURE
- cpfseq SetupPkt + bRequest
- bra USBCheckStdRequest7
- bra USBStdFeatureReqHandler
- ; GET_INTERFACE request?
- USBCheckStdRequest7
- movlw GET_INTF
- cpfseq SetupPkt + bRequest
- bra USBCheckStdRequest8
- mSetSourcePointer usb_alt_intf
- movf SetupPkt + bIntfID, W
- addwf pSrc, F
- movlw 1
- movwf wCount
- clrf wCount + 1
- bcf usb_stat, ctrl_trf_mem ; Indicate RAM
- bra USBStdSetSessionOwnerUSB9
- ; SET_INTERFACE request?
- USBCheckStdRequest8
- movlw SET_INTF
- cpfseq SetupPkt + bRequest
- return
- lfsr 2, usb_alt_intf
- movf SetupPkt + bIntfID, W
- movff SetupPkt + bAltID, PLUSW2
- ; Branch here after decoding one of the above USB standard requests.
- ; Assign a value to ctrl_trf_session_owner, to prevent stalling
- USBStdSetSessionOwnerUSB9
- movlw MUID_USB9
- movwf ctrl_trf_session_owner
- USBCheckStdRequestExit
- return
- ; From usb9.c line 136
- ;/******************************************************************************
- ; * Function: void USBStdGetDscHandler(void)
- ; *
- ; * PreCondition: None
- ; *
- ; * Input: None
- ; *
- ; * Output: None
- ; *
- ; * Side Effects: None
- ; *
- ; * Overview: This routine handles the standard GET_DESCRIPTOR request.
- ; * It utilizes tables dynamically looks up descriptor size.
- ; * This routine should never have to be modified if the tables
- ; * in usbdsc.c are declared correctly.
- ; *
- ; * Note: None
- ; *****************************************************************************/
- USBStdGetDscHandler
- ; movlb high 0x400 ; Point to proper bank
- movlw 0x80
- cpfseq SetupPkt + bmRequestType
- return
- movlw DSC_DEV
- cpfseq SetupPkt + bDscType
- bra USBStdGetDscHandler1
- mSetSourcePointer DeviceDescriptor
- mGetRomTableCount ; Set wCount
- bsf usb_stat, ctrl_trf_mem ; Indicate ROM
- bra USBStdSetSessionOwnerUSB9
- USBStdGetDscHandler1
- movlw DSC_CFG
- cpfseq SetupPkt + bDscType
- bra USBStdGetDscHandler2
- mSetSourcePointer Config1
- movlw low Config1Len ; Set wCount to total length
- movwf TBLPTRL
- movlw high Config1Len
- movwf TBLPTRH
- clrf TBLPTRU
- tblrd *+ ; Read count low
- movff TABLAT, wCount
- tblrd *+ ; Ignore RETLW opcode
- tblrd *+ ; Read count high
- movff TABLAT, wCount + 1
- bsf usb_stat, ctrl_trf_mem ; Indicate ROM
- bra USBStdSetSessionOwnerUSB9
- USBStdGetDscHandler2
- movlw DSC_STR
- cpfseq SetupPkt + bDscType
- return
- clrf TBLPTRU
- clrf TBLPTRH
- rlncf SetupPkt + bDscIndex, W ; Index * 2
- addlw low (USB_SD_Ptr) ; Add element offset to low address
- movwf TBLPTRL
- movlw high (USB_SD_Ptr)
- addwfc TBLPTRH, F
- tblrd *+ ; Get the data to TABLAT and move pointer forward
- movff TABLAT, pSrc ; Get low source address
- tblrd *
- movff TABLAT, pSrc + 1 ; Get high source address
- mGetRomTableCount ; Set wCount
- bsf usb_stat, ctrl_trf_mem ; Indicate ROM
- bra USBStdSetSessionOwnerUSB9
- ; From usb9.c line 180
- ;/******************************************************************************
- ; * Function: void USBStdSetCfgHandler(void)
- ; *
- ; * PreCondition: None
- ; *
- ; * Input: None
- ; *
- ; * Output: None
- ; *
- ; * Side Effects: None
- ; *
- ; * Overview: This routine first disables all endpoints by clearing
- ; * UEP registers. It then configures (initializes) endpoints
- ; * specified in the modifiable section.
- ; *
- ; * Note: None
- ; *****************************************************************************/
- USBStdSetCfgHandler
- ; movlb high 0x400 ; Point to proper bank
- movlw MUID_USB9
- movwf ctrl_trf_session_owner
- lfsr 2, UEP1 ; Reset all non-EP0 UEPn registers
- movlw 15
- USBStdSetCfgHandlerClearEPLoop
- clrf POSTINC2
- decfsz WREG, F
- bra USBStdSetCfgHandlerClearEPLoop
- lfsr 2, usb_alt_intf ; Clear usb_alt_intf array
- movlw MAX_NUM_INT
- USBStdSetCfgHandlerClearAltLoop
- clrf POSTINC2
- decfsz WREG, F
- bra USBStdSetCfgHandlerClearAltLoop
- movf SetupPkt + bCfgValue, W
- movwf usb_active_cfg
- bnz USBStdSetCfgHandler1
- movlw ADDRESS_STATE ; SetupPkt + bCfgValue = 0
- movwf usb_device_state
- return
- USBStdSetCfgHandler1
- movlw CONFIGURED_STATE
- movwf usb_device_state
- #ifdef USB_USE_HID
- rcall HIDInitEP
- #endif
- #ifdef USB_USE_CDC
- rcall CDCInitEP
- #endif
- return
- ; From usb9.c line 224
- ;/******************************************************************************
- ; * Function: void USBStdGetStatusHandler(void)
- ; *
- ; * PreCondition: None
- ; *
- ; * Input: None
- ; *
- ; * Output: None
- ; *
- ; * Side Effects: None
- ; *
- ; * Overview: This routine handles the standard GET_STATUS request
- ; *
- ; * Note: None
- ; *****************************************************************************/
- USBStdGetStatusHandler
- ; movlb high 0x400 ; Point to proper bank
- clrf CtrlTrfData ; Initialize content
- clrf CtrlTrfData + 1
- movf SetupPkt, W ; Recipient = RCPT_DEV?
- andlw 0x1f ; Mask to lower 5 bits
- sublw RCPT_DEV
- bnz USBStdGetStatusHandler1 ; No
- ;
- ; Recipient of this Setup packet was "Device": set bits to indicate power & remote wakeup
- ; Decoding of "Self-powered" & "Remote Wakeup"
- ; _byte0: bit0: Self-Powered Status [0] Bus-Powered [1] Self-Powered
- ; bit1: RemoteWakeup [0] Disabled [1] Enabled
- ;
- #ifdef USB_SELF_POWER
- bsf CtrlTrfData, 0
- #endif
- btfsc usb_stat, RemoteWakeup
- bsf CtrlTrfData, 1
- bra USBStdGetStatusSetSessionOwner
- ;
- USBStdGetStatusHandler1
- movf SetupPkt, W ; Recipient = RCPT_INTF?
- andlw 0x1f ; Mask to lower 5 bits
- sublw RCPT_INTF
- bnz USBStdGetStatusHandler2 ; No
- ;
- ; Recipient of this Setup packet was "Interface": No data to update
- bra USBStdGetStatusSetSessionOwner
- ;
- USBStdGetStatusHandler2
- movf SetupPkt, W ; Recipient = RCPT_EP?
- andlw 0x1f ; Mask to lower 5 bits
- sublw RCPT_EP
- bnz USBStdGetStatusHandler3 ; No
- ;
- ; Recipient of this Setup packet was "Endpoint"
- rcall USBCalcEPAddress ; Put endpoint buffer address in FSR2
- movf INDF2, W
- andlw _BSTALL
- bz USBStdGetStatusSetSessionOwner
- bsf CtrlTrfData, 0
- USBStdGetStatusSetSessionOwner
- movlw MUID_USB9
- movwf ctrl_trf_session_owner
- USBStdGetStatusHandler3
- movlw MUID_USB9
- cpfseq ctrl_trf_session_owner
- return
- mSetSourcePointer CtrlTrfData
- movlw 2 ; Set count
- movwf wCount
- clrf wCount + 1
- bcf usb_stat, ctrl_trf_mem ; Indicate RAM
- return
- ; From usb9.c line 281
- ;/******************************************************************************
- ; * Function: void USBStdFeatureReqHandler(void)
- ; *
- ; * PreCondition: None
- ; *
- ; * Input: None
- ; *
- ; * Output: None
- ; *
- ; * Side Effects: None
- ; *
- ; * Overview: This routine handles the standard SET & CLEAR FEATURES
- ; * requests
- ; *
- ; * Note: None
- ; *****************************************************************************/
- USBStdFeatureReqHandler
- ; movlb high 0x400 ; Point to proper bank
- movlw DEVICE_REMOTE_WAKEUP ; If Feature = DEVICE_REMOTE_WAKEUP &
- cpfseq SetupPkt + bFeature
- bra USBStdFeatureReqHandler1
- movf SetupPkt, W ; Recipient = RCPT_DEV?
- andlw 0x1f ; Mask to lower 5 bits
- sublw RCPT_DEV
- bnz USBStdFeatureReqHandler1 ; No
- bsf usb_stat, RemoteWakeup ; Preset RemoteWakeup to 1
- movlw SET_FEATURE ; Request = SET_FEATURE?
- cpfseq SetupPkt + bRequest
- bcf usb_stat, RemoteWakeup ; No, RemoteWakeup = 0
- bra USBStdSetSessionOwnerUSB9
- USBStdFeatureReqHandler1
- movlw ENDPOINT_HALT ; If Feature = ENDPOINT_HALT &
- cpfseq SetupPkt + bFeature
- USBStdFeatureReqHandlerExit
- return
- movf SetupPkt, W ; Recepient = RCPT_EP &
- andlw 0x1f ; Mask to lower 5 bits
- sublw RCPT_EP
- bnz USBStdFeatureReqHandlerExit
- movf SetupPkt + bEPID, W ; EPNum != 0
- andlw 0x0f ; Mask to EPNum
- bz USBStdFeatureReqHandlerExit
- rcall USBCalcEPAddress ; Put endpoint buffer address in FSR2
- movlw SET_FEATURE ; Request = SET_FEATURE?
- cpfseq SetupPkt + bRequest
- bra USBStdFeatureReqHandler2 ; No
- movlw _USIE|_BSTALL
- movwf INDF2 ; Put in endpoint buffer
- bra USBStdSetSessionOwnerUSB9
- USBStdFeatureReqHandler2
- movlw _UCPU ; IN
- btfss SetupPkt + bEPID, EPDir ; EPDir = 1 (IN)?
- movlw _USIE|_DAT0|_DTSEN ; No - OUT
- movwf INDF2 ; Put in endpoint buffer
- bra USBStdSetSessionOwnerUSB9
- ; Put endpoint buffer address in FSR2 (ep0Bo+(EPNum*8)+(EPDir*4))
- USBCalcEPAddress
- lfsr 2, ep0Bo ; Point FSR2 to beginning of buffer area
- rlncf SetupPkt + bEPID, W ; Move endpoint direction to C
- rlcf SetupPkt + bEPID, W ; Endpoint number * 8 (roll in ep direction)
- rlncf WREG, F
- rlncf WREG, F
- addwf FSR2L, F ; Add to FSR2 (can't overflow to FSR2H)
- return
- ; From usbctrltrf.c line 78
- ;/******************************************************************************
- ; * Function: void USBCtrlEPService(void)
- ; *
- ; * PreCondition: USTAT is loaded with a valid endpoint address.
- ; *
- ; * Input: None
- ; *
- ; * Output: None
- ; *
- ; * Side Effects: None
- ; *
- ; * Overview: USBCtrlEPService checks for three transaction types that
- ; * it knows how to service and services them:
- ; * 1. EP0 SETUP
- ; * 2. EP0 OUT
- ; * 3. EP0 IN
- ; * It ignores all other types (i.e. EP1, EP2, etc.)
- ; *
- ; * Note: None
- ; *****************************************************************************/
- USBCtrlEPService
- ; movlb high 0x400 ; Point to proper bank
- movlw EP00_OUT
- cpfseq USTAT
- bra USBCtrlEPService1
- movf ep0Bo + Stat, W
- andlw 0x3c ; Mask to PID
- sublw (SETUP_TOKEN) << 2
- bz USBCtrlTrfSetupHandler
- bra USBCtrlTrfOutHandler
- USBCtrlEPService1
- movlw EP00_IN
- cpfseq USTAT
- return
- bra USBCtrlTrfInHandler
- ; From usbctrltrf.c line 133
- ;/******************************************************************************
- ; * Function: void USBCtrlTrfSetupHandler(void)
- ; *
- ; * PreCondition: SetupPkt buffer is loaded with valid USB Setup Data
- ; *
- ; * Input: None
- ; *
- ; * Output: None
- ; *
- ; * Side Effects: None
- ; *
- ; * Overview: This routine is a task dispatcher and has 3 stages.
- ; * 1. It initializes the control transfer state machine.
- ; * 2. It calls on each of the module that may know how to
- ; * service the Setup Request from the host.
- ; * Module Example: USB9, HID, CDC, MSD, ...
- ; * As new classes are added, ClassReqHandler table in
- ; * usbdsc.c should be updated to call all available
- ; * class handlers.
- ; * 3. Once each of the modules has had a chance to check if
- ; * it is responsible for servicing the request, stage 3
- ; * then checks direction of the transfer to determine how
- ; * to prepare EP0 for the control transfer.
- ; * Refer to USBCtrlEPServiceComplete() for more details.
- ; *
- ; * Note: Microchip USB Firmware has three different states for
- ; * the control transfer state machine:
- ; * 1. WAIT_SETUP
- ; * 2. CTRL_TRF_TX
- ; * 3. CTRL_TRF_RX
- ; * Refer to firmware manual to find out how one state
- ; * is transitioned to another.
- ; *
- ; * A Control Transfer is composed of many USB transactions.
- ; * When transferring data over multiple transactions,
- ; * it is important to keep track of data source, data
- ; * destination, and data count. These three parameters are
- ; * stored in pSrc,pDst, and wCount. A flag is used to
- ; * note if the data source is from ROM or RAM.
- ; *
- ; *****************************************************************************/
- USBCtrlTrfSetupHandler
- ; movlb high 0x400 ; Point to proper bank
- movlw WAIT_SETUP
- movwf ctrl_trf_state
- movlw MUID_NULL ; Set owner to NULL
- movwf ctrl_trf_session_owner
- clrf wCount
- clrf wCount + 1
- rcall USBCheckStdRequest
- movlw MUID_NULL
- cpfseq ctrl_trf_session_owner
- bra USBCtrlEPServiceComplete
- #ifdef USB_USE_HID
- rcall USBCheckHIDRequest
- #endif ; USB_USE_HID
- #ifdef USB_USE_CDC
- rcall USBCheckCDCRequest
- #endif ; USB_USE_CDC
- bra USBCtrlEPServiceComplete
- ; From usbctrltrf.c line 176
- ;/******************************************************************************
- ; * Function: void USBCtrlTrfOutHandler(void)
- ; *
- ; * PreCondition: None
- ; *
- ; * Input: None
- ; *
- ; * Output: None
- ; *
- ; * Side Effects: None
- ; *
- ; * Overview: This routine handles an OUT transaction according to
- ; * which control transfer state is currently active.
- ; *
- ; * Note: Note that if the the control transfer was from
- ; * host to device, the session owner should be notified
- ; * at the end of each OUT transaction to service the
- ; * received data.
- ; *
- ; *****************************************************************************/
- USBCtrlTrfOutHandler
- ; movlb high 0x400 ; Point to proper bank
- movlw CTRL_TRF_RX
- cpfseq ctrl_trf_state
- bra USBPrepareForNextSetupTrf
- rcall USBCtrlTrfRxService
- movlw _USIE|_DAT1|_DTSEN
- btfsc ep0Bo + Stat, DTS
- movlw _USIE|_DAT0|_DTSEN
- movwf ep0Bo + Stat
- return
- ; From usbctrltrf.c line 221
- ;/******************************************************************************
- ; * Function: void USBCtrlTrfInHandler(void)
- ; *
- ; * PreCondition: None
- ; *
- ; * Input: None
- ; *
- ; * Output: None
- ; *
- ; * Side Effects: None
- ; *
- ; * Overview: This routine handles an IN transaction according to
- ; * which control transfer state is currently active.
- ; *
- ; *
- ; * Note: A Set Address Request must not change the acutal address
- ; * of the device until the completion of the control
- ; * transfer. The end of the control transfer for Set Address
- ; * Request is an IN transaction. Therefore it is necessary
- ; * to service this unique situation when the condition is
- ; * right. Macro mUSBCheckAdrPendingState is defined in
- ; * usb9.h and its function is to specifically service this
- ; * event.
- ; *****************************************************************************/
- USBCtrlTrfInHandler
- ; movlb high 0x400 ; Point to proper bank
- movlw ADR_PENDING_STATE ; Must check if in ADR_PENDING_STATE
- cpfseq usb_device_state
- bra USBCtrlTrfInHandler1
- movf SetupPkt + bDevADR, W
- movwf UADDR
- movlw ADDRESS_STATE ; If UADDR > 0
- btfsc STATUS, Z
- movlw DEFAULT_STATE
- movwf usb_device_state
- USBCtrlTrfInHandler1
- movlw CTRL_TRF_TX
- cpfseq ctrl_trf_state
- bra USBPrepareForNextSetupTrf
- rcall USBCtrlTrfTxService
- movlw _USIE|_DAT1|_DTSEN
- btfsc ep0Bi + Stat, DTS
- movlw _USIE|_DAT0|_DTSEN
- movwf ep0Bi + Stat
- return
- ; From usbctrltrf.c line 260
- ;/******************************************************************************
- ; * Function: void USBCtrlTrfTxService(void)
- ; *
- ; * PreCondition: pSrc, wCount, and usb_stat.ctrl_trf_mem are setup properly.
- ; *
- ; * Input: None
- ; *
- ; * Output: None
- ; *
- ; * Side Effects: None
- ; *
- ; * Overview: This routine should be called from only two places.
- ; * One from USBCtrlEPServiceComplete() and one from
- ; * USBCtrlTrfInHandler(). It takes care of managing a
- ; * transfer over multiple USB transactions.
- ; *
- ; * Note: Copies one packet-ful of data pSrc (either ROM or RAM) to
- ; * EP0 IN buffer. It then updates pSrc to be ready for next
- ; * piece.
- ; * This routine works with isochronous endpoint larger than
- ; * 256 bytes and is shown here as an example of how to deal
- ; * with BC9 and BC8. In reality, a control endpoint can never
- ; * be larger than 64 bytes.
- ; *****************************************************************************/
- USBCtrlTrfTxService
- ; movlb high 0x400 ; Point to proper bank
- movf wCount, W ; Preset wCount bytes to send
- movwf usb_temp
- movf wCount + 1, W
- movwf usb_temp + 1
- sublw high EP0_BUFF_SIZE ; Make sure count does not exceed maximium length
- bnc USBCtrlTrfTxServiceCopy
- bnz USBCtrlTrfTxServiceSub
- movf wCount, W
- sublw low EP0_BUFF_SIZE
- bc USBCtrlTrfTxServiceSub
- USBCtrlTrfTxServiceCopy
- movlw low EP0_BUFF_SIZE ; Send buffer full of bytes
- movwf usb_temp
- movlw high EP0_BUFF_SIZE
- movwf usb_temp + 1
- USBCtrlTrfTxServiceSub
- movf usb_temp, W ; Subtract actual bytes to be sent from the buffer
- movwf ep0Bi + Cnt ; Save low number of bytes to send while we're here
- subwf wCount, F
- movf usb_temp + 1, W
- subwfb wCount + 1, F
- movf ep0Bi + Stat, W ; Get full Stat byte
- andlw 0xfc ; Clear bottom bits
- iorwf usb_temp + 1, W ; Put in high bits of bytes to send
- movwf ep0Bi + Stat ; Save it out
- lfsr 2, CtrlTrfData ; Set destination pointer
- movf usb_temp + 1, W ; Check high byte for 0
- bnz USBCtrlTrfTxServiceRomRam ; High byte not 0, must have something to do
- movf usb_temp, W ; Check low byte for 0
- bz USBCtrlTrfTxServiceExit ; If both 0 then nothing to send this time
- USBCtrlTrfTxServiceRomRam
- btfss usb_stat, ctrl_trf_mem ; ROM or RAM?
- bra USBCtrlTrfTxServiceRam ; RAM
- movff pSrc, TBLPTRL ; Move source pointer to TBLPTR
- movff pSrc + 1, TBLPTRH
- clrf TBLPTRU
- USBCtrlTrfTxServiceRomLoop
- tblrd *+
- movff TABLAT, POSTINC2 ; Copy one buffer to the other
- tblrd *+ ; Skip high location
- decf usb_temp, F ; Count down number of bytes
- bnz USBCtrlTrfTxServiceRomLoop
- decf usb_temp + 1, F
- bc USBCtrlTrfTxServiceRomLoop
- movff TBLPTRL, pSrc ; Update source pointer
- movff TBLPTRH, pSrc + 1
- return
- USBCtrlTrfTxServiceRam
- movff pSrc, FSR1L ; Move source pointer to FSR1
- movff pSrc + 1, FSR1H
- USBCtrlTrfTxServiceRamLoop
- movff POSTINC1, POSTINC2 ; Copy one buffer to the other
- decf usb_temp, F ; Count down number of bytes
- bnz USBCtrlTrfTxServiceRamLoop
- decf usb_temp + 1, F
- bc USBCtrlTrfTxServiceRamLoop
- movff FSR1L, pSrc ; Update source pointer
- movff FSR1H, pSrc + 1
- USBCtrlTrfTxServiceExit
- return
- ; From usbctrltrf.c line 330
- ;/******************************************************************************
- ; * Function: void USBCtrlTrfRxService(void)
- ; *
- ; * PreCondition: pDst and wCount are setup properly.
- ; * pSrc is always &CtrlTrfData
- ; * usb_stat.ctrl_trf_mem is always _RAM.
- ; * wCount should be set to 0 at the start of each control
- ; * transfer.
- ; *
- ; * Input: None
- ; *
- ; * Output: None
- ; *
- ; * Side Effects: None
- ; *
- ; * Overview: Transfers bytes received, at EP0 OUT buffer CtrlTrfData,
- ; * to user's buffer pointed by pDst.
- ; * This routine only knows how to handle raw byte data.
- ; * HIDmaker handles transferring and unpacking by a callback
- ; * function in the generated main program, called from here.
- ; *
- ; * Note: None
- ; *****************************************************************************/
- USBCtrlTrfRxService
- ; movlb high 0x400 ; Point to proper bank
- movf ep0Bo + Cnt, W ; Get low number of bytes to read
- movwf usb_temp ; usb_temp & usb_temp + 1 are bytes to read
- addwf wCount, F ; Accumulate total number of bytes read
- movf ep0Bo + Stat, W ; Get high bits to read
- andlw 0x03 ; Mask to the count
- movwf usb_temp + 1 ; Save to high byte of bytes to read
- addwfc wCount + 1, F ; Add overflow from low byte (C) and high byte to total number
- lfsr 1, CtrlTrfData ; Point FSR1 to source
- movff pDst, FSR2L ; Move destination pointer to FSR2
- movff pDst + 1, FSR2H
- movf usb_temp + 1, W ; Check high byte for 0
- bnz USBCtrlTrfRxServiceLoop ; High byte not 0, must have something to do
- movf usb_temp, W ; Check low byte for 0
- bz USBCtrlTrfRxServiceExit ; If both 0 then nothing to send this time
- USBCtrlTrfRxServiceLoop
- movff POSTINC1, POSTINC2 ; Copy one buffer to the other
- decf usb_temp, F ; Count down number of bytes
- bnz USBCtrlTrfRxServiceLoop
- decf usb_temp + 1, F
- bc USBCtrlTrfRxServiceLoop
- movff FSR2L, pDst ; Update destination pointer
- movff FSR2H, pDst + 1
- USBCtrlTrfRxServiceExit
- return
- ; From usbctrltrf.c line 382
- ;/******************************************************************************
- ; * Function: void USBCtrlEPServiceComplete(void)
- ; *
- ; * PreCondition: None
- ; *
- ; * Input: None
- ; *
- ; * Output: None
- ; *
- ; * Side Effects: None
- ; *
- ; * Overview: This routine wrap up the ramaining tasks in servicing
- ; * a Setup Request. Its main task is to set the endpoint
- ; * controls appropriately for a given situation. See code
- ; * below.
- ; * There are three main scenarios:
- ; * a) There was no handler for the Request, in this case
- ; * a STALL should be sent out.
- ; * b) The host has requested a read control transfer,
- ; * endpoints are required to be setup in a specific way.
- ; * c) The host has requested a write control transfer, or
- ; * a control data stage is not required, endpoints are
- ; * required to be setup in a specific way.
- ; *
- ; * Packet processing is resumed by clearing PKTDIS bit.
- ; *
- ; * Note: None
- ; *****************************************************************************/
- USBCtrlEPServiceComplete
- ; movlb high 0x400 ; Point to proper bank
- movlw MUID_NULL
- cpfseq ctrl_trf_session_owner
- bra USBCtrlEPServiceComplete1
- ;
- ; No handlers claimed ownership of this Setup packet.
- ; If no one knows how to service this request then stall.
- ; Must also prepare EP0 to receive the next SETUP transaction.
- movlw EP0_BUFF_SIZE
- movwf ep0Bo + Cnt
- movlw low SetupPkt
- movwf ep0Bo + ADRL
- movlw high SetupPkt
- movwf ep0Bo + ADRH
- movlw _USIE|_BSTALL
- movwf ep0Bo + Stat
- ; movlw _USIE|_BSTALL
- movwf ep0Bi + Stat
- bra USBCtrlEPServiceCompleteExit
- ;
- ; A module has claimed ownership of the control transfer session.
- USBCtrlEPServiceComplete1
- btfss SetupPkt, DataDir
- bra USBCtrlEPServiceComplete2
- movf wCount + 1, W ; Make sure count does not exceed max length requested by Host
- subwf SetupPkt + wLength + 1, W
- bnc USBCtrlEPServiceCompleteCopy
- bnz USBCtrlEPServiceComplete11
- movf wCount, W
- subwf SetupPkt + wLength, W
- bc USBCtrlEPServiceComplete11
- USBCtrlEPServiceCompleteCopy
- movff SetupPkt + wLength, wCount ; Set count to maximum
- movff SetupPkt + wLength + 1, wCount + 1
- ;
- ; Setup packet's data direction is "Device to Host"
- USBCtrlEPServiceComplete11
- rcall USBCtrlTrfTxService ; Actually copy the data to EP0 IN buffer
- movlw CTRL_TRF_TX
- movwf ctrl_trf_state
- ; Control Read:
- ; <SETUP[0]><IN[1]><IN[0]>...<OUT[1]> | <SETUP[0]>
- ; 1. Prepare OUT EP to respond to early termination
- ;
- ; NOTE:
- ; If something went wrong during the control transfer,
- ; the last status stage may not be sent by the host.
- ; When this happens, two different things could happen
- ; depending on the host.
- ; a) The host could send out a RESET.
- ; b) The host could send out a new SETUP transaction
- ; without sending a RESET first.
- ; To properly handle case (b), the OUT EP must be setup
- ; to receive either a zero length OUT transaction, or a
- ; new SETUP transaction.
- ;
- ; Since the SETUP transaction requires the DTS bit to be
- ; DAT0 while the zero length OUT status requires the DTS
- ; bit to be DAT1, the DTS bit check by the hardware should
- ; be disabled. This way the SIE could accept either of
- ; the two transactions.
- ;
- ; Furthermore, the Cnt byte should be set to prepare for
- ; the SETUP data (8-byte or more), and the buffer address
- ; should be pointed to SetupPkt.
- movlw EP0_BUFF_SIZE
- movwf ep0Bo + Cnt
- movlw low SetupPkt
- movwf ep0Bo + ADRL
- movlw high SetupPkt
- movwf ep0Bo + ADRH
- movlw _USIE ; Note: DTSEN is 0!
- movwf ep0Bo + Stat
- ; 2. Prepare IN EP to transfer data, Cnt should have
- ; been initialized by responsible request owner.
- movlw low CtrlTrfData
- movwf ep0Bi + ADRL
- movlw high CtrlTrfData
- movwf ep0Bi + ADRH
- movlw _USIE|_DAT1|_DTSEN
- movwf ep0Bi + Stat
- bra USBCtrlEPServiceCompleteExit
- ;
- ; Setup packet's data direction is "Host to Device"
- USBCtrlEPServiceComplete2
- movlw CTRL_TRF_RX
- movwf ctrl_trf_state
- ; Control Write:
- ; <SETUP[0]><OUT[1]><OUT[0]>...<IN[1]> | <SETUP[0]>
- ;
- ; 1. Prepare IN EP to respond to early termination
- ;
- ; This is the same as a Zero Length Packet Response
- ; for control transfer without a data stage
- clrf ep0Bi + Cnt
- movlw _USIE|_DAT1|_DTSEN
- movwf ep0Bi + Stat
- ; 2. Prepare OUT EP to receive data.
- movlw EP0_BUFF_SIZE
- movwf ep0Bo + Cnt
- movlw low CtrlTrfData
- movwf ep0Bo + ADRL
- movlw high CtrlTrfData
- movwf ep0Bo + ADRH
- movlw _USIE|_DAT1|_DTSEN
- movwf ep0Bo + Stat
- ;
- USBCtrlEPServiceCompleteExit
- ; PKTDIS bit is set when a Setup Transaction is received.
- ; Clear to resume packet processing.
- bcf UCON, PKTDIS
- return
- ; From usbctrltrf.c line 490
- ;/******************************************************************************
- ; * Function: void USBPrepareForNextSetupTrf(void)
- ; *
- ; * PreCondition: None
- ; *
- ; * Input: None
- ; *
- ; * Output: None
- ; *
- ; * Side Effects: None
- ; *
- ; * Overview: The routine forces EP0 OUT to be ready for a new Setup
- ; * transaction, and forces EP0 IN to be owned by CPU.
- ; *
- ; * Note: None
- ; *****************************************************************************/
- USBPrepareForNextSetupTrf
- ; movlb high 0x400 ; Point to proper bank
- movlw WAIT_SETUP
- movwf ctrl_trf_state
- movlw EP0_BUFF_SIZE
- movwf ep0Bo + Cnt
- movlw low SetupPkt
- movwf ep0Bo + ADRL
- movlw high SetupPkt
- movwf ep0Bo + ADRH
- movlw _USIE|_DAT0|_DTSEN ; EP0 buff dsc init
- movwf ep0Bo + Stat
- movlw _UCPU ; EP0 IN buffer initialization
- movwf ep0Bi + Stat
- return
- ; From usbdrv.c line ???
- ;/******************************************************************************
- ; * Function: void InitializeUSBDriver(void)
- ; *
- ; * PreCondition: None
- ; *
- ; * Input: None
- ; *
- ; * Output: None
- ; *
- ; * Side Effects: None
- ; *
- ; * Overview: This routine initializes variables used by the USB library
- ; * routines.
- ; *
- ; * Note: None
- ; *****************************************************************************/
- InitializeUSBDriver
- movlb high 0x400 ; Point to proper bank
- movlw UCFG_VAL
- movwf UCFG
- movlw DETACHED_STATE
- movwf usb_device_state
- clrf usb_stat
- clrf usb_active_cfg
- #ifdef USB_USE_HID
- rcall HIDInitEP
- #endif
- #ifdef USB_USE_CDC
- rcall CDCInitEP
- #endif
- return
- ; From usbdrv.c line 76
- ;/******************************************************************************
- ; * 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
- ; *****************************************************************************/
- USBCheckBusStatus
- movlb high 0x400 ; Point to proper bank
- ; Bus Attachment & Detachment Detection
- ; usb_bus_sense is an i/o pin defined in io_cfg.h
- #ifdef USE_USB_BUS_SENSE_IO
- btfss usb_bus_sense ; Is USB bus attached?
- bra USBCheckBusStatusDetached ; No
- #endif
- btfss UCON, USBEN ; Is the module off?
- rcall USBModuleEnable ; Is off, enable it
- #ifdef USE_USB_BUS_SENSE_IO
- bra USBCheckBusStatus1
- USBCheckBusStatusDetached
- btfsc UCON, USBEN ; Is the module on?
- rcall USBModuleDisable ; Is on, disable it
- #endif
- ;
- ; 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.
- USBCheckBusStatus1
- movlw ATTACHED_STATE
- cpfseq usb_device_state
- return
- btfsc UCON, SE0
- return
- clrf UIR ; Clear all USB interrupts
- clrf UIE ; Mask all USB interrupts
- bsf UIE, URSTIE ; Unmask RESET interrupt
- bsf UIE, IDLEIE ; Unmask IDLE interrupt
- movlw POWERED_STATE
- movwf usb_device_state
- return
- ; From usbdrv.c line 135
- USBModuleEnable
- ; movlb high 0x400 ; Point to proper bank
- clrf UCON
- clrf UIE ; Mask all USB interrupts
- bsf UCON, USBEN ; Enable module & attach to bus
- movlw ATTACHED_STATE
- movwf usb_device_state
- return
- ; From usbdrv.c line 192
- USBSoftDetach
- ; From usbdrv.c line 161
- USBModuleDisable
- movlb high 0x400 ; Point to proper bank
- clrf UCON ; Disable module & detach from bus
- clrf UIE ; Mask all USB interrupts
- movlw DETACHED_STATE
- movwf usb_device_state
- return
- ; From usbdrv.c line 215
- ;/******************************************************************************
- ; * 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
- ; *****************************************************************************/
- USBDriverService
- movlb high 0x400 ; Point to proper bank
- movlw DETACHED_STATE
- subwf usb_device_state, W
- bz USBDriverServiceExit ; Pointless to continue servicing
- ; if USB cable is not even attached.
- ;
- ; Task A: Service USB Activity Interrupt
- btfss UIR, ACTVIF
- bra USBDriverService1
- btfsc UIE, ACTVIE
- rcall USBWakeFromSuspend
- ;
- USBDriverService1
- btfsc UCON, SUSPND ; Are we suspended?
- return ; Pointless to continue servicing if the device is in suspend mode.
- ;
- ; 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.
- ;
- ; The USB reset flag is masked when the USB state is in
- ; DETACHED_STATE or ATTACHED_STATE, and therefore cannot
- ; cause a USB reset event during these two states.
- btfss UIR, URSTIF ; USB Bus Reset Interrupt?
- bra USBDriverService2
- btfsc UIE, URSTIE
- rcall USBProtocolResetHandler
- ;
- ; Task C: Check & service other USB interrupts
- USBDriverService2
- btfss UIR, IDLEIF
- bra USBDriverService3
- btfsc UIE, IDLEIE
- rcall USBSuspend
- USBDriverService3
- btfss UIR, SOFIF
- bra USBDriverService4
- btfsc UIE, SOFIE
- rcall USB_SOF_Handler
- USBDriverService4
- btfss UIR, STALLIF
- bra USBDriverService5
- btfsc UIE, STALLIE
- rcall USBStallHandler
- USBDriverService5
- btfss UIR, UERRIF
- bra USBDriverService6
- btfsc UIE, UERRIE
- rcall 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.
- USBDriverService6
- movlw DEFAULT_STATE
- subwf usb_device_state, W
- bnc USBDriverServiceExit
- ;
- ; Task D: Servicing USB Transaction Complete Interrupt
- btfss UIR, TRNIF
- bra USBDriverServiceExit
- btfss UIE, TRNIE
- bra USBDriverServiceExit
- ;
- ; USBCtrlEPService only services transactions over EP0.
- ; It ignores all other EP transactions.
- rcall USBCtrlEPService
- ; Other EPs 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.
- bcf UIR, TRNIF
- USBDriverServiceExit
- return
- ; From usbdrv.c line 301
- ;/******************************************************************************
- ; * Function: void USBSuspend(void)
- ; *
- ; * PreCondition: None
- ; *
- ; * Input: None
- ; *
- ; * Output: None
- ; *
- ; * Side Effects: None
- ; *
- ; * Overview:
- ; *
- ; * Note: None
- ; *****************************************************************************/
- USBSuspend
- ; NOTE: Do not clear UIRbits.ACTVIF here!
- ; Reason:
- ; ACTVIF is only generated once an IDLEIF has been generated.
- ; This is a 1:1 ratio interrupt generation.
- ; For every IDLEIF, there will be only one ACTVIF regardless of
- ; the number of subsequent bus transitions.
- ;
- ; If the ACTIF is cleared here, a problem could occur when:
- ; [ IDLE ][bus activity ->
- ; <--- 3 ms -----> ^
- ; ^ ACTVIF=1
- ; IDLEIF=1
- ; # # # # (#=Program polling flags)
- ; ^
- ; This polling loop will see both
- ; IDLEIF=1 and ACTVIF=1.
- ; However, the program services IDLEIF first
- ; because ACTIVIE=0.
- ; If this routine clears the only ACTIVIF,
- ; then it can never get out of the suspend
- ; mode.
- bsf UIE, ACTVIE ; Enable bus activity interrupt
- bcf UIR, IDLEIF
- bsf UCON, SUSPND ; Put USB module in power conserve
- ; At this point the PIC can go into sleep,idle, or
- ; switch to a slower clock, etc.
- return
- ; From usbdrv.c line 353
- ;/******************************************************************************
- ; * Function: void USBWakeFromSuspend(void)
- ; *
- ; * PreCondition: None
- ; *
- ; * Input: None
- ; *
- ; * Output: None
- ; *
- ; * Side Effects: None
- ; *
- ; * Overview:
- ; *
- ; * Note: None
- ; *****************************************************************************/
- USBWakeFromSuspend
- ; If using clock switching, this is the place to restore the
- ; original clock frequency.
- bcf UCON, SUSPND
- bcf UIE, ACTVIE
- bcf UIR, ACTVIF
- return
- ; From usbdrv.c line 402
- ;/******************************************************************************
- ; * 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
- ; *****************************************************************************/
- USBRemoteWakeup
- movlb high 0x400 ; Point to proper bank
- btfss usb_stat, RemoteWakeup ; Check if RemoteWakeup function has been enabled by the host.
- return ; No
- rcall USBWakeFromSuspend ; Unsuspend USB modue
- bsf UCON, RESUME ; Start RESUME signaling
- movlw 0x10 ; Set RESUME line for 1-13 ms
- movwf FSR2H ; Using FSR2 as temp
- clrf FSR2L
- USBRemoteWakeupLoop
- decfsz FSR2L, F
- bra USBRemoteWakeupLoop
- decfsz FSR2H, F
- bra USBRemoteWakeupLoop
- bcf UCON, RESUME
- return
- ; From usbdrv.c line 443
- ;/******************************************************************************
- ; * 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.
- ; *
- ; * Note: None
- ; *****************************************************************************/
- USB_SOF_Handler
- ; Callback routine here
- bcf UIR, SOFIF
- return
- ; From usbdrv.c line 486
- ;/******************************************************************************
- ; * 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.
- ; * If
- ; *****************************************************************************/
- USBStallHandler
- ; Does not really have to do anything here,
- ; even for the control endpoint.
- ; All BDs of Endpoint 0 are owned by SIE right now,
- ; but once a Setup Transaction is received, the ownership
- ; for EP0_OUT will be returned to CPU.
- ; When the Setup Transaction is serviced, the ownership
- ; for EP0_IN will then be forced back to CPU by firmware.
- ;
- ; NOTE: Above description is not quite true at this point.
- ; It seems the SIE never returns the UOWN bit to CPU,
- ; and a TRNIF is never generated upon successful
- ; reception of a SETUP transaction.
- ; Firmware work-around is implemented below.
- ;
- btfsc UEP0, EPSTALL
- rcall USBPrepareForNextSetupTrf ; Firmware Work-Around
- bcf UEP0, EPSTALL
- bcf UIR, STALLIF
- return
- ; From usbdrv.c line 528
- ;/******************************************************************************
- ; * 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
- ; *****************************************************************************/
- USBErrorHandler
- bcf UIR, UERRIF
- return
- ; From usbdrv.c line 555
- ;/******************************************************************************
- ; * 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
- ; *****************************************************************************/
- USBProtocolResetHandler
- ; movlb high 0x400 ; Point to proper bank
- clrf UEIR ; Clear all USB error flags
- clrf UIR ; Clears all USB interrupts
- movlw 0x9f ; Unmask all USB error interrupts
- movwf UEIE
- movlw 0x7b ; Enable all interrupts except ACTVIE
- movwf UIE
- clrf UADDR ; Reset to default address
- lfsr 2, UEP1 ; Reset all non-EP0 UEPn registers
- movlw 15
- USBProtocolResetHandlerClearLoop
- clrf POSTINC2
- decfsz WREG, F
- bra USBProtocolResetHandlerClearLoop
- movlw EP_CTRL|HSHK_EN ; Init EP0 as a Ctrl EP
- movwf UEP0
- btfsc UIR, TRNIF ; Flush any pending transactions
- USBProtocolResetHandlerFlushLoop
- bcf UIR, TRNIF
- btfsc UIR, TRNIF
- bra USBProtocolResetHandlerFlushLoop
- bcf UCON, PKTDIS ; Make sure packet processing is enabled
- rcall USBPrepareForNextSetupTrf
- bcf usb_stat, RemoteWakeup ; Default status flag to disable
- clrf usb_active_cfg ; Clear active configuration
- movlw DEFAULT_STATE
- movwf usb_device_state
- return
- #ifdef USB_USE_HID
- ; From hid.c line 72
- ;/******************************************************************************
- ; * Function: void USBCheckHIDRequest(void)
- ; *
- ; * PreCondition: None
- ; *
- ; * Input: None
- ; *
- ; * Output: None
- ; *
- ; * Side Effects: None
- ; *
- ; * Overview: This routine checks the setup data packet to see if it
- ; * knows how to handle it
- ; *
- ; * Note: None
- ; *****************************************************************************/
- USBCheckHIDRequest
- movlb high 0x400 ; Point to proper bank
- movf SetupPkt, W ; Recipient = RCPT_INTF?
- andlw 0x1f ; Mask to lower 5 bits
- sublw RCPT_INTF
- bnz USBCheckHIDRequestExit ; No
- movlw HID_INTF_ID ; IntfID = HID_INTF_ID?
- cpfseq SetupPkt + bIntfID
- USBCheckHIDRequestExit
- return ; No
- ;
- ; There are two standard requests that hid.c may support.
- ; 1. GET_DSC(DSC_HID,DSC_RPT,DSC_PHY);
- ; 2. SET_DSC(DSC_HID,DSC_RPT,DSC_PHY);
- ;
- movlw GET_DSC ; Request = GET_DSC?
- cpfseq SetupPkt + bRequest
- bra USBCheckHIDRequestClass ; No
- movlw DSC_HID ; DscType = DSC_HID?
- cpfseq SetupPkt + bDscType
- bra USBCheckHIDRequest1 ; No
- mSetSourcePointer HIDDescriptor1
- mGetRomTableCount ; Set wCount
- bsf usb_stat, ctrl_trf_mem ; Indicate ROM
- bra USBHIDSetSessionOwner
- USBCheckHIDRequest1
- movlw DSC_RPT ; DscType = DSC_RPT?
- cpfseq SetupPkt + bDscType
- bra USBCheckHIDRequest2 ; No
- mSetSourcePointer ReportDescriptor1
- movlw low (ReportDescriptor1Len) ; Set wCount
- movwf TBLPTRL
- movlw high (ReportDescriptor1Len)
- movwf TBLPTRH
- clrf TBLPTRU
- tblrd *+ ; Read count low
- movff TABLAT, wCount
- tblrd *+ ; Skip next
- tblrd * ; Read count high
- movff TABLAT, wCount + 1
- bsf usb_stat, ctrl_trf_mem ; Indicate ROM
- bra USBHIDSetSessionOwner
- USBCheckHIDRequest2
- ; movlw DSC_PHY ; DscType = DSC_PHY?
- ; cpfseq SetupPkt + bDscType
- ; return ; No
- USBCheckHIDRequestClass
- movf SetupPkt, W ; RequestType = CLASS?
- andlw 0x60 ; Mask to proper bits
- sublw (CLASS) << 5
- bnz USBCheckHIDRequestExit ; No
- ; movlw GET_REPORT ; Request = GET_REPORT?
- ; subwf SetupPkt + bRequest, W
- ; bz HIDGetReportHandler ; Yes
- ; movlw SET_REPORT ; Request = SET_REPORT?
- ; subwf SetupPkt + bRequest, W
- ; bz HIDSetReportHandler ; Yes
- movlw GET_IDLE ; Request = GET_IDLE?
- cpfseq SetupPkt + bRequest
- bra USBCheckHIDRequestClass1 ; No
- mSetSourcePointer idle_rate
- movlw 1
- movwf wCount
- clrf wCount + 1
- bcf usb_stat, ctrl_trf_mem ; Indicate RAM
- bra USBHIDSetSessionOwner
- USBCheckHIDRequestClass1
- movlw SET_IDLE ; Request = SET_IDLE?
- cpfseq SetupPkt + bRequest
- bra USBCheckHIDRequestClass2 ; No
- movff SetupPkt + wValue + 1, idle_rate
- bra USBHIDSetSessionOwner
- USBCheckHIDRequestClass2
- movlw GET_PROTOCOL ; Request = GET_PROTOCOL?
- cpfseq SetupPkt + bRequest
- bra USBCheckHIDRequestClass3 ; No
- mSetSourcePointer active_protocol
- movlw 1
- movwf wCount
- clrf wCount + 1
- bcf usb_stat, ctrl_trf_mem ; Indicate RAM
- bra USBHIDSetSessionOwner
- USBCheckHIDRequestClass3
- movlw SET_PROTOCOL ; Request = SET_PROTOCOL?
- cpfseq SetupPkt + bRequest
- return ; No
- movff SetupPkt + wValue, active_protocol
- USBHIDSetSessionOwner
- movlw MUID_HID
- movwf ctrl_trf_session_owner
- return
- ; From hid.c line 158
- ;/******************************************************************************
- ; * Function: void HIDInitEP(void)
- ; *
- ; * PreCondition: None
- ; *
- ; * Input: None
- ; *
- ; * Output: None
- ; *
- ; * Side Effects: None
- ; *
- ; * Overview: HIDInitEP initializes HID endpoints, buffer descriptors,
- ; * internal state-machine, and variables.
- ; * It should be called after the USB host has sent out a
- ; * SET_CONFIGURATION request.
- ; * See USBStdSetCfgHandler() in usb9.c for examples.
- ; *
- ; * Note: None
- ; *****************************************************************************/
- HIDInitEP
- movlw 1 ; Endpoint 1 Out
- movwf FSR0L
- lfsr 1, hid_report_out ; FSR1 = endpoint buffer address
- movlw HID_INT_OUT_EP_SIZE ; W = endpoint size
- rcall InitEPOut ; Inititalize the endpoint
- movlw 1 ; Endpoint 1 In
- movwf FSR0L
- lfsr 1, hid_report_in ; FSR1 = endpoint buffer address
- movlw HID_INT_IN_EP_SIZE ; W = endpoint size
- bra InitEPIn ; Inititalize the endpoint
- #endif ; USB_USE_HID
- #ifdef USB_USE_CDC
- ;/******************************************************************************
- ; * Function: void USBCheckCDCRequest(void)
- ; *
- ; * PreCondition: None
- ; *
- ; * Input: None
- ; *
- ; * Output: None
- ; *
- ; * Side Effects: None
- ; *
- ; * Overview: This routine checks the setup data packet to see if it
- ; * knows how to handle it
- ; *
- ; * Note: None
- ; *****************************************************************************/
- USBCheckCDCRequest
- ; /*
- ; * If request recipient is not an interface then return
- ; */
- movlb high 0x400 ; Point to proper bank
- movf SetupPkt, W ; Recipient = RCPT_INTF?
- andlw 0x1f ; Mask to lower 5 bits
- sublw RCPT_INTF
- bnz USBCheckCDCRequestExit ; No
- ; /*
- ; * If request type is not class-specific then return
- ; */
- movf SetupPkt, W ; RequestType = CLASS?
- andlw 0x60 ; Mask to proper bits
- sublw (CLASS) << 5
- bnz USBCheckCDCRequestExit ; No
- ; /*
- ; * Interface ID must match interface numbers associated with
- ; * CDC class, else return
- ; */
- movlw CDC_COMM_INTF_ID ; IntfID = CDC_COMM_INTF_ID?
- subwf SetupPkt + bIntfID, W
- bz USBCheckCDCRequest1 ; Yes
- movlw CDC_DATA_INTF_ID ; IntfID = CDC_DATA_INTF_ID?
- cpfseq SetupPkt + bIntfID
- USBCheckCDCRequestExit
- return ; No
- USBCheckCDCRequest1
- movlw SEND_ENCAPSULATED_COMMAND ; Request = SEND_ENCAPSULATED_COMMAND?
- cpfseq SetupPkt + bRequest
- bra USBCheckCDCRequest2 ; No
- mSetSourcePointer dummy_encapsulated_cmd_response
- bcf usb_stat, ctrl_trf_mem ; Indicate RAM
- movlw dummy_length
- movwf wCount
- clrf wCount + 1
- bra USBCDCSetSessionOwner
- USBCheckCDCRequest2
- movlw GET_ENCAPSULATED_RESPONSE ; Request = GET_ENCAPSULATED_RESPONSE?
- cpfseq SetupPkt + bRequest
- bra USBCheckCDCRequest3 ; No
- ; // Populate dummy_encapsulated_cmd_response first.
- mSetDestinationPointer dummy_encapsulated_cmd_response
- bra USBCDCSetSessionOwner
- USBCheckCDCRequest3
- movlw SET_COMM_FEATURE ; Request = SET_COMM_FEATURE?
- cpfseq SetupPkt + bRequest
- bra USBCheckCDCRequest4 ; No
- return ; Optional
- USBCheckCDCRequest4
- movlw GET_COMM_FEATURE ; Request = GET_COMM_FEATURE?
- cpfseq SetupPkt + bRequest
- bra USBCheckCDCRequest5 ; No
- return ; Optional
- USBCheckCDCRequest5
- movlw CLEAR_COMM_FEATURE ; Request = CLEAR_COMM_FEATURE?
- cpfseq SetupPkt + bRequest
- bra USBCheckCDCRequest6 ; No
- return ; Optional
- USBCheckCDCRequest6
- movlw SET_LINE_CODING ; Request = SET_LINE_CODING?
- cpfseq SetupPkt + bRequest
- bra USBCheckCDCRequest7 ; No
- mSetDestinationPointer line_coding
- bra USBCDCSetSessionOwner
- USBCheckCDCRequest7
- movlw GET_LINE_CODING ; Request = GET_LINE_CODING?
- cpfseq SetupPkt + bRequest
- bra USBCheckCDCRequest8 ; No
- ; Abstract line coding information
- movlw low 115200 ; baud rate
- movwf line_coding + dwDTERate
- movlw high 115200
- movwf line_coding + dwDTERate + 1
- movlw upper 115200
- movwf line_coding + dwDTERate + 2
- clrf line_coding + dwDTERate + 3
- clrf line_coding + bCharFormat ; 1 stop bit
- clrf line_coding + bParityType ; None
- movlw 8
- movwf line_coding + bDataBits ; 5,6,7,8, or 16
- mSetSourcePointer line_coding
- bcf usb_stat, ctrl_trf_mem ; Indicate RAM
- movlw LINE_CODING_LENGTH
- movwf wCount
- clrf wCount + 1
- bra USBCDCSetSessionOwner
- USBCheckCDCRequest8
- movlw SET_CONTROL_LINE_STATE ; Request = SET_CONTROL_LINE_STATE?
- cpfseq SetupPkt + bRequest
- bra USBCheckCDCRequest9 ; No
- movff SetupPkt + wValue, control_signal_bitmap
- bra USBCDCSetSessionOwner
- USBCheckCDCRequest9
- movlw SEND_BREAK ; Request = SEND_BREAK?
- cpfseq SetupPkt + bRequest
- bra USBCheckCDCRequest10 ; No
- return ; Optional
- USBCheckCDCRequest10
- return ; Default
- USBCDCSetSessionOwner
- movlw MUID_CDC
- movwf ctrl_trf_session_owner
- return
- ;/******************************************************************************
- ; * Function: void CDCInitEP(void)
- ; *
- ; * PreCondition: None
- ; *
- ; * Input: None
- ; *
- ; * Output: None
- ; *
- ; * Side Effects: None
- ; *
- ; * Overview: CDCInitEP initializes CDC endpoints, buffer descriptors,
- ; * internal state-machine, and variables.
- ; * It should be called after the USB host has sent out a
- ; * SET_CONFIGURATION request.
- ; * See USBStdSetCfgHandler() in usb9.c for examples.
- ; *
- ; * Note: None
- ; *****************************************************************************/
- CDCInitEP
- movlw 2 ; Endpoint 2 In
- movwf FSR0L
- lfsr 1, cdc_notice ; FSR1 = endpoint buffer address
- movlw CDC_INT_EP_SIZE ; W = endpoint size
- rcall InitEPIn ; Inititalize the endpoint
- movlw 3 ; Endpoint 3
- movwf FSR0L
- lfsr 1, cdc_data_rx ; FSR1 = endpoint buffer address
- movlw CDC_BULK_OUT_EP_SIZE ; W = endpoint size
- rcall InitEPOut ; Inititalize the endpoint
- movlw 3 ; Endpoint 3 In
- movwf FSR0L
- lfsr 1, cdc_data_tx ; FSR1 = endpoint buffer address
- movlw CDC_BULK_IN_EP_SIZE ; W = endpoint size
- bra InitEPIn ; Inititalize the endpoint
- #endif ; USB_USE_CDC
- ; Generic code for use by all the classes
- ; InitEPIn
- ; Generic initialize In endpoint
- ; Input:
- ; FSR0L is endpoint number
- ; FSR1 is endpoint buffer address
- ; W is endpoint buffer size
- ; Returns:
- ; Nada
- ; Uses
- ; FSR0 is BDT pointer
- ; FSR1 is endpoint buffer pointer
- ; FSR2 is endpoint table pointer
- InitEPIn
- ; Save maximum count at front of endpoint buffer and move buffer pointer up (no need to put in Cnt for In)
- movwf POSTINC1 ; Store maximum count at front of endpoint buffer and move up pointer
- ; Point FSR2 to endpoint table
- lfsr 2, UEP0
- movf FSR0L, W ; Add in endpoint number
- addwf FSR2L, F
- ; Enable In endpoint
- movlw EP_IN|HSHK_EN ; Enable In pipe
- iorwf INDF2, F
- ; Point FSR0 to endpoint BDT
- rlncf FSR0L, W ; Endpoint number * 8
- rlncf WREG, F
- rlncf WREG, F
- lfsr 0, ep0Bi ; Point FSR0 to beginning of BDT area
- addwf FSR0L, F ; Add endpoint offset to FSR0 (can't overflow to FSR0H)
- ; Set endpoint buffer address from FSR1
- movlw ADRL ; Point to ADRL
- movff FSR1L, PLUSW0
- movlw ADRH ; Point to ADRH
- movff FSR1H, PLUSW0
- ; Set endpoint status
- movlw _UCPU|_DAT1 ; Set transmit status
- movwf INDF0 ; Set Stat
- return
- ; InitEPOut
- ; Generic initialize Out endpoint
- ; Input:
- ; FSR0L is endpoint number
- ; FSR1 is endpoint buffer address
- ; W is endpoint buffer size
- ; Returns:
- ; Nada
- ; Uses
- ; FSR0 is BDT pointer
- ; FSR1 is endpoint buffer pointer
- ; FSR2 is endpoint table pointer
- InitEPOut
- ; Save maximum count at front of endpoint buffer and move buffer pointer up
- movwf POSTINC1 ; Store maximum count at front of endpoint buffer and move up pointer
- ; Point FSR2 to endpoint table
- lfsr 2, UEP0
- movf FSR0L, W ; Add in endpoint number
- addwf FSR2L, F
- ; Enable Out endpoint
- movlw EP_OUT|HSHK_EN ; Enable Out pipe
- iorwf INDF2, F
- ; Point FSR0 to endpoint BDT
- rlncf FSR0L, W ; Endpoint number * 8
- rlncf WREG, F
- rlncf WREG, F
- lfsr 0, ep0Bo ; Point FSR0 to beginning of BDT area
- addwf FSR0L, F ; Add endpoint offset to FSR0 (can't overflow to FSR0H)
- ; Set endpoint buffer address from FSR1 + 1
- movlw ADRL ; Point to ADRL
- movff FSR1L, PLUSW0
- movlw ADRH ; Point to ADRH
- movff FSR1H, PLUSW0
- ; Set Cnt to maximum count
- movf POSTDEC1, W ; Back up endpoint buffer pointer (no PREDEC1!)
- incf FSR0L, F ; Point to Cnt
- movff INDF1, POSTDEC0 ; Set maximum count and point back to Stat
- ; Set endpoint status
- movlw _USIE|_DAT0|_DTSEN ; Set receive status
- movwf INDF0 ; Set Stat
- return
- ; PutUSB
- ; Generic fill In endpoint for TX
- ; Input:
- ; FSR0L is endpoint number
- ; FSR1 is source buffer pointer
- ; W is count
- ; Returns:
- ; FSR1 is updated source buffer pointer
- ; W returns number sent
- ; Carry is clear for buffer not available
- ; Uses:
- ; FSR0 is BDT pointer
- ; FSR1 is source buffer pointer
- ; FSR2 is endpoint buffer pointer
- ; R0 in BANKA is temporary length storage
- PutUSB
- movwf R0 ; Save count
- ; Check to see if we're configured
- movlb high 0x400 ; Point to proper bank
- movlw CONFIGURED_STATE ; We might not be configured yet
- subwf usb_device_state, W
- movlw 0 ; 0 characters sent, so far
- bcf STATUS, C ; Clear Carry for possible error return
- bnz PutUSBNotReady ; We're not configured
- ; Point FSR0 to requested endpoint In BDT
- rlncf FSR0L, W ; Endpoint number * 8
- rlncf WREG, F
- rlncf WREG, F
- lfsr 0, ep0Bi ; Point FSR0 to beginning of BDT area
- addwf FSR0L, F ; Add endpoint offset to FSR0 (can't overflow to FSR0H)
- movlw 0 ; 0 characters sent, so far
- bcf STATUS, C ; Clear Carry for possible error return
- btfsc INDF0, UOWN ; Who owns the buffer (Stat, UOWN)?
- PutUSBNotReady
- return ; Busy (we don't)
- ; Get endpoint buffer address to FSR2
- movlw ADRL ; Point to ADRL
- movff PLUSW0, FSR2L
- movlw ADRH ; Point to ADRH
- movff PLUSW0, FSR2H
- movlw -1
- movf PLUSW2, W ; Get maximum length from in front of endpoint buffer
- cpfslt R0 ; Find number of bytes to send this time
- movwf R0 ; Too big - send maximum allowed length
- incf FSR0L, F ; Point to Cnt
- movf R0, W ; Get number to send
- movwf POSTDEC0 ; Put length into Cnt and point back to Stat
- bz PutUSBZero ; Zero to send
- PutUSBRamLoop
- movff POSTINC1, POSTINC2 ; Copy source buffer to endpoint buffer
- decfsz WREG, F ; Count down number of bytes to transfer
- bra PutUSBRamLoop
- PutUSBZero
- movlw _DTSMASK ; Save only DTS bit
- andwf INDF0, F
- btg INDF0, DTS ; Toggle DTS bit
- movlw _USIE|_DTSEN ; Turn ownership to SIE
- iorwf INDF0, F
- movf R0, W ; Return number of bytes sent
- bsf STATUS, C ; Set Carry for non-error return
- return
- ; GetUSB
- ; Generic get from Out endpoint for RX
- ; Input:
- ; FSR0L is endpoint number
- ; FSR1 is destination buffer pointer
- ; W is max buffer length
- ; Returns:
- ; FSR1 is updated destination buffer pointer
- ; W returns number received
- ; Carry is clear for buffer not available
- ; Uses
- ; FSR0 is BDT pointer
- ; FSR1 is destination buffer pointer
- ; FSR2 is endpoint buffer pointer
- ; R0 in BANKA is temporary length storage
- GetUSB
- movwf R0 ; Save max buffer length
- ; Check to see if we're configured
- movlb high 0x400 ; Point to proper bank
- movlw CONFIGURED_STATE ; We might not be configured yet
- subwf usb_device_state, W
- movlw 0 ; 0 characters received, so far
- bcf STATUS, C ; Clear Carry for possible error return
- bnz GetUSBNotReady ; We're not configured
- ; Point FSR0 to requested endpoint Out BDT
- rlncf FSR0L, W ; Endpoint number * 8
- rlncf WREG, F
- rlncf WREG, F
- lfsr 0, ep0Bo ; Point FSR0 to beginning of BDT area
- addwf FSR0L, F ; Add endpoint offset to FSR0 (can't overflow to FSR0H)
- movlw 0 ; 0 characters received, so far
- bcf STATUS, C ; Clear Carry for possible error return
- btfsc INDF0, UOWN ; Who owns the buffer (Stat, UOWN)?
- GetUSBNotReady
- return ; Busy (we don't)
- ; Get endpoint buffer address to FSR2
- movlw ADRL ; Point to ADRL
- movff PLUSW0, FSR2L
- movlw ADRH ; Point to ADRH
- movff PLUSW0, FSR2H
- movf PREINC0, W ; Get Cnt
- cpfslt R0 ; Make sure it's not longer than the buffer
- movwf R0 ; It's OK, save returned length
- movlw -1
- movf PLUSW2, W ; Get maximum length from in front of endpoint buffer
- movwf POSTDEC0 ; Reset max length and point back to Stat
- movf R0, W ; Get count to W
- bz GetUSBZero ; Nothing received
- GetUSBRamLoop
- movff POSTINC2, POSTINC1 ; Copy endpoint buffer to destination buffer
- decfsz WREG, F ; Count down number of bytes
- bra GetUSBRamLoop
- GetUSBZero
- movlw _DTSMASK ; Save only DTS bit
- andwf INDF0, F
- btg INDF0, DTS ; Toggle DTS bit
- movlw _USIE|_DTSEN ; Turn ownership to SIE
- iorwf INDF0, F
- movf R0, W ; Return number of bytes received
- bsf STATUS, C ; Set Carry for non-error return
- return