#include "../include/audio.h" #include "../include/fb.h" volatile unsigned* clk = (void*)CLOCK_BASE; volatile unsigned* pwm = (void*)PWM_BASE; volatile unsigned* dma = (void*)DMA_BASE; volatile unsigned* dmae = (void*)DMA_ENABLE; volatile unsigned* safe = (void*)DMA_ADDRESS; struct dma_cb playback_cb; void audio_init(void) { gpio_useAsAlt0(40); // Ensure PWM1 is mapped to GPIO 40/41 gpio_useAsAlt0(41); wait_msec(2); // Setup clock *(clk + BCM2711_PWMCLK_CNTL) = PM_PASSWORD | (1 << 5); // Stop clock wait_msec(2); int idiv = 2; *(clk + BCM2711_PWMCLK_DIV) = PM_PASSWORD | (idiv<<12); *(clk + BCM2711_PWMCLK_CNTL) = PM_PASSWORD | 16 | 1; // Osc + Enable wait_msec(2); // Setup PWM *(pwm + BCM2711_PWM_CONTROL) = 0; wait_msec(2); *(pwm+BCM2711_PWM0_RANGE) = 0x264; // 44.1khz, Stereo, 8-bit (54Mhz / 44100 / 2) *(pwm+BCM2711_PWM1_RANGE) = 0x264; *(pwm+BCM2711_PWM_CONTROL) = BCM2711_PWM1_USEFIFO | BCM2711_PWM1_ENABLE | BCM2711_PWM0_USEFIFO | BCM2711_PWM0_ENABLE | 1<<6; } void audio_play_cpu(unsigned char *data, unsigned int size) { int i=0; long status; // Write data out to FIFO while (i < size) { status = *(pwm + BCM2711_PWM_STATUS); if (!(status & BCM2711_FULL1)) { *(pwm+BCM2711_PWM_FIFO) = *(data + i); i++; *(pwm+BCM2711_PWM_FIFO) = *(data + i); i++; } if ((status & ERRORMASK)) { *(pwm+BCM2711_PWM_STATUS) = ERRORMASK; } } } void audio_play_dma(unsigned char *data, unsigned int size) { // Convert data (we expect 8-bit samples, but need to convert them to 32-bit words) for (int i=0;i