Waveform generator

 avatar
unknown
c_cpp
7 hours ago
2.0 kB
13
Indexable
#include "pico/stdlib.h"
#include "hardware/spi.h"
#include <cstdint>
#include <cmath>


constexpr uint CSn    = 16;   // FSYNC  (active‑low)
constexpr uint SCK    = 18;   // SPI0 SCLK
constexpr uint MOSI   = 19;   // SPI0 SDATA
constexpr uint RESETn = 20;   // RESET pin
constexpr uint OEn    = 21;   // Output Enable gate

static uint32_t calc_ftw(double fout_hz, double mclk_hz)
{
    constexpr double two_pow_28 = 268435456.0; // 2^28
    return static_cast<uint32_t>(std::round(fout_hz * two_pow_28 / mclk_hz));
}


static void ad9838_write(uint16_t word)
{
    gpio_put(CSn, 0);
    uint8_t bytes[2] = { static_cast<uint8_t>(word >> 8),
                         static_cast<uint8_t>(word & 0xFF) };
    spi_write_blocking(spi0, bytes, 2);
    gpio_put(CSn, 1);
}


static void ad9838_set_frequency(double fout_hz, double mclk_hz)
{
    // hold in reset
    ad9838_write(0x2100);

    // split frequency word onto its separate bytes
    uint32_t ftw = calc_ftw(fout_hz, mclk_hz);
    uint16_t lsb = 0x4000 | (ftw & 0x3FFF);
    uint16_t msb = 0x4000 | ((ftw >> 14) & 0x3FFF);

    //set frequency
    ad9838_write(lsb);
    ad9838_write(msb);

    ad9838_write(0x2000);
}

int main()
{
    constexpr double MCLK_HZ = 12'000'000.0;
    constexpr double FOUT_HZ = 1'000'000.0;    // desired output frequency

    stdio_init_all();
    gpio_init(PICO_DEFAULT_LED_PIN);
    gpio_set_dir(PICO_DEFAULT_LED_PIN, GPIO_OUT);


    spi_init(spi0, 8'000'000);
    spi_set_format(spi0, 8, SPI_CPOL_0, SPI_CPHA_0, SPI_MSB_FIRST);


    gpio_init(CSn);    gpio_set_dir(CSn, GPIO_OUT);    gpio_put(CSn, 1);
    gpio_init(RESETn); gpio_set_dir(RESETn, GPIO_OUT); gpio_put(RESETn, 0);
    gpio_init(OEn);    gpio_set_dir(OEn, GPIO_OUT);    gpio_put(OEn, 0);

    gpio_set_function(SCK,  GPIO_FUNC_SPI);
    gpio_set_function(MOSI, GPIO_FUNC_SPI);

    sleep_ms(10); // settle time after power‑up

    ad9838_set_frequency(FOUT_HZ, MCLK_HZ);
    gpio_put(OEn, 1);
    gpio_put(PICO_DEFAULT_LED_PIN, true);

    while (true) tight_loop_contents();
}
Editor is loading...
Leave a Comment