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