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

📄 usb_to_serial.asm

📁 usb serial converter
💻 ASM
📖 第 1 页 / 共 5 页
字号:
    pop     A                               ;
    reti                                    ;

;****************************************************************
; ISR: Ep1_Isr
;****************************************************************
;  The EndPoint1 interrupt is used to handle IN transfers 
;  when data is to be passed to the host from the device
;****************************************************************

Ep1_Isr:
    push    A

    di                                      ; Enable Interrupts for RX.

    ; If ACKD is not set, ignore this interrupt.
    
    iord    EP1_MODE                        ; 
    and     A, ACKD                         ; 
    jz      Ep1_Isr_Done                    ; 
    
;----------------------------------------------------------------

    mov     A, NAK_IN                       ; Clear ACKD
    iowr    EP1_MODE                        ;

    iord    EP1_COUNT                       ; Toggle Data toggle
    xor     A, DATA_TOGGLE                  ;
    iowr    EP1_COUNT                       ;

    mov     A, TRUE                         ; load_ep1 = TRUE
    mov     [load_ep1], A                   ;

;----------------------------------------------------------------

Ep1_Isr_Done:
    pop     A                               ;
    reti                                    ;

;****************************************************************
; ISR: Ep2_Isr
;****************************************************************
;  The Endpoint 2 Interrupt Service Routine (Ep2_Isr) is used to 
; handle OUT transfers when data is to be passed from host to 
; device.
;****************************************************************

Ep2_Isr:
    push    A                               ;

    ei                                      ;

    ; If last packet wasn't ACK'd, exit.
    
    iord    EP2_MODE                        ;
    and     A, ACKD                         ;
    jz      Ep2_Isr_Done                    ;

;----------------------------------------------------------------

Ep2_Isr_Process:

    mov     A, NAK_OUT                      ; Clear ACKD
    iowr    EP2_MODE                        ;
    
    mov     A, [output_count]               ;
    and     A, OUTPUT_COUNT                 ;
    mov     [tx_byte_count], A              ;

;----------------------------------------------------------------

    ; If serial port has not been configured,
    ; ignore tx_byte_count, DTR and RTS 
    ; controls.
    
    mov     A, [serial_configured]          ;
    and     A, TRUE                         ;
    jz      Enable_Ack                      ;

;----------------------------------------------------------------

    ; Update DTR based on request from host.
    
Control_Dtr:
    mov     A, [output_report + 0]          ;
    and     A, OUTPUT_DTR                   ;
    jz      Control_Dtr_Low                 ;
    
    mov     A, ~DTR                         ;
    and     [output_port_shadow], A         ;

    jmp     Control_Rts                     ;
    
Control_Dtr_Low:
    mov     A, DTR                          ;
    or      [output_port_shadow], A         ;

;----------------------------------------------------------------

    ; Update RTS based on request from host.
    
Control_Rts:
    mov     A, [output_report + 0]          ;
    and     A, OUTPUT_RTS                   ;
    jz      Control_Rts_Low                 ;
    
    mov     A, ~RTS                         ;
    and     [output_port_shadow], A         ;

    mov     A, ((~RTS) & RTS)               ;
    jmp     Write_Output                    ;
        
Control_Rts_Low:
    mov     A, RTS                          ;
    or      [output_port_shadow], A         ;

    mov     A, RTS                          ;

Write_Output:
    mov     [rts_shadow], A                 ;

    mov     A, [output_port_shadow]         ;
    iowr    OUTPUT_PORT                     ;

;----------------------------------------------------------------

    ; If tx_byte_count is not 0, set tx_pending.
    
    mov     A, [tx_byte_count]              ;
    cmp     A, 00h                          ;
    jz      Enable_Ack                      ;

    mov     A, TRUE                         ;
    mov     [tx_pending], A                 ;
    
    jmp     Ep2_Isr_Done                    ;

;----------------------------------------------------------------

    ; If tx_pending is FALSE, set EP2_MODE 
    ; to ACK_OUT.
    
Enable_Ack:
    mov     A, [tx_pending]                 ;
    cmp     A, TRUE                         ;
    jz      Ep2_Isr_Done                    ;
    
    mov     A, ACK_OUT                      ;
    iowr    EP2_MODE                        ;
    
;----------------------------------------------------------------

    ; Restore environment and exit ISR.
    
Ep2_Isr_Done:
    pop A                                   ;
    reti                                    ;

;****************************************************************
; FUNCTION: Main
;****************************************************************
; The Main routine handles serial communication with the device.  
; It times all recieves and transmit and calls on all the proper 
; subroutines to handle certain events.
;****************************************************************

Main:

IFDEF 0

    ; DEBUG: Load control report with 9600 baud 8/N/1
    mov     A, 00h                          ;
    mov     [control_report + 0], A         ;
    mov     A, C2h                          ;
    mov     [control_report + 1], A         ;
    mov     A, 00h                          ;
    mov     [control_report + 2], A         ;
    mov     A, 00h                          ;
    mov     [control_report + 3], A         ;
    mov     A, 03h                          ;
    mov     [control_report + 4], A         ;

    mov     A, 00h                          ;
    mov     [output_report + 0], A          ;
    mov     A, 0Ah                          ;
    mov     [output_report + 1], A          ;
    mov     A, 30h                          ;
    mov     [output_report + 2], A          ;
    mov     A, 31h                          ;
    mov     [output_report + 3], A          ;
    mov     A, 32h                          ;
    mov     [output_report + 4], A          ;
    mov     A, 33h                          ;
    mov     [output_report + 5], A          ;
    mov     A, 34h                          ;
    mov     [output_report + 6], A          ;
    mov     A, 35h                          ;
    mov     [output_report + 7], A          ;
    mov     A, 36h                          ;
    mov     [output_report + 8], A          ;
    mov     A, 37h                          ;
    mov     [output_report + 9], A          ;
    mov     A, 38h                          ;
    mov     [output_report + 10], A         ;
    mov     A, 39h                          ;
    mov     [output_report + 11], A         ;

    call    Setup_Serial                    ;
    call    Ep2_Isr_Process                 ;
    
    mov     A, TRUE                         ;
    mov     [tx_pending], A                 ;

ENDIF
        
;----------------------------------------------------------------

Main_Loop:
    mov     A, [load_ep1]                   ; If load_ep1 flag,
    cmp     A, TRUE                         ;
    jnz     Check_Setup_Flag                ;

    call    Load_Ep1_Fifo                   ; Load_Ep1

;----------------------------------------------------------------

Check_Setup_Flag:
    mov     A, [setup_serial]               ; If setup_serial flag,
    cmp     A, TRUE                         ;
    jnz     Check_Tx_Pending                ;

    call    Setup_Serial                    ; Setup_Serial

;----------------------------------------------------------------

Check_Tx_Pending:    
    mov     A, [tx_pending]                 ; If tx_pending flag, 
    cmp     A, TRUE                         ; 
    jnz     Idle                            ; 

    call    Tx_Data                         ; Tx_Data

;----------------------------------------------------------------

Idle:
    iowr    WDT                             ;

    jmp     Main_Loop                       ;

INCLUDE "SERIAL.ASM"
        
;****************************************************************
; ISR: Ep0_Isr
;****************************************************************
; The EndPoint0 interrupt is used for control transfers.
; The enumeration process will take place here.
;****************************************************************

Ep0_Isr:
    push    A                               ;

    iord    EP0_MODE                        ; Save the EP0 mode register
    mov     [ep0_mode_shadow], A            ;

    and     A, ACKD                         ;
    jz      Ep0_Isr_Done                    ;

;----------------------------------------------------------------

.start:
    mov     A, [ep0_mode_shadow]            ; If a setup was received 
    and     A, SETUP_RXD                    ;
    jz      .out                            ;

    call    Ep0_Setup                       ; handle it

    jmp     .exit                           ; and exit

;----------------------------------------------------------------

.out:
    mov     A, [ep0_mode_shadow]            ; If an OUT was received
    and     A, OUT_RXD                      ;
    jz      .in                             ;

    call    Ep0_Out                         ; handle it

    jmp     .exit                           ; and exit

;----------------------------------------------------------------

.in:
    mov     A, [ep0_mode_shadow]            ; If an IN was received
    and     A, IN_RXD                       ; 
    jz      .exit                           ;

    call    Ep0_In                          ; handle it

;----------------------------------------------------------------

    ; As long as there is no setup pending, 
    ; write the next mode.

.exit:
    iord    EP0_MODE                        ; 
    and     A, SETUP_RXD                    ; 
    jnz     Ep0_Isr_Done                    ; 
                                            ; 

    mov     A, [ep0_next_mode]              ; 
    iowr    EP0_MODE                        ; 

;----------------------------------------------------------------

Ep0_Isr_Done:                               ; 
    pop     A                               ;
    reti                                    ;

;****************************************************************
; Ep0_Setup handles the case when the packet is a setup packet. 
; It checks whether the data valid bit is set, that the count is 
; 10, and that the data toggle is 0
;****************************************************************

Ep0_Setup:
    mov     A, NAK_IN_OUT                   ;
    iowr    EP0_MODE                        ;
    
    iord    EP0_COUNT                       ;
    and     A, DATA_VALID                   ; is the data valid bit set
    jz      Stall_In_Out                    ; if not then stall

    iord    EP0_COUNT                       ;
    and     A, CNT_MSK                      ;
    cmp     A, 0Ah                          ; is the count 10
    jnz     Stall_In_Out                    ; if not then stall

    iord    EP0_COUNT                       ;
    and     A, DATA_TOGGLE                  ; is the data toggle bit 0
    jnz     Stall_In_Out                    ; if not then stall
    
    call    Stage_One                       ; process the setup packet

    ret                                     ;

;****************************************************************
; Ep0_Out handles an out transaction.  This occurs in the data 
; stage of a control write or in the status phase of a control 
; read.
;****************************************************************

Ep0_Out:
    mov     A, [ep0_next_mode]              ;
    and     A, MODE                         ;
    cmp     A, ACK_OUT_STATUS_IN            ;
    jnz     Stall_In_Out                    ;

;   mov     A, [ep0_mode_shadow]            ;
;   and     A, MODE                         ;
;   cmp     A, NAK_OUT_STATUS_IN            ;
;   jnz     Stall_In_Out                    ;

    mov     A, TRUE                         ;
    mov     [setup_serial], A               ;

    mov     X, SIZEOF_CONTROL_REPORT        ;

Fill_Config_Buffer:                         ;
    mov     A, [X + (ep0_fifo -1)]          ;
    mov     [X + (control_report - 1)], A   ;
    dec     X                               ;

⌨️ 快捷键说明

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