Line data Source code
1 : /* 2 : Buzzer driver 3 : */ 4 : /* 5 : This program is free software: you can redistribute it and/or modify 6 : it under the terms of the GNU General Public License as published by 7 : the Free Software Foundation, either version 3 of the License, or 8 : (at your option) any later version. 9 : 10 : This program is distributed in the hope that it will be useful, 11 : but WITHOUT ANY WARRANTY; without even the implied warranty of 12 : MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 : GNU General Public License for more details. 14 : 15 : You should have received a copy of the GNU General Public License 16 : along with this program. If not, see <http://www.gnu.org/licenses/>. 17 : */ 18 : #include "Buzzer.h" 19 : 20 : #include <AP_HAL/AP_HAL.h> 21 : 22 : #include "AP_Notify.h" 23 : 24 : extern const AP_HAL::HAL& hal; 25 : 26 2094 : bool Buzzer::init() 27 : { 28 2094 : if (pNotify->buzzer_enabled() == false) { 29 0 : return false; 30 : } 31 2094 : _pin = pNotify->get_buzz_pin(); 32 2094 : if (_pin <= 0) { 33 : // no buzzer 34 2094 : return false; 35 : } 36 : 37 : // setup the pin and ensure it's off 38 0 : hal.gpio->pinMode(_pin, HAL_GPIO_OUTPUT); 39 0 : on(false); 40 : 41 : // set initial boot states. This prevents us issuing a arming 42 : // warning in plane and rover on every boot 43 0 : _flags.armed = AP_Notify::flags.armed; 44 0 : _flags.failsafe_battery = AP_Notify::flags.failsafe_battery; 45 0 : return true; 46 : } 47 : 48 : // update - updates led according to timed_updated. Should be called at 50Hz 49 0 : void Buzzer::update() 50 : { 51 0 : update_pattern_to_play(); 52 0 : update_playing_pattern(); 53 0 : } 54 : 55 0 : void Buzzer::update_pattern_to_play() 56 : { 57 : // check for arming failed event 58 0 : if (AP_Notify::events.arming_failed) { 59 : // arming failed buzz 60 0 : play_pattern(SINGLE_BUZZ); 61 0 : return; 62 : } 63 : 64 0 : if (AP_HAL::millis() - _pattern_start_time < _pattern_start_interval_time_ms) { 65 : // do not interrupt playing patterns / enforce minumum separation 66 0 : return; 67 : } 68 : 69 : // initializing? 70 0 : if (_flags.gyro_calibrated != AP_Notify::flags.gyro_calibrated) { 71 0 : _flags.gyro_calibrated = AP_Notify::flags.gyro_calibrated; 72 0 : play_pattern(INIT_GYRO); 73 : } 74 : 75 : // check if prearm check are good 76 0 : if (AP_Notify::flags.pre_arm_check && !_flags.pre_arm_check) { 77 0 : _flags.pre_arm_check = true; 78 0 : play_pattern(PRE_ARM_GOOD); 79 : } 80 : 81 : // check if armed status has changed 82 0 : if (_flags.armed != AP_Notify::flags.armed) { 83 0 : _flags.armed = AP_Notify::flags.armed; 84 0 : if (_flags.armed) { 85 : // double buzz when armed 86 0 : play_pattern(ARMING_BUZZ); 87 : } else { 88 : // single buzz when disarmed 89 0 : play_pattern(SINGLE_BUZZ); 90 : } 91 0 : return; 92 : } 93 : 94 : // check ekf bad 95 0 : if (_flags.ekf_bad != AP_Notify::flags.ekf_bad) { 96 0 : _flags.ekf_bad = AP_Notify::flags.ekf_bad; 97 0 : if (_flags.ekf_bad) { 98 : // ekf bad warning buzz 99 0 : play_pattern(EKF_BAD); 100 : } 101 0 : return; 102 : } 103 : 104 : // if vehicle lost was enabled, starting beep 105 0 : if (AP_Notify::flags.vehicle_lost) { 106 0 : play_pattern(DOUBLE_BUZZ); 107 0 : return; 108 : } 109 : 110 : // if battery failsafe constantly single buzz 111 0 : if (AP_Notify::flags.failsafe_battery) { 112 0 : play_pattern(SINGLE_BUZZ); 113 0 : return; 114 : } 115 : } 116 : 117 : 118 0 : void Buzzer::update_playing_pattern() 119 : { 120 0 : if (_pattern == 0UL) { 121 0 : return; 122 : } 123 : 124 0 : const uint32_t delta = AP_HAL::millis() - _pattern_start_time; 125 0 : if (delta >= 3200) { 126 : // finished playing pattern 127 0 : on(false); 128 0 : _pattern = 0UL; 129 0 : return; 130 : } 131 0 : const uint32_t bit = delta / 100UL; // each bit is 100ms 132 0 : on(_pattern & (1U<<(31-bit))); 133 : } 134 : 135 : // on - turns the buzzer on or off 136 0 : void Buzzer::on(bool turn_on) 137 : { 138 : // return immediately if nothing to do 139 0 : if (_flags.on == turn_on) { 140 0 : return; 141 : } 142 : 143 : // update state 144 0 : _flags.on = turn_on; 145 : 146 : // pull pin high or low 147 0 : const uint8_t buzz_on = pNotify->get_buzz_level(); 148 0 : hal.gpio->write(_pin, _flags.on? buzz_on : !buzz_on); 149 : } 150 : 151 : /// play_pattern - plays the defined buzzer pattern 152 0 : void Buzzer::play_pattern(const uint32_t pattern) 153 : { 154 0 : _pattern = pattern; 155 0 : _pattern_start_time = AP_HAL::millis(); 156 0 : } 157 :