Skip to content

Commit 39f511a

Browse files
authored
Merge pull request cnlohr#837 from cnlohr/add_safe_timer_64_functions
Add 64-bit safe timer functions for 32- and 64-bit timers
2 parents 2d3240d + f7710d8 commit 39f511a

File tree

14 files changed

+127
-14
lines changed

14 files changed

+127
-14
lines changed

ch32fun/ch32fun.c

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1868,6 +1868,45 @@ void DelaySysTick( uint32_t n )
18681868
#endif
18691869
}
18701870

1871+
1872+
// Computes a 64-bit SysTick timestamp from the current CPU.
1873+
// If the CPU supports a 64-bit SysTick, then it will make sure it
1874+
// did not race condition. If it's a 32-bit SysTick, a virtual
1875+
// high word will be generated and incremented any time a wraparound
1876+
// is detected.
1877+
//
1878+
// In general, please do not use this function. In 99% of cases, using 32-bit
1879+
// functions with proper rollover is better. For instance you can use
1880+
// TimeElapsed32( start, end ).
1881+
//
1882+
// This should only be used when you must act on time periods exceeding 2^31
1883+
// ticks.
1884+
//
1885+
uint64_t funSysTick64( void )
1886+
{
1887+
uint32_t base = funSysTick32();
1888+
#ifdef funSysTickHigh
1889+
1890+
uint32_t high = funSysTickHigh();
1891+
uint32_t check = funSysTick32();
1892+
1893+
// If and only if check is higher than base can we guarantee high is
1894+
// valid and matches the check.
1895+
if( check >= base )
1896+
return ((uint64_t)high<<32) | check;
1897+
1898+
// Else we need a new high.
1899+
return (((uint64_t)(funSysTickHigh()))<<32) | check;
1900+
#else
1901+
static uint32_t lastBase;
1902+
static uint32_t high;
1903+
if( base < lastBase ) { printf( "Trigger\n" );high++; }
1904+
lastBase = base;
1905+
printf( "%d %d\n", lastBase, high );
1906+
return ((uint64_t)high<<32) | base;
1907+
#endif
1908+
}
1909+
18711910
#if defined(CH32H41x)
18721911
void StartV5F(v5f_main function)
18731912
{

ch32fun/ch32fun.h

Lines changed: 19 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,11 @@
2424
4. Delays
2525
Delay_Us(n)
2626
Delay_Ms(n)
27-
DelaySysTick( uint32_t n );
27+
DelaySysTick( uint32_t n )
28+
TimeElapsed32( uint32_t now, uint32_t start);
29+
TimeElapsed32U( now, start ); // For if events could be in the future.
30+
funSysTick32()
31+
funSysTick64()
2832
2933
5. printf
3034
printf, _write may be semihosted, or printed to UART.
@@ -889,7 +893,20 @@ extern "C" {
889893
#define Ticks_from_Us(n) ((n) * DELAY_US_TIME)
890894
#define Ticks_from_Ms(n) ((n) * DELAY_MS_TIME)
891895

892-
#define TimeElapsed32(now,start) ((uint32_t)((uint32_t)(now)-(uint32_t)(start)))
896+
#define TimeElapsed32(now,start) ((int32_t)((uint32_t)(now)-(uint32_t)(start)))
897+
#define TimeElapsed32u(now,start) ((uint32_t)((uint32_t)(now)-(uint32_t)(start)))
898+
899+
// #define funSysTick32() is defined per-architecture.
900+
901+
// Get a 64-bit timestamp. Please in general try to use 32-bit timestamps
902+
// whenever possible. Use functions that automatically handle rollover
903+
// correctly like TimeElapsed32( start, end ). Only use this in cases where
904+
// you must act on time periods exceeding 2^31 ticks.
905+
//
906+
// Also, if you are on a platform without a hardware 64-bit timer, you must
907+
// call this function at least once every 2^32 ticks to make sure MSBs aren't
908+
// lost.
909+
uint64_t funSysTick64( void );
893910

894911
// Add a certain number of nops. Note: These are usually executed in pairs
895912
// and take two cycles, so you typically would use 0, 2, 4, etc.
@@ -1010,7 +1027,6 @@ RV_STATIC_INLINE void funPinAF(u32 pin, u32 af)
10101027

10111028
#if defined(__riscv) || defined(__riscv__) || defined( CH32V003FUN_BASE )
10121029

1013-
10141030
// Stuff that can only be compiled on device (not for the programmer, or other host programs)
10151031

10161032
// Initialize the ADC calibrate it and set some sane defaults.

ch32fun/ch32h41xhw.h

Lines changed: 18 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -299,18 +299,31 @@ typedef enum IRQn
299299

300300
#define DEFAULT_INTERRUPT_VECTOR_CONTENTS BASE_VECTOR "\n.option pop;\n"
301301

302-
303-
304302
/* memory mapped structure for SysTick */
305303
typedef struct
306304
{
307305
__IO uint32_t CTLR;
308306
__IO uint32_t SR;
309-
__IO uint64_t CNT;
310-
uint32_t RESERVED0;
311-
__IO uint64_t CMP;
307+
union
308+
{
309+
struct
310+
{
311+
__IO uint32_t CNTL;
312+
__IO uint32_t CNTH;
313+
__IO uint32_t CMPL;
314+
__IO uint32_t CMPH;
315+
};
316+
struct
317+
{
318+
__IO uint64_t CNT;
319+
__IO uint64_t CMP;
320+
};
321+
};
312322
} SysTick_Type;
313323

324+
#define funSysTick32() (SysTick->CNTL)
325+
#define funSysTickHigh() (SysTick->CNTH)
326+
314327

315328
#endif /* __ASSEMBLER__*/
316329

ch32fun/ch32l103hw.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -165,6 +165,7 @@ typedef struct
165165
__IO uint64_t CMP;
166166
} SysTick_Type;
167167

168+
#define funSysTick32() (SysTick->CNT)
168169

169170
#endif /* __ASSEMBLER__*/
170171

ch32fun/ch32v003hw.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -101,6 +101,7 @@ typedef struct
101101
uint32_t RESERVED1;
102102
} SysTick_Type;
103103

104+
#define funSysTick32() (SysTick->CNT)
104105

105106
#endif /* __ASSEMBLER__*/
106107

ch32fun/ch32v10xhw.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -168,6 +168,9 @@ typedef struct __attribute__((packed))
168168
};
169169
} SysTick_Type;
170170

171+
#define funSysTick32() (SysTick->CNTL)
172+
#define funSysTickHigh() (SysTick->CNTH)
173+
171174
#endif /* __ASSEMBLER__*/
172175

173176
#define HardFault_IRQn EXC_IRQn

ch32fun/ch32v20xhw.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -200,6 +200,7 @@ typedef struct
200200
__IO uint64_t CMP;
201201
} SysTick_Type;
202202

203+
#define funSysTick32() (SysTick->CNT)
203204

204205
#endif /* __ASSEMBLER__*/
205206

ch32fun/ch32v30xhw.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -260,6 +260,7 @@ typedef struct
260260
__IO uint64_t CMP;
261261
} SysTick_Type;
262262

263+
#define funSysTick32() (SysTick->CNT)
263264

264265
#endif /* __ASSEMBLER__*/
265266

ch32fun/ch32x00xhw.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -109,6 +109,7 @@ typedef struct
109109
uint32_t RESERVED1;
110110
} SysTick_Type;
111111

112+
#define funSysTick32() (SysTick->CNT)
112113

113114
#endif /* __ASSEMBLER__*/
114115

ch32fun/ch32x03xhw.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -149,6 +149,8 @@ typedef struct
149149
};
150150
} SysTick_Type;
151151

152+
#define funSysTick32() (SysTick->CNTL)
153+
#define funSysTickHigh() (SysTick->CNTH)
152154

153155
#endif /* __ASSEMBLER__*/
154156

0 commit comments

Comments
 (0)