X-Git-Url: http://git.hcoop.net/clinton/Smoothieware.git/blobdiff_plain/8b295726d4614ff967ab9c6ad209e088334265a5..8b260c2c2f391324244eba299ef92e4186813a7b:/src/libs/Kernel.cpp diff --git a/src/libs/Kernel.cpp b/src/libs/Kernel.cpp index 6ad5b2d4..6dcffae5 100644 --- a/src/libs/Kernel.cpp +++ b/src/libs/Kernel.cpp @@ -24,10 +24,17 @@ #include "modules/robot/Robot.h" #include "modules/robot/Stepper.h" #include "modules/robot/Conveyor.h" -#include "modules/robot/Pauser.h" +#include "StepperMotor.h" +#include "BaseSolution.h" +#include "EndstopsPublicAccess.h" +#include "Configurator.h" +#include "SimpleShell.h" + +#include "platform_memory.h" #include #include +#include #define baud_rate_setting_checksum CHECKSUM("baud_rate") #define uart0_checksum CHECKSUM("uart0") @@ -35,11 +42,17 @@ #define base_stepping_frequency_checksum CHECKSUM("base_stepping_frequency") #define microseconds_per_step_pulse_checksum CHECKSUM("microseconds_per_step_pulse") #define acceleration_ticks_per_second_checksum CHECKSUM("acceleration_ticks_per_second") +#define disable_leds_checksum CHECKSUM("leds_disable") +#define grbl_mode_checksum CHECKSUM("grbl_mode") +#define ok_per_line_checksum CHECKSUM("ok_per_line") Kernel* Kernel::instance; // The kernel is the central point in Smoothie : it stores modules, and handles event calls Kernel::Kernel(){ + halted= false; + feed_hold= false; + instance= this; // setup the Singleton instance of the kernel // serial first at fixed baud rate (DEFAULT_SERIAL_BAUD_RATE) so config can report errors to serial @@ -67,32 +80,36 @@ Kernel::Kernel(){ #if MRI_ENABLE != 0 switch( __mriPlatform_CommUartIndex() ) { case 0: - this->serial = new SerialConsole(USBTX, USBRX, this->config->value(uart0_checksum,baud_rate_setting_checksum)->by_default(DEFAULT_SERIAL_BAUD_RATE)->as_number()); + this->serial = new(AHB0) SerialConsole(USBTX, USBRX, this->config->value(uart0_checksum,baud_rate_setting_checksum)->by_default(DEFAULT_SERIAL_BAUD_RATE)->as_number()); break; case 1: - this->serial = new SerialConsole( p13, p14, this->config->value(uart0_checksum,baud_rate_setting_checksum)->by_default(DEFAULT_SERIAL_BAUD_RATE)->as_number()); + this->serial = new(AHB0) SerialConsole( p13, p14, this->config->value(uart0_checksum,baud_rate_setting_checksum)->by_default(DEFAULT_SERIAL_BAUD_RATE)->as_number()); break; case 2: - this->serial = new SerialConsole( p28, p27, this->config->value(uart0_checksum,baud_rate_setting_checksum)->by_default(DEFAULT_SERIAL_BAUD_RATE)->as_number()); + this->serial = new(AHB0) SerialConsole( p28, p27, this->config->value(uart0_checksum,baud_rate_setting_checksum)->by_default(DEFAULT_SERIAL_BAUD_RATE)->as_number()); break; case 3: - this->serial = new SerialConsole( p9, p10, this->config->value(uart0_checksum,baud_rate_setting_checksum)->by_default(DEFAULT_SERIAL_BAUD_RATE)->as_number()); + this->serial = new(AHB0) SerialConsole( p9, p10, this->config->value(uart0_checksum,baud_rate_setting_checksum)->by_default(DEFAULT_SERIAL_BAUD_RATE)->as_number()); break; } #endif // default if(this->serial == NULL) { - this->serial = new SerialConsole(USBTX, USBRX, this->config->value(uart0_checksum,baud_rate_setting_checksum)->by_default(DEFAULT_SERIAL_BAUD_RATE)->as_number()); + this->serial = new(AHB0) SerialConsole(USBTX, USBRX, this->config->value(uart0_checksum,baud_rate_setting_checksum)->by_default(DEFAULT_SERIAL_BAUD_RATE)->as_number()); } - this->add_module( this->config ); + //some boards don't have leds.. TOO BAD! + this->use_leds= !this->config->value( disable_leds_checksum )->by_default(false)->as_bool(); + this->grbl_mode= this->config->value( grbl_mode_checksum )->by_default(false)->as_bool(); + this->ok_per_line= this->config->value( ok_per_line_checksum )->by_default(true)->as_bool(); + this->add_module( this->serial ); // HAL stuff add_module( this->slow_ticker = new SlowTicker()); this->step_ticker = new StepTicker(); - this->adc = new Adc(); + this->adc = new(AHB0) Adc(); // TODO : These should go into platform-specific files // LPC17xx-specific @@ -100,7 +117,6 @@ Kernel::Kernel(){ NVIC_SetPriority(TIMER0_IRQn, 2); NVIC_SetPriority(TIMER1_IRQn, 1); NVIC_SetPriority(TIMER2_IRQn, 4); - NVIC_SetPriority(RIT_IRQn, 4); NVIC_SetPriority(PendSV_IRQn, 3); // Set other priorities lower than the timers @@ -126,19 +142,82 @@ Kernel::Kernel(){ this->acceleration_ticks_per_second = THEKERNEL->config->value(acceleration_ticks_per_second_checksum)->by_default(1000)->as_number(); // Configure the step ticker ( TODO : shouldnt this go into stepticker's code ? ) - this->step_ticker->set_reset_delay( microseconds_per_step_pulse / 1000000.0F ); + this->step_ticker->set_unstep_time( microseconds_per_step_pulse ); this->step_ticker->set_frequency( this->base_stepping_frequency ); - this->step_ticker->set_acceleration_ticks_per_second(acceleration_ticks_per_second); // must be set after set_frequency // Core modules - this->add_module( new GcodeDispatch() ); + this->add_module( this->gcode_dispatch = new GcodeDispatch() ); this->add_module( this->robot = new Robot() ); this->add_module( this->stepper = new Stepper() ); this->add_module( this->conveyor = new Conveyor() ); - this->add_module( this->pauser = new Pauser() ); + this->add_module( this->simpleshell = new SimpleShell() ); + + this->planner = new(AHB0) Planner(); + this->configurator = new Configurator(); +} + +// return a GRBL-like query string for serial ? +std::string Kernel::get_query_string() +{ + std::string str; + bool homing; + bool ok = PublicData::get_value(endstops_checksum, get_homing_status_checksum, 0, &homing); + if(!ok) homing= false; + bool running= false; + + str.append("<"); + if(halted) { + str.append("Alarm,"); + }else if(homing) { + str.append("Home,"); + }else if(feed_hold) { + str.append("Hold,"); + }else if(this->conveyor->is_queue_empty()) { + str.append("Idle,"); + }else{ + running= true; + str.append("Run,"); + } + + if(running) { + // get real time current actuator position in mm + ActuatorCoordinates current_position{ + robot->actuators[X_AXIS]->get_current_position(), + robot->actuators[Y_AXIS]->get_current_position(), + robot->actuators[Z_AXIS]->get_current_position() + }; + + // get machine position from the actuator position using FK + float mpos[3]; + robot->arm_solution->actuator_to_cartesian(current_position, mpos); - this->planner = new Planner(); + char buf[128]; + // machine position + size_t n= snprintf(buf, sizeof(buf), "%1.4f,%1.4f,%1.4f,", robot->from_millimeters(mpos[0]), robot->from_millimeters(mpos[1]), robot->from_millimeters(mpos[2])); + str.append("MPos:").append(buf, n); + + // work space position + Robot::wcs_t pos= robot->mcs2wcs(mpos); + n= snprintf(buf, sizeof(buf), "%1.4f,%1.4f,%1.4f", robot->from_millimeters(std::get(pos)), robot->from_millimeters(std::get(pos)), robot->from_millimeters(std::get(pos))); + str.append("WPos:").append(buf, n); + str.append(">\r\n"); + + }else{ + // return the last milestone if idle + char buf[128]; + // machine position + Robot::wcs_t mpos= robot->get_axis_position(); + size_t n= snprintf(buf, sizeof(buf), "%1.4f,%1.4f,%1.4f,", robot->from_millimeters(std::get(mpos)), robot->from_millimeters(std::get(mpos)), robot->from_millimeters(std::get(mpos))); + str.append("MPos:").append(buf, n); + // work space position + Robot::wcs_t pos= robot->mcs2wcs(mpos); + n= snprintf(buf, sizeof(buf), "%1.4f,%1.4f,%1.4f", robot->from_millimeters(std::get(pos)), robot->from_millimeters(std::get(pos)), robot->from_millimeters(std::get(pos))); + str.append("WPos:").append(buf, n); + str.append(">\r\n"); + + } + return str; } // Add a module to Kernel. We don't actually hold a list of modules we just call its on_module_loaded @@ -151,16 +230,32 @@ void Kernel::register_for_event(_EVENT_ENUM id_event, Module *mod){ this->hooks[id_event].push_back(mod); } -// Call a specific event without arguments -void Kernel::call_event(_EVENT_ENUM id_event){ +// Call a specific event with an argument +void Kernel::call_event(_EVENT_ENUM id_event, void * argument){ + if(id_event == ON_HALT) { + this->halted= (argument == nullptr); + } for (auto m : hooks[id_event]) { - (m->*kernel_callback_functions[id_event])(this); + (m->*kernel_callback_functions[id_event])(argument); } } -// Call a specific event with an argument -void Kernel::call_event(_EVENT_ENUM id_event, void * argument){ +// These are used by tests to test for various things. basically mocks +bool Kernel::kernel_has_event(_EVENT_ENUM id_event, Module *mod) +{ for (auto m : hooks[id_event]) { - (m->*kernel_callback_functions[id_event])(argument); + if(m == mod) return true; + } + return false; +} + +void Kernel::unregister_for_event(_EVENT_ENUM id_event, Module *mod) +{ + for (auto i = hooks[id_event].begin(); i != hooks[id_event].end(); ++i) { + if(*i == mod) { + hooks[id_event].erase(i); + return; + } } } +