page 132,60 ;**************************************************************************** ; CODEC.ASM ; Initialization program for EVM56002 to communicate with CS4215 ; input connected to Mic inputs ; ; Copywrite (c) MOTOROLA 1994 ; Semiconductor Products Sector ; Digital Signal Processing Division ; ;**************************************************************************** ; ; portc usage: ; bit8: SSI TX (from DSP to Codec) ; bit7: ; bit6: ; bit5: ; bit4: codec reset (from DSP to Codec) ; bit3: ; bit2: data/control bar ; 0=control ; 1=data ; ; ; PROGRAM OUTLINE: ; ;1 program fsync and sclk == output ;2 write pc0 = 0 (control mode) ;3 send 64 bit frame x times, with dcb bit = 0, keep doing until read back as 0 ;4 send 64 bit frame x times, with dcb bit = 1, keep doing until read back as 1 ;5 re-program fsync and sclk == input ;6 write pc0 = 1 (data mode) ;7 receive/send data (echo slots 1,2,3,4; slots 5,6,7,8 == DIP switched) ; ;**************************************************************************** PAGE 255 NO_PREAMP equ $100000 LO_OUT_DRV equ $080000 HI_PASS_FILT equ $008000 SAMP_RATE_9 equ $003800 SAMP_RATE_48 equ $003000 SAMP_RATE_32 equ $001800 SAMP_RATE_27 equ $001000 SAMP_RATE_16 equ $000800 SAMP_RATE_8 equ $000000 STEREO equ $000400 DATA_8LIN equ $200300 DATA_8A equ $200200 DATA_8U equ $200100 DATA_16 equ $200000 IMMED_3STATE equ $800000 XTAL2_SELECT equ $200000 BITS_64 equ $000000 BITS_128 equ $040000 BITS_256 equ $080000 CODEC_MASTER equ $020000 CODEC_TX_OFF equ $010000 CTRL_WD_12 equ NO_PREAMP+HI_PASS_FILT+SAMP_RATE_48+STEREO+DATA_16 ;CLB=0 CTRL_WD_34 equ IMMED_3STATE+XTAL2_SELECT+BITS_64+CODEC_MASTER CTRL_WD_56 equ $000000 CTRL_WD_78 equ $000000 HEADPHONE_EN equ $800000 LINEOUT_EN equ $400000 LEFT_ATTN equ $010000 ;63*LEFT_ATTN = -94.5 dB, 1.5 dB steps SPEAKER_EN equ $004000 RIGHT_ATTN equ $000100 ;63*RIGHT_ATTN = -94.5 dB, 1.5 dB steps MIC_IN_SELECT equ $100000 LEFT_GAIN equ $010000 ;15*LEFT_GAIN = 22.5 dB, 1.5 dB steps MONITOR_ATTN equ $001000 ;15*MONITOR_ATTN = mute, 6 dB steps RIGHT_GAIN equ $000100 ;15*RIGHT_GAIN = 22.5 dB, 1.5 dB steps OUTPUT_SET equ HEADPHONE_EN+LINEOUT_EN+(LEFT_ATTN*4) INPUT_SET equ MIC_IN_SELECT+(15*MONITOR_ATTN)+(RIGHT_ATTN*4) ;---DSP56002 on-chip peripheral addresses PCD equ $FFE5 PCDDR equ $FFE3 PCC equ $FFE1 PBC equ $FFE0 CRA equ $FFEC CRB equ $FFED SSIDR equ $FFEF IPR equ $FFFF BCR equ $FFFE SSISR equ $FFEE PLL equ $FFFD START equ $40 org x:0 RX_BUFF_BASE equ * RX_data_1_2 ds 1 ;data time slot 1/2 for RX ISR RX_data_3_4 ds 1 ;data time slot 3/4 for RX ISR RX_data_5_6 ds 1 ;data time slot 5/6 for RX ISR RX_data_7_8 ds 1 ;data time slot 7/8 for RX ISR TX_BUFF_BASE equ * TX_data_1_2 ds 1 ;data time slot 1/2 for TX ISR TX_data_3_4 ds 1 ;data time slot 3/4 for TX ISR TX_data_5_6 ds 1 ;data time slot 5/6 for TX ISR TX_data_7_8 ds 1 ;data time slot 7/8 for TX ISR RX_PTR ds 1 ; Pointer for rx buffer TX_PTR ds 1 ; Pointer for tx buffer org p:0 jmp START org p:$C jsr ssi_rx_isr ;SSI RX jsr ssi_rx_isr ;SSI RX w/Exception jsr ssi_tx_isr ;SSI TX jsr ssi_tx_isr ;SSI TX w/Exception ;--------------------------------------------------------------------------- ; ; Main codec initialization program ; ;--------------------------------------------------------------------------- org p:START movep #$261009,x:PLL ;set PLL for MPY of 10x movep #$0000,x:BCR ; number of wait states ori #3,mr ;disable interrupts movec #0,sp move #0,omr ; single chip mode move #$40,r6 ; initialize stack pointer move #-1,m6 ; linear addressing move #RX_BUFF_BASE,x0 move x0,x:RX_PTR ; Initialize the rx pointer move #TX_BUFF_BASE,x0 move x0,x:TX_PTR ; Initialize the tx pointer jsr codec_init ; The following line of code jumps to "main" which is the location for ; the main code that will run after the codec is initialized. jmp main ;*************************************************************************** ;***** initialize the CS4215 codec ***** ;*************************************************************************** ; headphones and line out, and set up for no gain or attenuation, and no ; monitor feedback. ;*************************************************************************** ;*************************************************************************** ; ; initialize ssi -- fsync and sclk ==> outputs ; codec_init movep #$0000,x:PCC ; turn off ssi port movep #$4303,x:CRA ; 40MHz/16 = 2.5MHz SCLK, WL=16 bits, 4W/F movep #$FB30,x:CRB ; RIE,TIE,RE,TE, NTWK, SYN, FSR/RSR->bit movep #$14,x:PCDDR ; setup pc2 and pc4 as outputs movep #$0,x:PCD ; D/C~ and RESET~ = 0 ==> control mode ;----reset delay for codec ---- do #500,_delay_loop rep #2000 ; 100 us delay nop _delay_loop bset #4,x:PCD ; RESET~ = 1 movep #$3000,x:IPR ; set interrupt priority level andi #$FC,mr ; enable interrupts ;***************************************************************************** ; The following data sets up the CS4215 control mode data: ; (CTS = Control Time Slot, U/LN = upper/lower Nibble) ; ; +------ CTS1-UN: 0 0 1 MLB 0 0 0 0 ; |+----- CTS1-LN: OLB CLB X X 0 0 0 0 ; ||+---- CTS2-UN: HPF X DFR2 DFR1 0 0 1 0 ; |||+--- CTS2-LN: DFR0 ST DF1 DF0 1 1 0 0 ; x0 = $002Cxx ; ; +------ CTS3-UN: ITS MCK2 MCK1 MCK0 1 0 0 0 ; |+----- CTS3-LN: BSEL1 BSEL0 XCLK XEN 1 0 0 0 ; ||+---- CTS4-UN: TEST TEST TEST TEST (TEST MUST BE 0) ; |||+--- CTS4-LN: TEST TEST ENL DAD 0 0 0 0 ; x0 = $8800xx ;***************************************************************************** ;--- set up buffer with control mode data move #CTRL_WD_12,x0 move x0,x:TX_BUFF_BASE move #CTRL_WD_34,x0 move x0,x:TX_BUFF_BASE+1 move #CTRL_WD_56,x0 move x0,x:TX_BUFF_BASE+2 move #CTRL_WD_78,x0 move x0,x:TX_BUFF_BASE+3 movep #$01E8,x:PCC ; Turn on ssi port ; ; CLB == 0 ; jclr #3,x:SSISR,* ; wait until rx frame bit==1 jset #3,x:SSISR,* ; wait until rx frame bit==0 jclr #3,x:SSISR,* ; wait until rx frame bit==1 jset #18,x:RX_BUFF_BASE,* ; loop until CLB set ; ; CLB == 1 ; bset #18,x:TX_BUFF_BASE ;set CLB do #4,_init_loopB jclr #2,x:SSISR,* ; wait until tx frame bit==1 jset #2,x:SSISR,* ; wait until tx frame bit==0 _init_loopB movep #0,x:PCC ;disable, reset SSI ;***************************************************************************** ; now CLB should be 1 -- re-program fsync and sclk direction (i/p) -- also, ; circular buffer pointers for echoing data r0=current, r1=old data to send ; 1 frame later ; movep #$4303,x:CRA ; 16bits,4 word/frame, /2/4/2=2.5 MHz movep #$FB00,x:CRB ; rcv,xmt & int ena,netwk,syn,sclk==i/p,msb 1st movep #$14,x:PCD ; D/C~ pin = 1 ==> data mode movep #$01E8,x:PCC ; turn on ssi port rts ;************************** SSI TRANSMIT ISR ************************** ssi_tx_isr move r0,x:(r6)+ ; Save r0 to the stack. move m0,x:(r6)+ ; Save m0 to the stack. move #3,m0 ; Modulus 4 buffer. move x:TX_PTR,r0 ; Load the pointer to the tx buffer. jclr #2,x:SSISR,next_tx ; If not frame sync, jump to transmit data. move #TX_BUFF_BASE+1,r0 ; If frame sync, reset pointer. nop next_tx movep x:(r0)+,x:SSIDR ; SSI transfer data register. move r0,x:TX_PTR ; Update tx buffer pointer. move x:-(r6),m0 ; Restore m0. move x:-(r6),r0 ; Restore r0. rti ;************************** SSI receive ISR************************** ssi_rx_isr move r0,x:(r6)+ ; Save r0 to the stack. move m0,x:(r6)+ ; Save m0 to the stack. move #3,m0 ; Modulo 4 buffer. move x:RX_PTR,r0 ; Load the pointer to the rx buffer. jclr #3,x:SSISR,next_rx ; If not fr. syc, jump to receive data. move #RX_BUFF_BASE,r0 ; If frame sync, reset base pointer. nop next_rx movep x:SSIDR,x:(r0)+ ; Read out received data to buffer. move r0,x:RX_PTR ; Update rx buffer pointer. move x:-(r6),m0 ; Restore m0. move x:-(r6),r0 ; Restore r0. rti