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 //-----------------------------------------------------------------------------
12 #include "proxmark3_arm.h"
14 #include "commonutil.h"
20 size_t nbytes(size_t nbits
) {
21 return (nbits
>> 3) + ((nbits
% 8) > 0);
24 //convert hex digit to integer
25 uint8_t hex2int(char hexchar
) {
93 //ICEMAN: LED went from 1,2,3,4 -> 1,2,4,8
94 void LED(int led
, int ms
) {
95 if (led
& LED_A
) // Proxmark3 historical mapping: LED_ORANGE
97 if (led
& LED_B
) // Proxmark3 historical mapping: LED_GREEN
99 if (led
& LED_C
) // Proxmark3 historical mapping: LED_RED
101 if (led
& LED_D
) // Proxmark3 historical mapping: LED_RED2
119 void SpinOff(uint32_t pause
) {
128 // A = 1, B = 2, C = 4, D = 8
129 void SpinErr(uint8_t led
, uint32_t speed
, uint8_t times
) {
133 if (led
& LED_A
) // Proxmark3 historical mapping: LED_ORANGE
135 if (led
& LED_B
) // Proxmark3 historical mapping: LED_GREEN
137 if (led
& LED_C
) // Proxmark3 historical mapping: LED_RED
139 if (led
& LED_D
) // Proxmark3 historical mapping: LED_RED2
150 void SpinDown(uint32_t speed
) {
166 void SpinUp(uint32_t speed
) {
183 // Determine if a button is double clicked, single clicked,
184 // not clicked, or held down (for ms || 1sec)
185 // In general, don't use this function unless you expect a
186 // double click, otherwise it will waste 500ms -- use BUTTON_HELD instead
187 int BUTTON_CLICKED(int ms
) {
188 // Up to 500ms in between clicks to mean a double click
189 // timer counts in 21.3us increments (1024/48MHz)
190 // WARNING: timer can't measure more than 1.39s (21.3us * 0xffff)
192 if (DBGLEVEL
>= DBG_ERROR
) Dbprintf(_RED_("Error, BUTTON_CLICKED called with %i > 1390"), ms
);
195 int ticks
= ((MCK
/ 1000) * (ms
? ms
: 1000)) >> 10;
197 // If we're not even pressed, forget about it!
199 return BUTTON_NO_CLICK
;
201 // Borrow a PWM unit for my real-time clock
202 AT91C_BASE_PWMC
->PWMC_ENA
= PWM_CHANNEL(0);
203 // 48 MHz / 1024 gives 46.875 kHz
204 AT91C_BASE_PWMC_CH0
->PWMC_CMR
= PWM_CH_MODE_PRESCALER(10);
205 AT91C_BASE_PWMC_CH0
->PWMC_CDTYR
= 0;
206 AT91C_BASE_PWMC_CH0
->PWMC_CPRDR
= 0xffff;
208 uint16_t start
= AT91C_BASE_PWMC_CH0
->PWMC_CCNTR
;
212 uint16_t now
= AT91C_BASE_PWMC_CH0
->PWMC_CCNTR
;
214 // We haven't let off the button yet
216 // We just let it off!
217 if (!BUTTON_PRESS()) {
220 // reset our timer for 500ms
221 start
= AT91C_BASE_PWMC_CH0
->PWMC_CCNTR
;
222 ticks
= ((MCK
/ 1000) * (500)) >> 10;
225 // Still haven't let it off
227 // Have we held down a full second?
228 if (now
== (uint16_t)(start
+ ticks
))
232 // We already let off, did we click again?
234 // Sweet, double click!
236 return BUTTON_DOUBLE_CLICK
;
238 // Have we ran out of time to double click?
239 else if (now
== (uint16_t)(start
+ ticks
))
240 // At least we did a single click
241 return BUTTON_SINGLE_CLICK
;
246 // We should never get here
250 // Determine if a button is held down
251 int BUTTON_HELD(int ms
) {
252 // timer counts in 21.3us increments (1024/48MHz)
253 // WARNING: timer can't measure more than 1.39s (21.3us * 0xffff)
255 if (DBGLEVEL
>= DBG_ERROR
) Dbprintf(_RED_("Error, BUTTON_HELD called with %i > 1390"), ms
);
258 // If button is held for one second
259 int ticks
= (48000 * (ms
? ms
: 1000)) >> 10;
261 // If we're not even pressed, forget about it!
263 return BUTTON_NO_CLICK
;
265 // Borrow a PWM unit for my real-time clock
266 AT91C_BASE_PWMC
->PWMC_ENA
= PWM_CHANNEL(0);
267 // 48 MHz / 1024 gives 46.875 kHz
268 AT91C_BASE_PWMC_CH0
->PWMC_CMR
= PWM_CH_MODE_PRESCALER(10);
269 AT91C_BASE_PWMC_CH0
->PWMC_CDTYR
= 0;
270 AT91C_BASE_PWMC_CH0
->PWMC_CPRDR
= 0xffff;
272 uint16_t start
= AT91C_BASE_PWMC_CH0
->PWMC_CCNTR
;
275 uint16_t now
= AT91C_BASE_PWMC_CH0
->PWMC_CCNTR
;
277 // As soon as our button let go, we didn't hold long enough
279 return BUTTON_SINGLE_CLICK
;
281 // Have we waited the full second?
282 else if (now
== (uint16_t)(start
+ ticks
))
288 // We should never get here
292 bool data_available(void) {
293 #ifdef WITH_FPC_USART_HOST
294 return usb_poll_validate_length() || (usart_rxdata_available() > 0);
296 return usb_poll_validate_length();