# HG changeset patch # User Paul Boddie # Date 1539889518 -7200 # Node ID 06ce1f92f3e02402687ac37b99330ab4c2a64b86 # Parent 907787d1358cbdc6022b17ee90f6d1dad4a38f01 Demonstrated DMA channel chaining with cell transfers initiated using timer interrupt conditions and with a UART receive interrupt being used and handled to enable the first channel. diff -r 907787d1358c -r 06ce1f92f3e0 main.c --- a/main.c Thu Oct 18 21:04:00 2018 +0200 +++ b/main.c Thu Oct 18 21:05:18 2018 +0200 @@ -2,7 +2,8 @@ #include "init.h" #include "debug.h" -static const char message[] = "Hello!\r\n"; +static const char message1[] = "Hello!\r\n"; +static const char message2[] = "Again!\r\n"; static int uart_echo = 0; static void blink(uint32_t delay, uint32_t port, uint32_t pins) @@ -37,22 +38,40 @@ init_dma(); - /* Initiate DMA on UART receive interrupt, raising transfer completion - interrupt. Since the channel is not auto-enabled, it must be explicitly - enabled upon completion. */ + /* Initiate DMA on the Timer2 interrupt. Since the channel is not + auto-enabled, it must be explicitly enabled upon completion. */ dma_init(0, 3); - dma_set_interrupt(0, U1RX, 1); - dma_set_transfer(0, PHYSICAL((uint32_t) message), sizeof(message) - 1, + dma_set_interrupt(0, T2, 1); + dma_set_transfer(0, PHYSICAL((uint32_t) message1), sizeof(message1) - 1, + HW_PHYSICAL(UART_REG(1, UxTXREG)), 1, + 1); + + /* Enable DMA on the preceding channel's completion, with Timer3 initiating + transfers, raising a transfer completion interrupt. */ + + dma_init(1, 3); + dma_set_chaining(1, dma_chain_previous); + dma_set_interrupt(1, T3, 1); + dma_set_transfer(1, PHYSICAL((uint32_t) message2), sizeof(message2) - 1, HW_PHYSICAL(UART_REG(1, UxTXREG)), 1, 1); - dma_init_interrupt(0, 0b00001000, 7, 3); - dma_on(0); + dma_init_interrupt(1, 0b00001000, 7, 3); + + /* Configure timers. */ - /* Set UART interrupt priority below CPU priority. */ + timer_init(2, 0b111, 60000); + timer_init_interrupt(2, 1, 3); + timer_on(2); + + timer_init(3, 0b111, 40000); + timer_init_interrupt(3, 1, 3); + timer_on(3); + + /* Set UART interrupt priority above CPU priority to process events. */ uart_init(1, 115200); - uart_init_interrupt(1, UxRIF, 1, 3); + uart_init_interrupt(1, UxRIF, 7, 3); uart_on(1); interrupts_on(); @@ -86,12 +105,17 @@ val = REG(UART_REG(1, UxRXREG)); if (uart_echo) uart_write((char) val); + + /* Initiate transfer upon receiving a particular character. */ + + if (val == '0') + dma_on(0); } } /* Check for a DMA interrupt condition (CHBCIF). */ - ifs = REG(DMAIFS) & DMA_INT_FLAGS(0, 1); + ifs = REG(DMAIFS) & DMA_INT_FLAGS(1, 1); if (ifs) {