From 8c836a17ffbb2af2a0d10db3a3b031c4ee4b2f3d Mon Sep 17 00:00:00 2001 From: gdisirio Date: Mon, 26 Jul 2010 15:01:58 +0000 Subject: git-svn-id: svn://svn.code.sf.net/p/chibios/svn/trunk@2090 35acf78f-673a-0410-8e92-d51de3d6d3f4 --- os/hal/platforms/STM32/spi_lld.c | 50 ++++---- os/hal/platforms/STM32/spi_lld.h | 104 ++++++---------- os/hal/platforms/STM32/stm32_dma.h | 45 +++++++ os/hal/platforms/STM32/uart_lld.c | 248 +++++++++++++++++++++++++++++++++++++ os/hal/platforms/STM32/uart_lld.h | 163 ++++++++++++++++++++++++ 5 files changed, 521 insertions(+), 89 deletions(-) create mode 100644 os/hal/platforms/STM32/uart_lld.c create mode 100644 os/hal/platforms/STM32/uart_lld.h (limited to 'os/hal') 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 . +*/ + +/** + * @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 . +*/ + +/** + * @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_ */ + +/** @} */ -- cgit v1.2.3