4
4
5
5
This example demonstrates how to read audio data and output
6
6
it to a WAV file. This sketch outputs raw serial; an accompanying
7
- python script visualizes and converts the raw data to a WAV file.
8
-
9
- Note: Wave files are 1024kbps which is higher than most audio players
10
- can handle. Use VLC to play the output files.
7
+ python script visualizes and coverts the raw data to a WAV file.
11
8
12
9
Note: Audio samples are generated fast enough that we need to output
13
10
serial at 500kbps.
14
- */
15
-
16
- #include " am_bsp.h"
17
11
18
- // ----------------
19
- // Global Variables
20
- // ----------------
21
- #define BUFFSIZE 512
22
- uint32_t PDMDataBuffer[BUFFSIZE];
23
- int16_t *pi16Buffer = (int16_t *)PDMDataBuffer;
12
+ The PDM hardware is setup to take a sample every 64us (15.625kHz sample rate)
13
+ The PDM library uses DMA to transfer 4096 bytes every 262ms and stores the
14
+ data between two internal buffers. So check available() often and call getData
15
+ to prevent buffer overruns.
16
+ */
24
17
25
- // Rather than a cicular buffer we record to one buffer while the other is printed to serial
26
- volatile int16_t outBuffer1[BUFFSIZE];
27
- volatile int16_t outBuffer2[BUFFSIZE];
28
- volatile int buff1New = false ;
29
- volatile int buff2New = false ;
18
+ #include < PDM.h> // Include PDM library included with the Aruino_Apollo3 core
19
+ AP3_PDM myPDM; // Create instance of PDM class with our buffer
30
20
31
- am_hal_pdm_transfer_t sTransfer ;
21
+ #define pdmDataSize 4096 // Library requires array be 4096
22
+ uint16_t pdmData[pdmDataSize];
32
23
33
24
// -----------------
34
25
// PDM Configuration
@@ -53,104 +44,27 @@ am_hal_pdm_config_t newConfig = {
53
44
.bLRSwap = 0 ,
54
45
};
55
46
56
- // -----------------
57
- // PDM Configuration
58
- // -----------------
59
- void initPDM (void )
60
- {
61
- // Initialize, power-up and configure PDM
62
- am_hal_pdm_initialize (0 , &PDMHandle);
63
- am_hal_pdm_power_control (PDMHandle, AM_HAL_PDM_POWER_ON, false );
64
- am_hal_pdm_configure (PDMHandle, &newConfig);
65
- am_hal_pdm_enable (PDMHandle);
66
-
67
- // Configure PDM pins
68
- am_hal_gpio_pinconfig (AM_BSP_PDM_DATA, g_AM_BSP_PDM_DATA);
69
- am_hal_gpio_pinconfig (AM_BSP_PDM_CLOCK, g_AM_BSP_PDM_CLOCK);
70
-
71
- // Configure PDM interrupts - set to trigger on DMA completion
72
- am_hal_pdm_interrupt_enable (PDMHandle, (AM_HAL_PDM_INT_DERR | AM_HAL_PDM_INT_DCMP | AM_HAL_PDM_INT_UNDFL | AM_HAL_PDM_INT_OVF));
73
- // Configure DMA and target address.
74
- sTransfer .ui32TargetAddr = (uint32_t )PDMDataBuffer;
75
- sTransfer .ui32TotalCount = BUFFSIZE * 2 ;
76
-
77
- // Start the data transfer.
78
- am_hal_pdm_enable (PDMHandle);
79
- am_util_delay_ms (100 );
80
-
81
- am_hal_pdm_fifo_flush (PDMHandle);
82
- am_hal_pdm_dma_start (PDMHandle, &sTransfer );
83
-
84
- // Enable PDM interrupt
85
- NVIC_EnableIRQ (PDM_IRQn);
86
- }
87
-
88
- // -----------------------------
89
- // PDM Interrupt Service Routine
90
- // -----------------------------
91
- extern " C" void am_pdm_isr (void )
92
- {
93
- uint32_t ui32Status;
94
-
95
- // Read the interrupt status.
96
- am_hal_pdm_interrupt_status_get (PDMHandle, &ui32Status, true );
97
- am_hal_pdm_interrupt_clear (PDMHandle, ui32Status);
98
-
99
- // Once DMA transaction completes, move to Queue & Start next conversion
100
- if (ui32Status & AM_HAL_PDM_INT_DCMP)
101
- {
102
-
103
- // Store in the first available buffer
104
- if (buff1New == false )
105
- {
106
- for (int i = 0 ; i < BUFFSIZE; i++)
107
- {
108
- outBuffer1[i] = pi16Buffer[i];
109
- }
110
- buff1New = true ;
111
- }
112
- else if (buff2New == false )
113
- {
114
- for (int i = 0 ; i < BUFFSIZE; i++)
115
- {
116
- outBuffer2[i] = pi16Buffer[i];
117
- }
118
- buff2New = true ;
119
- }
120
- else
121
- {
122
- // Used for debugging
123
- Serial.println (" \n\r Over flow!" );
124
- }
125
-
126
- // Start next conversion
127
- am_hal_pdm_dma_start (PDMHandle, &sTransfer );
128
- }
129
- }
130
-
131
47
void setup ()
132
48
{
133
49
Serial.begin (500000 );
134
50
delay (10 );
135
- initPDM (); // Setup and begin PDM interrupts
136
- }
137
51
138
- void loop ()
139
- {
140
- processFrame ();
52
+ if (myPDM.begin () == false ) // Turn on PDM with default settings, start interrupts
53
+ {
54
+ Serial.println (" PDM Init failed. Are you sure these pins are PDM capable?" );
55
+ while (1 )
56
+ ;
57
+ }
58
+ myPDM.updateConfig (newConfig); // Send config struct
141
59
}
142
60
143
- void processFrame ()
61
+ void loop ()
144
62
{
145
- // Print any new data to serial port
146
- if (buff1New == true )
63
+ if (myPDM.available ())
147
64
{
148
- Serial.write ((uint8_t *)outBuffer1, sizeof (outBuffer1));
149
- buff1New = false ;
150
- }
151
- if (buff2New == true )
152
- {
153
- Serial.write ((uint8_t *)outBuffer2, sizeof (outBuffer2));
154
- buff2New = false ;
65
+ myPDM.getData (pdmData, pdmDataSize);
66
+
67
+ // Print data to serial port
68
+ Serial.write ((uint8_t *)pdmData, sizeof (pdmData));
155
69
}
156
- }
70
+ }
0 commit comments