PDM - Pulse Density Modulation#

Pulse Density Modulation (PDM) peripheral API.

PDM API functions provide full support for the PDM peripheral. The PDM peripheral accepts PDM bitstreams and produces PCM encoded output.

The following is an example PDM usage when interfacing to two PDM microphones:

Configure clocks and GPIO pins:

PDM_Init_TypeDef     pdmInit = PDM_INIT_DEFAULT;
CMU_DPLLInit_TypeDef pllInit = CMU_DPLL_LFXO_TO_40MHZ;

CMU_OscillatorEnable(cmuOsc_LFXO, true, true);
// Lock PLL to 1,411,209 Hz to achieve 44,100 kHz PCM sampling rate
// when using 32x PDM oversampling
pllInit.frequency = 1411209;
pllInit.m = 14;
pllInit.n = 645;
CMU_DPLLLock(&pllInit);

// Setup all GPIO's.
GPIO_PinModeSet(MIC_CLK_PORT, MIC_CLK_PIN, gpioModePushPull, 0);
GPIO_PinModeSet(MIC_DATA_PORT, MIC_DATA_PIN, gpioModeInput, 0);

// Set fast slew rate on PDM mic CLK and DATA pins
GPIO_SlewrateSet(MIC_CLK_PORT, 7U, 7U);

// Enable PDM peripheral clock.
CMU_ClockEnable(cmuClock_PDM, true);
// Select PDM reference clock source and enable it.
CMU_ClockSelectSet(cmuClock_PDMREF, cmuSelect_HFRCO);
CMU_ClockEnable(cmuClock_PDMREF, true);

// Route PDM signals to correct GPIO's.
PDM->ROUTELOC0 = (PDM->ROUTELOC0 & ~_PDM_ROUTELOC0_DAT0LOC_MASK)
                 | (MIC_DATA_PDM_LOC << _PDM_ROUTELOC0_DAT0LOC_SHIFT);
PDM->ROUTELOC1 = MIC_CLK_PDM_LOC << _PDM_ROUTELOC1_CLKLOC_SHIFT;
PDM->ROUTEPEN |= PDM_ROUTEPEN_CLKPEN | PDM_ROUTEPEN_DAT0PEN;

Initialize and start PDM, then read PCM samples from FIFO:

PDM_Init_TypeDef init = PDM_INIT_DEFAULT;
PDM_Init(PDM, &init);

while (true) {
  *pBuffer++ = PDM_Rx(PDM);
}

Modules#

PDM_Init_TypeDef

Enumerations#

enum
pdmCh3ClkPolarityRisingEdge = _PDM_CFG0_CH3CLKPOL_NORMAL
pdmCh3ClkPolarityFallingEdge = _PDM_CFG0_CH3CLKPOL_INVERT
}

Configure CH3 CLK Polarity.

enum
pdmCh2ClkPolarityRisingEdge = _PDM_CFG0_CH2CLKPOL_NORMAL
pdmCh2ClkPolarityFallingEdge = _PDM_CFG0_CH2CLKPOL_INVERT
}

Configure CH2 CLK Polarity.

enum
pdmCh1ClkPolarityRisingEdge = _PDM_CFG0_CH1CLKPOL_NORMAL
pdmCh1ClkPolarityFallingEdge = _PDM_CFG0_CH1CLKPOL_INVERT
}

Configure CH1 CLK Polarity.

enum
pdmCh0ClkPolarityRisingEdge = _PDM_CFG0_CH0CLKPOL_NORMAL
pdmCh0ClkPolarityFallingEdge = _PDM_CFG0_CH0CLKPOL_INVERT
}

Configure CH0 CLK Polarity.

enum
pdmFifoValidWatermarkOne = _PDM_CFG0_FIFODVL_ONE
pdmFifoValidWatermarkTwo = _PDM_CFG0_FIFODVL_TWO
pdmFifoValidWatermarkThree = _PDM_CFG0_FIFODVL_THREE
pdmFifoValidWatermarkFour = _PDM_CFG0_FIFODVL_FOUR
}

Configure FIFO Data valid level water-mark.

enum
pdmDataFormatRight16 = _PDM_CFG0_DATAFORMAT_RIGHT16
pdmDataFormatDouble16 = _PDM_CFG0_DATAFORMAT_DOUBLE16
pdmDataFormatRight24 = _PDM_CFG0_DATAFORMAT_RIGHT24
pdmDataFormatFull32bit = _PDM_CFG0_DATAFORMAT_FULL32BIT
pdmDataFormatLeft16 = _PDM_CFG0_DATAFORMAT_LEFT16
pdmDataFormatLeft24 = _PDM_CFG0_DATAFORMAT_LEFT24
pdmDataFormatRaw32bit = _PDM_CFG0_DATAFORMAT_RAW32BIT
}

Configure PDM filter data output format.

enum
pdmNumberOfChannelsOne = _PDM_CFG0_NUMCH_ONE
pdmNumberOfChannelsTwo = _PDM_CFG0_NUMCH_TWO
pdmNumberOfChannelsThree = _PDM_CFG0_NUMCH_THREE
pdmNumberOfChannelsFour = _PDM_CFG0_NUMCH_FOUR
}

Configure number of PDM channels.

enum
pdmFilterOrderSecond = _PDM_CFG0_FORDER_SECOND
pdmFilterOrderThird = _PDM_CFG0_FORDER_THIRD
pdmFilterOrderFourth = _PDM_CFG0_FORDER_FOURTH
pdmFilterOrderFifth = _PDM_CFG0_FORDER_FIFTH
}

Configure order of the PDM filter.

Functions#

void
PDM_DeInit(PDM_TypeDef *pdm)

De-initialize the PDM peripheral.

void
PDM_Init(PDM_TypeDef *pdm, const PDM_Init_TypeDef *init)

Initialize the PDM peripheral.

void
PDM_Reset(PDM_TypeDef *pdm)

Initialize PDM registers with reset values.

void
PDM_Clear(PDM_TypeDef *pdm)

Clear the PDM filter.

void
PDM_FifoFlush(PDM_TypeDef *pdm)

Flush the PDM sample FIFO.

void
PDM_IntClear(PDM_TypeDef *pdm, uint32_t flags)

Clear one or more pending PDM interrupts.

void
PDM_IntDisable(PDM_TypeDef *pdm, uint32_t flags)

Disable one or more PDM interrupts.

void
PDM_IntEnable(PDM_TypeDef *pdm, uint32_t flags)

Enable one or more PDM interrupts.

uint32_t
PDM_IntGet(PDM_TypeDef *pdm)

Get pending PDM interrupt flags.

uint32_t
PDM_IntGetEnabled(PDM_TypeDef *pdm)

Get enabled and pending PDM interrupt flags.

void
PDM_IntSet(PDM_TypeDef *pdm, uint32_t flags)

Set one or more pending PDM interrupts.

uint32_t
PDM_Rx(PDM_TypeDef *pdm)

Read one entry from the PDM FIFO.

void
PDM_Start(PDM_TypeDef *pdm)

Start the PDM operation (start the PDM filter).

uint32_t
PDM_StatusGet(PDM_TypeDef *pdm)

Get the PDM STATUS register.

void
PDM_Stop(PDM_TypeDef *pdm)

Stop the PDM operation (stop the PDM filter).

Macros#

#define

Default configuration for PDM.

Enumeration Documentation#

PDM_Ch3ClkPolarity_Typedef#

PDM_Ch3ClkPolarity_Typedef

Configure CH3 CLK Polarity.

Enumerator
pdmCh3ClkPolarityRisingEdge

Input data clocked on rising clock edge.

pdmCh3ClkPolarityFallingEdge

Input data clocked on falling clock edge.


Definition at line 108 of file platform/emlib/inc/em_pdm.h

PDM_Ch2ClkPolarity_Typedef#

PDM_Ch2ClkPolarity_Typedef

Configure CH2 CLK Polarity.

Enumerator
pdmCh2ClkPolarityRisingEdge

Input data clocked on rising clock edge.

pdmCh2ClkPolarityFallingEdge

Input data clocked on falling clock edge.


Definition at line 114 of file platform/emlib/inc/em_pdm.h

PDM_Ch1ClkPolarity_Typedef#

PDM_Ch1ClkPolarity_Typedef

Configure CH1 CLK Polarity.

Enumerator
pdmCh1ClkPolarityRisingEdge

Input data clocked on rising clock edge.

pdmCh1ClkPolarityFallingEdge

Input data clocked on falling clock edge.


Definition at line 121 of file platform/emlib/inc/em_pdm.h

PDM_Ch0ClkPolarity_Typedef#

PDM_Ch0ClkPolarity_Typedef

Configure CH0 CLK Polarity.

Enumerator
pdmCh0ClkPolarityRisingEdge

Input data clocked on rising clock edge.

pdmCh0ClkPolarityFallingEdge

Input data clocked on falling clock edge.


Definition at line 127 of file platform/emlib/inc/em_pdm.h

PDM_FifoValidWatermark_Typedef#

PDM_FifoValidWatermark_Typedef

Configure FIFO Data valid level water-mark.

Enumerator
pdmFifoValidWatermarkOne

At least one word.

pdmFifoValidWatermarkTwo

Two words.

pdmFifoValidWatermarkThree

Three words.

pdmFifoValidWatermarkFour

Four words.


Definition at line 133 of file platform/emlib/inc/em_pdm.h

PDM_DataFormat_TypeDef#

PDM_DataFormat_TypeDef

Configure PDM filter data output format.

Enumerator
pdmDataFormatRight16

Right aligned 16-bit, left bits are sign extended.

pdmDataFormatDouble16

Pack two 16-bit samples into one 32-bit word.

pdmDataFormatRight24

Right aligned 24bit, left bits are sign extended.

pdmDataFormatFull32bit

32 bit data.

pdmDataFormatLeft16

Left aligned 16-bit, right bits are zeros.

pdmDataFormatLeft24

Left aligned 24-bit, right bits are zeros.

pdmDataFormatRaw32bit

RAW 32 bit data from integrator.


Definition at line 141 of file platform/emlib/inc/em_pdm.h

PDM_NumberOfChannels_TypeDef#

PDM_NumberOfChannels_TypeDef

Configure number of PDM channels.

Enumerator
pdmNumberOfChannelsOne

Only one Channel.

pdmNumberOfChannelsTwo

Two Channels.

pdmNumberOfChannelsThree

Three Channels.

pdmNumberOfChannelsFour

Four Channels.


Definition at line 152 of file platform/emlib/inc/em_pdm.h

PDM_FilterOrder_TypeDef#

PDM_FilterOrder_TypeDef

Configure order of the PDM filter.

Enumerator
pdmFilterOrderSecond

Second order filter.

pdmFilterOrderThird

Third order filter.

pdmFilterOrderFourth

Fourth order filter.

pdmFilterOrderFifth

Fifth order filter.


Definition at line 162 of file platform/emlib/inc/em_pdm.h

Function Documentation#

PDM_DeInit#

void PDM_DeInit (PDM_TypeDef * pdm)

De-initialize the PDM peripheral.

Parameters
[in]pdm

A pointer to the PDM peripheral register block.

This function will stop the PDM filter and set PDM control registers to their reset values.


Definition at line 52 of file platform/emlib/src/em_pdm.c

PDM_Init#

void PDM_Init (PDM_TypeDef * pdm, const PDM_Init_TypeDef * init)

Initialize the PDM peripheral.

Parameters
[in]pdm

A pointer to the PDM peripheral register block.

[in]init

A pointer to the initialization structure used to configure the PDM.

This function will configure basic settings in PDM according to values in the initialization data structure.

Notice that enabling of PDM clock, setup of PDM pins and setup of PRS is not covered by this function.


Definition at line 77 of file platform/emlib/src/em_pdm.c

PDM_Reset#

void PDM_Reset (PDM_TypeDef * pdm)

Initialize PDM registers with reset values.

Parameters
[in]pdm

A pointer to the PDM peripheral register block.


Definition at line 134 of file platform/emlib/src/em_pdm.c

PDM_Clear#

void PDM_Clear (PDM_TypeDef * pdm)

Clear the PDM filter.

Parameters
[in]pdm

A pointer to the PDM peripheral register block.


Definition at line 257 of file platform/emlib/inc/em_pdm.h

PDM_FifoFlush#

void PDM_FifoFlush (PDM_TypeDef * pdm)

Flush the PDM sample FIFO.

Parameters
[in]pdm

A pointer to the PDM peripheral register block.


Definition at line 272 of file platform/emlib/inc/em_pdm.h

PDM_IntClear#

void PDM_IntClear (PDM_TypeDef * pdm, uint32_t flags)

Clear one or more pending PDM interrupts.

Parameters
[in]pdm

A pointer to the PDM peripheral register block.

[in]flags

Pending PDM interrupt sources to clear. Use one or more valid interrupt flags for the PDM module. The flags are PDM_IFC_DV, PDM_IFC_DVL, PDM_IFC_OF and PDM_IFC_UF.


Definition at line 292 of file platform/emlib/inc/em_pdm.h

PDM_IntDisable#

void PDM_IntDisable (PDM_TypeDef * pdm, uint32_t flags)

Disable one or more PDM interrupts.

Parameters
[in]pdm

A pointer to the PDM peripheral register block.

[in]flags

PDM interrupt sources to disable. Use one or more valid interrupt flags for the PDM module. The flags are PDM_IEN_DV, PDM_IEN_DVL, PDM_IEN_OF and PDM_IEN_UF.


Definition at line 313 of file platform/emlib/inc/em_pdm.h

PDM_IntEnable#

void PDM_IntEnable (PDM_TypeDef * pdm, uint32_t flags)

Enable one or more PDM interrupts.

Parameters
[in]pdm

A pointer to the PDM peripheral register block.

[in]flags

PDM interrupt sources to enable. Use one or more valid interrupt flags for the PDM module. The flags are PDM_IEN_DV, PDM_IEN_DVL, PDM_IEN_OF and PDM_IEN_UF.

Note

  • Depending on the use, a pending interrupt may already be set prior to enabling the interrupt. To ignore a pending interrupt, consider using PDM_IntClear() prior to enabling the interrupt.


Definition at line 335 of file platform/emlib/inc/em_pdm.h

PDM_IntGet#

uint32_t PDM_IntGet (PDM_TypeDef * pdm)

Get pending PDM interrupt flags.

Parameters
[in]pdm

A pointer to the PDM peripheral register block.

Note

  • Event bits are not cleared by the use of this function.

Returns

  • PDM interrupt sources pending. Returns one or more valid interrupt flags for PDM module. The flags are PDM_IF_DV, PDM_IF_DVL, PDM_IF_OF and PDM_IF_UF.


Definition at line 355 of file platform/emlib/inc/em_pdm.h

PDM_IntGetEnabled#

uint32_t PDM_IntGetEnabled (PDM_TypeDef * pdm)

Get enabled and pending PDM interrupt flags.

Parameters
[in]pdm

A pointer to the PDM peripheral register block.

Useful for handling more interrupt sources in the same interrupt handler.

Note

  • Interrupt flags are not cleared by the use of this function.

Returns

  • Pending and enabled PDM interrupt sources Return value is the bitwise AND of

    • the enabled interrupt sources in PDM_IEN and

    • the pending interrupt flags PDM_IF


Definition at line 377 of file platform/emlib/inc/em_pdm.h

PDM_IntSet#

void PDM_IntSet (PDM_TypeDef * pdm, uint32_t flags)

Set one or more pending PDM interrupts.

Parameters
[in]pdm

A pointer to the PDM peripheral register block.

[in]flags

PDM interrupt sources to set to pending. Use one or more valid interrupt flags for the PDM module. The flags are PDM_IFS_DV, PDM_IFS_DVL, PDM_IFS_OF and PDM_IFS_UF.


Definition at line 397 of file platform/emlib/inc/em_pdm.h

PDM_Rx#

uint32_t PDM_Rx (PDM_TypeDef * pdm)

Read one entry from the PDM FIFO.

Parameters
[in]pdm

A pointer to the PDM peripheral register block.

Note

  • This function will wait until a sample is available in the FIFO. Depending on PDM configuration, a FIFO entry can consist of one or two samples.

Returns

  • The entry read from the FIFO.


Definition at line 421 of file platform/emlib/inc/em_pdm.h

PDM_Start#

void PDM_Start (PDM_TypeDef * pdm)

Start the PDM operation (start the PDM filter).

Parameters
[in]pdm

A pointer to the PDM peripheral register block.


Definition at line 436 of file platform/emlib/inc/em_pdm.h

PDM_StatusGet#

uint32_t PDM_StatusGet (PDM_TypeDef * pdm)

Get the PDM STATUS register.

Parameters
[in]pdm

A pointer to the PDM peripheral register block.

Returns

  • STATUS register value.


Definition at line 454 of file platform/emlib/inc/em_pdm.h

PDM_Stop#

void PDM_Stop (PDM_TypeDef * pdm)

Stop the PDM operation (stop the PDM filter).

Parameters
[in]pdm

A pointer to the PDM peripheral register block.


Definition at line 466 of file platform/emlib/inc/em_pdm.h

Macro Definition Documentation#

PDM_INIT_DEFAULT#

#define PDM_INIT_DEFAULT
Value:
{ \
true, /* Start PDM filter after initialization. */ \
true, /* Enable PDM clock. */ \
32U, /* PDM down sampling rate. */ \
5U, /* PDM gain. */ \
pdmCh3ClkPolarityRisingEdge, /* N/A. */ \
pdmCh2ClkPolarityRisingEdge, /* N/A. */ \
pdmCh1ClkPolarityFallingEdge, /* Input data clocked on falling clock edge. */ \
pdmCh0ClkPolarityRisingEdge, /* Input data clocked on rising clock edge. */ \
false, /* N/A. */ \
true, /* Enable stereo mode for channel pair CH0 and CH1. */ \
pdmFifoValidWatermarkOne, /* At least one word water-mark level. */ \
pdmDataFormatDouble16, /* Two 16-bit samples per FIFO entry. */ \
pdmNumberOfChannelsTwo, /* Two Channels. */ \
pdmFilterOrderFifth, /* Fifth order filter. */ \
0U /* No clock prescaling. */ \
}

Default configuration for PDM.

Stereo Ch0/1, 16bit samples, 44,100 Hz sampling rate, 32 times oversampling (requires 1,411,209 Hz PDM clock).


Definition at line 207 of file platform/emlib/inc/em_pdm.h