major bug fixes, way too many to enumerate
authorArthur Wolf <wolf.arthur@gmail.com>
Mon, 5 Dec 2011 19:31:38 +0000 (20:31 +0100)
committerArthur Wolf <wolf.arthur@gmail.com>
Mon, 5 Dec 2011 19:31:38 +0000 (20:31 +0100)
30 files changed:
gcc4mbed/build/gcc4mbed.mk
gcc4mbed/build/mbed.ld
gcc4mbed/external/FATFileSystem/LPC1768/FATFileSystem.ar
gcc4mbed/external/mbed/LPC1768/capi.ar
gcc4mbed/external/mbed/LPC1768/mbed.ar
gcc4mbed/samples/CTest/makefile
gcc4mbed/samples/HelloWorld/main.cpp
gcc4mbed/samples/HelloWorld/makefile
gcc4mbed/samples/SDFileSystem/main.cpp
gcc4mbed/samples/SDFileSystem/makefile
gcc4mbed/samples/Ticker/main.cpp
gcc4mbed/samples/Ticker/makefile
gcc4mbed/src/gcc4mbed.c
gcc4mbed/src/syscalls.c
src/libs/Kernel.h
src/libs/RingBuffer.h
src/main.cpp
src/modules/communication/GcodeDispatch.cpp
src/modules/communication/SerialConsole.cpp
src/modules/communication/SerialConsole.h
src/modules/communication/utils/Gcode.cpp
src/modules/robot/Block.cpp
src/modules/robot/Block.h
src/modules/robot/Planner.cpp
src/modules/robot/Player.cpp [new file with mode: 0644]
src/modules/robot/Player.h [new file with mode: 0644]
src/modules/robot/Player.o [new file with mode: 0644]
src/modules/robot/Robot.cpp
src/modules/robot/Stepper.cpp
src/modules/tools/extruder/Extruder.cpp

index 74becc8..199d794 100644 (file)
 #                of the build directory which contains this gcc4mbed.mk file.
 #   LIBS_PREFIX: List of library/object files to prepend to mbed.ar capi.ar libs.
 #   LIBS_SUFFIX: List of library/object files to append to mbed.ar capi.ar libs.
+#   GCC4MBED_DELAYED_STDIO_INIT: Set to non-zero value to have intialization of
+#                                stdin/stdout/stderr delayed which will
+#                                shrink the size of the resulting binary if
+#                                APIs like printf(), scanf(), etc. aren't used.
 # Example makefile:
 #       PROJECT=HelloWorld
 #       SRC=.
 
 # Default project source to be located in current directory.
 ifndef SRC
-SRC=./src
+SRC=.
+endif
+
+# Default the init of stdio/stdout/stderr to occur before global constructors.
+ifndef GCC4MBED_DELAYED_STDIO_INIT
+GCC4MBED_DELAYED_STDIO_INIT=0
 endif
 
 # List of sources to be compiled/assembled
@@ -64,19 +73,19 @@ EXTERNAL_DIR = $(GCC4MBED_DIR)/external
 # Include path which points to external library headers and to subdirectories of this project which contain headers.
 SUBDIRS = $(wildcard $(SRC)/* $(SRC)/*/* $(SRC)/*/*/* $(SRC)/*/*/*/* $(SRC)/*/*/*/*/*)
 PROJINCS = $(sort $(dir $(SUBDIRS)))
-INCDIRS += $(PROJINCS) $(EXTERNAL_DIR)/mbed $(EXTERNAL_DIR)/mbed/LPC1768 $(EXTERNAL_DIR)/FATFileSystem
+INCDIRS += $(PROJINCS) $(EXTERNAL_DIR)/mbed $(EXTERNAL_DIR)/mbed/LPC1768 $(EXTERNAL_DIR)/FATFileSystem $(GCC4MBED_DIR)/mri
 
 # DEFINEs to be used when building C/C++ code
-DEFINES = -DTARGET_LPC1768
+DEFINES = -DTARGET_LPC1768 -DGCC4MBED_DELAYED_STDIO_INIT=$(GCC4MBED_DELAYED_STDIO_INIT)
 
 # Libraries to be linked into final binary
-LIBS = $(LIBS_PREFIX) $(EXTERNAL_DIR)/mbed/LPC1768/mbed.ar $(EXTERNAL_DIR)/mbed/LPC1768/capi.ar $(EXTERNAL_DIR)/FATFileSystem/LPC1768/FATFileSystem.ar $(LIBS_SUFFIX)
+LIBS = $(LIBS_PREFIX) $(GCC4MBED_DIR)/mri/mri.ar $(EXTERNAL_DIR)/mbed/LPC1768/mbed.ar $(EXTERNAL_DIR)/mbed/LPC1768/capi.ar $(EXTERNAL_DIR)/FATFileSystem/LPC1768/FATFileSystem.ar $(LIBS_SUFFIX)
 
 # Optimization level
 OPTIMIZATION = 2
 
 #  Compiler Options
-GPFLAGS = -O$(OPTIMIZATION) -gdwarf-2 -mcpu=cortex-m3 -mthumb -mthumb-interwork -fshort-wchar -ffunction-sections -fdata-sections -fpromote-loop-indices -Wall -Wextra -Wimplicit -Wcast-align -Wpointer-arith -Wredundant-decls -Wshadow -Wcast-qual -Wcast-align -fno-exceptions
+GPFLAGS = -O$(OPTIMIZATION) -gstabs+3 -mcpu=cortex-m3 -mthumb -mthumb-interwork -fshort-wchar -ffunction-sections -fdata-sections -fpromote-loop-indices -Wall -Wextra -Wimplicit -Wcast-align -Wpointer-arith -Wredundant-decls -Wshadow -Wcast-qual -Wcast-align -fno-exceptions
 GPFLAGS += $(patsubst %,-I%,$(INCDIRS))
 GPFLAGS += $(DEFINES)
 
@@ -94,12 +103,14 @@ OBJDUMP = arm-none-eabi-objdump
 SIZE = arm-none-eabi-size
 REMOVE = rm
 
-# Switch to cs-rm on Windows.
+# Switch to cs-rm on Windows and make sure that cmd.exe is used as shell.
 ifeq "$(MAKE)" "cs-make"
 REMOVE = cs-rm
+SHELL=cmd.exe
 endif
 
 #########################################################################
+.PHONY: all clean deploy
 
 all:: $(PROJECT).hex $(PROJECT).bin $(PROJECT).disasm
 
@@ -112,7 +123,7 @@ $(PROJECT).hex: $(PROJECT).elf
 $(PROJECT).disasm: $(PROJECT).elf
        $(OBJDUMP) -d $(PROJECT).elf >$(PROJECT).disasm
        
-$(PROJECT).elf: $(LSCRIPT) $(OBJECTS)
+$(PROJECT).elf: $(LSCRIPT) $(OBJECTS) $(LIBS)
        $(LD) $(LDFLAGS) $(OBJECTS) $(LIBS) -o $(PROJECT).elf
        $(SIZE) $(PROJECT).elf
 
index 5363eaa..edaa0c4 100644 (file)
@@ -127,6 +127,7 @@ SECTIONS
         _sidata = LOADADDR (.data);\r
         . = ALIGN(4);\r
         _sdata = .;\r
+        Image$$RW_IRAM1$$Base = .;\r
 \r
         *(.ARM.__AT_0x10000000)\r
         *(vtable vtable.*)\r
@@ -150,6 +151,7 @@ SECTIONS
 \r
         . = ALIGN(4);\r
         _ebss = . ;\r
+        Image$$RW_IRAM1$$ZI$$Limit = . ;\r
     } >IRAM0\r
 \r
     /**************************************************/\r
@@ -194,12 +196,16 @@ SECTIONS
        they will be left uninitialized. */\r
     .AHBSRAM0 (NOLOAD):\r
     {\r
+        Image$$RW_IRAM2$$Base = . ;\r
         *(AHBSRAM0)\r
+        Image$$RW_IRAM2$$ZI$$Limit = .;\r
     } > IRAM1\r
 \r
     .AHBSRAM1 (NOLOAD):\r
     {\r
+        Image$$RW_IRAM3$$Base = . ;\r
         *(AHBSRAM1)\r
+        Image$$RW_IRAM3$$ZI$$Limit = .;\r
     } > IRAM2\r
 \r
 \r
index 8099d00..87d3b12 100644 (file)
Binary files a/gcc4mbed/external/FATFileSystem/LPC1768/FATFileSystem.ar and b/gcc4mbed/external/FATFileSystem/LPC1768/FATFileSystem.ar differ
index 2657ac9..7001e3b 100644 (file)
Binary files a/gcc4mbed/external/mbed/LPC1768/capi.ar and b/gcc4mbed/external/mbed/LPC1768/capi.ar differ
index ed61020..c5b0be5 100644 (file)
Binary files a/gcc4mbed/external/mbed/LPC1768/mbed.ar and b/gcc4mbed/external/mbed/LPC1768/mbed.ar differ
index 678ea61..bc644bf 100644 (file)
@@ -15,5 +15,6 @@ PROJECT=CTest
 GCC4MBED_DIR=../..\r
 LIBS_PREFIX=\r
 LIBS_SUFFIX=\r
+GCC4MBED_DELAYED_STDIO_INIT=1\r
 \r
 include ../../build/gcc4mbed.mk\r
index 77b5dec..d6f4318 100644 (file)
@@ -21,11 +21,14 @@ DigitalOut myled(LED1);
 \r
 int main() \r
 {\r
+    volatile int IterationCount = 0;\r
+    \r
     while(1) \r
     {\r
         myled = 1;\r
         wait(0.2);\r
         myled = 0;\r
         wait(0.2);\r
+        IterationCount++;\r
     }\r
 }\r
index a031c3c..824e3a9 100644 (file)
@@ -15,5 +15,6 @@ PROJECT=HelloWorld
 GCC4MBED_DIR=../..\r
 LIBS_PREFIX=\r
 LIBS_SUFFIX=\r
+GCC4MBED_DELAYED_STDIO_INIT=1\r
 \r
 include ../../build/gcc4mbed.mk\r
index a0f638c..22046e2 100644 (file)
 /* LocalFileSystem test modified to use SD cards instead. */\r
 #include "mbed.h"\r
 #include "SDFileSystem.h"\r
-#include "agutil.h"\r
-\r
-\r
-extern "C" void HardFault_Handler(void)\r
-{\r
-    DebugDumpStack();\r
-    error("\r\nHardFault\r\n");\r
-}\r
-\r
-extern "C" void MemManage_Handler(void)\r
-{\r
-    DebugDumpStack();\r
-    error("\r\nMemManage\r\n");\r
-}\r
-\r
-extern "C" void BusFault_Handler(void)\r
-{\r
-    DebugDumpStack();\r
-    error("\r\nBusFault\r\n");\r
-}\r
-\r
-extern "C" void UsageFault_Handler(void)\r
-{\r
-    DebugDumpStack();\r
-    error("\r\nUsageFault\r\n");\r
-}\r
-\r
-extern "C" void SVC_Handler(void)\r
-{\r
-    DebugDumpStack();\r
-    error("\r\nSVC Call\r\n");\r
-}\r
-\r
-extern "C" void DebugMon_Handler(void)\r
-{\r
-    DebugDumpStack();\r
-    error("\r\nDebugMonitor\r\n");\r
-}\r
-\r
-extern "C" void PendSV_Handler(void)\r
-{\r
-    DebugDumpStack();\r
-    error("\r\nPendSV\r\n");\r
-}\r
-\r
-extern "C" void SysTick_Handler(void)\r
-{\r
-    DebugDumpStack();\r
-    error("\r\nSysTick");\r
-}\r
-\r
-\r
-void BreakHandler(void)\r
-{\r
-    DebugDumpStack();\r
-    error("\r\nManual Break\r\n");\r
-}\r
 \r
 \r
 SDFileSystem sd(p5, p6, p7, p8, "sd"); // the pinout on the mbed Cool Components workshop board\r
-InterruptIn BreakInterrupt(p9);\r
 \r
 \r
 int main() \r
 {\r
-    // If you pull p9 low, then it should break into a running program and dump the stack.\r
-    BreakInterrupt.mode(PullUp);\r
-    BreakInterrupt.fall(BreakHandler);\r
-\r
     int  Result = -1;\r
     char Buffer[32];\r
     \r
@@ -163,7 +101,5 @@ int main()
     printf("Test 10: closedir\r\n");\r
     closedir(d);\r
   \r
-\r
-\r
     printf("\r\nTest completed\r\n");\r
 }   \r
index dfce437..d01e8d8 100644 (file)
@@ -13,8 +13,8 @@
 # limitations under the License.\r
 PROJECT=SDFileSystem\r
 GCC4MBED_DIR=../..\r
-INCDIRS=../agutil\r
-LIBS_PREFIX=../agutil/agutil.ar\r
+INCDIRS=\r
+LIBS_PREFIX=\r
 LIBS_SUFFIX=\r
 \r
 include ../../build/gcc4mbed.mk\r
index 7bc7005..a4e54df 100644 (file)
@@ -13,7 +13,6 @@
    limitations under the License.\r
 */\r
 #include <mbed.h>\r
-#include <agutil.h>\r
 \r
 \r
 Ticker flipper;\r
@@ -30,15 +29,6 @@ int main()
     led2 = 1;\r
     flipper.attach(&flip, 5.0); // the address of the function to be attached (flip) and the interval (2 seconds)\r
 \r
-    // Dump the interrupt vector\r
-    printf("\r\n");\r
-    printf("Vector Table Offset Register\r\n");\r
-    DebugDumpMemory((void*)0xE000ED08, 4, 4);\r
-    \r
-    printf("Vector Table\r\n");\r
-    unsigned int VectorAddress = *((unsigned int*)0xE000ED08);\r
-    DebugDumpMemory((void*)VectorAddress, 4 * 32, 4);\r
-    \r
     // spin in a main loop. flipper will interrupt it to call flip\r
     while(1) {\r
         led1 = !led1;\r
index bd68112..38c28d2 100644 (file)
@@ -13,8 +13,8 @@
 # limitations under the License.\r
 PROJECT=Ticker\r
 GCC4MBED_DIR=../..\r
-INCDIRS=../agutil\r
-LIBS_PREFIX=../agutil/agutil.ar\r
+INCDIRS=\r
+LIBS_PREFIX=\r
 LIBS_SUFFIX=\r
 \r
 include ../../build/gcc4mbed.mk\r
index 4696992..7b66783 100644 (file)
@@ -26,7 +26,7 @@
  *  Modified by Sagar G V on Mar 11 2011. added __libc_init_array()\r
  *  Modfied by Adam Green in 2011 to support mbed.\r
  ******************************************************************************/\r
-#include "mbedsys.h"\r
+#include "mri.h"\r
 \r
 \r
 /* Exported constants --------------------------------------------------------*/\r
@@ -46,6 +46,8 @@ extern unsigned long _ebss;         /* end address for the .bss section. defined
 extern "C" int  main(void);\r
 extern "C" void __libc_init_array(void);\r
 extern "C" void exit(int ErrorCode);\r
+extern "C" void __GCC4MBEDOpenStandardHandles(void);\r
+extern "C" void __MriTestRegisters(void);\r
 \r
 \r
 /* CRT initialization code called from Reset_Handler after it calls SystemInit() */\r
@@ -81,9 +83,18 @@ extern "C" __attribute__ ((section(".mbed_init"))) void __main(void)
         *(pulDest++) = 0;\r
     }\r
 \r
+    /* Initialize stdin/stdout/stderr file handles. */\r
+    if (!GCC4MBED_DELAYED_STDIO_INIT)\r
+    {\r
+        __GCC4MBEDOpenStandardHandles();\r
+    }\r
+    \r
     /* Initialize static constructors. */\r
      __libc_init_array();\r
 \r
+    MriInit();\r
+    //__debugbreak();\r
+\r
     /* Call the application's entry point. */\r
     ExitCode = main();\r
     \r
index 0221238..07fb9ae 100644 (file)
@@ -47,7 +47,7 @@ static int g_StandardHandlesOpened = 0;
 \r
 \r
 /* Open the stdin/stdout/stderr handles */\r
-static void _OpenStandardHandles(void)\r
+extern "C" void __GCC4MBEDOpenStandardHandles(void)\r
 {\r
     /* Open stdin/stdout/stderr */\r
     _sys_open("/stdin", OPENMODE_R);\r
@@ -238,7 +238,7 @@ extern "C" int _read(int file, char *ptr, int len)
     /* Open stdin/stdout/stderr if needed */\r
     if (!g_StandardHandlesOpened && file < 3)\r
     {\r
-        _OpenStandardHandles();\r
+        __GCC4MBEDOpenStandardHandles();\r
     }\r
 \r
     /* Call the function in mbed.ar and let it handle the read */\r
@@ -258,7 +258,7 @@ extern "C" int _write(int file, char *ptr, int len)
     /* Open stdin/stdout/stderr if needed */\r
     if (!g_StandardHandlesOpened && file < 3)\r
     {\r
-        _OpenStandardHandles();\r
+        __GCC4MBEDOpenStandardHandles();\r
     }\r
 \r
     /* Call the function in mbed.ar and let it handle the writes */\r
index 8ec6b9f..74933b7 100644 (file)
@@ -56,6 +56,8 @@ class Kernel {
         Config*           config;
         Player*           player;
 
+        int debug;
+
     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
 
index 46f4d26..3476553 100644 (file)
@@ -16,6 +16,7 @@ template<class kind, int length> class RingBuffer {
         RingBuffer();
         int          size();
         int          capacity();
+        int          next_block_index(int index);
         void         push_back(kind object);
         void         pop_front(kind &object);
         void         get( int index, kind &object);
@@ -40,6 +41,12 @@ template<class kind, int length>  int RingBuffer<kind, length>::size(){
 return((this->head>this->tail)?length:0)+this->tail-head;
 }
 
+template<class kind, int length> int RingBuffer<kind, length>::next_block_index(int index){
+    index++;
+    if (index == length) { index = 0; }
+    return(index);
+}
+
 template<class kind, int length> void RingBuffer<kind, length>::push_back(kind object){
     this->buffer[this->tail] = object;
     this->tail = (tail+1)&(length-1);
@@ -80,8 +87,9 @@ template<class kind, int length> void RingBuffer<kind, length>::pop_front(kind &
 }
 
 template<class kind, int length> void RingBuffer<kind, length>::delete_first(){
-    kind dummy;
-    this->pop_front(dummy);
+    //kind dummy;
+    //this->pop_front(dummy);
+    this->head = (this->head+1)&(length-1);
 }
 
 
index 53bc70e..0575dbd 100644 (file)
@@ -9,6 +9,7 @@
 #include "libs/Kernel.h"
 #include "modules/tools/laser/Laser.h"
 #include "modules/tools/extruder/Extruder.h"
+#include "modules/robot/Player.h"
 #include "modules/utils/simpleshell/SimpleShell.h"
 #include "modules/utils/pauser/Pauser.h"
 #include "libs/SDFileSystem.h"
@@ -89,6 +90,8 @@ class TemperatureControl : public Module {
         }
 
         double get_temperature(){
+            double temp = this->new_thermistor_reading() ;
+            //this->kernel->serial->printf("adc reading: %f \r\n", temp); 
             return this->adc_value_to_temperature( this->new_thermistor_reading() );
         }
 
@@ -162,10 +165,14 @@ class TemperatureControl : public Module {
 
         double average_adc_reading(){
             double total;
+            int j=0;
             for( int i = 0; i <= this->queue.size()-1; i++ ){
+                j++; 
+                //this->kernel->serial->printf("value:%f\r\n", *(this->queue.get_ref(i)) ); 
                 total += *(this->queue.get_ref(i));
             }
-            return total / this->queue.size();
+            //this->kernel->serial->printf("total:%f, size:%d \r\n", total, this->queue.size() ); 
+            return total / j;
         }
 
         AnalogIn* thermistor_pin;
@@ -195,7 +202,6 @@ class TemperatureControl : public Module {
 };
 
 
-
 int main() {
 
     Kernel* kernel = new Kernel();
@@ -206,9 +212,11 @@ int main() {
     kernel->add_module( new Extruder(p26,p27) );
     kernel->add_module( new SimpleShell() );
     //kernel->add_module( new Pauser(p29,p30) );
-    //kernel->add_module( new TemperatureControl() );
+    kernel->add_module( new TemperatureControl() );
 
     while(1){
         kernel->call_event(ON_MAIN_LOOP);
+
     }
 }
+
index d2d3888..969594e 100644 (file)
@@ -13,6 +13,7 @@ using std::string;
 #include "utils/Gcode.h"
 #include "libs/nuts_bolts.h"
 #include "GcodeDispatch.h"
+#include "modules/robot/Player.h" 
 
 GcodeDispatch::GcodeDispatch(){}
 
@@ -35,10 +36,11 @@ void GcodeDispatch::on_console_line_received(void * line){
         Gcode gcode = Gcode();
         gcode.command = possible_command;
         this->kernel->call_event(ON_GCODE_RECEIVED, &gcode ); 
-        this->kernel->serial->printf("ok\r\n");
+        //this->kernel->serial->printf("ok %d \r\n", this->kernel->player->queue.size());
         //Gcode* test = new Gcode(); 
-        //this->kernel->serial->printf("ok %p\r\n", test);
+        //this->kernel->serial->printf("ok %d %p\r\n", this->kernel->player->queue.size(), test);
         //delete test;
+        this->kernel->serial->printf("ok\r\n");
 
     // Ignore comments 
     }else if( first_char == ';' || first_char == '(' ){
index cc05402..09ab0f8 100644 (file)
@@ -12,6 +12,7 @@ using std::string;
 #include "libs/Kernel.h"
 #include "libs/nuts_bolts.h"
 #include "SerialConsole.h"
+#include "libs/RingBuffer.h"
 
 // Serial reading module
 // Treats every received line as a command and passes it ( via event call ) to the command dispatcher. 
@@ -35,25 +36,53 @@ void SerialConsole::on_serial_char_received(){
         char received = this->getc();
         //On newline, we have received a line, else concatenate in buffer
         if( received == '\r' ){ return; }
-        if( received == '\n' ){
-            this->line_received();
-            receive_buffer = "";
-        }else{
-            this->receive_buffer += received;                
-        }
-   }
+        //if( received == '\n' ){
+        //    this->line_received();
+        //    receive_buffer = "";
+        //}else{
+        //    this->receive_buffer += received;                
+        //}
+        this->buffer.push_back(received); 
+    }
 }
         
 // Call event when newline received, for other modules to read the line
 inline void SerialConsole::line_received(){
-  string new_string = this->receive_buffer;
-  this->received_lines.insert(this->received_lines.begin(),new_string);
+  //string new_string = this->receive_buffer;
+  //this->received_lines.insert(this->received_lines.begin(),new_string);
 }
 
 // Actual event calling must happen in the main loop because if it happens in the interrupt we will loose data
 void SerialConsole::on_main_loop(void * argument){
-    if( this->received_lines.size() < 1 ){ return; }
-    this->kernel->call_event(ON_CONSOLE_LINE_RECEIVED, &this->received_lines.back() ); 
-    this->received_lines.pop_back();
+    //if( this->received_lines.size() < 1 ){ 
+    //    return; 
+    //}
+    //this->kernel->call_event(ON_CONSOLE_LINE_RECEIVED, &this->received_lines.back() ); 
+    //this->received_lines.pop_back();
+    if( this->has_char('\n') ){
+        int index = 0;
+        string received;
+        while(1){
+           char c;
+           this->buffer.pop_front(c);
+           if( c == '\n' ){
+                //this->printf("received: <%s> \r\n", received.c_str() );
+                this->kernel->call_event(ON_CONSOLE_LINE_RECEIVED, &received ); 
+                return;
+            }else{
+                received += c;
+            }
+        }
+    }
 }
 
+bool SerialConsole::has_char(char letter){
+    int index = this->buffer.head;
+    while( index != this->buffer.tail ){
+        if( this->buffer.buffer[index] == letter ){
+            return true;
+        }
+        index = this->buffer.next_block_index(index);
+    }
+    return false;
+}
index 79be4cf..328776b 100644 (file)
@@ -15,6 +15,7 @@
 #include <string>
 using std::string;
 #include "SerialConsole.h"
+#include "libs/RingBuffer.h"
 
 #define baud_rate_setting_ckeckusm 10922
 
@@ -26,9 +27,12 @@ class SerialConsole : public Module, public Serial {
         void on_serial_char_received();
         void line_received();
         virtual void on_main_loop(void * argument);
+        bool has_char(char letter);
         
-        string receive_buffer;                 // Received chars are stored here until a newline character is received
-        vector<std::string> received_lines;    // Received lines are stored here until they are requested
+        //string receive_buffer;                 // Received chars are stored here until a newline character is received
+        //vector<std::string> received_lines;    // Received lines are stored here until they are requested
+        RingBuffer<char,256> buffer;             // Receive buffer
+
 };
 
 #endif
index 28d2471..a1e7030 100644 (file)
@@ -7,15 +7,47 @@ Gcode::Gcode(){}
 
 // Whether or not a Gcode has a letter
 bool Gcode::has_letter( char letter ){
-    return ( this->command.find( letter ) != string::npos );
+    //return ( this->command->find( letter ) != string::npos );
+    for (size_t i=0; i < this->command.length(); i++){
+        if( this->command.at(i) == letter ){
+            return true;
+        }
+    }
+    return false;
 }
 
 // Retrieve the value for a given letter
+//double Gcode::get_value_old( char letter ){
+//    size_t start = this->command.find(letter);
+//    size_t end =   this->command.find_first_not_of("1234567890.-", start+1);
+//    if( end == string::npos ){ end = this->command.length()+1; }
+//    string extracted = this->command.substr( start+1, end-start-1 );
+//    double value = atof(extracted.c_str());
+//    return value; 
+//}
+
+
+// Retrieve the value for a given letter
+// We don't use the high-level methods of std::string because they call malloc and it's very bad to do that inside of interrupts
 double Gcode::get_value( char letter ){
-    size_t start = this->command.find(letter);
-    size_t end =   this->command.find_first_not_of("1234567890.-", start+1);
-    if( end == string::npos ){ end = this->command.length()+1; }
-    string extracted = this->command.substr( start+1, end-start-1 );
-    double value = atof(extracted.c_str());
-    return value; 
+    __disable_irq();
+    for (size_t i=0; i <= this->command.length()-1; i++){
+         if( letter == this->command.at(i) ){
+            size_t beginning = i+1;
+            char buffer[20];
+            for(size_t j=beginning; j <= this->command.length(); j++){
+                char c;
+                if( j == this->command.length() ){ c = ';'; }else{ c = this->command.at(j); }
+                if( c != '.' && c != '-' && ( c < '0' || c > '9' ) ){
+                    buffer[j-beginning] = '\0';
+                    __enable_irq();
+                    return atof(buffer); 
+                }else{
+                    buffer[j-beginning] = c;
+                }
+            }
+         }
+    }
+    __enable_irq();
+    return 0; 
 }
index 82f98f8..fe7c777 100644 (file)
@@ -21,10 +21,13 @@ using std::string;
 Block::Block(){
     clear_vector(this->steps);
     this->times_taken = 0;   // 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.
+    this->is_ready = false;
+    this->initial_rate = -1;
+    this->final_rate = -1;
 }
 
 void Block::debug(Kernel* kernel){
-    kernel->serial->printf(" steps:%4d|%4d|%4d(max:%4d) nominal:r%10d/s%6.1f mm:%9.6f rdelta:%8d acc:%5d dec:%5d rates:%10d>%10d \r\n", this->steps[0], this->steps[1], this->steps[2], this->steps_event_count, this->nominal_rate, this->nominal_speed, this->millimeters, this->rate_delta, this->accelerate_until, this->decelerate_after, this->initial_rate, this->final_rate );
+    kernel->serial->printf("%p: steps:%4d|%4d|%4d(max:%4d) nominal:r%10d/s%6.1f mm:%9.6f rdelta:%8d acc:%5d dec:%5d rates:%10d>%10d taken:%d ready:%d \r\n", this, this->steps[0], this->steps[1], this->steps[2], this->steps_event_count, this->nominal_rate, this->nominal_speed, this->millimeters, this->rate_delta, this->accelerate_until, this->decelerate_after, this->initial_rate, this->final_rate, this->times_taken, this->is_ready );
 }
 
 
@@ -47,6 +50,7 @@ void Block::calculate_trapezoid( double entryfactor, double exitfactor ){
 
     this->initial_rate = ceil(this->nominal_rate * entryfactor);   // (step/min) 
     this->final_rate   = ceil(this->nominal_rate * exitfactor);    // (step/min)
+    //this->player->kernel->serial->printf("%p: r:%d \r\n", this, this->initial_rate); 
     double acceleration_per_minute = this->rate_delta * this->planner->kernel->stepper->acceleration_ticks_per_second * 60.0; 
     int accelerate_steps = ceil( this->estimate_acceleration_distance( this->initial_rate, this->nominal_rate, acceleration_per_minute ) );
     int decelerate_steps = ceil( this->estimate_acceleration_distance( this->nominal_rate, this->final_rate,  -acceleration_per_minute ) );
@@ -153,24 +157,33 @@ void Block::forward_pass(Block* previous, Block* next){
 
 // Gcodes are attached to their respective blocks so that on_gcode_execute can be called with it
 void Block::append_gcode(Gcode* gcode){
-   this->commands.push_back(gcode->command);
-   this->travel_distances.push_back(gcode->millimeters_of_travel);
+   //this->commands.push_back(gcode->command);
+   //this->travel_distances.push_back(gcode->millimeters_of_travel);
+   __disable_irq();
+   this->gcodes.push_back(*gcode);
+   __enable_irq();
 }
 
 // The attached gcodes are then poped and the on_gcode_execute event is called with them as a parameter
 void Block::pop_and_execute_gcode(Kernel* &kernel){
-    for(unsigned short index=0; index<this->commands.size(); index++){
-        string command = this->commands.at(index);
-        double distance = this->travel_distances.at(index);
-        Gcode gcode = Gcode();
-        gcode.command = command;
-        gcode.millimeters_of_travel = distance;
-        kernel->call_event(ON_GCODE_EXECUTE, &gcode ); 
+    Block* block = const_cast<Block*>(this);
+    //for(unsigned short index=0; index<block->commands.size(); index++){
+    //    Gcode gcode = Gcode();
+    //    gcode.command = block->commands.at(index);
+    //    gcode.millimeters_of_travel = block->travel_distances.at(index);
+    //    kernel->call_event(ON_GCODE_EXECUTE, &gcode ); 
+    //}
+    for(unsigned short index=0; index<block->gcodes.size(); index++){
+        //this->player->kernel->serial->printf("exec: block:%p gcode:%p command:%p \r\n", block, &(block->gcodes[index]), &(block->gcodes[index].command) );
+        //this->player->kernel->serial->printf("                        str:%s \r\n", block->gcodes[index].command.c_str() );
+        //wait(0.1);
+        kernel->call_event(ON_GCODE_EXECUTE, &(block->gcodes[index]));
     }
 }
 
 // Signal the player that this block is ready to be injected into the system
 void Block::ready(){
+    this->is_ready = true;
     this->player->new_block_added();
 }
 
@@ -184,14 +197,40 @@ void Block::release(){
     this->times_taken--;
     if( this->times_taken < 1 ){
         this->player->kernel->call_event(ON_BLOCK_END, this);
-        //player->kernel->serial->printf("gcodes: %d, dist: %f \r\n", this->commands.size(), this->millimeters );
         this->pop_and_execute_gcode(this->player->kernel);
         Player* player = this->player;
+
+        //this->player->kernel->serial->printf("a %d\r\n", this->player->queue.size() );
         if( player->queue.size() > 0 ){ 
             player->queue.delete_first();
         } 
-        player->current_block = NULL; 
-        player->pop_and_process_new_block();
+
+        //this->player->kernel->serial->printf("b %d %d\r\n", this->player->queue.size(), player->looking_for_new_block );
+        
+        if( player->looking_for_new_block == false ){
+            //player->pop_and_process_new_block(123);
+            if( player->queue.size() > 0 ){
+                Block* candidate =  player->queue.get_ref(0);
+                if( candidate->is_ready ){
+                    //candidate->debug(player->kernel);
+                    //this->player->kernel->serial->printf("c %d %d\r\n", this->player->queue.size(), player->looking_for_new_block );
+                    player->current_block = candidate;
+                    player->kernel->call_event(ON_BLOCK_BEGIN, player->current_block);
+                    if( player->current_block->times_taken < 1 ){
+                        player->current_block->release();
+                    }
+                }else{
+
+                    player->current_block = NULL;
+
+                } 
+            }else{
+                //player->current_block->debug(player->kernel);
+                //this->player->kernel->serial->printf("d %d %d\r\n", this->player->queue.size(), player->looking_for_new_block );
+                //wait(0.1);
+                player->current_block = NULL;
+            }
+        }
     }
 }
 
index df7cd20..e50f743 100644 (file)
@@ -39,6 +39,7 @@ class Block {
 
         vector<std::string> commands;
         vector<double> travel_distances;
+        vector<Gcode> gcodes;
         
         unsigned int   steps[3];           // Number of steps for each axis for this block
         unsigned int   steps_event_count;  // Steps for the longest axis
@@ -60,6 +61,8 @@ class Block {
         double max_entry_speed;
         Planner* planner;
         Player*  player;
+        
+        bool is_ready;
 
         short 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.
 
index 91394e6..fd17e06 100644 (file)
@@ -43,7 +43,7 @@ void Planner::append_block( int target[], double feed_rate, double distance, dou
     //if( target[ALPHA_STEPPER] == this->position[ALPHA_STEPPER] && target[BETA_STEPPER] == this->position[BETA_STEPPER] && target[GAMMA_STEPPER] == this->position[GAMMA_STEPPER] ){ this->computing = false; return; }
 
     // Stall here if the queue is ful
-    while( this->kernel->player->queue.size() >= this->kernel->player->queue.capacity() ){ wait_us(100); }
+    while( this->kernel->player->queue.size() >= this->kernel->player->queue.capacity()-2 ){ wait_us(100); }
 
     Block* block = this->kernel->player->new_block();
     block->planner = this;   
@@ -176,6 +176,7 @@ void Planner::append_block( int target[], double feed_rate, double distance, dou
 // 3. Recalculate trapezoids for all blocks.
 //
 void Planner::recalculate() {
+   //this->kernel->serial->printf("recalculate last: %p, queue size: %d \r\n", this->kernel->player->queue.get_ref( this->kernel->player->queue.size()-1  ), this->kernel->player->queue.size() );
    this->reverse_pass();
    this->forward_pass();
    this->recalculate_trapezoids();
@@ -204,24 +205,55 @@ void Planner::forward_pass() {
 // planner_recalculate() after updating the blocks. Any recalulate flagged junction will
 // compute the two adjacent trapezoids to the junction, since the junction speed corresponds
 // to exit speed and entry speed of one another.
+/*
 void Planner::recalculate_trapezoids() {
     // For each block
-    for( int index = 0; index <= this->kernel->player->queue.size()-1; index++ ){ // We skip the first one because we need a previous
-
-        if( this->kernel->player->queue.size()-1 == index ){ //last block
+    int size = this->kernel->player->queue.size(); 
+    for( int index = 0; index <= size-1; index++ ){ // We skip the first one because we need a previous
+        if( size-1 == index ){ //last block
             Block* last = this->kernel->player->queue.get_ref(index);
             last->calculate_trapezoid( last->entry_speed / last->nominal_speed, MINIMUM_PLANNER_SPEED / last->nominal_speed ); 
+            this->kernel->serial->printf("%p: %d/%d last r:%d \r\n", last, index, size-1,  last->initial_rate); 
         }else{
             Block* current = this->kernel->player->queue.get_ref(index);
             Block* next =    this->kernel->player->queue.get_ref(index+1);
             if( current->recalculate_flag || next->recalculate_flag ){
                 current->calculate_trapezoid( current->entry_speed/current->nominal_speed, next->entry_speed/current->nominal_speed );
                 current->recalculate_flag = false; // Reset current only to ensure next trapezoid is computed
+                this->kernel->serial->printf("%p: %d/%d other r:%d \r\n", current, index, size-1, current->initial_rate); 
+            }else{
+                this->kernel->serial->printf("%p: %d/%d else r:%d \r\n", current, index, size-1, current->initial_rate); 
             } 
         }
     }
 }
+*/
+void Planner::recalculate_trapezoids() {
+    int block_index = this->kernel->player->queue.head;
+    Block* current;
+    Block* next = NULL;
 
+    //this->kernel->serial->printf("tail:%d head:%d size:%d\r\n", this->kernel->player->queue.tail, this->kernel->player->queue.head, this->kernel->player->queue.size());
+
+    while(block_index != this->kernel->player->queue.tail){
+        current = next;
+        next = &this->kernel->player->queue.buffer[block_index];
+        //this->kernel->serial->printf("index:%d current:%p next:%p \r\n", block_index, current, next );
+        if( current ){
+            // Recalculate if current block entry or exit junction speed has changed.
+            if( current->recalculate_flag || next->recalculate_flag ){
+                current->calculate_trapezoid( current->entry_speed/current->nominal_speed, next->entry_speed/current->nominal_speed );
+                current->recalculate_flag = false;
+            }
+        }
+        block_index = this->kernel->player->queue.next_block_index( block_index ); 
+    }
+
+    // Last/newest block in buffer. Exit speed is set with MINIMUM_PLANNER_SPEED. Always recalculated.
+    next->calculate_trapezoid( next->entry_speed/next->nominal_speed, MINIMUM_PLANNER_SPEED/next->nominal_speed); //TODO: Make configuration option
+    next->recalculate_flag = false;
+
+}
 
 // Debug function
 void Planner::dump_queue(){
diff --git a/src/modules/robot/Player.cpp b/src/modules/robot/Player.cpp
new file mode 100644 (file)
index 0000000..1681837
--- /dev/null
@@ -0,0 +1,99 @@
+/*  
+      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/>. 
+*/
+
+using namespace std;
+#include <vector>
+#include "mbed.h"
+#include "libs/nuts_bolts.h"
+#include "libs/RingBuffer.h"
+#include "../communication/utils/Gcode.h"
+#include "libs/Module.h"
+#include "libs/Kernel.h"
+#include "Block.h"
+#include "Player.h"
+#include "Planner.h"
+
+Player::Player(){
+    this->current_block = NULL;
+    this->looking_for_new_block = false;
+}
+
+// Append a block to the list
+Block* Player::new_block(){
+
+    // Clean up the vector of commands in the block we are about to replace
+    // It is quite strange to do this here, we really should do it inside Block->pop_and_execute_gcode
+    // but that function is called inside an interrupt and thus can break everything if the interrupt was trigerred during a memory access
+    //Block* block = this->queue.get_ref( this->queue.size()-1 );
+    Block* block = this->queue.get_ref( this->queue.size() );
+    if( block->player == this ){
+        for(short index=0; index<block->gcodes.size(); index++){
+            block->gcodes.pop_back(); 
+        }     
+        //for(short index=0; index<block->commands.size(); index++){
+        //    block->commands.pop_back();
+        //    block->travel_distances.pop_back();
+        //}
+    }
+    
+    // Create a new virgin Block in the queue 
+    this->queue.push_back(Block());
+    block = this->queue.get_ref( this->queue.size()-1 );
+    block->is_ready = false;
+    block->initial_rate = -2;
+    block->final_rate = -2;
+    block->player = this;
+    
+    return block;
+}
+
+// Used by blocks to signal when they are ready to be used by the system
+void Player::new_block_added(){
+    //this->kernel->serial->printf("new block: %p\r\n", this->current_block);
+
+    //if( this->current_block == 0x00 || this->queue.size() == 0 ){
+        //this->kernel->serial->printf("f %p %d\r\n", this->current_block, this->queue.size() ); 
+    //}
+
+
+    if( this->current_block == NULL ){
+        this->pop_and_process_new_block(33);
+    }
+}
+
+// Process a new block in the queue
+void Player::pop_and_process_new_block(int debug){
+    if( this->looking_for_new_block ){ return; }
+    this->looking_for_new_block = true;
+
+    if( this->current_block != NULL ){ this->looking_for_new_block = false; return; }
+
+    // Return if queue is empty 
+    if( this->queue.size() == 0 ){
+        this->current_block = NULL; 
+        // TODO : ON_QUEUE_EMPTY event 
+        this->looking_for_new_block = false;
+        return; 
+    }
+    
+    // Get a new block
+    this->current_block = this->queue.get_ref(0);
+
+    // Tell all modules about it
+    this->kernel->call_event(ON_BLOCK_BEGIN, this->current_block);
+    
+    // In case the module was not taken
+    if( this->current_block->times_taken < 1 ){
+        //this->kernel->serial->printf("e %p %d %d %d\r\n", this->current_block, this->queue.size(), this->current_block == 0x00, debug ); 
+        //wait(0.1);
+        this->looking_for_new_block = false;
+        this->current_block->release();
+    }
+
+    this->looking_for_new_block = false;
+
+}
diff --git a/src/modules/robot/Player.h b/src/modules/robot/Player.h
new file mode 100644 (file)
index 0000000..dd5254a
--- /dev/null
@@ -0,0 +1,32 @@
+/*  
+      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 PLAYER_H
+#define PLAYER_H
+#include "libs/Module.h"
+#include "libs/Kernel.h"
+using namespace std;
+#include <string>
+#include <vector>
+
+class Player : public Module {
+    public:
+        Player();
+
+        Block* new_block();
+        void new_block_added();
+        void pop_and_process_new_block(int debug);
+
+        RingBuffer<Block,32> queue;  // Queue of Blocks
+        Block* current_block;
+        bool looking_for_new_block;
+
+};
+
+
+
+#endif
diff --git a/src/modules/robot/Player.o b/src/modules/robot/Player.o
new file mode 100644 (file)
index 0000000..d1037f7
Binary files /dev/null and b/src/modules/robot/Player.o differ
index 97a0a4d..272b523 100644 (file)
@@ -53,7 +53,6 @@ void Robot::on_gcode_received(void * argument){
     Gcode* gcode = static_cast<Gcode*>(argument);
     gcode->call_on_gcode_execute_event_immediatly = false; 
     gcode->on_gcode_execute_event_called = false;
-    
     //If the queue is empty, execute immediatly, otherwise attach to the last added block
     if( this->kernel->player->queue.size() == 0 ){
         gcode->call_on_gcode_execute_event_immediatly = true;
@@ -67,7 +66,6 @@ void Robot::on_gcode_received(void * argument){
         block->append_gcode(gcode);
     }
     
-
 }
 
 
@@ -117,6 +115,8 @@ void Robot::execute_gcode(Gcode* gcode){
             }
             break;
     }
+
+
     // As far as the parser is concerned, the position is now == target. In reality the
     // motion control system might still be processing the action and the real tool position
     // in any intermediate location.
index 95ff009..d6bbed5 100644 (file)
@@ -9,6 +9,7 @@
 #include "libs/Kernel.h"
 #include "Stepper.h"
 #include "Planner.h"
+#include "Player.h"
 #include "mbed.h"
 #include <vector>
 using namespace std;
@@ -41,7 +42,9 @@ void Stepper::on_module_loaded(){
     LPC_TIM0->MR0 = 10000;
     LPC_TIM0->MCR = 11; // for MR0 and MR1, with no reset at MR1
     NVIC_EnableIRQ(TIMER0_IRQn);
-    NVIC_SetPriority(TIMER3_IRQn, 1); 
+    NVIC_SetPriority(TIMER3_IRQn, 3); 
+    NVIC_SetPriority(TIMER0_IRQn, 2); 
+    NVIC_SetPriority(TIMER1_IRQn, 2); 
     LPC_TIM0->TCR = 1; 
     
     // Step and Dir pins as outputs
@@ -100,7 +103,7 @@ void Stepper::on_block_begin(void* argument){
     // The stepper does not care about 0-blocks
     if( block->millimeters == 0.0 ){ return; }
     
-    this->current_block = block;
+    //this->current_block = block;
 
     // Mark the new block as of interrest to us
     block->take();
@@ -177,6 +180,7 @@ inline void Stepper::main_interrupt(){
     }else{
         this->out_bits = 0;
     }
+
 }
 
 // We compute this here instead of each time in the interrupt
@@ -241,7 +245,19 @@ void Stepper::set_step_events_per_minute( double steps_per_minute ){
 
     // Set the Timer interval 
     LPC_TIM0->MR0 = floor( ( SystemCoreClock/4 ) / ( (steps_per_minute/60L) * speed_factor ) );
-    
+    if( LPC_TIM0->MR0 < 150 ){
+        LPC_TIM0->MR0 = 150;
+
+        this->kernel->serial->printf("tim0mr0: %d, steps_per minute: %f \r\n", LPC_TIM0->MR0, steps_per_minute ); 
+        //Block* block = new Block();
+        //this->kernel->serial->printf(":l queue:%d debug:%d cb:%p cb=null:%d mem:%p tc:%u mr0:%u mr1:%u \r\n",  this->kernel->player->queue.size() , this->kernel->debug, this->current_block, this->current_block == NULL, block, LPC_TIM0->TC , LPC_TIM0->MR0, LPC_TIM0->MR1  ); 
+        //delete block;
+        //this->kernel->serial->printf("mr0:%u, st/m:%f, sf:%f, bsf:%f \r\n", LPC_TIM0->MR0, steps_per_minute, speed_factor, this->base_stepping_frequency );
+        //this->current_block->debug(this->kernel);
+        //wait(0.1);
+    }   
+
+
     // In case we change the Match Register to a value the Timer Counter has past
     if( LPC_TIM0->TC >= LPC_TIM0->MR0 ){ LPC_TIM0->TCR = 3; LPC_TIM0->TCR = 1; }
 
index ac70dad..720fd28 100644 (file)
@@ -1,6 +1,7 @@
 #include "mbed.h"
 #include "libs/Module.h"
 #include "libs/Kernel.h"
+#include "modules/robot/Player.h"
 #include "modules/robot/Block.h"
 #include "modules/tools/extruder/Extruder.h"
 
@@ -62,7 +63,7 @@ void Extruder::on_config_reload(void* argument){
 void Extruder::on_gcode_execute(void* argument){
     Gcode* gcode = static_cast<Gcode*>(argument);
    
-    //this->kernel->serial->printf("gcode_exec: %s \r\n", gcode->command.c_str() );
+    //this->kernel->serial->printf("e: %s\r\n", gcode->command.c_str() );
 
     // Absolute/relative mode
     if( gcode->has_letter('M')){
@@ -86,9 +87,11 @@ void Extruder::on_gcode_execute(void* argument){
             // Extrusion length 
             if( gcode->has_letter('E' )){
                 double extrusion_distance = gcode->get_value('E');
+                //this->kernel->serial->printf("a extrusion_distance: %f, target_position: %f, new_extrusion_distance: %f, current_position: %f  \r\n", extrusion_distance, this->target_position, extrusion_distance - this->target_position, this->current_position );
                 if( this->absolute_mode == true ){ 
                     extrusion_distance = extrusion_distance - this->target_position;
                 }
+                //this->kernel->serial->printf("b extrusion_distance: %f, target_position: %f \r\n", extrusion_distance, this->target_position );
                 if( fabs(gcode->millimeters_of_travel) < 0.0001 ){
                     this->solo_mode = true;
                     this->travel_distance = extrusion_distance;
@@ -115,28 +118,20 @@ void Extruder::on_gcode_execute(void* argument){
 void Extruder::on_block_begin(void* argument){
     Block* block = static_cast<Block*>(argument);
 
-    //this->kernel->serial->printf("block_begin ");
-    //block->debug(this->kernel);
-
     if( fabs(this->travel_distance) > 0.001 ){
         block->take(); // In solo mode we take the block so we can move even if the stepper has nothing to do
         this->current_block = block; 
-        //this->kernel->serial->printf("before: start:%f target:%f current:%f\r\n", this->start_position, this->target_position, this->current_position);
         this->start_position = this->target_position;
         this->target_position = this->start_position + this->travel_distance ;
-        //this->kernel->serial->printf("after: start:%f target:%f current:%f\r\n", this->start_position, this->target_position, this->current_position);
+        //this->kernel->serial->printf("bb: target_position: %f, travel_distance:%f \r\n", this->target_position, this->travel_distance );
         this->on_speed_change(this);
     }   
     if( fabs(this->travel_ratio) > 0.001 ){
         // In non-solo mode, we just follow the stepper module
         this->current_block = block; 
-        //this->kernel->serial->printf("before: start:%f target:%f current:%f\r\n", this->start_position, this->target_position, this->current_position);
-        //this->kernel->serial->printf("a:direction: %d start:%f current: %f target: %f add:%f close:%f \r\n", this->direction, this->start_position, this->current_position, this->target_position,  (double(double(1)/double(1001)))*double(this->direction),  fabs( this->current_position - this->target_position )  );
         this->start_position = this->target_position;
         this->target_position =  this->start_position + ( this->current_block->millimeters * this->travel_ratio );
         this->on_speed_change(this);
-        //this->kernel->serial->printf("d:direction: %d start:%f current: %f target: %f add:%f close:%f \r\n", this->direction, this->start_position, this->current_position, this->target_position,  (double(double(1)/double(1001)))*double(this->direction),  fabs( this->current_position - this->target_position )  );
-        //this->kernel->serial->printf("after: start:%f target:%f current:%f\r\n", this->start_position, this->target_position, this->current_position);
     } 
 
 }
@@ -148,9 +143,6 @@ void Extruder::on_block_end(void* argument){
 
 void Extruder::on_speed_change(void* argument){
 
-
-    if( this->debug ){ this->kernel->serial->printf("back in event \r\n");wait(0.1);  }
-
     // Set direction
     if( this->target_position > this->current_position ){ 
         this->direction = 1;
@@ -159,98 +151,46 @@ void Extruder::on_speed_change(void* argument){
     }
 
     if( fabs(this->travel_ratio) > 0.001 ){
-
-        if( this->debug ){ 
-            this->kernel->serial->printf("back in if \r\n");
-            this->kernel->stepper->current_block->debug(this->kernel); 
-            wait(0.1);  
-        }
-
-        // Do not change rate if stepper rate is null
         if( this->kernel->stepper->current_block == NULL || fabs(this->kernel->stepper->trapezoid_adjusted_rate) < 0.0001 || this->kernel->stepper->current_block->nominal_rate == 0 ){
-                return;
-            }
-
-
-        if( this->debug ){ this->kernel->serial->printf("back in if2 \r\n");wait(0.1);  }
-
-        // Get a current/nominal rate ratio
-        if( fabs(this->kernel->stepper->current_block->nominal_rate) < 0.01 ){ 
-            wait(1);  
+            return;
         }
 
-
-        if( this->debug ){ this->kernel->serial->printf("back in if3 \r\n");wait(0.1);  }
-
+        // Get a current/nominal rate ratio
         double stepper_rate_ratio = this->kernel->stepper->trapezoid_adjusted_rate / double( this->kernel->stepper->current_block->nominal_rate ) ;
         // Get a nominal duration for this block
-
-        
-        if( this->debug ){ this->kernel->serial->printf("back in if4 \r\n");wait(0.1);  }
-        
         double nominal_duration =  this->kernel->stepper->current_block->millimeters / ( this->kernel->stepper->current_block->nominal_speed / 60 )  ;
-       
-        bool testo = false; 
-        if( this->debug ){ 
-            this->kernel->serial->printf("back in if5 \r\n");wait(0.1); 
-            this->debug_count--;
-            if( this->debug_count == 0 ){ 
-                this->debug = false; 
-            } 
-            testo = true;  
-        }
-        if( testo ){ this->kernel->serial->printf("back in if7 \r\n");wait(0.1);  }
-        
         // Get extrusion nominal speed
-        if( fabs(nominal_duration) < 0.001 || this->debug ){ 
-            this->kernel->serial->printf("start debugging, nominal_duration: %f \r\n", double(nominal_duration));
-            this->kernel->stepper->current_block->debug(this->kernel); 
-            this->debug = true;
-            this->debug_count = 5; 
-            wait(0.1);
-        }
-
-        if( testo ){ this->kernel->serial->printf("back in if8 \r\n");wait(0.1);  }
         double nominal_extrusion_speed = fabs( this->target_position - this->start_position ) / nominal_duration;
-        
-        
-        if( testo ){ this->kernel->serial->printf("back in if9 \r\n");wait(0.1);  }
-        if( this->debug ){ this->kernel->serial->printf("nom_extr_speed: %f \r\n", double(nominal_extrusion_speed));wait(0.1);  }
         // Get adjusted speed
         double adjusted_speed = nominal_extrusion_speed * stepper_rate_ratio;
 
-
-        if( testo ){ this->kernel->serial->printf("back in if10 \r\n");wait(0.1);  }
-
-        if( this->debug ){ this->kernel->serial->printf("adj_speed a: %f \r\n", double(adjusted_speed));wait(0.1);  }
-        //this->kernel->serial->printf("e:direction: %d start:%f current: %f target: %f add:%f close:%f \r\n", this->direction, this->start_position, this->current_position, this->target_position,  (double(double(1)/double(1001)))*double(this->direction),  fabs( this->current_position - this->target_position )  );
-        //this->kernel->serial->printf("speed change rate:%f/%u=%f dur:%f=%f/%f nom_extr_spd:%f/%f=%f adj_speed:%f \r\n", this->kernel->stepper->trapezoid_adjusted_rate, this->kernel->stepper->current_block->nominal_rate, stepper_rate_ratio, nominal_duration, this->kernel->stepper->current_block->millimeters, this->kernel->stepper->current_block->nominal_speed / 60, ( this->target_position - this->start_position ), nominal_duration, nominal_extrusion_speed, adjusted_speed  ); 
-
-
-        if( testo ){ this->kernel->serial->printf("back in if11 \r\n");wait(0.1);  }
-        if( this->debug ){ this->kernel->serial->printf("adj_speed b: %f \r\n", double(adjusted_speed));wait(0.1);  }
         // Set timer
-        LPC_TIM1->MR0 = ((SystemCoreClock/4))/int(floor(adjusted_speed*1000)); 
+        if((adjusted_speed*1400) < 1 ){ 
+            return; 
+        } 
+        LPC_TIM1->MR0 = ((SystemCoreClock/4))/(adjusted_speed*1700); 
+        if( LPC_TIM1->MR0 < 300 ){ 
+            this->kernel->serial->printf("tim1mr0 %d, adjusted_speed: %f\r\n", LPC_TIM1->MR0, adjusted_speed ); 
+            LPC_TIM1->MR0 = 300; 
+        }
 
-        if( testo ){ this->kernel->serial->printf("back in if12 \r\n");wait(0.1);  }
-        if( this->debug ){ this->kernel->serial->printf("adj_speed c: %f \r\n", double(adjusted_speed));wait(0.1);  }
         // In case we are trying to set the timer to a limit it has already past by
         if( LPC_TIM1->TC >= LPC_TIM1->MR0 ){
             LPC_TIM1->TCR = 3; 
             LPC_TIM1->TCR = 1; 
         }
-
+        
         // Update Timer1    
         LPC_TIM1->MR1 = (( SystemCoreClock/4 ) / 1000000 ) * this->microseconds_per_step_pulse;
 
-        if( testo ){ this->kernel->serial->printf("back in if13 \r\n");wait(0.1);  }
-        if( this->debug ){ this->kernel->serial->printf("adj_speed d: %f \r\n", double(adjusted_speed));wait(1);  }
+
     }
 
     if( fabs(this->travel_distance) > 0.001 ){
 
         // Set timer
-        LPC_TIM1->MR0 = ((SystemCoreClock/4))/int(floor(1000)); 
+        LPC_TIM1->MR0 = ((SystemCoreClock/4))/int(floor(1.2*1700)); 
 
         // In case we are trying to set the timer to a limit it has already past by
         if( LPC_TIM1->TC >= LPC_TIM1->MR0 ){
@@ -266,14 +206,11 @@ void Extruder::on_speed_change(void* argument){
 }
 
 
-
-
-
 inline void Extruder::stepping_tick(){
-    if( fabs( this->current_position - this->target_position ) >= 0.001 ){
-        //this->kernel->serial->printf("b:direction: %d start:%f current: %f target: %f add:%f close:%f \r\n", this->direction, this->start_position, this->current_position, this->target_position,  (double(double(1)/double(1001)))*double(this->direction),  fabs( this->current_position - this->target_position )  );
-        this->current_position += (double(double(1)/double(1000)))*double(this->direction);
-        //this->kernel->serial->printf("c:direction: %d start:%f current: %f target: %f add:%f close:%f \r\n", this->direction, this->start_position, this->current_position, this->target_position,  (double(double(1)/double(1001)))*double(this->direction),  fabs( this->current_position - this->target_position )  );
+
+    //if( fabs( this->current_position - this->target_position ) >= 0.001 ){
+    if( ( this->current_position < this->target_position && this->direction == 1 ) || ( this->current_position > this->target_position && this->direction == -1 ) ){    
+        this->current_position += (double(double(1)/double(1700)))*double(this->direction);
         this->dir_pin = ((this->direction > 0) ? 1 : 0);
         this->step_pin = 1;
     }else{