STM32GENERIC/STM32/cores/arduino/stm32/SerialUART.cpp

207 lines
4.9 KiB
C++
Raw Normal View History

2017-04-14 13:43:17 -07:00
/**
* TODO: Check if txBuffer is NULL in every method
* TODO: generate different BUFFER_SIZE values for different boards based on available memory
* TODO: add alternate pin selection functions
* TODO: add constructor with custom buffer parameter
*/
2017-04-09 21:55:07 -07:00
#include "SerialUART.h"
2017-04-11 11:16:14 -07:00
#include "stm32_gpio_af.h"
2017-04-09 21:55:07 -07:00
2017-04-14 13:43:17 -07:00
/**
* Set the underlying UART instance.
*/
2017-04-09 21:55:07 -07:00
SerialUART::SerialUART(USART_TypeDef *instance) {
this->instance = instance;
}
2017-04-14 13:43:17 -07:00
/**
* Arduino always instantiates the Serial object.
*
* To save memory, this implementation will:
* - not use any memory if begin() is never called
* - use statically allocated memory, if begin() is called exactly in one SerialUARTs.
* - use statically allocated memory for the first, and malloc() for any subsequent calls to begin() on DIFFERENT SerialUARTs.
*/
2017-04-09 21:55:07 -07:00
void SerialUART::begin(const uint32_t baud) {
2017-04-14 13:43:17 -07:00
if (txBuffer == NULL) {
static uint8_t tx[BUFFER_SIZE];
static uint8_t static_tx_used = 0;
if (!static_tx_used) {
txBuffer = (uint8_t*)tx;
static_tx_used = true;
} else {
txBuffer = (uint8_t*)malloc(BUFFER_SIZE);
}
}
if (rxBuffer == NULL) {
static uint8_t rx[BUFFER_SIZE];
static uint8_t static_rx_used = 0;
if (!static_rx_used) {
txBuffer = (uint8_t*)rx;
static_rx_used = true;
} else {
rxBuffer = (uint8_t*)malloc(BUFFER_SIZE);
}
}
if (handle == NULL) {
static UART_HandleTypeDef h = {};
static uint8_t static_handle_used = 0;
if (!static_handle_used) {
handle = &h;
static_handle_used = true;
} else {
handle = (UART_HandleTypeDef*)malloc(sizeof(UART_HandleTypeDef));
}
}
2017-04-09 21:55:07 -07:00
handle->Instance = instance;
#ifdef USART1
if (handle->Instance == USART1) {
__HAL_RCC_USART1_CLK_ENABLE();
HAL_NVIC_SetPriority(USART1_IRQn, 0, 0);
HAL_NVIC_EnableIRQ(USART1_IRQn);
}
#endif
#ifdef USART2
if (handle->Instance == USART2) {
__HAL_RCC_USART2_CLK_ENABLE();
HAL_NVIC_SetPriority(USART2_IRQn, 0, 0);
HAL_NVIC_EnableIRQ(USART2_IRQn);
}
#endif
#ifdef USART3
if (handle->Instance == USART3) {
__HAL_RCC_USART3_CLK_ENABLE();
HAL_NVIC_SetPriority(USART3_IRQn, 0, 0);
HAL_NVIC_EnableIRQ(USART3_IRQn);
}
#endif
#ifdef USART4
if (handle->Instance == USART4) {
__HAL_RCC_USART4_CLK_ENABLE();
HAL_NVIC_SetPriority(USART4_IRQn, 0, 0);
HAL_NVIC_EnableIRQ(USART4_IRQn);
}
#endif
stm32AfUARTInit(instance, rxPort, rxPin, txPort, txPin);
2017-04-09 21:55:07 -07:00
handle->Init.BaudRate = baud;
handle->Init.WordLength = UART_WORDLENGTH_8B;
handle->Init.StopBits = UART_STOPBITS_1;
handle->Init.Parity = UART_PARITY_NONE;
handle->Init.Mode = UART_MODE_TX_RX;
handle->Init.HwFlowCtl = UART_HWCONTROL_NONE;
handle->Init.OverSampling = UART_OVERSAMPLING_16;
HAL_UART_Init(handle);
HAL_UART_Receive_IT(handle, &receive_buffer, 1);
}
int SerialUART::available() {
return rxEnd != rxStart;
}
int SerialUART::peek() {
if (available()) {
return rxBuffer[rxStart % BUFFER_SIZE];
} else {
return -1;
}
}
void SerialUART::flush() {
}
int SerialUART::read() {
if (available()) {
return rxBuffer[rxStart++ % BUFFER_SIZE];
} else {
return -1;
}
}
size_t SerialUART::write(const uint8_t c) {
while((txEnd + 1) % BUFFER_SIZE == txStart % BUFFER_SIZE);
2017-04-09 21:55:07 -07:00
txBuffer[txEnd % BUFFER_SIZE] = c;
txEnd++;
if (txEnd == txStart + 1) {
HAL_UART_Transmit_IT(handle, &txBuffer[txStart % BUFFER_SIZE], 1);
}
return 1;
}
void SerialUART::stm32SetRX(uint8_t rx) {
rxPort = variant_pin_list[rx].port;
rxPin = variant_pin_list[rx].pin_mask;
}
void SerialUART::stm32SetTX(uint8_t tx) {
txPort = variant_pin_list[tx].port;
txPin = variant_pin_list[tx].pin_mask;
}
2017-04-09 21:55:07 -07:00
//// Interrupt
SerialUART *interruptUART;
#ifdef USART1
extern "C" void USART1_IRQHandler(void) {
interruptUART = &SerialUART1;
HAL_UART_IRQHandler(interruptUART->handle);
}
SerialUART SerialUART1(USART1);
#endif
#ifdef USART2
extern "C" void USART2_IRQHandler(void) {
interruptUART = &SerialUART2;
HAL_UART_IRQHandler(interruptUART->handle);
}
SerialUART SerialUART2(USART2);
#endif
#ifdef USART3
extern "C" void USART3_IRQHandler(void) {
interruptUART = &SerialUART3;
HAL_UART_IRQHandler(interruptUART->handle);
}
SerialUART SerialUART3(USART3);
#endif
#ifdef USART4
extern "C" void USART4_IRQHandler(void) {
interruptUART = &SerialUART4;
HAL_UART_IRQHandler(interruptUART->handle);
}
SerialUART SerialUART4(USART4);
#endif
extern "C" void HAL_UART_TxCpltCallback(UART_HandleTypeDef *huart) {
interruptUART->txStart++;
if (interruptUART->txStart != interruptUART->txEnd) {
HAL_UART_Transmit_IT(interruptUART->handle, &interruptUART->txBuffer[interruptUART->txStart % BUFFER_SIZE], 1);
}
}
extern "C" void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart) {
interruptUART->rxBuffer[interruptUART->rxEnd % BUFFER_SIZE] = interruptUART->receive_buffer;
interruptUART->rxEnd++;
HAL_UART_Receive_IT(interruptUART->handle, &interruptUART->receive_buffer, 1);
}