44
55 This example demonstrates how to read audio data and output
66 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.
118
129 Note: Audio samples are generated fast enough that we need to output
1310 serial at 500kbps.
14- */
15-
16- #include " am_bsp.h"
1711
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+ */
2417
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
3020
31- am_hal_pdm_transfer_t sTransfer ;
21+ #define pdmDataSize 4096 // Library requires array be 4096
22+ uint16_t pdmData[pdmDataSize];
3223
3324// -----------------
3425// PDM Configuration
@@ -53,104 +44,27 @@ am_hal_pdm_config_t newConfig = {
5344 .bLRSwap = 0 ,
5445};
5546
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-
13147void setup ()
13248{
13349 Serial.begin (500000 );
13450 delay (10 );
135- initPDM (); // Setup and begin PDM interrupts
136- }
13751
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
14159}
14260
143- void processFrame ()
61+ void loop ()
14462{
145- // Print any new data to serial port
146- if (buff1New == true )
63+ if (myPDM.available ())
14764 {
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));
15569 }
156- }
70+ }
0 commit comments