]> cvs.zerfleddert.de Git - proxmark3-svn/blame - armsrc/util.c
maintain alphabetic order!
[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
67\r
955fc5e2 68void LEDsoff()\r
69{\r
70 LED_A_OFF();\r
71 LED_B_OFF();\r
72 LED_C_OFF();\r
73 LED_D_OFF();\r
74}\r
75\r
76// LEDs: R(C) O(A) G(B) -- R(D) [1, 2, 4 and 8]\r
77void LED(int led, int ms)\r
78{\r
79 if (led & LED_RED)\r
80 LED_C_ON();\r
81 if (led & LED_ORANGE)\r
82 LED_A_ON();\r
83 if (led & LED_GREEN)\r
84 LED_B_ON();\r
85 if (led & LED_RED2)\r
86 LED_D_ON();\r
87\r
88 if (!ms)\r
89 return;\r
90\r
91 SpinDelay(ms);\r
92\r
93 if (led & LED_RED)\r
94 LED_C_OFF();\r
95 if (led & LED_ORANGE)\r
96 LED_A_OFF();\r
97 if (led & LED_GREEN)\r
98 LED_B_OFF();\r
99 if (led & LED_RED2)\r
100 LED_D_OFF();\r
101}\r
5e6a0b23 102\r
955fc5e2 103\r
104// Determine if a button is double clicked, single clicked,\r
105// not clicked, or held down (for ms || 1sec)\r
106// In general, don't use this function unless you expect a\r
107// double click, otherwise it will waste 500ms -- use BUTTON_HELD instead\r
108int BUTTON_CLICKED(int ms)\r
109{\r
110 // Up to 500ms in between clicks to mean a double click\r
111 int ticks = (48000 * (ms ? ms : 1000)) >> 10;\r
112\r
113 // If we're not even pressed, forget about it!\r
114 if (!BUTTON_PRESS())\r
115 return BUTTON_NO_CLICK;\r
116\r
117 // Borrow a PWM unit for my real-time clock\r
118 PWM_ENABLE = PWM_CHANNEL(0);\r
119 // 48 MHz / 1024 gives 46.875 kHz\r
120 PWM_CH_MODE(0) = PWM_CH_MODE_PRESCALER(10);\r
121 PWM_CH_DUTY_CYCLE(0) = 0;\r
122 PWM_CH_PERIOD(0) = 0xffff;\r
5e6a0b23 123\r
955fc5e2 124 WORD start = (WORD)PWM_CH_COUNTER(0);\r
5e6a0b23 125\r
955fc5e2 126 int letoff = 0;\r
127 for(;;)\r
128 {\r
129 WORD now = (WORD)PWM_CH_COUNTER(0);\r
5e6a0b23 130\r
955fc5e2 131 // We haven't let off the button yet\r
132 if (!letoff)\r
133 {\r
134 // We just let it off!\r
135 if (!BUTTON_PRESS())\r
136 {\r
137 letoff = 1;\r
138\r
139 // reset our timer for 500ms\r
140 start = (WORD)PWM_CH_COUNTER(0);\r
141 ticks = (48000 * (500)) >> 10;\r
142 }\r
143\r
144 // Still haven't let it off\r
145 else\r
146 // Have we held down a full second?\r
147 if (now == (WORD)(start + ticks))\r
148 return BUTTON_HOLD;\r
149 }\r
150\r
151 // We already let off, did we click again?\r
152 else\r
153 // Sweet, double click!\r
154 if (BUTTON_PRESS())\r
155 return BUTTON_DOUBLE_CLICK;\r
156\r
157 // Have we ran out of time to double click?\r
158 else\r
159 if (now == (WORD)(start + ticks))\r
160 // At least we did a single click\r
161 return BUTTON_SINGLE_CLICK;\r
162\r
163 WDT_HIT();\r
164 }\r
165\r
166 // We should never get here\r
167 return BUTTON_ERROR;\r
168}\r
169\r
170// Determine if a button is held down\r
171int BUTTON_HELD(int ms)\r
172{\r
173 // If button is held for one second\r
174 int ticks = (48000 * (ms ? ms : 1000)) >> 10;\r
175\r
176 // If we're not even pressed, forget about it!\r
177 if (!BUTTON_PRESS())\r
178 return BUTTON_NO_CLICK;\r
5e6a0b23 179\r
955fc5e2 180 // Borrow a PWM unit for my real-time clock\r
181 PWM_ENABLE = PWM_CHANNEL(0);\r
182 // 48 MHz / 1024 gives 46.875 kHz\r
183 PWM_CH_MODE(0) = PWM_CH_MODE_PRESCALER(10);\r
184 PWM_CH_DUTY_CYCLE(0) = 0;\r
185 PWM_CH_PERIOD(0) = 0xffff;\r
5e6a0b23 186\r
955fc5e2 187 WORD start = (WORD)PWM_CH_COUNTER(0);\r
5e6a0b23 188\r
955fc5e2 189 for(;;)\r
190 {\r
191 WORD now = (WORD)PWM_CH_COUNTER(0);\r
5e6a0b23 192\r
955fc5e2 193 // As soon as our button let go, we didn't hold long enough\r
194 if (!BUTTON_PRESS())\r
195 return BUTTON_SINGLE_CLICK;\r
196\r
197 // Have we waited the full second?\r
198 else\r
199 if (now == (WORD)(start + ticks))\r
200 return BUTTON_HOLD;\r
5e6a0b23 201\r
955fc5e2 202 WDT_HIT();\r
203 }\r
204\r
205 // We should never get here\r
206 return BUTTON_ERROR;\r
207}\r
208\r
5e6a0b23 209// attempt at high resolution microsecond timer\r
210// beware: timer counts in 21.3uS increments (1024/48Mhz)\r
955fc5e2 211void SpinDelayUs(int us)\r
212{\r
213 int ticks = (48*us) >> 10;\r
955fc5e2 214\r
215 // Borrow a PWM unit for my real-time clock\r
216 PWM_ENABLE = PWM_CHANNEL(0);\r
217 // 48 MHz / 1024 gives 46.875 kHz\r
218 PWM_CH_MODE(0) = PWM_CH_MODE_PRESCALER(10);\r
219 PWM_CH_DUTY_CYCLE(0) = 0;\r
220 PWM_CH_PERIOD(0) = 0xffff;\r
221\r
222 WORD start = (WORD)PWM_CH_COUNTER(0);\r
223\r
5e6a0b23 224 for(;;) {\r
955fc5e2 225 WORD now = (WORD)PWM_CH_COUNTER(0);\r
226 if (now == (WORD)(start + ticks))\r
227 return;\r
228\r
229 WDT_HIT();\r
230 }\r
231}\r
5e6a0b23 232\r
233void SpinDelay(int ms)\r
234{\r
235 // convert to uS and call microsecond delay function\r
236 SpinDelayUs(ms*1000);\r
237}\r
8a6aec16 238\r
239/* Similar to FpgaGatherVersion this formats stored version information\r
240 * into a string representation. It takes a pointer to the struct version_information,\r
241 * verifies the magic properties, then stores a formatted string, prefixed by\r
242 * prefix in dst.
243 */\r
244void FormatVersionInformation(char *dst, int len, const char *prefix, void *version_information)\r
245{\r
246 struct version_information *v = (struct version_information*)version_information;\r
247 dst[0] = 0;\r
248 strncat(dst, prefix, len);\r
249 if(v->magic != VERSION_INFORMATION_MAGIC) {\r
250 strncat(dst, "Missing/Invalid version information", len);\r
251 return;\r
252 }\r
253 if(v->versionversion != 1) {\r
254 strncat(dst, "Version information not understood", len);\r
255 return;\r
256 }\r
257 if(!v->present) {\r
258 strncat(dst, "Version information not available", len);\r
259 return;\r
260 }\r
261 \r
262 strncat(dst, v->svnversion, len);\r
263 if(v->clean == 0) {\r
264 strncat(dst, "-unclean", len);\r
265 } else if(v->clean == 2) {\r
266 strncat(dst, "-suspect", len);\r
267 }\r
268 \r
269 strncat(dst, " ", len);\r
270 strncat(dst, v->buildtime, len);\r
271}\r
Impressum, Datenschutz