Notice. New forum software under development. It's going to miss a few functions and look a bit ugly for a while, but I'm working on it full time now as the old forum was too unstable. Couple days, all good. If you notice any issues, please contact me.
|
Forum Index : Microcontroller and PC projects : 32bit counter range extend to 64bit
Author | Message | ||||
PhenixRising Guru Joined: 07/11/2023 Location: United KingdomPosts: 858 |
Anyone know of a nifty way to do this? I do have a carry and borrow flag. I can come up with a clunky way of doing it but I'm obsessed with efficiency |
||||
EDNEDN Senior Member Joined: 18/02/2023 Location: United StatesPosts: 118 |
I would think the natural way to do this is have the 32 bit counter interrupt when it rolls over. And the interrupt routine would increment a 32 bit integer. Combined, the 32 bit integer (as the high order bits) and the 32 bit counter (as the low order bits) form a 64 bit counter. |
||||
Volhout Guru Joined: 05/03/2018 Location: NetherlandsPosts: 4233 |
And one piece of advise.. Make sure this interrupt (32 bit counter roll over) the highest level interrupt in your system. I have been chasing ghosts for weeks because once in a while another interrupt was executed right between the 32bit counter roll-over, and the increment of the other 32 bit counter. The non matching high and low 32 bits seemed like going back in time, and that upset the algorithms. Regards, Volhout P.S. MMBasic (CMM2/H7/Pico) uses 64bit variables. Edited 2024-02-16 18:29 by Volhout PicomiteVGA PETSCII ROBOTS |
||||
matherp Guru Joined: 11/12/2012 Location: United KingdomPosts: 9115 |
For interest - this is the code from the Pico SDK which returns a 64-bit timer from two 32-bit registers uint64_t time_us_64() { // Need to make sure that the upper 32 bits of the timer // don't change, so read that first uint32_t hi = timer_hw->timerawh; uint32_t lo; do { // Read the lower 32 bits lo = timer_hw->timerawl; // Now read the upper 32 bits again and // check that it hasn't incremented. If it has loop around // and read the lower 32 bits again to get an accurate value uint32_t next_hi = timer_hw->timerawh; if (hi == next_hi) break; hi = next_hi; } while (true); return ((uint64_t) hi << 32u) | lo; } The Pico timer increments every 1uS so 64 bits will overflow every 585 thousand years |
||||
PhenixRising Guru Joined: 07/11/2023 Location: United KingdomPosts: 858 |
Thanks guys. The counter is good for 40MHz. Interrupt might struggle |
||||
JohnS Guru Joined: 18/11/2011 Location: United KingdomPosts: 3801 |
I'm surprised that works without any use of volatile! John |
||||
matherp Guru Joined: 11/12/2012 Location: United KingdomPosts: 9115 |
All registers are defined volatile typedef volatile uint32_t io_rw_32; typedef const volatile uint32_t io_ro_32; typedef volatile uint32_t io_wo_32; typedef volatile uint16_t io_rw_16; typedef const volatile uint16_t io_ro_16; typedef volatile uint16_t io_wo_16; typedef volatile uint8_t io_rw_8; typedef const volatile uint8_t io_ro_8; typedef volatile uint8_t io_wo_8; typedef struct { _REG_(TIMER_TIMEHW_OFFSET) // TIMER_TIMEHW // Write to bits 63:32 of time io_wo_32 timehw; _REG_(TIMER_TIMELW_OFFSET) // TIMER_TIMELW // Write to bits 31:0 of time io_wo_32 timelw; _REG_(TIMER_TIMEHR_OFFSET) // TIMER_TIMEHR // Read from bits 63:32 of time io_ro_32 timehr; _REG_(TIMER_TIMELR_OFFSET) // TIMER_TIMELR // Read from bits 31:0 of time io_ro_32 timelr; |
||||
JohnS Guru Joined: 18/11/2011 Location: United KingdomPosts: 3801 |
Hooray :) John |
||||
Print this page |