This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

DAC61404: Read and Write register

Part Number: DAC61404

Write NOP register 00ABCD
------- read NOP register 80ABCD
------- read NOP register 800000
------- read NOP register 800000

why?Error?

  • Hi,

    Each read cycle requires two command,

    1. read command access ; set read register address  

    2. dummy read cycle ; read back data from previous set address 

    In your case getting data 2nd and 3rd read NOP is expected . 

    1. Write NOP with register address to be read back

    2. Issue read NOP to get data.

    Hope it will clarify your doubts.

  • I read it three times but returned value is 800000

    I writed 80ABCD

  • Hi,

    share code 

  • FPGA  Nios II

    SPI Mode 1

    SPI CLk 1MHZ

    //------------------Write to NOP  ---------------
    addr = 0x00;
    data = 0xabcd;
    isWrite = 1;
    ret = pkgCmd(addr, data, isWrite);
    printf("写NOP寄存器 %06X\n", (unsigned int)ret);

    tx_data_array[0] = ret;
    rx_data_array[0] = 0x000000;
    SPI_OLED_WR(tx_data_array, rx_data_array, len);

    //--------------------Read From NOP--------------
    isWrite = 0;
    addr = 0x00; //地址
    ret = pkgCmd(addr, data, isWrite);
    tx_data_array[0] = ret;
    rx_data_array[0] = 0x000000;
    SPI_OLED_WR(tx_data_array, rx_data_array, len);
    SPI_OLED_WR(tx_data_array, rx_data_array, len);
    printf("------- 读 NOP 寄存器 %06X\n", (unsigned int) (rx_data_array[0]));

    /**
    * SPIWrite Func
    */
    void SPI_OLED_WR(alt_u32* tx_data, alt_u32* rx_data, int len) {
    wifi_spi_command_pc(SPI_CTRL_CARD_BASE, 0, len, tx_data, len, rx_data, 0);
    /*alt_avalon_spi_command(SPI_CTRL_CARD_BASE, 0,
    len, tx_data, len, rx_data, 0);*/
    }
    ;

    //Pkg  CMD

    alt_u32 pkgCmd(alt_u8 addr, alt_u16 data, int isWrite) {
    alt_u32 ret = 0x000000;
    ret = (addr << 16) | data; //8 + 16 = 24位
    if (isWrite == 1) {
    //写操作 最高位置0
    ret = ret & 0x7fffff;
    } else {
    //读操作 最高位置1 1000 0000 ff ff ff ff
    ret = ret | 0x800000;
    }

    return ret;
    };

    //----------------------------------spi func-----------------------------------------------------------

    /******************************************************************************
    * *
    * License Agreement *
    * author: pc
    * pcjiushizhu@qq.com
    ******************************************************************************/

    #include "alt_types.h"
    #include "wifi_spi_base.h"
    #include "altera_avalon_spi_regs.h"
    #include "altera_avalon_pio_regs.h"
    #include "io.h"
    #include "system.h"
    #include <unistd.h> // usleep()

    #define READ_NOW
    #define DELAY 1

    int wifi_spi_command_pc(alt_u32 base, alt_u32 slave,
    alt_u32 write_length, alt_u32 * write_data,
    alt_u32 read_length, alt_u32 * read_data,
    alt_u32 flags)
    {
    const alt_u32 * write_end = write_data + write_length;

    alt_u32 status;


    /* Warning: this function is not currently safe if called in a multi-threaded
    * environment, something above must perform locking to make it safe if more
    * than one thread intends to use it.
    */

    IOWR_ALTERA_AVALON_SPI_SLAVE_SEL(base, 1 << slave);

    /* Set the SSO bit (force chipselect) only if the toggle flag is not set */
    if ((flags & ALT_AVALON_SPI_COMMAND_TOGGLE_SS_N) == 0) {
    IOWR_ALTERA_AVALON_SPI_CONTROL(base, ALTERA_AVALON_SPI_CONTROL_SSO_MSK);
    }

    //2016.5.5,增加同步操作,同步线操作,拉高同步头,主程序没有改。
    IOWR(PIO_SYNC_BASE,0, 0x01);

    /*
    * Discard any stale data present in the RXDATA register, in case
    * previous communication was interrupted and stale data was left
    * behind.清空rx
    */
    IORD_32DIRECT(base,0);

    /* Keep clocking until all the data has been processed. */
    for (;;) {
    //------------发送数据 --------------
    do {
    status = IORD_8DIRECT(base,8); //读SPI的status寄存器
    } while ((status & 0x40) != 0x40); //TRDY=1表示txdata寄存器空,可以发起新的一次写入,TRDY=0则等待

    {
    if (write_data < write_end) {
    IOWR_32DIRECT(base,4,(*write_data));
    write_data++;
    }
    }
    // usleep(10); //如果优化级别高了,就需要延时了。
    //------------紧接着接收数据------------
    do {
    status = IORD_8DIRECT(base,8); //读SPI的status寄存器
    } while ((status & 0x80) != 0x80); //RRDY=1表示rxdata寄存器满,可供读取,RRDY=0则等待

    {
    alt_u32 rxdata = IORD_32DIRECT(base,0);
    (*read_data) = rxdata;
    read_data++;

    if (write_data == write_end)
    break;
    }

    // usleep(10);//如果优化级别高了,就需要延时了。
    }

    /* Wait until the interface has finished transmitting */
    do
    {
    status = IORD_ALTERA_AVALON_SPI_STATUS(base);
    }
    while ((status & ALTERA_AVALON_SPI_STATUS_TMT_MSK) == 0);

    /* Clear SSO (release chipselect) unless the caller is going to
    * keep using this chip
    */
    if ((flags & ALT_AVALON_SPI_COMMAND_MERGE) == 0){
    // int i=1000, j=1000;
    // for(i=1000;i>0;i--){
    //// for(j=1000;j>0;j--){
    //// ;
    //// }
    // }
    IOWR_ALTERA_AVALON_SPI_CONTROL(base, 0);
    // usleep(5);
    }
    //同步线操作,拉低同步头
    IOWR(PIO_SYNC_BASE,0, 0x00);
    return read_length;
    }

  • Hi, I will get back to you after reviewing code. 

  • 1st read;

    1. Write NOP with register address to be read back

    //------------------Write to NOP  ---------------
    addr = 0x00;
    data = 0xabcd;
    isWrite = 1;
    ret = pkgCmd(addr, data, isWrite);
    printf("写NOP寄存器 %06X\n", (unsigned int)ret);

    tx_data_array[0] = ret;
    rx_data_array[0] = 0x000000;
    SPI_OLED_WR(tx_data_array, rx_data_array, len);

    2. dummy read cycle ; read back data from previous set address 

    //--------------------Read From NOP--------------
    isWrite = 0;
    addr = 0x00; //地址
    ret = pkgCmd(addr, data, isWrite);
    tx_data_array[0] = ret;
    rx_data_array[0] = 0x000000;
    SPI_OLED_WR(tx_data_array, rx_data_array, len);
    SPI_OLED_WR(tx_data_array, rx_data_array, len);
    printf("------- 读 NOP 寄存器 %06X\n", (unsigned int) (rx_data_array[0]));

    2nd read;

    repeat above step 1 & 2

    3rd read;

    repeat above step 1 & 2

    please try above sequence in your code.

    Thanks