1620Main.A51
; This module initializes the microcontroller then executes MAIN forever
;
        CSEG
Reset:
	MOV	SP, #235		; Initialize the Stack
	MOV	PageReg, #7FH		; Allows MOVX Ri to access EZ-USB memory

	MOV	R0, #Low(USBControl)	; Simulate a disconnect
	MOVX	A, @R0
	ANL	A, #11110011b		; Clear DISCON, DISCOE
	MOVX	@R0, A
	CALL	Wait100msec   		; Give the host time to react
	MOVX	A, @R0			; Reconnect with this new identity
	ORL	A, #00000110b           ; Set DISCOE to enable pullup resistor
	MOVX	@R0, A	 		; Set RENUM so that 8051 handles USB requests
	CLR	A
	MOV	FLAGS, A		; Start in Default state
InitializeMsecCounter:
	INC	A			; = 1
	MOV	Expired_Time, A
	MOV	Msec_counter, A
InitializeIOSystem:			; Work around the dScope monitor I/O needs
; Setup Port A as 8-bit OUTPUT port (no alternate functions)
; Setup an 8-bit INPUT port using PortB_Bits [7:4] and PortC_Bits[3:0]
; Assume a pre-existing configuration (ie dScope)	
	MOV	R0, #LOW(PortA_Config)	; PageReg = 7F = HIGH(PortA_Config)
	CLR	A
	MOVX	@R0, A			; No alternate functions
	MOV	R1, #LOW(PortA_OE)
	CPL	A			; = 0FFH
	MOVX	@R1, A			; Enable PortA for Output
	INC	R0			; Point to PortB_Config
	INC	R1			; Point to PortB_OE
	MOVX	A, @R0			; Get current configuration
	ANL	A, #0FH
	MOVX	@R0, A			; No alternate functions on upper nibble
	MOVX	A, @R1			; Get current configuration
	ORL	A, #0F0H
	MOVX	@R1, A			; Enable PortB_Bits[7:4] for Output
	INC	R0			; Point to PortC_Config
	INC	R1			; Point to PortC_OE
	MOVX	A, @R0			; Get current configuration
	ANL	A, #0F0H
	MOVX	@R0, A			; No alternate functions on lower nibble
	MOVX	A, @R1			; Get current configuration
	ORL	A, #0FH
	MOVX	@R1, A			; Enable PortC_Bits[3:0] for Output
InitializeThermometers:
	MOV	R0, #Low(PortA_Out)     ; Do all six at the same time
	MOV	A, #00000100b		; Select pattern
ILoop:	MOV	R6, A
	MOV	A, #00000001b		; Port A idle state
	ORL	A, R6
	MOVX	@R0, A			; Select one of the thermometers
	MOV	R5, #0CH		; Configure command
	CALL	SendByte
	MOV	R5, #00001010b		; Set CPU mode and continuous conversion
	CALL	SendByte
	MOV	R2, A			; Save A
	MOV	A, #00000001b		; Port A idle state
	MOVX	@R0, A
	MOV	Temp, #20
	CALL	Wait1msec		; Wait for write to complete
	MOV	A, R2			; Restore A
	MOV	R5, #0EEH		; Start temperature conversion command
	CALL	SendByte
	XCH	A, R6
	CLR	C			; Need to zero fill
	RLC	A
	JNZ	ILoop

InitializeInterruptSystem:		; First initialize the USB level 
	CLR	A
	MOV	R0, #LOW(IN07IEN)
	MOVX	@R0, A			; Disable interrupts from IN Endpoints 0-7
	INC	R0
	MOVX	@R0, A			; Disable interrupts from OUT Endpoints 0-7
	INC	R0
	MOV	A, #00000011b
	MOVX	@R0, A			; Enable (Resume, Suspend,) SOF and SUDAV INTs
	INC	R0
	MOV	A, #00000001b
	MOVX	@R0, A			; Enable Auto Vectoring for USB interrupts
	                                ; Now enable the main level
	MOV	EIE, #00000001b		; Enable INT2 = USB Interrupt (only) 		
        MOV	EI, #11000000b		; Enable interrupt subsystem (and Ser1 for dScope)
 
; Initialization Complete.
; 
MAIN:
	NOP				; Not much of a main loop for this example
	JMP	MAIN			; All actions are initiated by interrupts
; We are a slave, we wait to be told what to do

Wait100msec:
	MOV	Temp, #100
Wait1msec:				; A delay loop
	MOV	DPTR, #-1200		
More:	INC	DPTR			; 3 cycles
	MOV	A, DPL                  ; + 2
	ORL	A, DPH                  ; + 2
	JNZ	More                    ; + 3 = 10 cycles x 1200 = 1msec
	DJNZ	Temp, Wait1msec
	RET

ProcessOutputReport:		  	; A Report has just been received
; The report is 12 bytes long in this example
; It contains a new limits values
	MOV	DPTR, #EP0OutBuffer	; Point to the Report
	MOV	R0, #LimitValues
	MOV	R7, #12
CopyOR:	MOVX	A, @DPTR		; Get the Data
	MOV	@R0, A			; Update the local variable
	INC	DPTR
	INC	R0
	DJNZ	R7, CopyOR
	RET

CreateInputReport:			; Called from TIMER which detected the need
; The report is seven bytes long in this example
; It contains the temperature readings
	MOV	DPTR, #IN1ByteCount
	MOV	A, #7
	MOVX	@DPTR, A		; Endpoint 1 now 'armed', next IN will get data
	RET