diff --git a/libraries/AP_HAL_ChibiOS/RCOutput.cpp b/libraries/AP_HAL_ChibiOS/RCOutput.cpp index f2db63ba94..6a3466e855 100644 --- a/libraries/AP_HAL_ChibiOS/RCOutput.cpp +++ b/libraries/AP_HAL_ChibiOS/RCOutput.cpp @@ -197,6 +197,16 @@ void RCOutput::rcout_thread() // process any pending RC output requests timer_tick(time_out_us); +#if RCOU_DSHOT_TIMING_DEBUG + static bool output_masks = true; + if (AP_HAL::millis() > 5000 && output_masks) { + output_masks = false; + hal.console->printf("bdmask 0x%x, en_mask 0x%lx, 3dmask 0x%x:\n", _bdshot.mask, en_mask, _reversible_mask); + for (auto &group : pwm_group_list) { + hal.console->printf(" timer %u: ch_mask 0x%x, en_mask 0x%x\n", group.timer_id, group.ch_mask, group.en_mask); + } + } +#endif } } @@ -1328,8 +1338,9 @@ void RCOutput::dshot_send(pwm_group &group, uint32_t time_out_us) // assume that we won't be able to get the input capture lock group.bdshot.enabled = false; + uint16_t active_channels = group.ch_mask & group.en_mask; // now grab the input capture lock if we are able, we can only enable bi-dir on a group basis - if (((_bdshot.mask & group.ch_mask) == group.ch_mask) && group.has_ic()) { + if (((_bdshot.mask & active_channels) == active_channels) && group.has_ic()) { if (group.has_shared_ic_up_dma()) { // no locking required group.bdshot.enabled = true; @@ -1388,18 +1399,19 @@ void RCOutput::dshot_send(pwm_group &group, uint32_t time_out_us) #endif _bdshot.erpm[chan] = erpm; #endif + if (safety_on && !(safety_mask & (1U<<(chan+chan_offset)))) { + // safety is on, don't output anything + continue; + } + uint16_t pwm = period[chan]; - if (safety_on && !(safety_mask & (1U<<(chan+chan_offset)))) { - // safety is on, overwride pwm - pwm = 0; + if (pwm == 0) { + // no pwm, don't output anything + continue; } const uint16_t chan_mask = (1U<is_locked(), "DMA handle is already locked"); @@ -48,9 +50,10 @@ bool RCOutput::dshot_send_command(pwm_group& group, uint8_t command, uint8_t cha group.dshot_waiter = rcout_thread_ctx; bool bdshot_telem = false; #ifdef HAL_WITH_BIDIR_DSHOT + uint16_t active_channels = group.ch_mask & group.en_mask; // no need to get the input capture lock group.bdshot.enabled = false; - if ((_bdshot.mask & group.ch_mask) == group.ch_mask) { + if ((_bdshot.mask & active_channels) == active_channels) { bdshot_telem = true; // it's not clear why this is required, but without it we get no output if (group.pwm_started) { @@ -68,9 +71,13 @@ bool RCOutput::dshot_send_command(pwm_group& group, uint8_t command, uint8_t cha const uint16_t packet = create_dshot_packet(command, true, bdshot_telem); for (uint8_t i = 0; i < 4; i++) { - if (group.chan[i] == chan || (chan == RCOutput::ALL_CHANNELS && group.is_chan_enabled(i))) { + if (!group.is_chan_enabled(i)) { + continue; + } + + if (group.chan[i] == chan || chan == RCOutput::ALL_CHANNELS) { fill_DMA_buffer_dshot(group.dma_buffer + i, 4, packet, group.bit_width_mul); - } else if (group.is_chan_enabled(i)) { + } else { fill_DMA_buffer_dshot(group.dma_buffer + i, 4, zero_packet, group.bit_width_mul); } } @@ -78,7 +85,9 @@ bool RCOutput::dshot_send_command(pwm_group& group, uint8_t command, uint8_t cha chEvtGetAndClearEvents(group.dshot_event_mask); // start sending the pulses out send_pulses_DMAR(group, DSHOT_BUFFER_LENGTH); +#ifdef HAL_GPIO_LINE_GPIO81 TOGGLE_PIN_DEBUG(81); +#endif return true; }