I’m using AD9102, I write and read in all register but I haven't output signal.
What is the minimum registers configuration for generate a signal?
Can it work without calibration?
In attachment the schematic.
Regards.
Valentino
AD9102
Production
The AD9102 TxDAC and waveform generator is a high performance digital-to-analog converter (DAC) integrating on-chip pattern memory for complex waveform...
Datasheet
AD9102 on Analog.com
I’m using AD9102, I write and read in all register but I haven't output signal.
What is the minimum registers configuration for generate a signal?
Can it work without calibration?
In attachment the schematic.
Regards.
Valentino
Hello Valemea,
I struggled with this as well. The documentation is appalling.
Anyway, the secret of making it work is to understand that it is only the shadow registers that are updated when you write to the register set. We used a clock frequency of 167.772160 MHz to give a 10 Hz step resolution. This is the sequence I used to output a sine wave based on the built in DDS sine wave generator:
Out_port(~ad9102_nTrigger, ad9102_nTrigger); //Trigger is off
Out_port(~sig_gen_reset,sig_gen_reset ); //reset is inactive
usleep(100); //I don't know how long it takes to come out of reset - not in data sheet
sig_gen_control_701(SPICONFIG, 0x0); //use 4 wire mode - seperate transmit and receive pins
sig_gen_control_701(POWERCONFIG,0); //set the power config
sig_gen_control_701(CLOCKCONFIG,0); //set the clock config
sig_gen_control_701(DDS_TW32, 0); //we go for 1000 Hz, in 10 Hz steps = 100. 0 in upper word
sig_gen_control_701(DDS_TW1, 100 <<8); //1kHz, but in upper 8 bits of lower tuning word
sig_gen_control_701(DAC_DGAIN, DAC_GAIN_x1 <<4); //set the gain to 1. DAC_GAINx1 = 0400h
sig_gen_control_701(DACDOF, 0); //No offset
sig_gen_control_701(WAV_CONFIG, WAVE_DDS_SINE | WAVE_prestored); //set the waveform to DDS SINE
sig_gen_control_701(PAT_TYPE,0); //repeat continuously
sig_gen_control_701(RAMUPDATE,1); //update all SPI registers --ABSOLUTELY CRUCIAL
sig_gen_control_701(PAT_STATUS,1); //start pattern
Out_port(~ad9102_nTrigger, 0); //Start Trigger
After that you can change frequency with:
sig_gen_control_701(DDS_TW32, freq_value >> 8); //put bits [23..8] in upper tuning word
sig_gen_control_701(DDS_TW1, (freq_value & 0xFF) << 8); //put bits [7..0] upper 8 bits of lower tuning word
sig_gen_control_701(RAMUPDATE,1); //update all SPI registers --ABSOLUTELY CRUCIAL
I hope this helps.
Bart
Hi -
Yes the shadow register concept is expalined in the paragraph below from the data sheet. Teh idea is for the user to be able to update shadow registers while active registers are in use generating a signal. We're looking to continuosly improve our presentation of data sheet material. We will endeavor to get a better rating than appalling in the future.
Configuration Register Update Procedure
Most SPI accessible registers are double buffered. An active register set controls operation of the AD9102 during pattern generation. A set of shadow registers stores updated register values. Register updates can be written at any time. When configuration update is complete, the user writes a 1 to the UPDATE bit in the RAMUPDATE register. The UPDATE bit arms the register set for transfer from shadow registers to active registers. The AD9102
performs this transfer automatically the next time the pattern generator is off. This procedure does not apply to the 4k × 14 SRAM. For the SRAM update procedure, see the SRAM section.
Thanks,
Larry
Hello Larry,
Yes it is true the paragraph discusses RAMUPDATE, but there is no example of a minimum control sequence in the data sheet, which I think many users would have found helpful (as evidenced by the number of people having problems with it!). My confusion initially was that I assumed (incorrectly) that the shadow registers were only used when running, and not all the time. In addition it appears that nTrigger is required to transition to start an output.
Other points that could be in the data sheet:
1. The time from reset to being able to program values, and the minimum duration of the reset pulse.
2. The format of the DAC_DGAIN value. The data sheet says -2 to +2. Is this two's compliment? I found 0x400 is x1.
3. Please be specific about the sample format saved to RAM. It appears that the sample is stored in [15:2], and not [11:0] as Table 14 claims.
A value of 0 is mid range, up to 0x1FFF <<2 denoting maximum +ve amplitude, and 0x2000 <<2 denoting maximum -ve amplitude, and
0x3FFF <<2 being one count negative from the 0 point.
4. Confirm what the Start Address means. I found that the address range programmed is 0 .. 0xFFF <<4.
5. Confirm that the output sequence goes from start address to stop address inclusive and not start address to stop address - 1.
6. Confirm that Ram Update is required both when the pattern is running, and also when it is not running.
7. Make clearer that you cannot change a pattern (eg DDS sine to RAM), unless the pattern is off first.
8. I want to clock the RAM pattern at the rising edge of the DDS MSB rate. So I set DDS_CONFIG to 0x04 (bit 2 = 1), but this does not seem to work the way I expect.
9. The meaning of the DDS_PW (Phase Offset) is not defined. It is a 16 bit number. This suggests 0- 0xFFFF is 0 - 2pi radians. However, in my tests, I found the Phase register is not set absolutely (as in the AD9834), instead the DDS_PW represents an offset from the current phase value, which is random. It is not possible (please confirm) to reset the phase to a know angle (eg 0). This means we cannot start generating at a particular phase angle - most annoying. So what is the use of this register in a single channel application?
Anyway, the device is pretty good in some areas, so thanks - but I'm sad about the Triangle Wave generation, and Phase setting lackings.
Bart
Hello Larry,
I also seem to have two other problems.
1. DDS Clock Source
I cannot make the DDS_MSB_EN work in the DDS_CONFIG register.
My assumption is that if I program the RAM to have two values, 0x1FFF <<2 and 0x2000 <<2 at 0x6000 on, I set Start_addr to 0 <<4 and Stop_addr to 1<<4, and Pattern_period to 2, then I should get a square wave. If the DDS_MSB_EN is 0, then the square wave frequency should be CLK/2 frequency. If DDS_MSB_EN = 1, then the square wave should be at the DDS/2 frequency - which is what I want.
However, the DDS_MSB_EN bit does not seem to have any effect.
2. Sawtooth Frequency
I cannot work out how to change the Sawtooth frequency. Set to Triangle, I see the generator outputting 16384 samples increasing from -max to + max, and then 16384 samples from +max to -max, and repeating this. This yields just one frequency.
I can see that I can dwell at one sample for between 1 and 64 clock cycles, but that is a very coarse approach to setting the frequency. It means you can only get 64 frequencies - the next being half of the previous one. Kind of not very useful! I had assumed (silly of me) that the part would use the phase accumulator with the linear to sine wave conversion turned off (just as the AD9834 does), and so I could get any frequency. However, I cannot figure out how to do this. I would be grateful for any help.
Can you clarify what I'm doing wrong? Thanks.
Bart
1. I've attached an example where I used the DDS MSB enable as part of generating a chirp waveform with AD9106. The SRAM contains a list of DDS tuming words. The result (included) is one sinewave cycle at each DDS frequency.
2. For SAW tooth waveforms you can only adjust teh number of samples per step.
I hope thuis helps.
Thanks,
Larry
Hello Larry,
sadly the link you included did not go anywhere. I did see your memory content. All I actually need is the very few register allocations to show how to make the RAM address use the DDS MSB as clock rather than the input clock.
Now I don't want to chirp the DDS, I want to output directly from the RAM, WITHOUT the DDS, but using the DDS_MSB as clock. (I do understand that this means I could get jitter of 1 CLK In period, but I can work around that). I have this horrible feeling that the chip does not work this way. Yet another failing of the data sheet.
Currently this is my complete initialization (sig_gen_control_701 does the work of saving to the AD9102) to get going with:
Out_port(~ad9102_nTrigger, ad9102_nTrigger); //Trigger is off
sig_gen_control_701(SPICONFIG, 0x0); //use 4 wire mode
sig_gen_control_701(PAT_STATUS,0); //stop patterns if they are on
sig_gen_control_701(POWERCONFIG,0); //set the power config
sig_gen_control_701(CLOCKCONFIG,0); //set the clock config
sig_gen_control_701(DDS_TW32, 0); //initialize with 1000 Hz, in 10 Hz steps = 100. 0 in upper word
sig_gen_control_701(DDS_TW1, 100 <<8); //1kHz, but in upper 8 bits of lower tuning word
//The important bit:
sig_gen_control_701(DDS_CONFIG, RAM_DDS_MSB_CLK); //the RAM sequence is output on the rising DDS MSB <----- this is what I do, but it has no effect (RAM_DDS_MSB_CLK = 0x04)
sig_gen_control_701(DAC_DGAIN, DAC_GAIN_x1 <<4); //set the gain to 1
sig_gen_control_701(DACDOF, 0); //No offset
sig_gen_control_701(SAW_CONFIG, SAW_TRIANGLE); //make the sawtooth a triangle, with 1 sample/step
sig_gen_control_701(WAV_CONFIG, 0); //set the waveform to output from RAM from start to stop address
sig_gen_control_701(PAT_TYPE,0); //repeat continuously
sig_gen_control_701(PAT_PERIOD,4000); //the pattern is 4000 samples long - just to experiment with
sig_gen_control_701(START_ADDR,0<<4); //set the start address to 0 - used for square wave output
sig_gen_control_701(STOP_ADDR,4000<<4); //set end address inclusive
sig_gen_control_701(DAC_CST,0); //make sure constant value is 0
sig_gen_control_701(PAT_STATUS,MEM_ACCESS); //access memory
for (n=0; n<2000; n++) sig_gen_control_701(SRAM_DATA+n,0x7fff); //output minimum value for square wave
for (n=2000; n<4000; n++) sig_gen_control_701(SRAM_DATA+n,0x8000); //output max value for square wave
sig_gen_control_701(SRAM_DATA+4000, 0); //output 0 value - just to check how start/stop address works
sig_gen_control_701(PAT_STATUS,1); //start pattern
Out_port(~ad9102_nTrigger, 0); //Trigger is on
My whole design was predicated on the chip working this way, and this is the way I read the data sheet. I am very sad that I cannot do a swept Triangle wave, and now it looks like I can't do a swept arbitrary wave either. I guess that means throwing away the board (made a 100 so far), and just using a DAC, and using the FPGA instead. I was trying to save time, but no. (As an aside this is the second AD disappointment this year. The first was major, and caused a complete extra design loop, with added component cost and loss of performance - I'm using the AD4817 op-amp, and discovered when you power it down that the +IN input gets dragged to -V, confirmed with the designer as a chip bug. Now I have to isolate the input with a relay. Blah).
regards
Bart
Hi -
If you describe a waveform you want to generate and how you want to generate it I'll get it running in the lab if the AD9102 can do it and send you the regval file.
- Larry
Hello Larry,
Thanks for getting back to me so fast.
The simplest waveform I want to generate is a swept square wave.
So Ram [0] = 0x7FFF (-ve min)
Ram [1] = 0x8000 (+ve max)
Start = 0, Stop =1, Pattern length = 2
Output directly from Ram, continuous pattern, Address counter incremented by DDS_MSB
Set DDS frequency to any value (I used 1000 Hz).
I expect a Square Wave of 500 Hz.
If this can be done, I'll be grateful!
regards
Bart
Hi Bart –
I tried this in the lab just now. It turns out the DDS output MSB can only be used as the SRAM address counter clock if the DDS Tuning word source is set to RAM data.
- Larry
Hello Larry,
well that is a great shame. The utility of the chip has been severely compromised from my point of view - not wiring the Phase accumulator contents for triangle wave generation, and not allowing variable frequency AWG seems a huge loss of capability from what should have been simple given what is already in the chip.
I would not have used the chip if I had known these things. So as an AD insider, how does one go about improving the data sheet so that instead of saying
"The SRAM address counter can be programmed to be incremented by CLKP/CLKN (default) or by the rising edge of the DDS MSB" on page 23,
and again
"Selects the SRAM address counter clock as CLKP/CLKN when set to 0x0, DDS MSB when set to 0x1." in the Pattern Control 2 register description on page 34, both of which are WRONG, to say "but ONLY when the DDS Tuning word source is set to RAM data".
The designer needed his head read, I reckon.
So now I have two significant AD fails under my belt - the ADA4817 op-amp with a chip fault that drags the +IN pin to V- when powered down, and caused a great deal of angst on our part trying to re-design a 300 MHz capable work-around, and the AD9102, which we designed in on the strength of the data sheet, built a hundred boards, and find it can't do what the data sheet says. I am cross.
- Bart