This commit is contained in:
2024-12-22 05:22:46 +03:00
commit 1992e632d3
232 changed files with 20394 additions and 0 deletions

View File

@@ -0,0 +1,29 @@
all: compile test
DEV=ttyUSB0
test: M1.test M7.test
%.test:
MOTOR=$* ./seq_04.sh $(DEV)
MOTOR=$* ./seq_05.sh $(DEV)
MOTOR=$* ./seq_06.sh $(DEV)
MOTOR=$* ./seq_01a.sh $(DEV)
MOTOR=$* ./seq_01b.sh $(DEV)
MOTOR=$* ./seq_02.sh $(DEV)
MOTOR=$* ./seq_07a.sh $(DEV)
MOTOR=$* ./seq_07b.sh $(DEV)
MOTOR=$* ./seq_07c.sh $(DEV)
MOTOR=$* ./seq_03.sh $(DEV)
compile:
(cd ../../../pio_dirs/StepperDemo;rm -fR .pio; pio run -e esp32_V6_8_1 -t upload --upload-port /dev/$(DEV))
compile_idf4:
(cd ../../../pio_espidf/StepperDemo;rm -fR .pio; pio run -e esp32_idf_V5_3_0 -t upload --upload-port /dev/$(DEV))
compile_idf5:
(cd ../../../pio_espidf/StepperDemo;rm -fR .pio; pio run -e esp32_idf_V6_8_1 -t upload --upload-port /dev/$(DEV))
clean:
rm -f seq*.log

View File

@@ -0,0 +1,51 @@
BEGIN {
pass = 1
}
# This is for running motor
/^M[17]:/ {
api = substr($2,2)
pcnt = substr($3,2,length($3)-2)
if (pcnt < 0) {
if (api > 0) {
while (pcnt < 0) {
pcnt += 32767
}
}
}
api = api % 32767
delta = pcnt - api
if (api > pcnt) {
delta = api - pcnt
}
if ((delta > 66) && (delta < 32767-66)) {
print
print api, pcnt
pass = 0
print "FAIL HERE ^^^"
}
}
# This is for selected motor
/^>> M[17]:/ {
print
api = substr($3,2)
api = api % 32767
pcnt = substr($4,2,length($4)-2)
if (pcnt < 0) {
pcnt += 32767
}
if (api != pcnt) {
print api, pcnt
pass = 0
print "FAIL HERE ^^^"
}
}
END {
if (pass) {
print "PASS"
}
else {
print "FAIL"
}
}

View File

@@ -0,0 +1,34 @@
#!/bin/sh
TTY=${1:-ttyUSB0}
DEV="-d /dev/${TTY} -b 115200"
MOTOR=${MOTOR:-M1}
CMD="$MOTOR p7,-32767,32767 H25000 A10000 f w1000 X w100 pc R100 w100 W R1000 w1000 W "
PASS=">> $MOTOR: @1100 \\[1100\\]"
LOG="$0.log"
grabserial $DEV -c ' x reset ' -q "$MOTOR:" -e 10
sleep 2
grabserial $DEV -c "$CMD" -q "$PASS" -e 10 -o $LOG
echo
#if [ `gawk -f judge_pcnt_sync.awk $LOG | grep -c PASS` -ne 1 ]
#then
# grabserial $DEV -c 'r ' -q StepperDemo -e 1
# echo
# echo FAIL $0 pulse counter mismatch
# exit 1
#fi
if [ `grep -c "$PASS" $LOG` -eq 1 ]
then
echo PASS
else
grabserial $DEV -c ' r ' -q StepperDemo -e 1
echo
echo "FAIL $0 result pattern: $PASS"
exit 1
fi

View File

@@ -0,0 +1,34 @@
#!/bin/sh
TTY=${1:-ttyUSB0}
DEV="-d /dev/${TTY} -b 115200"
MOTOR=${MOTOR:-M1}
CMD="$MOTOR p7,-32767,32767 H25000 A10000 f w1000 X W pc R100 w100 W R1000 w1000 W "
PASS=">> $MOTOR: @1100 \\[1100\\]"
LOG="$0.log"
grabserial $DEV -c ' x reset ' -q "$MOTOR:" -e 10
sleep 2
grabserial $DEV -c "$CMD" -q "$PASS" -e 10 -o $LOG
echo
#if [ `gawk -f judge_pcnt_sync.awk $LOG | grep -c PASS` -ne 1 ]
#then
# grabserial $DEV -c 'r ' -q StepperDemo -e 1
# echo
# echo FAIL $0 pulse counter mismatch
# exit 1
#fi
if [ `grep -c "$PASS" $LOG` -eq 1 ]
then
echo PASS
else
grabserial $DEV -c ' r ' -q StepperDemo -e 1
echo
echo "FAIL $0 result pattern: $PASS"
exit 1
fi

View File

@@ -0,0 +1,34 @@
#!/bin/sh
TTY=${1:-ttyUSB0}
DEV="-d /dev/${TTY} -b 115200"
MOTOR=${MOTOR:-M1}
CMD="$MOTOR p7,-32767,32767 H25000 A10000 f w10 X W pc w 20 R1 W "
PASS=">> $MOTOR: @1 \\[1\\]"
LOG="$0.log"
grabserial $DEV -c ' x reset ' -q "$MOTOR:" -e 3
sleep 2
grabserial $DEV -c "$CMD" -q "$PASS" -e 10 -o $LOG
echo
#if [ `gawk -f judge_pcnt_sync.awk $LOG | grep -c PASS` -ne 1 ]
#then
# grabserial $DEV -c 'r ' -q StepperDemo -e 1
# echo
# echo FAIL $0 pulse counter mismatch
# exit 1
#fi
if [ `grep -c "$PASS" $LOG` -eq 1 ]
then
echo PASS
else
# grabserial $DEV -c ' r ' -q StepperDemo -e 1
echo
echo "FAIL $0 result pattern: $PASS"
exit 1
fi

View File

@@ -0,0 +1,32 @@
#!/bin/sh
TTY=${1:-ttyUSB0}
DEV="-d /dev/${TTY} -b 115200"
MOTOR=${MOTOR:-M1}
CMD="$MOTOR p7,-32767,32767 H30000 A100000 R30000 "
PASS=">> $MOTOR: @30000 \\[30000\\]"
LOG="$0.log"
grabserial $DEV -c ' x reset ' -q "$MOTOR:" -e 10
sleep 2
grabserial $DEV -c "$CMD" -q "$PASS" -e 3 -o $LOG
echo
if [ `gawk -f judge_pcnt_sync.awk $LOG | grep -c PASS` -ne 1 ]
then
grabserial $DEV -c 'r ' -q StepperDemo -e 1
echo
echo FAIL $0 pulse counter mismatch
exit 1
fi
if [ `grep -c "$PASS" $LOG` -eq 1 ]
then
echo PASS
else
grabserial $DEV -c ' r ' -q StepperDemo -e 1
echo
echo "FAIL $0 result pattern: $PASS"
exit 1
fi

View File

@@ -0,0 +1,43 @@
#!/bin/sh
TTY=${1:-ttyUSB0}
DEV="-d /dev/${TTY} -b 115200"
MOTOR=${MOTOR:-M1}
COMPLETE="test completed"
PASS="test passed"
MAX_RUN_S=300
# rmt has failed once 07, but repetitions are ok
for SEQ in 13 01 02 03 04 06 07 10 11
do
LOG="$0_$SEQ.log"
CMD="$MOTOR p7,-32767,32767 t $MOTOR $SEQ R "
echo "reset esp32"
grabserial $DEV -c ' x reset ' -q "$MOTOR:" -e 10
sleep 2
echo "send commands"
grabserial $DEV -c "$CMD" -q "$COMPLETE" -e $MAX_RUN_S -o $LOG
echo
if [ `gawk -f judge_pcnt_sync.awk $LOG | grep -c PASS` -ne 1 ]
then
grabserial $DEV -c 'r ' -q StepperDemo -e 1
echo
echo FAIL $0 pulse counter mismatch
echo "test sequence $SEQ"
exit 1
fi
if [ `grep -c "$PASS" $LOG` -eq 1 ]
then
echo PASS
else
grabserial $DEV -c ' x r ' -q StepperDemo -e 1
echo
echo "FAIL $0 result pattern: $PASS"
echo "test sequence $SEQ"
exit 1
fi
done

View File

@@ -0,0 +1,34 @@
#!/bin/sh
TTY=${1:-ttyUSB0}
DEV="-d /dev/${TTY} -b 115200"
MOTOR=${MOTOR:-M1}
CMD="$MOTOR p7,-32767,32767 H25000 A10000 R1 W "
PASS=">> $MOTOR: @1 \\[1\\]"
LOG="$0.log"
grabserial $DEV -c ' x reset ' -q "$MOTOR:" -e 10
sleep 2
grabserial $DEV -c "$CMD" -q "$PASS" -e 3 -o $LOG
echo
#if [ `gawk -f judge_pcnt_sync.awk $LOG | grep -c PASS` -ne 1 ]
#then
# grabserial $DEV -c 'r ' -q StepperDemo -e 1
# echo
# echo FAIL $0 pulse counter mismatch
# exit 1
#fi
if [ `grep -c "$PASS" $LOG` -eq 1 ]
then
echo PASS
else
grabserial $DEV -c ' r ' -q StepperDemo -e 1
echo
echo "FAIL $0 result pattern: $PASS"
exit 1
fi

View File

@@ -0,0 +1,34 @@
#!/bin/sh
TTY=${1:-ttyUSB0}
DEV="-d /dev/${TTY} -b 115200"
MOTOR=${MOTOR:-M1}
CMD="$MOTOR H25000 A10000 R1000 w200 X W p7,-32767,32767 ? R10 w1000 "
PASS=">> $MOTOR: @10 \\[10\\]"
LOG="$0.log"
grabserial $DEV -c ' x reset ' -q "$MOTOR:" -e 10
sleep 2
grabserial $DEV -c "$CMD" -q "$PASS" -e 3 -o $LOG
echo
#if [ `gawk -f judge_pcnt_sync.awk $LOG | grep -c PASS` -ne 1 ]
#then
# grabserial $DEV -c 'r ' -q StepperDemo -e 1
# echo
# echo FAIL $0 pulse counter mismatch
# exit 1
#fi
if [ `grep -c "$PASS" $LOG` -eq 1 ]
then
echo PASS
else
grabserial $DEV -c ' r ' -q StepperDemo -e 1
echo
echo "FAIL $0 result pattern: $PASS"
exit 1
fi

View File

@@ -0,0 +1,34 @@
#!/bin/sh
TTY=${1:-ttyUSB0}
DEV="-d /dev/${TTY} -b 115200"
MOTOR=${MOTOR:-M1}
CMD="$MOTOR p7,-32767,32767 V40 A1000000 R54 W "
PASS=">> $MOTOR: @54 \\[54\\]"
LOG="$0.log"
grabserial $DEV -c ' x reset ' -q "$MOTOR:" -e 10
sleep 2
grabserial $DEV -c "$CMD" -q "$PASS" -e 3 -o $LOG
echo
#if [ `gawk -f judge_pcnt_sync.awk $LOG | grep -c PASS` -ne 1 ]
#then
# grabserial $DEV -c 'r ' -q StepperDemo -e 1
# echo
# echo FAIL $0 pulse counter mismatch
# exit 1
#fi
if [ `grep -c "$PASS" $LOG` -eq 1 ]
then
echo PASS
else
grabserial $DEV -c ' r ' -q StepperDemo -e 1
echo
echo "FAIL $0 result pattern: $PASS"
exit 1
fi

View File

@@ -0,0 +1,34 @@
#!/bin/sh
TTY=${1:-ttyUSB0}
DEV="-d /dev/${TTY} -b 115200"
MOTOR=${MOTOR:-M1}
CMD="$MOTOR p7,-32767,32767 V40 A1000 R54 W R-54 W"
PASS=">> $MOTOR: @0 \\[0\\]"
LOG="$0.log"
grabserial $DEV -c ' x reset ' -q "$MOTOR:" -e 10
sleep 2
grabserial $DEV -c "$CMD" -q "$PASS" -e 3 -o $LOG
echo
#if [ `gawk -f judge_pcnt_sync.awk $LOG | grep -c PASS` -ne 1 ]
#then
# grabserial $DEV -c 'r ' -q StepperDemo -e 1
# echo
# echo FAIL $0 pulse counter mismatch
# exit 1
#fi
if [ `grep -c "$PASS" $LOG` -eq 1 ]
then
echo PASS
else
grabserial $DEV -c ' r ' -q StepperDemo -e 1
echo
echo "FAIL $0 result pattern: $PASS"
exit 1
fi

View File

@@ -0,0 +1,34 @@
#!/bin/sh
TTY=${1:-ttyUSB0}
DEV="-d /dev/${TTY} -b 115200"
MOTOR=${MOTOR:-M1}
CMD="$MOTOR p7,-32767,32767 V40 A1000 R20 W R-19 W"
PASS=">> $MOTOR: @1 \\[1\\]"
LOG="$0.log"
grabserial $DEV -c ' x reset ' -q "$MOTOR:" -e 10
sleep 2
grabserial $DEV -c "$CMD" -q "$PASS" -e 3 -o $LOG
echo
#if [ `gawk -f judge_pcnt_sync.awk $LOG | grep -c PASS` -ne 1 ]
#then
# grabserial $DEV -c 'r ' -q StepperDemo -e 1
# echo
# echo FAIL $0 pulse counter mismatch
# exit 1
#fi
if [ `grep -c "$PASS" $LOG` -eq 1 ]
then
echo PASS
else
grabserial $DEV -c ' r ' -q StepperDemo -e 1
echo
echo "FAIL $0 result pattern: $PASS"
exit 1
fi

View File

@@ -0,0 +1,34 @@
#!/bin/sh
TTY=${1:-ttyUSB0}
DEV="-d /dev/${TTY} -b 115200"
MOTOR=${MOTOR:-M1}
CMD="$MOTOR p7,-32767,32767 V40 A1000 R20 W "
PASS=">> $MOTOR: @20 \\[20\\]"
LOG="$0.log"
grabserial $DEV -c ' x reset ' -q "$MOTOR:" -e 10
sleep 2
grabserial $DEV -c "$CMD" -q "$PASS" -e 3 -o $LOG
echo
#if [ `gawk -f judge_pcnt_sync.awk $LOG | grep -c PASS` -ne 1 ]
#then
# grabserial $DEV -c 'r ' -q StepperDemo -e 1
# echo
# echo FAIL $0 pulse counter mismatch
# exit 1
#fi
if [ `grep -c "$PASS" $LOG` -eq 1 ]
then
echo PASS
else
grabserial $DEV -c ' r ' -q StepperDemo -e 1
echo
echo "FAIL $0 result pattern: $PASS"
exit 1
fi

View File

@@ -0,0 +1,33 @@
#!/bin/sh
DEV="-d /dev/ttyUSB0 -b 115200"
CMD="M1 p7,0,0 t M1 07 R "
PASS="Test passed"
MAX_RUN_S=10
LOG="$0.log"
grabserial $DEV -c 'reset ' -q "M1:" -e 10
sleep 2
grabserial $DEV -c "$CMD" -q "$PASS" -e $MAX_RUN_S -o $LOG
echo
if [ `gawk -f judge_pcnt_sync.awk $LOG | grep -c PASS` -ne 1 ]
then
grabserial $DEV -c 'r ' -q StepperDemo -e 1
echo
echo FAIL $0 pulse counter mismatch
exit 1
fi
if [ `grep -c "$PASS" $LOG` -eq 1 ]
then
echo PASS
else
grabserial $DEV -c 'r ' -q StepperDemo -e 1
echo
echo "FAIL $0 result pattern: $PASS"
exit 1
fi

View File

@@ -0,0 +1,13 @@
#!/bin/sh
# arduino idf4 based test
make compile
make M1.test M7.test
# idf4 based test
make compile_idf4
make M1.test M7.test
# idf5 only rmt-module supporting 8 steppers
make compile_idf5
make M1.test

View File

@@ -0,0 +1,58 @@
PRJ_ROOT=$(shell git rev-parse --show-toplevel)
CFLAGS=-DTEST -Werror -g -I$(PRJ_ROOT)/src
CXXFLAGS=-DTEST -Werror -g -DF_CPU=16000000 -I$(PRJ_ROOT)/src
LDLIBS=-lm -lc
TESTS=$(basename $(wildcard test_??.cpp))
test: $(TESTS) pmf_test rmc_test
./rmc_test
./pmf_test
rm -f test.log
$(addsuffix >>test.log &&,$(addprefix ./,$(TESTS))) echo "All tests passed"
LIB_H=FastAccelStepper.h PoorManFloat.h StepperISR.h \
RampGenerator.h RampConstAcceleration.h RampCalculator.h \
fas_arch/common.h
LIB_O=FastAccelStepper.o PoorManFloat.o StepperISR_test.o \
RampGenerator.o RampConstAcceleration.o RampCalculator.o StepperISR.o
SRC_LIB_H=$(addprefix $(PRJ_ROOT)/src/,$(LIB_H))
test_%: test_%.o $(LIB_O)
gcc -o $@ $< $(LIB_O) $(LDLIBS)
test_%.o: test_%.cpp $(SRC_LIB_H) RampChecker.h stubs.h
g++ -c $(CXXFLAGS) -o $@ $<
pmf_test: pmf_test.o PoorManFloat.o
pmf_test.o: pmf_test.cpp $(PRJ_ROOT)/src/PoorManFloat.h stubs.h test_03.h
rmc_test: rmc_test.o PoorManFloat.o RampCalculator.o
rmc_test.o: rmc_test.cpp $(PRJ_ROOT)/src/PoorManFloat.h $(PRJ_ROOT)/src/RampCalculator.h stubs.h test_03.h
FastAccelStepper.o: $(PRJ_ROOT)/src/FastAccelStepper.cpp $(SRC_LIB_H)
$(COMPILE.cpp) $< -o $@
PoorManFloat.o: $(PRJ_ROOT)/src/PoorManFloat.cpp $(PRJ_ROOT)/src/PoorManFloat.h
$(COMPILE.cpp) $< -o $@
RampGenerator.o: $(PRJ_ROOT)/src/RampGenerator.cpp $(SRC_LIB_H)
$(COMPILE.cpp) $< -o $@
RampConstAcceleration.o: $(PRJ_ROOT)/src/RampConstAcceleration.cpp $(SRC_LIB_H)
$(COMPILE.cpp) $< -o $@
RampCalculator.o: $(PRJ_ROOT)/src/RampCalculator.cpp $(SRC_LIB_H)
$(COMPILE.cpp) $< -o $@
StepperISR.o: $(PRJ_ROOT)/src/StepperISR.cpp $(SRC_LIB_H)
$(COMPILE.cpp) $< -o $@
StepperISR_test.o: StepperISR_test.cpp $(SRC_LIB_H)
VERSION=$(shell git rev-parse --short HEAD)
clean:
rm -f *.o test_[0-9][0-9] *.gnuplot pmf_test rmc_test test.log

View File

@@ -0,0 +1,59 @@
#include <stdint.h>
#include "PoorManFloat.h"
//
// This file can be renamed to a .ino and compiled as sketch to be run on the
// target e.g. arduino nano.
//
#include <Arduino.h>
#ifdef SIMULATOR
#include <avr/sleep.h>
#endif
uint16_t error_cnt = 0;
char buffer[256];
#define trace(s) Serial.println(s)
#define xprintf(args...)
#define test(x, msg) \
if (!(x)) { \
error_cnt++; \
Serial.print("ERROR: "); \
Serial.println(__LINE__); \
};
#include "test_03.h"
void setup() {
Serial.begin(115200);
Serial.println("Start test...");
bool result = perform_test();
if (result) {
Serial.println("TEST PASSED");
} else {
Serial.print("TEST FAILED: ");
Serial.print(error_cnt);
Serial.println(" errors");
}
#ifdef SIMULATOR
// if result is Ok. Toggle port twice, otherwise once
#define PIN 10
#define DIRPIN 7
pinMode(DIRPIN, OUTPUT);
digitalWrite(DIRPIN, HIGH);
pinMode(PIN, OUTPUT);
digitalWrite(PIN, HIGH);
digitalWrite(PIN, LOW);
if (result) {
digitalWrite(PIN, HIGH);
digitalWrite(PIN, LOW);
}
delay(1000);
noInterrupts();
sleep_cpu();
#endif
}
void loop() {}

View File

@@ -0,0 +1,46 @@
Tests;
- test_01
check queue functionality
- test_02
checks ramp timing
- pmf_test
checks PoorManFloat implementation
- test_04
one test case with speed change during ramp
- test_05
check for move/moveTo while ramp is processing
Introduce concept of interrupt generation during noInterrupts call
- test_06
check for stop during move
- test_07
test case with varying speed
- test_08
ramp to max speed with step wise increased length
- test_09
simple test case for V30 A1000000 R53 W R53
- test_10
test case for V30 a17164 w2000 a-1000
- test 11
test case for M1 A1000 V10000 f w300 V100000 U
This is stuck in state RED.
Revised test: M1 A1000 V10000 P100 w300 V100000 U
- test 12
ramp up with 1 step/s^2 to 1000us/step
- test 13
tests with maximum high acceleration
- test 14
test case for issue #178: Speed jump instead of decrease

View File

@@ -0,0 +1,142 @@
#include <stdlib.h>
#include <string.h>
class RampChecker {
public:
uint64_t total_ticks;
uint32_t last_dt;
uint32_t min_dt;
bool increase_ok;
bool flat_ok;
bool decrease_ok;
bool first;
bool dir_high;
bool reversing_allowed;
uint32_t accelerate_till;
uint32_t coast_till;
uint32_t time_coasting;
uint32_t pos;
uint32_t ticks_since_last_step;
float avg_accel;
FILE *gp_file;
char filename[100];
void next_ramp() {
increase_ok = true;
decrease_ok = false;
last_dt = ~0;
min_dt = ~0;
first = true;
dir_high = true;
coast_till = 0;
time_coasting = 0;
accelerate_till = 0;
reversing_allowed = false;
}
RampChecker() {
ticks_since_last_step = 0;
avg_accel = 0;
gp_file = NULL;
total_ticks = 0;
pos = 0;
next_ramp();
}
void start_plot(char *fname) {
int n = strlen(fname) - 8; // remove .gnuplot
strncpy(filename, fname, n);
filename[n] = 0;
gp_file = fopen(fname, "w");
fprintf(gp_file, "$data <<EOF\n");
}
void finish_plot() {
if (gp_file != NULL) {
fprintf(gp_file, "EOF\n");
fprintf(gp_file, "set term pngcairo size 1600, 800\n");
fprintf(gp_file, "set output \"%s.png\"\n", filename);
fprintf(gp_file, "set multiplot layout 2,2\n");
fprintf(gp_file, "set title \"speed [steps/s] over time [s]\"\n");
fprintf(gp_file, "plot $data using 1:2 with lines notitle\n");
fprintf(gp_file, "set title \"speed [steps/s] over position\"\n");
fprintf(gp_file, "plot $data using 4:2 with lines notitle\n");
fprintf(gp_file, "set title \"position over time [s]\"\n");
fprintf(gp_file, "plot $data using 1:4 with lines notitle\n");
fprintf(gp_file,
"set title \"averaged (!) acceleration [steps/s*s] over time "
"[s]\"\n");
fprintf(gp_file, "plot $data using 1:5 with lines notitle\n");
//fprintf(gp_file, "pause -1\n");
fclose(gp_file);
gp_file = NULL;
}
}
void check_section(struct queue_entry *e) {
uint8_t steps = e->steps;
if (steps == 0) {
// Just a pause
if (ticks_since_last_step <= 0xffff0000) {
ticks_since_last_step += e->ticks;
}
total_ticks += e->ticks;
printf("process pause %d => %u\n", e->ticks, ticks_since_last_step);
return;
}
if (e->toggle_dir) {
assert(reversing_allowed);
dir_high = !dir_high;
increase_ok = true;
last_dt = ~0;
decrease_ok = false;
}
if (dir_high) {
pos += steps;
} else {
pos -= steps;
}
uint32_t curr_dt = ticks_since_last_step;
total_ticks += steps * e->ticks;
if (!first) {
min_dt = min(min_dt, curr_dt);
}
float accel = 0;
if (last_dt != ~0) {
accel = (16000000.0 / float(curr_dt) - 16000000.0 / float(last_dt)) /
(1.0 / 16000000.0 * float(steps * curr_dt));
avg_accel += (accel - avg_accel) / (steps * 20);
}
printf(
"process command in ramp checker @%.6fs: steps = %d last = %u current "
"= %u "
" min_dt "
"= %u accel=%.6f inc=%s dec=%s\n",
total_ticks / 16000000.0, steps, last_dt, curr_dt, min_dt, accel,
increase_ok ? "ALLOW" : "NO", decrease_ok ? "ALLOW" : "NO");
if (gp_file != NULL) {
fprintf(gp_file, "%.6f %.2f %d %d %f\n", total_ticks / 16000000.0,
16000000.0 / last_dt, last_dt, pos, avg_accel);
}
assert(first || (steps * curr_dt > 0));
if (last_dt > curr_dt) {
assert(increase_ok);
accelerate_till = total_ticks;
decrease_ok = true;
} else if (last_dt < curr_dt) {
if (increase_ok) {
coast_till = total_ticks - curr_dt;
}
assert(decrease_ok);
increase_ok = false;
} else {
time_coasting += steps * curr_dt;
}
if (!first) {
last_dt = curr_dt;
}
ticks_since_last_step = e->ticks;
first = false;
}
};

View File

@@ -0,0 +1,124 @@
#include <assert.h>
#include <stdio.h>
#include <stdlib.h>
#include "FastAccelStepper.h"
#include "StepperISR.h"
char TCCR1A;
char TCCR1B;
char TCCR1C;
char TIMSK1;
char TIFR1;
unsigned short OCR1A;
unsigned short OCR1B;
StepperQueue fas_queue[NUM_QUEUES];
void inject_fill_interrupt(int mark) {}
void noInterrupts() {}
void interrupts() {}
#include "RampChecker.h"
class FastAccelStepperTest {
public:
void init_queue() {
fas_queue[0].read_idx = 0;
fas_queue[1].read_idx = 0;
fas_queue[0].next_write_idx = 0;
fas_queue[1].next_write_idx = 0;
}
void ramp() {
init_queue();
FastAccelStepper s = FastAccelStepper();
s.init(NULL, 0, 0);
RampChecker rc = RampChecker();
assert(0 == s.getCurrentPosition());
assert(s.isQueueEmpty());
s.setSpeedInHz(36800);
s.setAcceleration(1000000);
s.fill_queue();
assert(s.isQueueEmpty());
float old_planned_time_in_buffer = 0;
char fname[100];
sprintf(fname, "test_15.gnuplot");
rc.start_plot(fname);
s.runForward();
int32_t wait_ticks = TICKS_PER_S / 10;
uint8_t state = 0;
for (int i = 0; i < 2000; i++) {
if ((state == 0) && (wait_ticks < rc.total_ticks)) {
printf("New move\n");
s.move(-100000);
wait_ticks += TICKS_PER_S / 10;
state += 1;
}
if ((state == 1) && (wait_ticks < rc.total_ticks)) {
printf("move with changed acceleration\n");
s.setAcceleration(5000);
s.move(100000);
wait_ticks += TICKS_PER_S / 10;
state += 1;
}
if ((state == 2) && (wait_ticks < rc.total_ticks)) {
printf("stop");
s.stopMove();
wait_ticks += 2 * TICKS_PER_S / 10;
state += 1;
}
if (true) {
printf(
"Loop %d: Queue read/write = %d/%d Target pos = %d, Queue End "
"pos = %d QueueEmpty=%s\n",
i, fas_queue[0].read_idx, fas_queue[0].next_write_idx,
s.targetPos(), s.getPositionAfterCommandsCompleted(),
s.isQueueEmpty() ? "yes" : "no");
}
if (!s.isRampGeneratorActive()) {
break;
}
s.fill_queue();
if ((state == 3) && (wait_ticks < rc.total_ticks)) {
break;
}
uint32_t from_dt = rc.total_ticks;
while (!s.isQueueEmpty()) {
rc.increase_ok = true;
rc.decrease_ok = true;
rc.check_section(
&fas_queue[0].entry[fas_queue[0].read_idx & QUEUE_LEN_MASK]);
fas_queue[0].read_idx++;
}
uint32_t to_dt = rc.total_ticks;
float planned_time = (to_dt - from_dt) * 1.0 / 16000000;
printf("planned time in buffer: %.6fs\n", planned_time);
// This must be ensured, so that the stepper does not run out of
// commands
assert((i == 0) || (old_planned_time_in_buffer > 0.005));
old_planned_time_in_buffer = planned_time;
// stop after
if (rc.total_ticks > TICKS_PER_S * 40) {
break;
}
}
rc.finish_plot();
// test(!s.isRampGeneratorActive(), "too many commands created");
test(s.getCurrentPosition() > 70000, "stepper runs too slow");
test(s.getCurrentPosition() < 80000, "stepper runs too fast");
printf("Total time %f\n", rc.total_ticks / 16000000.0);
#if (TEST_CREATE_QUEUE_CHECKSUM == 1)
printf("CHECKSUM for %d/%d/%d: %d\n", steps, travel_dt, accel, s.checksum);
#endif
}
};
int main() {
FastAccelStepperTest test;
test.ramp();
printf("TEST_15 PASSED\n");
return 0;
}

View File

@@ -0,0 +1,29 @@
#include <stdint.h>
#include "PoorManFloat.h"
//
// This file can be renamed to a .ino and compiled as sketch to be run on the
// target e.g. arduino nano.
//
#include <assert.h>
#include <stdio.h>
#include <stdlib.h>
#define trace puts
#define xprintf printf
#define test(x, msg) \
if (!(x)) { \
puts(msg); \
assert(false); \
};
unsigned int error_cnt = 0;
#include "test_03.h"
int main() {
if (perform_test()) {
xprintf("TEST_03 PASSED\n");
}
}

View File

@@ -0,0 +1,94 @@
#include <assert.h>
#include <math.h>
#include <stdio.h>
#include <stdlib.h>
#include "RampCalculator.h"
// Not a real test case
int main() {
uint32_t res;
// Calculation is pre_calc/sqrt(steps)
//
float ramp_acceleration = 10000.0;
uint32_t max_speed_in_ticks = 1600;
struct ramp_config_s c;
c.init();
c.parameters.setAcceleration(ramp_acceleration);
c.parameters.setSpeedInTicks(max_speed_in_ticks);
char fname[100];
snprintf(fname, 100, "ramp.gnuplot");
FILE *gp_file = fopen(fname, "w");
fprintf(gp_file, "$data <<EOF\n");
uint64_t sum_ticks = 0;
float old_speed = 0;
for (uint32_t s = 1; s <= c.max_ramp_up_steps; s++) {
uint32_t ticks = c.calculate_ticks(s);
sum_ticks += ticks;
float ideal_speed = float(sum_ticks) / 16000000.0 * ramp_acceleration;
uint32_t rs = c.calculate_ramp_steps(ticks);
uint32_t ticks_back = c.calculate_ticks(rs);
uint32_t err = rs >= s ? rs - s : s - rs;
uint32_t err_ticks =
ticks >= ticks_back ? ticks - ticks_back : ticks_back - ticks;
float speed = 16000000.0 / float(ticks);
float speed_back = 16000000.0 / float(ticks_back);
old_speed = speed;
float err_speed =
speed <= speed_back ? speed - speed_back : speed_back - speed;
printf("%d: %d %d %f %d delta=%d delta_ticks=%d speed=%f\n", s,
16000000 / ticks, ticks, float(sum_ticks) / 16000000.0, rs, err,
err_ticks, err_speed);
fprintf(gp_file, "%d %f %d %d %d %d %d %f %f\n", s,
float(sum_ticks) / 16000000.0, 16000000 / ticks, ticks, rs, err,
err_ticks, err_speed, ideal_speed);
}
fprintf(gp_file, "EOF\n");
// fprintf(gp_file, "plot $data using 2:3 with linespoints\n");
// fprintf(gp_file, "set terminal pngcairo size 1024,768\n");
// fprintf(gp_file, "set output \"ramp.png\"\n");
fprintf(gp_file, "set terminal qt\n");
fprintf(gp_file, "set term qt size 1024,768\n");
fprintf(gp_file,
"set multiplot title \"Acceleration=%f max speed=%d steps/s\" layout "
"2,2 columnsfirst margins 0.1,0.9,0.1,0.9 spacing 0.1 columnsfirst\n",
ramp_acceleration, 16000000 / max_speed_in_ticks);
fprintf(gp_file, "set xlabel \"ramp steps\"\n");
fprintf(gp_file, "set ylabel \"speed in steps/s\"\n");
fprintf(
gp_file,
"plot $data using 1:3 with line title \"step to speed dependency\"\n");
fprintf(gp_file, "set xlabel \"ramp steps\"\n");
fprintf(gp_file, "set ylabel \"recovered ramp steps\"\n");
fprintf(gp_file,
"plot $data using 1:5 with line title \"steps(speed(steps))\"\n");
fprintf(gp_file, "set xlabel \"time in s\"\n");
fprintf(gp_file, "set ylabel \"speed in steps/s\"\n");
fprintf(gp_file, "plot $data using 2:3 with line title \"speed over time\",");
fprintf(gp_file, " $data using 2:9 with line title \"ideal speed\"\n");
fprintf(gp_file, "set xlabel \"time in s\"\n");
fprintf(gp_file, "set ylabel \"speed error in steps/s\"\n");
fprintf(gp_file, "set yrange [-10:10]\n");
fprintf(
gp_file,
"plot $data using 2:8 with line title \"speed error on ramp change\",");
fprintf(
gp_file,
" $data using 2:($3-$9) with line title \"speed error to ideal\"\n");
fprintf(gp_file, "unset multiplot\n");
fprintf(gp_file, "pause -1\n");
fclose(gp_file);
// assert(false);
return 0;
}

View File

@@ -0,0 +1,41 @@
#ifndef STUBS_H
#define STUBS_H
#define PROGMEM
#define pgm_read_byte_near(x) (*(x))
// For inducing interrupts while testing
void noInterrupts();
void interrupts();
void inject_fill_interrupt(int mark);
#define _BV(x) 0
#define ISR(x) void x()
#define inline
#define micros() 0
#include <math.h>
#define abs(x) ((x) > 0 ? (x) : -(x))
#define min(a, b) ((a) > (b) ? (b) : (a))
#define max(a, b) ((a) > (b) ? (a) : (b))
#define digitalWrite(a, b) \
{}
#define pinMode(a, b) \
{}
extern char TCCR1A;
extern char TCCR1B;
extern char TCCR1C;
extern char TIMSK1;
extern char TIFR1;
extern unsigned short OCR1A;
extern unsigned short OCR1B;
#define test(x, msg) \
if (!(x)) { \
puts(msg); \
assert(false); \
};
#endif

View File

@@ -0,0 +1,118 @@
#include <assert.h>
#include <stdio.h>
#include <stdlib.h>
#include "FastAccelStepper.h"
#include "StepperISR.h"
char TCCR1A;
char TCCR1B;
char TCCR1C;
char TIMSK1;
char TIFR1;
unsigned short OCR1A;
unsigned short OCR1B;
StepperQueue fas_queue[NUM_QUEUES];
void inject_fill_interrupt(int mark) {}
void noInterrupts() {}
void interrupts() {}
void init_queue() {
fas_queue[0].read_idx = 0;
fas_queue[0].next_write_idx = 0;
fas_queue[1].read_idx = 0;
fas_queue[1].next_write_idx = 0;
}
void basic_test() {
puts("basic_test...");
init_queue();
FastAccelStepper s = FastAccelStepper();
assert(0 == s.getCurrentPosition());
assert(s.isQueueEmpty());
assert(s.isQueueEmpty());
struct stepper_command_s cmd = {
.ticks = 10000, .steps = 100, .count_up = true};
int res = s.addQueueEntry(&cmd);
assert(res == AQE_OK);
assert(!s.isQueueEmpty());
}
void queue_full() {
puts("queue_full...");
init_queue();
FastAccelStepper s = FastAccelStepper();
s.init(NULL, 0, 0);
assert(0 == s.getCurrentPosition());
assert(s.isQueueEmpty());
assert(s.isQueueEmpty());
printf("Queue read/write = %d/%d\n", fas_queue[0].read_idx,
fas_queue[0].next_write_idx);
struct stepper_command_s cmd = {
.ticks = 10000, .steps = 100, .count_up = true};
for (int i = 0; i < QUEUE_LEN - 1; i++) {
s.addQueueEntry(&cmd);
assert(!s.isQueueEmpty());
assert(!s.isQueueFull());
printf("Queue read/write = %d/%d\n", fas_queue[0].read_idx,
fas_queue[0].next_write_idx);
}
s.addQueueEntry(&cmd);
printf("Queue read/write = %d/%d\n", fas_queue[0].read_idx,
fas_queue[0].next_write_idx);
assert(!s.isQueueEmpty());
assert(s.isQueueFull());
puts("...done");
}
void queue_out_of_range() {
int8_t res;
puts("queue_out_of_range...");
init_queue();
FastAccelStepper s = FastAccelStepper();
s.init(NULL, 0, 0);
assert(s.isQueueEmpty());
assert(0 == s.getCurrentPosition());
assert(s.isQueueEmpty());
assert(s.isQueueEmpty());
uint16_t ticks = s.getMaxSpeedInTicks();
ticks = ticks - 1;
struct stepper_command_s cmd2 = {
.ticks = ticks, .steps = 255, .count_up = true};
res = s.addQueueEntry(&cmd2);
test(res == AQE_ERROR_TICKS_TOO_LOW, "Too low ticks should trigger an error");
assert(s.isQueueEmpty());
struct stepper_command_s cmd3 = {
.ticks = MIN_CMD_TICKS - 1, .steps = 1, .count_up = true};
res = s.addQueueEntry(&cmd3);
test(res == AQE_ERROR_TICKS_TOO_LOW,
"Too short command time should trigger an error");
assert(s.isQueueEmpty());
}
void end_pos_test() {
init_queue();
FastAccelStepper s = FastAccelStepper();
s.init(NULL, 0, 0);
assert(0 == s.getPositionAfterCommandsCompleted());
struct stepper_command_s cmd = {.ticks = 65535, .steps = 1, .count_up = true};
assert(AQE_OK == s.addQueueEntry(&cmd));
assert(1 == s.getPositionAfterCommandsCompleted());
}
int main() {
// assert(sizeof(struct queue_entry) == 6);
basic_test();
queue_out_of_range();
queue_full();
end_pos_test();
printf("TEST_01 PASSED\n");
}

View File

@@ -0,0 +1,307 @@
#include <assert.h>
#include <stdio.h>
#include <stdlib.h>
#include "FastAccelStepper.h"
#include "StepperISR.h"
char TCCR1A;
char TCCR1B;
char TCCR1C;
char TIMSK1;
char TIFR1;
unsigned short OCR1A;
unsigned short OCR1B;
StepperQueue fas_queue[NUM_QUEUES];
void inject_fill_interrupt(int mark) {}
void noInterrupts() {}
void interrupts() {}
#include "RampChecker.h"
class FastAccelStepperTest {
public:
void init_queue() {
fas_queue[0].read_idx = 0;
fas_queue[1].read_idx = 0;
fas_queue[0].next_write_idx = 0;
fas_queue[1].next_write_idx = 0;
}
void with_empty_queue() {
printf("Test with empty queue\n");
init_queue();
FastAccelStepper s = FastAccelStepper();
s.init(NULL, 0, 0);
RampChecker rc = RampChecker();
assert(0 == s.getCurrentPosition());
assert(s.isQueueEmpty());
s.setSpeedInUs(10000);
s.setAcceleration(100);
s.fill_queue();
assert(s.isQueueEmpty());
s.move(1000);
s.fill_queue();
assert(!s.isQueueEmpty());
for (int i = 0; i < 1000; i++) {
if (false) {
printf(
"Loop %d: Queue read/write = %d/%d Target pos = %d, Queue End "
"pos = %d QueueEmpty=%s\n",
i, fas_queue[0].read_idx, fas_queue[0].next_write_idx,
s.targetPos(), s.getPositionAfterCommandsCompleted(),
s.isQueueEmpty() ? "yes" : "no");
}
if (!s.isRampGeneratorActive()) {
break;
}
s.fill_queue();
while (!s.isQueueEmpty()) {
rc.check_section(
&fas_queue_A.entry[fas_queue[0].read_idx & QUEUE_LEN_MASK]);
fas_queue[0].read_idx++;
}
}
test(!s.isRampGeneratorActive(), "too many commands created");
printf("min_dt=%u\n", rc.min_dt);
test(rc.min_dt == 160000, "max speed not reached");
}
void with_pars(const char *name, int32_t steps, uint32_t travel_dt,
uint32_t accel, bool reach_max_speed, float min_time,
float max_time, float allowed_ramp_time_delta,
bool call_moveTo_repeatedly = false,
bool call_setAccelertion_repeatedly = false,
bool alternatingAccelerationValue = false,
bool reversing_allowed = false,
uint32_t linear_acceleration_steps = 0,
uint32_t jump_step = 0) {
printf("Test %s test_with_pars steps=%d travel_dt=%d accel=%d dir=%s\n",
name, steps, travel_dt, accel, reach_max_speed ? "CW" : "CCW");
init_queue();
FastAccelStepper s = FastAccelStepper();
s.init(NULL, 0, 0);
s.setDirectionPin(0);
RampChecker rc = RampChecker();
rc.reversing_allowed = reversing_allowed;
assert(0 == s.getCurrentPosition());
assert(s.isQueueEmpty());
assert(0 == s.setSpeedInUs(travel_dt));
s.setAcceleration(accel);
s.setLinearAcceleration(linear_acceleration_steps);
s.setJumpStart(jump_step);
s.fill_queue();
assert(s.isQueueEmpty());
s.move(steps);
s.fill_queue();
assert(!s.isQueueEmpty());
float old_planned_time_in_buffer = 0;
char fname[100];
snprintf(fname, 100, "test_02_%s.gnuplot", name);
rc.start_plot(fname);
for (int i = 0; i < steps * 100; i++) {
if (call_moveTo_repeatedly) {
s.moveTo(steps);
}
if (call_setAccelertion_repeatedly) {
if (alternatingAccelerationValue) {
s.setAcceleration(accel + (i & 1) * 100);
} else {
s.setAcceleration(accel);
}
}
if (true) {
printf(
"Loop %d: Queue read/write = %d/%d Target pos = %d, Queue End "
"pos = %d QueueEmpty=%s\n",
i, fas_queue[0].read_idx, fas_queue[0].next_write_idx,
s.targetPos(), s.getPositionAfterCommandsCompleted(),
s.isQueueEmpty() ? "yes" : "no");
}
if (!s.isRampGeneratorActive()) {
break;
}
s.fill_queue();
uint32_t from_dt = rc.total_ticks;
while (!s.isQueueEmpty()) {
rc.check_section(
&fas_queue_A.entry[fas_queue[0].read_idx & QUEUE_LEN_MASK]);
fas_queue[0].read_idx++;
}
uint32_t to_dt = rc.total_ticks;
float planned_time = (to_dt - from_dt) * 1.0 / 16000000;
printf("planned time in buffer: %.6fs (old=%.6fs)\n", planned_time,
old_planned_time_in_buffer);
// This must be ensured, so that the stepper does not run out of commands
assert((i == 0) || (old_planned_time_in_buffer > 0.005));
old_planned_time_in_buffer = planned_time;
}
// Empty the queue
while (!s.isQueueEmpty()) {
rc.check_section(
&fas_queue_A.entry[fas_queue[0].read_idx & QUEUE_LEN_MASK]);
fas_queue[0].read_idx++;
}
rc.finish_plot();
printf("TEST=%s\n", name);
test(!s.isRampGeneratorActive(), "too many commands created");
printf("Total time %f < %f < %f ?\n", min_time,
rc.total_ticks / 16000000.0, max_time);
test(rc.total_ticks / 16000000.0 > min_time, "ramp too fast");
test(rc.total_ticks / 16000000.0 < max_time, "ramp too slow");
if (reach_max_speed) {
printf("%d = %d ?\n", rc.min_dt, travel_dt * 16);
test(rc.min_dt == travel_dt * 16, "max speed not reached");
} else {
printf("%d > %d ?\n", rc.min_dt, travel_dt * 16);
test(rc.min_dt > travel_dt * 16, "max speed reached");
}
float up_time, down_time;
if (reach_max_speed) {
printf("Ramp time up/coast/down/total=");
up_time = 1.0 * rc.accelerate_till / 16000000.0;
down_time = (1.0 * rc.total_ticks - 1.0 * rc.coast_till) / 16000000.0;
printf(" %f", 1.0 * rc.accelerate_till / 16000000.0);
printf(" %f", 1.0 * (rc.coast_till - rc.accelerate_till) / 16000000.0);
printf(" %f", 1.0 * (rc.total_ticks - rc.coast_till) / 16000000.0);
printf(" %f\n", 1.0 * rc.total_ticks / 16000000.0);
assert(rc.total_ticks > rc.coast_till);
} else {
printf("Ramp time up/down/total =");
up_time = 1.0 * rc.accelerate_till / 16000000.0;
down_time =
(1.0 * rc.total_ticks - 1.0 * rc.accelerate_till) / 16000000.0;
printf(" %f", 1.0 * rc.accelerate_till / 16000000.0);
printf(" %f", 1.0 * (rc.total_ticks - rc.accelerate_till) / 16000000.0);
printf(" %f\n", 1.0 * rc.total_ticks / 16000000.0);
}
// turned off
// test(abs(up_time - down_time) <
// 0.5 * (up_time + down_time) * allowed_ramp_time_delta,
// "assymmetric ramp");
#if (TEST_CREATE_QUEUE_CHECKSUM == 1)
printf("CHECKSUM for %d/%d/%d: %d\n", steps, travel_dt, accel, s.checksum);
#endif
}
};
int main() {
FastAccelStepperTest test;
float nc = 0.0; // if new ramp calculation is enabled
test.with_empty_queue();
// steps ticks_us accel maxspeed min/max_total_time
// jumps in speed in real on esp32
test.with_pars("f1", 1000, 4300, 10000, true, 4.5 - 0.2, 4.5 + 0.2, 0.5, true,
true);
// ramp 2*2s, 2*200 steps, coasting: 9600steps, 48s
test.with_pars("f2", 10000, 5000, 100, true, 2 * 2.0 + 48.0 - 0.2 - 0.4 * nc,
2 * 2.0 + 48.0 + 0.2, 0.2);
// ramp 2*0.02s, 2*2 steps, coasting: 1596 steps, 7.98s
test.with_pars("f3", 1600, 5000, 10000, true, 7.94, 8.02, 0.2);
// ramp 2*0.2s, 2*20 steps, coasting: 1560 steps, 7.8s
test.with_pars("f4", 1600, 5000, 1000, true, 2 * 0.2 + 7.8 - 0.1,
2 * 0.2 + 7.8 + 0.1, 0.2);
// ramp 2*1s, 5000 steps, coasting: 5000steps, 0.5s
test.with_pars("f5", 15000, 100, 10000, true, 2 * 1.0 + 0.5 - 0.1,
2 * 1.0 + 0.5 + 0.1, 0.2);
// ramp 2*0.02s, 2*2 steps, coasting: 96steps, 0.48
test.with_pars("f6", 100, 5000, 10000, true, 2 * 0.02 + 0.48 - 0.02,
2 * 0.02 + 0.48 + 0.02, 0.2);
// ramp 2s, 20000 steps => only ramp 2*0.4s
test.with_pars("f7", 1600, 50, 10000, false, 2 * 0.4 - 0.02 - 0.4 * nc,
2 * 0.4 + 0.02, 0.2);
// ramp 2*4s, 2*8000 steps, coasting 112000steps, 28s
test.with_pars("f8", 128000, 250, 1000, true, 2 * 4.0 + 28.0 - 0.1 - 0.1 * nc,
2 * 4.0 + 28.0 + 0.1, 0.2);
// ramp 2*4s, 2*8000 steps, coasting 56000steps, 14s
test.with_pars("f9", 72000, 250, 1000, true, 2 * 4.0 + 14.0 - 0.1 - 0.1 * nc,
2 * 4.0 + 14.0 + 0.1, 0.2);
// ramp 2*4s, 2*8000 steps, coasting 28000steps, 7s
test.with_pars("f10", 44000, 250, 1000, true, 2 * 4.0 + 7.0 - 0.1 - 0.1 * nc,
2 * 4.0 + 7.0 + 0.1, 0.2);
// ramp 2*4s, 2*8000 steps, coasting 2steps, 0.0005s
// fails with 16030
test.with_pars("f11", 16040, 250, 1000, true, 2 * 4.0 + 0.0 - 0.1 - 0.1 * nc,
2 * 4.0 + 0.1 + 0.1, 0.2);
// ramp 2*50s => 2*1s
test.with_pars("f12", 1000, 20, 1000, false, 2 * 1.0 - 0.15, 2 * 1.0 + 0.1,
0.2);
// The following five ramps are too fast.
// The first step should come after ~0.6s and
// the second after 0.89s. Implementation issues first step immediately
// with pause to 2nd step of 0.36s (actually 0.315s).
// So the first steps are issued within 0.36s instead of 0.89s.
//
// The implementation issues in addition the last two steps with 0.315s pause
float rd = 0.7; // rd means ramp deviation
//
// ramp 2*50s, thus with 500steps max speed not reached. 250steps need 10s
test.with_pars("f13", 500, 4000, 5, false, 20.0 - rd - 0.1 - 1.4 * nc,
20.0 - rd + 0.2, 0.2);
test.with_pars("f14", 2000, 4000, 5, false, 40.0 - rd - 0.1 - 1.7 * nc,
40.0 - rd + 0.2, 0.2);
// ramp 2*50s with 2*6250 steps => 100 steps at max speed using 0.4s
test.with_pars("f15", 12600, 4000, 5, true, 100.0 + 0.4 - 0.3 - rd - 2.3 * nc,
100.0 + 0.4 - rd + 0.24, 0.2);
// ramp 2*50s with 2*6250 steps => 4000 steps at max speed using 16s
test.with_pars("f16", 16500, 4000, 5, true, 116.0 - 0.3 - rd - 2.2 * nc,
116.0 + 0.23 - rd, 0.2);
// slow ramp: 2*50steps, 2*10s
rd = 1.4;
test.with_pars("f17", 100, 40, 1, false, 20.0 - 0.1 - rd - 2.0 * nc,
20.0 + 0.1 - rd, 1.0);
// jumps in speed in real => WORKS NOW
test.with_pars("f18", 256000, 40, 5000, true, 15.2 - 0.1, 15.2 + 0.2, 0.2);
// ramp time 625s, 7812500 steps
// test.with_pars("f19", 2000000, 40, 40, false, 2*223.0, 2*223.0);
// name, steps, travel_dt, accel, reach_max_speed, min_time, max_time,
// allowed_ramp_time_delta slow ramp time Those are anomalies (see github
// issue #8) on avr, but not on PC
// test.with_pars("f20", 50000, 270000, 10, true, 62.0, 63.0, 1.0);
test.with_pars("f20", 10, 1000000, 1, true, 9.9, 10.1, 1.0);
// no ramp time, just constant run time
test.with_pars("f21", 15000, 4000, 100000, true, 50.9, 60.1, 0.1);
test.with_pars("f22", 14634, 4100, 100000, true, 50.9, 60.1, 0.1);
// single step
test.with_pars("f23", 1, 100, 1000, false, 0.02, 0.05, 0.1);
// try to identify issue #40
test.with_pars("f24a", 5000, 200, 9999, true, 1.48 + 0.1 * nc, 1.5 + 0.1 * nc,
0.1, true, true, false, true);
test.with_pars("f24b", 5000, 200, 9999, true, 1.48 - 0.04 * nc,
1.50 - 0.04 * nc, 0.1, false, false, false);
test.with_pars("f24c", 5000, 200, 9999, true, 1.48 - 0.04 * nc,
1.50 - 0.04 * nc, 0.1, false, false, true);
test.with_pars("f24d", 5000, 200, 9999, true, 1.48 - 0.04 * nc,
1.50 - 0.04 * nc, 0.1, true, false, true);
test.with_pars("f25", 1000, 40, 0x7fffffff, true, 0.039, 0.041, 0.1);
// very short ramp. detected by esp32_hw_based tests seq_06.sh
test.with_pars("seq_06.sh", 54, 40, 1000000, false, 0.012, 0.018, 0.1);
// ramp with jump start
test.with_pars("f5_jumpstart", 15000, 100, 10000, true, 2 * 1.0 + 0.0 - 0.1,
2 * 1.0 + 0.5 + 0.1, 0.2, false, false, false, false, 0, 100);
// ramp with linea acceleration
test.with_pars("f5_linear_a", 15000, 100, 10000, true, 3, 4, 0.2, false,
false, false, false, 1000);
printf("TEST_02 PASSED\n");
return 0;
}

View File

@@ -0,0 +1,438 @@
#include <math.h>
struct const_tab {
uint32_t val_nom;
uint32_t val_denom;
bool squared;
pmf_logarithmic c;
};
bool perform_test() {
#define NR_OF_CONSTANTS 13
static const struct const_tab constants[NR_OF_CONSTANTS] = {
{1, 1, false, PMF_CONST_1},
{16000000, 1, false, PMF_CONST_16E6},
{3, 2, false, PMF_CONST_3_DIV_2},
{500, 1, false, PMF_CONST_500},
{1000, 1, false, PMF_CONST_1000},
{2000, 1, false, PMF_CONST_2000},
{32000, 1, false, PMF_CONST_32000},
{11313708, 1, false, PMF_CONST_16E6_DIV_SQRT_OF_2},
{21000000, 1, false, PMF_CONST_21E6},
{42000, 1, false, PMF_CONST_42000},
// The additional 4000 to make the test case pass
{14849242 + 4000, 1, false, PMF_CONST_21E6_DIV_SQRT_OF_2},
{16000000, 2, true, PMF_CONST_128E12}, // (16e6)^2 / 2
{21000000, 2, true, PMF_CONST_2205E11} // (21e6)^2 / 2
};
uint16_t l1;
pmf_logarithmic p1;
trace("Check leading_zeros()");
for (int16_t x_8 = 0; x_8 <= 255; x_8++) {
uint8_t leading = leading_zeros(x_8);
test(x_8 < (1 << (8 - leading)), "leading zeros too much");
test(x_8 >= (0x80 >> leading), "leading zeros too less");
}
trace("Check conversion u8 <=> pmfl");
p1 = pmfl_from((uint8_t)1);
l1 = pmfl_to_u16(p1);
xprintf("%x %d\n", p1, l1);
test(p1 == 0x0000, "value 1");
test(l1 == 1, "value 1");
trace("Check conversion u8 <=> pmfl by shift 8bit");
for (uint8_t n = 1; n < 8; n++) {
uint8_t v = 1 << n;
p1 = pmfl_from((uint8_t)v);
l1 = pmfl_to_u16(p1);
xprintf("8bit: %x %d\n", p1, l1);
test(p1 == ((int16_t)n) << 9, "value");
test(l1 == v, "value");
}
trace("Check conversion u8 <=> pmfl by shift 16bit");
for (uint8_t n = 1; n < 16; n++) {
uint16_t v = 1 << n;
p1 = pmfl_from((uint16_t)v);
l1 = pmfl_to_u16(p1);
xprintf("16bit: %x %d\n", p1, l1);
test(p1 == ((int16_t)n) << 9, "value");
test(l1 == v, "value");
}
trace("Check conversion u8 <=> pmfl by shift 32bit");
for (uint8_t n = 1; n < 32; n++) {
uint32_t v = 1;
v <<= n;
p1 = pmfl_from((uint32_t)v);
uint32_t res = pmfl_to_u32(p1);
xprintf("32bit: %x %u\n", p1, res);
test(p1 == (((int16_t)n) << 9), "value");
test(res == v, "value");
}
trace("Check conversion u8 <=> pmfl for all values");
for (uint8_t x_8 = 255; x_8 > 0; x_8--) {
p1 = pmfl_from((uint8_t)x_8);
uint16_t res_16 = pmfl_to_u16(p1);
if (res_16 != x_8) {
xprintf("%u => %x => %u\n", x_8, p1, res_16);
}
test(res_16 == x_8, "conversion error from uint8_t and back to uint16_t");
}
for (uint8_t n = 1; n <= 8; n++) {
for (uint8_t x_8 = 255; x_8 > 0; x_8--) {
uint16_t x_16 = x_8;
x_16 <<= n;
p1 = pmfl_from((uint8_t)x_8);
p1 = pmfl_shl(p1, n);
uint16_t res_16 = pmfl_to_u16(p1);
uint16_t delta = x_16 - res_16;
if (res_16 > x_16) {
delta = res_16 - x_16;
}
uint16_t limit = 1;
limit <<= n - 1;
if (delta > limit) {
xprintf("%u: %u => %x => %u, shifted: %d\n", x_8, x_16, p1, res_16, n);
}
test(delta <= limit,
"conversion error from uint8_t and back to uint16_t with shift");
}
}
for (uint8_t n = 1; n <= 24; n++) {
for (uint8_t x_8 = 255; x_8 > 0; x_8--) {
uint32_t x_32 = x_8;
x_32 <<= n;
p1 = pmfl_from((uint8_t)x_8);
p1 = pmfl_shl(p1, n);
uint32_t res_32 = pmfl_to_u32(p1);
uint32_t delta = x_32 - res_32;
if (res_32 > x_32) {
delta = res_32 - x_32;
}
uint32_t limit = 1;
limit <<= n - 1;
if (delta > limit) {
xprintf("%u: %u => %x => %u, shifted: %d\n", x_8, x_32, p1, res_32, n);
}
test(delta <= limit,
"conversion error from uint8_t and back to uint32_t with shift");
}
}
trace("Check conversion u16 <=> pmfl");
uint16_t limit = 0x100;
uint16_t trigger_16 = 0x8000;
for (uint16_t x_16 = 0xffff; x_16 > 0; x_16--) {
if ((x_16 & trigger_16) == 0) {
limit >>= 1;
trigger_16 >>= 1;
}
pmf_logarithmic p = pmfl_from((uint16_t)x_16);
uint16_t res_16 = pmfl_to_u16(p);
uint16_t delta = x_16 - res_16;
if (res_16 > x_16) {
delta = res_16 - x_16;
}
if (delta > limit) {
xprintf("%x => %x => %x (limit=%x)\n", x_16, p, res_16, limit);
}
test(delta <= limit, "conversion error from uint16_t and back to uint16_t");
}
for (uint8_t n = 1; n <= 16; n++) {
uint32_t msb = 32768;
for (uint16_t x_16 = 65535; x_16 > 256; x_16--) {
if ((x_16 & msb) == 0) {
msb >>= 1;
}
uint32_t x_32 = x_16;
x_32 <<= n;
p1 = pmfl_from((uint16_t)x_16);
p1 = pmfl_shl(p1, n);
uint32_t res_32 = pmfl_to_u32(p1);
uint32_t delta = x_32 - res_32;
uint32_t limit = (msb << n) >> 8;
limit += limit >> 2;
if (res_32 > x_32) {
delta = res_32 - x_32;
}
if (delta > limit) {
xprintf("%u: %u => %x => %u, shifted: %d, delta: %d > %d\n", x_16, x_32,
p1, res_32, n, delta, limit);
}
test(delta <= limit,
"conversion error from uint16_t and back to uint32_t with shift");
}
}
p1 = pmfl_from((uint32_t)0x10000);
test(pmfl_to_u16(p1) == 0xffff, "wrong overflow 16bit");
p1 = pmfl_from((uint32_t)0x80000000);
p1 = pmfl_shl(p1, 1);
test(pmfl_to_u32(p1) == 0xffffffff, "wrong overflow 32bit");
#ifndef SIMULATOR
trace("Check conversion u32 <=> pmfl");
uint32_t trigger_32 = 0x80000000;
uint32_t delta_32 = 0x01000000;
for (uint32_t x_32 = 0xffffffff; x_32 > 0; x_32 -= delta_32) {
if ((x_32 & trigger_32) == 0) {
trigger_32 >>= 1;
delta_32 >>= 1;
if (delta_32 == 0) {
delta_32 = 1;
}
}
pmf_logarithmic px = pmfl_from((uint32_t)x_32);
uint32_t res_32 = pmfl_to_u32(px);
uint32_t delta = x_32 - res_32;
if (res_32 > x_32) {
delta = res_32 - x_32;
}
if (delta > delta_32 + 1) {
xprintf("%x => %x => %x (delta=%x > %x)\n", x_32, px, res_32, delta,
delta_32);
}
test(delta <= delta_32 + 1,
"conversion error from uint32_t and back to uint32_t");
}
trace("Check multiply");
for (int16_t sa = -40; sa <= 40; sa++) {
for (uint32_t a_32 = 1; a_32 <= 0x1ff; a_32++) {
for (uint32_t b_32 = 1; b_32 <= 0x1ff; b_32++) {
p1 = pmfl_from(a_32);
pmf_logarithmic p2 = pmfl_from(b_32);
if (sa > 0) {
p1 = pmfl_shl(p1, sa);
} else if (sa < 0) {
p1 = pmfl_shr(p1, -sa);
}
pmf_logarithmic p = pmfl_multiply(p1, p2);
if (sa > 0) {
p = pmfl_shr(p, sa);
} else if (sa < 0) {
p = pmfl_shl(p, -sa);
}
uint32_t res = pmfl_to_u32(p);
uint32_t real_res = a_32 * b_32;
uint32_t repr_real = pmfl_to_u32(pmfl_from(real_res));
uint32_t delta = res - repr_real;
if (res < repr_real) {
delta = repr_real - res;
}
uint32_t limit = real_res >> 7;
if (delta > limit) {
xprintf("%d*%d=%d ~ %d =?= %d, diff=%d\n", a_32, b_32, a_32 * b_32,
repr_real, res, (int32_t)res - (int32_t)repr_real);
}
test(delta <= limit, "pmfl_multiply error");
}
}
}
#endif
trace("Check pmf constants");
bool error = false;
for (uint8_t i = 0; i < NR_OF_CONSTANTS; i++) {
const struct const_tab *dut = &constants[i];
pmf_logarithmic val = pmfl_from(dut->val_nom);
if (dut->squared) {
val += val;
}
if (dut->val_denom > 1) {
pmf_logarithmic val_denom = pmfl_from(dut->val_denom);
val -= val_denom;
}
pmf_logarithmic c = dut->c;
if (c != val) {
xprintf("(%d/%d)^%d => %x != %x\n", dut->val_nom, dut->val_denom,
dut->squared ? 2 : 1, val, c);
error = true;
}
}
test(!error, "constants");
trace("Check rsqrt");
for (int16_t sa = -20; sa <= 20; sa++) {
for (uint32_t a_32 = 1; a_32 <= 0x1ff; a_32++) {
p1 = pmfl_from(a_32);
if (sa > 0) {
p1 = pmfl_shl(p1, sa);
} else if (sa < 0) {
p1 = pmfl_shr(p1, -sa);
}
pmf_logarithmic p = pmfl_rsqrt(p1);
pmf_logarithmic pe =
pmfl_multiply(p1, pmfl_multiply(p, p)); // sqrt not yet tested
// pe should be approximately 1
uint32_t res = pmfl_to_u32(pmfl_shl(pe, 16));
int32_t diff = (int32_t)res - 0x10000;
if (abs(diff) > 384) {
xprintf("a=%d pmfl(x)=%x pmfl(rsqrt(x))=%x pmfl(rsqrt(x)^2*x)=%x ",
a_32, p1, p, pe);
xprintf("shift=%d rsqrt(%d)^2*%d*0x10000=%x, diff=%d\n", sa, a_32, a_32,
res, diff);
}
test(abs(diff) <= 384, "rsqrt error");
}
}
trace("Check square");
for (int16_t sa = -20; sa <= 20; sa++) {
for (uint32_t a_32 = 1; a_32 <= 0x1ff; a_32++) {
p1 = pmfl_from(a_32);
if (sa > 0) {
p1 = pmfl_shl(p1, sa);
} else if (sa < 0) {
p1 = pmfl_shr(p1, -sa);
}
pmf_logarithmic p = pmfl_square(p1);
pmf_logarithmic pe = pmfl_multiply(p1, p1);
int32_t diff = (int32_t)p - (int32_t)pe;
if (diff > 1) { // square has better precision than multiply
xprintf("a=%d pmfl(x)=%x pmfl(square(x))=%x pmfl(x*x)=%x ", a_32, p1,
p, pe);
xprintf("shift=%d, diff=%d\n", sa, 0);
}
test(diff <= 1, "square error");
}
}
trace("Check reciprocal square");
for (int16_t sa = -20; sa <= 20; sa++) {
for (uint32_t a_32 = 1; a_32 <= 0x1ff; a_32++) {
p1 = pmfl_from(a_32);
if (sa > 0) {
p1 = pmfl_shl(p1, sa);
} else if (sa < 0) {
p1 = pmfl_shr(p1, -sa);
}
pmf_logarithmic p = pmfl_rsquare(p1);
pmf_logarithmic pe = pmfl_multiply(p, pmfl_square(p1));
// pe should be approximately 1
uint32_t res = pmfl_to_u32(pmfl_shl(pe, 16));
int32_t diff = (int32_t)res - 0x10000;
if (abs(diff) > 384) {
xprintf("a=%d pmfl(x)=%x pmfl(rsquare(x))=%x pmfl(rsquare(x)*x^2)=%x ",
a_32, p1, p, pe);
xprintf("shift=%d rsquare(%d)*%d^2*0x10000=%x, diff=%d\n", sa, a_32,
a_32, res, diff);
}
test(abs(diff) <= 384, "rsquare error");
}
}
trace("Check reciprocal");
for (int16_t sa = -20; sa <= 20; sa++) {
for (uint32_t a_32 = 1; a_32 <= 0x1ff; a_32++) {
p1 = pmfl_from(a_32);
if (sa > 0) {
p1 = pmfl_shl(p1, sa);
} else if (sa < 0) {
p1 = pmfl_shr(p1, -sa);
}
pmf_logarithmic p = pmfl_reciprocal(p1);
pmf_logarithmic pe = pmfl_multiply(p, p1);
// xe should be approximately 1
uint32_t res = pmfl_to_u32(pmfl_shl(pe, 16));
int32_t diff = (int32_t)res - 0x10000;
if (abs(diff) > 384) {
xprintf(
"a=%d pmfl(x)=%x pmfl(reciprocal(x))=%x pmfl(reciprocal(x)*x)=%x ",
a_32, p1, p, pe);
xprintf("shift=%d reciprocal(%d)*%d*0x10000=%x, diff=%d\n", sa, a_32,
a_32, res, diff);
}
test(abs(diff) <= 384, "reciprocal error");
}
}
trace("Check specific use cases");
pmf_logarithmic x, x1, x2;
x1 = pmfl_from((uint32_t)0x0ffff);
x2 = pmfl_from((uint32_t)0x10100);
x = pmfl_multiply(x1, x2);
unsigned long back = pmfl_to_u32(x);
test(back == 0xffffffff, "overflow not catched");
x1 = pmfl_from((uint32_t)0x5555);
x2 = pmfl_from((uint32_t)0x0055);
x = pmfl_divide(x1, x2);
back = pmfl_to_u32(x);
xprintf("%x/%x=%x (back=%ld)\n", x1, x2, x, back);
test(back == 0x0101, "wrong division");
x1 = pmfl_from((uint32_t)0xf455);
x2 = pmfl_from((uint32_t)0x0030);
x = pmfl_divide(x1, x2);
back = pmfl_to_u32(x);
back--; // result is too high by one
xprintf("%x/%x=%x (%ld) f455/0030=%d\n", x1, x2, x, back, 0xf455 / 0x30);
test((back * 0x0030) <= 0xf455, "wrong division 1");
test((back * 0x0031) > 0xf455, "wrong division 2");
x1 = pmfl_from((uint32_t)0xf4555);
x = pmfl_shl(x1, 4);
back = pmfl_to_u32(x);
xprintf("%x => %x (%lx)\n", x1, x, back);
test(back == 0xf44000, "wrong pmfl_shl");
x1 = pmfl_from((uint32_t)0xf4555);
x = pmfl_shr(x1, 4);
back = pmfl_to_u32(x);
xprintf("%x => %x (%lx)\n", x1, x, back);
test(back == 0xf440, "wrong pmfl_shr");
x1 = pmfl_from((uint32_t)250);
x2 = pmfl_from((uint32_t)10000);
x = pmfl_divide(x1, x2);
back = pmfl_to_u32(x);
xprintf("%x/%x=%x (%ld)\n", x1, x2, x, back);
test(back == 0, "pmfl_divide 1");
x = pmfl_multiply(x, x2);
back = pmfl_to_u32(x);
xprintf("%x/%x*%x=%x (%ld)\n", x1, x2, x2, x, back);
back--; // value is one too high
test(back == 249, "pmfl_divide 2");
x1 = pmfl_from((uint32_t)250);
x2 = pmfl_from((uint32_t)10000);
x = pmfl_divide(x1, x2);
back = pmfl_to_u32(x);
xprintf("%x/%x=%x (%ld)\n", x1, x2, x, back);
test(back == 0, "pmfl_divide");
x = pmfl_shl(x, 10);
back = pmfl_to_u32(x);
xprintf("pmfl_shl(%x/%x,10)=%x (%ld)\n", x1, x2, x, back);
test(back == 25, "pmfl_divide/pmfl_shl");
x1 = pmfl_from((uint32_t)1600);
x2 = pmfl_from((uint32_t)1000000);
x = pmfl_divide(x1, x2);
back = pmfl_to_u32(x);
xprintf("%x/%x=%x (%ld)\n", x1, x2, x, back);
test(back == 0, "pmfl_divide");
x = pmfl_shl(x, 20);
back = pmfl_to_u32(x);
xprintf("pmfl_shl(%x/%x,20)=%x (%ld)\n", x1, x2, x, back);
test(back + 2 == 1678, "pmfl_divide/pmfl_shl");
x = pmfl_shr(x, 20);
back = pmfl_to_u32(x);
xprintf("pmfl_shr(pmfl_shl(%x/%x,20),20)=%x (%ld)\n", x1, x2, x, back);
test(back == 0, "pmfl_divide/pmfl_shl");
x1 = pmf_logarithmic((uint32_t)1500);
x = pmfl_pow_div_3(x1);
xprintf("%d/3=%d\n", x1, x);
// +1 is deviation
test(x + 1 == 500, "pmfl_pow_div_3");
return (error_cnt == 0);
}

View File

@@ -0,0 +1,169 @@
#include <assert.h>
#include <stdio.h>
#include <stdlib.h>
#include "FastAccelStepper.h"
#include "StepperISR.h"
char TCCR1A;
char TCCR1B;
char TCCR1C;
char TIMSK1;
char TIFR1;
unsigned short OCR1A;
unsigned short OCR1B;
StepperQueue fas_queue[NUM_QUEUES];
void inject_fill_interrupt(int mark) {}
void noInterrupts() {}
void interrupts() {}
#include "RampChecker.h"
class FastAccelStepperTest {
public:
void init_queue() {
fas_queue[0].read_idx = 0;
fas_queue[1].read_idx = 0;
fas_queue[0].next_write_idx = 0;
fas_queue[1].next_write_idx = 0;
}
void speed_increase() {
puts("Test test_speed_increase");
init_queue();
FastAccelStepper s = FastAccelStepper();
s.init(NULL, 0, 0);
RampChecker rc = RampChecker();
assert(0 == s.getCurrentPosition());
int32_t steps = 10000;
// Increase speed to 400, then further to 300
// Identified bug was a fast jump to 300 without acceleration
assert(s.isQueueEmpty());
s.setSpeedInUs(400);
s.setAcceleration(1000);
s.fill_queue();
assert(s.isQueueEmpty());
s.move(steps);
s.fill_queue();
assert(!s.isQueueEmpty());
float old_planned_time_in_buffer = 0;
int speed_increased = false;
for (int i = 0; i < steps; i++) {
if (!speed_increased && (s.getCurrentPosition() >= 5000)) {
puts("Change speed");
s.fill_queue(); // ensure queue is not empty
speed_increased = true;
s.setSpeedInUs(300);
s.move(steps);
}
if (true) {
printf(
"Loop %d: Queue read/write = %d/%d Target pos = %d, Queue End "
"pos = %d QueueEmpty=%s\n",
i, fas_queue[0].read_idx, fas_queue[0].next_write_idx,
s.targetPos(), s.getPositionAfterCommandsCompleted(),
s.isQueueEmpty() ? "yes" : "no");
}
if (!s.isRampGeneratorActive()) {
break;
}
s.fill_queue();
uint32_t from_dt = rc.total_ticks;
while (!s.isQueueEmpty()) {
rc.check_section(
&fas_queue[0].entry[fas_queue[0].read_idx & QUEUE_LEN_MASK]);
fas_queue[0].read_idx++;
}
uint32_t to_dt = rc.total_ticks;
float planned_time = (to_dt - from_dt) * 1.0 / 16000000;
printf("planned time in buffer: %.6fs\n", planned_time);
// This must be ensured, so that the stepper does not run out of commands
assert((i == 0) || (old_planned_time_in_buffer > 0.005));
old_planned_time_in_buffer = planned_time;
}
test(!s.isRampGeneratorActive(), "too many commands created");
printf("Total time %f\n", rc.total_ticks / 16000000.0);
#if (TEST_CREATE_QUEUE_CHECKSUM == 1)
printf("CHECKSUM for %d/%d/%d: %d\n", steps, travel_dt, accel, s.checksum);
#endif
}
void speed_decrease() {
puts("Test test_speed_decrease");
init_queue();
FastAccelStepper s = FastAccelStepper();
s.init(NULL, 0, 0);
RampChecker rc = RampChecker();
assert(0 == s.getCurrentPosition());
int32_t steps = 10000;
// Increase speed to 400, then further to 300
// Identified bug was a fast jump to 300 without acceleration
assert(s.isQueueEmpty());
s.setSpeedInUs(400);
s.setAcceleration(1000);
s.fill_queue();
assert(s.isQueueEmpty());
s.move(steps);
s.fill_queue();
assert(!s.isQueueEmpty());
float old_planned_time_in_buffer = 0;
int speed_decreased = false;
uint32_t count_state_dec = 0;
for (int i = 0; i < steps; i++) {
if (!speed_decreased && (s.getCurrentPosition() >= 5000)) {
puts("Change speed");
s.fill_queue(); // ensure queue is not empty
speed_decreased = true;
s.setSpeedInUs(500);
s.move(steps);
}
if (true) {
printf(
"Loop %d: Queue read/write = %d/%d Target pos = %d, Queue End "
"pos = %d QueueEmpty=%s\n",
i, fas_queue[0].read_idx, fas_queue[0].next_write_idx,
s.targetPos(), s.getPositionAfterCommandsCompleted(),
s.isQueueEmpty() ? "yes" : "no");
}
if (!s.isRampGeneratorActive()) {
break;
}
s.fill_queue();
if ((s.rampState() & RAMP_STATE_MASK) == RAMP_STATE_DECELERATE) {
count_state_dec++;
}
uint32_t from_dt = rc.total_ticks;
while (!s.isQueueEmpty()) {
rc.check_section(
&fas_queue[0].entry[fas_queue[0].read_idx & QUEUE_LEN_MASK]);
fas_queue[0].read_idx++;
}
uint32_t to_dt = rc.total_ticks;
float planned_time = (to_dt - from_dt) * 1.0 / 16000000;
printf("planned time in buffer: %.6fs\n", planned_time);
// This must be ensured, so that the stepper does not run out of commands
assert((i == 0) || (old_planned_time_in_buffer > 0.005));
old_planned_time_in_buffer = planned_time;
}
test(!s.isRampGeneratorActive(), "too many commands created");
test(count_state_dec > 10, "no deceleration to new speed");
printf("Total time %f\n", rc.total_ticks / 16000000.0);
#if (TEST_CREATE_QUEUE_CHECKSUM == 1)
printf("CHECKSUM for %d/%d/%d: %d\n", steps, travel_dt, accel, s.checksum);
#endif
}
};
int main() {
FastAccelStepperTest test;
test.speed_increase();
test.speed_decrease();
printf("TEST_04 PASSED\n");
return 0;
}

View File

@@ -0,0 +1,160 @@
#include <assert.h>
#include <stdio.h>
#include <stdlib.h>
#include "FastAccelStepper.h"
#include "StepperISR.h"
char TCCR1A;
char TCCR1B;
char TCCR1C;
char TIMSK1;
char TIFR1;
unsigned short OCR1A;
unsigned short OCR1B;
FastAccelStepper *stepper;
StepperQueue fas_queue[NUM_QUEUES];
int enable_inject_on_mark = -1;
bool enable_stepper_manage_on_interrupts = false;
bool enable_stepper_manage_on_noInterrupts = false;
bool in_manage = false;
#include "RampChecker.h"
class FastAccelStepperTest {
public:
void init_queue() {
fas_queue[0]._initVars();
fas_queue[1]._initVars();
}
void inject() { stepper->fill_queue(); }
void do_test() {
init_queue();
FastAccelStepper s = FastAccelStepper();
s.init(NULL, 0, 0);
stepper = &s;
RampChecker rc = RampChecker();
assert(0 == s.getCurrentPosition());
int32_t steps = 10000;
// Increase speed to 400, then further to 300
// Identified bug was a fast jump to 300 without acceleration
assert(s.isQueueEmpty());
s.setSpeedInUs(400);
s.setAcceleration(10000);
in_manage = true;
s.fill_queue();
in_manage = false;
assert(s.isQueueEmpty());
assert(!s.isRunning());
s.moveTo(3000);
assert(s.isRunning());
in_manage = true;
s.fill_queue();
in_manage = false;
assert(!s.isQueueEmpty());
float old_planned_time_in_buffer = 0;
int moveto_done = false;
for (int i = 0; i < steps; i++) {
if (!moveto_done && (s.getCurrentPosition() >= 500)) {
moveto_done = true;
s.moveTo(4000);
}
if (true) {
printf(
"Loop %d: Queue read/write = %d/%d Target pos = %d, Queue End "
"pos = %d QueueEmpty=%s\n",
i, fas_queue[0].read_idx, fas_queue[0].next_write_idx,
s.targetPos(), s.getPositionAfterCommandsCompleted(),
s.isQueueEmpty() ? "yes" : "no");
}
in_manage = true;
if (!s.isRampGeneratorActive() && s.isQueueEmpty()) {
break;
}
s.fill_queue();
uint32_t from_dt = rc.total_ticks;
while (!s.isQueueEmpty()) {
rc.check_section(
&fas_queue[0].entry[fas_queue[0].read_idx & QUEUE_LEN_MASK]);
fas_queue[0].read_idx++;
}
in_manage = false;
uint32_t to_dt = rc.total_ticks;
float planned_time = (to_dt - from_dt) * 1.0 / 16000000;
printf("%d: planned time in buffer: %.6fs\n", i, planned_time);
// This must be ensured, so that the stepper does not run out of commands
old_planned_time_in_buffer = planned_time;
}
test(!s.isRampGeneratorActive(), "too many commands created");
printf("Total time %f\n", rc.total_ticks / 16000000.0);
#if (TEST_CREATE_QUEUE_CHECKSUM == 1)
printf("CHECKSUM for %d/%d/%d: %d\n", steps, travel_dt, accel, s.checksum);
#endif
printf("Total steps = %d\n", rc.pos);
assert(rc.pos == 4000);
printf("TEST_05 Part PASSED\n");
}
};
FastAccelStepperTest test;
void inject_fill_interrupt(int mark) {
if ((mark == enable_inject_on_mark) && !in_manage) {
in_manage = true;
test.inject();
in_manage = false;
}
}
void noInterrupts() {
if (enable_stepper_manage_on_noInterrupts && !in_manage) {
in_manage = true;
test.inject();
in_manage = false;
}
}
void interrupts() {
if (enable_stepper_manage_on_interrupts && !in_manage) {
in_manage = true;
test.inject();
in_manage = false;
}
}
int main() {
enable_stepper_manage_on_interrupts = false;
enable_stepper_manage_on_noInterrupts = false;
enable_inject_on_mark = -1;
test.do_test();
enable_stepper_manage_on_interrupts = false;
enable_stepper_manage_on_noInterrupts = false;
enable_inject_on_mark = 0;
test.do_test();
enable_stepper_manage_on_interrupts = false;
enable_stepper_manage_on_noInterrupts = false;
enable_inject_on_mark = 1;
test.do_test();
enable_stepper_manage_on_interrupts = false;
enable_stepper_manage_on_noInterrupts = false;
enable_inject_on_mark = 2;
test.do_test();
enable_stepper_manage_on_interrupts = false;
enable_stepper_manage_on_noInterrupts = true;
enable_inject_on_mark = -1;
test.do_test();
enable_stepper_manage_on_interrupts = true;
enable_stepper_manage_on_noInterrupts = false;
enable_inject_on_mark = -1;
test.do_test();
printf("TEST_05 PASSED\n");
return 0;
}

View File

@@ -0,0 +1,189 @@
#include <assert.h>
#include <stdio.h>
#include <stdlib.h>
#include "FastAccelStepper.h"
#include "StepperISR.h"
char TCCR1A;
char TCCR1B;
char TCCR1C;
char TIMSK1;
char TIFR1;
unsigned short OCR1A;
unsigned short OCR1B;
StepperQueue fas_queue[NUM_QUEUES];
void inject_fill_interrupt(int mark) {}
void noInterrupts() {}
void interrupts() {}
#include "RampChecker.h"
class FastAccelStepperTest {
public:
void init_queue() {
fas_queue[0].read_idx = 0;
fas_queue[1].read_idx = 0;
fas_queue[0].next_write_idx = 0;
fas_queue[1].next_write_idx = 0;
}
void do_test1() {
init_queue();
FastAccelStepper s = FastAccelStepper();
s.init(NULL, 0, 0);
RampChecker rc = RampChecker();
assert(0 == s.getCurrentPosition());
int32_t steps = 15000;
// This sequence caused no stop:
// M1 N A100000 V4000 R15000
// V4300 U
// S
assert(s.isQueueEmpty());
s.setSpeedInUs(4000);
s.setAcceleration(100000);
s.fill_queue();
assert(s.isQueueEmpty());
s.move(steps);
s.fill_queue();
assert(!s.isQueueEmpty());
float old_planned_time_in_buffer = 0;
bool speed_changed = false;
bool stop_initiated = false;
for (int i = 0; i < steps; i++) {
if (!speed_changed && (s.getCurrentPosition() >= 1000)) {
puts("Change speed to 4300us");
s.fill_queue(); // ensure queue is not empty
speed_changed = true;
s.setSpeedInUs(4300);
s.applySpeedAcceleration();
}
if (!stop_initiated && (s.getCurrentPosition() >= 2000)) {
puts("Init stop");
s.fill_queue(); // ensure queue is not empty
stop_initiated = true;
s.stopMove();
}
if (true) {
printf(
"Loop %d: Queue read/write = %d/%d Target pos = %d, Queue End "
"pos = %d QueueEmpty=%s\n",
i, fas_queue[0].read_idx, fas_queue[0].next_write_idx,
s.targetPos(), s.getPositionAfterCommandsCompleted(),
s.isQueueEmpty() ? "yes" : "no");
}
if (!s.isRampGeneratorActive()) {
break;
}
s.fill_queue();
uint32_t from_dt = rc.total_ticks;
while (!s.isQueueEmpty()) {
rc.check_section(
&fas_queue[0].entry[fas_queue[0].read_idx & QUEUE_LEN_MASK]);
fas_queue[0].read_idx++;
}
uint32_t to_dt = rc.total_ticks;
float planned_time = (to_dt - from_dt) * 1.0 / 16000000;
printf("planned time in buffer: %.6fs\n", planned_time);
// This must be ensured, so that the stepper does not run out of commands
assert((i == 0) || (old_planned_time_in_buffer > 0.005));
old_planned_time_in_buffer = planned_time;
}
test(!s.isRampGeneratorActive(), "too many commands created");
test(s.getCurrentPosition() != steps, "has not stopped");
printf("Total time %f\n", rc.total_ticks / 16000000.0);
#if (TEST_CREATE_QUEUE_CHECKSUM == 1)
printf("CHECKSUM for %d/%d/%d: %d\n", steps, travel_dt, accel, s.checksum);
#endif
}
void do_test2(uint32_t stop_at_position) {
printf("do_test2 with stop at %d\n", stop_at_position);
init_queue();
FastAccelStepper s = FastAccelStepper();
s.init(NULL, 0, 0);
RampChecker rc = RampChecker();
assert(0 == s.getCurrentPosition());
int32_t steps = 15000;
// This sequence does not run to position 9999:
// M1 N A100 V100 P9999 w100 S W P9999
assert(s.isQueueEmpty());
s.setSpeedInUs(100);
s.setAcceleration(100);
s.fill_queue();
assert(s.isQueueEmpty());
s.moveTo(9999);
s.fill_queue();
assert(!s.isQueueEmpty());
float old_planned_time_in_buffer = 0;
bool stop_initiated = false;
bool restarted = false;
for (int i = 0; i < steps; i++) {
if (!stop_initiated && (s.getCurrentPosition() >= stop_at_position)) {
puts("Init stop");
s.fill_queue(); // ensure queue is not empty
stop_initiated = true;
s.stopMove();
}
if (true) {
printf(
"Loop %d: Queue read/write = %d/%d Target pos = %d, Queue End "
"pos = %d QueueEmpty=%s\n",
i, fas_queue[0].read_idx, fas_queue[0].next_write_idx,
s.targetPos(), s.getPositionAfterCommandsCompleted(),
s.isQueueEmpty() ? "yes" : "no");
}
s.fill_queue();
uint32_t from_dt = rc.total_ticks;
if (!s.isQueueEmpty()) {
while (!s.isQueueEmpty()) {
rc.check_section(
&fas_queue[0].entry[fas_queue[0].read_idx & QUEUE_LEN_MASK]);
fas_queue[0].read_idx++;
}
uint32_t to_dt = rc.total_ticks;
float planned_time = (to_dt - from_dt) * 1.0 / 16000000;
printf("planned time in buffer: %.6fs\n", planned_time);
// This must be ensured, so that the stepper does not run out of
// commands
assert((i == 0) || (old_planned_time_in_buffer > 0.005));
old_planned_time_in_buffer = planned_time;
}
if (!s.isRampGeneratorActive()) {
if (restarted) {
break;
}
puts("Continue move to end position");
rc.next_ramp();
restarted = true;
s.moveTo(9999);
}
}
printf("do_test2 with stop at %d\n", stop_at_position);
test(!s.isRampGeneratorActive(), "too many commands created");
printf("getCurrentPosition() = %d\n", s.getCurrentPosition());
test(s.getCurrentPosition() == 9999, "has not reached end position");
printf("Total time %f\n", rc.total_ticks / 16000000.0);
#if (TEST_CREATE_QUEUE_CHECKSUM == 1)
printf("CHECKSUM for %d/%d/%d: %d\n", steps, travel_dt, accel, s.checksum);
#endif
}
};
int main() {
FastAccelStepperTest test;
test.do_test1();
test.do_test2(100);
test.do_test2(5000);
test.do_test2(9000);
printf("TEST_06 PASSED\n");
return 0;
}

View File

@@ -0,0 +1,132 @@
#include <assert.h>
#include <stdio.h>
#include <stdlib.h>
#include <cinttypes>
#include "FastAccelStepper.h"
#include "StepperISR.h"
char TCCR1A;
char TCCR1B;
char TCCR1C;
char TIMSK1;
char TIFR1;
unsigned short OCR1A;
unsigned short OCR1B;
StepperQueue fas_queue[NUM_QUEUES];
void inject_fill_interrupt(int mark) {}
void noInterrupts() {}
void interrupts() {}
#include "RampChecker.h"
class FastAccelStepperTest {
public:
void init_queue() {
fas_queue[0].read_idx = 0;
fas_queue[1].read_idx = 0;
fas_queue[0].next_write_idx = 0;
fas_queue[1].next_write_idx = 0;
}
void do_test(uint64_t dt) {
init_queue();
FastAccelStepper s = FastAccelStepper();
s.init(NULL, 0, 0);
RampChecker rc = RampChecker();
assert(0 == s.getCurrentPosition());
// Reproduce test sequence 06
assert(s.getDirectionPin() == PIN_UNDEFINED);
uint32_t speed_us = 100;
int32_t steps = 32000;
assert(s.isQueueEmpty());
s.setSpeedInUs(speed_us);
s.setAcceleration(10000);
s.fill_queue();
assert(s.isQueueEmpty());
s.move(steps);
s.fill_queue();
assert(!s.isQueueEmpty());
float old_planned_time_in_buffer = 0;
uint64_t next_speed_change = dt;
uint64_t mid_point_ticks = 0;
char fname[100];
snprintf(fname, 100, "test_07.gnuplot");
rc.start_plot(fname);
for (int i = 0; i < 10 * steps; i++) {
if (rc.total_ticks > next_speed_change) {
next_speed_change += TICKS_PER_S / 10;
speed_us = 190 - speed_us;
printf("Change speed to %d\n", speed_us);
s.setSpeedInUs(speed_us);
s.applySpeedAcceleration();
}
if (true) {
printf(
"Loop %d: Queue read/write = %d/%d Target pos = %d, Queue End "
"pos = %d QueueEmpty=%s\n",
i, fas_queue[0].read_idx, fas_queue[0].next_write_idx,
s.targetPos(), s.getPositionAfterCommandsCompleted(),
s.isQueueEmpty() ? "yes" : "no");
}
if (!s.isRampGeneratorActive()) {
break;
}
s.fill_queue();
uint32_t from_dt = rc.total_ticks;
while (!s.isQueueEmpty()) {
if ((mid_point_ticks == 0) && (rc.pos >= steps / 2)) {
mid_point_ticks = rc.total_ticks;
}
rc.increase_ok = true;
rc.decrease_ok = true;
rc.check_section(
&fas_queue[0].entry[fas_queue[0].read_idx & QUEUE_LEN_MASK]);
fas_queue[0].read_idx++;
}
uint32_t to_dt = rc.total_ticks;
float planned_time = (to_dt - from_dt) * 1.0 / 16000000;
printf("planned time in buffer: %.6fs\n", planned_time);
// This must be ensured, so that the stepper does not run out of commands
assert((i == 0) || (old_planned_time_in_buffer > 0.005));
old_planned_time_in_buffer = planned_time;
test(s.getCurrentPosition() <= steps, "has overshot");
}
rc.finish_plot();
test(!s.isRampGeneratorActive(), "too many commands created");
test(s.getCurrentPosition() == steps, "has not reached target position");
printf("Total time %f\n", rc.total_ticks / 16000000.0);
printf("Time coasting = %d\n", rc.time_coasting);
test(rc.time_coasting < 46000000, "too much coasting");
printf("mid point @ %" PRIu64 " => total = %" PRIu64
", total ticks = %" PRIu64 "\n",
mid_point_ticks, 2 * mid_point_ticks, rc.total_ticks);
#define ALLOWED_ASYMMETRY 1000000L
printf("%ld\n", ALLOWED_ASYMMETRY);
test(mid_point_ticks * 2 < rc.total_ticks + ALLOWED_ASYMMETRY,
"ramp is not symmetric 1");
test(mid_point_ticks * 2 > rc.total_ticks - ALLOWED_ASYMMETRY,
"ramp is not symmetric 2");
#if (TEST_CREATE_QUEUE_CHECKSUM == 1)
printf("CHECKSUM for %d/%d/%d: %d\n", steps, travel_dt, accel, s.checksum);
#endif
}
};
int main() {
FastAccelStepperTest test;
for (uint64_t time_shift = 0; time_shift < TICKS_PER_S / 10;
time_shift += TICKS_PER_S / 7000) {
test.do_test(time_shift);
}
printf("TEST_07 PASSED\n");
return 0;
}

View File

@@ -0,0 +1,103 @@
#include <assert.h>
#include <stdio.h>
#include <stdlib.h>
#include "FastAccelStepper.h"
#include "StepperISR.h"
char TCCR1A;
char TCCR1B;
char TCCR1C;
char TIMSK1;
char TIFR1;
unsigned short OCR1A;
unsigned short OCR1B;
StepperQueue fas_queue[NUM_QUEUES];
void inject_fill_interrupt(int mark) {}
void noInterrupts() {}
void interrupts() {}
#include "RampChecker.h"
class FastAccelStepperTest {
public:
void init_queue() {
fas_queue[0].read_idx = 0;
fas_queue[1].read_idx = 0;
fas_queue[0].next_write_idx = 0;
fas_queue[1].next_write_idx = 0;
}
void ramp(uint32_t accel, uint32_t steps) {
init_queue();
FastAccelStepper s = FastAccelStepper();
s.init(NULL, 0, 0);
RampChecker rc = RampChecker();
assert(0 == s.getCurrentPosition());
// Reproduce test sequence 06
uint32_t speed_us = 40;
assert(s.isQueueEmpty());
s.setSpeedInUs(speed_us);
s.setAcceleration(accel);
s.fill_queue();
assert(s.isQueueEmpty());
s.move(steps);
s.fill_queue();
assert(!s.isQueueEmpty());
float old_planned_time_in_buffer = 0;
char fname[100];
snprintf(fname, 100, "test_08.gnuplot");
rc.start_plot(fname);
for (int i = 0; i < 100 * steps; i++) {
if (true) {
printf(
"Loop %d: Queue read/write = %d/%d Target pos = %d, Queue End "
"pos = %d QueueEmpty=%s\n",
i, fas_queue[0].read_idx, fas_queue[0].next_write_idx,
s.targetPos(), s.getPositionAfterCommandsCompleted(),
s.isQueueEmpty() ? "yes" : "no");
}
if (!s.isRampGeneratorActive()) {
break;
}
s.fill_queue();
uint32_t from_dt = rc.total_ticks;
while (!s.isQueueEmpty()) {
rc.increase_ok = true;
rc.decrease_ok = true;
rc.check_section(
&fas_queue[0].entry[fas_queue[0].read_idx & QUEUE_LEN_MASK]);
fas_queue[0].read_idx++;
}
uint32_t to_dt = rc.total_ticks;
float planned_time = (to_dt - from_dt) * 1.0 / 16000000;
printf("planned time in buffer: %.6fs\n", planned_time);
// This must be ensured, so that the stepper does not run out of commands
assert((i == 0) || (old_planned_time_in_buffer > 0.005));
old_planned_time_in_buffer = planned_time;
}
rc.finish_plot();
test(!s.isRampGeneratorActive(), "too many commands created");
test(s.getCurrentPosition() == steps, "has not reached target position");
printf("Total time %f\n", rc.total_ticks / 16000000.0);
#if (TEST_CREATE_QUEUE_CHECKSUM == 1)
printf("CHECKSUM for %d/%d/%d: %d\n", steps, travel_dt, accel, s.checksum);
#endif
}
};
int main() {
FastAccelStepperTest test;
test.ramp(100000, 400);
test.ramp(100000, 600);
for (uint32_t i = 0; i < 30; i++) {
test.ramp(1000000, 1000 + i);
}
printf("TEST_08 PASSED\n");
return 0;
}

View File

@@ -0,0 +1,99 @@
#include <assert.h>
#include <stdio.h>
#include <stdlib.h>
#include "FastAccelStepper.h"
#include "StepperISR.h"
char TCCR1A;
char TCCR1B;
char TCCR1C;
char TIMSK1;
char TIFR1;
unsigned short OCR1A;
unsigned short OCR1B;
StepperQueue fas_queue[NUM_QUEUES];
void inject_fill_interrupt(int mark) {}
void noInterrupts() {}
void interrupts() {}
#include "RampChecker.h"
class FastAccelStepperTest {
public:
void init_queue() {
fas_queue[0].read_idx = 0;
fas_queue[1].read_idx = 0;
fas_queue[0].next_write_idx = 0;
fas_queue[1].next_write_idx = 0;
}
void ramp(uint32_t steps) {
init_queue();
FastAccelStepper s = FastAccelStepper();
s.init(NULL, 0, 0);
RampChecker rc = RampChecker();
assert(0 == s.getCurrentPosition());
uint32_t speed_us = 40;
assert(s.isQueueEmpty());
s.setSpeedInUs(speed_us);
s.setAcceleration(1000000);
s.fill_queue();
assert(s.isQueueEmpty());
float old_planned_time_in_buffer = 0;
char fname[100];
snprintf(fname, 100, "test_09.gnuplot");
rc.start_plot(fname);
for (int j = 0; j < 2; j++) {
s.move(steps);
for (int i = 0; i < 100 * steps; i++) {
if (true) {
printf(
"Loop %d: Queue read/write = %d/%d Target pos = %d, Queue End "
"pos = %d QueueEmpty=%s\n",
i, fas_queue[0].read_idx, fas_queue[0].next_write_idx,
s.targetPos(), s.getPositionAfterCommandsCompleted(),
s.isQueueEmpty() ? "yes" : "no");
}
if (!s.isRampGeneratorActive()) {
break;
}
s.fill_queue();
uint32_t from_dt = rc.total_ticks;
while (!s.isQueueEmpty()) {
rc.increase_ok = true;
rc.decrease_ok = true;
rc.check_section(
&fas_queue[0].entry[fas_queue[0].read_idx & QUEUE_LEN_MASK]);
fas_queue[0].read_idx++;
}
uint32_t to_dt = rc.total_ticks;
float planned_time = (to_dt - from_dt) * 1.0 / 16000000;
printf("planned time in buffer: %.6fs\n", planned_time);
// This must be ensured, so that the stepper does not run out of
// commands
assert((i == 0) || (old_planned_time_in_buffer > 0.005));
old_planned_time_in_buffer = planned_time;
}
}
rc.finish_plot();
test(!s.isRampGeneratorActive(), "too many commands created");
test(s.getCurrentPosition() == 2 * steps,
"has not reached target position");
printf("Total time %f\n", rc.total_ticks / 16000000.0);
#if (TEST_CREATE_QUEUE_CHECKSUM == 1)
printf("CHECKSUM for %d/%d/%d: %d\n", steps, travel_dt, accel, s.checksum);
#endif
}
};
int main() {
FastAccelStepperTest test;
test.ramp(53);
printf("TEST_09 PASSED\n");
return 0;
}

View File

@@ -0,0 +1,107 @@
#include <assert.h>
#include <stdio.h>
#include <stdlib.h>
#include "FastAccelStepper.h"
#include "StepperISR.h"
char TCCR1A;
char TCCR1B;
char TCCR1C;
char TIMSK1;
char TIFR1;
unsigned short OCR1A;
unsigned short OCR1B;
StepperQueue fas_queue[NUM_QUEUES];
void inject_fill_interrupt(int mark) {}
void noInterrupts() {}
void interrupts() {}
#include "RampChecker.h"
class FastAccelStepperTest {
public:
void init_queue() {
fas_queue[0].read_idx = 0;
fas_queue[1].read_idx = 0;
fas_queue[0].next_write_idx = 0;
fas_queue[1].next_write_idx = 0;
}
void reduce_acceleration() {
puts("Test test_speed_decrease");
init_queue();
FastAccelStepper s = FastAccelStepper();
s.init(NULL, 0, 0);
RampChecker rc = RampChecker();
assert(0 == s.getCurrentPosition());
int32_t steps = 100000;
// Increase speed to 400, then further to 300
// Identified bug was a fast jump to 300 without acceleration
assert(s.isQueueEmpty());
s.setSpeedInUs(30);
s.fill_queue();
assert(s.isQueueEmpty());
s.moveByAcceleration(17164);
s.fill_queue();
assert(!s.isQueueEmpty());
float old_planned_time_in_buffer = 0;
int accel_decreased = false;
uint32_t count_state_dec = 0;
for (int i = 0; i < steps * 10; i++) {
if (!accel_decreased && (s.getCurrentPosition() >= 35000)) {
puts("Change acceleration");
accel_decreased = true;
s.moveByAcceleration(-1000);
s.fill_queue(); // ensure queue is not empty
}
if (accel_decreased && (s.getCurrentPosition() >= 37000)) {
test((s.rampState() & RAMP_STATE_MASK) != RAMP_STATE_COAST,
"Coasting is wrong state here");
break;
}
if (true) {
printf(
"Loop %d: Queue read/write = %d/%d Target pos = %d, Queue End "
"pos = %d QueueEmpty=%s\n",
i, fas_queue[0].read_idx, fas_queue[0].next_write_idx,
s.targetPos(), s.getPositionAfterCommandsCompleted(),
s.isQueueEmpty() ? "yes" : "no");
}
if (!s.isRampGeneratorActive()) {
break;
}
s.fill_queue();
if ((s.rampState() & RAMP_STATE_MASK) == RAMP_STATE_DECELERATE) {
count_state_dec++;
}
uint32_t from_dt = rc.total_ticks;
while (!s.isQueueEmpty()) {
rc.check_section(
&fas_queue[0].entry[fas_queue[0].read_idx & QUEUE_LEN_MASK]);
fas_queue[0].read_idx++;
}
uint32_t to_dt = rc.total_ticks;
float planned_time = (to_dt - from_dt) * 1.0 / 16000000;
printf("planned time in buffer: %.6fs\n", planned_time);
// This must be ensured, so that the stepper does not run out of commands
assert((i == 0) || (old_planned_time_in_buffer > 0.005));
old_planned_time_in_buffer = planned_time;
}
printf("Total time %f\n", rc.total_ticks / 16000000.0);
#if (TEST_CREATE_QUEUE_CHECKSUM == 1)
printf("CHECKSUM for %d/%d/%d: %d\n", steps, travel_dt, accel, s.checksum);
#endif
}
};
int main() {
FastAccelStepperTest test;
test.reduce_acceleration();
printf("TEST_10 PASSED\n");
return 0;
}

View File

@@ -0,0 +1,108 @@
#include <assert.h>
#include <stdio.h>
#include <stdlib.h>
#include "FastAccelStepper.h"
#include "StepperISR.h"
char TCCR1A;
char TCCR1B;
char TCCR1C;
char TIMSK1;
char TIFR1;
unsigned short OCR1A;
unsigned short OCR1B;
StepperQueue fas_queue[NUM_QUEUES];
void inject_fill_interrupt(int mark) {}
void noInterrupts() {}
void interrupts() {}
#include "RampChecker.h"
class FastAccelStepperTest {
public:
void init_queue() {
fas_queue[0].read_idx = 0;
fas_queue[1].read_idx = 0;
fas_queue[0].next_write_idx = 0;
fas_queue[1].next_write_idx = 0;
}
void reduce_speed() {
puts("Test test_speed_decrease");
init_queue();
FastAccelStepper s = FastAccelStepper();
s.init(NULL, 0, 0);
RampChecker rc = RampChecker();
assert(0 == s.getCurrentPosition());
int32_t steps = 100;
// M1 A1000 V10000 P100 w300 V100000 U
assert(s.isQueueEmpty());
s.setAcceleration(1000);
s.setSpeedInUs(10000);
s.fill_queue();
assert(s.isQueueEmpty());
s.moveTo(100);
s.fill_queue();
assert(!s.isQueueEmpty());
float old_planned_time_in_buffer = 0;
int speed_decreased = false;
uint32_t count_state_dec = 0;
for (int i = 0; i < steps * 10; i++) {
if (!speed_decreased && (s.getCurrentPosition() >= 35)) {
puts("Change speed");
speed_decreased = true;
s.setSpeedInUs(100000);
s.applySpeedAcceleration();
s.fill_queue(); // ensure queue is not empty
}
if (speed_decreased && (s.getCurrentPosition() >= 90)) {
test((s.rampState() & RAMP_STATE_MASK) == RAMP_STATE_COAST,
"Coasting is required state here");
break;
}
if (true) {
printf(
"Loop %d: Queue read/write = %d/%d Target pos = %d, Queue End "
"pos = %d QueueEmpty=%s\n",
i, fas_queue[0].read_idx, fas_queue[0].next_write_idx,
s.targetPos(), s.getPositionAfterCommandsCompleted(),
s.isQueueEmpty() ? "yes" : "no");
}
if (!s.isRampGeneratorActive()) {
break;
}
s.fill_queue();
if ((s.rampState() & RAMP_STATE_MASK) == RAMP_STATE_DECELERATE) {
count_state_dec++;
}
uint32_t from_dt = rc.total_ticks;
while (!s.isQueueEmpty()) {
rc.check_section(
&fas_queue[0].entry[fas_queue[0].read_idx & QUEUE_LEN_MASK]);
fas_queue[0].read_idx++;
}
uint32_t to_dt = rc.total_ticks;
float planned_time = (to_dt - from_dt) * 1.0 / 16000000;
printf("planned time in buffer: %.6fs\n", planned_time);
// This must be ensured, so that the stepper does not run out of commands
assert((i == 0) || (old_planned_time_in_buffer > 0.005));
old_planned_time_in_buffer = planned_time;
}
printf("Total time %f\n", rc.total_ticks / 16000000.0);
#if (TEST_CREATE_QUEUE_CHECKSUM == 1)
printf("CHECKSUM for %d/%d/%d: %d\n", steps, travel_dt, accel, s.checksum);
#endif
}
};
int main() {
FastAccelStepperTest test;
test.reduce_speed();
printf("TEST_11 PASSED\n");
return 0;
}

View File

@@ -0,0 +1,103 @@
#include <assert.h>
#include <stdio.h>
#include <stdlib.h>
#include "FastAccelStepper.h"
#include "StepperISR.h"
char TCCR1A;
char TCCR1B;
char TCCR1C;
char TIMSK1;
char TIFR1;
unsigned short OCR1A;
unsigned short OCR1B;
StepperQueue fas_queue[NUM_QUEUES];
void inject_fill_interrupt(int mark) {}
void noInterrupts() {}
void interrupts() {}
#include "RampChecker.h"
class FastAccelStepperTest {
public:
void init_queue() {
fas_queue[0].read_idx = 0;
fas_queue[1].read_idx = 0;
fas_queue[0].next_write_idx = 0;
fas_queue[1].next_write_idx = 0;
}
void ramp(uint32_t accel, uint32_t speed_us, uint32_t steps,
bool reach_coasting) {
init_queue();
FastAccelStepper s = FastAccelStepper();
s.init(NULL, 0, 0);
RampChecker rc = RampChecker();
assert(0 == s.getCurrentPosition());
assert(s.isQueueEmpty());
s.setSpeedInUs(speed_us);
s.setAcceleration(accel);
s.fill_queue();
assert(s.isQueueEmpty());
s.move(steps);
s.fill_queue();
assert(!s.isQueueEmpty());
float old_planned_time_in_buffer = 0;
char fname[100];
snprintf(fname, 100, "test_12.gnuplot");
rc.start_plot(fname);
bool coast = false;
for (int i = 0; i < 100 * steps; i++) {
if (true) {
printf(
"Loop %d: Queue read/write = %d/%d Target pos = %d, Queue End "
"pos = %d QueueEmpty=%s\n",
i, fas_queue[0].read_idx, fas_queue[0].next_write_idx,
s.targetPos(), s.getPositionAfterCommandsCompleted(),
s.isQueueEmpty() ? "yes" : "no");
}
if (!s.isRampGeneratorActive()) {
break;
}
s.fill_queue();
uint32_t from_dt = rc.total_ticks;
while (!s.isQueueEmpty()) {
rc.increase_ok = true;
rc.decrease_ok = true;
rc.check_section(
&fas_queue[0].entry[fas_queue[0].read_idx & QUEUE_LEN_MASK]);
fas_queue[0].read_idx++;
}
if ((s.rampState() & RAMP_STATE_MASK) == RAMP_STATE_COAST) {
coast = true;
}
uint32_t to_dt = rc.total_ticks;
float planned_time = (to_dt - from_dt) * 1.0 / 16000000;
printf("planned time in buffer: %.6fs\n", planned_time);
// This must be ensured, so that the stepper does not run out of commands
assert((i == 0) || (old_planned_time_in_buffer > 0.005));
old_planned_time_in_buffer = planned_time;
}
rc.finish_plot();
test(!s.isRampGeneratorActive(), "too many commands created");
test(s.getCurrentPosition() == steps, "has not reached target position");
test(coast == reach_coasting, "coasting target not met");
printf("Total time %f\n", rc.total_ticks / 16000000.0);
#if (TEST_CREATE_QUEUE_CHECKSUM == 1)
printf("CHECKSUM for %d/%d/%d: %d\n", steps, travel_dt, accel, s.checksum);
#endif
}
};
int main() {
FastAccelStepperTest test;
test.ramp(1, 1000, 999000, false);
test.ramp(1, 1000, 1001000, true);
printf("TEST_12 PASSED\n");
return 0;
}

View File

@@ -0,0 +1,113 @@
#include <assert.h>
#include <stdio.h>
#include <stdlib.h>
#include "FastAccelStepper.h"
#include "StepperISR.h"
char TCCR1A;
char TCCR1B;
char TCCR1C;
char TIMSK1;
char TIFR1;
unsigned short OCR1A;
unsigned short OCR1B;
StepperQueue fas_queue[NUM_QUEUES];
void inject_fill_interrupt(int mark) {}
void noInterrupts() {}
void interrupts() {}
#include "RampChecker.h"
class FastAccelStepperTest {
public:
void init_queue() {
fas_queue[0].read_idx = 0;
fas_queue[1].read_idx = 0;
fas_queue[0].next_write_idx = 0;
fas_queue[1].next_write_idx = 0;
}
void ramp(uint32_t accel, uint32_t speed_us, uint32_t steps,
bool reach_coasting) {
init_queue();
FastAccelStepper s = FastAccelStepper();
s.init(NULL, 0, 0);
RampChecker rc = RampChecker();
assert(0 == s.getCurrentPosition());
assert(s.isQueueEmpty());
s.setSpeedInUs(speed_us);
s.setAcceleration(accel);
s.fill_queue();
assert(s.isQueueEmpty());
s.move(steps);
s.fill_queue();
assert(!s.isQueueEmpty());
float old_planned_time_in_buffer = 0;
char fname[100];
snprintf(fname, 100, "test_13.gnuplot");
rc.start_plot(fname);
bool coast = false;
for (int i = 0; i < 100 * steps; i++) {
if (true) {
printf(
"Loop %d: Queue read/write = %d/%d Target pos = %d, Queue End "
"pos = %d QueueEmpty=%s\n",
i, fas_queue[0].read_idx, fas_queue[0].next_write_idx,
s.targetPos(), s.getPositionAfterCommandsCompleted(),
s.isQueueEmpty() ? "yes" : "no");
}
if (!s.isRampGeneratorActive()) {
break;
}
s.fill_queue();
uint32_t from_dt = rc.total_ticks;
while (!s.isQueueEmpty()) {
rc.increase_ok = true;
rc.decrease_ok = true;
rc.check_section(
&fas_queue[0].entry[fas_queue[0].read_idx & QUEUE_LEN_MASK]);
fas_queue[0].read_idx++;
}
if ((s.rampState() & RAMP_STATE_MASK) == RAMP_STATE_COAST) {
coast = true;
}
uint32_t to_dt = rc.total_ticks;
float planned_time = (to_dt - from_dt) * 1.0 / 16000000;
printf("planned time in buffer: %.6fs\n", planned_time);
// This must be ensured, so that the stepper does not run out of commands
assert((i == 0) || (old_planned_time_in_buffer > 0.005));
old_planned_time_in_buffer = planned_time;
}
while (!s.isQueueEmpty()) {
rc.increase_ok = true;
rc.decrease_ok = true;
rc.check_section(
&fas_queue[0].entry[fas_queue[0].read_idx & QUEUE_LEN_MASK]);
fas_queue[0].read_idx++;
}
rc.finish_plot();
test(!s.isRampGeneratorActive(), "too many commands created");
test(s.getCurrentPosition() == steps, "has not reached target position");
test(coast == reach_coasting, "coasting target not met");
printf("Total time %f\n", rc.total_ticks / 16000000.0);
#if (TEST_CREATE_QUEUE_CHECKSUM == 1)
printf("CHECKSUM for %d/%d/%d: %d\n", steps, travel_dt, accel, s.checksum);
#endif
}
};
int main() {
FastAccelStepperTest test;
for (uint16_t s = 1; s <= 255; s++) {
printf("test with steps s=%d\n", s);
test.ramp(INT32_MAX, 50, s, false);
puts("");
}
printf("TEST_13 PASSED\n");
return 0;
}

View File

@@ -0,0 +1,106 @@
#include <assert.h>
#include <stdio.h>
#include <stdlib.h>
#include "FastAccelStepper.h"
#include "StepperISR.h"
char TCCR1A;
char TCCR1B;
char TCCR1C;
char TIMSK1;
char TIFR1;
unsigned short OCR1A;
unsigned short OCR1B;
StepperQueue fas_queue[NUM_QUEUES];
void inject_fill_interrupt(int mark) {}
void noInterrupts() {}
void interrupts() {}
#include "RampChecker.h"
class FastAccelStepperTest {
public:
void init_queue() {
fas_queue[0].read_idx = 0;
fas_queue[1].read_idx = 0;
fas_queue[0].next_write_idx = 0;
fas_queue[1].next_write_idx = 0;
}
void ramp() {
init_queue();
FastAccelStepper s = FastAccelStepper();
s.init(NULL, 0, 0);
RampChecker rc = RampChecker();
assert(0 == s.getCurrentPosition());
uint32_t speed_us = 1000000 / 3600;
assert(s.isQueueEmpty());
s.setSpeedInUs(speed_us);
s.setAcceleration(320);
s.fill_queue();
assert(s.isQueueEmpty());
float old_planned_time_in_buffer = 0;
char fname[100];
snprintf(fname, 100, "test_14.gnuplot");
rc.start_plot(fname);
s.runForward();
for (int i = 0; i < 2000; i++) {
if (i == 1000) {
printf("Change speed\n");
s.setSpeedInUs(10000);
s.applySpeedAcceleration();
}
if (true) {
printf(
"Loop %d: Queue read/write = %d/%d Target pos = %d, Queue End "
"pos = %d QueueEmpty=%s\n",
i, fas_queue[0].read_idx, fas_queue[0].next_write_idx,
s.targetPos(), s.getPositionAfterCommandsCompleted(),
s.isQueueEmpty() ? "yes" : "no");
}
if (!s.isRampGeneratorActive()) {
break;
}
s.fill_queue();
uint32_t from_dt = rc.total_ticks;
while (!s.isQueueEmpty()) {
rc.increase_ok = true;
rc.decrease_ok = true;
rc.check_section(
&fas_queue[0].entry[fas_queue[0].read_idx & QUEUE_LEN_MASK]);
fas_queue[0].read_idx++;
}
uint32_t to_dt = rc.total_ticks;
float planned_time = (to_dt - from_dt) * 1.0 / 16000000;
printf("planned time in buffer: %.6fs\n", planned_time);
// This must be ensured, so that the stepper does not run out of
// commands
assert((i == 0) || (old_planned_time_in_buffer > 0.005));
old_planned_time_in_buffer = planned_time;
// stop after
if (rc.total_ticks > TICKS_PER_S * 40) {
break;
}
}
rc.finish_plot();
// test(!s.isRampGeneratorActive(), "too many commands created");
test(s.getCurrentPosition() > 70000, "stepper runs too slow");
test(s.getCurrentPosition() < 80000, "stepper runs too fast");
printf("Total time %f\n", rc.total_ticks / 16000000.0);
#if (TEST_CREATE_QUEUE_CHECKSUM == 1)
printf("CHECKSUM for %d/%d/%d: %d\n", steps, travel_dt, accel, s.checksum);
#endif
}
};
int main() {
FastAccelStepperTest test;
test.ramp();
printf("TEST_14 PASSED\n");
return 0;
}

View File

@@ -0,0 +1,119 @@
#include <assert.h>
#include <stdio.h>
#include <stdlib.h>
#include "FastAccelStepper.h"
#include "StepperISR.h"
char TCCR1A;
char TCCR1B;
char TCCR1C;
char TIMSK1;
char TIFR1;
unsigned short OCR1A;
unsigned short OCR1B;
StepperQueue fas_queue[NUM_QUEUES];
void inject_fill_interrupt(int mark) {}
void noInterrupts() {}
void interrupts() {}
#include "RampChecker.h"
class FastAccelStepperTest {
public:
void init_queue() {
fas_queue[0].read_idx = 0;
fas_queue[1].read_idx = 0;
fas_queue[0].next_write_idx = 0;
fas_queue[1].next_write_idx = 0;
}
void ramp(uint8_t forward_planning, uint32_t expected_steps) {
init_queue();
FastAccelStepper s = FastAccelStepper();
s.init(NULL, 0, 0);
RampChecker rc = RampChecker();
assert(0 == s.getCurrentPosition());
uint32_t speed_us = 1000000 / 3600;
assert(s.isQueueEmpty());
s.setSpeedInUs(speed_us);
s.setAcceleration(320);
s.setForwardPlanningTimeInMs(forward_planning);
s.fill_queue();
assert(s.isQueueEmpty());
float old_planned_time_in_buffer = 0;
char fname[100];
float sum_planning_time = 0;
float points = 0;
snprintf(fname, 100, "test_15_%dms.gnuplot", forward_planning);
rc.start_plot(fname);
s.runForward();
for (int i = 0; i < 2000; i++) {
if (i == 1000) {
printf("Change speed\n");
s.setSpeedInUs(10000);
s.applySpeedAcceleration();
}
if (true) {
printf(
"Loop %d: Queue read/write = %d/%d Target pos = %d, Queue End "
"pos = %d QueueEmpty=%s\n",
i, fas_queue[0].read_idx, fas_queue[0].next_write_idx,
s.targetPos(), s.getPositionAfterCommandsCompleted(),
s.isQueueEmpty() ? "yes" : "no");
}
if (!s.isRampGeneratorActive()) {
break;
}
s.fill_queue();
uint32_t from_dt = rc.total_ticks;
while (!s.isQueueEmpty()) {
rc.increase_ok = true;
rc.decrease_ok = true;
rc.check_section(
&fas_queue[0].entry[fas_queue[0].read_idx & QUEUE_LEN_MASK]);
fas_queue[0].read_idx++;
}
uint32_t to_dt = rc.total_ticks;
float planned_time = (to_dt - from_dt) * 1.0 / 16000000;
printf("planned time in buffer: %.6fs\n", planned_time);
sum_planning_time += planned_time;
points += 1.0;
// This must be ensured, so that the stepper does not run out of
// commands
assert((i == 0) || (old_planned_time_in_buffer > 0.005));
old_planned_time_in_buffer = planned_time;
// stop after
if (rc.total_ticks > TICKS_PER_S * 40) {
break;
}
}
rc.finish_plot();
// test(!s.isRampGeneratorActive(), "too many commands created");
printf("current position = %d\n", s.getCurrentPosition());
test(s.getCurrentPosition() > expected_steps - 10, "stepper runs too slow");
test(s.getCurrentPosition() < expected_steps + 10, "stepper runs too fast");
printf("Total time %f\n", rc.total_ticks / 16000000.0);
float avg_time = sum_planning_time / points * 1000.0;
printf("Average planning time: %f ms\n", avg_time);
test(avg_time < forward_planning + 1, "too much forward planning");
#if (TEST_CREATE_QUEUE_CHECKSUM == 1)
printf("CHECKSUM for %d/%d/%d: %d\n", steps, travel_dt, accel, s.checksum);
#endif
}
};
int main() {
FastAccelStepperTest test;
// run the ramp twice with 20 and with 5ms planning time.
// the ramp will change speed after half of the loops.
// The 5ms ramp will not have 20ms coasting in the buffer and as such runs much shorter.
test.ramp(20, 76936);
test.ramp(5, 11273);
printf("TEST_15 PASSED\n");
return 0;
}

2
extras/tests/simavr_based/.gitignore vendored Normal file
View File

@@ -0,0 +1,2 @@
.links
.makefiles

View File

@@ -0,0 +1,62 @@
ifndef SILENCE
SILENCE=0
endif
PRJ_ROOT=$(shell git rev-parse --show-toplevel)
TESTS=$(wildcard test_*)
TESTS_SD=$(wildcard test_*sd_*)
TEST_FILES=$(addsuffix /.tested,$(TESTS))
SD_SRC_DIRS=$(addsuffix /src/.dir,$(TESTS_SD))
SRC=$(wildcard ../../src/*)
test: $(TEST_FILES) pmf externalCall
pmf:
make -C test_pmf
externalCall:
make -C test_externalCall
%/.tested: $(SRC) run_avr %/expect.txt %/platformio.ini .makefiles .links
make SILENCE=$(SILENCE) -C $(dir $@)
.makefiles: makefiles
makefiles: $(addsuffix /Makefile,$(TESTS))
touch .makefiles
%/Makefile:
cd $(dir $@); ln -s ../Makefile.test Makefile
.links: links
links: $(SD_SRC_DIRS)
touch .links
%/src/.dir:
mkdir -p $(dir $@)
cd $(dir $@); ln -sf $(PRJ_ROOT)/examples/StepperDemo/* .
run_avr: simavr/simavr/run_avr
ln -s simavr/simavr/run_avr .
simavr/simavr/run_avr: simavr/simavr/sim/run_avr.c
make -C simavr build-simavr
simavr/simavr/sim/run_avr.c:
# git clone https://github.com/gin66/simavr.git
git clone https://github.com/buserror/simavr.git
(cd simavr;git checkout 132cc67)
proper: clean
rm -f run_avr
rm -fR simavr
clean:
rm -fR */.pio */.tested */x.vcd */result.txt
find . -type l -delete
find . -type d -empty -delete
rm -f .links .makefiles

View File

@@ -0,0 +1,127 @@
#
# In order to execute the test for one directory use:
#
# make -C test_sd_01b_328p -f ../Makefile.test
SRC=$(wildcard ../../../src/*) $(wildcard src/*)
# platformio should contain only one env section.
# This section states the dut name
# atmega168
# atmega168p
# atmega328
# atmega328p
# atmega2560_timer1
# atmega2560_timer3
# atmega2560_timer4
# atmega2560_timer5
#
DUT=$(shell gawk '/env:/{print(substr($$1,6,length($$1)-6))}' platformio.ini)
TRACES=-at StepISR=trace@0x25/0x08 # PB3
TRACES+=-at FillISR=trace@0x25/0x10 # PB4
#
ifeq ($(DUT),atmega2560_timer1)
DEVICE=atmega2560
TRACES+=-at StepA=trace@0x025/0x20 #OC1A PB5 11 ATMega2560
TRACES+=-at StepB=trace@0x025/0x40 #OC1B PB6 12 ATMega2560
TRACES+=-at StepC=trace@0x025/0x80 #OC1C PB7 13 ATMega2560
#
else ifeq ($(DUT),atmega2560_timer3)
DEVICE=atmega2560
TRACES+=-at StepA=trace@0x02e/0x08 #OC3A PE3 5 ATMega2560
TRACES+=-at StepB=trace@0x02e/0x10 #OC3B PE4 2 ATMega2560
TRACES+=-at StepC=trace@0x02e/0x20 #OC3C PE5 3 ATMega2560
#
else ifeq ($(DUT),atmega2560_timer4)
DEVICE=atmega2560
TRACES+=-at StepA=trace@0x102/0x08 #OC4A PH3 6 ATMega2560
TRACES+=-at StepB=trace@0x102/0x10 #OC4B PH4 7 ATMega2560
TRACES+=-at StepC=trace@0x102/0x20 #OC4C PH5 8 ATMega2560
#
else ifeq ($(DUT),atmega2560_timer5)
DEVICE=atmega2560
TRACES+=-at StepA=trace@0x10b/0x08 #OC5A PL3 46 ATMega2560
TRACES+=-at StepB=trace@0x10b/0x10 #OC5B PL4 45 ATMega2560
TRACES+=-at StepC=trace@0x10b/0x20 #OC5C PL5 44 ATMega2560
else ifeq ($(DUT),atmega168)
DEVICE=atmega168
TRACES+=-at StepA=trace@0x25/0x02 #OC1A PB1 9 ATMega168
TRACES+=-at StepB=trace@0x25/0x04 #OC1B PB2 10 ATMega168
else ifeq ($(DUT),atmega168p)
DEVICE=atmega168p
TRACES+=-at StepA=trace@0x25/0x02 #OC1A PB1 9 ATMega168p
TRACES+=-at StepB=trace@0x25/0x04 #OC1B PB2 10 ATMega168p
else ifeq ($(DUT),atmega328)
DEVICE=atmega328
TRACES+=-at StepA=trace@0x25/0x02 #OC1A PB1 9 ATMega328
TRACES+=-at StepB=trace@0x25/0x04 #OC1B PB2 10 ATMega328
else ifeq ($(DUT),atmega328p)
DEVICE=atmega328p
TRACES+=-at StepA=trace@0x25/0x02 #OC1A PB1 9 ATMega328p
TRACES+=-at StepB=trace@0x25/0x04 #OC1B PB2 10 ATMega328p
else ifeq ($(DUT),atmega32u4)
DEVICE=atmega32u4
TRACES+=-at StepA=trace@0x025/0x20 #OC1A PB5 11
TRACES+=-at StepB=trace@0x025/0x40 #OC1B PB6 12
#TRACES+=-at StepC=trace@0x025/0x80 #OC1C PB7 13
endif
ifeq ($(DEVICE),atmega2560)
TRACES+=-at DirA=trace@0x2b/0x01 # Pin 21 PD0
TRACES+=-at DirB=trace@0x2b/0x02 # Pin 20 PD1
TRACES+=-at DirC=trace@0x10b/0x80 # Pin 42 PL7
TRACES+=-at EnableA=trace@0x2b/0x04 # Pin 19 PD2
TRACES+=-at EnableB=trace@0x2b/0x08 # Pin 18 PD3
TRACES+=-at EnableC=trace@0x10b/0x40 # Pin 43 PL6
else ifeq ($(DEVICE),$(filter $(DEVICE),atmega168 atmega168p atmega328 atmega328p))
TRACES+=-at DirA=trace@0x2b/0x20 # Pin 5 PD5
TRACES+=-at DirB=trace@0x2b/0x80 # Pin 7 PD7
TRACES+=-at EnableA=trace@0x2b/0x40 # Pin 6 PD6
TRACES+=-at EnableB=trace@0x25/0x01 # Pin 0 PB0
else ifeq ($(DUT),atmega32u4)
TRACES+=-at DirA=trace@0x25/0x10 # Pin 26 PB4
TRACES+=-at DirB=trace@0x25/0x08 # Pin 14 PB3
#TRACES+=-at DirC=trace@0x10b/0x80 # Pin 42 PL7
TRACES+=-at EnableA=trace@0x25/0x04 # Pin 16 PB2
TRACES+=-at EnableB=trace@0x25/0x02 # Pin 15 PB1
#TRACES+=-at EnableC=trace@0x10b/0x40 # Pin 43 PL6
endif
FIRMWARE=".pio/build/$(DUT)/firmware.elf"
DIR=$(shell env pwd)
ifndef SILENCE
SILENCE=0
endif
test: .tested
.tested: result.txt expect.txt ../judge.awk
echo DUT=$(DUT)
rm -f .tested
gawk -f ../judge.awk -v DIR=$(DIR) result.txt expect.txt
test -f .tested
result.txt: x.vcd
gawk -v SILENCE=$(SILENCE) -f ../eval.awk x.vcd
cat expect.txt
x.vcd: $(SRC) ../run_avr platformio.ini
env pio run -e $(DUT) || ~/.platformio/penv/bin/pio run -e $(DUT) || ~/.local/bin/pio run -e $(DUT)
../run_avr $(FIRMWARE) -m $(DEVICE) -o x.vcd $(TRACES)
clean:
rm -fR .pio .tested x.vcd result.txt

View File

@@ -0,0 +1,31 @@
; PlatformIO Project Configuration File
;
; Build options: build flags, source filter
; Upload options: custom upload port, speed and extra flags
; Library options: dependencies, extra library storages
; Advanced options: extra scripting
;
; Please visit documentation for the other options and examples
; https://docs.platformio.org/page/projectconf.html
[platformio]
# There should be only one env section for the DUT under test.
# One of
# atmega168p
# atmega328p
# atmega2560_timer1
# atmega2560_timer3
# atmega2560_timer4
# atmega2560_timer5
#
[common]
# This is the line input to StepperDemo:
build_flags = -D SIM_TEST_INPUT='"? M1 V60 A40000 f w400 A40000 P0 w1000 W "'
[env:atmega328p]
platform = atmelavr
board = nanoatmega328
framework = arduino
build_flags = -Werror -Wall ${common.build_flags}
lib_extra_dirs = ../../../../..

View File

@@ -0,0 +1,128 @@
BEGIN {
ref = 16*100
dump_all = 0
}
dump_all == 1{print}
/^\$var wire 1/ {
names[++name_i] = $5
sym[$4] = $5
to_sym[$5] = $4
period_hl_hl[$4] = 0
period_lh_lh[$4] = 0
time_h[$4] = 0
time_l[$4] = 0
transition_l_h[$4] = 0
transition_h_l[$4] = 0
cnt_l_h[$4] = 0
cnt_h_l[$4] = 0
max_time_h[$4] = 0
sum_time_h[$4] = 0
state[$4] = "X"
}
/^#/ { time = substr($1,2) + 0 }
/^1.$/ {
s = substr($1,2)
if(!SILENCE) printf("%s=1 ", sym[s])
if (state[s] == 0) {
# transition L->H
cnt_l_h[s]++
last = transition_l_h[s]
transition_l_h[s] = time
if (last > 0) {
period_lh_lh[s] = time - last
}
last = transition_h_l[s]
if (last > 0) {
time_l[s] = time - last
}
if (sym[s] ~ /Step/) {
channel = substr(sym[s],5)
if(!SILENCE) printf("%s: ", channel)
dir = "Dir" channel
if (dir in to_sym) {
dir_sym = to_sym[dir]
if (state[dir_sym] == 0) {
position[channel]--
}
else {
position[channel]++
}
if(!SILENCE) printf("position=%d ",position[channel])
}
if(!SILENCE) printf("period=%.1fus high time=%.1fus",
period_lh_lh[s]/ref,time_h[s]/ref)
}
}
if(!SILENCE) printf("\n")
state[s] = 1
}
/^0.$/ {
s = substr($1,2)
if(!SILENCE) printf("%s=0 ", sym[s])
if (state[s] == 1) {
# transition H->L
cnt_h_l[s]++
last = transition_h_l[s]
transition_h_l[s] = time
if (last > 0) {
period_hl_hl[s] = time - last
}
last = transition_l_h[s]
if (last > 0) {
time_h[s] = time - last
}
if (sym[s] ~ /FillISR/) {
if(!SILENCE) printf("period=%.1fus ", period_lh_lh[s]/ref)
}
h_time = time_h[s]/ref
if(!SILENCE) printf("high time=%.1fus", h_time)
sum_time_h[s] += h_time
if (h_time > max_time_h[s]) {
max_time_h[s] = h_time
}
}
if(!SILENCE) printf("\n")
state[s] = 0
}
END {
n = asort(names)
for (i = 1;i <= n;i++) {
name = names[i]
s = to_sym[name]
info = sprintf("%8s: %8d*L->H, %8d*H->L",name,cnt_l_h[s],cnt_h_l[s])
if (name ~ /Step/) {
info = sprintf("%s, Max High=%dus Total High=%dus", info, max_time_h[s], sum_time_h[s])
}
if(!SILENCE) print(info)
if (name !~ /ISR/) {
print(info) >"result.txt"
}
}
channels["A"]=1
channels["B"]=1
channels["C"]=1
for (ch in channels) {
if (ch in position) {
info = sprintf("Position[%s]=%d\n",ch,position[ch])
if(!SILENCE) print(info)
print(info) >"result.txt"
}
}
for (i = 1;i <= n;i++) {
name = names[i]
s = to_sym[name]
if (max_time_h[s] > 0) {
info = sprintf("Time in %s max=%d us, total=%d us\n",name,max_time_h[s], sum_time_h[s])
if(!SILENCE) print(info)
print(info) >"result.txt"
}
}
}

View File

@@ -0,0 +1,38 @@
BEGIN {
ok = 1
timing = 0
if (DIR ~ /timing/) {
timing = 1
}
}
FNR == NR {
# result.txt
lines[FNR] = $0
}
FNR != NR {
# expect.txt
r = lines[FNR]
e = $0
r_test = r
e_test = e
if (timing == 0) {
gsub(/[0-9 ]*us/,"", r_test)
gsub(/[0-9 ]*us/,"", e_test)
}
if (e_test != r_test) {
print("result:",r)
print("expect:",e)
ok = 0
}
}
END {
if (ok == 1) {
print("PASS")
print("PASS") > ".tested"
}
}

View File

@@ -0,0 +1,22 @@
BEGIN {
ok = 0
}
FNR == NR {
# result.txt
lines[FNR] = $0
}
/^Position\[A\]/ {
print
}
$0 == "Position[A]=0" {
ok = 1
}
END {
if (ok == 1) {
print("PASS")
print("PASS") > ".tested"
}
}

View File

@@ -0,0 +1,26 @@
; PlatformIO Project Configuration File
;
; Build options: build flags, source filter
; Upload options: custom upload port, speed and extra flags
; Library options: dependencies, extra library storages
; Advanced options: extra scripting
;
; Please visit documentation for the other options and examples
; https://docs.platformio.org/page/projectconf.html
[platformio]
[env:avr]
platform = atmelavr
board = nanoatmega328
framework = arduino
build_flags = -Werror -Wall -D SIM_TEST_INPUT='"t M1 03 I R W "' -DSIMAVR_FOC_WORKAROUND
lib_extra_dirs = ../../../../..
[env:atmega2560]
platform = atmelavr
board = megaatmega2560
framework = arduino
build_flags = -Werror -Wall
lib_extra_dirs = ../../../../..

View File

@@ -0,0 +1,26 @@
; PlatformIO Project Configuration File
;
; Build options: build flags, source filter
; Upload options: custom upload port, speed and extra flags
; Library options: dependencies, extra library storages
; Advanced options: extra scripting
;
; Please visit documentation for the other options and examples
; https://docs.platformio.org/page/projectconf.html
[platformio]
[env:avr]
platform = atmelavr
board = nanoatmega328
framework = arduino
build_flags = -Werror -Wall -D SIM_TEST_INPUT='"t M1 04 I R W "' -DSIMAVR_FOC_WORKAROUND
lib_extra_dirs = ../../../../..
[env:atmega2560]
platform = atmelavr
board = megaatmega2560
framework = arduino
build_flags = -Werror -Wall
lib_extra_dirs = ../../../../..

View File

@@ -0,0 +1,26 @@
; PlatformIO Project Configuration File
;
; Build options: build flags, source filter
; Upload options: custom upload port, speed and extra flags
; Library options: dependencies, extra library storages
; Advanced options: extra scripting
;
; Please visit documentation for the other options and examples
; https://docs.platformio.org/page/projectconf.html
[platformio]
[env:avr]
platform = atmelavr
board = nanoatmega328
framework = arduino
build_flags = -Werror -Wall -D SIM_TEST_INPUT='"t M1 05 I R W "' -DSIMAVR_FOC_WORKAROUND
lib_extra_dirs = ../../../../..
[env:atmega2560]
platform = atmelavr
board = megaatmega2560
framework = arduino
build_flags = -Werror -Wall
lib_extra_dirs = ../../../../..

View File

@@ -0,0 +1,30 @@
; PlatformIO Project Configuration File
;
; Build options: build flags, source filter
; Upload options: custom upload port, speed and extra flags
; Library options: dependencies, extra library storages
; Advanced options: extra scripting
;
; Please visit documentation for the other options and examples
; https://docs.platformio.org/page/projectconf.html
[platformio]
# There should be only one env section for the DUT under test.
# One of
# atmega168p
# atmega328p
# atmega2560_timer1
# atmega2560_timer3
# atmega2560_timer4
# atmega2560_timer5
#
[common]
build_flags = -DTEST_TIMING
[env:atmega328p]
platform = atmelavr
board = nanoatmega328
framework = arduino
build_flags = -Werror -Wall -DSIMAVR_FOC_WORKAROUND ${common.build_flags}
lib_extra_dirs = ../../../../..

View File

@@ -0,0 +1,40 @@
#include <avr/sleep.h>
#include <AVRStepperPins.h>
#include <RampCalculator.h>
float acceleration_f;
uint32_t acceleration_i;
uint32_t steps;
void setup() {
Serial.begin(115200);
Serial.println("Start");
digitalWrite(stepPinStepperA, LOW);
digitalWrite(stepPinStepperB, LOW);
pinMode(stepPinStepperA, OUTPUT);
pinMode(stepPinStepperB, OUTPUT);
acceleration_f = 12345.0;
acceleration_i = 12345.0;
steps = 10;
}
void loop() {
digitalWrite(stepPinStepperA, HIGH);
uint32_t x;
// x = calculate_ticks_v1(steps, acceleration_f);
// x = calculate_ticks_v2(steps, acceleration_f);
// x = calculate_ticks_v3(steps, acceleration_f);
// x = calculate_ticks_v4(steps, acceleration_i);
// x = calculate_ticks_v5(steps, acceleration_i);
// x = calculate_ticks_v7(0x1234000, 1000);
x = calculate_ticks_v8(0x1234000, 1000);
digitalWrite(stepPinStepperA, LOW);
digitalWrite(stepPinStepperB, HIGH);
digitalWrite(stepPinStepperB, LOW);
Serial.println(x);
delay(100);
noInterrupts();
sleep_cpu();
}

View File

@@ -0,0 +1 @@
src/

View File

@@ -0,0 +1,131 @@
#
# In order to execute the test for one directory use:
#
# make -C test_sd_01b_328p -f ../Makefile.test
SRC=$(wildcard ../../../src/*) $(wildcard src/*)
# platformio should contain only one env section.
# This section states the dut name
# atmega168
# atmega168p
# atmega328
# atmega328p
# atmega2560_timer1
# atmega2560_timer3
# atmega2560_timer4
# atmega2560_timer5
#
DUT=$(shell gawk '/env:/{print(substr($$1,6,length($$1)-6))}' platformio.ini)
TRACES=-at StepISR=trace@0x25/0x08 # PB3
TRACES+=-at FillISR=trace@0x25/0x10 # PB4
#
ifeq ($(DUT),atmega2560_timer1)
DEVICE=atmega2560
TRACES+=-at StepA=trace@0x025/0x20 #OC1A PB5 11 ATMega2560
TRACES+=-at StepB=trace@0x025/0x40 #OC1B PB6 12 ATMega2560
TRACES+=-at StepC=trace@0x025/0x80 #OC1C PB7 13 ATMega2560
#
else ifeq ($(DUT),atmega2560_timer3)
DEVICE=atmega2560
TRACES+=-at StepA=trace@0x02e/0x08 #OC3A PE3 5 ATMega2560
TRACES+=-at StepB=trace@0x02e/0x10 #OC3B PE4 2 ATMega2560
TRACES+=-at StepC=trace@0x02e/0x20 #OC3C PE5 3 ATMega2560
#
else ifeq ($(DUT),atmega2560_timer4)
DEVICE=atmega2560
TRACES+=-at StepA=trace@0x102/0x08 #OC4A PH3 6 ATMega2560
TRACES+=-at StepB=trace@0x102/0x10 #OC4B PH4 7 ATMega2560
TRACES+=-at StepC=trace@0x102/0x20 #OC4C PH5 8 ATMega2560
#
else ifeq ($(DUT),atmega2560_timer5)
DEVICE=atmega2560
TRACES+=-at StepA=trace@0x10b/0x08 #OC5A PL3 46 ATMega2560
TRACES+=-at StepB=trace@0x10b/0x10 #OC5B PL4 45 ATMega2560
TRACES+=-at StepC=trace@0x10b/0x20 #OC5C PL5 44 ATMega2560
else ifeq ($(DUT),atmega168)
DEVICE=atmega168
TRACES+=-at StepA=trace@0x25/0x02 #OC1A PB1 9 ATMega168
TRACES+=-at StepB=trace@0x25/0x04 #OC1B PB2 10 ATMega168
else ifeq ($(DUT),atmega168p)
DEVICE=atmega168p
TRACES+=-at StepA=trace@0x25/0x02 #OC1A PB1 9 ATMega168p
TRACES+=-at StepB=trace@0x25/0x04 #OC1B PB2 10 ATMega168p
else ifeq ($(DUT),atmega328)
DEVICE=atmega328
TRACES+=-at StepA=trace@0x25/0x02 #OC1A PB1 9 ATMega328
TRACES+=-at StepB=trace@0x25/0x04 #OC1B PB2 10 ATMega328
else ifeq ($(DUT),atmega328p)
DEVICE=atmega328p
TRACES+=-at StepA=trace@0x25/0x02 #OC1A PB1 9 ATMega328p
TRACES+=-at StepB=trace@0x25/0x04 #OC1B PB2 10 ATMega328p
else ifeq ($(DUT),atmega32u4)
DEVICE=atmega32u4
TRACES+=-at StepA=trace@0x025/0x20 #OC1A PB5 11
TRACES+=-at StepB=trace@0x025/0x40 #OC1B PB6 12
#TRACES+=-at StepC=trace@0x025/0x80 #OC1C PB7 13
endif
ifeq ($(DEVICE),atmega2560)
TRACES+=-at DirA=trace@0x2b/0x01 # Pin 21 PD0
TRACES+=-at DirB=trace@0x2b/0x02 # Pin 20 PD1
TRACES+=-at DirC=trace@0x10b/0x80 # Pin 42 PL7
TRACES+=-at EnableA=trace@0x2b/0x04 # Pin 19 PD2
TRACES+=-at EnableB=trace@0x2b/0x08 # Pin 18 PD3
TRACES+=-at EnableC=trace@0x10b/0x40 # Pin 43 PL6
else ifeq ($(DEVICE),$(filter $(DEVICE),atmega168 atmega168p atmega328 atmega328p))
TRACES+=-at DirA=trace@0x2b/0x20 # Pin 5 PD5
TRACES+=-at DirB=trace@0x2b/0x80 # Pin 7 PD7
TRACES+=-at EnableA=trace@0x2b/0x40 # Pin 6 PD6
TRACES+=-at EnableB=trace@0x25/0x01 # Pin 8 PB0
else ifeq ($(DUT),atmega32u4)
TRACES+=-at DirA=trace@0x25/0x10 # Pin 26 PB4
TRACES+=-at DirB=trace@0x25/0x08 # Pin 14 PB3
#TRACES+=-at DirC=trace@0x10b/0x80 # Pin 42 PL7
TRACES+=-at EnableA=trace@0x25/0x04 # Pin 16 PB2
TRACES+=-at EnableB=trace@0x25/0x02 # Pin 15 PB1
#TRACES+=-at EnableC=trace@0x10b/0x40 # Pin 43 PL6
endif
FIRMWARE=".pio/build/$(DUT)/firmware.elf"
DIR=$(shell env pwd)
ifndef SILENCE
SILENCE=0
endif
test: .tested
.tested: result.txt expect.txt ../judge.awk
echo DUT=$(DUT)
rm -f .tested
gawk -f ../judge.awk -v DIR=$(DIR) result.txt expect.txt
test -f .tested
result.txt: x.vcd
gawk -v SILENCE=$(SILENCE) -f ../eval.awk x.vcd
cat expect.txt
x.vcd: $(SRC) ../run_avr platformio.ini src/ExternalCall.ino
~/.platformio/penv/bin/pio run -e $(DUT) || ~/.local/bin/pio run -e $(DUT) || env pio run -e $(DUT)
../run_avr $(FIRMWARE) -m $(DEVICE) -o x.vcd $(TRACES)
src/ExternalCall.ino:
mkdir -p src
cd src; ln -s ../../../../../examples/ExternalCall/ExternalCall.ino .
clean:
rm -fR .pio .tested x.vcd result.txt

View File

@@ -0,0 +1,22 @@
DirA: 3*L->H, 2*H->L
DirB: 3*L->H, 2*H->L
EnableA: 2*L->H, 1*H->L
EnableB: 2*L->H, 1*H->L
StepA: 2890*L->H, 2890*H->L, Max High=9us Total High=13574us
StepB: 2890*L->H, 2890*H->L, Max High=9us Total High=13454us
Position[A]=190
Position[B]=190
Time in DirA max=10063958 us, total=15122519 us
Time in DirB max=39260160 us, total=44318721 us
Time in EnableA max=4162 us, total=4162 us
Time in EnableB max=29200356 us, total=29200356 us
Time in StepA max=9 us, total=13574 us
Time in StepB max=9 us, total=13454 us

View File

@@ -0,0 +1,31 @@
; PlatformIO Project Configuration File
;
; Build options: build flags, source filter
; Upload options: custom upload port, speed and extra flags
; Library options: dependencies, extra library storages
; Advanced options: extra scripting
;
; Please visit documentation for the other options and examples
; https://docs.platformio.org/page/projectconf.html
[platformio]
# There should be only one env section for the DUT under test.
# One of
# atmega168p
# atmega328p
# atmega2560_timer1
# atmega2560_timer3
# atmega2560_timer4
# atmega2560_timer5
#
[common]
# This is the line input to StepperDemo:
build_flags = -D SIMULATOR
[env:atmega328p]
platform = atmelavr
board = nanoatmega328
framework = arduino
build_flags = -Werror -Wall ${common.build_flags}
lib_extra_dirs = ../../../../..

View File

@@ -0,0 +1 @@
src/

View File

@@ -0,0 +1,132 @@
#
# In order to execute the test for one directory use:
#
# make -C test_sd_01b_328p -f ../Makefile.test
SRC=$(wildcard ../../../src/*) $(wildcard src/*)
# platformio should contain only one env section.
# This section states the dut name
# atmega168
# atmega168p
# atmega328
# atmega328p
# atmega2560_timer1
# atmega2560_timer3
# atmega2560_timer4
# atmega2560_timer5
#
DUT=$(shell gawk '/env:/{print(substr($$1,6,length($$1)-6))}' platformio.ini)
TRACES=-at StepISR=trace@0x25/0x08 # PB3
TRACES+=-at FillISR=trace@0x25/0x10 # PB4
#
ifeq ($(DUT),atmega2560_timer1)
DEVICE=atmega2560
TRACES+=-at StepA=trace@0x025/0x20 #OC1A PB5 11 ATMega2560
TRACES+=-at StepB=trace@0x025/0x40 #OC1B PB6 12 ATMega2560
TRACES+=-at StepC=trace@0x025/0x80 #OC1C PB7 13 ATMega2560
#
else ifeq ($(DUT),atmega2560_timer3)
DEVICE=atmega2560
TRACES+=-at StepA=trace@0x02e/0x08 #OC3A PE3 5 ATMega2560
TRACES+=-at StepB=trace@0x02e/0x10 #OC3B PE4 2 ATMega2560
TRACES+=-at StepC=trace@0x02e/0x20 #OC3C PE5 3 ATMega2560
#
else ifeq ($(DUT),atmega2560_timer4)
DEVICE=atmega2560
TRACES+=-at StepA=trace@0x102/0x08 #OC4A PH3 6 ATMega2560
TRACES+=-at StepB=trace@0x102/0x10 #OC4B PH4 7 ATMega2560
TRACES+=-at StepC=trace@0x102/0x20 #OC4C PH5 8 ATMega2560
#
else ifeq ($(DUT),atmega2560_timer5)
DEVICE=atmega2560
TRACES+=-at StepA=trace@0x10b/0x08 #OC5A PL3 46 ATMega2560
TRACES+=-at StepB=trace@0x10b/0x10 #OC5B PL4 45 ATMega2560
TRACES+=-at StepC=trace@0x10b/0x20 #OC5C PL5 44 ATMega2560
else ifeq ($(DUT),atmega168)
DEVICE=atmega168
TRACES+=-at StepA=trace@0x25/0x02 #OC1A PB1 9 atmega168
TRACES+=-at StepB=trace@0x25/0x04 #OC1B PB2 10 atmega168
else ifeq ($(DUT),atmega168p)
DEVICE=atmega168p
TRACES+=-at StepA=trace@0x25/0x02 #OC1A PB1 9 atmega168p
TRACES+=-at StepB=trace@0x25/0x04 #OC1B PB2 10 atmega168p
else ifeq ($(DUT),atmega328)
DEVICE=atmega328
TRACES+=-at StepA=trace@0x25/0x02 #OC1A PB1 9 ATMega328
TRACES+=-at StepB=trace@0x25/0x04 #OC1B PB2 10 ATMega328
else ifeq ($(DUT),atmega328p)
DEVICE=atmega328p
TRACES+=-at StepA=trace@0x25/0x02 #OC1A PB1 9 ATMega328p
TRACES+=-at StepB=trace@0x25/0x04 #OC1B PB2 10 ATMega328p
else ifeq ($(DUT),atmega32u4)
DEVICE=atmega32u4
TRACES+=-at StepA=trace@0x025/0x20 #OC1A PB5 11
TRACES+=-at StepB=trace@0x025/0x40 #OC1B PB6 12
#TRACES+=-at StepC=trace@0x025/0x80 #OC1C PB7 13
endif
ifeq ($(DEVICE),atmega2560)
TRACES+=-at DirA=trace@0x2b/0x01 # Pin 21 PD0
TRACES+=-at DirB=trace@0x2b/0x02 # Pin 20 PD1
TRACES+=-at DirC=trace@0x10b/0x80 # Pin 42 PL7
TRACES+=-at EnableA=trace@0x2b/0x04 # Pin 19 PD2
TRACES+=-at EnableB=trace@0x2b/0x08 # Pin 18 PD3
TRACES+=-at EnableC=trace@0x10b/0x40 # Pin 43 PL6
else ifeq ($(DEVICE),$(filter $(DEVICE),atmega168 atmega168p atmega328 atmega328p))
TRACES+=-at DirA=trace@0x2b/0x20 # Pin 5 PD5
TRACES+=-at DirB=trace@0x2b/0x80 # Pin 7 PD7
TRACES+=-at EnableA=trace@0x2b/0x40 # Pin 6 PD6
TRACES+=-at EnableB=trace@0x25/0x01 # Pin 8 PB0
else ifeq ($(DUT),atmega32u4)
TRACES+=-at DirA=trace@0x25/0x10 # Pin 26 PB4
TRACES+=-at DirB=trace@0x25/0x08 # Pin 14 PB3
#TRACES+=-at DirC=trace@0x10b/0x80 # Pin 42 PL7
TRACES+=-at EnableA=trace@0x25/0x04 # Pin 16 PB2
TRACES+=-at EnableB=trace@0x25/0x02 # Pin 15 PB1
#TRACES+=-at EnableC=trace@0x10b/0x40 # Pin 43 PL6
endif
FIRMWARE=".pio/build/$(DUT)/firmware.elf"
DIR=$(shell env pwd)
ifndef SILENCE
SILENCE=0
endif
test: .tested
.tested: result.txt expect.txt ../judge.awk
echo DUT=$(DUT)
rm -f .tested
gawk -f ../judge.awk -v DIR=$(DIR) result.txt expect.txt
test -f .tested
result.txt: x.vcd
gawk -v SILENCE=$(SILENCE) -f ../eval.awk x.vcd >/dev/null
cat expect.txt
x.vcd: $(SRC) ../run_avr platformio.ini src/Issue150.ino
~/.platformio/penv/bin/pio run -e $(DUT) || ~/.local/bin/pio run -e $(DUT) || env pio run -e $(DUT)
../run_avr $(FIRMWARE) -m $(DEVICE) -o x.vcd $(TRACES)
src/Issue150.ino:
mkdir -p src
cd src; ln -s ../../../../../examples/Issue150/Issue150.ino .
clean:
rm -fR .pio .tested x.vcd result.txt

View File

@@ -0,0 +1,16 @@
DirA: 0*L->H, 0*H->L
DirB: 1*L->H, 0*H->L
EnableA: 2*L->H, 1*H->L
EnableB: 0*L->H, 0*H->L
StepA: 4000*L->H, 4000*H->L, Max High=10us Total High=20775us
StepB: 2*L->H, 2*H->L, Max High=4us Total High=9us
Position[A]=4000
Position[B]=2
Time in EnableA max=4194 us, total=4194 us
Time in StepA max=10 us, total=20775 us
Time in StepB max=4 us, total=9 us

View File

@@ -0,0 +1,31 @@
; PlatformIO Project Configuration File
;
; Build options: build flags, source filter
; Upload options: custom upload port, speed and extra flags
; Library options: dependencies, extra library storages
; Advanced options: extra scripting
;
; Please visit documentation for the other options and examples
; https://docs.platformio.org/page/projectconf.html
[platformio]
# There should be only one env section for the DUT under test.
# One of
# atmega168p
# atmega328p
# atmega2560_timer1
# atmega2560_timer3
# atmega2560_timer4
# atmega2560_timer5
#
[common]
# This is the line input to StepperDemo:
build_flags = -D SIMULATOR
[env:atmega328p]
platform = atmelavr
board = nanoatmega328
framework = arduino
build_flags = -Werror -Wall ${common.build_flags}
lib_extra_dirs = ../../../../..

View File

@@ -0,0 +1 @@
src/

View File

@@ -0,0 +1,132 @@
#
# In order to execute the test for one directory use:
#
# make -C test_sd_01b_328p -f ../Makefile.test
SRC=$(wildcard ../../../src/*) $(wildcard src/*)
# platformio should contain only one env section.
# This section states the dut name
# atmega168
# atmega168p
# atmega328
# atmega328p
# atmega2560_timer1
# atmega2560_timer3
# atmega2560_timer4
# atmega2560_timer5
#
DUT=$(shell gawk '/env:/{print(substr($$1,6,length($$1)-6))}' platformio.ini)
TRACES=-at StepISR=trace@0x25/0x08 # PB3
TRACES+=-at FillISR=trace@0x25/0x10 # PB4
#
ifeq ($(DUT),atmega2560_timer1)
DEVICE=atmega2560
TRACES+=-at StepA=trace@0x025/0x20 #OC1A PB5 11 ATMega2560
TRACES+=-at StepB=trace@0x025/0x40 #OC1B PB6 12 ATMega2560
TRACES+=-at StepC=trace@0x025/0x80 #OC1C PB7 13 ATMega2560
#
else ifeq ($(DUT),atmega2560_timer3)
DEVICE=atmega2560
TRACES+=-at StepA=trace@0x02e/0x08 #OC3A PE3 5 ATMega2560
TRACES+=-at StepB=trace@0x02e/0x10 #OC3B PE4 2 ATMega2560
TRACES+=-at StepC=trace@0x02e/0x20 #OC3C PE5 3 ATMega2560
#
else ifeq ($(DUT),atmega2560_timer4)
DEVICE=atmega2560
TRACES+=-at StepA=trace@0x102/0x08 #OC4A PH3 6 ATMega2560
TRACES+=-at StepB=trace@0x102/0x10 #OC4B PH4 7 ATMega2560
TRACES+=-at StepC=trace@0x102/0x20 #OC4C PH5 8 ATMega2560
#
else ifeq ($(DUT),atmega2560_timer5)
DEVICE=atmega2560
TRACES+=-at StepA=trace@0x10b/0x08 #OC5A PL3 46 ATMega2560
TRACES+=-at StepB=trace@0x10b/0x10 #OC5B PL4 45 ATMega2560
TRACES+=-at StepC=trace@0x10b/0x20 #OC5C PL5 44 ATMega2560
else ifeq ($(DUT),atmega168)
DEVICE=atmega168
TRACES+=-at StepA=trace@0x25/0x02 #OC1A PB1 9 atmega168
TRACES+=-at StepB=trace@0x25/0x04 #OC1B PB2 10 atmega168
else ifeq ($(DUT),atmega168p)
DEVICE=atmega168p
TRACES+=-at StepA=trace@0x25/0x02 #OC1A PB1 9 atmega168p
TRACES+=-at StepB=trace@0x25/0x04 #OC1B PB2 10 atmega168p
else ifeq ($(DUT),atmega328)
DEVICE=atmega328
TRACES+=-at StepA=trace@0x25/0x02 #OC1A PB1 9 ATMega328
TRACES+=-at StepB=trace@0x25/0x04 #OC1B PB2 10 ATMega328
else ifeq ($(DUT),atmega328p)
DEVICE=atmega328p
TRACES+=-at StepA=trace@0x25/0x02 #OC1A PB1 9 ATMega328p
TRACES+=-at StepB=trace@0x25/0x04 #OC1B PB2 10 ATMega328p
else ifeq ($(DUT),atmega32u4)
DEVICE=atmega32u4
TRACES+=-at StepA=trace@0x025/0x20 #OC1A PB5 11
TRACES+=-at StepB=trace@0x025/0x40 #OC1B PB6 12
#TRACES+=-at StepC=trace@0x025/0x80 #OC1C PB7 13
endif
ifeq ($(DEVICE),atmega2560)
TRACES+=-at DirA=trace@0x2b/0x01 # Pin 21 PD0
TRACES+=-at DirB=trace@0x2b/0x02 # Pin 20 PD1
TRACES+=-at DirC=trace@0x10b/0x80 # Pin 42 PL7
TRACES+=-at EnableA=trace@0x2b/0x04 # Pin 19 PD2
TRACES+=-at EnableB=trace@0x2b/0x08 # Pin 18 PD3
TRACES+=-at EnableC=trace@0x10b/0x40 # Pin 43 PL6
else ifeq ($(DEVICE),$(filter $(DEVICE),atmega168 atmega168p atmega328 atmega328p))
TRACES+=-at DirA=trace@0x2b/0x20 # Pin 5 PD5
TRACES+=-at DirB=trace@0x2b/0x80 # Pin 7 PD7
TRACES+=-at EnableA=trace@0x2b/0x40 # Pin 6 PD6
TRACES+=-at EnableB=trace@0x25/0x01 # Pin 8 PB0
else ifeq ($(DUT),atmega32u4)
TRACES+=-at DirA=trace@0x25/0x10 # Pin 26 PB4
TRACES+=-at DirB=trace@0x25/0x08 # Pin 14 PB3
#TRACES+=-at DirC=trace@0x10b/0x80 # Pin 42 PL7
TRACES+=-at EnableA=trace@0x25/0x04 # Pin 16 PB2
TRACES+=-at EnableB=trace@0x25/0x02 # Pin 15 PB1
#TRACES+=-at EnableC=trace@0x10b/0x40 # Pin 43 PL6
endif
FIRMWARE=".pio/build/$(DUT)/firmware.elf"
DIR=$(shell env pwd)
ifndef SILENCE
SILENCE=0
endif
test: .tested
.tested: result.txt expect.txt ../judge.awk
echo DUT=$(DUT)
rm -f .tested
gawk -f ../judge.awk -v DIR=$(DIR) result.txt expect.txt
test -f .tested
result.txt: x.vcd
gawk -v SILENCE=$(SILENCE) -f ../eval.awk x.vcd >/dev/null
cat expect.txt
x.vcd: $(SRC) ../run_avr platformio.ini src/Issue151.ino
~/.platformio/penv/bin/pio run -e $(DUT) || ~/.local/bin/pio run -e $(DUT) || env pio run -e $(DUT)
../run_avr $(FIRMWARE) -m $(DEVICE) -o x.vcd $(TRACES)
src/Issue151.ino:
mkdir -p src
cd src; ln -s ../../../../../examples/Issue151/Issue151.ino .
clean:
rm -fR .pio .tested x.vcd result.txt

View File

@@ -0,0 +1,16 @@
DirA: 0*L->H, 0*H->L
DirB: 1*L->H, 0*H->L
EnableA: 2*L->H, 1*H->L
EnableB: 0*L->H, 0*H->L
StepA: 20000*L->H, 20000*H->L, Max High=10us Total High=101913us
StepB: 2*L->H, 2*H->L, Max High=4us Total High=9us
Position[A]=20000
Position[B]=2
Time in EnableA max=4203 us, total=4203 us
Time in StepA max=10 us, total=101913 us
Time in StepB max=4 us, total=9 us

View File

@@ -0,0 +1,31 @@
; PlatformIO Project Configuration File
;
; Build options: build flags, source filter
; Upload options: custom upload port, speed and extra flags
; Library options: dependencies, extra library storages
; Advanced options: extra scripting
;
; Please visit documentation for the other options and examples
; https://docs.platformio.org/page/projectconf.html
[platformio]
# There should be only one env section for the DUT under test.
# One of
# atmega168p
# atmega328p
# atmega2560_timer1
# atmega2560_timer3
# atmega2560_timer4
# atmega2560_timer5
#
[common]
# This is the line input to StepperDemo:
build_flags = -D SIMULATOR
[env:atmega328p]
platform = atmelavr
board = nanoatmega328
framework = arduino
build_flags = -Werror -Wall ${common.build_flags}
lib_extra_dirs = ../../../../..

View File

@@ -0,0 +1 @@
src/

View File

@@ -0,0 +1,132 @@
#
# In order to execute the test for one directory use:
#
# make -C test_sd_01b_328p -f ../Makefile.test
SRC=$(wildcard ../../../src/*) $(wildcard src/*)
# platformio should contain only one env section.
# This section states the dut name
# atmega168
# atmega168p
# atmega328
# atmega328p
# atmega2560_timer1
# atmega2560_timer3
# atmega2560_timer4
# atmega2560_timer5
#
DUT=$(shell gawk '/env:/{print(substr($$1,6,length($$1)-6))}' platformio.ini)
TRACES=-at StepISR=trace@0x25/0x08 # PB3
TRACES+=-at FillISR=trace@0x25/0x10 # PB4
#
ifeq ($(DUT),atmega2560_timer1)
DEVICE=atmega2560
TRACES+=-at StepA=trace@0x025/0x20 #OC1A PB5 11 ATMega2560
TRACES+=-at StepB=trace@0x025/0x40 #OC1B PB6 12 ATMega2560
TRACES+=-at StepC=trace@0x025/0x80 #OC1C PB7 13 ATMega2560
#
else ifeq ($(DUT),atmega2560_timer3)
DEVICE=atmega2560
TRACES+=-at StepA=trace@0x02e/0x08 #OC3A PE3 5 ATMega2560
TRACES+=-at StepB=trace@0x02e/0x10 #OC3B PE4 2 ATMega2560
TRACES+=-at StepC=trace@0x02e/0x20 #OC3C PE5 3 ATMega2560
#
else ifeq ($(DUT),atmega2560_timer4)
DEVICE=atmega2560
TRACES+=-at StepA=trace@0x102/0x08 #OC4A PH3 6 ATMega2560
TRACES+=-at StepB=trace@0x102/0x10 #OC4B PH4 7 ATMega2560
TRACES+=-at StepC=trace@0x102/0x20 #OC4C PH5 8 ATMega2560
#
else ifeq ($(DUT),atmega2560_timer5)
DEVICE=atmega2560
TRACES+=-at StepA=trace@0x10b/0x08 #OC5A PL3 46 ATMega2560
TRACES+=-at StepB=trace@0x10b/0x10 #OC5B PL4 45 ATMega2560
TRACES+=-at StepC=trace@0x10b/0x20 #OC5C PL5 44 ATMega2560
else ifeq ($(DUT),atmega168)
DEVICE=atmega168
TRACES+=-at StepA=trace@0x25/0x02 #OC1A PB1 9 atmega168
TRACES+=-at StepB=trace@0x25/0x04 #OC1B PB2 10 atmega168
else ifeq ($(DUT),atmega168p)
DEVICE=atmega168p
TRACES+=-at StepA=trace@0x25/0x02 #OC1A PB1 9 atmega168p
TRACES+=-at StepB=trace@0x25/0x04 #OC1B PB2 10 atmega168p
else ifeq ($(DUT),atmega328)
DEVICE=atmega328
TRACES+=-at StepA=trace@0x25/0x02 #OC1A PB1 9 ATMega328
TRACES+=-at StepB=trace@0x25/0x04 #OC1B PB2 10 ATMega328
else ifeq ($(DUT),atmega328p)
DEVICE=atmega328p
TRACES+=-at StepA=trace@0x25/0x02 #OC1A PB1 9 ATMega328p
TRACES+=-at StepB=trace@0x25/0x04 #OC1B PB2 10 ATMega328p
else ifeq ($(DUT),atmega32u4)
DEVICE=atmega32u4
TRACES+=-at StepA=trace@0x025/0x20 #OC1A PB5 11
TRACES+=-at StepB=trace@0x025/0x40 #OC1B PB6 12
#TRACES+=-at StepC=trace@0x025/0x80 #OC1C PB7 13
endif
ifeq ($(DEVICE),atmega2560)
TRACES+=-at DirA=trace@0x2b/0x01 # Pin 21 PD0
TRACES+=-at DirB=trace@0x2b/0x02 # Pin 20 PD1
TRACES+=-at DirC=trace@0x10b/0x80 # Pin 42 PL7
TRACES+=-at EnableA=trace@0x2b/0x04 # Pin 19 PD2
TRACES+=-at EnableB=trace@0x2b/0x08 # Pin 18 PD3
TRACES+=-at EnableC=trace@0x10b/0x40 # Pin 43 PL6
else ifeq ($(DEVICE),$(filter $(DEVICE),atmega168 atmega168p atmega328 atmega328p))
TRACES+=-at DirA=trace@0x2b/0x20 # Pin 5 PD5
TRACES+=-at DirB=trace@0x2b/0x80 # Pin 7 PD7
TRACES+=-at EnableA=trace@0x2b/0x40 # Pin 6 PD6
TRACES+=-at EnableB=trace@0x25/0x01 # Pin 8 PB0
else ifeq ($(DUT),atmega32u4)
TRACES+=-at DirA=trace@0x25/0x10 # Pin 26 PB4
TRACES+=-at DirB=trace@0x25/0x08 # Pin 14 PB3
#TRACES+=-at DirC=trace@0x10b/0x80 # Pin 42 PL7
TRACES+=-at EnableA=trace@0x25/0x04 # Pin 16 PB2
TRACES+=-at EnableB=trace@0x25/0x02 # Pin 15 PB1
#TRACES+=-at EnableC=trace@0x10b/0x40 # Pin 43 PL6
endif
FIRMWARE=".pio/build/$(DUT)/firmware.elf"
DIR=$(shell env pwd)
ifndef SILENCE
SILENCE=0
endif
test: .tested
.tested: result.txt expect.txt ../judge.awk
echo DUT=$(DUT)
rm -f .tested
gawk -f ../judge.awk -v DIR=$(DIR) result.txt expect.txt
test -f .tested
result.txt: x.vcd
gawk -v SILENCE=$(SILENCE) -f ../eval.awk x.vcd >/dev/null
cat expect.txt
x.vcd: $(SRC) ../run_avr platformio.ini src/Issue152.ino
~/.platformio/penv/bin/pio run -e $(DUT) || ~/.local/bin/pio run -e $(DUT) || env pio run -e $(DUT)
../run_avr $(FIRMWARE) -m $(DEVICE) -o x.vcd $(TRACES)
src/Issue152.ino:
mkdir -p src
cd src; ln -s ../../../../../examples/Issue152/Issue152.ino .
clean:
rm -fR .pio .tested x.vcd result.txt

View File

@@ -0,0 +1,20 @@
DirA: 0*L->H, 0*H->L
DirB: 1*L->H, 0*H->L
EnableA: 2*L->H, 1*H->L
EnableB: 0*L->H, 0*H->L
StepA: 20000*L->H, 20000*H->L, Max High=10us Total High=104644us
StepB: 2*L->H, 2*H->L, Max High=4us Total High=9us
Position[A]=20000
Position[B]=2
Time in EnableA max=4199 us, total=4199 us
Time in FillISR max=1848 us, total=59230 us
Time in StepA max=10 us, total=104644 us
Time in StepB max=4 us, total=9 us
Time in StepISR max=7 us, total=85706 us

View File

@@ -0,0 +1,31 @@
; PlatformIO Project Configuration File
;
; Build options: build flags, source filter
; Upload options: custom upload port, speed and extra flags
; Library options: dependencies, extra library storages
; Advanced options: extra scripting
;
; Please visit documentation for the other options and examples
; https://docs.platformio.org/page/projectconf.html
[platformio]
# There should be only one env section for the DUT under test.
# One of
# atmega168p
# atmega328p
# atmega2560_timer1
# atmega2560_timer3
# atmega2560_timer4
# atmega2560_timer5
#
[common]
# This is the line input to StepperDemo:
build_flags = -D SIMULATOR -D SIMAVR_TIME_MEASUREMENT
[env:atmega328p]
platform = atmelavr
board = nanoatmega328
framework = arduino
build_flags = -Werror -Wall ${common.build_flags}
lib_extra_dirs = ../../../../..

View File

@@ -0,0 +1 @@
src/

View File

@@ -0,0 +1,132 @@
#
# In order to execute the test for one directory use:
#
# make -C test_sd_01b_328p -f ../Makefile.test
SRC=$(wildcard ../../../src/*) $(wildcard src/*)
# platformio should contain only one env section.
# This section states the dut name
# atmega168
# atmega168p
# atmega328
# atmega328p
# atmega2560_timer1
# atmega2560_timer3
# atmega2560_timer4
# atmega2560_timer5
#
DUT=$(shell gawk '/env:/{print(substr($$1,6,length($$1)-6))}' platformio.ini)
TRACES=-at StepISR=trace@0x25/0x08 # PB3
TRACES+=-at FillISR=trace@0x25/0x10 # PB4
#
ifeq ($(DUT),atmega2560_timer1)
DEVICE=atmega2560
TRACES+=-at StepA=trace@0x025/0x20 #OC1A PB5 11 ATMega2560
TRACES+=-at StepB=trace@0x025/0x40 #OC1B PB6 12 ATMega2560
TRACES+=-at StepC=trace@0x025/0x80 #OC1C PB7 13 ATMega2560
#
else ifeq ($(DUT),atmega2560_timer3)
DEVICE=atmega2560
TRACES+=-at StepA=trace@0x02e/0x08 #OC3A PE3 5 ATMega2560
TRACES+=-at StepB=trace@0x02e/0x10 #OC3B PE4 2 ATMega2560
TRACES+=-at StepC=trace@0x02e/0x20 #OC3C PE5 3 ATMega2560
#
else ifeq ($(DUT),atmega2560_timer4)
DEVICE=atmega2560
TRACES+=-at StepA=trace@0x102/0x08 #OC4A PH3 6 ATMega2560
TRACES+=-at StepB=trace@0x102/0x10 #OC4B PH4 7 ATMega2560
TRACES+=-at StepC=trace@0x102/0x20 #OC4C PH5 8 ATMega2560
#
else ifeq ($(DUT),atmega2560_timer5)
DEVICE=atmega2560
TRACES+=-at StepA=trace@0x10b/0x08 #OC5A PL3 46 ATMega2560
TRACES+=-at StepB=trace@0x10b/0x10 #OC5B PL4 45 ATMega2560
TRACES+=-at StepC=trace@0x10b/0x20 #OC5C PL5 44 ATMega2560
else ifeq ($(DUT),atmega168)
DEVICE=atmega168
TRACES+=-at StepA=trace@0x25/0x02 #OC1A PB1 9 atmega168
TRACES+=-at StepB=trace@0x25/0x04 #OC1B PB2 10 atmega168
else ifeq ($(DUT),atmega168p)
DEVICE=atmega168p
TRACES+=-at StepA=trace@0x25/0x02 #OC1A PB1 9 atmega168p
TRACES+=-at StepB=trace@0x25/0x04 #OC1B PB2 10 atmega168p
else ifeq ($(DUT),atmega328)
DEVICE=atmega328
TRACES+=-at StepA=trace@0x25/0x02 #OC1A PB1 9 ATMega328
TRACES+=-at StepB=trace@0x25/0x04 #OC1B PB2 10 ATMega328
else ifeq ($(DUT),atmega328p)
DEVICE=atmega328p
TRACES+=-at StepA=trace@0x25/0x02 #OC1A PB1 9 ATMega328p
TRACES+=-at StepB=trace@0x25/0x04 #OC1B PB2 10 ATMega328p
else ifeq ($(DUT),atmega32u4)
DEVICE=atmega32u4
TRACES+=-at StepA=trace@0x025/0x20 #OC1A PB5 11
TRACES+=-at StepB=trace@0x025/0x40 #OC1B PB6 12
#TRACES+=-at StepC=trace@0x025/0x80 #OC1C PB7 13
endif
ifeq ($(DEVICE),atmega2560)
TRACES+=-at DirA=trace@0x2b/0x01 # Pin 21 PD0
TRACES+=-at DirB=trace@0x2b/0x02 # Pin 20 PD1
TRACES+=-at DirC=trace@0x10b/0x80 # Pin 42 PL7
TRACES+=-at EnableA=trace@0x2b/0x04 # Pin 19 PD2
TRACES+=-at EnableB=trace@0x2b/0x08 # Pin 18 PD3
TRACES+=-at EnableC=trace@0x10b/0x40 # Pin 43 PL6
else ifeq ($(DEVICE),$(filter $(DEVICE),atmega168 atmega168p atmega328 atmega328p))
TRACES+=-at DirA=trace@0x2b/0x20 # Pin 5 PD5
TRACES+=-at DirB=trace@0x2b/0x80 # Pin 7 PD7
TRACES+=-at EnableA=trace@0x2b/0x40 # Pin 6 PD6
TRACES+=-at EnableB=trace@0x25/0x01 # Pin 8 PB0
else ifeq ($(DUT),atmega32u4)
TRACES+=-at DirA=trace@0x25/0x10 # Pin 26 PB4
TRACES+=-at DirB=trace@0x25/0x08 # Pin 14 PB3
#TRACES+=-at DirC=trace@0x10b/0x80 # Pin 42 PL7
TRACES+=-at EnableA=trace@0x25/0x04 # Pin 16 PB2
TRACES+=-at EnableB=trace@0x25/0x02 # Pin 15 PB1
#TRACES+=-at EnableC=trace@0x10b/0x40 # Pin 43 PL6
endif
FIRMWARE=".pio/build/$(DUT)/firmware.elf"
DIR=$(shell env pwd)
ifndef SILENCE
SILENCE=0
endif
test: .tested
.tested: result.txt expect.txt ../judge.awk
echo DUT=$(DUT)
rm -f .tested
gawk -f ../judge.awk -v DIR=$(DIR) result.txt expect.txt
test -f .tested
result.txt: x.vcd
gawk -v SILENCE=$(SILENCE) -f ../eval.awk x.vcd >/dev/null
cat expect.txt
x.vcd: $(SRC) ../run_avr platformio.ini src/Issue172.ino
~/.platformio/penv/bin/pio run -e $(DUT) || ~/.local/bin/pio run -e $(DUT) || env pio run -e $(DUT)
../run_avr $(FIRMWARE) -m $(DEVICE) -o x.vcd $(TRACES)
src/Issue172.ino:
mkdir -p src
cd src; ln -s ../../../../../examples/Issue172/Issue172.ino .
clean:
rm -fR .pio .tested x.vcd result.txt

View File

@@ -0,0 +1,20 @@
DirA: 0*L->H, 1*H->L
DirB: 1*L->H, 0*H->L
EnableA: 2*L->H, 1*H->L
EnableB: 0*L->H, 0*H->L
StepA: 2060*L->H, 2060*H->L, Max High=9us Total High=8067us
StepB: 2*L->H, 2*H->L, Max High=4us Total High=9us
Position[A]=0
Position[B]=2
Time in EnableA max=4204 us, total=4204 us
Time in FillISR max=1737 us, total=39497 us
Time in StepA max=9 us, total=8067 us
Time in StepB max=4 us, total=9 us
Time in StepISR max=6 us, total=8184 us

View File

@@ -0,0 +1,31 @@
; PlatformIO Project Configuration File
;
; Build options: build flags, source filter
; Upload options: custom upload port, speed and extra flags
; Library options: dependencies, extra library storages
; Advanced options: extra scripting
;
; Please visit documentation for the other options and examples
; https://docs.platformio.org/page/projectconf.html
[platformio]
# There should be only one env section for the DUT under test.
# One of
# atmega168p
# atmega328p
# atmega2560_timer1
# atmega2560_timer3
# atmega2560_timer4
# atmega2560_timer5
#
[common]
# This is the line input to StepperDemo:
build_flags = -D SIMULATOR -D SIMAVR_TIME_MEASUREMENT
[env:atmega328p]
platform = atmelavr
board = nanoatmega328
framework = arduino
build_flags = -Werror -Wall ${common.build_flags}
lib_extra_dirs = ../../../../..

View File

@@ -0,0 +1 @@
src/

View File

@@ -0,0 +1,132 @@
#
# In order to execute the test for one directory use:
#
# make -C test_sd_01b_328p -f ../Makefile.test
SRC=$(wildcard ../../../src/*) $(wildcard src/*)
# platformio should contain only one env section.
# This section states the dut name
# atmega168
# atmega168p
# atmega328
# atmega328p
# atmega2560_timer1
# atmega2560_timer3
# atmega2560_timer4
# atmega2560_timer5
#
DUT=$(shell gawk '/env:/{print(substr($$1,6,length($$1)-6))}' platformio.ini)
TRACES=-at StepISR=trace@0x25/0x08 # PB3
TRACES+=-at FillISR=trace@0x25/0x10 # PB4
#
ifeq ($(DUT),atmega2560_timer1)
DEVICE=atmega2560
TRACES+=-at StepA=trace@0x025/0x20 #OC1A PB5 11 ATMega2560
TRACES+=-at StepB=trace@0x025/0x40 #OC1B PB6 12 ATMega2560
TRACES+=-at StepC=trace@0x025/0x80 #OC1C PB7 13 ATMega2560
#
else ifeq ($(DUT),atmega2560_timer3)
DEVICE=atmega2560
TRACES+=-at StepA=trace@0x02e/0x08 #OC3A PE3 5 ATMega2560
TRACES+=-at StepB=trace@0x02e/0x10 #OC3B PE4 2 ATMega2560
TRACES+=-at StepC=trace@0x02e/0x20 #OC3C PE5 3 ATMega2560
#
else ifeq ($(DUT),atmega2560_timer4)
DEVICE=atmega2560
TRACES+=-at StepA=trace@0x102/0x08 #OC4A PH3 6 ATMega2560
TRACES+=-at StepB=trace@0x102/0x10 #OC4B PH4 7 ATMega2560
TRACES+=-at StepC=trace@0x102/0x20 #OC4C PH5 8 ATMega2560
#
else ifeq ($(DUT),atmega2560_timer5)
DEVICE=atmega2560
TRACES+=-at StepA=trace@0x10b/0x08 #OC5A PL3 46 ATMega2560
TRACES+=-at StepB=trace@0x10b/0x10 #OC5B PL4 45 ATMega2560
TRACES+=-at StepC=trace@0x10b/0x20 #OC5C PL5 44 ATMega2560
else ifeq ($(DUT),atmega168)
DEVICE=atmega168
TRACES+=-at StepA=trace@0x25/0x02 #OC1A PB1 9 atmega168
TRACES+=-at StepB=trace@0x25/0x04 #OC1B PB2 10 atmega168
else ifeq ($(DUT),atmega168p)
DEVICE=atmega168p
TRACES+=-at StepA=trace@0x25/0x02 #OC1A PB1 9 atmega168p
TRACES+=-at StepB=trace@0x25/0x04 #OC1B PB2 10 atmega168p
else ifeq ($(DUT),atmega328)
DEVICE=atmega328
TRACES+=-at StepA=trace@0x25/0x02 #OC1A PB1 9 ATMega328
TRACES+=-at StepB=trace@0x25/0x04 #OC1B PB2 10 ATMega328
else ifeq ($(DUT),atmega328p)
DEVICE=atmega328p
TRACES+=-at StepA=trace@0x25/0x02 #OC1A PB1 9 ATMega328p
TRACES+=-at StepB=trace@0x25/0x04 #OC1B PB2 10 ATMega328p
else ifeq ($(DUT),atmega32u4)
DEVICE=atmega32u4
TRACES+=-at StepA=trace@0x025/0x20 #OC1A PB5 11
TRACES+=-at StepB=trace@0x025/0x40 #OC1B PB6 12
#TRACES+=-at StepC=trace@0x025/0x80 #OC1C PB7 13
endif
ifeq ($(DEVICE),atmega2560)
TRACES+=-at DirA=trace@0x2b/0x01 # Pin 21 PD0
TRACES+=-at DirB=trace@0x2b/0x02 # Pin 20 PD1
TRACES+=-at DirC=trace@0x10b/0x80 # Pin 42 PL7
TRACES+=-at EnableA=trace@0x2b/0x04 # Pin 19 PD2
TRACES+=-at EnableB=trace@0x2b/0x08 # Pin 18 PD3
TRACES+=-at EnableC=trace@0x10b/0x40 # Pin 43 PL6
else ifeq ($(DEVICE),$(filter $(DEVICE),atmega168 atmega168p atmega328 atmega328p))
TRACES+=-at DirA=trace@0x2b/0x20 # Pin 5 PD5
TRACES+=-at DirB=trace@0x2b/0x80 # Pin 7 PD7
TRACES+=-at EnableA=trace@0x2b/0x40 # Pin 6 PD6
TRACES+=-at EnableB=trace@0x25/0x01 # Pin 8 PB0
else ifeq ($(DUT),atmega32u4)
TRACES+=-at DirA=trace@0x25/0x10 # Pin 26 PB4
TRACES+=-at DirB=trace@0x25/0x08 # Pin 14 PB3
#TRACES+=-at DirC=trace@0x10b/0x80 # Pin 42 PL7
TRACES+=-at EnableA=trace@0x25/0x04 # Pin 16 PB2
TRACES+=-at EnableB=trace@0x25/0x02 # Pin 15 PB1
#TRACES+=-at EnableC=trace@0x10b/0x40 # Pin 43 PL6
endif
FIRMWARE=".pio/build/$(DUT)/firmware.elf"
DIR=$(shell env pwd)
ifndef SILENCE
SILENCE=0
endif
test: .tested
.tested: result.txt expect.txt ../judge.awk
echo DUT=$(DUT)
rm -f .tested
gawk -f ../judge.awk -v DIR=$(DIR) result.txt expect.txt
test -f .tested
result.txt: x.vcd
gawk -v SILENCE=$(SILENCE) -f ../eval.awk x.vcd >/dev/null
cat expect.txt
x.vcd: $(SRC) ../run_avr platformio.ini src/Issue173.ino
~/.platformio/penv/bin/pio run -e $(DUT) || ~/.local/bin/pio run -e $(DUT) || env pio run -e $(DUT)
../run_avr $(FIRMWARE) -m $(DEVICE) -o x.vcd $(TRACES)
src/Issue173.ino:
mkdir -p src
cd src; ln -s ../../../../../examples/Issue173/Issue173.ino .
clean:
rm -fR .pio .tested x.vcd result.txt

View File

@@ -0,0 +1,20 @@
DirA: 0*L->H, 1*H->L
DirB: 1*L->H, 0*H->L
EnableA: 3*L->H, 2*H->L
EnableB: 0*L->H, 0*H->L
StepA: 1050*L->H, 1050*H->L, Max High=9us Total High=4119us
StepB: 2*L->H, 2*H->L, Max High=4us Total High=9us
Position[A]=0
Position[B]=2
Time in EnableA max=4204 us, total=8409 us
Time in FillISR max=1917 us, total=25558 us
Time in StepA max=9 us, total=4119 us
Time in StepB max=4 us, total=9 us
Time in StepISR max=5 us, total=4224 us

View File

@@ -0,0 +1,31 @@
; PlatformIO Project Configuration File
;
; Build options: build flags, source filter
; Upload options: custom upload port, speed and extra flags
; Library options: dependencies, extra library storages
; Advanced options: extra scripting
;
; Please visit documentation for the other options and examples
; https://docs.platformio.org/page/projectconf.html
[platformio]
# There should be only one env section for the DUT under test.
# One of
# atmega168p
# atmega328p
# atmega2560_timer1
# atmega2560_timer3
# atmega2560_timer4
# atmega2560_timer5
#
[common]
# This is the line input to StepperDemo:
build_flags = -D SIMULATOR -D SIMAVR_TIME_MEASUREMENT
[env:atmega328p]
platform = atmelavr
board = nanoatmega328
framework = arduino
build_flags = -Werror -Wall ${common.build_flags}
lib_extra_dirs = ../../../../..

View File

@@ -0,0 +1 @@
src/

View File

@@ -0,0 +1,132 @@
#
# In order to execute the test for one directory use:
#
# make -C test_sd_01b_328p -f ../Makefile.test
SRC=$(wildcard ../../../src/*) $(wildcard src/*)
# platformio should contain only one env section.
# This section states the dut name
# atmega168
# atmega168p
# atmega328
# atmega328p
# atmega2560_timer1
# atmega2560_timer3
# atmega2560_timer4
# atmega2560_timer5
#
DUT=$(shell gawk '/env:/{print(substr($$1,6,length($$1)-6))}' platformio.ini)
TRACES=-at StepISR=trace@0x25/0x08 # PB3
TRACES+=-at FillISR=trace@0x25/0x10 # PB4
#
ifeq ($(DUT),atmega2560_timer1)
DEVICE=atmega2560
TRACES+=-at StepA=trace@0x025/0x20 #OC1A PB5 11 ATMega2560
TRACES+=-at StepB=trace@0x025/0x40 #OC1B PB6 12 ATMega2560
TRACES+=-at StepC=trace@0x025/0x80 #OC1C PB7 13 ATMega2560
#
else ifeq ($(DUT),atmega2560_timer3)
DEVICE=atmega2560
TRACES+=-at StepA=trace@0x02e/0x08 #OC3A PE3 5 ATMega2560
TRACES+=-at StepB=trace@0x02e/0x10 #OC3B PE4 2 ATMega2560
TRACES+=-at StepC=trace@0x02e/0x20 #OC3C PE5 3 ATMega2560
#
else ifeq ($(DUT),atmega2560_timer4)
DEVICE=atmega2560
TRACES+=-at StepA=trace@0x102/0x08 #OC4A PH3 6 ATMega2560
TRACES+=-at StepB=trace@0x102/0x10 #OC4B PH4 7 ATMega2560
TRACES+=-at StepC=trace@0x102/0x20 #OC4C PH5 8 ATMega2560
#
else ifeq ($(DUT),atmega2560_timer5)
DEVICE=atmega2560
TRACES+=-at StepA=trace@0x10b/0x08 #OC5A PL3 46 ATMega2560
TRACES+=-at StepB=trace@0x10b/0x10 #OC5B PL4 45 ATMega2560
TRACES+=-at StepC=trace@0x10b/0x20 #OC5C PL5 44 ATMega2560
else ifeq ($(DUT),atmega168)
DEVICE=atmega168
TRACES+=-at StepA=trace@0x25/0x02 #OC1A PB1 9 atmega168
TRACES+=-at StepB=trace@0x25/0x04 #OC1B PB2 10 atmega168
else ifeq ($(DUT),atmega168p)
DEVICE=atmega168p
TRACES+=-at StepA=trace@0x25/0x02 #OC1A PB1 9 atmega168p
TRACES+=-at StepB=trace@0x25/0x04 #OC1B PB2 10 atmega168p
else ifeq ($(DUT),atmega328)
DEVICE=atmega328
TRACES+=-at StepA=trace@0x25/0x02 #OC1A PB1 9 ATMega328
TRACES+=-at StepB=trace@0x25/0x04 #OC1B PB2 10 ATMega328
else ifeq ($(DUT),atmega328p)
DEVICE=atmega328p
TRACES+=-at StepA=trace@0x25/0x02 #OC1A PB1 9 ATMega328p
TRACES+=-at StepB=trace@0x25/0x04 #OC1B PB2 10 ATMega328p
else ifeq ($(DUT),atmega32u4)
DEVICE=atmega32u4
TRACES+=-at StepA=trace@0x025/0x20 #OC1A PB5 11
TRACES+=-at StepB=trace@0x025/0x40 #OC1B PB6 12
#TRACES+=-at StepC=trace@0x025/0x80 #OC1C PB7 13
endif
ifeq ($(DEVICE),atmega2560)
TRACES+=-at DirA=trace@0x2b/0x01 # Pin 21 PD0
TRACES+=-at DirB=trace@0x2b/0x02 # Pin 20 PD1
TRACES+=-at DirC=trace@0x10b/0x80 # Pin 42 PL7
TRACES+=-at EnableA=trace@0x2b/0x04 # Pin 19 PD2
TRACES+=-at EnableB=trace@0x2b/0x08 # Pin 18 PD3
TRACES+=-at EnableC=trace@0x10b/0x40 # Pin 43 PL6
else ifeq ($(DEVICE),$(filter $(DEVICE),atmega168 atmega168p atmega328 atmega328p))
TRACES+=-at DirA=trace@0x2b/0x20 # Pin 5 PD5
TRACES+=-at DirB=trace@0x2b/0x80 # Pin 7 PD7
TRACES+=-at EnableA=trace@0x2b/0x40 # Pin 6 PD6
TRACES+=-at EnableB=trace@0x25/0x01 # Pin 8 PB0
else ifeq ($(DUT),atmega32u4)
TRACES+=-at DirA=trace@0x25/0x10 # Pin 26 PB4
TRACES+=-at DirB=trace@0x25/0x08 # Pin 14 PB3
#TRACES+=-at DirC=trace@0x10b/0x80 # Pin 42 PL7
TRACES+=-at EnableA=trace@0x25/0x04 # Pin 16 PB2
TRACES+=-at EnableB=trace@0x25/0x02 # Pin 15 PB1
#TRACES+=-at EnableC=trace@0x10b/0x40 # Pin 43 PL6
endif
FIRMWARE=".pio/build/$(DUT)/firmware.elf"
DIR=$(shell env pwd)
ifndef SILENCE
SILENCE=0
endif
test: .tested
.tested: result.txt expect.txt ../judge.awk
echo DUT=$(DUT)
rm -f .tested
gawk -f ../judge.awk -v DIR=$(DIR) result.txt expect.txt
test -f .tested
result.txt: x.vcd
gawk -v SILENCE=$(SILENCE) -f ../eval.awk x.vcd >/dev/null
cat expect.txt
x.vcd: $(SRC) ../run_avr platformio.ini src/Issue208.ino
~/.platformio/penv/bin/pio run -e $(DUT) || ~/.local/bin/pio run -e $(DUT) || env pio run -e $(DUT)
../run_avr $(FIRMWARE) -m $(DEVICE) -o x.vcd $(TRACES)
src/Issue208.ino:
mkdir -p src
cd src; ln -s ../../../../../examples/Issue208/Issue208.ino .
clean:
rm -fR .pio .tested x.vcd result.txt

View File

@@ -0,0 +1,18 @@
DirA: 0*L->H, 1*H->L
DirB: 1*L->H, 0*H->L
EnableA: 0*L->H, 0*H->L
EnableB: 0*L->H, 0*H->L
StepA: 234999*L->H, 234999*H->L, Max High=10us Total High=923957us
StepB: 2*L->H, 2*H->L, Max High=12us Total High=25us
Position[A]=37271
Position[B]=2
Time in FillISR max=776 us, total=1220640 us
Time in StepA max=10 us, total=923957 us
Time in StepB max=12 us, total=25 us
Time in StepISR max=6 us, total=894406 us

View File

@@ -0,0 +1,31 @@
; PlatformIO Project Configuration File
;
; Build options: build flags, source filter
; Upload options: custom upload port, speed and extra flags
; Library options: dependencies, extra library storages
; Advanced options: extra scripting
;
; Please visit documentation for the other options and examples
; https://docs.platformio.org/page/projectconf.html
[platformio]
# There should be only one env section for the DUT under test.
# One of
# atmega168p
# atmega328p
# atmega2560_timer1
# atmega2560_timer3
# atmega2560_timer4
# atmega2560_timer5
#
[common]
# This is the line input to StepperDemo:
build_flags = -D SIMULATOR -D SIMAVR_TIME_MEASUREMENT
[env:atmega328p]
platform = atmelavr
board = nanoatmega328
framework = arduino
build_flags = -Werror -Wall ${common.build_flags}
lib_extra_dirs = ../../../../..

View File

@@ -0,0 +1 @@
src/

View File

@@ -0,0 +1,131 @@
#
# In order to execute the test for one directory use:
#
# make -C test_sd_01b_328p -f ../Makefile.test
SRC=$(wildcard ../../../src/*) $(wildcard src/*)
# platformio should contain only one env section.
# This section states the dut name
# atmega168
# atmega168p
# atmega328
# atmega328p
# atmega2560_timer1
# atmega2560_timer3
# atmega2560_timer4
# atmega2560_timer5
#
DUT=$(shell gawk '/env:/{print(substr($$1,6,length($$1)-6))}' platformio.ini)
TRACES=-at StepISR=trace@0x25/0x08 # PB3
TRACES+=-at FillISR=trace@0x25/0x10 # PB4
#
ifeq ($(DUT),atmega2560_timer1)
DEVICE=atmega2560
TRACES+=-at StepA=trace@0x025/0x20 #OC1A PB5 11 ATMega2560
TRACES+=-at StepB=trace@0x025/0x40 #OC1B PB6 12 ATMega2560
TRACES+=-at StepC=trace@0x025/0x80 #OC1C PB7 13 ATMega2560
#
else ifeq ($(DUT),atmega2560_timer3)
DEVICE=atmega2560
TRACES+=-at StepA=trace@0x02e/0x08 #OC3A PE3 5 ATMega2560
TRACES+=-at StepB=trace@0x02e/0x10 #OC3B PE4 2 ATMega2560
TRACES+=-at StepC=trace@0x02e/0x20 #OC3C PE5 3 ATMega2560
#
else ifeq ($(DUT),atmega2560_timer4)
DEVICE=atmega2560
TRACES+=-at StepA=trace@0x102/0x08 #OC4A PH3 6 ATMega2560
TRACES+=-at StepB=trace@0x102/0x10 #OC4B PH4 7 ATMega2560
TRACES+=-at StepC=trace@0x102/0x20 #OC4C PH5 8 ATMega2560
#
else ifeq ($(DUT),atmega2560_timer5)
DEVICE=atmega2560
TRACES+=-at StepA=trace@0x10b/0x08 #OC5A PL3 46 ATMega2560
TRACES+=-at StepB=trace@0x10b/0x10 #OC5B PL4 45 ATMega2560
TRACES+=-at StepC=trace@0x10b/0x20 #OC5C PL5 44 ATMega2560
else ifeq ($(DUT),atmega168)
DEVICE=atmega168
TRACES+=-at StepA=trace@0x25/0x02 #OC1A PB1 9 atmega168
TRACES+=-at StepB=trace@0x25/0x04 #OC1B PB2 10 atmega168
else ifeq ($(DUT),atmega168p)
DEVICE=atmega168p
TRACES+=-at StepA=trace@0x25/0x02 #OC1A PB1 9 atmega168p
TRACES+=-at StepB=trace@0x25/0x04 #OC1B PB2 10 atmega168p
else ifeq ($(DUT),atmega328)
DEVICE=atmega328
TRACES+=-at StepA=trace@0x25/0x02 #OC1A PB1 9 ATMega328
TRACES+=-at StepB=trace@0x25/0x04 #OC1B PB2 10 ATMega328
else ifeq ($(DUT),atmega328p)
DEVICE=atmega328p
TRACES+=-at StepA=trace@0x25/0x02 #OC1A PB1 9 ATMega328p
TRACES+=-at StepB=trace@0x25/0x04 #OC1B PB2 10 ATMega328p
else ifeq ($(DUT),atmega32u4)
DEVICE=atmega32u4
TRACES+=-at StepA=trace@0x025/0x20 #OC1A PB5 11
TRACES+=-at StepB=trace@0x025/0x40 #OC1B PB6 12
#TRACES+=-at StepC=trace@0x025/0x80 #OC1C PB7 13
endif
ifeq ($(DEVICE),atmega2560)
TRACES+=-at DirA=trace@0x2b/0x01 # Pin 21 PD0
TRACES+=-at DirB=trace@0x2b/0x02 # Pin 20 PD1
TRACES+=-at DirC=trace@0x10b/0x80 # Pin 42 PL7
TRACES+=-at EnableA=trace@0x2b/0x04 # Pin 19 PD2
TRACES+=-at EnableB=trace@0x2b/0x08 # Pin 18 PD3
TRACES+=-at EnableC=trace@0x10b/0x40 # Pin 43 PL6
else ifeq ($(DEVICE),$(filter $(DEVICE),atmega168 atmega168p atmega328 atmega328p))
TRACES+=-at DirA=trace@0x2b/0x20 # Pin 5 PD5
TRACES+=-at DirB=trace@0x2b/0x80 # Pin 7 PD7
TRACES+=-at EnableA=trace@0x2b/0x40 # Pin 6 PD6
TRACES+=-at EnableB=trace@0x25/0x01 # Pin 8 PB0
else ifeq ($(DUT),atmega32u4)
TRACES+=-at DirA=trace@0x25/0x10 # Pin 26 PB4
TRACES+=-at DirB=trace@0x25/0x08 # Pin 14 PB3
#TRACES+=-at DirC=trace@0x10b/0x80 # Pin 42 PL7
TRACES+=-at EnableA=trace@0x25/0x04 # Pin 16 PB2
TRACES+=-at EnableB=trace@0x25/0x02 # Pin 15 PB1
#TRACES+=-at EnableC=trace@0x10b/0x40 # Pin 43 PL6
endif
FIRMWARE=".pio/build/$(DUT)/firmware.elf"
DIR=$(shell env pwd)
ifndef SILENCE
SILENCE=0
endif
test: .tested
.tested: result.txt ../judge_pos0.awk
echo DUT=$(DUT)
rm -f .tested
gawk -f ../judge_pos0.awk -v DIR=$(DIR) result.txt
test -f .tested
result.txt: x.vcd
gawk -v SILENCE=$(SILENCE) -f ../eval.awk x.vcd >/dev/null
x.vcd: $(SRC) ../run_avr platformio.ini src/Issue250.ino
~/.platformio/penv/bin/pio run -e $(DUT) || ~/.local/bin/pio run -e $(DUT) || env pio run -e $(DUT)
../run_avr $(FIRMWARE) -m $(DEVICE) -o x.vcd $(TRACES)
src/Issue250.ino:
mkdir -p src
cd src; ln -s ../../../../../examples/Issue250/Issue250.ino .
clean:
rm -fR .pio .tested x.vcd result.txt

View File

@@ -0,0 +1,31 @@
; PlatformIO Project Configuration File
;
; Build options: build flags, source filter
; Upload options: custom upload port, speed and extra flags
; Library options: dependencies, extra library storages
; Advanced options: extra scripting
;
; Please visit documentation for the other options and examples
; https://docs.platformio.org/page/projectconf.html
[platformio]
# There should be only one env section for the DUT under test.
# One of
# atmega168p
# atmega328p
# atmega2560_timer1
# atmega2560_timer3
# atmega2560_timer4
# atmega2560_timer5
#
[common]
# This is the line input to StepperDemo:
build_flags = -D SIMULATOR -D SIMAVR_TIME_MEASUREMENT
[env:atmega328p]
platform = atmelavr
board = nanoatmega328
framework = arduino
build_flags = -Werror -Wall ${common.build_flags}
lib_extra_dirs = ../../../../..

View File

@@ -0,0 +1 @@
src/

View File

@@ -0,0 +1,131 @@
#
# In order to execute the test for one directory use:
#
# make -C test_sd_01b_328p -f ../Makefile.test
SRC=$(wildcard ../../../src/*) $(wildcard src/*)
# platformio should contain only one env section.
# This section states the dut name
# atmega168
# atmega168p
# atmega328
# atmega328p
# atmega2560_timer1
# atmega2560_timer3
# atmega2560_timer4
# atmega2560_timer5
#
DUT=$(shell gawk '/env:/{print(substr($$1,6,length($$1)-6))}' platformio.ini)
TRACES=-at StepISR=trace@0x25/0x08 # PB3
TRACES+=-at FillISR=trace@0x25/0x10 # PB4
#
ifeq ($(DUT),atmega2560_timer1)
DEVICE=atmega2560
TRACES+=-at StepA=trace@0x025/0x20 #OC1A PB5 11 ATMega2560
TRACES+=-at StepB=trace@0x025/0x40 #OC1B PB6 12 ATMega2560
TRACES+=-at StepC=trace@0x025/0x80 #OC1C PB7 13 ATMega2560
#
else ifeq ($(DUT),atmega2560_timer3)
DEVICE=atmega2560
TRACES+=-at StepA=trace@0x02e/0x08 #OC3A PE3 5 ATMega2560
TRACES+=-at StepB=trace@0x02e/0x10 #OC3B PE4 2 ATMega2560
TRACES+=-at StepC=trace@0x02e/0x20 #OC3C PE5 3 ATMega2560
#
else ifeq ($(DUT),atmega2560_timer4)
DEVICE=atmega2560
TRACES+=-at StepA=trace@0x102/0x08 #OC4A PH3 6 ATMega2560
TRACES+=-at StepB=trace@0x102/0x10 #OC4B PH4 7 ATMega2560
TRACES+=-at StepC=trace@0x102/0x20 #OC4C PH5 8 ATMega2560
#
else ifeq ($(DUT),atmega2560_timer5)
DEVICE=atmega2560
TRACES+=-at StepA=trace@0x10b/0x08 #OC5A PL3 46 ATMega2560
TRACES+=-at StepB=trace@0x10b/0x10 #OC5B PL4 45 ATMega2560
TRACES+=-at StepC=trace@0x10b/0x20 #OC5C PL5 44 ATMega2560
else ifeq ($(DUT),atmega168)
DEVICE=atmega168
TRACES+=-at StepA=trace@0x25/0x02 #OC1A PB1 9 atmega168
TRACES+=-at StepB=trace@0x25/0x04 #OC1B PB2 10 atmega168
else ifeq ($(DUT),atmega168p)
DEVICE=atmega168p
TRACES+=-at StepA=trace@0x25/0x02 #OC1A PB1 9 atmega168p
TRACES+=-at StepB=trace@0x25/0x04 #OC1B PB2 10 atmega168p
else ifeq ($(DUT),atmega328)
DEVICE=atmega328
TRACES+=-at StepA=trace@0x25/0x02 #OC1A PB1 9 ATMega328
TRACES+=-at StepB=trace@0x25/0x04 #OC1B PB2 10 ATMega328
else ifeq ($(DUT),atmega328p)
DEVICE=atmega328p
TRACES+=-at StepA=trace@0x25/0x02 #OC1A PB1 9 ATMega328p
TRACES+=-at StepB=trace@0x25/0x04 #OC1B PB2 10 ATMega328p
else ifeq ($(DUT),atmega32u4)
DEVICE=atmega32u4
TRACES+=-at StepA=trace@0x025/0x20 #OC1A PB5 11
TRACES+=-at StepB=trace@0x025/0x40 #OC1B PB6 12
#TRACES+=-at StepC=trace@0x025/0x80 #OC1C PB7 13
endif
ifeq ($(DEVICE),atmega2560)
TRACES+=-at DirA=trace@0x2b/0x01 # Pin 21 PD0
TRACES+=-at DirB=trace@0x2b/0x02 # Pin 20 PD1
TRACES+=-at DirC=trace@0x10b/0x80 # Pin 42 PL7
TRACES+=-at EnableA=trace@0x2b/0x04 # Pin 19 PD2
TRACES+=-at EnableB=trace@0x2b/0x08 # Pin 18 PD3
TRACES+=-at EnableC=trace@0x10b/0x40 # Pin 43 PL6
else ifeq ($(DEVICE),$(filter $(DEVICE),atmega168 atmega168p atmega328 atmega328p))
TRACES+=-at DirA=trace@0x2b/0x20 # Pin 5 PD5
TRACES+=-at DirB=trace@0x2b/0x80 # Pin 7 PD7
TRACES+=-at EnableA=trace@0x2b/0x40 # Pin 6 PD6
TRACES+=-at EnableB=trace@0x25/0x01 # Pin 8 PB0
else ifeq ($(DUT),atmega32u4)
TRACES+=-at DirA=trace@0x25/0x10 # Pin 26 PB4
TRACES+=-at DirB=trace@0x25/0x08 # Pin 14 PB3
#TRACES+=-at DirC=trace@0x10b/0x80 # Pin 42 PL7
TRACES+=-at EnableA=trace@0x25/0x04 # Pin 16 PB2
TRACES+=-at EnableB=trace@0x25/0x02 # Pin 15 PB1
#TRACES+=-at EnableC=trace@0x10b/0x40 # Pin 43 PL6
endif
FIRMWARE=".pio/build/$(DUT)/firmware.elf"
DIR=$(shell env pwd)
ifndef SILENCE
SILENCE=0
endif
test: .tested
.tested: result.txt ../judge_pos0.awk
echo DUT=$(DUT)
rm -f .tested
gawk -f ../judge_pos0.awk -v DIR=$(DIR) result.txt
test -f .tested
result.txt: x.vcd
gawk -v SILENCE=$(SILENCE) -f ../eval.awk x.vcd >/dev/null
x.vcd: $(SRC) ../run_avr platformio.ini src/Issue250.ino
~/.platformio/penv/bin/pio run -e $(DUT) || ~/.local/bin/pio run -e $(DUT) || env pio run -e $(DUT)
../run_avr $(FIRMWARE) -m $(DEVICE) -o x.vcd $(TRACES)
src/Issue250.ino:
mkdir -p src
cd src; ln -s ../../../../../examples/Issue250/Issue250.ino .
clean:
rm -fR .pio .tested x.vcd result.txt

View File

@@ -0,0 +1,32 @@
; PlatformIO Project Configuration File
;
; Build options: build flags, source filter
; Upload options: custom upload port, speed and extra flags
; Library options: dependencies, extra library storages
; Advanced options: extra scripting
;
; Please visit documentation for the other options and examples
; https://docs.platformio.org/page/projectconf.html
[platformio]
# There should be only one env section for the DUT under test.
# One of
# atmega168p
# atmega328p
# atmega2560_timer1
# atmega2560_timer3
# atmega2560_timer4
# atmega2560_timer5
#
[common]
# This is the line input to StepperDemo:
#build_flags = -D SIMULATOR -D SIMAVR_TIME_MEASUREMENT -D BLOCK_INTERRUPT_US=30
build_flags = -D SIMULATOR -D SIMAVR_TIME_MEASUREMENT -D BLOCK_INTERRUPT_US=30 -D LOOPS=100 -D TOGGLE_DIRECTION=false -D USE_MOVETO=false
[env:atmega328p]
platform = atmelavr
board = nanoatmega328
framework = arduino
build_flags = -Werror -Wall ${common.build_flags}
lib_extra_dirs = ../../../../..

View File

@@ -0,0 +1 @@
src/

View File

@@ -0,0 +1,131 @@
#
# In order to execute the test for one directory use:
#
# make -C test_sd_01b_328p -f ../Makefile.test
SRC=$(wildcard ../../../src/*) $(wildcard src/*)
# platformio should contain only one env section.
# This section states the dut name
# atmega168
# atmega168p
# atmega328
# atmega328p
# atmega2560_timer1
# atmega2560_timer3
# atmega2560_timer4
# atmega2560_timer5
#
DUT=$(shell gawk '/env:/{print(substr($$1,6,length($$1)-6))}' platformio.ini)
TRACES=-at StepISR=trace@0x25/0x08 # PB3
TRACES+=-at FillISR=trace@0x25/0x10 # PB4
#
ifeq ($(DUT),atmega2560_timer1)
DEVICE=atmega2560
TRACES+=-at StepA=trace@0x025/0x20 #OC1A PB5 11 ATMega2560
TRACES+=-at StepB=trace@0x025/0x40 #OC1B PB6 12 ATMega2560
TRACES+=-at StepC=trace@0x025/0x80 #OC1C PB7 13 ATMega2560
#
else ifeq ($(DUT),atmega2560_timer3)
DEVICE=atmega2560
TRACES+=-at StepA=trace@0x02e/0x08 #OC3A PE3 5 ATMega2560
TRACES+=-at StepB=trace@0x02e/0x10 #OC3B PE4 2 ATMega2560
TRACES+=-at StepC=trace@0x02e/0x20 #OC3C PE5 3 ATMega2560
#
else ifeq ($(DUT),atmega2560_timer4)
DEVICE=atmega2560
TRACES+=-at StepA=trace@0x102/0x08 #OC4A PH3 6 ATMega2560
TRACES+=-at StepB=trace@0x102/0x10 #OC4B PH4 7 ATMega2560
TRACES+=-at StepC=trace@0x102/0x20 #OC4C PH5 8 ATMega2560
#
else ifeq ($(DUT),atmega2560_timer5)
DEVICE=atmega2560
TRACES+=-at StepA=trace@0x10b/0x08 #OC5A PL3 46 ATMega2560
TRACES+=-at StepB=trace@0x10b/0x10 #OC5B PL4 45 ATMega2560
TRACES+=-at StepC=trace@0x10b/0x20 #OC5C PL5 44 ATMega2560
else ifeq ($(DUT),atmega168)
DEVICE=atmega168
TRACES+=-at StepA=trace@0x25/0x02 #OC1A PB1 9 atmega168
TRACES+=-at StepB=trace@0x25/0x04 #OC1B PB2 10 atmega168
else ifeq ($(DUT),atmega168p)
DEVICE=atmega168p
TRACES+=-at StepA=trace@0x25/0x02 #OC1A PB1 9 atmega168p
TRACES+=-at StepB=trace@0x25/0x04 #OC1B PB2 10 atmega168p
else ifeq ($(DUT),atmega328)
DEVICE=atmega328
TRACES+=-at StepA=trace@0x25/0x02 #OC1A PB1 9 ATMega328
TRACES+=-at StepB=trace@0x25/0x04 #OC1B PB2 10 ATMega328
else ifeq ($(DUT),atmega328p)
DEVICE=atmega328p
TRACES+=-at StepA=trace@0x25/0x02 #OC1A PB1 9 ATMega328p
TRACES+=-at StepB=trace@0x25/0x04 #OC1B PB2 10 ATMega328p
else ifeq ($(DUT),atmega32u4)
DEVICE=atmega32u4
TRACES+=-at StepA=trace@0x025/0x20 #OC1A PB5 11
TRACES+=-at StepB=trace@0x025/0x40 #OC1B PB6 12
#TRACES+=-at StepC=trace@0x025/0x80 #OC1C PB7 13
endif
ifeq ($(DEVICE),atmega2560)
TRACES+=-at DirA=trace@0x2b/0x01 # Pin 21 PD0
TRACES+=-at DirB=trace@0x2b/0x02 # Pin 20 PD1
TRACES+=-at DirC=trace@0x10b/0x80 # Pin 42 PL7
TRACES+=-at EnableA=trace@0x2b/0x04 # Pin 19 PD2
TRACES+=-at EnableB=trace@0x2b/0x08 # Pin 18 PD3
TRACES+=-at EnableC=trace@0x10b/0x40 # Pin 43 PL6
else ifeq ($(DEVICE),$(filter $(DEVICE),atmega168 atmega168p atmega328 atmega328p))
TRACES+=-at DirA=trace@0x2b/0x20 # Pin 5 PD5
TRACES+=-at DirB=trace@0x2b/0x80 # Pin 7 PD7
TRACES+=-at EnableA=trace@0x2b/0x40 # Pin 6 PD6
TRACES+=-at EnableB=trace@0x25/0x01 # Pin 8 PB0
else ifeq ($(DUT),atmega32u4)
TRACES+=-at DirA=trace@0x25/0x10 # Pin 26 PB4
TRACES+=-at DirB=trace@0x25/0x08 # Pin 14 PB3
#TRACES+=-at DirC=trace@0x10b/0x80 # Pin 42 PL7
TRACES+=-at EnableA=trace@0x25/0x04 # Pin 16 PB2
TRACES+=-at EnableB=trace@0x25/0x02 # Pin 15 PB1
#TRACES+=-at EnableC=trace@0x10b/0x40 # Pin 43 PL6
endif
FIRMWARE=".pio/build/$(DUT)/firmware.elf"
DIR=$(shell env pwd)
ifndef SILENCE
SILENCE=0
endif
test: .tested
.tested: result.txt ../judge_pos0.awk
echo DUT=$(DUT)
rm -f .tested
gawk -f ../judge_pos0.awk -v DIR=$(DIR) result.txt
test -f .tested
result.txt: x.vcd
gawk -v SILENCE=$(SILENCE) -f ../eval.awk x.vcd >/dev/null
x.vcd: $(SRC) ../run_avr platformio.ini src/Issue280.ino
~/.platformio/penv/bin/pio run -e $(DUT) || ~/.local/bin/pio run -e $(DUT) || env pio run -e $(DUT)
../run_avr $(FIRMWARE) -m $(DEVICE) -o x.vcd $(TRACES)
src/Issue280.ino:
mkdir -p src
cd src; ln -s ../../../../../examples/Issue280/Issue280.ino .
clean:
rm -fR .pio .tested x.vcd result.txt

View File

@@ -0,0 +1,16 @@
DirA: 0*L->H, 1*H->L
DirB: 0*L->H, 0*H->L
EnableA: 3*L->H, 2*H->L
EnableB: 0*L->H, 0*H->L
StepA: 33872*L->H, 33872*H->L, Max High=10us Total High=133363us
StepB: 0*L->H, 0*H->L, Max High=0us Total High=0us
Position[A]=0
Time in EnableA max=8284 us, total=12482 us
Time in FillISR max=1734 us, total=175782 us
Time in StepA max=10 us, total=133363 us
Time in StepISR max=5 us, total=128886 us

View File

@@ -0,0 +1,31 @@
; PlatformIO Project Configuration File
;
; Build options: build flags, source filter
; Upload options: custom upload port, speed and extra flags
; Library options: dependencies, extra library storages
; Advanced options: extra scripting
;
; Please visit documentation for the other options and examples
; https://docs.platformio.org/page/projectconf.html
[platformio]
# There should be only one env section for the DUT under test.
# One of
# atmega168p
# atmega328p
# atmega2560_timer1
# atmega2560_timer3
# atmega2560_timer4
# atmega2560_timer5
#
[common]
# This is the line input to StepperDemo:
build_flags = -D SIMULATOR -D SIMAVR_TIME_MEASUREMENT
[env:atmega328p]
platform = atmelavr
board = nanoatmega328
framework = arduino
build_flags = -Werror -Wall ${common.build_flags}
lib_extra_dirs = ../../../../..

View File

@@ -0,0 +1 @@
src/

View File

@@ -0,0 +1,135 @@
#
# In order to execute the test for one directory use:
#
# make -C test_sd_01b_328p -f ../Makefile.test
SRC=$(wildcard ../../../src/*) $(wildcard src/*)
# platformio should contain only one env section.
# This section states the dut name
# atmega168
# atmega168p
# atmega328
# atmega328p
# atmega2560_timer1
# atmega2560_timer3
# atmega2560_timer4
# atmega2560_timer5
#
DUT=$(shell gawk '/env:/{print(substr($$1,6,length($$1)-6))}' platformio.ini)
TRACES=-at StepISR=trace@0x25/0x08 # PB3
TRACES+=-at FillISR=trace@0x25/0x10 # PB4
#
ifeq ($(DUT),atmega2560_timer1)
DEVICE=atmega2560
TRACES+=-at StepA=trace@0x025/0x20 #OC1A PB5 11 ATMega2560
TRACES+=-at StepB=trace@0x025/0x40 #OC1B PB6 12 ATMega2560
TRACES+=-at StepC=trace@0x025/0x80 #OC1C PB7 13 ATMega2560
#
else ifeq ($(DUT),atmega2560_timer3)
DEVICE=atmega2560
TRACES+=-at StepA=trace@0x02e/0x08 #OC3A PE3 5 ATMega2560
TRACES+=-at StepB=trace@0x02e/0x10 #OC3B PE4 2 ATMega2560
TRACES+=-at StepC=trace@0x02e/0x20 #OC3C PE5 3 ATMega2560
#
else ifeq ($(DUT),atmega2560_timer4)
DEVICE=atmega2560
TRACES+=-at StepA=trace@0x102/0x08 #OC4A PH3 6 ATMega2560
TRACES+=-at StepB=trace@0x102/0x10 #OC4B PH4 7 ATMega2560
TRACES+=-at StepC=trace@0x102/0x20 #OC4C PH5 8 ATMega2560
#
else ifeq ($(DUT),atmega2560_timer5)
DEVICE=atmega2560
TRACES+=-at StepA=trace@0x10b/0x08 #OC5A PL3 46 ATMega2560
TRACES+=-at StepB=trace@0x10b/0x10 #OC5B PL4 45 ATMega2560
TRACES+=-at StepC=trace@0x10b/0x20 #OC5C PL5 44 ATMega2560
else ifeq ($(DUT),atmega168)
DEVICE=atmega168
TRACES+=-at StepA=trace@0x25/0x02 #OC1A PB1 9 atmega168
TRACES+=-at StepB=trace@0x25/0x04 #OC1B PB2 10 atmega168
else ifeq ($(DUT),atmega168p)
DEVICE=atmega168p
TRACES+=-at StepA=trace@0x25/0x02 #OC1A PB1 9 atmega168p
TRACES+=-at StepB=trace@0x25/0x04 #OC1B PB2 10 atmega168p
else ifeq ($(DUT),atmega328)
DEVICE=atmega328
TRACES+=-at StepA=trace@0x25/0x02 #OC1A PB1 9 ATMega328
TRACES+=-at StepB=trace@0x25/0x04 #OC1B PB2 10 ATMega328
else ifeq ($(DUT),atmega328p)
DEVICE=atmega328p
TRACES+=-at StepA=trace@0x25/0x02 #OC1A PB1 9 ATMega328p
TRACES+=-at StepB=trace@0x25/0x04 #OC1B PB2 10 ATMega328p
else ifeq ($(DUT),atmega32u4)
DEVICE=atmega32u4
TRACES+=-at StepA=trace@0x025/0x20 #OC1A PB5 11
TRACES+=-at StepB=trace@0x025/0x40 #OC1B PB6 12
#TRACES+=-at StepC=trace@0x025/0x80 #OC1C PB7 13
endif
ifeq ($(DEVICE),atmega2560)
TRACES+=-at DirA=trace@0x2b/0x01 # Pin 21 PD0
TRACES+=-at DirB=trace@0x2b/0x02 # Pin 20 PD1
TRACES+=-at DirC=trace@0x10b/0x80 # Pin 42 PL7
TRACES+=-at EnableA=trace@0x2b/0x04 # Pin 19 PD2
TRACES+=-at EnableB=trace@0x2b/0x08 # Pin 18 PD3
TRACES+=-at EnableC=trace@0x10b/0x40 # Pin 43 PL6
else ifeq ($(DEVICE),$(filter $(DEVICE),atmega168 atmega168p atmega328 atmega328p))
TRACES+=-at DirA=trace@0x2b/0x20 # Pin 5 PD5
TRACES+=-at DirB=trace@0x2b/0x80 # Pin 7 PD7
TRACES+=-at EnableA=trace@0x2b/0x40 # Pin 6 PD6
TRACES+=-at EnableB=trace@0x25/0x01 # Pin 8 PB0
else ifeq ($(DUT),atmega32u4)
TRACES+=-at DirA=trace@0x25/0x10 # Pin 26 PB4
TRACES+=-at DirB=trace@0x25/0x08 # Pin 14 PB3
#TRACES+=-at DirC=trace@0x10b/0x80 # Pin 42 PL7
TRACES+=-at EnableA=trace@0x25/0x04 # Pin 16 PB2
TRACES+=-at EnableB=trace@0x25/0x02 # Pin 15 PB1
#TRACES+=-at EnableC=trace@0x10b/0x40 # Pin 43 PL6
endif
FIRMWARE=".pio/build/$(DUT)/firmware.elf"
DIR=$(shell env pwd)
ifndef SILENCE
SILENCE=0
endif
test: .tested
.tested: result.txt expect.txt ../judge.awk
echo DUT=$(DUT)
rm -f .tested
gawk -f ../judge.awk -v DIR=$(DIR) result.txt expect.txt
test -f .tested
result.txt: x.vcd
gawk -v SILENCE=$(SILENCE) -f ../eval.awk x.vcd
cat expect.txt
x.vcd: $(SRC) ../run_avr platformio.ini src/PMF_test.ino src/test_03.h
~/.platformio/penv/bin/pio run -e $(DUT) || ~/.local/bin/pio run -e $(DUT) || env pio run -e $(DUT)
../run_avr $(FIRMWARE) -m $(DEVICE) -o x.vcd $(TRACES)
src/PMF_test.ino:
mkdir -p src
cd src; ln -s ../../../pc_based/PMF_test.ino .
src/test_03.h:
mkdir -p src
cd src; ln -s ../../../pc_based/test_03.h .
clean:
rm -fR .pio .tested x.vcd result.txt

View File

@@ -0,0 +1,10 @@
DirA: 0*L->H, 0*H->L
DirB: 1*L->H, 0*H->L
EnableA: 0*L->H, 0*H->L
EnableB: 0*L->H, 0*H->L
StepA: 0*L->H, 0*H->L, Max High=0us Total High=0us
StepB: 2*L->H, 2*H->L, Max High=12us Total High=16us
Position[B]=2
Time in StepB max=12 us, total=16 us

View File

@@ -0,0 +1,31 @@
; PlatformIO Project Configuration File
;
; Build options: build flags, source filter
; Upload options: custom upload port, speed and extra flags
; Library options: dependencies, extra library storages
; Advanced options: extra scripting
;
; Please visit documentation for the other options and examples
; https://docs.platformio.org/page/projectconf.html
[platformio]
# There should be only one env section for the DUT under test.
# One of
# atmega168p
# atmega328p
# atmega2560_timer1
# atmega2560_timer3
# atmega2560_timer4
# atmega2560_timer5
#
[common]
# This is the line input to StepperDemo:
build_flags = -D SIMULATOR
[env:atmega328p]
platform = atmelavr
board = nanoatmega328
framework = arduino
build_flags = -Werror -Wall ${common.build_flags}
lib_extra_dirs = ../../../../..

View File

@@ -0,0 +1,15 @@
DirA: 0*L->H, 0*H->L
DirB: 1*L->H, 0*H->L
DirC: 0*L->H, 0*H->L
EnableA: 1*L->H, 1*H->L
EnableB: 1*L->H, 0*H->L
EnableC: 1*L->H, 0*H->L
StepA: 3200*L->H, 3200*H->L, Max High=13us Total High=17018us
StepB: 0*L->H, 0*H->L, Max High=0us Total High=0us
StepC: 0*L->H, 0*H->L, Max High=0us Total High=0us
Position[A]=3200
Time in EnableA max=450673 us, total=450673 us
Time in StepA max=13 us, total=17018 us

View File

@@ -0,0 +1,32 @@
; PlatformIO Project Configuration File
;
; Build options: build flags, source filter
; Upload options: custom upload port, speed and extra flags
; Library options: dependencies, extra library storages
; Advanced options: extra scripting
;
; Please visit documentation for the other options and examples
; https://docs.platformio.org/page/projectconf.html
[platformio]
# There should be only one env section for the DUT under test.
# One of
# atmega168p
# atmega328p
# atmega2560_timer1
# atmega2560_timer3
# atmega2560_timer4
# atmega2560_timer5
#
[common]
# This is the line input to StepperDemo:
build_flags = -D SIM_TEST_INPUT='"? M1 A1000 V100 R3200 W t W "'
[env:atmega2560_timer1]
platform = atmelavr
board = megaatmega2560
framework = arduino
build_flags = -Werror -Wall -DFAS_TIMER_MODULE=1 ${common.build_flags}
lib_extra_dirs = ../../../../..

View File

@@ -0,0 +1,15 @@
DirA: 0*L->H, 0*H->L
DirB: 1*L->H, 0*H->L
DirC: 0*L->H, 0*H->L
EnableA: 1*L->H, 1*H->L
EnableB: 1*L->H, 0*H->L
EnableC: 1*L->H, 0*H->L
StepA: 3200*L->H, 3200*H->L, Max High=13us Total High=17029us
StepB: 0*L->H, 0*H->L, Max High=0us Total High=0us
StepC: 0*L->H, 0*H->L, Max High=0us Total High=0us
Position[A]=3200
Time in EnableA max=450673 us, total=450673 us
Time in StepA max=13 us, total=17029 us

View File

@@ -0,0 +1,32 @@
; PlatformIO Project Configuration File
;
; Build options: build flags, source filter
; Upload options: custom upload port, speed and extra flags
; Library options: dependencies, extra library storages
; Advanced options: extra scripting
;
; Please visit documentation for the other options and examples
; https://docs.platformio.org/page/projectconf.html
[platformio]
# There should be only one env section for the DUT under test.
# One of
# atmega168p
# atmega328p
# atmega2560_timer1
# atmega2560_timer3
# atmega2560_timer4
# atmega2560_timer5
#
[common]
# This is the line input to StepperDemo:
build_flags = -D SIM_TEST_INPUT='"? M1 A1000 V100 R3200 W t W "'
[env:atmega2560_timer3]
platform = atmelavr
board = megaatmega2560
framework = arduino
build_flags = -Werror -Wall -DFAS_TIMER_MODULE=3 ${common.build_flags}
lib_extra_dirs = ../../../../..

View File

@@ -0,0 +1,15 @@
DirA: 0*L->H, 0*H->L
DirB: 1*L->H, 0*H->L
DirC: 0*L->H, 0*H->L
EnableA: 1*L->H, 1*H->L
EnableB: 1*L->H, 0*H->L
EnableC: 1*L->H, 0*H->L
StepA: 3200*L->H, 3200*H->L, Max High=13us Total High=17029us
StepB: 0*L->H, 0*H->L, Max High=0us Total High=0us
StepC: 0*L->H, 0*H->L, Max High=0us Total High=0us
Position[A]=3200
Time in EnableA max=450673 us, total=450673 us
Time in StepA max=13 us, total=17029 us

Some files were not shown because too many files have changed in this diff Show More