Post Go back to editing

Sinewave from RAM with AD9102

Hi guys!

Trying to validate the AD9102 and grabbed an Arduino for the sake of simplicity.

I want to give it a LUT with 6 sine values and let the DDS run over it to produce a sign with 30 or 60MHz. Analog and digital gain are configured, tuning word, stop address and power as well.

In the wave config register I've selected DDS Output and waveform read from RAM, when setting the RUN-Bit in the PAT_STATUS register I'm getting a 60MHz sine but I can't deactivate it with a 0x0000 to the PAT_STATUS register or set anything at all.

Here's my source code of the project, maybe one can give some suggestions what I'm missing from the data sheet or sth.

#include <SPI.h>
uint16_t ramvalues[6] = { 8192,16384,16384,8192,0,0};
#define DAC_AGAIN_REG       0x0007
#define RAM_UPDATE_REG      0x001D
#define PAT_STATUS_REG      0x001E
#define PAT_DELAY_REG       0x0020
#define WAV_CONFIG_REG      0x0027
#define DAC_DGAIN_REG       0x0035
#define DDS_TW32_REG        0x003E
#define DDS_TW1_REG         0x003F
#define STOP_ADDR_REG       0x005E
#define SRAM_LOW_ADDR       0x6000
#define SRAM_HIGH_ADDR      0x6FFF
//#########################     COMMANDS #########################
#define PAT_WRITE           0x0004
#define WAV_CONFIG_RAM      0x0030
#define PAT_RUN             0x0001
#define TUNING_WORD_L       0x0000
#define TUNING_WORD_H       0x4000
#define DDS_STOP_ADDR       0x0050
#define DACAGAIN            0x4000
#define DACDGAIN            0x4000
#define START_DELAY         0x0000


void write_lookup();
uint16_t write_register(uint16_t reg, uint16_t value);

const int SPICS = 10;
const int SPIMISO = 12;
const int SPIMOSI = 11;
const int SPISCK = 13;

uint16_t adreg = 0; 
uint16_t adval = 0;
uint16_t answer = 0;


void setup() {
  Serial.begin(115200);
  digitalWrite(SPICS, HIGH);
  // start the SPI library:
  SPI.begin();
  // reduce speed
  SPI.setClockDivider(SPI_CLOCK_DIV8); 
  // initalize the  data ready and chip select pins:
  pinMode(SPIMISO, INPUT);
  pinMode(SPICS, OUTPUT);
  pinMode(SPIMOSI, OUTPUT);
  pinMode(SPISCK, OUTPUT);

  delay(100);
  write_lookup();  
}
void loop() {
  //Wait for command
  while(Serial.available() < 4);
  
  adreg = Serial.read() <<8;
  adreg += Serial.read();
  adval = Serial.read() << 8;
  adval += Serial.read();
  answer = write_register(adreg,adval);
  Serial.write(answer>>8);
  Serial.write(answer);

}

void write_lookup()
{
    write_register(PAT_STATUS_REG,PAT_WRITE);
    for( int i = 0; i <= 5 ; i++)
    {
      write_register(SRAM_LOW_ADDR+i,ramvalues[i]);
    }    
    
    // Select DDS Output / Wave from RAM
    write_register(WAV_CONFIG_REG,WAV_CONFIG_RAM);
    // Set stop address at 6 values
    write_register(STOP_ADDR_REG,DDS_STOP_ADDR);
    // Set tuning word to 0x4000000
    write_register(DDS_TW32_REG,TUNING_WORD_H);
    // No Start Delay
    write_register(PAT_DELAY_REG,START_DELAY);
    // Set analog gain
    write_register(DAC_AGAIN_REG,DACAGAIN);
    // Set digital gain
    write_register(DAC_DGAIN_REG,DACDGAIN);
    // Update Registers
    write_register(RAM_UPDATE_REG,0x0001);
    // Start pattern generation
    write_register(PAT_STATUS_REG,PAT_RUN);
}


uint16_t write_register(uint16_t reg, uint16_t value)
{   uint16_t answer;
    digitalWrite(SPICS,LOW);
    SPI.transfer16(reg);
    answer = SPI.transfer16(value);
    digitalWrite(SPICS,HIGH);
    return answer;
}

My Oscilloscope picture so far:

Parents
  • First success in using internal DDS for Sine!

    With a change in Tuning word you will receive different frequencies. Will share a minimal setup for Arduino here so everyone can enjoy a bit of C Code ;)

    But any help for SRAM values would be appreciated!

    By the way, change your Arduino to 3.3V with a mod or use a level shifter, otherwise you may burn your IC (worked for me without though)

    #include <SPI.h>
    //#########################     REGISTERS     #########################
    #define SPICONFIG_REG               0x0000
    #define POWERCONFIG_REG             0x0001
    #define CLKCONFIG_REG               0x0002
    #define REFRESISTOR_REG             0x0003
    #define DAC_AGAIN_REG               0x0007
    #define DAC_RANGE_REG               0x0008
    #define DAC_RESET_REG               0x000C
    #define CAL_CONFIG_REG              0x000D
    #define COMP_OFFSET_REG             0x000E
    #define RAM_UPDATE_REG              0x001D
    #define PAT_STATUS_REG              0x001E
    #define PAT_TYPE_REG                0x001F
    #define PAT_DELAY_REG               0x0020
    #define DAC_DOFFSET_REG             0x0025
    #define WAV_CONFIG_REG              0x0027
    #define PAT_TIMEBASE_REG            0x0028
    #define PAT_PERIOD_REG              0x0029
    #define DAC_PAT_REG                 0x002B
    #define DOUT_START_REG              0x002C
    #define DOUT_CONFIG_REG             0x002D
    #define DAC_CST_REG                 0x0031
    #define DAC_DGAIN_REG               0x0035
    #define SAW_CONFIG_REG              0x0037
    #define DDS_TW32_REG                0x003E
    #define DDS_TW1_REG                 0x003F
    #define DDS_PHASE_OFFSET_REG        0x0043
    #define TRIG_TW_SEL_REG             0x0044
    #define DDS_CONFIG_REG              0x0045
    #define TW_RAM_CONFIG_REG           0x0047
    #define START_DLY_REG               0x005C
    #define START_ADDR_REG              0x005D
    #define STOP_ADDR_REG               0x005E
    #define DDS_CYC_REG                 0x005F
    #define CFG_ERROR_REG               0x0060
    #define SRAM_LOW_ADDR               0x6000
    #define SRAM_HIGH_ADDR              0x6FFF
    //#########################     COMMANDS     #########################
    #define PAT_READ                    0x000C
    #define PAT_WRITE                   0x0004
    #define PAT_RUN                     0x0001
    
    void write_lookup();
    uint16_t write_register(uint16_t reg, uint16_t value);
    
    const int SPICS = 10;
    const int SPIMISO = 12;
    const int SPIMOSI = 11;
    const int SPISCK = 13;
    
    uint16_t adreg = 0; 
    uint16_t adval = 0;
    uint16_t answer = 0;
    
    
    void setup() {
      Serial.begin(115200);
      digitalWrite(SPICS, HIGH);
      // start the SPI library:
      SPI.begin();
      SPI.setClockDivider(SPI_CLOCK_DIV8); //Geschwindigkeit verlangsamen
      // initalize the  data ready and chip select pins:
      pinMode(SPIMISO, INPUT);
      pinMode(SPICS, OUTPUT);
      pinMode(SPIMOSI, OUTPUT);
      pinMode(SPISCK, OUTPUT);
    
      delay(100);
      write_lookup();
      // give the sensor time to set up:
      
    }
    void loop() {
      while(Serial.available() < 4);
      
      adreg = Serial.read() <<8;
      adreg += Serial.read();
      adval = Serial.read() << 8;
      adval += Serial.read();
      answer = write_register(adreg,adval);
      Serial.write(answer>>8);
      Serial.write(answer);
    
    }
    
    void write_lookup()
    {
        write_register(PAT_STATUS_REG,PAT_WRITE);
        // Set analog gain
        write_register(DAC_AGAIN_REG           ,0x4000);
        write_register(DAC_RESET_REG           ,0x1f00);
        // Set continuous
        write_register(PAT_TYPE_REG            ,0x0000);
        // Set Trigger to Start Delay in Cycles
        write_register(PAT_DELAY_REG           ,0x000E);
        // Select Internal DDS Output with prestored Sine Waveform
        write_register(WAV_CONFIG_REG          ,0x0032);
        // Set digital gain
        write_register(DAC_DGAIN_REG           ,0x4000);
        // Set Tuningword to 2AAAAA (30MHz)
        write_register(DDS_TW32_REG            ,0x2AAA);
        write_register(DDS_TW1_REG             ,0xAA00);
        // Delay only for first pattern
        write_register(TRIG_TW_SEL_REG         ,0x0002);
        // Update all registers
        write_register(RAM_UPDATE_REG,0x0001);
        // Set RUN bit to start wave generation
        write_register(PAT_STATUS_REG,PAT_RUN);
    }
    
    uint16_t write_register(uint16_t reg, uint16_t value)
    {   uint16_t answer;
        digitalWrite(SPICS,LOW);
        SPI.transfer16(reg);
        answer = SPI.transfer16(value);
        digitalWrite(SPICS,HIGH);
        return answer;
    }

  • Sorry for the delay, but you last post appeared that you had it figured out!

    To generate a sine wave DDS is the way to go. Using SRAM would give you a fairly coarse frequency resolution of fs/4096.

    Regards,

    Will

Reply Children