X-Git-Url: https://git.zerfleddert.de/cgi-bin/gitweb.cgi/proxmark3-svn/blobdiff_plain/955fc5e2f83742dc68d4bc0505314e0da6a840cc..d6e91bf0866c8cfcc8b3d67e11c11c39f9cfffaf:/armsrc/util.c

diff --git a/armsrc/util.c b/armsrc/util.c
index 5af09f88..3cad25f4 100644
--- a/armsrc/util.c
+++ b/armsrc/util.c
@@ -52,6 +52,19 @@ int strlen(char *str)
 	return l;
 }
 
+char* strncat(char *dest, const char *src, unsigned int n)
+{
+	unsigned int dest_len = strlen(dest);
+	unsigned int i;
+	
+	for (i = 0 ; i < n && src[i] != '\0' ; i++)
+		dest[dest_len + i] = src[i];
+	dest[dest_len + i] = '\0';
+	
+	return dest;
+}
+
+
 void LEDsoff()
 {
 	LED_A_OFF();
@@ -86,7 +99,7 @@ void LED(int led, int ms)
 	if (led & LED_RED2)
 		LED_D_OFF();
 }
-	
+
 
 // Determine if a button is double clicked, single clicked,
 // not clicked, or held down (for ms || 1sec)
@@ -102,19 +115,19 @@ int BUTTON_CLICKED(int ms)
 		return BUTTON_NO_CLICK;
 
 	// Borrow a PWM unit for my real-time clock
-	PWM_ENABLE = PWM_CHANNEL(0);
+	AT91C_BASE_PWMC->PWMC_ENA = PWM_CHANNEL(0);
 	// 48 MHz / 1024 gives 46.875 kHz
-	PWM_CH_MODE(0) = PWM_CH_MODE_PRESCALER(10);
-	PWM_CH_DUTY_CYCLE(0) = 0;
-	PWM_CH_PERIOD(0) = 0xffff;
-	
-	WORD start = (WORD)PWM_CH_COUNTER(0);
-	
+	AT91C_BASE_PWMC_CH0->PWMC_CMR = PWM_CH_MODE_PRESCALER(10);
+	AT91C_BASE_PWMC_CH0->PWMC_CDTYR = 0;
+	AT91C_BASE_PWMC_CH0->PWMC_CPRDR = 0xffff;
+
+	WORD start = AT91C_BASE_PWMC_CH0->PWMC_CCNTR;
+
 	int letoff = 0;
 	for(;;)
 	{
-		WORD now = (WORD)PWM_CH_COUNTER(0);
-		
+		WORD now = AT91C_BASE_PWMC_CH0->PWMC_CCNTR;
+
 		// We haven't let off the button yet
 		if (!letoff)
 		{
@@ -124,7 +137,7 @@ int BUTTON_CLICKED(int ms)
 				letoff = 1;
 
 				// reset our timer for 500ms
-				start = (WORD)PWM_CH_COUNTER(0);
+				start = AT91C_BASE_PWMC_CH0->PWMC_CCNTR;
 				ticks = (48000 * (500)) >> 10;
 			}
 
@@ -163,20 +176,20 @@ int BUTTON_HELD(int ms)
 	// If we're not even pressed, forget about it!
 	if (!BUTTON_PRESS())
 		return BUTTON_NO_CLICK;
-	
+
 	// Borrow a PWM unit for my real-time clock
-	PWM_ENABLE = PWM_CHANNEL(0);
+	AT91C_BASE_PWMC->PWMC_ENA = PWM_CHANNEL(0);
 	// 48 MHz / 1024 gives 46.875 kHz
-	PWM_CH_MODE(0) = PWM_CH_MODE_PRESCALER(10);
-	PWM_CH_DUTY_CYCLE(0) = 0;
-	PWM_CH_PERIOD(0) = 0xffff;
-	
-	WORD start = (WORD)PWM_CH_COUNTER(0);
-	
+	AT91C_BASE_PWMC_CH0->PWMC_CMR = PWM_CH_MODE_PRESCALER(10);
+	AT91C_BASE_PWMC_CH0->PWMC_CDTYR = 0;
+	AT91C_BASE_PWMC_CH0->PWMC_CPRDR = 0xffff;
+
+	WORD start = AT91C_BASE_PWMC_CH0->PWMC_CCNTR;
+
 	for(;;)
 	{
-		WORD now = (WORD)PWM_CH_COUNTER(0);
-		
+		WORD now = AT91C_BASE_PWMC_CH0->PWMC_CCNTR;
+
 		// As soon as our button let go, we didn't hold long enough
 		if (!BUTTON_PRESS())
 			return BUTTON_SINGLE_CLICK;
@@ -185,7 +198,7 @@ int BUTTON_HELD(int ms)
 		else
 			if (now == (WORD)(start + ticks))
 				return BUTTON_HOLD;
-		
+
 		WDT_HIT();
 	}
 
@@ -193,47 +206,66 @@ int BUTTON_HELD(int ms)
 	return BUTTON_ERROR;
 }
 
+// attempt at high resolution microsecond timer
+// beware: timer counts in 21.3uS increments (1024/48Mhz)
 void SpinDelayUs(int us)
 {
 	int ticks = (48*us) >> 10;
-	
+
 	// Borrow a PWM unit for my real-time clock
-	PWM_ENABLE = PWM_CHANNEL(0);
+	AT91C_BASE_PWMC->PWMC_ENA = PWM_CHANNEL(0);
 	// 48 MHz / 1024 gives 46.875 kHz
-	PWM_CH_MODE(0) = PWM_CH_MODE_PRESCALER(10);
-	PWM_CH_DUTY_CYCLE(0) = 0;
-	PWM_CH_PERIOD(0) = 0xffff;
-	
-	WORD start = (WORD)PWM_CH_COUNTER(0);
-	
+	AT91C_BASE_PWMC_CH0->PWMC_CMR = PWM_CH_MODE_PRESCALER(10);
+	AT91C_BASE_PWMC_CH0->PWMC_CDTYR = 0;
+	AT91C_BASE_PWMC_CH0->PWMC_CPRDR = 0xffff;
+
+	WORD start = AT91C_BASE_PWMC_CH0->PWMC_CCNTR;
+
 	for(;;) {
-		WORD now = (WORD)PWM_CH_COUNTER(0);
-		if(now == (WORD)(start + ticks)) {
+		WORD now = AT91C_BASE_PWMC_CH0->PWMC_CCNTR;
+		if (now == (WORD)(start + ticks))
 			return;
-		}
+
 		WDT_HIT();
 	}
 }
 
 void SpinDelay(int ms)
 {
-	int ticks = (48000*ms) >> 10;
-
-	// Borrow a PWM unit for my real-time clock
-	PWM_ENABLE = PWM_CHANNEL(0);
-	// 48 MHz / 1024 gives 46.875 kHz
-	PWM_CH_MODE(0) = PWM_CH_MODE_PRESCALER(10);
-	PWM_CH_DUTY_CYCLE(0) = 0;
-	PWM_CH_PERIOD(0) = 0xffff;
-
-	WORD start = (WORD)PWM_CH_COUNTER(0);
-
-	for(;;)
-	{
-		WORD now = (WORD)PWM_CH_COUNTER(0);
-		if (now == (WORD)(start + ticks))
-			return;
+  // convert to uS and call microsecond delay function
+	SpinDelayUs(ms*1000);
+}
 
-		WDT_HIT();
+/* Similar to FpgaGatherVersion this formats stored version information
+ * into a string representation. It takes a pointer to the struct version_information,
+ * verifies the magic properties, then stores a formatted string, prefixed by
+ * prefix in dst.
+ */
+void FormatVersionInformation(char *dst, int len, const char *prefix, void *version_information)
+{
+	struct version_information *v = (struct version_information*)version_information;
+	dst[0] = 0;
+	strncat(dst, prefix, len);
+	if(v->magic != VERSION_INFORMATION_MAGIC) {
+		strncat(dst, "Missing/Invalid version information", len);
+		return;
+	}
+	if(v->versionversion != 1) {
+		strncat(dst, "Version information not understood", len);
+		return;
+	}
+	if(!v->present) {
+		strncat(dst, "Version information not available", len);
+		return;
 	}
+	
+	strncat(dst, v->svnversion, len);
+	if(v->clean == 0) {
+		strncat(dst, "-unclean", len);
+	} else if(v->clean == 2) {
+		strncat(dst, "-suspect", len);
+	}
+	
+	strncat(dst, " ", len);
+	strncat(dst, v->buildtime, len);
 }