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.

138 lines
6.5 KiB

2 years ago
2 years ago
2 years ago
  1. //
  2. // Created by zwsd
  3. //
  4. #pragma once
  5. #include <map>
  6. #include "basic.hpp"
  7. #include "sdk/os/zos.hpp"
  8. #include "sdk\components\zprotocols\zcancmder\zcancmder_protocol.hpp"
  9. #define ZCAN_SEND_CMD_PREFIX(varcmdid, overtime) \
  10. auto *cmdheader = (Cmdheader_t *)m_txbuf; \
  11. auto *cmd = (varcmdid##_cmd_t *)cmdheader->data; \
  12. cmdheader->cmdid = MODULE_CMDID(varcmdid); \
  13. cmdheader->subcmdid = SUBCMDID(varcmdid); \
  14. cmdheader->packetType = zcr::kpt_cmd; \
  15. static_assert(sizeof(varcmdid##_cmd_t) <= sizeof(m_txbuf), "m_txbuf is too small"); \
  16. cmd->id = m_id;
  17. #define ZCAN_SEND_CMD_WITH_STATUS_CB(varcmdid, overtime, ...) \
  18. ZCAN_SEND_CMD_PREFIX(varcmdid, overtime) \
  19. __VA_ARGS__ \
  20. int32_t errorcode = m_cancmder->sendCmdWithStatusCb((uint8_t *)m_txbuf, sizeof(*cmdheader) + sizeof(*cmd), getindexcache(varcmdid), overtime, status_cb); \
  21. return errorcode;
  22. #define ZCAN_SEND_CMD(varcmdid, ack, overtime, ...) \
  23. ZCAN_SEND_CMD_PREFIX(varcmdid, overtime) \
  24. __VA_ARGS__ \
  25. int32_t errorcode = m_cancmder->sendCmd((uint8_t *)m_txbuf, sizeof(*cmdheader) + sizeof(*cmd), (uint8_t *)&ack, sizeof(ack), overtime); \
  26. return errorcode;
  27. #define ZCAN_SEND_CMD_NO_ACK(varcmdid, overtime, ...) \
  28. ZCAN_SEND_CMD_PREFIX(varcmdid, overtime) \
  29. __VA_ARGS__ \
  30. int32_t errorcode = m_cancmder->sendCmdNoAck((uint8_t *)m_txbuf, sizeof(*cmdheader) + sizeof(*cmd), overtime); \
  31. return errorcode;
  32. namespace iflytop {
  33. using namespace std;
  34. typedef function<void(CanPacketRxBuffer *report)> zcan_commnader_master_onpacket_t;
  35. class ZCanCommnaderMasterListener {
  36. public:
  37. zcan_commnader_master_onpacket_t on_ack;
  38. zcan_commnader_master_onpacket_t on_cmd_exec_status_report;
  39. zcan_commnader_master_onpacket_t on_report;
  40. };
  41. class ZCanCommnaderMaster : public ZCanIRQListener {
  42. public:
  43. class CFG {
  44. public:
  45. uint8_t deviceId; //
  46. /*******************************************************************************
  47. * CANConfig *
  48. *******************************************************************************/
  49. CAN_HandleTypeDef *canHandle; // Ĭ��ʹ��CAN1
  50. int canFilterIndex0; // ������0 ���գ�������������Ϣ
  51. int maxFilterNum; // ʹ�õĹ���������������ֵ14��Ĭ��Ϊ7
  52. int rxfifoNum; // ʹ�õ�FIFO,Ĭ��ʹ��FIFO0
  53. int packetRxOvertime_ms; //
  54. };
  55. uint8_t txbuff[2100];
  56. public:
  57. class LoopJobContext {
  58. public:
  59. bool hasDoneSomething;
  60. };
  61. private:
  62. CFG *m_config = NULL; // ����
  63. bool m_canOnRxDataFlag = false; // �Ƿ������ݽ��գ����ڴ��ж�������ת�Ƶ�MainLoop������
  64. uint32_t m_lastPacketTicket = 0; // ��һ�ν��յ���Ϣ��ʱ�䣬�����ж��������Ƿ��Ͽ�����
  65. HAL_StatusTypeDef m_lastTransmitStatus; // �ϴε���can���ͷ����ķ���ֵ
  66. #define CAN_PACKET_RX_BUFFER_NUM 5
  67. CanPacketRxBuffer m_canPacketRxBuffer[CAN_PACKET_RX_BUFFER_NUM];
  68. int txPacketInterval_ms = 0;
  69. ZThread m_loopThread;
  70. map<uint16_t, ZCanCommnaderMasterListener> m_on_packet_map;
  71. zmutex m_on_packet_map_lock;
  72. uint16_t m_index_off = 0;
  73. zmutex txlock;
  74. public:
  75. ZCanCommnaderMaster() {}
  76. CFG *createCFG();
  77. void init(CFG *cfg);
  78. int32_t sendCmd(uint8_t *packet, size_t len, uint8_t *rxbuf, size_t rxbuflen, int overtime_ms);
  79. int32_t sendCmdNoAck(uint8_t *packet, size_t len, int overtime_ms);
  80. int32_t sendCmdWithStatusCb(uint8_t *packet, size_t len, uint16_t &packetindex, int overtime_ms, action_cb_status_t status_cb);
  81. int32_t sendPacketBlock(uint8_t *packet, size_t len, uint16_t &packetindex, uint8_t *rxbuf, size_t rxbuflen, int overtime_ms, zcan_commnader_master_onpacket_t onReport);
  82. void setTxPacketInterval(int interval_ms) { txPacketInterval_ms = interval_ms; }
  83. public:
  84. virtual void STM32_HAL_onCAN_RxFifo0MsgPending(CAN_HandleTypeDef *can);
  85. virtual void STM32_HAL_onCAN_Error(CAN_HandleTypeDef *can);
  86. private:
  87. void loop();
  88. uint8_t getDeviceId() { return m_config->deviceId; }
  89. void sendPacket(uint8_t *packet, size_t len);
  90. void regListener(uint16_t index, //
  91. zcan_commnader_master_onpacket_t onack, //
  92. zcan_commnader_master_onpacket_t on_cmd_exec_status_report, //
  93. zcan_commnader_master_onpacket_t on_report);
  94. void unregListener(uint16_t index);
  95. void callListener(CanPacketRxBuffer *report);
  96. void unregListenerAckCB(uint16_t index);
  97. bool isListenerReg(uint16_t index);
  98. int getListenerNum();
  99. uint16_t generateFreeIndex();
  100. bool sendPacketSub(int npacket, int packetIndex, uint8_t *packet, size_t len, int overtimems);
  101. HAL_StatusTypeDef initializeFilter();
  102. HAL_StatusTypeDef activateRxIT();
  103. HAL_StatusTypeDef deactivateRxIT();
  104. bool getRxMessage(CAN_RxHeaderTypeDef *pHeader, uint8_t aData[] /*8byte table*/);
  105. size_t safe_memcpy(void *dst, size_t dst_max_size, void *src, size_t src_len);
  106. void initCanPacketRxBuffer(CanPacketRxBuffer *buf, uint16_t id);
  107. CanPacketRxBuffer *allocCanPacketRxBufferInIRQ(uint16_t id);
  108. CanPacketRxBuffer *findCanPacketRxBufferInIRQ(uint16_t id);
  109. void freeCanPacketRxBuffer(uint16_t id);
  110. void processReadyPacket(CanPacketRxBuffer *buf);
  111. };
  112. } // namespace iflytop