/////////////////////////////////////////////////////////////////////////////////////// // NAME: init1939viaSPI.c (Sample-based Talkthrough) // // DATE: 02/06/10 // // PURPOSE: Programs the control registers on the AD1939 via SPI accesses. // // USAGE: This file contains the subroutines for accessing the AD1939 control // registers via SPI, and sets up the AD1939s for TDM serial communication. // //////////////////////////////////////////////////////////////////////////////////////// #include "global.h" #include "ad1939.h" #include "spi.h" // NOTE: To select ADC/DAC Sample Rate of either 48 kHz, 96 kHz or 192 kHz, choose one // of the following 3 macros to set the sample rate (only one at a time). #define USE_48_KHZ_SAMPLE_RATE //#define USE_96_KHZ_SAMPLE_RATE //#define USE_192_KHZ_SAMPLE_RATE /* Setup the SPI parameters here in a buffer first */ unsigned char ConfigParam1939 [] = { (AD1939_ADDR), DACMUTE, 0x00, (AD1939_ADDR), CLKCTRL0, DIS_ADC_DAC | INPUT256 | PLL_IN_MCLK | MCLK_OUT_OFF | PLL_PWR_DWN, (AD1939_ADDR), CLKCTRL1, DAC_CLK_PLL | ADC_CLK_PLL | DIS_VREF, #ifdef USE_48_KHZ_SAMPLE_RATE (AD1939_ADDR), DACCTRL0, DAC_FMT_I2S | DAC_BCLK_DLY_1 | DAC_SR_48K, #endif #ifdef USE_96_KHZ_SAMPLE_RATE (AD1939_ADDR), DACCTRL0, DAC_FMT_I2S | DAC_BCLK_DLY_1 | DAC_SR_96K, #endif #ifdef USE_192_KHZ_SAMPLE_RATE (AD1939_ADDR), DACCTRL0, DAC_FMT_I2S | DAC_BCLK_DLY_1 | DAC_SR_192K, #endif (AD1939_ADDR), DACCTRL1, DAC_BCLK_SLAVE| DAC_LRCLK_SLAVE | DAC_CHANNELS_2 | DAC_LATCH_MID, //Ddebug (AD1939_ADDR), DACCTRL1, DAC_BCLK_SLAVE| DAC_LRCLK_SLAVE | DAC_CHANNELS_2 | DAC_LATCH_MID, //Ddebug (AD1939_ADDR), DACCTRL2, DAC_WIDTH_24, #ifdef USE_48_KHZ_SAMPLE_RATE (AD1939_ADDR), ADCCTRL0, ADC_SR_48K, #endif #ifdef USE_96_KHZ_SAMPLE_RATE (AD1939_ADDR), ADCCTRL0, ADC_SR_96K, #endif #ifdef USE_192_KHZ_SAMPLE_RATE (AD1939_ADDR), ADCCTRL0, ADC_SR_192K, #endif (AD1939_ADDR), ADCCTRL1, ADC_LATCH_MID | ADC_FMT_I2S | ADC_BCLK_DLY_1 | ADC_WIDTH_24, (AD1939_ADDR), ADCCTRL2, ADC_BCLK_SRC_INTERNAL | ADC_BCLK_MASTER | ADC_CHANNELS_2 | ADC_LRCLK_MASTER | ADC_LRCLK_FMT_50_50|ADC_LRCLK_POL_NORM|ADC_BCLK_POL_NORM, // NDdebug (AD1939_ADDR), ADCCTRL2, ADC_BCLK_SRC_INTERNAL | ADC_BCLK_MASTER | ADC_CHANNELS_2 | ADC_LRCLK_MASTER | ADC_LRCLK_FMT_50_50|ADC_LRCLK_POL_NORM|ADC_BCLK_POL_NORM, // NDdebug (AD1939_ADDR), DACVOL_L1, DACVOL_MAX, (AD1939_ADDR), DACVOL_R1, DACVOL_MAX, (AD1939_ADDR), DACVOL_L2, DACVOL_MAX, (AD1939_ADDR), DACVOL_R2, DACVOL_MAX, (AD1939_ADDR), DACVOL_L3, DACVOL_MAX, (AD1939_ADDR), DACVOL_R3, DACVOL_MAX, (AD1939_ADDR), DACVOL_L4, DACVOL_MAX, (AD1939_ADDR), DACVOL_R4, DACVOL_MAX, (AD1939_ADDR), CLKCTRL0, DIS_ADC_DAC | PLL_IN_MCLK | MCLK_OUT_OFF | INPUT256 | PLL_PWR_UP, (AD1939_ADDR), CLKCTRL0, ENA_ADC_DAC | PLL_IN_MCLK | MCLK_OUT_OFF | INPUT256 | PLL_PWR_UP, (AD1939_ADDR), DACMUTE, 0x00, } ; /* Setup the SPI parameters here in a buffer first */ unsigned char ConfigParam1939_1 [] = { (AD1939_ADDR), DACMUTE, 0x00, (AD1939_ADDR), CLKCTRL0, DIS_ADC_DAC | INPUT256 | PLL_IN_MCLK | MCLK_OUT_OFF | PLL_PWR_DWN, (AD1939_ADDR), CLKCTRL1, DAC_CLK_PLL | ADC_CLK_PLL | DIS_VREF, #ifdef USE_48_KHZ_SAMPLE_RATE (AD1939_ADDR), DACCTRL0, DAC_FMT_I2S | DAC_BCLK_DLY_1 | DAC_SR_48K, #endif #ifdef USE_96_KHZ_SAMPLE_RATE (AD1939_ADDR), DACCTRL0, DAC_FMT_I2S | DAC_BCLK_DLY_1 | DAC_SR_96K, #endif #ifdef USE_192_KHZ_SAMPLE_RATE (AD1939_ADDR), DACCTRL0, DAC_FMT_I2S | DAC_BCLK_DLY_1 | DAC_SR_192K, #endif (AD1939_ADDR), DACCTRL1, DAC_BCLK_SLAVE| DAC_LRCLK_SLAVE | DAC_CHANNELS_2 | DAC_LATCH_MID, //Ddebug (AD1939_ADDR), DACCTRL1, DAC_BCLK_SLAVE| DAC_LRCLK_SLAVE | DAC_CHANNELS_2 | DAC_LATCH_MID, //Ddebug (AD1939_ADDR), DACCTRL2, DAC_WIDTH_24, #ifdef USE_48_KHZ_SAMPLE_RATE (AD1939_ADDR), ADCCTRL0, ADC_SR_48K, #endif #ifdef USE_96_KHZ_SAMPLE_RATE (AD1939_ADDR), ADCCTRL0, ADC_SR_96K, #endif #ifdef USE_192_KHZ_SAMPLE_RATE (AD1939_ADDR), ADCCTRL0, ADC_SR_192K, #endif (AD1939_ADDR), ADCCTRL1, ADC_LATCH_MID | ADC_FMT_I2S | ADC_BCLK_DLY_1 | ADC_WIDTH_24, (AD1939_ADDR), ADCCTRL2, ADC_BCLK_SRC_PIN | ADC_BCLK_SLAVE | ADC_CHANNELS_2 | ADC_LRCLK_SLAVE | ADC_LRCLK_FMT_50_50 | ADC_LRCLK_POL_NORM|ADC_BCLK_POL_NORM, // NDdebug (AD1939_ADDR), ADCCTRL2, ADC_BCLK_SRC_PIN | ADC_BCLK_SLAVE | ADC_CHANNELS_2 | ADC_LRCLK_SLAVE | ADC_LRCLK_FMT_50_50 | ADC_LRCLK_POL_NORM|ADC_BCLK_POL_NORM, // NDdebug // (AD1939_ADDR), ADCCTRL2, ADC_BCLK_SRC_INTERNAL | ADC_BCLK_MASTER | ADC_CHANNELS_2 | ADC_LRCLK_MASTER | ADC_LRCLK_FMT_50_50|ADC_LRCLK_POL_NORM|ADC_BCLK_POL_NORM, // NDdebug // (AD1939_ADDR), ADCCTRL2, ADC_BCLK_SRC_INTERNAL | ADC_BCLK_MASTER | ADC_CHANNELS_2 | ADC_LRCLK_MASTER | ADC_LRCLK_FMT_50_50|ADC_LRCLK_POL_NORM|ADC_BCLK_POL_NORM, // NDdebug (AD1939_ADDR), DACVOL_L1, DACVOL_MAX, (AD1939_ADDR), DACVOL_R1, DACVOL_MAX, (AD1939_ADDR), DACVOL_L2, DACVOL_MAX, (AD1939_ADDR), DACVOL_R2, DACVOL_MAX, (AD1939_ADDR), DACVOL_L3, DACVOL_MAX, (AD1939_ADDR), DACVOL_R3, DACVOL_MAX, (AD1939_ADDR), DACVOL_L4, DACVOL_MAX, (AD1939_ADDR), DACVOL_R4, DACVOL_MAX, (AD1939_ADDR), CLKCTRL0, DIS_ADC_DAC | PLL_IN_MCLK | MCLK_OUT_OFF | INPUT256 | PLL_PWR_UP, (AD1939_ADDR), CLKCTRL0, ENA_ADC_DAC | PLL_IN_MCLK | MCLK_OUT_OFF | INPUT256 | PLL_PWR_UP, (AD1939_ADDR), DACMUTE, 0x00, } ; unsigned char AD1938_Regs_Read[sizeof(ConfigParam1939) / 3]; volatile int spiFlag ; /////////////////////////////////////////////////////////////////////////////// // Set up the SPI port to access the AD1939 // Call with SPI flag to use /////////////////////////////////////////////////////////////////////////////// void SetupSPI1939(unsigned int SPI_Flag) { // Configure the SPI Control registers // First clear a few registers *pSPICTL = (TXFLSH | RXFLSH) ; *pSPIFLG = 0; // Setup the baud rate to 1MHz //*pSPIBAUD = 100; *pSPIBAUD = 25; // Setup the SPI Flag register using the Flag specified in the call *pSPIFLG = (0xF00|SPI_Flag); // Now setup the SPI Control register *pSPICTL = (SPIEN | SPIMS | WL8 | MSBF | TIMOD1 | CPHASE | CLKPL | SMLS|GM); } /////////////////////////////////////////////////////////////////////////////// // Disable the SPI Port /////////////////////////////////////////////////////////////////////////////// void DisableSPI1939(void) { *pSPICTL = (TXFLSH | RXFLSH); } /////////////////////////////////////////////////////////////////////////////// // Send a word to the AD1939 via SPI // Call with the AD1939 address, register address, register data, // and SPI flag to use /////////////////////////////////////////////////////////////////////////////// void Configure1939Register (unsigned char rwaddr,unsigned char regaddr,unsigned char regdata, unsigned int spiselect) { int i,j; unsigned char val[3]; SELECT_SPI_SLAVE(spiselect); val[0]=WR(rwaddr); val[1]=regaddr; val[2]=regdata; for(i=0;i<3;i++) { j=0; *pTXSPI = val[i] ; // Delay(136); //Wait for the SPI to indicate that it has finished. while ((*pSPISTAT & TXS)) {j++;} } j=0; //Wait for the SPI to indicate that it has finished. while (!(*pSPISTAT & SPIFE)) {j++;} Delay(10); DESELECT_SPI_SLAVE(spiselect); } /////////////////////////////////////////////////////////////////////////////// // Receive a register setting from the AD1939 // Call with the register address, and SPI flag to use; returns register data /////////////////////////////////////////////////////////////////////////////// unsigned char Get1939Register (unsigned char regaddr, unsigned int spiselect) { int i,j; unsigned char val[3]; unsigned int tmp; SELECT_SPI_SLAVE(spiselect); val[0]=RD(AD1939_ADDR); val[1]=regaddr; val[2]=0; for(i=0;i<3;i++) { j=0; *pTXSPI = val[i] ; //Wait for the SPI to indicate that it has finished. while ((*pSPISTAT & TXS)) {j++;} } j=0; //Wait for the SPI to indicate that it has finished. while (!(*pSPISTAT & SPIF)) {j++;} while (!(*pSPISTAT & SPIFE)) {j++;} Delay(10); tmp = *pRXSPI; DESELECT_SPI_SLAVE(spiselect); return tmp; } int LockCount = 0; unsigned int LockTest; /////////////////////////////////////////////////////////////////////////////// // Set up all AD1939 registers via SPI /////////////////////////////////////////////////////////////////////////////// void Init1939viaSPI() { int configSize = sizeof(ConfigParam1939); int i,j=0 ; unsigned char tmpA[sizeof(ConfigParam1939) / 3]; //Set up AD1939 SetupSPI1939(AD1939_CS); //Write register settings for(i = 0; i < configSize-6; i+=3) { Configure1939Register(ConfigParam1939[i], ConfigParam1939[i+1], ConfigParam1939[i+2], AD1939_CS); Delay(272); //Read back register settings for debugging AD1938_Regs_Read[j++] = Get1939Register(ConfigParam1939[i+1], AD1939_CS); Delay(272); } // Make sure the PLL is locked before enabling the CODEC. LockTest = Get1939Register(0x1, AD1939_CS); while (!(LockTest & AD1938_PLL_LOCK)) { LockTest = Get1939Register(CLKCTRL1, AD1939_CS); LockCount++; } for(i = configSize-6; i < configSize; i+=3) { Configure1939Register(ConfigParam1939[i], ConfigParam1939[i+1], ConfigParam1939[i+2], AD1939_CS); Delay(272*20); //Read back register settings for debugging // AD1938_Regs_Read[j++] = Get1939Register(ConfigParam1939[i+1], AD1939_CS); // Delay(272); } DisableSPI1939(); } void Init1939viaSPI1() { int configSize = sizeof(ConfigParam1939_1); int i,j=0 ; unsigned char tmpA[sizeof(ConfigParam1939_1) / 3]; //Set up AD1939 SetupSPI1939(AD1939_CS); //Write register settings for(i = 0; i < configSize-6; i+=3) { Configure1939Register(ConfigParam1939_1[i], ConfigParam1939_1[i+1], ConfigParam1939_1[i+2], AD1939_CS); Delay(272); //Read back register settings for debugging AD1938_Regs_Read[j++] = Get1939Register(ConfigParam1939_1[i+1], AD1939_CS); Delay(272); } // Make sure the PLL is locked before enabling the CODEC. LockTest = Get1939Register(0x1, AD1939_CS); while (!(LockTest & AD1938_PLL_LOCK)) { LockTest = Get1939Register(CLKCTRL1, AD1939_CS); LockCount++; } for(i = configSize-6; i < configSize; i+=3) { Configure1939Register(ConfigParam1939_1[i], ConfigParam1939_1[i+1], ConfigParam1939_1[i+2], AD1939_CS); Delay(272); //Read back register settings for debugging AD1938_Regs_Read[j++] = Get1939Register(ConfigParam1939_1[i+1], AD1939_CS); Delay(272); } DisableSPI1939(); }