You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
142 lines
5.6 KiB
C
142 lines
5.6 KiB
C
/***************************************************************************//**
|
|
* @file usart2_it.c
|
|
* @brief UART with interrupt and ring buffer
|
|
*//****************************************************************************/
|
|
|
|
#include "stm32f4xx_hal.h"
|
|
//------------------------------C library---------------------------------------
|
|
#include <stdlib.h>
|
|
//----------------------------user includes-------------------------------------
|
|
#include "usart2_it.h"
|
|
#include "usart2_it_cfg.h"
|
|
//------------------------------------------------------------------------------
|
|
|
|
|
|
|
|
|
|
/* Private typedefs ----------------------------------------------------------*/
|
|
|
|
/* Private macros ------------------------------------------------------------*/
|
|
|
|
//====== UART buffer defines ===================================================
|
|
#define USART2_RXBUF_MASK (USART2_RXBUF_SIZE - 1)
|
|
#define USART2_TXBUF_MASK (USART2_TXBUF_SIZE - 1)
|
|
|
|
#if ( USART2_RXBUF_SIZE & USART2_RXBUF_MASK )
|
|
#error RX buffer size is not a power of 2!
|
|
#endif
|
|
|
|
#if ( USART2_TXBUF_SIZE & USART2_TXBUF_MASK )
|
|
#error TX buffer size is not a power of 2!
|
|
#endif
|
|
|
|
|
|
/* Private variables ---------------------------------------------------------*/
|
|
|
|
//====== Variables for transmitter =============================================
|
|
static uint8_t Usart2TxBuf[USART2_TXBUF_SIZE];
|
|
static uint16_t Usart2TxWrIdx = 0;
|
|
static volatile uint16_t Usart2TxRdIdx = 0;
|
|
|
|
//====== Variables for Receiver ================================================
|
|
static uint8_t Usart2RxBuf[USART2_RXBUF_SIZE];
|
|
static volatile uint16_t Usart2RxWrIdx = 0;
|
|
static volatile uint16_t Usart2RxRdIdx = 0;
|
|
|
|
|
|
/* Public variables ----------------------------------------------------------*/
|
|
|
|
|
|
/* Functions -----------------------------------------------------------------*/
|
|
|
|
|
|
/***************************************************************************//**
|
|
* @brief USART2 init
|
|
*//****************************************************************************/
|
|
void Usart2_Init(void) {
|
|
USART2->CR1 |= USART_CR1_RXNEIE; // Enable RX interrupt
|
|
}
|
|
|
|
|
|
/***************************************************************************//**
|
|
* @brief USART2 interrupt handler
|
|
*//****************************************************************************/
|
|
void USART2_IRQHandler(void) {
|
|
uint32_t statusreg = USART2->SR; // read interrupt flags
|
|
|
|
if ((statusreg & USART_SR_RXNE)) { // RX interrupt
|
|
uint8_t d = USART2->DR; // read received byte
|
|
uint_fast16_t wr = Usart2RxWrIdx;
|
|
wr = (wr + 1) & USART2_RXBUF_MASK; // new write index
|
|
Usart2RxBuf[wr] = d; // received data to buffer
|
|
Usart2RxWrIdx = wr; // Store new index
|
|
}
|
|
|
|
if ((statusreg & USART_SR_TXE)) { // TX interrupt
|
|
uint_fast16_t rd = Usart2TxRdIdx;
|
|
uint_fast16_t wr = Usart2TxWrIdx;
|
|
if (wr != rd) { // data in buffer
|
|
rd = (rd + 1) & USART2_TXBUF_MASK; // new read index
|
|
USART2->DR = Usart2TxBuf[rd]; // send data byte
|
|
Usart2TxRdIdx = rd; // Store new index
|
|
if (wr == rd) { // data buffer empty
|
|
USART2->CR1 &= ~USART_CR1_TXEIE; // INT disable
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
/***************************************************************************//**
|
|
* @brief Send byte to UART
|
|
* @param d: byte to send
|
|
*//****************************************************************************/
|
|
void Usart2_PutByte(uint8_t d) {
|
|
uint_fast16_t wr = Usart2TxWrIdx;
|
|
wr = (wr + 1) & USART2_TXBUF_MASK; // new write index
|
|
if (wr == Usart2TxRdIdx) { // No free space in buffer (overflow)
|
|
return; // drop remaining data (Attention! Buffer overflow not signaled! Use bigger buffer)
|
|
}
|
|
Usart2TxBuf[wr] = d; // Store data in buffer
|
|
Usart2TxWrIdx = wr; // Store new index
|
|
USART2->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 Usart2_PutData (void* src, uint16_t n) {
|
|
uint8_t* p = src;
|
|
uint_fast16_t wr = Usart2TxWrIdx;
|
|
while (n) {
|
|
wr = (wr + 1) & USART2_TXBUF_MASK; // new write index
|
|
if (wr == Usart2TxRdIdx) { // No free space in buffer (overflow)
|
|
break; // drop remaining data (Attention! Buffer overflow not signaled! Use bigger buffer)
|
|
}
|
|
Usart2TxBuf[wr] = *p; // Store data in buffer
|
|
p++;
|
|
n--;
|
|
}
|
|
Usart2TxWrIdx = wr; // Store new index
|
|
USART2->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 Usart2_GetByte(void) {
|
|
uint_fast16_t rd = Usart2RxRdIdx;
|
|
if (rd != Usart2RxWrIdx) { // new data in buffer
|
|
rd = (rd + 1) & USART2_RXBUF_MASK; // new read index
|
|
Usart2RxRdIdx = rd; // store new index
|
|
return Usart2RxBuf[rd]; // return with data
|
|
}else {
|
|
return -1; // buffer empty
|
|
}
|
|
}
|
|
|