Skip to content

Commit f684596

Browse files
committed
adding pcm5122 arduino example
1 parent a992f8a commit f684596

File tree

2 files changed

+274
-0
lines changed

2 files changed

+274
-0
lines changed

PCM5122_Examples/Arduino_PCM5122/.feather_rp2040.test.only

Whitespace-only changes.
Lines changed: 274 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,274 @@
1+
// SPDX-FileCopyrightText: 2025 Ladyada for Adafruit Industries
2+
//
3+
// SPDX-License-Identifier: MIT
4+
5+
/*!
6+
*
7+
* Basic test example for the Adafruit PCM5122
8+
*
9+
* Written by Limor 'ladyada' Fried with assistance from Claude Code
10+
* for Adafruit Industries.
11+
*
12+
* MIT license, all text here must be included in any redistribution.
13+
*/
14+
15+
#include <Adafruit_PCM51xx.h>
16+
#include <I2S.h>
17+
#include <math.h>
18+
19+
Adafruit_PCM51xx pcm;
20+
21+
#define pBCLK D9 // BITCLOCK - I2S clock
22+
#define pWS D10 // LRCLOCK - Word select
23+
#define pDOUT D11 // DATA - I2S data
24+
25+
// Create I2S port
26+
I2S i2s(OUTPUT);
27+
28+
const int frequency = 440; // frequency of square wave in Hz
29+
const int amplitude = 500; // amplitude of square wave
30+
const int sampleRate = 16000; // 16 KHz is a good quality
31+
32+
const int halfWavelength = (sampleRate / frequency); // half wavelength of square wave
33+
34+
int16_t sample = amplitude; // current sample value
35+
int count = 0;
36+
37+
void setup() {
38+
Serial.begin(115200);
39+
while (!Serial) delay(10);
40+
41+
Serial.println(F("Adafruit PCM51xx Test"));
42+
43+
// I2C mode (default)
44+
if (!pcm.begin()) {
45+
Serial.println(F("Could not find PCM51xx, check wiring!"));
46+
while (1) delay(10);
47+
}
48+
49+
// Hardware SPI mode (uncomment to use)
50+
// if (!pcm.begin(10, &SPI)) { // CS pin 10
51+
// Serial.println(F("Could not find PCM51xx over SPI, check wiring!"));
52+
// while (1) delay(10);
53+
// }
54+
55+
// Software SPI mode (uncomment to use)
56+
// if (!pcm.begin(10, 11, 12, 13)) { // CS, MOSI, MISO, SCLK
57+
// Serial.println(F("Could not find PCM51xx over software SPI, check wiring!"));
58+
// while (1) delay(10);
59+
// }
60+
61+
Serial.println(F("PCM51xx initialized successfully!"));
62+
63+
// Set I2S format to I2S
64+
Serial.println(F("Setting I2S format"));
65+
pcm.setI2SFormat(PCM51XX_I2S_FORMAT_I2S);
66+
67+
// Read and display current format
68+
pcm51xx_i2s_format_t format = pcm.getI2SFormat();
69+
Serial.print(F("Current I2S format: "));
70+
switch (format) {
71+
case PCM51XX_I2S_FORMAT_I2S:
72+
Serial.println(F("I2S"));
73+
break;
74+
case PCM51XX_I2S_FORMAT_TDM:
75+
Serial.println(F("TDM/DSP"));
76+
break;
77+
case PCM51XX_I2S_FORMAT_RTJ:
78+
Serial.println(F("Right Justified"));
79+
break;
80+
case PCM51XX_I2S_FORMAT_LTJ:
81+
Serial.println(F("Left Justified"));
82+
break;
83+
default:
84+
Serial.println(F("Unknown"));
85+
break;
86+
}
87+
88+
// Set I2S word length to 32-bit
89+
Serial.println(F("Setting I2S word length"));
90+
pcm.setI2SSize(PCM51XX_I2S_SIZE_16BIT);
91+
92+
// Read and display current word length
93+
pcm51xx_i2s_size_t size = pcm.getI2SSize();
94+
Serial.print(F("Current I2S word length: "));
95+
switch (size) {
96+
case PCM51XX_I2S_SIZE_16BIT:
97+
Serial.println(F("16 bits"));
98+
break;
99+
case PCM51XX_I2S_SIZE_20BIT:
100+
Serial.println(F("20 bits"));
101+
break;
102+
case PCM51XX_I2S_SIZE_24BIT:
103+
Serial.println(F("24 bits"));
104+
break;
105+
case PCM51XX_I2S_SIZE_32BIT:
106+
Serial.println(F("32 bits"));
107+
break;
108+
default:
109+
Serial.println(F("Unknown"));
110+
break;
111+
}
112+
113+
// Set error detection bits
114+
if (!pcm.ignoreFSDetect(true) || !pcm.ignoreBCKDetect(true) || !pcm.ignoreSCKDetect(true) ||
115+
!pcm.ignoreClockHalt(true) || !pcm.ignoreClockMissing(true) || !pcm.disableClockAutoset(false) ||
116+
!pcm.ignorePLLUnlock(true)) {
117+
Serial.println(F("Error detection failed to configure"));
118+
}
119+
120+
// Enable PLL
121+
Serial.println(F("Enabling PLL"));
122+
pcm.enablePLL(true);
123+
124+
// Check PLL status
125+
bool pllEnabled = pcm.isPLLEnabled();
126+
Serial.print(F("PLL enabled: "));
127+
Serial.println(pllEnabled ? F("Yes") : F("No"));
128+
129+
// Set PLL reference to BCK
130+
Serial.println(F("Setting PLL reference"));
131+
pcm.setPLLReference(PCM51XX_PLL_REF_BCK);
132+
133+
// Read and display current PLL reference
134+
pcm51xx_pll_ref_t pllRef = pcm.getPLLReference();
135+
Serial.print(F("Current PLL reference: "));
136+
switch (pllRef) {
137+
case PCM51XX_PLL_REF_SCK:
138+
Serial.println(F("SCK"));
139+
break;
140+
case PCM51XX_PLL_REF_BCK:
141+
Serial.println(F("BCK"));
142+
break;
143+
case PCM51XX_PLL_REF_GPIO:
144+
Serial.println(F("GPIO"));
145+
break;
146+
default:
147+
Serial.println(F("Unknown"));
148+
break;
149+
}
150+
151+
// Set DAC clock source to PLL
152+
Serial.println(F("Setting DAC source"));
153+
pcm.setDACSource(PCM51XX_DAC_CLK_PLL);
154+
155+
// Read and display current DAC source
156+
pcm51xx_dac_clk_src_t dacSource = pcm.getDACSource();
157+
Serial.print(F("Current DAC source: "));
158+
switch (dacSource) {
159+
case PCM51XX_DAC_CLK_MASTER:
160+
Serial.println(F("Master clock (auto-select)"));
161+
break;
162+
case PCM51XX_DAC_CLK_PLL:
163+
Serial.println(F("PLL clock"));
164+
break;
165+
case PCM51XX_DAC_CLK_SCK:
166+
Serial.println(F("SCK clock"));
167+
break;
168+
case PCM51XX_DAC_CLK_BCK:
169+
Serial.println(F("BCK clock"));
170+
break;
171+
default:
172+
Serial.println(F("Unknown"));
173+
break;
174+
}
175+
176+
// Test auto mute (default turn off)
177+
Serial.println(F("Setting auto mute"));
178+
pcm.setAutoMute(false);
179+
180+
// Read and display current auto mute status
181+
bool autoMuteEnabled = pcm.getAutoMute();
182+
Serial.print(F("Auto mute: "));
183+
Serial.println(autoMuteEnabled ? F("Enabled") : F("Disabled"));
184+
185+
// Test mute (default do not mute)
186+
Serial.println(F("Setting mute"));
187+
pcm.mute(false);
188+
189+
// Read and display current mute status
190+
bool muteEnabled = pcm.isMuted();
191+
Serial.print(F("Mute: "));
192+
Serial.println(muteEnabled ? F("Enabled") : F("Disabled"));
193+
194+
// Check DSP boot status and power state
195+
Serial.print(F("DSP boot done: "));
196+
Serial.println(pcm.getDSPBootDone() ? F("Yes") : F("No"));
197+
198+
pcm51xx_power_state_t powerState = pcm.getPowerState();
199+
Serial.print(F("Power state: "));
200+
switch (powerState) {
201+
case PCM51XX_POWER_POWERDOWN:
202+
Serial.println(F("Powerdown"));
203+
break;
204+
case PCM51XX_POWER_WAIT_CP_VALID:
205+
Serial.println(F("Wait for CP voltage valid"));
206+
break;
207+
case PCM51XX_POWER_CALIBRATION_1:
208+
case PCM51XX_POWER_CALIBRATION_2:
209+
Serial.println(F("Calibration"));
210+
break;
211+
case PCM51XX_POWER_VOLUME_RAMP_UP:
212+
Serial.println(F("Volume ramp up"));
213+
break;
214+
case PCM51XX_POWER_RUN_PLAYING:
215+
Serial.println(F("Run (Playing)"));
216+
break;
217+
case PCM51XX_POWER_LINE_SHORT:
218+
Serial.println(F("Line output short / Low impedance"));
219+
break;
220+
case PCM51XX_POWER_VOLUME_RAMP_DOWN:
221+
Serial.println(F("Volume ramp down"));
222+
break;
223+
case PCM51XX_POWER_STANDBY:
224+
Serial.println(F("Standby"));
225+
break;
226+
default:
227+
Serial.println(F("Unknown"));
228+
break;
229+
}
230+
231+
// Check PLL lock status
232+
bool pllLocked = pcm.isPLLLocked();
233+
Serial.print(F("PLL locked: "));
234+
Serial.println(pllLocked ? F("Yes") : F("No"));
235+
236+
// Set volume to -6dB on both channels
237+
Serial.println(F("Setting volume"));
238+
pcm.setVolumeDB(-6.0, -6.0);
239+
240+
// Read and display current volume
241+
float leftVol, rightVol;
242+
pcm.getVolumeDB(&leftVol, &rightVol);
243+
Serial.print(F("Current volume - Left: "));
244+
Serial.print(leftVol, 1);
245+
Serial.print(F("dB, Right: "));
246+
Serial.print(rightVol, 1);
247+
Serial.println(F("dB"));
248+
249+
// Initialize I2S peripheral
250+
Serial.println("Initializing I2S...");
251+
i2s.setBCLK(pBCLK);
252+
i2s.setDATA(pDOUT);
253+
i2s.setBitsPerSample(16);
254+
255+
// Start I2S at the sample rate
256+
if (!i2s.begin(sampleRate)) {
257+
Serial.println("Failed to initialize I2S!");
258+
}
259+
260+
}
261+
262+
void loop() {
263+
if (count % halfWavelength == 0) {
264+
// invert the sample every half wavelength count multiple to generate square wave
265+
sample = -1 * sample;
266+
}
267+
268+
// write the same sample twice, once for left and once for the right channel
269+
i2s.write(sample);
270+
i2s.write(sample);
271+
272+
// increment the counter for the next sample
273+
count++;
274+
}

0 commit comments

Comments
 (0)