DSPRelated.com
Forums

C6713 ADC Code- Help Needed

Started by Richard Williams May 26, 2010
B.S.

A few things to note:
after the input_sample value is read, it is gone.
Your code is reading the input sample value twice (this is an error).
Therefore, it must be read into a location.
My answers to your questions prefixed by

---------- Original Message -----------
From: B S
To: Richard Williams
Sent: Wed, 26 May 2010 00:57:24 -0700 (PDT)
Subject: Re: [c6x] C6713 ADC Code- Help Needed

> Hi Richard,
>
> I managed to sample 1KHz sine wave and saw the FFT magnitude plot of
> the signal in CCS but there are some doubts I need to clairify in one
> code shown below. I will appreciate your help.
>
> This is an interrupt-based program. Each
> time an interrupt INT11 occurs, a sample is read from the [UTF-8?]codec’s
> ADC and written to the [UTF-8?]codec’s DAC. Furthermore, each sample is
> written to a 512-element circular buffer implemented using an array
> buffer and an index i that is incremented after each sample is stored.
> The index is reset to zero when it reaches the end of the buffer.
> Consequently, the array always contains the 512 most recent
> sample values.
>
> //Loop_intr.c Loop program using
> interrupt, output=input
> //Comm routines and support files included in C6xdskinit.c
#include "DSK6713_AIC23.h" //codec-DSK interface support

Uint32 fs=DSK6713_AIC23_FREQ_8KHZ; //set sampling rate

//following three lines missing from your code
#define DSK6713_AIC23_INPUT_MIC 0x0015
#define DSK6713_AIC23_INPUT_LINE 0x0011
Uint16 inputsource=DSK6713_AIC23_INPUT_MIC; // select input

#define BUFFER_SIZE 512 //buffer size
short buffer[BUFFER_SIZE]; //buffer where data is stored
int i = 0;

interrupt void c_int11() //interrupt service routine
{
// remove this line:output_sample((short)input_sample());//input/output
data
buffer[i] =((short)input_sample()); //store data in buffer
// add the following line
output_sample(buffer[i]);

i++; //increment buffer index
if (i==BUFFER_SIZE) i = 0; //reinit index if buffer full
return; //return from ISR
}

void main()
{
comm_intr(); //init DSK, codec, McBSP
while(1); //infinite loop
}
>
> I have
> also attached C6713dskinit.c and Vectors_intr.asm files that includes
> comm_intr() and output_sample() functions. After the initialization
> and selection/enabling of an interrupt, execution waits within the
> infinite while loop until an interrupt occurs. Upon interrupt,
> execution proceeds to the ISR c_int11, as specified in the vector file
> vectors_intr.asm. An interrupt occurs every sample period Ts = 1/Fs > 1/(8 kHz) = 0.125ms, at which time an input sample value is read from
> the [UTF-8?]codec’s ADC and then sent as output to the [UTF-8?]codec’s
DAC.
>
> 1. I am not getting the point that how
> interrupt has been executing after 0.125ms ? I couldn't found any
> where in the code where it has been defined.
Your code told the codec to sample at 8k hz.
8k hz is 0.125msec.

>
> 2. How can I know that
> how much data point does input sample have ?
The function input_sample() is defined to return a 32bit value
Your code cast that value to 16 bits via the line ...=(short)input_sample();

>
> 3. Program starts with main() and call the function comm_intr() but
> when the function interrupt void c_int11() executes ?
The interrupt function c_int11() executes every 0.125msec.
It executes at the 0.125msec rate because the codec has been told to produce a
sample at a 8k hz rate.
Note:
variable 'Uint32 fs' and 'Uint16 inputsource' are global variables, that your
code defines, that are used by the 'comm_intr()' function to setup the codec.

>
> 4. I will appreciate it
> you could explain me the routine of this program in your summarize word.

Your code tells the codec to produce a sample at a 8k hz rate.
Each sample production also produces an interrupt event.
The vectors file contains a pointer at a known location/offset
where a interrupt event from the McBSP (which is connected to the ADC on the
codec) will fetch the address of the function to be executed to handle the
interrupt event.

When the interrupt event occurs, the DSP hardware will do the following things:
1)save the address that was in the PC register.
This address is saved on the stack and the stack pointer register is incremented
to the next available address.
2)fetch the address of the c_int11() function from the vectors table and load it
into the PC register, then the c_int11() function is executed.

Note:
1)the PC register always contains the address of the next instruction to be
executed.
2)in the vectors file, the vectors table contains the address of each interrupt
event handler. Which interrupt event handler address is fetched and placed into
the PC register depends on the source of the interrupt. This interrupt vector
selection, saving of the PC, updating the PC, and stack pointer increment are
all handled by the DSP hardware.

The c_int11() function is the interrupt handler for the McBSP 'input ready
event'.

The c_int11() function performs certain actions that you will not see in the
source code.
These actions can be seen by single stepping through the c_int11() function with
the CCS debug facilities.

Specifically,
Upon entry to the c_int11() function, several registers are saved on the stack
and the stack pointer is incremented to the next available address.
Upon exit from the c_int11() function, those same several registers are restored
from the stack and the stack pointer is decremented to remove the register save
area from the stack.

Finally, the top value from the stack is placed into the PC register and the
stack pointer is decremented to remove the save area for the PC register from
the stack.

Since the register values are restored and the PC now points to the next
instruction to be executed (from before the interrupt event occurred), the
program resumes from where it was.

BTW:
(the following is only for later versions of your code, but good info to know)
having the code responding to an interrupt every 0.125msec eats up a lot of the
available CPU cycles.
A much better method is to have the EDMA perform all the processing (without
involving the CPU) until a buffer full of data is accumulated. Then the EMDA
will produce a single interrupt. The interrupt handler will then have lots of
time to process that buffer of data.
Even better is to link two EDMA configurations together along with two input
buffers. This results in the EDMA continually input data into a buffer and the
other buffer being available for the CPU to process.
This same idea about linking two EDMA configurations together and using two
buffers can also be applied to the output operations.
Then the DSP CPU only responds to a single EDMA interrupt event. At each
interrupt event, the CPU has a fresh input buffer to process.

>
> Looking forward for your response.
>
> -BS
>

------- End of Forwarded Message -------

_____________________________________