YAHAL
Yet Another Hardware Abstraction Library
Loading...
Searching...
No Matches
max98357_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 "max98357_rp2040_drv.h"
17#include "max98357.pio.h"
18
19max98357_rp2040_drv::max98357_rp2040_drv(gpio_pin_t din_pin,
20 gpio_pin_t bclk_pin,
21 gpio_pin_t lrclk_pin,
22 gpio_pin_t sd_pin)
23 : pcm_audio_interface(PCM_FIFO_SIZE), _sd(sd_pin), _edge(28)
24{
25 // Set up GPIOs
26 gpio_rp2040 din ( din_pin );
27 gpio_rp2040 bclk ( bclk_pin );
28 gpio_rp2040 lrclk( lrclk_pin );
29 din.setSEL (_IO_BANK0_::GPIO_CTRL_FUNCSEL__pio0);
30 bclk.setSEL (_IO_BANK0_::GPIO_CTRL_FUNCSEL__pio0);
31 lrclk.setSEL(_IO_BANK0_::GPIO_CTRL_FUNCSEL__pio0);
32 _sd.gpioMode(GPIO::OUTPUT_OPEN_DRAIN | GPIO::INIT_HIGH);
33 _edge.gpioMode(GPIO::OUTPUT);
34
35 // Create and set up the PIO state machines
36 _pcm_sm = pio_rp2040::pio0.loadProgram(max98357_program);
37 configure_SM(_pcm_sm, din_pin, bclk_pin, lrclk_pin);
38 _pcm_sm->attachIrq([this]() -> void {
39 // Fill the PIO TX FIFO
40 pcm_value_t pcm_value;
41 int16_t last_val = 0;
42 while (!_pcm_sm->TxFifoFull()) {
43 uint32_t val = 0;
44 if (pcmFifoGet(pcm_value)) {
45 // MAX98357 PIO state machine expects 32 bit integers
46 // (upper 16 bit left channel, lower 16 bit right channel)
47 if (last_val <= 0 && pcm_value.left >= 0) _edge = HIGH;
48 if (last_val >= 0 && pcm_value.left <= 0) _edge = LOW;
49 last_val = pcm_value.left;
50 val = (pcm_value.left << 16) | pcm_value.right;
51 }
52 _pcm_sm->writeTxFifo(val);
53 }
54 });
55 _pcm_sm->enableIrq();
56 _pcm_sm->enable();
57}
58
59void max98357_rp2040_drv::setPcmRate(uint32_t Hz) {
60 // Delegate the rate setting to the PIO support code
61 setRate(_pcm_sm, Hz);
62}