aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--os/hal/platforms/STM32/spi_lld.c50
-rw-r--r--os/hal/platforms/STM32/spi_lld.h104
-rw-r--r--os/hal/platforms/STM32/stm32_dma.h45
-rw-r--r--os/hal/platforms/STM32/uart_lld.c248
-rw-r--r--os/hal/platforms/STM32/uart_lld.h163
5 files changed, 521 insertions, 89 deletions
diff --git a/os/hal/platforms/STM32/spi_lld.c b/os/hal/platforms/STM32/spi_lld.c
index 0dc47a81e..9c00b561a 100644
--- a/os/hal/platforms/STM32/spi_lld.c
+++ b/os/hal/platforms/STM32/spi_lld.c
@@ -18,8 +18,9 @@
*/
/**
- * @file STM32/spi_lld.c
- * @brief STM32 SPI subsystem low level driver source.
+ * @file STM32/spi_lld.c
+ * @brief STM32 SPI subsystem low level driver source.
+ *
* @addtogroup STM32_SPI
* @{
*/
@@ -113,7 +114,7 @@ static void spi_start_wait(SPIDriver *spip, size_t n,
#if USE_STM32_SPI1 || defined(__DOXYGEN__)
/**
- * @brief SPI1 RX DMA interrupt handler (channel 2).
+ * @brief SPI1 RX DMA interrupt handler (channel 2).
*/
CH_IRQ_HANDLER(Vector70) {
@@ -130,7 +131,7 @@ CH_IRQ_HANDLER(Vector70) {
}
/**
- * @brief SPI1 TX DMA interrupt handler (channel 3).
+ * @brief SPI1 TX DMA interrupt handler (channel 3).
*/
CH_IRQ_HANDLER(Vector74) {
@@ -146,7 +147,7 @@ CH_IRQ_HANDLER(Vector74) {
#if USE_STM32_SPI2 || defined(__DOXYGEN__)
/**
- * @brief SPI2 RX DMA interrupt handler (channel 4).
+ * @brief SPI2 RX DMA interrupt handler (channel 4).
*/
CH_IRQ_HANDLER(Vector78) {
@@ -163,7 +164,7 @@ CH_IRQ_HANDLER(Vector78) {
}
/**
- * @brief SPI2 TX DMA interrupt handler (channel 5).
+ * @brief SPI2 TX DMA interrupt handler (channel 5).
*/
CH_IRQ_HANDLER(Vector7C) {
@@ -179,7 +180,7 @@ CH_IRQ_HANDLER(Vector7C) {
#if USE_STM32_SPI3 || defined(__DOXYGEN__)
/**
- * @brief SPI3 RX DMA interrupt handler (DMA2, channel 1).
+ * @brief SPI3 RX DMA interrupt handler (DMA2, channel 1).
*/
CH_IRQ_HANDLER(Vector120) {
@@ -196,7 +197,7 @@ CH_IRQ_HANDLER(Vector120) {
}
/**
- * @brief SPI3 TX DMA2 interrupt handler (DMA2, channel 2).
+ * @brief SPI3 TX DMA2 interrupt handler (DMA2, channel 2).
*/
CH_IRQ_HANDLER(Vector124) {
@@ -215,7 +216,7 @@ CH_IRQ_HANDLER(Vector124) {
/*===========================================================================*/
/**
- * @brief Low level SPI driver initialization.
+ * @brief Low level SPI driver initialization.
*/
void spi_lld_init(void) {
@@ -256,7 +257,7 @@ void spi_lld_init(void) {
}
/**
- * @brief Configures and activates the SPI peripheral.
+ * @brief Configures and activates the SPI peripheral.
*
* @param[in] spip pointer to the @p SPIDriver object
*/
@@ -306,7 +307,7 @@ void spi_lld_start(SPIDriver *spip) {
}
/**
- * @brief Deactivates the SPI peripheral.
+ * @brief Deactivates the SPI peripheral.
*
* @param[in] spip pointer to the @p SPIDriver object
*/
@@ -342,7 +343,7 @@ void spi_lld_stop(SPIDriver *spip) {
}
/**
- * @brief Asserts the slave select signal and prepares for transfers.
+ * @brief Asserts the slave select signal and prepares for transfers.
*
* @param[in] spip pointer to the @p SPIDriver object
*/
@@ -352,7 +353,7 @@ void spi_lld_select(SPIDriver *spip) {
}
/**
- * @brief Deasserts the slave select signal.
+ * @brief Deasserts the slave select signal.
* @details The previously selected peripheral is unselected.
*
* @param[in] spip pointer to the @p SPIDriver object
@@ -363,7 +364,7 @@ void spi_lld_unselect(SPIDriver *spip) {
}
/**
- * @brief Ignores data on the SPI bus.
+ * @brief Ignores data on the SPI bus.
* @details This function transmits a series of idle words on the SPI bus and
* ignores the received data. This function can be invoked even
* when a slave select signal has not been yet asserted.
@@ -379,16 +380,15 @@ void spi_lld_ignore(SPIDriver *spip, size_t n) {
}
/**
- * @brief Exchanges data on the SPI bus.
+ * @brief Exchanges data on the SPI bus.
* @details This function performs a simultaneous transmit/receive operation.
+ * @note The buffers are organized as uint8_t arrays for data sizes below or
+ * equal to 8 bits else it is organized as uint16_t arrays.
*
* @param[in] spip pointer to the @p SPIDriver object
* @param[in] n number of words to be exchanged
* @param[in] txbuf the pointer to the transmit buffer
* @param[out] rxbuf the pointer to the receive buffer
- *
- * @note The buffers are organized as uint8_t arrays for data sizes below or
- * equal to 8 bits else it is organized as uint16_t arrays.
*/
void spi_lld_exchange(SPIDriver *spip, size_t n,
const void *txbuf, void *rxbuf) {
@@ -399,14 +399,13 @@ void spi_lld_exchange(SPIDriver *spip, size_t n,
}
/**
- * @brief Sends data ever the SPI bus.
+ * @brief Sends data ever the SPI bus.
+ * @note The buffers are organized as uint8_t arrays for data sizes below or
+ * equal to 8 bits else it is organized as uint16_t arrays.
*
* @param[in] spip pointer to the @p SPIDriver object
* @param[in] n number of words to send
* @param[in] txbuf the pointer to the transmit buffer
- *
- * @note The buffers are organized as uint8_t arrays for data sizes below or
- * equal to 8 bits else it is organized as uint16_t arrays.
*/
void spi_lld_send(SPIDriver *spip, size_t n, const void *txbuf) {
@@ -416,14 +415,13 @@ void spi_lld_send(SPIDriver *spip, size_t n, const void *txbuf) {
}
/**
- * @brief Receives data from the SPI bus.
+ * @brief Receives data from the SPI bus.
+ * @note The buffers are organized as uint8_t arrays for data sizes below or
+ * equal to 8 bits else it is organized as uint16_t arrays.
*
* @param[in] spip pointer to the @p SPIDriver object
* @param[in] n number of words to receive
* @param[out] rxbuf the pointer to the receive buffer
- *
- * @note The buffers are organized as uint8_t arrays for data sizes below or
- * equal to 8 bits else it is organized as uint16_t arrays.
*/
void spi_lld_receive(SPIDriver *spip, size_t n, void *rxbuf) {
diff --git a/os/hal/platforms/STM32/spi_lld.h b/os/hal/platforms/STM32/spi_lld.h
index 4b44a2750..b93497e41 100644
--- a/os/hal/platforms/STM32/spi_lld.h
+++ b/os/hal/platforms/STM32/spi_lld.h
@@ -39,105 +39,105 @@
/*===========================================================================*/
/**
- * @brief SPI1 driver enable switch.
+ * @brief SPI1 driver enable switch.
* @details If set to @p TRUE the support for SPI1 is included.
- * @note The default is @p TRUE.
+ * @note The default is @p TRUE.
*/
#if !defined(USE_STM32_SPI1) || defined(__DOXYGEN__)
#define USE_STM32_SPI1 TRUE
#endif
/**
- * @brief SPI2 driver enable switch.
+ * @brief SPI2 driver enable switch.
* @details If set to @p TRUE the support for SPI2 is included.
- * @note The default is @p TRUE.
+ * @note The default is @p TRUE.
*/
#if !defined(USE_STM32_SPI2) || defined(__DOXYGEN__)
#define USE_STM32_SPI2 TRUE
#endif
/**
- * @brief SPI3 driver enable switch.
+ * @brief SPI3 driver enable switch.
* @details If set to @p TRUE the support for SPI3 is included.
- * @note The default is @p TRUE.
+ * @note The default is @p TRUE.
*/
#if !defined(USE_STM32_SPI3) || defined(__DOXYGEN__)
#define USE_STM32_SPI3 FALSE
#endif
/**
- * @brief SPI1 DMA priority (0..3|lowest..highest).
- * @note The priority level is used for both the TX and RX DMA channels but
- * because of the channels ordering the RX channel has always priority
- * over the TX channel.
+ * @brief SPI1 DMA priority (0..3|lowest..highest).
+ * @note The priority level is used for both the TX and RX DMA channels but
+ * because of the channels ordering the RX channel has always priority
+ * over the TX channel.
*/
#if !defined(STM32_SPI1_DMA_PRIORITY) || defined(__DOXYGEN__)
#define STM32_SPI1_DMA_PRIORITY 2
#endif
/**
- * @brief SPI2 DMA priority (0..3|lowest..highest).
- * @note The priority level is used for both the TX and RX DMA channels but
- * because of the channels ordering the RX channel has always priority
- * over the TX channel.
+ * @brief SPI2 DMA priority (0..3|lowest..highest).
+ * @note The priority level is used for both the TX and RX DMA channels but
+ * because of the channels ordering the RX channel has always priority
+ * over the TX channel.
*/
#if !defined(STM32_SPI2_DMA_PRIORITY) || defined(__DOXYGEN__)
#define STM32_SPI2_DMA_PRIORITY 2
#endif
/**
- * @brief SPI3 DMA priority (0..3|lowest..highest).
- * @note The priority level is used for both the TX and RX DMA channels but
- * because of the channels ordering the RX channel has always priority
- * over the TX channel.
+ * @brief SPI3 DMA priority (0..3|lowest..highest).
+ * @note The priority level is used for both the TX and RX DMA channels but
+ * because of the channels ordering the RX channel has always priority
+ * over the TX channel.
*/
#if !defined(STM32_SPI3_DMA_PRIORITY) || defined(__DOXYGEN__)
#define STM32_SPI3_DMA_PRIORITY 2
#endif
/**
- * @brief SPI1 interrupt priority level setting.
+ * @brief SPI1 interrupt priority level setting.
*/
#if !defined(STM32_SPI1_IRQ_PRIORITY) || defined(__DOXYGEN__)
#define STM32_SPI1_IRQ_PRIORITY 10
#endif
/**
- * @brief SPI2 interrupt priority level setting.
+ * @brief SPI2 interrupt priority level setting.
*/
#if !defined(STM32_SPI2_IRQ_PRIORITY) || defined(__DOXYGEN__)
#define STM32_SPI2_IRQ_PRIORITY 10
#endif
/**
- * @brief SPI3 interrupt priority level setting.
+ * @brief SPI3 interrupt priority level setting.
*/
#if !defined(STM32_SPI3_IRQ_PRIORITY) || defined(__DOXYGEN__)
#define STM32_SPI3_IRQ_PRIORITY 10
#endif
/**
- * @brief SPI1 DMA error hook.
- * @note The default action for DMA errors is a system halt because DMA error
- * can only happen because programming errors.
+ * @brief SPI1 DMA error hook.
+ * @note The default action for DMA errors is a system halt because DMA error
+ * can only happen because programming errors.
*/
#if !defined(STM32_SPI1_DMA_ERROR_HOOK) || defined(__DOXYGEN__)
#define STM32_SPI1_DMA_ERROR_HOOK() chSysHalt()
#endif
/**
- * @brief SPI2 DMA error hook.
- * @note The default action for DMA errors is a system halt because DMA error
- * can only happen because programming errors.
+ * @brief SPI2 DMA error hook.
+ * @note The default action for DMA errors is a system halt because DMA error
+ * can only happen because programming errors.
*/
#if !defined(STM32_SPI2_DMA_ERROR_HOOK) || defined(__DOXYGEN__)
#define STM32_SPI2_DMA_ERROR_HOOK() chSysHalt()
#endif
/**
- * @brief SPI3 DMA error hook.
- * @note The default action for DMA errors is a system halt because DMA error
- * can only happen because programming errors.
+ * @brief SPI3 DMA error hook.
+ * @note The default action for DMA errors is a system halt because DMA error
+ * can only happen because programming errors.
*/
#if !defined(STM32_SPI3_DMA_ERROR_HOOK) || defined(__DOXYGEN__)
#define STM32_SPI3_DMA_ERROR_HOOK() chSysHalt()
@@ -155,17 +155,11 @@
* @brief Driver configuration structure.
*/
typedef struct {
- /**
- * @brief The chip select line port.
- */
+ /** @brief The chip select line port.*/
ioportid_t spc_ssport;
- /**
- * @brief The chip select line pad number.
- */
+ /** @brief The chip select line pad number.*/
uint16_t spc_sspad;
- /**
- * @brief SPI initialization data.
- */
+ /** @brief SPI initialization data.*/
uint16_t spc_cr1;
} SPIConfig;
@@ -173,44 +167,28 @@ typedef struct {
* @brief Structure representing a SPI driver.
*/
typedef struct {
- /**
- * @brief Driver state.
- */
+ /** @brief Driver state.*/
spistate_t spd_state;
#if SPI_USE_MUTUAL_EXCLUSION || defined(__DOXYGEN__)
#if CH_USE_MUTEXES || defined(__DOXYGEN__)
- /**
- * @brief Mutex protecting the bus.
- */
+ /** @brief Mutex protecting the bus.*/
Mutex spd_mutex;
#elif CH_USE_SEMAPHORES
Semaphore spd_semaphore;
#endif
#endif /* SPI_USE_MUTUAL_EXCLUSION */
- /**
- * @brief Current configuration data.
- */
+ /** @brief Current configuration data.*/
const SPIConfig *spd_config;
/* End of the mandatory fields.*/
- /**
- * @brief Thread waiting for I/O completion.
- */
+ /** @brief Thread waiting for I/O completion.*/
Thread *spd_thread;
- /**
- * @brief Pointer to the SPIx registers block.
- */
+ /** @brief Pointer to the SPIx registers block.*/
SPI_TypeDef *spd_spi;
- /**
- * @brief Pointer to the receive DMA channel registers block.
- */
+ /** @brief Pointer to the receive DMA channel registers block.*/
DMA_Channel_TypeDef *spd_dmarx;
- /**
- * @brief Pointer to the transmit DMA channel registers block.
- */
+ /** @brief Pointer to the transmit DMA channel registers block.*/
DMA_Channel_TypeDef *spd_dmatx;
- /**
- * @brief DMA priority bit mask.
- */
+ /** @brief DMA priority bit mask.*/
uint32_t spd_dmaprio;
} SPIDriver;
diff --git a/os/hal/platforms/STM32/stm32_dma.h b/os/hal/platforms/STM32/stm32_dma.h
index 51c16741b..b34be76b9 100644
--- a/os/hal/platforms/STM32/stm32_dma.h
+++ b/os/hal/platforms/STM32/stm32_dma.h
@@ -20,6 +20,8 @@
/**
* @file stm32_dma.h
* @brief STM32 DMA helper driver header.
+ * @note This file requires definitions from the ST STM32 header file
+ * stm3232f10x.h.
*
* @addtogroup STM32_DMA
* @{
@@ -52,10 +54,53 @@
/* Driver data structures and types. */
/*===========================================================================*/
+/**
+ * @brief STM32 DMA channel memory structure.
+ */
+typedef struct {
+ volatile uint32_t CCR;
+ volatile uint32_t CNDTR;
+ volatile uint32_t CPAR;
+ volatile uint32_t CMAR;
+ volatile uint32_t dummy;
+} stm32_dma_channel_t;
+
+/**
+ * @brief STM32 DMA subsystem memory structure.
+ * @note This structure has been redefined here because it is convenient to
+ * have the channels organized as an array, the ST header does not
+ * do that.
+ */
+typedef struct {
+ volatile uint32_t ISR;
+ volatile uint32_t IFCR;
+ stm32_dma_channel_t channels[7];
+} stm32_dma_t:
+
/*===========================================================================*/
/* Driver macros. */
/*===========================================================================*/
+#define STM32_DMA1_BASE (AHBPERIPH_BASE + 0x0000)
+#define STM32_DMA1 ((stm32_dma_t *)STM32_DMA1_BASE)
+#define STM32_DMA1_CH1 (STM32_DMA1->channels[0])
+#define STM32_DMA1_CH2 (STM32_DMA1->channels[1])
+#define STM32_DMA1_CH3 (STM32_DMA1->channels[2])
+#define STM32_DMA1_CH4 (STM32_DMA1->channels[3])
+#define STM32_DMA1_CH5 (STM32_DMA1->channels[4])
+#define STM32_DMA1_CH6 (STM32_DMA1->channels[5])
+#define STM32_DMA1_CH7 (STM32_DMA1->channels[6])
+
+#if defined(STM32F10X_HD) || defined (STM32F10X_CL) || defined(__DOXYGEN__)
+#define STM32_DMA2_BASE (AHBPERIPH_BASE + 0x0400)
+#define STM32_DMA2 ((stm32_dma_t *)STM32_DMA2_BASE)
+#define STM32_DMA2_CH1 (STM32_DMA2->channels[0])
+#define STM32_DMA2_CH2 (STM32_DMA2->channels[1])
+#define STM32_DMA2_CH3 (STM32_DMA2->channels[2])
+#define STM32_DMA2_CH4 (STM32_DMA2->channels[3])
+#define STM32_DMA2_CH5 (STM32_DMA2->channels[4])
+#endif
+
/*===========================================================================*/
/* External declarations. */
/*===========================================================================*/
diff --git a/os/hal/platforms/STM32/uart_lld.c b/os/hal/platforms/STM32/uart_lld.c
new file mode 100644
index 000000000..4967bb06f
--- /dev/null
+++ b/os/hal/platforms/STM32/uart_lld.c
@@ -0,0 +1,248 @@
+/*
+ ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010 Giovanni Di Sirio.
+
+ This file is part of ChibiOS/RT.
+
+ ChibiOS/RT 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 3 of the License, or
+ (at your option) any later version.
+
+ ChibiOS/RT 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.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
+*/
+
+/**
+ * @file STM32/uart_lld.c
+ * @brief STM32 low level UART driver code.
+ *
+ * @addtogroup STM32_UART
+ * @{
+ */
+
+#include "ch.h"
+#include "hal.h"
+
+#if CH_HAL_USE_UART || defined(__DOXYGEN__)
+
+/*===========================================================================*/
+/* Driver exported variables. */
+/*===========================================================================*/
+
+/** @brief USART1 UART driver identifier.*/
+#if STM32_UART_USE_USART1 || defined(__DOXYGEN__)
+UARTDriver UARTD1;
+#endif
+
+/*===========================================================================*/
+/* Driver local variables. */
+/*===========================================================================*/
+
+/*===========================================================================*/
+/* Driver local functions. */
+/*===========================================================================*/
+
+#define dma_setup(dmap, cndtr, cmar, ccr) { \
+ (dmap)->CNDTR = (uint32_t)(cndtr); \
+ (dmap)->CMAR = (uint32_t)(cmar); \
+ (dmap)->CCR = (uint32_t)(ccr); \
+}
+
+#define dma_disable(dmap) { \
+ (dmap)->CCR = 0; \
+}
+
+#define dma_rx_setup(uartp, cndtr, cmar, ccr) \
+ dma_setup((uartp)->ud_dmarx, (cndtr), (cmar), (uartp)->ud_dmaccr|(ccr))
+
+#define dma_tx_setup(uartp, cndtr, cmar, ccr) { \
+ dma_setup((uartp)->ud_dmatx, (cndtr), (cmar), (uartp)->ud_dmaccr|(ccr))
+
+/**
+ * @brief USART initialization.
+ * @details This function must be invoked with interrupts disabled.
+ *
+ * @param[in] uartp pointer to the @p UARTDriver object
+ */
+static void usart_start(UARTDriver *uartp) {
+ USART_TypeDef *u = uartp->ud_usart;
+
+ /* Baud rate setting.*/
+ if (uartp->ud_usart == USART1)
+ u->BRR = STM32_PCLK2 / uartp->ud_config->uc_speed;
+ else
+ u->BRR = STM32_PCLK1 / uartp->ud_config->uc_speed;
+
+ /* Note that some bits are enforced because required for correct driver
+ operations.*/
+ u->CR1 = uartp->ud_config->uc_cr1 | USART_CR1_UE | USART_CR1_PEIE |
+ USART_CR1_TE | USART_CR1_RE;
+ u->CR2 = uartp->ud_config->uc_cr2 | USART_CR2_LBDIE;
+ u->CR3 = uartp->ud_config->uc_cr3 | USART_CR3_EIE;
+ (void)u->SR; /* SR reset step 1.*/
+ (void)u->DR; /* SR reset step 2.*/
+
+ /* RX DMA channel preparation, circular 1 frame transfers, an interrupt is
+ generated for each received character.*/
+ dma_rx_setup(uartp, 1, &uartp->ud_rxbuf,
+ DMA_CCR1_TCIE | DMA_CCR1_TEIE | DMA_CCR1_CIRC | DMA_CCR1_EN);
+
+ /* TX DMA channel preparation, simply disabled.*/
+ dma_disable(uartp->ud_dmatx);
+}
+
+/**
+ * @brief USART de-initialization.
+ * @details This function must be invoked with interrupts disabled.
+ *
+ * @param[in] u pointer to an USART I/O block
+ */
+static void usart_stop(UARTDriver *uartp) {
+
+ /* Stops RX and TX DMA channels.*/
+ dma_disable(uartp->ud_dmarx);
+ dma_disable(uartp->ud_dmatx);
+
+ /* Stops USART operations.*/
+ uartp->ud_usart->CR1 = 0;
+ uartp->ud_usart->CR2 = 0;
+ uartp->ud_usart->CR3 = 0;
+}
+
+/*===========================================================================*/
+/* Driver interrupt handlers. */
+/*===========================================================================*/
+
+/*===========================================================================*/
+/* Driver exported functions. */
+/*===========================================================================*/
+
+/**
+ * @brief Low level UART driver initialization.
+ */
+void uart_lld_init(void) {
+
+#if STM32_UART_USE_USART1
+ RCC->APB2RSTR = RCC_APB2RSTR_USART1RST;
+ RCC->APB2RSTR = 0;
+ uartObjectInit(&UARTD1);
+ UARTD1.ud_usart = USART1;
+ UARTD1.ud_dmarx = DMA1_Channel4;
+ UARTD1.ud_dmatx = DMA1_Channel5;
+ UARTD1.ud_dmaccr = 0;
+ UARTD1.ud_dmarmsk = 0xF << (4 - 1);
+ UARTD1.ud_dmatmsk = 0xF << (5 - 1);
+#endif
+}
+
+/**
+ * @brief Configures and activates the UART peripheral.
+ *
+ * @param[in] uartp pointer to the @p UARTDriver object
+ */
+void uart_lld_start(UARTDriver *uartp) {
+
+ if (uartp->ud_state == UART_STOP) {
+#if STM32_UART_USE_USART1
+ if (&UARTD1 == uartp) {
+ dmaEnable(DMA1_ID); /* NOTE: Must be enabled before the IRQs.*/
+ NVICEnableVector(USART1_IRQn,
+ CORTEX_PRIORITY_MASK(STM32_UART_USART1_IRQ_PRIORITY));
+ NVICEnableVector(DMA1_Channel4_IRQn,
+ CORTEX_PRIORITY_MASK(STM32_UART_USART1_IRQ_PRIORITY));
+ NVICEnableVector(DMA1_Channel5_IRQn,
+ CORTEX_PRIORITY_MASK(STM32_UART_USART1_IRQ_PRIORITY));
+ RCC->APB2ENR |= RCC_APB2ENR_USART1EN;
+ }
+#endif
+
+ /* Static DMA setup, the transfer size depends on the USART settings,
+ it is 16 bits if M=1 and PCE=0 else it is 8 bits.*/
+ uartp->ud_dmaccr = STM32_UART_USART1_DMA_PRIORITY << 12;
+ if ((uartp->ud_config->uc_cr1 & (USART_CR1_M | USART_CR1_PCE)) == USART_CR1_M)
+ uartp->ud_dmaccr |= DMA_CCR1_MSIZE_0 | DMA_CCR1_PSIZE_0;
+ uartp->ud_dmarx->CPAR = (uint32_t)&uartp->ud_usart->DR;
+ uartp->ud_dmatx->CPAR = (uint32_t)&uartp->ud_usart->DR;
+ }
+ uartp->ud_txstate = UART_TX_IDLE;
+ uartp->ud_rxstate = UART_RX_IDLE;
+ usart_start(uartp);
+}
+
+/**
+ * @brief Deactivates the UART peripheral.
+ *
+ * @param[in] uartp pointer to the @p UARTDriver object
+ */
+void uart_lld_stop(UARTDriver *uartp) {
+
+ if (uartp->ud_state == SD_READY) {
+ usart_stop(uartp);
+
+#if STM32_UART_USE_USART1
+ if (&UARTD1 == uartp) {
+ NVICDisableVector(USART1_IRQn);
+ NVICDisableVector(DMA1_Channel4_IRQn);
+ NVICDisableVector(DMA1_Channel5_IRQn);
+ dmaDisable(DMA1_ID);
+ RCC->APB2ENR &= ~RCC_APB2ENR_USART1EN;
+ return;
+ }
+#endif
+ }
+}
+
+/**
+ * @brief Starts a transmission on the UART peripheral.
+ * @note The buffers are organized as uint8_t arrays for data sizes below
+ * or equal to 8 bits else it is organized as uint16_t arrays.
+ *
+ * @param[in] uartp pointer to the @p UARTDriver object
+ * @param[in] n number of data frames to send
+ * @param[in] txbuf the pointer to the transmit buffer
+ */
+void uart_lld_start_send(UARTDriver *uartp, size_t n, const void *txbuf) {
+
+}
+
+/**
+ * @brief Stops any ongoing transmission.
+ * @note Stopping a transmission also suppresses the transmission callbacks.
+ *
+ * @param[in] uartp pointer to the @p UARTDriver object
+ */
+void uart_lld_stop_send(UARTDriver *uartp) {
+
+}
+
+/**
+ * @brief Starts a receive operation on the UART peripheral.
+ * @note The buffers are organized as uint8_t arrays for data sizes below
+ * or equal to 8 bits else it is organized as uint16_t arrays.
+ *
+ * @param[in] uartp pointer to the @p UARTDriver object
+ * @param[in] n number of data frames to send
+ * @param[in] rxbuf the pointer to the receive buffer
+ */
+void uart_lld_start_receive(UARTDriver *uartp, size_t n, void *rxbuf) {
+
+}
+
+/**
+ * @brief Stops any ongoing receive operation.
+ * @note Stopping a receive operation also suppresses the receive callbacks.
+ *
+ * @param[in] uartp pointer to the @p UARTDriver object
+ */
+void uart_lld_stop_receive(UARTDriver *uartp) {
+
+}
+
+#endif /* CH_HAL_USE_UART */
+
+/** @} */
diff --git a/os/hal/platforms/STM32/uart_lld.h b/os/hal/platforms/STM32/uart_lld.h
new file mode 100644
index 000000000..50216608e
--- /dev/null
+++ b/os/hal/platforms/STM32/uart_lld.h
@@ -0,0 +1,163 @@
+/*
+ ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010 Giovanni Di Sirio.
+
+ This file is part of ChibiOS/RT.
+
+ ChibiOS/RT 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 3 of the License, or
+ (at your option) any later version.
+
+ ChibiOS/RT 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.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
+*/
+
+/**
+ * @file STM32/uart_lld.h
+ * @brief STM32 low level UART driver header.
+ *
+ * @addtogroup STM32_UART
+ * @{
+ */
+
+#ifndef _UART_LLD_H_
+#define _UART_LLD_H_
+
+#if CH_HAL_USE_UART || defined(__DOXYGEN__)
+
+/*===========================================================================*/
+/* Driver constants. */
+/*===========================================================================*/
+
+/*===========================================================================*/
+/* Driver pre-compile time settings. */
+/*===========================================================================*/
+
+/**
+ * @brief UART driver on USART1 enable switch.
+ * @details If set to @p TRUE the support for USART1 is included.
+ * @note The default is @p FALSE.
+ */
+#if !defined(STM32_UART_USE_USART1) || defined(__DOXYGEN__)
+#define STM32_UART_USE_USART1 TRUE
+#endif
+
+/**
+ * @brief USART1 interrupt priority level setting.
+ */
+#if !defined(STM32_UART_USART1_IRQ_PRIO) || defined(__DOXYGEN__)
+#define STM32_UART_USART1_IRQ_PRIORITY 12
+#endif
+
+/**
+ * @brief USART1 DMA priority (0..3|lowest..highest).
+ * @note The priority level is used for both the TX and RX DMA channels but
+ * because of the channels ordering the RX channel has always priority
+ * over the TX channel.
+ */
+#if !defined(STM32_UART_USART1_DMA_PRIO) || defined(__DOXYGEN__)
+#define STM32_UART_USART1_DMA_PRIORITY 1
+#endif
+
+/*===========================================================================*/
+/* Derived constants and error checks. */
+/*===========================================================================*/
+
+/*===========================================================================*/
+/* Driver data structures and types. */
+/*===========================================================================*/
+
+/**
+ * @brief UART driver condition flags type.
+ */
+typedef uint32_t uartflags_t;
+
+/**
+ * @brief Driver configuration structure.
+ * @note It could be empty on some architectures.
+ */
+typedef struct {
+ /** @brief End of transmission buffer callback.*/
+ uartcb_t uc_txend1;
+ /** @brief Physical end of transmission callback.*/
+ uartcb_t uc_txend2;
+ /** @brief Receive buffer filled callback.*/
+ uartcb_t uc_rxend;
+ /** @brief Character received while out if the @p UART_RECEIVE state.*/
+ uartcb_t uc_rxchar;
+ /** @brief Receive error callback.*/
+ uartcb_t uc_rxerr;
+ /* End of the mandatory fields.*/
+ /** @brief Bit rate.*/
+ uint32_t uc_speed;
+ /** @brief Initialization value for the CR1 register.*/
+ uint16_t uc_cr1;
+ /** @brief Initialization value for the CR2 register.*/
+ uint16_t uc_cr2;
+ /** @brief Initialization value for the CR3 register.*/
+ uint16_t uc_cr3;
+} UARTConfig;
+
+/**
+ * @brief Structure representing an UART driver.
+ */
+typedef struct {
+ /** @brief Driver state.*/
+ uartstate_t ud_state;
+ /** @brief Current configuration data.*/
+ const UARTConfig *ud_config;
+ /** @brief Transmitter state.*/
+ uarttxstate_t ud_txstate;
+ /** @brief Receiver state.*/
+ uartrxstate_t ud_rxstate;
+ /** @brief UART driver status flags.*/
+ uartflags_t ud_flags;
+ /* End of the mandatory fields.*/
+ /** @brief Default receive buffer while into @p UART_RX_IDLE state.*/
+ uint16_t ud_rxbuf;
+ /** @brief Pointer to the USART registers block.*/
+ USART_TypeDef *ud_usart;
+ /** @brief Pointer to the receive DMA channel registers block.*/
+ DMA_Channel_TypeDef *ud_dmarx;
+ /** @brief Receive DMA flags mask*/
+ uint32_t ud_dmarmsk;
+ /** @brief Pointer to the transmit DMA channel registers block.*/
+ DMA_Channel_TypeDef *ud_dmatx;
+ /** @brief Transmit DMA flags mask*/
+ uint32_t ud_dmatmsk;
+ /** @brief DMA priority bit mask.*/
+ uint32_t ud_dmaccr;
+} UARTDriver;
+
+/*===========================================================================*/
+/* Driver macros. */
+/*===========================================================================*/
+
+/*===========================================================================*/
+/* External declarations. */
+/*===========================================================================*/
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+ void uart_lld_init(void);
+ void uart_lld_start(UARTDriver *uartp);
+ void uart_lld_stop(UARTDriver *uartp);
+ void uart_lld_start_send(UARTDriver *uartp, size_t n, const void *txbuf);
+ void uart_lld_stop_send(UARTDriver *uartp);
+ void uart_lld_start_receive(UARTDriver *uartp, size_t n, void *rxbuf);
+ void uart_lld_stop_receive(UARTDriver *uartp);
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* CH_HAL_USE_UART */
+
+#endif /* _UART_LLD_H_ */
+
+/** @} */