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.
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.
ISO15693 codec was undocumented and without comments in relevant parts. I decided to spend 3 days diving into XMega interrupts and Chameleon's lowest level code. Now, I hope, it should be more readable for everyone, even newbies like my old self was before I started this deep dive.
Also, I fixed the bug referenced here https://github.com/geo-rg/ChameleonMini/issues/4 which locked the chameleon when no response was to be sent to the reader
Started from the smallest threshold and when the first good threshold is obtained, stop.
May also need to extend the TIMEOUT to make this work.
Need the reader reading all the timing when sniffing in order to auto calibrate
(cherry picked from commit 2c3d5f5)
This will prepare for the autocalibrate of threshold
If card selection fully detected, then the threshold is good,
Otherwise it is not good.
(cherry picked from commit f5c8485)
It now decode and sample in the same time, so the decode half bit sampling to Manchester in the CodecTask can be removed.
This optimisation may also fix the bug that the CodecTask not finished after start of Reader->Card Sampling and make the reader->Card sampling not in perfect timing and cause the Reader ->Card Sniffed data to be wrong.
Trace from oscilloscope for the Problem:
ReaderSniffing Enable
__________ _________
__| |____________________| |_________
CardSniffing Enable
_____________ _______
________________| |______________|
Task
__ ___----
_|__|__|__|___| |__|__|__|__|__|_| |__|__|__|__|
"-" indicate the problem
(cherry picked from commit a246b98)
This fix the bug that the sniffing get wrong data when the time gap between card signal and reader signal is too small
(cherry picked from commit 573cb49)
Print log after a round finished
Otherwise it will take too much cpu cycles then the card traffic sniffing may not start in time
(cherry picked from commit 48c89f5)