📄 ad1881_init.asm
字号:
/*****************************************************************************************************************
(C) Copyright 2002 - Analog Devices, Inc. All rights reserved.
File Name: AD1881_Init.asm
Date Modified: 4/11/02 Rev 1.0
Purpose: AD1881/ADSP-21160 SPORT0 Initialization Driver
Developed using the ADSP-21160 EZ-Kit Lite Evaluation Platform
Demonstrate initialization and operation of a SPORT0-AC'97 link between the ADSP21160
and sets up AD1881 to send/recieve data at 48 KHz using the SPORT0 rx ISR
for audio processing.
*****************************************************************************************************************/
//#include "bandpass.h"
#include <def21160.h>
#include "AD1881_Registers.h"
.GLOBAL Clear_All_SPT0_Regs;
.GLOBAL Program_SPORT0_Registers;
.GLOBAL Program_DMA_Controller;
.GLOBAL AD1881_Codec_Initialization;
.GLOBAL Codec_Reset;
.GLOBAL tx_buf;
.GLOBAL rx_buf;
//---------------------------------------------------------------------------
.segment /dm seg_dmda;
.var rx_buf[5]; // receive buffer
// transmit buffer
.var tx_buf[16] = ENABLE_VFbit_SLOT1_SLOT2, // set valid bits for slot 0, 1, and 2
SERIAL_CONFIGURATION, // serial configuration register address
0xFF80, // initially set to 16-bit slot mode for ADI SPORT compatibility
0x0000, // stuff other slots with zeros for now
0x0000,
0x0000,
0x0000,
0x0000,
0x0000,
0x0000,
0x0000,
0x0000,
0x0000,
0x0000,
0x0000,
0x0000;
.var rcv_tcb[8] = 0, 0, 0, 0, 0, 5, 1, 0; // receive tcb
.var xmit_tcb[8] = 0, 0, 0, 0, 0, 16, 1, 0; // transmit tcb
.var Init_Codec_Registers[34] =
MASTER_VOLUME, 0x0000, // Master Volume set for no attenuation
MASTER_VOLUME_MONO, 0x8000, // Master Mono volume is muted
PC_BEEP_Volume, 0x8000, // PC volume is muted
PHONE_Volume, 0x8008, // Phone Volume is muted
MIC_Volume, 0x8048, // 20 dB gain stage on, MIC Input analog loopback is muted
LINE_IN_Volume, 0x8808, // Line Input analog loopback is muted
CD_Volume, 0x8808, // CD Volume is muted
VIDEO_Volume, 0x8808, // Video Volume is muted
AUX_Volume, 0x8808, // AUX Volume is muted
PCM_OUT_Volume, 0x0808, // PCM out from DACs is 0 db gain for both channels
RECORD_SELECT, Select_LINE_INPUT, // Record Select on Line Inputs for L/R channels
RECORD_GAIN, Line_Level_Volume, // Record Gain set for 0 dB on both L/R channels
GENERAL_PURPOSE, 0x0000, // 0x8000, goes through 3D circuitry
THREE_D_CONTROL_REG, 0x0000, // no phat stereo
MISC_CONTROL_BITS, 0x0000, // use SR0 for both Left and Right ADCs and DACs, repeat sample
SAMPLE_RATE_GENERATE_0, Sample_Rate2, // user selectable sample rate
SAMPLE_RATE_GENERATE_1, 48000; // Sample Rate Generator 1 not used in this example
.var Codec_Init_Results[34] =
0, 0,
0, 0,
0, 0,
0, 0,
0, 0,
0, 0,
0, 0,
0, 0,
0, 0,
0, 0,
0, 0,
0, 0,
0, 0,
0, 0,
0, 0,
0, 0,
0, 0;
.endseg;
.SEGMENT /pm seg_pmco;
Clear_All_SPT0_Regs:
IRPTL = 0x00000000; // clear pending interrupts
bit clr imask SPT0I;
R0 = 0x00000000;
dm(SRCTL0) = R0; // sport0 receive control register
dm(RDIV0) = R0; // sport0 receive frame sync divide register
dm(STCTL0) = R0; // sport0 transmit control register
dm(MRCS0) = R0; // sport0 receive multichannel word enable register
dm(MTCS0) = R0; // sport0 transmit multichannel word enable register
dm(MRCCS0) = R0; // sport0 receive multichannel companding enable register
dm(MTCCS0) = R0; // sport0 transmit multichannel companding enable register
// reset SPORT0 DMA parameters back to the Reset Default State
R1 = 0x1FFFF; dm(II0) = R1;
R1 = 0x0001; dm(IM0) = R1;
R1 = 0xFFFF; dm(C0) = R1;
R1 = 0x00000; dm(CP0) = R1;
R1 = 0x1FFFF; dm(GP0) = R1;
R1 = 0x1FFFF; dm(II2) = R1;
R1 = 0x0001; dm(IM2) = R1;
R1 = 0xFFFF; dm(C2) = R1;
R1 = 0x00000; dm(CP2) = R1;
R1 = 0x1FFFF; dm(GP2) = R1;
RTS;
Clear_All_SPT0_Regs.end:
// ---------------------------------------------------------------------------------------------
// Sport0 Control Register Programming
// Multichannel Mode dma w/ chain, erly fs, act hi fs, fall edge, no pack, data=16/big/zero
// ---------------------------------------------------------------------------------------------
Program_SPORT0_Registers:
// sport0 receive control register
R0 = 0x1F0C40F0; // 16 chans, int rfs, ext rclk, slen = 15, sden & schen enabled
dm(SRCTL0) = R0; // sport 0 receive control register
// sport0 receive frame sync divide register
R0 = 0x00FF0000; // SCKfrq(12.288M)/RFSfrq(48.0K)-1 = 0x00FF
dm(RDIV0) = R0;
// sport0 transmit control register
R0 = 0x001C00F0; // 1 cyc mfd, data depend, slen = 15, sden & schen enabled
dm(STCTL0) = R0; // sport 0 transmit control register
// sport0 receive and transmit multichannel word enable registers
R0 = 0x001F001F; // enable receive channels 0-4
dm(MRCS0) = R0;
R0 = 0xFFFFFFFF; // enable transmit channels 0-6
dm(MTCS0) = R0;
// sport0 transmit and receive multichannel companding enable registers
R0 = 0x00000000; // no companding
dm(MRCCS0) = R0; // no companding on receive
dm(MTCCS0) = R0; // no companding on transmit
RTS;
Program_SPORT0_Registers.end:
//----------------------------------------------------------------------------------
// DMA Controller Programming For SPORT0
//----------------------------------------------------------------------------------
Program_DMA_Controller:
r1 = 0x0003FFFF; // cpx register mask
// sport0 dma control tx chain pointer register
r0 = tx_buf;
dm(xmit_tcb + 7) = r0; // internal dma address used for chaining
r0 = 1;
dm(xmit_tcb + 6) = r0; // DMA internal memory DMA modifier
r0 = 16;
dm(xmit_tcb + 5) = r0; // DMA internal memory buffer count
r0 = xmit_tcb + 7; // get DMA chaining internal mem pointer containing tx_buf address
r0 = r1 AND r0; // mask the pointer
r0 = BSET r0 BY 18; // set the pci bit
dm(xmit_tcb + 4) = r0; // write DMA transmit block chain pointer to TCB buffer
dm(CP2) = r0; // transmit block chain pointer, initiate tx0 DMA transfers
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
// - Note: Tshift0 & TX0 will be automatically loaded with the first 2 values in the -
// - Tx buffer. The Tx buffer pointer ( II3 ) will increment by 2x the modify value -
// - ( IM3 ). -
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
// sport0 dma control rx chain pointer register
r0 = rx_buf;
dm(rcv_tcb + 7) = r0; // internal dma address used for chaining
r0 = 1;
dm(rcv_tcb + 6) = r0; // DMA internal memory DMA modifier
r0 = 5;
dm(rcv_tcb + 5) = r0; // DMA internal memory buffer count
r0 = rcv_tcb + 7;
r0 = r1 AND r0; // mask the pointer
r0 = BSET r0 BY 18; // set the pci bit
dm(rcv_tcb + 4) = r0; // write DMA receive block chain pointer to TCB buffer
dm(CP0) = r0; // receive block chain pointer, initiate rx0 DMA transfers
RTS;
Program_DMA_Controller.end:
// --------------------------------------------------------------------------------------
// AD1881 Codec Reset
// --------------------------------------------------------------------------------------
Codec_Reset:
bit set MODE2 FLG3O;
bit clr FLAGS FLG3;
R4 = 0x10000 ; //Set number of bytes to be programmed
LCNTR = R4, DO reset_hold UNTIL LCE;
nop;
nop;
nop;
reset_hold:
nop;
bit set FLAGS FLG3;
RTS;
Codec_Reset.end:
// --------------------------------------------------------------------------------------
// AD1881 Codec Initialization
// --------------------------------------------------------------------------------------
AD1881_Codec_Initialization:
bit set imask SPT0I; // enable sport0 x-mit interrupt
Enable_SPORT0_Transfers:
// enable SPORT0 multichannel operation
R0 = DM(SRCTL0) ; // load the sport0 control reg
R0 = BSET R0 BY 23 ; // set the sport0 multichannel ena bit
DM(SRCTL0) = R0 ; // prgm the sport0 control reg
Wait_Codec_Ready: // Wait for CODEC Ready State
R0 = DM(rx_buf + 0); // get bit 15 status bit from AD1881 tag phase slot 0
R1 = 0x8000; // mask out codec ready bit in tag phase
R0 = R0 AND R1; // test the codec ready status flag bit
IF EQ JUMP Wait_Codec_Ready; // if flag is lo, continue to wait for a hi
idle; // wait for a couple of TDM audio frames to pass
idle;
Initialize_1881_Registers:
i4 = Init_Codec_Registers; // pointer to codec initialization commands
r12 = ENABLE_VFbit_SLOT1_SLOT2; // enable valid frame bit, and slots 1 and 2 valid data bits
LCNTR = 17, DO Codec_Init UNTIL LCE;
dm(tx_buf + TAG_PHASE) = r12; // set valid slot bits in tag phase for slots 0, 1 , 2
r1 = dm(i4, 1); // fetch next codec register address
dm(tx_buf + COMMAND_ADDRESS_SLOT) = r1; // put fetched codec register address into tx slot 1
r1 = dm(i4, 1); // fetch register data contents
dm(tx_buf + COMMAND_DATA_SLOT) = r1; // put fetched codec register data into tx slot 2
Codec_Init: idle; // wait until TDM frame is transmitted
AD1881_Codec_Initialization.end:
//------------------------------------------------------------------------------------------------------
// Verify integrity of AD1881 indexed control register states to see if communication was successful
//------------------------------------------------------------------------------------------------------
// This section of codes is for debugging/verification of AD1881 registers. Theses instructions
// initiate codec read requests of registers shown in the Init_Codec_Registers buffer. The results
// of the read requests are placed in an output buffer called Codec_Init_Results, in which even
// DSP memory addresses contain the AD1881 register address, and the DSP's odd address in the buffer
// contains the register data for the AD1881 address. The AD1881 registers can then be verified with
// a JTAG emulator or debug monitor program. This section of code can be removed after debug.
//------------------------------------------------------------------------------------------------------
verify_reg_writes:
i4 = Init_Codec_Registers;
m4 = 2;
i5 = Codec_Init_Results;
r12 = ENABLE_VFbit_SLOT1; // enable valid frame bit, and slots 1 data bits
LCNTR = 17, Do ad1881_register_status UNTIL LCE;
dm(tx_buf + TAG_PHASE) = r12; // set valid slot bits in tag phase for slots 0, 1 , 2
r1 = dm(i4,2); // get indexed register address that is to be inspected
r2 = 0x8000; // set bit #15 for read request in command address word
r1 = r1 OR r2; // OR read request with the indirect register value
dm(tx_buf + COMMAND_ADDRESS_SLOT) = r1; // send value out of command address timeslot
idle; // wait for 2 audio frame to go by, latency in getting data
idle;
r4 = dm(rx_buf + STATUS_ADDRESS_SLOT);
dm(i5,1) = r4;
r4 = dm(rx_buf + STATUS_DATA_SLOT); // fetch value of requested indexed register data
dm(i5,1) = r4; // store to results buffer
ad1881_register_status: nop;
// For variable sample rate support, you must powerdown and powerback up the ADCs and DACs
// so that the incoming ADC data and DAC requests occur in left/right pairs
PowerDown_DACs_ADCs:
idle;
r12 = ENABLE_VFbit_SLOT1_SLOT2; // enable valid frame bit, and slots 1 and 2 valid data bits
dm(tx_buf + TAG_PHASE) = r12; // set valid slot bits in tag phase for slots 0, 1 , 2
r0=POWERDOWN_CTRL_STAT;
dm(tx_buf + COMMAND_ADDRESS_SLOT) = r0;
r0=0x0300; // power down all DACs/ADCs
dm(tx_buf + COMMAND_DATA_SLOT) = r0;
idle;
idle;
LCNTR = AD1881_RESET_CYCLES-2, DO reset_loop UNTIL LCE;
reset_loop: NOP; // wait for the min RESETb lo spec time
idle;
r12 = ENABLE_VFbit_SLOT1_SLOT2; // enable valid frame bit, and slots 1 and 2 valid data bits
dm(tx_buf + TAG_PHASE) = r12; // set valid slot bits in tag phase for slots 0, 1 , 2
r0=POWERDOWN_CTRL_STAT; // address to write to
dm(tx_buf + COMMAND_ADDRESS_SLOT) = r0;
r0=0; // power up all DACs/ADCs
dm(tx_buf + COMMAND_DATA_SLOT) = r0;
idle;
idle;
// Both wait loops total to 80000 DSP cycles, or 1.0 mSec
LCNTR = AD1881_WARMUP_CYCLES1-2, DO warmup_loop1 UNTIL LCE;
warmup_loop1: NOP; // wait for AD1881 warm-up
LCNTR = AD1881_WARMUP_CYCLES2-2, DO warmup_loop2 UNTIL LCE;
warmup_loop2: NOP; // wait for AD1881 warm-up
// ----------------------------------------------------------------------------------------------------
bit clr imask SPT0I; // disable sport0 xmit
RTS; // End of AD1881 Initialization
// -------------------------------------------------------------------------------------------
.endseg;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -