44 static unsigned int dmadrvChannelId;
45 static uint16_t *sampleBuffer;
46 static size_t sampleBufferLen;
47 static volatile bool sampleBufferReady;
48 static uint32_t sampleCount;
50 static volatile bool dmaBusy;
51 static float soundLevel;
52 static uint32_t cmuClkoutSel1;
66 static bool dmaCompleteCallback(
unsigned int channel,
unsigned int sequenceNo,
void *userParam );
67 static void adcEnable(
bool enable );
87 uint32_t
MIC_init( uint32_t fs, uint16_t *buffer,
size_t len )
91 uint32_t auxhfrcoFreq;
98 CMU ->ADCCTRL = CMU_ADCCTRL_ADC0CLKSEL_AUXHFRCO;
106 adcInit.em2ClockConfig = adcEm2ClockOnDemand;
114 adcInitScan.
prsSel = MIC_CONFIG_ADC_PRSSEL;
115 adcInitScan.scanDmaEm2Wu =
true;
118 ADC_ScanInputClear( &adcInitScan );
119 ADC_ScanSingleEndedInputAdd( &adcInitScan, adcScanInputGroup0, MIC_CONFIG_ADC_POSSEL );
124 PRS_SourceAsyncSignalSet( MIC_CONFIG_PRS_CH, MIC_CONFIG_PRS_SOURCE, MIC_CONFIG_PRS_SIGNAL );
126 #if MIC_CONFIG_USE_LETIMER
138 letimerInit.
enable =
false;
144 timerTop = timerFreq / fs - 1;
145 fs = timerFreq / (timerTop + 1);
152 cmuClkoutSel1 = CMU_CTRL_CLKOUTSEL1_ULFRCOQ;
156 cmuClkoutSel1 = CMU_CTRL_CLKOUTSEL1_LFXOQ;
170 sampleBufferReady =
false;
171 sampleBuffer = buffer;
172 sampleBufferLen = len;
193 PRS_SourceAsyncSignalSet( MIC_CONFIG_PRS_CH, 0, 0 );
217 if( nSamples > sampleBufferLen ) {
218 sampleCount = sampleBufferLen;
221 sampleCount = nSamples;
229 (
void *) sampleBuffer,
230 (
void *) &(
ADC0 ->SCANDATA ),
239 sampleBufferReady =
false;
275 for( i = 0; i < sampleCount; i++ ) {
276 mean += (float) sampleBuffer[i];
278 mean = mean / (float) sampleCount;
302 if( sampleBufferReady ) {
309 for( i = 0; i < sampleCount; i++ ) {
310 sample = ( (float) sampleBuffer[i] - mean ) / 2047.5;
311 power += sample * sample;
313 power = power / (float) sampleCount;
316 soundLevel = 10.0f * log10f( power );
318 sampleBufferReady =
false;
361 static bool dmaCompleteCallback(
unsigned int channel,
unsigned int sequenceNo,
void *userParam )
367 sampleBufferReady =
true;
384 static void adcEnable(
bool enable )
387 #if MIC_CONFIG_USE_LETIMER
393 CMU->CTRL |= cmuClkoutSel1;
396 CMU->CTRL &= ~cmuClkoutSel1;
Clock management unit (CMU) API.
void CMU_ClockSelectSet(CMU_Clock_TypeDef clock, CMU_Select_TypeDef ref)
Select reference clock/oscillator used for a clock branch.
#define MIC_ADC_CLOCK_FREQ
void LETIMER_Enable(LETIMER_TypeDef *letimer, bool enable)
Start/stop LETIMER.
#define ADC_INITSCAN_DEFAULT
void LETIMER_Init(LETIMER_TypeDef *letimer, const LETIMER_Init_TypeDef *init)
Initialize LETIMER.
Ecode_t DMADRV_PeripheralMemory(unsigned int channelId, DMADRV_PeripheralSignal_t peripheralSignal, void *dst, void *src, bool dstInc, int len, DMADRV_DataSize_t size, DMADRV_Callback_t callback, void *cbUserParam)
Start a peripheral to memory DMA transfer.
static void adcInit(void)
Initializes the A/D converter.
Low Energy Timer (LETIMER) peripheral API.
CMSIS Cortex-M Peripheral Access Layer for Silicon Laboratories microcontroller devices.
void LETIMER_RepeatSet(LETIMER_TypeDef *letimer, unsigned int rep, uint32_t value)
Set LETIMER repeat counter register value.
LETIMER_UFOA_TypeDef ufoa0
uint32_t BOARD_micEnable(bool enable)
Enables or disables the MEMS microphone.
#define LETIMER_INIT_DEFAULT
void ADC_Init(ADC_TypeDef *adc, const ADC_Init_TypeDef *init)
Initialize ADC.
ADC_PRSSEL_TypeDef prsSel
uint8_t ADC_TimebaseCalc(uint32_t hfperFreq)
Calculate timebase value in order to get a timebase providing at least 1us.
Utility Functions for the Thunderboard Sense.
void LETIMER_CompareSet(LETIMER_TypeDef *letimer, unsigned int comp, uint32_t value)
Set LETIMER compare register value.
void CMU_ClockEnable(CMU_Clock_TypeDef clock, bool enable)
Enable/disable a clock.
Ecode_t DMADRV_Init(void)
Initialize DMADRV.
#define ECODE_EMDRV_DMADRV_OK
Success return value.
uint16_t * MIC_getSampleBuffer(void)
Gets the sample buffer.
Driver for the SPV1840LR5H-B MEMS Microphone.
bool MIC_isBusy(void)
Checks if the microphone is in use.
Energy management unit (EMU) peripheral API.
Ecode_t DMADRV_AllocateChannel(unsigned int *channelId, void *capabilities)
Allocate (reserve) a DMA channel.
uint8_t ADC_PrescaleCalc(uint32_t adcFreq, uint32_t hfperFreq)
Calculate prescaler value used to determine ADC clock.
void ADC_InitScan(ADC_TypeDef *adc, const ADC_InitScan_TypeDef *init)
Initialize ADC scan sequence.
void MIC_deInit(void)
Powers down the MEMS microphone stops the ADC and frees up the DMA channel.
uint32_t MIC_init(uint32_t fs, uint16_t *buffer, size_t len)
Initializes MEMS microphone and sets up the DMA, ADC and clocking.
Analog to Digital Converter (ADC) peripheral API.
float MIC_getSoundLevel(float *var)
Calculates the sound level.
uint32_t CMU_ClockFreqGet(CMU_Clock_TypeDef clock)
Get clock frequency for a clock point.
ADC_Ref_TypeDef reference
BOARD module header file.
float MIC_getMean(void)
Calculates the average value of the samples in the buffer.
Peripheral Reflex System (PRS) peripheral API.
Ecode_t DMADRV_FreeChannel(unsigned int channelId)
Free an allocate (reserved) DMA channel.
void MIC_start(uint32_t nSamples)
Starts taking samples using DMA from the microphone.