⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 usb_ch9.asm

📁 This firmware translates a PS/2 mouse to a USB mouse. The translator firmware is entirely interrup
💻 ASM
📖 第 1 页 / 共 4 页
字号:
;                            Software License Agreement
;
; The software supplied herewith by Microchip Technology Incorporated (the "Company")
; for its PICmicro(r) Microcontroller is intended and supplied to you, the Company's
; 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 "AS 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.
;
; ###############################################################################
;   filename:           USB_CH9.ASM
;
; Implements the chapter 9 enumeration commands for Microchip's
; PIC16C7x5 parts.
;
; ###############################################################################
;
;   Author(s):          Dan Butler and Reston Condit
;   Company:            Microchip Technology Inc
;
;   Revision:           1.21
;   Date:               08 August 2001
;   Assembled using     MPASM 2.61
;   Revision History:
;   23 August 2000      DZB Changed descriptor pointers to 16 bits.
;   24 August 2000      DZB Moved EP1 & 2 configuration from USBReset
;                           to Set_Configuration to implement requirement in
;                           USB V1.1 spec paragraph 5.3.1.2
;   28 August 2000      DZB Force data toggle on OUT packets in PutUSB
;   20 March 2001       DZB Reduced use of common RAM
;   20 March 2001       DZB Put and Get use their own temp variable (GPtemp) to
;                           avoid collisions with the ISR's use of temp.
;   29 March 2001       DZB Fixed saving of bank bits in GetUSB
;   02 May 2001         DZB Implemented SHOW_ENUM_STATUS to show enumeration
;                           status on the PORTB LEDs: 0- Powered, 1- Default,
;                           2- addressed, 3- configured, 4- sleep, 
;                           5- EP0 Activity, 6- EP1 Activity, 7- EP2 Activity
;   03 August 2001      RAC Made distinct GetEP and PutEP macros for endpoints 1 
;                           and 2.  These functions are GetEP1, GetEP2, PutEP1, and 
;                           PutEP2.  Instances of the these macros are created in
;                           usb_ch9.asm.
;   08 August 2001      RAC Corrected various banking and paging issues.
;   15 August           RAC Added Report_desc_index function in descript.asm.
;                           This function allows more than one report descriptor
;                           to be used. 
;
;################################################################################
;
;    include files:
;       P16C765.inc     Rev 1.00
;       usb_defs.inc    Rev 1.00
;
;################################################################################

#include <p16C765.inc>
#include "usb_defs.inc"

    errorlevel -302 ; supress "register not in bank0, check page bits" message

#define SHOW_ENUM_STATUS

unbanked    udata_shr   ; these will get assigned to unbanked RAM (0x70-0x7F)
temp        res     1   ; short term temp register used in Get Interface
GPtemp      res     1   ; temporary storage location used in Get and PutEPn

    global  BufferDescriptor
    global  BufferData
    global  temp
    global  temp2
    global  EP0_maxLength
    global  EP0_start
    global  EP0_end

bank2   udata
BufferDescriptor    res     3
BufferData          res     8
USBMaskedInterrupts res     1
USB_Curr_Config     res     1
USB_status_device   res     1   ; status of device
USB_dev_req         res     1
USB_address_pending res     1
USBMaskedErrors     res     1
PIDs                res     1
EP0_start           res     2   ; pointer to first byte of data to send
EP0_end             res     1   ; pointer to last byte of data to send
EP0_maxLength       res     1
temp2               res     1
bufindex            res     1
USB_Interface       res     3   ; allow 3 interfaces to have alternate endpoints
inner               res     1
outer               res     1
dest_ptr            res     1   ; used in buffer copies for Get and
source_ptr          res     1   ; Put USB calls
hid_dest_ptr        res     1   ; used in buffer copies for HIDSetReport
hid_source_ptr      res     1   ;
counter             res     1
bytecounter         res     1   ; saved copy that will be returned in W
RP_save             res     1   ; save bank bits while copying buffers
IS_IDLE             res     1
USB_USTAT           res     1   ; copy of the USTAT register before clearing TOK_DNE

    global  USB_Curr_Config    
    global  USB_status_device
    global  USB_dev_req
    global  USB_Interface

#ifdef      COUNTERRORS
USB_PID_ERR         res     2   ; 16 bit counters for each error condition
USB_CRC5_ERR        res     2
USB_CRC16_ERR       res     2
USB_DFN8_ERR        res     2
USB_BTO_ERR         res     2
USB_WRT_ERR         res     2
USB_OWN_ERR         res     2
USB_BTS_ERR         res     2
#endif

    extern  Config_desc_index
    extern  Descriptions
    extern  string_index
    extern  String0
    extern  String0_end
    extern  ClassSpecificRequest
    extern  Check_Class_Specific_IN
    extern  Get_Report_Descriptor
    extern  Get_HID_Descriptor
    extern  DeviceDescriptor
    extern  StringDescriptions

; **********************************************************************
; This section contains the functions to interface with the main 
; application.
; **********************************************************************

interface	code

; **********************************************************************
; GETEP1 and GETEP2
;
; Note:  These functions are, in reality, macros defined in usb_defs.inc.
;        To save ROM, delete the instances below that you will not need.
;
; Enter with buffer pointer in IRP+FSR.  
; Checks the semaphore for the OUT endpoint, and copies the buffer 
; if available.  Restores the bank bits as we found them.
;
; Returns the bytecount in the W register and return status in the carry
; bit as follows:
; 0 - no buffer available,
; 1 - Buffer copied and buffer made available for next transfer.
; 
; The number of bytes moved is returned in W reg.
; **********************************************************************

	GETEP1		; create instance of GETEP1
	GETEP2		; create instance of GETEP2

; **********************************************************************
; PUTEP1 and PUTEP2
;
; Note:  These functions are, in reality, macros defined in usb_defs.inc.
;        To save ROM, delete the instances below that you will not need.
;
; Enter with bytecount in W and buffer pointer in IRP+FSR.
; the bytecount is encoded in the lower nybble of W.
;
; Tests the owns bit for the IN side of the specified Endpoint.
; If we own the buffer, the buffer pointed to by the FSR is copied
; to the EPn In buffer, then the owns bit is set so the data will be
; TX'd next time polled.  
;
; Returns the status in the carry bit as follows:
; 1 - buffer available and copied.
; 0 - buffer not available (try again later)
; **********************************************************************
	PUTEP1      ; create instance of PUTEP1
	PUTEP2      ; create instance of PUTEP2

; *********************************************************************
; Stall Endpoint.
; Sets the stall bit in the Endpoint Control Register.  For the control
; Endpoint, this implements a Protocol stall and is used when the request
; is invalid for the current device state.  For non-control Endpoints,
; this is a Functional Stall, meaning that the device needs outside 
; intervention and trying again later won't help until it's been serviced.
; enter with endpoint # to stall in Wreg.
; *********************************************************************
StallUSBEP
    bsf     STATUS,IRP      ; select banks 2/3
    andlw   0x03            ; try to keep things under control
    addlw   low UEP0        ; add address of endpoint control reg
    movwf   FSR
    bsf     INDF,EP_STALL   ; set stall bit
    return

; *********************************************************************
; Unstall Endpoint.
; Sets the stall bit in the Endpoint Control Register.  For the control
; Endpoint, this implements a Protocol stall and is used when the request
; is invalid for the current device state.  For non-control Endpoints,
; this is a Functional Stall, meaning that the device needs outside 
; intervention and trying again later won't help until it's been serviced.
; enter with endpoint # to stall in Wreg.
; *********************************************************************
UnstallUSBEP
    bsf     STATUS,IRP      ; select banks 2/3
    andlw   0x03            ; try to keep things under control
    addlw   low UEP0        ; add address of endpoint control reg
    movwf   FSR
    bcf     INDF,EP_STALL   ; clear stall bit
    return

; *********************************************************************
; CheckSleep
; Checks the USB Sleep bit.  If the bit is set, the
; Endpoint, this implements a Protocol stall and is used when the request
; is invalid for the current device state.  For non-control Endpoints,
; this is a Functional Stall, meaning that the device needs outside 
; intervention and trying again later won't help until it's been serviced.
; enter with endpoint # to stall in Wreg.
; *********************************************************************
CheckSleep
    global  CheckSleep

    banksel IS_IDLE
    btfss   IS_IDLE,0       ; test the bus idle bit
    goto    nosleeptoday

#ifdef SHOW_ENUM_STATUS
    banksel PORTB
    bsf     PORTB,4         ; turn on LED 4 to indicate we've gone to sleep
    banksel UIR
#endif
    bsf     STATUS,RP0      ; point to bank 3
    bcf     UIR,ACTIVITY
    bsf     UIE,ACTIVITY    ; enable the USB activity interrupt
    bsf     UCTRL,SUSPND    ; put USB regulator and transciever in low power state
    sleep                   ; and go to sleep
    nop
    bcf     UCTRL,SUSPND
    bcf     UIR,UIDLE
    bsf     UIE,UIDLE
    bcf     UIR,ACTIVITY
    bcf     UIE,ACTIVITY
#ifdef SHOW_ENUM_STATUS
    banksel PORTB
    bcf     PORTB,4         ; turn off LED 4 to indicate we're back.
#endif

nosleeptoday
    return

; *********************************************************************
; Remote Wakeup
; Checks USB_status_device to see if the host enabled Remote Wakeup
; If so, perform Remote wakeup and disable remote wakeup feature
; It is called by PortBChange
; *********************************************************************
RemoteWakeup
    global  RemoteWakeup

    banksel USB_status_device    
    btfss   USB_status_device, 1
    goto    RemoteEnd

    clrf    inner
    movlw   0xB0
    movwf   outer

    bsf     STATUS, RP0     ; BANK 3
    bsf     UCTRL, 2        ; RESUME SIGNALING
    bcf     STATUS, RP0     ; BANK 2

    incfsz  inner,f         ; DELAY over 10mS
    goto    $-1
    incfsz  outer,f
    goto    $-3

    bsf     STATUS,RP0
    bcf     UCTRL, 2        ; Clear Resume bit
    bcf     STATUS,RP0
    bcf     USB_status_device, 1    ; Disable Remote Wakeup
    
RemoteEnd
    return


; *********************************************************************
; USB Soft Detach
; Clears the DEV_ATT bit, electrically disconnecting the device to the bus.
; This removes the device from the bus, then reconnects so it can be
; re-enumerated by the host.  This is envisioned as a last ditch effort
; by the software.
; *********************************************************************
SoftDetachUSB
    global  SoftDetachUSB

    banksel UCTRL
    bcf     UCTRL,DEV_ATT   ; clear attach bit

    bcf     STATUS, RP0     ; bank 2
    
    clrf    outer
    clrf    inner

    incfsz  inner,f
    goto    $-1
    incfsz  outer,f
    goto    $-3

    pagesel InitUSB
    call    InitUSB         ; reinitialize the USB peripheral
    return


; ******************************************************************
; Init USB
; Initializes the USB peripheral, sets up the interrupts
; ******************************************************************
InitUSB
    global  InitUSB

    banksel USWSTAT
    clrf    USWSTAT         ; default to powered state
    movlw   0x01            ; mask all USB interrupts except reset
    movwf   UIE
    clrf    UIR             ; clear all USB Interrupt flags
    movlw   0x08            ; Device attached
    movwf   UCTRL

    bcf     STATUS, RP0     ; bank 2
    clrf    USB_Curr_Config
    movlw   1
    movwf   USB_status_device
    clrf    USB_Interface
    clrf    USB_Interface+1
    clrf    USB_Interface+2
    movlw   0xFF
    movwf   USB_dev_req     ; no device requests in process
#ifdef COUNTERRORS
    clrf    USB_PID_ERR
    clrf    USB_PID_ERR+1
    clrf    USB_CRC5_ERR
    clrf    USB_CRC5_ERR+1
    clrf    USB_CRC16_ERR
    clrf    USB_CRC16_ERR+1
    clrf    USB_DFN8_ERR
    clrf    USB_DFN8_ERR+1
    clrf    USB_BTO_ERR
    clrf    USB_BTO_ERR+1
    clrf    USB_WRT_ERR
    clrf    USB_WRT_ERR+1
    clrf    USB_OWN_ERR
    clrf    USB_OWN_ERR+1
    clrf    USB_BTS_ERR
    clrf    USB_BTS_ERR+1
#endif

    banksel PIR1            ; bank 0
    bcf     PIR1,USBIF      ; clear the USB flag
    bsf     STATUS,RP0      ; bank 1
    bsf     PIE1,USBIE      ; enable usb interrupt
    bsf     INTCON, 6       ; enable global and peripheral interrupts
    bsf     INTCON, 7
#ifdef SHOW_ENUM_STATUS
    bcf     STATUS,RP0      ; select bank 0
    bsf     PORTB,0         ; set bit zero to indicate Powered status
#endif
    return


; ******************************************************************
; DeInit USB
; Shuts down the USB peripheral, clears the interrupt enable.
; ******************************************************************
DeInitUSB
    global  DeInitUSB

    banksel UCTRL
    bcf     UCTRL,DEV_ATT   ; D+/D- go high Z
    bsf     UCTRL,SUSPND    ; Place USB module in low power mode.

    clrf    USWSTAT         ; set device state to powered.

    bcf     STATUS,RP1      ; select bank 1
    bcf     PIE1,USBIE      ; clear USB interrupt enable
#ifdef SHOW_ENUM_STATUS
    bcf     STATUS,RP0
    movlw   0x01
    movwf   PORTB           ; clear all lights except powered
    bsf     STATUS,RP0
#endif

    return


core    code
; The functions below are the core functions
; ******************************************************************
; USB interrupt triggered, Why?
; Poll the USB interrupt flags to find the cause.
; ******************************************************************
ServiceUSBInt
    global  ServiceUSBInt

    banksel UIR
    movf    UIR,w           ; get the USB interrupt register
    andwf   UIE,w           ; mask off the disabled interrupts
    bcf     STATUS, RP0     ; BANK 2
    btfsc   STATUS,Z        ; is there any unmasked interrupts?
    goto    ExitServiceUSBInt ; no, bail out.

    pagesel TokenDone
    movwf   USBMaskedInterrupts
    btfsc   USBMaskedInterrupts,TOK_DNE    ; was it a token done?
    call    TokenDone
    banksel USBMaskedInterrupts
    btfsc   USBMaskedInterrupts,USB_RST
    call    USBReset
    btfsc   USBMaskedInterrupts,STALL
    call    USBStall
    btfsc   USBMaskedInterrupts,UERR
    call    USBError
    btfsc   USBMaskedInterrupts,UIDLE
    call    USBSleep
    btfsc   USBMaskedInterrupts,ACTIVITY

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -