Hi, I am trying to develop a simple loop using the ADS 8361 , C6713 DSK (with 5-6k interface) and the DAC 8831. All I want to do now is to read data in using the ADS and pass it out using the DAC. Once this runs properly I intend to put in code for a PID controller. To make this loop I have used the code from SLAA 164, and SLAA246 and a few suggestions in a previous e2e ti post.
http://e2e.ti.com/support/data_converters/precision_data_converters/f/73/p/2858/9827.aspx#9827
I read the data in using McBsp0 and write it out using McBsp1. The lines of code that write to McBsp 1 (highlighted in code below) sit in the ISR for the McBsp0 receive interrupt. I took the configurations for McBsp0 and 1 from the SLAA 164 and SLAA 246 respectively.
The problem is that when I pass in a signal (in this case a 1 Hz sinusoid) the output is the same except its jumping between two values, as shown in figure below. This was recorded using a National Instruments DAQ USB 6356 at 100,000 samples per second.
I have copied my code below. Can you please provide me any suggestions or clues about what I am doing wrong here.
/************************************************************//* FILENAME: main.c *//* DESCRIPTION: This program uses McBSP0 to read 1024 *//* samples continuously from the ADS8361 16-bit 500KSPS *//* Analog-to-Digital Converter. The samples are stored in *//* the buffer called ad_buffer. */ /* AUTHOR : DAP Application Group, T. Hendrick, Dallas *//* CREATED 2002(C) BY TEXAS INSTRUMENTS INCORPORATED. *//* VERSION: 1.0 *//************************************************************/#include "led_Mcbsp0cfg.h"
/* Header file */#include "csl.h"#include "csl_irq.h"#include "csl_mcbsp.h"#include "dsk6713.h"/*Declarations*/#define BLOCK_SZ 1 /* size of data buffer */ /*DSP/BIOS variables*/extern far MCBSP_Handle hMcbsp0;extern far MCBSP_Handle hMcbsp1;
/*Global variables*/unsigned int ad_buffer[BLOCK_SZ];unsigned short ad_buffer_A[BLOCK_SZ], ad_buffer_B[BLOCK_SZ], i=0, j=0,x=0; unsigned volatile int ad_temp;
/******************************************************************************\* Function: main()* Description: Enables McBSP1 receive interrupt and McBSP1\******************************************************************************/
void main() {
DSK6713_init(); DSK6713_rset(DSK6713_MISC, 0x03); //NOTE - McBSP 2 is on HPI Conn! IRQ_enable(IRQ_EVT_RINT0); MCBSP_start(hMcbsp0, MCBSP_RCV_START | MCBSP_SRGR_START| MCBSP_SRGR_FRAMESYNC, 0); MCBSP_start(hMcbsp1, MCBSP_XMIT_START | MCBSP_SRGR_START| MCBSP_SRGR_FRAMESYNC, 0); }
/******************************************************************************\* Function: McBSP1Rcv_ISR()* Description: McBSP0 Receive Interrupt Service Routine. Reads sample out of * receive register and stores it in array call ad_buffer. When the buffer * table is full, it resets the pointer to the beginning and flushing receive* buffers.\******************************************************************************/
void McBSP0Rcv_ISR(void){ /* Wait until a value is received then read it */ while (!MCBSP_rrdy(hMcbsp0)); ad_temp = MCBSP_read(hMcbsp0) >>2; if( (ad_temp & 0x00010000) == 0x00010000 ) { ad_buffer_A[i] = (short)(ad_temp & 0xFFFF); // WRITE DATA TO MCBSP 1 while (!MCBSP_xrdy(hMcbsp1)); MCBSP_write(hMcbsp1, ad_buffer_A[i]); i++; } else {
ad_buffer_B [i] = (short)(ad_temp & 0xFFFF);
}
if (i >= BLOCK_SZ ) /* Reset index? */ { i=0; MCBSP_read(hMcbsp0); /* Flush receive register */ MCBSP_read(hMcbsp0); /* Flush receive register */ }
/******************************************************************************\* End of main.c\******************************************************************************/
Hi Umar,
There may be something in the setup of the McBSP to the DAC8831 and/or the ADS8361. In CCS, there is an option to 'View Memory', you can also open a graph window to display the contents of ad_buffer_A. Can you please verify that the data received by the McBSP0 is actually correct?
Regards,
Tom
Hi Tom,
Yes I think the data is being read correctly into ad_buffer_A. To verify this I increased the buffer size BLOCK_SZ to 1000 so that I can see a waveform. Since I am running the ADS 8361 in mode II , the sample rate is 250 kSPS. So a buffer size of 1000 implies that I collect data for 1000 x (1/250000) = 4ms. I then passed in a 1000 Hz sine and as expected got the 4 cycles. I have pasted the screen shot below,
I guess the sharp jump after cycle three occurs because I stop the code execution while the buffer is being filled.
The DAC output carries the sine wave envelope, so I suspect the issue may be in your code translation. The data from the ADS8361 is in binary twos compliment format, while the DAC8831 expects to see straight binary data. Try X'oring your ad_buffer_a with 0x8000.
I tried the XOR method however it didn't work either. So I tried many other things just to see if the problem might be somewhere else and what I found was that if I take my original code (the one I pasted previously) and do the following changes it either works or fails completely. When it fails the output is a flat DC. Here are the changes I made,
Changed McBSP 0 frame period to 19 and frame width to 18
and McBSP 1 frame period to 17
So what I guess is that the problem is with the McBSP settings. In addition I have noticed that when I try to view the contents of ad_buffer_A I get completely invalid data. But any way as long as it outputs the data correctly I guess it is doing some thing right.
Can you please provide me some suggestions regarding how I can make it work all the time. I have copied a screen shot of the input to ADS8361 (1000 Hz sine) and the corresponding DAC8831 output.
Best regards,
Umar Khan.
Can you post your project (zip up the folder and attach)? I'll take a look at it.
Please find my project folder attached. Many thanks for your help.
7140.dskLoop.rar
Umar Khan
Sorry for the delay here - I was at NI Week 2012 the past few days (very cool, by the way) and am now back in Dallas. I'll take a look at your code over the weekend and see if we can't get this resolved by Monday.
Hi again Umar,
Are you using our DAC8831EVM for this loop? If so, let me know how you have SW1 set (towards BIP or UNI?). I added a little routine to your project to output a sine wave directly to the dac without going through the ADS8361 and it seems to be working just fine without any modifications to the McBSP settings.
Yes I am using the DAC8831 EVM with the SW1 switch towards BIP, since I eventually need a bipolar output.
Umar.
OK - that should work. Try the attached project and let me know what happens.
I tried the code you sent (main2 with the modified cdb ) but did not get the expected sine. Also the problem that the code dosen't work all the time is still there. I then tried the following,
Tried to output the cosine table
Replaced the index variable i in the line that writes data to McBSP with a constant to see if a DC is given out
Replaced the loop before McBSP initialization with a nested loop to increase the delay before McBSP is initialized
Tried all these things and the original code you sent on a Win XP PC. Uptill now I have been using a Win 7 PC with XP Mode. I suspected that the XP mode was the problem .
In all these cases I got the same result, i.e either a very noisy output or a DC. I used view graph option to see the contents of sine and cosine arrays, they look ok (pasted below).
The next figure shows the input to the ADC and the output from DAC. I passed in a 1000 Hz sine just to see if I can display it using view graph for ad_buffer_A but that data was clearly incorrect.
The output from the DAC should have been the sine as stored in sine table.
What happens if you use main.c and not Main2, I modified the cdb but I also changed the way you are masking and shifting the data. That is the code that worked for me...
Sorry for the delay. I tried your code, main.c with both modifiedCDB and the orignal CDB files but the output just continued to be a flat DC. I tried changing the highlighted line below so that ad_buffer_B is written instead of ad_buffer_A but that didn't help either,
if( (ad_temp & 0x00020000) == 0x00020000 ) { ad_buffer_B[i] = (short)(ad_temp & 0x0000FFFF); //My PID will be here // ... // WRITE DATA TO MCBSP 1 while (!MCBSP_xrdy(hMcbsp1)); MCBSP_write(hMcbsp1, ad_buffer_A[i]^0x8000); i++; }
However I kept trying lots of other things untill finally this one worked. I took my orignal dskLoop code and set the
Sample rate generator for ADC to Frame Period =20, Frame Width=19, Clock freq Divider =12,
Sample rate generator for DAC to Frame Period =17, Frame Width=1, Clock freq Divider =15,
XORed ad_buffer_A with 0x8000
I have now connected the analog input of the ADC as single ended source with 2.5V ref taken from the EVM. The input now varies from 0-5 and the DAC output from -2.5 to 2.5. It has worked every time so far and hope it continues to do so.
So I guess I can move on to implementing my PID controller and the new set of stuff like modifying the dap signal conditioning boards for matching my I/O voltage ranges and filtering requirements :)
Many thanks for you help Tom, your suggestions were really helpful.
That's great news! I'm happy to hear that you're up and running finally!