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

📄 dc550_interrupt.s43

📁 一款经典的数字电话设计资料
💻 S43
📖 第 1 页 / 共 3 页
字号:
;*****************************************************************************;
;*  CONFIDENTIAL                                                             *;
;*  Sigpro Copyright 2003, All rights reserved                               *;
;*****************************************************************************;
;*  CLIENT:  Telematrix                                                      *;
;*  PROJECT: DC550 Digital Centrex Phone                                     *;
;*  FILE:    dc550_hwinit.s43                                                *;
;*****************************************************************************;
;*  This file contains the interrupt handler routine for Timer A             *;
;*****************************************************************************;
#define __ASSEMBLY__  1
#include "dc550_local.h"
#include "dc550_interrupt.h"

#define TELEPHONE          1


        NAME    dc550_interrupt(16)
        RSEG    CODE

        PUBLIC  interrupt_counter
        PUBLIC  interrupt_state
        PUBLIC  interrupt_rxmessage
        PUBLIC  interrupt_txmessage
        PUBLIC  interrupt_rxready
        PUBLIC  interrupt_txready
        PUBLIC  interrupt_txmsgerror
        PUBLIC  interrupt_init
        PUBLIC  interrupt_timer_handler
        PUBLIC  parityErrors
        PUBLIC  addressErrors
        PUBLIC  collisionsOnTx
        PUBLIC  interrupt_buzzercounter
        
        EXTERN  ledBlinkData
        EXTERN  ledState
        EXTERN  display_usingbus

;******************************************************************************
;*  CENTREX MODEM CONSTANTS
;******************************************************************************
INT_TIME	EQU	192
PERIOD_8K	EQU	383
PERIOD_HF	EQU	23
THRESHOLD       EQU     10h

;******************************************************************************
;*  INTERRUPT LEVEL RESERVED REGISTERS
;******************************************************************************
#define	cosine_sum      R4
#define	sine_sum        R5

;******************************************************************************
;*  FUNCTION: void interrupt_init(void)
;******************************************************************************
;*  DESCRIPTION:
;*  This function initializes the variables for the one interrupt handler.
;******************************************************************************
interrupt_init:
        MOV     #0,&interrupt_counter           ; interrupt_counter = 0
        MOV     #0,&interrupt_state             ; interrupt_state = 0
        MOV     #0,&interrupt_rxmessage         ; interrupt_rxmessage = 0
        MOV.B   #0,&interrupt_rxready           ; interrupt_rxready = 0
        MOV     #0,&interrupt_txmessage         ; interrupt_txmessage = 0
        MOV.B   #0,&interrupt_txready           ; interrupt_txready = 0
        MOV     #0,&interrupt_modemstate        ; interrupt_modemstate  = A
        MOV     #0,&interrupt_rxcounter         ; interrupt_rxcounter = -3
        MOV     #0,&interrupt_rxbuffer          ; interrupt_rxbuffer = 0
        MOV     #0,&interrupt_txcounter         ; interrupt_txcounter = 0
        MOV     #0,&interrupt_txbuffer          ; interrupt_txbuffer = 0
        MOV.B   #0,&interrupt_rxparity          ; interrupt_rxparity = 0
        MOV.B   #0,&interrupt_rxmsgerror        ; interrupt_rxmsgerror = 0
        MOV.B   #0,&interrupt_txparityak        ; interrupt_txparityak = 0
        MOV.B   #0,&interrupt_txmsgerror        ; interrupt_txmsgerror = 0
        MOV.B   #03h,&interrupt_tx8khzsamples   ; interrupt_tx8khzsamples = 4
        MOV     #0010h,&interrupt_rtcounter     ; interrupt_rtcounter = 0x10
        MOV     #0,&interrupt_tvcounter         ; interrupt_tvcounter = 0
        CLR     &numWinSamples                  ; numWinSamples = 0;
        CLR     &winIdx                         ; winIdx = 0;
        CLR     &sin_win_sum                    ; sin_win_sum = 0;
        CLR     &cosin_win_sum                  ; cosin_win_sum = 0;
        CLR     &parityErrors                   ; parityErrors = 0;
        CLR     &addressErrors                  ; addressErrors = 0;
        CLR     &collisionsOnTx                 ; collisionsOnTx = 0;
        MOV     #01h,interrupt_agcthreshold     ; interrupt_agcthreshold = 0x01
        MOV     #0,interrupt_buzzercounter      ; interrupt_buzzercounter = 0
        
        CLR.W   &led_switch                     ; led_switch = 0
        
        RET             


;******************************************************************************
;*  FUNCTION: void interrupt_timer_handler(void)
;******************************************************************************
;*  DESCRIPTION:
;*  This interrupt handler is called once every 31.25 microseconds by Timer A
;*  through the interrupt vector defined below.  The interrupt handler has
;*  five possible states:
;*  0. In State 0, it initializes Timer B (used for the carrier signal for
;*     transmission), switches the State variable to 1, and returns
;*  1. In State 1, it runs the modem transmit code, switches the State
;*     variable to 2, and returns
;*  1. In State 2, it updates the LEDs, switches the State variable to 3, and
;*     returns
;*  3. In State 3, it increments the interrupt_counter (used to track the
;*     passage of time), updates the interrupt_buzzercounter and switches
;*     the buzzer pin if necessary, switches the State variable to 4,
;*     and returns
;*  4. In State 4, it runs the modem receive code, switches the State
;*     variable to 1, and returns
;*  All states are executed perpetually except for State 0, which only runs
;*  once.  The interrupt handler also reads a sample from the ADC in all
;*  states.  Each set of 4 samples can then be evaluated in the modem receive
;*  code to see if they constitute a 1 or a 0.
;* 
;*  The modem, which is run in states 1 and 4, also has multiple states:
;*  A. Hunting for carrier
;*  B. Verifying a detected carrier
;*  C. Receiving bits
;*  D. Acknowledging receipt of bits
;*  E. Transmitting bits for start, direction, address, and command
;*  F. Transmitting repeat bit
;*  G. Transmitting collision bit
;*  H. Transmitting parity bit
;*  I. Receiving acknowledgement
;*  J. <Obsolete>
;*  K. <Obsolete>
;*  L. Vegetating for a fixed amount of time
;*
;*  NOTES:
;*  + Every time State B is entered, rxcounter must be set to -3
;*  + Only B or G and get into A, only A can get into B, only D or F or I can 
;*    get into G, and only E can get into F or I, so D and E MUST set 
;*    timerb_period to PERIOD_HF.
;*  + Since Interrupt 1 reads the first sine sample, it gets R5 for free
;*  + rxmsgerror gets set to 0x20 if the collision bit on the message was set.
;*    The message is then ignored, and rxmsgerror gets set to 0, regardless of
;*    parity or anything else.
;*  + rxmsgerror gets set to 0x11 if the parity was wrong.  The message is then
;*    ignored, and rxmsgerror gets set to 0x01.
;*  + txmsgerror is 0x01 when a PACK is not received.  The message is then
;*    retransmitted with the repeat bit set.
;*  + txmsgerror ix 0x02 when a PACK is not received twice in a row.  In
;*    this case, the message will be dropped.
;*  + txmsgerror is 0x04 when a collision is detected. The message is then
;*    retransmitted, but without the repeat bit set.
;*  + Because of the averaging algorithm, our rxcounter = 0 on the receive
;*    side is currently 250us after the t = 0 described in the NIS spec
;******************************************************************************


;******************************************************************************
;*  INTERRUPT_STATE_0
;******************************************************************************
;*  Interrupt State 0 only executes once; it is used to initialize Timer B in 
;*  syncwith the Timer A interrupt
;******************************************************************************
INTERRUPT_STATE_0
	; Sets up Timer_B for N*32KHz Toggle Rate
	; Since the system does not have a digital to analog converter,
	; Timer_B is used to generate the 8KHz signal for a 1 bit.  A 0 bit
	; uses a 128KHz signal, which is then drowned out using a band pass
	; filter.
	mov	#PERIOD_HF,&interrupt_timerb_period
	mov	#PERIOD_HF,&TBCCR0
	;set outmode 4 for toggle, delayed loard of TBCCR0
	mov	#00280h,&TBCCTL0
#if TDB
	mov	#00214h,&TBCTL  	;start TIMER_B up mode, select SMCLK as input clock
#else
	mov	#00114h,&TBCTL          ;start TIMER_B up mode, select ACLK as input clock
#endif

	
	; 34 KHz receive code
	MOV	&ADC12MEM0,cosine_sum

	; Increment to State 1
        MOV     #2,&interrupt_state     

        RETI


;******************************************************************************
;*  INTERRUPT_STATE_1
;******************************************************************************
;*  Interrupt State 1 runs the modem transmit code.
;******************************************************************************
INTERRUPT_STATE_1

        ; This must happen immediately before Timer B rolls over so that the
        ; interrupt handler and Timer B remain in sync
        MOV     interrupt_timerb_period,&TBCCR0;

        ADD     interrupt_modemstate,pc
        JMP     int1A
        JMP     int1r                     ; The transmit side doesn't really do
        JMP     int1r                     ; anything in states B and C
        JMP     int1D
        JMP     int1E
        JMP     int1F
        JMP     int1G
        JMP     int1H
        JMP     int1I
        JMP     int1r                     ; The transmit side doesn't really do
        JMP     int1r                     ; anything in states J and K
        ;The pc will automatically jump through for State L

; Interrupt 1, State L (Vegetating for a fixed amount of time)
int1L:  DEC     interrupt_tvcounter       ; tvcounter--;
        JNZ     int1r                     ; if(tvcounter) break;
        MOV     #10h,interrupt_rtcounter  ; else { rtcounter = 2ms;
        MOV     #0,interrupt_modemstate   ;   modemstate = A;
        JMP     int1r                     ;   break; }
	
; Interrupt 1, State K (Verifying carrier, transmit disabled)
; The transmit side doesn't really do anything here
; timerb_period should be PERIOD_HF
; int1K:  JMP     int1r

; Interrupt 1, State J (Hunting for carrier, transmit disabled)
; The transmit side doesn't really do anything here
; timerb_period should be PERIOD_HF
; int1J:  JMP     int1r

; Interrupt 1, State I (Receiving acknowledgement)
; timerb_period should be PERIOD_HF
int1I:  INC     interrupt_txcounter;      ; txcounter++;
        CMP     #0098h,interrupt_txcounter
        JL      int1r                     ; if(txcounter < 19ms) break;
        CMP.B   #1,interrupt_txparityak   ; // Reverse logic below
        JL      int1I4                    ; if(txparityak >= 1) {
        MOV.B   #0,interrupt_txready      ;   txready = 0;
        MOV     #10h,interrupt_tvcounter  ;   tvcounter = 2ms;
        MOV.B   #0,interrupt_txmsgerror   ;   txmsgerror = 0;
        MOV     #22,interrupt_modemstate  ;   modemstate = L;
        JMP     int1r                     ;   break; }
                                          ; //There was no ack
int1I4: MOV     #10h,interrupt_tvcounter  ; else { tvcounter=2ms;
        XOR.B   #01h,interrupt_txmsgerror ;   txmsgerror ^= 1;
        JNZ     int1I5                    ;   // if no ack 2x, drop the msg
        MOV.B   #2,interrupt_txmsgerror   ;   if(!txmsgerror) txmsgerror=2;
        MOV     #01h,interrupt_agcthreshold ;   interrupt_agcthreshold = 0x01
        MOV.B   #0,interrupt_txready      ;     txready=0;
        MOV     #10h,interrupt_tvcounter  ;     tvcounter = 2ms;
int1I5: MOV     #22,interrupt_modemstate  ;   modemstate = L;
        JMP     int1r                     ;   break;

; Interrupt 1, State H (Transmitting parity bit)
int1H:  INC     interrupt_txcounter       ; txcounter++;
        CMP     #0080h,interrupt_txcounter; //Reverse logic below
        JL      int1r                     ; if( 16ms have elapsed ) {
        MOV     #PERIOD_HF,interrupt_timerb_period
        BIT.B   #04h,interrupt_txmsgerror ;      timerb_period = PERIODHF;
        JNZ     int1H4                    ;      if((txmsgerror&0x04)==0) //RL
        MOV.B   #0,interrupt_txparityak   ;        txparityak = 0;
        MOV     #16,interrupt_modemstate  ;        modemstate = I;
        JMP     int1r                     ;        break;
int1H4: MOV     #28h,interrupt_tvcounter  ;      else { //There was a collision
        MOV.B   #0,interrupt_txmsgerror   ;        tvcounter=5ms;txmsgerror=0;
        MOV     #22,interrupt_modemstate  ;        modemstate=L;
        JMP     int1r                     ;        break;

; Interrupt 1, State G (Transmitting collision bit)
int1G:  INC     interrupt_txcounter       ; txcounter++;
        CMP     #0078h,interrupt_txcounter; //Reverse logic below
        JL      int1r                     ; if( 15ms have elapsed ) {
        MOV     #14,interrupt_modemstate  ;   modemstate = H
        MOV     #0,numWinSamples          ;   clear window variables
        MOV     #0,winIdx
        MOV     #0,sin_win_sum
        MOV     #0,cosin_win_sum          ;   // parity bit is between 15ms
        BIT.B   #01h,interrupt_txparityak ;   // and 16ms
        JNZ     int1G4                    ;   if (txparityak==0)
        MOV     #PERIOD_HF,interrupt_timerb_period
        JMP     int1r                     ;     timerb_period = PERIOD_HF;
int1G4: MOV     #PERIOD_8K,interrupt_timerb_period
        JMP     int1r                     ;   else{timerb_period=PERIOD_8K;

; Interrupt 1, State F (Transmitting repeat bit)
int1F:  INC     interrupt_txcounter       ; txcounter++;
        CMP     #0070h,interrupt_txcounter; //Reverse logic below
        JL      int1r                     ; if( 14ms have elapsed ) {
        MOV     #12,interrupt_modemstate  ;   modemstate = G
        MOV     #0,numWinSamples          ;   clear window variables
        MOV     #0,winIdx
        MOV     #0,sin_win_sum
        MOV     #0,cosin_win_sum          ;   // collision bit is between 14ms
        BIT.B   #04h,interrupt_txmsgerror ;   // and 15ms
        JNZ     int1F4                    ;   if((txmsgerror&0x04)==0) //RL
        MOV     #PERIOD_8K,interrupt_timerb_period
        XOR.B   #01h,interrupt_txparityak ;     timerb_period=PERIOD_8K;
        JMP     int1r                     ;     txparityak ^= 0x01; }
int1F4: MOV     #PERIOD_HF,interrupt_timerb_period
        JMP     int1r                     ;   else timerb_period=PERIOD_HF;

; Interrupt 1, State E
; (Transmitting bits for start, direction, address, and command)
int1E:  INC     interrupt_txcounter       ; txcounter++;
        BIT     #7,interrupt_txcounter    ; //Reverse logic below

⌨️ 快捷键说明

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