Skip to content

Instantly share code, notes, and snippets.

@mharsch
Created April 30, 2023 00:49
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save mharsch/fa4a388fb0beedaccf456c9112c6bf8d to your computer and use it in GitHub Desktop.
Save mharsch/fa4a388fb0beedaccf456c9112c6bf8d to your computer and use it in GitHub Desktop.
/**
* V. Hunter Adams
* DDS of sine wave on MCP4822 DAC w/ ISR
*
* Modified example code from Raspberry Pi
* Copyright (c) 2020 Raspberry Pi (Trading) Ltd.
*
* SPDX-License-Identifier: BSD-3-Clause
*
GPIO 8 (pico pin 11) MCP4725 SDA
GPIO 9 (pico pin 12) MCP4725 SCL
3.3v (pico pin 36) -> VCC on DAC
GND (pico pin 13) -> GND on DAC
*/
#include <stdio.h>
#include <math.h>
#include "pico/stdlib.h"
#include "hardware/i2c.h"
//DDS parameters
#define two32 4294967296.0 // 2^32
#define Fs 40000
// the DDS units:
volatile unsigned int phase_accum_main;
volatile unsigned int phase_incr_main = (800.0*two32)/Fs ;//
// I2C data
uint16_t DAC_data ; // output value
//DAC parameters
// A-channel, 1x, active
#define DAC_config_chan_A 0b0011000000000000
// B-channel, 1x, active
#define DAC_config_chan_B 0b1011000000000000
//I2C configurations
#define ADDRESS 0x62
#define I2C_CHAN i2c0
#define SDA_PIN 8
#define SCL_PIN 9
#define I2C_BAUD_RATE 400000
#define MCP4725_CMD_WRITEDAC (0x40)
// DDS sine table
#define sine_table_size 256
volatile int sin_table[sine_table_size] ;
// Timer ISR
bool repeating_timer_callback(struct repeating_timer *t) {
// DDS phase and sine table lookup
phase_accum_main += phase_incr_main ;
DAC_data = (DAC_config_chan_A | ((sin_table[phase_accum_main>>24] + 2048) & 0xffff)) ;
uint8_t packet[3];
packet[0] = MCP4725_CMD_WRITEDAC;
packet[1] = DAC_data / 16; // Upper data bits (D11.D10.D9.D8.D7.D6.D5.D4)
packet[2] = (DAC_data % 16) << 4; // Lower data bits (D3.D2.D1.D0.x.x.x.x)
i2c_write_blocking(I2C_CHAN, ADDRESS, packet, 3, false) ;
return true;
}
int main() {
// Initialize stdio
stdio_init_all();
printf("Hello, DAC!\n");
// Initialize SPI channel (channel, baud rate set to 20MHz)
//spi_init(SPI_PORT, 20000000) ;
// Format (channel, data bits per transfer, polarity, phase, order)
//spi_set_format(SPI_PORT, 16, 0, 0, 0);
i2c_init(I2C_CHAN, I2C_BAUD_RATE);
gpio_set_function(SDA_PIN, GPIO_FUNC_I2C);
gpio_set_function(SCL_PIN, GPIO_FUNC_I2C);
gpio_pull_up(SDA_PIN);
gpio_pull_up(SCL_PIN);
// Map SPI signals to GPIO ports
//gpio_set_function(PIN_MISO, GPIO_FUNC_SPI);
//gpio_set_function(PIN_SCK, GPIO_FUNC_SPI);
//gpio_set_function(PIN_MOSI, GPIO_FUNC_SPI);
//gpio_set_function(PIN_CS, GPIO_FUNC_SPI) ;
// === build the sine lookup table =======
// scaled to produce values between 0 and 4096
int ii;
for (ii = 0; ii < sine_table_size; ii++){
sin_table[ii] = (int)(2047*sin((float)ii*6.283/(float)sine_table_size));
}
// Create a repeating timer that calls repeating_timer_callback.
// If the delay is > 0 then this is the delay between the previous callback ending and the next starting.
// If the delay is negative (see below) then the next call to the callback will be exactly x us after the
// start of the call to the last callback
struct repeating_timer timer;
// Negative delay so means we will call repeating_timer_callback, and call it again
// 25us (40kHz) later regardless of how long the callback took to execute
add_repeating_timer_us(-50, repeating_timer_callback, NULL, &timer);
while(1){
}
return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment