Skip to content

Commit 6847154

Browse files
author
Nathan Seidle
committed
Remove old Uart bits. Update keywords. Add examples.
1 parent 134aa6b commit 6847154

File tree

6 files changed

+445
-73
lines changed

6 files changed

+445
-73
lines changed

libraries/PDM/examples/Example1_MicrophoneOutput/Example1_MicrophoneOutput.ino

Lines changed: 26 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -3,40 +3,27 @@
33
License: MIT. See SparkFun Arduino Apollo3 Project for more information
44
55
This example demonstrates how to use the PDM microphone on Artemis boards.
6+
This library and example are heavily based on the Apollo3 pdm_fft example.
67
*/
78

8-
#define ARM_MATH_CM4
9-
#include <arm_math.h>
10-
11-
//*****************************************************************************
12-
//
13-
// Example parameters.
14-
//
15-
//*****************************************************************************
16-
#define PDM_FFT_SIZE 4096
17-
//uint32_t pdmDataBufferSize = 4096;
18-
#define pdmDataBufferSize 4096
19-
20-
//#define PDM_FFT_BYTES (PDM_FFT_SIZE * 2)
21-
#define PRINT_PDM_DATA 0
22-
#define PRINT_FFT_DATA 0
23-
24-
//*****************************************************************************
25-
//
26-
// Global variables.
27-
//
28-
//*****************************************************************************
29-
//uint32_t g_ui32PDMDataBuffer[pdmDataBufferSize];
9+
//Global variables needed for this sketch
10+
#define pdmDataBufferSize 4096 //Default is array of 4096 * 32bit
3011
uint32_t pdmDataBuffer[pdmDataBufferSize];
3112
float g_fPDMTimeDomain[pdmDataBufferSize * 2];
3213
float g_fPDMFrequencyDomain[pdmDataBufferSize * 2];
3314
float g_fPDMMagnitudes[pdmDataBufferSize * 2];
34-
3515
uint32_t sampleFreq;
3616

17+
//Enable these defines for additional debug printing
18+
#define PRINT_PDM_DATA 0
19+
#define PRINT_FFT_DATA 0
20+
3721
#include <PDM.h> //Include PDM library included with the Aruino_Apollo3 core
22+
AP3_PDM myPDM; //Create instance of PDM class
3823

39-
AP3_PDM myPDM;
24+
//Math library needed for FFT
25+
#define ARM_MATH_CM4
26+
#include <arm_math.h>
4027

4128
void setup()
4229
{
@@ -57,9 +44,9 @@ void setup()
5744
//myPDM.setGain(AM_HAL_PDM_GAIN_P210DB);
5845
//myPDM.setChannel(AM_HAL_PDM_CHANNEL_STEREO);
5946

60-
pdm_config_print();
61-
am_hal_pdm_fifo_flush(myPDM._PDMhandle);
62-
myPDM.getData(pdmDataBuffer, pdmDataBufferSize);
47+
printPDMConfig();
48+
49+
myPDM.getData(pdmDataBuffer, pdmDataBufferSize); //This clears the current PDM FIFO and starts DMA
6350
}
6451

6552
void loop()
@@ -68,15 +55,15 @@ void loop()
6855

6956
if (myPDM.available())
7057
{
71-
pcm_fft_print();
58+
printLoudest();
7259

7360
while (PRINT_PDM_DATA || PRINT_FFT_DATA);
7461

7562
// Start converting the next set of PCM samples.
7663
myPDM.getData(pdmDataBuffer, pdmDataBufferSize);
7764
}
7865

79-
// Go to Deep Sleep.
66+
// Go to Deep Sleep until the PDM ISR or other ISR wakes us.
8067
am_hal_sysctrl_sleep(AM_HAL_SYSCTRL_SLEEP_DEEP);
8168

8269
am_hal_interrupt_master_enable();
@@ -87,8 +74,7 @@ void loop()
8774
// Analyze and print frequency data.
8875
//
8976
//*****************************************************************************
90-
void
91-
pcm_fft_print(void)
77+
void printLoudest(void)
9278
{
9379
float fMaxValue;
9480
uint32_t ui32MaxIndex;
@@ -99,7 +85,7 @@ pcm_fft_print(void)
9985
// Convert the PDM samples to floats, and arrange them in the format
10086
// required by the FFT function.
10187
//
102-
for (uint32_t i = 0; i < PDM_FFT_SIZE; i++)
88+
for (uint32_t i = 0; i < pdmDataBufferSize; i++)
10389
{
10490
if (PRINT_PDM_DATA)
10591
{
@@ -119,13 +105,13 @@ pcm_fft_print(void)
119105
// Perform the FFT.
120106
//
121107
arm_cfft_radix4_instance_f32 S;
122-
arm_cfft_radix4_init_f32(&S, PDM_FFT_SIZE, 0, 1);
108+
arm_cfft_radix4_init_f32(&S, pdmDataBufferSize, 0, 1);
123109
arm_cfft_radix4_f32(&S, g_fPDMTimeDomain);
124-
arm_cmplx_mag_f32(g_fPDMTimeDomain, g_fPDMMagnitudes, PDM_FFT_SIZE);
110+
arm_cmplx_mag_f32(g_fPDMTimeDomain, g_fPDMMagnitudes, pdmDataBufferSize);
125111

126112
if (PRINT_FFT_DATA)
127113
{
128-
for (uint32_t i = 0; i < PDM_FFT_SIZE / 2; i++)
114+
for (uint32_t i = 0; i < pdmDataBufferSize / 2; i++)
129115
{
130116
Serial.printf("%f\n", g_fPDMMagnitudes[i]);
131117
}
@@ -136,9 +122,9 @@ pcm_fft_print(void)
136122
//
137123
// Find the frequency bin with the largest magnitude.
138124
//
139-
arm_max_f32(g_fPDMMagnitudes, PDM_FFT_SIZE / 2, &fMaxValue, &ui32MaxIndex);
125+
arm_max_f32(g_fPDMMagnitudes, pdmDataBufferSize / 2, &fMaxValue, &ui32MaxIndex);
140126

141-
ui32LoudestFrequency = (sampleFreq * ui32MaxIndex) / PDM_FFT_SIZE;
127+
ui32LoudestFrequency = (sampleFreq * ui32MaxIndex) / pdmDataBufferSize;
142128

143129
if (PRINT_FFT_DATA)
144130
{
@@ -153,8 +139,7 @@ pcm_fft_print(void)
153139
// Print PDM configuration data.
154140
//
155141
//*****************************************************************************
156-
void
157-
pdm_config_print(void)
142+
void printPDMConfig(void)
158143
{
159144
uint32_t PDMClk;
160145
uint32_t MClkDiv;
@@ -195,12 +180,12 @@ pdm_config_print(void)
195180
//
196181
sampleFreq = (PDMClk / (MClkDiv * 2 * myPDM.getDecimationRate()));
197182

198-
frequencyUnits = (float) sampleFreq / (float) PDM_FFT_SIZE;
183+
frequencyUnits = (float) sampleFreq / (float) pdmDataBufferSize;
199184

200185
Serial.printf("Settings:\n");
201186
Serial.printf("PDM Clock (Hz): %12d\n", PDMClk);
202187
Serial.printf("Decimation Rate: %12d\n", myPDM.getDecimationRate());
203188
Serial.printf("Effective Sample Freq.: %12d\n", sampleFreq);
204-
Serial.printf("FFT Length: %12d\n\n", PDM_FFT_SIZE);
189+
Serial.printf("FFT Length: %12d\n\n", pdmDataBufferSize);
205190
Serial.printf("FFT Resolution: %15.3f Hz\n", frequencyUnits);
206191
}
Lines changed: 191 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,191 @@
1+
/* Author: Nathan Seidle
2+
Created: July 24, 2019
3+
License: MIT. See SparkFun Arduino Apollo3 Project for more information
4+
5+
This example shows how to modify the various PDM interface settings.
6+
*/
7+
8+
//Global variables needed for this sketch
9+
#define pdmDataBufferSize 4096 //Default is array of 4096 * 32bit
10+
uint32_t pdmDataBuffer[pdmDataBufferSize];
11+
float g_fPDMTimeDomain[pdmDataBufferSize * 2];
12+
float g_fPDMFrequencyDomain[pdmDataBufferSize * 2];
13+
float g_fPDMMagnitudes[pdmDataBufferSize * 2];
14+
uint32_t sampleFreq;
15+
16+
//Enable these defines for additional debug printing
17+
#define PRINT_PDM_DATA 0
18+
#define PRINT_FFT_DATA 0
19+
20+
#include <PDM.h> //Include PDM library included with the Aruino_Apollo3 core
21+
AP3_PDM myPDM; //Create instance of PDM class
22+
23+
//Math library needed for FFT
24+
#define ARM_MATH_CM4
25+
#include <arm_math.h>
26+
27+
void setup()
28+
{
29+
Serial.begin(9600);
30+
Serial.println("SparkFun PDM Example");
31+
32+
// Turn on the PDM, set it up for our chosen recording settings, and start
33+
// the first DMA transaction.
34+
if (myPDM.begin(22, 23) == false) //Data, clock - These are the pin names from variant file, not pad names
35+
{
36+
Serial.println("PDM Init failed. Are you sure these pins are PDM capable?");
37+
while (1);
38+
}
39+
Serial.println("PDM Initialized");
40+
41+
//For more settings see the
42+
myPDM.setClockSpeed(AM_HAL_PDM_CLK_3MHZ);
43+
myPDM.setClockDivider(AM_HAL_PDM_MCLKDIV_1);
44+
myPDM.setGain(AM_HAL_PDM_GAIN_P210DB);
45+
myPDM.setChannel(AM_HAL_PDM_CHANNEL_STEREO);
46+
47+
printPDMConfig();
48+
49+
myPDM.getData(pdmDataBuffer, pdmDataBufferSize); //This clears the current PDM FIFO and starts DMA
50+
}
51+
52+
void loop()
53+
{
54+
am_hal_interrupt_master_disable();
55+
56+
if (myPDM.available())
57+
{
58+
printLoudest();
59+
60+
while (PRINT_PDM_DATA || PRINT_FFT_DATA);
61+
62+
// Start converting the next set of PCM samples.
63+
myPDM.getData(pdmDataBuffer, pdmDataBufferSize);
64+
}
65+
66+
// Go to Deep Sleep until the PDM ISR or other ISR wakes us.
67+
am_hal_sysctrl_sleep(AM_HAL_SYSCTRL_SLEEP_DEEP);
68+
69+
am_hal_interrupt_master_enable();
70+
}
71+
72+
//*****************************************************************************
73+
//
74+
// Analyze and print frequency data.
75+
//
76+
//*****************************************************************************
77+
void printLoudest(void)
78+
{
79+
float fMaxValue;
80+
uint32_t ui32MaxIndex;
81+
int16_t *pi16PDMData = (int16_t *) pdmDataBuffer;
82+
uint32_t ui32LoudestFrequency;
83+
84+
//
85+
// Convert the PDM samples to floats, and arrange them in the format
86+
// required by the FFT function.
87+
//
88+
for (uint32_t i = 0; i < pdmDataBufferSize; i++)
89+
{
90+
if (PRINT_PDM_DATA)
91+
{
92+
Serial.printf("%d\n", pi16PDMData[i]);
93+
}
94+
95+
g_fPDMTimeDomain[2 * i] = pi16PDMData[i] / 1.0;
96+
g_fPDMTimeDomain[2 * i + 1] = 0.0;
97+
}
98+
99+
if (PRINT_PDM_DATA)
100+
{
101+
Serial.printf("END\n");
102+
}
103+
104+
//
105+
// Perform the FFT.
106+
//
107+
arm_cfft_radix4_instance_f32 S;
108+
arm_cfft_radix4_init_f32(&S, pdmDataBufferSize, 0, 1);
109+
arm_cfft_radix4_f32(&S, g_fPDMTimeDomain);
110+
arm_cmplx_mag_f32(g_fPDMTimeDomain, g_fPDMMagnitudes, pdmDataBufferSize);
111+
112+
if (PRINT_FFT_DATA)
113+
{
114+
for (uint32_t i = 0; i < pdmDataBufferSize / 2; i++)
115+
{
116+
Serial.printf("%f\n", g_fPDMMagnitudes[i]);
117+
}
118+
119+
Serial.printf("END\n");
120+
}
121+
122+
//
123+
// Find the frequency bin with the largest magnitude.
124+
//
125+
arm_max_f32(g_fPDMMagnitudes, pdmDataBufferSize / 2, &fMaxValue, &ui32MaxIndex);
126+
127+
ui32LoudestFrequency = (sampleFreq * ui32MaxIndex) / pdmDataBufferSize;
128+
129+
if (PRINT_FFT_DATA)
130+
{
131+
Serial.printf("Loudest frequency bin: %d\n", ui32MaxIndex);
132+
}
133+
134+
Serial.printf("Loudest frequency: %d \n", ui32LoudestFrequency);
135+
}
136+
137+
//*****************************************************************************
138+
//
139+
// Print PDM configuration data.
140+
//
141+
//*****************************************************************************
142+
void printPDMConfig(void)
143+
{
144+
uint32_t PDMClk;
145+
uint32_t MClkDiv;
146+
float frequencyUnits;
147+
148+
//
149+
// Read the config structure to figure out what our internal clock is set
150+
// to.
151+
//
152+
switch (myPDM.getClockDivider())
153+
{
154+
case AM_HAL_PDM_MCLKDIV_4: MClkDiv = 4; break;
155+
case AM_HAL_PDM_MCLKDIV_3: MClkDiv = 3; break;
156+
case AM_HAL_PDM_MCLKDIV_2: MClkDiv = 2; break;
157+
case AM_HAL_PDM_MCLKDIV_1: MClkDiv = 1; break;
158+
159+
default:
160+
MClkDiv = 0;
161+
}
162+
163+
switch (myPDM.getClockSpeed())
164+
{
165+
case AM_HAL_PDM_CLK_12MHZ: PDMClk = 12000000; break;
166+
case AM_HAL_PDM_CLK_6MHZ: PDMClk = 6000000; break;
167+
case AM_HAL_PDM_CLK_3MHZ: PDMClk = 3000000; break;
168+
case AM_HAL_PDM_CLK_1_5MHZ: PDMClk = 1500000; break;
169+
case AM_HAL_PDM_CLK_750KHZ: PDMClk = 750000; break;
170+
case AM_HAL_PDM_CLK_375KHZ: PDMClk = 375000; break;
171+
case AM_HAL_PDM_CLK_187KHZ: PDMClk = 187000; break;
172+
173+
default:
174+
PDMClk = 0;
175+
}
176+
177+
//
178+
// Record the effective sample frequency. We'll need it later to print the
179+
// loudest frequency from the sample.
180+
//
181+
sampleFreq = (PDMClk / (MClkDiv * 2 * myPDM.getDecimationRate()));
182+
183+
frequencyUnits = (float) sampleFreq / (float) pdmDataBufferSize;
184+
185+
Serial.printf("Settings:\n");
186+
Serial.printf("PDM Clock (Hz): %12d\n", PDMClk);
187+
Serial.printf("Decimation Rate: %12d\n", myPDM.getDecimationRate());
188+
Serial.printf("Effective Sample Freq.: %12d\n", sampleFreq);
189+
Serial.printf("FFT Length: %12d\n\n", pdmDataBufferSize);
190+
Serial.printf("FFT Resolution: %15.3f Hz\n", frequencyUnits);
191+
}

0 commit comments

Comments
 (0)