Difference between revisions of "Nrf52-timer-config"
m |
m (→^ nRF5x shutting down timer) |
||
Line 94: | Line 94: | ||
== [[#top|^]] nRF5x shutting down timer == | == [[#top|^]] nRF5x shutting down timer == | ||
+ | |||
+ | Well here is something interesting and promising, the comment along side the following definition of <code>NRF_TIMER_TASK_SHUTDOWN</code> implies that this action powers off the timer: | ||
<pre> | <pre> | ||
Line 101: | Line 103: | ||
./hal/nrf_timer.h:108: NRF_TIMER_TASK_SHUTDOWN = offsetof(NRF_TIMER_Type, TASKS_SHUTDOWN), ///< Task for powering off the timer. | ./hal/nrf_timer.h:108: NRF_TIMER_TASK_SHUTDOWN = offsetof(NRF_TIMER_Type, TASKS_SHUTDOWN), ///< Task for powering off the timer. | ||
</pre> | </pre> | ||
+ | |||
+ | So then where and how is <code>offsetof()</code> defined? | ||
+ | |||
+ | <!-- comment --> | ||
+ | |||
+ | == [[#top|^]] offsetof() routine definition == | ||
+ | |||
<!-- comment --> | <!-- comment --> |
Revision as of 23:58, 25 April 2021
2021-04-25
Looking at some example code in nRF5SDK153059ac345/nRF5_SDK_15.3.0_59ac345/components/app_simple_timer.c
, there are routines to init, start, stop (pause) and to uninitialize. Given a task to assure that a Nordic chip goes into lower or lowest possible power mode, we'll first examine the 'stop' and 'uninit' routines in this Nordic demo code.
The routine uint32_t app_simple_timer_stop(void)
is a wrapper to nrf_drv_timer_pause(nrfx_timer_t const * const p_instance)
. Going through reverse engineering steps this routine is first defined via a macro:
./integration/nrfx/legacy/nrf_drv_timer.h:82:#define nrf_drv_timer_pause nrfx_timer_pause
The definition of nrfx_timer_pause()
is in the following .c file,
./modules/nrfx/drivers/include/nrfx_timer.h:186:void nrfx_timer_pause(nrfx_timer_t const * const p_instance); ./modules/nrfx/drivers/src/nrfx_timer.c:170:void nrfx_timer_pause(nrfx_timer_t const * const p_instance)
First Nordic demo code directories in which we're reviewing files:
nRF5SDK153059ac345/nRF5_SDK_15.3.0_59ac345/components/libraries/simple_timer nRF5SDK153059ac345/nRF5_SDK_15.3.0_59ac345/modules nRF5SDK153059ac345/nRF5_SDK_15.3.0_59ac345/modules/nrfx/drivers/include nRF5SDK153059ac345/nRF5_SDK_15.3.0_59ac345/modules/nrfx/drivers/src nRF5SDK153059ac345/nRF5_SDK_15.3.0_59ac345/integration/nrfx/legacy
Something interesting in file nrfx_timer.c, looks like a compile time evaluation may determine the size of an array of time_control_block_t
types:
64 static timer_control_block_t m_cb[NRFX_TIMER_ENABLED_COUNT];
. . . sure enough, in ../include/nrfx_timer.h
there is an enum whose members are conditionally compiled. Clever!:
enum { #if NRFX_CHECK(NRFX_TIMER0_ENABLED) NRFX_TIMER0_INST_IDX, #endif #if NRFX_CHECK(NRFX_TIMER1_ENABLED) NRFX_TIMER1_INST_IDX, #endif #if NRFX_CHECK(NRFX_TIMER2_ENABLED) NRFX_TIMER2_INST_IDX, #endif #if NRFX_CHECK(NRFX_TIMER3_ENABLED) NRFX_TIMER3_INST_IDX, #endif #if NRFX_CHECK(NRFX_TIMER4_ENABLED) NRFX_TIMER4_INST_IDX, #endif NRFX_TIMER_ENABLED_COUNT };
So the first demo routine of interest, to pause or equivalently stop a timer is:
void nrfx_timer_pause(nrfx_timer_t const * const p_instance) { NRFX_ASSERT(m_cb[p_instance->instance_id].state != NRFX_DRV_STATE_UNINITIALIZED); nrf_timer_task_trigger(p_instance->p_reg, NRF_TIMER_TASK_STOP); NRFX_LOG_INFO("Paused instance: %d.", p_instance->instance_id); }
We're looking at this to determine whether stopping a timer removes power from the timer peripheral in the nRF52 SoC. Looks like there is another layer of routine nesting with the call here to nrf_timer_task_trigger()
. There may be some clue as to how this routine works, and possibly one of the parameters it accepts will power off a given timer. Here are all calls to it in the nrfx/drivers directory:
ted@localhost$ ./nRF5SDK153059ac345/nRF5_SDK_15.3.0_59ac345/modules/nrfx/drivers $ grep -nr nrf_timer_task_trigger ./* ./src/nrfx_timer.c:144: nrf_timer_task_trigger(p_instance->p_reg, NRF_TIMER_TASK_START); ./src/nrfx_timer.c:152: nrf_timer_task_trigger(p_instance->p_reg, NRF_TIMER_TASK_SHUTDOWN); ./src/nrfx_timer.c:166: nrf_timer_task_trigger(p_instance->p_reg, NRF_TIMER_TASK_START); ./src/nrfx_timer.c:173: nrf_timer_task_trigger(p_instance->p_reg, NRF_TIMER_TASK_STOP); ./src/nrfx_timer.c:180: nrf_timer_task_trigger(p_instance->p_reg, NRF_TIMER_TASK_CLEAR); ./src/nrfx_timer.c:188: nrf_timer_task_trigger(p_instance->p_reg, NRF_TIMER_TASK_COUNT); ./src/nrfx_timer.c:197: nrf_timer_task_trigger(p_instance->p_reg,
From the file ./hal/nrf_timer.h
looks also like nrf_timer_task_trigger() is normally an in-lined routine:
#ifndef SUPPRESS_INLINE_IMPLEMENTATION __STATIC_INLINE void nrf_timer_task_trigger(NRF_TIMER_Type * p_reg, nrf_timer_task_t task) { *((volatile uint32_t *)((uint8_t *)p_reg + (uint32_t)task)) = 0x1UL; }
So this routine writes a timer peripheral control register with the value 1. Seems a little odd, is there some syntax I am misreading here? . . .
^ nRF5x shutting down timer
Well here is something interesting and promising, the comment along side the following definition of NRF_TIMER_TASK_SHUTDOWN
implies that this action powers off the timer:
/nRF5SDK153059ac345/nRF5_SDK_15.3.0_59ac345/modules/nrfx $ grep -nr NRF_TIMER_TASK_SHUTDOWN ./* ./drivers/src/nrfx_timer.c:152: nrf_timer_task_trigger(p_instance->p_reg, NRF_TIMER_TASK_SHUTDOWN); ./hal/nrf_timer.h:108: NRF_TIMER_TASK_SHUTDOWN = offsetof(NRF_TIMER_Type, TASKS_SHUTDOWN), ///< Task for powering off the timer.
So then where and how is offsetof()
defined?