diff --git a/.gitignore b/.gitignore
index 844cd7a..326f9fc 100644
--- a/.gitignore
+++ b/.gitignore
@@ -3,3 +3,5 @@
*.elf
*.DS_Store
*.d
+*~
+\#*\#
diff --git a/config.h b/config.h
index ccba270..6a1f77c 100644
--- a/config.h
+++ b/config.h
@@ -84,7 +84,7 @@
// parser state depending on user preferences.
#define N_STARTUP_LINE 2 // Integer (1-3)
-// Allows GRBL to tranck and report gcode line numbers. Enabling this means that the planning buffer
+// Allows GRBL to track and report gcode line numbers. Enabling this means that the planning buffer
// goes from 18 or 16 to make room for the additional line number data in the plan_block_t struct
// #define USE_LINE_NUMBERS // Disabled by default. Uncomment to enable.
diff --git a/coolant_control.c b/coolant_control.c
index 60cbf2f..3c1a681 100644
--- a/coolant_control.c
+++ b/coolant_control.c
@@ -46,7 +46,8 @@ void coolant_stop()
void coolant_run(uint8_t mode)
{
if (sys.state == STATE_CHECK_MODE) { return; }
-
+
+ protocol_auto_cycle_start();
protocol_buffer_synchronize(); // Ensure coolant turns on when specified in program.
if (mode == COOLANT_FLOOD_ENABLE) {
COOLANT_FLOOD_PORT |= (1 << COOLANT_FLOOD_BIT);
diff --git a/gcode.c b/gcode.c
index 8557956..cdef3ad 100644
--- a/gcode.c
+++ b/gcode.c
@@ -62,7 +62,7 @@ void gc_sync_position()
{
uint8_t i;
for (i=0; i.
-OBJECTS = main.o simulator.o runtime.o ../protocol.o ../planner.o ../settings.o ../print.o ../nuts_bolts.o eeprom.o serial.o avr/pgmspace.o avr/interrupt.o util/delay.o util/floatunsisf.o ../stepper.o ../gcode.o ../spindle_control.o ../motion_control.o ../limits.o ../report.o ../coolant_control.o
+PLATFORM = LINUX
+
+OBJECTS = main.o simulator.o serial.o ../main.o ../protocol.o ../planner.o ../settings.o ../print.o ../nuts_bolts.o eeprom.o ../serial.o avr/pgmspace.o avr/interrupt.o avr/io.o util/delay.o util/floatunsisf.o ../stepper.o ../gcode.o ../spindle_control.o ../motion_control.o ../limits.o ../report.o ../coolant_control.o ../probe.o ../system.o kbhit.o platform_$(PLATFORM).o
CLOCK = 16000000
EXE_NAME = grbl_sim.exe
-COMPILE = $(CC) -Wall -Os -DF_CPU=$(CLOCK) -include config.h -I.
-
+COMPILE = $(CC) -Wall -g -DF_CPU=$(CLOCK) -include config.h -I. -DPLAT_$(PLATFORM)
+LINUX_LIBRARIES = -lrt -pthread
# symbolic targets:
all: main
@@ -30,15 +32,18 @@ clean:
# file targets:
main: $(OBJECTS)
- $(COMPILE) -o $(EXE_NAME) $(OBJECTS) -lm
+ $(COMPILE) -o $(EXE_NAME) $(OBJECTS) -lm -lrt $($(PLATFORM)_LIBRARIES)
%.o: %.c
- $(COMPILE) -c $< -o $@
-
-../protocol.o: ../protocol.c
- $(COMPILE) -include rename_execute_runtime.h -c $< -o $@
+ $(COMPILE) -c $< -o $@
../planner.o: ../planner.c
$(COMPILE) -include planner_inject_accessors.c -c $< -o $@
+../serial.o: ../serial.c
+ $(COMPILE) -include serial_hooks.h -c $< -o $@
+
+../main.o: ../main.c
+ $(COMPILE) -include rename_main.h -c $< -o $@
+
diff --git a/sim/avr/interrupt.c b/sim/avr/interrupt.c
index 10b5225..2bcbe0d 100644
--- a/sim/avr/interrupt.c
+++ b/sim/avr/interrupt.c
@@ -21,23 +21,115 @@
*/
#include "interrupt.h"
+#include "io.h"
+
+//pseudo-Interrupt vector table
+isr_fp compa_vect[6]={0};
+isr_fp compb_vect[6]={0};
+isr_fp ovf_vect[6]={0};
+
+
+void sei() {io.sreg|=SEI;}
+void cli() {io.sreg&=~SEI;}
+
+
+
+int16_t sim_scaling[8]={0,1,8,64,256,1024,1,1}; //clock scalars
+//Timer/Counter modes: these are incomplete, but enough for this application
+enum sim_wgm_mode {
+ wgm_NORMAL,
+ wgm_CTC,
+ wgm_FAST_PWM,
+ wgm_PHASE_PWM,
+ wgm_PH_F_PWM,
+ wgm_RESERVED
+};
+
+enum sim_wgm_mode sim_wgm0[4] = {wgm_NORMAL,wgm_PHASE_PWM,wgm_CTC,wgm_FAST_PWM};
+enum sim_wgm_mode sim_wgmN[8] = {wgm_NORMAL,wgm_PHASE_PWM,wgm_PHASE_PWM,wgm_PH_F_PWM,
+ wgm_CTC, wgm_FAST_PWM, wgm_FAST_PWM, wgm_FAST_PWM};
+
+void timer_interrupts() {
+ int i;
+ uint8_t ien = io.sreg&SEI; //interrupts enabled?
+ io.prescaler++;
+
+ //all clocks
+ for (i=0;i<2;i++){
+
+ uint8_t cs = io.tccrb[i]&7; //clock select bits
+ int16_t increment = sim_scaling[cs];
+ //check scaling to see if timer fires
+ if (increment && (io.prescaler&(increment-1))==0) {
+
+ //select waveform generation mode
+ enum sim_wgm_mode mode;
+ if (i==0 || i==2) { //(T0 and T2 are different from rest)
+ uint8_t wgm = io.tccra[i]&3; //look at low 2 bits
+ mode = sim_wgm0[wgm];
+ }
+ else {
+ uint8_t wgm = ((io.tccrb[i]&8)>>1) | (io.tccra[i]&3); //only using 3 bits for now
+ mode = sim_wgmN[wgm];
+ }
+
+ //tick
+ io.tcnt[i]++;
+ //comparators
+ if ((io.timsk[i]&(1<
-
-// dummy register variables
-extern uint16_t timsk0;
-extern uint16_t timsk1;
-extern uint16_t timsk2;
-extern uint16_t tcnt0;
-extern uint16_t tcnt2;
-extern uint16_t tccr0b;
-extern uint16_t tccr0a;
-extern uint16_t tccr2a;
-extern uint16_t tccr2b;
-extern uint16_t tccr1b;
-extern uint16_t tccr1a;
-extern uint16_t ocr1a;
-extern uint16_t ocr2a;
-extern uint16_t pcmsk0;
-extern uint16_t pcicr;
-
// macros to turn avr interrupts into regular functions
-#define TIMER1_COMPA_vect
+//#define TIMER1_COMPA_vect
#define ISR(a) void interrupt_ ## a ()
-// enable interrupts does nothing in the simulation environment
+// Stub of the timer interrupt functions we need
+void interrupt_TIMER0_COMPA_vect();
+void interrupt_TIMER1_COMPA_vect();
+void interrupt_TIMER0_OVF_vect();
+void interrupt_SERIAL_UDRE();
+void interrupt_SERIAL_RX();
+
+
+//pseudo-Interrupt vector table
+typedef void(*isr_fp)(void);
+extern isr_fp compa_vect[6];
+extern isr_fp compb_vect[6];
+extern isr_fp ovf_vect[6];
+
+
+// enable interrupts now does something in the simulation environment
+#define SEI 0x80
void sei();
void cli();
-// dummy macros for interrupt related registers
-#define TIMSK0 timsk0
-#define TIMSK1 timsk1
-#define TIMSK2 timsk2
-#define OCR1A ocr1a
-#define OCR2A ocr2a
-#define OCIE1A 0
-#define OCIE2A 0
-#define TCNT0 tcnt0
-#define TCNT2 tcnt2
-#define TCCR0B tccr0b
-#define TCCR0A tccr0a
-#define TCCR1A tccr1a
-#define TCCR1B tccr1b
-#define TCCR2A tccr2a
-#define TCCR2B tccr2b
-#define CS21 0
-#define CS10 0
-#define WGM13 0
-#define WGM12 0
-#define WGM11 0
-#define WGM10 0
-#define WGM21 0
-#define COM1A0 0
-#define COM1B0 0
-#define TOIE0 0
-#define TOIE2 0
-#define PCICR pcicr
+//simulate timer operation
+void timer_interrupts();
+
+
#endif
diff --git a/sim/avr/io.c b/sim/avr/io.c
new file mode 100644
index 0000000..8290fec
--- /dev/null
+++ b/sim/avr/io.c
@@ -0,0 +1,4 @@
+#include "io.h"
+
+// dummy register variables
+volatile io_sim_t io={{0}};
diff --git a/sim/avr/io.h b/sim/avr/io.h
index 885021a..df8a515 100644
--- a/sim/avr/io.h
+++ b/sim/avr/io.h
@@ -1,5 +1,6 @@
/*
- io.h - dummy replacement for the avr include of the same name
+ interrupt.h - replacement for the avr include of the same name to provide
+ dummy register variables and macros
Part of Grbl Simulator
@@ -19,3 +20,182 @@
along with Grbl. If not, see .
*/
+
+#ifndef io_h
+#define io_h
+
+#include
+
+union hilo16 {
+ uint16_t w;
+ struct {
+ uint8_t l; //TODO: check that these are right order on x86. Doesn't matter for current usage, but might someday
+ uint8_t h;
+ };
+};
+
+enum {
+ SIM_A, SIM_B, SIM_C, SIM_D, SIM_E,
+ SIM_F, SIM_G, SIM_H, SIM_J, SIM_K, SIM_L,
+ SIM_PORT_COUNT
+};
+
+#define SIM_N_TIMERS 6
+
+
+// dummy register variables
+typedef struct io_sim {
+ uint8_t ddr[SIM_PORT_COUNT];
+ uint8_t port[SIM_PORT_COUNT];
+ uint8_t pin[SIM_PORT_COUNT];
+ uint8_t timsk[SIM_N_TIMERS];
+ uint16_t ocra[SIM_N_TIMERS];
+ uint16_t ocrb[SIM_N_TIMERS];
+ uint16_t ocrc[SIM_N_TIMERS];
+ uint16_t tcnt[SIM_N_TIMERS]; //tcint0 is really only 8bit
+ uint8_t tccra[SIM_N_TIMERS];
+ uint8_t tccrb[SIM_N_TIMERS];
+ uint8_t tifr[SIM_N_TIMERS];
+ uint8_t pcicr;
+ uint8_t pcmsk[3];
+ uint8_t ucsr0[3];
+ uint8_t udr[3];
+ union hilo16 ubrr0;
+
+ uint16_t prescaler; //continuously running
+ uint8_t sreg;
+
+
+} io_sim_t;
+volatile extern io_sim_t io;
+
+
+
+
+// dummy macros for interrupt related registers
+#define PORTA io.port[SIM_A]
+#define PORTB io.port[SIM_B]
+#define PORTC io.port[SIM_C]
+#define PORTD io.port[SIM_D]
+#define PORTE io.port[SIM_E]
+#define PORTF io.port[SIM_F]
+#define PORTG io.port[SIM_G]
+#define PORTH io.port[SIM_H]
+#define PORTJ io.port[SIM_J]
+#define PORTK io.port[SIM_K]
+#define PORTL io.port[SIM_L]
+
+#define DDRA io.ddr[SIM_A]
+#define DDRB io.ddr[SIM_B]
+#define DDRC io.ddr[SIM_C]
+#define DDRD io.ddr[SIM_D]
+#define DDRE io.ddr[SIM_E]
+#define DDRF io.ddr[SIM_F]
+#define DDRG io.ddr[SIM_G]
+#define DDRH io.ddr[SIM_H]
+#define DDRJ io.ddr[SIM_J]
+
+#define PINA io.pin[SIM_A]
+#define PINB io.pin[SIM_B]
+#define PINC io.pin[SIM_C]
+#define PIND io.pin[SIM_D]
+#define PINE io.pin[SIM_E]
+#define PINF io.pin[SIM_F]
+#define PING io.pin[SIM_G]
+#define PINH io.pin[SIM_H]
+#define PINJ io.pin[SIM_J]
+#define PINK io.pin[SIM_K]
+#define PINL io.pin[SIM_L]
+
+
+#define TIMSK0 io.timsk[0]
+#define TIMSK1 io.timsk[1]
+#define TIMSK2 io.timsk[2]
+#define TIMSK3 io.timsk[3]
+#define TIMSK4 io.timsk[4]
+#define TIMSK5 io.timsk[5]
+
+
+#define SIM_TOV 0
+#define SIM_OCA 1
+#define SIM_OCB 2
+#define SIM_OCC 3
+#define SIM_ICI 5
+
+#define OCIE0A SIM_OCA
+#define OCIE0B SIM_OCB
+#define TOIE0 SIM_TOV
+
+#define ICIE1 SIM_ICI
+#define OCIE1C SIM_OCC
+#define OCIE1B SIM_OCB
+#define OCIE1A SIM_OCA
+#define TOIE1 SIM_ICI
+
+#define ICIE2 SIM_ICI
+#define OCIE2C SIM_OCC
+#define OCIE2B SIM_OCB
+#define OCIE2A SIM_OCA
+#define TOIE2 SIM_TOV
+
+#define OCR0A io.ocra[0]
+#define OCR1A io.ocra[1]
+#define OCR2A io.ocra[2]
+ //There are more..
+
+
+#define TCNT0 io.tcnt[0]
+#define TCNT1 io.tcnt[1]
+#define TCNT2 io.tcnt[2]
+
+#define TCCR0B io.tccra[0]
+#define TCCR0A io.tccrb[0]
+#define TCCR1A io.tccra[1]
+#define TCCR1B io.tccrb[1]
+#define TCCR2A io.tccra[2]
+#define TCCR2B io.tccrb[2]
+
+#define CS00 0
+#define CS01 1
+#define CS12 2
+#define CS11 1
+#define CS10 0
+#define CS21 1
+
+#define WGM13 4
+#define WGM12 3
+#define WGM11 1
+#define WGM10 0
+#define WGM21 1
+
+#define COM1A1 7
+#define COM1A0 6
+#define COM1B1 5
+#define COM1B0 4
+#define COM1C1 3
+#define COM1C0 2
+
+
+#define PCICR io.pcicr
+#define PCIE0 0
+#define PCIE1 1
+
+//serial channel
+#define UCSR0A io.ucsr0[SIM_A]
+#define UCSR0B io.ucsr0[SIM_B]
+#define UDR0 io.udr[0]
+#define UDRIE0 0
+#define RXCIE0 1
+#define RXEN0 2
+#define TXEN0 3
+#define U2X0 4
+#define UBRR0H io.ubrr0.h
+#define UBRR0L io.ubrr0.l
+
+#define PCMSK0 io.pcmsk[0]
+#define PCMSK1 io.pcmsk[1]
+#define PCMSK2 io.pcmsk[2]
+
+
+
+#endif
diff --git a/sim/avr/wdt.h b/sim/avr/wdt.h
new file mode 100644
index 0000000..482f4fd
--- /dev/null
+++ b/sim/avr/wdt.h
@@ -0,0 +1 @@
+uint16_t wdt;
diff --git a/sim/config.h b/sim/config.h
index 404accd..5baa20c 100644
--- a/sim/config.h
+++ b/sim/config.h
@@ -24,94 +24,5 @@
#include "../config.h"
#include
-
-// dummy register variables implemented in simulator.c
-extern uint8_t stepping_ddr;
-extern uint8_t stepping_port;
-extern uint8_t spindle_ddr;
-extern uint8_t spindle_port;
-extern uint8_t limit_ddr;
-extern uint8_t limit_port;
-extern uint8_t limit_int_reg;
-extern uint8_t pinout_ddr;
-extern uint8_t pinout_port;
-extern uint8_t pinout_int_reg;
-extern uint8_t coolant_flood_ddr;
-extern uint8_t coolant_flood_port;
-
-// ReDefine pin-assignments
-#undef STEPPING_DDR
-#define STEPPING_DDR stepping_ddr
-#undef STEPPING_PORT
-#define STEPPING_PORT stepping_port
-#undef X_STEP_BIT
-#define X_STEP_BIT 2 // Uno Digital Pin 2
-#undef Y_STEP_BIT
-#define Y_STEP_BIT 3 // Uno Digital Pin 3
-#undef Z_STEP_BIT
-#define Z_STEP_BIT 4 // Uno Digital Pin 4
-#undef X_DIRECTION_BIT
-#define X_DIRECTION_BIT 5 // Uno Digital Pin 5
-#undef Y_DIRECTION_BIT
-#define Y_DIRECTION_BIT 6 // Uno Digital Pin 6
-#undef Z_DIRECTION_BIT
-#define Z_DIRECTION_BIT 7 // Uno Digital Pin 7
-
-#undef STEPPERS_DISABLE_DDR
-#define STEPPERS_DISABLE_DDR stepping_ddr
-#undef STEPPERS_DISABLE_PORT
-#define STEPPERS_DISABLE_PORT stepping_port
-#undef STEPPERS_DISABLE_BIT
-#define STEPPERS_DISABLE_BIT 0 // Uno Digital Pin 8
-
-#undef LIMIT_DDR
-#define LIMIT_DDR limit_ddr
-#undef LIMIT_PORT
-#define LIMIT_PORT limit_port
-#undef LIMIT_PIN
-#define LIMIT_PIN limit_port
-#undef X_LIMIT_BIT
-#define X_LIMIT_BIT 1 // Uno Digital Pin 9
-#undef Y_LIMIT_BIT
-#define Y_LIMIT_BIT 2 // Uno Digital Pin 10
-#undef Z_LIMIT_BIT
-#define Z_LIMIT_BIT 3 // Uno Digital Pin 11
-#undef LIMIT_INT
-#define LIMIT_INT 0
-#undef LIMIT_PCMSK
-#define LIMIT_PCMSK limit_int_reg
-
-#undef SPINDLE_ENABLE_DDR
-#define SPINDLE_ENABLE_DDR spindle_ddr
-#undef SPINDLE_ENABLE_PORT
-#define SPINDLE_ENABLE_PORT spindle_port
-#undef SPINDLE_ENABLE_BIT
-#define SPINDLE_ENABLE_BIT 4 // Uno Digital Pin 12
-
-#undef SPINDLE_DIRECTION_DDR
-#define SPINDLE_DIRECTION_DDR spindle_ddr
-#undef SPINDLE_DIRECTION_PORT
-#define SPINDLE_DIRECTION_PORT spindle_port
-#undef SPINDLE_DIRECTION_BIT
-#define SPINDLE_DIRECTION_BIT 5 // Uno Digital Pin 13
-
-#undef PINOUT_DDR
-#define PINOUT_DDR pinout_ddr
-#undef PINOUT_PORT
-#define PINOUT_PORT pinout_port
-#undef PINOUT_PIN
-#define PINOUT_PIN pinout_port
-#undef PINOUT_PCMSK
-#define PINOUT_PCMSK pinout_int_reg
-#undef PINOUT_INT
-#define PINOUT_INT 0
-
-#undef COOLANT_FLOOD_DDR
-#define COOLANT_FLOOD_DDR coolant_flood_ddr
-#undef COOLANT_FLOOD_PORT
-#define COOLANT_FLOOD_PORT coolant_flood_port
-#undef COOLANT_FLOOD_BIT
-#define COOLANT_FLOOD_BIT 0
-
-
+#define AUTO_REPORT_MOVE_DONE
#endif
diff --git a/sim/eeprom.c b/sim/eeprom.c
index 5c3c3f3..0291e85 100644
--- a/sim/eeprom.c
+++ b/sim/eeprom.c
@@ -21,18 +21,75 @@
*/
// These are never called in the simulator
+#include
+#define MAX_EEPROM_SIZE 4096 //4KB EEPROM in Mega
+
+
+FILE* eeprom_create_empty_file(){
+ FILE* fp = fopen("EEPROM.DAT","w+b");
+ int i;
+ if (fp){
+ for(i=0;i 0; size--) {
+ checksum = (checksum << 1) || (checksum >> 7);
+ checksum += *source;
+ eeprom_put_char(destination++, *(source++));
+ }
+ eeprom_put_char(destination, checksum);
}
int memcpy_from_eeprom_with_checksum(char *destination, unsigned int source, unsigned int size) {
- return 0;
+ unsigned char data, checksum = 0;
+ for(; size > 0; size--) {
+ data = eeprom_get_char(source++);
+ checksum = (checksum << 1) || (checksum >> 7);
+ checksum += data;
+ *(destination++) = data;
+ }
+ return(checksum == eeprom_get_char(source));
}
// end of file
diff --git a/sim/eeprom.h b/sim/eeprom.h
new file mode 100644
index 0000000..6b9a562
--- /dev/null
+++ b/sim/eeprom.h
@@ -0,0 +1,3 @@
+
+#include "../eeprom.h"
+void eeprom_close();
diff --git a/sim/kbhit.c b/sim/kbhit.c
new file mode 100644
index 0000000..7fc6e9e
--- /dev/null
+++ b/sim/kbhit.c
@@ -0,0 +1,6 @@
+#include
+#include
+
+#include "kbhit.h"
+
+
diff --git a/sim/runtime.c b/sim/kbhit.h
similarity index 50%
rename from sim/runtime.c
rename to sim/kbhit.h
index 1b38d6a..7ce1a91 100644
--- a/sim/runtime.c
+++ b/sim/kbhit.h
@@ -1,38 +1,39 @@
-/*
- runtime.c - replacement for the modul of the same name in grbl
- Run time commands are not processed in the simulator.
- Instead, the execute_runtime() is used as a hook to handle stepper simulation
- and printing of simulation results.
-
- Part of Grbl Simulator
-
- Copyright (c) 2012 Jens Geisler
-
- Grbl 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.
-
- Grbl 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 Grbl. If not, see .
-*/
-
-#include "simulator.h"
-#include
-
-void orig_protocol_execute_runtime(void);
-
-// replacement for original execute_runtime as a hook to print blocks as they are generated
-// and to control simulation of buffered blocks
-void protocol_execute_runtime(void) {
- orig_protocol_execute_runtime();
- //printf("printBlock():\n");
- printBlock();
- //printf("handle_buffer():\n");
- handle_buffer();
-}
+/*
+ kbhit.h - keyboard hit detection - used in serial port replacement for grbl sim
+
+ linux kbhit taken from http://cboard.cprogramming.com/c-programming/63166-kbhit-linux.html.
+ By 'thanatos':http://cboard.cprogramming.com/member.php?u=380
+
+ Part of Grbl Simulator
+
+ Copyright (c) 2014 Adam Shelly
+
+ Grbl 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.
+
+ Grbl 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 Grbl. If not, see .
+*/
+
+//if linux
+#include
+#include
+#include
+
+int kbhit(void);
+void enable_kbhit(int);
+
+
+//else
+//#include
+//#define enable_kbhit(e)
+//#define kbhit _kbhit
+//endif
+
diff --git a/sim/main.c b/sim/main.c
index d157ac3..e2a4e2e 100644
--- a/sim/main.c
+++ b/sim/main.c
@@ -34,18 +34,106 @@
#include "simulator.h"
+arg_vars_t args;
+const char* progname;
+
+int usage(const char* badarg){
+ if (badarg){
+ printf("Unrecognized option %s\n",badarg);
+ }
+ printf("Usage: \n"
+ "%s [options] [time_step] [block_file]\n"
+ " Options:\n"
+ " -r : minimum time step for printing stepper values. Default=0=no print.\n"
+ " -t