Post Go back to editing

AD9910 - Loading the RAM data files without Eval-board

 Although it would be a fundamental question, let me ask one question. I want to know how to load the RAM data files without evaluation board.

 Above all, I want to introduce my procedures for loading the RAM data files with the evaluation board and software which were provided by Analog Device. Using evauation board and software, I successfully loaded the RAM data files and I could easily generate some ramp signals which I wanted. To be specific, several detailed conditions are mentioned below.

 - Fsystemclk = 1GHz

 - Start frequency = 250 MHz

 - End frequency = 350 MHz

 - frequency step = 0.1 MHz

 => RAM data files : 250MHz, 250.1MHz, 250.2MHz ~ 352 MHz, 352.1 MHz, 352.2 MHz

                                (# of data = 1024, I attached RAM data files which consists of Hex)

 I loaded these RAM data files using RAM I/O Window in the evaluation software. And then, Using Profiles Window, I designated each RA segment by setting Beginning and Final Address, step rate, and mode control.

 

 What I really want to know about is how I can load the RAM data files without Evaluation software and board. I want to know the similar procedure as I loaded attched text files in the RAM I/O Window when I used Eval-software. I think I might have to use SPI control pin such as SDIO, SCLK, I/O_RESET pins. Could you please let me know the detailed process for loading RAM data files?

250_350MHz.txt.zip
  • Yes, you must use the SPI pins to communicate with the device in order to load data into the RAM (see the "Load/Retrieve RAM Operation" subsection of the "RAM Control" section of the datasheet).

    The basic procedure is as follows...

    1. Write the desired start and end addresses into the RAM Profile registers. Note each RAM Profile register defines a specific RAM segment (that is, RAM address range).
    2. Apply the appropriate logic levels to the Profile pins to select a particular RAM segment. This points the internal RAM controller to the appropriate address range in the RAM.
    3. Write to SPI address 0x16 the number of 32-bit words corresponding to the address range specified by the start and end addresses in the selected Profile. Note SPI address 0x16 serves as an external gateway to/from the RAM. The RAM controller takes each 32-bit word written to (or read from) SPI address 0x16 and transfers it to (or extracts it from) the appropriate address of the RAM. Note the controller "knows" how many 32-bit words to expect based on the start/end address values stored in the selected RAM Profile register. The SPI address 0x16 "gateway" is how you load or retrieve RAM data.

    The above procedure loads up the RAM segment with your data. Now you can "play back" the RAM contents to the desired destination (DDS frequency, phase or amplitude). The datasheet explains the various RAM playback modes, which you set up by programming the appropriate SPI registers. Note RAM "playback" is different from reading the RAM contents via the SPI address 0x16 gateway. Playback operation is an internal operation that "copies" the RAM segment data to the desired internal DDS parameter (frequency/phase/amplitude) at a specified "playback rate".

  • Thank you for your reply. However, I still have several questions regarding procedures above.

    This is my actions with respect to each procedure. Could you please confirm my each action?

    1. Write the desired start and end addresses into the RAM Profile registers. Note each RAM Profile register defines a specific RAM segment (that is, RAM address range).

        -> start address (10 bit) : 00 0000 0000  (start frequency = 250MHz, 0)

        -> end address  (10 bit) : 11 1110 1000  (end frequency  = 350MHz, 1000)

        -> address step rate (16 bit) : 0000 0000 0000 1010 (ramp rate delta t = 40ns, 10)

                    

       2. Apply the appropriate logic levels to the Profile pins to select a particular RAM segment. This points the internal   

          RAM controller to the appropriate address range in the RAM.

         -> profile pins (3 bit) : 000 (Activate Profile=0 for using profile 0)

       3. Write to SPI address 0x16 the number of 32-bit words corresponding to the address range specified by the start and end addresses in the selected Profile. Note SPI address 0x16 serves as an external gateway to/from the RAM. The RAM controller takes each 32-bit word written to (or read from) SPI address 0x16 and transfers it to (or extracts it from) the appropriate address of the RAM. Note the controller "knows" how many 32-bit words to expect based on the start/end address values stored in the selected RAM Profile register. The SPI address 0x16 "gateway" is how you load or retrieve RAM data.

         -> It is hard for me to understand this procedure. I think I have to set the specified frequency range from 250 MHz to 350 MHz.

        

        ->  Could you please write the correct SPI address 0x16 [31:0] for the address range below?

        

            FTW of 250 MHz = 2147483648, 1000 0000 0000 0000 0000 0000 0000 0000

            FTW of 350 MHz = 3006477107, 1011 0011 0011 0011 0011 0011 0011 0011

       

        -> What is the number of 32-bit words ? I have two values 250MHz and 350 MHz, and total length of FTWs is 64 bit. However, the assinged RAM (0x16) is only 32 bit. How do I let the start and end address to contain the RAM (0x16).

  • First, be aware that in item #1 of your previous post, the 10-bit values are the start and end RAM address locations of the desired RAM segment. Nothing else. They have nothing to do with the frequency values.

    Item #3 is the process for getting your desired frequency words into the desired RAM segment. You have specified 1001 frequency words corresponding to address range 0 to 1000. So, you will be writing 1001 32-b words to SPI address 0x16. The 1st word will be the 32-b value corresponding to 250 MHz and the 1001-th word will be the 32-b word corresponding to 350 MHz. The 2nd through the 1000-th 32-b words are all the other desired frequencies between 250 MHz and 350 MHz. Writing all 1001-words (i.e., frequencies) to the RAM segment effectively defines the frequency sweep.

    Regarding your last question, when you select the profile for the desired RAM segment (Profile 0 in your case), the RAM controller "knows" the start and end address (0 and 1000) because of the profile selection (which you have presumably programmed prior to writing to the portal (SPI address 0x16). Hence, the controller now expects 1001 32-b words via the portal because that is what you programmed for the start and end address values in the selected profile (Profile 0).

  • hi 

    i try to operate ram mode or DRG mode without evaluation board but i failed.i tried your way above by SPI protocol using Arduino uno "micro-controller" to Operate RAM mode. my program in steps :

    1- CFR1......... {0x80,0x00,0x00,0x00} ram enable=1   to make the profile0 to be Ram-profile not single tone-profile         

    2-CFR2.........default {0x00,0x40,0x08,0x20}

    3-CFR3........ {0x1D,0x3f,0x41,0x32}......1GSbps

    4-RAM Profile registers.........{0x00,0x00,0x0a,0xfa,0x00,0x00,0x00,0x21} Write the desired start ,end and rate                                                               addresses like above adresses from 250MHz to 350MHz (0000000000 to 11 1110                                                              1000) and the rate (0000 0000 0000 1010).

    5-MASTREST

    6-CS.....LOW

    7- write the CFR1 data from the arduino to the ad9910

    8-Apply the profile pins to select the Ram-profile0........digitalWrite(prof0,LOW);
                                                                                           digitalWrite(prof1,LOW);
                                                                                           digitalWrite(prof2,LOW);

    9-write the Ram-profile0 data from the arduino to the ad9910

    10-update 

    11- write the CFR2 data from the arduino to the ad9910

    12-update 

    13-write the CFR3 data from the arduino to the ad9910

    14-update 

    15-CFR1......ram enable=0 to Write the data to the 0x16 RAM

    16-update

    17- Write the data to the 0x16 Ram like this.............tx_byte(0x16);
                                                                                      for(f=0;f<1000;f++)
                                                                                       {
                                                                                        value = (unsigned long)(round((x*pow(2,32))/1000));....FTW eq.
                                                                                        x=x+0.1;........x=250MHz +0.1 Step
                                                                                        tx_byte(value);......take first byte & transfer it
                                                                                        tx_byte(value>>8);......take second byte & transfer it
                                                                                        tx_byte(value>>16);......take third  byte & transfer it
                                                                                        tx_byte(value>>24);......take the fourth  byte & transfer it

                                                                                        }

    18-update

    19- CFR1......ram enable=1 to Operate the play-back mode

    20-update

    21-CS.....HIGH

    ////////////////////////////////////////////////////////////////////////////CODE/////////////////////////////////////////////////////////////////////////////////////////

    #define prof0 0
    #define prof1 1
    #define prof2 2
    #define MASTREST 5
    #define upd 6
    #define CS 10

    #include <SPI.h>

    unsigned char cfr1[]={0x80,0x00,0x00,0x00};                       //Step_1
    unsigned char cfr2[]={0x00,0x40,0x08,0x20};                       //Step_2
    unsigned char cfr3[]={0x1D,0x3f,0x41,0x32};                        //Step_3
    unsigned char profile0ram[]={0x00,0x00,0x0a,0xfa,0x00,0x00,0x00,0x21};                     //Step_4


    void setup()
    {
    unsigned int k,m,f;
    unsigned long value;
    float x=250;
    SPI.begin();
    pinMode(MASTREST,OUTPUT);
    pinMode(upd,OUTPUT);
    pinMode(CS,OUTPUT);
    pinMode(prof0,OUTPUT);
    pinMode(prof1,OUTPUT);
    pinMode(prof2,OUTPUT);


    digitalWrite(MASTREST,HIGH);                                                             //Step_5
    digitalWrite(MASTREST,LOW);                                                              

    digitalWrite(CS,LOW);                                                                             //Step_6


    tx_byte(0x00);                                                                                       //Step_7
    for(m=0;m<4;m++)
    tx_byte(cfr1[m]);



    digitalWrite(prof0,LOW);                                                                       //Step_8
    digitalWrite(prof1,LOW);
    digitalWrite(prof2,LOW);

    tx_byte(0x0e);                                                                                      //Step_9
    for(m=0;m<8;m++)
    tx_byte(profile0ram[m]);


    digitalWrite(upd,HIGH);                                                                       //Step_10
    digitalWrite(upd,LOW);


    tx_byte(0x01);                                                                                     //Step_11
    for(m=0;m<4;m++)
    tx_byte(cfr2[m]);

    digitalWrite(upd,HIGH);                                                                      //Step_12
    digitalWrite(upd,LOW);

    tx_byte(0x02);                                                                                    //Step_13
    for(m=0;m<4;m++)
    tx_byte(cfr3[m]);

    digitalWrite(upd,HIGH);                                                                    //Step_14
    digitalWrite(upd,LOW);

    cfr1[m]=0x00;                                                                                    //Step_15
    tx_byte(0x00);
    for(m=0;m<4;m++)
    tx_byte(cfr1[m]);

    digitalWrite(upd,HIGH);                                                                      //Step_16
    digitalWrite(upd,LOW);

    tx_byte(0x16);                                                                                     //Step_17
    for(f=0;f<1000;f++)
    {
    value = (unsigned long)(round((x*pow(2,32))/1000));
    x=x+0.1;
    tx_byte(value);
    tx_byte(value>>8);
    tx_byte(value>>16);
    tx_byte(value>>24);

    }
    digitalWrite(upd,HIGH);                                                                              //Step_18
    digitalWrite(upd,LOW);

    cfr1[m]=0x80;                                                                                              //Step_19
    tx_byte(0x00);
    for(m=0;m<4;m++)
    tx_byte(cfr1[m]);

    digitalWrite(upd,HIGH);                                                                               //Step_20
    digitalWrite(upd,LOW);



    digitalWrite(CS,HIGH);                                                                               //Step_21
    }

    void tx_byte(unsigned char tx_dat)                                      // Function for transfer data from Arduino to AD9910
    {
    SPI.transfer(tx_dat);
    }

    void loop()
    {

    }

                                                                                            

    Please help me in my project.....thank you ^_^

  • Generally, what you are doing seems reasonable.

    A couple of observations:

    1) CFR3[15]=0 is the device default setting. However, the default setting enables the divide-by-2 block at the REFCLK input, which means your system clock is operating at 500MHz (rather than the desired 1GHz). To bypass the divider, program CFR3[15]=1.

     

    2) RAM Step Rate=0x000A (10 decimal). With a 1GHz system clock, this yields a RAM address step period of 40ns. So, with 1000 RAM address locations, the entire frequency sweep lasts a mere 4us. Do you have a means to reliably observe such a brief chirp? For debugging purposes, I would recommend making the step rate value very large so that the sweep occurs slowly giving you a better chance of observing what is going on.

    Also, try writing the RAM data to Register 0x16 with RAM Enable=1. It has always been unclear to me whether this bit should be set or cleared for loading the RAM. In my opinion, given the RAM controller requires knowledge of the RAM start and end address values in the selected RAM Profile, it makes sense to have RAM Enable=1 so that the profile register is in RAM mode (rather than Single Tone mode).

    Actually, now that I think about it, you can easily verify whether the RAM Enable should be set or cleared for proper operation. Write a simple test program to load and then read back (verify) the RAM data. Then, run the test with RAM Enable=0. Repeat the test with RAM Enable=1. The method that produces a valid read back of the data is the one to use.

  • This question has been assumed as answered either offline via email or with a multi-part answer. This question has now been closed out. If you have an inquiry related to this topic please post a new question in the applicable product forum.

    Thank you,
    EZ Admin