Skip to content

Commit 7e9d235

Browse files
author
Nathan Seidle
committed
Dual buffer method working
1 parent 44f9ef1 commit 7e9d235

File tree

3 files changed

+109
-32
lines changed

3 files changed

+109
-32
lines changed

libraries/PDM/examples/Example4_RecordToWav/readme.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,5 +7,5 @@ This example demonstrates how to read audio data and output it to a WAV file. A
77
Gotchas:
88

99
* You will need to modify the python script to match the COM port used on your computer. For Windows based machines find the
10-
* You will need to use VLC to play the WAV clips. The bitrate is 1024kbps which is higher than most audio players can handle.
10+
* You may need to use VLC to play the WAV clips. The bitrate is 256kbps which is higher than some audio players can handle.
1111
* Audio samples are generated fast enough that we need to output serial at 500kbps.

libraries/PDM/src/PDM.cpp

Lines changed: 91 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,15 @@ SOFTWARE.
2222
#include "PDM.h"
2323

2424
AP3_PDM *ap3_pdm_handle = 0;
25-
am_hal_pdm_transfer_t sTransfer;
25+
26+
// AP3_PDM::AP3_PDM(uint16_t *userBuffer, uint32_t bufferSize)
27+
// {
28+
// _userBuffer = userBuffer;
29+
// _userBufferSize = bufferSize;
30+
31+
// _readHead = 0;
32+
// _writeHead = 0;
33+
// }
2634

2735
bool AP3_PDM::begin(ap3_gpio_pin_t pinPDMData, ap3_gpio_pin_t pinPDMClock)
2836
{
@@ -40,15 +48,19 @@ bool AP3_PDM::begin(ap3_gpio_pin_t pinPDMData, ap3_gpio_pin_t pinPDMClock)
4048

4149
bool AP3_PDM::available(void)
4250
{
43-
if (_head != _tail)
51+
// if (_readHead != _writeHead)
52+
if (buff1New || buff2New)
4453
return (true);
4554
return (false);
4655
}
4756

4857
bool AP3_PDM::isOverrun(void)
4958
{
5059
if (_overrun == true)
60+
{
61+
_overrun = false;
5162
return (true);
63+
}
5264
return (false);
5365
}
5466

@@ -124,7 +136,7 @@ ap3_err_t AP3_PDM::_begin(void)
124136

125137
// Configure DMA and set target address of internal buffer.
126138
sTransfer.ui32TargetAddr = (uint32_t)_pdmDataBuffer;
127-
sTransfer.ui32TotalCount = pdmDataBufferSize * 2;
139+
sTransfer.ui32TotalCount = _pdmBufferSize * 2;
128140

129141
// Start the data transfer.
130142
am_hal_pdm_enable(_PDMhandle);
@@ -278,23 +290,36 @@ ap3_err_t ap3_pdm_pad_funcsel(ap3_pdm_pad_type_e type, ap3_gpio_pad_t pad, uint8
278290
// Returns number of bytes read.
279291
//
280292
//*****************************************************************************
281-
uint32_t AP3_PDM::getData(uint32_t *externalBuffer, uint32_t bufferSize)
293+
uint32_t AP3_PDM::getData(uint16_t *externalBuffer, uint32_t externalBufferSize)
282294
{
283-
if (bufferSize > circularBufferSize)
284-
bufferSize = circularBufferSize;
295+
if (externalBufferSize > _pdmBufferSize)
296+
externalBufferSize = _pdmBufferSize;
285297

286-
noInterrupts();
287-
288-
//Move data from internal buffer to external caller
289-
for (int x = 0; x < bufferSize; x++)
298+
//Move data from internal buffers to external caller
299+
if (buff1New == true)
290300
{
291-
externalBuffer[x] = _pdmCircularBuffer[tail];
292-
if (tail++ == circularBufferSize)
301+
for (int x = 0; x < externalBufferSize; x++)
302+
{
303+
externalBuffer[x] = outBuffer1[x];
304+
}
305+
buff1New = false;
293306
}
294-
295-
interrupts();
296-
297-
return (bufferSize)
307+
else if (buff2New == true)
308+
{
309+
for (int x = 0; x < externalBufferSize; x++)
310+
{
311+
externalBuffer[x] = outBuffer2[x];
312+
}
313+
buff2New = false;
314+
}
315+
// for (int x = 0; x < externalBufferSize; x++)
316+
// {
317+
// externalBuffer[x] = _userBuffer[_readHead];
318+
// _readHead++; //Advance the read head
319+
// _readHead %= _userBufferSize; //Wrap if necessary
320+
// }
321+
322+
return (externalBufferSize);
298323
}
299324

300325
inline void AP3_PDM::pdm_isr(void)
@@ -307,18 +332,60 @@ inline void AP3_PDM::pdm_isr(void)
307332

308333
if (ui32Status & AM_HAL_PDM_INT_DCMP)
309334
{
310-
//Move current DMA to circular buffer
311-
for (int x = 0; x < pdmDataBufferSize; x++)
335+
uint32_t tempReadAmt = _pdmBufferSize;
336+
337+
// if (_writeHead + _pdmBufferSize > _userBufferSize)
338+
// {
339+
// //Goes past the end of our buffer, adjust the amout to read so we hit end of buffer
340+
// tempReadAmt = _userBufferSize - _writeHead; //16384 - 16000 = 384
341+
// }
342+
343+
// int i;
344+
// for (i = 0; i < tempReadAmt; i++)
345+
// {
346+
// _userBuffer[_writeHead + i] = _pdmDataBuffer[i];
347+
// }
348+
349+
// _writeHead += tempReadAmt; //Advance the head
350+
// _writeHead %= _userBufferSize; //Wrap the head
351+
352+
// if (tempReadAmt < _pdmBufferSize)
353+
// {
354+
// //Finish the read where i had left off
355+
// for (; i < _pdmBufferSize; i++)
356+
// {
357+
// _userBuffer[i - tempReadAmt] = _pdmDataBuffer[i];
358+
// }
359+
360+
// _writeHead += _pdmBufferSize - tempReadAmt;
361+
// }
362+
//Check for overflow
363+
//if (_writeHead + pdmBufferSize
364+
365+
//Store in the first available buffer
366+
if (buff1New == false)
312367
{
313-
_pdmCircularBuffer[head++] = _pdmDataBuffer[x];
314-
if (_head++ == circularBufferSize)
315-
_head = 0;
368+
for (int i = 0; i < _pdmBufferSize; i++)
369+
{
370+
outBuffer1[i] = pi16Buffer[i];
371+
}
372+
buff1New = true;
316373
}
317-
318-
if (_head == _tail)
374+
else if (buff2New == false)
375+
{
376+
for (int i = 0; i < _pdmBufferSize; i++)
377+
{
378+
outBuffer2[i] = pi16Buffer[i];
379+
}
380+
buff2New = true;
381+
}
382+
else
319383
{
320-
Serial.println("Buffer overrun!");
321384
_overrun = true;
385+
//Used for debugging
386+
Serial.println("\n\rOver flow!");
387+
while (1)
388+
;
322389
}
323390

324391
//Start next conversion

libraries/PDM/src/PDM.h

Lines changed: 17 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -95,6 +95,8 @@ const am_hal_pdm_config_t ap3_pdm_config_default = {
9595
class AP3_PDM
9696
{
9797
public:
98+
//AP3_PDM(uint16_t *userBuffer, uint32_t bufferSize);
99+
98100
bool begin(ap3_gpio_pin_t pinPDMData = MIC_DATA, ap3_gpio_pin_t pinPDMClock = MIC_CLOCK);
99101
bool available(void); //Goes true if circular buffer is not empty
100102
bool isOverrun(void); //Goes true if head crosses tail
@@ -115,7 +117,7 @@ class AP3_PDM
115117

116118
bool updateConfig(am_hal_pdm_config_t newConfiguration);
117119

118-
uint32_t getData(uint32_t *externalBuffer, uint32_t bufferSize);
120+
uint32_t getData(uint16_t *externalBuffer, uint32_t bufferSize);
119121

120122
void pdm_isr(void);
121123

@@ -129,15 +131,23 @@ class AP3_PDM
129131

130132
//volatile bool _PDMdataReady = false;
131133

132-
volatile bool _head = 0;
133-
volatile bool _tail = 0;
134+
am_hal_pdm_transfer_t sTransfer;
135+
136+
// uint32_t _userBufferSize = 0;
137+
// uint16_t *_userBuffer;
138+
139+
// volatile uint32_t _writeHead = 0;
140+
// volatile uint32_t _readHead = 0;
134141
volatile bool _overrun = false;
135142

136-
#define pdmDataBufferSize 512 //Default is array of 4096 * 32bit
137-
volatile uint32_t _pdmDataBuffer[pdmDataBufferSize]; //This has been filled previous to ISR being called
143+
#define _pdmBufferSize 4096 //Default is array of 4096 * 32bit
144+
volatile uint32_t _pdmDataBuffer[_pdmBufferSize];
145+
int16_t *pi16Buffer = (int16_t *)_pdmDataBuffer;
138146

139-
#define circularBufferSize 4096
140-
volatile uint32_t _pdmCircularBuffer[circularBufferSize]; //This is filled by ISR and read by getData
147+
volatile int16_t outBuffer1[_pdmBufferSize];
148+
volatile int16_t outBuffer2[_pdmBufferSize];
149+
volatile int buff1New = false;
150+
volatile int buff2New = false;
141151
};
142152

143153
#endif //_PDM_H_

0 commit comments

Comments
 (0)