diff --git a/arch/arm/src/stm32/stm32_dma.c b/arch/arm/src/stm32/stm32_dma.c
index 3cf6ae0a1b1e15a1a989b4bcfa0a8dadc2755064..9824be7e83bb990035d488f044febded4899a3ac 100755
--- a/arch/arm/src/stm32/stm32_dma.c
+++ b/arch/arm/src/stm32/stm32_dma.c
@@ -39,10 +39,15 @@
 
 #include <nuttx/config.h>
 #include <sys/types.h>
+
+#include <semaphore.h>
 #include <debug.h>
+#include <errno.h>
+
 #include <arch/irq.h>
 
 #include "up_arch.h"
+#include "os_internal.h"
 #include "chip.h"
 #include "stm32_dma.h"
 #include "stm32_internal.h"
@@ -50,23 +55,262 @@
 /****************************************************************************
  * Pre-processor Definitions
  ****************************************************************************/
+
+#define DMA1_NCHANNELS   7
+#if STM32_NDMA > 1
+#  define DMA2_NCHANNELS 5
+#  define DMA_NCHANNELS  (DMA1_NCHANNELS+DMA2_NCHANNELS)
+#else
+#  define DMA_NCHANNELS  DMA1_NCHANNELS
+#endif
+
+/* Convert the DMA channel base address to the DMA register block address */
  
+#define DMA_BASE(ch)     (ch & 0xfffffc00)
+
 /****************************************************************************
  * Private Types
  ****************************************************************************/
 
+/* Pinch a byte if is possible if there are not very many DMA channels */
+
+#if DMA_NCHANNELS > 8
+typedef uint16 dma_bitset_t;
+#else
+typedef uint8 dma_bitset_t;
+#endif
+
+/* This structure descibes one DMA channel */
+
+struct stm32_dma_s
+{
+  ubyte          chan;     /* DMA channel number */
+  ubyte          irq;      /* DMA channel IRQ number */
+  uint32         base;     /* DMA register channel base address */
+  dma_callback_t callback; /* Callback invoked when the DMA completes */
+};
+
 /****************************************************************************
  * Private Data
  ****************************************************************************/
 
+/* This bitset indicates which DMA channels have been allocated */
+
+static dma_bitset_t g_dmaallocated;
+static sem_t        g_allocsem;
+
+/* This array describes the state of each DMA */
+
+static struct stm32_dma_s g_dma[DMA_NCHANNELS] =
+{
+  {
+	.chan     = 0,
+	.irq      = STM32_IRQ_DMA1CH1,
+    .base     = STM32_DMA1_BASE + STM32_DMACHAN_OFFSET(0),
+  },
+  {
+	.chan     = 1,
+	.irq      = STM32_IRQ_DMA1CH2,
+    .base     = STM32_DMA1_BASE + STM32_DMACHAN_OFFSET(1),
+  },
+  {
+	.chan     = 2,
+	.irq      = STM32_IRQ_DMA1CH3,
+    .base     = STM32_DMA1_BASE + STM32_DMACHAN_OFFSET(2),
+  },
+  {
+	.chan     = 3,
+	.irq      = STM32_IRQ_DMA1CH4,
+    .base     = STM32_DMA1_BASE + STM32_DMACHAN_OFFSET(3),
+  },
+  {
+	.chan     = 4,
+	.irq      = STM32_IRQ_DMA1CH5,
+    .base     = STM32_DMA1_BASE + STM32_DMACHAN_OFFSET(4),
+  },
+  {
+	.chan     = 5,
+	.irq      = STM32_IRQ_DMA1CH6,
+    .base     = STM32_DMA1_BASE + STM32_DMACHAN_OFFSET(5),
+  },
+  {
+	.chan     = 6,
+	.irq      = STM32_IRQ_DMA1CH7,
+    .base     = STM32_DMA1_BASE + STM32_DMACHAN_OFFSET(6),
+  },
+#if STM32_NDMA > 1
+  {
+	.chan     = 7,
+	.irq      = STM32_IRQ_DMA2CH1,
+    .base     = STM32_DMA2_BASE + STM32_DMACHAN_OFFSET(0),
+  },
+  {
+	.chan     = 8,
+	.irq      = STM32_IRQ_DMA2CH2,
+    .base     = STM32_DMA2_BASE + STM32_DMACHAN_OFFSET(1),
+  },
+  {
+	.chan     = 9,
+	.irq      = STM32_IRQ_DMA2CH3,
+    .base     = STM32_DMA2_BASE + STM32_DMACHAN_OFFSET(2),
+  },
+  {
+	.chan     = 10,
+	.irq      = STM32_IRQ_DMA2CH4,
+    .base     = STM32_DMA2_BASE + STM32_DMACHAN_OFFSET(3),
+  },
+  {
+	.chan     = 11,
+	.irq      = STM32_IRQ_DMA2CH5,
+    .base     = STM32_DMA2_BASE + STM32_DMACHAN_OFFSET(4),
+  },
+#endif
+};
+
 /****************************************************************************
  * Private Functions
  ****************************************************************************/
 
 /****************************************************************************
- * Global Functions
+ * DMA register access functions
  ****************************************************************************/
 
+/* Get non-channel register from DMA1 or DMA2 */
+
+static inline uint32 dmabase_getreg(struct stm32_dma_s *dmach, uint32 offset)
+{
+  return getreg32(DMA_BASE(dmach->base) + offset);
+}
+
+/* Write to non-channel register in DMA1 or DMA2 */
+
+static inline void dmabase_putreg(struct stm32_dma_s *dmach, uint32 offset, uint32 value)
+{
+  putreg32(value, DMA_BASE(dmach->base) + offset);
+}
+
+/* Get channel register from DMA1 or DMA2 */
+
+static inline uint32 dmachan_getreg(struct stm32_dma_s *dmach, uint32 offset)
+{
+  return getreg32(dmach->base + offset);
+}
+
+/* Write to channel register in DMA1 or DMA2 */
+
+static inline void dmachan_putreg(struct stm32_dma_s *dmach, uint32 offset, uint32 value)
+{
+  putreg32(value, dmach->base + offset);
+}
+
+/************************************************************************************
+ * Name: stm32_dmatake() and stm32_dmagive()
+ *
+ * Description:
+ *  Take/give semaphore that protects the channel allocation bitset
+ *
+ ************************************************************************************/
+
+static void stm32_dmatake(void)
+{
+  /* Take the semaphore (perhaps waiting) */
+
+  while (sem_wait(&g_allocsem) != 0)
+    {
+      /* The only case that an error should occur here is if the wait was awakened
+       * by a signal.
+       */
+
+      ASSERT(errno == EINTR);
+    }
+}
+
+static inline void stm32_dmagive(void)
+{
+  (void)sem_post(&g_allocsem);
+}
+
+/************************************************************************************
+ * Name: stm32_dmainterrupt
+ *
+ * Description:
+ *  DMA interrupt handler
+ *
+ ************************************************************************************/
+
+static int stm32_dmainterrupt(int irq, void *context)
+{
+  struct stm32_dma_s *dmach;
+  uint32 isr;
+  int chan;
+
+  /* Get the channel structure from the interrupt number */
+
+  if (irq >= STM32_IRQ_DMA1CH1 && irq <= STM32_IRQ_DMA1CH7)
+    {
+      chan = irq - STM32_IRQ_DMA1CH1;
+    }
+  else
+#if STM32_NDMA > 1
+  if (irq >= STM32_IRQ_DMA2CH1 && irq <= STM32_IRQ_DMA2CH5)
+    {
+      chan = irq - STM32_IRQ_DMA2CH1 + DMA1_NCHANNELS;
+    }
+  else
+#endif
+    {
+      PANIC(OSERR_INTERNAL);
+    }
+  dmach = &g_dma[chan];
+
+  /* Get the interrupt status (for this channel only) */
+
+  isr = dmabase_getreg(dmach, STM32_DMA_ISR_OFFSET) & ~DMA_ISR_CHAN_MASK(chan);
+
+  /* Clear pending interrupts (for this channel only) */
+
+  dmabase_putreg(dmach, STM32_DMA_IFCR_OFFSET, isr);
+
+  /* Invoke the callback */
+
+  if (dmach->callback)
+    {
+      dmach->callback(dmach, isr >> DMA_ISR_CHAN_SHIFT(chan));
+    }
+  return OK;
+}
+
+/****************************************************************************
+ * Public Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: stm32_dmainitialize
+ *
+ * Description:
+ *   Initialize the DMA subsystem
+ *
+ * Returned Value:
+ *   None
+ *
+ ****************************************************************************/
+
+void weak_function stm32_dmainitialize(void)
+{
+  int chan;
+
+  /* Initialize the semaphore used to protect the allocation bitset */
+
+  sem_init(&g_allocsem, 0, 1);
+
+  /* Attach DMA interrupt vectors */
+
+  for (chan = 0; chan < DMA_NCHANNELS; chan++)
+    {
+      irq_attach(g_dma[chan].irq, stm32_dmainterrupt);
+    }
+}
+
 /****************************************************************************
  * Name: stm32_dmachannel
  *
@@ -80,5 +324,116 @@
 
 DMA_HANDLE stm32_dmachannel(void)
 {
-  return NULL;
+  struct stm32_dma_s *dmach = NULL;
+  int chan;
+  int bit;
+
+  /* Make sure that we exclusive access to the DMA bitset */
+
+  stm32_dmatake();
+
+  /* Try each possible channel */
+
+  for (chan = 0, bit = 1; chan < DMA_NCHANNELS; chan++, bit <<= 1)
+    {
+      /* Has this channel been allocated? */
+
+      if ((g_dmaallocated & bit) == 0)
+        {
+          /* No.. grab it and return */
+
+          g_dmaallocated |= bit;
+          dmach = &g_dma[chan];
+          break;
+        }
+    }
+     
+  stm32_dmagive();
+  return (DMA_HANDLE)dmach;
+}
+
+/****************************************************************************
+ * Name: stm32_dmasetup
+ *
+ * Description:
+ *   Configure DMA before using
+ *
+ ****************************************************************************/
+
+void stm32_dmasetup(DMA_HANDLE handle, uint32 paddr, uint32 maddr, size_t ntransfers, uint32 ccr)
+{
+  struct stm32_dma_s *dmach = (struct stm32_dma_s *)handle;
+  uint32 regval;
+
+  /* Set the peripheral register address in the DMA_CPARx register. The data
+   * will be moved from/to this address to/from the memory after the
+   * peripheral event.
+   */
+
+  dmachan_putreg(dmach, STM32_DMACHAN_CPAR_OFFSET, paddr);
+
+  /* Set the memory address in the DMA_CMARx register. The data will be
+   * written to or read from this memory after the peripheral event.
+   */
+
+  dmachan_putreg(dmach, STM32_DMACHAN_CMAR_OFFSET, maddr);
+
+  /* Configure the total number of data to be transferred in the DMA_CNDTRx
+   * register.  After each peripheral event, this value will be decremented.
+   */
+
+  dmachan_putreg(dmach, STM32_DMACHAN_CNDTR_OFFSET, ntransfers);
+
+  /* Configure the channel priority using the PL[1:0] bits in the DMA_CCRx
+   * register.  Configure data transfer direction, circular mode, peripheral & memory
+   * incremented mode, peripheral & memory data size, and interrupt after
+   * half and/or full transfer in the DMA_CCRx register.
+   */
+
+  regval  = dmachan_gettreg(dmach, STM32_DMACHAN_CCR_OFFSET);
+  regval &= ~(DMA_CCR_MEM2MEM|DMA_CCR_PL_MASK|DMA_CCR_MSIZE_MASK|DMA_CCR_PSIZE_MASK|
+              DMA_CCR_MINC|DMA_CCR_PINC|DMA_CCR_CIRC|DMA_CCR_DIR);
+  ccr    &=  (DMA_CCR_MEM2MEM|DMA_CCR_PL_MASK|DMA_CCR_MSIZE_MASK|DMA_CCR_PSIZE_MASK|
+              DMA_CCR_MINC|DMA_CCR_PINC|DMA_CCR_CIRC|DMA_CCR_DIR);
+  regval |= ccr;
+  dmachan_putreg(dmach, STM32_DMACHAN_CCR_OFFSET, regval);
+}
+
+/****************************************************************************
+ * Name: stm32_dmastart
+ *
+ * Description:
+ *   Start the DMA transfer
+ *
+ ****************************************************************************/
+
+void stm32_dmastart(DMA_HANDLE handle, dma_callback_t callback, boolean half)
+{
+  struct stm32_dma_s *dmach = (struct stm32_dma_s *)handle;
+  int irq;
+  uint32 ccr;
+
+  DEBUGASSERT(handle != NULL);
+
+  /* Save the callback.  This will be invoked whent the DMA commpletes */
+
+  dmach->callback = callback;
+
+  /* Activate the channel by setting the ENABLE bit in the DMA_CCRx register.
+   * As soon as the channel is enabled, it can serve any DMA request from the
+   * peripheral connected on the channel.
+   */
+
+  ccr  = dmachan_gettreg(dmach, STM32_DMACHAN_CCR_OFFSET);
+  ccr |= DMA_CCR_EN;
+
+  /* Once half of the bytes are transferred, the half-transfer flag (HTIF) is
+   * set and an interrupt is generated if the Half-Transfer Interrupt Enable
+   * bit (HTIE) is set. At the end of the transfer, the Transfer Complete Flag
+   * (TCIF) is set and an interrupt is generated if the Transfer Complete
+   * Interrupt Enable bit (TCIE) is set.
+   */
+
+  ccr |= (half ? (DMA_CCR_HTIE|DMA_CCR_TEIE) : (DMA_CCR_TCIE|DMA_CCR_TEIE));
+  dmachan_putreg(dmach, STM32_DMACHAN_CCR_OFFSET, ccr);
 }
diff --git a/arch/arm/src/stm32/stm32_dma.h b/arch/arm/src/stm32/stm32_dma.h
index f62acccf4784a49ef76ae23c7914b7c817b9f55e..8c44674aa450736646fc799cd4ae973be8727a64 100644
--- a/arch/arm/src/stm32/stm32_dma.h
+++ b/arch/arm/src/stm32/stm32_dma.h
@@ -60,10 +60,20 @@
 
 /* Register Offsets *****************************************************************/
 
-#define STM32_DMA_ISR_OFFSET      0x0000 /* DMA interrupt status register */
-#define STM32_DMA_IFCR_OFFSET     0x0004 /* DMA interrupt flag clear register */
+#define STM32_DMA_ISR_OFFSET        0x0000 /* DMA interrupt status register */
+#define STM32_DMA_IFCR_OFFSET       0x0004 /* DMA interrupt flag clear register */
+
+#define STM32_DMACHAN_OFFSET(n)    (0x0014*(n))
+#define STM32_DMACHAN_CCR_OFFSET   0x0008
+#define STM32_DMACHAN_CNDTR_OFFSET 0x000c
+#define STM32_DMACHAN_CPAR_OFFSET  0x0010
+#define STM32_DMACHAN_CMAR_OFFSET  0x0014
+
+#define STM32_DMA_CCR_OFFSET(n)   (STM32_DMACHAN_CCR_OFFSET+STM32_DMACHAN_OFFSET(n))
+#define STM32_DMA_CNDTR_OFFSET(n) (STM32_DMACHAN_CNDTR_OFFSET+STM32_DMACHAN_OFFSET(n))
+#define STM32_DMA_CPAR_OFFSET(n)  (STM32_DMACHAN_CPAR_OFFSET+STM32_DMACHAN_OFFSET(n))
+#define STM32_DMA_CMAR_OFFSET(n)  (STM32_DMACHAN_CMAR_OFFSET+STM32_DMACHAN_OFFSET(n))
 
-#define STM32_DMA_CCR_OFFSET(n)   (0x0008+0x0014*(n))
 #define STM32_DMA_CCR1_OFFSET     0x0008 /* DMA channel 1 configuration register */
 #define STM32_DMA_CCR2_OFFSET     0x001c /* DMA channel 2 configuration register */
 #define STM32_DMA_CCR3_OFFSET     0x0030 /* DMA channel 3 configuration register */
@@ -72,7 +82,6 @@
 #define STM32_DMA_CCR6_OFFSET     0x006c /* DMA channel 6 configuration register */
 #define STM32_DMA_CCR7_OFFSET     0x0080 /* DMA channel 7 configuration register */
 
-#define STM32_DMA_CNDTR_OFFSET(n) (0x000c+0x0014*(n))
 #define STM32_DMA_CNDTR1_OFFSET   0x000c /* DMA channel 1 number of data register */
 #define STM32_DMA_CNDTR2_OFFSET   0x0020 /* DMA channel 2 number of data register */
 #define STM32_DMA_CNDTR3_OFFSET   0x0034 /* DMA channel 3 number of data register */
@@ -81,7 +90,6 @@
 #define STM32_DMA_CNDTR6_OFFSET   0x0070 /* DMA channel 6 number of data register */
 #define STM32_DMA_CNDTR7_OFFSET   0x0084 /* DMA channel 7 number of data register */
 
-#define STM32_DMA_CPAR_OFFSET(n)  (0x0010+0x0014*(n))
 #define STM32_DMA_CPAR1_OFFSET    0x0010 /* DMA channel 1 peripheral address register */
 #define STM32_DMA_CPAR2_OFFSET    0x0024 /* DMA channel 2 peripheral address register */
 #define STM32_DMA_CPAR3_OFFSET    0x0038 /* DMA channel 3 peripheral address register */
@@ -90,7 +98,6 @@
 #define STM32_DMA_CPAR6_OFFSET    0x0074 /* DMA channel 6 peripheral address register */
 #define STM32_DMA_CPAR7_OFFSET    0x0088 /* DMA channel 7 peripheral address register */
 
-#define STM32_DMA_CMAR_OFFSET(n)  (0x0014+0x0014*(n))
 #define STM32_DMA_CMAR1_OFFSET    0x0014 /* DMA channel 1 memory address register */
 #define STM32_DMA_CMAR2_OFFSET    0x0028 /* DMA channel 2 memory address register */
 #define STM32_DMA_CMAR3_OFFSET    0x003c /* DMA channel 3 memory address register */
@@ -101,102 +108,132 @@
 
 /* Register Addresses ***************************************************************/
 
-#define STM32_DMA_ISRC            (STM32_DMA_BASE+STM32_DMA_ISRC_OFFSET)
-#define STM32_DMA_IFCR            (STM32_DMA_BASE+STM32_DMA_IFCR_OFFSET)
-
-#define STM32_DMA_CCR(n)          (STM32_DMA_BASE+STM32_DMA_CCR_OFFSET(n))
-#define STM32_DMA_CCR1            (STM32_DMA_BASE+STM32_DMA_CCR1_OFFSET)
-#define STM32_DMA_CCR2            (STM32_DMA_BASE+STM32_DMA_CCR2_OFFSET)
-#define STM32_DMA_CCR3            (STM32_DMA_BASE+STM32_DMA_CCR3_OFFSET)
-#define STM32_DMA_CCR4            (STM32_DMA_BASE+STM32_DMA_CCR4_OFFSET)
-#define STM32_DMA_CCR5            (STM32_DMA_BASE+STM32_DMA_CCR5_OFFSET)
-#define STM32_DMA_CCR6            (STM32_DMA_BASE+STM32_DMA_CCR6_OFFSET)
-#define STM32_DMA_CCR7            (STM32_DMA_BASE+STM32_DMA_CCR7_OFFSET)
-
-#define STM32_DMA_CNDTR(n)        (STM32_DMA_BASE+STM32_DMA_CNDTR_OFFSET(n))
-#define STM32_DMA_CNDTR1          (STM32_DMA_BASE+STM32_DMA_CNDTR1_OFFSET)
-#define STM32_DMA_CNDTR2          (STM32_DMA_BASE+STM32_DMA_CNDTR2_OFFSET)
-#define STM32_DMA_CNDTR3          (STM32_DMA_BASE+STM32_DMA_CNDTR3_OFFSET)
-#define STM32_DMA_CNDTR4          (STM32_DMA_BASE+STM32_DMA_CNDTR4_OFFSET)
-#define STM32_DMA_CNDTR5          (STM32_DMA_BASE+STM32_DMA_CNDTR5_OFFSET)
-#define STM32_DMA_CNDTR6          (STM32_DMA_BASE+STM32_DMA_CNDTR6_OFFSET)
-#define STM32_DMA_CNDTR7          (STM32_DMA_BASE+STM32_DMA_CNDTR7_OFFSET)
-
-#define STM32_DMA_CPAR(n)         (STM32_DMA_BASE+STM32_DMA_CPAR_OFFSET(n))
-#define STM32_DMA_CPAR1           (STM32_DMA_BASE+STM32_DMA_CPAR1_OFFSET)
-#define STM32_DMA_CPAR2           (STM32_DMA_BASE+STM32_DMA_CPAR2_OFFSET)
-#define STM32_DMA_CPAR3           (STM32_DMA_BASE+STM32_DMA_CPAR3_OFFSET)
-#define STM32_DMA_CPAR4           (STM32_DMA_BASE+STM32_DMA_CPAR4_OFFSET)
-#define STM32_DMA_CPAR5           (STM32_DMA_BASE+STM32_DMA_CPAR5_OFFSET)
-#define STM32_DMA_CPAR6           (STM32_DMA_BASE+STM32_DMA_CPAR6_OFFSET)
-#define STM32_DMA_CPAR7           (STM32_DMA_BASE+STM32_DMA_CPAR7_OFFSET)
-
-#define STM32_DMA_CMAR(n)         (STM32_DMA_BASE+STM32_DMA_CMAR_OFFSET(n))
-#define STM32_DMA_CMAR1           (STM32_DMA_BASE+STM32_DMA_CMAR1_OFFSET)
-#define STM32_DMA_CMAR2           (STM32_DMA_BASE+STM32_DMA_CMAR2_OFFSET)
-#define STM32_DMA_CMAR3           (STM32_DMA_BASE+STM32_DMA_CMAR3_OFFSET)
-#define STM32_DMA_CMAR4           (STM32_DMA_BASE+STM32_DMA_CMAR4_OFFSET)
-#define STM32_DMA_CMAR5           (STM32_DMA_BASE+STM32_DMA_CMAR5_OFFSET)
-#define STM32_DMA_CMAR6           (STM32_DMA_BASE+STM32_DMA_CMAR6_OFFSET)
-#define STM32_DMA_CMAR7           (STM32_DMA_BASE+STM32_DMA_CMAR7_OFFSET)
+#define STM32_DMA1_ISRC           (STM32_DMA1_BASE+STM32_DMA_ISR_OFFSET)
+#define STM32_DMA1_IFCR           (STM32_DMA1_BASE+STM32_DMA_IFCR_OFFSET)
+
+#define STM32_DMA1_CCR(n)         (STM32_DMA1_BASE+STM32_DMA_CCR_OFFSET(n))
+#define STM32_DMA1_CCR1           (STM32_DMA1_BASE+STM32_DMA_CCR1_OFFSET)
+#define STM32_DMA1_CCR2           (STM32_DMA1_BASE+STM32_DMA_CCR2_OFFSET)
+#define STM32_DMA1_CCR3           (STM32_DMA1_BASE+STM32_DMA_CCR3_OFFSET)
+#define STM32_DMA1_CCR4           (STM32_DMA1_BASE+STM32_DMA_CCR4_OFFSET)
+#define STM32_DMA1_CCR5           (STM32_DMA1_BASE+STM32_DMA_CCR5_OFFSET)
+#define STM32_DMA1_CCR6           (STM32_DMA1_BASE+STM32_DMA_CCR6_OFFSET)
+#define STM32_DMA1_CCR7           (STM32_DMA1_BASE+STM32_DMA_CCR7_OFFSET)
+
+#define STM32_DMA1_CNDTR(n)       (STM32_DMA1_BASE+STM32_DMA_CNDTR_OFFSET(n))
+#define STM32_DMA1_CNDTR1         (STM32_DMA1_BASE+STM32_DMA_CNDTR1_OFFSET)
+#define STM32_DMA1_CNDTR2         (STM32_DMA1_BASE+STM32_DMA_CNDTR2_OFFSET)
+#define STM32_DMA1_CNDTR3         (STM32_DMA1_BASE+STM32_DMA_CNDTR3_OFFSET)
+#define STM32_DMA1_CNDTR4         (STM32_DMA1_BASE+STM32_DMA_CNDTR4_OFFSET)
+#define STM32_DMA1_CNDTR5         (STM32_DMA1_BASE+STM32_DMA_CNDTR5_OFFSET)
+#define STM32_DMA1_CNDTR6         (STM32_DMA1_BASE+STM32_DMA_CNDTR6_OFFSET)
+#define STM32_DMA1_CNDTR7         (STM32_DMA1_BASE+STM32_DMA_CNDTR7_OFFSET)
+
+#define STM32_DMA1_CPAR(n)        (STM32_DMA1_BASE+STM32_DMA_CPAR_OFFSET(n))
+#define STM32_DMA1_CPAR1          (STM32_DMA1_BASE+STM32_DMA_CPAR1_OFFSET)
+#define STM32_DMA1_CPAR2          (STM32_DMA1_BASE+STM32_DMA_CPAR2_OFFSET)
+#define STM32_DMA1_CPAR3          (STM32_DMA1_BASE+STM32_DMA_CPAR3_OFFSET)
+#define STM32_DMA1_CPAR4          (STM32_DMA1_BASE+STM32_DMA_CPAR4_OFFSET)
+#define STM32_DMA1_CPAR5          (STM32_DMA1_BASE+STM32_DMA_CPAR5_OFFSET)
+#define STM32_DMA1_CPAR6          (STM32_DMA1_BASE+STM32_DMA_CPAR6_OFFSET)
+#define STM32_DMA1_CPAR7          (STM32_DMA1_BASE+STM32_DMA_CPAR7_OFFSET)
+
+#define STM32_DMA1_CMAR(n)        (STM32_DMA1_BASE+STM32_DMA_CMAR_OFFSET(n))
+#define STM32_DMA1_CMAR1          (STM32_DMA1_BASE+STM32_DMA_CMAR1_OFFSET)
+#define STM32_DMA1_CMAR2          (STM32_DMA1_BASE+STM32_DMA_CMAR2_OFFSET)
+#define STM32_DMA1_CMAR3          (STM32_DMA1_BASE+STM32_DMA_CMAR3_OFFSET)
+#define STM32_DMA1_CMAR4          (STM32_DMA1_BASE+STM32_DMA_CMAR4_OFFSET)
+#define STM32_DMA1_CMAR5          (STM32_DMA1_BASE+STM32_DMA_CMAR5_OFFSET)
+#define STM32_DMA1_CMAR6          (STM32_DMA1_BASE+STM32_DMA_CMAR6_OFFSET)
+#define STM32_DMA1_CMAR7          (STM32_DMA1_BASE+STM32_DMA_CMAR7_OFFSET)
+
+#define STM32_DMA2_ISRC           (STM32_DMA2_BASE+STM32_DMA_ISR_OFFSET)
+#define STM32_DMA2_IFCR           (STM32_DMA2_BASE+STM32_DMA_IFCR_OFFSET)
+
+#define STM32_DMA2_CCR(n)         (STM32_DMA2_BASE+STM32_DMA_CCR_OFFSET(n))
+#define STM32_DMA2_CCR1           (STM32_DMA2_BASE+STM32_DMA_CCR1_OFFSET)
+#define STM32_DMA2_CCR2           (STM32_DMA2_BASE+STM32_DMA_CCR2_OFFSET)
+#define STM32_DMA2_CCR3           (STM32_DMA2_BASE+STM32_DMA_CCR3_OFFSET)
+#define STM32_DMA2_CCR4           (STM32_DMA2_BASE+STM32_DMA_CCR4_OFFSET)
+#define STM32_DMA2_CCR5           (STM32_DMA2_BASE+STM32_DMA_CCR5_OFFSET)
+
+#define STM32_DMA2_CNDTR(n)       (STM32_DMA2_BASE+STM32_DMA_CNDTR_OFFSET(n))
+#define STM32_DMA2_CNDTR1         (STM32_DMA2_BASE+STM32_DMA_CNDTR1_OFFSET)
+#define STM32_DMA2_CNDTR2         (STM32_DMA2_BASE+STM32_DMA_CNDTR2_OFFSET)
+#define STM32_DMA2_CNDTR3         (STM32_DMA2_BASE+STM32_DMA_CNDTR3_OFFSET)
+#define STM32_DMA2_CNDTR4         (STM32_DMA2_BASE+STM32_DMA_CNDTR4_OFFSET)
+#define STM32_DMA2_CNDTR5         (STM32_DMA2_BASE+STM32_DMA_CNDTR5_OFFSET)
+
+#define STM32_DMA2_CPAR(n)        (STM32_DMA2_BASE+STM32_DMA_CPAR_OFFSET(n))
+#define STM32_DMA2_CPAR1          (STM32_DMA2_BASE+STM32_DMA_CPAR1_OFFSET)
+#define STM32_DMA2_CPAR2          (STM32_DMA2_BASE+STM32_DMA_CPAR2_OFFSET)
+#define STM32_DMA2_CPAR3          (STM32_DMA2_BASE+STM32_DMA_CPAR3_OFFSET)
+#define STM32_DMA2_CPAR4          (STM32_DMA2_BASE+STM32_DMA_CPAR4_OFFSET)
+#define STM32_DMA2_CPAR5          (STM32_DMA2_BASE+STM32_DMA_CPAR5_OFFSET)
+
+#define STM32_DMA2_CMAR(n)        (STM32_DMA2_BASE+STM32_DMA_CMAR_OFFSET(n))
+#define STM32_DMA2_CMAR1          (STM32_DMA2_BASE+STM32_DMA_CMAR1_OFFSET)
+#define STM32_DMA2_CMAR2          (STM32_DMA2_BASE+STM32_DMA_CMAR2_OFFSET)
+#define STM32_DMA2_CMAR3          (STM32_DMA2_BASE+STM32_DMA_CMAR3_OFFSET)
+#define STM32_DMA2_CMAR4          (STM32_DMA2_BASE+STM32_DMA_CMAR4_OFFSET)
+#define STM32_DMA2_CMAR5          (STM32_DMA2_BASE+STM32_DMA_CMAR5_OFFSET)
 
 /* Register Bitfield Definitions ****************************************************/
 
+#define DMA_CHAN_SHIFT(n)         ((n) << 2)
+#define DMA_CHAN_MASK             0x0f
+#define DMA_CHAN_GIF_BIT          (1 << 0)  /* Bit 0: Channel Global interrupt flag */
+#define DMA_CHAN_TCIF_BIT         (1 << 1)  /* Bit 1: Channel Transfer Complete flag */
+#define DMA_CHAN_HTIF_BIT         (1 << 2)  /* Bit 2: Channel Half Transfer flag */
+#define DMA_CHAN_TEIF_BIT         (1 << 3)  /* Bit 3: Channel Transfer Error flag */
+
 /* DMA interrupt status register */
 
-#define DMA_ISRC_CHAN_SHIFT(n)    (4*(n))
-#define DMA_ISRC_CHAN_MASK(n)     (0x0f <<  DMA_ISRC_CHAN_SHIFT(n))
-#define DMA_ISRC_CHAN1_SHIFT      (0)       /* Bits 3-0:  DMA Channel 1 interrupt status */
-#define DMA_ISRC_CHAN1_MASK       (0x0f <<  DMA_ISRC_CHAN1_SHIFT)
-#define DMA_ISRC_CHAN2_SHIFT      (4)       /* Bits 7-4:  DMA Channel 2 interrupt status */
-#define DMA_ISRC_CHAN2_MASK       (0x0f <<  DMA_ISRC_CHAN2_SHIFT)
-#define DMA_ISRC_CHAN3_SHIFT      (8)       /* Bits 11-8:  DMA Channel 3 interrupt status */
-#define DMA_ISRC_CHAN3_MASK       (0x0f <<  DMA_ISRC_CHAN3_SHIFT)
-#define DMA_ISRC_CHAN4_SHIFT      (12)      /* Bits 15-12:  DMA Channel 4 interrupt status */
-#define DMA_ISRC_CHAN4_MASK       (0x0f <<  DMA_ISRC_CHAN4_SHIFT)
-#define DMA_ISRC_CHAN5_SHIFT      (16)      /* Bits 19-16:  DMA Channel 5 interrupt status */
-#define DMA_ISRC_CHAN5_MASK       (0x0f <<  DMA_ISRC_CHAN5_SHIFT)
-#define DMA_ISRC_CHAN6_SHIFT      (20)      /* Bits 23-20:  DMA Channel 6 interrupt status */
-#define DMA_ISRC_CHAN6_MASK       (0x0f <<  DMA_ISRC_CHAN6_SHIFT)
-#define DMA_ISRC_CHAN7_SHIFT      (24)      /* Bits 27-24:  DMA Channel 7 interrupt status */
-#define DMA_ISRC_CHAN7_MASK       (0x0f <<  DMA_ISRC_CHAN7_SHIFT)
-
-#define DMA_ISRC_GIF_BIT          (1 << 0)  /* Bit 0: Channel Global interrupt flag */
-#define DMA_ISRC_GIF(n)           (DMA_ISRC_GIF_BIT << DMA_ISRC_CHAN_SHIFT(n))
-#define DMA_ISRC_TCIF_BIT         (1 << 1)  /* Bit 1: Channel Transfer Complete flag */
-#define DMA_ISRC_TCIF(n)          (DMA_ISRC_TCIF_BIT << DMA_ISRC_CHAN_SHIFT(n))
-#define DMA_ISRC_HTIF_BIT         (1 << 2)  /* Bit 2: Channel Half Transfer flag */
-#define DMA_ISRC_HTIF(n)          (DMA_ISRC_HTIF_BIT  << DMA_ISRC_CHAN_SHIFT(n))
-#define DMA_ISRC_TEIF_BIT         (1 << 3)  /* Bit 3: Channel Transfer Error flag */
-#define DMA_ISRC_TEIF(n)          (DMA_ISRC_TEIF_BIT << DMA_ISRC_CHAN_SHIFT(n))
+#define DMA_ISR_CHAN_SHIFT(n)     DMA_CHAN_SHIFT(n)
+#define DMA_ISR_CHAN_MASK(n)      (DMA_CHAN_MASK <<  DMA_ISR_CHAN_SHIFT(n))
+#define DMA_ISR_CHAN1_SHIFT       (0)       /* Bits 3-0:  DMA Channel 1 interrupt status */
+#define DMA_ISR_CHAN1_MASK        (DMA_CHAN_MASK <<  DMA_ISR_CHAN1_SHIFT)
+#define DMA_ISR_CHAN2_SHIFT       (4)       /* Bits 7-4:  DMA Channel 2 interrupt status */
+#define DMA_ISR_CHAN2_MASK        (DMA_CHAN_MASK <<  DMA_ISR_CHAN2_SHIFT)
+#define DMA_ISR_CHAN3_SHIFT       (8)       /* Bits 11-8:  DMA Channel 3 interrupt status */
+#define DMA_ISR_CHAN3_MASK        (DMA_CHAN_MASK <<  DMA_ISR_CHAN3_SHIFT)
+#define DMA_ISR_CHAN4_SHIFT       (12)      /* Bits 15-12:  DMA Channel 4 interrupt status */
+#define DMA_ISR_CHAN4_MASK        (DMA_CHAN_MASK <<  DMA_ISR_CHAN4_SHIFT)
+#define DMA_ISR_CHAN5_SHIFT       (16)      /* Bits 19-16:  DMA Channel 5 interrupt status */
+#define DMA_ISR_CHAN5_MASK        (DMA_CHAN_MASK <<  DMA_ISR_CHAN5_SHIFT)
+#define DMA_ISR_CHAN6_SHIFT       (20)      /* Bits 23-20:  DMA Channel 6 interrupt status */
+#define DMA_ISR_CHAN6_MASK        (DMA_CHAN_MASK <<  DMA_ISR_CHAN6_SHIFT)
+#define DMA_ISR_CHAN7_SHIFT       (24)      /* Bits 27-24:  DMA Channel 7 interrupt status */
+#define DMA_ISR_CHAN7_MASK        (DMA_CHAN_MASK <<  DMA_ISR_CHAN7_SHIFT)
+
+#define DMA_ISR_GIF(n)            (DMA_CHAN_GIF_BIT << DMA_ISR_CHAN_SHIFT(n))
+#define DMA_ISR_TCIF(n)           (DMA_CHAN_TCIF_BIT << DMA_ISR_CHAN_SHIFT(n))
+#define DMA_ISR_HTIF(n)           (DMA_CHAN_HTIF_BIT << DMA_ISR_CHAN_SHIFT(n))
+#define DMA_ISR_TEIF(n)           (DMA_CHAN_TEIF_BIT << DMA_ISR_CHAN_SHIFT(n))
 
 /* DMA interrupt flag clear register */
 
-#define DMA_IFCR_CHAN_SHIFT(n)    (4*(n))
-#define DMA_IFCR_CHAN_MASK(n)     (0x0f <<  DMA_IFCR_CHAN_SHIFT(n))
+#define DMA_IFCR_CHAN_SHIFT(n)    DMA_CHAN_SHIFT(n)
+#define DMA_IFCR_CHAN_MASK(n)     (DMA_CHAN_MASK <<  DMA_IFCR_CHAN_SHIFT(n))
 #define DMA_IFCR_CHAN1_SHIFT      (0)       /* Bits 3-0:  DMA Channel 1 interrupt flag clear */
-#define DMA_IFCR_CHAN1_MASK       (0x0f <<  DMA_IFCR_CHAN1_SHIFT)
+#define DMA_IFCR_CHAN1_MASK       (DMA_CHAN_MASK <<  DMA_IFCR_CHAN1_SHIFT)
 #define DMA_IFCR_CHAN2_SHIFT      (4)       /* Bits 7-4:  DMA Channel 2 interrupt flag clear */
-#define DMA_IFCR_CHAN2_MASK       (0x0f <<  DMA_IFCR_CHAN2_SHIFT)
+#define DMA_IFCR_CHAN2_MASK       (DMA_CHAN_MASK <<  DMA_IFCR_CHAN2_SHIFT)
 #define DMA_IFCR_CHAN3_SHIFT      (8)       /* Bits 11-8:  DMA Channel 3 interrupt flag clear */
-#define DMA_IFCR_CHAN3_MASK       (0x0f <<  DMA_IFCR_CHAN3_SHIFT)
+#define DMA_IFCR_CHAN3_MASK       (DMA_CHAN_MASK <<  DMA_IFCR_CHAN3_SHIFT)
 #define DMA_IFCR_CHAN4_SHIFT      (12)      /* Bits 15-12:  DMA Channel 4 interrupt flag clear */
-#define DMA_IFCR_CHAN4_MASK       (0x0f <<  DMA_IFCR_CHAN4_SHIFT)
+#define DMA_IFCR_CHAN4_MASK       (DMA_CHAN_MASK <<  DMA_IFCR_CHAN4_SHIFT)
 #define DMA_IFCR_CHAN5_SHIFT      (16)      /* Bits 19-16:  DMA Channel 5 interrupt flag clear */
-#define DMA_IFCR_CHAN5_MASK       (0x0f <<  DMA_IFCR_CHAN5_SHIFT)
+#define DMA_IFCR_CHAN5_MASK       (DMA_CHAN_MASK <<  DMA_IFCR_CHAN5_SHIFT)
 #define DMA_IFCR_CHAN6_SHIFT      (20)      /* Bits 23-20:  DMA Channel 6 interrupt flag clear */
-#define DMA_IFCR_CHAN6_MASK       (0x0f <<  DMA_IFCR_CHAN6_SHIFT)
+#define DMA_IFCR_CHAN6_MASK       (DMA_CHAN_MASK <<  DMA_IFCR_CHAN6_SHIFT)
 #define DMA_IFCR_CHAN7_SHIFT      (24)      /* Bits 27-24:  DMA Channel 7 interrupt flag clear */
-#define DMA_IFCR_CHAN7_MASK       (0x0f <<  DMA_IFCR_CHAN7_SHIFT)
-
-#define DMA_IFCR_CGIF_BIT         (1 << 0)  /* Bit 0: Channel Global interrupt clear */
-#define DMA_IFCR_CGIF(n)          (DMA_IFCR_CGIF_BIT << DMA_IFCR_CHAN_SHIFT(n))
-#define DMA_IFCR_CTCIF_BIT        (1 << 1)  /* Bit 1: Channel Transfer Complete clear */
-#define DMA_IFCR_CTCIF(n)         (DMA_IFCR_CTCIF_BIT << DMA_IFCR_CHAN_SHIFT(n))
-#define DMA_IFCR_CHTIF_BIT        (1 << 2)  /* Bit 2: Channel Half Transfer clear */
-#define DMA_IFCR_CHTIF(n)         (DMA_IFCR_CHTIF_BIT  << DMA_IFCR_CHAN_SHIFT(n))
-#define DMA_IFCR_CTEIF_BIT        (1 << 3)  /* Bit 3: Channel Transfer Error clear */
-#define DMA_IFCR_CTEIF(n)         (DMA_IFCR_CTEIF_BIT << DMA_IFCR_CHAN_SHIFT(n))
+#define DMA_IFCR_CHAN7_MASK       (DMA_CHAN_MASK <<  DMA_IFCR_CHAN7_SHIFT)
+
+#define DMA_IFCR_CGIF(n)          (DMA_CHAN_GIF_BIT << DMA_IFCR_CHAN_SHIFT(n))
+#define DMA_IFCR_CTCIF(n)         (DMA_CHAN_TCIF_BIT << DMA_IFCR_CHAN_SHIFT(n))
+#define DMA_IFCR_CHTIF(n)         (DMA_CHAN_HTIF_BIT << DMA_IFCR_CHAN_SHIFT(n))
+#define DMA_IFCR_CTEIF(n)         (DMA_CHAN_TEIF_BIT << DMA_IFCR_CHAN_SHIFT(n))
 
 /* DMA channel configuration register */
 
diff --git a/arch/arm/src/stm32/stm32_internal.h b/arch/arm/src/stm32/stm32_internal.h
index fc2df7d68d1e61a08ab39f4e0de9f5544b801662..ee0c639bf82c93743366e41b730a7d0561aa4072 100755
--- a/arch/arm/src/stm32/stm32_internal.h
+++ b/arch/arm/src/stm32/stm32_internal.h
@@ -380,6 +380,7 @@
  ************************************************************************************/
 
 typedef FAR void *DMA_HANDLE;
+typedef void (*dma_callback_t)(DMA_HANDLE handle, ubyte isr);
 
 /************************************************************************************
  * Inline Functions
@@ -476,6 +477,19 @@ EXTERN int stm32_dumpgpio(uint32 pinset, const char *msg);
 #  define stm32_dumpgpio(p,m)
 #endif
 
+/****************************************************************************
+ * Name: stm32_dmainitialize
+ *
+ * Description:
+ *   Initialize the DMA subsystem
+ *
+ * Returned Value:
+ *   None
+ *
+ ****************************************************************************/
+
+EXTERN void weak_function stm32_dmainitialize(void);
+
 /****************************************************************************
  * Name: stm32_dmachannel
  *
@@ -489,6 +503,27 @@ EXTERN int stm32_dumpgpio(uint32 pinset, const char *msg);
 
 EXTERN DMA_HANDLE stm32_dmachannel(void);
 
+/****************************************************************************
+ * Name: stm32_dmasetup
+ *
+ * Description:
+ *   Configure DMA before using
+ *
+ ****************************************************************************/
+
+EXTERN void stm32_dmasetup(DMA_HANDLE handle, uint32 paddr, uint32 maddr,
+                           size_t ntransfers, uint32 ccr);
+
+/****************************************************************************
+ * Name: stm32_dmastart
+ *
+ * Description:
+ *   Start the DMA transfer
+ *
+ ****************************************************************************/
+
+EXTERN void stm32_dmastart(DMA_HANDLE handle, dma_callback_t callback, boolean half);
+
 /************************************************************************************
  * Function: stm32_ethinitialize
  *
diff --git a/arch/arm/src/stm32/stm32_spi.c b/arch/arm/src/stm32/stm32_spi.c
index 581c02f69521508c615dae0347cdd17a7cfa4388..f485006c61abe181869c3db5b1a4931a0c541ff5 100755
--- a/arch/arm/src/stm32/stm32_spi.c
+++ b/arch/arm/src/stm32/stm32_spi.c
@@ -869,7 +869,7 @@ void stm32_spitake(FAR struct spi_dev_s *dev)
        * by a signal.
        */
 
-      ASSERT(*get_errno_ptr() == EINTR);
+      ASSERT(errno == EINTR);
     }
 }
 
diff --git a/configs/stm3210e-eval/src/up_boot.c b/configs/stm3210e-eval/src/up_boot.c
index aef793520ff1f9702f20983e181ece8ea68b9850..9787abaeb13b898fbb0ee78224c6895b90c5115c 100755
--- a/configs/stm3210e-eval/src/up_boot.c
+++ b/configs/stm3210e-eval/src/up_boot.c
@@ -72,6 +72,15 @@
 
 void stm32_boardinitialize(void)
 {
+  /* Initialize the DMA subsystem if the weak function stm32_dmainitialize has been
+   * brought into the build
+   */
+
+  if (stm32_dmainitialize)
+    {
+      stm32_dmainitialize();
+    }
+
   /* Configure SPI chip selects if 1) SPI is not disabled, and 2) the weak function
    * stm32_spiinitialize() has been brought into the link.
    */