simulator: Add position to datalog.out
Cleanup datalog output a bit. * Add close/flush on exit in case we have pending data * Use hash for comment characters to be compatible with gnuplot * Report x/y/z/e position in array
This commit is contained in:
parent
1db17acc03
commit
cf015623e3
|
|
@ -8,13 +8,22 @@
|
||||||
#include "simulator.h"
|
#include "simulator.h"
|
||||||
#include "data_recorder.h"
|
#include "data_recorder.h"
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
#include <time.h>
|
#include <time.h>
|
||||||
|
|
||||||
static FILE *file;
|
static FILE *file;
|
||||||
|
|
||||||
#define MAX_PINS 100
|
#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 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) {
|
void recorder_init(const char* filename) {
|
||||||
sim_assert( ! file, "Recorder already initialized");
|
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");
|
sim_assert(file, "record_init: failed to create file");
|
||||||
|
|
||||||
time_t t = time(NULL);
|
time_t t = time(NULL);
|
||||||
fprintf(file, "; Teacup_Firmware simulator data log on %s\n",
|
fprintf(file, "# Teacup_Firmware simulator v1.0\n");
|
||||||
asctime(localtime(&t)));
|
fprintf(file, "# Recorded %s\n", asctime(localtime(&t)));
|
||||||
fflush(file);
|
fflush(file);
|
||||||
|
on_exit(recorder_close, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
void add_trace_var(const char* name, int pin) {
|
void add_trace_var(const char* name, int pin) {
|
||||||
sim_assert(file, "add_trace_var: Recorder not initialized");
|
sim_assert(file, "add_trace_var: Recorder not initialized");
|
||||||
sim_assert(pin < MAX_PINS, "pin number invalid");
|
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)
|
if (pin >= pin_count)
|
||||||
pin_count = pin + 1;
|
pin_count = pin + 1;
|
||||||
fflush(file);
|
fflush(file);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Record a binary signal change
|
static uint64_t prev_t;
|
||||||
void record_pin(int pin, bool state, uint32_t t) {
|
static void emit_log_data(void) {
|
||||||
if (state == values[pin]) return;
|
|
||||||
|
|
||||||
sim_assert(file , "record_pin: Recorder not initialized");
|
|
||||||
sim_assert(pin < MAX_PINS, "pin number invalid");
|
|
||||||
|
|
||||||
values[pin] = state;
|
|
||||||
|
|
||||||
// Naive format: each line contains all values, beginning with the time
|
// 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++)
|
for (int i = 0; i < pin_count; i++)
|
||||||
fprintf(file, " %u", values[i]);
|
fprintf(file, " %u", values[i]);
|
||||||
fprintf(file, "\n");
|
fprintf(file, "\n");
|
||||||
fflush(file);
|
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 char comment_buffer[300];
|
||||||
static int comment_buffer_index;
|
static int comment_buffer_index;
|
||||||
void record_comment_stream(char ch) {
|
void record_comment_stream(char ch) {
|
||||||
|
|
@ -75,6 +93,6 @@ void record_comment_stream(char ch) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void record_comment(const char * msg) {
|
void record_comment(const char * msg) {
|
||||||
fprintf(file, "; %s\n", msg);
|
fprintf(file, "# %s\n", msg);
|
||||||
fflush(file);
|
fflush(file);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -6,7 +6,7 @@
|
||||||
#define DATA_RECORDER_H_
|
#define DATA_RECORDER_H_
|
||||||
|
|
||||||
void recorder_init(const char* filename);
|
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 add_trace_var(const char* name, int pin);
|
||||||
void record_comment(const char * msg);
|
void record_comment(const char * msg);
|
||||||
void record_comment_stream(char ch);
|
void record_comment_stream(char ch);
|
||||||
|
|
|
||||||
|
|
@ -28,6 +28,12 @@ volatile uint8_t
|
||||||
DIO3_WPORT,
|
DIO3_WPORT,
|
||||||
DIO4_WPORT;
|
DIO4_WPORT;
|
||||||
|
|
||||||
|
#define AXES 4
|
||||||
|
enum {
|
||||||
|
TRACE_POS = 0, /* 0..AXES-1 */
|
||||||
|
TRACE_PINS = AXES,
|
||||||
|
};
|
||||||
|
|
||||||
int g_argc;
|
int g_argc;
|
||||||
char** g_argv;
|
char** g_argv;
|
||||||
void sim_start(int argc, char** argv) {
|
void sim_start(int argc, char** argv) {
|
||||||
|
|
@ -40,7 +46,14 @@ void sim_start(int argc, char** argv) {
|
||||||
recorder_init("datalog.out");
|
recorder_init("datalog.out");
|
||||||
|
|
||||||
// Record pin names in datalog
|
// 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_STEP_PIN);
|
||||||
NAME_PIN(X_DIR_PIN);
|
NAME_PIN(X_DIR_PIN);
|
||||||
NAME_PIN(X_MIN_PIN);
|
NAME_PIN(X_MIN_PIN);
|
||||||
|
|
@ -58,11 +71,6 @@ void sim_start(int argc, char** argv) {
|
||||||
NAME_PIN(E_ENABLE_PIN);
|
NAME_PIN(E_ENABLE_PIN);
|
||||||
|
|
||||||
NAME_PIN(STEPPER_ENABLE_PIN);
|
NAME_PIN(STEPPER_ENABLE_PIN);
|
||||||
|
|
||||||
NAME_PIN(SCK);
|
|
||||||
NAME_PIN(MOSI);
|
|
||||||
NAME_PIN(MISO);
|
|
||||||
NAME_PIN(SS);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* -- debugging ------------------------------------------------------------ */
|
/* -- debugging ------------------------------------------------------------ */
|
||||||
|
|
@ -74,16 +82,26 @@ static void fbreset(void) { fputs("\033[m" , stdout); }
|
||||||
|
|
||||||
static void bred(void) { fputs("\033[0;41m" , stdout); }
|
static void bred(void) { fputs("\033[0;41m" , stdout); }
|
||||||
|
|
||||||
void sim_info(const char fmt[], ...) {
|
static void vsim_info_cont(const char fmt[], va_list ap) {
|
||||||
va_list ap;
|
|
||||||
fgreen();
|
fgreen();
|
||||||
va_start(ap, fmt);
|
|
||||||
vprintf(fmt, ap);
|
vprintf(fmt, ap);
|
||||||
va_end(ap);
|
va_end(ap);
|
||||||
fputc('\n', stdout);
|
|
||||||
fbreset();
|
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[], ...) {
|
void sim_debug(const char fmt[], ...) {
|
||||||
#ifdef SIM_DEBUG
|
#ifdef SIM_DEBUG
|
||||||
va_list ap;
|
va_list ap;
|
||||||
|
|
@ -130,20 +148,29 @@ void cli(void) {
|
||||||
sim_interrupts = false;
|
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 ------------------------------------------------------------ */
|
/* -- PIN I/O ------------------------------------------------------------ */
|
||||||
|
|
||||||
#define out true
|
#define out true
|
||||||
#define in false
|
#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 direction[PIN_NB];
|
||||||
static bool state[PIN_NB];
|
static bool state[PIN_NB];
|
||||||
|
|
||||||
static void print_pos(void) {
|
static void print_pos(void) {
|
||||||
printf("print_pos: %d, %d, %d, %d\n", x, y, z, e);
|
char * axis = "xyze";
|
||||||
sim_info("x:%5d y:%5d z:%5d e:%5d", x, y, z, e);
|
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) {
|
bool READ(pin_t pin) {
|
||||||
|
|
@ -154,6 +181,7 @@ bool READ(pin_t pin) {
|
||||||
|
|
||||||
void WRITE(pin_t pin, bool s) {
|
void WRITE(pin_t pin, bool s) {
|
||||||
bool old_state = state[pin];
|
bool old_state = state[pin];
|
||||||
|
uint64_t nseconds = sim_runtime_ns();
|
||||||
sim_assert(pin < PIN_NB, "WRITE: Pin number out of range");
|
sim_assert(pin < PIN_NB, "WRITE: Pin number out of range");
|
||||||
|
|
||||||
if (direction[pin] == out) {
|
if (direction[pin] == out) {
|
||||||
|
|
@ -161,8 +189,7 @@ void WRITE(pin_t pin, bool s) {
|
||||||
}
|
}
|
||||||
|
|
||||||
if (old_state != s) {
|
if (old_state != s) {
|
||||||
uint32_t useconds = (uint32_t)sim_runtime_ns();
|
record_pin(TRACE_PINS + pin, s, nseconds);
|
||||||
record_pin(pin, s, useconds);
|
|
||||||
#ifdef TRACE_ALL_PINS
|
#ifdef TRACE_ALL_PINS
|
||||||
fgreen();
|
fgreen();
|
||||||
for (int i = 0; i < PIN_NB; i++) {
|
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 */
|
if (s && !old_state) { /* rising edge */
|
||||||
|
int axis = AXIS_NONE;
|
||||||
|
int dir;
|
||||||
switch (pin) {
|
switch (pin) {
|
||||||
case X_STEP_PIN:
|
case X_STEP_PIN:
|
||||||
x += state[X_DIR_PIN] ? 1 : -1;
|
dir = state[X_DIR_PIN] ? 1 : -1;
|
||||||
print_pos();
|
axis = X_AXIS;
|
||||||
break;
|
break;
|
||||||
case Y_STEP_PIN:
|
case Y_STEP_PIN:
|
||||||
y += state[Y_DIR_PIN] ? 1 : -1;
|
dir = state[Y_DIR_PIN] ? 1 : -1;
|
||||||
print_pos();
|
axis = Y_AXIS;
|
||||||
break;
|
break;
|
||||||
case Z_STEP_PIN:
|
case Z_STEP_PIN:
|
||||||
z += state[Z_DIR_PIN] ? 1 : -1;
|
dir = state[Z_DIR_PIN] ? 1 : -1;
|
||||||
print_pos();
|
axis = Z_AXIS;
|
||||||
break;
|
break;
|
||||||
case E_STEP_PIN:
|
case E_STEP_PIN:
|
||||||
e += state[E_DIR_PIN] ? 1 : -1;
|
dir = state[E_DIR_PIN] ? 1 : -1;
|
||||||
print_pos();
|
axis = E_AXIS;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
if ( axis != AXIS_NONE ) {
|
||||||
|
pos[axis] += dir;
|
||||||
|
record_pin(TRACE_POS + axis, pos[axis], nseconds);
|
||||||
|
print_pos();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -95,7 +95,7 @@ static void timer1_isr(int cause, siginfo_t *HowCome, void *ucontext) {
|
||||||
real / (avr?avr:1) );
|
real / (avr?avr:1) );
|
||||||
printf("test: 10ms=%u 250ms=%u 1s=%u total=%luns actual=%luns\n",
|
printf("test: 10ms=%u 250ms=%u 1s=%u total=%luns actual=%luns\n",
|
||||||
clock_counter_10ms, clock_counter_250ms, clock_counter_1s,
|
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",
|
//printf(" timer1_isr tick_time=%04X now=%04X delta=%u total=%u\n",
|
||||||
// TICK_TIME , now, now_us() - then, (now_us() - begin)/1000000 ) ;
|
// TICK_TIME , now, now_us() - then, (now_us() - begin)/1000000 ) ;
|
||||||
then = now;
|
then = now;
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue