Test code which wants to customize config.h can do so without
touching config.h itself by wrapping config.h in a macro variable
which is passed in to the compiler. It defaults to "config.h" if
no override is provided.
This change would break makefile dependency checking since the selection
of a different header file on the command line is not noticed by make
as a build-trigger. To solve this, we add a layer to the BUILDDIR path
so build products are now specific to the USER_CONFIG choice if it is
not "config.h".
This obviously requires less place on the stack and accordingly a
few CPU cycles less, but more importantly, it lets decide
dda_start() whether a previous movement is to be taken into account
or not.
To make this decision more reliable, add a flag for movements done.
Else it could happen we'd try to join with a movement done long
before.
This code was accidentally removed long ago in a botched merge. This
patch recovers it and makes it build again. I've done minimal testing
and some necessary cleanup. It compiles and runs, but it probably still
has a few dust bunnies here and there.
I added registers and pin definitions to simulator.h and
simulator/simulator.c which I needed to match my Gen7-based config.
Other configs or non-AVR ports will need to define more or different
registers. Some registers are 16-bits, some are 8-bit, and some are just
constant values (enums). A more clever solution would read in the
chip-specific header and produce saner definitions which covered all
GPIOs. But this commit just takes the quick and easy path to support my
own hardware.
Most of this code originated in these commits:
commit cbf41dd4ad
Author: Stephan Walter <stephan@walter.name>
Date: Mon Oct 18 20:28:08 2010 +0200
document simulation
commit 3028b297f3
Author: Stephan Walter <stephan@walter.name>
Date: Mon Oct 18 20:15:59 2010 +0200
Add simulation code: use "make sim"
Additional tweaks:
Revert va_args processing for AVR, but keep 'int' generalization
for simulation. gcc wasn't lying. The sim really aborts without this.
Remove delay(us) from simulator (obsolete).
Improve the README.sim to demonstrate working pronterface connection
to sim. Also fix the build instructions.
Appease all stock configs.
Stub out intercom and shush usb_serial when building simulator.
Pretend to be all chip-types for config appeasement.
Replace sim_timer with AVR-simulator timer:
The original sim_timer and sim_clock provided direct replacements
for timer/clock.c in the main code. But when the main code changed,
simcode did not. The main clock.c was dropped and merged into timer.c.
Also, the timer.c now has movement calculation code in it in some
cases (ACCELERATION_TEMPORAL) and it would be wrong to teach the
simulator to do the same thing. Instead, teach the simulator to
emulate the AVR Timer1 functionality, reacting to values written to
OCR1A and OCR1B timer comparison registers.
Whenever OCR1A/B are changed, the sim_setTimer function needs to be
called. It is called automatically after a timer event, so changes
within the timer ISRs do not need to bother with this.
A C++ class could make this requirement go away by noticing the
assignment. On the other hand, a chip-agnostic timer.c would help
make the main code more portable. The latter cleanup is probably
better for us in the long run.
Before, endstops were checked on every step, wasting precious time.
Checking them 500 times a second should be more than sufficient.
Additionally, an endstop stop now properly decelerates the movement.
This is one important step towards handling accidental endstop hits
gracefully, as it avoids step losses in such situations.
As a sample application, use it in queue_empty().
There's also ATOMIC_BLOCK() coming with avr-libc, but this requires
a C99 compiler while Arduino IDE insists on running avr-gcc in C89 mode.
This means, modify existing code to let the lookahead algorithms
do their work. It also means to remove some unused code in
dda_lookahead.c and reordering some code to make it work with
LOOKAHEAD undefined.
This makes the code cleaner and the reduction of code
probably easily compensates for keeping global interrupts
enabled for a bit longer. Talked to macscifi about this.
Saves about 300 bytes of binary size.
This is a intrusive patch and for now, it's done for the X axis only.
To make comparison with the former approach easier ...
The advantages of this change:
- Converting from mm to steps in gcode_parse.c and back in dda.c
wastes cycles and accuracy.
- In dda.c, UM_PER_STEP simply goes away, so distance calculations
work now with STEPS_PER_MM > 500 just fine. 1/16 microstepping
on threaded rods (Z axis) becomes possible.
- Distance calculations (feedrate, acceleration, ...) become much
simpler.
- A wide range of STEPS_PER_M can now be handled at reasonable
(4 decimal digit) accuracy with a simple macro. Formerly,
we were limited to 500 steps/mm, now we can do 4'096 steps/mm
and could easily raise this another digit.
Disadvantages:
- STEPS_PER_MM is gone in config.h, using STEPS_PER_M is required,
because the preprocessor refuses to compare numbers with decimal
points in them.
- The DDA has to store the position in steps anyways to avoid
rounding errors.
This prevents nasty surprises because this restriction is not mentioned in the configuration files. It also allows better tuning of performance against memory usage.
Traumflug: costs 18 bytes flash, so it's bearable.
Specifically, disable interrupts just before returning and then enable
the timer interrupt if appropriate. This means that the timer interrupt
cannot actually fire until after the RETI, so the function cannot be
entered recursively.
manage the movebuffer (mb_head, mb_tail, movebuffer).
The approach taken is to leave all of the variables non-volatile
and use memory barriers to control reads/writes. read/modify/write
operations that can be done outside of the interrupt context are
protected by disabling interrupts.
Also, manually cache the pointer to the movebuffer of interest
as the compiler does a poor job of reusing the pointer even in
places that it could.
There are still some groups of accesses to the movebuffer data that need
to be protected by disabling interrupts, but these are all related
to sending back debug data. The error will cause occassional mismatched
values to be sent back via the serial connection, but they do not
affect the actual operation of the code, so they will be addressed
in a separate checkin.
Conflicts:
dda_queue.c
This costs 2 bytes of ram, but saves 60 bytes of flash. Doing so
also eliminates the need to disable interrupts while clearing flags
in the ifclock macro.
Conflicts:
clock.c
timer.c
timer.h
After lots of try and error the conclusion was, disabling this
interrupt makes the timer vulnerable to be messed up by
characters incoming over the serial line. So, now the
interrupt is enabled as a move starts and not disabled before
the move, and all subsequent moves are done.