#include "zuart.hpp" #include #include #include "critical_context.hpp" #include "malloc.h" #include "zhal_core.hpp" 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 ZASSERT(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); ZASSERT(m_rxBuffer != NULL); m_rxBufferLen = cfg->rxbuffersize; m_isRxing = false; m_dataIsReady = false; m_rxBufferPos = 0; m_lastRxTime = 0; onebyte = 0; ZHALCORE::getInstance()->regPeriodJob([this](ZHALCORE::Context &context) { 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() { ZASSERT(m_rxBuffer != NULL); ZASSERT(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 (ifly_has_passedms(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(); } } /******************************************************************************* * 中断 * *******************************************************************************/ 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 = chip_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