diff --git a/part10-multicore/io.h b/part10-multicore/io.h index 5c8f2e4..ff2fa98 100644 --- a/part10-multicore/io.h +++ b/part10-multicore/io.h @@ -1,4 +1,6 @@ #define PERIPHERAL_BASE 0xFE000000 +#define LEGACY_BASE 0x7E000000 +#define SAFE_ADDRESS 0x00400000 // Somewhere safe to store a lot of data void uart_init(); void uart_writeText(char *buffer); diff --git a/part10-multicore/kernel.c b/part10-multicore/kernel.c index 09f656b..b8c3dd0 100644 --- a/part10-multicore/kernel.c +++ b/part10-multicore/kernel.c @@ -3,7 +3,10 @@ #include "multicore.h" #define PWM_BASE (PERIPHERAL_BASE + 0x20C000 + 0x800) /* PWM1 register base address on RPi4 */ +#define PWM_LEGACY_BASE (LEGACY_BASE + 0x20C000 + 0x800) /* PWM1 register base legacy address on RPi4 */ #define CLOCK_BASE (PERIPHERAL_BASE + 0x101000) +#define DMA_BASE (PERIPHERAL_BASE + 0x007100) /* DMA register base address */ +#define DMA_ENABLE (DMA_BASE + 0xFF0) /* DMA global enable bits */ #define BCM2711_PWMCLK_CNTL 40 #define BCM2711_PWMCLK_DIV 41 @@ -31,8 +34,71 @@ #define BCM2711_FULL1 0x1 #define ERRORMASK (BCM2711_GAPO2 | BCM2711_GAPO1 | BCM2711_RERR1 | BCM2711_WERR1) +#define DMA_CS 0 /* Control/status register offset for DMA channel 0 */ +#define DMA_CONBLK_AD 1 +#define DMA_EN1 1 << 1 /* Enable DMA engine 1 */ +#define DMA_ACTIVE 1 /* Active bit set */ +#define DMA_DEST_DREQ 0x40 /* Use DREQ to pace peripheral writes */ +#define DMA_PERMAP_1 0x10000 /* PWM1 peripheral for DREQ */ +#define DMA_SRC_INC 0x100 /* Increment source address */ + 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*)SAFE_ADDRESS; + +struct dma_cb { + unsigned int ti; + unsigned int source_ad; + unsigned int dest_ad; + unsigned int txfr_len; + unsigned int stride; + unsigned int nextconbk; + unsigned int null1; + unsigned int null2; +} __attribute__((aligned(32))); + +struct dma_cb playback_cb; + +static void playaudio_dma(void) +{ + extern unsigned char _binary_audio_bin_start[]; + extern unsigned char _binary_audio_bin_size[]; + + unsigned int size = (long)&_binary_audio_bin_size; + unsigned char *data = &(_binary_audio_bin_start[0]); + + // Convert data + + for (int i=0;i finished"); } void core1_main(void) { - clear_core1(); // Only run once + clear_core1(); // Only run once debugstr("Playing on CPU Core #1... "); playaudio_cpu(); debugstr(" done"); debugcrlf(); - start_core2(core2_main); // Kick it off on core 2 + start_core2(core2_main); // Kick it off on core 2 } void core0_main(void) { while (1) { wait_msec(0x100000); - debugstr("x"); + debugstr("x"); // Print an x roughly every 1 second } } @@ -128,6 +201,6 @@ void main(void) audio_init(); debugstr("done"); debugcrlf(); - start_core1(core1_main); // Kick it off on core 1 - core0_main(); // Loop endlessly, printing x's + start_core1(core1_main); // Kick it off on core 1 + core0_main(); // Loop endlessly, printing x's }