qipp
2025-11-07 744722688187eb4991c72464e2bb5e06b244fee7
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
 ///////////////////////////////////////////////////////////////////////////////////////
// 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();
}