Michael Kaiser / Mbed 2 deprecated DMA_LPC2368

Dependencies:   mbed

Revision:
0:d8223b8b898e
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/main.cpp	Fri Mar 24 08:15:28 2017 +0000
@@ -0,0 +1,82 @@
+#include "mbed.h"
+#include "LPC2368_DMA.h"
+
+/* This is a really simple example of using the GPDMA unit on the LPC2368
+ * The GPDMA unit cannot transfer between arbitrary blocks of memory.
+ * It can only transfer between USB memory and to/from a perhipheral which is a
+ * bit restrictive and I see why support has been dropped for this particular CPU.
+ * 
+ * To Compile, make sure your MBED library is set to revision 121 as this
+ * was the last revision to support the LPC2368
+ *
+ * If all is well, you should see the top 3 LEDs lit indicating the DMA
+ * succeeded and LED1 should be blinking.
+ * You'll notice LED4 takes a little while to light up. This is simply
+ * because the CPU takes 0.2 seconds to come around the while loop and check
+ * the buffer again.
+ */
+
+DigitalOut gLED1(LED1);
+DigitalOut gLED2(LED2);
+DigitalOut gLED3(LED3);
+DigitalOut gLED4(LED4);
+
+int main()
+{
+    char * src = (char *)0x7FD00100; // USB RAM (Arbitrary memory to memory DMA is not supported on LPC2368)
+    char * dst = (char *)0x7FD00000; // USB RAM (See "30.4.1 Memory regions accessible by the GPDMA" in UM10211.PDF LPC23XX User manual)
+
+
+    // Copy our message to the source buffer by CPU as the GPDMA unit on the LPC2368 cannot DMA between arbitrary locations in memory
+    // and I don't know a portable way to force the compiler to store this message at the specific address.
+    const char message[] = "Hello World. This is a test of the DMA transfer capabilities of the LPC2368.";
+    memcpy( src, message, sizeof(message) );
+    memset( dst, 0, sizeof(message) );
+    
+
+    // Enable Power, Interrupts and DMA. Note, We don't use the interrupt in this example
+    LPC_SC->PCONP               |= POWER_CONTROL_GPDMA;
+    NVIC_EnableIRQ( DMA_IRQn );
+    LPC_GPDMA->DMACConfig       = 1;        // enable global DMA before we configure a channel
+
+    // Clear the Error registers in case of any previous interrupts or errors
+    LPC_GPDMA->DMACIntTCClear   = DMA_INTERRUPT_TERMINAL_COUNT_CLEAR_CH0;
+    LPC_GPDMA->DMACIntErrClr    = DMA_INTERRUPT_ERROR_CLEAR_CH0;
+    
+    // Set the DMA parameters for MemToMem
+    LPC_GPDMACH0->DMACCSrcAddr  = (uint32_t)src;
+    LPC_GPDMACH0->DMACCDestAddr = (uint32_t)dst;
+    LPC_GPDMACH0->DMACCLLI      = 0;    // no scatter/gather LLI data is being used here so set to NULL
+    LPC_GPDMACH0->DMACCControl  = DMA_CHANNEL_CONTROL_TRANSFER_LENGTH( sizeof(message) )
+                                | DMA_CHANNEL_CONTROL_SRC_BURST_SIZE( DMA_CHANNEL_CONTROL_SIZE_1 )
+                                | DMA_CHANNEL_CONTROL_DST_BURST_SIZE( DMA_CHANNEL_CONTROL_SIZE_1 )
+                                | DMA_CHANNEL_CONTROL_SRC_WIDTH( DMA_CHANNEL_CONTROL_WIDTH_BYTE )
+                                | DMA_CHANNEL_CONTROL_DST_WIDTH( DMA_CHANNEL_CONTROL_WIDTH_BYTE )
+                                | DMA_CHANNEL_CONTROL_SRC_INC
+                                | DMA_CHANNEL_CONTROL_DST_INC
+                                ;
+    LPC_GPDMACH0->DMACCConfig   = DMA_CHANNEL_CONFIG_ENABLE
+                                | DMA_CHANNEL_CONFIG_SET_PERIPHERAL_SRC(DMA_CHANNEL_CONFIG_PERIPHERAL_NONE)
+                                | DMA_CHANNEL_CONFIG_SET_PERIPHERAL_DST(DMA_CHANNEL_CONFIG_PERIPHERAL_NONE)
+                                | DMA_CHANNEL_CONFIG_FLOW_CONTROL_MEM_TO_MEM
+                                ;
+    
+    
+    while(1)
+    {
+        // Set LED2 if the first byte of the message was transfered.
+        gLED2 = ( src[0] == dst[0])?1:0;
+        
+        // Set LED3 if the 4th byte of the message was transfered.
+        gLED3 = ( src[4] == dst[4])?1:0;
+        
+        // Set LED4 if the whole message was transfered.
+        gLED4 = ( memcmp( src, dst, sizeof(message) ) == 0 )?1:0;
+ 
+        // Just flash LED1 to show the CPU is still working and nothing has crashed it.
+        gLED1 = 1;
+        wait(0.1);
+        gLED1 = 0;
+        wait(0.1);
+    }
+}