; ############################################################################### ; filename: HIDCLASS.ASM ; USB Human Interface Device (HID) class specific ; commands ; ; Implements the chapter 9 enumeration commands for Microchip's ; PIC16C7x5 parts. ; ; Control is routed here when a token done interrupt is received and ; the bit 5 of the RequestType byte is set (0x20). Prior to this, the ; EP0 buffer has been copied to common RAM. Data in the ; ; ############################################################################### ; ; Author: Dario Greggio (based on work by Dan Butler) ; Company: ADPM Synthesis sas (based on work by Microchip Technology Inc) ; ; Revision: 2.00 ; Date: 23 April 2002 ; Assembled using MPASM 2.30.07 ; Revision History ; 20 March 2001 DZB Revamped parsing of HID class specific tokens ; 20 March 2001 DZB Set Protocol (21 0B) supported by returning a zero ; length packet. Add code as necessary to give ; meaning to the specified protocol value. ; 29 March 2001 DZB ; Change log: ; GD: ; 18/4/01: inizio ; ;################################################################################ ; ; include files: ; P16C765.inc Rev 1.00 ; usb_defs.inc Rev 1.00 ; ;################################################################################ list p=16c745,r=dec ; list directive to define processor, r=RADICE numerica di default (dec, hex...) #include #include "usb_defs.inc" extern Report_desc_index extern Descr_desc_index extern Descriptions extern BufferData extern BufferDescriptor extern wrongstate extern USB_dev_req extern EP0_maxLength extern EP0_start extern EP0_end extern copy_descriptor_to_EP0 extern Send_0Len_pkt extern HID_Descriptor extern USB_Protocol global ClassSpecificRequest global Get_HID_Descriptor ;USBBANK code core code ; ****************************************************************** ; Get Class Specific Descriptor ; ****************************************************************** ClassSpecificRequest: #ifdef FUNCTIONIDS SELECTBANK3 movlw 0x03 ; save state bits andwf USWSTAT,f movlw CLASSSPECIFIC iorwf USWSTAT,f ; place in upper 6 bits of register bcf STATUS, RP0 #endif pagesel Host2DevHIDRequest movfw BufferData+bmRequestType xorlw 0x21 btfsc STATUS,Z goto Host2DevHIDRequest pagesel Host2DevReportRequest movfw BufferData+bmRequestType xorlw 0x22 btfsc STATUS,Z goto Host2DevReportRequest pagesel Host2DevPhysicalRequest movfw BufferData+bmRequestType xorlw 0x23 btfsc STATUS,Z goto Host2DevPhysicalRequest pagesel Dev2HostHIDRequest movfw BufferData+bmRequestType xorlw 0xA1 btfsc STATUS,Z goto Dev2HostHIDRequest pagesel Dev2HostReportRequest movfw BufferData+bmRequestType xorlw 0xA2 btfsc STATUS,Z goto Dev2HostReportRequest pagesel Dev2HostPhysicalRequest movfw BufferData+bmRequestType xorlw 0xA3 btfsc STATUS,Z goto Dev2HostPhysicalRequest pagesel wrongstate goto wrongstate ; Need to add code if you need to handle optional functions ; such as get/set_idle. Otherwise, send STALL buy calling ; to signal the host that the feature is not implemented. Host2DevHIDRequest ; DA USB touch screen !! TESTARE!! movf BufferData+bRequest,w pagesel Get_Report_Descriptor xorlw 0x06 btfsc STATUS,Z goto Get_Report_Descriptor movfw BufferData+bRequest xorlw 0x09 pagesel SetHIDReport btfsc STATUS,Z goto SetHIDReport movfw BufferData+bRequest xorlw 0x0A pagesel SetIdle btfsc STATUS,Z goto SetIdle movfw BufferData+bRequest xorlw 0x0B pagesel SetProtocol btfsc STATUS,Z goto SetProtocol pagesel wrongstate goto wrongstate Dev2HostHIDRequest movfw BufferData+bRequest xorlw 0x01 pagesel GetHIDReport btfsc STATUS,Z goto GetHIDReport movf BufferData+bRequest,w xorlw 0x02 pagesel GetIdle btfsc STATUS,Z goto GetIdle movf BufferData+bRequest,w xorlw 0x03 pagesel GetProtocol btfsc STATUS,Z goto GetProtocol pagesel wrongstate goto wrongstate ; ****************************************************************** ; Get Report Descriptor ; Returns the Report descriptor ; Checks for the report type (input, output or Feature). ; ma che dici? NON è vero! in wValue+1 c'e' il val. 21 opp. 22 opp. come da routine chiamante (in usb_ch9.asm) ; però, chiamato da qua sopra, potrebbe funzionare... ; ****************************************************************** Get_Report_Descriptor global Get_Report_Descriptor banksel EP0_start movlw GET_DESCRIPTOR movwf USB_dev_req ; currently processing a get descriptor request movlw 8 movwf EP0_maxLength ; movfw BufferData+(wValue+1) ; check report ID (in spec 1.1 è chiamato "tipo") ; xorlw 0x01 ; was it an Input Report? ; pagesel TryOutputReport ; btfsc STATUS,Z ; goto TryOutputReport bcf STATUS,C rlf BufferData+wIndex,w pagesel Report_desc_index call Report_desc_index ; translate index to offset into descriptor table movwf EP0_start bcf STATUS,C rlf BufferData+wIndex,w addlw 1 ; point to high order byte call Report_desc_index ; translate index to offset into descriptor table movwf EP0_start+1 pagesel Descriptions call Descriptions movwf EP0_end incf EP0_start,f pagesel CheckReportLength goto CheckReportLength ; MAI ESEGUITO! v. sopra! TryOutputReport ; movfw BufferData+(wValue+1) ; check report ID (in spec 1.1 è chiamato "tipo") xorlw 0x02 ; was it an Output Report? pagesel TryFeatureReport btfsc STATUS,Z goto TryFeatureReport bcf STATUS,C rlf BufferData+wIndex,w pagesel Report_desc_index call Report_desc_index ; translate index to offset into descriptor table movwf EP0_start bcf STATUS,C rlf BufferData+wIndex,w addlw 1 ; point to high order byte call Report_desc_index ; translate index to offset into descriptor table movwf EP0_start+1 pagesel Descriptions call Descriptions movwf EP0_end incf EP0_start,f pagesel CheckReportLength goto CheckReportLength TryFeatureReport ; movfw BufferData+(wValue+1) ; check report ID (in spec 1.1 è chiamato "tipo") xorlw 0x03 ; was it an Output Report? ma che dici?? 3=? pagesel wrongstate btfsc STATUS,Z goto wrongstate ; Fill EP0IN buffer here... return CheckReportLength movfw BufferData+(wLength+1) ; Is the host requesting more than 255 bytes? pagesel nolimit_rpt bnz nolimit_rpt ; If so, the host is requesting more than we have check_low_bytes movfw BufferData+wLength subwf EP0_end,w ; if not, compare the amount the host is request movfw BufferData+wLength ; with the length of the descriptor btfsc STATUS,C ; if the host is request less than the descriptor movwf EP0_end ; length, send only as much as what the host wants nolimit_rpt incf EP0_end,f pagesel copy_descriptor_to_EP0 call copy_descriptor_to_EP0 return Get_HID_Descriptor: global Get_HID_Descriptor movlw GET_DESCRIPTOR movwf USB_dev_req ; currently processing a get descriptor request movlw 8 movwf EP0_maxLength ; e wValue+1 qui?? frega nulla? in spec 1.1 si dice che è il "tipo"... (v. sopra) bcf STATUS,C rlf BufferData+wValue,w ; get # (QUA NON sembra index il puntatore... v.sopra) pagesel Descr_desc_index call Descr_desc_index ; translate index to offset into descriptor table movwf EP0_start bcf STATUS,C rlf BufferData+wValue,w addlw 1 ; point to high order byte call Descr_desc_index ; translate index to offset into descriptor table movwf EP0_start+1 pagesel Descriptions call Descriptions movwf EP0_end movf BufferData+(wLength+1),f pagesel nolimit_hid bnz nolimit_hid subwf BufferData+wLength,w movfw BufferData+wLength btfss STATUS,C movwf EP0_end nolimit_hid: incf EP0_end,f pagesel copy_descriptor_to_EP0 call copy_descriptor_to_EP0 return Get_Physical_Descriptor: return Check_Class_Specific_IN: global Check_Class_Specific_IN pagesel copy_descriptor_to_EP0 movfw USB_dev_req xorlw GET_DESCRIPTOR btfsc STATUS,Z call copy_descriptor_to_EP0 return ; ****************************************************************** ; These requests are parsed out, but nothing is actually done with them ; currently they simply stall EP0 to show that the request is not ; supported. If you need to support them, fill in the code. ; ****************************************************************** Host2DevReportRequest: Host2DevPhysicalRequest: Dev2HostReportRequest: Dev2HostPhysicalRequest: GetIdle: ; serve per Tastiera (v.) GetPhysical: pagesel wrongstate goto wrongstate SetHIDReport: movlw HID_SET_REPORT movwf USB_dev_req ; store status banksel BD0OST movlw 0xc8 ; reset buffer: SENZA di questo, il PC non manda SET_REPORT (x Led!) movwf BD0OST ; i dati vengono poi gestiti in TokenOut (v. USB_CH9.ASM) ; extern StdBeep ; pagesel StdBeep ; call StdBeep ; pagesel SetHIDReport ; BANKSEL USB_dev_req return GetHIDReport ; Write functionality for Get_Report here and uncomment following lines ; bsf STATUS,RP1 ; bank3 ; movlw 0xC8 ; movwf BD0IST ; return pagesel wrongstate ; ... e togliere questi! goto wrongstate ; ****************************************************************** ; As written, Set Protocol merely returns a zero length packet to keep the OS happy. ; If your application actually needs to do something with the protocol value specified ; here's where to add the code. ; ****************************************************************** SetProtocol: ; 2.00 movfw BufferData+wValue movwf USB_Protocol pagesel Send_0Len_pkt call Send_0Len_pkt return ; banksel BD0IBC ; select bank 3 ; movlw 0x00 ; movwf BD0IBC ; set the byte count field to zero ; movlw 0xc8 ; movwf BD0IST ; Set the OWNs bit ; Add code here to actually do something with the protocol value specified. return GetProtocol: ; 2.00 banksel BD0IAL bankisel BD0IAL movf BD0IAL,w ; get buffer address movwf FSR bcf STATUS,RP0 ; bank 2 movfw USB_Protocol bsf STATUS,RP0 ; bank 3 movwf INDF movlw 1 movwf BD0IBC movlw 0xC8 movwf BD0IST return SetIdle: ;tratto da USB_touch screen, 19/5/03, TESTARE!! banksel BD0IBC ; select bank 3 movlw 0x00 movwf BD0IBC ; set the byte count field to zero movlw 0xc8 movwf BD0IST ; Set the OWNs bit return end