📄 usbsm.lst
字号:
0035 ;========================================================================
0035 ; program listing
0035 ;========================================================================
0035
0035
0035 ;========================================================================
0035 ; The 128 uSec interrupt is not used by the keyboard code. The keyboard
0035 ; only does not require the DAC or GPIO port in this version of
0035 ; firmware. It may be necessary to enable GPIO interrupts when the
0035 ; keyboard enters a power down suspend mode.
0035 DoNothing_ISR:
0035 73 [08] reti ; return from interrupt
0036
0036 ;========================================================================
0036 ; Suspend
0036 ;
0036 ; This routine is invoked from the main loop when bus activity has ceased for
0036 ; 3 msec or more. This routine prepares the keyboard for suspension, suspends
0036 ; the part, and restores the keyboard upon a subsequent resume.
0036 ;========================================================================
0036 ; Suspend
0036 ;
0036 ; This routine is invoked from the main loop when bus activity has ceased for
0036 ; 3 msec or more. This routine prepares the keyboard for suspension, suspends
0036 ; the part, and restores the keyboard upon a subsequent resume.
0036
0036 Suspend:
0036
0036 2D [05] push A
0037 ; (since all pins are guaranteed to not float)
0037
0037 54 E3 [10] call mouse_suspend ; put PS/2 mouse in stream mode
0039 70 [08] di ; disable interrupts
003A 19 FF [04] mov A, RESISTIVE_NEG ; all ports resistive neg so that
003C 2A 08 [05] iowr GPIO_Config ; we stay within suspend current budget (500uA)
003E 19 00 [04] mov A, 0 ; pull down the column lines
0040 2A 00 [05] iowr Port0_Data
0042 2A 01 [05] iowr Port1_Data
0044 1A 88 [06] mov A, [ksc_p3out]
0046 0D 07 [04] or A, P3_LED_MASK ; turn LEDs off
0048 10 3F [04] and A, ~P3_KEY_MASK ; don't touch bit 6 & 7 (PS/2 mouse interface)
004A 2A 03 [05] iowr Port3_Data
004C 19 FF [04] mov A, FFh
004E 2A 06 [05] iowr Port2_Interrupt ; enable port 2 GPIO interrupt for keyboard
0050 19 20 [04] mov A, GPIO_ONLY_MASK ; enable GPIO interrupt only
0052 2A 20 [05] iowr Global_Interrupt
0054 1A 22 [06] mov A, [remote_wakeup_status] ; is remote wakeup feature enabled?
0056 16 02 [04] cmp A, ENABLE_REMOTE_WAKEUP
0058 B0 5B [05] jnz Suspend_controller
005A 72 [08] ei
005B Suspend_controller:
005B
005B 29 FF [05] iord Status_Control ; set the suspend bit causing suspend
005D 0D 08 [04] or A, 08h
005F 2A FF [05] iowr Status_Control ; we are suspended here
0061
0061 ; resume !!!!!!
0061 20 [04] nop ; execute a nop after resuming
0062
0062 70 [08] di
0063 2A 26 [05] iowr Watchdog
0065 29 1F [05] iord USB_Status_Control ; check if there is no bus activity
0067 10 08 [04] and A, 08h
0069 16 00 [04] cmp A, 00h
006B B0 9D [05] jnz GPIO_disable_interrupts ; if there is bus activity,
006D ; disable interrupts and exit
006D
006D
006D 19 04 [04] mov A, TIMER_ONLY_MASK ; enable 1ms interrupt
006F 2A 20 [05] iowr Global_Interrupt
0071 72 [08] ei
0072 1A 2F [06] mov A, [1ms_counter] ; clear wakeup counter
0074 01 05 [04] add A,5
0076
0076 wakeup_delay: ; wait 5ms before we send the wakeup signal
0076 2A 26 [05] iowr Watchdog
0078 17 2F [06] cmp A, [1ms_counter]
007A B0 76 [05] jnz wakeup_delay
007C
007C 70 [08] di ; disable interrupts
007D
007D 29 1F [05] iord USB_Status_Control ; check again if there is no bus activity
007F 10 08 [04] and A, 08h ; after 5ms
0081 16 00 [04] cmp A, 00h
0083 B0 9D [05] jnz GPIO_disable_interrupts ; if there is bus activity,
0085 ; disable interrupts and exit
0085
0085
0085 19 02 [04] mov A, FORCE_J ; force J state to correct cross-over voltage
0087 2A 1F [05] iowr USB_Status_Control ; problem during resume signalling
0089
0089 19 01 [04] mov A, FORCE_K ; start sending resume signal
008B 2A 1F [05] iowr USB_Status_Control
008D
008D 72 [08] ei ; enable 1ms interrupt again
008E 1A 2F [06] mov A, [1ms_counter] ; clear wakeup counter
0090 01 0A [04] add A,0ah
0092
0092 wakeup_duration: ; send resume signal for 10ms
0092 2A 26 [05] iowr Watchdog
0094 17 2F [06] cmp A, [1ms_counter]
0096 B0 92 [05] jnz wakeup_duration
0098
0098 70 [08] di ; disable interrupts
0099
0099 19 00 [04] mov A, NOT_FORCING ; let SIE control D+/D-
009B 2A 1F [05] iowr USB_Status_Control
009D
009D
009D GPIO_disable_interrupts: ;
009D ;interrupts are off when we get here
009D 29 1F [05] iord USB_Status_Control
009F 10 F7 [04] and A, F7h ; clear Bus Activity bit
00A1 2A 1F [05] iowr USB_Status_Control
00A3
00A3 19 00 [04] mov A, 0
00A5 2A 06 [05] iowr Port2_Interrupt ; disable GPIO interrupt for keyboard
00A7
00A7 19 25 [04] mov A, GPIO_TIMER_RESET_MASK ; enable GPIO and 1ms interrupts
00A9 2A 20 [05] iowr Global_Interrupt
00AB
00AB
00AB 72 [08] ei
00AC 54 F8 [10] call mouse_resume ; put PS/2 mouse into polling mode
00AE 70 [08] di
00AF Skip_suspend:
00AF 19 F5 [04] mov A, NORMAL ; restore original GPIO configuration
00B1 2A 08 [05] iowr GPIO_Config
00B3 19 00 [04] mov A,0
00B5 31 34 [05] mov [suspend_counter],A
00B7 53 9E [10] call ksc_restore_ports ; restore column ports to pre-suspend values
00B9 72 [08] ei
00BA 2B [04] pop A
00BB 3F [08] ret
00BC
00BC
00BC
00BC check_activity:
00BC
00BC 29 1F [05] iord USB_Status_Control ; check if there is bus activity
00BE 10 08 [04] and A, 08h
00C0 3F [08] ret
00C1
00C1 ;========================================================================
00C1 ; The 1 msec interrupt is used to clear the watchdog timer, to maintain
00C1 ; all timers with a 1msec granularity
00C1 ;========================================================================
00C1
00C1 One_mSec_ISR:
00C1 23 2F [07] inc [1ms_counter] ;increment 1msec timer
00C3 1A 2F [06] mov A,[1ms_counter]
00C5 10 03 [04] and A,3
00C7
00C7 B0 CF [05] jnz check_bus_activity_status ;every 4 msec, do the following:
00C9
00C9 1A 38 [06] mov A,[background_flags] ; set the flag to scan the keyboard
00CB 0D 02 [04] or A,SCAN_FLAG
00CD 31 38 [05] mov [background_flags],A
00CF
00CF check_bus_activity_status:
00CF 29 1F [05] iord USB_Status_Control ; check if there is no bus activity
00D1 10 08 [04] and A, 08h
00D3 16 00 [04] cmp A,0h
00D5 A0 E3 [05] jz Inc_counter ; if there was bus activity
00D7 29 1F [05] iord USB_Status_Control ; clear the bus activity bit
00D9 10 F7 [04] and A, 0F7h
00DB 2A 1F [05] iowr USB_Status_Control
00DD 19 00 [04] mov A, 0h ; clear the suspend counter
00DF 31 34 [05] mov [suspend_counter], A ;
00E1 80 F1 [05] jmp Exit_1ms
00E3
00E3 Inc_counter: ;there was no bus activity,
00E3 23 34 [07] inc [suspend_counter] ;so increment the bus activity counter
00E5 1A 34 [06] mov A,[suspend_counter]
00E7 16 03 [04] cmp A, 03h ;if 3msecs of bus inactivity passed
00E9 C0 F1 [05] jc Exit_1ms
00EB 1A 38 [06] mov A,[background_flags] ; set the suspend flag
00ED 0D 01 [04] or A,SUSPEND_FLAG
00EF 31 38 [05] mov [background_flags],A ;
00F1
00F1
00F1 Exit_1ms:
00F1 56 E6 [10] call mouse_1mS_int ; call the mouse 1msec ISR code.
00F3 2B [04] pop A
00F4 73 [08] reti ; return from interrupt
00F5 ;========================================================================
00F5 ; Endpoint one is used to send keyboard data to the host. This interrupt
00F5 ; occurs if the USB serial interface engine has transferred a packet
00F5 ; to the host (including NAKs).
00F5 ;
00F5 ; This routine disables another transfer until valid data has been loaded
00F5 ; into the endpoint. This routine is also responsible for toggling the
00F5 ; data 0/1 bit for endpoint one after every successful transfer.
00F5 USB_EP1_ISR:
00F5 2D [05] push A ; save accumulator on stack
00F6 29 14 [05] iord EP_A1_Mode ; test whether we have an ACK bit
00F8 10 10 [04] and A, ACK_BIT
00FA A1 08 [05] jz doneEP1 ; do nothing if we don't have an ACK bit
00FC
00FC 19 0C [04] mov A, NAKIN ; clear ACK bit
00FE 20 [04] NOP
00FF 1F [04] XPAGE
0100 2A 14 [05] iowr EP_A1_Mode
0102
0102 29 13 [05] iord EP_A1_Counter ; flip data 0/1 bit after
0104 13 80 [04] xor A, DATATOGGLE ; a successful data transfer
0106 2A 13 [05] iowr EP_A1_Counter
0108
0108
0108 doneEP1:
0108 2B [04] pop A ; restore accumulator from stack
0109 73 [08] reti ; return from interrupt
010A
010A ;========================================================================
010A ; Endpoint two is used to consumer/power key data to the host. This interrupt
010A ; occurs if the USB serial interface engine has transferred a packet
010A ; to the host (including NAKs).
010A ;
010A ; This routine disables another transfer until valid data has been loaded
010A ; into the endpoint. This routine is also responsible for toggling the
010A ; data 0/1 bit for endpoint one after every successful transfer.
010A USB_EP2_ISR:
010A 2D [05] push A ; save accumulator on stack
010B 29 16 [05] iord EP_A2_Mode ; test whether we have an ACK bit
010D 10 10 [04] and A, ACK_BIT
010F A1 1B [05] jz doneEP2 ; do nothing if we don't have an ACK bit
0111
0111 19 0C [04] mov A, NAKIN ; clear ACK bit
0113 2A 16 [05] iowr EP_A2_Mode
0115
0115 29 15 [05] iord EP_A2_Counter ; flip data 0/1 bit after
0117 13 80 [04] xor A, DATATOGGLE ; a successful data transfer
0119 2A 15 [05] iowr EP_A2_Counter
0
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -