;                            Software License Agreement
;
; The software supplied herewith by Microchip Technology Incorporated (the "Company")
; for its PICmicro® 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:		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:			Dan Butler
;    	Company:		Microchip Technology Inc
;
;	Revision:		1.10
;	Date:			07-December-2000
;	Assembled using		MPASM 2.30.07
;
;################################################################################
;
;	include files:
;		P16C745.inc	Rev 1.00
;		usb_defs.inc	Rev 1.00
;
;################################################################################
#include <p16C745.inc>
#include "usb_defs.inc"

	extern	ReportDescriptor
	extern	ReportDescriptorStart
	extern	ReportDescriptorEnd
	extern  HIDDescriptorStart
	extern	HIDDescriptorEnd
	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	copy_string_descriptor_to_EP0
	extern	Send_0Len_pkt

	global	GetClassSpecificDescriptor
	global 	Get_Report_Descriptor

	code
; ******************************************************************
; Get Descriptor
; Handles the three different Get Descriptor commands
; ******************************************************************
;ClassSpecific
;#ifdef FUNCTIONIDS
;	SELECTBANK3
;	movlw	0x03		; save state bits
;	andwf	USWSTAT,f
;	movlw	CLASSSPECIFIC
;	iorwf	USWSTAT,f	; place in upper 6 bits of register
;	SELECTBANK2
;#endif
;	movf	BufferData+wValueHigh,w	; get descriptor type
;	xorlw	0x1
;	xorlw	0x22
;	btfsc	STATUS,Z
;	goto    Get_Report_Descriptor
;
;	movf	BufferData+wValueHigh,w	; get descriptor type
;	xorlw	0x21
;	btfsc	STATUS,Z
;	goto	Get_Idle
;
;	movf	BufferData+wValueHigh,w	; get descriptor type
;	xorlw	0x09
;	btfsc	STATUS,Z
;	goto	Set_Report
;
;	movf	BufferData+wValueHigh,w	; get descriptor type
;	xorlw	0x0A
;	btfsc	STATUS,Z
;	goto	Set_Idle
;	goto	wrongstate
;	goto	GetClassSpecificDescriptor

;Get_Report
;	return

;Get_Idle
;	return

;Set_Report
;	return

;Set_Idle
;	call	Send_0Len_pkt
;	return

GetClassSpecificDescriptor
#ifdef FUNCTIONIDS
	SELECTBANK3
	movlw	0x03		; save state bits
	andwf	USWSTAT,f
	movlw	CLASSSPECIFIC
	iorwf	USWSTAT,f	; place in upper 6 bits of register
	SELECTBANK2
#endif
	global	GetClassSpecificDescriptor
	pagesel	GetClassSpecificDescriptor
	movf	BufferData+(wValue+1),w
	xorlw	0x21
	btfsc	STATUS,Z
	goto	Get_HID_Descriptor
	movf	BufferData+(wValue+1),w
	xorlw	0x22
	btfsc	STATUS,Z
	goto	Get_Report_Descriptor
	movf	BufferData+(wValue+1),w
	xorlw	0x23
	btfsc	STATUS,Z
	goto	Get_Physical_Descriptor
	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.

; ******************************************************************
; Get Report Descriptor
; Returns the Mouse Report descriptor
; ******************************************************************
Get_Report_Descriptor
	pagesel	ReportDescriptorStart
	movlw	GET_DESCRIPTOR
	movwf	USB_dev_req		; currently processing a get descriptor request

	movlw	8
	movwf	EP0_maxLength

	call	ReportDescriptorStart	; get the starting address relative to "Description" in usb_ch9.asm
	movwf	EP0_start		; copy_descriptor_to_EP0 will find the find the physical addr.
	call	ReportDescriptorEnd	; get the length of the descriptor
	movwf	EP0_end

	movf	BufferData+(wLength+1),f	; Is the host requesting more than 255 bytes?
	btfss	STATUS,Z			; If so, the host is requesting more than we have
	goto	nolimit_rpt			; send the whole descriptor

	subwf	BufferData+wLength,w		; if not, compare the amount the host is request
	movf	BufferData+wLength,w		; with the length of the descriptor
	btfss	STATUS,C			; if the host is request less than the descriptor
	movwf	EP0_end				; length, send only as much as what the host what

nolimit_rpt
	pagesel	copy_descriptor_to_EP0		
	call	copy_descriptor_to_EP0
	return

Get_HID_Descriptor
	pagesel	HIDDescriptorStart
	movlw	GET_DESCRIPTOR
	movwf	USB_dev_req		; currently processing a get descriptor request

	movlw	8
	movwf	EP0_maxLength

	call	HIDDescriptorStart
	movwf	EP0_start
	call	HIDDescriptorEnd
	movwf	EP0_end

	movf	BufferData+(wLength+1),f
	btfss	STATUS,Z
	goto	nolimit_hid

	subwf	BufferData+wLength,w
	movf	BufferData+wLength,w
	btfss	STATUS,C
	movwf	EP0_end

nolimit_hid
	movf	EP0_start,w			; yes: limit size to buffer size
	addwf	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
	movf	USB_dev_req,w
	xorlw	GET_DESCRIPTOR
	btfss	STATUS,Z
	goto	Check_Report
	call	copy_string_descriptor_to_EP0
	return

Check_Report
	movf	USB_dev_req,w
	xorlw	GET_DESCRIPTOR
	btfss	STATUS,Z
	goto	$+2
	call	copy_string_descriptor_to_EP0
	return

	end
