In this project I wanna using resistor ladder (R-2R) technology to make a Digital-to-Analog Converter (DAC) audio signals smoother, thereby achieving a better-sounding effect. It is expected to support audio formats up to 16bit/48kHz.
HardwareRaspberry Pi Pico 2
lot of resistor: 10K ohm / 20K ohm
Operational Amplifier: MCP6004
Schmatics:
Pico 2 pinout
R2R ladder:
Connect the R2R resistor circuit to each GPIO of the Pi Pico 2.
Output buffer:
Using MCP6004 as a buffer to improve the output capability of the circuit.
make a PCBA
since code issue I use 16bit only.
MS VS code
pico sdk
test PIO function
from hello_pio example modify hello.pio
.pio_version 0 // only requires PIO version 0
.program R2Rtest
.wrap_target
pull block
out pins, 16
.wrapand hello.c to gen sine wave though DMA.
#include "hello.pio.h"
#include <stdio.h>
#include <stdint.h>
#include <math.h>
#include "pico/stdlib.h"
#include "hardware/pio.h"
#include "hardware/dma.h"
#include "hardware/irq.h"
#include "hardware/clocks.h"
#define SAMPLE_RATE 48000
#define BUFFER_SIZE 4096
uint16_t buffer[BUFFER_SIZE];
PIO pio;
uint sm;
uint offset;
pio_sm_config c;
float clk_div;
// ===== DMA A =====
int dma_a;
dma_channel_config cfg_a;
int main()
{
stdio_init_all();
for (int i = 0; i < 2048; i++) //4096/2
{
double phase = (2.0 * M_PI * i) / 2048;
double s = sin(phase);
uint16_t value = (uint16_t)((s + 1.0) * 32767.0); //16bit
// 2 wave
buffer[i] = value;
buffer[i+2048] = value;
}
pio = pio0;
sm = 0;
offset = pio_add_program(pio, &R2Rtest_program);
c = R2Rtest_program_get_default_config(offset);
// ===== GPIO 設定 =====
for (int i = 0; i < 16; i++)
{
pio_gpio_init(pio, i);
gpio_set_function(i, GPIO_FUNC_PIO0);
}
sm_config_set_out_pins(&c, 0, 16);
pio_sm_set_consecutive_pindirs(pio, sm, 0, 16, true);
// LSB -> GPIO0
sm_config_set_out_shift(&c, true, false, 32);
// each sample 1 instruction
clk_div = (float)clock_get_hz(clk_sys) / (SAMPLE_RATE * 2);
sm_config_set_clkdiv(&c, clk_div);
pio_sm_init(pio, sm, offset, &c);
pio_sm_set_enabled(pio, sm, true);
// ===== DMA A =====
dma_a = dma_claim_unused_channel(true);
cfg_a = dma_channel_get_default_config(dma_a);
channel_config_set_read_increment(&cfg_a, true);
channel_config_set_write_increment(&cfg_a, false);
channel_config_set_dreq(&cfg_a, pio_get_dreq(pio, sm, true));
channel_config_set_transfer_data_size(&cfg_a, DMA_SIZE_16);
channel_config_set_irq_quiet(&cfg_a, true);
dma_channel_configure(
dma_a,
&cfg_a,
&pio->txf[sm],
buffer,
BUFFER_SIZE,
false);
dma_channel_start(dma_a);
// heartbeat LED
gpio_init(25);
gpio_set_dir(25, GPIO_OUT);
while (1)
{
gpio_put(25, 1);
sleep_ms(300);
gpio_put(25, 0);
sleep_ms(300);
tight_loop_contents();
}
}USB:
From tinyusb example it build a usb audio device.
It can easily build a USB speaker device.
Optimize sound quality
Higher sound quality





Comments