| 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 |