Merge pull request #227 from drandreas/development

Clean Legic Reader
This commit is contained in:
Iceman 2018-08-12 13:58:25 +02:00 committed by GitHub
commit 905df58cc3
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
8 changed files with 539 additions and 1682 deletions

View file

@ -74,6 +74,7 @@ extern void switch_off(void);
// Options for the HF reader, correlating against rx from tag // Options for the HF reader, correlating against rx from tag
#define FPGA_HF_READER_RX_XCORR_848_KHZ (1<<0) #define FPGA_HF_READER_RX_XCORR_848_KHZ (1<<0)
#define FPGA_HF_READER_RX_XCORR_SNOOP (1<<1) #define FPGA_HF_READER_RX_XCORR_SNOOP (1<<1)
#define FPGA_HF_READER_RX_XCORR_QUARTER (1<<2)
// Options for the HF simulated tag, how to modulate // Options for the HF simulated tag, how to modulate
#define FPGA_HF_SIMULATOR_NO_MODULATION (0<<0) // 0000 #define FPGA_HF_SIMULATOR_NO_MODULATION (0<<0) // 0000
#define FPGA_HF_SIMULATOR_MODULATE_BPSK (1<<0) // 0001 #define FPGA_HF_SIMULATOR_MODULATE_BPSK (1<<0) // 0001

File diff suppressed because it is too large Load diff

View file

@ -11,38 +11,11 @@
#ifndef __LEGICRF_H #ifndef __LEGICRF_H
#define __LEGICRF_H #define __LEGICRF_H
#include "proxmark3.h" // #include "proxmark3.h"
#include "apps.h"
#include "util.h" //
#include "string.h"
#include "legic_prng.h" // legic PRNG impl
#include "crc.h" // legic crc-4
#include "ticks.h" // timers
#include "legic.h" // legic_card_select_t struct
extern void LegicRfSimulate(int phase, int frame, int reqresp);
extern int LegicRfReader(uint16_t offset, uint16_t len, uint8_t iv);
extern void LegicRfWriter(uint16_t offset, uint16_t byte, uint8_t iv, uint8_t *data);
extern void LegicRfInfo(void); extern void LegicRfInfo(void);
extern void LegicRfReader(uint16_t offset, uint16_t len, uint8_t iv);
uint32_t get_key_stream(int skip, int count); extern void LegicRfWriter(uint16_t offset, uint16_t byte, uint8_t iv, uint8_t *data);
void frame_send_tag(uint16_t response, uint8_t bits); extern void LegicRfSimulate(int phase, int frame, int reqresp);
void frame_sendAsReader(uint32_t data, uint8_t bits);
int legic_read_byte( uint16_t index, uint8_t cmd_sz);
bool legic_write_byte(uint16_t index, uint8_t byte, uint8_t addr_sz);
int legic_select_card(legic_card_select_t *p_card);
int legic_select_card_iv(legic_card_select_t *p_card, uint8_t iv);
void LegicCommonInit(bool clear_mem);
// emulator mem
void LegicEMemSet(uint32_t arg0, uint32_t arg1, uint8_t *data);
void LegicEMemGet(uint32_t arg0, uint32_t arg1);
void legic_emlset_mem(uint8_t *data, int offset, int numofbytes);
void legic_emlget_mem(uint8_t *data, int offset, int numofbytes);
void ice_legic_setup();
#endif /* __LEGICRF_H */ #endif /* __LEGICRF_H */

View file

@ -169,59 +169,70 @@ uint32_t RAMFUNC GetCountSspClk(void) {
} }
// ------------------------------------------------------------------------- // -------------------------------------------------------------------------
// Timer for bitbanging, or LF stuff when you need a very precis timer // Timer for bitbanging, or LF stuff when you need a very precis timer
// 1us = 1.5ticks // 1us = 1.5ticks
// ------------------------------------------------------------------------- // -------------------------------------------------------------------------
void StartTicks(void){ void StartTicks(void){
//initialization of the timer // initialization of the timer
// tc1 is higher 0xFFFF0000
// tc0 is lower 0x0000FFFF
AT91C_BASE_PMC->PMC_PCER |= (1 << AT91C_ID_TC0) | (1 << AT91C_ID_TC1); AT91C_BASE_PMC->PMC_PCER |= (1 << AT91C_ID_TC0) | (1 << AT91C_ID_TC1);
AT91C_BASE_TCB->TCB_BMR = AT91C_TCB_TC0XC0S_NONE | AT91C_TCB_TC1XC1S_TIOA0 | AT91C_TCB_TC2XC2S_NONE; AT91C_BASE_TCB->TCB_BMR = AT91C_TCB_TC0XC0S_NONE | AT91C_TCB_TC1XC1S_TIOA0 | AT91C_TCB_TC2XC2S_NONE;
AT91C_BASE_TC0->TC_CCR = AT91C_TC_CLKDIS;
AT91C_BASE_TC0->TC_CMR = AT91C_TC_CLKS_TIMER_DIV3_CLOCK | // MCK(48MHz) / 32
AT91C_TC_WAVE | AT91C_TC_WAVESEL_UP_AUTO | AT91C_TC_ACPA_CLEAR |
AT91C_TC_ACPC_SET | AT91C_TC_ASWTRG_SET;
AT91C_BASE_TC0->TC_RA = 1;
AT91C_BASE_TC0->TC_RC = 0;
AT91C_BASE_TC1->TC_CCR = AT91C_TC_CLKDIS; // timer disable // disable TC0 and TC1 for re-configuration
AT91C_BASE_TC1->TC_CMR = AT91C_TC_CLKS_XC1; // from TC0 AT91C_BASE_TC0->TC_CCR = AT91C_TC_CLKDIS;
AT91C_BASE_TC1->TC_CCR = AT91C_TC_CLKDIS;
AT91C_BASE_TC0->TC_CCR = AT91C_TC_CLKEN | AT91C_TC_SWTRG;
AT91C_BASE_TC1->TC_CCR = AT91C_TC_CLKEN | AT91C_TC_SWTRG; // first configure TC1 (higher, 0xFFFF0000) 16 bit counter
AT91C_BASE_TCB->TCB_BCR = 1; AT91C_BASE_TC1->TC_CMR = AT91C_TC_CLKS_XC1; // just connect to TIOA0 from TC0
AT91C_BASE_TC1->TC_CCR = AT91C_TC_CLKEN | AT91C_TC_SWTRG; // re-enable timer and wait for TC0
// wait until timer becomes zero.
while (AT91C_BASE_TC1->TC_CV > 0); // second configure TC0 (lower, 0x0000FFFF) 16 bit counter
AT91C_BASE_TC0->TC_CMR = AT91C_TC_CLKS_TIMER_DIV3_CLOCK | // MCK(48MHz) / 32
AT91C_TC_WAVE | AT91C_TC_WAVESEL_UP_AUTO |
AT91C_TC_ACPA_CLEAR | // RA comperator clears TIOA (carry bit)
AT91C_TC_ACPC_SET | // RC comperator sets TIOA (carry bit)
AT91C_TC_ASWTRG_SET; // SWTriger sets TIOA (carry bit)
AT91C_BASE_TC0->TC_RC = 0; // set TIOA (carry bit) on overflow, return to zero
AT91C_BASE_TC0->TC_RA = 1; // clear carry bit on next clock cycle
AT91C_BASE_TC0->TC_CCR = AT91C_TC_CLKEN | AT91C_TC_SWTRG; // reset and re-enable timer
// synchronized startup procedure
while (AT91C_BASE_TC0->TC_CV > 0); // wait until TC0 returned to zero
while (AT91C_BASE_TC0->TC_CV < 2); // and has started (TC_CV > TC_RA, now TC1 is cleared)
// return to zero
AT91C_BASE_TC1->TC_CCR = AT91C_TC_SWTRG;
AT91C_BASE_TC0->TC_CCR = AT91C_TC_SWTRG;
while (AT91C_BASE_TC0->TC_CV > 0);
} }
uint32_t GetTicks(void) {
uint32_t hi, lo;
do {
hi = AT91C_BASE_TC1->TC_CV;
lo = AT91C_BASE_TC0->TC_CV;
} while(hi != AT91C_BASE_TC1->TC_CV);
return (hi << 16) | lo;
}
// Wait - Spindelay in ticks. // Wait - Spindelay in ticks.
// if called with a high number, this will trigger the WDT... // if called with a high number, this will trigger the WDT...
void WaitTicks(uint32_t ticks){ void WaitTicks(uint32_t ticks){
if ( ticks == 0 ) return; if ( ticks == 0 ) return;
ticks += GET_TICKS; ticks += GetTicks();
while (GET_TICKS < ticks); while (GetTicks() < ticks);
} }
// Wait / Spindelay in us (microseconds) // Wait / Spindelay in us (microseconds)
// 1us = 1.5ticks. // 1us = 1.5ticks.
void WaitUS(uint16_t us){ void WaitUS(uint16_t us){
if ( us == 0 ) return; WaitTicks( (uint32_t)us * 3/2 );
WaitTicks( (uint32_t)us * 3/2 );
} }
void WaitMS(uint16_t ms){ void WaitMS(uint16_t ms){
if (ms == 0) return;
WaitTicks( (uint32_t)ms * 1500 ); WaitTicks( (uint32_t)ms * 1500 );
} }
// Starts Clock and waits until its reset
void ResetTicks(void){
AT91C_BASE_TC0->TC_CCR = AT91C_TC_CLKEN | AT91C_TC_SWTRG;
AT91C_BASE_TC1->TC_CCR = AT91C_TC_CLKEN | AT91C_TC_SWTRG;
while (AT91C_BASE_TC1->TC_CV > 0);
}
void ResetTimer(AT91PS_TC timer){
timer->TC_CCR = AT91C_TC_CLKEN | AT91C_TC_SWTRG;
while(timer->TC_CV > 0) ;
}
// stop clock // stop clock
void StopTicks(void){ void StopTicks(void){
AT91C_BASE_TC0->TC_CCR = AT91C_TC_CLKDIS; AT91C_BASE_TC0->TC_CCR = AT91C_TC_CLKDIS;

View file

@ -19,7 +19,7 @@
#include "proxmark3.h" #include "proxmark3.h"
#ifndef GET_TICKS #ifndef GET_TICKS
# define GET_TICKS (uint32_t)((AT91C_BASE_TC1->TC_CV << 16) | AT91C_BASE_TC0->TC_CV) #define GET_TICKS GetTicks()
#endif #endif
void SpinDelay(int ms); void SpinDelay(int ms);
@ -32,17 +32,15 @@ void StartCountUS(void);
uint32_t RAMFUNC GetCountUS(void); uint32_t RAMFUNC GetCountUS(void);
void ResetUSClock(void); void ResetUSClock(void);
void SpinDelayCountUs(uint32_t us); void SpinDelayCountUs(uint32_t us);
//uint32_t RAMFUNC GetDeltaCountUS(void);
void StartCountSspClk(); void StartCountSspClk();
void ResetSspClk(void); void ResetSspClk(void);
uint32_t RAMFUNC GetCountSspClk(); uint32_t RAMFUNC GetCountSspClk();
extern void StartTicks(void); void StartTicks(void);
extern void WaitTicks(uint32_t ticks); uint32_t GetTicks(void);
extern void WaitUS(uint16_t us); void WaitTicks(uint32_t ticks);
extern void WaitMS(uint16_t ms); void WaitUS(uint16_t us);
extern void ResetTicks(); void WaitMS(uint16_t ms);
extern void ResetTimer(AT91PS_TC timer); void StopTicks(void);
extern void StopTicks(void);
#endif #endif

View file

@ -518,9 +518,9 @@ int CmdTraceList(const char *Cmd) {
if ( protocol == ISO_14443A || protocol == PROTO_MIFARE) if ( protocol == ISO_14443A || protocol == PROTO_MIFARE)
PrintAndLogEx(NORMAL, "iso14443a - All times are in carrier periods (1/13.56Mhz)"); PrintAndLogEx(NORMAL, "iso14443a - All times are in carrier periods (1/13.56Mhz)");
if ( protocol == ICLASS ) if ( protocol == ICLASS )
PrintAndLogEx(NORMAL, "iClass - Timings are not as accurate"); PrintAndLogEx(NORMAL, "iClass - Timings are not as accurate");
if ( protocol == LEGIC ) if ( protocol == LEGIC )
PrintAndLogEx(NORMAL, "LEGIC - Timings are in ticks (1us == 1.5ticks)"); PrintAndLogEx(NORMAL, "LEGIC - Timings are in ticks (1us == 1.5ticks)");
if ( protocol == ISO_15693 ) if ( protocol == ISO_15693 )
PrintAndLogEx(NORMAL, "ISO15693 - Timings are not as accurate"); PrintAndLogEx(NORMAL, "ISO15693 - Timings are not as accurate");
if ( protocol == FELICA ) if ( protocol == FELICA )

Binary file not shown.

View file

@ -71,19 +71,8 @@ always @(negedge ssp_clk)
assign ssp_frame = (hi_byte_div == 3'b000); assign ssp_frame = (hi_byte_div == 3'b000);
// Implement a hysteresis to give out the received signal on assign ssp_din = 1'b0;
// ssp_din. Sample at fc.
assign adc_clk = ck_1356meg;
// ADC data appears on the rising edge, so sample it on the falling edge assign dbg = ssp_frame;
reg after_hysteresis;
always @(negedge adc_clk)
begin
if(& adc_d[6:4]) after_hysteresis <= 1'b1;
else if(~(| adc_d[6:4])) after_hysteresis <= 1'b0;
end
assign ssp_din = after_hysteresis; endmodule
assign dbg = after_hysteresis;
endmodule