@@ -20,7 +20,7 @@ uint8_t rawBuffer1[RAW_BUFFER_SIZE];
20
20
uint8_t * rawBuffer[2 ] = {rawBuffer0, rawBuffer1};
21
21
volatile int rawBufferIndex = 0 ;
22
22
23
- int decimation = 64 ;
23
+ int decimation = 128 ;
24
24
25
25
// final buffer is the one to be filled with PCM data
26
26
int16_t * volatile finalBuffer;
@@ -45,6 +45,7 @@ PDMClass::PDMClass(int dinPin, int clkPin, int pwrPin) :
45
45
_channels(-1 ),
46
46
_samplerate(-1 ),
47
47
_init(-1 ),
48
+ _cutSamples(100 ),
48
49
_dmaChannel(0 ),
49
50
_pio(nullptr ),
50
51
_smIdx(-1 ),
@@ -55,6 +56,12 @@ PDMClass::~PDMClass() {
55
56
}
56
57
57
58
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
+
58
65
// _channels = channels; // only one channel available
59
66
60
67
// clear the final buffers
@@ -63,6 +70,18 @@ int PDMClass::begin(int channels, int sampleRate) {
63
70
int finalBufferLength = _doubleBuffer.availableForWrite () / sizeof (int16_t );
64
71
_doubleBuffer.swap (0 );
65
72
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
+
66
85
int rawBufferLength = RAW_BUFFER_SIZE / (decimation / 8 );
67
86
// Saturate number of samples. Remaining bytes are dropped.
68
87
if (rawBufferLength > finalBufferLength) {
@@ -71,6 +90,7 @@ int PDMClass::begin(int channels, int sampleRate) {
71
90
72
91
/* Initialize Open PDM library */
73
92
filter.Fs = sampleRate;
93
+ filter.MaxVolume = 1 ;
74
94
filter.nSamples = rawBufferLength;
75
95
filter.LP_HZ = sampleRate / 2 ;
76
96
filter.HP_HZ = 10 ;
@@ -88,7 +108,7 @@ int PDMClass::begin(int channels, int sampleRate) {
88
108
89
109
if (!_pdmPgm.prepare (&_pio, &_smIdx, &_pgmOffset)) {
90
110
// ERROR, no free slots
91
- return - 1 ;
111
+ return 0 ;
92
112
}
93
113
pdm_pio_program_init (_pio, _smIdx, _pgmOffset, _clkPin, _dinPin, clkDiv);
94
114
@@ -118,14 +138,29 @@ int PDMClass::begin(int channels, int sampleRate) {
118
138
true // Start immediately
119
139
);
120
140
141
+ _cutSamples = 100 ;
142
+
121
143
_init = 1 ;
122
144
123
145
return 1 ;
124
146
}
125
147
126
148
void PDMClass::end () {
149
+
150
+ if (_init != 1 ) {
151
+ return ;
152
+ }
153
+
154
+ dma_channel_set_irq0_enabled (_dmaChannel, false );
127
155
dma_channel_abort (_dmaChannel);
156
+ dma_channel_unclaim (_dmaChannel);
157
+ irq_remove_handler (DMA_IRQ_0, dmaHandler);
158
+ pio_sm_unclaim (_pio, _smIdx);
128
159
pinMode (_clkPin, INPUT);
160
+ rawBufferIndex = 0 ;
161
+ _pgmOffset = -1 ;
162
+
163
+ _init = 0 ;
129
164
}
130
165
131
166
int PDMClass::available () {
@@ -163,32 +198,32 @@ void PDMClass::setBufferSize(int bufferSize) {
163
198
}
164
199
165
200
void PDMClass::IrqHandler (bool halftranfer) {
166
- static int cutSamples = 100 ;
167
201
168
202
// Clear the interrupt request.
169
203
dma_hw->ints0 = 1u << _dmaChannel;
170
204
// Restart dma pointing to the other buffer
171
205
int shadowIndex = rawBufferIndex ^ 1 ;
172
206
dma_channel_set_write_addr (_dmaChannel, rawBuffer[shadowIndex], true );
173
207
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;
177
225
}
178
226
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
-
192
227
if (_onReceive) {
193
228
_onReceive ();
194
229
}
0 commit comments