Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
main.cpp@0:d8223b8b898e, 2017-03-24 (annotated)
- 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?
| User | Revision | Line number | New 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 | } |