update firmware.bin
[clinton/Smoothieware.git] / src / modules / utils / pausebutton / PauseButton.cpp
1 #include "libs/Kernel.h"
2 #include "PauseButton.h"
3 #include "libs/nuts_bolts.h"
4 #include "libs/utils.h"
5 #include "Config.h"
6 #include "SlowTicker.h"
7 #include "libs/SerialMessage.h"
8 #include "libs/StreamOutput.h"
9 #include "Pauser.h"
10 #include "checksumm.h"
11 #include "ConfigValue.h"
12 #include "StreamOutputPool.h"
13
14 using namespace std;
15
16 #define pause_button_enable_checksum CHECKSUM("pause_button_enable")
17 #define kill_button_enable_checksum CHECKSUM("kill_button_enable")
18 #define pause_button_pin_checksum CHECKSUM("pause_button_pin")
19 #define kill_button_pin_checksum CHECKSUM("kill_button_pin")
20
21 PauseButton::PauseButton()
22 {
23 this->button_state = true;
24 this->killed = false;
25 this->do_kill= false;
26 }
27
28 void PauseButton::on_module_loaded()
29 {
30 this->pause_enable = THEKERNEL->config->value( pause_button_enable_checksum )->by_default(false)->as_bool();
31 this->kill_enable = THEKERNEL->config->value( kill_button_enable_checksum )->by_default(false)->as_bool();
32 this->pause_button.from_string( THEKERNEL->config->value( pause_button_pin_checksum )->by_default("2.12")->as_string())->as_input();
33 this->kill_button.from_string( THEKERNEL->config->value( kill_button_pin_checksum )->by_default("nc")->as_string())->as_input();
34
35 if(this->kill_enable && this->kill_button.connected() && pause_button.equals(kill_button)) {
36 // kill button takes priority
37 this->pause_enable = false;
38
39 } else if(this->kill_enable && !this->kill_button.connected() && !this->pause_enable && pause_button.connected()) {
40 // use pause button for kill button if kill buttin not specifically defined
41 this->kill_button = this->pause_button;
42 }
43
44 this->register_for_event(ON_CONSOLE_LINE_RECEIVED);
45
46 if( (this->pause_enable && this->pause_button.connected()) || (this->kill_enable && this->kill_button.connected()) ) {
47 THEKERNEL->slow_ticker->attach( 10, this, &PauseButton::button_tick );
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;
56 THEKERNEL->call_event(ON_HALT, nullptr);
57 THEKERNEL->streams->printf("Kill button pressed - reset or M999 to continue\r\n");
58 }
59 }
60
61 //TODO: Make this use InterruptIn
62 //Check the state of the button and act accordingly based on current pause state
63 // Note this is ISR so don't do anything nasty in here
64 uint32_t PauseButton::button_tick(uint32_t dummy)
65 {
66 // If pause button changed
67 if(this->pause_enable && this->pause_button.connected()) {
68 bool newstate = this->pause_button.get();
69 if(this->button_state != newstate) {
70 this->button_state = newstate;
71 // If button pressed
72 if( this->button_state ) {
73 if( THEKERNEL->pauser->paused() ) {
74 THEKERNEL->pauser->release();
75 } else {
76 THEKERNEL->pauser->take();
77 }
78 }
79 }
80 }
81
82 if(!this->killed && this->kill_enable && this->kill_button.connected() && !this->kill_button.get()) {
83 this->killed = true;
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;
87 }
88
89 return 0;
90 }
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
97 if(this->killed && new_message.message == "M999") {
98 this->killed= false;
99 return;
100 }
101
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
106 string cmd = shift_parameter(new_message.message);
107
108 if (cmd == "freeze") {
109 if( !THEKERNEL->pauser->paused() ) {
110 THEKERNEL->pauser->take();
111 }
112
113 } else if (cmd == "unfreeze") {
114 if( THEKERNEL->pauser->paused() ) {
115 THEKERNEL->pauser->release();
116 }
117 }
118 }
119