You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 

223 lines
5.7 KiB

#include "zuart.hpp"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
using namespace iflytop;
static ZUART *s_uart_table[10];
static int s_numUart;
static void prv_reg_uart(ZUART *uart) {
if (s_numUart < 10) {
s_uart_table[s_numUart++] = uart;
}
}
ZUART *prv_find_uart(UART_HandleTypeDef *huart) {
for (int i = 0; i < s_numUart; i++) {
if (s_uart_table[i]->getHuart() == huart) {
return s_uart_table[i];
}
}
return NULL;
}
extern "C" {
void HAL_UART_TxCpltCallback(UART_HandleTypeDef *huart) {
ZUART *stm32uart = prv_find_uart(huart);
if (stm32uart != NULL) stm32uart->HAL_UART_TxCpltCallback();
}
void HAL_UART_TxHalfCpltCallback(UART_HandleTypeDef *huart) {
ZUART *stm32uart = prv_find_uart(huart);
if (stm32uart != NULL) stm32uart->HAL_UART_TxHalfCpltCallback();
}
void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart) {
ZUART *stm32uart = prv_find_uart(huart);
if (stm32uart != NULL) stm32uart->HAL_UART_RxCpltCallback();
}
void HAL_UART_RxHalfCpltCallback(UART_HandleTypeDef *huart) {
ZUART *stm32uart = prv_find_uart(huart);
if (stm32uart != NULL) stm32uart->HAL_UART_RxHalfCpltCallback();
}
void HAL_UART_ErrorCallback(UART_HandleTypeDef *huart) {
ZUART *stm32uart = prv_find_uart(huart);
if (stm32uart != NULL) stm32uart->HAL_UART_ErrorCallback();
}
void HAL_UART_AbortCpltCallback(UART_HandleTypeDef *huart) {
ZUART *stm32uart = prv_find_uart(huart);
if (stm32uart != NULL) stm32uart->HAL_UART_AbortCpltCallback();
}
void HAL_UART_AbortTransmitCpltCallback(UART_HandleTypeDef *huart) {
ZUART *stm32uart = prv_find_uart(huart);
if (stm32uart != NULL) stm32uart->HAL_UART_AbortTransmitCpltCallback();
}
void HAL_UART_AbortReceiveCpltCallback(UART_HandleTypeDef *huart) {
ZUART *stm32uart = prv_find_uart(huart);
if (stm32uart != NULL) stm32uart->HAL_UART_AbortReceiveCpltCallback();
}
}
IRQn_Type ZUART::getUartIRQType() {
#ifdef USART1
if (m_huart->Instance == USART1) {
return USART1_IRQn;
}
#endif
#ifdef USART2
if (m_huart->Instance == USART2) {
return USART2_IRQn;
}
#endif
#ifdef USART3
if (m_huart->Instance == USART3) {
return USART3_IRQn;
}
#endif
#ifdef UART4
if (m_huart->Instance == UART4) {
return UART4_IRQn;
}
#endif
#ifdef UART5
if (m_huart->Instance == UART5) {
return UART5_IRQn;
}
#endif
#ifdef USART6
if (m_huart->Instance == USART6) {
return USART6_IRQn;
}
#endif
ZEARLY_ASSERT(false);
return USART1_IRQn;
}
void ZUART::initialize(cfg_t *cfg, callback_t cb) {
m_name = cfg->name;
m_huart = cfg->huart;
m_cb = cb;
m_rxovertime_ms = cfg->rxovertime_ms;
m_rxBuffer = (uint8_t *)malloc(cfg->rxbuffersize);
memset(m_rxBuffer, 0, cfg->rxbuffersize);
ZEARLY_ASSERT(m_rxBuffer != NULL);
m_rxBufferLen = cfg->rxbuffersize;
m_isRxing = false;
m_dataIsReady = false;
m_rxBufferPos = 0;
m_lastRxTime = 0;
onebyte = 0;
ChipTimIrqShceduler::instance().regPeriodJob([this](ChipTimIrqShceduler::Job *job) { periodicJob(); }, 1);
prv_reg_uart(this);
}
void ZUART::initialize(cfg_t *cfg) { initialize(cfg, NULL); }
bool ZUART::tx(uint8_t *data, size_t len) {
HAL_UART_Transmit(m_huart, data, len, 0xffff);
return true;
}
bool ZUART::tx(const char *data) {
HAL_UART_Transmit(m_huart, (uint8_t *)data, strlen(data), 0xffff);
return true;
}
bool ZUART::startRxIt() {
ZEARLY_ASSERT(m_rxBuffer != NULL);
ZEARLY_ASSERT(NVIC_GetEnableIRQ(getUartIRQType()) != 0);
if (m_isRxing) return true;
m_isRxing = true;
HAL_UART_Receive_IT(m_huart, &onebyte, 1);
return true;
}
bool ZUART::dataIsReady() {
// CriticalContext criticalContext;
if (m_dataIsReady) {
return true;
}
if (!m_dataIsReady && m_rxBufferPos != 0) {
if (zchip_clock_hasspassed(m_lastRxTime) > (uint32_t)m_rxovertime_ms) {
m_dataIsReady = true;
return true;
}
}
return false;
}
void ZUART::clearRxData() {
// ZCriticalContext criticalContext;
m_dataIsReady = false;
memset(m_rxBuffer, 0, m_rxBufferLen);
m_rxBufferPos = 0;
}
void ZUART::periodicJob() {
if (dataIsReady()) {
if (m_cb) {
m_cb(m_rxBuffer, m_rxBufferPos);
}
clearRxData();
}
if (m_isRxing) {
if (!(HAL_UART_GetState(m_huart) == HAL_UART_STATE_BUSY_RX || HAL_UART_GetState(m_huart) == HAL_UART_STATE_BUSY_TX_RX)) {
HAL_UART_Receive_IT(m_huart, &onebyte, 1);
}
}
}
/*******************************************************************************
* 中断 *
*******************************************************************************/
void ZUART::HAL_UART_TxCpltCallback() {}
void ZUART::HAL_UART_TxHalfCpltCallback() {}
void ZUART::HAL_UART_RxCpltCallback() {
if (m_dataIsReady) {
HAL_UART_Receive_IT(m_huart, &onebyte, 1);
return;
}
m_rxBuffer[m_rxBufferPos] = onebyte;
m_rxBufferPos++;
m_lastRxTime = zchip_clock_get_ticket();
if (m_rxBufferPos >= m_rxBufferLen) {
m_dataIsReady = true;
}
HAL_UART_Receive_IT(m_huart, &onebyte, 1);
}
void ZUART::HAL_UART_RxHalfCpltCallback() {}
void ZUART::HAL_UART_ErrorCallback() {
HAL_UART_AbortReceive_IT(m_huart);
HAL_UART_Receive_IT(m_huart, &onebyte, 1);
}
void ZUART::HAL_UART_AbortCpltCallback() {}
void ZUART::HAL_UART_AbortTransmitCpltCallback() {}
void ZUART::HAL_UART_AbortReceiveCpltCallback() {}
namespace iflytop {
#if 0
#ifdef USART1
ZUART STM32_UART1("uart1", USART1);
#endif
#ifdef USART2
ZUART STM32_UART2("uart2", USART2);
#endif
#ifdef USART3
ZUART STM32_UART3("uart3", USART3);
#endif
#ifdef UART4
ZUART STM32_UART4("uart4", UART4);
#endif
#ifdef UART5
ZUART STM32_UART5("uart5", UART5);
#endif
#ifdef USART6
ZUART STM32_UART6("uart6", USART6);
#endif
#endif
} // namespace iflytop