/***************************************************************************//** * @file usart1_it.c * @brief UART with interrupt and ring buffer (USART1) *//****************************************************************************/ #include "stm32f4xx_hal.h" //------------------------------C library--------------------------------------- #include //----------------------------user includes------------------------------------- #include "usart1_it.h" #include "usart1_it_cfg.h" //------------------------------------------------------------------------------ /* Private typedefs ----------------------------------------------------------*/ /* Private macros ------------------------------------------------------------*/ //====== UART buffer defines =================================================== #define USART1_RXBUF_MASK (USART1_RXBUF_SIZE - 1) #define USART1_TXBUF_MASK (USART1_TXBUF_SIZE - 1) #if ( USART1_RXBUF_SIZE & USART1_RXBUF_MASK ) #error RX buffer size is not a power of 2! #endif #if ( USART1_TXBUF_SIZE & USART1_TXBUF_MASK ) #error TX buffer size is not a power of 2! #endif /* Private variables ---------------------------------------------------------*/ //====== Variables for transmitter ============================================= static uint8_t Usart1TxBuf[USART1_TXBUF_SIZE]; static uint16_t Usart1TxWrIdx = 0; static volatile uint16_t Usart1TxRdIdx = 0; //====== Variables for Receiver ================================================ static uint8_t Usart1RxBuf[USART1_RXBUF_SIZE]; static volatile uint16_t Usart1RxWrIdx = 0; static volatile uint16_t Usart1RxRdIdx = 0; /* Public variables ----------------------------------------------------------*/ /* Functions -----------------------------------------------------------------*/ /***************************************************************************//** * @brief USART1 init *//****************************************************************************/ void Usart1_Init(void) { USART1->CR1 |= USART_CR1_RXNEIE; // Enable RX interrupt } /***************************************************************************//** * @brief USART1 interrupt handler *//****************************************************************************/ void USART1_IRQHandler(void) { uint32_t statusreg = USART1->SR; // read interrupt flags if ((statusreg & USART_SR_RXNE)) { // RX interrupt uint8_t d = USART1->DR; // read received byte uint_fast16_t wr = Usart1RxWrIdx; wr = (wr + 1) & USART1_RXBUF_MASK; // new write index Usart1RxBuf[wr] = d; // received data to buffer Usart1RxWrIdx = wr; // Store new index } if ((statusreg & USART_SR_TXE)) { // TX interrupt uint_fast16_t rd = Usart1TxRdIdx; uint_fast16_t wr = Usart1TxWrIdx; if (wr != rd) { // data in buffer rd = (rd + 1) & USART1_TXBUF_MASK; // new read index USART1->DR = Usart1TxBuf[rd]; // send data byte Usart1TxRdIdx = rd; // Store new index } if (wr == rd) { // data buffer empty USART1->CR1 &= ~USART_CR1_TXEIE; // INT disable } } } /***************************************************************************//** * @brief Send byte to UART * @param d: byte to send *//****************************************************************************/ void Usart1_PutByte(uint8_t d) { uint_fast16_t wr = Usart1TxWrIdx; wr = (wr + 1) & USART1_TXBUF_MASK; // new write index if (wr == Usart1TxRdIdx) { // No free space in buffer (overflow) return; // drop remaining data (Attention! Buffer overflow not signaled! Use bigger buffer) } Usart1TxBuf[wr] = d; // Store data in buffer Usart1TxWrIdx = wr; // Store new index USART1->CR1 |= USART_CR1_TXEIE; // Interrupt enable (start send) } /***************************************************************************//** * @brief Send more data to UART * @param src: data to send * @param n: count of data *//****************************************************************************/ void Usart1_PutData (void* src, uint16_t n) { uint8_t* p = src; uint_fast16_t wr = Usart1TxWrIdx; while (n) { wr = (wr + 1) & USART1_TXBUF_MASK; // new write index if (wr == Usart1TxRdIdx) { // No free space in buffer (overflow) break; // drop remaining data (Attention! Buffer overflow not signaled! Use bigger buffer) } Usart1TxBuf[wr] = *p; // Store data in buffer p++; n--; } Usart1TxWrIdx = wr; // Store new index USART1->CR1 |= USART_CR1_TXEIE; // Interrupt enable (start send) } /***************************************************************************//** * @brief Read data from UART RX buffer * @return received character, -1: no data in RX buffer *//****************************************************************************/ int16_t Usart1_GetByte(void) { uint_fast16_t rd = Usart1RxRdIdx; if (rd != Usart1RxWrIdx) { // new data in buffer rd = (rd + 1) & USART1_RXBUF_MASK; // new read index Usart1RxRdIdx = rd; // store new index return Usart1RxBuf[rd]; // return with data }else { return -1; // buffer empty } }