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.

151 lines
5.5 KiB

12 months ago
  1. #pragma once
  2. #include "base/appdep.hpp"
  3. namespace iflytop {
  4. using namespace transmit_disfection_protocol;
  5. typedef enum {
  6. kIOBlower,
  7. kHighPowerUartBlower,
  8. kMiniPwmBlower,
  9. } BlowerType_t;
  10. class BlowerController {
  11. BlowerType_t m_blowerType = kIOBlower;
  12. // kIOBlower
  13. ZGPIO m_ctrlGpio;
  14. // kHighPowerUartBlower
  15. ModbusBlockHost m_modbusblock;
  16. // kMiniPwmBlower
  17. TIM_HandleTypeDef* m_miniPwmBlower_htim;
  18. uint32_t m_miniPwmBlower_channle;
  19. ZGPIO m_miniPwmBlower_enGpio;
  20. ZGPIO m_miniPwmBlower_fbGpio;
  21. ZADC m_iadc;
  22. bool m_iadcIsInit = false;
  23. bool m_isInitialized = false;
  24. bool isopen = false;
  25. public:
  26. void initialize(Pin_t ctrlGpio, ADC_HandleTypeDef* iadc, uint32_t ich) {
  27. m_ctrlGpio.initAsOutput(ctrlGpio, kxs_gpio_nopull, true, false);
  28. m_iadc.initialize("Blower-iadc", iadc, ich);
  29. AppPeriodTaskMgr::ins()->regTask("AC-ADC", [this]() { periodTask(); }, 1000);
  30. m_blowerType = kIOBlower;
  31. m_isInitialized = true;
  32. bindFn();
  33. }
  34. void initializeAsHighPowerUartBlower(UART_HandleTypeDef* huart, ADC_HandleTypeDef* iadc, uint32_t ich) {
  35. m_modbusblock.initialize(huart);
  36. m_iadc.initialize("Blower-iadc", iadc, ich);
  37. AppPeriodTaskMgr::ins()->regTask("AC-ADC", [this]() { periodTask(); }, 1000);
  38. m_blowerType = kHighPowerUartBlower;
  39. m_isInitialized = true;
  40. bindFn();
  41. }
  42. void initializeAsMiniPwmBlower(TIM_HandleTypeDef* htim, uint32_t channel, Pin_t enGpio, Pin_t fbGpio) {
  43. m_miniPwmBlower_htim = htim;
  44. m_miniPwmBlower_channle = channel;
  45. m_miniPwmBlower_enGpio.initAsOutput(enGpio, kxs_gpio_nopull, true, false);
  46. m_miniPwmBlower_fbGpio.initAsInput(fbGpio, kxs_gpio_nopull, kxs_gpio_rising_irq, false);
  47. AppPeriodTaskMgr::ins()->regTask("AC-ADC", [this]() { periodTask(); }, 1000);
  48. m_blowerType = kMiniPwmBlower;
  49. m_isInitialized = true;
  50. bindFn();
  51. }
  52. bool isInitialized() { return m_isInitialized; }
  53. void bindFn() {
  54. BIND_FN(BlowerController, this, fn_blower_ctrl);
  55. BIND_FN(BlowerController, this, fn_blower_ctrl_safe_valve);
  56. BIND_FN(BlowerController, this, fn_blower_read_ei);
  57. BIND_FN(BlowerController, this, fn_blower_is_error);
  58. BIND_FN(BlowerController, this, fn_blower_read_ei_adc_raw);
  59. BIND_FN(BlowerController, this, fn_blower_is_open);
  60. }
  61. /***********************************************************************************************************************
  62. * FN *
  63. ***********************************************************************************************************************/
  64. void blower_ctrl(int32_t val) {
  65. if (m_blowerType == kIOBlower) {
  66. m_ctrlGpio.write(val);
  67. } else if (m_blowerType == kHighPowerUartBlower) {
  68. if (val > 0) {
  69. m_modbusblock.writeReg06(1, 0x2000, 1, 100);
  70. } else {
  71. m_modbusblock.writeReg06(1, 0x2000, 6, 100);
  72. }
  73. } else if (m_blowerType == kMiniPwmBlower) {
  74. mini_pwm_blower_ctrl(val);
  75. }
  76. }
  77. void blower_ctrl_safe_valve(int32_t val) {}
  78. int32_t blower_read_ei() {
  79. if (m_blowerType == kIOBlower || m_blowerType == kHighPowerUartBlower) {
  80. return blowserAdcToCurrent(m_iadc.getCacheVal());
  81. }
  82. return 0;
  83. }
  84. int32_t blower_read_iadc() {
  85. if (m_blowerType == kIOBlower || m_blowerType == kHighPowerUartBlower) {
  86. return m_iadc.getCacheVal();
  87. }
  88. return 0;
  89. }
  90. int32_t blower_is_error() {
  91. // TODO: 栏杆箱消毒机添加故障检测
  92. return 0;
  93. }
  94. void periodTask() {
  95. if (m_iadc.isInited()) m_iadc.updateAdcValToCache();
  96. }
  97. /***********************************************************************************************************************
  98. * PP *
  99. ***********************************************************************************************************************/
  100. void fn_blower_ctrl(ProcessContext* cxt) { //
  101. blower_ctrl(GET_PARAM(0));
  102. zcanbus_send_ack(cxt->packet, NULL, 0);
  103. isopen = GET_PARAM(0) > 0 ? true : false;
  104. }
  105. void fn_blower_ctrl_safe_valve(ProcessContext* cxt) { //
  106. blower_ctrl_safe_valve(GET_PARAM(0));
  107. zcanbus_send_ack(cxt->packet, NULL, 0);
  108. }
  109. void fn_blower_read_ei(ProcessContext* cxt) { zcanbus_send_ack(cxt->packet, blower_read_ei()); }
  110. void fn_blower_read_ei_adc_raw(ProcessContext* cxt) { zcanbus_send_ack(cxt->packet, m_iadc.getCacheVal()); }
  111. void fn_blower_is_error(ProcessContext* cxt) { zcanbus_send_ack(cxt->packet, blower_is_error()); }
  112. void fn_blower_is_open(ProcessContext* cxt) { zcanbus_send_ack(cxt->packet, isopen); }
  113. private:
  114. void mini_pwm_blower_ctrl(int32_t duty) {
  115. duty = 100 - duty;
  116. if (duty < 0) duty = 0;
  117. if (duty > 100) duty = 100;
  118. TIM_OC_InitTypeDef sConfigOC = {0};
  119. sConfigOC.OCMode = TIM_OCMODE_PWM1;
  120. sConfigOC.Pulse = duty / 100.0 * __HAL_TIM_GET_AUTORELOAD(m_miniPwmBlower_htim);
  121. sConfigOC.OCPolarity = TIM_OCPOLARITY_HIGH;
  122. sConfigOC.OCFastMode = TIM_OCFAST_DISABLE;
  123. sConfigOC.OCIdleState = TIM_OCIDLESTATE_RESET;
  124. sConfigOC.OCNIdleState = TIM_OCNIDLESTATE_RESET;
  125. HAL_TIM_PWM_ConfigChannel(m_miniPwmBlower_htim, &sConfigOC, m_miniPwmBlower_channle);
  126. HAL_TIM_PWM_Stop(m_miniPwmBlower_htim, m_miniPwmBlower_channle);
  127. HAL_TIM_PWM_Start(m_miniPwmBlower_htim, m_miniPwmBlower_channle);
  128. m_miniPwmBlower_enGpio.write(duty != 0);
  129. }
  130. };
  131. } // namespace iflytop