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.

DAC80504: Unable to get output on DAC

Part Number: DAC80504


Tool/software:

Hello,

I'm using the DAC80504RTET with the TMS320F28035MPNTEP microcontroller. When attempting to read the device ID, I received 0x00, although activity is visible on the MISO line. I also attempted to write to DAC register 0x08, but no output is observed on the analog output. I have attached my program here.

Function call Uint16 devID = spi_readFromDAC(0x01);

SPI signal capture of device ID read .

Ch0 : CS

Ch1: CLK

Ch2: MISO (SDO)

Ch3: MOSI (SDI)

Write Operation : spi_writeToDAC(0x08, 0x5555)

void spi_configureSPIAModule(void)
{
    EALLOW;

    // GPIO configuration
    GpioCtrlRegs.GPAMUX2.bit.GPIO16 = 1; // SPISIMOA (MOSI)
    GpioCtrlRegs.GPAMUX2.bit.GPIO17 = 1; // SPISOMIA (MISO)
    GpioCtrlRegs.GPAMUX2.bit.GPIO18 = 1; // SPICLKA (CLK)
    GpioCtrlRegs.GPAMUX2.bit.GPIO19 = 1; // SPISTEA (CS)

    GpioCtrlRegs.GPAPUD.bit.GPIO16 = 0;
    GpioCtrlRegs.GPAPUD.bit.GPIO17 = 0;
    GpioCtrlRegs.GPAPUD.bit.GPIO18 = 0;
    GpioCtrlRegs.GPAPUD.bit.GPIO19 = 0;

    // SPI config
    SpiaRegs.SPICCR.bit.SPISWRESET = 0;       // Hold in reset
    SpiaRegs.SPICCR.bit.SPICHAR = 7;          // 8-bit char
    SpiaRegs.SPICCR.bit.CLKPOLARITY = 1;      // CPOL = 1 (clock idle high)

    SpiaRegs.SPICTL.all = 0;
    SpiaRegs.SPICTL.bit.CLK_PHASE = 0; //CPHA=0
    SpiaRegs.SPICTL.bit.MASTER_SLAVE = 1;
    SpiaRegs.SPICTL.bit.OVERRUNINTENA = 0;
    SpiaRegs.SPICTL.bit.SPIINTENA = 0;
    SpiaRegs.SPICTL.bit.TALK = 1;

    SpiaRegs.SPIBRR = 0x007F;                 // ~468.75kHz
    SpiaRegs.SPICCR.bit.SPISWRESET = 1;       // Release SPI
    SpiaRegs.SPIPRI.bit.FREE = 1;             // Run in emulation suspend

    // Enable FIFO
    SpiaRegs.SPIFFTX.bit.SPIRST = 1;          // FIFO reset
    SpiaRegs.SPIFFTX.bit.SPIFFENA = 1;        // Enable FIFO enhancements
    SpiaRegs.SPIFFTX.bit.TXFFIL = 0;          // Interrupt level (unused)
    SpiaRegs.SPIFFTX.bit.TXFFIENA = 0;        // Disable TX FIFO interrupt
    SpiaRegs.SPIFFTX.bit.TXFFINTCLR = 1;      // Clear interrupt flag
    SpiaRegs.SPIFFTX.bit.TXFIFO = 1;          // FIFO reset again

    SpiaRegs.SPIFFRX.bit.RXFFIL = 0;
    SpiaRegs.SPIFFRX.bit.RXFFIENA = 0;

    SpiaRegs.SPIFFCT.all = 0x00;              // FIFO delay

    EDIS;
}

void spi_writeToDAC(Uint8 regAddr, Uint16 value)
{
    Uint8 cmd = regAddr & 0x0F;
    Uint8 data_msb = (value >> 8) & 0xFF;
    Uint8 data_lsb = value & 0xFF;

    // Send 3 bytes via FIFO (no gap)
    SpiaRegs.SPITXBUF = ((Uint16)cmd) << 8;
    SpiaRegs.SPITXBUF = ((Uint16)data_msb) << 8;
    SpiaRegs.SPITXBUF = ((Uint16)data_lsb) << 8;

    // Wait until transmit complete
    while (SpiaRegs.SPIFFTX.bit.TXFFST != 0);  // Wait until FIFO is empty
}

Uint16 spi_readFromDAC(Uint8 regAddr)
{
    Uint16 readMSB, readLSB;
    Uint16 dummy;
    Uint8 cmdByte = 0x80 | (regAddr & 0x0F);  // Bit 7 = 1 for read

    // Clear RX FIFO
    SpiaRegs.SPIFFRX.bit.RXFIFORESET = 0;
    SpiaRegs.SPIFFRX.bit.RXFIFORESET = 1;

    SpiaRegs.SPITXBUF = ((Uint16)cmdByte) << 8; // Byte 1
    SpiaRegs.SPITXBUF = 0x0000;                 // Byte 2
    SpiaRegs.SPITXBUF = 0x0000;                 // Byte 3

    // Wait for all 3 bytes to arrive
    while (SpiaRegs.SPIFFRX.bit.RXFFST < 3);

    dummy    = SpiaRegs.SPIRXBUF;
    readMSB  = SpiaRegs.SPIRXBUF >> 8;
    readLSB  = SpiaRegs.SPIRXBUF >> 8;


    return (readMSB << 8) | readLSB;
}

Can you please guide me with this?

  • Hello, 

    About the DAC output. You should set REF-DIV to VIO with a 3.3V VDD if you plan to use the internal reference. The max reference (including the internal reference) is VDD/2. You can also set GAIN to VIO to gain the output back up. If the reference condition is violated then the internal reference buffer shuts down and this could be the reason you are seeing no change on the output even if your write command is correct. 

    About SDO, A SPI read takes two access cycles. It looks like the screenshot you shared is the first access cycle where you are sending the read command to register 1 (DEVID). Is there any data returned on SDO if you send another command (any command, could be a write to another register, another read, or a write to the NOP register). 

    Best,

    Katlynne Jones

  • Hi,

    For reading device ID, I updated function spi_readFromDAC to send another command. You can see there is some data returned for 2nd command in below screenshot. I am still getting devID zero. Guessing I am making mistake while extracting SDO. Can you please review my code below

    Ch0 : CS

    Ch1: CLK

    Ch2: MISO (SDO)

    Ch3: MOSI (SDI)

    Uint16 spi_readFromDAC(Uint8 regAddr)
    {
    Uint16 readMSB, readLSB;
    Uint16 dummy;
    Uint8 cmdByte = 0x80 | (regAddr & 0x0F); // Bit 7 = 1 for read

    // Clear RX FIFO
    SpiaRegs.SPIFFRX.bit.RXFIFORESET = 0;
    SpiaRegs.SPIFFRX.bit.RXFIFORESET = 1;

    // Send read command (24 bits)
    SpiaRegs.SPITXBUF = ((Uint16)cmdByte) << 8; // Byte 1
    SpiaRegs.SPITXBUF = 0x0000; // Byte 2
    SpiaRegs.SPITXBUF = 0x0000; // Byte 3

    // Wait for all 3 bytes to arrive
    while (SpiaRegs.SPIFFRX.bit.RXFFST < 3);

    dummy = SpiaRegs.SPIRXBUF; // Discard received byte

    // Send dummy write (24 bits) to receive data
    SpiaRegs.SPITXBUF = 0x0000; // Byte 1
    SpiaRegs.SPITXBUF = 0x0000; // Byte 2
    SpiaRegs.SPITXBUF = 0x0000; // Byte 3

    // Wait for all 3 bytes to arrive
    while (SpiaRegs.SPIFFRX.bit.RXFFST < 3);

    // Read the received data
    readMSB = SpiaRegs.SPIRXBUF;
    readLSB = SpiaRegs.SPIRXBUF;

    // Combine MSB and LSB
    return (readMSB << 8) | readLSB;
    }

    For DAC output issue, will writing to Gain register resolve my issue.?. My REF_DIV and Gain is connected to GND. I will use internal reference and update gain register to get output voltage 0 to 5v (2.5*2).

    I tried configuring Gain register but still DAC output is at zero volt

    spi_writeToDAC(0x04, 0x1); //set GAIN=2
    spi_writeToDAC(0x08, 0xFFFF);

    void spi_writeToDAC(Uint8 regAddr, Uint16 value)
    {
    Uint8 cmd = regAddr & 0x0F;
    Uint8 data_msb = (value >> 8) & 0xFF;
    Uint8 data_lsb = value & 0xFF;

    // Send 3 bytes via FIFO (no gap)
    SpiaRegs.SPITXBUF = ((Uint16)cmd) << 8;
    SpiaRegs.SPITXBUF = ((Uint16)data_msb) << 8;
    SpiaRegs.SPITXBUF = ((Uint16)data_lsb) << 8;

    // Wait until transmit complete
    while (SpiaRegs.SPIFFTX.bit.TXFFST != 0); // Wait until FIFO is empty
    }

  • Hello, 

    Did you change your code? Originally your SPI writes were correct with data being shifted out on the rising edge of SCLK and captured on the falling edge. Not it looks like you are shifting data on the falling edge. This could be why you code is not recognizing the data that is being clocked out on SDO. You can change the FSDO bit in the status register to change which edge the DAC shifts data out on. But your controller should be shifting data out on SDI on the rising edge. 

    The data on SDO looks correct for the device ID. 

    Yes, you can update REF-DIV and BUF-GAIN in the GAIN register. The status of the HW pins just selects the default state. it's odd that it looks like the read command worked even though your data seems to be shifting on the wrong edge but try changing the edge and updating the GAIN register and output register again. 

    Best,

    Katlynne Jones

  • Katlynne,

    Now I changed CLKPOLARITY= 0, CLK_PHASE = 0 to have "Data is output on the rising edge of the SPICLK signal. Input data is latched on the falling edge of the SPICLK signal". Below is the captured signal for device ID read. Now my function is returning device ID 1 which is obviously wrong.

    Wrote to Gain register (spi_writeToDAC(0x04, 0x1);) but no output on DAC

    I have attached my code here. Is it possible to connect directly to resolve this quickly?

    spi_configureSPIAModule();
    regValue = spi_readFromDAC(0x01);
    spi_writeToDAC(0x08, 0xFFFF);
    
    void spi_configureSPIAModule(void)
    {
        EALLOW;
    
        // GPIO configuration
        GpioCtrlRegs.GPAMUX2.bit.GPIO16 = 1; // SPISIMOA (MOSI)
        GpioCtrlRegs.GPAMUX2.bit.GPIO17 = 1; // SPISOMIA (MISO)
        GpioCtrlRegs.GPAMUX2.bit.GPIO18 = 1; // SPICLKA (CLK)
        GpioCtrlRegs.GPAMUX2.bit.GPIO19 = 1; // SPISTEA (CS)
    
        GpioCtrlRegs.GPAPUD.bit.GPIO16 = 0;
        GpioCtrlRegs.GPAPUD.bit.GPIO17 = 0;
        GpioCtrlRegs.GPAPUD.bit.GPIO18 = 0;
        GpioCtrlRegs.GPAPUD.bit.GPIO19 = 0;
    
        // SPI config
        SpiaRegs.SPICCR.bit.SPISWRESET = 0;       // Hold in reset
        SpiaRegs.SPICCR.bit.SPICHAR = 7;          // 8-bit char
        SpiaRegs.SPICCR.bit.CLKPOLARITY = 0;      // Data is output on rising edge and input on falling edge
    
        SpiaRegs.SPICTL.all = 0;
        SpiaRegs.SPICTL.bit.CLK_PHASE = 0; // Data is output on the rising edge of the SPICLK signal. Input data is latched on the falling edge of the SPICLK signal
        SpiaRegs.SPICTL.bit.MASTER_SLAVE = 1;
        SpiaRegs.SPICTL.bit.OVERRUNINTENA = 0;
        SpiaRegs.SPICTL.bit.SPIINTENA = 0;
        SpiaRegs.SPICTL.bit.TALK = 1;
    
        SpiaRegs.SPIBRR = 0x007F;                 // ~468.75kHz
        SpiaRegs.SPICCR.bit.SPISWRESET = 1;       // Release SPI
        SpiaRegs.SPIPRI.bit.FREE = 1;             // Run in emulation suspend
    
        // Enable FIFO
        SpiaRegs.SPIFFTX.bit.SPIRST = 1;          // FIFO reset
        SpiaRegs.SPIFFTX.bit.SPIFFENA = 1;        // Enable FIFO enhancements
        SpiaRegs.SPIFFTX.bit.TXFFIL = 0;          // Interrupt level (unused)
        SpiaRegs.SPIFFTX.bit.TXFFIENA = 0;        // Disable TX FIFO interrupt
        SpiaRegs.SPIFFTX.bit.TXFFINTCLR = 1;      // Clear interrupt flag
        SpiaRegs.SPIFFTX.bit.TXFIFO = 1;          // FIFO reset again
    
        SpiaRegs.SPIFFRX.bit.RXFFIL = 0;
        SpiaRegs.SPIFFRX.bit.RXFFIENA = 0;
    
        SpiaRegs.SPIFFCT.all = 0x00;              // FIFO delay
    
        EDIS;
    
        spi_writeToDAC(0x04, 0x1);//GAIN =2;
    }
    
    void spi_writeToDAC(Uint8 regAddr, Uint16 value)
    {
        Uint8 cmd = regAddr & 0x0F;
        Uint8 data_msb = (value >> 8) & 0xFF;
        Uint8 data_lsb = value & 0xFF;
    
        // Send 3 bytes via FIFO (no gap)
        SpiaRegs.SPITXBUF = ((Uint16)cmd) << 8;
        SpiaRegs.SPITXBUF = ((Uint16)data_msb) << 8;
        SpiaRegs.SPITXBUF = ((Uint16)data_lsb) << 8;
    
        // Wait until transmit complete
        while (SpiaRegs.SPIFFTX.bit.TXFFST != 0);  // Wait until FIFO is empty
    }
    
    Uint16 spi_readFromDAC(Uint8 regAddr)
    {
        Uint16 readMSB, readLSB;
        Uint16 dummy;
        Uint8 cmdByte = 0x80 | (regAddr & 0x0F);  // Bit 7 = 1 for read
    
        // Clear RX FIFO
        SpiaRegs.SPIFFRX.bit.RXFIFORESET = 0;
        SpiaRegs.SPIFFRX.bit.RXFIFORESET = 1;
    
        // Send read command (24 bits)
        SpiaRegs.SPITXBUF = ((Uint16)cmdByte) << 8; // Byte 1
        SpiaRegs.SPITXBUF = 0x0000;                 // Byte 2
        SpiaRegs.SPITXBUF = 0x0000;                 // Byte 3
    
        // Wait for all 3 bytes to arrive
        while (SpiaRegs.SPIFFRX.bit.RXFFST < 3);
    
        dummy = SpiaRegs.SPIRXBUF; // Discard received byte
    
        // Send dummy write (24 bits) to receive data
        SpiaRegs.SPITXBUF = 0x0000; // Byte 1
        SpiaRegs.SPITXBUF = 0x0000; // Byte 2
        SpiaRegs.SPITXBUF = 0x0000; // Byte 3
    
        // Wait for all 3 bytes to arrive
        while (SpiaRegs.SPIFFRX.bit.RXFFST < 3);
    
        // Read the received data
        readMSB = SpiaRegs.SPIRXBUF;
        readLSB = SpiaRegs.SPIRXBUF;
    
        // Combine MSB and LSB
        return (readMSB << 8) | readLSB;
    }

  • I tweaked my spi_readFromDAC() function little bit and started getting data similar to what I see on SDO line. 

    I received 0x81 0x04 0x17 when I read Rx buffer.  So device ID = 0x0417.

    Below is screenshot of writing 0xFFFF to DAC register 0x08 (spi_writeToDAC(0x08, 0xFFFF);)

    I changed REF_DIV bit in gain register 1 and started getting voltage on output. Voltage range is 0 to 2.5V.

    Why am not getting output when REF_DIV bit is 0?

  • Hello,

    0x0417 is the correct device ID for DAC80504.

    I talked about the REF-DIV setting earlier in this chain. You have the REF-DIV pin grounded which defaults to divide by 1. This will not work for your VDD supply and the internal reference. You need to divide the reference by 2 and then set the gain to 2 to get the full-scale 0-2.5V output. 

    You should set REF-DIV to VIO with a 3.3V VDD if you plan to use the internal reference. The max reference (including the internal reference) is VDD/2. You can also set GAIN to VIO to gain the output back up. If the reference condition is violated then the internal reference buffer shuts down and this could be the reason you are seeing no change on the output even if your write command is correct. 

    Best,

    Katlynne Jones