timing changes

main() no longer waits an extra millisecond between scan cycles, just to
be safe.  before, i was thinking that perhaps the
timer__get_millisecond() call might catch the tail end of whatever
millisecond it was getting, and then the scan cycle would be anywhere
between 4ms and 5ms.  but since we wait for our OPT__DEBOUNCE_TIME to be
up *directly before* getting the new time, we shouldn't be catching the
tail end of anything.  we should be getting as close as practically
possible to *exactly* OPT__DEBOUNCE_TIME milliseconds.

the timer__ functions now use and return 16-bit values instead of 32-bit
ones.  the rational is that 16-bit counters for milliseconds are good up
to ~1 minute, which should be enough for most things.  if a greater
length of time is needed, a function can reschedule it self, and only
execute it's body code after being called a certain number of times.
also, i'm considering making a main__ timer, that counts scan cycles
instead of milliseconds.  that would have the advantage of having lower
resolution (so, less overhead) and being able to schedule functions to
run and such without executing anything in an interrupt vector.
partial-rewrite
Ben Blazak 2013-05-09 03:57:21 -07:00
parent a03b9ec2a1
commit 36ed9d1974
3 changed files with 44 additions and 20 deletions

View File

@ -8,12 +8,6 @@
* Timer interface
*
* Prefix: `timer__`
*
* TODO:
* - write `timer__schedule(uint32_t milliseconds, void(*)(void) function)`, to
* schedule `function` to run in `milliseconds`.
* - will need to be careful with this function, as everything called by it
* will be executing within an interrupt vector.
*/
@ -23,7 +17,38 @@
// ----------------------------------------------------------------------------
uint8_t timer__init(void);
uint8_t timer__init (void);
uint16_t timer__get_milliseconds (void);
uint8_t timer__schedule ( uint16_t milliseconds,
void(*)(void) function );
// TODO: `timer__schedule()`, to schedule `function` to run in `milliseconds`
// - will need to be careful with this function, as everything called by it
// will be executing within an interrupt vector.
// TODO: after this, should probably make a `main__schedule()`, to schedule
// `function` to run in `cycles` (or `scans`). this will have the benefit of
// being lower resolution (while still high enough resolution for a lot of
// things; and perhaps exactly what other things call for). Also, functions
// scheduled that way will not be executing from within an interrupt vector, so
// they could, within reason, do more or less what they want.
// ----------------------------------------------------------------------------
// ----------------------------------------------------------------------------
#endif // ERGODOX_FIRMWARE__LIB__TIMER__H
// ============================================================================
// === documentation ==========================================================
// ============================================================================
// ----------------------------------------------------------------------------
// functions ------------------------------------------------------------------
// ----------------------------------------------------------------------------
// === timer__init() ===
/** functions/timer__init/description
* Initialize the timer
*
@ -35,9 +60,9 @@ uint8_t timer__init(void);
* - Should be called exactly once by `main()` before entering the run loop.
*/
uint32_t timer__get_milliseconds(void);
// === timer__get_milliseconds() ===
/** functions/timer__get_milliseconds/description
* Return the number of milliseconds since the timer was initialized (mod 2^32)
* Return the number of milliseconds since the timer was initialized (mod 2^16)
*
* ---------------------------------------------------------------------
* number highest value in in in in
@ -51,7 +76,7 @@ uint32_t timer__get_milliseconds(void);
*
* Usage notes:
*
* - It's unnecessary to keep 32-bit resolution when storing the value returned
* - It's unnecessary to keep 16-bit resolution when storing the value returned
* by `timer__get_milliseconds()` if you don't need it. Use variables of the
* smallest type that can (*always*) hold the amount of time you'll be
* dealing with.
@ -99,8 +124,3 @@ uint32_t timer__get_milliseconds(void);
* except within the first 255 milliseconds of the timer being initialized.
*/
// ----------------------------------------------------------------------------
// ----------------------------------------------------------------------------
#endif // ERGODOX_FIRMWARE__LIB__TIMER__H

View File

@ -16,7 +16,13 @@
// ----------------------------------------------------------------------------
static volatile uint32_t _milliseconds;
#if F_CPU != 16000000
#error "Expecting different CPU frequency"
#endif
// ----------------------------------------------------------------------------
static volatile uint16_t _milliseconds;
// ----------------------------------------------------------------------------
@ -29,7 +35,7 @@ uint8_t timer__init(void) {
return 0; // success
}
uint32_t timer__get_milliseconds(void) {
uint16_t timer__get_milliseconds(void) {
return _milliseconds;
}

View File

@ -88,10 +88,8 @@ int main(void) {
was_pressed = temp;
// delay if necessary, then rescan
// - add 1 to `OPT__DEBOUNCE_TIME` in case `time_scan_started` caught
// the tail end of the millisecond it recorded
while( (uint8_t)(timer__get_milliseconds()-time_scan_started)
< OPT__DEBOUNCE_TIME + 1 );
< OPT__DEBOUNCE_TIME );
time_scan_started = timer__get_milliseconds();
kb__update_matrix(*is_pressed);