I am working on an application using an STM32U5A5 nucleo board with four MEMs PDM output format microphones. The microphones are configured such that data is valid for the left channel on a rising clock edge and valid for the right channel on a falling clock edge. My configuration is illustrated below.
Path | Microphone | MDF_SDI pin | valid Edge | Filter | GPDMA channel
1 L1-------------> MDF1_SDI0 ----->rising----> MDF_DFLT0---> 2
2 R1------------> MDF1_SDI0 ----->falling----> MDF_DFLT1---> 3
3 L2-------------> MDF1_SDI2 ---->rising-----> MDF_DFLT2---> 4
4 R2------------> MDF1_SDI2 - --->falling----> MDF_DFLT3---> 5
I have noticed that after reset, I'm not able to start a mono recording on path 2 unless a recording was previously started on path 1. Similarly, I' m not able to start a recording on path 4 unless a recording was previously started on path 3. Once path 1 has been configured, I'm able to independently start and stop recordings on path 2. Same for path 3 and 4. I am able to start recording on paths 1 and 3 irrespective of whether recordings have previously been started on other paths. The only difference in the initialization procedure between paths 1 and 2 is the bitstream selection setting (0 vs 1). Similarly, the only difference between the initialization for paths 3 and 4 is bitstream selection 4 vs 5. For paths 1 and 2, TRGO is set and reset after the initialization procedure. I've included the initialization procedure I'm using below:
#define AUDIO_L 0
#define AUDIO_R 1
#define ULTRA_L 2
#define ULTRA_R 3
void MDFFilterInit(MDF_Filter_TypeDef *filter, uint8_t bssel)
{
// Configure serial interface for SPI regular mode
// deactivate serial interface if active
if (filter->SITFCR & MDF_SITFCR_SITFACTIVE)
{
filter->SITFCR &= ~MDF_SITFCR_SITFEN;
while (filter->SITFCR & MDF_SITFCR_SITFACTIVE)
{
}
}
CLEAR_BIT(filter->SITFCR, MDF_SITFCR_SCKSRC | MDF_SITFCR_STH |
MDF_SITFCR_SITFMOD | MDF_SITFCR_SCKSRC |
MDF_SITFCR_SITFEN);
// clock absence detection
SET_BIT(filter->SITFCR, MDF_SITFCR_STH);
// normal SPI mode
SET_BIT(filter->SITFCR, MDF_SITFCR_SITFMOD_0);
if (bssel > AUDIO_R)
{
bssel += 2;
SET_BIT(filter->SITFCR, MDF_SITFCR_SCKSRC_0);
}
// enable
SET_BIT(filter->SITFCR, MDF_SITFCR_SITFEN);
// Configure digital fliter
// deactivate digital filter if active
if (filter->DFLTCR & MDF_DFLTCR_DFLTACTIVE)
{
filter->DFLTCR &= ~MDF_DFLTCR_DFLTEN;
while (filter->DFLTCR & MDF_DFLTCR_DFLTACTIVE)
{
}
}
if (filter->BSMXCR & MDF_BSMXCR_BSMXACTIVATE)
{
Error_Handler();
}
// Select data valid clock edge
SET_BIT(filter->BSMXCR, bssel & MDF_BSMXCR_BSSEL);
// Select trigger source
CLEAR_BIT(filter->DFLTCR, MDF_DFLTCR_TRGSRC);
if (bssel < ULTRA_L)
{
// set acquisition mode
MODIFY_REG(filter->DFLTCR, MDF_DFLTCR_ACQMOD, MDF_DFLTCR_ACQMOD_1);
}
else
{
CLEAR_BIT(filter->DFLTCR, MDF_DFLTCR_ACQMOD);
}
// DMA mode
SET_BIT(filter->DFLTCR, MDF_DFLTCR_DMAEN);
// 3 dB cutoff
SET_BIT(filter->DFLTRSFR, MDF_DFLTRSFR_HPFC_0);
// Enable filter. Sampling will only start when trigger is set.
SET_BIT(filter->DFLTCR, MDF_DFLTCR_DFLTEN);
}
My workaround is so initialize and then immediately de-initialize Filter0 when I only want to use Filter1 (same for Filter3 and Filter4). Then I am able to record only on filters 2 and 4 after reset.