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

📄 serial.asm

📁 usb serial converter
💻 ASM
📖 第 1 页 / 共 4 页
字号:
    
;----------------------------------------------------------------

    ; Shift data byte right 1 bit. (Carry 
    ; was cleared by previous "jnz" instruction.)
    mov     A, [X + rx_buffer]              ; [6]
    rrc     A                               ; [4]  
    mov     [X + rx_buffer], A              ; [6]  

    ; If parity is off, we're done.
    mov     A, [parity_on]                  ; [5]
    cmp     A, TRUE                         ; [5]
    jnz     Increment_Buffer_In             ; [5/4]
    
    ; Kill 17 cycles (104 - 87 = 17).
    8_CYCLE_DELAY                           ; [8]
    7_CYCLE_DELAY                           ; [7]

    BIT_DELAY                               ; [14 + (bit_rate * 104)]
    
    jmp     Rx_Parity_Bit                   ; [5]

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

Rx_D7_Bit_Next:
    ; Shift data byte right one bit.
    CLR_C                                   ; [4]
    mov     A, [X + rx_buffer]              ; [6]
    rrc     A                               ; [4]  
    mov     [X + rx_buffer], A              ; [6]  

    ; Kill 31 cycles (104 - 73 = 31).
    call    26_Cycle_Delay                  ; [26]
    5_CYCLE_DELAY                           ; [5]

    BIT_DELAY                               ; [14 + (bit_rate * 104)]
    
;****************************************************************

Rx_D7_Bit:

    ; Read RXD and update parity.
    iord    INPUT_PORT                      ; [5] 
    xor     [parity], A                     ; [7] 

    ; Add new bit to byte.
    and     A, RXD                          ; [4] 
    or      [X + rx_buffer], A              ; [8]  

    ; If parity is off, we're done.
    mov     A, [parity_on]                  ; [5]
    cmp     A, TRUE                         ; [5]
    jnz     Increment_Buffer_In             ; [5/4]
    
;----------------------------------------------------------------

    ; Kill 52 cycles (104 - 52 = 52).
    call    46_Cycle_Delay                  ; [46]
    6_CYCLE_DELAY                           ; [6]
    
    BIT_DELAY                               ; [14 + (bit_rate * 104)]
    
;****************************************************************

Rx_Parity_Bit:

    ; Update parity and leave in A.
    iord    INPUT_PORT                      ; [5] 
    xor     A, [parity]                     ; [6] 

    ; Check parity
    and     A, RXD                          ; [4] 
    jz      Increment_Buffer_In             ; [5/4]

    ; There was a parity error. Save the buffer 
    ; address in the error_location variable. 

    mov     A, [rx_buffer_in]               ; [5]
    or      A, ERROR_FLAG                   ; [4]
    mov     [error_location], A             ; [5]

IFDEF HW_FLOW_CONTROL

    mov     A, RTS                          ; [4]
    or      [output_port_shadow], A         ; [7]
    
ENDIF

;****************************************************************

Increment_Buffer_In: 

    ; Increment the rx_buffer_in pointer.

    inc     [rx_buffer_in]                  ; [7]
    mov     A, (SIZEOF_RX_BUFFER - 1)       ; [4]
    and     [rx_buffer_in], A               ; [7]

IFDEF HW_FLOW_CONTROL

    ; If the amount of available buffer space is 
    ; less than the RTS_LAG value, release RTS.

    mov     A, [rx_buffer_out]              ; [5]
    sub     A, [rx_buffer_in]               ; [6]
    sub     A, (RTS_LAG + 1)                ; [4]
    and     A, (SIZEOF_RX_BUFFER - 1)       ; [4]
    jnz     Update_Rts                      ; [5/4]  

    mov     A, RTS                          ; [4]
    or      [output_port_shadow], A         ; [7]

Update_Rts:
    mov     A, [output_port_shadow]         ; [5]
    iowr    OUTPUT_PORT                     ; [5]

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

Wait_For_Stop:
   
    ; Wait for the RXD high which either means that 
    ; we're still in the parity bit and the parity
    ; bit is high or we're in the stop bit.

    iord    INPUT_PORT                      ; [5]
    and     A, RXD                          ; [4]
    jz      Wait_For_Stop                   ; [5/4]
    
    ; Re-enable RXD interrupt.

    mov     A, RXD                          ; [4]
    iowr    P0_IE                           ; [5]

Rx_Data_Done:
    pop     X                               ; [4]
    pop     A                               ; [4]
    reti                                    ; [8]

;************************************************************
; FUNCTION: Load_Ep1_Fifo
;************************************************************
; The Ep1 FIFO is currently empty. If there is data available
; in the rx_buffer, copy the minimum of either the amount of
; available data or the amount of data that will fill a 
; report to ep1_fifo. In any case, create a new report 
; header to send in to the host.
;************************************************************

Load_Ep1_Fifo:
    push    A                               ;
    push    X                               ;
    
    mov     A, 00h                          ;
    mov     [temp], A                       ;
    mov     [byte_counter], A               ;

    ; Pre-clear the input report status and 
    ; count bytes.
    
    mov     [input_status], A               ;
    mov     [input_count], A                ;
        
    call    Clear_Input_Report              ;
    
;------------------------------------------------------------

.Load_Buffer:

    ; If the buffer is empty, stop loading 
    ; the FIFO and go prepare the report 
    ; header.

    mov     A, [rx_buffer_out]              ; Is buffer empty?
    cmp     A, [rx_buffer_in]               ;
    jz      .Exit_Load                      ; Yes

    ; If the current buffer location is an 
    ; error location, stop loading the FIFO
    ; and set the error flag in the input 
    ; report.

    or      A, ERROR_FLAG                   ;
    cmp     A, [error_location]             ;
    jz      .Set_Error_Flag                 ;
    
    ; Copy byte from rx_buffer into input_data.
    
    mov     X, [rx_buffer_out]              ; 
    mov     A, [X + rx_buffer]              ; 

    mov     X, [byte_counter]               ; 
    mov     [X + (input_data)], A           ; 

    ; Increment rx_buffer_out.
    
    mov     A, [rx_buffer_out]              ;
    inc     A                               ;
    and     A, (SIZEOF_RX_BUFFER-1)         ;
    mov     [rx_buffer_out], A              ;

    ; Increment byte_counter.
    
    inc     [byte_counter]                  ;
    
    ; If the FIFO is not full, loop to Load_Buffer 
    ; and continue to load the FIFO.
    
    mov     A, [byte_counter]               ; FIFO full?
    cmp     A, (SIZEOF_INPUT_REPORT - SIZEOF_INPUT_HEADER)    ;
    jnz     .Load_Buffer                    ; no

    ; The FIFO is full. Jump to prepare the 
    ; header for the report.
    
    jmp     .Exit_Load                      ; yes

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

.Set_Error_Flag:

    ; Load temp with INPUT_ERROR_FLAG.
    
    mov     A, INPUT_ERROR                  ;
    mov     [temp], A                       ;

    ; Increment rx_buffer_out.
    
    mov     A, [rx_buffer_out]              ;
    inc     A                               ;
    and     A, (SIZEOF_RX_BUFFER-1)         ;
    mov     [rx_buffer_out], A              ;

    ; Clear error_location.
    
    mov     A, 00h                          ;
    mov     [error_location], A             ;
        
;------------------------------------------------------------

.Exit_Load:    

    ; Read the current state of the input bits
    ; (RI, CD, DSR, and CTS) located at P0.4 - 
    ; P0.1 and shift them into the upper nibble. 
    ; Invert the state of these bits. Clear the
    ; lower nibble and load the error flag into 
    ; the lower nibble. Finally, put the resulting
    ; value into byte 0 of the ep1_fifo, which is
    ; the header location for the input report.

    iord    INPUT_PORT                      ; Read P0
    asl                                     ; Shift left 3 bits
    asl                                     ;
    asl                                     ;
    xor     A, FFh                          ; Invert value
    and     A, F0h                          ; Clear lower nibble
    or      A, [temp]                       ; Or in error flag
    mov     [input_status], A               ; Load in byte 0
    
    ; Get the number of data bytes loaded into 
    ; the ep1_fifo (not including the two header 
    ; bytes) and load that value into byte 1 of 
    ; the ep1_fifo. 

    mov     A, [byte_counter]               ;
    or      [input_count], A                ;
    
    ; Now that the ep_fifo is loaded, clear 
    ; the load_ep1 flag.
    
    mov     A, FALSE                        ;
    mov     [load_ep1], A                   ;
        
    ; Enable the new report to be transmitted
    ; from the endpoint at the next available
    ; opportunity.
    
    mov     A, ACK_IN                       ; EP1 MODE = ACK_IN
    iowr    EP1_MODE                        ;

    ; If buffer is empty, enable RXD interrupt.
    
    mov     A, [rx_buffer_in]               ; Is buffer empty?
    cmp     A, [rx_buffer_out]              ;
    jnz     .Do_Not_Reenable                ; No

    mov     A, RXD                          ;
    iowr    P0_IE                           ;

IFDEF HW_FLOW_CONTROL

    ; Assert RTS low unless host has requested
    ; that RTS be deasserted high.

    mov     A, [output_port_shadow]         ;
    and     A, ~RTS                         ;
    or      A, [rts_shadow]                 ;
    mov     [output_port_shadow], A         ;
    iowr    OUTPUT_PORT                     ;

ENDIF

.Do_Not_Reenable:
    pop     X                               ;
    pop     A                               ;

Load_Ep1_Fifo_X:
    ret                                     ;

;************************************************************
; FUNCTION: nn_Cycle_Delay
;************************************************************

50_Cycle_Delay:                               
    nop                                     ; [4]

46_Cycle_Delay:                               
    nop                                     ; [4]

42_Cycle_Delay:                               
    nop                                     ; [4]

38_Cycle_Delay:                               
    nop                                     ; [4]

34_Cycle_Delay:                              
    nop                                     ; [4]

30_Cycle_Delay:                              
    nop                                     ; [4]

26_Cycle_Delay:                               
    nop                                     ; [4]

22_Cycle_Delay:                               
    nop                                     ; [4]

18_Cycle_Delay:                               
    ret                                     ; [8]



    


⌨️ 快捷键说明

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