; This module services the real time interrupt ; It is also responsible for the "real world" buttons and lights ; ; CHANGE SINCE THE BOOK TEXT WAS FINALIZED: Idle_Time is used by the Operating System ; to override the report times defined in the Endpoint Descriptor. A device driver ; will modify Idle_Time to change the reporting characteristics of a HID device. ; During initialization the OS sets Idle_Time = 0 which turns reporting OFF unless ; a change is detected; an application that starts to poll a HID device will appear ; to hang. While it is possible to write extra PCHost application code to re-enable ; Idle_Time is it simpler to defeat this mechanism by IGNORRING the Idle_Time value. ; ; Get a Real Time interrupt every One millisecond (using SOF interrupt) ; ; HID devices work on a 4 millisecond timer ; We have one task ; a) Strobe the LEDs (only one is ever really on, saves power) ServiceTimerRoutine: DJNZ Msec_counter, Done ; Only need to check every 4msec MOV Msec_counter, #4 ; Reinitialize ; ; LED task ; Light the next LED in sequence MOV A, LEDStrobe ; Get the current enabling pattern RL A MOV LEDStrobe, A ; Save for next time ANL A, LEDValue ; Get the LED image CALL WriteLEDs ; Update the real world ; ; Create an Input Report from the Buttons value ; This will be continually overwritten while the PCHost is not polling for data CALL ReadButtons JMP CreateInputReport ; RETurn via CreateInputReport ; Talk to the "real world" buttons and lights ReadButtons: MOV DPTR, #PortB_Pins MOVX A, @DPTR ANL A, #0F0H ; Get upper nibble MOV Temp, A INC DPTR ; Point to PortC_Pins MOVX A, @DPTR ANL A, #0FH ; Get lower nibble ORL A, Temp ; Merge both halves together RET WriteLEDs: CPL A ; 0 = LED on MOV DPTR, #PortA_Out MOVX @DPTR, A Done: RET