www.pudn.com > Echo_Cancel.rar > AD1885_Init.asm
/************************************************************************************************ * TITLE: AD1885_Init * PURPOSE: Initialize AD1885 codec * * * Modified: 07/12/2001 - GJO * ************************************************************************************************/ #include#include "2191_EZ_KIT.h" /************************************************************************************************/ /* GLOBAL DECLARATIONS */ /************************************************************************************************/ .GLOBAL Codec_Reset; .GLOBAL Program_SPORT0_Registers; .GLOBAL Program_DMA_Controller; .GLOBAL AD1885_Codec_Initialization; /***************************************************************************************************** CONSTANT & MACRO DEFINITIONS *****************************************************************************************************/ /********************************************/ /* register address */ /* -------------- ----------- */ #define REGS_RESET 0x0000 #define MASTER_VOLUME 0x0200 #define HEAD_VOLUME 0x0400 #define MASTER_VOLUME_MONO 0x0600 #define RESERVED_REG_2 0x0800 #define PC_BEEP_Volume 0x0A00 #define PHONE_Volume 0x0C00 #define MIC_Volume 0x0E00 #define LINE_IN_Volume 0x1000 #define CD_Volume 0x1200 #define VIDEO_Volume 0x1400 #define AUX_Volume 0x1600 #define PCM_OUT_Volume 0x1800 #define RECORD_SELECT 0x1A00 #define RECORD_GAIN 0x1C00 #define RESERVED_REG_3 0x1E00 #define GENERAL_PURPOSE 0x2000 #define THREE_D_CONTROL_REG 0x2200 #define RESERVED_REG_4 0x2400 #define POWERDOWN_CTRL_STAT 0x2600 #define EXTEND_AUDIO_ID 0x2800 #define EXTEND_AUDIO_CTL 0x2A00 #define SAMPLE_RATE_GENERATE_1 0x2C00 #define SAMPLE_RATE_GENERATE_0 0x3200 #define JACK_SENSE 0x7200 #define SERIAL_CONFIGURATION 0x7400 #define MISC_CONTROL_BITS 0x7600 #define SAMPLE_RATE_0_Alias 0x7800 #define SAMPLE_RATE_1_Alias 0x7A00 #define VENDOR_ID_1 0x7C00 #define VENDOR_ID_2 0x7E00 /* Mask bit selections in Serial Configuration Register for accessing registers on any of the 3 codecs */ #define MASTER_Reg_Mask 0x1000 #define SLAVE1_Reg_Mask 0x2000 #define SLAVE2_Reg_Mask 0x4000 #define MASTER_SLAVE1 0x3000 #define MASTER_SLAVE2 0x5000 #define MASTER_SLAVE1_SLAVE2 0x7000 /* Macros for setting Bits 15, 14 and 13 in Slot 0 Tag Phase */ #define ENABLE_VFbit_SLOT1_SLOT2 0xE000 #define ENABLE_VFbit_SLOT1 0xC000 #define ENABLE_VFbit_STEREO 0x9800 /* TDM Timeslot Definitions */ #define TAG_PHASE 0 #define COMMAND_ADDRESS_SLOT 1 #define COMMAND_DATA_SLOT 2 #define STATUS_ADDRESS_SLOT 1 #define STATUS_DATA_SLOT 2 #define LEFT 3 #define RIGHT 4 /************************************************************************************************/ /* DM data */ /************************************************************************************************/ .SECTION /dm data1; .var rx_buf[16]; /* receive buffer */ .GLOBAL rx_buf; /* transmit buffer */ .var tx_buf[16] = ENABLE_VFbit_SLOT1_SLOT2, SERIAL_CONFIGURATION, 0x9900, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000; .GLOBAL tx_buf; /***********************************/ /* Codec Register Initializations */ /* - refer to AD1885 Data Sheet for register bit assignments */ .var Init_Codec_Registers[50] = REGS_RESET, 0xFFFF, MASTER_VOLUME, 0x0000, /* Unmute Master Volume */ HEAD_VOLUME, 0x0000, /* Adjusted Headphone Vloume */ MASTER_VOLUME_MONO, 0x8000, PC_BEEP_Volume, 0x8000, PHONE_Volume, 0x8008, MIC_Volume, 0x8048, LINE_IN_Volume, 0x8808, CD_Volume, 0x8808, VIDEO_Volume, 0x8808, AUX_Volume, 0x8808, PCM_OUT_Volume, 0x0F0F, /* Unmuted and attenuate by 10.5 dB */ RECORD_SELECT, 0x0000, /* Selected MIC IN as Record Select */ RECORD_GAIN, 0x0A0A, /* Unmuted Record Gain */ GENERAL_PURPOSE, 0x0000, THREE_D_CONTROL_REG, 0x0000, POWERDOWN_CTRL_STAT, 0x0000, EXTEND_AUDIO_ID, 0x0001, EXTEND_AUDIO_CTL, 0x0001, SAMPLE_RATE_GENERATE_1, 0xBB80, /*Sample Rate 14.875 KHz*/ SAMPLE_RATE_GENERATE_0, 0xBB80, JACK_SENSE, 0x0000, MISC_CONTROL_BITS, 0x0404, VENDOR_ID_1, 0x4144, VENDOR_ID_2, 0x5360; .var Codec_Init_Results[50]; .var RX_Status = 0x8000; /* RX Processing flag */ .GLOBAL RX_Status; .SECTION /pm program; /************************************************************************************************/ /* AD1885 HARDWARE RESET */ /* Toggle flag_7 to assert and deassert 1885_RESET */ /************************************************************************************************/ Codec_Reset: IOPG = General_Purpose_IO; AY0 = IO(DIR); AY1 = 0x008C; /* Configure PF I/O pins 2, 3, 7 as outputs */ AR = AY0 OR AY1; IO(DIR) = AR; AR = 0x0010; IO(MASKAS) = AR; /* Unmask FLAG 4 as GPIO interrupt source 0 */ AR = 0x0000; IO(FSPR) = AR; /* Select FLAG polarity as active High - NOTE: Depends on hardware implementation */ AR = 0x0000; IO(FSSR) = AR; /* Select Flag input as level sensitive */ AX1 = 0x0088; /* Assert AD1885 /RESET (active low) */ IO(FLAGC) = AX1; CNTR = 0xA0; /* AD1885 /Reset Active low for 1 usec assuming 160Mhz DSP Core CLK */ DO loop_1 until CE; /* Duration of 1 usec */ loop_1: nop; AX1 = 0x0088; /* De-assert AD1885 /RESET and turn-on PF_2 (LED_10)*/ IO(FLAGS) = AX1; CNTR = 0x4; /* Delay to allow the Codec to recover from Reset */ DO loop_2 until CE; CNTR = 0x6A40; DO loop_3 until CE; loop_3: nop; loop_2: nop; RTS; Codec_Reset.end: /************************************************************************************************/ /* SPORT0 CONTROL REGISTER PROGRAMMING */ /* Multichannel Mode, Autobuffer DMA , Early FS, Active HI FS, Fall Edge, Data=16 */ /************************************************************************************************/ Program_SPORT0_Registers: DIS int; /* Disable all interrupts */ IRPTL = 0x0; /* Clear all interrupts */ ICNTL = 0x0; /* Interrupt nesting disable */ IMASK = 0; /* Initially no interrupts */ IOPG = Interrupt_Controller_Page; /* Assign Interrupt Vector Table Priorities */ ar = 0xbb0b; io(IPR0) = ar; /* 1=Sport0 RX */ ar = 0xbbbb; /* Remainder assigned lowest priorities */ io(IPR1) = ar; io(IPR2) = ar; ar = 0xbbb2; io(IPR3) = ar; /* RESET SPORT0 & DMA */ IOPG = SPORT0_Controller_Page; /* Set IOPG for SPORT0 */ ar = 0x0000; io(SP0_TCR) = ar; io(SP0_RCR) = ar; io(SP0DR_CFG) = ar; io(SP0DT_CFG) = ar; io(SP0_MCMC1) = ar; ar = 3; io(SP0DR_IRQ) = ar; io(SP0DT_IRQ) = ar; /* Set SPORT0 frame sync divisor */ ar = 0x00FF; /* AC'97 48Khz Frame Sync with 12.288Mhz Input Clock */ io(SP0_RFSDIV) = ar; /* Set: Internal RFS, 16-bits receive, Internal clock */ ar = (IRFS + BITS16 ); /* + ICLK);*/ io(SP0_RCR) = ar; /* Set: 16-bits transmit */ ar = (BITS16); io(SP0_TCR) = ar; /* Enable MCM Transmit and Receive Channels */ ar = 0xFFFF; /* Enable 16 Channels for TX */ io(SP0_MTCS0) = ar; ar = 0x0000; /* ...disable the remaining channels */ io(SP0_MTCS1) = ar; io(SP0_MTCS2) = ar; io(SP0_MTCS3) = ar; io(SP0_MTCS4) = ar; io(SP0_MTCS5) = ar; io(SP0_MTCS6) = ar; io(SP0_MTCS7) = ar; ar = 0xFFFF; /* Enable 16 Channels for RX */ io(SP0_MRCS0) = ar; ar = 0x0000; /* ...disable the remaining channels */ io(SP0_MRCS1) = ar; io(SP0_MRCS2) = ar; io(SP0_MRCS3) = ar; io(SP0_MRCS4) = ar; io(SP0_MRCS5) = ar; io(SP0_MRCS6) = ar; io(SP0_MRCS7) = ar; /* Set MCM Configuration Reg 1 - MCM enalbled , 1 frame delay, Win size = 16 Channels */ ar = 0x0023; io(SP0_MCMC1) = ar; /* Set MCM Configuration Reg 2 */ ar = 0x000C; io(SP0_MCMC2) = ar; /* SPORT0 Interrupts Unmasked */ AY0=IMASK; AY1=0x0050; AR = AY0 or AY1; /* Clear SPORT0 TX and RX mask bits */ IMASK=AR; RTS; Program_SPORT0_Registers.end: /************************************************************************************************/ /* DMA Controller Programming For SPORT0 */ /************************************************************************************************/ Program_DMA_Controller: /* SPORT0 DMA AUTOBUFFER XMIT */ ar= 0x0010; /* Set Autobuffer */ io(SP0DT_CFG) = ar; ar = 0; /* SPORT0 TX DMA Internal Memory Page */ io(SP0DT_SRP) = ar; ar = tx_buf; /* SPORT0 TX DMA Internal Memory Address */ io(SP0DT_SRA) = ar; ar = LENGTH(tx_buf); /* SPORT0 TX DMA Internal Memory Count */ io(SP0DT_CNT) = ar; /* SPORT0 DMA AUTOBUFFER RCV */ ar= 0x0010; /* Set Autobuffer */ io(SP0DR_CFG) = ar; ar = 0; /* SPORT0 RX DMA Internal Memory Page */ io(SP0DR_SRP) = ar; ar = rx_buf; /* SPORT0 RX DMA Internal Memory Address */ io(SP0DR_SRA) = ar; ar = LENGTH(rx_buf); /* SPORT0 RX DMA Internal Memory Count */ io(SP0DR_CNT) = ar; /* ENABLE SPORT0 DMA and DIRECTION IN DMA CONFIGURATION REGISTER */ ar = 0x0011; /* Enable TX DMA */ io(SP0DT_CFG) = ar; ar = 0x0017; /* Enable RX DMA, RX Direction (mem write), RX Interrupts */ io(SP0DR_CFG) = ar; RTS; Program_DMA_Controller.end: /************************************************************************************************/ /* AD1885 Codec Initialization */ /************************************************************************************************/ AD1885_Codec_Initialization: ax0 = io(SP0_RCR); /* Enable SPORT0 RX */ ar = setbit 0 of ax0; io(SP0_RCR) = ar; ax0 = io(SP0_TCR); /* Enable SPORT0 TX */ ar = setbit 0 of ax0; io(SP0_TCR) = ar; ENA int; /* Enable Interrupts */ idle; /* Wait for a few RX interrupts to ensure SPORT is up and running */ idle; ay0 = 0x8000; Wait_Codec_Ready: ax0 = dm(rx_buf + 0); /* Get status bit 15 from AD1885 Tag - SLOT '0' */ ar =ax0 AND ay0; if eq jump Wait_Codec_Ready; AX0 = IOPG; IOPG = General_Purpose_IO; AX1 = 0x008C; /* Assert PF 3 (LED 11 on 2191 EZKIT) indicating codec-DSP communication established */ IO(FLAGS) = AX1; IOPG = AX0; /* Write Various registers of AD1885 to configre it - will read back these same registers to ensure they are properly configured */ Initialize_1885_Registers: i3 = Init_Codec_Registers; /* Pointer to codec initialization commands */ l3 = 0; CNTR = 25; ax0 = ENABLE_VFbit_SLOT1_SLOT2; dm(tx_buf + TAG_PHASE) = ax0; /* Set 'Valid Slot' bits in TAG phase for SLOTS '0', '1' , '2' */ DO Codec_Init UNTIL CE; ax0 = dm(i3, 1); /* Fetch next AD1885 register address */ dm(tx_buf + COMMAND_ADDRESS_SLOT) = ax0; /* ...put fetched codec register address into TX SLOT '1' */ ax0 = dm(i3, 1); /* Fetch register data contents */ dm(tx_buf + COMMAND_DATA_SLOT) = ax0; /* ...put fetched codec register data into TX SLOT '2' */ idle; Codec_Init: idle; /* ...wait for 2 TDM frames... */ /* Verify AD1885 register writes */ verify_reg_writes: i3 = Init_Codec_Registers; l3 = 0; i2 = Codec_Init_Results; l2 = 0; CNTR =25; ax0 = ENABLE_VFbit_SLOT1; dm(tx_buf + TAG_PHASE) = ax0; /* Set 'Valid Slot' bits in TAG phase for SLOTS '0', '1' */ Do ad1885_register_status UNTIL CE; ax0 = dm(i3,2); /* Get next AD1885 register address that is to be read */ ay0 = 0x8000; /* Set bit #15 to signify AC'97 'Read-Request' in Command address word */ ar = ax0 OR ay0; dm(tx_buf + COMMAND_ADDRESS_SLOT) = ar; /* TX value out of Command address time slot */ idle; /* Wait for 5 AC'97 frames to go by, latency in getting data from AD1885 */ idle; idle; idle; idle; ax0 = dm(rx_buf + STATUS_ADDRESS_SLOT); dm(i2,1) = ax0; ax0 = dm(rx_buf + STATUS_DATA_SLOT); ad1885_register_status: dm(i2,1) = ax0; /* Store to results buffer */ RTS; /* End of AD1885 Initialization */ AD1885_Codec_Initialization.end: /************************************************************************************************/