1 //----------------------------------------------------------------------------- 
   2 // Jonathan Westhues, Sept 2005 
   4 // This code is licensed to you under the terms of the GNU GPL, version 2 or, 
   5 // at your option, any later version. See the LICENSE.txt file for the text of 
   7 //----------------------------------------------------------------------------- 
   8 // Utility functions used in many places, not specific to any piece of code. 
   9 //----------------------------------------------------------------------------- 
  11 #include "proxmark3.h" 
  16 size_t nbytes(size_t nbits
) { 
  17         return (nbits
/8)+((nbits%8
)>0); 
  20 uint32_t SwapBits(uint32_t value
, int nrbits
) { 
  22         uint32_t newvalue 
= 0; 
  23         for(i 
= 0; i 
< nrbits
; i
++) { 
  24                 newvalue 
^= ((value 
>> i
) & 1) << (nrbits 
- 1 - i
); 
  29 void num_to_bytes(uint64_t n
, size_t len
, uint8_t* dest
) 
  32                 dest
[len
] = (uint8_t) n
; 
  37 uint64_t bytes_to_num(uint8_t* src
, size_t len
) 
  42                 num 
= (num 
<< 8) | (*src
); 
  56 // LEDs: R(C) O(A) G(B) -- R(D) [1, 2, 4 and 8] 
  57 void LED(int led
, int ms
) 
  84 // Determine if a button is double clicked, single clicked, 
  85 // not clicked, or held down (for ms || 1sec) 
  86 // In general, don't use this function unless you expect a 
  87 // double click, otherwise it will waste 500ms -- use BUTTON_HELD instead 
  88 int BUTTON_CLICKED(int ms
) 
  90         // Up to 500ms in between clicks to mean a double click 
  91         int ticks 
= (48000 * (ms 
? ms 
: 1000)) >> 10; 
  93         // If we're not even pressed, forget about it! 
  95                 return BUTTON_NO_CLICK
; 
  97         // Borrow a PWM unit for my real-time clock 
  98         AT91C_BASE_PWMC
->PWMC_ENA 
= PWM_CHANNEL(0); 
  99         // 48 MHz / 1024 gives 46.875 kHz 
 100         AT91C_BASE_PWMC_CH0
->PWMC_CMR 
= PWM_CH_MODE_PRESCALER(10); 
 101         AT91C_BASE_PWMC_CH0
->PWMC_CDTYR 
= 0; 
 102         AT91C_BASE_PWMC_CH0
->PWMC_CPRDR 
= 0xffff; 
 104         uint16_t start 
= AT91C_BASE_PWMC_CH0
->PWMC_CCNTR
; 
 109                 uint16_t now 
= AT91C_BASE_PWMC_CH0
->PWMC_CCNTR
; 
 111                 // We haven't let off the button yet 
 114                         // We just let it off! 
 119                                 // reset our timer for 500ms 
 120                                 start 
= AT91C_BASE_PWMC_CH0
->PWMC_CCNTR
; 
 121                                 ticks 
= (48000 * (500)) >> 10; 
 124                         // Still haven't let it off 
 126                                 // Have we held down a full second? 
 127                                 if (now 
== (uint16_t)(start 
+ ticks
)) 
 131                 // We already let off, did we click again? 
 133                         // Sweet, double click! 
 135                                 return BUTTON_DOUBLE_CLICK
; 
 137                         // Have we ran out of time to double click? 
 139                                 if (now 
== (uint16_t)(start 
+ ticks
)) 
 140                                         // At least we did a single click 
 141                                         return BUTTON_SINGLE_CLICK
; 
 146         // We should never get here 
 150 // Determine if a button is held down 
 151 int BUTTON_HELD(int ms
) 
 153         // If button is held for one second 
 154         int ticks 
= (48000 * (ms 
? ms 
: 1000)) >> 10; 
 156         // If we're not even pressed, forget about it! 
 158                 return BUTTON_NO_CLICK
; 
 160         // Borrow a PWM unit for my real-time clock 
 161         AT91C_BASE_PWMC
->PWMC_ENA 
= PWM_CHANNEL(0); 
 162         // 48 MHz / 1024 gives 46.875 kHz 
 163         AT91C_BASE_PWMC_CH0
->PWMC_CMR 
= PWM_CH_MODE_PRESCALER(10); 
 164         AT91C_BASE_PWMC_CH0
->PWMC_CDTYR 
= 0; 
 165         AT91C_BASE_PWMC_CH0
->PWMC_CPRDR 
= 0xffff; 
 167         uint16_t start 
= AT91C_BASE_PWMC_CH0
->PWMC_CCNTR
; 
 171                 uint16_t now 
= AT91C_BASE_PWMC_CH0
->PWMC_CCNTR
; 
 173                 // As soon as our button let go, we didn't hold long enough 
 175                         return BUTTON_SINGLE_CLICK
; 
 177                 // Have we waited the full second? 
 179                         if (now 
== (uint16_t)(start 
+ ticks
)) 
 185         // We should never get here 
 189 // attempt at high resolution microsecond timer 
 190 // beware: timer counts in 21.3uS increments (1024/48Mhz) 
 191 void SpinDelayUs(int us
) 
 193         int ticks 
= (48*us
) >> 10; 
 195         // Borrow a PWM unit for my real-time clock 
 196         AT91C_BASE_PWMC
->PWMC_ENA 
= PWM_CHANNEL(0); 
 197         // 48 MHz / 1024 gives 46.875 kHz 
 198         AT91C_BASE_PWMC_CH0
->PWMC_CMR 
= PWM_CH_MODE_PRESCALER(10); 
 199         AT91C_BASE_PWMC_CH0
->PWMC_CDTYR 
= 0; 
 200         AT91C_BASE_PWMC_CH0
->PWMC_CPRDR 
= 0xffff; 
 202         uint16_t start 
= AT91C_BASE_PWMC_CH0
->PWMC_CCNTR
; 
 205                 uint16_t now 
= AT91C_BASE_PWMC_CH0
->PWMC_CCNTR
; 
 206                 if (now 
== (uint16_t)(start 
+ ticks
)) 
 213 void SpinDelay(int ms
) 
 215   // convert to uS and call microsecond delay function 
 216         SpinDelayUs(ms
*1000); 
 219 /* Similar to FpgaGatherVersion this formats stored version information 
 220  * into a string representation. It takes a pointer to the struct version_information, 
 221  * verifies the magic properties, then stores a formatted string, prefixed by 
 224 void FormatVersionInformation(char *dst
, int len
, const char *prefix
, void *version_information
) 
 226         struct version_information 
*v 
= (struct version_information
*)version_information
; 
 228         strncat(dst
, prefix
, len
); 
 229         if(v
->magic 
!= VERSION_INFORMATION_MAGIC
) { 
 230                 strncat(dst
, "Missing/Invalid version information", len
); 
 233         if(v
->versionversion 
!= 1) { 
 234                 strncat(dst
, "Version information not understood", len
); 
 238                 strncat(dst
, "Version information not available", len
); 
 242         strncat(dst
, v
->svnversion
, len
); 
 244                 strncat(dst
, "-unclean", len
); 
 245         } else if(v
->clean 
== 2) { 
 246                 strncat(dst
, "-suspect", len
); 
 249         strncat(dst
, " ", len
); 
 250         strncat(dst
, v
->buildtime
, len
); 
 253 //  ------------------------------------------------------------------------- 
 255 //  ------------------------------------------------------------------------- 
 258 //      ti = GetTickCount(); 
 260 //      ti = GetTickCount() - ti; 
 261 //      Dbprintf("timer(1s): %d t=%d", ti, GetTickCount()); 
 263 void StartTickCount() 
 265 //  must be 0x40, but on my cpu - included divider is optimal 
 269         AT91C_BASE_RTTC
->RTTC_RTMR 
= AT91C_RTTC_RTTRST 
+ 0x001D; // was 0x003B 
 273 * Get the current count. 
 275 uint32_t RAMFUNC 
GetTickCount(){ 
 276         return AT91C_BASE_RTTC
->RTTC_RTVR
;// was * 2; 
 279 //  ------------------------------------------------------------------------- 
 280 //  microseconds timer  
 281 //  ------------------------------------------------------------------------- 
 284         AT91C_BASE_PMC
->PMC_PCER 
|= (0x1 << 12) | (0x1 << 13) | (0x1 << 14); 
 285 //      AT91C_BASE_TCB->TCB_BMR = AT91C_TCB_TC1XC1S_TIOA0; 
 286         AT91C_BASE_TCB
->TCB_BMR 
= AT91C_TCB_TC0XC0S_NONE 
| AT91C_TCB_TC1XC1S_TIOA0 
| AT91C_TCB_TC2XC2S_NONE
; 
 289         AT91C_BASE_TC0
->TC_CCR 
= AT91C_TC_CLKDIS
; // timer disable 
 290         AT91C_BASE_TC0
->TC_CMR 
= AT91C_TC_CLKS_TIMER_DIV3_CLOCK 
| // MCK(48MHz)/32 -- tick=1.5mks 
 291                                                                                                                 AT91C_TC_WAVE 
| AT91C_TC_WAVESEL_UP_AUTO 
| AT91C_TC_ACPA_CLEAR 
| 
 292                                                                                                                 AT91C_TC_ACPC_SET 
| AT91C_TC_ASWTRG_SET
; 
 293         AT91C_BASE_TC0
->TC_RA 
= 1; 
 294         AT91C_BASE_TC0
->TC_RC 
= 0xBFFF + 1; // 0xC000 
 296         AT91C_BASE_TC1
->TC_CCR 
= AT91C_TC_CLKDIS
; // timer disable   
 297         AT91C_BASE_TC1
->TC_CMR 
= AT91C_TC_CLKS_XC1
; // from timer 0 
 299         AT91C_BASE_TC0
->TC_CCR 
= AT91C_TC_CLKEN
; 
 300         AT91C_BASE_TC1
->TC_CCR 
= AT91C_TC_CLKEN
; 
 301         AT91C_BASE_TCB
->TCB_BCR 
= 1; 
 304 uint32_t RAMFUNC 
GetCountUS(){ 
 305         return (AT91C_BASE_TC1
->TC_CV 
* 0x8000) + ((AT91C_BASE_TC0
->TC_CV 
/ 15) * 10); 
 308 static uint32_t GlobalUsCounter 
= 0; 
 310 uint32_t RAMFUNC 
GetDeltaCountUS(){ 
 311         uint32_t g_cnt 
= GetCountUS(); 
 312         uint32_t g_res 
= g_cnt 
- GlobalUsCounter
; 
 313         GlobalUsCounter 
= g_cnt
; 
 318 //  ------------------------------------------------------------------------- 
 319 //  Timer for iso14443 commands. Uses ssp_clk from FPGA  
 320 //  ------------------------------------------------------------------------- 
 321 void StartCountSspClk() 
 323         AT91C_BASE_PMC
->PMC_PCER 
= (1 << AT91C_ID_TC0
) | (1 << AT91C_ID_TC1
) | (1 << AT91C_ID_TC2
);  // Enable Clock to all timers 
 324         AT91C_BASE_TCB
->TCB_BMR 
= AT91C_TCB_TC0XC0S_TIOA1               
// XC0 Clock = TIOA1 
 325                                                         | AT91C_TCB_TC1XC1S_NONE                
// XC1 Clock = none 
 326                                                         | AT91C_TCB_TC2XC2S_TIOA0
;              // XC2 Clock = TIOA0 
 328         // configure TC1 to create a short pulse on TIOA1 when a rising edge on TIOB1 (= ssp_clk from FPGA) occurs: 
 329         AT91C_BASE_TC1
->TC_CCR 
= AT91C_TC_CLKDIS
;                               // disable TC1 
 330         AT91C_BASE_TC1
->TC_CMR 
= AT91C_TC_CLKS_TIMER_DIV1_CLOCK 
// TC1 Clock = MCK(48MHz)/2 = 24MHz 
 331                                                         | AT91C_TC_CPCSTOP                              
// Stop clock on RC compare 
 332                                                         | AT91C_TC_EEVTEDG_RISING               
// Trigger on rising edge of Event 
 333                                                         | AT91C_TC_EEVT_TIOB                    
// Event-Source: TIOB1 (= ssp_clk from FPGA = 13,56MHz/16) 
 334                                                         | AT91C_TC_ENETRG                               
// Enable external trigger event 
 335                                                         | AT91C_TC_WAVESEL_UP                   
// Upmode without automatic trigger on RC compare 
 336                                                         | AT91C_TC_WAVE                                 
// Waveform Mode 
 337                                                         | AT91C_TC_AEEVT_SET                    
// Set TIOA1 on external event 
 338                                                         | AT91C_TC_ACPC_CLEAR
;                  // Clear TIOA1 on RC Compare 
 339         AT91C_BASE_TC1
->TC_RC 
= 0x04;                                                   // RC Compare value = 0x04 
 341         // use TC0 to count TIOA1 pulses 
 342         AT91C_BASE_TC0
->TC_CCR 
= AT91C_TC_CLKDIS
;                               // disable TC0 
 343         AT91C_BASE_TC0
->TC_CMR 
= AT91C_TC_CLKS_XC0                              
// TC0 clock = XC0 clock = TIOA1 
 344                                                         | AT91C_TC_WAVE                                 
// Waveform Mode 
 345                                                         | AT91C_TC_WAVESEL_UP                   
// just count 
 346                                                         | AT91C_TC_ACPA_CLEAR                   
// Clear TIOA0 on RA Compare 
 347                                                         | AT91C_TC_ACPC_SET
;                    // Set TIOA0 on RC Compare 
 348         AT91C_BASE_TC0
->TC_RA 
= 1;                                                              // RA Compare value = 1; pulse width to TC2 
 349         AT91C_BASE_TC0
->TC_RC 
= 0;                                                              // RC Compare value = 0; increment TC2 on overflow 
 351         // use TC2 to count TIOA0 pulses (giving us a 32bit counter (TC0/TC2) clocked by ssp_clk) 
 352         AT91C_BASE_TC2
->TC_CCR 
= AT91C_TC_CLKDIS
;                               // disable TC2   
 353         AT91C_BASE_TC2
->TC_CMR 
= AT91C_TC_CLKS_XC2                              
// TC2 clock = XC2 clock = TIOA0 
 354                                                         | AT91C_TC_WAVE                                 
// Waveform Mode 
 355                                                         | AT91C_TC_WAVESEL_UP
;                  // just count 
 357         AT91C_BASE_TC0
->TC_CCR 
= AT91C_TC_CLKEN
;                                // enable TC0 
 358         AT91C_BASE_TC1
->TC_CCR 
= AT91C_TC_CLKEN
;                                // enable TC1 
 359         AT91C_BASE_TC2
->TC_CCR 
= AT91C_TC_CLKEN
;                                // enable TC2 
 362         // synchronize the counter with the ssp_frame signal. Note: FPGA must be in any iso14446 mode, otherwise the frame signal would not be present  
 364         while(!(AT91C_BASE_PIOA
->PIO_PDSR 
& GPIO_SSC_FRAME
));   // wait for ssp_frame to go high (start of frame) 
 365         while(AT91C_BASE_PIOA
->PIO_PDSR 
& GPIO_SSC_FRAME
);              // wait for ssp_frame to be low 
 366         // after the falling edge of ssp_frame, there is delay of 1/13,56MHz (73ns) until the next rising edge of ssp_clk. This are only a few 
 367         // processor cycles. We therefore may or may not be able to sync on this edge. Therefore better make sure that we miss it: 
 368         while(!(AT91C_BASE_PIOA
->PIO_PDSR 
& GPIO_SSC_CLK
));     // wait for ssp_clk to go high 
 369         // note: up to now two ssp_clk rising edges have passed since the rising edge of ssp_frame 
 370         // it is now safe to assert a sync signal. This sets all timers to 0 on next active clock edge 
 371         AT91C_BASE_TCB
->TCB_BCR 
= 1;                                                    // assert Sync (set all timers to 0 on next active clock edge) 
 372         // at the next (3rd) ssp_clk rising edge, TC1 will be reset (and not generate a clock signal to TC0) 
 373         // at the next (4th) ssp_clk rising edge, TC0 (the low word of our counter) will be reset. From now on, 
 374         // whenever the last three bits of our counter go 0, we can be sure to be in the middle of a frame transfer. 
 375         // (just started with the transfer of the 4th Bit). 
 376         // The high word of the counter (TC2) will not reset until the low word (TC0) overflows. Therefore need to wait quite some time before 
 377         // we can use the counter. 
 378         while (AT91C_BASE_TC0
->TC_CV 
< 0xFFF0); 
 382 uint32_t RAMFUNC 
GetCountSspClk(){ 
 384         tmp_count 
= (AT91C_BASE_TC2
->TC_CV 
<< 16) | AT91C_BASE_TC0
->TC_CV
; 
 385         if ((tmp_count 
& 0x0000ffff) == 0) { //small chance that we may have missed an increment in TC2 
 386                 return (AT91C_BASE_TC2
->TC_CV 
<< 16);