1 //-----------------------------------------------------------------------------
2 // Utility functions used in many places, not specific to any piece of code.
3 // Jonathan Westhues, Sept 2005
4 //-----------------------------------------------------------------------------
8 void *memcpy(void *dest
, const void *src
, int len
)
20 void *memset(void *dest
, int c
, int len
)
30 int memcmp(const void *av
, const void *bv
, int len
)
55 char* strncat(char *dest
, const char *src
, unsigned int n
)
57 unsigned int dest_len
= strlen(dest
);
60 for (i
= 0 ; i
< n
&& src
[i
] != '\0' ; i
++)
61 dest
[dest_len
+ i
] = src
[i
];
62 dest
[dest_len
+ i
] = '\0';
67 void num_to_bytes(uint64_t n
, size_t len
, byte_t
* dest
)
70 dest
[len
] = (byte_t
) n
;
75 uint64_t bytes_to_num(byte_t
* src
, size_t len
)
80 num
= (num
<< 8) | (*src
);
94 // LEDs: R(C) O(A) G(B) -- R(D) [1, 2, 4 and 8]
95 void LED(int led
, int ms
)
113 if (led
& LED_ORANGE
)
122 // Determine if a button is double clicked, single clicked,
123 // not clicked, or held down (for ms || 1sec)
124 // In general, don't use this function unless you expect a
125 // double click, otherwise it will waste 500ms -- use BUTTON_HELD instead
126 int BUTTON_CLICKED(int ms
)
128 // Up to 500ms in between clicks to mean a double click
129 int ticks
= (48000 * (ms
? ms
: 1000)) >> 10;
131 // If we're not even pressed, forget about it!
133 return BUTTON_NO_CLICK
;
135 // Borrow a PWM unit for my real-time clock
136 AT91C_BASE_PWMC
->PWMC_ENA
= PWM_CHANNEL(0);
137 // 48 MHz / 1024 gives 46.875 kHz
138 AT91C_BASE_PWMC_CH0
->PWMC_CMR
= PWM_CH_MODE_PRESCALER(10);
139 AT91C_BASE_PWMC_CH0
->PWMC_CDTYR
= 0;
140 AT91C_BASE_PWMC_CH0
->PWMC_CPRDR
= 0xffff;
142 WORD start
= AT91C_BASE_PWMC_CH0
->PWMC_CCNTR
;
147 WORD now
= AT91C_BASE_PWMC_CH0
->PWMC_CCNTR
;
149 // We haven't let off the button yet
152 // We just let it off!
157 // reset our timer for 500ms
158 start
= AT91C_BASE_PWMC_CH0
->PWMC_CCNTR
;
159 ticks
= (48000 * (500)) >> 10;
162 // Still haven't let it off
164 // Have we held down a full second?
165 if (now
== (WORD
)(start
+ ticks
))
169 // We already let off, did we click again?
171 // Sweet, double click!
173 return BUTTON_DOUBLE_CLICK
;
175 // Have we ran out of time to double click?
177 if (now
== (WORD
)(start
+ ticks
))
178 // At least we did a single click
179 return BUTTON_SINGLE_CLICK
;
184 // We should never get here
188 // Determine if a button is held down
189 int BUTTON_HELD(int ms
)
191 // If button is held for one second
192 int ticks
= (48000 * (ms
? ms
: 1000)) >> 10;
194 // If we're not even pressed, forget about it!
196 return BUTTON_NO_CLICK
;
198 // Borrow a PWM unit for my real-time clock
199 AT91C_BASE_PWMC
->PWMC_ENA
= PWM_CHANNEL(0);
200 // 48 MHz / 1024 gives 46.875 kHz
201 AT91C_BASE_PWMC_CH0
->PWMC_CMR
= PWM_CH_MODE_PRESCALER(10);
202 AT91C_BASE_PWMC_CH0
->PWMC_CDTYR
= 0;
203 AT91C_BASE_PWMC_CH0
->PWMC_CPRDR
= 0xffff;
205 WORD start
= AT91C_BASE_PWMC_CH0
->PWMC_CCNTR
;
209 WORD now
= AT91C_BASE_PWMC_CH0
->PWMC_CCNTR
;
211 // As soon as our button let go, we didn't hold long enough
213 return BUTTON_SINGLE_CLICK
;
215 // Have we waited the full second?
217 if (now
== (WORD
)(start
+ ticks
))
223 // We should never get here
227 // attempt at high resolution microsecond timer
228 // beware: timer counts in 21.3uS increments (1024/48Mhz)
229 void SpinDelayUs(int us
)
231 int ticks
= (48*us
) >> 10;
233 // Borrow a PWM unit for my real-time clock
234 AT91C_BASE_PWMC
->PWMC_ENA
= PWM_CHANNEL(0);
235 // 48 MHz / 1024 gives 46.875 kHz
236 AT91C_BASE_PWMC_CH0
->PWMC_CMR
= PWM_CH_MODE_PRESCALER(10);
237 AT91C_BASE_PWMC_CH0
->PWMC_CDTYR
= 0;
238 AT91C_BASE_PWMC_CH0
->PWMC_CPRDR
= 0xffff;
240 WORD start
= AT91C_BASE_PWMC_CH0
->PWMC_CCNTR
;
243 WORD now
= AT91C_BASE_PWMC_CH0
->PWMC_CCNTR
;
244 if (now
== (WORD
)(start
+ ticks
))
251 void SpinDelay(int ms
)
253 // convert to uS and call microsecond delay function
254 SpinDelayUs(ms
*1000);
257 /* Similar to FpgaGatherVersion this formats stored version information
258 * into a string representation. It takes a pointer to the struct version_information,
259 * verifies the magic properties, then stores a formatted string, prefixed by
262 void FormatVersionInformation(char *dst
, int len
, const char *prefix
, void *version_information
)
264 struct version_information
*v
= (struct version_information
*)version_information
;
266 strncat(dst
, prefix
, len
);
267 if(v
->magic
!= VERSION_INFORMATION_MAGIC
) {
268 strncat(dst
, "Missing/Invalid version information", len
);
271 if(v
->versionversion
!= 1) {
272 strncat(dst
, "Version information not understood", len
);
276 strncat(dst
, "Version information not available", len
);
280 strncat(dst
, v
->svnversion
, len
);
282 strncat(dst
, "-unclean", len
);
283 } else if(v
->clean
== 2) {
284 strncat(dst
, "-suspect", len
);
287 strncat(dst
, " ", len
);
288 strncat(dst
, v
->buildtime
, len
);