diff --git a/sbs.conf b/sbs.conf
index d36862388d5c544e3f0833b2237ead914e7a7fa0..db4938d4d2253e703f06de4c793d630178ee3214 100644
--- a/sbs.conf
+++ b/sbs.conf
@@ -164,3 +164,11 @@ BinName:    anakin-test-dma
 Include:    %shared %i2c %math %anakin-data
 Defines:   
 Main:       anakin-test-dma
+
+[dma-lowlevel-test]
+Type:       board
+BoardId:    stm32f429zi_skyward_anakin
+BinName:    dma-lowlevel-test
+Include:    %shared %i2c %math %anakin-data
+Defines:   
+Main:       dma-lowlevel-test
diff --git a/src/entrypoints/dma-lowlevel-test.cpp b/src/entrypoints/dma-lowlevel-test.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..4a3cfef33397dfc124678ff9c1130c01d32d224d
--- /dev/null
+++ b/src/entrypoints/dma-lowlevel-test.cpp
@@ -0,0 +1,50 @@
+
+#include <sensors/iNemo.h>
+#include <sensors/FXAS21002.h>
+#include <sensors/MPU9250.h>
+#include <sensors/LPS331AP.h>
+#include <sensors/MAX21105.h>
+#include <sensors/MS580301BA07.h>
+
+#include <DMA/DMA.h>
+#include <DMA/SensorSampling.h>
+
+typedef Gpio<GPIOA_BASE, 5> GpioSck;
+typedef Gpio<GPIOA_BASE, 6> GpioMiso;
+typedef Gpio<GPIOA_BASE, 7> GpioMosi;
+typedef BusSPI < 1, GpioMosi, GpioMiso, GpioSck> busSPI1;
+
+typedef ProtocolSPI<busSPI1, Gpio<GPIOD_BASE, 13>> spiMPU9250;
+typedef ProtocolSPI<busSPI1, Gpio<GPIOG_BASE, 11>> spiINEMOA;
+typedef ProtocolSPI<busSPI1, Gpio<GPIOG_BASE,  9>> spiINEMOG;
+
+typedef MPU9250<spiMPU9250> mpu_t;
+typedef iNEMOLSM9DS0<spiINEMOG,spiINEMOA> inemo_t;
+
+int main()
+{
+    puts("\n\n---");
+    auto& spi=SPIDriver::instance();
+    
+    inemo_t inemo(inemo_t::ACC_FS_16G,inemo_t::GYRO_FS_245,inemo_t::COMPASS_FS_2);
+    if(inemo.init()==false) puts("init failed");
+    auto req=inemo.buildDMARequest();
+    
+    auto sample=[&]()
+    {
+        if(spi.transaction(req)==false) puts("DMA error");
+        for(auto& r : req) inemo.onDMAUpdate(r);
+    };
+    
+    for(int i=0;i<2;i++)
+    {
+        Thread::sleep(20);
+        sample();
+    }
+    
+    for(;;)
+    {
+        getchar();
+        sample();
+    }
+}
diff --git a/src/shared/DMA/DMA.cpp b/src/shared/DMA/DMA.cpp
index 791e2355c8af6714cf3979313fac021a0eed9c6d..7e53eab192419f74cd997535d37744a6f9a210fe 100644
--- a/src/shared/DMA/DMA.cpp
+++ b/src/shared/DMA/DMA.cpp
@@ -34,15 +34,15 @@ typedef Gpio<GPIOA_BASE,7> mosi;
 /**
  * DMA RX end of transfer
  */
-void __attribute__((naked)) DMA2_Stream5_IRQHandler()
+void __attribute__((naked)) DMA2_Stream0_IRQHandler()
 {
     saveContext();
     asm volatile("bl _Z20SPI1rxDmaHandlerImplv");
     restoreContext();
 }
 
-static Thread *waiting = NULL;
-static vector<SPIRequest> *requestVector;
+static Thread *waiting = nullptr;
+static vector<SPIRequest> *requestVector = nullptr;
 static size_t requestIndex = 0;
 static bool error = false;
 
@@ -53,10 +53,16 @@ void __attribute__((used)) SPI1rxDmaHandlerImpl()
 {
     if(DMA2->LISR & (DMA_LISR_TEIF0 | DMA_LISR_DMEIF0)) 
         error = true;
+    if(DMA2->HISR & (DMA_HISR_TEIF5 | DMA_HISR_DMEIF5)) 
+        error = true;
     DMA2->LIFCR = DMA_LIFCR_CTCIF0
                 | DMA_LIFCR_CTEIF0
                 | DMA_LIFCR_CDMEIF0;
+    DMA2->HIFCR = DMA_HIFCR_CTCIF5
+                | DMA_HIFCR_CTEIF5
+                | DMA_HIFCR_CDMEIF5;
     
+    if(requestVector==nullptr) return;
     (*requestVector)[requestIndex].IRQendTransaction();
 
     if( ++requestIndex >= requestVector->size() )
@@ -114,8 +120,9 @@ bool SPIDriver::transaction(vector<SPIRequest>& requests)
         }
     }
    
-    bool result=!error;
     disableDMA();
+    requestVector=nullptr;
+    bool result=!error;
     pthread_mutex_unlock(&mutex);
     return result;
 }
@@ -143,8 +150,8 @@ SPIDriver::SPIDriver()
 //                  | SPI_CR1_BR_1 //Less than 10MHz
                   | SPI_CR1_BR_2 // fClock / 32
                   | SPI_CR1_SPE; //SPI enabled
-        NVIC_SetPriority(DMA2_Stream5_IRQn,10);//Low priority for DMA
-        NVIC_EnableIRQ(DMA2_Stream5_IRQn);
+        NVIC_SetPriority(DMA2_Stream0_IRQn,10);//Low priority for DMA
+        NVIC_EnableIRQ(DMA2_Stream0_IRQn);
     }
 }
 
@@ -166,6 +173,7 @@ void SPIRequest::IRQbeginTransaction()
     DMA2_Stream0->CR   = DMA_SxCR_CHSEL_1 | DMA_SxCR_CHSEL_0 // Channel 3
                        | DMA_SxCR_PL_1    //High priority because fifo disabled
                        | DMA_SxCR_MINC    //Increment memory pointer
+                       | DMA_SxCR_TCIE    //Interrupt on transfer complete
                        | DMA_SxCR_TEIE    //Interrupt on transfer error
                        | DMA_SxCR_DMEIE   //Interrupt on direct mode error
                        | DMA_SxCR_EN;     //Start DMA
@@ -179,7 +187,6 @@ void SPIRequest::IRQbeginTransaction()
                        | DMA_SxCR_PL_1    //High priority because fifo disabled
                        | DMA_SxCR_MINC    //Increment memory pointer
                        | DMA_SxCR_DIR_0   //Memory to peripheral
-                       | DMA_SxCR_TCIE    //Interrupt on transfer complete
                        | DMA_SxCR_TEIE    //Interrupt on transfer error 
                        | DMA_SxCR_DMEIE   //Interrupt on direct mode error
                        | DMA_SxCR_EN;     //Start DMA
@@ -188,10 +195,6 @@ void SPIRequest::IRQbeginTransaction()
     
 void SPIRequest::IRQendTransaction()
 {
-    //FIXME: ensure dead time between CS high and CS low!!!
-    //And, is it really needed?
     chipSelect.high();
-    
-    //TX dma channel has no IRQ, so clear flag here
-    DMA2->HIFCR=DMA_HIFCR_CTCIF5;
+    delayUs(10); //FIXME: properly size the delay
 }