Home
JAQForum Ver 24.01
Log In or Join  
Active Topics
Local Time 12:28 26 Nov 2024 Privacy Policy
Jump to

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 Kingdom
Posts: 858
Posted: 01:08am 16 Feb 2024
Copy link to clipboard 
Print this post

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 States
Posts: 118
Posted: 02:20am 16 Feb 2024
Copy link to clipboard 
Print this post

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: Netherlands
Posts: 4233
Posted: 08:28am 16 Feb 2024
Copy link to clipboard 
Print this post

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 Kingdom
Posts: 9115
Posted: 08:37am 16 Feb 2024
Copy link to clipboard 
Print this post

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 Kingdom
Posts: 858
Posted: 09:00am 16 Feb 2024
Copy link to clipboard 
Print this post

Thanks guys. The counter is good for 40MHz. Interrupt might struggle  
 
JohnS
Guru

Joined: 18/11/2011
Location: United Kingdom
Posts: 3801
Posted: 09:40am 16 Feb 2024
Copy link to clipboard 
Print this post

  matherp said  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;
}


I'm surprised that works without any use of volatile!

John
 
matherp
Guru

Joined: 11/12/2012
Location: United Kingdom
Posts: 9115
Posted: 10:34am 16 Feb 2024
Copy link to clipboard 
Print this post

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 Kingdom
Posts: 3801
Posted: 10:55am 16 Feb 2024
Copy link to clipboard 
Print this post

  matherp said  All registers are defined volatile

Hooray :)

John
 
Print this page


To reply to this topic, you need to log in.

© JAQ Software 2024