Line data Source code
1 : #include "AP_HAL.h" 2 : 3 : extern const AP_HAL::HAL &hal; 4 : 5 : uint32_t AP_HAL::RCOutput::DSHOT_BIT_WIDTH_TICKS = DSHOT_BIT_WIDTH_TICKS_DEFAULT; 6 : uint32_t AP_HAL::RCOutput::DSHOT_BIT_0_TICKS = DSHOT_BIT_0_TICKS_DEFAULT; 7 : uint32_t AP_HAL::RCOutput::DSHOT_BIT_1_TICKS = DSHOT_BIT_1_TICKS_DEFAULT; 8 : 9 : // helper function for implementation of get_output_mode_banner 10 0 : const char* AP_HAL::RCOutput::get_output_mode_string(enum output_mode out_mode) const 11 : { 12 : // convert mode to string 13 0 : switch (out_mode) { 14 0 : case MODE_PWM_NONE: 15 0 : return "None"; 16 0 : case MODE_PWM_NORMAL: 17 0 : return "PWM"; 18 0 : case MODE_PWM_ONESHOT: 19 0 : return "OneS"; 20 0 : case MODE_PWM_ONESHOT125: 21 0 : return "OS125"; 22 0 : case MODE_PWM_BRUSHED: 23 0 : return "Brush"; 24 0 : case MODE_PWM_DSHOT150: 25 0 : return "DS150"; 26 0 : case MODE_PWM_DSHOT300: 27 0 : return "DS300"; 28 0 : case MODE_PWM_DSHOT600: 29 0 : return "DS600"; 30 0 : case MODE_PWM_DSHOT1200: 31 0 : return "DS1200"; 32 0 : case MODE_NEOPIXEL: 33 : case MODE_NEOPIXELRGB: 34 0 : return "NeoP"; 35 0 : case MODE_PROFILED: 36 0 : return "ProfiLED"; 37 : } 38 : 39 : // we should never reach here but just in case 40 0 : return "Unknown"; 41 : } 42 : 43 : // convert output mode to string. helper function for implementation of get_output_mode_banner 44 0 : void AP_HAL::RCOutput::append_to_banner(char banner_msg[], uint8_t banner_msg_len, output_mode out_mode, uint8_t low_ch, uint8_t high_ch) const 45 : { 46 0 : const char* mode_str = get_output_mode_string(out_mode); 47 : 48 : // make copy of banner_msg 49 0 : char banner_msg_temp[banner_msg_len]; 50 0 : memcpy(banner_msg_temp, banner_msg, banner_msg_len); 51 : 52 0 : if (low_ch == high_ch) { 53 : // handle single channel case 54 0 : hal.util->snprintf(banner_msg, banner_msg_len, "%s %s:%u", banner_msg_temp, mode_str, (unsigned)low_ch); 55 : } else { 56 : // the general case 57 0 : hal.util->snprintf(banner_msg, banner_msg_len, "%s %s:%u-%u", banner_msg_temp, mode_str, (unsigned)low_ch, (unsigned)high_ch); 58 : } 59 0 : } 60 : 61 : /* 62 : true when the output mode is of type dshot 63 : */ 64 0 : bool AP_HAL::RCOutput::is_dshot_protocol(const enum output_mode mode) 65 : { 66 0 : switch (mode) { 67 0 : case MODE_PWM_DSHOT150: 68 : case MODE_PWM_DSHOT300: 69 : case MODE_PWM_DSHOT600: 70 : case MODE_PWM_DSHOT1200: 71 0 : return true; 72 0 : default: 73 0 : return false; 74 : } 75 : } 76 : 77 : /* 78 : * calculate the prescaler required to achieve the desire bitrate 79 : */ 80 154 : uint32_t AP_HAL::RCOutput::calculate_bitrate_prescaler(uint32_t timer_clock, uint32_t target_frequency, bool at_least_freq) 81 : { 82 154 : if (target_frequency > timer_clock) { 83 : // we can't achieve the desired frequency 84 0 : return 0; 85 : } 86 : 87 : uint32_t prescaler; 88 : 89 154 : if (at_least_freq) { // choose a frequency of at least the target, needed by BLHeli_S 90 56 : prescaler = uint32_t(floorf((float) timer_clock / target_frequency + 0.01f) - 1); 91 : } else { // original prescaler calculation from betaflight, chooses closest 92 : // bi-dir dshot is incredibly sensitive to the bitrate 93 98 : prescaler = uint32_t(lrintf((float) timer_clock / target_frequency + 0.01f) - 1); 94 : } 95 : 96 154 : return prescaler; 97 : } 98 : 99 : /* 100 : returns the pwm value scaled to [-1;1] regrading to set_esc_scaling ranges range without constraints. 101 : */ 102 0 : float AP_HAL::RCOutput::scale_esc_to_unity(uint16_t pwm) const 103 : { 104 0 : return 2.0 * ((float) pwm - _esc_pwm_min) / (_esc_pwm_max - _esc_pwm_min) - 1.0; 105 : } 106 :