started hacking on the new conveyor model
authorJim Morris <morris@wolfman.com>
Tue, 17 May 2016 08:01:20 +0000 (01:01 -0700)
committerJim Morris <morris@wolfman.com>
Tue, 17 May 2016 08:01:20 +0000 (01:01 -0700)
removed stepper as it doesn nothing now
removed the events on_block_begin, on_block_end, on_gcode_execute

16 files changed:
src/libs/Kernel.cpp
src/libs/Kernel.h
src/libs/Module.cpp
src/libs/Module.h
src/libs/Pin.h
src/libs/StepTicker.h
src/libs/StepperMotor.cpp
src/libs/StepperMotor.h
src/modules/robot/Block.cpp
src/modules/robot/Block.h
src/modules/robot/Conveyor.cpp
src/modules/robot/Conveyor.h
src/modules/robot/Planner.cpp
src/modules/robot/Robot.cpp
src/modules/robot/Stepper.cpp [deleted file]
src/modules/robot/Stepper.h [deleted file]

index 6dcffae..d19b161 100644 (file)
@@ -22,7 +22,6 @@
 #include "modules/communication/GcodeDispatch.h"
 #include "modules/robot/Planner.h"
 #include "modules/robot/Robot.h"
-#include "modules/robot/Stepper.h"
 #include "modules/robot/Conveyor.h"
 #include "StepperMotor.h"
 #include "BaseSolution.h"
@@ -148,7 +147,6 @@ Kernel::Kernel(){
     // Core modules
     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->simpleshell    = new SimpleShell()   );
 
index 77398fc..6434b7a 100644 (file)
@@ -24,7 +24,6 @@ class SerialConsole;
 class StreamOutputPool;
 class GcodeDispatch;
 class Robot;
-class Stepper;
 class Planner;
 class StepTicker;
 class Adc;
@@ -60,7 +59,6 @@ class Kernel {
         StreamOutputPool* streams;
         GcodeDispatch*    gcode_dispatch;
         Robot*            robot;
-        Stepper*          stepper;
         Planner*          planner;
         Config*           config;
         Conveyor*         conveyor;
index 1ab5212..b941563 100644 (file)
@@ -17,10 +17,6 @@ const ModuleCallback kernel_callback_functions[NUMBER_OF_DEFINED_EVENTS] = {
     &Module::on_main_loop,
     &Module::on_console_line_received,
     &Module::on_gcode_received,
-    &Module::on_gcode_execute,
-    &Module::on_speed_change,
-    &Module::on_block_begin,
-    &Module::on_block_end,
     &Module::on_idle,
     &Module::on_second_tick,
     &Module::on_get_public_data,
index 1c38a5e..8a9134b 100644 (file)
@@ -15,10 +15,6 @@ enum _EVENT_ENUM {
     ON_MAIN_LOOP,
     ON_CONSOLE_LINE_RECEIVED,
     ON_GCODE_RECEIVED,
-    ON_GCODE_EXECUTE,
-    ON_SPEED_CHANGE,
-    ON_BLOCK_BEGIN,
-    ON_BLOCK_END,
     ON_IDLE,
     ON_SECOND_TICK,
     ON_GET_PUBLIC_DATA,
@@ -48,10 +44,6 @@ public:
     virtual void on_main_loop(void *) {};
     virtual void on_console_line_received(void *) {};
     virtual void on_gcode_received(void *) {};
-    virtual void on_gcode_execute(void *) {};
-    virtual void on_speed_change(void *) {};
-    virtual void on_block_begin(void *) {};
-    virtual void on_block_end(void *) {};
     virtual void on_idle(void *) {};
     virtual void on_second_tick(void *) {};
     virtual void on_get_public_data(void *) {};
index 0f87952..c3e781f 100644 (file)
@@ -49,7 +49,7 @@ class Pin {
 
         Pin* pull_none(void);
 
-        inline bool get(){
+        inline bool get() const{
             if (!this->valid) return false;
             return this->inverting ^ (( this->port->FIOPIN >> this->pin ) & 1);
         }
index e26547d..8c08966 100644 (file)
@@ -38,6 +38,7 @@ class StepTicker{
         void start();
         bool add_job(Block *block) { return jobq.put(block); }
         bool is_jobq_full() const { return jobq.full(); }
+        bool is_jobq_empty() const { return jobq.empty(); }
 
         // whatever setup the block should register this to know when it is done
         std::function<void()> finished_fnc{nullptr};
index d3c435c..adac816 100644 (file)
 // in steps/sec the default minimum speed (was 20steps/sec hardcoded)
 float StepperMotor::default_minimum_actuator_rate= 20.0F;
 
-// A StepperMotor represents an actual stepper motor. It is used to generate steps that move the actual motor at a given speed
-
-StepperMotor::StepperMotor()
-{
-    init();
-}
-
 StepperMotor::StepperMotor(Pin &step, Pin &dir, Pin &en) : step_pin(step), dir_pin(dir), en_pin(en)
 {
-    init();
-    enable(false);
     set_high_on_debug(en.port_number, en.pin);
-}
-
-StepperMotor::~StepperMotor()
-{
-}
-
-void StepperMotor::init()
-{
     // register this motor with the step ticker, and get its index in that array and bit position
     this->index= THEKERNEL->step_ticker->register_motor(this);
 
@@ -44,6 +27,28 @@ void StepperMotor::init()
     last_milestone_steps = 0;
     last_milestone_mm    = 0.0F;
     current_position_steps= 0;
+    enable(false);
+
+    this->register_for_event(ON_HALT);
+    this->register_for_event(ON_ENABLE);
+}
+
+StepperMotor::~StepperMotor()
+{
+    THEKERNEL->unregister_for_event(ON_HALT, this);
+    THEKERNEL->unregister_for_event(ON_ENABLE, this);
+}
+
+void StepperMotor::on_halt(void *argument)
+{
+    if(argument == nullptr) {
+        enable(false);
+    }
+}
+
+void StepperMotor::on_enable(void *argument)
+{
+    enable(argument != nullptr);
 }
 
 void StepperMotor::change_steps_per_mm(float new_steps)
index 8a9f8ac..0e1eb6c 100644 (file)
@@ -7,11 +7,11 @@
 
 #pragma once
 
+#include "Module.h"
 #include "Pin.h"
 
-class StepperMotor {
+class StepperMotor  : public Module {
     public:
-        StepperMotor();
         StepperMotor(Pin& step, Pin& dir, Pin& en);
         ~StepperMotor();
 
@@ -20,6 +20,7 @@ class StepperMotor {
         inline void set_direction(bool f) { direction= f; dir_pin.set(f); }
 
         inline void enable(bool state) { en_pin.set(!state); };
+        inline bool is_enabled() const { return !en_pin.get(); };
 
         bool which_direction() const { return direction; }
 
@@ -40,7 +41,8 @@ class StepperMotor {
         friend class Robot;
 
     private:
-        void init();
+        void on_halt(void *argument);
+        void on_enable(void *argument);
 
         int index;
 
index 01acab5..773a09c 100644 (file)
@@ -15,7 +15,6 @@
 #include "Conveyor.h"
 #include "Gcode.h"
 #include "libs/StreamOutputPool.h"
-#include "Stepper.h"
 #include "StepTicker.h"
 
 #include "mri.h"
@@ -40,8 +39,8 @@ void Block::clear()
 {
     //commands.clear();
     //travel_distances.clear();
-    gcodes.clear();
-    std::vector<Gcode>().swap(gcodes); // this resizes the vector releasing its memory
+    //gcodes.clear();
+    //std::vector<Gcode>().swap(gcodes); // this resizes the vector releasing its memory
 
     this->steps.fill(0);
 
@@ -60,7 +59,8 @@ void Block::clear()
     nominal_length_flag = false;
     max_entry_speed     = 0.0F;
     is_ready            = false;
-    times_taken         = 0;
+    is_job              = false;
+
     acceleration_per_tick= 0;
     deceleration_per_tick= 0;
     total_move_ticks= 0;
@@ -68,7 +68,7 @@ void Block::clear()
 
 void Block::debug()
 {
-    THEKERNEL->streams->printf("%p: steps:X%04lu Y%04lu Z%04lu(max:%4lu) nominal:r%6.1f/s%6.1f mm:%9.6f acc:%5lu dec:%5lu rates:%10.4f entry/max: %10.4f/%10.4f taken:%d ready:%d recalc:%d nomlen:%d\r\n",
+    THEKERNEL->streams->printf("%p: steps:X%04lu Y%04lu Z%04lu(max:%4lu) nominal:r%6.1f/s%6.1f mm:%9.6f acc:%5lu dec:%5lu rates:%10.4f entry/max: %10.4f/%10.4f ready:%d is_job:%d recalc:%d nomlen:%d\r\n",
                                this,
                                this->steps[0],
                                this->steps[1],
@@ -82,8 +82,8 @@ void Block::debug()
                                this->initial_rate,
                                this->entry_speed,
                                this->max_entry_speed,
-                               this->times_taken,
                                this->is_ready,
+                               this->is_job,
                                recalculate_flag ? 1 : 0,
                                nominal_length_flag ? 1 : 0
                               );
@@ -102,8 +102,7 @@ void Block::debug()
 void Block::calculate_trapezoid( float entryspeed, float exitspeed )
 {
     // if block is currently executing, don't touch anything!
-    if (times_taken)
-        return;
+    if(is_job) return;
 
     float initial_rate = this->nominal_rate * (entryspeed / this->nominal_speed); // steps/sec
     float final_rate = this->nominal_rate * (exitspeed / this->nominal_speed);
@@ -256,8 +255,9 @@ float Block::max_exit_speed()
 {
     // if block is currently executing, return cached exit speed from calculate_trapezoid
     // this ensures that a block following a currently executing block will have correct entry speed
-    if (times_taken)
-        return exit_speed;
+    // FIXME
+    // if (times_taken)
+    //     return exit_speed;
 
     // if nominal_length_flag is asserted
     // we are guaranteed to reach nominal speed regardless of entry speed
@@ -272,31 +272,28 @@ float Block::max_exit_speed()
 }
 
 // Gcodes are attached to their respective blocks so that on_gcode_execute can be called with it
-void Block::append_gcode(Gcode* gcode)
-{
-    Gcode new_gcode = *gcode;
-    new_gcode.strip_parameters(); // optimization to save memory we strip off the XYZIJK parameters from the saved command
-    gcodes.push_back(new_gcode);
-}
+// void Block::append_gcode(Gcode* gcode)
+// {
+//     Gcode new_gcode = *gcode;
+//     new_gcode.strip_parameters(); // optimization to save memory we strip off the XYZIJK parameters from the saved command
+//     gcodes.push_back(new_gcode);
+// }
 
 void Block::begin()
 {
+    // can no longer be used in planning
     recalculate_flag = false;
+    is_job= true; // mark as being executed or qued for execution
 
+    // TODO probably should remove this
     if (!is_ready)
         __debugbreak();
 
-    times_taken = -1;
-
     // execute all the gcodes related to this block
-    for(unsigned int index = 0; index < gcodes.size(); index++)
-        THEKERNEL->call_event(ON_GCODE_EXECUTE, &(gcodes[index]));
-
+    // for(unsigned int index = 0; index < gcodes.size(); index++)
+    //     THEKERNEL->call_event(ON_GCODE_EXECUTE, &(gcodes[index]));
 
-    THEKERNEL->call_event(ON_BLOCK_BEGIN, this);
-
-    if (times_taken < 0)
-        release();
+    THEKERNEL->conveyor->on_block_begin(this);
 }
 
 // Signal the conveyor that this block is ready to be injected into the system
@@ -305,25 +302,11 @@ void Block::ready()
     this->is_ready = true;
 }
 
-// Mark the block as taken by one more module
-void Block::take()
-{
-    if (times_taken < 0)
-        times_taken = 0;
-    times_taken++;
-}
-
-// Mark the block as no longer taken by one module, go to next block if this frees it
+// Mark the block as finished
 void Block::release()
 {
-    if (--this->times_taken <= 0) {
-        times_taken = 0;
-        if (is_ready) {
-            is_ready = false;
-            THEKERNEL->call_event(ON_BLOCK_END, this);
-
-            // ensure conveyor gets called last
-            THEKERNEL->conveyor->on_block_end(this);
-        }
+    if (is_ready) {
+        is_ready = false;
+        THEKERNEL->conveyor->on_block_end(this);
     }
 }
index 152af04..ca1905b 100644 (file)
@@ -27,9 +27,8 @@ class Block {
 
         void debug();
 
-        void append_gcode(Gcode* gcode);
+       // void append_gcode(Gcode* gcode);
 
-        void take();
         void release();
 
         void ready();
@@ -38,7 +37,7 @@ class Block {
 
         void begin();
 
-        std::vector<Gcode> gcodes;
+        //std::vector<Gcode> gcodes;
 
         std::array<uint32_t, k_max_actuators> steps; // Number of steps for each axis for this block
         uint32_t steps_event_count;  // Steps for the longest axis
@@ -59,13 +58,12 @@ class Block {
 
         float max_entry_speed;
 
-        int16_t times_taken;    // A block can be "taken" by any number of modules, and the next block is not moved to until all the modules have "released" it. This value serves as a tracker.
-
         std::bitset<k_max_actuators> direction_bits;     // Direction for each axis in bit form, relative to the direction port's mask
         struct {
             bool recalculate_flag:1;             // Planner flag to recalculate trapezoids on entry junction
             bool nominal_length_flag:1;          // Planner flag for nominal speed always reached
             bool is_ready:1;
+            bool is_job:1;                       // set when queued to run in the job queue
         };
 };
 
index f8b6873..ac4408b 100644 (file)
@@ -5,8 +5,6 @@
       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/nuts_bolts.h"
 #include "libs/RingBuffer.h"
 #include "../communication/utils/Gcode.h"
@@ -22,6 +20,10 @@ using namespace std;
 #include "Config.h"
 #include "libs/StreamOutputPool.h"
 #include "ConfigValue.h"
+#include "StepTicker.h"
+
+#include <functional>
+#include <vector>
 
 #define planner_queue_size_checksum CHECKSUM("planner_queue_size")
 
@@ -52,38 +54,74 @@ using namespace std;
  * Thus, our two ringbuffers exist sharing the one ring of blocks, and we safely marshall used blocks from ISR context to IDLE context for safe cleanup.
  */
 
-Conveyor::Conveyor(){
+
+/*
+
+A Block is created by the planner in Planner::append_block() and stuck on the
+head of the queue.
+
+The Conveyor is always checking (in on_idle) when blocks on the queue become
+fully planned (ie recalculate flag gets cleared). When this happens a pointer
+to the block is pushed onto the job queue in stepticker, but also left in the
+block queue. If the job queue is full then it will get pushed when the job
+queue has room.
+
+Once the job has finished being executed the block is
+removed from the block queue (at least marked to be removed as explained
+above).
+
+If the block queue has entries that are not yet fully planned, and a certain
+time has elapsed it gives up waiting and forces the tail of the block queue
+onto the job queue, the time needs to be configurable, but it needs to be long
+enough to allow gcodes to be sent from a host, or read from sdcard, so that
+even very short moves will get some planning, otherwise a stream of very short
+moves will be very jerky as they will always decelerate to zero. However the
+delay cannot be so long that there is a noticable lag for jog commands.
+
+TODO an optimization is to remove the block from the block queue and put it
+into the job queue, as this happens in on_idle it should be safe to do without
+the double  pointer stuff. as the job queue has nothing that needs deleting
+this works out.
+
+*/
+
+Conveyor::Conveyor()
+{
     gc_pending = queue.tail_i;
     running = false;
     flush = false;
-    halted= false;
+    halted = false;
 }
 
-void Conveyor::on_module_loaded(){
+void Conveyor::on_module_loaded()
+{
     register_for_event(ON_IDLE);
     register_for_event(ON_MAIN_LOOP);
     register_for_event(ON_HALT);
 
-    on_config_reload(this);
+    // Attach to the end_of_move stepper event
+    THEKERNEL->step_ticker->finished_fnc = std::bind( &Conveyor::all_moves_finished, this);
+    queue.resize(THEKERNEL->config->value(planner_queue_size_checksum)->by_default(32)->as_number());
 }
 
-void Conveyor::on_halt(void* argument){
+void Conveyor::on_halt(void* argument)
+{
     if(argument == nullptr) {
-        halted= true;
+        halted = true;
         flush_queue();
-    }else{
-        halted= false;
+    } else {
+        halted = false;
     }
 }
 
 // Delete blocks here, because they can't be deleted in interrupt context ( see Block.cpp:release )
 // note that blocks get cleaned as they come off the tail, so head ALWAYS points to a cleaned block.
-void Conveyor::on_idle(void* argument){
-    if (queue.tail_i != gc_pending)
-    {
+void Conveyor::on_idle(void* argument)
+{
+    if (queue.tail_i != gc_pending) {
         if (queue.is_empty()) {
             __debugbreak();
-        }else{
+        } else {
             // Cleanly delete block
             Block* block = queue.tail_ref();
 //             block->debug();
@@ -113,34 +151,59 @@ void Conveyor::on_idle(void* argument){
 
 void Conveyor::on_main_loop(void*)
 {
-    if (running)
-        return;
+    if (running) {
+        if(THEKERNEL->step_ticker->is_jobq_full()) return;
 
-    if (queue.is_empty())
-    {
-        if (queue.head_ref()->gcodes.size())
-        {
-            queue_head_block();
-            ensure_running();
-        }
+        // see if there are any fully planned things on the queue we can give to step ticker
+        // TODO....
+
+        return;
     }
-    else
-        // queue not empty
+
+    // not currently running, see if we can find something to do
+    if (queue.is_empty()) {
+        // nothing to do
+
+        // if (queue.head_ref()->gcodes.size())
+        // {
+        //     queue_head_block();
+        //     ensure_running();
+        // }
+    } else {
+        // queue not empty so see if we can stick something on the stepticker job queue
+        // we have to walk back and find blocks where recalculate_flag is clear.
+        // otherwise if the jobq is empty... (don't force anyhting if we have at least one thing on the job queue)
+        // see if we have reached the time limit, otherwise give it some more time to finish planning some entries
+        // if we have reached the time limit force the next thing on the queue into the jobq, fully planned or not
         ensure_running();
+    }
 }
 
-void Conveyor::on_config_reload(void* argument)
+// void Conveyor::append_gcode(Gcode* gcode)
+// {
+//     queue.head_ref()->append_gcode(gcode);
+// }
+
+// When all moves in a block have finished this is called by step ticker (in the pendsv ISR)
+void Conveyor::all_moves_finished()
 {
-    queue.resize(THEKERNEL->config->value(planner_queue_size_checksum)->by_default(32)->as_number());
+    // TODO ideally we should pass in the pointer to the block that just completed, but stepticker doesn't really know what it is,
+    // but it has to be the tail of the block queue
+    // we mark the block as deleted here (release it), which will call on_block_end() below
+    this->queue.item_ref(gc_pending)->release();
 }
 
-void Conveyor::append_gcode(Gcode* gcode)
+// A new block is popped from the queue
+void Conveyor::on_block_begin(Block *block)
 {
-    queue.head_ref()->append_gcode(gcode);
+    // setup stepticker to execute this block
+    // if it returns false the job queue was full
+    THEKERNEL->step_ticker->add_job(block);
 }
 
 // Process a new block in the queue
-void Conveyor::on_block_end(void* block)
+// gets called when the block is released
+void Conveyor::on_block_end(Block *block)
 {
     if (queue.is_empty())
         __debugbreak();
@@ -148,23 +211,22 @@ void Conveyor::on_block_end(void* block)
     gc_pending = queue.next(gc_pending);
 
     // mark entire queue for GC if flush flag is asserted
-    if (flush){
+    if (flush) {
         while (gc_pending != queue.head_i) {
             gc_pending = queue.next(gc_pending);
         }
     }
 
     // Return if queue is empty
-    if (gc_pending == queue.head_i)
-    {
+    if (gc_pending == queue.head_i) {
         running = false;
         return;
     }
 
-    // Get a new block
-    Block* next = this->queue.item_ref(gc_pending);
+//     // Get a new block
+//     Block* next = this->queue.item_ref(gc_pending);
+//     next->begin(); // causes on_block_begin() (above) to be called
 
-    next->begin();
 }
 
 // Wait for the queue to be empty
@@ -192,7 +254,7 @@ void Conveyor::queue_head_block()
         // clear and release the block on the head
         queue.head_ref()->clear();
 
-    }else{
+    } else {
         queue.head_ref()->ready();
         queue.produce_head();
     }
@@ -200,13 +262,15 @@ void Conveyor::queue_head_block()
 
 void Conveyor::ensure_running()
 {
-    if (!running)
-    {
-        if (gc_pending == queue.head_i)
-            return;
+    // if we are already running or the block queue is empty do nothing
+    if (running || gc_pending == queue.head_i) return;
 
+    // if the job queue is empty we can force the next block into it
+    if(THEKERNEL->step_ticker->is_jobq_empty()) {
+        // force the next block if not already forced
+        if(queue.item_ref(gc_pending)->is_job) return;
         running = true;
-        queue.item_ref(gc_pending)->begin();
+        queue.item_ref(gc_pending)->begin(); // on_block_begin() above gets called
     }
 }
 
@@ -230,8 +294,7 @@ void Conveyor::flush_queue()
 // Debug function
 void Conveyor::dump_queue()
 {
-    for (unsigned int index = queue.tail_i, i = 0; true; index = queue.next(index), i++ )
-    {
+    for (unsigned int index = queue.tail_i, i = 0; true; index = queue.next(index), i++ ) {
         THEKERNEL->streams->printf("block %03d > ", i);
         queue.item_ref(index)->debug();
 
index 22dc030..d29d299 100644 (file)
@@ -26,19 +26,16 @@ public:
     void on_module_loaded(void);
     void on_idle(void *);
     void on_main_loop(void *);
-    void on_block_end(void *);
+    void on_block_end(Block *);
+    void on_block_begin(Block *);
     void on_halt(void *);
-    void on_config_reload(void *);
-
-    void notify_block_finished(Block *);
 
     void wait_for_empty_queue();
     bool is_queue_empty() { return queue.is_empty(); };
     bool is_queue_full() { return queue.is_full(); };
 
-    void ensure_running(void);
 
-    void append_gcode(Gcode *);
+    //void append_gcode(Gcode *);
     void queue_head_block(void);
 
     void dump_queue(void);
@@ -48,8 +45,10 @@ public:
     friend class Planner; // for queue
 
 private:
-    typedef HeapRing<Block> Queue_t;
+    void all_moves_finished();
+    void ensure_running(void);
 
+    using  Queue_t= HeapRing<Block>;
     Queue_t queue;  // Queue of Blocks
     volatile unsigned int gc_pending;
 
index 544f54f..96a4b25 100644 (file)
@@ -21,7 +21,6 @@ using namespace std;
 #include "Config.h"
 #include "checksumm.h"
 #include "Robot.h"
-#include "Stepper.h"
 #include "ConfigValue.h"
 
 #include <math.h>
index ec176a8..761562c 100644 (file)
@@ -468,6 +468,15 @@ void Robot::on_gcode_received(void *argument)
                 current_wcs = 0;
                 absolute_mode = true;
                 break;
+            case 17:
+                THEKERNEL->call_event(ON_ENABLE, (void*)1); // turn all enable pins on
+                break;
+
+            case 18: // this used to support parameters, now it ignores them
+            case 84:
+                THEKERNEL->conveyor->wait_for_empty_queue();
+                THEKERNEL->call_event(ON_ENABLE, nullptr); // turn all enable pins off
+                break;
 
             case 92: // M92 - set steps per mm
                 if (gcode->has_letter('X'))
@@ -758,7 +767,7 @@ void Robot::process_move(Gcode *gcode)
 void Robot::distance_in_gcode_is_known(Gcode * gcode)
 {
     //If the queue is empty, execute immediately, otherwise attach to the last added block
-    THEKERNEL->conveyor->append_gcode(gcode);
+    //THEKERNEL->conveyor->append_gcode(gcode);
 }
 
 // reset the machine position for all axis. Used for homing.
@@ -976,10 +985,11 @@ bool Robot::append_line(Gcode *gcode, const float target[], float rate_mm_s )
 
     this->next_command_is_MCS = false; // always reset this
 
-    if(moved) {
-        // if adding these blocks didn't start executing, do that now
-        THEKERNEL->conveyor->ensure_running();
-    }
+    // this is not neede as COnveyor::on_main_loop will do something
+    // if(moved) {
+    //     // if adding these blocks didn't start executing, do that now
+    //     THEKERNEL->conveyor->ensure_running();
+    // }
 
     return moved;
 }
diff --git a/src/modules/robot/Stepper.cpp b/src/modules/robot/Stepper.cpp
deleted file mode 100644 (file)
index 041e0a5..0000000
+++ /dev/null
@@ -1,139 +0,0 @@
-/*
-      This file is part of Smoothie (http://smoothieware.org/). The motion control part is heavily based on Grbl (https://github.com/simen/grbl) with additions from Sungeun K. Jeon (https://github.com/chamnit/grbl)
-      Smoothie is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.
-      Smoothie is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
-      You should have received a copy of the GNU General Public License along with Smoothie. If not, see <http://www.gnu.org/licenses/>.
-*/
-
-#include "Stepper.h"
-
-#include "libs/Module.h"
-#include "libs/Kernel.h"
-#include "Planner.h"
-#include "Conveyor.h"
-#include "StepperMotor.h"
-#include "Robot.h"
-#include "checksumm.h"
-#include "SlowTicker.h"
-#include "Config.h"
-#include "ConfigValue.h"
-#include "Gcode.h"
-#include "Block.h"
-#include "StepTicker.h"
-
-#include <functional>
-
-#include "libs/nuts_bolts.h"
-#include "libs/Hook.h"
-
-#include <mri.h>
-
-// The stepper reacts to blocks that have XYZ movement to transform them into actual stepper motor moves
-Stepper::Stepper()
-{
-    this->current_block = NULL;
-}
-
-//Called when the module has just been loaded
-void Stepper::on_module_loaded()
-{
-    this->register_for_event(ON_BLOCK_BEGIN);
-    this->register_for_event(ON_BLOCK_END);
-    this->register_for_event(ON_GCODE_RECEIVED);
-    this->register_for_event(ON_HALT);
-
-    // Get onfiguration
-    this->on_config_reload(this);
-
-    // Attach to the end_of_move stepper event
-    THEKERNEL->step_ticker->finished_fnc= std::bind( &Stepper::stepper_motor_finished_move, this);
-}
-
-// Get configuration from the config file
-void Stepper::on_config_reload(void *argument)
-{
-    // Steppers start off by default
-    this->turn_enable_pins_off();
-}
-
-void Stepper::on_halt(void *argument)
-{
-    if(argument == nullptr) {
-        this->turn_enable_pins_off();
-    }
-}
-
-void Stepper::on_gcode_received(void *argument)
-{
-    Gcode *gcode = static_cast<Gcode *>(argument);
-
-    if( gcode->has_m) {
-        if( gcode->m == 17 ) {
-            this->turn_enable_pins_on();
-
-        }else if( (gcode->m == 84 || gcode->m == 18) && !gcode->has_letter('E') ) {
-            THEKERNEL->conveyor->wait_for_empty_queue();
-            this->turn_enable_pins_off();
-        }
-    }
-}
-
-// Enable steppers
-void Stepper::turn_enable_pins_on()
-{
-    for (auto a : THEKERNEL->robot->actuators)
-        a->enable(true);
-    this->enable_pins_status = true;
-    THEKERNEL->call_event(ON_ENABLE, (void*)1);
-}
-
-// Disable steppers
-void Stepper::turn_enable_pins_off()
-{
-    for (auto a : THEKERNEL->robot->actuators)
-        a->enable(false);
-    this->enable_pins_status = false;
-    THEKERNEL->call_event(ON_ENABLE, nullptr);
-}
-
-// A new block is popped from the queue
-void Stepper::on_block_begin(void *argument)
-{
-    Block *block  = static_cast<Block *>(argument);
-
-    // Mark the new block as of interrest to us, handle blocks that have no axis moves properly (like Extrude blocks etc)
-    bool take = false;
-    if (block->millimeters > 0.0F) {
-        for (size_t s = 0; !take && s < THEKERNEL->robot->actuators.size(); s++) {
-            take = block->steps[s] > 0;
-        }
-    }
-    if(!take) return;
-
-    block->take();
-
-    // We can't move with the enable pins off
-    if( this->enable_pins_status == false ) {
-        this->turn_enable_pins_on();
-    }
-
-    this->current_block = block;
-
-    // setup stepticker to execute this block
-    THEKERNEL->step_ticker->add_job(block);
-}
-
-// Current block is discarded
-void Stepper::on_block_end(void *argument)
-{
-    this->current_block = NULL; //stfu !
-}
-
-// When all moves in a block have finished this is called by step ticker (in the pendsv ISR)
-void Stepper::stepper_motor_finished_move()
-{
-    // This block is finished, release it
-    if( this->current_block != NULL ) {
-        this->current_block->release();
-    }
-}
diff --git a/src/modules/robot/Stepper.h b/src/modules/robot/Stepper.h
deleted file mode 100644 (file)
index 4fb741f..0000000
+++ /dev/null
@@ -1,47 +0,0 @@
-/*
-      This file is part of Smoothie (http://smoothieware.org/). The motion control part is heavily based on Grbl (https://github.com/simen/grbl).
-      Smoothie is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.
-      Smoothie is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
-      You should have received a copy of the GNU General Public License along with Smoothie. If not, see <http://www.gnu.org/licenses/>.
-*/
-
-#ifndef STEPPER_H
-#define STEPPER_H
-
-#include "libs/Module.h"
-#include <stdint.h>
-
-class Block;
-class StepperMotor;
-
-class Stepper : public Module
-{
-public:
-    Stepper();
-    void on_module_loaded();
-    void on_config_reload(void *argument);
-    void on_block_begin(void *argument);
-    void on_block_end(void *argument);
-    void on_gcode_received(void *argument);
-    void on_halt(void *argument);
-
-    void turn_enable_pins_on();
-    void turn_enable_pins_off();
-
-    const Block *get_current_block() const { return current_block; }
-
-private:
-    void stepper_motor_finished_move();
-
-    Block *current_block;
-
-    struct {
-        bool enable_pins_status:1;
-    };
-
-};
-
-
-
-
-#endif