Add simulator for SD card driver, plus add stubs for SPI and PFF
primarily to prevent the on-device code from being picked up by
the makefiles for the simulator.
Previously, values of ignored keys simply got lost and were
replaced with the ones from from the metadata file. Now this
value is preserved and perhaps, some time in the future, we'll
use this bit of information to to provide the right value when
re-enabling it.
Previously they were dropped only at save time, which is too late
for the GUI. This is mostly for robustness, the case where a
value was removed from config files, but not yet from the GUI.
Shouldn't cause functional change.
So far, values commented out are still ignored, which is why the
used regexp changed. This will hopefully change in the future,
so a configuration can remember disabled values, too.
This solves the problem of choice menus being populated with too
many entries. Before, such menus would pick up values from
board.metadata as well as from the actually loaded file.
File printer.metadata contains no options, so no adjustment
needed there.
This has to work, else we can't provide default values for new
items.
Now loading a RAMPS board and just saving it results in an
identical file. Very well. Not so for other boards, because
disabled values still get lost.
This means a custom function in pff_diskio.c, disk_parsep(),
which replaces disk_readp(). Now it no longer reads a whole
sector for every single byte, but only once per line of G-code.
Performance is now much better than with buffered reading, the
1 MB file with 16'468 lines of comments, 64 bytes per line,
read and parses now in just 46 seconds, which means 358 lines
or 22'795 bytes per second.
Unfortunately all the binary size loss is gone compared to the
previous version, we're 68 bytes bigger than before buffer-less
parsing. Reason is the new function disk_parsep() in
pff_diskio.h. RAM usage is still low.
ATmega... '168 '328(P) '644(P) '1280
FLASH: 22276 bytes 155.39% 72.51% 35.09% 17.27%
RAM: 1331 bytes 129.98% 64.99% 32.50% 16.25%
EEPROM: 32 bytes 3.12% 1.56% 1.56% 0.78%
Formerly we took efforts to read only small chunks into a
(small) buffer, just to read this buffer byte by byte yet
again for parsing. It's more efficient and requires less
code to parse the character at read time directly. This
way we can read in chunks of exactly one line, making the
buffer obsolete.
First step is to implement this in mendel.c and in sd.c/.h.
This gets rid of the buffer already.
Very inefficient in pff.c and pff_diskio.c so far, more
than 40 minutes / less than 500 bytes/s for reading this
1 MB comments file. Reason is, for every single byte a
whole sector is read. Nevertheless, this attempt appears
to be on the right track.
Binary is 156 bytes smaller, 16 bytes less RAM:
ATmega... '168 '328(P) '644(P) '1280
FLASH: 22052 bytes 153.82% 71.78% 34.73% 17.09%
RAM: 1331 bytes 129.98% 64.99% 32.50% 16.25%
EEPROM: 32 bytes 3.12% 1.56% 1.56% 0.78%
Add shortcuts to Makefile-example for regressiontests and program
so it can more easily be used as-is.
Remove the comment suggesting to use Makefile-AVR directly instead
since it is no longer more convenient, at least for the original
reason.
We should not fail the regression test if the user's config is
missing or misconfigured.
Also turn on -Werror for simulator validation, too. This might be
a bit presumptuous since we are dependent on the user's installed
gcc instance; but we already depending on him to be able to build
the simulator at all, so this doesn't seem to be too much of a
stretch.
This was found by running the new regression tests. ...and seeing
that this is pretty old code, I wonder how Teacup could ever
compile for the Teensy2 guys.
For now this is just a number of different configurations and a
makefile target, "make regressiontests", to build with them.
Further tests, e.g. using SimulAVR or the hostside simulator
to check actual behaviour of the firmware are welcome.
This raises abstraction and even makes the binary a bit smaller
(2 bytes without SD, 14 bytes with SD).
A G-code file with 16'384 lines of comments, 64 bytes per line
( = 1 MB file size), is read and parsed from SD card in 2:47
minutes, or at a speed of 5924 bytes/second.
FAT12 was not choosen, because it's virtually no longer in use
(allows volume sizes up to 32 MB, only) and would increase
binary size by another 248 bytes.
Measured sizes are in a comment in pff_conf.h, where one can also
enable or disable support for these variants.
Turned out to be pretty easy with all the more complex bits
already in place.
Strategy is to always parse a full line from one of the sources.
Accordingly, simply sending a character on the serial line stops
reading from SD until the line coming in over serial is completed.
As we're around here, lets see how fast this implementation is.
All measurements are raw reading performance, without actual
parsing of the G-code.
With SPI_2X disabled (see line 8 in spi.h), performance is
195 seconds per megabyte, equivalent to about 50'000 baud.
With SPI_2X enabled, performance is 159 seconds per megabyte,
or 60'000 baud.
Still, SPI_2X is left disabled to increase reliability. Reading
from SD is faster by design, because there is no checksumming and
also no waiting for the "ok" to be sent back. In case reading
G-code from SD ever becomes a bottleneck, there are even more
opportunities in addition to enabling SPI_2X, like making sdbuffer
bigger, like micro-optimizing spi_rw() and similar stuff.
Next to the implementation of sd_read_byte() as well as M24 and
M25, yet another demo: read the file and write it to the serial
line, to show correctness of the implementation.
This solves lines like these, with previous answer:
M23 bla*3
ok E: Bad M-code 233
M23 123*92
ok E: Bad M-code 88
It should also solve lines with ;-comment _and_ a checksum.
This is neccessary to allow file names with leading digits. It's
still possible to send commands like M105 with spaces in between
("M1 05") and also to put space between character and number, like
"X 15.0".
Part 2 is to implement M23: select file. That's more than just a
few lines, as we also have to teach the gcode-parser to collect
strings.
For now the file is simply tested for successful opening, no
actual printing, yet.
About build size: during development there was another
implementation, which didn't abstract SD card functions into
sd.c/.h, but put them into gcode_process.c directly. At the
feature completeness of this commit, the other implementation
used 70 bytes flash less, but also 23 bytes more RAM. So I decided
for the more abstracted/encapsulated version. --Traumflug
Also, this adds 14 bytes binary size even without SD card support.
A lot more #ifdefs around each use of next_target.read_string
would remove this, but after all we do care a bit about
readability of the source code, so let's sacrify these 14 bytes
to it. --Traumflug
Part 1 is, implement
- M20: List SD card.
- M21: Initialize SD card (has to be done before listing).
- M22: Release SD card.
Do all this in one chunk, splitting this up wouldn't allow to test
the result.
Let the preprocessor decide wether this piece of code is compiled
at all. Previous behaviour was to compile it unconditionally and
rely on the optimizer to remove it after that. Trusting the
optimizer is fine, but only if the code is warning-free in all cases.
This is all the commands to read from and write to SPI,
initializing the card, read in blocks and so on. This should
make Petit FatFs actually usable.
So far read-only and no M-codes to let end users play with
this stuff.
The demonstration code was changed to list the SD card's
top level directory over and over again.
Some modifications to avoid file name conflicts with other parts and
make it compile. As the glue code to the hardware (spi.c/.h) is
still missing, there are a few warnings, of course.
Changes to this library are tracked in pff.c.