📄 serial.asm
字号:
;****************************************************************
; 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 + -