Skip to content

PDM: cleanup and fix #138

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 8 commits into from
Mar 8, 2021
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
105 changes: 36 additions & 69 deletions libraries/PDM/src/stm32/PDM.cpp
Original file line number Diff line number Diff line change
@@ -23,15 +23,12 @@
#ifdef TARGET_STM

#include "PDM.h"
#include "audio.h"
#include "mbed.h"
extern "C" {
#include "audio.h"
}

#define AUDIO_FREQUENCY BSP_AUDIO_FREQUENCY_16K
#define AUDIO_IN_PDM_BUFFER_SIZE (uint32_t)(128)

//ALIGN_32BYTES (uint16_t recordPDMBuf[AUDIO_IN_PDM_BUFFER_SIZE]) __attribute__((section(".OPEN_AMP_SHMEM")));
// FIXME: need to add an entry for RAM_D3 to linker script
uint16_t* recordPDMBuf = (uint16_t*)0x38000000;
extern "C" uint16_t *g_pcmbuf;

PDMClass::PDMClass(int dinPin, int clkPin, int pwrPin) :
_dinPin(dinPin),
@@ -45,14 +42,10 @@ PDMClass::~PDMClass()
{
}

int PDMClass::begin(int channels, long sampleRate) {

_channels = channels;

// fixme: only works in stereo mode
channels = 2;
static int gain_db = -1;
static int _samplerate = -1;

setBufferSize(AUDIO_IN_PDM_BUFFER_SIZE / 4 * channels);
int PDMClass::begin(int channels, long sampleRate) {

if (isBoardRev2()) {
mbed::I2C i2c(PB_7, PB_6);
@@ -69,43 +62,36 @@ int PDMClass::begin(int channels, long sampleRate) {
i2c.write(8 << 1, data, sizeof(data));
}

BSP_AUDIO_IN_SelectInterface(AUDIO_IN_INTERFACE_PDM);
_channels = channels;
_samplerate = sampleRate;

/* Initialize audio IN at REC_FREQ*/
if (BSP_AUDIO_IN_InitEx(INPUT_DEVICE_DIGITAL_MIC, AUDIO_FREQUENCY, DEFAULT_AUDIO_IN_BIT_RESOLUTION, channels) != AUDIO_OK)
{
return 0;
if (gain_db == -1) {
gain_db = 24;
}

/* Start the record */
BSP_AUDIO_IN_Record((uint16_t*)recordPDMBuf, AUDIO_IN_PDM_BUFFER_SIZE * channels);
return 1;
//g_pcmbuf = (uint16_t*)_doubleBuffer.data();

if(py_audio_init(channels, sampleRate, gain_db, 0.9883f)) {
py_audio_start_streaming();
return 1;
}
return 0;
}

void PDMClass::end()
{
py_audio_stop_streaming();
py_audio_deinit();
}

int PDMClass::available()
{
size_t avail = _doubleBuffer.available();
if (_channels == 1) {
return avail/2;
} else {
return avail;
}
return avail;
}

int PDMClass::read(void* buffer, size_t size)
{
if (_channels == 1) {
uint16_t temp[size*2];
int read = _doubleBuffer.read(temp, size*2);
for (int i = 0; i < size; i++) {
((uint16_t*)buffer)[i] = temp[i*2];
}
return read;
}
int read = _doubleBuffer.read(buffer, size);
return read;
}
@@ -117,7 +103,9 @@ void PDMClass::onReceive(void(*function)(void))

void PDMClass::setGain(int gain)
{

gain_db = gain;
//end();
//begin(_channels, _samplerate);
}

void PDMClass::setBufferSize(int bufferSize)
@@ -127,49 +115,28 @@ void PDMClass::setBufferSize(int bufferSize)

void PDMClass::IrqHandler(bool halftranfer)
{

int start = halftranfer ? 0 : AUDIO_IN_PDM_BUFFER_SIZE;

if (BSP_AUDIO_IN_GetInterface() == AUDIO_IN_INTERFACE_PDM && _doubleBuffer.available() == 0) {

/* Invalidate Data Cache to get the updated content of the SRAM*/
SCB_InvalidateDCache_by_Addr((uint32_t *)&recordPDMBuf[start], AUDIO_IN_PDM_BUFFER_SIZE * 2);

//memcpy((uint16_t*)_doubleBuffer.data(), (uint16_t*)&recordPDMBuf[start], AUDIO_IN_PDM_BUFFER_SIZE/2);
BSP_AUDIO_IN_PDMToPCM((uint16_t*)&recordPDMBuf[start], (uint16_t*)_doubleBuffer.data());

/* Clean Data Cache to update the content of the SRAM */
SCB_CleanDCache_by_Addr((uint32_t*)_doubleBuffer.data(), AUDIO_IN_PDM_BUFFER_SIZE * 2);

if (_doubleBuffer.available() == 0) {
g_pcmbuf = (uint16_t*)_doubleBuffer.data();
audio_pendsv_callback();
_doubleBuffer.swap(_doubleBuffer.availableForWrite());
}

if (_onReceive) {
_onReceive();
}
}

extern "C" {
/**
@brief Calculates the remaining file size and new position of the pointer.
@param None
@retval None
*/
__attribute__((__used__)) void BSP_AUDIO_IN_TransferComplete_CallBack(void)
{
PDM.IrqHandler(false);
}
void PDMIrqHandler(bool halftranfer)
{
PDM.IrqHandler(halftranfer);
}

/**
@brief Manages the DMA Half Transfer complete interrupt.
@param None
@retval None
*/
__attribute__((__used__)) void BSP_AUDIO_IN_HalfTransfer_CallBack(void)
{
PDM.IrqHandler(true);
}
void PDMsetBufferSize(int size) {
PDM.setBufferSize(size);
}
}

PDMClass PDM(0, 0, 0);

#endif
#endif
1,852 changes: 285 additions & 1,567 deletions libraries/PDM/src/stm32/audio.c

Large diffs are not rendered by default.

360 changes: 27 additions & 333 deletions libraries/PDM/src/stm32/audio.h

Large diffs are not rendered by default.

122 changes: 0 additions & 122 deletions libraries/PDM/src/stm32/codec_api.h

This file was deleted.

28 changes: 0 additions & 28 deletions libraries/PDM/src/stm32/irq.c

This file was deleted.

1,043 changes: 0 additions & 1,043 deletions libraries/PDM/src/stm32/wm8994.c

This file was deleted.

188 changes: 0 additions & 188 deletions libraries/PDM/src/stm32/wm8994.h

This file was deleted.

1 change: 1 addition & 0 deletions libraries/PDM/src/utility/PDMDoubleBuffer.cpp
Original file line number Diff line number Diff line change
@@ -34,6 +34,7 @@ PDMDoubleBuffer::~PDMDoubleBuffer()
void PDMDoubleBuffer::setSize(int size)
{
_size = size;
reset();
}

void PDMDoubleBuffer::reset()
2 changes: 1 addition & 1 deletion libraries/PDM/src/utility/PDMDoubleBuffer.h
Original file line number Diff line number Diff line change
@@ -43,7 +43,7 @@ class PDMDoubleBuffer
void swap(int length = 0);

private:
uint8_t* _buffer[2];
uint8_t* _buffer[2] __attribute__((aligned (16)));
int _size;
volatile int _length[2];
volatile int _readOffset[2];