Fork of Smoothie to port to mbed non-LPC targets.

Dependencies:   mbed

Fork of Smoothie by Stéphane Cachat

Committer:
Michael J. Spencer
Date:
Fri Feb 28 18:52:52 2014 -0800
Revision:
2:1df0b61d3b5a
Parent:
0:31e91bb0ef3c
Child:
3:f151d08d335c
Update to latest Smoothie.

Who changed what in which revision?

UserRevisionLine numberNew contents of line
Michael J. Spencer 2:1df0b61d3b5a 1 /*
scachat 0:31e91bb0ef3c 2 This file is part of Smoothie (http://smoothieware.org/). The motion control part is heavily based on Grbl (https://github.com/simen/grbl).
scachat 0:31e91bb0ef3c 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.
scachat 0:31e91bb0ef3c 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.
Michael J. Spencer 2:1df0b61d3b5a 5 You should have received a copy of the GNU General Public License along with Smoothie. If not, see <http://www.gnu.org/licenses/>.
scachat 0:31e91bb0ef3c 6 */
scachat 0:31e91bb0ef3c 7
scachat 0:31e91bb0ef3c 8 using namespace std;
scachat 0:31e91bb0ef3c 9 #include <vector>
scachat 0:31e91bb0ef3c 10 #include "libs/nuts_bolts.h"
scachat 0:31e91bb0ef3c 11 #include "libs/Module.h"
scachat 0:31e91bb0ef3c 12 #include "libs/Kernel.h"
scachat 0:31e91bb0ef3c 13 #include "SlowTicker.h"
scachat 0:31e91bb0ef3c 14 #include "libs/Hook.h"
Michael J. Spencer 2:1df0b61d3b5a 15 #include "modules/robot/Conveyor.h"
scachat 0:31e91bb0ef3c 16
Michael J. Spencer 2:1df0b61d3b5a 17 #include <mri.h>
Michael J. Spencer 2:1df0b61d3b5a 18
Michael J. Spencer 2:1df0b61d3b5a 19 // This module uses a Timer to periodically call hooks
Michael J. Spencer 2:1df0b61d3b5a 20 // Modules register with a function ( callback ) and a frequency, and we then call that function at the given frequency.
scachat 0:31e91bb0ef3c 21
scachat 0:31e91bb0ef3c 22 SlowTicker* global_slow_ticker;
scachat 0:31e91bb0ef3c 23
scachat 0:31e91bb0ef3c 24 SlowTicker::SlowTicker(){
Michael J. Spencer 2:1df0b61d3b5a 25 max_frequency = 0;
scachat 0:31e91bb0ef3c 26 global_slow_ticker = this;
Michael J. Spencer 2:1df0b61d3b5a 27
Michael J. Spencer 2:1df0b61d3b5a 28 // Configure the actual timer
scachat 0:31e91bb0ef3c 29 LPC_SC->PCONP |= (1 << 22); // Power Ticker ON
Michael J. Spencer 2:1df0b61d3b5a 30 LPC_TIM2->MR0 = 10000; // Initial dummy value for Match Register
scachat 0:31e91bb0ef3c 31 LPC_TIM2->MCR = 3; // Match on MR0, reset on MR0
scachat 0:31e91bb0ef3c 32 LPC_TIM2->TCR = 1; // Enable interrupt
scachat 0:31e91bb0ef3c 33 NVIC_EnableIRQ(TIMER2_IRQn); // Enable interrupt handler
Michael J. Spencer 2:1df0b61d3b5a 34
Michael J. Spencer 2:1df0b61d3b5a 35 // ISP button
Michael J. Spencer 2:1df0b61d3b5a 36 ispbtn.from_string("2.10")->as_input()->pull_up();
Michael J. Spencer 2:1df0b61d3b5a 37
Michael J. Spencer 2:1df0b61d3b5a 38 // TODO: What is this ??
Michael J. Spencer 2:1df0b61d3b5a 39 flag_1s_flag = 0;
Michael J. Spencer 2:1df0b61d3b5a 40 flag_1s_count = SystemCoreClock>>2;
Michael J. Spencer 2:1df0b61d3b5a 41
Michael J. Spencer 2:1df0b61d3b5a 42 g4_ticks = 0;
Michael J. Spencer 2:1df0b61d3b5a 43 g4_pause = false;
Michael J. Spencer 2:1df0b61d3b5a 44 }
Michael J. Spencer 2:1df0b61d3b5a 45
Michael J. Spencer 2:1df0b61d3b5a 46 void SlowTicker::on_module_loaded(){
Michael J. Spencer 2:1df0b61d3b5a 47 register_for_event(ON_IDLE);
Michael J. Spencer 2:1df0b61d3b5a 48 register_for_event(ON_GCODE_RECEIVED);
Michael J. Spencer 2:1df0b61d3b5a 49 register_for_event(ON_GCODE_EXECUTE);
Michael J. Spencer 2:1df0b61d3b5a 50 }
Michael J. Spencer 2:1df0b61d3b5a 51
Michael J. Spencer 2:1df0b61d3b5a 52 // Set the base frequency we use for all sub-frequencies
Michael J. Spencer 2:1df0b61d3b5a 53 void SlowTicker::set_frequency( int frequency ){
Michael J. Spencer 2:1df0b61d3b5a 54 this->interval = (SystemCoreClock >> 2) / frequency; // SystemCoreClock/4 = Timer increments in a second
Michael J. Spencer 2:1df0b61d3b5a 55 LPC_TIM2->MR0 = this->interval;
Michael J. Spencer 2:1df0b61d3b5a 56 LPC_TIM2->TCR = 3; // Reset
Michael J. Spencer 2:1df0b61d3b5a 57 LPC_TIM2->TCR = 1; // Reset
Michael J. Spencer 2:1df0b61d3b5a 58 flag_1s_count= SystemCoreClock>>2;
scachat 0:31e91bb0ef3c 59 }
scachat 0:31e91bb0ef3c 60
Michael J. Spencer 2:1df0b61d3b5a 61 // The actual interrupt being called by the timer, this is where work is done
Michael J. Spencer 2:1df0b61d3b5a 62 void SlowTicker::tick(){
Michael J. Spencer 2:1df0b61d3b5a 63
Michael J. Spencer 2:1df0b61d3b5a 64 // Call all hooks that need to be called ( bresenham )
Michael J. Spencer 2:1df0b61d3b5a 65 for (uint32_t i=0; i<this->hooks.size(); i++){
Michael J. Spencer 2:1df0b61d3b5a 66 Hook* hook = this->hooks.at(i);
Michael J. Spencer 2:1df0b61d3b5a 67 hook->countdown -= this->interval;
Michael J. Spencer 2:1df0b61d3b5a 68 if (hook->countdown < 0)
Michael J. Spencer 2:1df0b61d3b5a 69 {
Michael J. Spencer 2:1df0b61d3b5a 70 hook->countdown += hook->interval;
Michael J. Spencer 2:1df0b61d3b5a 71 hook->call();
Michael J. Spencer 2:1df0b61d3b5a 72 }
Michael J. Spencer 2:1df0b61d3b5a 73 }
Michael J. Spencer 2:1df0b61d3b5a 74
Michael J. Spencer 2:1df0b61d3b5a 75 // deduct tick time from secound counter
Michael J. Spencer 2:1df0b61d3b5a 76 flag_1s_count -= this->interval;
Michael J. Spencer 2:1df0b61d3b5a 77 // if a whole second has elapsed,
Michael J. Spencer 2:1df0b61d3b5a 78 if (flag_1s_count < 0)
Michael J. Spencer 2:1df0b61d3b5a 79 {
Michael J. Spencer 2:1df0b61d3b5a 80 // add a second to our counter
Michael J. Spencer 2:1df0b61d3b5a 81 flag_1s_count += SystemCoreClock >> 2;
Michael J. Spencer 2:1df0b61d3b5a 82 // and set a flag for idle event to pick up
Michael J. Spencer 2:1df0b61d3b5a 83 flag_1s_flag++;
Michael J. Spencer 2:1df0b61d3b5a 84 }
Michael J. Spencer 2:1df0b61d3b5a 85
Michael J. Spencer 2:1df0b61d3b5a 86 // if we're counting down a pause
Michael J. Spencer 2:1df0b61d3b5a 87 if (g4_ticks > 0)
Michael J. Spencer 2:1df0b61d3b5a 88 {
Michael J. Spencer 2:1df0b61d3b5a 89 // deduct tick time from timeout
Michael J. Spencer 2:1df0b61d3b5a 90 if (g4_ticks > interval)
Michael J. Spencer 2:1df0b61d3b5a 91 g4_ticks -= interval;
Michael J. Spencer 2:1df0b61d3b5a 92 else
Michael J. Spencer 2:1df0b61d3b5a 93 g4_ticks = 0;
Michael J. Spencer 2:1df0b61d3b5a 94 }
Michael J. Spencer 2:1df0b61d3b5a 95
Michael J. Spencer 2:1df0b61d3b5a 96 // Enter MRI mode if the ISP button is pressed
Michael J. Spencer 2:1df0b61d3b5a 97 // TODO: This should have it's own module
Michael J. Spencer 2:1df0b61d3b5a 98 if (ispbtn.get() == 0)
Michael J. Spencer 2:1df0b61d3b5a 99 __debugbreak();
Michael J. Spencer 2:1df0b61d3b5a 100
scachat 0:31e91bb0ef3c 101 }
scachat 0:31e91bb0ef3c 102
Michael J. Spencer 2:1df0b61d3b5a 103 bool SlowTicker::flag_1s(){
Michael J. Spencer 2:1df0b61d3b5a 104 // atomic flag check routine
Michael J. Spencer 2:1df0b61d3b5a 105 // first disable interrupts
Michael J. Spencer 2:1df0b61d3b5a 106 __disable_irq();
Michael J. Spencer 2:1df0b61d3b5a 107 // then check for a flag
Michael J. Spencer 2:1df0b61d3b5a 108 if (flag_1s_flag)
Michael J. Spencer 2:1df0b61d3b5a 109 {
Michael J. Spencer 2:1df0b61d3b5a 110 // if we have a flag, decrement the counter
Michael J. Spencer 2:1df0b61d3b5a 111 flag_1s_flag--;
Michael J. Spencer 2:1df0b61d3b5a 112 // re-enable interrupts
Michael J. Spencer 2:1df0b61d3b5a 113 __enable_irq();
Michael J. Spencer 2:1df0b61d3b5a 114 // and tell caller that we consumed a flag
Michael J. Spencer 2:1df0b61d3b5a 115 return true;
Michael J. Spencer 2:1df0b61d3b5a 116 }
Michael J. Spencer 2:1df0b61d3b5a 117 // if no flag, re-enable interrupts and return false
Michael J. Spencer 2:1df0b61d3b5a 118 __enable_irq();
Michael J. Spencer 2:1df0b61d3b5a 119 return false;
Michael J. Spencer 2:1df0b61d3b5a 120 }
Michael J. Spencer 2:1df0b61d3b5a 121
Michael J. Spencer 2:1df0b61d3b5a 122 #include "gpio.h"
Michael J. Spencer 2:1df0b61d3b5a 123 extern GPIO leds[];
Michael J. Spencer 2:1df0b61d3b5a 124 void SlowTicker::on_idle(void*)
Michael J. Spencer 2:1df0b61d3b5a 125 {
Michael J. Spencer 2:1df0b61d3b5a 126 static uint16_t ledcnt= 0;
Michael J. Spencer 2:1df0b61d3b5a 127 if(THEKERNEL->use_leds) {
Michael J. Spencer 2:1df0b61d3b5a 128 // flash led 3 to show we are alive
Michael J. Spencer 2:1df0b61d3b5a 129 leds[2]= (ledcnt++ & 0x1000) ? 1 : 0;
Michael J. Spencer 2:1df0b61d3b5a 130 }
Michael J. Spencer 2:1df0b61d3b5a 131
Michael J. Spencer 2:1df0b61d3b5a 132 // if interrupt has set the 1 second flag
Michael J. Spencer 2:1df0b61d3b5a 133 if (flag_1s())
Michael J. Spencer 2:1df0b61d3b5a 134 // fire the on_second_tick event
Michael J. Spencer 2:1df0b61d3b5a 135 THEKERNEL->call_event(ON_SECOND_TICK);
Michael J. Spencer 2:1df0b61d3b5a 136
Michael J. Spencer 2:1df0b61d3b5a 137 // if G4 has finished, release our pause
Michael J. Spencer 2:1df0b61d3b5a 138 if (g4_pause && (g4_ticks == 0))
Michael J. Spencer 2:1df0b61d3b5a 139 {
Michael J. Spencer 2:1df0b61d3b5a 140 g4_pause = false;
Michael J. Spencer 2:1df0b61d3b5a 141 THEKERNEL->pauser->release();
Michael J. Spencer 2:1df0b61d3b5a 142 }
Michael J. Spencer 2:1df0b61d3b5a 143 }
Michael J. Spencer 2:1df0b61d3b5a 144
Michael J. Spencer 2:1df0b61d3b5a 145 // When a G4-type gcode is received, add it to the queue so we can execute it in time
Michael J. Spencer 2:1df0b61d3b5a 146 void SlowTicker::on_gcode_received(void* argument){
Michael J. Spencer 2:1df0b61d3b5a 147 Gcode* gcode = static_cast<Gcode*>(argument);
Michael J. Spencer 2:1df0b61d3b5a 148 // Add the gcode to the queue ourselves if we need it
Michael J. Spencer 2:1df0b61d3b5a 149 if( gcode->has_g && gcode->g == 4 ){
Michael J. Spencer 2:1df0b61d3b5a 150 THEKERNEL->conveyor->append_gcode(gcode);
Michael J. Spencer 2:1df0b61d3b5a 151 // ensure that no subsequent gcodes get executed along with our G4
Michael J. Spencer 2:1df0b61d3b5a 152 THEKERNEL->conveyor->queue_head_block();
Michael J. Spencer 2:1df0b61d3b5a 153 }
Michael J. Spencer 2:1df0b61d3b5a 154 }
Michael J. Spencer 2:1df0b61d3b5a 155
Michael J. Spencer 2:1df0b61d3b5a 156 // When a G4-type gcode is executed, start the pause
Michael J. Spencer 2:1df0b61d3b5a 157 void SlowTicker::on_gcode_execute(void* argument){
Michael J. Spencer 2:1df0b61d3b5a 158 Gcode* gcode = static_cast<Gcode*>(argument);
Michael J. Spencer 2:1df0b61d3b5a 159
Michael J. Spencer 2:1df0b61d3b5a 160 if (gcode->has_g){
Michael J. Spencer 2:1df0b61d3b5a 161 if (gcode->g == 4){
Michael J. Spencer 2:1df0b61d3b5a 162 gcode->mark_as_taken();
Michael J. Spencer 2:1df0b61d3b5a 163 bool updated = false;
Michael J. Spencer 2:1df0b61d3b5a 164 if (gcode->has_letter('P')) {
Michael J. Spencer 2:1df0b61d3b5a 165 updated = true;
Michael J. Spencer 2:1df0b61d3b5a 166 g4_ticks += gcode->get_int('P') * ((SystemCoreClock >> 2) / 1000UL);
Michael J. Spencer 2:1df0b61d3b5a 167 }
Michael J. Spencer 2:1df0b61d3b5a 168 if (gcode->has_letter('S')) {
Michael J. Spencer 2:1df0b61d3b5a 169 updated = true;
Michael J. Spencer 2:1df0b61d3b5a 170 g4_ticks += gcode->get_int('S') * (SystemCoreClock >> 2);
Michael J. Spencer 2:1df0b61d3b5a 171 }
Michael J. Spencer 2:1df0b61d3b5a 172 if (updated){
Michael J. Spencer 2:1df0b61d3b5a 173 // G4 Smm Pnn should pause for mm seconds + nn milliseconds
Michael J. Spencer 2:1df0b61d3b5a 174 // at 120MHz core clock, the longest possible delay is (2^32 / (120MHz / 4)) = 143 seconds
Michael J. Spencer 2:1df0b61d3b5a 175 if (!g4_pause){
Michael J. Spencer 2:1df0b61d3b5a 176 g4_pause = true;
Michael J. Spencer 2:1df0b61d3b5a 177 THEKERNEL->pauser->take();
Michael J. Spencer 2:1df0b61d3b5a 178 }
Michael J. Spencer 2:1df0b61d3b5a 179 }
Michael J. Spencer 2:1df0b61d3b5a 180 }
scachat 0:31e91bb0ef3c 181 }
scachat 0:31e91bb0ef3c 182 }
scachat 0:31e91bb0ef3c 183
scachat 0:31e91bb0ef3c 184 extern "C" void TIMER2_IRQHandler (void){
scachat 0:31e91bb0ef3c 185 if((LPC_TIM2->IR >> 0) & 1){ // If interrupt register set for MR0
Michael J. Spencer 2:1df0b61d3b5a 186 LPC_TIM2->IR |= 1 << 0; // Reset it
scachat 0:31e91bb0ef3c 187 }
Michael J. Spencer 2:1df0b61d3b5a 188 global_slow_ticker->tick();
scachat 0:31e91bb0ef3c 189 }
scachat 0:31e91bb0ef3c 190