3 #if CONFIG_HAL_BOARD_SUBTYPE == HAL_BOARD_SUBTYPE_LINUX_BEBOP || CONFIG_HAL_BOARD_SUBTYPE == HAL_BOARD_SUBTYPE_LINUX_DISCO 22 #define BEBOP_BLDC_I2C_ADDR 0x08 23 #define BEBOP_BLDC_STARTPROP 0x40 24 #define BEBOP_BLDC_SETREFSPEED 0x02 26 #define BEBOP_BLDC_GETOBSDATA 0x20 39 #define BEBOP_BLDC_TOGGLE_GPIO 0x4d 40 #define BEBOP_BLDC_GPIO_0 (1 << 0) 41 #define BEBOP_BLDC_GPIO_1 (1 << 1) 42 #define BEBOP_BLDC_GPIO_2 (1 << 2) 43 #define BEBOP_BLDC_GPIO_3 (1 << 3) 44 #define BEBOP_BLDC_GPIO_POWER (1 << 4) 46 #define BEBOP_BLDC_STOP_PROP 0x60 48 #define BEBOP_BLDC_CLEAR_ERROR 0x80 50 #define BEBOP_BLDC_PLAY_SOUND 0x82 52 #define BEBOP_BLDC_GET_INFO 0xA0 54 #define BEBOP_BLDC_MIN_PERIOD_US 1100 55 #define BEBOP_BLDC_MAX_PERIOD_US 1900 56 #define BEBOP_BLDC_MIN_RPM 1000 58 #define BEBOP_BLDC_MAX_RPM_1 11000 59 #define BEBOP_BLDC_MAX_RPM_2 12200 60 #define BEBOP_BLDC_MAX_RPM_DISCO 12500 65 #define RCOUT_BEBOP_RTPRIO 14 67 #define BEBOP_BLDC_TIMEOUT_NS 500000000 82 using namespace Linux;
87 : _dev(
std::move(dev))
99 uint8_t checksum = data[0];
102 for (i = 1; i < len; i++)
103 checksum = checksum ^ data[i];
124 struct PACKED bldc_ref_speed_data {
127 uint8_t enable_security;
138 data.enable_security = 0;
139 data.checksum =
_checksum((uint8_t *) &data,
sizeof(data) - 1);
145 _dev->
transfer((uint8_t *)&data,
sizeof(data),
nullptr, 0);
152 if (info ==
nullptr) {
156 memset(info, 0,
sizeof(
struct bldc_info));
171 struct PACKED bldc_obs_data {
178 #if CONFIG_HAL_BOARD_SUBTYPE == HAL_BOARD_SUBTYPE_LINUX_DISCO 188 memset(&data, 0,
sizeof(data));
196 if (data.checksum !=
_checksum((uint8_t*)&data,
sizeof(data)-1)) {
200 memset(&obs, 0,
sizeof(obs));
203 for (uint8_t i = 0; i <
_n_motors; i++) {
207 data.rpm[i] &= (uint16_t)(~(1 << 7));
209 if (obs.
rpm[i] == 0) {
213 printf(
"rpm %u %u %u %u status 0x%02x temp %u\n",
215 (
unsigned)data.status,
216 (
unsigned)data.temp);
222 switch (bldc_status) {
235 obs.
error = data.error;
294 uint16_t duration_ms)
309 msg.period =
htobe16(period_us);
310 msg.duration =
htobe16(duration_ms);
316 _dev->
transfer((uint8_t *)&msg,
sizeof(msg),
nullptr, 0);
323 float period_us_fl = period_us;
327 return (uint16_t)rpm_fl;
335 pthread_condattr_t cond_attr;
338 ret = pthread_mutex_init(&
_mutex,
nullptr);
340 perror(
"RCout_Bebop: failed to init mutex\n");
344 pthread_mutex_lock(&
_mutex);
346 pthread_condattr_init(&cond_attr);
347 pthread_condattr_setclock(&cond_attr, CLOCK_MONOTONIC);
348 ret = pthread_cond_init(&
_cond, &cond_attr);
349 pthread_condattr_destroy(&cond_attr);
351 perror(
"RCout_Bebop: failed to init cond\n");
355 ret = pthread_attr_init(&attr);
357 perror(
"RCOut_Bebop: failed to init attr\n");
360 pthread_attr_setinheritsched(&attr, PTHREAD_EXPLICIT_SCHED);
361 pthread_attr_setschedpolicy(&attr, SCHED_FIFO);
362 pthread_attr_setschedparam(&attr, ¶m);
365 perror(
"RCOut_Bebop: failed to create thread\n");
378 pthread_mutex_unlock(&
_mutex);
425 pthread_mutex_lock(&
_mutex);
427 pthread_cond_signal(&
_cond);
428 pthread_mutex_unlock(&
_mutex);
443 for (
int i = 0; i < len; i++) {
444 period_us[i] =
read(0 + i);
472 memset(current_period_us, 0,
sizeof(current_period_us));
481 #if CONFIG_HAL_BOARD_SUBTYPE != HAL_BOARD_SUBTYPE_LINUX_DISCO 482 uint8_t bebop_bldc_right_front, bebop_bldc_left_front,
483 bebop_bldc_left_back, bebop_bldc_right_back;
490 bebop_bldc_left_front = BEBOP_BLDC_MOTOR_2;
491 bebop_bldc_left_back = BEBOP_BLDC_MOTOR_3;
492 bebop_bldc_right_back = BEBOP_BLDC_MOTOR_4;
494 bebop_bldc_right_front = BEBOP_BLDC_MOTOR_2;
496 bebop_bldc_left_back = BEBOP_BLDC_MOTOR_4;
497 bebop_bldc_right_back = BEBOP_BLDC_MOTOR_3;
500 bebop_bldc_channels[0] = bebop_bldc_right_front;
501 bebop_bldc_channels[1] = bebop_bldc_left_back;
502 bebop_bldc_channels[2] = bebop_bldc_left_front;
503 bebop_bldc_channels[3] = bebop_bldc_right_back;
513 }
else if (hw_version < 0) {
518 printf(
"Bebop: vers %u/%u type %u nmotors %u n_flights %u last_flight_time %u total_flight_time %u maxrpm %u\n",
525 pthread_mutex_lock(&
_mutex);
528 pthread_mutex_unlock(&
_mutex);
541 ret = pthread_cond_timedwait(&
_cond, &
_mutex, &ts);
545 pthread_mutex_unlock(&
_mutex);
550 if (current_period_us[i] <=
_min_pwm + 50) {
uint16_t last_flight_time
int printf(const char *fmt,...)
static uint32_t be32toh(be32_t value)
void clock_gettime(uint32_t a1, void *a2)
int16_t constrain_int16(const int16_t amt, const int16_t low, const int16_t high)
#define BEBOP_BLDC_SETREFSPEED
void set_esc_scaling(uint16_t min_pwm, uint16_t max_pwm) override
#define BEBOP_BLDC_PLAY_SOUND
#define BEBOP_BLDC_STOP_PROP
int read_obs_data(BebopBLDC_ObsData &data)
char * strerror(int errnum)
POSIX strerror() - convert POSIX errno to text with user message.
#define BEBOP_BLDC_MAX_RPM_DISCO
virtual Semaphore * get_semaphore() override=0
#define BEBOP_BLDC_GETOBSDATA
bool _get_info(struct bldc_info *info)
uint16_t read(uint8_t ch) override
#define HAL_SEMAPHORE_BLOCK_FOREVER
virtual bool take(uint32_t timeout_ms) WARN_IF_UNUSED=0
#define BEBOP_BLDC_CLEAR_ERROR
#define BEBOP_BLDC_TIMEOUT_NS
#define BEBOP_BLDC_TOGGLE_GPIO
uint16_t _rpm[BEBOP_BLDC_MOTORS_NUM]
#define BEBOP_BLDC_GPIO_POWER
uint16_t get_freq(uint8_t ch) override
#define BEBOP_BLDC_GET_INFO
uint8_t rpm_saturated[BEBOP_BLDC_MOTORS_NUM]
void enable_ch(uint8_t ch) override
static Util * from(AP_HAL::Util *util)
uint16_t _request_period_us[BEBOP_BLDC_MOTORS_NUM]
uint16_t _period_us_to_rpm(uint16_t period_us)
void perror(const char *s)
POSIX perror() - convert POSIX errno to text with user message.
static uint16_t be16toh(be16_t value)
uint16_t _period_us[BEBOP_BLDC_MOTORS_NUM]
static AP_HAL::OwnPtr< AP_HAL::Device > dev
void _set_ref_speed(uint16_t rpm[BEBOP_BLDC_MOTORS_NUM])
void disable_ch(uint8_t ch) override
#define BEBOP_BLDC_MAX_RPM_1
virtual bool transfer(const uint8_t *send, uint32_t send_len, uint8_t *recv, uint32_t recv_len) override=0
#define RCOUT_BEBOP_RTPRIO
static be16_t htobe16(uint16_t value)
void _toggle_gpio(uint8_t mask)
uint16_t rpm[BEBOP_BLDC_MOTORS_NUM]
static const AP_HAL::HAL & hal
#define BEBOP_BLDC_MAX_PERIOD_US
#define BEBOP_BLDC_STARTPROP
#define BEBOP_BLDC_GPIO_2
AP_HAL::OwnPtr< AP_HAL::I2CDevice > _dev
static void * _control_thread(void *arg)
#define error(fmt, args ...)
uint8_t _checksum(uint8_t *data, unsigned int len)
uint32_t total_flight_time
bool read_registers(uint8_t first_reg, uint8_t *recv, uint32_t recv_len)
void set_freq(uint32_t chmask, uint16_t freq_hz) override
void panic(const char *errormsg,...) FMT_PRINTF(1
#define BEBOP_BLDC_MAX_RPM_2
void write(uint8_t ch, uint16_t period_us) override
bool write_register(uint8_t reg, uint8_t val, bool checked=false)
void _play_sound(uint8_t sound)
#define BEBOP_BLDC_MIN_PERIOD_US
uint16_t __ap_bitwise be16_t
void play_note(uint8_t pwm, uint16_t period_us, uint16_t duration_ms)
#define BEBOP_BLDC_MIN_RPM