]> git.zerfleddert.de Git - proxmark3-svn/blob - armsrc/util.c
mifare client update
[proxmark3-svn] / armsrc / util.c
1 //-----------------------------------------------------------------------------
2 // Utility functions used in many places, not specific to any piece of code.
3 // Jonathan Westhues, Sept 2005
4 //-----------------------------------------------------------------------------
5 #include <proxmark3.h>
6 #include "apps.h"
7
8 void *memcpy(void *dest, const void *src, int len)
9 {
10 BYTE *d = dest;
11 const BYTE *s = src;
12 while((len--) > 0) {
13 *d = *s;
14 d++;
15 s++;
16 }
17 return dest;
18 }
19
20 void *memset(void *dest, int c, int len)
21 {
22 BYTE *d = dest;
23 while((len--) > 0) {
24 *d = c;
25 d++;
26 }
27 return dest;
28 }
29
30 int memcmp(const void *av, const void *bv, int len)
31 {
32 const BYTE *a = av;
33 const BYTE *b = bv;
34
35 while((len--) > 0) {
36 if(*a != *b) {
37 return *a - *b;
38 }
39 a++;
40 b++;
41 }
42 return 0;
43 }
44
45 int strlen(char *str)
46 {
47 int l = 0;
48 while(*str) {
49 l++;
50 str++;
51 }
52 return l;
53 }
54
55 char* strncat(char *dest, const char *src, unsigned int n)
56 {
57 unsigned int dest_len = strlen(dest);
58 unsigned int i;
59
60 for (i = 0 ; i < n && src[i] != '\0' ; i++)
61 dest[dest_len + i] = src[i];
62 dest[dest_len + i] = '\0';
63
64 return dest;
65 }
66
67
68 void LEDsoff()
69 {
70 LED_A_OFF();
71 LED_B_OFF();
72 LED_C_OFF();
73 LED_D_OFF();
74 }
75
76 // LEDs: R(C) O(A) G(B) -- R(D) [1, 2, 4 and 8]
77 void LED(int led, int ms)
78 {
79 if (led & LED_RED)
80 LED_C_ON();
81 if (led & LED_ORANGE)
82 LED_A_ON();
83 if (led & LED_GREEN)
84 LED_B_ON();
85 if (led & LED_RED2)
86 LED_D_ON();
87
88 if (!ms)
89 return;
90
91 SpinDelay(ms);
92
93 if (led & LED_RED)
94 LED_C_OFF();
95 if (led & LED_ORANGE)
96 LED_A_OFF();
97 if (led & LED_GREEN)
98 LED_B_OFF();
99 if (led & LED_RED2)
100 LED_D_OFF();
101 }
102
103
104 // Determine if a button is double clicked, single clicked,
105 // not clicked, or held down (for ms || 1sec)
106 // In general, don't use this function unless you expect a
107 // double click, otherwise it will waste 500ms -- use BUTTON_HELD instead
108 int BUTTON_CLICKED(int ms)
109 {
110 // Up to 500ms in between clicks to mean a double click
111 int ticks = (48000 * (ms ? ms : 1000)) >> 10;
112
113 // If we're not even pressed, forget about it!
114 if (!BUTTON_PRESS())
115 return BUTTON_NO_CLICK;
116
117 // Borrow a PWM unit for my real-time clock
118 AT91C_BASE_PWMC->PWMC_ENA = PWM_CHANNEL(0);
119 // 48 MHz / 1024 gives 46.875 kHz
120 AT91C_BASE_PWMC_CH0->PWMC_CMR = PWM_CH_MODE_PRESCALER(10);
121 AT91C_BASE_PWMC_CH0->PWMC_CDTYR = 0;
122 AT91C_BASE_PWMC_CH0->PWMC_CPRDR = 0xffff;
123
124 WORD start = AT91C_BASE_PWMC_CH0->PWMC_CCNTR;
125
126 int letoff = 0;
127 for(;;)
128 {
129 WORD now = AT91C_BASE_PWMC_CH0->PWMC_CCNTR;
130
131 // We haven't let off the button yet
132 if (!letoff)
133 {
134 // We just let it off!
135 if (!BUTTON_PRESS())
136 {
137 letoff = 1;
138
139 // reset our timer for 500ms
140 start = AT91C_BASE_PWMC_CH0->PWMC_CCNTR;
141 ticks = (48000 * (500)) >> 10;
142 }
143
144 // Still haven't let it off
145 else
146 // Have we held down a full second?
147 if (now == (WORD)(start + ticks))
148 return BUTTON_HOLD;
149 }
150
151 // We already let off, did we click again?
152 else
153 // Sweet, double click!
154 if (BUTTON_PRESS())
155 return BUTTON_DOUBLE_CLICK;
156
157 // Have we ran out of time to double click?
158 else
159 if (now == (WORD)(start + ticks))
160 // At least we did a single click
161 return BUTTON_SINGLE_CLICK;
162
163 WDT_HIT();
164 }
165
166 // We should never get here
167 return BUTTON_ERROR;
168 }
169
170 // Determine if a button is held down
171 int BUTTON_HELD(int ms)
172 {
173 // If button is held for one second
174 int ticks = (48000 * (ms ? ms : 1000)) >> 10;
175
176 // If we're not even pressed, forget about it!
177 if (!BUTTON_PRESS())
178 return BUTTON_NO_CLICK;
179
180 // Borrow a PWM unit for my real-time clock
181 AT91C_BASE_PWMC->PWMC_ENA = PWM_CHANNEL(0);
182 // 48 MHz / 1024 gives 46.875 kHz
183 AT91C_BASE_PWMC_CH0->PWMC_CMR = PWM_CH_MODE_PRESCALER(10);
184 AT91C_BASE_PWMC_CH0->PWMC_CDTYR = 0;
185 AT91C_BASE_PWMC_CH0->PWMC_CPRDR = 0xffff;
186
187 WORD start = AT91C_BASE_PWMC_CH0->PWMC_CCNTR;
188
189 for(;;)
190 {
191 WORD now = AT91C_BASE_PWMC_CH0->PWMC_CCNTR;
192
193 // As soon as our button let go, we didn't hold long enough
194 if (!BUTTON_PRESS())
195 return BUTTON_SINGLE_CLICK;
196
197 // Have we waited the full second?
198 else
199 if (now == (WORD)(start + ticks))
200 return BUTTON_HOLD;
201
202 WDT_HIT();
203 }
204
205 // We should never get here
206 return BUTTON_ERROR;
207 }
208
209 // attempt at high resolution microsecond timer
210 // beware: timer counts in 21.3uS increments (1024/48Mhz)
211 void SpinDelayUs(int us)
212 {
213 int ticks = (48*us) >> 10;
214
215 // Borrow a PWM unit for my real-time clock
216 AT91C_BASE_PWMC->PWMC_ENA = PWM_CHANNEL(0);
217 // 48 MHz / 1024 gives 46.875 kHz
218 AT91C_BASE_PWMC_CH0->PWMC_CMR = PWM_CH_MODE_PRESCALER(10);
219 AT91C_BASE_PWMC_CH0->PWMC_CDTYR = 0;
220 AT91C_BASE_PWMC_CH0->PWMC_CPRDR = 0xffff;
221
222 WORD start = AT91C_BASE_PWMC_CH0->PWMC_CCNTR;
223
224 for(;;) {
225 WORD now = AT91C_BASE_PWMC_CH0->PWMC_CCNTR;
226 if (now == (WORD)(start + ticks))
227 return;
228
229 WDT_HIT();
230 }
231 }
232
233 void SpinDelay(int ms)
234 {
235 // convert to uS and call microsecond delay function
236 SpinDelayUs(ms*1000);
237 }
238
239 /* Similar to FpgaGatherVersion this formats stored version information
240 * into a string representation. It takes a pointer to the struct version_information,
241 * verifies the magic properties, then stores a formatted string, prefixed by
242 * prefix in dst.
243 */
244 void FormatVersionInformation(char *dst, int len, const char *prefix, void *version_information)
245 {
246 struct version_information *v = (struct version_information*)version_information;
247 dst[0] = 0;
248 strncat(dst, prefix, len);
249 if(v->magic != VERSION_INFORMATION_MAGIC) {
250 strncat(dst, "Missing/Invalid version information", len);
251 return;
252 }
253 if(v->versionversion != 1) {
254 strncat(dst, "Version information not understood", len);
255 return;
256 }
257 if(!v->present) {
258 strncat(dst, "Version information not available", len);
259 return;
260 }
261
262 strncat(dst, v->svnversion, len);
263 if(v->clean == 0) {
264 strncat(dst, "-unclean", len);
265 } else if(v->clean == 2) {
266 strncat(dst, "-suspect", len);
267 }
268
269 strncat(dst, " ", len);
270 strncat(dst, v->buildtime, len);
271 }
Impressum, Datenschutz