Post Go back to editing

Reading the AD9959 registers

Product Number: AD9959

Hi, I'm trying to work on implementing my own driver for the AD9959 with the stm32 microcontroller. I wrote down a write function that works for now. I am able to write the wanted frequency, phase an amplitude to the respected register in order to have the right input. But for some reason , I am unable to read form the registers through my function AD9959_read() which takes on parameter the register address I want to access. Here is what am I doing for now.

1. Sending the read instruction to the device with SPI , in my case if I want to read the CFR register, it would be (10000011)

2. Set the CS pin to LOW

3. Receiving the register bytes and store it into a variable with SPI 

4. Set the CS pin to HIGH

I am using the HAL library for the SPI , so i am using the function HAL_SPI_Transmit() ad HAL_SPI_receive(). I am not sure of the step 3 and 4 since I'm not writing to the registers. For the test , I'm first doing a master reset which should put all the registers to their defautl state but when I'm trying to read for example the CSR I get 0x00 instead of 0xF0.

It seems like I'm missing something here.

Thank you for your time!

Parents
  • Hi  ,

    AD9959 has 2 phases to a serial communication cycle. 

    Phase 1 (Instruction Cycle):

    1. Take note that each bit of the instruction byte is registered on each rising edge of the SCLK (Serial Data Clock). 

    2. Instruction byte determines whether it is a read or write operation. It contains the serial address of the address register. 

    Phase 2 (Actual Data Transfer):

    1. The number of bytes being transferred during this phase is a function of the register being accesses. 

    2.  The number of additional SCLK rising edges required for data transfer and instruction byte depends on the number of bytes of the register and the serial I/O mode of operation.

    3. For example, when accessing FR2(it is 2 bytes wide), Phase 2 requires that 2 bytes be transferred, then communication cycles is then complete. 

    It can be best described in this figure. 

    All the best,

    Jules

  • Hi  , Ok I see that I indeed need to set the CS pin to Low for the read operation, I understand that each bytes is reading at a falling edge of SCLK and I understand each phase, I see from the datasheet that the t_dv time is 12ns maybe that's the key to my problem, I'll try to had a delay in my function.

    Thank you

  •  

    Ok the problem persist when using the HAL_SPI_Receive(), the received buffer returns 0. Before doing so however, I'am able to write at CSR with the value 0xF2, to enable all channel and for the single-bit serail mode (3-wire mode) I/O mode of operation. I can write to all channel a desired frequency and phase. 

    My MISO is connected to the SDIO_2 , the SCLK to the SCK pin of the board and MOSI to the SDIO_0.

    I transmit a read instruction to the board , do the bit D7 of the instruction byte is 1 and the first 4 bytes are the serial address of the register I want to read. It is implemented like this in my code:

    uint8_t read_instruction = (READ_INST | reg_addr & 0x1F) with READ_INST = 0x80

    then I set the CS pin to LOW and start the transmit and receive spi function from the HAL library but the receive buffer still have no value. 

    I can share more of my code if needed to but for now im in a dead end. It looks quite simple as a task but it's not doing a thing.

    I'll keep looking for a solution

  • Hi  ,

    I can't think of other ways that might have caused this issue. I'll try to think and let you know in case I encounter other ways which might help. 

    Also, I'm not familiar with the way STM32 works and their libraries but it might be worth checking if there are things needed for initialization and such. 

    All the best,

    Jules

  • Hi   I'm pretty sure the initiazation is done properly, but I'll check again. I manage to see the SPI signals, when I send the byte instruction for a read the MISO signal never updates for some reason

  • Ok the problem persist, I realized that when I'm sending the reading command, only the MOSI line is updating which means that my write function did not set the serial I/O in single 3 wire mode, but everytime I'm trying to read the CSR register after a master reset and a write (setting bit 1 to 1 for 3 wire single mode) I'm reading a 0xA instead of 0xF2 I dont get it. Should I let SDIO_3 pin on ground, or could I use it as a GPIO ? I have SDIO_0 for MOSI and SDIO_2 as MISO, but whatever I do, it seems I'm not writing the correct values, but I am able to write any frequencies for every channel... I just dont know what to do...

Reply
  • Ok the problem persist, I realized that when I'm sending the reading command, only the MOSI line is updating which means that my write function did not set the serial I/O in single 3 wire mode, but everytime I'm trying to read the CSR register after a master reset and a write (setting bit 1 to 1 for 3 wire single mode) I'm reading a 0xA instead of 0xF2 I dont get it. Should I let SDIO_3 pin on ground, or could I use it as a GPIO ? I have SDIO_0 for MOSI and SDIO_2 as MISO, but whatever I do, it seems I'm not writing the correct values, but I am able to write any frequencies for every channel... I just dont know what to do...

Children
  • Hi  ,

    I don't know if this can be of any help but might worth be following it:

    1. Power up the DUT and issue a master reset. A master reset places the part in single-tone mode and single-bit mode for serial programming operations. Frequency tuning words and phase offset words default to 0 at this point.

    2. Enable only one channel enable bit (Register 0x00) and disable the other channel enable bits.

    3. Using the serial I/O port, program the desired frequency tuning word (Register 0x04) and/or the phase offset word (Register 0x05) for the enabled channel.

    4. Repeat Step 2 and Step 3 for each channel.

    5. Send an I/O update signal. After an I/O update, all channels should output their programmed frequency and/or phase offset value.

    (Found in Page 19 of the data sheet)

    Also, as for your question any unused pin such as SDIO_3 should be connected to ground. 

    All the best,

    Jules

  • Hi  , Sorry for the late response, as for your answer, I did what you suggest, and well, it works fine I can write to each individual channel the desired frequency and phase. For the reading though, before doing so, I active only 1 channel as it is said in the datasheet (page 31, fifth paragraph starting for the left) But I still get no value. Here is a part of an example on page 31 :

    If i understand that correctly, for the reading operation, I must transfer not only the reading command but also the length of the registers or, as soon as the command is transfer in the next SCK cycle, the device gives back the number of the register bytes in function of the register length ?

    I'am still on single-bit 3 wire mode, and I am certain of my write function at 100% but it seems like I'm missing something big because I can properly read register values from the evaluation software, but in manual control the device I get stuck somewhere it seems.