Created
April 30, 2023 00:49
-
-
Save mharsch/fa4a388fb0beedaccf456c9112c6bf8d to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/** | |
* 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