You should have received a copy of the GNU General Public License along with Smoothie. If not, see <http://www.gnu.org/licenses/>.
*/
-using namespace std;
-#include <vector>
#include "libs/Kernel.h"
#include "libs/Module.h"
#include "libs/Config.h"
// The kernel is the central point in Smoothie : it stores modules, and handles event calls
Kernel::Kernel(){
+ // Value init for the arrays
+ for( uint8_t i = 0; i < NUMBER_OF_DEFINED_EVENTS; i++ ){ this->hooks[i][0] = NULL; }
+
// Config first, because we need the baud_rate setting before we start serial
this->config = new Config();
}
void Kernel::register_for_event(unsigned int id_event, Module* module){
- this->hooks[id_event].push_back(module);
+ uint8_t current_id = 0;
+ Module* current = this->hooks[id_event][0];
+ while(current != NULL ){
+ if( current == module ){ return; }
+ current_id++;
+ current = this->hooks[id_event][current_id];
+ }
+ this->hooks[id_event][current_id] = module;
+ this->hooks[id_event][current_id+1] = NULL;
}
void Kernel::call_event(unsigned int id_event){
- for(unsigned int i=0; i < this->hooks[id_event].size(); i++){
- (this->hooks[id_event][i]->*kernel_callback_functions[id_event])(this);
+ uint8_t current_id = 0; Module* current = this->hooks[id_event][0];
+ while(current != NULL ){ // For each active stepper
+ (current->*kernel_callback_functions[id_event])(this);
+ current_id++;
+ current = this->hooks[id_event][current_id];
}
}
void Kernel::call_event(unsigned int id_event, void * argument){
- for(unsigned int i=0; i < this->hooks[id_event].size(); i++){
- (this->hooks[id_event][i]->*kernel_callback_functions[id_event])(argument);
+ uint8_t current_id = 0; Module* current = this->hooks[id_event][0];
+ while(current != NULL ){ // For each active stepper
+ (current->*kernel_callback_functions[id_event])(argument);
+ current_id++;
+ current = this->hooks[id_event][current_id];
}
}
#define ON_IDLE 11
-using namespace std;
-#include <vector>
-
typedef void (Module::*ModuleCallback)(void * argument);
//Module manager
Digipot* digipot;
private:
- vector<Module*> hooks[NUMBER_OF_DEFINED_EVENTS]; // When a module asks to be called for a specific event ( a hook ), this is where that request is remembered
+ Module* hooks[NUMBER_OF_DEFINED_EVENTS][16]; // When a module asks to be called for a specific event ( a hook ), this is where that request is remembered
};
Gcode gcode = Gcode();
gcode.command = single_command;
gcode.stream = new_message.stream;
+ gcode.prepare_cached_values();
//Dispatch message!
this->kernel->call_event(ON_GCODE_RECEIVED, &gcode );
//__enable_irq();
return 0;
}
+
+void Gcode::prepare_cached_values(){
+ if( this->has_letter('G') ){
+ this->has_g = true;
+ this->g = this->get_value('G');
+ }else{
+ this->has_g = false;
+ }
+ if( this->has_letter('M') ){
+ this->has_m = true;
+ this->m = this->get_value('m');
+ }else{
+ this->has_m = false;
+ }
+}
#include <string>
using std::string;
#include "libs/StreamOutput.h"
-// Object to represent a Gcode comman
+// Object to represent a Gcode command
#include <stdlib.h>
class Gcode {
Gcode();
bool has_letter( char letter );
double get_value ( char letter );
+ void prepare_cached_values();
string command;
double millimeters_of_travel;
bool call_on_gcode_execute_event_immediatly;
bool on_gcode_execute_event_called;
+ bool has_m;
+ bool has_g;
+ unsigned int m;
+ unsigned int g;
+
StreamOutput* stream;
};
#endif
void Stepper::on_gcode_execute(void* argument){
Gcode* gcode = static_cast<Gcode*>(argument);
- if( gcode->has_letter('M')){
- int code = (int) gcode->get_value('M');
- if( code == 17 ){
+ if( gcode->has_m){
+ if( gcode->m == 17 ){
this->turn_enable_pins_on();
}
- if( code == 84 || code == 18 ){
+ if( gcode->m == 84 || gcode->m == 18 ){
this->turn_enable_pins_off();
}
}
Gcode* gcode = static_cast<Gcode*>(argument);
// Absolute/relative mode
- if( gcode->has_letter('M')){
- int code = (int) gcode->get_value('M');
- if( code == 82 ){ this->absolute_mode = true; }
- if( code == 83 ){ this->absolute_mode = false; }
- if( code == 84 ){ this->en_pin->set(1); }
+ if( gcode->has_m ){
+ if( gcode->m == 82 ){ this->absolute_mode = true; }
+ if( gcode->m == 83 ){ this->absolute_mode = false; }
+ if( gcode->m == 84 ){ this->en_pin->set(1); }
}
// The mode is OFF by default, and SOLO or FOLLOW only if we need to extrude
this->mode = OFF;
- if( gcode->has_letter('G') ){
+ if( gcode->has_g ){
// G92: Reset extruder position
- if( gcode->get_value('G') == 92 ){
+ if( gcode->g == 92 ){
if( gcode->has_letter('E') ){
this->current_position = gcode->get_value('E');
this->target_position = this->current_position;
}
}
}
-
}
// When a new block begins, either follow the robot, or step by ourselves ( or stay back and do nothing )
void TemperatureControl::on_gcode_execute(void* argument){
Gcode* gcode = static_cast<Gcode*>(argument);
-
-
- //gcode->stream->printf("%u %u %u \r\n",gcode->has_letter('M'), (gcode->get_value('M') == 104), gcode->has_letter('S') );
-
- // Set temperature without waiting
- if( gcode->has_letter('M') && gcode->get_value('M') == this->set_m_code && gcode->has_letter('S') ){
- //gcode->stream->printf("setting to %f meaning %u \r\n", gcode->get_value('S'), this->temperature_to_adc_value( gcode->get_value('S') ) );
- this->set_desired_temperature(gcode->get_value('S'));
- }
-
- // Set temperature and wait
- if( gcode->has_letter('M') && gcode->get_value('M') == this->set_and_wait_m_code && gcode->has_letter('S') ){
- this->set_desired_temperature(gcode->get_value('S'));
-
- // Pause
- this->kernel->pauser->take();
- this->waiting = true;
-
- }
-
- // Get temperature
- if( gcode->has_letter('M') && gcode->get_value('M') == this->get_m_code ){
- gcode->stream->printf("get temperature: %f current:%f target:%f bare_value:%u \r\n", this->get_temperature(), this->new_thermistor_reading(), this->desired_adc_value, this->kernel->adc->read(this->thermistor_pin) );
+ if( gcode->has_m){
+ // Set temperature without waiting
+ if( gcode->m == this->set_m_code && gcode->has_letter('S') ){
+ //gcode->stream->printf("setting to %f meaning %u \r\n", gcode->get_value('S'), this->temperature_to_adc_value( gcode->get_value('S') ) );
+ this->set_desired_temperature(gcode->get_value('S'));
+ }
+ // Set temperature and wait
+ if( gcode->m == this->set_and_wait_m_code && gcode->has_letter('S') ){
+ this->set_desired_temperature(gcode->get_value('S'));
+ // Pause
+ this->kernel->pauser->take();
+ this->waiting = true;
+ }
+ // Get temperature
+ if( gcode->m == this->get_m_code ){
+ gcode->stream->printf("get temperature: %f current:%f target:%f bare_value:%u \r\n", this->get_temperature(), this->new_thermistor_reading(), this->desired_adc_value, this->kernel->adc->read(this->thermistor_pin) );
+ }
}
}
void Configurator::on_module_loaded(){
this->register_for_event(ON_CONSOLE_LINE_RECEIVED);
-// this->register_for_event(ON_GCODE_EXECUTE);
+// this->register_for_event(ON_GCODE_RECEIVED);
// this->register_for_event(ON_MAIN_LOOP);
}
}
// Process and respond to eeprom gcodes (M50x)
-void Configurator::on_gcode_execute(void* argument){
+void Configurator::on_gcode_received(void* argument){
Gcode* gcode = static_cast<Gcode*>(argument);
if( gcode->has_letter('G') ){
int code = gcode->get_value('G');
void on_module_loaded();
void on_console_line_received( void* argument );
- void on_gcode_execute( void* argument );
+ void on_gcode_received( void* argument );
void on_main_loop( void* argument );
void config_get_command( string parameters, StreamOutput* stream );