📄 serial.asm
字号:
mov A, [stop_bit_count] ; [5]
sub A, 02h ; [4]
jz Tx_Stop_0_Stop_1_Next ; [5/4]
;----------------------------------------------------------------
Tx_Stop_0_Done:
; Kill 4 cycles (104 - 100 = 4).
4_CYCLE_DELAY ; [4]
BIT_DELAY ; [14 + (bit_rate * 104)]
jmp Tx_Data_Loop ; [5] -> [63]
;----------------------------------------------------------------
Tx_Stop_0_Stop_1_Next:
; Kill 61 cycles (104 - 43 = 61).
call 30_Cycle_Delay ; [30]
call 26_Cycle_Delay ; [26]
5_CYCLE_DELAY ; [5]
;----------------------------------------------------------------
Tx_Stop_1_Next:
BIT_DELAY ; [14 + (bit_rate * 104)]
mov A, TXD ; [4]
or A, [temp] ; [6]
;***************************************************************
Tx_Stop_1:
iowr OUTPUT_PORT ; [5]
; Kill 17 cycles (104 - 87 = 17).
6_CYCLE_DELAY ; [6]
6_CYCLE_DELAY ; [6]
5_CYCLE_DELAY ; [5]
BIT_DELAY ; [14 + (bit_rate * 104)]
jmp Tx_Data_Loop ; [5] -> [63]
;***************************************************************
Tx_Data_Done:
mov A, 00h ;
mov [tx_byte_counter], A ;
mov A, FALSE ;
mov [tx_pending], A ;
; 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 ;
mov A, ACK_OUT ; EP2_MODE = ACK_OUT
iowr EP2_MODE ;
Tx_Data_Exit:
ei ;
ret ;
;****************************************************************
; ISR: Rx_Data
;****************************************************************
;
; The Rx_Data ISR has some interesting timing requirements.
; These requirements are discussed below:
;
; First of all, there should be a multiple of 52 cycles from
; the falling edge of RXD through the iord statement located at
; Rx_Start_Bit. As currently implemented, there are (50 - 54)
; plus a multiple of 52 cycles.
;
; Second, there should be a multiple of 104 cycles between
; subsequent samplings of RXD by means of the iord instruction.
;
; Last, there should be a minimum of time spent post-processing
; the operation so as to guarantee an ability to detect the
; next RXD interrupt. Theoretically, at 115K baud, the maximum
; available time from sampling of either the last data bit or the
; parity bit until completion of the last stop bit is 1.5 bit
; times (or 156 cycles). As currently implemented, the Rx_Data
; ISR should complete in less than 125 cycles.
;
;****************************************************************
Gpio_Isr:
Rx_Data: ; [16-20]
push A ; [5]
push X ; [5]
; HALF_BIT_DELAY ; [14 + (bit_rate * 52)]
; 5_CYCLE_DELAY ; [5]
EIGHTH_BIT_DELAY
;****************************************************************
Rx_Start_Bit:
; Read RXD and exit if high.
iord INPUT_PORT ; [5]
and A, RXD ; [4]
jnz Rx_Data_Done ; [5/4]
; Disable RXD interrupt
mov A, 00h ; [4]
iowr P0_IE ; [5]
; Initialize X with rx_buffer pointer.
mov X, [rx_buffer_in] ; [5]
; Clear current data location.
mov A, 00h ; [4]
mov [X + rx_buffer], A ; [6]
; Initialize parity.
mov A, [parity_type] ; [5]
mov [parity], A ; [5]
; Kill 43 cycles (104 - 61 = 43).
call 38_Cycle_Delay ; [38]
5_CYCLE_DELAY ; [5]
BIT_DELAY ; [14 + (bit_rate * 104)]
;****************************************************************
Rx_D0_Bit:
; Read RXD and update parity.
iord INPUT_PORT ; [5]
xor [parity], A ; [7]
; Add new bit to byte and shift data
; byte right one bit.
and A, RXD ; [4]
or A, [X + rx_buffer] ; [7]
rrc A ; [4]
mov [X + rx_buffer], A ; [6]
; Kill 57 cycles (104 - 47 = 57).
call 50_Cycle_Delay ; [50]
7_CYCLE_DELAY ; [7]
BIT_DELAY ; [14 + (bit_rate * 104)]
;****************************************************************
Rx_D1_Bit:
; Read RXD and update parity.
iord INPUT_PORT ; [5]
xor [parity], A ; [7]
; Add new bit to byte and shift data
; byte right one bit.
and A, RXD ; [4]
or A, [X + rx_buffer] ; [7]
rrc A ; [4]
mov [X + rx_buffer], A ; [6]
; Kill 57 cycles (104 - 47 = 57).
call 50_Cycle_Delay ; [50]
7_CYCLE_DELAY ; [7]
BIT_DELAY ; [14 + (bit_rate * 104)]
;****************************************************************
Rx_D2_Bit:
; Read RXD and update parity.
iord INPUT_PORT ; [5]
xor [parity], A ; [7]
; Add new bit to byte and shift data
; byte right one bit.
and A, RXD ; [4]
or A, [X + rx_buffer] ; [7]
rrc A ; [4]
mov [X + rx_buffer], A ; [6]
; Kill 57 cycles (104 - 47 = 57).
call 50_Cycle_Delay ; [50]
7_CYCLE_DELAY ; [7]
BIT_DELAY ; [14 + (bit_rate * 104)]
;****************************************************************
Rx_D3_Bit:
; Read RXD and update parity.
iord INPUT_PORT ; [5]
xor [parity], A ; [7]
; Add new bit to byte and shift data
; byte right one bit.
and A, RXD ; [4]
or A, [X + rx_buffer] ; [7]
rrc A ; [4]
mov [X + rx_buffer], A ; [6]
; Kill 57 cycles (104 - 47 = 57).
call 50_Cycle_Delay ; [50]
7_CYCLE_DELAY ; [7]
BIT_DELAY ; [14 + (bit_rate * 104)]
;****************************************************************
Rx_D4_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 data_bit_count is not 5, get ready
; to receive bit 5.
mov A, [data_bit_count] ; [5]
cmp A, 05h ; [5]
jnz Rx_D5_Bit_Next ; [5/4]
;----------------------------------------------------------------
; Shift data byte right 3 bits. (Carry
; was cleared by previous "jnz" instruction.)
mov A, [X + rx_buffer] ; [6]
rrc A ; [4]
rrc A ; [4]
rrc A ; [4]
mov [X + rx_buffer], A ; [6]
Check_Parity:
; If parity is off, we're done.
mov A, [parity_on] ; [5]
cmp A, TRUE ; [5]
jnz Increment_Buffer_In ; [5/4]
; Kill 9 cycles (104 - 95 = 9).
5_CYCLE_DELAY ; [5]
4_CYCLE_DELAY ; [4]
BIT_DELAY ; [14 + (bit_rate * 104)]
jmp Rx_Parity_Bit ; [5]
;----------------------------------------------------------------
Rx_D5_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_D5_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 data_bit_count is not 6, get ready
; to receive bit 7.
mov A, [data_bit_count] ; [5]
cmp A, 06h ; [5]
jnz Rx_D6_Bit_Next ; [5/4]
;----------------------------------------------------------------
; Shift data byte right 2 bits. (Carry
; was cleared by previous "jnz" instruction.)
mov A, [X + rx_buffer] ; [6]
rrc A ; [4]
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 13 cycles (104 - 91 = 13).
7_CYCLE_DELAY ; [7]
6_CYCLE_DELAY ; [6]
BIT_DELAY ; [14 + (bit_rate * 104)]
jmp Rx_Parity_Bit ; [5]
;----------------------------------------------------------------
Rx_D6_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_D6_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 data_bit_count is not 7, get ready
; to receive bit 8.
mov A, [data_bit_count] ; [5]
cmp A, 07h ; [5]
jnz Rx_D7_Bit_Next ; [5/4]
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -