Extruder,TemperatureControl: minor comment changes
[clinton/Smoothieware.git] / src / modules / robot / Conveyor.cpp
CommitLineData
f80d18b9
L
1/*
2 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)
3 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.
4 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.
5 You should have received a copy of the GNU General Public License along with Smoothie. If not, see <http://www.gnu.org/licenses/>.
6*/
7
8using namespace std;
9#include <vector>
10#include "libs/nuts_bolts.h"
11#include "libs/RingBuffer.h"
12#include "../communication/utils/Gcode.h"
13#include "libs/Module.h"
14#include "libs/Kernel.h"
15#include "Timer.h" // mbed.h lib
16#include "wait_api.h" // mbed.h lib
17#include "Block.h"
18#include "Conveyor.h"
19#include "Planner.h"
55456577 20#include "mri.h"
f80d18b9 21
0b3e628f
MM
22#define planner_queue_size_checksum CHECKSUM("planner_queue_size")
23
edac9072
AW
24// The conveyor holds the queue of blocks, takes care of creating them, and starting the executing chain of blocks
25
f80d18b9 26Conveyor::Conveyor(){
c501670b 27 gc_pending = queue.tail_i;
2134bcf2 28 running = false;
702023f3
MM
29}
30
d149c730 31void Conveyor::on_module_loaded(){
702023f3 32 register_for_event(ON_IDLE);
0b3e628f
MM
33 register_for_event(ON_CONFIG_RELOAD);
34
35 on_config_reload(this);
702023f3
MM
36}
37
edac9072 38// Delete blocks here, because they can't be deleted in interrupt context ( see Block.cpp:release )
d149c730 39void Conveyor::on_idle(void* argument){
55456577 40 if (queue.tail_i != gc_pending)
c501670b 41 {
55456577
MM
42 if (queue.is_empty())
43 __debugbreak();
44 else
45 {
46 // Cleanly delete block
47 Block* block = queue.tail_ref();
48 block->gcodes.clear();
49 queue.consume_tail();
50 }
702023f3 51 }
3facc890
MM
52 else if (queue.is_empty())
53 {
54 // if someone has appended gcodes but the queue is stopped
55 // make sure they get executed in a timely fashion
56 if (queue.head_ref()->gcodes.size())
57 {
58 queue_head_block();
59 ensure_running();
60 }
61 }
36aca284
MM
62 else
63 // queue not empty
64 ensure_running();
f80d18b9
L
65}
66
0b3e628f
MM
67void Conveyor::on_config_reload(void* argument)
68{
69 queue.resize(THEKERNEL->config->value(planner_queue_size_checksum)->by_default(32)->as_number());
70}
71
e0ee24ed
MM
72void Conveyor::append_gcode(Gcode* gcode)
73{
74 gcode->mark_as_taken();
c87f8e07 75 queue.head_ref()->append_gcode(gcode);
e0ee24ed
MM
76}
77
f80d18b9 78// Process a new block in the queue
2134bcf2
MM
79void Conveyor::on_block_end(void* block)
80{
55456577
MM
81 if (queue.is_empty())
82 __debugbreak();
0b3e628f 83
2134bcf2 84 gc_pending = queue.next(gc_pending);
f80d18b9
L
85
86 // Return if queue is empty
2134bcf2
MM
87 if (gc_pending == queue.head_i)
88 {
89 running = false;
f80d18b9
L
90 return;
91 }
702023f3 92
f80d18b9 93 // Get a new block
2134bcf2 94 Block* next = this->queue.item_ref(gc_pending);
f80d18b9 95
2134bcf2 96 next->begin();
f80d18b9
L
97}
98
edac9072 99// Wait for the queue to have a given number of free blocks
c501670b
MM
100void Conveyor::wait_for_queue(int free_blocks)
101{
102 while (queue.is_full())
2134bcf2
MM
103 {
104 ensure_running();
314ab8f7 105 THEKERNEL->call_event(ON_IDLE);
2134bcf2 106 }
f80d18b9 107}
17c68379 108
edac9072 109// Wait for the queue to be empty
c501670b
MM
110void Conveyor::wait_for_empty_queue()
111{
112 while (!queue.is_empty())
2134bcf2
MM
113 {
114 ensure_running();
314ab8f7 115 THEKERNEL->call_event(ON_IDLE);
2134bcf2 116 }
17c68379
BG
117}
118
68d16168 119// Return true if the queue is empty
c501670b
MM
120bool Conveyor::is_queue_empty()
121{
122 return queue.is_empty();
68d16168
L
123}
124
2134bcf2
MM
125void Conveyor::queue_head_block()
126{
127 while (queue.is_full())
128 {
129 ensure_running();
130 THEKERNEL->call_event(ON_IDLE, this);
131 }
132
133 queue.produce_head();
134}
135
136void Conveyor::ensure_running()
137{
138 if (!running)
139 {
140 running = true;
141 queue.tail_ref()->begin();
142 }
143}
c501670b 144
a617ac35
MM
145// Debug function
146void Conveyor::dump_queue()
147{
148 for (unsigned int index = queue.tail_i, i = 0; true; index = queue.next(index), i++ )
149 {
150 THEKERNEL->streams->printf("block %03d > ", i);
151 queue.item_ref(index)->debug();
152
153 if (index == queue.head_i)
154 break;
155 }
156}
157
c501670b
MM
158// feels hacky, but apparently the way to do it
159#include "HeapRing.cpp"
160template class HeapRing<Block>;