ISO15693 CRC calculation is slow and it delayed too much transmission of long
frames. Some readers marked transmission as unsuccesfull and ignored data.
Moving CRC calculation inside the codec allows to start modulating the field
while the CRC is not yet ready but, by the time it has to be trasmitted,
calculation will be done.
This fixes https://github.com/emsec/ChameleonMini/issues/262
In EM4233, there still are issues with Read Multiple command when block
locking status is requested for more than 0x1F blocks
Implemented a check in ISO15693 codec to avoid out of bound CRC writes.
Removed the if-elseif in EM4233 to use a switch case which yields minor
speed improvements of ~1,5 microseconds
Avoid reading the UID every AppProcess tick in both EM4233 and TiTagIT
to save ~11 microseconds.
Unvarying interrupt configuration moved from StartISO15693Demod to CodecInit
Fixed an old issue (https://github.com/geo-rg/ChameleonMini/issues/4) properly
overwriting the PERBUF register when no data has to be sent
Loadmodulation ISR has a new GOTO label which is called when ISO t1 time is
elapsed, but data is not yet ready. This way it is possible to avoid checking
for state validity on every ISR hit
New inline function to clean up interrupts when field noise (garbage)
is incorrectly picked up
Bitrate configuration in ISO15693_EOC has been simplified
Cleaned up header file with useless defines. Moved defines to .c when there was
no need to share them with other source files
Annotated numer of clock cycles consumed by asm ISR sharing routine
As usual, this work was done with @MrModDom
Since GCC 10, the compiler defaults to -fno-common, thus variables with
multiple tentative definitions result in linker errors.
We've (me and @MrMoDDoM) extern-ed the shared variables to fix the issue.
Also, when I implemented ISR sharing, somehow I forgot about a function
which was shared as well, so I fixed that mistake and added a couple of
comments on how shared function calls work.
While in the process of writing a new codec I stumbled upon the long
standing issue of ISR sharing in AVR MCUs.
Actually this is accomplished with an ISR written in C, which simply
calls another plain C function referenced via a function pointer
updated at runtime.
This approach is slow because GCC can't optimize the ISR, since it
does not know which registers will be used, so it defaults to push/pop
all of them.
My solution keeps the concept of pointers to functions, but greatly
improves speed by reducing the ISR itself to the bare minimum to call
another function, which will be compiled by GCC as a signal.
This means all interrupt optimizations will be put in place by GCC,
while ISRs can be still written in plain C code, but the overhead is
now much smaller. It has proven to reduce by 20 the number of
instructions for every ISR, mainly pushes/pops, which cuts the clock
cycle count down by 30 cycles (1 cycle for every push, 2 for pop).
In time units, this means 1.1 uSec are saved for every ISR invocation
and every shared ISR now takes only 13 clock cycles more than the
"bare" one.
A new ISR_SHARED function type has been defined in Common.h to hide
away from the programmer GCC attributes. All new shared interrupt
handling routines should be defined of this type to prevent
stack and registers corruption.
Minor changes were made to Codec.h to allow including it in .S files.
This adds automatic cloning of Mifare Ultralight cards to the selected
setting.
Currently, only the DUMP_MFU command existed. In order to clone a Mifare
Ultralight card, the user had to convert the hex output of DUMP_MFU to binary
and upload the result to the card.
The CLONE_MFU command will attempt to read and store the Mifare Ultralight
contents directy to the slot which is then transitioned to emulation mode.
The CLONE_MFU button action does the same, so the board can be configured to
clone cards by simply selecting a slot with one button and cloning with the
other.