8000 PDM library re-port (#1160) · dyno-project/arduino-pico@7df080e · GitHub
[go: up one dir, main page]

Skip to content

Commit 7df080e

Browse files
authored
PDM library re-port (earlephilhower#1160)
See earlephilhower#1156
1 parent b400897 commit 7df080e

File tree

2 files changed

+57
-19
lines changed

2 files changed

+57
-19
lines changed

libraries/PDM/src/PDM.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@ class PDMClass {
3838

3939
//PORTENTA_H7 min -12 max 51
4040
//NANO 33 BLE SENSe min 0 max 80
41+
//NICLA_VISION min 0 max 8
4142
void setGain(int gain);
4243
void setBufferSize(int bufferSize);
4344
size_t getBufferSize();
@@ -56,6 +57,8 @@ class PDMClass {
5657
int _gain;
5758
int _init;
5859

60+
int _cutSamples;
61+
5962
// Hardware peripherals used
6063
uint _dmaChannel;
6164
PIO _pio;

libraries/PDM/src/rp2040/PDM.cpp

Lines changed: 54 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ uint8_t rawBuffer1[RAW_BUFFER_SIZE];
2020
uint8_t* rawBuffer[2] = {rawBuffer0, rawBuffer1};
2121
volatile int rawBufferIndex = 0;
2222

23-
int decimation = 64;
23+
int decimation = 128;
2424

2525
// final buffer is the one to be filled with PCM data
2626
int16_t* volatile finalBuffer;
@@ -45,6 +45,7 @@ PDMClass::PDMClass(int dinPin, int clkPin, int pwrPin) :
4545
_channels(-1),
4646
_samplerate(-1),
4747
_init(-1),
48+
_cutSamples(100),
4849
_dmaChannel(0),
4950
_pio(nullptr),
5051
_smIdx(-1),
@@ -55,6 +56,12 @@ PDMClass::~PDMClass() {
5556
}
5657

5758
int PDMClass::begin(int channels, int sampleRate) {
59+
60+
if (_init == 1) {
61+
//ERROR: please call end first
62+
return < 10000 span class="pl-c1">0;
63+
}
64+
5865
//_channels = channels; // only one channel available
5966

6067
// clear the final buffers
@@ -63,6 +70,18 @@ int PDMClass::begin(int channels, int sampleRate) {
6370
int finalBufferLength = _doubleBuffer.availableForWrite() / sizeof(int16_t);
6471
_doubleBuffer.swap(0);
6572

73+
// The mic accepts an input clock from 1.2 to 3.25 Mhz
74+
// Setup the decimation factor accordingly
75+
if ((sampleRate * decimation * 2) > 3250000) {
76+
decimation = 64;
77+
}
78+
79+
// Sanity check, abort if still over 3.25Mhz
80+
if ((sampleRate * decimation * 2) > 3250000) {
81+
//ERROR: Sample rate too high, the mic would glitch
82+
return -1;
83+
}
84+
6685
int rawBufferLength = RAW_BUFFER_SIZE / (decimation / 8);
6786
// Saturate number of samples. Remaining bytes are dropped.
6887
if (rawBufferLength > finalBufferLength) {
@@ -71,6 +90,7 @@ int PDMClass::begin(int channels, int sampleRate) {
7190

7291
/* Initialize Open PDM library */
7392
filter.Fs = sampleRate;
93+
filter.MaxVolume = 1;
7494
filter.nSamples = rawBufferLength;
7595
filter.LP_HZ = sampleRate / 2;
7696
filter.HP_HZ = 10;
@@ -88,7 +108,7 @@ int PDMClass::begin(int channels, int sampleRate) {
88108

89109
if (!_pdmPgm.prepare(&_pio, &_smIdx, &_pgmOffset)) {
90110
// ERROR, no free slots
91-
return -1;
111+
return 0;
92112
}
93113
pdm_pio_program_init(_pio, _smIdx, _pgmOffset, _clkPin, _dinPin, clkDiv);
94114

@@ -118,14 +138,29 @@ int PDMClass::begin(int channels, int sampleRate) {
118138
true // Start immediately
119139
);
120140

141+
_cutSamples = 100;
142+
121143
_init = 1;
122144

123145
return 1;
124146
}
125147

126148
void PDMClass::end() {
149+
150+
if (_init != 1) {
151+
return;
152+
}
153+
154+
dma_channel_set_irq0_enabled(_dmaChannel, false);
127155
dma_channel_abort(_dmaChannel);
156+
dma_channel_unclaim(_dmaChannel);
157+
irq_remove_handler(DMA_IRQ_0, dmaHandler);
158+
pio_sm_unclaim(_pio, _smIdx);
128159
pinMode(_clkPin, INPUT);
160+
rawBufferIndex = 0;
161+
_pgmOffset = -1;
162+
163+
_init = 0;
129164
}
130165

131166
int PDMClass::available() {
@@ -163,32 +198,32 @@ void PDMClass::setBufferSize(int bufferSize) {
163198
}
164199

165200
void PDMClass::IrqHandler(bool halftranfer) {
166-
static int cutSamples = 100;
167201

168202
// Clear the interrupt request.
169203
dma_hw->ints0 = 1u << _dmaChannel;
170204
// Restart dma pointing to the other buffer
171205
int shadowIndex = rawBufferIndex ^ 1;
172206
dma_channel_set_write_addr(_dmaChannel, rawBuffer[shadowIndex], true);
173207

174-
if (_doubleBuffer.available()) {
175-
// buffer overflow, stop
176-
return end();
208+
if (!_doubleBuffer.available()) {
209+
// fill final buffer with PCM samples
210+
if (filter.Decimation == 128) {
211+
Open_PDM_Filter_128(rawBuffer[rawBufferIndex], finalBuffer, 1, &filter);
212+
} else {
213+
Open_PDM_Filter_64(rawBuffer[rawBufferIndex], finalBuffer, 1, &filter);
214+
}
215+
216+
if (_cutSamples) {
217+
memset(finalBuffer, 0, _cutSamples);
218+
_cutSamples = 0;
219+
}
220+
221+
// swap final buffer and raw buffers' indexes
222+
finalBuffer = (int16_t*)_doubleBuffer.data();
223+
_doubleBuffer.swap(filter.nSamples * sizeof(int16_t));
224+
rawBufferIndex = shadowIndex;
177225
}
178226

179-
// fill final buffer with PCM samples
180-
Open_PDM_Filter_64(rawBuffer[rawBufferIndex], finalBuffer, 1, &filter);
181-
182-
if (cutSamples) {
183-
memset(finalBuffer, 0, cutSamples);
184-
cutSamples = 0;
185-
}
186-
187-
// swap final buffer and raw buffers' indexes
188-
finalBuffer = (int16_t*)_doubleBuffer.data();
189-
_doubleBuffer.swap(filter.nSamples * sizeof(int16_t));
190-
rawBufferIndex = shadowIndex;
191-
192227
if (_onReceive) {
193228
_onReceive();
194229
}

0 commit comments

Comments
 (0)
0