Skip to content

Commit 85a9711

Browse files
authored
Merge pull request #409 from adafruit/fix-pdm
fix pdm issue with #352
2 parents 4159172 + f132517 commit 85a9711

File tree

4 files changed

+56
-27
lines changed

4 files changed

+56
-27
lines changed

libraries/PDM/examples/PDMSerialPlotter/PDMSerialPlotter.ino

Lines changed: 2 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -10,10 +10,6 @@
1010

1111
#include <PDM.h>
1212

13-
// The default Circuit Playground Bluefruit pins
14-
// data pin, clock pin, power pin (-1 if not used)
15-
PDMClass PDM(24, 25, -1);
16-
1713
// buffer to read samples into, each sample is 16-bits
1814
short sampleBuffer[256];
1915

@@ -41,8 +37,6 @@ void setup() {
4137

4238
void loop() {
4339
// wait for samples to be read
44-
PDM.IrqHandler();
45-
4640
if (samplesRead) {
4741
// print samples to the serial monitor or plotter
4842
for (int i = 0; i < samplesRead; i++) {
@@ -62,4 +56,5 @@ void onPDMdata() {
6256

6357
// 16-bit, 2 bytes per sample
6458
samplesRead = bytesAvailable / 2;
65-
}
59+
}
60+

libraries/PDM/src/PDM.cpp

Lines changed: 41 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -44,23 +44,37 @@ PDMClass::~PDMClass()
4444
{
4545
}
4646

47+
void PDMClass::setPins(int dataPin, int clkPin, int pwrPin)
48+
{
49+
_dinPin = dataPin;
50+
_clkPin = clkPin;
51+
_pwrPin = pwrPin;
52+
}
53+
4754
int PDMClass::begin(int channels, long sampleRate)
4855
{
4956
_channels = channels;
5057

51-
/*
58+
// Enable high frequency oscillator if not already enabled
59+
if (NRF_CLOCK->EVENTS_HFCLKSTARTED == 0) {
60+
NRF_CLOCK->TASKS_HFCLKSTART = 1;
61+
while (NRF_CLOCK->EVENTS_HFCLKSTARTED == 0) { }
62+
}
63+
5264
// configure the sample rate and channels
5365
switch (sampleRate) {
5466
case 16000:
55-
nrf_pdm_clock_set(NRF_PDM_FREQ_1032K);
67+
#ifndef NRF52832_XXAA
68+
NRF_PDM->RATIO = ((PDM_RATIO_RATIO_Ratio80 << PDM_RATIO_RATIO_Pos) & PDM_RATIO_RATIO_Msk);
69+
#endif
70+
nrf_pdm_clock_set(NRF_PDM_FREQ_1280K);
5671
break;
5772
case 41667:
5873
nrf_pdm_clock_set(NRF_PDM_FREQ_2667K);
5974
break;
6075
default:
6176
return 0; // unsupported
6277
}
63-
*/
6478

6579
switch (channels) {
6680
case 2:
@@ -74,6 +88,7 @@ int PDMClass::begin(int channels, long sampleRate)
7488
default:
7589
return 0; // unsupported
7690
}
91+
7792
setGain(DEFAULT_PDM_GAIN);
7893

7994
// configure the I/O and mux
@@ -82,8 +97,6 @@ int PDMClass::begin(int channels, long sampleRate)
8297

8398
pinMode(_dinPin, INPUT);
8499

85-
Serial.printf("Clock P %d Data P %d\n", digitalPinToPinName(_clkPin), digitalPinToPinName(_dinPin));
86-
87100
nrf_pdm_psel_connect(digitalPinToPinName(_clkPin), digitalPinToPinName(_dinPin));
88101

89102
// clear events and enable PDM interrupts
@@ -98,14 +111,13 @@ int PDMClass::begin(int channels, long sampleRate)
98111
digitalWrite(_pwrPin, HIGH);
99112
}
100113

101-
102114
// clear the buffer
103115
_doubleBuffer.reset();
116+
104117
// set the PDM IRQ priority and enable
105118
NVIC_SetPriority(PDM_IRQn, PDM_IRQ_PRIORITY);
106119
NVIC_ClearPendingIRQ(PDM_IRQn);
107120
NVIC_EnableIRQ(PDM_IRQn);
108-
109121

110122
// set the buffer for transfer
111123
// nrf_pdm_buffer_set((uint32_t*)_doubleBuffer.data(), _doubleBuffer.availableForWrite() / (sizeof(int16_t) * _channels));
@@ -116,7 +128,6 @@ int PDMClass::begin(int channels, long sampleRate)
116128
nrf_pdm_event_clear(NRF_PDM_EVENT_STARTED);
117129
nrf_pdm_task_trigger(NRF_PDM_TASK_START);
118130

119-
120131
return 1;
121132
}
122133

@@ -133,6 +144,8 @@ void PDMClass::end()
133144
pinMode(_pwrPin, INPUT);
134145
}
135146

147+
// Don't disable high frequency oscillator since it could be in use by RADIO
148+
136149
// unconfigure the I/O and un-mux
137150
nrf_pdm_psel_disconnect();
138151

@@ -145,7 +158,7 @@ int PDMClass::available()
145158

146159
size_t avail = _doubleBuffer.available();
147160

148-
//NVIC_EnableIRQ(PDM_IRQn);
161+
NVIC_EnableIRQ(PDM_IRQn);
149162

150163
return avail;
151164
}
@@ -156,7 +169,7 @@ int PDMClass::read(void* buffer, size_t size)
156169

157170
int read = _doubleBuffer.read(buffer, size);
158171

159-
//NVIC_EnableIRQ(PDM_IRQn);
172+
NVIC_EnableIRQ(PDM_IRQn);
160173

161174
return read;
162175
}
@@ -203,13 +216,24 @@ void PDMClass::IrqHandler()
203216
}
204217
}
205218

206-
extern "C" {
207-
void PDM_IRQHandler(void);
208-
}
209-
210-
void PDM_IRQHandler(void)
219+
extern "C"
211220
{
212-
PDM.IrqHandler();
221+
void PDM_IRQHandler(void)
222+
{
223+
PDM.IrqHandler();
224+
}
213225
}
214226

215-
extern PDMClass PDM;
227+
#ifndef PIN_PDM_DIN
228+
#define PIN_PDM_DIN -1
229+
#endif
230+
231+
#ifndef PIN_PDM_CLK
232+
#define PIN_PDM_CLK -1
233+
#endif
234+
235+
#ifndef PIN_PDM_PWR
236+
#define PIN_PDM_PWR -1
237+
#endif
238+
239+
PDMClass PDM(PIN_PDM_DIN, PIN_PDM_CLK, PIN_PDM_PWR);

libraries/PDM/src/PDM.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@ class PDMClass
3333
PDMClass(int dataPin, int clkPin, int pwrPin);
3434
virtual ~PDMClass();
3535

36+
void setPins(int dataPin, int clkPin, int pwrPin);
3637
int begin(int channels, long sampleRate);
3738
void end();
3839

variants/circuitplayground_nrf52840/variant.h

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -54,8 +54,8 @@ extern "C"
5454
#define LED_STATE_ON 1 // State when LED is litted
5555

5656
// Buttons
57-
#define PIN_BUTTON1 (4)
58-
#define PIN_BUTTON2 (5)
57+
#define PIN_BUTTON1 (4)
58+
#define PIN_BUTTON2 (5)
5959

6060
// Microphone
6161
#define PIN_PDM_DIN 24
@@ -120,7 +120,9 @@ static const uint8_t SCK = PIN_SPI_SCK ;
120120
#define PIN_WIRE1_SDA (28)
121121
#define PIN_WIRE1_SCL (26)
122122

123-
// QSPI Pins
123+
/*
124+
* QSPI Interfaces
125+
*/
124126
#define PIN_QSPI_SCK 29
125127
#define PIN_QSPI_CS 30
126128
#define PIN_QSPI_IO0 31
@@ -134,6 +136,13 @@ static const uint8_t SCK = PIN_SPI_SCK ;
134136
#define USB_MSC_BLOCK_SIZE 512
135137
#define USB_MSC_BLOCK_COUNT ((2*1024*1024) / USB_MSC_BLOCK_SIZE)
136138

139+
/*
140+
* PDM Interfaces
141+
*/
142+
#define PIN_PDM_DIN 24
143+
#define PIN_PDM_CLK 25
144+
#define PIN_PDM_PWR -1 // not used
145+
137146
#ifdef __cplusplus
138147
}
139148
#endif

0 commit comments

Comments
 (0)