Browse Source
Refactors DMAPP for drawbar disinfection machine
Refactors DMAPP for drawbar disinfection machine
Adds support for drawbar disinfection machines, including PWM blower control and air leak test functionality. Refactors blower and air compressor control into services and controllers for better modularity and testability. These services handle the hardware-specific implementations, while the controllers manage the application logic and protocol interactions. Updates board initialization and configuration to support the new hardware setup. Adds a flag to enable/disable period log output.DT100B
24 changed files with 774 additions and 288 deletions
-
4.settings/language.settings.xml
-
3dap/dap.cfg
-
1flush_by_dap.bat
-
132usrc/app/dmapp.cpp
-
2usrc/app/dmapp.hpp
-
10usrc/base/gflag/gflag.c
-
3usrc/base/gflag/gflag.h
-
56usrc/dmapp_controler/air_compressor_controller.cpp
-
19usrc/dmapp_controler/air_compressor_controller.hpp
-
71usrc/dmapp_controler/blower_controller.cpp
-
21usrc/dmapp_controler/blower_controller.hpp
-
93usrc/dmapp_service/air_compressor_ctrl_service.cpp
-
26usrc/dmapp_service/air_compressor_ctrl_service.hpp
-
258usrc/dmapp_service/blower_ctrl_service.cpp
-
37usrc/dmapp_service/blower_ctrl_service.hpp
-
20usrc/irq/hal_irq_processer.cpp
-
6usrc/irq/hal_irq_processer.hpp
-
107usrc/module/air_compressor_controller.hpp
-
157usrc/module/blower_controller.hpp
-
26usrc/module/h2o2_sensor.cpp
-
1usrc/module/module.hpp
-
2usrc/project_configs.h
-
5usrc/protocol_processer_impl/public_cmd_processer.cpp
-
2usrc/protocol_processer_impl/public_cmd_processer.hpp
@ -0,0 +1,3 @@ |
|||
adapter driver cmsis-dap |
|||
transport select swd |
|||
source [find target/stm32f4x.cfg] |
@ -0,0 +1 @@ |
|||
openocd.exe -f ./dap/dap.cfg -c "init; reset halt; wait_halt; flash write_image erase ./Debug/transmit_disinfection_micro.hex" -c reset -c shutdown |
@ -0,0 +1,56 @@ |
|||
#include "air_compressor_controller.hpp"
|
|||
|
|||
#include "base/appdep.hpp"
|
|||
#include "dmapp_service/air_compressor_ctrl_service.hpp"
|
|||
|
|||
using namespace iflytop; |
|||
using namespace transmit_disfection_protocol; |
|||
|
|||
#define TAG "AirCompressor"
|
|||
|
|||
void AirCompressorController::initialize() { |
|||
REG_LAMADA_FN(kfn_air_compressor_ctrl, [](ProcessContext* cxt) { fn_air_compressor_ctrl(cxt); }); |
|||
REG_LAMADA_FN(kfn_air_compressor_ctrl_safe_valve, [](ProcessContext* cxt) { fn_air_compressor_ctrl_safe_valve(cxt); }); |
|||
REG_LAMADA_FN(kfn_air_compressor_read_ei, [](ProcessContext* cxt) { fn_air_compressor_read_ei(cxt); }); |
|||
REG_LAMADA_FN(kfn_air_compressor_is_open, [](ProcessContext* cxt) { fn_air_compressor_is_open(cxt); }); |
|||
REG_LAMADA_FN(kfn_air_compressor_read_type, [](ProcessContext* cxt) { fn_air_compressor_read_type(cxt); }); |
|||
REG_LAMADA_FN(kfn_air_compressor_read_state, [](ProcessContext* cxt) { fn_air_compressor_read_state(cxt); }); |
|||
} |
|||
void AirCompressorController::fn_air_compressor_ctrl(ProcessContext* cxt) { |
|||
if (PRAAM_LEN() != 1) { |
|||
ZLOGE(TAG, "fn_air_compressor_ctrl: invalid param num, %d", PRAAM_LEN()); |
|||
zcanbus_send_errorack(cxt->packet, kerr_invalid_param_num); |
|||
return; |
|||
} |
|||
int32_t val = GET_PARAM(0); |
|||
ZLOGI(TAG, "fn_air_compressor_ctrl, val: %d", val); |
|||
AirCompressorCtrlService::ctrl(val); |
|||
zcanbus_send_ack(cxt->packet, NULL, 0); |
|||
} |
|||
void AirCompressorController::fn_air_compressor_ctrl_safe_valve(ProcessContext* cxt) { |
|||
// Safe valve control is not implemented yet
|
|||
zcanbus_send_ack(cxt->packet, NULL, 0); |
|||
} |
|||
void AirCompressorController::fn_air_compressor_read_ei(ProcessContext* cxt) { //
|
|||
int32_t ei = AirCompressorCtrlService::readCurrent(); |
|||
ZLOGI(TAG, "fn_air_compressor_read_ei, ei: %d", ei); |
|||
zcanbus_send_ack(cxt->packet, ei); |
|||
} |
|||
void AirCompressorController::fn_air_compressor_is_open(ProcessContext* cxt) { //
|
|||
int32_t power = AirCompressorCtrlService::readPowerLevel(); |
|||
ZLOGI(TAG, "fn_air_compressor_is_open, power: %d", power); |
|||
zcanbus_send_ack(cxt->packet, power); |
|||
} |
|||
void AirCompressorController::fn_air_compressor_read_type(ProcessContext* cxt) { //
|
|||
int32_t type = AirCompressorCtrlService::getType(); |
|||
ZLOGI(TAG, "fn_air_compressor_read_type, type: %d", type); |
|||
zcanbus_send_ack(cxt->packet, type); |
|||
} |
|||
|
|||
void AirCompressorController::fn_air_compressor_read_state(ProcessContext* cxt) { //
|
|||
static int16_t state[10] = {0}; |
|||
memset(state, 0, sizeof(state)); // Clear the state array
|
|||
int32_t maxnum = 0; |
|||
AirCompressorCtrlService::readState(state, &maxnum); |
|||
zcanbus_send_ack(cxt->packet, (uint8_t*)state, maxnum * sizeof(int16_t)); |
|||
} |
@ -0,0 +1,19 @@ |
|||
#pragma once
|
|||
#include "base/appdep.hpp"
|
|||
|
|||
namespace iflytop { |
|||
using namespace transmit_disfection_protocol; |
|||
class AirCompressorController { |
|||
public: |
|||
static void initialize(); |
|||
|
|||
static void fn_air_compressor_ctrl(ProcessContext* cxt); |
|||
static void fn_air_compressor_ctrl_safe_valve(ProcessContext* cxt); |
|||
static void fn_air_compressor_read_ei(ProcessContext* cxt); |
|||
// static void fn_air_compressor_read_ei_adc_raw(ProcessContext* cxt);
|
|||
static void fn_air_compressor_is_open(ProcessContext* cxt); |
|||
static void fn_air_compressor_read_type(ProcessContext* cxt); |
|||
static void fn_air_compressor_read_state(ProcessContext* cxt); |
|||
}; |
|||
|
|||
} // namespace iflytop
|
@ -0,0 +1,71 @@ |
|||
#include "blower_controller.hpp"
|
|||
|
|||
#include "base/appdep.hpp"
|
|||
#include "dmapp_service/blower_ctrl_service.hpp"
|
|||
|
|||
using namespace iflytop; |
|||
using namespace transmit_disfection_protocol; |
|||
#define TAG "BlowerController"
|
|||
|
|||
void BlowerController::initialize() { |
|||
REG_LAMADA_FN(kfn_blower_ctrl, [](ProcessContext* cxt) { fn_blower_ctrl(cxt); }); |
|||
REG_LAMADA_FN(kfn_blower_ctrl_safe_valve, [](ProcessContext* cxt) { fn_blower_ctrl_safe_valve(cxt); }); |
|||
REG_LAMADA_FN(kfn_blower_read_ei, [](ProcessContext* cxt) { fn_blower_read_ei(cxt); }); |
|||
REG_LAMADA_FN(kfn_blower_is_open, [](ProcessContext* cxt) { fn_blower_is_open(cxt); }); |
|||
REG_LAMADA_FN(kfn_blower_read_state, [](ProcessContext* cxt) { fn_blower_is_open(cxt); }); |
|||
} |
|||
|
|||
void BlowerController::fn_blower_ctrl(ProcessContext* cxt) { |
|||
if (PRAAM_LEN() != 1) { |
|||
ZLOGE(TAG, "fn_blower_ctrl: invalid param num, %d", PRAAM_LEN()); |
|||
zcanbus_send_errorack(cxt->packet, kerr_invalid_param_num); |
|||
return; |
|||
} |
|||
|
|||
int32_t val = GET_PARAM(0); |
|||
if (val > 100) val = 100; |
|||
if (val < 0) val = 0; |
|||
|
|||
ZLOGI(TAG, "fn_blower_ctrl, val: %d", val); |
|||
BlowerCtrlService::ctrl(val); |
|||
zcanbus_send_ack(cxt->packet, NULL, 0); |
|||
} |
|||
void BlowerController::fn_blower_ctrl_safe_valve(ProcessContext* cxt) { zcanbus_send_ack(cxt->packet, NULL, 0); } |
|||
void BlowerController::fn_blower_read_ei(ProcessContext* cxt) { |
|||
int32_t ei = 0; |
|||
blower_state_t state = {0}; |
|||
int32_t ret = BlowerCtrlService::readState(&state); |
|||
if (ret != 0) { |
|||
ZLOGI(TAG, "fn_blower_read_ei error, %d", ret); |
|||
zcanbus_send_errorack(cxt->packet, ret); |
|||
return; |
|||
} |
|||
ei = state.blowerI; |
|||
ZLOGI(TAG, "fn_blower_read_ei, ei: %d", ei); |
|||
zcanbus_send_ack(cxt->packet, ei); |
|||
} |
|||
|
|||
void BlowerController::fn_blower_is_open(ProcessContext* cxt) { //
|
|||
int32_t power = BlowerCtrlService::readState()->power; |
|||
ZLOGI(TAG, "fn_blower_is_open, power: %d", power); |
|||
zcanbus_send_ack(cxt->packet, power); |
|||
} |
|||
|
|||
void BlowerController::fn_blower_read_type(ProcessContext* cxt) { |
|||
int32_t type = BlowerCtrlService::getType(); |
|||
if (type == kNotSet) { |
|||
zcanbus_send_errorack(cxt->packet, -1); |
|||
return; |
|||
} |
|||
ZLOGI(TAG, "fn_blower_read_type, type: %d", type); |
|||
zcanbus_send_ack(cxt->packet, (int32_t)type); |
|||
} |
|||
|
|||
void BlowerController::fn_blower_read_state(ProcessContext* cxt) { |
|||
static int16_t state[10]; |
|||
int32_t maxnum = 5; |
|||
memset(state, 0, sizeof(state)); // Clear the state array
|
|||
|
|||
BlowerCtrlService::readState(state, &maxnum); |
|||
zcanbus_send_ack(cxt->packet, (uint8_t*)state, maxnum * sizeof(int16_t)); |
|||
} |
@ -0,0 +1,21 @@ |
|||
#pragma once
|
|||
#include "base/appdep.hpp"
|
|||
|
|||
namespace iflytop { |
|||
using namespace transmit_disfection_protocol; |
|||
class BlowerController { |
|||
public: |
|||
static void initialize(); |
|||
|
|||
static void fn_blower_ctrl(ProcessContext* cxt); |
|||
static void fn_blower_ctrl_safe_valve(ProcessContext* cxt); |
|||
static void fn_blower_read_ei(ProcessContext* cxt); |
|||
static void fn_blower_is_open(ProcessContext* cxt); |
|||
|
|||
// static void fn_blower_read_ei_adc_raw(ProcessContext* cxt);
|
|||
// static void fn_blower_is_error(ProcessContext* cxt);
|
|||
static void fn_blower_read_type(ProcessContext* cxt); |
|||
static void fn_blower_read_state(ProcessContext* cxt); |
|||
}; |
|||
|
|||
} // namespace iflytop
|
@ -0,0 +1,93 @@ |
|||
#include "air_compressor_ctrl_service.hpp"
|
|||
|
|||
#include "base/appdep.hpp"
|
|||
#include "board\public_board.hpp"
|
|||
//
|
|||
#include "board\hal\dbdm_power_ctrl_board.hpp"
|
|||
#include "board\hal\large_space_dm_power_ctrl_board.hpp"
|
|||
#include "irq\hal_irq_processer.hpp"
|
|||
|
|||
using namespace iflytop; |
|||
using namespace transmit_disfection_protocol; |
|||
|
|||
typedef struct { |
|||
ZGPIO ctrlGpio; // 控制引脚
|
|||
ZADC iAdc; // 电流采集
|
|||
} IOAirCompressor_t; |
|||
|
|||
typedef struct { |
|||
int32_t mark; |
|||
} MiniPwmAirPump_t; |
|||
|
|||
static AirCompressorType_t m_type = kAirCompressorType_notSet; |
|||
static IOAirCompressor_t m_ioAirCompressor; |
|||
static MiniPwmAirPump_t m_miniPwmAirPump; |
|||
|
|||
static int32_t m_power_level; |
|||
|
|||
// ZASSERT(!m_isInitialized);
|
|||
// m_ctrlGpio.initAsOutput(ctrlGpio, kxs_gpio_nopull, true, false);
|
|||
// m_iAdc.initialize("AirComAdc", iadc, ich);
|
|||
// m_isInitialized = true;
|
|||
|
|||
// AppPeriodTaskMgr::ins()->regTask("AC-ADC", [this]() { periodTask(); }, 1000);
|
|||
|
|||
void AirCompressorCtrlService::initialize() { |
|||
if (PORT::isPowerCtrlBoard() && (PORT::isLargeSpaceDM() || PORT::isSamllSpaceDM() || PORT::isPipeDM() || PORT::isDT600B())) { |
|||
LargeSpaceDmPowerCtrlBoardHal::HADC1_INIT(); |
|||
m_ioAirCompressor.ctrlGpio.initAsOutput(PC3, kxs_gpio_nopull, true, false); // 初始化空压机控制引脚
|
|||
m_ioAirCompressor.iAdc.initialize("AirComAdc", &hadc1, ADC_CHANNEL_0); // 初始化空压机电流采集
|
|||
m_type = kAirCompressorType_IO; // IO控制的空压机
|
|||
|
|||
AppPeriodTaskMgr::ins()->regTask( |
|||
"AC-ADC", |
|||
[]() { |
|||
m_ioAirCompressor.iAdc.updateAdcValToCache(); // 周期性更新空压机电流采集值
|
|||
}, |
|||
500); // 每秒更新一次
|
|||
} |
|||
//
|
|||
else if (PORT::isPowerCtrlBoard() && PORT::isDrawBarDM()) { |
|||
// PC6 pwm控制具体控制见
|
|||
// PC4 反馈每圈1个脉冲
|
|||
} |
|||
} |
|||
bool AirCompressorCtrlService::isSupport() { |
|||
if (PORT::isPowerCtrlBoard() && (PORT::isLargeSpaceDM() || PORT::isSamllSpaceDM() || PORT::isPipeDM() || PORT::isDT600B())) { |
|||
return true; // 支持空压机控制
|
|||
} |
|||
return false; |
|||
} |
|||
|
|||
int AirCompressorCtrlService::getType() { |
|||
return m_type; // 返回已设置的空压机类型
|
|||
} |
|||
int32_t AirCompressorCtrlService::ctrl(int32_t val) { |
|||
if (m_type == kAirCompressorType_IO) { |
|||
m_ioAirCompressor.ctrlGpio.write(val); // 控制空压机开关
|
|||
m_power_level = val; // 更新功率等级
|
|||
return 0; // 成功
|
|||
} |
|||
return kerr_function_not_support; // 不支持的空压机类型
|
|||
} |
|||
void AirCompressorCtrlService::readState(int16_t* state, int32_t* maxnum) { |
|||
if (m_type == kAirCompressorType_IO) { |
|||
state[0] = m_power_level; |
|||
state[1] = airCompressorAdcToCurrent(m_ioAirCompressor.iAdc.getCacheVal()); |
|||
*maxnum = 2; // 返回空压机状态
|
|||
} else { |
|||
state[0] = m_power_level; |
|||
*maxnum = 1; // 返回空压机状态
|
|||
} |
|||
} |
|||
|
|||
int32_t AirCompressorCtrlService::readCurrent() { |
|||
if (m_type == kAirCompressorType_IO) { |
|||
return airCompressorAdcToCurrent(m_ioAirCompressor.iAdc.getCacheVal()); // 返回空压机电流值
|
|||
} |
|||
return 0; |
|||
} |
|||
|
|||
int32_t AirCompressorCtrlService::readPowerLevel() { |
|||
return m_power_level; // 返回空压机功率等级
|
|||
} |
@ -0,0 +1,26 @@ |
|||
#pragma once
|
|||
#include "base/appdep.hpp"
|
|||
|
|||
namespace iflytop { |
|||
using namespace transmit_disfection_protocol; |
|||
|
|||
typedef enum { |
|||
kAirCompressorType_notSet, |
|||
kAirCompressorType_IO, |
|||
kAirCompressorType_MiniPwmAirPump, |
|||
} AirCompressorType_t; |
|||
|
|||
class AirCompressorCtrlService { |
|||
public: |
|||
static void initialize(); |
|||
static bool isSupport(); |
|||
|
|||
static int getType(); |
|||
static int32_t ctrl(int32_t val); |
|||
static void readState(int16_t* state, int32_t* maxnum); |
|||
|
|||
static int32_t readCurrent(); |
|||
static int32_t readPowerLevel(); |
|||
}; |
|||
|
|||
} // namespace iflytop
|
@ -0,0 +1,258 @@ |
|||
#include "blower_ctrl_service.hpp"
|
|||
|
|||
#include "board\public_board.hpp"
|
|||
//
|
|||
#include "board\hal\dbdm_power_ctrl_board.hpp"
|
|||
#include "board\hal\large_space_dm_power_ctrl_board.hpp"
|
|||
#include "irq\hal_irq_processer.hpp"
|
|||
|
|||
using namespace iflytop; |
|||
using namespace transmit_disfection_protocol; |
|||
|
|||
#define TAG "BlowerCtrlService"
|
|||
|
|||
#define IOBLOWER_ERROR_CURRENT_MIN 500
|
|||
#define IOBLOWER_ERROR_CURRENT_MAX 3000
|
|||
#define IOBLOWER_ERROR_JUDGE_TIMES 5
|
|||
|
|||
typedef struct { |
|||
ZGPIO ctrlGpio; |
|||
ZADC iadc; |
|||
} IOBlower; |
|||
|
|||
typedef struct { |
|||
ModbusBlockHost ctrlModbusMaster; |
|||
ZGPIO coolingFanCtrlGpio; // 控制冷却风扇
|
|||
ZADC coolingFanIAdc; // 冷却风扇电流采集
|
|||
|
|||
uint16_t subErrorCode = 0; // 从设备错误码
|
|||
} HighPowerUartBlower; |
|||
|
|||
typedef struct { |
|||
TIM_HandleTypeDef* htim; |
|||
uint32_t channle; |
|||
ZGPIO enGpio; |
|||
ZGPIO fbGpio; |
|||
int32_t blowerFbCnt; |
|||
} PwmBlower; |
|||
|
|||
static IOBlower ioblower; |
|||
static HighPowerUartBlower highPowerUartBlower; |
|||
static PwmBlower miniPwmBlower; |
|||
|
|||
static BlowerType_t m_blowerType = kIOBlower; |
|||
static bool m_isopen = false; |
|||
static int32_t m_powerVal = 0; |
|||
static int32_t m_open_ticket = 0; |
|||
|
|||
static zmutex lock = {"BlowerCtrlService"}; |
|||
|
|||
void mini_pwm_blower_ctrl(int32_t duty) { |
|||
duty = 100 - duty; |
|||
if (duty < 0) duty = 0; |
|||
if (duty > 100) duty = 100; |
|||
|
|||
TIM_OC_InitTypeDef sConfigOC = {0}; |
|||
sConfigOC.OCMode = TIM_OCMODE_PWM1; |
|||
sConfigOC.Pulse = duty / 100.0 * __HAL_TIM_GET_AUTORELOAD(miniPwmBlower.htim); |
|||
sConfigOC.OCPolarity = TIM_OCPOLARITY_HIGH; |
|||
sConfigOC.OCFastMode = TIM_OCFAST_DISABLE; |
|||
sConfigOC.OCIdleState = TIM_OCIDLESTATE_RESET; |
|||
sConfigOC.OCNIdleState = TIM_OCNIDLESTATE_RESET; |
|||
|
|||
HAL_TIM_PWM_ConfigChannel(miniPwmBlower.htim, &sConfigOC, miniPwmBlower.channle); |
|||
HAL_TIM_PWM_Stop(miniPwmBlower.htim, miniPwmBlower.channle); |
|||
HAL_TIM_PWM_Start(miniPwmBlower.htim, miniPwmBlower.channle); |
|||
|
|||
miniPwmBlower.enGpio.setState(duty != 0); |
|||
} |
|||
|
|||
bool BlowerCtrlService::isSupport() { |
|||
if (PORT::isPowerCtrlBoard() && (PORT::isLargeSpaceDM() || PORT::isSamllSpaceDM() || PORT::isDT600B())) { |
|||
return true; |
|||
} else if (PORT::isPowerCtrlBoard() && (PORT::isPipeDM())) { |
|||
return true; |
|||
} else if (PORT::isPowerCtrlBoard() && (PORT::isDrawBarDM())) { |
|||
return true; |
|||
} |
|||
return false; |
|||
} |
|||
|
|||
void BlowerCtrlService::initialize() { |
|||
lock.init(); |
|||
|
|||
if (PORT::isPowerCtrlBoard() && (PORT::isLargeSpaceDM() || PORT::isSamllSpaceDM() || PORT::isDT600B())) { |
|||
/***********************************************************************************************************************
|
|||
* IOBblower * |
|||
***********************************************************************************************************************/ |
|||
|
|||
m_blowerType = kIOBlower; |
|||
|
|||
LargeSpaceDmPowerCtrlBoardHal::HADC1_INIT(); |
|||
ioblower.ctrlGpio.initAsOutput(PC5, kxs_gpio_nopull, true, false); |
|||
ioblower.iadc.initialize("Blower-iadc", &hadc1, ADC_CHANNEL_1); |
|||
AppPeriodTaskMgr::ins()->regTask("AC-ADC", []() { ioblower.iadc.updateAdcValToCache(); }, 500); |
|||
} //
|
|||
else if (PORT::isPowerCtrlBoard() && (PORT::isPipeDM())) { |
|||
/***********************************************************************************************************************
|
|||
* HighPowerUartBlower * |
|||
***********************************************************************************************************************/ |
|||
|
|||
m_blowerType = kHighPowerUartBlower; |
|||
|
|||
LargeSpaceDmPowerCtrlBoardHal::HADC1_INIT(); |
|||
LargeSpaceDmPowerCtrlBoardHal::HUART2_INIT(9600, UART_STOPBITS_1); |
|||
|
|||
highPowerUartBlower.coolingFanCtrlGpio.initAsOutput(PC5, kxs_gpio_nopull, true, false); |
|||
highPowerUartBlower.ctrlModbusMaster.initialize(&huart2); |
|||
highPowerUartBlower.coolingFanIAdc.initialize("Blower-coolingFan-iadc", &hadc1, ADC_CHANNEL_1); |
|||
|
|||
AppPeriodTaskMgr::ins()->regTask( |
|||
"HighPowerUartBlower-Monitor", |
|||
[]() { |
|||
highPowerUartBlower.coolingFanIAdc.updateAdcValToCache(); |
|||
{ |
|||
uint16_t regval = 0; |
|||
bool status = highPowerUartBlower.ctrlModbusMaster.readReg03(1, 0x8000, ®val, 50); |
|||
if (status) { |
|||
highPowerUartBlower.subErrorCode = regval; |
|||
} else { |
|||
highPowerUartBlower.subErrorCode = 0xffff; |
|||
} |
|||
} |
|||
}, |
|||
500); |
|||
|
|||
} // 拉杆箱
|
|||
else if (PORT::isPowerCtrlBoard() && (PORT::isDrawBarDM())) { |
|||
/***********************************************************************************************************************
|
|||
* PWMBLower * |
|||
***********************************************************************************************************************/ |
|||
// 宁波锚点调速风机
|
|||
|
|||
m_blowerType = kMiniPwmBlower; |
|||
DBDMPowerCtrlBoard::HTIM3_INIT(); // TIM3
|
|||
miniPwmBlower.htim = &htim3; // TIM1
|
|||
miniPwmBlower.channle = TIM_CHANNEL_3; // TIM1_CH1 PC8
|
|||
|
|||
miniPwmBlower.fbGpio.initAsInput(PC9, kxs_gpio_nopull, kxs_gpio_rising_irq, false /*mirror*/); // PC9
|
|||
miniPwmBlower.enGpio.initAsOutput(PC10, kxs_gpio_nopull, true, false); // PC10
|
|||
|
|||
AppPeriodTaskMgr::ins()->regTask("HighPowerUartBlower-Monitor", []() { miniPwmBlower.blowerFbCnt = PC9_IRQ_CNT; }, 30); |
|||
|
|||
} else { |
|||
ZLOGE(TAG, "BlowerCtrlService::initialize() not support this board"); |
|||
return; |
|||
} |
|||
} |
|||
|
|||
int BlowerCtrlService::getType() { return m_blowerType; } |
|||
|
|||
/**
|
|||
* @brief 风机控制 |
|||
* |
|||
* @param val |
|||
*/ |
|||
int32_t BlowerCtrlService::ctrl(int32_t val) { |
|||
zlock_guard l(lock); |
|||
if (val > 100) val = 100; |
|||
if (val < 0) val = 0; |
|||
|
|||
bool toOpen = val > 0 ? true : false; |
|||
int toPowerVal = val; |
|||
|
|||
switch (m_blowerType) { |
|||
/***********************************************************************************************************************
|
|||
* kIOBlower * |
|||
***********************************************************************************************************************/ |
|||
case kIOBlower: |
|||
ioblower.ctrlGpio.write(toOpen); |
|||
break; |
|||
|
|||
/***********************************************************************************************************************
|
|||
* kHighPowerUartBlower * |
|||
***********************************************************************************************************************/ |
|||
case kHighPowerUartBlower: |
|||
|
|||
highPowerUartBlower.coolingFanCtrlGpio.write(toOpen); |
|||
if (toOpen) { |
|||
if (!highPowerUartBlower.ctrlModbusMaster.writeReg06(1, 0x2000, 1, 50)) return kerr_subdevice_overtime; |
|||
} else { |
|||
if (!highPowerUartBlower.ctrlModbusMaster.writeReg06(1, 0x2000, 6, 50)) return kerr_subdevice_overtime; |
|||
} |
|||
break; |
|||
|
|||
/***********************************************************************************************************************
|
|||
* kMiniPwmBlower * |
|||
***********************************************************************************************************************/ |
|||
case kMiniPwmBlower: |
|||
mini_pwm_blower_ctrl(toPowerVal); |
|||
break; |
|||
|
|||
default: |
|||
return kerr_function_not_support; |
|||
} |
|||
|
|||
// sync state
|
|||
m_open_ticket = zos_get_tick(); |
|||
m_isopen = toOpen; |
|||
m_powerVal = toPowerVal; |
|||
return 0; |
|||
} |
|||
blower_state_t* BlowerCtrlService::readState() { |
|||
static blower_state_t state; |
|||
readState(&state); |
|||
return &state; |
|||
} |
|||
|
|||
int32_t BlowerCtrlService::readState(blower_state_t* state) { |
|||
zlock_guard l(lock); |
|||
|
|||
switch (m_blowerType) { |
|||
case kIOBlower: |
|||
state->power = m_powerVal; |
|||
state->blowerI = blowserAdcToCurrent(ioblower.iadc.getCacheVal()); |
|||
break; |
|||
case kHighPowerUartBlower: |
|||
state->power = m_powerVal; |
|||
state->coolfanI = blowserAdcToCurrent(highPowerUartBlower.coolingFanIAdc.getCacheVal()); |
|||
state->subDeviceErrorCode = highPowerUartBlower.subErrorCode; |
|||
break; |
|||
case kMiniPwmBlower: |
|||
state->power = m_powerVal; |
|||
state->blowerFbCNT = miniPwmBlower.blowerFbCnt; |
|||
break; |
|||
default: |
|||
break; |
|||
} |
|||
return 0; |
|||
} |
|||
|
|||
void BlowerCtrlService::readState(int16_t* state, int32_t* maxnum) { |
|||
zlock_guard l(lock); |
|||
switch (m_blowerType) { |
|||
case kIOBlower: |
|||
state[0] = m_powerVal; |
|||
state[1] = blowserAdcToCurrent(ioblower.iadc.getCacheVal()); |
|||
*maxnum = 2; //
|
|||
break; |
|||
case kHighPowerUartBlower: |
|||
state[0] = m_powerVal; |
|||
state[1] = blowserAdcToCurrent(highPowerUartBlower.coolingFanIAdc.getCacheVal()); |
|||
state[2] = highPowerUartBlower.subErrorCode; |
|||
*maxnum = 3; //
|
|||
|
|||
break; |
|||
case kMiniPwmBlower: |
|||
state[0] = m_powerVal; |
|||
state[1] = miniPwmBlower.blowerFbCnt; |
|||
*maxnum = 2; //
|
|||
break; |
|||
default: |
|||
state[0] = m_powerVal; |
|||
*maxnum = 1; |
|||
|
|||
break; |
|||
} |
|||
return; |
|||
} |
@ -0,0 +1,37 @@ |
|||
#pragma once
|
|||
#include "base/appdep.hpp"
|
|||
|
|||
namespace iflytop { |
|||
typedef enum { |
|||
kNotSet, |
|||
kIOBlower, |
|||
kHighPowerUartBlower, |
|||
kMiniPwmBlower, |
|||
} BlowerType_t; |
|||
|
|||
typedef struct { |
|||
int16_t power; |
|||
int16_t blowerI; // 风机电流 ma
|
|||
int16_t coolfanI; // 冷却风扇电流 ma
|
|||
int16_t blowerFbCNT; // 风机反馈CNT
|
|||
int16_t coolfanFbCnt; // 冷却风扇反馈CNT
|
|||
int16_t subDeviceErrorCode; // 从设备错误码
|
|||
} blower_state_t; |
|||
|
|||
class BlowerCtrlService { |
|||
public: |
|||
static void initialize(); |
|||
static bool isSupport(); |
|||
|
|||
static int getType(); |
|||
|
|||
static int32_t ctrl(int32_t val); |
|||
static int32_t readState(blower_state_t* state); |
|||
static blower_state_t* readState(); |
|||
|
|||
static void readState(int16_t* state, int32_t* maxnum); |
|||
|
|||
|
|||
}; |
|||
|
|||
} // namespace iflytop
|
@ -0,0 +1,20 @@ |
|||
#include "hal_irq_processer.hpp"
|
|||
|
|||
#include "board\public_board.hpp"
|
|||
|
|||
using namespace iflytop; |
|||
|
|||
uint32_t PC9_IRQ_CNT; |
|||
uint32_t PC4_IRQ_CNT; |
|||
|
|||
extern "C" { |
|||
void HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin) { |
|||
if (PORT::isPowerCtrlBoard() && PORT::isDrawBarDM()) { |
|||
if (GPIO_Pin == GPIO_PIN_9) { |
|||
PC9_IRQ_CNT++; |
|||
} else if (GPIO_Pin == GPIO_PIN_4) { |
|||
PC4_IRQ_CNT++; |
|||
} |
|||
} |
|||
} |
|||
} |
@ -0,0 +1,6 @@ |
|||
#pragma once
|
|||
|
|||
#include "base/appdep.hpp"
|
|||
|
|||
extern uint32_t PC9_IRQ_CNT; |
|||
extern uint32_t PC4_IRQ_CNT; |
@ -1,54 +1,53 @@ |
|||
#pragma once
|
|||
#include "base/appdep.hpp"
|
|||
|
|||
namespace iflytop { |
|||
using namespace transmit_disfection_protocol; |
|||
|
|||
class AirCompressorController { |
|||
ZGPIO m_ctrlGpio; |
|||
ZADC m_iAdc; |
|||
bool m_isInitialized = false; |
|||
|
|||
public: |
|||
static AirCompressorController* ins() { |
|||
static AirCompressorController instance; |
|||
return &instance; |
|||
} |
|||
|
|||
void initialize(Pin_t ctrlGpio, ADC_HandleTypeDef* iadc, uint32_t ich) { |
|||
ZASSERT(!m_isInitialized); |
|||
m_ctrlGpio.initAsOutput(ctrlGpio, kxs_gpio_nopull, true, false); |
|||
m_iAdc.initialize("AirComAdc", iadc, ich); |
|||
m_isInitialized = true; |
|||
|
|||
AppPeriodTaskMgr::ins()->regTask("AC-ADC", [this]() { periodTask(); }, 1000); |
|||
// BIND
|
|||
BIND_FN(AirCompressorController, this, fn_air_compressor_ctrl); |
|||
BIND_FN(AirCompressorController, this, fn_air_compressor_ctrl_safe_valve); |
|||
BIND_FN(AirCompressorController, this, fn_air_compressor_read_ei); |
|||
BIND_FN(AirCompressorController, this, fn_air_compressor_read_ei_adc_raw); |
|||
BIND_FN(AirCompressorController, this, fn_air_compressor_is_open); |
|||
} |
|||
bool isInitialized() { return m_isInitialized; } |
|||
|
|||
public: |
|||
void open(bool val) { m_ctrlGpio.write(val); } |
|||
bool isOpen() { return m_ctrlGpio.read(); } |
|||
|
|||
private: |
|||
// PP
|
|||
void fn_air_compressor_ctrl(ProcessContext* cxt) { //
|
|||
m_ctrlGpio.write(GET_PARAM(0)); |
|||
zcanbus_send_ack(cxt->packet, NULL, 0); |
|||
} |
|||
void fn_air_compressor_ctrl_safe_valve(ProcessContext* cxt) { zcanbus_send_ack(cxt->packet, NULL, 0); } |
|||
void fn_air_compressor_read_ei(ProcessContext* cxt) { zcanbus_send_ack(cxt->packet, airCompressorAdcToCurrent(m_iAdc.getCacheVal())); } |
|||
void fn_air_compressor_read_ei_adc_raw(ProcessContext* cxt) { zcanbus_send_ack(cxt->packet, m_iAdc.getCacheVal()); } |
|||
void fn_air_compressor_is_open(ProcessContext* cxt) { zcanbus_send_ack(cxt->packet, m_ctrlGpio.read()); } |
|||
|
|||
private: |
|||
void periodTask() { m_iAdc.updateAdcValToCache(); } |
|||
}; |
|||
} // namespace iflytop
|
|||
|
|||
#pragma once
|
|||
// #pragma once
|
|||
// #include "base/appdep.hpp"
|
|||
|
|||
// namespace iflytop {
|
|||
// using namespace transmit_disfection_protocol;
|
|||
|
|||
// class AirCompressorController {
|
|||
// ZGPIO m_ctrlGpio;
|
|||
// ZADC m_iAdc;
|
|||
// bool m_isInitialized = false;
|
|||
|
|||
// public:
|
|||
// static AirCompressorController* ins() {
|
|||
// static AirCompressorController instance;
|
|||
// return &instance;
|
|||
// }
|
|||
|
|||
// void initialize(Pin_t ctrlGpio, ADC_HandleTypeDef* iadc, uint32_t ich) {
|
|||
// ZASSERT(!m_isInitialized);
|
|||
// m_ctrlGpio.initAsOutput(ctrlGpio, kxs_gpio_nopull, true, false);
|
|||
// m_iAdc.initialize("AirComAdc", iadc, ich);
|
|||
// m_isInitialized = true;
|
|||
|
|||
// AppPeriodTaskMgr::ins()->regTask("AC-ADC", [this]() { periodTask(); }, 1000);
|
|||
// // BIND
|
|||
// BIND_FN(AirCompressorController, this, fn_air_compressor_ctrl);
|
|||
// BIND_FN(AirCompressorController, this, fn_air_compressor_ctrl_safe_valve);
|
|||
// BIND_FN(AirCompressorController, this, fn_air_compressor_read_ei);
|
|||
// BIND_FN(AirCompressorController, this, fn_air_compressor_read_ei_adc_raw);
|
|||
// BIND_FN(AirCompressorController, this, fn_air_compressor_is_open);
|
|||
// }
|
|||
// bool isInitialized() { return m_isInitialized; }
|
|||
|
|||
// public:
|
|||
// void open(bool val) { m_ctrlGpio.write(val); }
|
|||
// bool isOpen() { return m_ctrlGpio.read(); }
|
|||
|
|||
// private:
|
|||
// // PP
|
|||
// void fn_air_compressor_ctrl(ProcessContext* cxt) { //
|
|||
// m_ctrlGpio.write(GET_PARAM(0));
|
|||
// zcanbus_send_ack(cxt->packet, NULL, 0);
|
|||
// }
|
|||
// void fn_air_compressor_ctrl_safe_valve(ProcessContext* cxt) { zcanbus_send_ack(cxt->packet, NULL, 0); }
|
|||
// void fn_air_compressor_read_ei(ProcessContext* cxt) { zcanbus_send_ack(cxt->packet, airCompressorAdcToCurrent(m_iAdc.getCacheVal())); }
|
|||
// void fn_air_compressor_read_ei_adc_raw(ProcessContext* cxt) { zcanbus_send_ack(cxt->packet, m_iAdc.getCacheVal()); }
|
|||
// void fn_air_compressor_is_open(ProcessContext* cxt) { zcanbus_send_ack(cxt->packet, m_ctrlGpio.read()); }
|
|||
|
|||
// private:
|
|||
// void periodTask() { m_iAdc.updateAdcValToCache(); }
|
|||
// };
|
|||
// } // namespace iflytop
|
|||
|
@ -1,157 +0,0 @@ |
|||
#pragma once
|
|||
#include "base/appdep.hpp"
|
|||
|
|||
namespace iflytop { |
|||
using namespace transmit_disfection_protocol; |
|||
|
|||
typedef enum { |
|||
kIOBlower, |
|||
kHighPowerUartBlower, |
|||
kMiniPwmBlower, |
|||
} BlowerType_t; |
|||
|
|||
class BlowerController { |
|||
BlowerType_t m_blowerType = kIOBlower; |
|||
|
|||
// kIOBlower
|
|||
ZGPIO m_ctrlGpio; |
|||
|
|||
// kHighPowerUartBlower
|
|||
ModbusBlockHost m_modbusblock; |
|||
|
|||
// kMiniPwmBlower
|
|||
TIM_HandleTypeDef* m_miniPwmBlower_htim; |
|||
uint32_t m_miniPwmBlower_channle; |
|||
ZGPIO m_miniPwmBlower_enGpio; |
|||
ZGPIO m_miniPwmBlower_fbGpio; |
|||
|
|||
ZADC m_iadc; |
|||
bool m_iadcIsInit = false; |
|||
|
|||
bool m_isInitialized = false; |
|||
bool isopen = false; |
|||
|
|||
public: |
|||
void initialize(Pin_t ctrlGpio, ADC_HandleTypeDef* iadc, uint32_t ich) { |
|||
m_ctrlGpio.initAsOutput(ctrlGpio, kxs_gpio_nopull, true, false); |
|||
m_iadc.initialize("Blower-iadc", iadc, ich); |
|||
AppPeriodTaskMgr::ins()->regTask("AC-ADC", [this]() { periodTask(); }, 1000); |
|||
m_blowerType = kIOBlower; |
|||
m_isInitialized = true; |
|||
bindFn(); |
|||
} |
|||
|
|||
void initializeAsHighPowerUartBlower(Pin_t ctrlGpio, UART_HandleTypeDef* huart, ADC_HandleTypeDef* iadc, uint32_t ich) { |
|||
m_ctrlGpio.initAsOutput(ctrlGpio, kxs_gpio_nopull, true, false); |
|||
m_modbusblock.initialize(huart); |
|||
// m_modbusblock.enableDump(true)upda;
|
|||
m_iadc.initialize("Blower-iadc", iadc, ich); |
|||
AppPeriodTaskMgr::ins()->regTask("AC-ADC", [this]() { periodTask(); }, 1000); |
|||
m_blowerType = kHighPowerUartBlower; |
|||
m_isInitialized = true; |
|||
bindFn(); |
|||
} |
|||
void initializeAsMiniPwmBlower(TIM_HandleTypeDef* htim, uint32_t channel, Pin_t enGpio, Pin_t fbGpio) { |
|||
m_miniPwmBlower_htim = htim; |
|||
m_miniPwmBlower_channle = channel; |
|||
m_miniPwmBlower_enGpio.initAsOutput(enGpio, kxs_gpio_nopull, true, false); |
|||
m_miniPwmBlower_fbGpio.initAsInput(fbGpio, kxs_gpio_nopull, kxs_gpio_rising_irq, false); |
|||
AppPeriodTaskMgr::ins()->regTask("AC-ADC", [this]() { periodTask(); }, 1000); |
|||
m_blowerType = kMiniPwmBlower; |
|||
m_isInitialized = true; |
|||
bindFn(); |
|||
} |
|||
|
|||
bool isInitialized() { return m_isInitialized; } |
|||
|
|||
void bindFn() { |
|||
BIND_FN(BlowerController, this, fn_blower_ctrl); |
|||
BIND_FN(BlowerController, this, fn_blower_ctrl_safe_valve); |
|||
BIND_FN(BlowerController, this, fn_blower_read_ei); |
|||
BIND_FN(BlowerController, this, fn_blower_is_error); |
|||
BIND_FN(BlowerController, this, fn_blower_read_ei_adc_raw); |
|||
BIND_FN(BlowerController, this, fn_blower_is_open); |
|||
} |
|||
|
|||
/***********************************************************************************************************************
|
|||
* FN * |
|||
***********************************************************************************************************************/ |
|||
void blower_ctrl(int32_t val) {} |
|||
void blower_ctrl_safe_valve(int32_t val) {} |
|||
int32_t blower_read_ei() { |
|||
if (m_blowerType == kIOBlower || m_blowerType == kHighPowerUartBlower) { |
|||
return blowserAdcToCurrent(m_iadc.getCacheVal()); |
|||
} |
|||
return 0; |
|||
} |
|||
int32_t blower_read_iadc() { |
|||
if (m_blowerType == kIOBlower || m_blowerType == kHighPowerUartBlower) { |
|||
return m_iadc.getCacheVal(); |
|||
} |
|||
return 0; |
|||
} |
|||
|
|||
int32_t blower_is_error() { |
|||
// TODO: 栏杆箱消毒机添加故障检测
|
|||
return 0; |
|||
} |
|||
|
|||
void periodTask() { |
|||
if (m_iadc.isInited()) m_iadc.updateAdcValToCache(); |
|||
} |
|||
|
|||
/***********************************************************************************************************************
|
|||
* PP * |
|||
***********************************************************************************************************************/ |
|||
void fn_blower_ctrl(ProcessContext* cxt) { //
|
|||
int32_t val = GET_PARAM(0); |
|||
if (m_blowerType == kIOBlower) { |
|||
m_ctrlGpio.write(val); |
|||
zcanbus_send_ack(cxt->packet, NULL, 0); |
|||
isopen = GET_PARAM(0) > 0 ? true : false; |
|||
} else if (m_blowerType == kHighPowerUartBlower) { |
|||
m_ctrlGpio.write(val); |
|||
bool suc = val > 0 ? m_modbusblock.writeReg06(1, 0x2000, 1, 50) : m_modbusblock.writeReg06(1, 0x2000, 6, 50); |
|||
if (suc) { |
|||
m_ctrlGpio.write(val); |
|||
zcanbus_send_ack(cxt->packet, NULL, 0); |
|||
isopen = GET_PARAM(0) > 0 ? true : false; |
|||
} else { |
|||
zcanbus_send_errorack(cxt->packet, kerr_subdevice_overtime); |
|||
} |
|||
|
|||
} else if (m_blowerType == kMiniPwmBlower) { |
|||
mini_pwm_blower_ctrl(val); |
|||
} |
|||
} |
|||
void fn_blower_ctrl_safe_valve(ProcessContext* cxt) { //
|
|||
blower_ctrl_safe_valve(GET_PARAM(0)); |
|||
zcanbus_send_ack(cxt->packet, NULL, 0); |
|||
} |
|||
void fn_blower_read_ei(ProcessContext* cxt) { zcanbus_send_ack(cxt->packet, blower_read_ei()); } |
|||
void fn_blower_read_ei_adc_raw(ProcessContext* cxt) { zcanbus_send_ack(cxt->packet, m_iadc.getCacheVal()); } |
|||
void fn_blower_is_error(ProcessContext* cxt) { zcanbus_send_ack(cxt->packet, blower_is_error()); } |
|||
void fn_blower_is_open(ProcessContext* cxt) { zcanbus_send_ack(cxt->packet, isopen); } |
|||
|
|||
private: |
|||
void mini_pwm_blower_ctrl(int32_t duty) { |
|||
duty = 100 - duty; |
|||
if (duty < 0) duty = 0; |
|||
if (duty > 100) duty = 100; |
|||
|
|||
TIM_OC_InitTypeDef sConfigOC = {0}; |
|||
sConfigOC.OCMode = TIM_OCMODE_PWM1; |
|||
sConfigOC.Pulse = duty / 100.0 * __HAL_TIM_GET_AUTORELOAD(m_miniPwmBlower_htim); |
|||
sConfigOC.OCPolarity = TIM_OCPOLARITY_HIGH; |
|||
sConfigOC.OCFastMode = TIM_OCFAST_DISABLE; |
|||
sConfigOC.OCIdleState = TIM_OCIDLESTATE_RESET; |
|||
sConfigOC.OCNIdleState = TIM_OCNIDLESTATE_RESET; |
|||
|
|||
HAL_TIM_PWM_ConfigChannel(m_miniPwmBlower_htim, &sConfigOC, m_miniPwmBlower_channle); |
|||
HAL_TIM_PWM_Stop(m_miniPwmBlower_htim, m_miniPwmBlower_channle); |
|||
HAL_TIM_PWM_Start(m_miniPwmBlower_htim, m_miniPwmBlower_channle); |
|||
|
|||
m_miniPwmBlower_enGpio.write(duty != 0); |
|||
} |
|||
}; |
|||
} // namespace iflytop
|
Write
Preview
Loading…
Cancel
Save
Reference in new issue