cancel
Showing results for 
Search instead for 
Did you mean: 

BSMX falling edge data not always available

jcmoreau
Associate II

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.
0 REPLIES 0