Skip to content

Commit 733020d

Browse files
See #49.
1. Fix for anomaly in micros() whwn the counter wrapped just before it was read 2. Specify timer configuration as constants to make micros() considerably faster
1 parent a086f96 commit 733020d

File tree

2 files changed

+23
-14
lines changed

2 files changed

+23
-14
lines changed

.gitignore

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,4 +3,6 @@ cores/arduino/mydebug.cpp
33
libraries/Storage/.development
44
cores/arduino/mydebug.cpp.donotuse
55
.DS_Store
6-
.DS_Store?
6+
.DS_Store?
7+
/.vs
8+
/.gitignore

cores/arduino/time.cpp

Lines changed: 20 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,10 @@
22
#include "IRQManager.h"
33
#include "FspTimer.h"
44

5+
// this file implements the following public funcions: delay, delayMicroseconds, yield, millis, micros
6+
// The millis and micros implementation uses timer AGT0 (24 HMz, 16-bits, count-down mode, 1 ms period)
7+
58
volatile unsigned long agt_time_ms = 0;
6-
uint32_t _freq_hz = 0;
79

810
__attribute__((weak)) void delay(uint32_t ms) {
911
R_BSP_SoftwareDelay(ms, BSP_DELAY_UNITS_MILLISECONDS);
@@ -17,20 +19,24 @@ __attribute__((weak)) void yield() {
1719
}
1820

1921
static FspTimer main_timer;
20-
21-
static uint32_t _top_counter;
22+
// specifying these details as constants makes micros() faster !
23+
#define _timer_type AGT_TIMER
24+
#define _timer_index 0
25+
#define _timer_underflow_bit R_AGT0->AGTCR_b.TUNDF
26+
#define _timer_clock_divider TIMER_SOURCE_DIV_8 // dividers 1, 2, 4 and 8 work because _timer_period is < 16-bit. bug in R4 1.0.2: divider 4 acts as 1 !?
27+
#define _timer_clock_freq 24000000UL
28+
#define _timer_ticks_per_us (_timer_clock_freq / ((1 << _timer_clock_divider) * 1000000UL))
29+
#define _timer_period (_timer_ticks_per_us * 1000UL)
2230

2331
static void timer_micros_callback(timer_callback_args_t __attribute((unused)) *p_args) {
24-
agt_time_ms += 1; //1ms
32+
agt_time_ms += 1;
2533
}
2634

2735
void startAgt() {
28-
main_timer.begin(TIMER_MODE_PERIODIC, AGT_TIMER, 0, 2000.0f, 0.5f, timer_micros_callback);
29-
IRQManager::getInstance().addPeripheral(IRQ_AGT,(void*)main_timer.get_cfg());
36+
main_timer.begin(TIMER_MODE_PERIODIC, _timer_type, _timer_index, _timer_period, 1, _timer_clock_divider, timer_micros_callback);;
37+
main_timer.setup_overflow_irq();
3038
main_timer.open();
31-
_top_counter = main_timer.get_counter();
32-
main_timer.start();
33-
_freq_hz = main_timer.get_freq_hz();
39+
main_timer.start(); // bug in R4 1.0.2: calling start() is not necessary: open() starts the counter already !?
3440
}
3541

3642
unsigned long millis()
@@ -43,10 +49,11 @@ unsigned long millis()
4349
}
4450

4551
unsigned long micros() {
46-
47-
// Convert time to us
52+
// Return time in us
4853
NVIC_DisableIRQ(main_timer.get_cfg()->cycle_end_irq);
49-
uint32_t time_us = ((main_timer.get_period_raw() - main_timer.get_counter()) * 1000 / main_timer.get_period_raw()) + (agt_time_ms * 1000);
54+
uint32_t ms = agt_time_ms;
55+
uint32_t cnt = main_timer.get_counter();
56+
if (_timer_underflow_bit && (cnt > (_timer_period / 2))) ++ms; // the counter wrapped arround just before it was read
5057
NVIC_EnableIRQ(main_timer.get_cfg()->cycle_end_irq);
51-
return time_us;
58+
return ms * 1000 + (((_timer_period - 1) - cnt) / _timer_ticks_per_us);
5259
}

0 commit comments

Comments
 (0)