PDM

Detailed Description

Pulse Density Modulation (PDM) peripheral API.

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

Example PDM usage when interfacing to two PDM microphones:

Configure clocks and GPIO pins:

// Lock PLL to 1,411,209 Hz to achive 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.
// Select PDM reference clock source and enable it.
// 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(PDM, &init);
while (true) {
*pBuffer++ = PDM_Rx(PDM);
}

Data Structures

struct  PDM_Init_TypeDef
 

Macros

#define PDM_INIT_DEFAULT
 

Enumerations

enum  PDM_Ch0ClkPolarity_Typedef {
  pdmCh0ClkPolarityRisingEdge = _PDM_CFG0_CH0CLKPOL_NORMAL,
  pdmCh0ClkPolarityFallingEdge = _PDM_CFG0_CH0CLKPOL_INVERT
}
 
enum  PDM_Ch1ClkPolarity_Typedef {
  pdmCh1ClkPolarityRisingEdge = _PDM_CFG0_CH1CLKPOL_NORMAL,
  pdmCh1ClkPolarityFallingEdge = _PDM_CFG0_CH1CLKPOL_INVERT
}
 
enum  PDM_Ch2ClkPolarity_Typedef {
  pdmCh2ClkPolarityRisingEdge = _PDM_CFG0_CH2CLKPOL_NORMAL,
  pdmCh2ClkPolarityFallingEdge = _PDM_CFG0_CH2CLKPOL_INVERT
}
 
enum  PDM_Ch3ClkPolarity_Typedef {
  pdmCh3ClkPolarityRisingEdge = _PDM_CFG0_CH3CLKPOL_NORMAL,
  pdmCh3ClkPolarityFallingEdge = _PDM_CFG0_CH3CLKPOL_INVERT
}
 
enum  PDM_DataFormat_TypeDef {
  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
}
 
enum  PDM_FifoValidWatermark_Typedef {
  pdmFifoValidWatermarkOne = _PDM_CFG0_FIFODVL_ONE,
  pdmFifoValidWatermarkTwo = _PDM_CFG0_FIFODVL_TWO,
  pdmFifoValidWatermarkThree = _PDM_CFG0_FIFODVL_THREE,
  pdmFifoValidWatermarkFour = _PDM_CFG0_FIFODVL_FOUR
}
 
enum  PDM_FilterOrder_TypeDef {
  pdmFilterOrderSecond = _PDM_CFG0_FORDER_SECOND,
  pdmFilterOrderThird = _PDM_CFG0_FORDER_THIRD,
  pdmFilterOrderFourth = _PDM_CFG0_FORDER_FOURTH,
  pdmFilterOrderFifth = _PDM_CFG0_FORDER_FIFTH
}
 
enum  PDM_NumberOfChannels_TypeDef {
  pdmNumberOfChannelsOne = _PDM_CFG0_NUMCH_ONE,
  pdmNumberOfChannelsTwo = _PDM_CFG0_NUMCH_TWO,
  pdmNumberOfChannelsThree = _PDM_CFG0_NUMCH_THREE,
  pdmNumberOfChannelsFour = _PDM_CFG0_NUMCH_FOUR
}
 

Functions

__STATIC_INLINE void PDM_Clear (PDM_TypeDef *pdm)
 Clear PDM filter.
 
void PDM_DeInit (PDM_TypeDef *pdm)
 De-initialize the PDM peripheral.
 
__STATIC_INLINE void PDM_FifoFlush (PDM_TypeDef *pdm)
 Flush the PDM sample FIFO.
 
void PDM_Init (PDM_TypeDef *pdm, const PDM_Init_TypeDef *init)
 Initialize the PDM peripheral.
 
__STATIC_INLINE void PDM_IntClear (PDM_TypeDef *pdm, uint32_t flags)
 Clear one or more pending PDM interrupts.
 
__STATIC_INLINE void PDM_IntDisable (PDM_TypeDef *pdm, uint32_t flags)
 Disable one or more PDM interrupts.
 
__STATIC_INLINE void PDM_IntEnable (PDM_TypeDef *pdm, uint32_t flags)
 Enable one or more PDM interrupts.
 
__STATIC_INLINE uint32_t PDM_IntGet (PDM_TypeDef *pdm)
 Get pending PDM interrupt flags.
 
__STATIC_INLINE uint32_t PDM_IntGetEnabled (PDM_TypeDef *pdm)
 Get enabled and pending PDM interrupt flags. Useful for handling more interrupt sources in the same interrupt handler.
 
__STATIC_INLINE void PDM_IntSet (PDM_TypeDef *pdm, uint32_t flags)
 Set one or more pending PDM interrupts.
 
void PDM_Reset (PDM_TypeDef *pdm)
 Initialize PDM registers with reset values.
 
__STATIC_INLINE uint32_t PDM_Rx (PDM_TypeDef *pdm)
 Read one entry from the PDM FIFO.
 
__STATIC_INLINE void PDM_Start (PDM_TypeDef *pdm)
 Start PDM operation (start the PDM filter).
 
__STATIC_INLINE uint32_t PDM_StatusGet (PDM_TypeDef *pdm)
 Get PDM STATUS register.
 
__STATIC_INLINE void PDM_Stop (PDM_TypeDef *pdm)
 Stop PDM operation (stop the PDM filter).
 

Macro Definition Documentation

#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 212 of file em_pdm.h.

Enumeration Type Documentation

Configure CH0 CLK Polarity.

Enumerator
pdmCh0ClkPolarityRisingEdge 

Input data clocked on rising clock edge.

pdmCh0ClkPolarityFallingEdge 

Input data clocked on falling clock edge.

Definition at line 132 of file em_pdm.h.

Configure CH1 CLK Polarity.

Enumerator
pdmCh1ClkPolarityRisingEdge 

Input data clocked on rising clock edge.

pdmCh1ClkPolarityFallingEdge 

Input data clocked on falling clock edge.

Definition at line 126 of file em_pdm.h.

Configure CH2 CLK Polarity.

Enumerator
pdmCh2ClkPolarityRisingEdge 

Input data clocked on rising clock edge.

pdmCh2ClkPolarityFallingEdge 

Input data clocked on falling clock edge.

Definition at line 119 of file em_pdm.h.

Configure CH3 CLK Polarity.

Enumerator
pdmCh3ClkPolarityRisingEdge 

Input data clocked on rising clock edge.

pdmCh3ClkPolarityFallingEdge 

Input data clocked on falling clock edge.

Definition at line 113 of file em_pdm.h.

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 146 of file em_pdm.h.

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 138 of file em_pdm.h.

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 167 of file em_pdm.h.

Configure number of PDM channels.

Enumerator
pdmNumberOfChannelsOne 

Only one Channel.

pdmNumberOfChannelsTwo 

Two Channels.

pdmNumberOfChannelsThree 

Three Channels.

pdmNumberOfChannelsFour 

Four Channels.

Definition at line 157 of file em_pdm.h.

Function Documentation

__STATIC_INLINE void PDM_Clear ( PDM_TypeDef *  pdm)

Clear PDM filter.

Parameters
[in]pdmA pointer to the PDM peripheral register block.

Definition at line 262 of file em_pdm.h.

Referenced by PDM_DeInit(), and PDM_Init().

void PDM_DeInit ( PDM_TypeDef *  pdm)

De-initialize the PDM peripheral.

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

Parameters
[in]pdmA pointer to the PDM peripheral register block.

Definition at line 57 of file em_pdm.c.

References PDM_Clear(), PDM_FifoFlush(), PDM_Reset(), and PDM_Stop().

__STATIC_INLINE void PDM_FifoFlush ( PDM_TypeDef *  pdm)

Flush the PDM sample FIFO.

Parameters
[in]pdmA pointer to the PDM peripheral register block.

Definition at line 277 of file em_pdm.h.

Referenced by PDM_DeInit(), and PDM_Init().

void PDM_Init ( PDM_TypeDef *  pdm,
const PDM_Init_TypeDef init 
)

Initialize the PDM peripheral.

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.

Parameters
[in]pdmA pointer to the PDM peripheral register block.
[in]initA pointer to the initialization structure used to configure the PDM.

Definition at line 82 of file em_pdm.c.

References PDM_Init_TypeDef::ch0ClkPolarity, PDM_Init_TypeDef::ch1ClkPolarity, PDM_Init_TypeDef::ch2ClkPolarity, PDM_Init_TypeDef::ch3ClkPolarity, PDM_Init_TypeDef::dataFormat, PDM_Init_TypeDef::dsr, PDM_Init_TypeDef::enableCh0Ch1Stereo, PDM_Init_TypeDef::enableCh2Ch3Stereo, PDM_Init_TypeDef::fifoValidWatermark, PDM_Init_TypeDef::filterOrder, PDM_Init_TypeDef::gain, PDM_Init_TypeDef::numChannels, PDM_Init_TypeDef::outClkEn, PDM_Clear(), PDM_FifoFlush(), PDM_Start(), PDM_Init_TypeDef::prescaler, and PDM_Init_TypeDef::start.

__STATIC_INLINE void PDM_IntClear ( PDM_TypeDef *  pdm,
uint32_t  flags 
)

Clear one or more pending PDM interrupts.

Parameters
[in]pdmA pointer to the PDM peripheral register block.
[in]flagsPending 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 297 of file em_pdm.h.

__STATIC_INLINE void PDM_IntDisable ( PDM_TypeDef *  pdm,
uint32_t  flags 
)

Disable one or more PDM interrupts.

Parameters
[in]pdmA pointer to the PDM peripheral register block.
[in]flagsPDM 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 318 of file em_pdm.h.

__STATIC_INLINE void PDM_IntEnable ( PDM_TypeDef *  pdm,
uint32_t  flags 
)

Enable one or more PDM interrupts.

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.
Parameters
[in]pdmA pointer to the PDM peripheral register block.
[in]flagsPDM 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.

Definition at line 340 of file em_pdm.h.

__STATIC_INLINE uint32_t PDM_IntGet ( PDM_TypeDef *  pdm)

Get pending PDM interrupt flags.

Note
Event bits are not cleared by the use of this function.
Parameters
[in]pdmA pointer to the PDM peripheral register block.
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 360 of file em_pdm.h.

__STATIC_INLINE uint32_t PDM_IntGetEnabled ( PDM_TypeDef *  pdm)

Get enabled and pending PDM interrupt flags. Useful for handling more interrupt sources in the same interrupt handler.

Note
Interrupt flags are not cleared by the use of this function.
Parameters
[in]pdmA pointer to the PDM peripheral register block.
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 382 of file em_pdm.h.

__STATIC_INLINE void PDM_IntSet ( PDM_TypeDef *  pdm,
uint32_t  flags 
)

Set one or more pending PDM interrupts.

Parameters
[in]pdmA pointer to the PDM peripheral register block.
[in]flagsPDM 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 402 of file em_pdm.h.

void PDM_Reset ( PDM_TypeDef *  pdm)

Initialize PDM registers with reset values.

Parameters
[in]pdmA pointer to the PDM peripheral register block.

Definition at line 139 of file em_pdm.c.

Referenced by PDM_DeInit().

__STATIC_INLINE uint32_t PDM_Rx ( PDM_TypeDef *  pdm)

Read one entry from the PDM FIFO.

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.
Parameters
[in]pdmA pointer to the PDM peripheral register block.
Returns
The entry read from the FIFO.

Definition at line 426 of file em_pdm.h.

__STATIC_INLINE void PDM_Start ( PDM_TypeDef *  pdm)

Start PDM operation (start the PDM filter).

Parameters
[in]pdmA pointer to the PDM peripheral register block.

Definition at line 441 of file em_pdm.h.

Referenced by PDM_Init().

__STATIC_INLINE uint32_t PDM_StatusGet ( PDM_TypeDef *  pdm)

Get PDM STATUS register.

Parameters
[in]pdmA pointer to the PDM peripheral register block.
Returns
STATUS register value.

Definition at line 459 of file em_pdm.h.

__STATIC_INLINE void PDM_Stop ( PDM_TypeDef *  pdm)

Stop PDM operation (stop the PDM filter).

Parameters
[in]pdmA pointer to the PDM peripheral register block.

Definition at line 471 of file em_pdm.h.

Referenced by PDM_DeInit().