C0G/NPO ceramic capacitor should be used for filtering. Low | C0G/NPO ceramic capacitor should be used for filtering. Low | ||||
quality ceramic (X7R, Y5V, Z5U, etc) can cause signal distortion.</p> | quality ceramic (X7R, Y5V, Z5U, etc) can cause signal distortion.</p> | ||||
<h3>Notes</h3> | <h3>Notes</h3> | ||||
<p>This object only works properly when Tools > CPU_Speed is set to | |||||
48 or 96 MHz. Other speeds aren't supported and will likely fail | |||||
in strange ways.</p> | |||||
<p>The PWM carrier frequency is 88.2 kHz. The suggested circuit | <p>The PWM carrier frequency is 88.2 kHz. The suggested circuit | ||||
will only slightly filter the carrier. Extra filtering will be | will only slightly filter the carrier. Extra filtering will be | ||||
required for a clean signal without the ultrasonic PWM carrier. | required for a clean signal without the ultrasonic PWM carrier. |
DMAMEM uint32_t pwm_dma_buffer[AUDIO_BLOCK_SAMPLES*2]; | DMAMEM uint32_t pwm_dma_buffer[AUDIO_BLOCK_SAMPLES*2]; | ||||
DMAChannel AudioOutputPWM::dma; | DMAChannel AudioOutputPWM::dma; | ||||
// TODO: this code assumes F_BUS is 48 MHz. | |||||
// supporting other speeds is not easy, but should be done someday | |||||
void AudioOutputPWM::begin(void) | void AudioOutputPWM::begin(void) | ||||
{ | { | ||||
dma.begin(true); // Allocate the DMA channel first | dma.begin(true); // Allocate the DMA channel first |
#ifndef pdb_h_ | #ifndef pdb_h_ | ||||
#define pdb_h_ | #define pdb_h_ | ||||
#include "kinetis.h" | |||||
// Multiple input & output objects use the Programmable Delay Block | // Multiple input & output objects use the Programmable Delay Block | ||||
// to set their sample rate. They must all configure the same | // to set their sample rate. They must all configure the same | ||||
// period to avoid chaos. | // period to avoid chaos. | ||||
#define PDB_CONFIG (PDB_SC_TRGSEL(15) | PDB_SC_PDBEN | PDB_SC_CONT) | #define PDB_CONFIG (PDB_SC_TRGSEL(15) | PDB_SC_PDBEN | PDB_SC_CONT) | ||||
#define PDB_PERIOD 1087 // 48e6 / 44100 | |||||
#if F_BUS == 60000000 | |||||
#define PDB_PERIOD (1360-1) | |||||
#elif F_BUS == 56000000 | |||||
#define PDB_PERIOD (1269-1) // 0.026% error | |||||
#elif F_BUS == 48000000 | |||||
#define PDB_PERIOD (1088-1) | |||||
#elif F_BUS == 36000000 | |||||
#define PDB_PERIOD (816-1) | |||||
#elif F_BUS == 24000000 | |||||
#define PDB_PERIOD (544-1) | |||||
#elif F_BUS == 16000000 | |||||
#define PDB_PERIOD (363-1) // 0.092% error | |||||
#else | |||||
#error "Unsupported F_BUS speed" | |||||
#endif | |||||
#endif | #endif |