;****************************************************************** ; ; ; Filename: init.asm ; ; Author: Ronald W. Bazillion ; ; Module Description: ; ; This module initializes the DSP56307EVM board. ; The initialization procedure features initialization ; of the 56307 DSP and the CS4218 Audio Codec. The ; configuration of the 56307EVM board is hardwired to ; receive Mode 4 data from the codec. In this mode, the ; audio data and the control data are separated where the ; audio data is transmitted and received in the ESSI STD0, ; and SRD0 pins. The control data is transmitted out on the ; SC12 pin. The 56307EVM board ties the CDOUT pin to ground ; thus you can only transmit data to the codec. ; ;****************************************************************** ;DEFINES FOR CONTROL WORDS SENT TO CODEC ;----------------------------------------- CTRL_RIGHT_AD_GAIN equ $0000 ;RIGHT INPUT A/D GAIN (0dB gain) CTRL_LEFT_AD_GAIN equ $0000 ;LEFT INPUT A/D GAIN (0 dB gain) CTRL_ISR equ $0001 ;INPUT MUX RIGHT SELECT (selected RIN2) CTRL_ISL equ $0002 ;INPUT MUX LEFT SELECT (selected LIN2) CTRL_MUTE equ $0000 ;MUTE SELECTION (selected no muting) CTRL_RIGHT_DA_ATT equ $0010 ;D/A ATTENUATION RIGHT CHANNEL (select -3dB) (00000 - 11111 = 0dB - -46.5 dB 1.5 dB steps) CTRL_LEFT_DA_ATT equ $0200 ;D/A ATTENUATION LEFT CHANNEL (select -3dB) (00000 - 11111 = 0dB - -46.5 dB 1.5 dB steps) CTRL_DO1 equ $0000 ;DIGITAL OUTPUT 1 (selected output low) CTRL_INT_MASK equ $4000 ;MASK INTERRUPT PIN (selected to mask interrupt; since INT PIN is tied high and not used) ;define first and second control word to be sent to the codec. ;-------------------------------------------------------------- CTRL_CDIN_12 equ CTRL_RIGHT_AD_GAIN+CTRL_LEFT_AD_GAIN CTRL_CDIN_34 equ CTRL_ISR+CTRL_ISL+CTRL_MUTE+CTRL_RIGHT_DA_ATT+CTRL_LEFT_DA_ATT+CTRL_DO1+CTRL_INT_MASK ;ESSI INTERNAL X I/O REGISTERS ;------------------------------ M_TX00 equ $FFFFBC ;ESSI 0 Transmit Data Register M_RX0 equ $FFFFB8 ;ESSI 0 Receive Data Register M_SSISR0 equ $FFFFB7 ;ESSI 0 Status Register M_CRB0 equ $FFFFB6 ;ESSI 0 Control Register B M_CRA0 equ $FFFFB5 ;ESSI 0 Control Register A M_PCRC equ $FFFFBF ;Port C Control Register (PCRC) M_PCTL equ $FFFFFD ;PLL Control Register M_PRRC equ $FFFFBE ;Port C Direction Register (PRRC) M_PDRC equ $FFFFBD ;Port C GPIO Data Register (PDRC) M_PRRD equ $FFFFAE ;Port D Direction Register (PRRD) M_PDRD equ $FFFFAD ;Port D GPIO Data Register (PDRD) M_IPRP equ $FFFFFE ;Peripheral Interrupt Priority Register ;CODE ENTRY POINTS ;------------------ PBASE equ $100 ;CONTROL AND DATA WORD STORAGE ;----------------------------- org x:$00 RX_BUFF_BASE EQU * RX_data_1 ds 1 ;data time slot 1 for RX ISR RX_data_2 ds 1 ;data time slot 2 for RX ISR TX_BUFF_BASE EQU * TX_data_1 ds 1 ;data time slot 1 for TX ISR TX_data_2 ds 1 ;data time slot 2 for TX ISR RX_PTR ds 1 ;Pointer for rx buffer TX_PTR ds 1 ;Pointer for tx buffer CTRL_WD_HI ds 1 ;storage for control word HI CTRL_WD_LO ds 1 ;storage for control word LO ;interrupt vector jump table ;----------------------------- org p:$00 jmp START org p:$30 jsr essi0_rx jsr essi0_rx_we jsr essi0_rx_ls jsr essi0_tx jsr essi0_tx_we jsr essi0_tx_ls ;*************************************************************************** ; ; module: start ; ; description: This program is used to initialize the DSP56307. ; This module is called from on powerup or reset. ; ;*************************************************************************** org p:PBASE START movep #$040006,x:M_PCTL ; PLL Enabled ; Core Clock Multiplier = 7 X 12.288 = 86.016MHz ori #3,mr ; mask interrupts movec #0,sp ; clear hardware stack pointer move #0,omr ; operating mode 0 move #TX_BUFF_BASE,r6 nop move r6,x:TX_PTR ;point tx pointer to address of tx buffer move #RX_BUFF_BASE,r7 nop move r7,x:RX_PTR ;point rx pointer to address of rx buffer move #1,m6 ;Modulo 2 buffer move m6,m7 ;Modulo 2 buffer movep #$0000,x:M_PCRC ; disable ESSI0 port (for now) movep #$101803,x:M_CRA0 ; 12.288MHz/8 = 1.536MHz SCLK ; prescale modulus = 8 ; prescaler range = Fcore/1 ; frame rate divider = 2 ; 16-bits per word ; 32-bits per frame ; 16-bit data aligned to bit 23 movep #$ff330c,x:M_CRB0 ; Enable REIE,TEIE,RLIE,TLIE, ; RIE,TIE,RE,TE0 ; network mode, synchronous, ; out on rising/in on falling ; shift MSB first ; external clock source drives SCK ; (codec is master) ; RX frame sync pulses active for ; 1 bit clock immediately before ; transfer period ; positive frame sync polarity ; frame sync length is 1-bit movep #$0001,x:M_PRRC ; set PC0=CODEC_RESET~ as output movep #$0007,x:M_PRRD ; set PD0=CCS~ as output ; set PD1=CCLK as output ; set PD2=CDIN as output bclr #$0,x:M_PDRC ; Reset codec (Active Low) bclr #$0,x:M_PDRD ; Assert CCS (Active Low) ;Reset delay for codec do #1000,_delay_loop rep #1000 ; minimum 50 ms delay nop _delay_loop ;Send control data to codec bset #$0000,x:M_PDRC ; deassert codec reset movep #$0004,x:M_IPRP ; set int priority level for ESSI0 to 1 andi #$fc,mr ; enable interrupts jsr init_codec ; initialize codec movep #$003e,x:M_PCRC ; enable ESSI0 except SC00 which is GPIO jmp MAIN ;jump to start of main program (initialization finished) ;*************************************************************************** ; ; module: init_codec ; ; description: This function initializes the CS4218 codec. ; ;*************************************************************************** org p: ;relative addressing linker will place ;module in next available P memory section. ;In this case, it will be placed right after ;the START routine. init_codec dummy_control bclr #$0,x:M_PDRD ; assert CCS move #$0000,x0 move x0,x:CTRL_WD_HI ;load dummy word high move x0,x:CTRL_WD_LO ;load dummy word low jsr send_control bset #$0,x:M_PDRD ; deasert CCS set_control bclr #$0,x:M_PDRD ; assert CCS move #CTRL_CDIN_34,x0 move x0,x:CTRL_WD_HI ;load control word high move #CTRL_CDIN_12,x0 move x0,x:CTRL_WD_LO ;load control word low jsr send_control bset #$0,x:M_PDRD ; deasert CCS rts ;------------------------------------------------- ; ; Subroutine functions used in init_codec routine: ; ; send_control send_word ; ;------------------------------------------------- send_control clr a move x:CTRL_WD_HI,a1 jsr send_word move x:CTRL_WD_LO,a1 jsr send_word ; send control data to codec (one bit at a time) rts send_word do #16,end_bit_send ; 16 bits per word bset #$01,x:M_PDRD ; toggle CCLK clock high jclr #23,a1,bit_low ; test msb bset #$02,x:M_PDRD ; CDIN bit is high, send a one jmp continue bit_low bclr #$02,x:M_PDRD ; CDIN bit is low, send a zero continue rep #2 ; delay 162.76 ns nop bclr #$01,x:M_PDRD ; toggle CCLK clock low lsl a ; shift control word to 1 bit to left end_bit_send rts ;************************************************************************************************** ; ; MODULE: Interrupt Service Routines ; Decription: These modules are the interrupt service routines used ; by when an interrupt is made to the DSP. These routines ; are the functions pointed to by the vector jump table. ; The TX and RX ISRs use registers r6 and r7. To avoid ; conflicts with the ISRs use only registers r0-r5 & m0-m5 ; in your main programs. ; ; Normally, you want the ISR routines to be as fast as possible; which ; relates to the fewest instructions possible. ; ; Remember, that the DSP is interrupted every 1/Fs seconds to receive a ; new sample so your program MUST process the previous sample before 1/Fs ; seconds to achieve real-time action. This translates to the maximum number ; of instructions by the formula below. ; ; number of instructions = T / Tins ; ; T = 1/Fs = sampling period between samples ; Tins 1/Fclk = time for each instruction ; ; example: (1/48Khz) / (1/86.016Mhz) = 1792 instructions ; ; This also takes into account that each instruction runs in one clock ; cycle. This does not mean that you are limited to 1792 instructions. ; But if you have more than 1792 instructions, you won't be able to process ; samples in real-time. Notice the maximum number of samples allowed for ; real-time is proportional to the sampling period ,clock multiplier, and ; clock frequency. Notice in this example how I can increase the number of ; instructions by changing the sampling rate. ; ; example: (1/8Khz) / (1/86.016Mhz) = 10752 instructions ; ;************************************************************************************************* essi0_tx_we bclr #4,x:M_SSISR0 ;Clear Transmitter Underrun flag essi0_tx_ls essi0_tx move x:TX_PTR,r6 ; load the address of the next data point to transmit rep #1 ; repeat nop to allow pipeline to update r6 nop movep x:(r6)+,x:M_TX00 ; Transmit 16 bit data word. move r6,x:TX_PTR ; Update tx buffer pointer. rti essi0_rx_we bclr #5,x:M_SSISR0 ; Clear receiver Overrun error flag essi0_rx_ls essi0_rx move x:RX_PTR,r7 rep #1 ; repeat nop to allow pipeline to update r7 nop movep x:M_RX0,x:(r7)+ ; Receive 16 bit data word. move r7,x:RX_PTR ; Update RX buffer pointer rti ;------------------------------------------------------- ; ; function macros ; ; wait_frame_sync, get_left_channel, get_right_channel, ; ; transmit_left_channel, transmit_right_channel ; ; ;------------------------------------------------------- wait_frame macro jclr #3,x:M_SSISR0,* ; wait if RX frame sync bit = 0 jset #3,x:M_SSISR0,* ; wait if RX frame sync bit = 1 endm get_left_channel macro move x:RX_BUFF_BASE,x0 ;get left channel data endm get_right_channel macro move x:RX_BUFF_BASE+1,y0 ;get right channel data endm transmit_left_channel macro move a,x:TX_BUFF_BASE ;place left channel data endm ;in TX Buffer to be sent to codec transmit_right_channel macro move b,x:TX_BUFF_BASE+1 ;place right channel data endm ;in TX Buffer to be sent to codec