Digital Microphone
This sample implements the function of DMIC collecting analog voice and decoding it with CODEC.
DMIC collects voice data, encodes it with CODEC, sends it to I2S receiving FIFO, and uses DMA to carry the data to UART.
The PC receives the data transferred from the UART through the serial assistant, parses the data using audio parsing software, and plays the recorded voice.
Requirements
The sample supports the following development kits:
Hardware Platforms |
Board Name |
---|---|
RTL87x2G HDK |
RTL87x2G EVB |
For more requirements, please refer to Quick Start.
Wiring
EVB external DMIC module, connect P2_2 to CLK, P2_3 to DATA.
EVB external FT232 module, connect P3_2 to RX, P3_3 to TX.
Building and Downloading
This sample can be found in the SDK folder:
Project file: samples\peripheral\codec\dmic\proj\rtl87x2g\mdk
Project file: samples\peripheral\codec\dmic\proj\rtl87x2g\gcc
To build and run the sample, follow the steps listed below:
Open sample project file.
To build the target, follow the steps listed on the Generating App Image in Quick Start.
After a successful compilation, the app bin
app_MP_xxx.bin
will be generated in the directorymdk\bin
orgcc\bin
.To download app bin into EVB board, follow the steps listed on the MP Tool Download in Quick Start.
Press reset button on EVB board and it will start running.
Experimental Verification
Preparation Phase
Start a PC terminal like PuTTY or UartAssist and connect to the used COM port with the following UART settings:
Baud rate: 3000000
8 data bits
1 stop bit
No parity
No hardware flow control
Start an audio parsing software.
Testing Phase
From the beginning to the end of the recording, the captured audio data is decoded and transmitted to the PC terminal via UART.
Copy the decoded data from the PC terminal to a newly created HEX bin file.
Use audio parsing software to view the waveform of the decoded voice, or play the voice.
Code Overview
This chapter will be introduced according to the following several parts:
Peripheral initialization will be introduced in chapter Initialization.
Functional implementation after initialization will be introduced in chapter Functional Implementation.
Source Code Directory
Project Directory:
sdk\samples\peripheral\codec\dmic\proj
Source Code Directory:
sdk\samples\peripheral\codec\dmic\src
Source files are currently categorized into several groups as below.
└── Project: dmic
└── secure_only_app
└── Device includes startup code
├── startup_rtl.c
└── system_rtl.c
├── CMSIS includes CMSIS header files
├── CMSE Library Non-secure callable lib
├── Lib includes all binary symbol files that user application is built on
└── rtl87x2g_io.lib
├── Peripheral includes all peripheral drivers and module code used by the application
├── rtl_rcc.c
├── rtl_pinmux.c
├── rtl_uart.c
├── rtl_gdma.c
├── rtl_nvic.c
├── rtl_codec.c
└── rtl_i2s.c
└── APP includes the ble_peripheral user application implementation
├── main_ns.c
└── io_codec.c
Initialization
The initialization process includes the initialization of the codec, uart, i2s, and gdma modules as follows
board_codec_init
contains the PAD and PINMUX settings for CODEC and DMIC:
Configure PAD: set pins, PINMUX mode, PowerOn, no internal Pull-Up.
Configure PINMUX: Assign pins to DMIC1_CLK, DMIC1_DAT, BCLK_SPORT0, LRC_RX_SPORT0, SDI_CODEC_SLAVE, and SDO_CODEC_SLAVE functions respectively.
Pad_Config(DMIC_MSBC_CLK_PIN, PAD_PINMUX_MODE, PAD_IS_PWRON, PAD_PULL_NONE, PAD_OUT_DISABLE,
PAD_OUT_LOW);
Pad_Config(DMIC_MSBC_DAT_PIN, PAD_PINMUX_MODE, PAD_IS_PWRON, PAD_PULL_NONE, PAD_OUT_DISABLE,
PAD_OUT_LOW);
Pinmux_Config(DMIC_MSBC_CLK_PIN, DMIC1_CLK);
Pinmux_Config(DMIC_MSBC_DAT_PIN, DMIC1_DAT);
Pad_Config(CODEC_BCLK_PIN, PAD_PINMUX_MODE, PAD_IS_PWRON, PAD_PULL_NONE, PAD_OUT_ENABLE,
PAD_OUT_LOW);
Pad_Config(CODEC_LRCLK_PIN, PAD_PINMUX_MODE, PAD_IS_PWRON, PAD_PULL_NONE, PAD_OUT_ENABLE,
PAD_OUT_LOW);
Pad_Config(CODEC_TX_PIN, PAD_PINMUX_MODE, PAD_IS_PWRON, PAD_PULL_NONE, PAD_OUT_ENABLE, PAD_OUT_LOW);
Pad_Config(CODEC_RX_PIN, PAD_PINMUX_MODE, PAD_IS_PWRON, PAD_PULL_NONE, PAD_OUT_ENABLE, PAD_OUT_LOW);
Pinmux_Config(CODEC_BCLK_PIN, BCLK_SPORT0);
Pinmux_Config(CODEC_LRCLK_PIN, LRC_RX_SPORT0);
Pinmux_Config(CODEC_TX_PIN, SDI_CODEC_SLAVE);
Pinmux_Config(CODEC_RX_PIN, SDO_CODEC_SLAVE);
board_uart_init
contains the PAD and PINMUX settings for UART, refer to amic initialization.
driver_i2s_init
contains the initialization of I2S peripherals, refer to amic initialization.
driver_uart_init
contains the initialization of UART peripherals, refer to amic initialization.
driver_gdma_init
contains the initialization of GDMA peripherals, refer to amic initialization.
driver_codec_init
contains the initialization of CODEC peripherals:
Enable PCC clock.
Select DMIC for microphone type.
Set the DMIC clock frequency to 2500kHz.
Set the data latch method for channel 0 digital microphone to rising edge latch.
Set the sampling frequency to 16kHz.
Set the data format to I2S format.
Set the channel width to 32 bits.
Set the RX data width to 16 bits.
Set the I2S channel order to left and right.
RCC_PeriphClockCmd(APBPeriph_CODEC, APBPeriph_CODEC_CLOCK, ENABLE);
...
CODEC_InitStruct.CODEC_Ch0MicType = CODEC_CH_DMIC;
CODEC_InitStruct.CODEC_DmicClock = DMIC_Clock_2500KHz;
CODEC_InitStruct.CODEC_Ch0DmicDataLatch = DMIC_Ch_Rising_Latch;
CODEC_InitStruct.CODEC_SampleRate0 = SAMPLE_RATE_16KHz;
CODEC_InitStruct.CODEC_I2SFormat = CODEC_I2S_DataFormat_I2S;
CODEC_InitStruct.CODEC_I2SChannelLen = I2S_CHANNELLEN_32;
CODEC_InitStruct.CODEC_I2SRxDataWidth = CODEC_I2S_Rx_DataWidth_16Bits;
CODEC_InitStruct.CODEC_I2SChSequence = CODEC_I2S_CH_L_R;
Functional Implementation
Enable I2S transmit mode and receive mode; enable GDMA channel 0.
I2S_Cmd(I2S0, I2S_MODE_TX | I2S_MODE_RX, ENABLE);
GDMA_Cmd(GDMA_Channel_DMIC_NUM, ENABLE);
DMIC collects analog voice data, decodes it by CODEC, sends it to I2S0 receiving FIFO, and carries the data to UART5 by using GDMA; when the data transmission is completed, it triggers the
GDMA_INT_Transfer
interrupt, and enters the interrupt handlerGDMA_Channel_DMIC_Handler
.Reset the source and destination addresses.
Reset the GDMA transfer data size.
Clear the GDMA channel 0
GDMA_INT_Transfer
interrupt pending bit and enable GDMA channel 0.
GDMA_SetSourceAddress(GDMA_Channel_DMIC, (uint32_t)(&(I2S0->I2S_RX_FIFO_RD_ADDR)));
GDMA_SetDestinationAddress(GDMA_Channel_DMIC, (uint32_t)(&(UART5->UART_RBR_THR)));
GDMA_SetBufferSize(GDMA_Channel_DMIC, AUDIO_FRAME_SIZE / 4);
GDMA_ClearINTPendingBit(GDMA_Channel_DMIC_NUM, GDMA_INT_Transfer);
GDMA_Cmd(GDMA_Channel_DMIC_NUM, ENABLE);