⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 main1.asm

📁 Holteck HT82M9XX的USB Mouse的Firmware汇编代码
💻 ASM
字号:
;-----------------------------------------------------------------------------------
; Filename : MAIN1.ASM
;-----------------------------------------------------------------------------------
include                 ht82k96e.inc
include                 usbrf.inc
include                 usbFIFO.inc

extern                  bFLAG_HvRpt     :bit
extern                  btime_out_KB    :bit
extern                  baddr_state     :bit
extern                  bcfgvalue       :bit
extern                  breseume_s      :bit
extern                  bRmtWakeup      :bit


;for MOUSE
scanin                  equ             pa

extern                  F_MouseChange   : bit

extern  InitializeMouseSensor           : near
extern  GetMouseDeltaXY                 : near
extern  WheelCheck                      : near
extern  ButtonCheck                     : near
extern  tempA                           : byte
extern  tempB                           : byte

extern  MouseSuspend                    : near

extern  Ram_init                        :near

extern  config_USB                      :near
extern  start_timer                     :near
extern  ReportKBTime                    :byte
extern  TempKBTime                      :byte
extern  TempKBTime_L                    :byte
extern  temp1                           :byte
extern  temp2                           :byte
extern  F_ButtonChange          : bit           ; (03-11-2004)
extern  DeltaXCounter           : byte          ; (03-11-2004)
extern  DeltaYCounter           : byte          ; (03-11-2004)
extern  DeltaZCounter           : byte          ; (03-11-2004)

main            .section         'code'
;------------------------------------------------------------------------------
;       main program here
;------------------------------------------------------------------------------
main_start:
        mov     a,status                        ;
        and     a,00110000b                     ;
        xor     a,00110000b                     ; 检查是否由WDT所wakeup
        sz      z                               ;
        jmp     watch_wake                      ; 从WDT timeout起来

        clr     wdt                             ;
        mov     a,00000111b                     ;
        mov     WDTS,a                          ;

        call    Ram_init                        ;
        call    config_USB                      ; 选择系统频率,USB mode,内部ADC参考电压,清除所有的pipe interrupt

        clr     USR.4                           ; 关掉PS2 mode
        set     USR.5                           ; 选择USB mode
        mov     a,00000011b                     ; 打开USB INT
        mov     intc,a                          ;

        call    InitializeMouseSensor           ; Initialize mouse sensor

        snz     chk_usb_reset_event             ; 检查chk_usb_reset_event(URST=USC.2)
        jmp     $-1

USBInterfaceDetected:
        set     baddr_state                     ; USB in address state

        mov     a,00000011b                     ; Turn on global INT
        mov     intc,a                          ; Turn on USB INT
;------------------------------------------------------------------------------------------------
USBMainLoop:
        clr     wdt                             ;
        sz      suspend_line                    ; 检查suspend_line是否为HIGH
        jmp     Tosuspend                       ; 若suspend_line=HIGH,则Tosuspend
;------------------------------------------------------------------------------------------------
maintag:
        SZ      bCfgValue                       ; Has configured?(是否执行过SetConfiguration命令)
        JMP     maintag_cnt                     ; Yes
        JMP     USBMainLoop                     ; No
maintag_cnt:
        ;----------------------------------------------------------------------
        ; Remark : Button和Wheel(Z轴)状态要随时检查,MouseDeltaXY则是等data传回
        ;          给Host之後才检查
        ;----------------------------------------------------------------------
        call    ButtonCheck                     ; 检查Button状态
        call    WheelCheck                      ; 检查滚轮状态(Z轴)

        sz      F_MouseChange                   ; 检查F_MouseChange是否为0
        jmp     NeedReportCheck                 ; 若F_MouseChange=1,则跳到NeedReportCheck

        call    GetMouseDeltaXY                 ; 检查Mouse的X,Y轴

        call    DetermineMouseChange            ; (03-17-2004)根据最新的Mouse状态来决定F_MouseChange是否为1

;------------------------------------------------------------------------------------------------
NeedReportCheck:
        ;Whether has device been configured ?
        ;Yes: May report data ?
        SZ      bCfgValue                       ; USB是否configured?(在STD1.ASM的SetConfiguration中)
        JMP     HasConfigured                   ; Yes
        JMP     USBMainLoop                     ; No

HasConfigured:
;In Normal State
        SZ      bFLAG_HvRpt                     ; 是否已经report Host第一次
        JMP     Check_Mouse_KB_state            ; 若是bFLAG_HvRpt=1,则Check_Mouse_KB_state

        ;Report all data immediately anyway!! 无论如何一定要将Mouse的状态传给Host
        call    start_timer                     ; 打开TMR0 INT和USB INT,并起动TMR0每80uSec timeout一次
        set     F_MouseChange                   ; 把F_MouseChange=1,表示即将要把目前FIFO buffer中的内容送出去
        clr     tempkbtime_L                    ; 将timer counter设为0
        clr     tempkbtime                      ;
        SET     bFLAG_HvRpt                     ; 把bFLAG_HvRpt=1,表示report Host第一次已完成(has reported)

        ;reset key changed flag
        jmp     USBMainLoop                     ;
;-----------------------------------------------------------------------------------
Check_Mouse_KB_State:
        SZ      ReportKBTime                    ; 检查ReportKBTime是否为0(SetIdle command之後,Host会指定ReportKBTime的值)
        jmp     check_TIME_OUT_KB               ; 若ReportKBTime不为0,则check_time_out_KB
        JMP     USBMainLoop                     ; 若ReportKBTime=0,则直接跳回USBMainLoop (Has Idle time)
;-----------------------------------------------------------------------------------
check_time_out_KB:      
        SZ      btime_out_KB                    ; 检查btime_out_KB是否为0(只有计算Idle rate到达後,才会将btime_out_KB设为1)
        set     F_MouseChange                   ; 若btime_out_KB=1,则设定F_MouseChange=1(应该要送出一笔mouse状态了)
        JMP     USBMainLoop                     ;
;-----------------------------------------------------------------------------------
ToSuspend:
        clr     timer0_on                       ; 关掉TMR0
        clr     timer1_on                       ; 关掉TMR1
        call    MouseSuspend                    ; 进入suspend之前,使device的I/O不耗电

        ;----------------------------------------------------------------------
        ; Remark : 连续检查suspend_line=1,持续一段时间(将近3秒),若suspend_line
        ;          在这期间LOW下来了,则Exit_of_suspend
        ;----------------------------------------------------------------------
wait_about_3s:
;about wait_3s for 6MHz crystal
        mov     a,16                            ;
        mov     temp2,a                         ; temp2=10H
        set     temp1                           ; temp1=FFH
        set     acc                             ; ACC=FFH
wait_3s:
        snz     suspend_line                    ; 检查suspend_line=HIGH持续3 Sec
        jmp     exit_of_suspend                 ; 若suspend_line=LOW,则exit_of_suspend
        sdz     acc                             ;
        jmp     wait_3s                         ;
        sdz     temp1                           ;
        jmp     wait_3s                         ;
        sdz     temp2                           ;
        jmp     wait_3s
                                
;------------------------------------------------------------------------------------------
#define mouse_event_mask 01111100B
ToSuspend_again:                                ; 确定要进入suspend状态
        clr     on_usb_clk                      ; 关掉USB clock
        ;set     regulator_off                   ; 关掉V33O regulator(但必须在LVR disable时才能关掉,
                                                 ; 否则可能会引起LowVoltageReset,若能关掉,则suspend电流可以从390uA降到230uA)
        clr     regulator_off                   ; 永远打开V33O regulator(SUSP2 bit),suspend电流390uA仍低於500uA规格
        nop                                     ;
        halt                                    ; 进入suspend状态

        ;----------------------------------------------------------------------------------
        ; Remark : 从HALT wakeup起来後,要检查是suspend_line LOW下来,还是按键的wakeup.WDT RESET
        ;          後也是跳到这里
        ;----------------------------------------------------------------------------------
watch_wake:
        mov     A, PA                           ;
        mov     tempA, A                        ; tempA=PA状态
        mov     A, 03                           ;
        mov     tempB, A                        ; tempB=03H
DebounceWatchWakeLoop:
        set     ACC                             ;
        clr     wdt                             ;
        snz     suspend_line                    ; 检查suspend_line维持HIGH
        jmp     exit_of_resume_mode             ; 若检查到suspend_line为LOW,则exit_of_resume_mode
        sdz     ACC                             ;
        jmp     $-4                             ;

        mov     A, PA                           ; 读取PA按键状态
        xor     A, tempA                        ; Debounce PA按键状态
        snz     Z                               ;
        jmp     watch_wake                      ;

        sdz     tempB                           ;
        jmp     DebounceWatchWakeLoop           ;

;check I/O wakeup
        mov     a, scanin                       ; scanin=PA
        xor     a, mouse_event_mask             ; mouse_event_mask=01111100B
        sz      z                               ; 检查是否有按键按下
        jmp     wait_reseume_out                ; 若没有任何按键按下
;------------------------------------------------------------------------------------------
RemoteWakeup:
;output wakeup pulse
        snz     bRmtWakeup                      ; 检查USB device是否Enable RemoteWakeup能力
        jmp     ToSuspend_again                 ; 若bRmtWakeup=0,则再度回到suspend

        set     on_usb_clk                      ; 打开USB clock
        clr     regulator_off                   ; 打开V33O regulator

        set     wakeup_line                     ; USC.RMWK=1
        nop                                     ;
        nop                                     ;
        nop                                     ; Delay 2uSec来确保SIE收到RemoteWakeup command
        nop                                     ; uC会通知USB Host离开suspend mode
        nop                                     ;
        nop                                     ;
        clr     wakeup_line                     ; USC.RMWK=0
        set     breseume_s                      ; 设定breseume_s=1(强迫必须要停留在wait_reseume_out回圈)
;------------------------------------------------------------------------------------------
wait_reseume_out:
        clr     wdt                             ;
        sz      breseume_s                      ; 等待breseume_s被设为0(下一次USB_INT的check_access_FIFO会将breseume_s=0)
        jmp     wait_reseume_out                ;

exit_of_resume_mode:
        snz     suspend_line                    ; 检查suspend_line是否为1
        jmp     exit_of_suspend                 ; 若suspend_line=0,则重新initialize mouse
        jmp     ToSuspend_again                 ; 若suspend_line=1,则再进入suspend

;------------------------------------------------------------------------------------------
; Remark : 从suspend mode中Wakeup起来後要做什麽
;------------------------------------------------------------------------------------------
exit_of_suspend:
        CLR     bFLAG_HvRpt                     ; 将bFLAG_HvRpt重设为0
        call    InitializeMouseSensor           ; Initialize mouse sensor
        jmp     USBMainLoop                     ;

;------------------------------------------------------------------------------
; Function : DetermineMouseChange
; Remark   : 根据最新的DeltaXCounter,DeltaYCounter,DeltaZCounter,F_ButtonChange
;            来决定F_MouseChange是否为1
;------------------------------------------------------------------------------
DetermineMouseChange:
        sz      DeltaXCounter                   ; (03-11-2004)判断X轴状态是否有改变
        set     F_MouseChange                   ; (03-11-2004)若有则把F_MouseChange设为1

        sz      DeltaYCounter                   ; (03-11-2004)判断Y轴状态是否有改变
        set     F_MouseChange                   ; (03-11-2004)若有则把F_MouseChange设为1

        sz      F_ButtonChange                  ; (03-11-2004)判断Button状态是否有改变
        set     F_MouseChange                   ; (03-11-2004)若有则把F_MouseChange设为1
        
        sz      DeltaZCounter                   ; (03-10-2004)判断Z轴状态是否有改变
        set     F_MouseChange                   ; (03-10-2004)若有则把F_MouseChange设为1
ExitDetermineMouseChange:
        ret
;----------------------------------------------------------------------------------------------
public          main_start
public          DetermineMouseChange
                                                
END

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -