Initial code package commit.
[apps/c55x-digital-mic-decimation.git] / src / IdleLoop.c
1 /* ============================================================================\r
2  * Copyright (c) 2016 Texas Instruments Incorporated.\r
3  *\r
4  *  Redistribution and use in source and binary forms, with or without\r
5  *  modification, are permitted provided that the following conditions\r
6  *  are met:\r
7  *\r
8  *    Redistributions of source code must retain the above copyright\r
9  *    notice, this list of conditions and the following disclaimer.\r
10  *\r
11  *    Redistributions in binary form must reproduce the above copyright\r
12  *    notice, this list of conditions and the following disclaimer in the\r
13  *    documentation and/or other materials provided with the\r
14  *    distribution.\r
15  *\r
16  *    Neither the name of Texas Instruments Incorporated nor the names of\r
17  *    its contributors may be used to endorse or promote products derived\r
18  *    from this software without specific prior written permission.\r
19  *\r
20  *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\r
21  *  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\r
22  *  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\r
23  *  A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT\r
24  *  OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,\r
25  *  SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT\r
26  *  LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\r
27  *  DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\r
28  *  THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\r
29  *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\r
30  *  OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\r
31  *\r
32   ===============================================================================*/\r
33 \r
34 #include "stdio.h"\r
35 #include "stdlib.h"\r
36 \r
37 // CSLR include files\r
38 #include "soc.h"\r
39 #include "cslr.h"\r
40 #include "cslr_sysctrl.h"\r
41 \r
42 // CSL include files\r
43 #include "csl_i2s.h"\r
44 #include "csl_dma.h"\r
45 #include "csl_intc.h"\r
46 \r
47 // other include files\r
48 #include "pll_control.h"\r
49 #include "IdleLoop.h"\r
50 #include "pick_bits_cic.h"\r
51 #include "BlkFirDecim.h"\r
52 #include "diggain.h"\r
53 \r
54 \r
55 #define MAX_LINE_LEN                ( 80 )  /* maximum line length */\r
56 char buffer[MAX_LINE_LEN];\r
57 \r
58 \r
59 /* Circular buffers for capturing output data (debug) */\r
60 #if 1\r
61 /* Input circular data buffer left */\r
62 Uint32 inCircBufLeft[IN_CIRCBUF_LEN];\r
63 /* Input circular data buffer right */\r
64 Uint32 inCircBufRight[IN_CIRCBUF_LEN];\r
65 #endif\r
66 #if 0 \r
67 /* CIC output circular buffer */\r
68 Int32 cicOutCircBuf[CIC_OUT_CIRCBUF_LEN];\r
69 #endif\r
70 #if 0\r
71 /* FIR1 output circular buffer */\r
72 Int32 fir1OutCircBuf[FIR1_OUT_CIRCBUF_LEN];\r
73 #endif \r
74 #if 0\r
75 /* FIR2 output circular buffer */\r
76 Int32 fir2OutCircBuf[FIR2_OUT_CIRCBUF_LEN];\r
77 #endif\r
78 \r
79 /* Digital gain output circular buffer */\r
80 Int16 digGainOutCircBuf[DIGGAIN_OUT_CIRCBUF_LEN];\r
81 \r
82 \r
83 CSL_I2sHandle    hI2s;\r
84 I2S_Config        hwConfig;\r
85 \r
86 CSL_DMA_Handle dmaLeftRxHandle;\r
87 CSL_DMA_Handle dmaRightRxHandle;\r
88 CSL_DMA_Config dmaConfig;\r
89 CSL_DMA_ChannelObj dmaObj0, dmaObj1;\r
90 Uint16 dmaFrameCount = 0;\r
91 \r
92 #pragma DATA_ALIGN(i2sDmaReadBufLeft, 2);\r
93 #pragma DATA_SECTION(i2sDmaReadBufLeft, ".i2sDmaReadBufLeft")\r
94 Uint32 i2sDmaReadBufLeft[I2S_DMA_BUF_LEN];\r
95 #pragma DATA_ALIGN(i2sDmaReadBufRight, 2);\r
96 #pragma DATA_SECTION(i2sDmaReadBufRight, ".i2sDmaReadBufRight")\r
97 Uint32 i2sDmaReadBufRight[I2S_DMA_BUF_LEN];\r
98 Uint16 pingPongFlag = 0;\r
99 \r
100 /* CIC output frame */\r
101 #pragma DATA_SECTION(cicOutFrame, ".cicOutFrame")\r
102 Int32 cicOutFrame[CIC_OUT_FRAME_LEN];\r
103 \r
104 /* CIC state */\r
105 Int32 cicState[2*CIC_NS];\r
106 \r
107 /* FIR1 Coefficients (S16Q15) */\r
108 #pragma DATA_SECTION(fir1Coefs, ".fir1Coefs")\r
109 const Int16 fir1Coefs[FIR1_NUM_COEFS] = \r
110 {     -98,        0,      609,        0,    -2288,        0,     9968,    16386,     \r
111      9968,        0,    -2288,        0,      609,        0,      -98\r
112 };\r
113 \r
114 /* Delay line */\r
115 #pragma DATA_SECTION(fir1DlyBuf, ".fir1DlyBuf")\r
116 Int32 fir1DlyBuf[FIR1_NUM_COEFS+2+1]; // +2 for input samples req'd for 2 output samples computed per outer loop, +1 for index of oldest sample\r
117 \r
118 /* FIR1 Output frame */\r
119 #pragma DATA_SECTION(fir1OutFrame, ".fir1OutFrame")\r
120 Int32 fir1OutFrame[FIR1_OUT_FRAME_LEN];\r
121 \r
122 /* FIR2 Coefficients (S16Q15) */\r
123 #pragma DATA_SECTION(fir2Coefs, ".fir2Coefs")\r
124 const Int16 fir2Coefs[FIR2_NUM_COEFS] = \r
125 {      -4,        2,       10,       -3,      -27,       -2,       51,       15,\r
126       -89,      -50,      135,      114,     -185,     -222,      226,      386,    \r
127      -241,     -623,      198,      947,      -56,    -1396,     -266,     2043,\r
128       959,    -3164,    -2809,     6281,    16481,    16481,     6281,    -2809,    \r
129     -3164,      959,     2043,     -266,    -1396,      -56,      947,      198,    \r
130      -623,     -241,      386,      226,     -222,     -185,      114,      135,    \r
131       -50,      -89,       15,       51,       -2,      -27,       -3,       10,        \r
132         2,       -4\r
133 };\r
134 \r
135 /* Delay line */\r
136 #pragma DATA_SECTION(fir2DlyBuf, ".fir2DlyBuf")\r
137 Int32 fir2DlyBuf[FIR2_NUM_COEFS+2+1]; // +2 for input samples req'd for 2 output samples computed per outer loop, +1 for index of oldest sample\r
138 \r
139 /* FIR2 Output frame */\r
140 #pragma DATA_SECTION(fir2OutFrame, ".fir2OutFrame")\r
141 Int32 fir2OutFrame[FIR2_OUT_FRAME_LEN];\r
142 \r
143 /* Digital gain output frame */\r
144 #pragma DATA_SECTION(digGainOutFrame, ".digGainOutFrame")\r
145 Int16 digGainOutFrame[DIGGAIN_OUT_FRAME_LEN];\r
146 \r
147 //#define DIGGAIN ( (Uint16)5<<8 ) /* 1.0 (0 dB) in U16Q8 */\r
148 #define DIGGAIN ( (Uint16)10<<8 ) /* 10.0 (20 dB) in U16Q8 */\r
149 //#define DIGGAIN ( (Uint16)0x1f9f ) /* 31.6228 (30 dB) in U16Q8 */\r
150 //#define DIGGAIN ( (Uint16)100<<8 ) /* 100.0 (40 dB) in U16Q8 */\r
151 \r
152 // Clock gating for all peripherals\r
153 void ClockGatingAll(void);\r
154 \r
155 // DSP LDO Switch\r
156 // mode:    105 - set DSP LDO to 1.05V  \r
157 //            130 - set DSP LDO to 1.3V\r
158 //            other - no change\r
159 void DspLdoSwitch(int mode);\r
160 \r
161 // USB LDO Switch\r
162 // mode:    0 - disable USB LDO  \r
163 //          1 - enable USB LDO\r
164 //          other - no change\r
165 void UsbLdoSwitch(int mode);\r
166 \r
167 // GI2S and DMA initialization\r
168 CSL_Status I2sDmaInit(void);\r
169 \r
170 // user defined algorithm\r
171 void UserAlgorithm(void);\r
172 \r
173 // Put CPU in idle\r
174 void UserIdle(void);\r
175 \r
176 // DMA ISR\r
177 interrupt void DmaIsr(void);\r
178 \r
179 void main(void)\r
180 {\r
181 \r
182     CSL_Status status;\r
183     \r
184     printf("Start the IdleLoop\n");\r
185     \r
186     /* Clock gate all peripherals */\r
187     ClockGatingAll();\r
188     \r
189     /* Set DSP LDO to desired output voltage */\r
190     DspLdoSwitch(DSP_LDO);\r
191 \r
192     /* Set the PLL to pll_mhz */\r
193     status = pll_sample(PLL_MHZ);\r
194     if (status != CSL_SOK)\r
195     {\r
196         printf("ERROR: Unable to set PLL\n");\r
197         exit(1);\r
198     }\r
199     \r
200     /* Turn off the USB LDO */\r
201     UsbLdoSwitch(0);\r
202 \r
203     /* Initialize I2S and DMA engine */\r
204     status = I2sDmaInit();\r
205     if (status != CSL_SOK)\r
206     {\r
207         printf("ERROR: Unable to initialize I2S and DMA\n");\r
208         exit(1);\r
209     }\r
210     \r
211     /* SP0 Mode 1 (I2S0 and GP[5:4]) */\r
212     CSL_FINST(CSL_SYSCTRL_REGS->EBSR, SYS_EBSR_SP0MODE, MODE1);\r
213     /* SP1 Mode 1 (I2S1 and GP[11:10]) */\r
214     CSL_FINST(CSL_SYSCTRL_REGS->EBSR, SYS_EBSR_SP1MODE, MODE1);\r
215     /* PP Mode 1 (SPI, GPIO[17:12], UART, and I2S2) */\r
216     CSL_FINST(CSL_SYSCTRL_REGS->EBSR, SYS_EBSR_PPMODE, MODE1);\r
217 \r
218     /* Configure PCGCR1 & PCGCR2 */\r
219     CSL_FINS(CSL_SYSCTRL_REGS->PCGCR2, SYS_PCGCR2_DMA1CG, CSL_SYS_PCGCR2_DMA1CG_DISABLED);\r
220     CSL_FINS(CSL_SYSCTRL_REGS->PCGCR2, SYS_PCGCR2_DMA2CG, CSL_SYS_PCGCR2_DMA2CG_DISABLED);\r
221     CSL_FINS(CSL_SYSCTRL_REGS->PCGCR2, SYS_PCGCR2_DMA3CG, CSL_SYS_PCGCR2_DMA3CG_DISABLED);\r
222 \r
223     /* Set CPUI, DPORTI, IPORTI, XPORT and HWAI in ICR */\r
224     *(volatile ioport Uint16 *)(0x0001) = (0x000E | 1<<0 | 1<<5 | 1<<6 | 1<<8 | 1<<9);\r
225 \r
226     while (1)\r
227     {\r
228         /* Perform your algorithm here */\r
229         UserAlgorithm();\r
230 \r
231 #if 1\r
232         /* Set CPU to Idle */\r
233         UserIdle();\r
234 #endif\r
235     }\r
236 }\r
237 \r
238 // Clock gating for all peripherals\r
239 void ClockGatingAll(void)\r
240 {\r
241     Uint16 pcgcr_value;\r
242     //Uint16 clkstop_value;\r
243     //Uint16 status;\r
244 \r
245     // enable the MPORT and disable HWA\r
246     *(volatile ioport unsigned int *)0x0001 = 0x020E;\r
247     asm("   idle");\r
248     \r
249     // set PCGCR1\r
250     pcgcr_value = 0; \r
251     // clock gating SPI\r
252     pcgcr_value |= CSL_FMKT(SYS_PCGCR1_SPICG, DISABLED);\r
253     // clock gating SD/MMC\r
254     pcgcr_value |= CSL_FMKT(SYS_PCGCR1_MMCSD0CG, DISABLED);\r
255     pcgcr_value |= CSL_FMKT(SYS_PCGCR1_MMCSD1CG, DISABLED);\r
256 \r
257     // clock gating UART\r
258     pcgcr_value |= CSL_FMKT(SYS_PCGCR1_UARTCG, DISABLED);\r
259 \r
260 \r
261     // clock gating EMIF\r
262     pcgcr_value |= CSL_FMKT(SYS_PCGCR1_EMIFCG, DISABLED);\r
263 \r
264     // clock gating I2S I2S 0\r
265     pcgcr_value |= CSL_FMKT(SYS_PCGCR1_I2S0CG, DISABLED);\r
266     // clock gating I2S I2S 1\r
267    // pcgcr_value |= CSL_FMKT(SYS_PCGCR1_I2S1CG, DISABLED);\r
268     // clock gating I2S I2S 2\r
269     pcgcr_value |= CSL_FMKT(SYS_PCGCR1_I2S2CG, DISABLED);\r
270     // clock gating I2S I2S 3\r
271     pcgcr_value |= CSL_FMKT(SYS_PCGCR1_I2S3CG, DISABLED);\r
272 \r
273     // clock gating DMA0\r
274     pcgcr_value |= CSL_FMKT(SYS_PCGCR1_DMA0CG, DISABLED);\r
275 \r
276         // clock gating Timer 0\r
277     pcgcr_value |= CSL_FMKT(SYS_PCGCR1_TMR0CG, DISABLED);\r
278     // clock gating Timer 1\r
279     pcgcr_value |= CSL_FMKT(SYS_PCGCR1_TMR1CG, DISABLED);\r
280     // clock gating Timer 2\r
281     pcgcr_value |= CSL_FMKT(SYS_PCGCR1_TMR2CG, DISABLED);\r
282 \r
283     // clock gating I2C\r
284     pcgcr_value |= CSL_FMKT(SYS_PCGCR1_I2CCG, DISABLED);\r
285 \r
286         // write to PCGCR1\r
287     CSL_FSET(CSL_SYSCTRL_REGS->PCGCR1, 15, 0, pcgcr_value);\r
288     \r
289     // set PCGCR2\r
290     pcgcr_value = 0; \r
291     // clock gating LCD\r
292  //  pcgcr_value |= CSL_FMKT(SYS_PCGCR2_LCDCG, DISABLED);\r
293 \r
294     // clock gating SAR\r
295     pcgcr_value |= CSL_FMKT(SYS_PCGCR2_SARCG, DISABLED);\r
296 \r
297     // clock gating DMA1\r
298     pcgcr_value |= CSL_FMKT(SYS_PCGCR2_DMA1CG, DISABLED);\r
299     // clock gating DMA2\r
300     pcgcr_value |= CSL_FMKT(SYS_PCGCR2_DMA2CG, DISABLED);\r
301     // clock gating DMA3\r
302     pcgcr_value |= CSL_FMKT(SYS_PCGCR2_DMA3CG, DISABLED);\r
303 \r
304     // clock gating analog registers\r
305     pcgcr_value |= CSL_FMKT(SYS_PCGCR2_ANAREGCG, DISABLED);\r
306 \r
307         // clock gating USB\r
308     pcgcr_value |= CSL_FMKT(SYS_PCGCR2_USBCG, DISABLED);\r
309 \r
310     // write to PCGCR2\r
311     CSL_FSET(CSL_SYSCTRL_REGS->PCGCR2, 15, 0, pcgcr_value);\r
312     \r
313     // turn off the XF\r
314     // set bit 13 of ST1_55 to 0\r
315     asm("    bit(ST1, #ST1_XF) = #0");\r
316 \r
317 #if 0\r
318     // set all GPIO pins to be output and low to save power\r
319     // set the GPIO pin 0 - 15 to output, set SYS_GPIO_DIR0 (0x1C06) bit 0 and 15 to 1 \r
320     *(volatile ioport unsigned int *)(0x1C06) = 0xFFFF;\r
321     // set the GPIO pin 16 - 31 to output, set SYS_GPIO_DIR1 (0x1C07) bit 0 and 15 to 1 \r
322     *(volatile ioport unsigned int *)(0x1C07) = 0xFFFF;\r
323     \r
324     // set the GPIO 0 - 15 to 0, set SYS_GPIO_DATAOUT0 (0x1C0A) bit 0 and 15 to 0\r
325     *(volatile ioport unsigned int *)(0x1C0A) = 0x0000;\r
326     // set the GPIO 16 - 31 to 0, set SYS_GPIO_DATAOUT1 (0x1C0B) bit 0 and 15 to 0\r
327     *(volatile ioport unsigned int *)(0x1C0B) = 0x0000;\r
328 #endif\r
329     \r
330 \r
331     return;\r
332 }\r
333 \r
334 // DSP LDO Switch\r
335 // mode:    105 - set DSP LDO to 1.05V  \r
336 //            130 - set DSP LDO to 1.3V\r
337 //            other - no change\r
338 void DspLdoSwitch(int mode)\r
339 {\r
340     if (mode==130)\r
341     {\r
342         /* enable the Analog Register only */\r
343         *((ioport volatile unsigned int *)0x1C03) &= ~(0x0040);\r
344         // set DSP LDO to 1.05V (clear bit 1)\r
345         *(volatile ioport unsigned int *)(0x7004) &= 0xFFFD;\r
346         /* disable the Analog Register only */\r
347         *((ioport volatile unsigned int *)0x1C03) |= 0x0040;\r
348     }\r
349     \r
350     if (mode==105)\r
351     {\r
352         /* enable the Analog Register only */\r
353         *((ioport volatile unsigned int *)0x1C03) &= ~(0x0040);\r
354         // set DSP LDO to 1.05V (set bit 1)\r
355         *(volatile ioport unsigned int *)(0x7004) |= 0x0002;\r
356         /* disable the Analog Register only */\r
357         *((ioport volatile unsigned int *)0x1C03) |= 0x0040;\r
358     }\r
359 }\r
360 \r
361 // USB LDO Switch\r
362 // mode:    0 - disable USB LDO  \r
363 //          1 - enable USB LDO\r
364 //          other - no change\r
365 void UsbLdoSwitch(int mode)\r
366 {\r
367     if (mode==0)\r
368     {\r
369         /* enable the Analog Register only */\r
370         *((ioport volatile unsigned int *)0x1C03) &= ~(0x0040);\r
371         // disable USB LDO (clear bit 0)\r
372         *(volatile ioport unsigned int *)(0x7004) &= 0xFFFE;\r
373         /* disable the Analog Register only */\r
374         *((ioport volatile unsigned int *)0x1C03) |= 0x0040;\r
375     }\r
376     \r
377     if (mode==1)\r
378     {\r
379         /* enable the Analog Register only */\r
380         *((ioport volatile unsigned int *)0x1C03) &= ~(0x0040);\r
381         // enable USB LDO (set bit 0)\r
382         *(volatile ioport unsigned int *)(0x7004) |= 0x0001;\r
383         /* disable the Analog Register only */\r
384         *((ioport volatile unsigned int *)0x1C03) |= 0x0040;\r
385     }\r
386 }\r
387 \r
388 // Address for interrupt vector table\r
389 extern void VECSTART(void); // defined in vector table\r
390 CSL_IRQ_Dispatch     dispatchTable;\r
391 // GI2S and DMA initialization\r
392 CSL_Status I2sDmaInit(void)\r
393 {\r
394     CSL_Status status;\r
395     Uint16 ifrValue;\r
396 \r
397     // set up DMA INT and ISR\r
398     // set up dispatch table\r
399     status = IRQ_init(&dispatchTable, 0);\r
400     if(status != CSL_SOK)\r
401     {\r
402         return (status);\r
403     } else\r
404     {\r
405         printf ("INT Module Configured successfully\n");\r
406     }\r
407 \r
408     /* Configure and Enable the DMA interrupt */\r
409     IRQ_globalDisable();\r
410 \r
411     /* Clear any pending interrupts */\r
412     IRQ_clearAll();\r
413 \r
414     /* Disable all the interrupts */\r
415     IRQ_disableAll();\r
416     \r
417     // to set the interrupt vector table address\r
418     status = IRQ_setVecs((Uint32)&VECSTART);\r
419     if(status != CSL_SOK)\r
420     {\r
421         return (status);\r
422     } else\r
423     {\r
424         printf ("Get interrupt vector table successfully\n");\r
425     }\r
426     \r
427     // clear pending DMA interrupt\r
428     IRQ_clear(DMA_EVENT);\r
429     \r
430     // clear the DMA interrupt\r
431     ifrValue = CSL_SYSCTRL_REGS->DMAIFR;\r
432     CSL_SYSCTRL_REGS->DMAIFR |= ifrValue;\r
433 \r
434     // plug in DMA ISR\r
435     IRQ_plug(DMA_EVENT, &DmaIsr);\r
436     \r
437     // enable DMA interrupt\r
438     IRQ_enable(DMA_EVENT);\r
439 \r
440     // enable global interrupt\r
441     IRQ_globalEnable();\r
442 \r
443 \r
444     // DMA engine initialization\r
445     // Open the device with instance 0 (digital mic connected to I2S0 on C5515 EVM)\r
446     hI2s = I2S_open(I2S_INSTANCE0, DMA_POLLED, I2S_CHAN_STEREO);\r
447     if(NULL == hI2s)\r
448     {\r
449         status = CSL_ESYS_FAIL;\r
450         return (status);\r
451     }\r
452     else\r
453     {\r
454         printf ("I2S Module Instance opened successfully\n");\r
455     }\r
456 \r
457     /** Set the value for the configure structure                */\r
458     hwConfig.dataFormat     = I2S_DATAFORMAT_LJUST;\r
459     hwConfig.i2sMode        = I2S_MASTER;\r
460     hwConfig.wordLen        = I2S_WORDLEN_32;\r
461     hwConfig.signext        = I2S_SIGNEXT_ENABLE;   // don't care since 32-bit wordlength\r
462     hwConfig.datapack       = I2S_DATAPACK_DISABLE; // don't care since 32-bit wordlength\r
463     hwConfig.datadelay      = I2S_DATADELAY_ONEBIT;\r
464     hwConfig.clkPol         = I2S_RISING_EDGE;      // receive data is sampled on the rising edge\r
465     hwConfig.fsPol          = I2S_FSPOL_LOW;\r
466     hwConfig.loopBackMode   = I2S_LOOPBACK_DISABLE;\r
467     hwConfig.dataType       = I2S_STEREO_ENABLE;\r
468     //hwConfig.clkDiv         = I2S_CLKDIV32;         // 32.768e6/32 = 1.024e6 (clock to digital mic)\r
469     hwConfig.clkDiv         = I2S_CLKDIV16;         // 16.384e6/16 = 1.024e6 (clock to digital mic)\r
470     hwConfig.fsDiv          = I2S_FSDIV64;          // 64 bit clocks per frame, or 32 bit clocks per channel */\r
471     hwConfig.FError         = I2S_FSERROR_DISABLE;\r
472     hwConfig.OuError        = I2S_OUERROR_DISABLE;\r
473 \r
474     /** Configure hardware registers                            */\r
475     status = I2S_setup(hI2s, &hwConfig);\r
476     if(status != CSL_SOK)\r
477     {\r
478         return (status);\r
479     }\r
480     else\r
481     {\r
482         printf ("I2S Module Configured successfully\n");\r
483     }\r
484 \r
485     // Configure DMA0 channel 0 for I2S0 channel read\r
486     dmaConfig.pingPongMode = CSL_DMA_PING_PONG_ENABLE;\r
487     dmaConfig.autoMode     = CSL_DMA_AUTORELOAD_ENABLE;\r
488     dmaConfig.burstLen     = CSL_DMA_TXBURST_1WORD;\r
489     dmaConfig.trigger      = CSL_DMA_EVENT_TRIGGER;\r
490     dmaConfig.dmaEvt       = CSL_DMA_EVT_I2S0_RX;\r
491     dmaConfig.dmaInt       = CSL_DMA_INTERRUPT_ENABLE;\r
492     dmaConfig.chanDir      = CSL_DMA_READ;\r
493     dmaConfig.trfType      = CSL_DMA_TRANSFER_IO_MEMORY;\r
494     dmaConfig.dataLen      = I2S_DMA_BUF_LEN*4; // bytes in 32-bit word\r
495     dmaConfig.srcAddr      = (Uint32)0x2828;\r
496     dmaConfig.destAddr     = (Uint32)i2sDmaReadBufLeft;\r
497 \r
498     // DMA initialization\r
499     status = DMA_init();\r
500     if (status != CSL_SOK)\r
501     {\r
502         printf("DMA_init() Failed \n");\r
503         dmaLeftRxHandle = NULL;\r
504         dmaRightRxHandle = NULL;\r
505         return status;\r
506     }\r
507 \r
508     // Open DMA0 channel 0 for I2S0 channel read\r
509     dmaLeftRxHandle = DMA_open(CSL_DMA_CHAN0, &dmaObj0, &status);\r
510     if (dmaLeftRxHandle == NULL)\r
511     {\r
512         printf("DMA_open CH0 Failed \n");\r
513         dmaLeftRxHandle = NULL;\r
514     }\r
515 \r
516     status = DMA_config(dmaLeftRxHandle, &dmaConfig);\r
517     if (status != CSL_SOK)\r
518     {\r
519         printf("DMA_config CH0 Failed \n");\r
520         dmaLeftRxHandle = NULL;\r
521     }\r
522 \r
523    /* Configure DMA0 channel 1 for I2S0 channel read */\r
524     dmaConfig.pingPongMode = CSL_DMA_PING_PONG_ENABLE;\r
525     dmaConfig.autoMode     = CSL_DMA_AUTORELOAD_ENABLE;\r
526     dmaConfig.burstLen     = CSL_DMA_TXBURST_1WORD;\r
527     dmaConfig.trigger      = CSL_DMA_EVENT_TRIGGER;\r
528     dmaConfig.dmaEvt       = CSL_DMA_EVT_I2S0_RX;\r
529     dmaConfig.dmaInt       = CSL_DMA_INTERRUPT_ENABLE;\r
530     dmaConfig.chanDir      = CSL_DMA_READ;\r
531     dmaConfig.trfType      = CSL_DMA_TRANSFER_IO_MEMORY;\r
532     dmaConfig.dataLen      = I2S_DMA_BUF_LEN*4; // bytes in 32-bit word\r
533     dmaConfig.srcAddr      = (Uint32)0x282C;\r
534     dmaConfig.destAddr     = (Uint32)i2sDmaReadBufRight;\r
535 \r
536     // Open DMA0 channel 1 for I2S0 channel read\r
537     dmaRightRxHandle = DMA_open(CSL_DMA_CHAN1, &dmaObj1, &status);\r
538     if (dmaRightRxHandle == NULL)\r
539     {\r
540         printf("DMA_open CH1 Failed \n");\r
541         dmaRightRxHandle = NULL;\r
542     }\r
543 \r
544     status = DMA_config(dmaRightRxHandle, &dmaConfig);\r
545     if (status != CSL_SOK)\r
546     {\r
547         printf("DMA_config CH1 Failed \n");\r
548         dmaRightRxHandle = NULL;\r
549     }\r
550 \r
551     // enable I2S\r
552     I2S_transEnable(hI2s, TRUE);\r
553     \r
554     // Start left Rx DMA\r
555     status = DMA_start(dmaLeftRxHandle);\r
556     if (status != CSL_SOK)\r
557     {\r
558         printf("I2S Dma Left Failed!!\n");\r
559         return (status);\r
560     }\r
561     \r
562     // Start right Rx DMA\r
563     status = DMA_start(dmaRightRxHandle);\r
564     if (status != CSL_SOK)\r
565     {\r
566         printf("I2S Dma Right Failed!!\n");\r
567         return (status);\r
568     }\r
569 \r
570     return CSL_SOK;\r
571 }\r
572 \r
573 volatile long LoopCount = 0;\r
574 // user defined algorithm\r
575 void UserAlgorithm(void)\r
576 {\r
577     volatile int i, numFrame, offset;\r
578     Uint16 numOutSamps;\r
579 \r
580     if (dmaFrameCount >= 2)\r
581     {\r
582         /* Determine which frame to use ping or pong */\r
583         offset = pingPongFlag*IN_FRAME_LEN_PER_CH;\r
584 \r
585         /* Perform CIC */\r
586         pickBitsCic(&i2sDmaReadBufLeft[offset], &i2sDmaReadBufRight[offset], IN_FRAME_LEN_PER_CH, cicState, cicOutFrame, &numOutSamps);\r
587 \r
588         /* Compute FIR1 output */\r
589         blkFirDecim2(cicOutFrame, (Int16 *)fir1Coefs, fir1OutFrame, fir1DlyBuf, CIC_OUT_FRAME_LEN, FIR1_NUM_COEFS);\r
590 \r
591         /* Compute FIR2 output */\r
592         blkFirDecim2(fir1OutFrame, (Int16 *)fir2Coefs, fir2OutFrame, fir2DlyBuf, FIR1_OUT_FRAME_LEN, FIR2_NUM_COEFS);\r
593 \r
594         /* Apply digital gain */\r
595        appDiggain(fir2OutFrame, DIGGAIN, digGainOutFrame, FIR2_OUT_FRAME_LEN);\r
596 \r
597         /* Get current frame number */\r
598         numFrame = LoopCount%NUM_FRAMES_PER_CIRCBUF;\r
599 \r
600         /* Write digital gain output to circular buffer */\r
601         for (i=0; i<DIGGAIN_OUT_FRAME_LEN; i++)\r
602         {\r
603             digGainOutCircBuf[numFrame*DIGGAIN_OUT_FRAME_LEN+i] = digGainOutFrame[i];\r
604         }\r
605        \r
606 #if 0 // write input data into circular buffers\r
607         /* Copy the current frame from ping or pong frame into input circular buffers */\r
608         for (i=0; i<IN_FRAME_LEN_PER_CH; i++)\r
609         {\r
610             /* Write left channel */\r
611             inCircBufLeft[numFrame*IN_FRAME_LEN_PER_CH+i] = i2sDmaReadBufLeft[offset+i];\r
612             /* Write right channel */\r
613             inCircBufRight[numFrame*IN_FRAME_LEN_PER_CH+i] = i2sDmaReadBufRight[offset+i];\r
614         }\r
615 #endif\r
616 \r
617 #if 0 // write CIC output into circular buffers\r
618         for (i=0; i<CIC_OUT_FRAME_LEN; i++)\r
619         {\r
620             cicOutCircBuf[numFrame*CIC_OUT_FRAME_LEN+i] = cicOutFrame[i];\r
621         }\r
622 #endif        \r
623 \r
624 #if 0 // write FIR1 output into circular buffers\r
625         for (i=0; i<FIR1_OUT_FRAME_LEN; i++)\r
626         {\r
627             fir1OutCircBuf[numFrame*FIR1_OUT_FRAME_LEN+i] = fir1OutFrame[i];\r
628         }\r
629 #endif        \r
630 \r
631 #if 0 // write FIR2 output into circular buffers\r
632         /* Copy the current frame from ping or pong frame into input circular buffers */\r
633         for (i=0; i<FIR2_OUT_FRAME_LEN; i++)\r
634         {\r
635             fir2OutCircBuf[numFrame*FIR2_OUT_FRAME_LEN+i] = fir2OutFrame[i];\r
636         }\r
637 #endif        \r
638 \r
639 #if 0 // debug -- stop DMAs on frame boundary\r
640         /* Stop DMAs to get consistent DMA transfers from digital mic */\r
641         if ((pingPongFlag == 0) && (LoopCount > 500)) // 500*20e-3 = 10 sec. \r
642         {\r
643             *((ioport volatile unsigned int *)0x0C05) &= ~0x8000; // disable DMA\r
644             *((ioport volatile unsigned int *)0x0C25) &= ~0x8000; // disable DMA\r
645             while(1);\r
646         }\r
647 #endif\r
648 \r
649         /* Toggle ping/pong flag */\r
650         pingPongFlag ^= 1;\r
651         \r
652         /* Clear DMA frame count */\r
653         dmaFrameCount = 0;\r
654 \r
655         LoopCount++;\r
656     }\r
657 }\r
658 \r
659 // Put CPU in idle\r
660 void UserIdle(void)\r
661 {\r
662     /* Execute idle instruction */\r
663     asm("    idle");\r
664 }\r
665 \r
666 Uint32 dmaIntCount = 0;\r
667 // DMA ISR\r
668 interrupt void DmaIsr(void)\r
669 {\r
670     Uint16 ifrValue;\r
671 \r
672     // clear the DMA interrupt\r
673     ifrValue = CSL_SYSCTRL_REGS->DMAIFR;\r
674     CSL_SYSCTRL_REGS->DMAIFR = ifrValue;\r
675     \r
676     // wait for the DMA0 CH0 transfer to complete\r
677     // if left frame is in\r
678     if (ifrValue & 0x1)    \r
679     {\r
680         dmaFrameCount++;\r
681     }\r
682     \r
683     // wait for the DMA0 CH1 transfer to complete\r
684     // if the right frame is in\r
685     if (ifrValue & 0x2)\r
686     {\r
687         dmaFrameCount++;\r
688     }    \r
689 \r
690     dmaIntCount++;\r
691 }\r