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

📄 serial.asm

📁 usb serial converter
💻 ASM
📖 第 1 页 / 共 4 页
字号:
;****************************************************************
; FILE: SERIAL.ASM
;****************************************************************

;************************************************************    
; FUNCTION: Reset_Serial
;************************************************************    
; The Reset_Serial function clears all of the serial data
; variables and the output report.
;************************************************************    

Reset_Serial:
    mov     A, 00h                          ;
    mov     X, (SIZEOF_VARIABLE_BLOCK - 1)  ;

.Clear_Variable_Loop:

    mov     [X + bit_rate], A               ;
    dec     X                               ;
    jnz     .Clear_Variable_Loop            ;

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

Clear_Output_Report:

    mov     X, (SIZEOF_OUTPUT_REPORT - 1)   ;

.Clear_Output_Report_Loop:

    mov     [X + output_report], A          ;
    dec     X                               ;
    jnc     .Clear_Output_Report_Loop       ;

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

Clear_Input_Report:

    mov     X, (SIZEOF_INPUT_REPORT - 1)    ;

.Clear_Input_Report_Loop:

    mov     [X + input_report], A           ;
    dec     X                               ;
    jnc     .Clear_Input_Report_Loop        ;

    ret                                     ;

;************************************************************
; Setup_Serial
;************************************************************
;
; This function uses the information provided in the config
; data report to configure the serial communications. The
; config report consists of five bytes of data. The first 
; four bytes [0..3] specify the baud rate. We will use this
; information to determine a "bit rate". The formula for
; determining the bit rate is:
;
;            115200
; bit rate = ------ - 1
;             baud 
;                  
; The fifth byte contains the control settings. These settings
; are mapped as follows:
;
; Bit 7: Reset
; Bit 6: Not used
; Bit 5: Parity type (1 = Odd, 0 = Even)
; Bit 4: Parity on (1 = On, 0 = Off)
; Bit 3: Stop bits (0 = 1 stop bit, 1 = 2 stop bits)
; Bits 2-0: Bit Count - 5 (0 = 5 bits - 3 = 8 bits)
;
;************************************************************

Setup_Serial:
    mov     A, [config]                     ; Reset?
    and     A, RESET                        ;
    jz      Set_Baud                        ; No

    call    Reset_Serial                    ; Yes

    jmp     Setup_Serial_Done               ; 

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

Set_Baud:

    call    Set_Baud_Rate                   ;
    
;------------------------------------------------------------

Set_Data_Bit_Count:
    
    ; The data bit count field of the config
    ; defines the number of data bits. The number 
    ; in this field is actually an offset from 5 
    ; bits (i.e., If the value is 0, the number of 
    ; data bits is 0 + 5 = 5. If the value is 3, 
    ; the number of data bits is 3 + 5 = 8.)

    mov     A, [config]                     ; data_bit_count = data_bits + 5
    and     A, BIT_COUNT                    ;
    add     A, 05h                          ;
    mov     [data_bit_count], A             ;

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

    ; Check parity enable.
    
Check_Parity_On:
    mov     A, [config]                     ; If no parity, continue
    and     A, PARITY_ON                    ;
    jnz     Set_Parity_On                   ;

    ; If parity is off, set parity_on to FALSE,
    ; bypass the check of parity type and continue
    ; with stop bit settings.
    
Set_Parity_Off:    
    mov     A, FALSE                        ;
    mov     [parity_on], A                  ;

    jmp     Check_Stop_Bits                 ;
    
Set_Parity_On:    
    mov     A, TRUE                         ;
    mov     [parity_on], A                  ;

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

    ; Since parity is on, determine whether 
    ; parity is odd or even and set parity_type
    ; appropriately.
    
Check_Parity_Type:
    mov     A, [config]                     ; if parity type = 1, even parity
    and     A, PARITY_TYPE                  ;
    jnz     Set_Odd_Parity                  ;

Set_Even_Parity:
    mov     A, EVEN_PARITY                  ; parity_type = even
    mov     [parity_type], A                ;

    jmp     Check_Stop_Bits                 ;
    
Set_Odd_Parity:
    mov     A, ODD_PARITY                   ;
    mov     [parity_type], A                ;

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

Check_Stop_Bits:
    mov     A, [config]                     ;
    and     A, STOP_BITS                    ;
    jnz     Two_Stop_Bits                   ;

One_Stop_Bit:
    mov     A, 01h                          ;
    mov     [stop_bit_count], A             ;

    jmp     Setup_Done                      ;
            
Two_Stop_Bits:
    mov     A, 02h                          ;
    mov     [stop_bit_count], A             ;
        
;------------------------------------------------------------

Setup_Done:
    mov     A, FALSE                        ; Clear setup_serial
    mov     [setup_serial], A               ;
    
    mov     A, TRUE                         ; Set serial_configured
    mov     [serial_configured], A          ;

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

    mov     A, [output_port_shadow]         ; Drive TXD high
    or      A, TXD                          ;
    mov     [output_port_shadow], A         ;
    iowr    OUTPUT_PORT                     ;
    
IFDEF 64013

    mov     A, ((P3_CFG_MSK & CMOS_NONE) | (P2_CFG_MSK & CMOS_NONE) | (P1_CFG_MSK & CMOS_NONE) | (P0_CFG_MSK & RES_NEG))
    iowr    GPIO_CFG                        ; 

;   mov     A, FFh                          ; Set P2_DATA to do nothing
;   iowr    P2_DATA                         ;

    mov     A, 00h                          ; Clear P3_DATA
    iowr    P3_DATA                         ;

ENDIF

IFDEF 63743

    ; Set INPUT_PORT to Hi-Z input mode.
    
    mov     A, 00h                          ; Set P0 to input
    iowr    P0_MODE_0                       ;
    iowr    P0_MODE_1                       ;
        
    ; Set OUTPUT_PORT to hi-current output mode.
    
    mov     A, FFh                          ; Set P1 to output high current
    iowr    P1_MODE_0                       ; 
    iowr    P1_MODE_1                       ; 

    ; Set INPUT_PORT interrupt polarity to
    ; negative edge.
    
    mov     A, 00h                          ; 
    iowr    P0_IP                           ;

ENDIF

    mov     A, RXD                          ; Enable RXD interrupt
    iowr    P0_IE                           ;

    mov     A, (GPIO_INT_EN | USB_RST_INT_EN) ; 
    iowr    IE                              ; 

    mov     A, [output_port_shadow]         ; Assert RTS and DTR
    and     A, ~(RTS | DTR)                 ;
    mov     [output_port_shadow], A         ;
    iowr    OUTPUT_PORT                     ;
    
;------------------------------------------------------------

    mov     A, ACK_IN                       ; EP1_MODE = ACK_IN
    iowr    EP1_MODE                        ;

    mov     A, ACK_OUT                      ; EP2_MODE = ACK_OUT
    iowr    EP2_MODE                        ;

Setup_Serial_Done:
    ret                                     ;

;************************************************************
; baud_rate_table
;************************************************************
; The baud_rate_table consists of a number of conversion
; entries. Each entry contains a baud rate value and a bit
; rate value. Note that the baud rate value is simply the
; second byte of a three-byte value. For instance, 115200 
; decimal is 1C200 in hex. The resulting constant defined 
; for BAUD_115200 is C2h.
;************************************************************

XPAGEOFF
baud_rate_table:
    db      BAUD_115200, ((115200 / 115200) - 1)    ;
    db      BAUD_57600,  ((115200 / 57600) - 1)     ;
    db      BAUD_38400,  ((115200 / 38400) - 1)     ;
    db      BAUD_19200,  ((115200 / 19200) - 1)     ;
baud_rate_default:    
    db      BAUD_9600,   ((115200 / 9600) - 1)      ;
    db      BAUD_4800,   ((115200 / 4800) - 1)      ;
    db      BAUD_2400,   ((115200 / 2400) - 1)      ;    
    db      BAUD_1200,   ((115200 / 1200) - 1)      ;
    db      BAUD_600,    ((115200 / 600) - 1)       ;
baud_rate_table_end:
XPAGEON 

SIZEOF_BAUD_TBL:    equ     (baud_rate_table_end - baud_rate_table)
DEFAULT_BAUD_ENTRY: equ     (baud_rate_default - baud_rate_table)

;************************************************************
; Set_Baud_Rate
;************************************************************
; The Set_Baud_Rate function uses the baud_rate_table to
; determine the appropriate bit rate for a given baud rate.
; It searches the baud_rate_table for an entry that contains
; a baud rate value that matches the value stored in 
; baud_rate_byte_1. If it finds a match, it retrieves the bit
; rate value for that baud rate setting and stores that value
; in bit_rate. If no match is found, it retrieves the default
; baud rate setting and sets the bit_rate value appropriately.
;************************************************************

Set_Baud_Rate:
    mov     X, 00h                          ; Tbl pointer
    
.Loop:
    mov     A, X                            ; Get entry
    index   baud_rate_table                 ;
    
    ; If it's the one that we're looking for, go to
    ; Found_It.
    
    cmp     A, [baud_rate_byte_1]           ;
    jz      .Found_It                       ;

    ; Otherwise, increment the pointer to the next 
    ; table entry.
    
    inc     X                               ;
    inc     X                               ;
    
    ; Check to make sure that we haven't reached the 
    ; end of the table. If we haven't, loop and 
    ; continue with the next entry.
    
    mov     A, X                            ;
    cmp     A, SIZEOF_BAUD_TBL              ;
    jnz     .Loop                           ;

    ; Otherwise, if no entry is found, we set a default value. 
    ; 
       
    mov     X, DEFAULT_BAUD_ENTRY           ;

    ; At this point, we've located the baud entry within the
    ; table. We'll load the baud time values for that baud
    ; rate into the baud_time variables.
            
.Found_It:
    inc     X                               ; baud_time_hi = entry.hi
    mov     A, X                            ;
    index   baud_rate_table                 ;
    mov     [bit_rate], A                   ;
    
Set_Baud_Rate_X:
    ret                                     ;
                 
;****************************************************************
; FUNCTION: Tx_Data
;****************************************************************
; Tx_Data handles the transmission of data to the serial
; device.
;****************************************************************

Tx_Data:
    di                                      ; [4]

    mov     A, [output_port_shadow]         ; [5]
    and     A, ~TXD                         ; [4]
IFDEF HW_FLOW_CONTROL
    or      A, RTS                          ; [4]
ENDIF
    mov     [temp], A                       ; [5]

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

Tx_Data_Loop:
    mov     A, [tx_byte_count]              ; [5]
    sub     A, [tx_byte_counter]            ; [6]

⌨️ 快捷键说明

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