YAHAL
Yet Another Hardware Abstraction Library
Loading...
Searching...
No Matches
dac8311_rp2040_drv.cpp
1// ---------------------------------------------
2// This file is part of
3// _ _ __ _ _ __ __
4// ( \/ ) /__\ ( )_( ) /__\ ( )
5// \ / /(__)\ ) _ ( /(__)\ )(__
6// (__)(__)(__)(_) (_)(__)(__)(____)
7//
8// Yet Another HW Abstraction Library
9// Copyright (C) Andreas Terstegge
10// BSD Licensed (see file LICENSE)
11//
12// ---------------------------------------------
13//
14#define PCM_FIFO_SIZE 2048
15
16#include "dac8311_rp2040_drv.h"
17#include "dac8311.pio.h"
18
19dac8311_rp2040_drv::dac8311_rp2040_drv( gpio_pin_t mosi_pin,
20 gpio_pin_t sclk_pin,
21 gpio_pin_t sync_pin,
22 gpio_pin_t enable)
23 : pcm_audio_interface(PCM_FIFO_SIZE), _enable(enable)
24{
25 // Set up GPIOs
26 gpio_rp2040 mosi( mosi_pin );
27 gpio_rp2040 sclk( sclk_pin );
28 gpio_rp2040 sync( sync_pin );
29 mosi.setSEL(_IO_BANK0_::GPIO_CTRL_FUNCSEL__pio0);
30 sclk.setSEL(_IO_BANK0_::GPIO_CTRL_FUNCSEL__pio0);
31 sync.setSEL(_IO_BANK0_::GPIO_CTRL_FUNCSEL__pio0);
32 _enable.gpioMode(GPIO::OUTPUT | GPIO::INIT_HIGH);
33
34 // Create and set up the PIO state machines
35 _pcm_sm = pio_rp2040::pio0.loadProgram(dac8311_program);
36 configure_SM(_pcm_sm, mosi_pin, sclk_pin, sync_pin);
37 _pcm_sm->attachIrq([this]() -> void {
38 // Fill the PIO TX FIFO
39 pcm_value_t pcm_value;
40 while (!_pcm_sm->TxFifoFull()) {
41 uint32_t val = 0;
42 if (pcmFifoGet(pcm_value)) {
43 // Calculate a mono signal by taking
44 // the average of left and right channel
45 val = (pcm_value.left + pcm_value.right) / 2;
46 }
47 // Convert the 16 bit signed PCM value
48 // to a 14 bit unsigned value, as needed
49 // by the DAC8311. The upper 16 bits of
50 // the value written to writeTxFifo are
51 // transferred by the PIO code.
52 _pcm_sm->writeTxFifo((val + 32768) << 14);
53 }
54 });
55 _pcm_sm->enableIrq();
56 _pcm_sm->enable();
57 enable_output(true);
58}
59
60void dac8311_rp2040_drv::setPcmRate(uint32_t Hz) {
61 // Delegate the rate setting to the PIO support code
62 setRate(_pcm_sm, Hz);
63}