diff --git a/Makefile b/Makefile
index a40ed396fa2aed088155d835014d346e4ad91640..a946a513d92de1eef32568278839de168e8445d7 100644
--- a/Makefile
+++ b/Makefile
@@ -63,7 +63,7 @@ clean-recursive:
 	done
 
 clean-topdir:
-	-rm $(OBJ) main.elf main.hex main.bin main.map $(OBJ:.o=.d)
+	-rm -f $(OBJ) main.elf main.hex main.bin main.map $(OBJ:.o=.d)
 
 main: main.elf
 	$(CP) -O ihex   main.elf main.hex
diff --git a/miosix/Makefile b/miosix/Makefile
index 392c914cf9afe1c71196d157bc8c383b05f08155..174a6157206534600dfddc6000d93ea440001c25 100644
--- a/miosix/Makefile
+++ b/miosix/Makefile
@@ -66,7 +66,7 @@ all: $(OBJ) $(BOOT_FILE)
 	$(AR) rcs libmiosix.a $(OBJ)
 
 clean:
-	-rm $(OBJ) $(BOOT_FILE) libmiosix.a $(OBJ:.o=.d)
+	-rm -f $(OBJ) $(BOOT_FILE) libmiosix.a $(OBJ:.o=.d)
 	-rm -f $(BOOT_FILE:.o=.d)
 
 %.o: %.s
diff --git a/miosix/_doc/textdoc/Changelog.txt b/miosix/_doc/textdoc/Changelog.txt
index e3bd861c07d8b6fa73338d7df631e6fb80503c2a..d6eaaa84af3128068a2985baa22a54c89b45365c 100644
--- a/miosix/_doc/textdoc/Changelog.txt
+++ b/miosix/_doc/textdoc/Changelog.txt
@@ -1,5 +1,8 @@
 Changelog for Miosix np embedded OS
 
+- Added -f option to rm in Makefile and miosix/Makefile, so that when
+  doing make clean on an already clean directory, no errors are reported
+- Added DMA RX for USART1 un STM32Serial. Also fixed bugs on stm32f1.
 - Fixed a bug in STM32Serial: the position of the PPRE1 and PPRE2 bitfields
   in RCC->CFGR varies from device family. This was causing incorrect baudrate
   settings in some configurations.
diff --git a/miosix/arch/common/drivers/serial_stm32.cpp b/miosix/arch/common/drivers/serial_stm32.cpp
index fccf420411d0ff37b85fbade545a6f363938d5fc..c22751e7689202160455f4c9663456c5033b56f7 100644
--- a/miosix/arch/common/drivers/serial_stm32.cpp
+++ b/miosix/arch/common/drivers/serial_stm32.cpp
@@ -123,6 +123,14 @@ void __attribute__((noinline)) usart1txDmaImpl()
     if(ports[0]) ports[0]->IRQhandleDMAtx();
 }
 
+/**
+ * \internal USART1 DMA rx actual implementation
+ */
+void __attribute__((noinline)) usart1rxDmaImpl()
+{
+    if(ports[0]) ports[0]->IRQhandleDMArx();
+}
+
 #ifdef _ARCH_CORTEXM3_STM32
 /**
  * \internal DMA1 Channel 4 IRQ (configured as USART1 TX)
@@ -134,6 +142,16 @@ void __attribute__((naked)) DMA1_Channel4_IRQHandler()
     restoreContext();
 }
 
+/**
+ * \internal DMA1 Channel 5 IRQ (configured as USART1 RX)
+ */
+void __attribute__((naked)) DMA1_Channel5_IRQHandler()
+{
+    saveContext();
+    asm volatile("bl _Z15usart1rxDmaImplv");
+    restoreContext();
+}
+
 #else //stm32f2 and stm32f4
 
 /**
@@ -145,6 +163,16 @@ void __attribute__((naked)) DMA2_Stream7_IRQHandler()
     asm volatile("bl _Z15usart1txDmaImplv");
     restoreContext();
 }
+
+/**
+ * \internal DMA2 stream 5 IRQ (configured as USART1 RX)
+ */
+void __attribute__((naked)) DMA2_Stream5_IRQHandler()
+{
+    saveContext();
+    asm volatile("bl _Z15usart1rxDmaImplv");
+    restoreContext();
+}
 #endif
 #endif //SERIAL_1_DMA
 
@@ -211,12 +239,20 @@ STM32Serial::STM32Serial(int id, int baudrate, FlowCtrl flowControl)
             RCC->AHBENR |= RCC_AHBENR_DMA1EN;
             NVIC_SetPriority(DMA1_Channel4_IRQn,15);//Lowest priority for serial
             NVIC_EnableIRQ(DMA1_Channel4_IRQn);
+            //Higher priority to ensure IRQhandleDMArx() is called before
+            //IRQhandleInterrupt(), so that idle is set correctly
+            NVIC_SetPriority(DMA1_Channel5_IRQn,14);
+            NVIC_EnableIRQ(DMA1_Channel5_IRQn);
             #else //stm32f2, stm32f4
             RCC->AHB1ENR |= RCC_AHB1ENR_DMA2EN;
             NVIC_SetPriority(DMA2_Stream7_IRQn,15);//Lowest priority for serial
             NVIC_EnableIRQ(DMA2_Stream7_IRQn);
+            //Higher priority to ensure IRQhandleDMArx() is called before
+            //IRQhandleInterrupt(), so that idle is set correctly
+            NVIC_SetPriority(DMA2_Stream5_IRQn,14);
+            NVIC_EnableIRQ(DMA2_Stream5_IRQn);
             #endif
-            port->CR3=USART_CR3_DMAT;
+            port->CR3=USART_CR3_DMAT | USART_CR3_DMAR;
             #endif //SERIAL_1_DMA
             #ifndef _ARCH_CORTEXM3_STM32
             //Only stm32f2, f4 and l1 have the new alternate function mapping
@@ -290,8 +326,21 @@ STM32Serial::STM32Serial(int id, int baudrate, FlowCtrl flowControl)
     }
     const unsigned int quot=2*freq/baudrate; //2*freq for round to nearest
     port->BRR=quot/2 + (quot & 1);           //Round to nearest
-    if(flowControl) port->CR3=USART_CR3_RTSE | USART_CR3_CTSE;
+    if(flowControl==false) port->CR3 |= USART_CR3_ONEBIT;
+    else port->CR3 |= USART_CR3_ONEBIT | USART_CR3_RTSE | USART_CR3_CTSE;
     //Enabled, 8 data bit, no parity, interrupt on character rx
+    
+#ifdef SERIAL_1_DMA
+    if(this==ports[0])
+    {
+        port->CR1 = USART_CR1_UE     //Enable port
+                  | USART_CR1_IDLEIE //Interrupt on idle line
+                  | USART_CR1_TE     //Transmission enbled
+                  | USART_CR1_RE;    //Reception enabled
+        IRQdmaReadStart();
+        return;
+    }
+#endif //SERIAL_1_DMA
     port->CR1 = USART_CR1_UE     //Enable port
               | USART_CR1_RXNEIE //Interrupt on data received
               | USART_CR1_IDLEIE //Interrupt on idle line
@@ -344,6 +393,7 @@ ssize_t STM32Serial::writeBlock(const void *buffer, size_t size, off_t where)
             {
                 //DMA is limited to 64K
                 size_t transferSize=min<size_t>(remaining-txBufferSize,65535);
+                waitDmaTxCompletion();
                 writeDma(buf,transferSize);
                 buf+=transferSize;
                 remaining-=transferSize;
@@ -352,6 +402,9 @@ ssize_t STM32Serial::writeBlock(const void *buffer, size_t size, off_t where)
         while(remaining>0)
         {
             size_t transferSize=min<size_t>(remaining,txBufferSize);
+            waitDmaTxCompletion();
+            //Copy to txBuffer only after DMA xfer completed, as the previous
+            //xfer may be using the same buffer
             memcpy(txBuffer,buf,transferSize);
             writeDma(txBuffer,transferSize);
             buf+=transferSize;
@@ -410,17 +463,25 @@ void STM32Serial::IRQhandleInterrupt()
 {
     unsigned int status=port->SR;
     char c;
+    #ifdef SERIAL_1_DMA
+    if(this!=ports[0] && (status & USART_SR_RXNE))
+    #else //SERIAL_1_DMA
     if(status & USART_SR_RXNE)
+    #endif //SERIAL_1_DMA
     {
         //Always read data, since this clears interrupt flags
         c=port->DR;
-        //If no noise nor framing nor parity error put data in buffer
-        if((status & 0x7)==0) if(rxQueue.tryPut(c)==false) /*fifo overflow*/;
+        //If no error put data in buffer
+        if((status & USART_SR_FE)==0)
+            if(rxQueue.tryPut(c)==false) /*fifo overflow*/;
         idle=false;
     }
     if(status & USART_SR_IDLE)
     {
         c=port->DR; //clears interrupt flags
+        #ifdef SERIAL_1_DMA
+        if(this==ports[0]) IRQreadDma();
+        #endif //SERIAL_1_DMA
         idle=true;
     }
     if((status & USART_SR_IDLE) || rxQueue.size()>=rxQueueMin)
@@ -456,6 +517,17 @@ void STM32Serial::IRQhandleDMAtx()
         Scheduler::IRQfindNextThread();
     txWaiting=0;
 }
+
+void STM32Serial::IRQhandleDMArx()
+{
+    IRQreadDma();
+    idle=false;
+    if(rxWaiting==0) return;
+    rxWaiting->IRQwakeup();
+    if(rxWaiting->IRQgetPriority()>Thread::IRQgetCurrentThread()->IRQgetPriority())
+        Scheduler::IRQfindNextThread();
+    rxWaiting=0;
+}
 #endif //SERIAL_1_DMA
 
 STM32Serial::~STM32Serial()
@@ -473,10 +545,13 @@ STM32Serial::~STM32Serial()
         {
             case 1:
                 #ifdef SERIAL_1_DMA
+                IRQdmaReadStop();
                 #ifdef _ARCH_CORTEXM3_STM32
                 NVIC_DisableIRQ(DMA1_Channel4_IRQn);
+                NVIC_DisableIRQ(DMA1_Channel5_IRQn);
                 #else //stm32f2, stm32f4
                 NVIC_DisableIRQ(DMA2_Stream7_IRQn);
+                NVIC_DisableIRQ(DMA2_Stream5_IRQn);
                 #endif
                 #endif //SERIAL_1_DMA
                 NVIC_DisableIRQ(USART1_IRQn);
@@ -495,7 +570,7 @@ STM32Serial::~STM32Serial()
 }
 
 #ifdef SERIAL_1_DMA
-void STM32Serial::writeDma(const char *buffer, size_t size)
+void STM32Serial::waitDmaTxCompletion()
 {
     FastInterruptDisableLock dLock;
     // If a previous DMA xfer is in progress, wait
@@ -510,7 +585,10 @@ void STM32Serial::writeDma(const char *buffer, size_t size)
             }
         } while(txWaiting);
     }
-    // Setup DMA xfer
+}
+
+void STM32Serial::writeDma(const char *buffer, size_t size)
+{
     dmaTxInProgress=true;
     #ifdef _ARCH_CORTEXM3_STM32
     DMA1_Channel4->CPAR=reinterpret_cast<unsigned int>(&port->DR);
@@ -539,6 +617,58 @@ void STM32Serial::writeDma(const char *buffer, size_t size)
                    | DMA_SxCR_EN;     //Start the DMA
     #endif //_ARCH_CORTEXM3_STM32
 }
+
+void STM32Serial::IRQreadDma()
+{
+    unsigned int elem=IRQdmaReadStop();
+    for(int i=0;i<elem;i++)
+        if(rxQueue.tryPut(rxBuffer[i])==false) /*fifo overflow*/;
+    IRQdmaReadStart();
+}
+
+void STM32Serial::IRQdmaReadStart()
+{
+    #ifdef _ARCH_CORTEXM3_STM32
+    DMA1_Channel5->CPAR=reinterpret_cast<unsigned int>(&port->DR);
+    DMA1_Channel5->CMAR=reinterpret_cast<unsigned int>(rxBuffer);
+    DMA1_Channel5->CNDTR=rxQueueMin;
+    DMA1_Channel5->CCR=DMA_CCR4_MINC  //Increment RAM pointer
+                     | 0              //Peripheral to memory
+                     | DMA_CCR4_TEIE  //Interrupt on transfer error
+                     | DMA_CCR4_TCIE  //Interrupt on transfer complete
+                     | DMA_CCR4_EN;   //Start DMA
+    #else //_ARCH_CORTEXM3_STM32
+    DMA2_Stream5->PAR=reinterpret_cast<unsigned int>(&port->DR);
+    DMA2_Stream5->M0AR=reinterpret_cast<unsigned int>(rxBuffer);
+    DMA2_Stream5->NDTR=rxQueueMin;
+    DMA2_Stream5->CR=DMA_SxCR_CHSEL_2 //Select channel 4 (USART_RX)
+                   | DMA_SxCR_MINC    //Increment RAM pointer
+                   | 0                //Peripheral to memory
+                   | DMA_SxCR_HTIE    //Interrupt on half transfer
+                   | DMA_SxCR_TEIE    //Interrupt on transfer error
+                   | DMA_SxCR_DMEIE   //Interrupt on direct mode error
+                   | DMA_SxCR_EN;     //Start the DMA
+    #endif //_ARCH_CORTEXM3_STM32
+}
+
+int STM32Serial::IRQdmaReadStop()
+{
+    #ifdef _ARCH_CORTEXM3_STM32
+    DMA1_Channel5->CCR=0;
+    DMA1->IFCR=DMA_IFCR_CGIF5;
+    return rxQueueMin-DMA1_Channel5->CNDTR;
+    #else //_ARCH_CORTEXM3_STM32
+    //Stop DMA and wait for it to actually stop
+    DMA2_Stream5->CR&= ~DMA_SxCR_EN;
+    while(DMA2_Stream5->CR & DMA_SxCR_EN) ;
+    DMA2->HIFCR=DMA_HIFCR_CTCIF5
+              | DMA_HIFCR_CHTIF5
+              | DMA_HIFCR_CTEIF5
+              | DMA_HIFCR_CDMEIF5
+              | DMA_HIFCR_CFEIF5;
+    return rxQueueMin-DMA2_Stream5->NDTR;
+    #endif //_ARCH_CORTEXM3_STM32
+}
 #endif //SERIAL_1_DMA
 
 } //namespace miosix
diff --git a/miosix/arch/common/drivers/serial_stm32.h b/miosix/arch/common/drivers/serial_stm32.h
index 860ba3309b6b3301e2ff06d672102ce41966e003..2287008ca034c2629452eba252c1278af3737f67 100644
--- a/miosix/arch/common/drivers/serial_stm32.h
+++ b/miosix/arch/common/drivers/serial_stm32.h
@@ -124,6 +124,12 @@ public:
      * Never call this from user code.
      */
     void IRQhandleDMAtx();
+    
+    /**
+     * \internal the serial port DMA rx interrupts call this member function.
+     * Never call this from user code.
+     */
+    void IRQhandleDMArx();
     #endif //SERIAL_1_DMA
     
     /**
@@ -134,11 +140,33 @@ public:
 private:
     #ifdef SERIAL_1_DMA
     /**
-     * Write to the serial port using DMA
+     * Wait until a pending DMA TX completes, if any
+     */
+    void waitDmaTxCompletion();
+    
+    /**
+     * Write to the serial port using DMA. When the function returns, the DMA
+     * transfer is still in progress.
      * \param buffer buffer to write
      * \param size size of buffer to write
      */
     void writeDma(const char *buffer, size_t size);
+    
+    /**
+     * Read from DMA buffer and write data to queue
+     */
+    void IRQreadDma();
+    
+    /**
+     * Start DMA read
+     */
+    void IRQdmaReadStart();
+    
+    /**
+     * Stop DMA read
+     * \return the number of characters in rxBuffer
+     */
+    int IRQdmaReadStop();
     #endif //SERIAL_1_DMA
     
     /**
@@ -165,6 +193,9 @@ private:
     /// the fact that this class must be allocated on the heap as it derives
     /// from Device, and the Miosix linker scripts never put the heap in CCM
     char txBuffer[txBufferSize];
+    /// This buffer emulates the behaviour of a 16550. It is filled using DMA
+    /// and an interrupt is fired as soon as it is half full
+    char rxBuffer[rxQueueMin];
     bool dmaTxInProgress;             ///< True if a DMA tx is in progress
     #endif //SERIAL_1_DMA
     bool idle;                        ///< Receiver idle
diff --git a/miosix/arch/cortexM3_stm32/stm32f103ze_stm3210e-eval/interfaces-impl/bsp.cpp b/miosix/arch/cortexM3_stm32/stm32f103ze_stm3210e-eval/interfaces-impl/bsp.cpp
index eb1a52c6b6062c1e112cc75b715fd63aa53787be..8c26f00b130ca481a85f6ac4302055b3a81e88fd 100644
--- a/miosix/arch/cortexM3_stm32/stm32f103ze_stm3210e-eval/interfaces-impl/bsp.cpp
+++ b/miosix/arch/cortexM3_stm32/stm32f103ze_stm3210e-eval/interfaces-impl/bsp.cpp
@@ -96,6 +96,14 @@ minimize power consumption all unused GPIO must not be left floating.
 */
 void shutdown()
 {
+    //FIXME: at the time of writing, Miosix's newlib does not yet provide the
+    //sys/ioctl.h header file. Replace with a call to ioctl() when ready
+    #ifdef WITH_FILESYSTEM
+    miosix::getFileDescriptorTable().ioctl(STDOUT_FILENO,IOCTL_SYNC,0);
+    #else //WITH_FILESYSTEM
+    DefaultConsole::instance().get()->ioctl(IOCTL_SYNC,0);
+    #endif //WITH_FILESYSTEM
+
     #ifdef WITH_FILESYSTEM
     FilesystemManager::instance().umountAll();
     #endif //WITH_FILESYSTEM