Browse Source

修复串口 触发异常中断后 不停的进入中断的BUG

master
zhaohe 2 months ago
parent
commit
85aebbf926
  1. 49
      sdk/chip/exhal/stm32_exhal_uart.cpp
  2. 2
      sdk/chip/exhal/stm32_exhal_uart.hpp
  3. 1
      sdk/chip/irq_dispatcher/zuart_irq_dispatcher.cpp
  4. 64
      sdk/components/pipette_module/pipette_ctrl_module.cpp
  5. 3
      sdk/components/pipette_module/pipette_ctrl_module.hpp
  6. 1
      sdk/components/pipette_module/pipette_ctrl_module_utils.cpp
  7. 14
      sdk/components/sensors/smtp2_v2/smtp2_v2.cpp
  8. 25
      sdk/components/sensors/smtp2_v2/smtp2_v2.hpp
  9. 48
      sdk/components/sensors/smtp2_v2/smtp_pressure_stream_processer.hpp
  10. 1
      sdk/components/zcan_protocol_parser/zcan_protocol_parser.cpp
  11. 8
      usrc/subboards/subboard80_cliptip/subboard80_cliptip_board.c

49
sdk/chip/exhal/stm32_exhal_uart.cpp

@ -14,6 +14,7 @@ typedef enum {
RECEIVE_TO_IDLE_DMA,
AUTO_READ_DMA,
AUTO_READ_IT,
AUTO_READ_IT_ONE_BYTE,
} HAL_EX_UART_RX_STATE_T;
typedef struct {
@ -101,10 +102,27 @@ static inline void processWhenAutoReadIT(EXHAL_UART_t* huart, ZUartIrqDispatcher
HAL_UARTEx_ReceiveToIdle_IT(huart->huart, huart->autoRxBuffer, sizeof(huart->autoRxBuffer));
}
} else if (event == ZUartIrqDispatcher::UART_IRQ_Error) {
__HAL_UART_CLEAR_PEFLAG(huart->huart);
HAL_UARTEx_ReceiveToIdle_IT(huart->huart, huart->autoRxBuffer, sizeof(huart->autoRxBuffer));
}
}
static inline void processWhenAutoReadOneByteIT(EXHAL_UART_t* huart, ZUartIrqDispatcher::IRQType event, int size) {
// printf("rx: %d size:%d\n", event, size);
// if (huart->huart == &huart3) printf("%d",event);
if (event == ZUartIrqDispatcher::UART_IRQ_RxCplt) {
HAL_UART_Receive_IT(huart->huart, huart->autoRxBuffer, 1);
huart->autoRxSize = 1;
uint8_t rx = huart->autoRxBuffer[0];
if (huart->listener) {
huart->listener(huart->huart, &rx, huart->autoRxSize);
}
} else if (event == ZUartIrqDispatcher::UART_IRQ_Error) {
__HAL_UART_CLEAR_PEFLAG(huart->huart);
HAL_UART_Receive_IT(huart->huart, huart->autoRxBuffer, 1);
}
}
void EXHAL_UART_OnUartIrq(UART_HandleTypeDef* huart, ZUartIrqDispatcher::IRQType event, int size) {
EXHAL_UART_t* exhal_uart = EXHAL_UART_Get(huart);
if (exhal_uart == NULL) return;
@ -124,6 +142,9 @@ void EXHAL_UART_OnUartIrq(UART_HandleTypeDef* huart, ZUartIrqDispatcher::IRQType
case AUTO_READ_IT:
processWhenAutoReadIT(exhal_uart, event, size);
break;
case AUTO_READ_IT_ONE_BYTE:
processWhenAutoReadOneByteIT(exhal_uart, event, size);
break;
default:
break;
}
@ -183,14 +204,14 @@ void EXHAL_UART_RS485_EnTx(UART_HandleTypeDef* huart, bool en) {
HAL_StatusTypeDef EXHAL_UART_RegListener(UART_HandleTypeDef* huart, EXHAL_UART_Listener_t listener) {
EXHAL_UART_t* exhal_uart = EXHAL_UART_Get(huart);
ZEARLY_ASSERT(exhal_uart != NULL);
exhal_uart->listener = listener;
exhal_uart->listener = listener;
return HAL_OK;
}
HAL_StatusTypeDef EXHAL_UART_TransmitBlock_DMA(UART_HandleTypeDef* huart, uint8_t* data, size_t len) {
EXHAL_UART_t* exhal_uart = EXHAL_UART_Get(huart);
ZEARLY_ASSERT(exhal_uart != NULL);
exhal_uart->rxstate = TRANSMIT_BLOCK_DMA;
exhal_uart->rxstate = TRANSMIT_BLOCK_DMA;
HAL_StatusTypeDef ret = HAL_UART_Transmit_DMA(huart, data, len);
if (ret != HAL_OK) {
@ -204,8 +225,8 @@ HAL_StatusTypeDef EXHAL_UART_TransmitBlock_DMA(UART_HandleTypeDef* huart, uint8_
return HAL_OK;
}
HAL_StatusTypeDef EXHAL_UART_TransmitStringBlock(UART_HandleTypeDef* huart, const char* data){//
return HAL_UART_Transmit(huart, (uint8_t*)data, strlen(data),100);
HAL_StatusTypeDef EXHAL_UART_TransmitStringBlock(UART_HandleTypeDef* huart, const char* data) { //
return HAL_UART_Transmit(huart, (uint8_t*)data, strlen(data), 100);
}
static void __attribute__((noinline)) clearUartRxCache(UART_HandleTypeDef* huart) { //
@ -263,7 +284,7 @@ HAL_StatusTypeDef EXHAL_UART_DMAStartAutoRead(UART_HandleTypeDef* huart) {
EXHAL_UART_t* exhal_uart = EXHAL_UART_Get(huart);
ZEARLY_ASSERT(exhal_uart != NULL);
exhal_uart->rxstate = AUTO_READ_DMA;
exhal_uart->rxstate = AUTO_READ_DMA;
HAL_UARTEx_ReceiveToIdle_DMA_force(huart, exhal_uart->autoRxBuffer, sizeof(exhal_uart->autoRxBuffer));
__HAL_DMA_DISABLE_IT(huart->hdmarx, DMA_IT_HT);
@ -301,7 +322,7 @@ HAL_StatusTypeDef EXHAL_UART_ITStartAutoRead(UART_HandleTypeDef* huart) {
EXHAL_UART_t* exhal_uart = EXHAL_UART_Get(huart);
ZEARLY_ASSERT(exhal_uart != NULL);
exhal_uart->rxstate = AUTO_READ_IT;
exhal_uart->rxstate = AUTO_READ_IT;
while (true) {
HAL_StatusTypeDef ret = HAL_UARTEx_ReceiveToIdle_IT(huart, exhal_uart->autoRxBuffer, sizeof(exhal_uart->autoRxBuffer));
@ -310,6 +331,22 @@ HAL_StatusTypeDef EXHAL_UART_ITStartAutoRead(UART_HandleTypeDef* huart) {
}
return HAL_OK;
}
HAL_StatusTypeDef EXHAL_UART_ITStartAutoReadOneByte(UART_HandleTypeDef* huart) {
clearUartRxCache(huart);
EXHAL_UART_t* exhal_uart = EXHAL_UART_Get(huart);
ZEARLY_ASSERT(exhal_uart != NULL);
exhal_uart->rxstate = AUTO_READ_IT_ONE_BYTE;
while (true) {
HAL_StatusTypeDef ret = HAL_UART_Receive_IT(huart, exhal_uart->autoRxBuffer, 1);
if (ret == HAL_OK) break;
HAL_UART_AbortReceive(huart);
}
return HAL_OK;
}
HAL_StatusTypeDef EXHAL_UART_ITStopAutoRead(UART_HandleTypeDef* huart) {
if (huart == NULL) {
return HAL_ERROR;

2
sdk/chip/exhal/stm32_exhal_uart.hpp

@ -23,7 +23,6 @@ void EXHAL_UART_RS485_EnTx(UART_HandleTypeDef* huart, bool en);
HAL_StatusTypeDef EXHAL_UART_TransmitBlock_DMA(UART_HandleTypeDef* huart, uint8_t* data, size_t len);
HAL_StatusTypeDef EXHAL_UART_TransmitStringBlock(UART_HandleTypeDef* huart, const char* data);
// rx blcok
HAL_StatusTypeDef EXHAL_UARTEx_ReceiveToIdle_DMA_Start(UART_HandleTypeDef* huart, uint8_t* data, int32_t len);
HAL_StatusTypeDef EXHAL_UARTEx_ReceiveToIdle_DMA_Wait(UART_HandleTypeDef* huart, size_t* rxlen, int32_t overtime);
@ -35,4 +34,5 @@ HAL_StatusTypeDef EXHAL_UART_DMAStartAutoRead(UART_HandleTypeDef* huart);
HAL_StatusTypeDef EXHAL_UART_DMAStopAutoRead(UART_HandleTypeDef* huart);
HAL_StatusTypeDef EXHAL_UART_ITStartAutoRead(UART_HandleTypeDef* huart);
HAL_StatusTypeDef EXHAL_UART_ITStartAutoReadOneByte(UART_HandleTypeDef* huart);
HAL_StatusTypeDef EXHAL_UART_ITStopAutoRead(UART_HandleTypeDef* huart);

1
sdk/chip/irq_dispatcher/zuart_irq_dispatcher.cpp

@ -21,6 +21,7 @@ void HAL_UART_RxHalfCpltCallback(UART_HandleTypeDef *huart) { //
}
void HAL_UART_ErrorCallback(UART_HandleTypeDef *huart) { //
ZUartIrqDispatcher::callOnUartIrq(ZUartIrqDispatcher::UART_IRQ_Error, huart, 0);
__HAL_UART_CLEAR_PEFLAG(huart);
}
void HAL_UART_AbortCpltCallback(UART_HandleTypeDef *huart) { //
ZUartIrqDispatcher::callOnUartIrq(ZUartIrqDispatcher::UART_IRQ_AbortCplt, huart, 0);

64
sdk/components/pipette_module/pipette_ctrl_module.cpp

@ -25,56 +25,32 @@ void PipetteModule::initialize(int32_t id, hardward_config_t *hardwaredcfg) { /
m_zm->getGState(); // 读取状态,清空下复位标识
m_piette_gun_io1.initAsInput(hardwaredcfg->IO1, ZGPIO::kMode_pullup, ZGPIO::kIRQ_noIrq, hardwaredcfg->IO1Mirror);
ZASSERT(hardwaredcfg->uart232);
EXHAL_UART_BindUart("pipette-uart232", hardwaredcfg->uart232);
EXHAL_UART_RegListener(hardwaredcfg->uart232, [this](UART_HandleTypeDef *huart, uint8_t *data, size_t len) {
printf("!rx(%d): ", len);
if (len > 0) {
printf("%c", data[0]);
}
printf("\n");
});
EXHAL_UART_ITStartAutoRead(hardwaredcfg->uart232);
while (true) {
EXHAL_UART_TransmitStringBlock(hardwaredcfg->uart232, "/1QR\r");
osDelay(10);
}
m_smtp2.pump_set_pressure_data_stream_port(0); //
// EXHAL_UART_BindUart("pipette-uart", hardwaredcfg->uart);
// EXHAL_UART_RegListener(hardwaredcfg->uart, [this](UART_HandleTypeDef *huart, uint8_t *data, size_t len) {
// printf("!rx(%d): ", len);
// for (size_t i = 0; i < len; i++) {
// printf("%c", data[i]);
// }
// printf("\n");
// });
// EXHAL_UART_DMAStartAutoRead(hardwaredcfg->uart);
// EXHAL_UART_TransmitStringBlock(hardwaredcfg->uart, "/1QR\r");
// HAL_Delay(1000);
// EXHAL_UART_TransmitStringBlock(hardwaredcfg->uart232, "/1QR\r");
// m_smtp2.pump_factory_reset();
// osDelay(1000);
// 设置泵机压力数据流走232
m_smtp2.pump_set_pressure_data_stream_port(1);
// 测试泵机连接性
test_connectivity();
// 参数初始化
parameter_init();
// 同步参数到步进电机
zm_sync_base_cfg();
get_platinfo_smart(m_state.platinfo_cpyid, &m_now_platinfo);
int32_t maxul = 0;
// int32_t ecode = 0;
// m_smtp2.pump_set_tip_type(smtp2::TipSize_t::TS1000UL); // 默认1000ul
// m_smtp2.pump_get_max_limit(&maxul);
// ZLOGI(TAG, "1pipette gun max limit:%d", maxul);
// 读取SMTP2泵机版本
ZLOGI(TAG, "pipette gun version:%s", m_smtp2.pump_read_version());
m_smtp2.pump_set_tip_type(smtp2::TipSize_t::TS200UL); //
m_smtp2.pump_get_max_limit(&maxul);
ZLOGI(TAG, "2pipette gun max limit:%d", maxul);
// 上报压力流 ! 不能一直打开压力流,一直打开压力流,会导致SMTP2无法响应其他命令
// m_smtp2.pump_init();
// while (true) {
// int32_t isbusy = 1;
// m_smtp2.pump_get_state(&isbusy);
// if (isbusy == 0) break;
// osDelay(10);
// }
// m_smtp2.sendcmd_direct("/1f1+300A1250R\r");
ZLOGI(TAG, "pipette gun version:%s", m_smtp2.pump_read_version());
ZASSERT(hardwaredcfg->uart232);
EXHAL_UART_BindUart("pipette-uart232", hardwaredcfg->uart232);
EXHAL_UART_RegListener(hardwaredcfg->uart232, [this](UART_HandleTypeDef *huart, uint8_t *data, size_t len) { smtpPressureStreamProcesser.process_rx(data[0]); });
EXHAL_UART_ITStartAutoReadOneByte(hardwaredcfg->uart232);
}
void PipetteModule::test_connectivity() {

3
sdk/components/pipette_module/pipette_ctrl_module.hpp

@ -5,6 +5,7 @@
#include "sdk/os/zos.hpp"
#include "sdk\components\api\zi_module.hpp"
#include "sdk\components\sensors\smtp2_v2\smtp2_v2.hpp"
#include "sdk\components\sensors\smtp2_v2\smtp_pressure_stream_processer.hpp"
#include "sdk\components\tmc\basic\tmc_ic_interface.hpp"
#include "sdk\components\tmc\ic\ztmc5130.hpp"
#include "sdk\components\zcancmder\zcanreceiver.hpp"
@ -80,6 +81,8 @@ class PipetteModule : public ZIModule {
liquid_info_t m_now_liquid_info; // 当前液体信息
liquid_info_t m_now_liquid_in_gun_info; // 当前枪内液体信息
SmtpPressureStreamProcesser smtpPressureStreamProcesser;
/***********************************************************************************************************************
* Config *
***********************************************************************************************************************/

1
sdk/components/pipette_module/pipette_ctrl_module_utils.cpp

@ -177,7 +177,6 @@ void PipetteModule::dump(const char *title, distribu_all_param_t *param) {
ZLOGI(TAG, "-------------------------- %s --------------------------", title);
ZLOGI(TAG, "- container_pos: %d", param->container_pos);
ZLOGI(TAG, "- dest_container_cpyid: %d", param->dest_container_cpyid);
ZLOGI(TAG, "- dest_container_is_empty: %d", param->dest_container_is_empty);
ZLOGI(TAG, "- dest_liquid_cfg_index: %d", param->dest_liquid_cfg_index);
ZLOGI(TAG, "- distribu_type: %d", param->distribu_type);
ZLOGI(TAG, "- mix_volume: %d", param->mix_volume);

14
sdk/components/sensors/smtp2_v2/smtp2_v2.cpp

@ -11,12 +11,11 @@ using namespace smtp2;
#define TAG "SMTP2"
#define OVERTIME 100
#define DUMP_HEX 0
#define DUMP_HEX 1
#define RE_SEND_TIMES 5
#define RE_SEND_DELAY 400
#if DUMP_HEX
static const char* hex2str(const char* hex, size_t len) {
static char buf[256];
memset(buf, 0, sizeof(buf));
@ -25,7 +24,6 @@ static const char* hex2str(const char* hex, size_t len) {
}
return buf;
}
#endif
void SMTP2V2::initialize(UART_HandleTypeDef* uart, uint8_t id, DMA_HandleTypeDef* hdma_rx, DMA_HandleTypeDef* hdma_tx) {
m_uart = uart;
@ -120,7 +118,7 @@ int32_t SMTP2V2::pump_put_tip() {
}
int32_t SMTP2V2::pump_factory_reset() {
ZLOGI(TAG, "pump_factory_reset");
_sendcmd(true, "/1!22R\r"); //
_sendcmd(true, "/1!22R\r"); //
_sendcmd(true, "/1!0R\r"); // 复位指令没有回执,所以这里只能使用方法_sendcmd
_sendcmd(true, "/1!0R\r"); // 复位指令没有回执,所以这里只能使用方法_sendcmd
return 0;
@ -432,6 +430,14 @@ int32_t SMTP2V2::setstate(bool dump, const char* format, ...) {
return getAckEcode();
}
bool SMTP2V2::sendcmd_direct(const char* cmd) {
m_rxNum = 0;
ZLOGI(TAG, "tx:%s", cmd);
bool ret = _sendcmd_dma(cmd);
ZLOGI(TAG, "rx:(%d) (%s) %s", m_rxNum, hex2str(m_rxbuf, m_rxNum), m_rxbuf);
return ret;
}
bool SMTP2V2::_sendcmd(bool dump, const char* cmd) {
m_rxNum = 0;

25
sdk/components/sensors/smtp2_v2/smtp2_v2.hpp

@ -192,10 +192,10 @@ class SMTP2V2 {
***********************************************************************************************************************/
int32_t pump_set_plld_start_delay(int32_t delay_ms);
int32_t pump_set_vcfg(VelCfg* vcfg);
int32_t pump_set_io1_mode(int32_t mode); // 0LLD输出高 1LLD输出低 2通用输出
int32_t pump_set_io1_state(int32_t state); //
int32_t pump_set_io2_mode(int32_t mode); // 0通用输入 1紧急制动 2Tip脱落输出高 3Tip脱落输出低
int32_t pump_set_tip_type(TipSize_t size); // Tip大小 0:1ml 1:200ul(max:250ul) 2:50ul(max:62ul) 3=20ul(max:40ul)
int32_t pump_set_io1_mode(int32_t mode); // 0LLD输出高 1LLD输出低 2通用输出
int32_t pump_set_io1_state(int32_t state); //
int32_t pump_set_io2_mode(int32_t mode); // 0通用输入 1紧急制动 2Tip脱落输出高 3Tip脱落输出低
int32_t pump_set_tip_type(TipSize_t size); // Tip大小 0:1ml 1:200ul(max:250ul) 2:50ul(max:62ul) 3=20ul(max:40ul)
// int32_t pump_set_max_limit(int32_t nl); //
int32_t pump_get_max_limit(int32_t* nl); // 获取最大行程
int32_t pump_enable_temp_compensation(int32_t enable); // 0:关闭 1:开启
@ -216,14 +216,14 @@ class SMTP2V2 {
/***********************************************************************************************************************
* ACTION *
***********************************************************************************************************************/
int32_t pump_init(); // 泵机初始化(归零)
int32_t pump_put_tip(); // 丢弃TIP
int32_t pump_factory_reset(); // 泵机复位
int32_t pump_stop(); // 停止
int32_t pump_init(); // 泵机初始化(归零)
int32_t pump_put_tip(); // 丢弃TIP
int32_t pump_factory_reset(); // 泵机复位
int32_t pump_stop(); // 停止
int32_t _pump_move_to_nl(VelCfg* vcfg, int32_t nl);
int32_t pump_move_to_nl(VelCfg* vcfg, int32_t nl); //
int32_t pump_move_by_nl(VelCfg* vcfg, int32_t nl); //
int32_t pump_aspirate_plld(int32_t pressure_threshold, VelCfg* vcfg); // plld,分配探测
int32_t pump_move_to_nl(VelCfg* vcfg, int32_t nl); //
int32_t pump_move_by_nl(VelCfg* vcfg, int32_t nl); //
int32_t pump_aspirate_plld(int32_t pressure_threshold, VelCfg* vcfg); // plld,分配探测
int32_t pump_aspirate_plld_get_state(int32_t* detected);
int32_t pump_clld(int32_t c_threshold); // clld 0...130
@ -247,7 +247,7 @@ class SMTP2V2 {
int32_t pump_get_infer_eigen_time(int32_t* eigen_time);
void dumpparam();
bool sendcmd_direct(const char* cmd);
private:
int32_t runaction(bool dump, const char* format, ...);
@ -255,6 +255,7 @@ class SMTP2V2 {
int32_t readstate(bool dump, const char* format, ...);
int32_t setstate(bool dump, const char* format, ...);
public:
bool _sendcmd(bool dump, const char* cmd);
bool _sendcmd_dma(const char* cmd);

48
sdk/components/sensors/smtp2_v2/smtp_pressure_stream_processer.hpp

@ -0,0 +1,48 @@
#pragma once
#include <string.h>
#include "a8000_protocol\protocol.hpp"
#include "sdk\os\zos.hpp"
namespace iflytop {
using namespace std;
class SmtpPressureStreamProcesser {
private:
uint8_t m_rxbuf[20] = {0};
int32_t m_rxnum = 0;
bool m_is_ready_flag = false;
char m_state = '`';
int32_t m_pressure = 0;
char m_pressure_cache[10];
int32_t m_pressure_uuid = 0;
public:
void process_rx(char data) {
if (data == '/') {
m_rxnum = 0;
}
if (m_rxnum >= sizeof(m_rxbuf) - 1) return;
m_rxbuf[m_rxnum] = data;
m_rxnum++;
if (m_rxbuf[m_rxnum - 1] == 0x0a && m_rxbuf[m_rxnum - 2] == 0x0d && m_rxbuf[1] == '0') {
if ((m_rxnum - 6) != 4) return;
memcpy(m_pressure_cache, &m_rxbuf[3], 4);
m_pressure_cache[4] = 0; // Null-terminate the string
m_pressure = atoi(m_pressure_cache);
m_pressure_uuid++;
m_is_ready_flag = true;
}
}
void getPressure(int32_t *pressure, int32_t *pressureuuid) const {
__disable_irq();
if (pressure) *pressure = m_pressure;
if (pressureuuid) *pressureuuid = m_pressure_uuid;
__enable_irq();
}
};
} // namespace iflytop

1
sdk/components/zcan_protocol_parser/zcan_protocol_parser.cpp

@ -185,7 +185,6 @@ void ZCanProtocolParser::initialize(ZCanReceiver* cancmder) {
REGFN(pipette_pump_pierce_through);
REGFN(pipette_pump_aspirate_set_param);
REGFN(pipette_pump_aspirate);
REGFN(pipette_pump_distribu);
REGFN(pipette_get_sensor_sample_data);
REGFN(pipette_get_sensor_sample_data_num);
REGFN(pipette_read_state);

8
usrc/subboards/subboard80_cliptip/subboard80_cliptip_board.c

@ -192,7 +192,10 @@ static void UART3_Init() {
if (HAL_UART_Init(&huart3) != HAL_OK) {
Error_Handler();
}
/**USART3 GPIO Configuration
PD8 ------> USART3_TX
PD9 ------> USART3_RX
*/
GPIO_InitStruct.Pin = GPIO_PIN_8 | GPIO_PIN_9;
GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
GPIO_InitStruct.Pull = GPIO_NOPULL;
@ -242,6 +245,9 @@ static void UART3_Init() {
HAL_NVIC_SetPriority(DMA1_Stream3_IRQn, 5, 0);
HAL_NVIC_EnableIRQ(DMA1_Stream3_IRQn);
HAL_NVIC_SetPriority(USART3_IRQn, 5, 0);
HAL_NVIC_EnableIRQ(USART3_IRQn);
}
void subboard80_cliptip_board_init() {

Loading…
Cancel
Save