Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Copter-3.6: check aux switch and mode switch inputs are within range #10216

Merged
merged 2 commits into from
Jan 11, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion ArduCopter/Copter.h
Original file line number Diff line number Diff line change
Expand Up @@ -899,7 +899,7 @@ class Copter : public AP_HAL::HAL::Callbacks {
bool check_if_auxsw_mode_used(uint8_t auxsw_mode_check);
bool check_duplicate_auxsw(void);
void reset_control_switch();
uint8_t read_3pos_switch(uint8_t chan);
bool read_3pos_switch(uint8_t chan, uint8_t &ret) const WARN_IF_UNUSED;
void read_aux_switches();
void init_aux_switches();
void init_aux_switch_function(int8_t ch_option, uint8_t ch_flag);
Expand Down
78 changes: 55 additions & 23 deletions ArduCopter/switches.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,13 @@

//Documentation of Aux Switch Flags:
struct {
uint8_t CH6_flag : 2; // 0, 1 // ch6 aux switch : 0 is low or false, 1 is center or true, 2 is high
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This change looks unrelated?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@peterbarker, I had to do that actually or the read_3pos_switch wouldn't accept the .CH6_flag as an argument.

Txs for reviewing!

uint8_t CH7_flag : 2; // 2, 3 // ch7 aux switch : 0 is low or false, 1 is center or true, 2 is high
uint8_t CH8_flag : 2; // 4, 5 // ch8 aux switch : 0 is low or false, 1 is center or true, 2 is high
uint8_t CH9_flag : 2; // 6, 7 // ch9 aux switch : 0 is low or false, 1 is center or true, 2 is high
uint8_t CH10_flag : 2; // 8, 9 // ch10 aux switch : 0 is low or false, 1 is center or true, 2 is high
uint8_t CH11_flag : 2; // 10,11 // ch11 aux switch : 0 is low or false, 1 is center or true, 2 is high
uint8_t CH12_flag : 2; // 12,13 // ch12 aux switch : 0 is low or false, 1 is center or true, 2 is high
uint8_t CH6_flag; // ch6 aux switch : 0 is low or false, 1 is center or true, 2 is high
uint8_t CH7_flag; // ch7 aux switch : 0 is low or false, 1 is center or true, 2 is high
uint8_t CH8_flag; // ch8 aux switch : 0 is low or false, 1 is center or true, 2 is high
uint8_t CH9_flag; // ch9 aux switch : 0 is low or false, 1 is center or true, 2 is high
uint8_t CH10_flag; // ch10 aux switch : 0 is low or false, 1 is center or true, 2 is high
uint8_t CH11_flag; // ch11 aux switch : 0 is low or false, 1 is center or true, 2 is high
uint8_t CH12_flag; // ch12 aux switch : 0 is low or false, 1 is center or true, 2 is high
} aux_con;

void Copter::read_control_switch()
Expand All @@ -25,6 +25,14 @@ void Copter::read_control_switch()
// calculate position of flight mode switch
int8_t switch_position;
uint16_t mode_in = RC_Channels::rc_channel(g.flight_mode_chan-1)->get_radio_in();

// protect against out-of-range mode channel inputs
if ((mode_in <= 900) || (mode_in >= 2200)) {
// reset switch edge time so any debounce is not fooled
control_switch_state.last_edge_time_ms = tnow_ms;
return;
}

if (mode_in < 1231) switch_position = 0;
else if (mode_in < 1361) switch_position = 1;
else if (mode_in < 1491) switch_position = 2;
Expand Down Expand Up @@ -113,21 +121,33 @@ void Copter::reset_control_switch()
}

// read_3pos_switch
uint8_t Copter::read_3pos_switch(uint8_t chan)
bool Copter::read_3pos_switch(uint8_t chan, uint8_t &ret) const
{
uint16_t radio_in = RC_Channels::rc_channel(chan)->get_radio_in();
if (radio_in < AUX_SWITCH_PWM_TRIGGER_LOW) return AUX_SWITCH_LOW; // switch is in low position
if (radio_in > AUX_SWITCH_PWM_TRIGGER_HIGH) return AUX_SWITCH_HIGH; // switch is in high position
return AUX_SWITCH_MIDDLE; // switch is in middle position
const uint16_t radio_in = RC_Channels::rc_channel(chan)->get_radio_in();
if ((radio_in <= 900) || (radio_in >= 2200)) {
return false;
}
if (radio_in < AUX_SWITCH_PWM_TRIGGER_LOW) {
// switch is in low position
ret = AUX_SWITCH_LOW;
} else if (radio_in > AUX_SWITCH_PWM_TRIGGER_HIGH) {
// switch is in high position
ret = AUX_SWITCH_HIGH;
} else {
// switch is in middle position
ret = AUX_SWITCH_MIDDLE;
}
return true;
}

// can't take reference to a bitfield member, thus a #define:
#define read_aux_switch(chan, flag, option) \
#define read_aux_switch(chan, flag, option) \
do { \
switch_position = read_3pos_switch(chan); \
if (debounce_aux_switch(chan, flag) && flag != switch_position) { \
flag = switch_position; \
do_aux_switch_function(option, flag); \
if (read_3pos_switch(chan, switch_position)) { \
if (debounce_aux_switch(chan, flag) && flag != switch_position) { \
flag = switch_position; \
do_aux_switch_function(option, flag); \
} \
} \
} while (false)

Expand Down Expand Up @@ -155,14 +175,26 @@ void Copter::read_aux_switches()
void Copter::init_aux_switches()
{
// set the CH7 ~ CH12 flags
aux_con.CH7_flag = read_3pos_switch(CH_7);
aux_con.CH8_flag = read_3pos_switch(CH_8);
aux_con.CH10_flag = read_3pos_switch(CH_10);
aux_con.CH11_flag = read_3pos_switch(CH_11);
if (!read_3pos_switch(CH_7, aux_con.CH7_flag)) {
aux_con.CH7_flag = AUX_SWITCH_LOW;
}
if (!read_3pos_switch(CH_8, aux_con.CH8_flag)) {
aux_con.CH8_flag = AUX_SWITCH_LOW;
}
if (!read_3pos_switch(CH_10, aux_con.CH10_flag)) {
aux_con.CH10_flag = AUX_SWITCH_LOW;
}
if (!read_3pos_switch(CH_11, aux_con.CH11_flag)) {
aux_con.CH11_flag = AUX_SWITCH_LOW;
}

// ch9, ch12 only supported on some boards
aux_con.CH9_flag = read_3pos_switch(CH_9);
aux_con.CH12_flag = read_3pos_switch(CH_12);
if (!read_3pos_switch(CH_9, aux_con.CH9_flag)) {
aux_con.CH9_flag = AUX_SWITCH_LOW;
}
if (!read_3pos_switch(CH_12, aux_con.CH12_flag)) {
aux_con.CH12_flag = AUX_SWITCH_LOW;
}

// initialise functions assigned to switches
init_aux_switch_function(g.ch7_option, aux_con.CH7_flag);
Expand Down