diff --git a/miosix/arch/common/drivers/serial_stm32.cpp b/miosix/arch/common/drivers/serial_stm32.cpp
deleted file mode 100644
index f35c32d70937e682b04c70a94c2a32d7bbab4c89..0000000000000000000000000000000000000000
--- a/miosix/arch/common/drivers/serial_stm32.cpp
+++ /dev/null
@@ -1,1402 +0,0 @@
-/***************************************************************************
- *   Copyright (C) 2010-2018 by Terraneo Federico                          *
- *                                                                         *
- *   This program is free software; you can redistribute it and/or modify  *
- *   it under the terms of the GNU General Public License as published by  *
- *   the Free Software Foundation; either version 2 of the License, or     *
- *   (at your option) any later version.                                   *
- *                                                                         *
- *   This program is distributed in the hope that it will be useful,       *
- *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
- *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
- *   GNU General Public License for more details.                          *
- *                                                                         *
- *   As a special exception, if other files instantiate templates or use   *
- *   macros or inline functions from this file, or you compile this file   *
- *   and link it with other works to produce a work based on this file,    *
- *   this file does not by itself cause the resulting work to be covered   *
- *   by the GNU General Public License. However the source code for this   *
- *   file must still be made available in accordance with the GNU General  *
- *   Public License. This exception does not invalidate any other reasons  *
- *   why a work based on this file might be covered by the GNU General     *
- *   Public License.                                                       *
- *                                                                         *
- *   You should have received a copy of the GNU General Public License     *
- *   along with this program; if not, see <http://www.gnu.org/licenses/>   *
- ***************************************************************************/ 
-
-#include <cstring>
-#include <errno.h>
-#include <termios.h>
-#include "serial_stm32.h"
-#include "kernel/sync.h"
-#include "kernel/scheduler/scheduler.h"
-#include "filesystem/ioctl.h"
-#include "cache/cortexMx_cache.h"
-
-using namespace std;
-using namespace miosix;
-
-//Work around ST renaming register fields for some STM32L4
-#if defined(USART_CR1_RXNEIE_RXFNEIE) && !defined(USART_CR1_RXNEIE)
-#define USART_CR1_RXNEIE    USART_CR1_RXNEIE_RXFNEIE
-#endif
-#if defined(USART_ISR_RXNE_RXFNE) && !defined(USART_ISR_RXNE)
-#define USART_ISR_RXNE      USART_ISR_RXNE_RXFNE
-#endif
-#if defined(USART_ISR_TXE_TXFNF) && !defined(USART_ISR_TXE)
-#define USART_ISR_TXE       USART_ISR_TXE_TXFNF
-#endif
-
-#ifdef STM32F030x8
-// On this chip only USART1 exists
-#define STM32_NO_SERIAL_2_3
-#endif
-
-static const int numPorts=3; //Supporting only USART1, USART2, USART3
-
-//A nice feature of the stm32 is that the USART are connected to the same
-//GPIOS in all families, stm32f1, f2, f4 and l1. Additionally, USART1 is
-//always connected to the APB2, while USART2 and USART3 are always on APB1
-//Unfortunately, this does not hold with DMA.
-typedef Gpio<GPIOA_BASE,9>  u1tx;
-typedef Gpio<GPIOA_BASE,10> u1rx;
-typedef Gpio<GPIOA_BASE,11> u1cts;
-typedef Gpio<GPIOA_BASE,12> u1rts;
-
-typedef Gpio<GPIOA_BASE,2>  u2tx;
-typedef Gpio<GPIOA_BASE,3>  u2rx;
-typedef Gpio<GPIOA_BASE,0>  u2cts;
-typedef Gpio<GPIOA_BASE,1>  u2rts;
-
-typedef Gpio<GPIOB_BASE,10> u3tx;
-typedef Gpio<GPIOB_BASE,11> u3rx;
-typedef Gpio<GPIOB_BASE,13> u3cts;
-typedef Gpio<GPIOB_BASE,14> u3rts;
-
-/// Pointer to serial port classes to let interrupts access the classes
-static STM32Serial *ports[numPorts]={0};
-
-/**
- * \internal interrupt routine for usart1 actual implementation
- */
-void __attribute__((noinline)) usart1irqImpl()
-{
-   if(ports[0]) ports[0]->IRQhandleInterrupt();
-}
-
-/**
- * \internal interrupt routine for usart1
- */
-void __attribute__((naked)) USART1_IRQHandler()
-{
-    saveContext();
-    asm volatile("bl _Z13usart1irqImplv");
-    restoreContext();
-}
-
-#if !defined(STM32_NO_SERIAL_2_3)
-
-/**
- * \internal interrupt routine for usart2 actual implementation
- */
-void __attribute__((noinline)) usart2irqImpl()
-{
-   if(ports[1]) ports[1]->IRQhandleInterrupt();
-}
-
-/**
- * \internal interrupt routine for usart2
- */
-void __attribute__((naked)) USART2_IRQHandler()
-{
-    saveContext();
-    asm volatile("bl _Z13usart2irqImplv");
-    restoreContext();
-}
-
-#if !defined(STM32F411xE) && !defined(STM32F401xE) && !defined(STM32F401xC)
-/**
- * \internal interrupt routine for usart3 actual implementation
- */
-void __attribute__((noinline)) usart3irqImpl()
-{
-   if(ports[2]) ports[2]->IRQhandleInterrupt();
-}
-
-/**
- * \internal interrupt routine for usart3
- */
-#if !defined(STM32F072xB)
-void __attribute__((naked)) USART3_IRQHandler()
-{
-    saveContext();
-    asm volatile("bl _Z13usart3irqImplv");
-    restoreContext();
-}
-#else  //!defined(STM32F072xB)
-void __attribute__((naked)) USART3_4_IRQHandler()
-{
-    saveContext();
-    asm volatile("bl _Z13usart3irqImplv");
-    restoreContext();
-}
-#endif //!defined(STM32F072xB)
-#endif //!defined(STM32F411xE) && !defined(STM32F401xE) && !defined(STM32F401xC)
-#endif //!defined(STM32_NO_SERIAL_2_3)
-
-#ifdef SERIAL_1_DMA
-
-/**
- * \internal USART1 DMA tx actual implementation
- */
-void __attribute__((noinline)) usart1txDmaImpl()
-{
-    #if defined(_ARCH_CORTEXM3_STM32F1) || defined (_ARCH_CORTEXM4_STM32F3) \
-     || defined(_ARCH_CORTEXM4_STM32L4)
-    DMA1->IFCR=DMA_IFCR_CGIF4;
-    DMA1_Channel4->CCR=0; //Disable DMA
-    #elif defined(_ARCH_CORTEXM7_STM32H7) //stm32f2 and f4
-    DMA1->HIFCR = DMA_HIFCR_CTCIF7
-                | DMA_HIFCR_CTEIF7
-                | DMA_HIFCR_CDMEIF7
-                | DMA_HIFCR_CFEIF7;
-    #else //stm32f2 and f4
-    DMA2->HIFCR = DMA_HIFCR_CTCIF7
-                | DMA_HIFCR_CTEIF7
-                | DMA_HIFCR_CDMEIF7
-                | DMA_HIFCR_CFEIF7;
-    #endif
-    if(ports[0]) ports[0]->IRQhandleDMAtx();
-}
-
-/**
- * \internal USART1 DMA rx actual implementation
- */
-void __attribute__((noinline)) usart1rxDmaImpl()
-{
-    if(ports[0]) ports[0]->IRQhandleDMArx();
-}
-
-#if defined(_ARCH_CORTEXM3_STM32F1) || defined (_ARCH_CORTEXM4_STM32F3) \
- || defined(_ARCH_CORTEXM4_STM32L4)
-/**
- * \internal DMA1 Channel 4 IRQ (configured as USART1 TX)
- */
-void __attribute__((naked)) DMA1_Channel4_IRQHandler()
-{
-    saveContext();
-    asm volatile("bl _Z15usart1txDmaImplv");
-    restoreContext();
-}
-
-/**
- * \internal DMA1 Channel 5 IRQ (configured as USART1 RX)
- */
-void __attribute__((naked)) DMA1_Channel5_IRQHandler()
-{
-    saveContext();
-    asm volatile("bl _Z15usart1rxDmaImplv");
-    restoreContext();
-}
-
-#elif defined(_ARCH_CORTEXM7_STM32H7)
-
-/**
- * \internal DMA1 stream 7 IRQ (configured as USART1 TX)
- */
-void __attribute__((naked)) DMA1_Stream7_IRQHandler()
-{
-    saveContext();
-    asm volatile("bl _Z15usart1txDmaImplv");
-    restoreContext();
-}
-
-/**
- * \internal DMA1 stream 5 IRQ (configured as USART1 RX)
- */
-void __attribute__((naked)) DMA1_Stream5_IRQHandler()
-{
-    saveContext();
-    asm volatile("bl _Z15usart1rxDmaImplv");
-    restoreContext();
-}
-
-#else //stm32f2 and stm32f4
-
-/**
- * \internal DMA2 stream 7 IRQ (configured as USART1 TX)
- */
-void __attribute__((naked)) DMA2_Stream7_IRQHandler()
-{
-    saveContext();
-    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
-
-#if defined(SERIAL_2_DMA) && !defined(STM32_NO_SERIAL_2_3)
-
-/**
- * \internal USART2 DMA tx actual implementation
- */
-void __attribute__((noinline)) usart2txDmaImpl()
-{
-    #if defined(_ARCH_CORTEXM3_STM32F1) || defined (_ARCH_CORTEXM4_STM32F3) \
-     || defined(_ARCH_CORTEXM4_STM32L4)
-    DMA1->IFCR=DMA_IFCR_CGIF7;
-    DMA1_Channel7->CCR=0; //Disable DMA
-    #else //stm32f2 and f4
-    DMA1->HIFCR = DMA_HIFCR_CTCIF6
-                | DMA_HIFCR_CTEIF6
-                | DMA_HIFCR_CDMEIF6
-                | DMA_HIFCR_CFEIF6;
-    #endif
-    if(ports[1]) ports[1]->IRQhandleDMAtx();
-}
-
-/**
- * \internal USART2 DMA rx actual implementation
- */
-void __attribute__((noinline)) usart2rxDmaImpl()
-{
-    if(ports[1]) ports[1]->IRQhandleDMArx();
-}
-
-#if defined(_ARCH_CORTEXM3_STM32F1) || defined (_ARCH_CORTEXM4_STM32F3) \
- || defined(_ARCH_CORTEXM4_STM32L4)
-/**
- * \internal DMA1 Channel 7 IRQ (configured as USART2 TX)
- */
-void __attribute__((naked)) DMA1_Channel7_IRQHandler()
-{
-    saveContext();
-    asm volatile("bl _Z15usart2txDmaImplv");
-    restoreContext();
-}
-
-/**
- * \internal DMA1 Channel 6 IRQ (configured as USART2 RX)
- */
-void __attribute__((naked)) DMA1_Channel6_IRQHandler()
-{
-    saveContext();
-    asm volatile("bl _Z15usart2rxDmaImplv");
-    restoreContext();
-}
-
-#elif defined(_ARCH_CORTEXM7_STM32H7)
-
-/**
- * \internal DMA1 stream 6 IRQ (configured as USART2 TX)
- */
-void __attribute__((naked)) DMA1_Stream6_IRQHandler()
-{
-    saveContext();
-    asm volatile("bl _Z15usart2txDmaImplv");
-    restoreContext();
-}
-
-/**
- * \internal DMA1 stream 4 IRQ (configured as USART2 RX)
- */
-void __attribute__((naked)) DMA1_Stream4_IRQHandler()
-{
-    saveContext();
-    asm volatile("bl _Z15usart2rxDmaImplv");
-    restoreContext();
-}
-
-#else //stm32f2 and stm32f4
-
-/**
- * \internal DMA1 stream 6 IRQ (configured as USART2 TX)
- */
-void __attribute__((naked)) DMA1_Stream6_IRQHandler()
-{
-    saveContext();
-    asm volatile("bl _Z15usart2txDmaImplv");
-    restoreContext();
-}
-
-/**
- * \internal DMA1 stream 5 IRQ (configured as USART2 RX)
- */
-void __attribute__((naked)) DMA1_Stream5_IRQHandler()
-{
-    saveContext();
-    asm volatile("bl _Z15usart2rxDmaImplv");
-    restoreContext();
-}
-#endif
-#endif //SERIAL_2_DMA
-
-#if defined(SERIAL_3_DMA) && !defined(STM32_NO_SERIAL_2_3)
-
-/**
- * \internal USART3 DMA tx actual implementation
- */
-void __attribute__((noinline)) usart3txDmaImpl()
-{
-    #if defined(_ARCH_CORTEXM3_STM32F1) || defined (_ARCH_CORTEXM4_STM32F3) \
-     || defined(_ARCH_CORTEXM4_STM32L4)
-    DMA1->IFCR=DMA_IFCR_CGIF2;
-    DMA1_Channel2->CCR=0; //Disable DMA
-    #else //stm32f2 and f4
-    DMA1->LIFCR = DMA_LIFCR_CTCIF3
-                | DMA_LIFCR_CTEIF3
-                | DMA_LIFCR_CDMEIF3
-                | DMA_LIFCR_CFEIF3;
-    #endif
-    if(ports[2]) ports[2]->IRQhandleDMAtx();
-}
-
-/**
- * \internal USART3 DMA rx actual implementation
- */
-void __attribute__((noinline)) usart3rxDmaImpl()
-{
-    if(ports[2]) ports[2]->IRQhandleDMArx();
-}
-
-#if defined(_ARCH_CORTEXM3_STM32F1) || defined (_ARCH_CORTEXM4_STM32F3) \
- || defined(_ARCH_CORTEXM4_STM32L4)
-/**
- * \internal DMA1 Channel 2 IRQ (configured as USART3 TX)
- */
-void __attribute__((naked)) DMA1_Channel2_IRQHandler()
-{
-    saveContext();
-    asm volatile("bl _Z15usart3txDmaImplv");
-    restoreContext();
-}
-
-/**
- * \internal DMA1 Channel 3 IRQ (configured as USART3 RX)
- */
-void __attribute__((naked)) DMA1_Channel3_IRQHandler()
-{
-    saveContext();
-    asm volatile("bl _Z15usart3rxDmaImplv");
-    restoreContext();
-}
-
-#else //stm32f2 and stm32f4
-
-/**
- * \internal DMA1 stream 3 IRQ (configured as USART3 TX)
- */
-void __attribute__((naked)) DMA1_Stream3_IRQHandler()
-{
-    saveContext();
-    asm volatile("bl _Z15usart3txDmaImplv");
-    restoreContext();
-}
-
-/**
- * \internal DMA1 stream 1 IRQ (configured as USART3 RX)
- */
-void __attribute__((naked)) DMA1_Stream1_IRQHandler()
-{
-    saveContext();
-    asm volatile("bl _Z15usart3rxDmaImplv");
-    restoreContext();
-}
-#endif
-#endif //SERIAL_3_DMA
-
-namespace miosix {
-
-#ifdef SERIAL_DMA
-#if defined(_ARCH_CORTEXM4_STM32F4) || defined(_ARCH_CORTEXM4_STM32F3) \
- || defined(_ARCH_CORTEXM4_STM32L4)
-/**
- * The STM3F3, STM32F4 and STM32L4 have an ugly quirk of having 64KB RAM area
- * called CCM that can only be accessed by the processor and not be the DMA.
- * \param x pointer to check
- * \return true if the pointer is inside the CCM, and thus it isn't possible
- * to use it for DMA transfers
- */
-static bool isInCCMarea(const void *x)
-{
-    unsigned int ptr=reinterpret_cast<const unsigned int>(x);
-    return (ptr>=0x10000000) && (ptr<(0x10000000+64*1024));
-}
-#else //_ARCH_CORTEXM4_STM32F4 and _ARCH_CORTEXM4_STM32F3
-static inline bool isInCCMarea(const void *x) { return false; }
-#endif // _ARCH_CORTEXM4_STM32F4 and _ARCH_CORTEXM4_STM32F3
-#endif //SERIAL_DMA
-
-//
-// class STM32Serial
-//
-
-// A note on the baudrate/500: the buffer is selected so as to withstand
-// 20ms of full data rate. In the 8N1 format one char is made of 10 bits.
-// So (baudrate/10)*0.02=baudrate/500
-STM32Serial::STM32Serial(int id, int baudrate, FlowCtrl flowControl)
-        : Device(Device::TTY), rxQueue(rxQueueMin+baudrate/500),
-          flowControl(flowControl==RTSCTS), portId(id)
-{
-    //stm32f1 alternate function mapping does not work like later stm32 chips,
-    //its only purpose is to change the GPIO pins allocated to a peripherals.
-    //There is no AF register per pin, but an AF register per peripheral
-    //with several mutually exclusive mapping options. 
-    //Therefore we don't need to configure AF on stm32f1 for the serial to work
-    #if !defined(_ARCH_CORTEXM3_STM32F1)
-    //stm32f2, f4, l4, l1, f7, h7, l0 require alternate function mapping
-    //stm32f0/l0 family has different alternate function mapping
-    //with respect to the other families
-    #if defined(_ARCH_CORTEXM0_STM32F0)
-    int altFunc = 1; // F0 only
-    #elif defined(_ARCH_CORTEXM0PLUS_STM32L0)
-    int altFunc = 4; // L0 only
-    #else
-    int altFunc = 7; // everyone else
-    #endif
-    switch(id)
-    {
-        case 1:
-            u1tx::alternateFunction(altFunc);
-            u1rx::alternateFunction(altFunc);
-            if(flowControl)
-            {
-                u1rts::alternateFunction(altFunc);
-                u1cts::alternateFunction(altFunc);
-            }
-            break;
-        case 2:
-            u2tx::alternateFunction(altFunc);
-            u2rx::alternateFunction(altFunc);
-            if(flowControl)
-            {
-                u2rts::alternateFunction(altFunc);
-                u2cts::alternateFunction(altFunc);
-            }
-            break;
-        case 3:
-            u3tx::alternateFunction(altFunc);
-            u3rx::alternateFunction(altFunc);
-            if(flowControl)
-            {
-                u3rts::alternateFunction(altFunc);
-                u3cts::alternateFunction(altFunc);
-            }
-            break;
-    }
-    #endif
-    
-    switch(id)
-    {
-        case 1:
-            commonInit(id,baudrate,u1tx::getPin(),u1rx::getPin(),
-                       u1rts::getPin(),u1cts::getPin());
-            break;
-        case 2:
-            commonInit(id,baudrate,u2tx::getPin(),u2rx::getPin(),
-                       u2rts::getPin(),u2cts::getPin());
-            break;
-        case 3:
-            commonInit(id,baudrate,u3tx::getPin(),u3rx::getPin(),
-                       u3rts::getPin(),u3cts::getPin());
-            break;
-    }
-}
-
-STM32Serial::STM32Serial(int id, int baudrate, GpioPin tx, GpioPin rx)
-    : Device(Device::TTY), rxQueue(rxQueueMin+baudrate/500),
-      flowControl(false), portId(id)
-{
-    commonInit(id,baudrate,tx,rx,tx,rx); //The last two args will be ignored
-}
-
-STM32Serial::STM32Serial(int id, int baudrate, GpioPin tx, GpioPin rx,
-    miosix::GpioPin rts, miosix::GpioPin cts)
-    : Device(Device::TTY), rxQueue(rxQueueMin+baudrate/500),
-      flowControl(true), portId(id)
-{
-    commonInit(id,baudrate,tx,rx,rts,cts);
-}
-
-void STM32Serial::commonInit(int id, int baudrate, GpioPin tx, GpioPin rx,
-                             GpioPin rts, GpioPin cts)
-{
-    #ifdef SERIAL_DMA
-    dmaTx=0;
-    dmaRx=0;
-    txWaiting=0;
-    dmaTxInProgress=false;
-    #endif //SERIAL_DMA
-    InterruptDisableLock dLock;
-    if(id<1|| id>numPorts || ports[id-1]!=0) errorHandler(UNEXPECTED);
-    ports[id-1]=this;
-    unsigned int freq=SystemCoreClock;
-    switch(id)
-    {
-        case 1:
-            port=USART1;
-            RCC->APB2ENR |= RCC_APB2ENR_USART1EN;
-            RCC_SYNC();
-            #ifdef SERIAL_1_DMA
-            #if defined(_ARCH_CORTEXM3_STM32F1) || defined(_ARCH_CORTEXM4_STM32F3) \
-             || defined(_ARCH_CORTEXM4_STM32L4)
-            #ifdef _ARCH_CORTEXM4_STM32L4
-            RCC->AHB1ENR |= RCC_AHBENR_DMA1EN;
-            DMA1_CSELR->CSELR  |= (2 << DMA_CSELR_C4S_Pos) // Assign DMA1_CH4 to USART1_TX
-                               |  (2 << DMA_CSELR_C5S_Pos);// Assign DMA1_CH5 to USART1_RX
-            #else 
-            RCC->AHBENR |= RCC_AHBENR_DMA1EN;
-            #endif
-            RCC_SYNC();
-            NVIC_SetPriority(DMA1_Channel4_IRQn,15);//Lowest priority for serial
-            NVIC_EnableIRQ(DMA1_Channel4_IRQn);
-            dmaTx=DMA1_Channel4;
-            //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);
-            dmaRx=DMA1_Channel5;
-            #elif defined(_ARCH_CORTEXM7_STM32H7) 
-            RCC->AHB1ENR |= RCC_AHB1ENR_DMA1EN; // enabling DMA1 clock
-            RCC_SYNC();
-            // enabling interrupts
-            dmaRx=DMA1_Stream5;
-            NVIC_EnableIRQ(DMA1_Stream5_IRQn);
-            NVIC_SetPriority(DMA1_Stream5_IRQn,14);
-            dmaTx=DMA1_Stream7;
-            NVIC_EnableIRQ(DMA1_Stream7_IRQn);
-            NVIC_SetPriority(DMA1_Stream7_IRQn,15);
-            // Configuring DMAMUX            
-            DMAMUX1_Channel5->CCR &= ~DMAMUX_CxCR_DMAREQ_ID;
-            DMAMUX1_Channel5->CCR |= DMAMUX_CxCR_DMAREQ_ID_0
-                                   | DMAMUX_CxCR_DMAREQ_ID_3
-                                   | DMAMUX_CxCR_DMAREQ_ID_5;
-            DMAMUX1_Channel7->CCR &= ~DMAMUX_CxCR_DMAREQ_ID;
-            DMAMUX1_Channel7->CCR |= DMAMUX_CxCR_DMAREQ_ID_1
-                                   | DMAMUX_CxCR_DMAREQ_ID_3
-                                   | DMAMUX_CxCR_DMAREQ_ID_5;
-            #else //stm32f2, stm32f4
-            RCC->AHB1ENR |= RCC_AHB1ENR_DMA2EN;
-            RCC_SYNC();
-            NVIC_SetPriority(DMA2_Stream7_IRQn,15);//Lowest priority for serial
-            NVIC_EnableIRQ(DMA2_Stream7_IRQn);
-            dmaTx=DMA2_Stream7;
-            //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);
-            dmaRx=DMA2_Stream5;
-            #endif
-            port->CR3=USART_CR3_DMAT | USART_CR3_DMAR;
-            #endif //SERIAL_1_DMA
-            NVIC_SetPriority(USART1_IRQn,15);//Lowest priority for serial
-            NVIC_EnableIRQ(USART1_IRQn);
-            #if !defined(_ARCH_CORTEXM7_STM32H7) && !defined(_ARCH_CORTEXM0_STM32F0)
-            if(RCC->CFGR & RCC_CFGR_PPRE2_2) freq/=1<<(((RCC->CFGR>>RCC_CFGR_PPRE2_Pos) & 0x3)+1);
-            #elif defined(_ARCH_CORTEXM0_STM32F0)
-            // STM32F0 family has only PPRE2 register
-            if(RCC->CFGR & RCC_CFGR_PPRE_2) freq/=1<<(((RCC->CFGR>>RCC_CFGR_PPRE_Pos) & 0x3)+1);
-            #else
-            //rcc_hclk3 = SystemCoreClock / HPRE
-            //rcc_pclk2 = rcc_hclk1 / D2PPRE2
-            //NOTE: are rcc_hclk3 and rcc_hclk1 the same signal?
-            //usart1 clock is rcc_pclk2
-            if(RCC->D1CFGR & RCC_D1CFGR_HPRE_3)
-                freq/=1<<(((RCC->D1CFGR>>RCC_D1CFGR_HPRE_Pos) & 0x7)+1);
-            if(RCC->D2CFGR & RCC_D2CFGR_D2PPRE2_2)
-                freq/=1<<(((RCC->D2CFGR>>RCC_D2CFGR_D2PPRE2_Pos) & 0x3)+1);
-            #endif //_ARCH_CORTEXM7_STM32H7
-            break;
-        
-        #if !defined(STM32_NO_SERIAL_2_3)
-        case 2:
-            port=USART2;
-            #ifndef _ARCH_CORTEXM7_STM32H7
-            #ifndef _ARCH_CORTEXM4_STM32L4
-            RCC->APB1ENR |= RCC_APB1ENR_USART2EN;
-            #else  //_ARCH_CORTEXM4_STM32L4
-            RCC->APB1ENR1 |= RCC_APB1ENR1_USART2EN;
-            #endif //_ARCH_CORTEXM4_STM32L4
-            #else  //_ARCH_CORTEXM7_STM32H7
-            RCC->APB1LENR |= RCC_APB1LENR_USART2EN;
-            #endif //_ARCH_CORTEXM7_STM32H7
-            RCC_SYNC();
-            #ifdef SERIAL_2_DMA
-            #if defined(_ARCH_CORTEXM3_STM32F1) || defined(_ARCH_CORTEXM4_STM32F3) \
-             || defined(_ARCH_CORTEXM4_STM32L4)
-            #ifdef _ARCH_CORTEXM4_STM32L4
-            RCC->AHB1ENR |= RCC_AHB1ENR_DMA1EN;
-            DMA1_CSELR->CSELR  |= (2 << DMA_CSELR_C7S_Pos) // Assign DMA1_CH7 to USART2_TX
-                               |  (2 << DMA_CSELR_C6S_Pos);// Assign DMA1_CH6 to USART2_RX
-            #else 
-            RCC->AHBENR |= RCC_AHBENR_DMA1EN;
-            #endif
-            RCC_SYNC();
-            NVIC_SetPriority(DMA1_Channel7_IRQn,15);//Lowest priority for serial
-            NVIC_EnableIRQ(DMA1_Channel7_IRQn);
-            dmaTx=DMA1_Channel7;
-            //Higher priority to ensure IRQhandleDMArx() is called before
-            //IRQhandleInterrupt(), so that idle is set correctly
-            NVIC_SetPriority(DMA1_Channel6_IRQn,14);
-            NVIC_EnableIRQ(DMA1_Channel6_IRQn);
-            dmaRx=DMA1_Channel6;
-            #elif defined(_ARCH_CORTEXM7_STM32H7) 
-            RCC->AHB1ENR |= RCC_AHB1ENR_DMA1EN; // enabling DMA1 clock
-            RCC_SYNC();
-            // enabling interrupts
-            dmaRx=DMA1_Stream4;
-            NVIC_EnableIRQ(DMA1_Stream4_IRQn);
-            NVIC_SetPriority(DMA1_Stream4_IRQn,14);
-            dmaTx=DMA1_Stream6;
-            NVIC_EnableIRQ(DMA1_Stream6_IRQn);
-            NVIC_SetPriority(DMA1_Stream6_IRQn,15);
-            // Configuring DMAMUX            
-            DMAMUX1_Channel4->CCR &= ~DMAMUX_CxCR_DMAREQ_ID;
-            DMAMUX1_Channel4->CCR |= DMAMUX_CxCR_DMAREQ_ID_0
-                                   | DMAMUX_CxCR_DMAREQ_ID_1
-                                   | DMAMUX_CxCR_DMAREQ_ID_3
-                                   | DMAMUX_CxCR_DMAREQ_ID_5;
-            DMAMUX1_Channel6->CCR &= ~DMAMUX_CxCR_DMAREQ_ID;
-            DMAMUX1_Channel6->CCR |= DMAMUX_CxCR_DMAREQ_ID_2
-                                   | DMAMUX_CxCR_DMAREQ_ID_3
-                                   | DMAMUX_CxCR_DMAREQ_ID_5;
-            #else //stm32f2, stm32f4
-            RCC->AHB1ENR |= RCC_AHB1ENR_DMA1EN;
-            RCC_SYNC();
-            NVIC_SetPriority(DMA1_Stream6_IRQn,15);//Lowest priority for serial
-            NVIC_EnableIRQ(DMA1_Stream6_IRQn);
-            dmaTx=DMA1_Stream6;
-            //Higher priority to ensure IRQhandleDMArx() is called before
-            //IRQhandleInterrupt(), so that idle is set correctly
-            NVIC_SetPriority(DMA1_Stream5_IRQn,14);
-            NVIC_EnableIRQ(DMA1_Stream5_IRQn);
-            dmaRx=DMA1_Stream5;
-            #endif
-            port->CR3=USART_CR3_DMAT | USART_CR3_DMAR;
-            #endif //SERIAL_2_DMA
-            NVIC_SetPriority(USART2_IRQn,15);//Lowest priority for serial
-            NVIC_EnableIRQ(USART2_IRQn);
-            #if !defined(_ARCH_CORTEXM7_STM32H7) && !defined(_ARCH_CORTEXM0_STM32F0)
-            if(RCC->CFGR & RCC_CFGR_PPRE1_2) freq/=1<<(((RCC->CFGR>>RCC_CFGR_PPRE1_Pos) & 0x3)+1);
-            #elif defined(_ARCH_CORTEXM0_STM32F0)
-            // STM32F0 family has only PPRE2 register
-            if(RCC->CFGR & RCC_CFGR_PPRE_2) freq/=1<<(((RCC->CFGR>>RCC_CFGR_PPRE_Pos) & 0x3)+1);
-            #else //_ARCH_CORTEXM7_STM32H7
-            //rcc_hclk3 = SystemCoreClock / HPRE
-            //rcc_pclk1 = rcc_hclk1 / D2PPRE1
-            //NOTE: are rcc_hclk3 and rcc_hclk1 the same signal?
-            //usart2 clock is rcc_pclk1
-            if(RCC->D1CFGR & RCC_D1CFGR_HPRE_3)
-                freq/=1<<(((RCC->D1CFGR>>RCC_D1CFGR_HPRE_Pos) & 0x7)+1);
-            if(RCC->D2CFGR & RCC_D2CFGR_D2PPRE1_2)
-                freq/=1<<(((RCC->D2CFGR>>RCC_D2CFGR_D2PPRE1_Pos) & 0x3)+1);
-            #endif //_ARCH_CORTEXM7_STM32H7
-            break;
-        #if !defined(STM32F411xE) && !defined(STM32F401xE) && !defined(STM32F401xC) && !defined(STM32L053xx)
-        case 3:
-            port=USART3;
-            #ifndef _ARCH_CORTEXM7_STM32H7
-            #ifndef _ARCH_CORTEXM4_STM32L4
-            RCC->APB1ENR |= RCC_APB1ENR_USART3EN;
-            #else  //_ARCH_CORTEXM4_STM32L4
-            RCC->APB1ENR1 |= RCC_APB1ENR1_USART3EN;
-            #endif //_ARCH_CORTEXM4_STM32L4
-            #else
-            RCC->APB1LENR |= RCC_APB1LENR_USART3EN;
-            #endif //_ARCH_CORTEXM7_STM32H7
-            RCC_SYNC();
-            #ifdef SERIAL_3_DMA
-            #if defined(_ARCH_CORTEXM3_STM32F1) || defined(_ARCH_CORTEXM4_STM32F3) \
-             || defined(_ARCH_CORTEXM4_STM32L4)
-            #ifdef _ARCH_CORTEXM4_STM32L4
-            RCC->AHB1ENR |= RCC_AHB1ENR_DMA1EN;
-            DMA1_CSELR->CSELR  |= (2 << DMA_CSELR_C2S_Pos) // Assign DMA1_CH2 to USART2_TX
-                               |  (2 << DMA_CSELR_C3S_Pos);// Assign DMA1_CH3 to USART2_RX
-            #else 
-            RCC->AHBENR |= RCC_AHBENR_DMA1EN;
-            #endif
-            RCC_SYNC();
-            NVIC_SetPriority(DMA1_Channel2_IRQn,15);//Lowest priority for serial
-            NVIC_EnableIRQ(DMA1_Channel2_IRQn);
-            dmaTx=DMA1_Channel2;
-            //Higher priority to ensure IRQhandleDMArx() is called before
-            //IRQhandleInterrupt(), so that idle is set correctly
-            NVIC_SetPriority(DMA1_Channel3_IRQn,14);
-            NVIC_EnableIRQ(DMA1_Channel3_IRQn);
-            dmaRx=DMA1_Channel3;
-            #elif defined(_ARCH_CORTEXM7_STM32H7) 
-            RCC->AHB1ENR |= RCC_AHB1ENR_DMA1EN; // enabling DMA1 clock
-            RCC_SYNC();
-            // enabling interrupts
-            dmaRx=DMA1_Stream1;
-            NVIC_EnableIRQ(DMA1_Stream1_IRQn);
-            NVIC_SetPriority(DMA1_Stream1_IRQn,14);
-            dmaTx=DMA1_Stream3;
-            NVIC_EnableIRQ(DMA1_Stream3_IRQn);
-            NVIC_SetPriority(DMA1_Stream3_IRQn,15);
-            // Configuring DMAMUX            
-            DMAMUX1_Channel1->CCR &= ~DMAMUX_CxCR_DMAREQ_ID;
-            DMAMUX1_Channel1->CCR |= DMAMUX_CxCR_DMAREQ_ID_0
-                                   | DMAMUX_CxCR_DMAREQ_ID_2
-                                   | DMAMUX_CxCR_DMAREQ_ID_3
-                                   | DMAMUX_CxCR_DMAREQ_ID_5;
-            DMAMUX1_Channel3->CCR &= ~DMAMUX_CxCR_DMAREQ_ID;
-            DMAMUX1_Channel3->CCR |= DMAMUX_CxCR_DMAREQ_ID_1
-                                   | DMAMUX_CxCR_DMAREQ_ID_2
-                                   | DMAMUX_CxCR_DMAREQ_ID_3
-                                   | DMAMUX_CxCR_DMAREQ_ID_5;
-            #else //stm32f2, stm32f4
-            RCC->AHB1ENR |= RCC_AHB1ENR_DMA1EN;
-            RCC_SYNC();
-            NVIC_SetPriority(DMA1_Stream3_IRQn,15);//Lowest priority for serial
-            NVIC_EnableIRQ(DMA1_Stream3_IRQn);
-            dmaTx=DMA1_Stream3;
-            //Higher priority to ensure IRQhandleDMArx() is called before
-            //IRQhandleInterrupt(), so that idle is set correctly
-            NVIC_SetPriority(DMA1_Stream1_IRQn,14);
-            NVIC_EnableIRQ(DMA1_Stream1_IRQn);
-            dmaRx=DMA1_Stream1;
-            #endif
-            port->CR3=USART_CR3_DMAT | USART_CR3_DMAR;
-            #endif //SERIAL_3_DMA
-            #if !defined(STM32F072xB) && !defined(STM32L053xx)
-            NVIC_SetPriority(USART3_IRQn,15);//Lowest priority for serial
-            NVIC_EnableIRQ(USART3_IRQn);
-            #else  //STM32F072xB
-            NVIC_SetPriority(USART3_4_IRQn,15);
-            NVIC_EnableIRQ(USART3_4_IRQn);
-            #endif //STM32F072xB
-            #if !defined(_ARCH_CORTEXM7_STM32H7) && !defined(_ARCH_CORTEXM0_STM32F0)
-            if(RCC->CFGR & RCC_CFGR_PPRE1_2) freq/=1<<(((RCC->CFGR>>RCC_CFGR_PPRE1_Pos) & 0x3)+1);
-            #elif defined(_ARCH_CORTEXM0_STM32F0)
-            // STM32F0 family has only PPRE2 register
-            if(RCC->CFGR & RCC_CFGR_PPRE_2) freq/=1<<(((RCC->CFGR>>RCC_CFGR_PPRE_Pos) & 0x3)+1);
-            #else //_ARCH_CORTEXM7_STM32H7
-            //rcc_hclk3 = SystemCoreClock / HPRE
-            //rcc_pclk1 = rcc_hclk1 / D2PPRE1
-            //NOTE: are rcc_hclk3 and rcc_hclk1 the same signal?
-            //usart2 clock is rcc_pclk1
-            if(RCC->D1CFGR & RCC_D1CFGR_HPRE_3)
-                freq/=1<<(((RCC->D1CFGR>>RCC_D1CFGR_HPRE_Pos) & 0x7)+1);
-            if(RCC->D2CFGR & RCC_D2CFGR_D2PPRE1_2)
-                freq/=1<<(((RCC->D2CFGR>>RCC_D2CFGR_D2PPRE1_Pos) & 0x3)+1);
-            #endif //_ARCH_CORTEXM7_STM32H7
-            break;
-        #endif //!defined(STM32F411xE) && !defined(STM32F401xE) && !defined(STM32F401xC)
-        #endif //!defined(STM32_NO_SERIAL_2_3)
-    }
-    //Quirk: stm32f1 rx pin has to be in input mode, while stm32f2 and up want
-    //it in ALTERNATE mode. Go figure...
-    #ifdef _ARCH_CORTEXM3_STM32F1
-    Mode::Mode_ rxPinMode=Mode::INPUT;
-    #else //_ARCH_CORTEXM3_STM32F1
-    Mode::Mode_ rxPinMode=Mode::ALTERNATE;
-    #endif //_ARCH_CORTEXM3_STM32F1
-    tx.mode(Mode::ALTERNATE);
-    rx.mode(rxPinMode);
-    if(flowControl)
-    {
-        rts.mode(Mode::ALTERNATE);
-        cts.mode(rxPinMode);
-    }
-    const unsigned int quot=2*freq/baudrate; //2*freq for round to nearest
-    port->BRR=quot/2 + (quot & 1);           //Round to nearest
-    //Quirk: some stm32 do not have onebit mode (stm32f101,f102,f103)
-    #ifdef USART_CR3_ONEBIT
-    if(flowControl==false) port->CR3 |= USART_CR3_ONEBIT;
-    else port->CR3 |= USART_CR3_ONEBIT | USART_CR3_RTSE | USART_CR3_CTSE;
-    #else
-    if(flowControl) port->CR3 |= USART_CR3_RTSE | USART_CR3_CTSE;
-    #endif
-    //Enabled, 8 data bit, no parity, interrupt on character rx
-    #ifdef SERIAL_DMA
-    if(dmaTx)
-    {
-        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_DMA
-    port->CR1 = USART_CR1_UE     //Enable port
-              | USART_CR1_RXNEIE //Interrupt on data received
-              | USART_CR1_IDLEIE //Interrupt on idle line
-              | USART_CR1_TE     //Transmission enbled
-              | USART_CR1_RE;    //Reception enabled
-}
-
-ssize_t STM32Serial::readBlock(void *buffer, size_t size, off_t where)
-{
-    Lock<FastMutex> l(rxMutex);
-    char *buf=reinterpret_cast<char*>(buffer);
-    size_t result=0;
-    FastInterruptDisableLock dLock;
-    DeepSleepLock dpLock;
-    for(;;)
-    {
-        //Try to get data from the queue
-        for(;result<size;result++)
-        {
-            if(rxQueue.tryGet(buf[result])==false) break;
-            //This is here just not to keep IRQ disabled for the whole loop
-            FastInterruptEnableLock eLock(dLock);
-        }
-        if(idle && result>0) break;
-        if(result==size) break;
-        //Wait for data in the queue
-        do {
-            rxWaiting=Thread::IRQgetCurrentThread();
-            Thread::IRQwait();
-            {
-                FastInterruptEnableLock eLock(dLock);
-                Thread::yield();
-            }
-        } while(rxWaiting);
-    }
-    return result;
-}
-
-ssize_t STM32Serial::writeBlock(const void *buffer, size_t size, off_t where)
-{
-    Lock<FastMutex> l(txMutex);
-    DeepSleepLock dpLock;
-    const char *buf=reinterpret_cast<const char*>(buffer);
-    #ifdef SERIAL_DMA
-    if(dmaTx)
-    {
-        size_t remaining=size;
-        if(isInCCMarea(buf)==false)
-        {
-            //Use zero copy for all but the last txBufferSize bytes, if possible
-            while(remaining>txBufferSize)
-            {
-                //DMA is limited to 64K
-                size_t transferSize=min<size_t>(remaining-txBufferSize,65535);
-                waitDmaTxCompletion();
-                writeDma(buf,transferSize);
-                buf+=transferSize;
-                remaining-=transferSize;
-            }
-        }
-        while(remaining>0)
-        {
-            size_t transferSize=min(remaining,static_cast<size_t>(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;
-            remaining-=transferSize;
-        }
-        #ifdef WITH_DEEP_SLEEP
-        //The serial driver by default can return even though the last part of
-        //the data is still being transmitted by the DMA. When using deep sleep
-        //however the DMA operation needs to be fully enclosed by a deep sleep
-        //lock to prevent the scheduler from stopping peripheral clocks.
-        waitDmaTxCompletion();
-        waitSerialTxFifoEmpty(); //TODO: optimize by doing it only when entering deep sleep
-        #endif //WITH_DEEP_SLEEP
-        return size;
-    }
-    #endif //SERIAL_DMA
-    for(size_t i=0;i<size;i++)
-    {
-        #if !defined(_ARCH_CORTEXM7_STM32F7) && !defined(_ARCH_CORTEXM7_STM32H7) \
-         && !defined(_ARCH_CORTEXM0_STM32F0) && !defined(_ARCH_CORTEXM4_STM32F3) \
-         && !defined(_ARCH_CORTEXM4_STM32L4) && !defined(_ARCH_CORTEXM0PLUS_STM32L0)
-        while((port->SR & USART_SR_TXE)==0) ;
-        port->DR=*buf++;
-        #elif defined(_ARCH_CORTEXM7_STM32H7)
-        while((port->ISR & USART_ISR_TXE_TXFNF)==0) ;
-        port->TDR=*buf++;
-        #else //_ARCH_CORTEXM7_STM32F7/H7
-        while((port->ISR & USART_ISR_TXE)==0) ;
-        port->TDR=*buf++;
-        #endif //_ARCH_CORTEXM7_STM32F7/H7
-    }
-    return size;
-}
-
-void STM32Serial::IRQwrite(const char *str)
-{
-    // We can reach here also with only kernel paused, so make sure
-    // interrupts are disabled. This is important for the DMA case
-    bool interrupts=areInterruptsEnabled();
-    if(interrupts) fastDisableInterrupts();
-    #ifdef SERIAL_DMA
-    if(dmaTx)
-    {
-        #if defined(_ARCH_CORTEXM3_STM32F1) || defined(_ARCH_CORTEXM4_STM32F3) \
-         || defined(_ARCH_CORTEXM4_STM32L4)
-        //If no DMA transfer is in progress bit EN is zero. Otherwise wait until
-        //DMA xfer ends, by waiting for the TC (or TE) interrupt flag
-        static const unsigned int irqMask[]=
-        {
-            (DMA_ISR_TCIF4 | DMA_ISR_TEIF4),
-            (DMA_ISR_TCIF7 | DMA_ISR_TEIF7),
-            (DMA_ISR_TCIF2 | DMA_ISR_TEIF2)
-        };
-        #if !defined(_ARCH_CORTEXM3_STM32L1)
-        // Workaround for ST messing up with flag definitions...
-        constexpr unsigned int DMA_CCR4_EN = DMA_CCR_EN;
-        #endif
-        while((dmaTx->CCR & DMA_CCR4_EN) && !(DMA1->ISR & irqMask[getId()-1])) ;
-        #else //_ARCH_CORTEXM3_STM32F1
-        //Wait until DMA xfer ends. EN bit is cleared by hardware on transfer end
-        while(dmaTx->CR & DMA_SxCR_EN) ;
-        #endif //_ARCH_CORTEXM3_STM32F1
-    }
-    #endif //SERIAL_DMA
-    while(*str)
-    {
-        #if !defined(_ARCH_CORTEXM7_STM32F7) && !defined(_ARCH_CORTEXM7_STM32H7) \
-         && !defined(_ARCH_CORTEXM0_STM32F0) && !defined(_ARCH_CORTEXM4_STM32F3) \
-         && !defined(_ARCH_CORTEXM4_STM32L4) && !defined(_ARCH_CORTEXM0PLUS_STM32L0)
-        while((port->SR & USART_SR_TXE)==0) ;
-        port->DR=*str++;
-        #elif defined(_ARCH_CORTEXM7_STM32H7)
-        while((port->ISR & USART_ISR_TXE_TXFNF)==0) ;
-        port->TDR=*str++;
-        #else //_ARCH_CORTEXM7_STM32F7/H7
-        while((port->ISR & USART_ISR_TXE)==0) ;
-        port->TDR=*str++;
-        #endif //_ARCH_CORTEXM7_STM32F7/H7
-    }
-    waitSerialTxFifoEmpty();
-    if(interrupts) fastEnableInterrupts();
-}
-
-int STM32Serial::ioctl(int cmd, void* arg)
-{
-    if(reinterpret_cast<unsigned>(arg) & 0b11) return -EFAULT; //Unaligned
-    termios *t=reinterpret_cast<termios*>(arg);
-    switch(cmd)
-    {
-        case IOCTL_SYNC:
-            waitSerialTxFifoEmpty();
-            return 0;
-        case IOCTL_TCGETATTR:
-            t->c_iflag=IGNBRK | IGNPAR;
-            t->c_oflag=0;
-            t->c_cflag=CS8 | (flowControl ? CRTSCTS : 0);
-            t->c_lflag=0;
-            return 0;
-        case IOCTL_TCSETATTR_NOW:
-        case IOCTL_TCSETATTR_DRAIN:
-        case IOCTL_TCSETATTR_FLUSH:
-            //Changing things at runtime unsupported, so do nothing, but don't
-            //return error as console_device.h implements some attribute changes
-            return 0;
-        default:
-            return -ENOTTY; //Means the operation does not apply to this descriptor
-    }
-}
-
-void STM32Serial::IRQhandleInterrupt()
-{
-    #if !defined(_ARCH_CORTEXM7_STM32F7) && !defined(_ARCH_CORTEXM7_STM32H7) \
-     && !defined(_ARCH_CORTEXM0_STM32F0)   && !defined(_ARCH_CORTEXM4_STM32F3) \
-     && !defined(_ARCH_CORTEXM4_STM32L4) && !defined(_ARCH_CORTEXM0PLUS_STM32L0)
-    unsigned int status=port->SR;
-    #elif defined(_ARCH_CORTEXM7_STM32H7)
-    unsigned int status=port->ISR;
-    constexpr unsigned int USART_SR_RXNE=USART_ISR_RXNE_RXFNE;
-    constexpr unsigned int USART_SR_IDLE=USART_ISR_IDLE;
-    constexpr unsigned int USART_SR_FE  =USART_ISR_FE;
-    #else //_ARCH_CORTEXM7_STM32F7/H7
-    unsigned int status=port->ISR;
-    constexpr unsigned int USART_SR_RXNE=USART_ISR_RXNE;
-    constexpr unsigned int USART_SR_IDLE=USART_ISR_IDLE;
-    constexpr unsigned int USART_SR_FE  =USART_ISR_FE;
-    #endif //_ARCH_CORTEXM7_STM32F7/H7
-    char c;
-    #ifdef SERIAL_DMA
-    if(dmaRx==0 && (status & USART_SR_RXNE))
-    #else //SERIAL_DMA
-    if(status & USART_SR_RXNE)
-    #endif //SERIAL_DMA
-    {
-        //Always read data, since this clears interrupt flags
-        #if !defined(_ARCH_CORTEXM7_STM32F7) && !defined(_ARCH_CORTEXM7_STM32H7) \
-         && !defined(_ARCH_CORTEXM0_STM32F0) && !defined(_ARCH_CORTEXM4_STM32F3) \
-         && !defined(_ARCH_CORTEXM4_STM32L4) && !defined(_ARCH_CORTEXM0PLUS_STM32L0)
-        c=port->DR;
-        #else //_ARCH_CORTEXM7_STM32F7/H7
-        c=port->RDR;
-        #endif //_ARCH_CORTEXM7_STM32F7/H7
-        //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)
-    {
-        #if !defined(_ARCH_CORTEXM7_STM32F7) && !defined(_ARCH_CORTEXM7_STM32H7) \
-         && !defined(_ARCH_CORTEXM0_STM32F0) && !defined(_ARCH_CORTEXM4_STM32F3) \
-         && !defined(_ARCH_CORTEXM4_STM32L4) && !defined(_ARCH_CORTEXM0PLUS_STM32L0)
-        c=port->DR; //clears interrupt flags
-        #else //_ARCH_CORTEXM7_STM32F7/H7
-        port->ICR=USART_ICR_IDLECF; //clears interrupt flags
-        #endif //_ARCH_CORTEXM7_STM32F7/H7
-        #ifdef SERIAL_DMA
-        if(dmaRx) IRQreadDma();
-        #endif //SERIAL_DMA
-        idle=true;
-    }
-    if((status & USART_SR_IDLE) || rxQueue.size()>=rxQueueMin)
-    {
-        //Enough data in buffer or idle line, awake thread
-        if(rxWaiting)
-        {
-            rxWaiting->IRQwakeup();
-            if(rxWaiting->IRQgetPriority()>
-                Thread::IRQgetCurrentThread()->IRQgetPriority())
-                    Scheduler::IRQfindNextThread();
-            rxWaiting=0;
-        }
-    }
-}
-
-#ifdef SERIAL_DMA
-void STM32Serial::IRQhandleDMAtx()
-{
-    dmaTxInProgress=false;
-    if(txWaiting==0) return;
-    txWaiting->IRQwakeup();
-    if(txWaiting->IRQgetPriority()>Thread::IRQgetCurrentThread()->IRQgetPriority())
-        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_DMA
-
-STM32Serial::~STM32Serial()
-{
-    waitSerialTxFifoEmpty();
-    {
-        InterruptDisableLock dLock;
-        port->CR1=0;
-        int id=getId();
-        ports[id-1]=0;
-        switch(id)
-        {
-            case 1:
-                #ifdef SERIAL_1_DMA
-                IRQdmaReadStop();
-                #if defined(_ARCH_CORTEXM3_STM32F1) || defined(_ARCH_CORTEXM4_STM32F3) \
-                 || defined(_ARCH_CORTEXM4_STM32L4)
-                NVIC_DisableIRQ(DMA1_Channel4_IRQn);
-                NVIC_ClearPendingIRQ(DMA1_Channel4_IRQn);
-                NVIC_DisableIRQ(DMA1_Channel5_IRQn);
-                NVIC_ClearPendingIRQ(DMA1_Channel5_IRQn);
-                #elif defined(_ARCH_CORTEXM7_STM32H7)
-                NVIC_DisableIRQ(DMA1_Stream7_IRQn);
-                NVIC_ClearPendingIRQ(DMA1_Stream7_IRQn);
-                NVIC_DisableIRQ(DMA1_Stream5_IRQn);
-                NVIC_ClearPendingIRQ(DMA1_Stream5_IRQn);
-                #else //stm32f2, stm32f4
-                NVIC_DisableIRQ(DMA2_Stream7_IRQn);
-                NVIC_ClearPendingIRQ(DMA2_Stream7_IRQn);
-                NVIC_DisableIRQ(DMA2_Stream5_IRQn);
-                NVIC_ClearPendingIRQ(DMA2_Stream5_IRQn);
-                #endif
-                #endif //SERIAL_1_DMA
-                NVIC_DisableIRQ(USART1_IRQn);
-                NVIC_ClearPendingIRQ(USART1_IRQn);
-                RCC->APB2ENR &= ~RCC_APB2ENR_USART1EN;
-                break;
-                
-            #if !defined(STM32_NO_SERIAL_2_3)    
-            case 2:
-                #ifdef SERIAL_2_DMA
-                IRQdmaReadStop();
-                #if defined(_ARCH_CORTEXM3_STM32F1) || defined(_ARCH_CORTEXM4_STM32F3) \
-                 || defined(_ARCH_CORTEXM4_STM32L4)
-                NVIC_DisableIRQ(DMA1_Channel7_IRQn);
-                NVIC_ClearPendingIRQ(DMA1_Channel7_IRQn);
-                NVIC_DisableIRQ(DMA1_Channel6_IRQn);
-                NVIC_ClearPendingIRQ(DMA1_Channel6_IRQn);
-                #else //stm32f2, stm32f4
-                NVIC_DisableIRQ(DMA1_Stream6_IRQn);
-                NVIC_ClearPendingIRQ(DMA1_Stream6_IRQn);
-                NVIC_DisableIRQ(DMA1_Stream5_IRQn);
-                NVIC_ClearPendingIRQ(DMA1_Stream5_IRQn);
-                #endif
-                #endif //SERIAL_2_DMA
-                NVIC_DisableIRQ(USART2_IRQn);
-                NVIC_ClearPendingIRQ(USART2_IRQn);
-                #ifndef _ARCH_CORTEXM7_STM32H7
-                #ifdef _ARCH_CORTEXM4_STM32L4
-                RCC->APB1ENR1 &= ~RCC_APB1ENR1_USART2EN;
-                #else
-                RCC->APB1ENR &= ~RCC_APB1ENR_USART2EN;
-                #endif
-                #else //_ARCH_CORTEXM7_STM32H7
-                RCC->APB1LENR &= ~RCC_APB1LENR_USART2EN;
-                #endif //_ARCH_CORTEXM7_STM32H7
-                break;
-            #if !defined(STM32F411xE) && !defined(STM32F401xE) && !defined(STM32F401xC) && !defined(STM32L053xx)
-            case 3:
-                #ifdef SERIAL_3_DMA
-                IRQdmaReadStop();
-                #if defined(_ARCH_CORTEXM3_STM32F1) || defined(_ARCH_CORTEXM4_STM32F3) \
-                 || defined(_ARCH_CORTEXM4_STM32L4)
-                NVIC_DisableIRQ(DMA1_Channel2_IRQn);
-                NVIC_ClearPendingIRQ(DMA1_Channel2_IRQn);
-                NVIC_DisableIRQ(DMA1_Channel3_IRQn);
-                NVIC_ClearPendingIRQ(DMA1_Channel3_IRQn);
-                #else //stm32f2, stm32f4
-                NVIC_DisableIRQ(DMA1_Stream3_IRQn);
-                NVIC_ClearPendingIRQ(DMA1_Stream3_IRQn);
-                NVIC_DisableIRQ(DMA1_Stream1_IRQn);
-                NVIC_ClearPendingIRQ(DMA1_Stream1_IRQn);
-                #endif
-                #endif //SERIAL_3_DMA
-                #if !defined(STM32F072xB)
-                NVIC_SetPriority(USART3_IRQn,15);//Lowest priority for serial
-                NVIC_EnableIRQ(USART3_IRQn);
-                #else  //STM32F072xB
-                NVIC_SetPriority(USART3_4_IRQn,15);
-                NVIC_EnableIRQ(USART3_4_IRQn);
-                #endif //STM32F072xB
-                #ifndef _ARCH_CORTEXM7_STM32H7
-                #ifdef _ARCH_CORTEXM4_STM32L4
-                RCC->APB1ENR1 &= ~RCC_APB1ENR1_USART3EN;
-                #else
-                RCC->APB1ENR &= ~RCC_APB1ENR_USART3EN;
-                #endif
-                #else //_ARCH_CORTEXM7_STM32H7
-                RCC->APB1LENR &= ~RCC_APB1LENR_USART3EN;
-                #endif //_ARCH_CORTEXM7_STM32H7
-                break;
-            #endif //!defined(STM32F411xE) && !defined(STM32F401xE) && !defined(STM32F401xC)
-            #endif //!defined(STM32_NO_SERIAL_2_3)
-        }
-    }
-}
-
-#ifdef SERIAL_DMA
-void STM32Serial::waitDmaTxCompletion()
-{
-    FastInterruptDisableLock dLock;
-    // If a previous DMA xfer is in progress, wait
-    if(dmaTxInProgress)
-    {
-        txWaiting=Thread::IRQgetCurrentThread();
-        do {
-            Thread::IRQwait();
-            {
-                FastInterruptEnableLock eLock(dLock);
-                Thread::yield();
-            }
-        } while(txWaiting);
-    }
-}
-
-void STM32Serial::writeDma(const char *buffer, size_t size)
-{
-    markBufferBeforeDmaWrite(buffer,size);
-    //Quirk: DMA messes up the TC bit, and causes waitSerialTxFifoEmpty() to
-    //return prematurely, causing characters to be missed when rebooting
-    //immediately a write. You can just clear the bit manually, but doing that
-    //is dangerous, as if you clear the bit but for any reason the serial
-    //write doesn't start (think an invalid buffer, or another thread crashing),
-    //then TC will never be set and waitSerialTxFifoEmpty() deadlocks!
-    //The only way to clear it safely is to first read SR and then write to
-    //DR (thus the bit is cleared at the same time a transmission is started,
-    //and the race condition is eliminated). This is the purpose of this
-    //instruction, it reads SR. When we start the DMA, the DMA controller
-    //writes to DR and completes the TC clear sequence.
-    DeepSleepLock dpLock;
-    #if !defined(_ARCH_CORTEXM7_STM32F7) && !defined(_ARCH_CORTEXM7_STM32H7) \
-     && !defined(_ARCH_CORTEXM0_STM32F0)   && !defined(_ARCH_CORTEXM4_STM32F3) \
-     && !defined(_ARCH_CORTEXM4_STM32L4)
-    while((port->SR & USART_SR_TXE)==0) ;
-    #elif defined(_ARCH_CORTEXM7_STM32H7)
-    while((port->ISR & USART_ISR_TXE_TXFNF)==0) ;
-    #else //_ARCH_CORTEXM7_STM32F7/H7
-    while((port->ISR & USART_ISR_TXE)==0) ;
-    #endif //_ARCH_CORTEXM7_STM32F7/H7
-    
-    dmaTxInProgress=true;
-    #if defined(_ARCH_CORTEXM3_STM32F1) || defined(_ARCH_CORTEXM4_STM32F3) || \
-        defined(_ARCH_CORTEXM4_STM32L4)
-    #if defined(_ARCH_CORTEXM3_STM32F1)
-    dmaTx->CPAR=reinterpret_cast<unsigned int>(&port->DR);
-    #else
-    dmaTx->CPAR=reinterpret_cast<unsigned int>(&port->TDR);
-    #endif
-    dmaTx->CMAR=reinterpret_cast<unsigned int>(buffer);
-    dmaTx->CNDTR=size;
-    dmaTx->CCR = DMA_CCR_MINC  //Increment RAM pointer
-               | DMA_CCR_DIR   //Memory to peripheral
-               | DMA_CCR_TEIE  //Interrupt on transfer error
-               | DMA_CCR_TCIE  //Interrupt on transfer complete
-               | DMA_CCR_EN;   //Start DMA
-    #else  //_ARCH_CORTEXM4_STM32F3
-    #if !defined(_ARCH_CORTEXM7_STM32F7) && !defined(_ARCH_CORTEXM7_STM32H7) \
-     && !defined(_ARCH_CORTEXM0_STM32F0)
-    dmaTx->PAR=reinterpret_cast<unsigned int>(&port->DR);
-    #else //_ARCH_CORTEXM7_STM32F7/H7
-    dmaTx->PAR=reinterpret_cast<unsigned int>(&port->TDR);
-    #endif //_ARCH_CORTEXM7_STM32F7/H7
-    dmaTx->M0AR=reinterpret_cast<unsigned int>(buffer);
-    dmaTx->NDTR=size;
-    //Quirk: not enabling DMA_SxFCR_FEIE because the USART seems to
-    //generate a spurious fifo error. The code was tested and the
-    //transfer completes successfully even in the presence of this fifo
-    //error
-    dmaTx->FCR=DMA_SxFCR_DMDIS;//Enable fifo
-    #ifndef _ARCH_CORTEXM7_STM32H7
-    dmaTx->CR = DMA_SxCR_CHSEL_2 //Select channel 4 (USART_TX)
-              | DMA_SxCR_MINC    //Increment RAM pointer
-              | DMA_SxCR_DIR_0   //Memory to peripheral
-              | DMA_SxCR_TCIE    //Interrupt on completion
-              | DMA_SxCR_TEIE    //Interrupt on transfer error
-              | DMA_SxCR_DMEIE   //Interrupt on direct mode error
-              | DMA_SxCR_EN;     //Start the DMA
-    #else
-    dmaTx->CR = DMA_SxCR_MINC    //Increment RAM pointer
-              | DMA_SxCR_DIR_0   //Memory to peripheral
-              | DMA_SxCR_TCIE    //Interrupt on completion
-              | DMA_SxCR_TEIE    //Interrupt on transfer error
-              | DMA_SxCR_DMEIE   //Interrupt on direct mode error
-              | DMA_SxCR_EN;     //Start the DMA
-    #endif //_ARCH_CORTEXM7_STM32H7
-    #endif //_ARCH_CORTEXM4_STM32F3
-}
-
-void STM32Serial::IRQreadDma()
-{
-    int elem=IRQdmaReadStop();
-    markBufferAfterDmaRead(rxBuffer,rxQueueMin);
-    for(int i=0;i<elem;i++)
-        if(rxQueue.tryPut(rxBuffer[i])==false) /*fifo overflow*/;
-    IRQdmaReadStart();
-}
-
-void STM32Serial::IRQdmaReadStart()
-{
-    #if defined(_ARCH_CORTEXM3_STM32F1) || defined(_ARCH_CORTEXM4_STM32F3) || \
-        defined(_ARCH_CORTEXM4_STM32L4)
-    #if defined(_ARCH_CORTEXM3_STM32F1)
-    dmaRx->CPAR=reinterpret_cast<unsigned int>(&port->DR);
-    #else
-    dmaRx->CPAR=reinterpret_cast<unsigned int>(&port->RDR);
-    #endif
-    dmaRx->CMAR=reinterpret_cast<unsigned int>(rxBuffer);
-    dmaRx->CNDTR=rxQueueMin;
-    dmaRx->CCR = DMA_CCR_MINC  //Increment RAM pointer
-               | 0              //Peripheral to memory
-               | DMA_CCR_TEIE  //Interrupt on transfer error
-               | DMA_CCR_TCIE  //Interrupt on transfer complete
-               | DMA_CCR_EN;   //Start DMA
-    #else //_ARCH_CORTEXM4_STM32F3
-    #if !defined(_ARCH_CORTEXM7_STM32F7) && !defined(_ARCH_CORTEXM7_STM32H7) \
-     && !defined(_ARCH_CORTEXM0_STM32F0)
-    dmaRx->PAR=reinterpret_cast<unsigned int>(&port->DR);
-    #else //_ARCH_CORTEXM7_STM32F7/H7
-    dmaRx->PAR=reinterpret_cast<unsigned int>(&port->RDR);
-    #endif //_ARCH_CORTEXM7_STM32F7/H7
-    dmaRx->M0AR=reinterpret_cast<unsigned int>(rxBuffer);
-    dmaRx->NDTR=rxQueueMin;
-    #ifndef _ARCH_CORTEXM7_STM32H7
-    dmaRx->CR = DMA_SxCR_CHSEL_2 //Select channel 2 (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
-    #else
-    dmaRx->CR = 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_CORTEXM7_STM32H7
-    #endif //_ARCH_CORTEXM4_STM32F3
-}
-
-int STM32Serial::IRQdmaReadStop()
-{
-    #if defined(_ARCH_CORTEXM3_STM32F1) || defined(_ARCH_CORTEXM4_STM32F3) \
-     || defined(_ARCH_CORTEXM4_STM32L4) 
-    dmaRx->CCR=0;
-    static const unsigned int irqMask[]=
-    {
-        DMA_IFCR_CGIF5,
-        DMA_IFCR_CGIF6,
-        DMA_IFCR_CGIF3   
-    };
-    DMA1->IFCR=irqMask[getId()-1];
-    return rxQueueMin-dmaRx->CNDTR;
-    #else //_ARCH_CORTEXM3_STM32F1
-    //Stop DMA and wait for it to actually stop
-    dmaRx->CR &= ~DMA_SxCR_EN;
-    while(dmaRx->CR & DMA_SxCR_EN) ;
-
-
-    #ifdef _ARCH_CORTEXM7_STM32H7
-    static const unsigned int irqMask[]=
-    {
-        (DMA_HIFCR_CTCIF5 | DMA_HIFCR_CHTIF5 | DMA_HIFCR_CTEIF5 | DMA_HIFCR_CDMEIF5 | DMA_HIFCR_CFEIF5),
-        (DMA_HIFCR_CTCIF4 | DMA_HIFCR_CHTIF4 | DMA_HIFCR_CTEIF4 | DMA_HIFCR_CDMEIF4 | DMA_HIFCR_CFEIF4),
-        (DMA_LIFCR_CTCIF1 | DMA_LIFCR_CHTIF1 | DMA_LIFCR_CTEIF1 | DMA_LIFCR_CDMEIF1 | DMA_LIFCR_CFEIF1)
-    };
-    #else
-    static const unsigned int irqMask[]=
-    {
-        (DMA_HIFCR_CTCIF5 | DMA_HIFCR_CHTIF5 | DMA_HIFCR_CTEIF5 | DMA_HIFCR_CDMEIF5 | DMA_HIFCR_CFEIF5),
-        (DMA_HIFCR_CTCIF5 | DMA_HIFCR_CHTIF5 | DMA_HIFCR_CTEIF5 | DMA_HIFCR_CDMEIF5 | DMA_HIFCR_CFEIF5),
-        (DMA_LIFCR_CTCIF1 | DMA_LIFCR_CHTIF1 | DMA_LIFCR_CTEIF1 | DMA_LIFCR_CDMEIF1 | DMA_LIFCR_CFEIF1)
-    };
-    #endif
-
-    #ifdef _ARCH_CORTEXM7_STM32H7
-    static volatile unsigned long * const irqRegs[]=
-    {
-        &DMA1->HIFCR,
-        &DMA1->HIFCR,
-        &DMA1->LIFCR
-    };
-    #else
-    static volatile unsigned long * const irqRegs[]=
-    {
-        &DMA2->HIFCR,
-        &DMA1->HIFCR,
-        &DMA1->LIFCR
-    };
-    #endif
-    *irqRegs[getId()-1]=irqMask[getId()-1];
-    return rxQueueMin-dmaRx->NDTR;
-    #endif //_ARCH_CORTEXM3_STM32F1
-}
-#endif //SERIAL_DMA
-
-} //namespace miosix
diff --git a/miosix/arch/common/drivers/serial_stm32.h b/miosix/arch/common/drivers/serial_stm32.h
deleted file mode 100644
index 9b2ab44b15874f4245c7b63edd28a0e50c9ee121..0000000000000000000000000000000000000000
--- a/miosix/arch/common/drivers/serial_stm32.h
+++ /dev/null
@@ -1,296 +0,0 @@
-/***************************************************************************
- *   Copyright (C) 2010-2018 by Terraneo Federico                          *
- *                                                                         *
- *   This program is free software; you can redistribute it and/or modify  *
- *   it under the terms of the GNU General Public License as published by  *
- *   the Free Software Foundation; either version 2 of the License, or     *
- *   (at your option) any later version.                                   *
- *                                                                         *
- *   This program is distributed in the hope that it will be useful,       *
- *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
- *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
- *   GNU General Public License for more details.                          *
- *                                                                         *
- *   As a special exception, if other files instantiate templates or use   *
- *   macros or inline functions from this file, or you compile this file   *
- *   and link it with other works to produce a work based on this file,    *
- *   this file does not by itself cause the resulting work to be covered   *
- *   by the GNU General Public License. However the source code for this   *
- *   file must still be made available in accordance with the GNU General  *
- *   Public License. This exception does not invalidate any other reasons  *
- *   why a work based on this file might be covered by the GNU General     *
- *   Public License.                                                       *
- *                                                                         *
- *   You should have received a copy of the GNU General Public License     *
- *   along with this program; if not, see <http://www.gnu.org/licenses/>   *
- ***************************************************************************/ 
-
-#ifndef SERIAL_STM32_H
-#define	SERIAL_STM32_H
-
-#include "filesystem/console/console_device.h"
-#include "kernel/sync.h"
-#include "kernel/queue.h"
-#include "interfaces/gpio.h"
-#include "board_settings.h"
-
-#if defined(_ARCH_CORTEXM3_STM32F1) && defined(__ENABLE_XRAM)
-//Quirk: concurrent access to the FSMC from both core and DMA is broken in
-//the stm32f1, so disable DMA mode if XRAM is enabled.
-#undef SERIAL_1_DMA
-#undef SERIAL_2_DMA
-#undef SERIAL_3_DMA
-#endif
-
-#if defined(SERIAL_1_DMA) || defined(SERIAL_2_DMA) || defined(SERIAL_3_DMA)
-#define SERIAL_DMA
-#endif
-
-#if defined(SERIAL_DMA) && defined(_ARCH_CORTEXM0_STM32F0) \
-    && defined(_ARCH_CORTEXM0PLUS_STM32L0)
-#undef SERIAL_1_DMA
-#undef SERIAL_2_DMA
-#undef SERIAL_3_DMA
-#undef SERIAL_DMA
-#warning "DMA not yet implemented for STM32F0/STM32L0 family"
-#endif
-
-namespace miosix {
-
-/**
- * Serial port class for stm32 microcontrollers.
- * Only supports USART1, USART2 and USART3
- * Additionally, USARTx can use DMA if SERIAL_x_DMA is defined in
- * board_settings.h, while the other serial use polling for transmission,
- * and interrupt for reception.
- * 
- * Classes of this type are reference counted, must be allocated on the heap
- * and managed through intrusive_ref_ptr<FileBase>
- */
-class STM32Serial : public Device
-{
-public:
-    enum FlowCtrl
-    {
-        NOFLOWCTRL, ///< No hardware flow control
-        RTSCTS      ///< RTS/CTS hardware flow control
-    };
-    
-    /**
-     * Constructor, initializes the serial port using the default pins, which
-     * are:
-     * USART1: tx=PA9  rx=PA10 cts=PA11 rts=PA12
-     * USART2: tx=PA2  rx=PA3  cts=PA0  rts=PA1
-     * USART3: tx=PB10 rx=PB11 cts=PB13 rts=PB14
-     * If you board has a different mapping, use one of the other constructors.
-     * 
-     * Calls errorHandler(UNEXPECTED) if id is not in the correct range, or when
-     * attempting to construct multiple objects with the same id. That is,
-     * it is possible to instantiate only one instance of this class for each
-     * hardware USART.
-     * \param id a number 1 to 3 to select which USART
-     * \param baudrate serial port baudrate
-     * \param flowControl to enable hardware flow control on this port
-     */
-    STM32Serial(int id, int baudrate, FlowCtrl flowControl=NOFLOWCTRL);
-    
-    /**
-     * Constructor, initializes the serial port using remapped pins and disables
-     * flow control.
-     * 
-     * NOTE: for stm32f2, f4, f7 and h7 you have to set the correct alternate
-     * function to the pins in order to connect then to the USART peripheral
-     * before passing them to this class.
-     * 
-     * Calls errorHandler(UNEXPECTED) if id is not in the correct range, or when
-     * attempting to construct multiple objects with the same id. That is,
-     * it is possible to instantiate only one instance of this class for each
-     * hardware USART.
-     * \param id a number 1 to 3 to select which USART
-     * \param baudrate serial port baudrate
-     * \param tx tx pin
-     * \param rx rx pin
-     */
-    STM32Serial(int id, int baudrate, miosix::GpioPin tx, miosix::GpioPin rx);
-    
-    /**
-     * Constructor, initializes the serial port using remapped pins and enables
-     * flow control.
-     * 
-     * NOTE: for stm32f2, f4, f7 and h7 you have to set the correct alternate
-     * function to the pins in order to connect then to the USART peripheral
-     * before passing them to this class.
-     * 
-     * Calls errorHandler(UNEXPECTED) if id is not in the correct range, or when
-     * attempting to construct multiple objects with the same id. That is,
-     * it is possible to instantiate only one instance of this class for each
-     * hardware USART.
-     * \param id a number 1 to 3 to select which USART
-     * \param tx tx pin
-     * \param rx rx pin
-     * \param rts rts pin
-     * \param cts cts pin
-     */
-    STM32Serial(int id, int baudrate, miosix::GpioPin tx, miosix::GpioPin rx,
-                miosix::GpioPin rts, miosix::GpioPin cts);
-    
-    /**
-     * Read a block of data
-     * \param buffer buffer where read data will be stored
-     * \param size buffer size
-     * \param where where to read from
-     * \return number of bytes read or a negative number on failure. Note that
-     * it is normal for this function to return less character than the amount
-     * asked
-     */
-    ssize_t readBlock(void *buffer, size_t size, off_t where);
-    
-    /**
-     * Write a block of data
-     * \param buffer buffer where take data to write
-     * \param size buffer size
-     * \param where where to write to
-     * \return number of bytes written or a negative number on failure
-     */
-    ssize_t writeBlock(const void *buffer, size_t size, off_t where);
-    
-    /**
-     * Write a string.
-     * An extension to the Device interface that adds a new member function,
-     * which is used by the kernel on console devices to write debug information
-     * before the kernel is started or in case of serious errors, right before
-     * rebooting.
-     * Can ONLY be called when the kernel is not yet started, paused or within
-     * an interrupt. This default implementation ignores writes.
-     * \param str the string to write. The string must be NUL terminated.
-     */
-    void IRQwrite(const char *str);
-    
-    /**
-     * Performs device-specific operations
-     * \param cmd specifies the operation to perform
-     * \param arg optional argument that some operation require
-     * \return the exact return value depends on CMD, -1 is returned on error
-     */
-    int ioctl(int cmd, void *arg);
-    
-    /**
-     * \internal the serial port interrupts call this member function.
-     * Never call this from user code.
-     */
-    void IRQhandleInterrupt();
-    
-    #ifdef SERIAL_DMA
-    /**
-     * \internal the serial port DMA tx interrupts call this member function.
-     * 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_DMA
-    
-    /**
-     * \return port id, 1 for USART1, 2 for USART2, ... 
-     */
-    int getId() const { return portId; }
-    
-    /**
-     * Destructor
-     */
-    ~STM32Serial();
-    
-private:
-    /**
-     * Code common for all constructors
-     */
-    void commonInit(int id, int baudrate, miosix::GpioPin tx, miosix::GpioPin rx,
-                    miosix::GpioPin rts, miosix::GpioPin cts);
-    
-    #ifdef SERIAL_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_DMA
-    
-    /**
-     * Wait until all characters have been written to the serial port.
-     * Needs to be callable from interrupts disabled (it is used in IRQwrite)
-     */
-    void waitSerialTxFifoEmpty()
-    {
-        #if !defined(_ARCH_CORTEXM7_STM32F7) && !defined(_ARCH_CORTEXM7_STM32H7) \
-         && !defined(_ARCH_CORTEXM0_STM32F0) && !defined(_ARCH_CORTEXM4_STM32F3) \
-         && !defined(_ARCH_CORTEXM4_STM32L4) && !defined(_ARCH_CORTEXM0PLUS_STM32L0)
-        while((port->SR & USART_SR_TC)==0) ;
-        #else //_ARCH_CORTEXM7_STM32F7/H7
-        while((port->ISR & USART_ISR_TC)==0) ;
-        #endif //_ARCH_CORTEXM7_STM32F7/H7
-    }
-
-    FastMutex txMutex;                ///< Mutex locked during transmission
-    FastMutex rxMutex;                ///< Mutex locked during reception
-    
-    DynUnsyncQueue<char> rxQueue;     ///< Receiving queue
-    static const unsigned int rxQueueMin=16; ///< Minimum queue size
-    Thread *rxWaiting=0;              ///< Thread waiting for rx, or 0
-    
-    USART_TypeDef *port;              ///< Pointer to USART peripheral
-    #ifdef SERIAL_DMA
-    #if defined(_ARCH_CORTEXM3_STM32F1) || defined(_ARCH_CORTEXM4_STM32F3) \
-     || defined(_ARCH_CORTEXM4_STM32L4)
-    DMA_Channel_TypeDef *dmaTx;       ///< Pointer to DMA TX peripheral
-    DMA_Channel_TypeDef *dmaRx;       ///< Pointer to DMA RX peripheral
-    #else //_ARCH_CORTEXM3_STM32F1 and _ARCH_CORTEXM4_STM32F3
-    DMA_Stream_TypeDef *dmaTx;        ///< Pointer to DMA TX peripheral
-    DMA_Stream_TypeDef *dmaRx;        ///< Pointer to DMA RX peripheral
-    #endif //_ARCH_CORTEXM3_STM32F1 and _ARCH_CORTEXM4_STM32F3
-    Thread *txWaiting;                ///< Thread waiting for tx, or 0
-    static const unsigned int txBufferSize=16; ///< Size of tx buffer, for tx speedup
-    /// Tx buffer, for tx speedup. This buffer must not end up in the CCM of the
-    /// STM32F4, as it is used to perform DMA operations. This is guaranteed by
-    /// 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_DMA
-    bool idle=true;                   ///< Receiver idle
-    const bool flowControl;           ///< True if flow control GPIOs enabled
-    const unsigned char portId;       ///< 1 for USART1, 2 for USART2, ...
-};
-
-} //namespace miosix
-
-#endif //SERIAL_STM32_H