diff --git a/simulator/data_recorder.c b/simulator/data_recorder.c index c0d6170..75693ca 100644 --- a/simulator/data_recorder.c +++ b/simulator/data_recorder.c @@ -8,13 +8,22 @@ #include "simulator.h" #include "data_recorder.h" #include +#include #include static FILE *file; #define MAX_PINS 100 -static uint32_t values[MAX_PINS]; ///< Pin and value states +static int32_t values[MAX_PINS]; ///< Pin and value states static int pin_count; ///< Number of pins we emit +static void emit_log_data(void); + +static void recorder_close(int code, void*x ) { + // force last line to emit + emit_log_data(); + fflush(file); + fclose(file); +} void recorder_init(const char* filename) { sim_assert( ! file, "Recorder already initialized"); @@ -23,38 +32,47 @@ void recorder_init(const char* filename) { sim_assert(file, "record_init: failed to create file"); time_t t = time(NULL); - fprintf(file, "; Teacup_Firmware simulator data log on %s\n", - asctime(localtime(&t))); + fprintf(file, "# Teacup_Firmware simulator v1.0\n"); + fprintf(file, "# Recorded %s\n", asctime(localtime(&t))); fflush(file); + on_exit(recorder_close, NULL); } void add_trace_var(const char* name, int pin) { sim_assert(file, "add_trace_var: Recorder not initialized"); sim_assert(pin < MAX_PINS, "pin number invalid"); - fprintf(file, "; %d - %s\n", pin, name); + fprintf(file, "# %d - %s\n", pin, name); if (pin >= pin_count) pin_count = pin + 1; fflush(file); } -// Record a binary signal change -void record_pin(int pin, bool state, uint32_t t) { - if (state == values[pin]) return; - - sim_assert(file , "record_pin: Recorder not initialized"); - sim_assert(pin < MAX_PINS, "pin number invalid"); - - values[pin] = state; - +static uint64_t prev_t; +static void emit_log_data(void) { // Naive format: each line contains all values, beginning with the time - fprintf(file, "%u", t); + fprintf(file, "%lu", prev_t/1000); // microseconds for (int i = 0; i < pin_count; i++) fprintf(file, " %u", values[i]); fprintf(file, "\n"); fflush(file); } +// Record a value signal change +void record_pin(int pin, int32_t state, uint64_t t) { + if (state == values[pin] && t == prev_t ) return; + + sim_assert(file , "record_pin: Recorder not initialized"); + sim_assert(pin < MAX_PINS, "pin number invalid"); + + // Record previous state when new state value appears + if ( t != prev_t ) { + emit_log_data(); + } + prev_t = t; + values[pin] = state; +} + static char comment_buffer[300]; static int comment_buffer_index; void record_comment_stream(char ch) { @@ -75,6 +93,6 @@ void record_comment_stream(char ch) { } void record_comment(const char * msg) { - fprintf(file, "; %s\n", msg); + fprintf(file, "# %s\n", msg); fflush(file); } diff --git a/simulator/data_recorder.h b/simulator/data_recorder.h index 067cdb6..e2cccff 100644 --- a/simulator/data_recorder.h +++ b/simulator/data_recorder.h @@ -6,7 +6,7 @@ #define DATA_RECORDER_H_ void recorder_init(const char* filename); -void record_pin(int pin, bool state, uint32_t time); +void record_pin(int pin, int32_t state, uint64_t time); void add_trace_var(const char* name, int pin); void record_comment(const char * msg); void record_comment_stream(char ch); diff --git a/simulator/simulator.c b/simulator/simulator.c index ab05a22..09bc555 100644 --- a/simulator/simulator.c +++ b/simulator/simulator.c @@ -28,6 +28,12 @@ volatile uint8_t DIO3_WPORT, DIO4_WPORT; +#define AXES 4 +enum { + TRACE_POS = 0, /* 0..AXES-1 */ + TRACE_PINS = AXES, +}; + int g_argc; char** g_argv; void sim_start(int argc, char** argv) { @@ -40,7 +46,14 @@ void sim_start(int argc, char** argv) { recorder_init("datalog.out"); // Record pin names in datalog -#define NAME_PIN(x) add_trace_var(#x , x); +#define NAME_PIN_AXES(x) \ + add_trace_var(#x "_X" , TRACE_##x + 0); \ + add_trace_var(#x "_Y" , TRACE_##x + 1); \ + add_trace_var(#x "_Z" , TRACE_##x + 2); \ + add_trace_var(#x "_E" , TRACE_##x + 3); + NAME_PIN_AXES(POS); + +#define NAME_PIN(x) add_trace_var(#x , TRACE_PINS + x); NAME_PIN(X_STEP_PIN); NAME_PIN(X_DIR_PIN); NAME_PIN(X_MIN_PIN); @@ -58,11 +71,6 @@ void sim_start(int argc, char** argv) { NAME_PIN(E_ENABLE_PIN); NAME_PIN(STEPPER_ENABLE_PIN); - - NAME_PIN(SCK); - NAME_PIN(MOSI); - NAME_PIN(MISO); - NAME_PIN(SS); } /* -- debugging ------------------------------------------------------------ */ @@ -74,16 +82,26 @@ static void fbreset(void) { fputs("\033[m" , stdout); } static void bred(void) { fputs("\033[0;41m" , stdout); } -void sim_info(const char fmt[], ...) { - va_list ap; +static void vsim_info_cont(const char fmt[], va_list ap) { fgreen(); - va_start(ap, fmt); vprintf(fmt, ap); va_end(ap); - fputc('\n', stdout); fbreset(); } +static void sim_info_cont(const char fmt[], ...) { + va_list ap; + va_start(ap, fmt); + vsim_info_cont(fmt, ap); +} + +void sim_info(const char fmt[], ...) { + va_list ap; + va_start(ap, fmt); + vsim_info_cont(fmt, ap); + fputc('\n', stdout); +} + void sim_debug(const char fmt[], ...) { #ifdef SIM_DEBUG va_list ap; @@ -130,20 +148,29 @@ void cli(void) { sim_interrupts = false; } +/** Maximum time (ns) between steps which we still consider "movement" + * Must be less than 0x20000000, MAXINT/2 */ +#define MAX_IDLE_TIME_NS (2*1000*1000*1000) +#define NS_PER_SEC (1000*1000*1000) // Token for "1 billion" /* -- PIN I/O ------------------------------------------------------------ */ #define out true #define in false -static int x = 0, y = 0, z = 0, e = 0; +enum { X_AXIS, Y_AXIS, Z_AXIS, E_AXIS , AXIS_MAX , AXIS_NONE }; +static int pos[AXIS_MAX]; ///< Current position in steps static bool direction[PIN_NB]; static bool state[PIN_NB]; static void print_pos(void) { - printf("print_pos: %d, %d, %d, %d\n", x, y, z, e); - sim_info("x:%5d y:%5d z:%5d e:%5d", x, y, z, e); + char * axis = "xyze"; + int i; + for ( i = X_AXIS ; i < AXIS_MAX ; i++ ) { + sim_info_cont("%c:%5d ", axis[i], pos[i]); + } + sim_info(""); } bool READ(pin_t pin) { @@ -154,6 +181,7 @@ bool READ(pin_t pin) { void WRITE(pin_t pin, bool s) { bool old_state = state[pin]; + uint64_t nseconds = sim_runtime_ns(); sim_assert(pin < PIN_NB, "WRITE: Pin number out of range"); if (direction[pin] == out) { @@ -161,8 +189,7 @@ void WRITE(pin_t pin, bool s) { } if (old_state != s) { - uint32_t useconds = (uint32_t)sim_runtime_ns(); - record_pin(pin, s, useconds); + record_pin(TRACE_PINS + pin, s, nseconds); #ifdef TRACE_ALL_PINS fgreen(); for (int i = 0; i < PIN_NB; i++) { @@ -182,26 +209,33 @@ void WRITE(pin_t pin, bool s) { } if (s && !old_state) { /* rising edge */ + int axis = AXIS_NONE; + int dir; switch (pin) { case X_STEP_PIN: - x += state[X_DIR_PIN] ? 1 : -1; - print_pos(); + dir = state[X_DIR_PIN] ? 1 : -1; + axis = X_AXIS; break; case Y_STEP_PIN: - y += state[Y_DIR_PIN] ? 1 : -1; - print_pos(); + dir = state[Y_DIR_PIN] ? 1 : -1; + axis = Y_AXIS; break; case Z_STEP_PIN: - z += state[Z_DIR_PIN] ? 1 : -1; - print_pos(); + dir = state[Z_DIR_PIN] ? 1 : -1; + axis = Z_AXIS; break; case E_STEP_PIN: - e += state[E_DIR_PIN] ? 1 : -1; - print_pos(); + dir = state[E_DIR_PIN] ? 1 : -1; + axis = E_AXIS; break; default: break; } + if ( axis != AXIS_NONE ) { + pos[axis] += dir; + record_pin(TRACE_POS + axis, pos[axis], nseconds); + print_pos(); + } } } diff --git a/simulator/timer_ext.c b/simulator/timer_ext.c index 6911d22..d11f98c 100644 --- a/simulator/timer_ext.c +++ b/simulator/timer_ext.c @@ -95,7 +95,7 @@ static void timer1_isr(int cause, siginfo_t *HowCome, void *ucontext) { real / (avr?avr:1) ); printf("test: 10ms=%u 250ms=%u 1s=%u total=%luns actual=%luns\n", clock_counter_10ms, clock_counter_250ms, clock_counter_1s, - now - begin , now - then); + now - begin, now - then, sim_runtime_ns()); //printf(" timer1_isr tick_time=%04X now=%04X delta=%u total=%u\n", // TICK_TIME , now, now_us() - then, (now_us() - begin)/1000000 ) ; then = now;