|
| 1 | +/**************************************************************************** |
| 2 | + * |
| 3 | + * Copyright (c) 2025 PX4 Development Team. All rights reserved. |
| 4 | + * |
| 5 | + * Redistribution and use in source and binary forms, with or without |
| 6 | + * modification, are permitted provided that the following conditions |
| 7 | + * are met: |
| 8 | + * |
| 9 | + * 1. Redistributions of source code must retain the above copyright |
| 10 | + * notice, this list of conditions and the following disclaimer. |
| 11 | + * 2. Redistributions in binary form must reproduce the above copyright |
| 12 | + * notice, this list of conditions and the following disclaimer in |
| 13 | + * the documentation and/or other materials provided with the |
| 14 | + * distribution. |
| 15 | + * 3. Neither the name PX4 nor the names of its contributors may be |
| 16 | + * used to endorse or promote products derived from this software |
| 17 | + * without specific prior written permission. |
| 18 | + * |
| 19 | + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS |
| 20 | + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT |
| 21 | + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS |
| 22 | + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE |
| 23 | + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, |
| 24 | + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, |
| 25 | + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS |
| 26 | + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED |
| 27 | + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT |
| 28 | + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN |
| 29 | + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE |
| 30 | + * POSSIBILITY OF SUCH DAMAGE. |
| 31 | + * |
| 32 | + ****************************************************************************/ |
| 33 | + |
| 34 | +/** |
| 35 | + * @file HiwonderEMM.hpp |
| 36 | + * |
| 37 | + * Driver for the Hiwonder 4-channel encoder motor driver over I2C. |
| 38 | + * |
| 39 | + * Product: https://www.hiwonder.com/products/4-channel-encoder-motor-driver |
| 40 | + * |
| 41 | + */ |
| 42 | + |
| 43 | +#pragma once |
| 44 | + |
| 45 | +#include <cstdint> |
| 46 | +#include <drivers/device/i2c.h> |
| 47 | +#include <px4_boardconfig.h> |
| 48 | +#include <px4_log.h> |
| 49 | +#include <drivers/device/device.h> |
| 50 | +#include <lib/mixer_module/mixer_module.hpp> |
| 51 | +#include <px4_platform_common/module.h> |
| 52 | +#include <lib/perf/perf_counter.h> |
| 53 | +#include <drivers/drv_hrt.h> |
| 54 | +#include <px4_platform_common/getopt.h> |
| 55 | +#include <px4_platform_common/sem.hpp> |
| 56 | +#include <px4_defines.h> |
| 57 | + |
| 58 | +static constexpr int I2C_ADDR = 0x34; // I2C address |
| 59 | +static constexpr int ADC_BAT_ADDR = 0; // Voltage address |
| 60 | +static constexpr int MOTOR_TYPE_ADDR = 0x14; // Set the motor type |
| 61 | +static constexpr int MOTOR_ENCODER_POLARITY_ADDR = 21; // Set the encoder direction polarity |
| 62 | +static constexpr int MOTOR_FIXED_PWM_ADDR = 31; // Fixed PWM control, open loop |
| 63 | +static constexpr int MOTOR_FIXED_SPEED_ADDR = 51; // Fixed speed control, closed loop |
| 64 | +static constexpr int MOTOR_ENCODER_TOTAL_ADDR = 60; // Total pulse value of 4 encoder motors |
| 65 | +static constexpr int MOTOR_TYPE_WITHOUT_ENCODER = 0; // Motor without encoder |
| 66 | +static constexpr int MOTOR_TYPE_TT = 1; // TT encoder motor |
| 67 | +static constexpr int MOTOR_TYPE_N20 = 2; // N20 encoder motor |
| 68 | +static constexpr int MOTOR_TYPE_JGB37_520_12V_110RPM = 3; // JGB37 encoder motor |
| 69 | +static constexpr int BUS_FREQUENCY = 100000; // I2C bus frequency |
| 70 | +static constexpr int I2CBUS = 1; // I2C bus number |
| 71 | +static constexpr int CHANNEL_COUNT = 4; // Number of output channels |
| 72 | + |
| 73 | +class HiwonderEMM : public ModuleBase<HiwonderEMM>, public OutputModuleInterface, public device::I2C |
| 74 | +{ |
| 75 | +public: |
| 76 | + HiwonderEMM(); |
| 77 | + ~HiwonderEMM() override = default; |
| 78 | + int init() override; |
| 79 | + static int task_spawn(int argc, char *argv[]); |
| 80 | + static int custom_command(int argc, char *argv[]); |
| 81 | + static int print_usage(const char *reason = nullptr); |
| 82 | + bool updateOutputs(uint16_t *outputs, unsigned num_outputs, |
| 83 | + unsigned num_control_groups_updated) override; |
| 84 | + int print_status() override; |
| 85 | + |
| 86 | +protected: |
| 87 | + int probe() override; |
| 88 | + |
| 89 | +private: |
| 90 | + MixingOutput _mixing_output { |
| 91 | + "EMM", |
| 92 | + CHANNEL_COUNT, |
| 93 | + *this, |
| 94 | + MixingOutput::SchedulingPolicy::Auto, |
| 95 | + false |
| 96 | + }; |
| 97 | + void Run() override; |
| 98 | + int read_adc(int &adc_value); |
| 99 | + int set_motor_speed(const uint8_t speed_values[4]); |
| 100 | +}; |
0 commit comments