From f8c40043e469d81f2a9f380d6723b92c79bd30bc Mon Sep 17 00:00:00 2001 From: gdisirio Date: Fri, 1 Jan 2010 13:41:31 +0000 Subject: Serial driver enhancements for STM32 and AT91SAM7. git-svn-id: svn://svn.code.sf.net/p/chibios/svn/trunk@1485 35acf78f-673a-0410-8e92-d51de3d6d3f4 --- os/hal/platforms/AT91SAM7/serial_lld.c | 122 +++++++++++++------------ os/hal/platforms/AT91SAM7/serial_lld.h | 81 +++++++++-------- os/hal/platforms/STM32/serial_lld.c | 157 ++++++++++++++++++--------------- os/hal/platforms/STM32/serial_lld.h | 100 ++++++++++++--------- 4 files changed, 253 insertions(+), 207 deletions(-) (limited to 'os/hal/platforms') diff --git a/os/hal/platforms/AT91SAM7/serial_lld.c b/os/hal/platforms/AT91SAM7/serial_lld.c index be28045fc..8fac96e33 100644 --- a/os/hal/platforms/AT91SAM7/serial_lld.c +++ b/os/hal/platforms/AT91SAM7/serial_lld.c @@ -66,7 +66,7 @@ SerialDriver SD2; /*===========================================================================*/ /** @brief Driver default configuration.*/ -static const SerialDriverConfig default_config = { +static const SerialConfig default_config = { 38400, AT91C_US_USMODE_NORMAL | AT91C_US_CLKS_CLOCK | AT91C_US_CHRL_8_BITS | AT91C_US_PAR_NONE | AT91C_US_NBSTOP_1_BIT @@ -78,21 +78,22 @@ static const SerialDriverConfig default_config = { /** * @brief USART initialization. - * @param[in] u pointer to an USART I/O block - * @param[in] config the architecture-dependent serial driver configuration + * + * @param[in] sdp communication channel associated to the USART */ -static void usart_init(AT91PS_USART u, const SerialDriverConfig *config) { +static void usart_init(SerialDriver *sdp) { + AT91PS_USART u = sdp->sd.usart; /* Disables IRQ sources and stop operations.*/ u->US_IDR = 0xFFFFFFFF; u->US_CR = AT91C_US_RSTRX | AT91C_US_RSTTX | AT91C_US_RSTSTA; /* New parameters setup.*/ - if (config->mr & AT91C_US_OVER) - u->US_BRGR = MCK / (config->speed * 8); + if (sdp->sd.config->sc_mr & AT91C_US_OVER) + u->US_BRGR = MCK / (sdp->sd.config->sc_speed * 8); else - u->US_BRGR = MCK / (config->speed * 16); - u->US_MR = config->mr; + u->US_BRGR = MCK / (sdp->sd.config->sc_speed * 16); + u->US_MR = sdp->sd.config->sc_mr; u->US_RTOR = 0; u->US_TTGR = 0; @@ -121,7 +122,7 @@ static void usart_deinit(AT91PS_USART u) { * @param[in] err USART CSR register value * @param[in] sdp communication channel associated to the USART */ -static void set_error(AT91_REG csr, SerialDriver *sdp) { +static void set_error(SerialDriver *sdp, AT91_REG csr) { sdflags_t sts = 0; if (csr & AT91C_US_OVRE) @@ -142,27 +143,35 @@ __attribute__((noinline)) #endif /** * @brief Common IRQ handler. - * @param[in] u pointer to an USART I/O block - * @param[in] com communication channel associated to the USART + * + * @param[in] sdp communication channel associated to the USART */ -static void serve_interrupt(AT91PS_USART u, SerialDriver *sdp) { +static void serve_interrupt(SerialDriver *sdp) { + uint32_t csr; + AT91PS_USART u = sdp->sd.usart; - if (u->US_CSR & AT91C_US_RXRDY) { + csr = u->US_CSR; + if (csr & AT91C_US_RXRDY) { chSysLockFromIsr(); sdIncomingDataI(sdp, u->US_RHR); chSysUnlockFromIsr(); } - if (u->US_CSR & AT91C_US_TXRDY) { + if ((u->US_IMR & AT91C_US_TXRDY) && (csr & AT91C_US_TXRDY)) { + msg_t b; + chSysLockFromIsr(); - msg_t b = sdRequestDataI(sdp); - chSysUnlockFromIsr(); - if (b < Q_OK) + b = chOQGetI(&sdp->sd.oqueue); + if (b < Q_OK) { + chEvtBroadcastI(&sdp->bac.oevent); u->US_IDR = AT91C_US_TXRDY; + } else u->US_THR = b; + chSysUnlockFromIsr(); } - if (u->US_CSR & (AT91C_US_OVRE | AT91C_US_FRAME | AT91C_US_PARE | AT91C_US_RXBRK)) { - set_error(u->US_CSR, sdp); + csr &= (AT91C_US_OVRE | AT91C_US_FRAME | AT91C_US_PARE | AT91C_US_RXBRK); + if (csr != 0) { + set_error(sdp, csr); u->US_CR = AT91C_US_RSTSTA; } AT91C_BASE_AIC->AIC_EOICR = 0; @@ -191,7 +200,7 @@ CH_IRQ_HANDLER(USART0IrqHandler) { CH_IRQ_PROLOGUE(); - serve_interrupt(AT91C_BASE_US0, &SD1); + serve_interrupt(&SD1); CH_IRQ_EPILOGUE(); } @@ -202,7 +211,7 @@ CH_IRQ_HANDLER(USART1IrqHandler) { CH_IRQ_PROLOGUE(); - serve_interrupt(AT91C_BASE_US1, &SD2); + serve_interrupt(&SD2); CH_IRQ_EPILOGUE(); } @@ -219,6 +228,7 @@ void sd_lld_init(void) { #if USE_SAM7_USART0 sdObjectInit(&SD1, NULL, notify1); + SD1.sd.usart = AT91C_BASE_US0; AT91C_BASE_PIOA->PIO_PDR = SAM7_USART0_RX | SAM7_USART0_TX; AT91C_BASE_PIOA->PIO_ASR = SAM7_USART0_RX | SAM7_USART0_TX; AT91C_BASE_PIOA->PIO_PPUDR = SAM7_USART0_RX | SAM7_USART0_TX; @@ -229,6 +239,7 @@ void sd_lld_init(void) { #if USE_SAM7_USART1 sdObjectInit(&SD2, NULL, notify2); + SD2.sd.usart = AT91C_BASE_US1; AT91C_BASE_PIOA->PIO_PDR = SAM7_USART1_RX | SAM7_USART1_TX; AT91C_BASE_PIOA->PIO_ASR = SAM7_USART1_RX | SAM7_USART1_TX; AT91C_BASE_PIOA->PIO_PPUDR = SAM7_USART1_RX | SAM7_USART1_TX; @@ -242,37 +253,33 @@ void sd_lld_init(void) { * @brief Low level serial driver configuration and (re)start. * * @param[in] sdp pointer to a @p SerialDriver object - * @param[in] config the architecture-dependent serial driver configuration. - * If this parameter is set to @p NULL then a default - * configuration is used. */ -void sd_lld_start(SerialDriver *sdp, const SerialDriverConfig *config) { +void sd_lld_start(SerialDriver *sdp) { - if (config == NULL) - config = &default_config; + if (sdp->sd.config == NULL) + sdp->sd.config = &default_config; + if (sdp->sd.state == SD_STOP) { #if USE_SAM7_USART0 - if (&SD1 == sdp) { - /* Starts the clock and clears possible sources of immediate interrupts.*/ - AT91C_BASE_PMC->PMC_PCER = (1 << AT91C_ID_US0); - /* USART initialization.*/ - usart_init(AT91C_BASE_US0, config); - /* Enables associated interrupt vector.*/ - AIC_EnableIT(AT91C_ID_US0); - return; - } + if (&SD1 == sdp) { + /* Starts the clock and clears possible sources of immediate interrupts.*/ + AT91C_BASE_PMC->PMC_PCER = (1 << AT91C_ID_US0); + /* Enables associated interrupt vector.*/ + AIC_EnableIT(AT91C_ID_US0); + return; + } #endif #if USE_SAM7_USART1 - if (&SD2 == sdp) { - /* Starts the clock and clears possible sources of immediate interrupts.*/ - AT91C_BASE_PMC->PMC_PCER = (1 << AT91C_ID_US1); - /* USART initialization.*/ - usart_init(AT91C_BASE_US1, config); - /* Enables associated interrupt vector.*/ - AIC_EnableIT(AT91C_ID_US1); - return; - } + if (&SD2 == sdp) { + /* Starts the clock and clears possible sources of immediate interrupts.*/ + AT91C_BASE_PMC->PMC_PCER = (1 << AT91C_ID_US1); + /* Enables associated interrupt vector.*/ + AIC_EnableIT(AT91C_ID_US1); + return; + } #endif + } + usart_init(sdp); } /** @@ -284,22 +291,23 @@ void sd_lld_start(SerialDriver *sdp, const SerialDriverConfig *config) { */ void sd_lld_stop(SerialDriver *sdp) { + if (sdp->sd.state == SD_READY) { + usart_deinit(sdp->sd.usart); #if USE_SAM7_USART0 - if (&SD1 == sdp) { - usart_deinit(AT91C_BASE_US0); - AT91C_BASE_PMC->PMC_PCDR = (1 << AT91C_ID_US0); - AIC_DisableIT(AT91C_ID_US0); - return; - } + if (&SD1 == sdp) { + AT91C_BASE_PMC->PMC_PCDR = (1 << AT91C_ID_US0); + AIC_DisableIT(AT91C_ID_US0); + return; + } #endif #if USE_SAM7_USART1 - if (&SD2 == sdp) { - usart_deinit(AT91C_BASE_US1); - AT91C_BASE_PMC->PMC_PCDR = (1 << AT91C_ID_US1); - AIC_DisableIT(AT91C_ID_US1); - return; - } + if (&SD2 == sdp) { + AT91C_BASE_PMC->PMC_PCDR = (1 << AT91C_ID_US1); + AIC_DisableIT(AT91C_ID_US1); + return; + } #endif + } } #endif /* CH_HAL_USE_SERIAL */ diff --git a/os/hal/platforms/AT91SAM7/serial_lld.h b/os/hal/platforms/AT91SAM7/serial_lld.h index b5394aeed..7b7deba95 100644 --- a/os/hal/platforms/AT91SAM7/serial_lld.h +++ b/os/hal/platforms/AT91SAM7/serial_lld.h @@ -37,16 +37,6 @@ /* Driver pre-compile time settings. */ /*===========================================================================*/ -/** - * @brief Serial buffers size. - * @details Configuration parameter, you can change the depth of the queue - * buffers depending on the requirements of your application. - * @note The default is 128 bytes for both the transmission and receive buffers. - */ -#if !defined(SERIAL_BUFFERS_SIZE) || defined(__DOXYGEN__) -#define SERIAL_BUFFERS_SIZE 128 -#endif - /** * @brief UART0 driver enable switch. * @details If set to @p TRUE the support for USART1 is included. @@ -92,49 +82,68 @@ */ typedef uint32_t sdflags_t; +/** + * @brief AT91SAM7 Serial Driver configuration structure. + * @details An instance of this structure must be passed to @p sdStart() + * in order to configure and start a serial driver operations. + */ +typedef struct { + /** + * @brief Bit rate. + */ + uint32_t sc_speed; + /** + * @brief Initialization value for the MR register. + */ + uint32_t sc_mr; +} SerialConfig; + /** * @brief @p SerialDriver specific data. */ struct _serial_driver_data { /** - * Input queue, incoming data can be read from this input queue by - * using the queues APIs. + * @brief Driver state. + */ + sdstate_t state; + /** + * @brief Current configuration data. + */ + const SerialConfig *config; + /** + * @brief Input queue, incoming data can be read from this input queue by + * using the queues APIs. + */ + InputQueue iqueue; + /** + * @brief Output queue, outgoing data can be written to this output queue by + * using the queues APIs. */ - InputQueue iqueue; + OutputQueue oqueue; /** - * Output queue, outgoing data can be written to this output queue by - * using the queues APIs. + * @brief Status Change @p EventSource. This event is generated when one or + * more condition flags change. */ - OutputQueue oqueue; + EventSource sevent; /** - * Status Change @p EventSource. This event is generated when one or more - * condition flags change. + * @brief I/O driver status flags. */ - EventSource sevent; + sdflags_t flags; /** - * I/O driver status flags. + * @brief Input circular buffer. */ - sdflags_t flags; + uint8_t ib[SERIAL_BUFFERS_SIZE]; /** - * Input circular buffer. + * @brief Output circular buffer. */ - uint8_t ib[SERIAL_BUFFERS_SIZE]; + uint8_t ob[SERIAL_BUFFERS_SIZE]; + /* End of the mandatory fields.*/ /** - * Output circular buffer. + * @brief Pointer to the USART registers block. */ - uint8_t ob[SERIAL_BUFFERS_SIZE]; + AT91PS_USART usart; }; -/** - * @brief AT91SAM7 Serial Driver configuration structure. - * @details An instance of this structure must be passed to @p sdStart() - * in order to configure and start a serial driver operations. - */ -typedef struct { - uint32_t speed; - uint32_t mr; -} SerialDriverConfig; - /*===========================================================================*/ /* Driver macros. */ /*===========================================================================*/ @@ -155,7 +164,7 @@ extern SerialDriver SD2; extern "C" { #endif void sd_lld_init(void); - void sd_lld_start(SerialDriver *sdp, const SerialDriverConfig *config); + void sd_lld_start(SerialDriver *sdp); void sd_lld_stop(SerialDriver *sdp); #ifdef __cplusplus } diff --git a/os/hal/platforms/STM32/serial_lld.c b/os/hal/platforms/STM32/serial_lld.c index afa0bffc6..6d28fe71f 100644 --- a/os/hal/platforms/STM32/serial_lld.c +++ b/os/hal/platforms/STM32/serial_lld.c @@ -53,7 +53,7 @@ SerialDriver SD3; /*===========================================================================*/ /** @brief Driver default configuration.*/ -static const SerialDriverConfig default_config = +static const SerialConfig default_config = { 38400, 0, @@ -69,26 +69,29 @@ static const SerialDriverConfig default_config = * @brief USART initialization. * @details This function must be invoked with interrupts disabled. * - * @param[in] u pointer to an USART I/O block - * @param[in] config the architecture-dependent serial driver configuration + * @param[in] sdp pointer to a @p SerialDriver object */ -static void usart_init(USART_TypeDef *u, const SerialDriverConfig *config) { +static void usart_init(SerialDriver *sdp) { + USART_TypeDef *u = sdp->sd.usart; /* * Baud rate setting. */ - if (u == USART1) - u->BRR = APB2CLK / config->speed; + if (sdp->sd.usart == USART1) + u->BRR = APB2CLK / sdp->sd.config->sc_speed; else - u->BRR = APB1CLK / config->speed; + u->BRR = APB1CLK / sdp->sd.config->sc_speed; /* * Note that some bits are enforced. */ - u->CR1 = config->cr1 | USART_CR1_UE | USART_CR1_PEIE | USART_CR1_RXNEIE | - USART_CR1_TE | USART_CR1_RE; - u->CR2 = config->cr2; - u->CR3 = config->cr3 | USART_CR3_EIE; + u->CR1 = sdp->sd.config->sc_cr1 | USART_CR1_UE | USART_CR1_PEIE | + USART_CR1_RXNEIE | USART_CR1_TE | + USART_CR1_RE; + u->CR2 = sdp->sd.config->sc_cr2 | USART_CR2_LBDIE; + u->CR3 = sdp->sd.config->sc_cr3 | USART_CR3_EIE; + (void)u->SR; /* SR reset step 1.*/ + (void)u->DR; /* SR reset step 2.*/ } /** @@ -106,10 +109,11 @@ static void usart_deinit(USART_TypeDef *u) { /** * @brief Error handling routine. + * + * @param[in] sdp pointer to a @p SerialDriver object * @param[in] sr USART SR register value - * @param[in] com communication channel associated to the USART */ -static void set_error(uint16_t sr, SerialDriver *sdp) { +static void set_error(SerialDriver *sdp, uint16_t sr) { sdflags_t sts = 0; if (sr & USART_SR_ORE) @@ -118,6 +122,8 @@ static void set_error(uint16_t sr, SerialDriver *sdp) { sts |= SD_PARITY_ERROR; if (sr & USART_SR_FE) sts |= SD_FRAMING_ERROR; + if (sr & USART_SR_NE) + sts |= SD_NOISE_ERROR; if (sr & USART_SR_LBD) sts |= SD_BREAK_DETECTED; chSysLockFromIsr(); @@ -127,27 +133,36 @@ static void set_error(uint16_t sr, SerialDriver *sdp) { /** * @brief Common IRQ handler. - * @param[in] u pointer to an USART I/O block - * @param[in] com communication channel associated to the USART + * + * @param[in] sdp communication channel associated to the USART */ -static void serve_interrupt(USART_TypeDef *u, SerialDriver *sdp) { - uint16_t sr = u->SR; - - if (sr & (USART_SR_ORE | USART_SR_FE | USART_SR_PE | USART_SR_LBD)) - set_error(sr, sdp); +static void serve_interrupt(SerialDriver *sdp) { + USART_TypeDef *u = sdp->sd.usart; + uint16_t cr1 = u->CR1; + uint16_t sr = u->SR; /* SR reset step 1.*/ + uint16_t dr = u->DR; /* SR reset step 2.*/ + + if (sr & (USART_SR_LBD | USART_SR_ORE | USART_SR_NE | + USART_SR_FE | USART_SR_PE)) { + set_error(sdp, sr); + u->SR = 0; /* Clears the LBD bit in the SR.*/ + } if (sr & USART_SR_RXNE) { chSysLockFromIsr(); - sdIncomingDataI(sdp, u->DR); + sdIncomingDataI(sdp, (uint8_t)dr); chSysUnlockFromIsr(); } - if (sr & USART_SR_TXE) { + if ((cr1 & USART_CR1_TXEIE) && (sr & USART_SR_TXE)) { + msg_t b; chSysLockFromIsr(); - msg_t b = sdRequestDataI(sdp); - chSysUnlockFromIsr(); - if (b < Q_OK) - u->CR1 &= ~USART_CR1_TXEIE; + b = chOQGetI(&sdp->sd.oqueue); + if (b < Q_OK) { + chEvtBroadcastI(&sdp->bac.oevent); + u->CR1 = cr1 & ~USART_CR1_TXEIE; + } else u->DR = b; + chSysUnlockFromIsr(); } } @@ -181,7 +196,7 @@ CH_IRQ_HANDLER(VectorD4) { CH_IRQ_PROLOGUE(); - serve_interrupt(USART1, &SD1); + serve_interrupt(&SD1); CH_IRQ_EPILOGUE(); } @@ -192,7 +207,7 @@ CH_IRQ_HANDLER(VectorD8) { CH_IRQ_PROLOGUE(); - serve_interrupt(USART2, &SD2); + serve_interrupt(&SD2); CH_IRQ_EPILOGUE(); } @@ -203,7 +218,7 @@ CH_IRQ_HANDLER(VectorDC) { CH_IRQ_PROLOGUE(); - serve_interrupt(USART3, &SD3); + serve_interrupt(&SD3); CH_IRQ_EPILOGUE(); } @@ -220,14 +235,17 @@ void sd_lld_init(void) { #if USE_STM32_USART1 sdObjectInit(&SD1, NULL, notify1); + SD1.sd.usart = USART1; #endif #if USE_STM32_USART2 sdObjectInit(&SD2, NULL, notify2); + SD2.sd.usart = USART2; #endif #if USE_STM32_USART3 sdObjectInit(&SD3, NULL, notify3); + SD3.sd.usart = USART3; #endif } @@ -235,39 +253,36 @@ void sd_lld_init(void) { * @brief Low level serial driver configuration and (re)start. * * @param[in] sdp pointer to a @p SerialDriver object - * @param[in] config the architecture-dependent serial driver configuration. - * If this parameter is set to @p NULL then a default - * configuration is used. */ -void sd_lld_start(SerialDriver *sdp, const SerialDriverConfig *config) { +void sd_lld_start(SerialDriver *sdp) { - if (config == NULL) - config = &default_config; + if (sdp->sd.config == NULL) + sdp->sd.config = &default_config; + if (sdp->sd.state == SD_STOP) { #if USE_STM32_USART1 - if (&SD1 == sdp) { - RCC->APB2ENR |= RCC_APB2ENR_USART1EN; - usart_init(USART1, config); - NVICEnableVector(USART1_IRQn, STM32_USART1_PRIORITY); - return; - } + if (&SD1 == sdp) { + RCC->APB2ENR |= RCC_APB2ENR_USART1EN; + NVICEnableVector(USART1_IRQn, STM32_USART1_PRIORITY); + return; + } #endif #if USE_STM32_USART2 - if (&SD2 == sdp) { - RCC->APB1ENR |= RCC_APB1ENR_USART2EN; - usart_init(USART2, config); - NVICEnableVector(USART2_IRQn, STM32_USART2_PRIORITY); - return; - } + if (&SD2 == sdp) { + RCC->APB1ENR |= RCC_APB1ENR_USART2EN; + NVICEnableVector(USART2_IRQn, STM32_USART2_PRIORITY); + return; + } #endif #if USE_STM32_USART3 - if (&SD3 == sdp) { - RCC->APB1ENR |= RCC_APB1ENR_USART3EN; - usart_init(USART3, config); - NVICEnableVector(USART3_IRQn, STM32_USART3_PRIORITY); - return; - } + if (&SD3 == sdp) { + RCC->APB1ENR |= RCC_APB1ENR_USART3EN; + NVICEnableVector(USART3_IRQn, STM32_USART3_PRIORITY); + return; + } #endif + } + usart_init(sdp); } /** @@ -279,30 +294,30 @@ void sd_lld_start(SerialDriver *sdp, const SerialDriverConfig *config) { */ void sd_lld_stop(SerialDriver *sdp) { + if (sdp->sd.state == SD_READY) { + usart_deinit(sdp->sd.usart); #if USE_STM32_USART1 - if (&SD1 == sdp) { - usart_deinit(USART1); - RCC->APB2ENR &= ~RCC_APB2ENR_USART1EN; - NVICDisableVector(USART1_IRQn); - return; - } + if (&SD1 == sdp) { + RCC->APB2ENR &= ~RCC_APB2ENR_USART1EN; + NVICDisableVector(USART1_IRQn); + return; + } #endif #if USE_STM32_USART2 - if (&SD2 == sdp) { - usart_deinit(USART2); - RCC->APB1ENR &= ~RCC_APB1ENR_USART2EN; - NVICDisableVector(USART2_IRQn); - return; - } + if (&SD2 == sdp) { + RCC->APB1ENR &= ~RCC_APB1ENR_USART2EN; + NVICDisableVector(USART2_IRQn); + return; + } #endif #if USE_STM32_USART3 - if (&SD3 == sdp) { - usart_deinit(USART3); - RCC->APB1ENR &= ~RCC_APB1ENR_USART3EN; - NVICDisableVector(USART3_IRQn); - return; - } + if (&SD3 == sdp) { + RCC->APB1ENR &= ~RCC_APB1ENR_USART3EN; + NVICDisableVector(USART3_IRQn); + return; + } #endif + } } #endif /* CH_HAL_USE_SERIAL */ diff --git a/os/hal/platforms/STM32/serial_lld.h b/os/hal/platforms/STM32/serial_lld.h index 073f8be1f..64c74f5f9 100644 --- a/os/hal/platforms/STM32/serial_lld.h +++ b/os/hal/platforms/STM32/serial_lld.h @@ -37,16 +37,6 @@ /* Driver pre-compile time settings. */ /*===========================================================================*/ -/** - * @brief Serial buffers size setting. - * @details Configuration parameter, you can change the depth of the queue - * buffers depending on the requirements of your application. - * @note The default is 128 bytes for both the transmission and receive buffers. - */ -#if !defined(SERIAL_BUFFERS_SIZE) || defined(__DOXYGEN__) -#define SERIAL_BUFFERS_SIZE 128 -#endif - /** * @brief USART1 driver enable switch. * @details If set to @p TRUE the support for USART1 is included. @@ -111,56 +101,80 @@ */ typedef uint32_t sdflags_t; +/** + * @brief STM32 Serial Driver configuration structure. + * @details An instance of this structure must be passed to @p sdStart() + * in order to configure and start a serial driver operations. + * + * @note This structure content is architecture dependent, each driver + * implementation defines its own version and the custom static + * initializers. + */ +typedef struct { + /** + * @brief Bit rate. + */ + uint32_t sc_speed; + /** + * @brief Initialization value for the CR1 register. + */ + uint16_t sc_cr1; + /** + * @brief Initialization value for the CR2 register. + */ + uint16_t sc_cr2; + /** + * @brief Initialization value for the CR3 register. + */ + uint16_t sc_cr3; +} SerialConfig; + /** * @brief @p SerialDriver specific data. */ struct _serial_driver_data { /** - * Input queue, incoming data can be read from this input queue by - * using the queues APIs. + * @brief Driver state. + */ + sdstate_t state; + /** + * @brief Current configuration data. + */ + const SerialConfig *config; + /** + * @brief Input queue, incoming data can be read from this input queue by + * using the queues APIs. + */ + InputQueue iqueue; + /** + * @brief Output queue, outgoing data can be written to this output queue by + * using the queues APIs. */ - InputQueue iqueue; + OutputQueue oqueue; /** - * Output queue, outgoing data can be written to this output queue by - * using the queues APIs. + * @brief Status Change @p EventSource. This event is generated when one or + * more condition flags change. */ - OutputQueue oqueue; + EventSource sevent; /** - * Status Change @p EventSource. This event is generated when one or more - * condition flags change. + * @brief I/O driver status flags. */ - EventSource sevent; + sdflags_t flags; /** - * I/O driver status flags. + * @brief Input circular buffer. */ - sdflags_t flags; + uint8_t ib[SERIAL_BUFFERS_SIZE]; /** - * Input circular buffer. + * @brief Output circular buffer. */ - uint8_t ib[SERIAL_BUFFERS_SIZE]; + uint8_t ob[SERIAL_BUFFERS_SIZE]; + /* End of the mandatory fields.*/ /** - * Output circular buffer. + * @brief Pointer to the USART registers block. */ - uint8_t ob[SERIAL_BUFFERS_SIZE]; + USART_TypeDef *usart; }; -/** - * @brief STM32 Serial Driver configuration structure. - * @details An instance of this structure must be passed to @p sdStart() - * in order to configure and start a serial driver operations. - * - * @note This structure content is architecture dependent, each driver - * implementation defines its own version and the custom static - * initializers. - */ -typedef struct { - - uint32_t speed; - uint16_t cr1; - uint16_t cr2; - uint16_t cr3; -} SerialDriverConfig; - /*===========================================================================*/ /* Driver macros. */ /*===========================================================================*/ @@ -192,7 +206,7 @@ extern SerialDriver SD3; extern "C" { #endif void sd_lld_init(void); - void sd_lld_start(SerialDriver *sdp, const SerialDriverConfig *config); + void sd_lld_start(SerialDriver *sdp); void sd_lld_stop(SerialDriver *sdp); #ifdef __cplusplus } -- cgit v1.2.3