Michael Kaiser / Mbed 2 deprecated DMA_LPC2368

Dependencies:   mbed

Committer:
TheTerrierFromHell
Date:
Fri Mar 24 08:15:28 2017 +0000
Revision:
0:d8223b8b898e
First version of the LPC2368 DMA example showing memory to memory transfer.

Who changed what in which revision?

UserRevisionLine numberNew contents of line
TheTerrierFromHell 0:d8223b8b898e 1 #include "mbed.h"
TheTerrierFromHell 0:d8223b8b898e 2 #include "LPC2368_DMA.h"
TheTerrierFromHell 0:d8223b8b898e 3
TheTerrierFromHell 0:d8223b8b898e 4 /* This is a really simple example of using the GPDMA unit on the LPC2368
TheTerrierFromHell 0:d8223b8b898e 5 * The GPDMA unit cannot transfer between arbitrary blocks of memory.
TheTerrierFromHell 0:d8223b8b898e 6 * It can only transfer between USB memory and to/from a perhipheral which is a
TheTerrierFromHell 0:d8223b8b898e 7 * bit restrictive and I see why support has been dropped for this particular CPU.
TheTerrierFromHell 0:d8223b8b898e 8 *
TheTerrierFromHell 0:d8223b8b898e 9 * To Compile, make sure your MBED library is set to revision 121 as this
TheTerrierFromHell 0:d8223b8b898e 10 * was the last revision to support the LPC2368
TheTerrierFromHell 0:d8223b8b898e 11 *
TheTerrierFromHell 0:d8223b8b898e 12 * If all is well, you should see the top 3 LEDs lit indicating the DMA
TheTerrierFromHell 0:d8223b8b898e 13 * succeeded and LED1 should be blinking.
TheTerrierFromHell 0:d8223b8b898e 14 * You'll notice LED4 takes a little while to light up. This is simply
TheTerrierFromHell 0:d8223b8b898e 15 * because the CPU takes 0.2 seconds to come around the while loop and check
TheTerrierFromHell 0:d8223b8b898e 16 * the buffer again.
TheTerrierFromHell 0:d8223b8b898e 17 */
TheTerrierFromHell 0:d8223b8b898e 18
TheTerrierFromHell 0:d8223b8b898e 19 DigitalOut gLED1(LED1);
TheTerrierFromHell 0:d8223b8b898e 20 DigitalOut gLED2(LED2);
TheTerrierFromHell 0:d8223b8b898e 21 DigitalOut gLED3(LED3);
TheTerrierFromHell 0:d8223b8b898e 22 DigitalOut gLED4(LED4);
TheTerrierFromHell 0:d8223b8b898e 23
TheTerrierFromHell 0:d8223b8b898e 24 int main()
TheTerrierFromHell 0:d8223b8b898e 25 {
TheTerrierFromHell 0:d8223b8b898e 26 char * src = (char *)0x7FD00100; // USB RAM (Arbitrary memory to memory DMA is not supported on LPC2368)
TheTerrierFromHell 0:d8223b8b898e 27 char * dst = (char *)0x7FD00000; // USB RAM (See "30.4.1 Memory regions accessible by the GPDMA" in UM10211.PDF LPC23XX User manual)
TheTerrierFromHell 0:d8223b8b898e 28
TheTerrierFromHell 0:d8223b8b898e 29
TheTerrierFromHell 0:d8223b8b898e 30 // Copy our message to the source buffer by CPU as the GPDMA unit on the LPC2368 cannot DMA between arbitrary locations in memory
TheTerrierFromHell 0:d8223b8b898e 31 // and I don't know a portable way to force the compiler to store this message at the specific address.
TheTerrierFromHell 0:d8223b8b898e 32 const char message[] = "Hello World. This is a test of the DMA transfer capabilities of the LPC2368.";
TheTerrierFromHell 0:d8223b8b898e 33 memcpy( src, message, sizeof(message) );
TheTerrierFromHell 0:d8223b8b898e 34 memset( dst, 0, sizeof(message) );
TheTerrierFromHell 0:d8223b8b898e 35
TheTerrierFromHell 0:d8223b8b898e 36
TheTerrierFromHell 0:d8223b8b898e 37 // Enable Power, Interrupts and DMA. Note, We don't use the interrupt in this example
TheTerrierFromHell 0:d8223b8b898e 38 LPC_SC->PCONP |= POWER_CONTROL_GPDMA;
TheTerrierFromHell 0:d8223b8b898e 39 NVIC_EnableIRQ( DMA_IRQn );
TheTerrierFromHell 0:d8223b8b898e 40 LPC_GPDMA->DMACConfig = 1; // enable global DMA before we configure a channel
TheTerrierFromHell 0:d8223b8b898e 41
TheTerrierFromHell 0:d8223b8b898e 42 // Clear the Error registers in case of any previous interrupts or errors
TheTerrierFromHell 0:d8223b8b898e 43 LPC_GPDMA->DMACIntTCClear = DMA_INTERRUPT_TERMINAL_COUNT_CLEAR_CH0;
TheTerrierFromHell 0:d8223b8b898e 44 LPC_GPDMA->DMACIntErrClr = DMA_INTERRUPT_ERROR_CLEAR_CH0;
TheTerrierFromHell 0:d8223b8b898e 45
TheTerrierFromHell 0:d8223b8b898e 46 // Set the DMA parameters for MemToMem
TheTerrierFromHell 0:d8223b8b898e 47 LPC_GPDMACH0->DMACCSrcAddr = (uint32_t)src;
TheTerrierFromHell 0:d8223b8b898e 48 LPC_GPDMACH0->DMACCDestAddr = (uint32_t)dst;
TheTerrierFromHell 0:d8223b8b898e 49 LPC_GPDMACH0->DMACCLLI = 0; // no scatter/gather LLI data is being used here so set to NULL
TheTerrierFromHell 0:d8223b8b898e 50 LPC_GPDMACH0->DMACCControl = DMA_CHANNEL_CONTROL_TRANSFER_LENGTH( sizeof(message) )
TheTerrierFromHell 0:d8223b8b898e 51 | DMA_CHANNEL_CONTROL_SRC_BURST_SIZE( DMA_CHANNEL_CONTROL_SIZE_1 )
TheTerrierFromHell 0:d8223b8b898e 52 | DMA_CHANNEL_CONTROL_DST_BURST_SIZE( DMA_CHANNEL_CONTROL_SIZE_1 )
TheTerrierFromHell 0:d8223b8b898e 53 | DMA_CHANNEL_CONTROL_SRC_WIDTH( DMA_CHANNEL_CONTROL_WIDTH_BYTE )
TheTerrierFromHell 0:d8223b8b898e 54 | DMA_CHANNEL_CONTROL_DST_WIDTH( DMA_CHANNEL_CONTROL_WIDTH_BYTE )
TheTerrierFromHell 0:d8223b8b898e 55 | DMA_CHANNEL_CONTROL_SRC_INC
TheTerrierFromHell 0:d8223b8b898e 56 | DMA_CHANNEL_CONTROL_DST_INC
TheTerrierFromHell 0:d8223b8b898e 57 ;
TheTerrierFromHell 0:d8223b8b898e 58 LPC_GPDMACH0->DMACCConfig = DMA_CHANNEL_CONFIG_ENABLE
TheTerrierFromHell 0:d8223b8b898e 59 | DMA_CHANNEL_CONFIG_SET_PERIPHERAL_SRC(DMA_CHANNEL_CONFIG_PERIPHERAL_NONE)
TheTerrierFromHell 0:d8223b8b898e 60 | DMA_CHANNEL_CONFIG_SET_PERIPHERAL_DST(DMA_CHANNEL_CONFIG_PERIPHERAL_NONE)
TheTerrierFromHell 0:d8223b8b898e 61 | DMA_CHANNEL_CONFIG_FLOW_CONTROL_MEM_TO_MEM
TheTerrierFromHell 0:d8223b8b898e 62 ;
TheTerrierFromHell 0:d8223b8b898e 63
TheTerrierFromHell 0:d8223b8b898e 64
TheTerrierFromHell 0:d8223b8b898e 65 while(1)
TheTerrierFromHell 0:d8223b8b898e 66 {
TheTerrierFromHell 0:d8223b8b898e 67 // Set LED2 if the first byte of the message was transfered.
TheTerrierFromHell 0:d8223b8b898e 68 gLED2 = ( src[0] == dst[0])?1:0;
TheTerrierFromHell 0:d8223b8b898e 69
TheTerrierFromHell 0:d8223b8b898e 70 // Set LED3 if the 4th byte of the message was transfered.
TheTerrierFromHell 0:d8223b8b898e 71 gLED3 = ( src[4] == dst[4])?1:0;
TheTerrierFromHell 0:d8223b8b898e 72
TheTerrierFromHell 0:d8223b8b898e 73 // Set LED4 if the whole message was transfered.
TheTerrierFromHell 0:d8223b8b898e 74 gLED4 = ( memcmp( src, dst, sizeof(message) ) == 0 )?1:0;
TheTerrierFromHell 0:d8223b8b898e 75
TheTerrierFromHell 0:d8223b8b898e 76 // Just flash LED1 to show the CPU is still working and nothing has crashed it.
TheTerrierFromHell 0:d8223b8b898e 77 gLED1 = 1;
TheTerrierFromHell 0:d8223b8b898e 78 wait(0.1);
TheTerrierFromHell 0:d8223b8b898e 79 gLED1 = 0;
TheTerrierFromHell 0:d8223b8b898e 80 wait(0.1);
TheTerrierFromHell 0:d8223b8b898e 81 }
TheTerrierFromHell 0:d8223b8b898e 82 }