From 660e70c5072dea03fe8bf19d960934a2d71f58d4 Mon Sep 17 00:00:00 2001 From: Adam Greenwood-Byrne Date: Thu, 18 Feb 2021 23:00:54 +0000 Subject: [PATCH] Minor doc changes --- part9-sound/README.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/part9-sound/README.md b/part9-sound/README.md index 5dc4560..e39497a 100644 --- a/part9-sound/README.md +++ b/part9-sound/README.md @@ -64,11 +64,11 @@ And that's it... The PWM will pick up the digital data in the buffer and send it Doing it with DMA ----------------- -Our first challenge is that DMA transfers and FIFO registers are 4 bytes wide, so our single byte samples need some zero-padding. Because `data` is an `unsigned char *` and `safe` is (technically) an `unsigned int *`, we can do this in C with a simple for loop. You'll notice that `safe` is a memory location in RAM which we know to be beyond our program code (`SAFE_ADDRESS` is defined in _io.h_). +In `playaudio_dma()` our first challenge is that DMA transfers and FIFO registers are 4 bytes wide, so our single byte samples need some zero-padding. Because `data` is an `unsigned char *` and `safe` is (technically) an `unsigned int *`, we can do this copy with a simple _for loop_. You'll notice that `safe` is a memory location in RAM which we know to be beyond our program code (`SAFE_ADDRESS` is defined in _io.h_). -We then set up the DMA Control Block. This is an in-memory structure that will tell the DMA engine everything it needs to know to perform the transfer. This is very well-documented already, but worth pointing out is `DMA_DEST_DREQ` and `DMA_PERMAP_1`. These settings ensure we use our previously-set hardware clock to 'pace' the transfer. If we didn't do this, the DMA engine would just get it done as fast as it could (and our audio wouldn't sound great!). `SRC_INC` simply tells the DMA engine to increment the source address throughout the transfer. We'll be keeping the destination address constant since we want it to always point to the PWM module's FIFO input. Note also the use of `PWM_LEGACY_BASE` rather than `PWM_BASE` to address this peripheral memory. This is another quirk of the Raspberry Pi 4 hardware! +We then set up the DMA Control Block. This is an in-memory structure that will tell the DMA engine everything it needs to know to perform the transfer. This is very well-documented already, but worth pointing out is `DMA_DEST_DREQ` and `DMA_PERMAP_1`. These settings ensure that we use our previously-set hardware clock to 'pace' the transfer. If we didn't do this, the DMA engine would just get it done as fast as it could (and our audio wouldn't sound great!). `SRC_INC` simply tells the DMA engine to increment the source address throughout the transfer. We'll be keeping the destination address constant though, since we want it to always point to the PWM module's FIFO input. Note also the use of `PWM_LEGACY_BASE` rather than `PWM_BASE` to address this peripheral memory. This is another quirk of the Raspberry Pi 4 hardware! -Note finally how we set `.nextconbk` to 0x00. This tells the DMA engine that there is no more work to do after this job is complete. If we wanted to loop the audio sample infinitely, we could simply set this to address the same control block structure again! +Note finally how we set `.nextconbk` to 0x00. This tells the DMA engine that there is no more work to do after this job is complete. If we wanted to loop the audio sample infinitely (nobody needs that much of me singing!), we could simply set this to address the same control block structure again. As we enable the DMA engine, playback begins. Notably, however, we're returned to `main()` immediately and the CPU can get on with other things, thereby meeting our design goal.