/** * @brief RX DMA common service routine. * * @param[in] uartp pointer to the @p UARTDriver object * @param[in] flags pre-shifted content of the ISR register */ static void uart_lld_serve_rx_end_irq(UARTDriver *uartp, uint32_t flags) { /* DMA errors handling.*/ #if defined(STM32_UART_DMA_ERROR_HOOK) if ((flags & (STM32_DMA_ISR_TEIF | STM32_DMA_ISR_DMEIF)) != 0) { STM32_UART_DMA_ERROR_HOOK(uartp); } #else (void)flags; #endif if (uartp->rxstate == UART_RX_IDLE) { /* Receiver in idle state, a callback is generated, if enabled, for each received character and then the driver stays in the same state.*/ if (uartp->config->rxchar_cb != NULL) uartp->config->rxchar_cb(uartp, uartp->rxbuf); } else { /* Receiver in active state, a callback is generated, if enabled, after a completed transfer.*/ dmaStreamDisable(uartp->dmarx); uartp->rxstate = UART_RX_COMPLETE; if (uartp->config->rxend_cb != NULL) uartp->config->rxend_cb(uartp); /* If the callback didn't explicitly change state then the receiver automatically returns to the idle state.*/ if (uartp->rxstate == UART_RX_COMPLETE) { uartp->rxstate = UART_RX_IDLE; set_rx_idle_loop(uartp); } } }
/** * @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) { uint32_t cr1; USART_TypeDef *u = uartp->usart; /* Defensive programming, starting from a clean state.*/ usart_stop(uartp); /* Baud rate setting.*/ u->BRR = (uint32_t)(uartp->clock / uartp->config->speed); /* Resetting eventual pending status flags.*/ u->ICR = 0xFFFFFFFFU; /* Note that some bits are enforced because required for correct driver operations.*/ u->CR2 = uartp->config->cr2 | USART_CR2_LBDIE; u->CR3 = uartp->config->cr3 | USART_CR3_DMAT | USART_CR3_DMAR | USART_CR3_EIE; /* Mustn't ever set TCIE here - if done, it causes an immediate interrupt.*/ cr1 = USART_CR1_UE | USART_CR1_PEIE | USART_CR1_TE | USART_CR1_RE; u->CR1 = uartp->config->cr1 | cr1; /* Starting the receiver idle loop.*/ set_rx_idle_loop(uartp); }
/** * @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) { uint16_t cr1; USART_TypeDef *u = uartp->usart; /* Defensive programming, starting from a clean state.*/ usart_stop(uartp); /* Baud rate setting.*/ if (uartp->usart == USART1) u->BRR = STM32_PCLK2 / uartp->config->speed; else u->BRR = STM32_PCLK1 / uartp->config->speed; /* Resetting eventual pending status flags.*/ (void)u->SR; /* SR reset step 1.*/ (void)u->DR; /* SR reset step 2.*/ u->SR = 0; /* Note that some bits are enforced because required for correct driver operations.*/ if (uartp->config->txend2_cb == NULL) cr1 = USART_CR1_UE | USART_CR1_PEIE | USART_CR1_TE | USART_CR1_RE; else cr1 = USART_CR1_UE | USART_CR1_PEIE | USART_CR1_TE | USART_CR1_RE | USART_CR1_TCIE; u->CR1 = uartp->config->cr1 | cr1; u->CR2 = uartp->config->cr2 | USART_CR2_LBDIE; u->CR3 = uartp->config->cr3 | USART_CR3_DMAT | USART_CR3_DMAR | USART_CR3_EIE; /* Starting the receiver idle loop.*/ set_rx_idle_loop(uartp); }
/** * @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 * * @return The number of data frames not received by the * stopped receive operation. * * @notapi */ size_t uart_lld_stop_receive(UARTDriver *uartp) { size_t n; dmaStreamDisable(uartp->dmarx); n = dmaStreamGetTransactionSize(uartp->dmarx); set_rx_idle_loop(uartp); return n; }
/** * @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) { uint16_t cr1; USART_TypeDef *u = uartp->usart; /* Defensive programming, starting from a clean state.*/ usart_stop(uartp); /* Baud rate setting.*/ #if STM32_HAS_USART6 if ((uartp->usart == USART1) || (uartp->usart == USART6)) #else if (uartp->usart == USART1) #endif u->BRR = STM32_PCLK2 / uartp->config->speed; else u->BRR = STM32_PCLK1 / uartp->config->speed; /* Resetting eventual pending status flags.*/ (void)u->SR; /* SR reset step 1.*/ (void)u->DR; /* SR reset step 2.*/ u->SR = 0; /* Note that some bits are enforced because required for correct driver operations.*/ u->CR2 = uartp->config->cr2 | USART_CR2_LBDIE; u->CR3 = uartp->config->cr3 | USART_CR3_DMAT | USART_CR3_DMAR | USART_CR3_EIE; /* Mustn't ever set TCIE here - if done, it causes an immediate interrupt.*/ cr1 = USART_CR1_UE | USART_CR1_PEIE | USART_CR1_TE | USART_CR1_RE; u->CR1 = uartp->config->cr1 | cr1; /* Starting the receiver idle loop.*/ set_rx_idle_loop(uartp); }