Line data Source code
1 : /* 2 : This program is free software: you can redistribute it and/or modify 3 : it under the terms of the GNU General Public License as published by 4 : the Free Software Foundation, either version 3 of the License, or 5 : (at your option) any later version. 6 : 7 : This program is distributed in the hope that it will be useful, 8 : but WITHOUT ANY WARRANTY; without even the implied warranty of 9 : MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 10 : GNU General Public License for more details. 11 : 12 : You should have received a copy of the GNU General Public License 13 : along with this program. If not, see <http://www.gnu.org/licenses/>. 14 : */ 15 : #pragma once 16 : 17 : #include <AP_HAL/AP_HAL_Boards.h> 18 : 19 : #ifndef HAL_BUTTON_ENABLED 20 : #define HAL_BUTTON_ENABLED 1 21 : #endif 22 : 23 : #if HAL_BUTTON_ENABLED 24 : 25 : #include <AP_HAL/AP_HAL.h> 26 : #include <AP_Param/AP_Param.h> 27 : 28 : // allow buttons for up to 4 pins 29 : #define AP_BUTTON_NUM_PINS 4 30 : 31 : // how often we send reports 32 : #define AP_BUTTON_REPORT_PERIOD_MS 1000 33 : 34 : class AP_Button { 35 : public: 36 : // constructor 37 : AP_Button(void); 38 : 39 : /* Do not allow copies */ 40 : CLASS_NO_COPY(AP_Button); 41 : 42 : static const struct AP_Param::GroupInfo var_info[]; 43 : 44 : // update button state and send messages, called periodically by main loop 45 : void update(void); 46 : 47 66481 : static AP_Button *get_singleton(void) { 48 66481 : return _singleton; 49 : } 50 : 51 : // get state of a button 52 : // used by scripting 53 : bool get_button_state(uint8_t number); 54 : 55 : // check settings are valid 56 : bool arming_checks(size_t buflen, char *buffer) const; 57 : 58 : private: 59 : 60 : static AP_Button *_singleton; 61 : 62 : AP_Int8 enable; 63 : AP_Int8 pin[AP_BUTTON_NUM_PINS]; 64 : AP_Int8 options[AP_BUTTON_NUM_PINS]; // if a pin's bit is set then it uses PWM assertion 65 : 66 181139 : bool is_pwm_input(uint8_t n) const { 67 181139 : return ((uint8_t)options[n].get() & (1U<<0)) != 0; 68 : } 69 12 : bool is_input_inverted(uint8_t n) const { 70 12 : return ((uint8_t)options[n].get() & (1U<<1)) != 0; 71 : } 72 : 73 : AP_Int16 pin_func[AP_BUTTON_NUM_PINS]; // from the RC_Channel functions 74 : 75 : // number of seconds to send change notifications 76 : AP_Int16 report_send_time; 77 : 78 : // last button press mask 79 : uint8_t last_mask; 80 : 81 : // debounced button press mask 82 : uint8_t debounce_mask; 83 : 84 : // current state of PWM pins: 85 : uint8_t pwm_state; 86 : uint8_t tentative_pwm_state; // for debouncing 87 : uint64_t pwm_start_debounce_ms; 88 : 89 : // mask indicating which action was most recent taken for pins 90 : uint8_t state_actioned_mask; 91 : 92 : // pwm sources are used when using PWM on the input 93 : AP_HAL::PWMSource pwm_pin_source[AP_BUTTON_NUM_PINS]; 94 : 95 : // state from the timer interrupt: 96 : HAL_Semaphore last_debounced_change_ms_sem; 97 : // last time GPIO pins were debounced: 98 : uint64_t last_debounced_change_ms; 99 : 100 : // time at least last debounce changes across both PWM and GPIO 101 : // pins was detected: 102 : uint64_t last_debounce_ms; 103 : 104 : // when the mask last changed 105 : uint64_t last_change_time_ms; 106 : 107 : // when button change events were last actioned 108 : uint64_t last_action_time_ms; 109 : 110 : // true if allocated aux functions have been initialised 111 : bool aux_functions_initialised; 112 : // call init_aux_function for all used functions 113 : void run_aux_functions(bool force); 114 : 115 : // time of last report 116 : uint32_t last_report_ms; 117 : 118 : // has the timer been installed? 119 : bool initialised; 120 : 121 : // called by timer thread 122 : void timer_update(void); 123 : 124 : // get current mask 125 : uint8_t get_mask(void); 126 : 127 : // send a BUTTON_CHANGE report 128 : void send_report(void) const; 129 : 130 : // setup pins as pullup input 131 : void setup_pins(); 132 : }; 133 : 134 : namespace AP { 135 : AP_Button &button(); 136 : }; 137 : 138 : #endif