; 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