diff --git a/app/modules/tmr.c b/app/modules/tmr.c index 10c09db3..5c689001 100644 --- a/app/modules/tmr.c +++ b/app/modules/tmr.c @@ -142,6 +142,13 @@ static int tmr_now(lua_State* L){ return 1; } +// Lua: tmr.ccount() , returns CCOUNT register +static int tmr_ccount( lua_State* L ) +{ + lua_pushinteger(L, CCOUNT_REG); + return 1; +} + static tmr_t tmr_get( lua_State *L, int stack ) { tmr_t t = (tmr_t)luaL_checkudata(L, stack, "tmr.timer"); if (t == NULL) @@ -392,6 +399,7 @@ LROT_BEGIN(tmr) LROT_FUNCENTRY( wdclr, tmr_wdclr ) LROT_FUNCENTRY( softwd, tmr_softwd ) LROT_FUNCENTRY( time, tmr_time ) + LROT_FUNCENTRY( ccount, tmr_ccount ) #ifdef TIMER_SUSPEND_ENABLE LROT_FUNCENTRY( suspend_all, tmr_suspend_all ) LROT_FUNCENTRY( resume_all, tmr_resume_all ) diff --git a/app/platform/platform.h b/app/platform/platform.h index 68c6811f..36aee526 100644 --- a/app/platform/platform.h +++ b/app/platform/platform.h @@ -372,4 +372,7 @@ platform_task_handle_t platform_task_get_id(platform_task_callback_t t); bool platform_post(uint8 prio, platform_task_handle_t h, platform_task_param_t par); +// Get current value of CCOUNt register +#define CCOUNT_REG ({ int32_t r; asm volatile("rsr %0, ccount" : "=r"(r)); r;}) + #endif diff --git a/docs/modules/tmr.md b/docs/modules/tmr.md index cfe4135a..5ac52f33 100644 --- a/docs/modules/tmr.md +++ b/docs/modules/tmr.md @@ -145,6 +145,42 @@ none #### Returns `nil` +## tmr.ccount() + +Get value of CPU CCOUNT register which contains CPU ticks. The register is 32-bit and rolls over. + +Converting the register's CPU ticks to us is done by dividing it to 80 or 160 (CPU80/CPU160) i.e. `tmr.ccount() / node.getcpufreq()`. + +Register arithmetic works without need to account for roll over, unlike `tmr.now()`. Because of same reason when CCOUNT is having its 32nd bit set, it appears in Lua as negative number. + +#### Syntax +`tmr.ccount()` + +#### Returns +The current value of CCOUNT register. + +#### Example +```lua +function timeIt(fnc, cnt) + local function loopIt(f2) + local t0 = tmr.ccount() + for i=1,cnt do + f2() + end + local t1 = tmr.ccount() + return math.ceil((t1-t0)/cnt) + end + assert(type(fnc) == "function", "function to test missing") + cnt = cnt or 1000 + local emptyTime = loopIt(function()end) + local deltaCPUTicks = math.abs(loopIt(fnc) - emptyTime) + local deltaUS = math.ceil(deltaCPUTicks/node.getcpufreq()) + return deltaCPUTicks, deltaUS +end + +print( timeIt(function() tmr.ccount() end) ) +``` + ## Timer Object Methods ### tobj:alarm()