Commit | Line | Data |
---|---|---|
81b547a1 AW |
1 | #include "libs/Kernel.h" |
2 | #include "PauseButton.h" | |
3 | #include "libs/nuts_bolts.h" | |
4 | #include "libs/utils.h" | |
61134a65 JM |
5 | #include "Config.h" |
6 | #include "SlowTicker.h" | |
9bce85f9 L |
7 | #include "libs/SerialMessage.h" |
8 | #include "libs/StreamOutput.h" | |
61134a65 | 9 | #include "Pauser.h" |
7af0714f | 10 | #include "checksumm.h" |
8d54c34c | 11 | #include "ConfigValue.h" |
e558f082 | 12 | #include "StreamOutputPool.h" |
61134a65 | 13 | |
81b547a1 AW |
14 | using namespace std; |
15 | ||
4e722c00 | 16 | #define pause_button_enable_checksum CHECKSUM("pause_button_enable") |
e558f082 | 17 | #define kill_button_enable_checksum CHECKSUM("kill_button_enable") |
4e722c00 | 18 | #define pause_button_pin_checksum CHECKSUM("pause_button_pin") |
e558f082 | 19 | #define kill_button_pin_checksum CHECKSUM("kill_button_pin") |
4e722c00 | 20 | |
76217df5 JM |
21 | PauseButton::PauseButton() |
22 | { | |
e558f082 | 23 | this->button_state = true; |
76217df5 | 24 | this->killed = false; |
85bb9a93 | 25 | this->do_kill= false; |
e558f082 | 26 | } |
81b547a1 | 27 | |
76217df5 JM |
28 | void PauseButton::on_module_loaded() |
29 | { | |
e558f082 | 30 | this->pause_enable = THEKERNEL->config->value( pause_button_enable_checksum )->by_default(false)->as_bool(); |
5dfe966f | 31 | this->kill_enable = THEKERNEL->config->value( kill_button_enable_checksum )->by_default(false)->as_bool(); |
e558f082 | 32 | this->pause_button.from_string( THEKERNEL->config->value( pause_button_pin_checksum )->by_default("2.12")->as_string())->as_input(); |
5dfe966f | 33 | this->kill_button.from_string( THEKERNEL->config->value( kill_button_pin_checksum )->by_default("nc")->as_string())->as_input(); |
81b547a1 | 34 | |
5dfe966f | 35 | if(this->kill_enable && this->kill_button.connected() && pause_button.equals(kill_button)) { |
e558f082 | 36 | // kill button takes priority |
76217df5 JM |
37 | this->pause_enable = false; |
38 | ||
39 | } else if(this->kill_enable && !this->kill_button.connected() && !this->pause_enable && pause_button.connected()) { | |
85bb9a93 | 40 | // use pause button for kill button if kill buttin not specifically defined |
76217df5 | 41 | this->kill_button = this->pause_button; |
e558f082 | 42 | } |
81b547a1 | 43 | |
9bce85f9 | 44 | this->register_for_event(ON_CONSOLE_LINE_RECEIVED); |
4e722c00 | 45 | |
e558f082 | 46 | if( (this->pause_enable && this->pause_button.connected()) || (this->kill_enable && this->kill_button.connected()) ) { |
373d0bf1 | 47 | THEKERNEL->slow_ticker->attach( 10, this, &PauseButton::button_tick ); |
85bb9a93 JM |
48 | this->register_for_event(ON_IDLE); |
49 | } | |
50 | } | |
51 | ||
52 | void PauseButton::on_idle(void *argument) | |
53 | { | |
54 | if(do_kill) { | |
55 | do_kill= false; | |
728477c4 | 56 | THEKERNEL->call_event(ON_HALT, nullptr); |
85bb9a93 | 57 | THEKERNEL->streams->printf("Kill button pressed - reset or M999 to continue\r\n"); |
e558f082 | 58 | } |
81b547a1 AW |
59 | } |
60 | ||
7b49793d | 61 | //TODO: Make this use InterruptIn |
7dc903db | 62 | //Check the state of the button and act accordingly based on current pause state |
728477c4 | 63 | // Note this is ISR so don't do anything nasty in here |
76217df5 JM |
64 | uint32_t PauseButton::button_tick(uint32_t dummy) |
65 | { | |
e558f082 JM |
66 | // If pause button changed |
67 | if(this->pause_enable && this->pause_button.connected()) { | |
68 | bool newstate = this->pause_button.get(); | |
76217df5 | 69 | if(this->button_state != newstate) { |
e558f082 JM |
70 | this->button_state = newstate; |
71 | // If button pressed | |
76217df5 JM |
72 | if( this->button_state ) { |
73 | if( THEKERNEL->pauser->paused() ) { | |
e558f082 | 74 | THEKERNEL->pauser->release(); |
76217df5 | 75 | } else { |
e558f082 JM |
76 | THEKERNEL->pauser->take(); |
77 | } | |
df27a6a3 MM |
78 | } |
79 | } | |
81b547a1 | 80 | } |
e558f082 | 81 | |
76217df5 JM |
82 | if(!this->killed && this->kill_enable && this->kill_button.connected() && !this->kill_button.get()) { |
83 | this->killed = true; | |
85bb9a93 JM |
84 | // we can't call this in ISR, and we need to block on_main_loop so do it in on_idle |
85 | // THEKERNEL->call_event(ON_HALT); | |
86 | this->do_kill= true; | |
e558f082 JM |
87 | } |
88 | ||
f03d3c1c | 89 | return 0; |
81b547a1 | 90 | } |
9bce85f9 L |
91 | |
92 | // When a new line is received, check if it is a command, and if it is, act upon it | |
93 | void PauseButton::on_console_line_received( void *argument ) | |
94 | { | |
95 | SerialMessage new_message = *static_cast<SerialMessage *>(argument); | |
96 | ||
891910b6 JM |
97 | if(this->killed && new_message.message == "M999") { |
98 | this->killed= false; | |
99 | return; | |
100 | } | |
101 | ||
9bce85f9 L |
102 | // ignore comments and blank lines and if this is a G code then also ignore it |
103 | char first_char = new_message.message[0]; | |
104 | if(strchr(";( \n\rGMTN", first_char) != NULL) return; | |
105 | ||
76217df5 | 106 | string cmd = shift_parameter(new_message.message); |
9bce85f9 | 107 | |
e558f082 | 108 | if (cmd == "freeze") { |
76217df5 | 109 | if( !THEKERNEL->pauser->paused() ) { |
9bce85f9 L |
110 | THEKERNEL->pauser->take(); |
111 | } | |
7dc903db | 112 | |
76217df5 JM |
113 | } else if (cmd == "unfreeze") { |
114 | if( THEKERNEL->pauser->paused() ) { | |
9bce85f9 L |
115 | THEKERNEL->pauser->release(); |
116 | } | |
117 | } | |
118 | } | |
119 |