Line data Source code
1 : /* 2 : This program is free software: you can redistribute it and/or modify 3 : it under the terms of the GNU General Public License as published by 4 : the Free Software Foundation, either version 3 of the License, or 5 : (at your option) any later version. 6 : 7 : This program is distributed in the hope that it will be useful, 8 : but WITHOUT ANY WARRANTY; without even the implied warranty of 9 : MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 10 : GNU General Public License for more details. 11 : 12 : You should have received a copy of the GNU General Public License 13 : along with this program. If not, see <http://www.gnu.org/licenses/>. 14 : */ 15 : /* 16 : * AP_KDECAN.h 17 : * 18 : * Author: Francisco Ferreira and Tom Pittenger 19 : */ 20 : 21 : #pragma once 22 : 23 : #include <AP_KDECAN/AP_KDECAN_config.h> 24 : 25 : #if AP_KDECAN_ENABLED 26 : #include <AP_HAL/AP_HAL.h> 27 : 28 : #include <AP_CANManager/AP_CANSensor.h> 29 : #include <AP_Param/AP_Param.h> 30 : #include <AP_ESC_Telem/AP_ESC_Telem_Backend.h> 31 : 32 : #define AP_KDECAN_USE_EVENTS (defined(CH_CFG_USE_EVENTS) && CH_CFG_USE_EVENTS == TRUE) 33 : 34 : #if AP_KDECAN_USE_EVENTS 35 : #include <ch.h> 36 : #endif 37 : 38 : #define DEFAULT_NUM_POLES 14 39 : 40 : #define KDECAN_MAX_NUM_ESCS 8 41 : 42 : class AP_KDECAN_Driver : public CANSensor 43 : #if HAL_WITH_ESC_TELEM 44 : , public AP_ESC_Telem_Backend 45 : #endif 46 : { 47 : public: 48 : 49 : AP_KDECAN_Driver(); 50 : 51 : // called from SRV_Channels 52 : void update(const uint8_t num_poles); 53 : 54 : private: 55 : 56 : // handler for incoming frames 57 : void handle_frame(AP_HAL::CANFrame &frame) override; 58 : 59 : bool send_packet_uint16(const uint8_t address, const uint8_t dest_id, const uint32_t timeout_us, const uint16_t data); 60 : bool send_packet(const uint8_t address, const uint8_t dest_id, const uint32_t timeout_us, const uint8_t *data = nullptr, const uint8_t data_len = 0); 61 : 62 : void loop(); 63 : 64 : struct { 65 : uint32_t detected_bitmask; 66 : uint32_t detected_bitmask_ms; 67 : } _init; 68 : 69 : struct { 70 : HAL_Semaphore sem; 71 : bool is_new; 72 : uint32_t last_new_ms; 73 : uint16_t pwm[NUM_SERVO_CHANNELS]; 74 : #if AP_KDECAN_USE_EVENTS 75 : thread_t *thread_ctx; 76 : #endif 77 : } _output; 78 : 79 : #if HAL_WITH_ESC_TELEM 80 : struct { 81 : uint8_t num_poles; 82 : uint32_t timer_ms; 83 : } _telemetry; 84 : #endif 85 : 86 : union frame_id_t { 87 : struct PACKED { 88 : uint8_t object_address; 89 : uint8_t destination_id; 90 : uint8_t source_id; 91 : uint8_t priority:5; 92 : uint8_t unused:3; 93 : }; 94 : uint32_t value; 95 : }; 96 : 97 : static const uint8_t AUTOPILOT_NODE_ID = 0; 98 : static const uint8_t BROADCAST_NODE_ID = 1; 99 : static const uint8_t ESC_NODE_ID_FIRST = 2; 100 : 101 : static const uint8_t ESC_INFO_OBJ_ADDR = 0; 102 : static const uint8_t SET_PWM_OBJ_ADDR = 1; 103 : static const uint8_t VOLTAGE_OBJ_ADDR = 2; 104 : static const uint8_t CURRENT_OBJ_ADDR = 3; 105 : static const uint8_t RPM_OBJ_ADDR = 4; 106 : static const uint8_t TEMPERATURE_OBJ_ADDR = 5; 107 : static const uint8_t GET_PWM_INPUT_OBJ_ADDR = 6; 108 : static const uint8_t GET_PWM_OUTPUT_OBJ_ADDR = 7; 109 : static const uint8_t MCU_ID_OBJ_ADDR = 8; 110 : static const uint8_t UPDATE_NODE_ID_OBJ_ADDR = 9; 111 : static const uint8_t ENUM_OBJ_ADDR = 10; 112 : static const uint8_t TELEMETRY_OBJ_ADDR = 11; 113 : 114 : 115 : static const uint32_t TELEMETRY_INTERVAL_MS = 100; 116 : 117 : }; 118 : 119 : class AP_KDECAN { 120 : public: 121 : AP_KDECAN(); 122 : 123 : /* Do not allow copies */ 124 : CLASS_NO_COPY(AP_KDECAN); 125 : 126 : static const struct AP_Param::GroupInfo var_info[]; 127 : 128 : void init(); 129 : void update(); 130 : 131 83384328 : static AP_KDECAN *get_singleton() { return _singleton; } 132 : 133 : private: 134 : static AP_KDECAN *_singleton; 135 : 136 : AP_Int8 _num_poles; 137 : AP_KDECAN_Driver *_driver; 138 : }; 139 : namespace AP { 140 : AP_KDECAN *kdecan(); 141 : }; 142 : 143 : #endif // AP_KDECAN_ENABLED