Forum Discussion

Altera_Forum's avatar
Altera_Forum
Icon for Honored Contributor rankHonored Contributor
9 years ago

connecting 4 GPIO pins to DAC using SPI interface

Hi.

I am new to altera and am interested in connecting a DAC via the GPIO pins on my development board. the DAC takes a data connection using the spi interface so I am wondering what is the best design to use. i currently have a 3-wire SPI slave with miso mosi, clock, and ssn wires exported (See attached photo). The DAC also requires a certain delay to be introduced. Do you know how to set this up in QSYS? Also, does anyone have sample code for this in NIOS II (eclipse)?

Best.

Leeor.

http://www.alteraforum.com/forum/webkit-fake-url://c0936f7a-870c-4c01-862a-90bf11529605/image.tiff

6 Replies

  • Altera_Forum's avatar
    Altera_Forum
    Icon for Honored Contributor rankHonored Contributor

    In general you have two options:

    1. use PIOs and directly bit-bang them to drive spi wires

    2. instantiate a SPI master core in your Qsys

    The nr.1 is generally used when you have a microcontroller without native spi interface and you don't bother about performance; but in your case the nr.2 is definitely more convenient, since on a FPGA the spi core comes for free.

    First of all you need to instantiate and configure the SPI core in your system. You'll find it in the standard set of Qsys interface devices.

    Then connect the Avalon slave port to your Nios data master and route the 4 exported spi wires to the fpga pins connected to your DAC.

    After you have build the Quartus project and configured the fpga, you simply use the HAL library functions to access the spi device, transmit and receive data.
  • Altera_Forum's avatar
    Altera_Forum
    Icon for Honored Contributor rankHonored Contributor

    Hi Chris.

    Does this Qsys setup make sense (am attaching a zip file of the screenshot since this site reduces automatically the size of the image file)? I hope I got the wires connected correctly.

    Also, do you know of any resource/code that I can use to send 16 bit data continuously?

    I'll be reading the data streams direction from external memory and I'm afraid of is that the CPU would not be able to send the data at a sufficient rate. I need to send the 16 bit data stream at 1MHz input speed. Does that mean I need a clock that operates at >16 MHZ operating the DAC/SPI (one start bit, one stop bit, and 16 bits each per clock cycle)?

    Thanks again!
  • Altera_Forum's avatar
    Altera_Forum
    Icon for Honored Contributor rankHonored Contributor

    The connections are correct. This way your Nios processor can directly write the spi master control port to transmit data.

    Anyway if you really want a 1Mhz data rate, I believe you'd hardly achieve it with Nios operating this way. Nios is not a very fast processor and if you want to use it for other tasks in your design, it would not keep up with that transmission rate.

    You'd better use a dma to transfer data from your memory to spi.

    Regarding clock rate, since the DAC requires 18bit per data (including start and stop bits), you need at least 18MHz. Then, for example, if your system clock is 100MHz you can set SPI sclk to 20MHz.
  • Altera_Forum's avatar
    Altera_Forum
    Icon for Honored Contributor rankHonored Contributor

    I think that one mistake I made was that I created an SPI slave rather than SPI master to write out signals. I've changed the SPI from slave to master, but still it doesn't work. I have the following code that basically runs if an button is pressed:

    if (print_cnt == 1)

    printf("LED Pattern 1\n");

    alt_u8 tx = 10020;

    alt_u8 rx = 0;

    return_code = alt_avalon_spi_command(SPI_0_BASE,0 ,

    1, tx,

    0, rx,

    0);

    For some reason, this causes the FPGA to get stuck and stop working. Any thoughts why?
  • Altera_Forum's avatar
    Altera_Forum
    Icon for Honored Contributor rankHonored Contributor

    update:

    i debuged the noise II processor.

    it turns out that within the alt_avalon_spi_command function the code gets stuck in this line:

    do

    {

    status = IORD_ALTERA_AVALON_SPI_STATUS(base);

    }

    while (((status & ALTERA_AVALON_SPI_STATUS_TRDY_MSK) == 0 || credits == 0) &&

    (status & ALTERA_AVALON_SPI_STATUS_RRDY_MSK) == 0);

    any thoughts why?
  • Altera_Forum's avatar
    Altera_Forum
    Icon for Honored Contributor rankHonored Contributor

    First of all, debug the control port by manually accessing SPI registers: use IORD and IOWR like in the alt_avalon_spi_command code above, just to be sure the MM interface is ok.

    You can also directly write the TX register and verify if you get any serial data out.