diff --git a/frontend/desktop/emulator/emulator.go b/frontend/desktop/emulator/emulator.go index c039fd4..d262afe 100644 --- a/frontend/desktop/emulator/emulator.go +++ b/frontend/desktop/emulator/emulator.go @@ -414,12 +414,7 @@ func (e *Emulator) perfLoop() { rtc.update(interval) } - var instCounter uint64 - if e.currentRunMode == RunModeLoop { - instCounter = uint64(C.inst_counter) - } else { - instCounter = uint64(C.scheduler_get_counter(e.sched)) - } + instCounter := uint64(C.nrf52832_get_cycle_counter(e.nrf52)) e.instPerSecond = (1e6 * (instCounter - lastCounter)) / uint64(interval.Microseconds()) lastCounter = instCounter diff --git a/frontend/desktop/emulator/pinetime.go b/frontend/desktop/emulator/pinetime.go index 15e1d41..7b8db6c 100644 --- a/frontend/desktop/emulator/pinetime.go +++ b/frontend/desktop/emulator/pinetime.go @@ -1,6 +1,6 @@ package emulator -const BaseFrequencyHZ = 18_000_000 +const BaseFrequencyHZ = 64_000_000 const ( PinCharging = 12 diff --git a/include/nrf52832.h b/include/nrf52832.h index 75bbae7..bc3af46 100644 --- a/include/nrf52832.h +++ b/include/nrf52832.h @@ -86,7 +86,7 @@ typedef struct NRF52832_inst_t NRF52832_t; NRF52832_t *nrf52832_new(const program_t *flash, size_t sram_size); void nrf52832_reset(NRF52832_t *); -void nrf52832_step(NRF52832_t *); +int nrf52832_step(NRF52832_t *); cpu_t *nrf52832_get_cpu(NRF52832_t *); bus_spi_t *nrf52832_get_spi(NRF52832_t *); diff --git a/include/pinetime.h b/include/pinetime.h index 0482998..e9ec6b6 100644 --- a/include/pinetime.h +++ b/include/pinetime.h @@ -24,7 +24,7 @@ typedef struct pinetime_t pinetime_t; pinetime_t *pinetime_new(const program_t *program); void pinetime_free(pinetime_t *); void pinetime_reset(pinetime_t *); -void pinetime_step(pinetime_t *); +int pinetime_step(pinetime_t *); NRF52832_t *pinetime_get_nrf52832(pinetime_t *); st7789_t *pinetime_get_st7789(pinetime_t *); diff --git a/include/scheduler.h b/include/scheduler.h index a7324f8..c2aca6a 100644 --- a/include/scheduler.h +++ b/include/scheduler.h @@ -10,5 +10,4 @@ typedef struct scheduler_t scheduler_t; scheduler_t *scheduler_new(scheduler_cb_t cb, void *userdata, size_t target_hz); void scheduler_run(scheduler_t *); void scheduler_stop(scheduler_t *); -uint64_t scheduler_get_counter(scheduler_t *); void scheduler_set_frequency(scheduler_t *, size_t target_hz); diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 7fbb51a..ba9f343 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -74,7 +74,7 @@ set(WASM_EXPORTS pinetime_new pinetime_step pinetime_loop pinetime_reset pinetime_get_st7789 st7789_read_screen_rgba st7789_is_sleeping st7789_get_write_count st7789_is_sleeping pinetime_get_cst816s cst816s_do_touch cst816s_release_touch - pinetime_get_nrf52832 nrf52832_get_sram_size nrf52832_get_pins pins_set pins_clear + pinetime_get_nrf52832 nrf52832_get_sram_size nrf52832_get_pins pins_set pins_clear pins_read_all pinetime_get_spinorflash spinorflash_get_buffer spinorflash_get_buffer_size nrf52832_get_cpu cpu_is_sleeping cpu_mem program_new program_load_binary program_load_elf program_write_variable diff --git a/src/nrf52832.c b/src/nrf52832.c index f2cda27..aa9218b 100644 --- a/src/nrf52832.c +++ b/src/nrf52832.c @@ -173,7 +173,7 @@ void nrf52832_reset(NRF52832_t *nrf52832) cpu_reset(nrf52832->cpu); } -void nrf52832_step(NRF52832_t *nrf52832) +int nrf52832_step(NRF52832_t *nrf52832) { current_ppi = nrf52832->ppi; @@ -184,6 +184,8 @@ void nrf52832_step(NRF52832_t *nrf52832) nrf52832->cycle_counter += cycles; ticker_hftick(nrf52832->ticker, cycles); + + return cycles; } cpu_t *nrf52832_get_cpu(NRF52832_t *chip) diff --git a/src/pinetime.c b/src/pinetime.c index 35d255c..5b1ace6 100644 --- a/src/pinetime.c +++ b/src/pinetime.c @@ -55,9 +55,9 @@ void pinetime_reset(pinetime_t *pt) nrf52832_reset(pt->nrf); } -void pinetime_step(pinetime_t *pt) +int pinetime_step(pinetime_t *pt) { - nrf52832_step(pt->nrf); + return nrf52832_step(pt->nrf); } NRF52832_t *pinetime_get_nrf52832(pinetime_t *pt) diff --git a/src/scheduler.c b/src/scheduler.c index bd63453..3f36452 100644 --- a/src/scheduler.c +++ b/src/scheduler.c @@ -2,6 +2,7 @@ #include #include +#include #include #include #include @@ -9,7 +10,7 @@ #include "ie_time.h" -#define SCHEDULER_HZ 50 +#define US_PER_ITERATION 100000 struct scheduler_t { @@ -18,9 +19,7 @@ struct scheduler_t bool stop; - size_t iteration_count, should_take_ns; - - uint64_t counter; + size_t cycles_per_iteration; }; scheduler_t *scheduler_new(scheduler_cb_t cb, void *userdata, size_t target_hz) @@ -29,7 +28,7 @@ scheduler_t *scheduler_new(scheduler_cb_t cb, void *userdata, size_t target_hz) scheduler->cb = cb; scheduler->userdata = userdata; scheduler->stop = false; - + scheduler_set_frequency(scheduler, target_hz); return scheduler; @@ -37,30 +36,29 @@ scheduler_t *scheduler_new(scheduler_cb_t cb, void *userdata, size_t target_hz) void scheduler_run(scheduler_t *sched) { - struct timespec ts_rem, ts_req = {0}; + struct timespec ts_req = {0}; sched->stop = false; + ssize_t fuel; + while (!sched->stop) { - // Copy variables here to prevent them from changing during the loop body - size_t iteration_count = sched->iteration_count; - size_t should_take_ns = sched->should_take_ns; + fuel = sched->cycles_per_iteration; - uint64_t start = microseconds_now(); + uint64_t start = microseconds_now_real(); - for (size_t i = 0; i < iteration_count; i++) + while (fuel > 0) { - sched->counter += sched->cb(sched->userdata); + fuel -= sched->cb(sched->userdata); } - size_t end = microseconds_now(); - size_t elapsed_ns = (end - start) * 1e3; + uint64_t elapsed_us = microseconds_now_real() - start; - if (elapsed_ns < should_take_ns) + if (elapsed_us < US_PER_ITERATION) { - ts_req.tv_nsec = should_take_ns - elapsed_ns; - nanosleep(&ts_req, &ts_rem); + ts_req.tv_nsec = (US_PER_ITERATION - elapsed_us) * 1000; + while (nanosleep(&ts_req, &ts_req)); } } } @@ -70,13 +68,7 @@ void scheduler_stop(scheduler_t *sched) sched->stop = true; } -uint64_t scheduler_get_counter(scheduler_t *sched) -{ - return sched->counter; -} - void scheduler_set_frequency(scheduler_t *sched, size_t target_hz) { - sched->iteration_count = target_hz / SCHEDULER_HZ; - sched->should_take_ns = (1e9 * sched->iteration_count) / target_hz; + sched->cycles_per_iteration = (target_hz * US_PER_ITERATION) / 1000000; }