Waveform generator
unknown
c_cpp
7 months ago
2.0 kB
33
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