📄 dc550_interrupt.s43
字号:
; Interrupt 4, State E and F (Transmitting bits for start, direction, address,
; command, and repeat; no collision detection is required for collision and
; parity bits)
; This does not check for collision when the txcounter has just changed
int4EF: CMP #PERIOD_HF,interrupt_timerb_period
JNE int4r ; if(timerb_period==PERIOD_HF) //RL
BIT #04,interrupt_txcounter ; if(txcounter%8 >= 4)
JZ int4EF4
ADD_SAMPLE_WINFULL ; add sample to window
CALC_SQUARES ; calculate pythagorean into R4
MOV interrupt_agcthreshold,R5
RLA R5
CMP R5,R4 ;
JL int4r ; if(R4>=interrupt_agcthreshold)
DEC.B interrupt_tx8khzsamples ; else // Possible collision
JNZ int4r ; tx8khzsamples--;
; if(tx8khzsamples==0)
MOV.B #04h,interrupt_txmsgerror ; txmsgerror = 0x04
JMP int4r ; return;
int4EF4: ; else {
ADD_SAMPLE ; add sin/cos samples to the
; window of eight
MOV.B #04h,interrupt_tx8khzsamples
JMP int4r ; tx8khzsamples = 3; }
; Interrupt 4, State D (Acknowledging receipt of bits)
int4D: INC interrupt_rxcounter ; rxcounter++;
CMP #00A4h,interrupt_rxcounter;
JL int4r ; if(rxcounter < 0x00A4) break;
BIT.B #30h,interrupt_rxmsgerror ; else {
JZ int4D2 ; if(rxmsgerror & 0x30) { //RL
AND.B #01h,interrupt_rxmsgerror ; rxmsgerror &= 1;
MOV #0010h,interrupt_rtcounter; rtcounter = 0x10;
MOV #0,interrupt_modemstate ; modemstate = A;
JMP int4r ; break; }
int4D2: BIT #0004h,interrupt_rxbuffer ; // Reverse logic again below
JNZ int4D4 ; else if(!(rxbuffer & 4)) {
MOV.B #0,interrupt_rxmsgerror ; rxmsgerror = 0;
MOV interrupt_rxbuffer,interrupt_rxmessage
MOV.B #1,interrupt_rxready ; rxmessage=rxbuffer; rxready=1;
MOV #0010h,interrupt_rtcounter; rtcounter = 0x10;
MOV #0,interrupt_modemstate ; modemstate = A;
JMP int4r ; break;
int4D4: BIT.B #01h,interrupt_rxmsgerror ;
JZ int4D6 ; else if(rxmsgerror & 0x01) { //RL
MOV.B #0,interrupt_rxmsgerror ; rxmsgerror = 0;
MOV interrupt_rxbuffer,interrupt_rxmessage
MOV.B #1,interrupt_rxready ; rxmessage=rxbuffer; rxready=1;
MOV #0010h,interrupt_rtcounter; rtcounter = 0x10;
MOV #0,interrupt_modemstate ; modemstate = A;
JMP int4r ; break;
int4D6: MOV.B #0,interrupt_rxmsgerror ; else { rxmsgerror = 0;
MOV #0010h,interrupt_rtcounter; rtcounter = 0x10;
MOV #0,interrupt_modemstate ; modemstate = A;
JMP int4r ; break; }}
;******************************************************************************
; Interrupt 4 runs the modem receive code
INTERRUPT_STATE_4
ADD interrupt_modemstate,pc
JMP int4A
JMP int4B
JMP int4C
JMP int4D
JMP int4EF
JMP int4EF
JMP int4r ; The receive side does nothing in
JMP int4r ; states G and H
JMP int4I
JMP int4r ; States J and K have been made
JMP int4r ; obsolete
JMP int4r ; The receive side does nothing in L
;******************************************************************************
;******************************************************************************
int4r: ; 34 KHz receive code
MOV &ADC12MEM0,cosine_sum
; Return to State 1
MOV #2,&interrupt_state
RETI
;******************************************************************************
; Interrupt 4, State C (Receiving bits)
int4C: INC interrupt_rxcounter ; rxcounter++;
CMP #007Ah,interrupt_rxcounter; //Reverse logic below
JL int4C8 ; if( 16ms have elapsed ) {
;;
;; ALL DATA BITS RECEIVED
;;
MOV #0,numWinSamples ; clear window variables
MOV #0,winIdx
MOV #0,sin_win_sum
MOV #0,cosin_win_sum
;;
;; CHECK PARITY
;;
BIT.B #01h,interrupt_rxparity ; // Check rxparity
; if( !LSB(rxparity) )
JZ int4C4 ; rxmsgerror = 0x11; (int4C4)
;;
;; CHECK ADDRESS
;;
MOV interrupt_rxbuffer,R4 ; // This is telephone code
AND #7800h,R4 ; if((rxbuffer & 0x7800)!= 0x4000)
CMP #4000h,R4 ; rxmsgerror = 0x20; (int4C6)
JNE int4C5 ; break;
;;
;; CHECK COLLISION
;;
BIT #0002h,interrupt_rxbuffer ; else if((rxbuffer & 0x0002)== 0)
; rxmsgerror = 0x20; (int4C6)
JZ int4C6 ; break;
MOV #PERIOD_8K,interrupt_timerb_period
MOV #6,interrupt_modemstate ; interrupt_modemstate = D;
JMP int4r ; doublebreak; }
int4C4: MOV.B #11h,interrupt_rxmsgerror ; (see above, check rxparity code)
INC parityErrors ; parityErrors++;
JMP int4C7
int4C5: MOV.B #20h,interrupt_rxmsgerror ; (see above, address)
INC addressErrors ; addressErrors++;
JMP int4C7
int4C6: MOV.B #20h,interrupt_rxmsgerror ; (see above, collision)
INC collisionsOnTx ; collisionsOnTx++;
int4C7: MOV #PERIOD_HF,interrupt_timerb_period
MOV #6,interrupt_modemstate ; interrupt_modemstate = D;
JMP int4r ; doublebreakbreak; }}
;;
;; STILL RECEIVING DATA BITS
;;
int4C8: ; else ( //16ms have not elapsed
ADD_SAMPLE_WINFULL ; add sample to window
BIT #7,interrupt_rxcounter ; if( rxcounter%8 == 0) //RL
JNZ int4r ; return;
CALC_SQUARES ; calculate pythagorean into R4
RLA interrupt_rxbuffer ; rxbuffer is ready for next bit
CMP interrupt_agcthreshold,R4 ;
JL int4r ; if( R4 < agcthreshold ) break;
BIS #0001h,interrupt_rxbuffer ; else {interrupt_rxbuffer|=0x01;
XOR.B #01h,interrupt_rxparity ; interrupt_rxparity ^= 0x01;
JMP int4r ; break; }}}
; Interrupt 4, State B (Verifying a detected carrier)
int4B: CMP #0,interrupt_rtcounter
JEQ int4B1
DEC interrupt_rtcounter
int4B1: ADD_SAMPLE_WINFULL ; add sample to window
INC interrupt_rxcounter ; rxcounter++;
CMP #08h,interrupt_rxcounter ; if(rxcounter < 8) { //RL
JGE int4B8
CALC_SQUARES ; R4 = pythagorean
CMP interrupt_agcthreshold,R4 ; if(R4 < agcthreshold)
JGE int4B4
CMP #0,interrupt_rxcounter ; if(rxcounter >= 0) {
JN int4B2
MOV.B #20h,interrupt_rxmsgerror ; // This is effectively an
; // address error
MOV #PERIOD_HF,interrupt_timerb_period
MOV #6,interrupt_modemstate ; modemstate = D;
JMP int4r ; return; }
int4B2: MOV #0,interrupt_modemstate ; else { modemstate = A;
JMP int4r ; return; }
int4B4: CMP interrupt_pythagmax,R4 ; else // (R4 >= agcthreshold)
JL int4B6 ; if(R4 >= pythagmax)
MOV R4,interrupt_pythagmax ; pythagmax = R4
int4B6: CMP #07,interrupt_rxcounter ; if(rxcounter >= 7) {
JL int4r
MOV interrupt_pythagmax,R4 ; R4 = pythagmax
RRA R4 ; R4>>2;
RRA R4
CMP interrupt_agcthreshold,R4 ; if(R4 >= agcthreshold) {
JL int4B7
MOV R4,interrupt_agcthreshold ; agcthreshold = R4;
JMP int4r ; return; }
int4B7: INC interrupt_rxcounter ; else rxcounter++;
; // This goes through to 4B8
; else { // (rxcounter >= 8)
int4B8: MOV #4,interrupt_modemstate ; interrupt_modemstate = C;
MOV #3,interrupt_rxbuffer ; rxbuffer = 0x03;
MOV.B #0,interrupt_rxparity ; rxparity = 0x00;
JMP int4r ; return; }
; Interrupt 4, State A (Hunting for carrier)
int4A: CMP #0,interrupt_rtcounter
JEQ int4A1
DEC interrupt_rtcounter
int4A1: CMP #4,&numWinSamples ; must have a full window before
JL int4A2 ; we'll try to detect carrier
ADD_SAMPLE_WINFULL ; add sample to window
CALC_SQUARES ; calculate pythagorean into R4
CMP interrupt_agcthreshold,R4; if( R4 < interrupt_agcthreshold) break;
JL int4r
MOV #2,interrupt_modemstate ; else { interrupt_modemstate = B;
MOV #-3,interrupt_rxcounter ; rxcounter = -3;
MOV R4,interrupt_pythagmax ; pythagmax = R4;
JMP int4r ; break; }
int4A2: ADD_SAMPLE ; add sin/cos samples to the
; window of eight
JMP int4r ; return;
;******************************************************************************
;* INTERRUPT VECTORS
;******************************************************************************
COMMON INTVEC
DS 12
DW interrupt_timer_handler
;******************************************************************************
;* STATIC VARIABLES
;******************************************************************************
RSEG UDATA0
interrupt_counter:
DS 2
interrupt_state:
DS 2
interrupt_rxmessage:
DS 2
interrupt_txmessage:
DS 2
interrupt_rxready:
DS 1
interrupt_txready:
DS 1
interrupt_timerb_period:
DS 2
interrupt_modemstate:
DS 2
interrupt_rxcounter:
DS 2
interrupt_rxbuffer:
DS 2
interrupt_txcounter:
DS 2
interrupt_txbuffer:
DS 2
interrupt_rxparity:
DS 1
interrupt_rxmsgerror:
DS 1
interrupt_txparityak:
DS 1
interrupt_txmsgerror:
DS 1
interrupt_tx8khzsamples:
DS 1
interrupt_rtcounter:
DS 2
interrupt_tvcounter:
DS 2
led_switch:
DS 2
numWinSamples:
DS 2
winIdx:
DS 2
sin_win_sum:
DS 2
cosin_win_sum:
DS 2
sin_val_0:
DS 2
sin_val_1:
DS 2
sin_val_2:
DS 2
sin_val_3:
DS 2
cosin_val_0:
DS 2
cosin_val_1:
DS 2
cosin_val_2:
DS 2
cosin_val_3:
DS 2
parityErrors:
DS 2
addressErrors:
DS 2
collisionsOnTx:
DS 2
interrupt_agcthreshold:
DS 2
interrupt_buzzercounter:
DS 2
interrupt_pythagmax:
DS 2
END
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -