Constant voltage output from the DAC.

Placement, modules, components and accessories; the ones that exist and the the nice-to-be's
Post Reply
atzengin
Posts: 1
Joined: Mon Jul 20, 2020 3:58 pm

Constant voltage output from the DAC.

Post by atzengin » Thu Jul 18, 2024 1:40 pm

Hi everyone,

I've been struggling with the analog outputs recently.
I have used the given example IP (AXI4-Stream Red Pitaya DAC) and my custom DAC interface.
Both gave me the same results.
I want to get a constant DC voltage between 0 and +1 volt from the analog outputs.

First, whenever I set a DAC code from the GPIO, it resets back to zero immediately at the next clock pulse.
I expected it to keep the voltage level since the GPIO still holds the same DAC code, and it's still applied to the DAC data input.

Second, I couldn't understand the relationship between the DAC code and the output voltage.
For instance, since the DAC is 14 bits, the analog range must be divided between -1V and +1V.
So, the DAC code must be related to this analog range and between 0x0000 and 0x3FFF.
Am I wrong?
Since I only wanted positive voltages, I tried to adjust the DAC code accordingly, but whatever I did, I always got bipolar outputs with positive and negative components.

Is there something in the "Amplifier & filter" block given on the 4th page of the schematics preventing only unipolar output? (https://downloads.redpitaya.com/doc//Re ... v1.0.1.pdf)

All the best,


Here is the alternative DAC module that I wrote but still getting the same results:

Code: Select all

`timescale 1ns / 1ps


module DAC_AD9767 (
    input wire clk,                  // System clock
    input wire reset_n,              // Active low reset
    input wire [31:0] data_in,       // 32-bit input data
    input wire data_valid,           // Input data valid signal
    output reg [13:0] dac_data,      // DAC data output
    output reg dac_clock,            // DAC clock (CLK2/IQCLK)
    output reg iqwrt,                // WRT1/IQWRT signal
    output reg iqsel                 // WRT2/IQSEL signal
);

    // Internal registers
    reg [13:0] ch1_data, ch2_data;
    reg [1:0] state;
    reg data_loaded;

    // State machine parameters
    localparam IDLE = 2'b00;
    localparam SEND_CH1 = 2'b01;
    localparam SEND_CH2 = 2'b10;

    // Clock divider for DAC clock
    reg clk_div;
    always @(posedge clk or negedge reset_n) begin
        if (!reset_n)
            clk_div <= 1'b0;
        else
            clk_div <= ~clk_div;
    end

    // Main state machine
    always @(posedge clk or negedge reset_n) begin
        if (!reset_n) begin
            state <= IDLE;
            ch1_data <= 14'b0;
            ch2_data <= 14'b0;
            dac_data <= 14'b0;
            iqwrt <= 1'b0;
            iqsel <= 1'b0;
            data_loaded <= 1'b0;
        end else begin
            case (state)
                IDLE: begin
                    if (data_valid) begin
                        ch1_data <= data_in[15:0];
                        ch2_data <= data_in[31:16];
                        state <= SEND_CH1;
                        data_loaded <= 1'b1;
                    end
                end
                
                SEND_CH1: begin
                    if (clk_div) begin
                        dac_data <= ch1_data;
                        iqwrt <= 1'b1;
                        iqsel <= 1'b0;
                        state <= SEND_CH2;
                    end
                end
                
                SEND_CH2: begin
                    if (clk_div) begin
                        dac_data <= ch2_data;
                        iqwrt <= 1'b1;
                        iqsel <= 1'b1;
                        state <= IDLE;
                        data_loaded <= 1'b0;
                    end
                end
                
                default: state <= IDLE;
            endcase

            // Reset iqwrt after one clock cycle
            if (iqwrt)
                iqwrt <= 1'b0;
        end
    end

    // Generate DAC clock
    always @(posedge clk or negedge reset_n) begin
        if (!reset_n)
            dac_clock <= 1'b0;
        else if (data_loaded)
            dac_clock <= clk_div;
        else
            dac_clock <= 1'b0;
    end

endmodule
And here is the C code for testing purposes:

Code: Select all

#include <stdio.h>
#include <stdint.h>
#include <unistd.h>
#include <sys/mman.h>
#include <fcntl.h>
#include <stdlib.h>
#include <time.h>

int main(int argc, char **argv)
{
  int fd;


  void *dacmap;
  char *name = "/dev/mem";

  uint32_t dac_addr   = 0x41210000;

  if((fd = open(name, O_RDWR)) < 0){
    perror("open");
    return 1;
  }
  dacmap = mmap(NULL, sysconf(_SC_PAGESIZE), PROT_WRITE, MAP_SHARED, fd, dac_addr );

  uint32_t dacVal;
  uint16_t iTemp;
  while (1)
  {
      for (uint16_t i = 0; i < 0x4000; i += 0xFFF)
      { 
          iTemp = (~i & 0x3FFF); // 14 bit
          dacVal = (iTemp << 16) | iTemp;
          *((uint32_t *)(dacmap)) = dacVal;
          printf("DAC\t:\t%d\t0x%0x\n", i, dacVal);
          //usleep(10000);
      }
  }
  munmap(dacmap, sysconf(_SC_PAGESIZE));
  return 0;
}
Here is the output signal:
https://imgur.com/a/m1Xfq5u

And here is the output signal when I set the for loop up to 0x2000. I expected to see the positive part of the output. But here it is:

https://imgur.com/a/GBKkyvx

User avatar
redpitaya
Site Admin
Posts: 940
Joined: Wed Mar 26, 2014 7:04 pm

Re: Constant voltage output from the DAC.

Post by redpitaya » Wed Jul 24, 2024 2:37 pm

Hello atzengin,
Thank you for writing on the forum.

The 14-bits of the DAC encode the full output voltage range of +-1 V, where the MSB is used as a sign bit. The positive voltages are from 0x0000 to 0x1FFF (1 V) - MSB == 0. And the negative voltages are from 0x2000 to 0x3FFF (-1 V) - MSB == 1.

There is nothing in the output analog filter that is preventing a unipolar output.

I hope this helps :).

Post Reply
jadalnie klasyczne ekskluzywne meble wypoczynkowe do salonu ekskluzywne meble tapicerowane ekskluzywne meble do sypialni ekskluzywne meble włoskie

Who is online

Users browsing this forum: No registered users and 7 guests