MYNEWT-79: move common hal code from mcu to hal
Project: http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/repo Commit: http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/commit/183873d8 Tree: http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/tree/183873d8 Diff: http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/diff/183873d8 Branch: refs/heads/develop Commit: 183873d8890de9fb6579dc3a738937c1b1d8006d Parents: 7bd50b3 Author: William San Filippo <wi...@runtime.io> Authored: Fri Jun 17 10:46:20 2016 -0700 Committer: William San Filippo <wi...@runtime.io> Committed: Thu Jun 23 16:39:04 2016 -0700 ---------------------------------------------------------------------- hw/hal/include/hal/hal_cputime.h | 30 +- hw/mcu/native/src/hal_cputime.c | 385 +++----------------------- hw/mcu/nordic/nrf51xxx/src/hal_cputime.c | 308 +-------------------- hw/mcu/nordic/nrf52xxx/src/hal_cputime.c | 318 +-------------------- hw/mcu/stm/stm32f4xx/src/hal_cputime.c | 355 +++--------------------- 5 files changed, 111 insertions(+), 1285 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/183873d8/hw/hal/include/hal/hal_cputime.h ---------------------------------------------------------------------- diff --git a/hw/hal/include/hal/hal_cputime.h b/hw/hal/include/hal/hal_cputime.h index 63b723b..001bac5 100644 --- a/hw/hal/include/hal/hal_cputime.h +++ b/hw/hal/include/hal/hal_cputime.h @@ -38,6 +38,23 @@ struct cpu_timer { TAILQ_ENTRY(cpu_timer) link; }; +/* CPUTIME data. */ +struct cputime_data +{ + uint32_t ticks_per_usec; /* number of ticks per usec */ + uint32_t cputime_high; /* high word of 64-bit cpu time */ + uint32_t timer_isrs; /* Number of timer interrupts */ + uint32_t ocmp_ints; /* Number of ocmp interrupts */ + uint32_t uif_ints; /* Number of overflow interrupts */ +}; +extern struct cputime_data g_cputime; + +/* Helpful macros to compare cputimes */ +#define CPUTIME_LT(__t1, __t2) ((int32_t) ((__t1) - (__t2)) < 0) +#define CPUTIME_GT(__t1, __t2) ((int32_t) ((__t1) - (__t2)) > 0) +#define CPUTIME_GEQ(__t1, __t2) ((int32_t) ((__t1) - (__t2)) >= 0) +#define CPUTIME_LEQ(__t1, __t2) ((int32_t) ((__t1) - (__t2)) <= 0) + /** * cputime init * @@ -183,11 +200,16 @@ void cputime_timer_relative(struct cpu_timer *timer, uint32_t usecs); */ void cputime_timer_stop(struct cpu_timer *timer); -#define CPUTIME_LT(__t1, __t2) ((int32_t) ((__t1) - (__t2)) < 0) -#define CPUTIME_GT(__t1, __t2) ((int32_t) ((__t1) - (__t2)) > 0) -#define CPUTIME_GEQ(__t1, __t2) ((int32_t) ((__t1) - (__t2)) >= 0) -#define CPUTIME_LEQ(__t1, __t2) ((int32_t) ((__t1) - (__t2)) <= 0) +/* + * Used between MCU specific files and generic HAL. Not intended as an API + * to be called by the user. + */ +void cputime_chk_expiration(void); +/*--- HW specific API. These are not intended to be called by user ---*/ +void cputime_disable_ocmp(void); +void cputime_set_ocmp(struct cpu_timer *timer); +int cputime_hw_init(uint32_t clock_freq); #ifdef __cplusplus } http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/183873d8/hw/mcu/native/src/hal_cputime.c ---------------------------------------------------------------------- diff --git a/hw/mcu/native/src/hal_cputime.c b/hw/mcu/native/src/hal_cputime.c index b493a7d..850bfc5 100644 --- a/hw/mcu/native/src/hal_cputime.c +++ b/hw/mcu/native/src/hal_cputime.c @@ -6,7 +6,7 @@ * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at - * + * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, @@ -21,21 +21,6 @@ #include "os/os.h" #include "hal/hal_cputime.h" -/* CPUTIME data */ -struct cputime_data -{ - uint32_t ticks_per_usec; /* number of ticks per usec */ - uint32_t timer_isrs; /* Number of timer interrupts */ - uint32_t ocmp_ints; /* Number of ocmp interrupts */ - uint32_t uif_ints; /* Number of overflow interrupts */ - uint32_t last_ostime; - uint64_t cputime; /* 64-bit cputime */ -}; -struct cputime_data g_cputime; - -/* Queue for timers */ -TAILQ_HEAD(cputime_qhead, cpu_timer) g_cputimer_q; - /* For native cpu implementation */ #define NATIVE_CPUTIME_STACK_SIZE (1024) os_stack_t g_native_cputime_stack[NATIVE_CPUTIME_STACK_SIZE]; @@ -44,15 +29,16 @@ struct os_task g_native_cputime_task; struct os_callout_func g_native_cputimer; struct os_eventq g_native_cputime_evq; static uint32_t g_native_cputime_cputicks_per_ostick; - +static uint64_t g_native_cputime; +static uint32_t g_native_cputime_last_ostime; /** * Convert cpu time ticks to os ticks. - * - * - * @param cputicks - * - * @return uint32_t + * + * + * @param cputicks + * + * @return uint32_t */ static uint32_t native_cputime_ticks_to_osticks(uint32_t cputicks) @@ -64,13 +50,13 @@ native_cputime_ticks_to_osticks(uint32_t cputicks) } /** - * cputime set ocmp - * - * Set the OCMP used by the cputime module to the desired cputime. - * + * cputime set ocmp + * + * Set the OCMP used by the cputime module to the desired cputime. + * * @param timer Pointer to timer. */ -static void +void cputime_set_ocmp(struct cpu_timer *timer) { uint32_t curtime; @@ -88,43 +74,9 @@ cputime_set_ocmp(struct cpu_timer *timer) } /** - * cputime chk expiration - * - * Iterates through the cputimer queue to determine if any timers have expired. - * If the timer has expired the timer is removed from the queue and the timer - * callback function is executed. - * - */ -static void -cputime_chk_expiration(void) -{ - os_sr_t sr; - struct cpu_timer *timer; - - OS_ENTER_CRITICAL(sr); - while ((timer = TAILQ_FIRST(&g_cputimer_q)) != NULL) { - if ((int32_t)(cputime_get32() - timer->cputime) >= 0) { - TAILQ_REMOVE(&g_cputimer_q, timer, link); - timer->cb(timer->arg); - } else { - break; - } - } - - /* Any timers left on queue? If so, we need to set OCMP */ - timer = TAILQ_FIRST(&g_cputimer_q); - if (timer) { - cputime_set_ocmp(timer); - } else { - os_callout_stop(&g_native_cputimer.cf_c); - } - OS_EXIT_CRITICAL(sr); -} - -/** - * This is the function called when the cputimer fires off. - * - * @param arg + * This is the function called when the cputimer fires off. + * + * @param arg */ void native_cputimer_cb(void *arg) @@ -158,38 +110,35 @@ native_cputime_task_handler(void *arg) } /** - * cputime init - * - * Initialize the cputime module. This must be called after os_init is called - * and before any other timer API are used. This should be called only once - * and should be called before the hardware timer is used. - * + * cputime init + * + * Initialize the cputime module. This must be called after os_init is called + * and before any other timer API are used. This should be called only once + * and should be called before the hardware timer is used. + * * @param clock_freq The desired cputime frequency, in hertz (Hz). - * + * * @return int 0 on success; -1 on error. */ int -cputime_init(uint32_t clock_freq) +cputime_hw_init(uint32_t clock_freq) { /* Clock frequency must be at least 1 MHz */ if (clock_freq < 1000000U) { return -1; } - /* Initialize the timer queue */ - TAILQ_INIT(&g_cputimer_q); - /* Set the clock frequency */ g_cputime.ticks_per_usec = clock_freq / 1000000U; g_native_cputime_cputicks_per_ostick = clock_freq / OS_TICKS_PER_SEC; - os_task_init(&g_native_cputime_task, - "native_cputimer", - native_cputime_task_handler, - NULL, - OS_TASK_PRI_HIGHEST, - OS_WAIT_FOREVER, - g_native_cputime_stack, + os_task_init(&g_native_cputime_task, + "native_cputimer", + native_cputime_task_handler, + NULL, + OS_TASK_PRI_HIGHEST, + OS_WAIT_FOREVER, + g_native_cputime_stack, NATIVE_CPUTIME_STACK_SIZE); /* Initialize the eventq and task */ @@ -206,23 +155,23 @@ cputime_init(uint32_t clock_freq) /** * cputime get64 - * - * Returns cputime as a 64-bit number. - * + * + * Returns cputime as a 64-bit number. + * * @return uint64_t The 64-bit representation of cputime. */ -uint64_t +uint64_t cputime_get64(void) { cputime_get32(); - return g_cputime.cputime; + return g_native_cputime; } /** - * cputime get32 - * - * Returns the low 32 bits of cputime. - * + * cputime get32 + * + * Returns the low 32 bits of cputime. + * * @return uint32_t The lower 32 bits of cputime */ uint32_t @@ -234,260 +183,14 @@ cputime_get32(void) OS_ENTER_CRITICAL(sr); ostime = os_time_get(); - delta_osticks = (uint32_t)(ostime - g_cputime.last_ostime); + delta_osticks = (uint32_t)(ostime - g_native_cputime_last_ostime); if (delta_osticks) { - g_cputime.last_ostime = ostime; - g_cputime.cputime += + g_native_cputime_last_ostime = ostime; + g_native_cputime += (uint64_t)g_native_cputime_cputicks_per_ostick * delta_osticks; } OS_EXIT_CRITICAL(sr); - return (uint32_t)g_cputime.cputime; -} - -/** - * cputime nsecs to ticks - * - * Converts the given number of nanoseconds into cputime ticks. - * - * @param usecs The number of nanoseconds to convert to ticks - * - * @return uint32_t The number of ticks corresponding to 'nsecs' - */ -uint32_t -cputime_nsecs_to_ticks(uint32_t nsecs) -{ - uint32_t ticks; - - ticks = ((nsecs * g_cputime.ticks_per_usec) + 999) / 1000; - return ticks; -} - -/** - * cputime ticks to nsecs - * - * Convert the given number of ticks into nanoseconds. - * - * @param ticks The number of ticks to convert to nanoseconds. - * - * @return uint32_t The number of nanoseconds corresponding to 'ticks' - */ -uint32_t -cputime_ticks_to_nsecs(uint32_t ticks) -{ - uint32_t nsecs; - - nsecs = ((ticks * 1000) + (g_cputime.ticks_per_usec - 1)) / - g_cputime.ticks_per_usec; - - return nsecs; -} - -/** - * cputime usecs to ticks - * - * Converts the given number of microseconds into cputime ticks. - * - * @param usecs The number of microseconds to convert to ticks - * - * @return uint32_t The number of ticks corresponding to 'usecs' - */ -uint32_t -cputime_usecs_to_ticks(uint32_t usecs) -{ - uint32_t ticks; - - ticks = (usecs * g_cputime.ticks_per_usec); - return ticks; -} - -/** - * cputime ticks to usecs - * - * Convert the given number of ticks into microseconds. - * - * @param ticks The number of ticks to convert to microseconds. - * - * @return uint32_t The number of microseconds corresponding to 'ticks' - */ -uint32_t -cputime_ticks_to_usecs(uint32_t ticks) -{ - uint32_t us; - - us = (ticks + (g_cputime.ticks_per_usec - 1)) / g_cputime.ticks_per_usec; - return us; -} - -/** - * cputime delay ticks - * - * Wait until the number of ticks has elapsed. This is a blocking delay. - * - * @param ticks The number of ticks to wait. - */ -void -cputime_delay_ticks(uint32_t ticks) -{ - uint32_t until; - - until = cputime_get32() + ticks; - while ((int32_t)(cputime_get32() - until) < 0) { - /* Loop here till finished */ - } -} - -/** - * cputime delay nsecs - * - * Wait until 'nsecs' nanoseconds has elapsed. This is a blocking delay. - * - * @param nsecs The number of nanoseconds to wait. - */ -void -cputime_delay_nsecs(uint32_t nsecs) -{ - uint32_t ticks; - - ticks = cputime_nsecs_to_ticks(nsecs); - cputime_delay_ticks(ticks); -} - -/** - * cputime delay usecs - * - * Wait until 'usecs' microseconds has elapsed. This is a blocking delay. - * - * @param usecs The number of usecs to wait. - */ -void -cputime_delay_usecs(uint32_t usecs) -{ - uint32_t ticks; - - ticks = cputime_usecs_to_ticks(usecs); - cputime_delay_ticks(ticks); -} - -/** - * cputime timer init - * - * - * @param timer The timer to initialize. Cannot be NULL. - * @param fp The timer callback function. Cannot be NULL. - * @param arg Pointer to data object to pass to timer. - */ -void -cputime_timer_init(struct cpu_timer *timer, cputimer_func fp, void *arg) -{ - assert(timer != NULL); - assert(fp != NULL); - - timer->cb = fp; - timer->arg = arg; - timer->link.tqe_prev = (void *) NULL; -} - -/** - * cputime timer start - * - * Start a cputimer that will expire at 'cputime'. If cputime has already - * passed, the timer callback will still be called (at interrupt context). - * - * @param timer Pointer to timer to start. Cannot be NULL. - * @param cputime The cputime at which the timer should expire. - */ -void -cputime_timer_start(struct cpu_timer *timer, uint32_t cputime) -{ - struct cpu_timer *entry; - os_sr_t sr; - - assert(timer != NULL); - - /* XXX: should this use a mutex? not sure... */ - OS_ENTER_CRITICAL(sr); - - timer->cputime = cputime; - if (TAILQ_EMPTY(&g_cputimer_q)) { - TAILQ_INSERT_HEAD(&g_cputimer_q, timer, link); - } else { - TAILQ_FOREACH(entry, &g_cputimer_q, link) { - if ((int32_t)(timer->cputime - entry->cputime) < 0) { - TAILQ_INSERT_BEFORE(entry, timer, link); - break; - } - } - if (!entry) { - TAILQ_INSERT_TAIL(&g_cputimer_q, timer, link); - } - } - - /* If this is the head, we need to set new OCMP */ - if (timer == TAILQ_FIRST(&g_cputimer_q)) { - cputime_set_ocmp(timer); - } - - OS_EXIT_CRITICAL(sr); -} - -/** - * cputimer timer relative - * - * Sets a cpu timer that will expire 'usecs' microseconds from the current - * cputime. - * - * @param timer Pointer to timer. Cannot be NULL. - * @param usecs The number of usecs from now at which the timer will expire. - */ -void -cputime_timer_relative(struct cpu_timer *timer, uint32_t usecs) -{ - uint32_t cputime; - - assert(timer != NULL); - - cputime = cputime_get32() + cputime_usecs_to_ticks(usecs); - cputime_timer_start(timer, cputime); -} - -/** - * cputime timer stop - * - * Stops a cputimer from running. The timer is removed from the timer queue - * and interrupts are disabled if no timers are left on the queue. Can be - * called even if timer is running. - * - * @param timer Pointer to cputimer to stop. Cannot be NULL. - */ -void -cputime_timer_stop(struct cpu_timer *timer) -{ - os_sr_t sr; - int reset_ocmp; - struct cpu_timer *entry; - - assert(timer != NULL); - - OS_ENTER_CRITICAL(sr); - - /* If first on queue, we will need to reset OCMP */ - if (timer->link.tqe_prev != NULL) { - reset_ocmp = 0; - if (timer == TAILQ_FIRST(&g_cputimer_q)) { - entry = TAILQ_NEXT(timer, link); - reset_ocmp = 1; - } - TAILQ_REMOVE(&g_cputimer_q, timer, link); - if (reset_ocmp) { - if (entry) { - cputime_set_ocmp(entry); - } else { - os_callout_stop(&g_native_cputimer.cf_c); - } - } - } - - OS_EXIT_CRITICAL(sr); + return (uint32_t)g_native_cputime; } http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/183873d8/hw/mcu/nordic/nrf51xxx/src/hal_cputime.c ---------------------------------------------------------------------- diff --git a/hw/mcu/nordic/nrf51xxx/src/hal_cputime.c b/hw/mcu/nordic/nrf51xxx/src/hal_cputime.c index eb12237..8f2815d 100644 --- a/hw/mcu/nordic/nrf51xxx/src/hal_cputime.c +++ b/hw/mcu/nordic/nrf51xxx/src/hal_cputime.c @@ -50,21 +50,7 @@ * - Sync to OSTIME. */ -/* CPUTIME data */ -struct cputime_data -{ - uint32_t ticks_per_usec; /* number of ticks per usec */ - uint32_t cputime_high; /* high word of 64-bit cpu time */ - uint32_t timer_isrs; /* Number of timer interrupts */ - uint32_t ocmp_ints; /* Number of ocmp interrupts */ - uint32_t uif_ints; /* Number of overflow interrupts */ -}; -struct cputime_data g_cputime; - -/* Queue for timers */ -TAILQ_HEAD(cputime_qhead, cpu_timer) g_cputimer_q; - -__STATIC_INLINE void +void cputime_disable_ocmp(void) { CPUTIMER->INTENCLR = CPUTIMER_INT_MASK(CPUTIMER_CC_INT); @@ -79,7 +65,7 @@ cputime_disable_ocmp(void) * * @param timer Pointer to timer. */ -static void +void cputime_set_ocmp(struct cpu_timer *timer) { /* Disable ocmp interrupt and set new value */ @@ -101,41 +87,6 @@ cputime_set_ocmp(struct cpu_timer *timer) } /** - * cputime chk expiration - * - * Iterates through the cputimer queue to determine if any timers have expired. - * If the timer has expired the timer is removed from the queue and the timer - * callback function is executed. - * - */ -static void -cputime_chk_expiration(void) -{ - uint32_t ctx; - struct cpu_timer *timer; - - __HAL_DISABLE_INTERRUPTS(ctx); - while ((timer = TAILQ_FIRST(&g_cputimer_q)) != NULL) { - if ((int32_t)(cputime_get32() - timer->cputime) >= 0) { - TAILQ_REMOVE(&g_cputimer_q, timer, link); - timer->link.tqe_prev = NULL; - timer->cb(timer->arg); - } else { - break; - } - } - - /* Any timers left on queue? If so, we need to set OCMP */ - timer = TAILQ_FIRST(&g_cputimer_q); - if (timer) { - cputime_set_ocmp(timer); - } else { - cputime_disable_ocmp(); - } - __HAL_ENABLE_INTERRUPTS(ctx); -} - -/** * cputime isr * * This is the global timer interrupt routine. @@ -197,7 +148,7 @@ cputime_isr(void) * @return int 0 on success; -1 on error. */ int -cputime_init(uint32_t clock_freq) +cputime_hw_init(uint32_t clock_freq) { uint32_t ctx; uint32_t max_freq; @@ -250,9 +201,6 @@ cputime_init(uint32_t clock_freq) return -1; } - /* Initialize the timer queue */ - TAILQ_INIT(&g_cputimer_q); - /* disable interrupts */ __HAL_DISABLE_INTERRUPTS(ctx); @@ -339,253 +287,3 @@ cputime_get32(void) return cpu_time; } - -/** - * cputime nsecs to ticks - * - * Converts the given number of nanoseconds into cputime ticks. - * - * @param usecs The number of nanoseconds to convert to ticks - * - * @return uint32_t The number of ticks corresponding to 'nsecs' - */ -uint32_t -cputime_nsecs_to_ticks(uint32_t nsecs) -{ - uint32_t ticks; - - ticks = ((nsecs * g_cputime.ticks_per_usec) + 999) / 1000; - return ticks; -} - -/** - * cputime ticks to nsecs - * - * Convert the given number of ticks into nanoseconds. - * - * @param ticks The number of ticks to convert to nanoseconds. - * - * @return uint32_t The number of nanoseconds corresponding to 'ticks' - */ -uint32_t -cputime_ticks_to_nsecs(uint32_t ticks) -{ - uint32_t nsecs; - - nsecs = ((ticks * 1000) + (g_cputime.ticks_per_usec - 1)) / - g_cputime.ticks_per_usec; - - return nsecs; -} - -/** - * cputime usecs to ticks - * - * Converts the given number of microseconds into cputime ticks. - * - * @param usecs The number of microseconds to convert to ticks - * - * @return uint32_t The number of ticks corresponding to 'usecs' - */ -uint32_t -cputime_usecs_to_ticks(uint32_t usecs) -{ - uint32_t ticks; - - ticks = (usecs * g_cputime.ticks_per_usec); - return ticks; -} - -/** - * cputime ticks to usecs - * - * Convert the given number of ticks into microseconds. - * - * @param ticks The number of ticks to convert to microseconds. - * - * @return uint32_t The number of microseconds corresponding to 'ticks' - */ -uint32_t -cputime_ticks_to_usecs(uint32_t ticks) -{ - uint32_t us; - - us = (ticks + (g_cputime.ticks_per_usec - 1)) / g_cputime.ticks_per_usec; - return us; -} - -/** - * cputime delay ticks - * - * Wait until the number of ticks has elapsed. This is a blocking delay. - * - * @param ticks The number of ticks to wait. - */ -void -cputime_delay_ticks(uint32_t ticks) -{ - uint32_t until; - - until = cputime_get32() + ticks; - while ((int32_t)(cputime_get32() - until) < 0) { - /* Loop here till finished */ - } -} - -/** - * cputime delay nsecs - * - * Wait until 'nsecs' nanoseconds has elapsed. This is a blocking delay. - * - * @param nsecs The number of nanoseconds to wait. - */ -void -cputime_delay_nsecs(uint32_t nsecs) -{ - uint32_t ticks; - - ticks = cputime_nsecs_to_ticks(nsecs); - cputime_delay_ticks(ticks); -} - -/** - * cputime delay usecs - * - * Wait until 'usecs' microseconds has elapsed. This is a blocking delay. - * - * @param usecs The number of usecs to wait. - */ -void -cputime_delay_usecs(uint32_t usecs) -{ - uint32_t ticks; - - ticks = cputime_usecs_to_ticks(usecs); - cputime_delay_ticks(ticks); -} - -/** - * cputime timer init - * - * - * @param timer The timer to initialize. Cannot be NULL. - * @param fp The timer callback function. Cannot be NULL. - * @param arg Pointer to data object to pass to timer. - */ -void -cputime_timer_init(struct cpu_timer *timer, cputimer_func fp, void *arg) -{ - assert(timer != NULL); - assert(fp != NULL); - - timer->cb = fp; - timer->arg = arg; - timer->link.tqe_prev = (void *) NULL; -} - -/** - * cputime timer start - * - * Start a cputimer that will expire at 'cputime'. If cputime has already - * passed, the timer callback will still be called (at interrupt context). - * Cannot be called when the timer has already started. - * - * @param timer Pointer to timer to start. Cannot be NULL. - * @param cputime The cputime at which the timer should expire. - */ -void -cputime_timer_start(struct cpu_timer *timer, uint32_t cputime) -{ - struct cpu_timer *entry; - uint32_t ctx; - - assert(timer != NULL); - assert(timer->link.tqe_prev == NULL); - - /* XXX: should this use a mutex? not sure... */ - __HAL_DISABLE_INTERRUPTS(ctx); - - timer->cputime = cputime; - if (TAILQ_EMPTY(&g_cputimer_q)) { - TAILQ_INSERT_HEAD(&g_cputimer_q, timer, link); - } else { - TAILQ_FOREACH(entry, &g_cputimer_q, link) { - if ((int32_t)(timer->cputime - entry->cputime) < 0) { - TAILQ_INSERT_BEFORE(entry, timer, link); - break; - } - } - if (!entry) { - TAILQ_INSERT_TAIL(&g_cputimer_q, timer, link); - } - } - - /* If this is the head, we need to set new OCMP */ - if (timer == TAILQ_FIRST(&g_cputimer_q)) { - cputime_set_ocmp(timer); - } - - __HAL_ENABLE_INTERRUPTS(ctx); -} - -/** - * cputimer timer relative - * - * Sets a cpu timer that will expire 'usecs' microseconds from the current - * cputime. - * - * @param timer Pointer to timer. Cannot be NULL. - * @param usecs The number of usecs from now at which the timer will expire. - */ -void -cputime_timer_relative(struct cpu_timer *timer, uint32_t usecs) -{ - uint32_t cputime; - - assert(timer != NULL); - - cputime = cputime_get32() + cputime_usecs_to_ticks(usecs); - cputime_timer_start(timer, cputime); -} - -/** - * cputime timer stop - * - * Stops a cputimer from running. The timer is removed from the timer queue - * and interrupts are disabled if no timers are left on the queue. Can be - * called even if timer is not running. - * - * @param timer Pointer to cputimer to stop. Cannot be NULL. - */ -void -cputime_timer_stop(struct cpu_timer *timer) -{ - int reset_ocmp; - uint32_t ctx; - struct cpu_timer *entry; - - assert(timer != NULL); - - __HAL_DISABLE_INTERRUPTS(ctx); - - if (timer->link.tqe_prev != NULL) { - reset_ocmp = 0; - if (timer == TAILQ_FIRST(&g_cputimer_q)) { - /* If first on queue, we will need to reset OCMP */ - entry = TAILQ_NEXT(timer, link); - reset_ocmp = 1; - } - TAILQ_REMOVE(&g_cputimer_q, timer, link); - timer->link.tqe_prev = NULL; - if (reset_ocmp) { - if (entry) { - cputime_set_ocmp(entry); - } else { - cputime_disable_ocmp(); - } - } - } - - __HAL_ENABLE_INTERRUPTS(ctx); -} - http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/183873d8/hw/mcu/nordic/nrf52xxx/src/hal_cputime.c ---------------------------------------------------------------------- diff --git a/hw/mcu/nordic/nrf52xxx/src/hal_cputime.c b/hw/mcu/nordic/nrf52xxx/src/hal_cputime.c index fbcc96d..d58fee3 100644 --- a/hw/mcu/nordic/nrf52xxx/src/hal_cputime.c +++ b/hw/mcu/nordic/nrf52xxx/src/hal_cputime.c @@ -49,22 +49,7 @@ * - Should I use macro for compare channel? * - Sync to OSTIME. */ - -/* CPUTIME data */ -struct cputime_data -{ - uint32_t ticks_per_usec; /* number of ticks per usec */ - uint32_t cputime_high; /* high word of 64-bit cpu time */ - uint32_t timer_isrs; /* Number of timer interrupts */ - uint32_t ocmp_ints; /* Number of ocmp interrupts */ - uint32_t uif_ints; /* Number of overflow interrupts */ -}; -struct cputime_data g_cputime; - -/* Queue for timers */ -TAILQ_HEAD(cputime_qhead, cpu_timer) g_cputimer_q; - -__STATIC_INLINE void +void cputime_disable_ocmp(void) { CPUTIMER->INTENCLR = CPUTIMER_INT_MASK(CPUTIMER_CC_INT); @@ -79,11 +64,11 @@ cputime_disable_ocmp(void) * * @param timer Pointer to timer. */ -static void +void cputime_set_ocmp(struct cpu_timer *timer) { /* Disable ocmp interrupt and set new value */ - cputime_disable_ocmp(); + CPUTIMER->INTENCLR = CPUTIMER_INT_MASK(CPUTIMER_CC_INT); /* Set output compare register to timer expiration */ CPUTIMER->CC[CPUTIMER_CC_INT] = timer->cputime; @@ -101,41 +86,6 @@ cputime_set_ocmp(struct cpu_timer *timer) } /** - * cputime chk expiration - * - * Iterates through the cputimer queue to determine if any timers have expired. - * If the timer has expired the timer is removed from the queue and the timer - * callback function is executed. - * - */ -static void -cputime_chk_expiration(void) -{ - uint32_t ctx; - struct cpu_timer *timer; - - __HAL_DISABLE_INTERRUPTS(ctx); - while ((timer = TAILQ_FIRST(&g_cputimer_q)) != NULL) { - if ((int32_t)(cputime_get32() - timer->cputime) >= 0) { - TAILQ_REMOVE(&g_cputimer_q, timer, link); - timer->link.tqe_prev = NULL; - timer->cb(timer->arg); - } else { - break; - } - } - - /* Any timers left on queue? If so, we need to set OCMP */ - timer = TAILQ_FIRST(&g_cputimer_q); - if (timer) { - cputime_set_ocmp(timer); - } else { - cputime_disable_ocmp(); - } - __HAL_ENABLE_INTERRUPTS(ctx); -} - -/** * cputime isr * * This is the global timer interrupt routine. @@ -186,18 +136,17 @@ cputime_isr(void) } /** - * cputime init + * cputime hw init * - * Initialize the cputime module. This must be called after os_init is called - * and before any other timer API are used. This should be called only once - * and should be called before the hardware timer is used. + * Initialize the cputime hw. This should be called only once and should be + * called before the hardware timer is used. * * @param clock_freq The desired cputime frequency, in hertz (Hz). * * @return int 0 on success; -1 on error. */ int -cputime_init(uint32_t clock_freq) +cputime_hw_init(uint32_t clock_freq) { uint32_t ctx; uint32_t max_freq; @@ -250,9 +199,6 @@ cputime_init(uint32_t clock_freq) return -1; } - /* Initialize the timer queue */ - TAILQ_INIT(&g_cputimer_q); - /* disable interrupts */ __HAL_DISABLE_INTERRUPTS(ctx); @@ -339,253 +285,3 @@ cputime_get32(void) return cpu_time; } - -/** - * cputime nsecs to ticks - * - * Converts the given number of nanoseconds into cputime ticks. - * - * @param usecs The number of nanoseconds to convert to ticks - * - * @return uint32_t The number of ticks corresponding to 'nsecs' - */ -uint32_t -cputime_nsecs_to_ticks(uint32_t nsecs) -{ - uint32_t ticks; - - ticks = ((nsecs * g_cputime.ticks_per_usec) + 999) / 1000; - return ticks; -} - -/** - * cputime ticks to nsecs - * - * Convert the given number of ticks into nanoseconds. - * - * @param ticks The number of ticks to convert to nanoseconds. - * - * @return uint32_t The number of nanoseconds corresponding to 'ticks' - */ -uint32_t -cputime_ticks_to_nsecs(uint32_t ticks) -{ - uint32_t nsecs; - - nsecs = ((ticks * 1000) + (g_cputime.ticks_per_usec - 1)) / - g_cputime.ticks_per_usec; - - return nsecs; -} - -/** - * cputime usecs to ticks - * - * Converts the given number of microseconds into cputime ticks. - * - * @param usecs The number of microseconds to convert to ticks - * - * @return uint32_t The number of ticks corresponding to 'usecs' - */ -uint32_t -cputime_usecs_to_ticks(uint32_t usecs) -{ - uint32_t ticks; - - ticks = (usecs * g_cputime.ticks_per_usec); - return ticks; -} - -/** - * cputime ticks to usecs - * - * Convert the given number of ticks into microseconds. - * - * @param ticks The number of ticks to convert to microseconds. - * - * @return uint32_t The number of microseconds corresponding to 'ticks' - */ -uint32_t -cputime_ticks_to_usecs(uint32_t ticks) -{ - uint32_t us; - - us = (ticks + (g_cputime.ticks_per_usec - 1)) / g_cputime.ticks_per_usec; - return us; -} - -/** - * cputime delay ticks - * - * Wait until the number of ticks has elapsed. This is a blocking delay. - * - * @param ticks The number of ticks to wait. - */ -void -cputime_delay_ticks(uint32_t ticks) -{ - uint32_t until; - - until = cputime_get32() + ticks; - while ((int32_t)(cputime_get32() - until) < 0) { - /* Loop here till finished */ - } -} - -/** - * cputime delay nsecs - * - * Wait until 'nsecs' nanoseconds has elapsed. This is a blocking delay. - * - * @param nsecs The number of nanoseconds to wait. - */ -void -cputime_delay_nsecs(uint32_t nsecs) -{ - uint32_t ticks; - - ticks = cputime_nsecs_to_ticks(nsecs); - cputime_delay_ticks(ticks); -} - -/** - * cputime delay usecs - * - * Wait until 'usecs' microseconds has elapsed. This is a blocking delay. - * - * @param usecs The number of usecs to wait. - */ -void -cputime_delay_usecs(uint32_t usecs) -{ - uint32_t ticks; - - ticks = cputime_usecs_to_ticks(usecs); - cputime_delay_ticks(ticks); -} - -/** - * cputime timer init - * - * - * @param timer The timer to initialize. Cannot be NULL. - * @param fp The timer callback function. Cannot be NULL. - * @param arg Pointer to data object to pass to timer. - */ -void -cputime_timer_init(struct cpu_timer *timer, cputimer_func fp, void *arg) -{ - assert(timer != NULL); - assert(fp != NULL); - - timer->cb = fp; - timer->arg = arg; - timer->link.tqe_prev = (void *) NULL; -} - -/** - * cputime timer start - * - * Start a cputimer that will expire at 'cputime'. If cputime has already - * passed, the timer callback will still be called (at interrupt context). - * Cannot be called when the timer has already started. - * - * @param timer Pointer to timer to start. Cannot be NULL. - * @param cputime The cputime at which the timer should expire. - */ -void -cputime_timer_start(struct cpu_timer *timer, uint32_t cputime) -{ - struct cpu_timer *entry; - uint32_t ctx; - - assert(timer != NULL); - assert(timer->link.tqe_prev == NULL); - - /* XXX: should this use a mutex? not sure... */ - __HAL_DISABLE_INTERRUPTS(ctx); - - timer->cputime = cputime; - if (TAILQ_EMPTY(&g_cputimer_q)) { - TAILQ_INSERT_HEAD(&g_cputimer_q, timer, link); - } else { - TAILQ_FOREACH(entry, &g_cputimer_q, link) { - if ((int32_t)(timer->cputime - entry->cputime) < 0) { - TAILQ_INSERT_BEFORE(entry, timer, link); - break; - } - } - if (!entry) { - TAILQ_INSERT_TAIL(&g_cputimer_q, timer, link); - } - } - - /* If this is the head, we need to set new OCMP */ - if (timer == TAILQ_FIRST(&g_cputimer_q)) { - cputime_set_ocmp(timer); - } - - __HAL_ENABLE_INTERRUPTS(ctx); -} - -/** - * cputimer timer relative - * - * Sets a cpu timer that will expire 'usecs' microseconds from the current - * cputime. - * - * @param timer Pointer to timer. Cannot be NULL. - * @param usecs The number of usecs from now at which the timer will expire. - */ -void -cputime_timer_relative(struct cpu_timer *timer, uint32_t usecs) -{ - uint32_t cputime; - - assert(timer != NULL); - - cputime = cputime_get32() + cputime_usecs_to_ticks(usecs); - cputime_timer_start(timer, cputime); -} - -/** - * cputime timer stop - * - * Stops a cputimer from running. The timer is removed from the timer queue - * and interrupts are disabled if no timers are left on the queue. Can be - * called even if timer is not running. - * - * @param timer Pointer to cputimer to stop. Cannot be NULL. - */ -void -cputime_timer_stop(struct cpu_timer *timer) -{ - int reset_ocmp; - uint32_t ctx; - struct cpu_timer *entry; - - assert(timer != NULL); - - __HAL_DISABLE_INTERRUPTS(ctx); - - if (timer->link.tqe_prev != NULL) { - reset_ocmp = 0; - if (timer == TAILQ_FIRST(&g_cputimer_q)) { - /* If first on queue, we will need to reset OCMP */ - entry = TAILQ_NEXT(timer, link); - reset_ocmp = 1; - } - TAILQ_REMOVE(&g_cputimer_q, timer, link); - timer->link.tqe_prev = NULL; - if (reset_ocmp) { - if (entry) { - cputime_set_ocmp(entry); - } else { - cputime_disable_ocmp(); - } - } - } - - __HAL_ENABLE_INTERRUPTS(ctx); -} - http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/183873d8/hw/mcu/stm/stm32f4xx/src/hal_cputime.c ---------------------------------------------------------------------- diff --git a/hw/mcu/stm/stm32f4xx/src/hal_cputime.c b/hw/mcu/stm/stm32f4xx/src/hal_cputime.c index f3ada59..0025670 100644 --- a/hw/mcu/stm/stm32f4xx/src/hal_cputime.c +++ b/hw/mcu/stm/stm32f4xx/src/hal_cputime.c @@ -6,7 +6,7 @@ * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at - * + * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, @@ -31,28 +31,20 @@ * - Sync to OSTIME. */ -/* CPUTIME data */ -struct cputime_data +void +cputime_disable_ocmp(void) { - uint32_t ticks_per_usec; /* number of ticks per usec */ - uint32_t cputime_high; /* high word of 64-bit cpu time */ - uint32_t timer_isrs; /* Number of timer interrupts */ - uint32_t ocmp_ints; /* Number of ocmp interrupts */ - uint32_t uif_ints; /* Number of overflow interrupts */ -}; -struct cputime_data g_cputime; - -/* Queue for timers */ -TAILQ_HEAD(cputime_qhead, cpu_timer) g_cputimer_q; + TIM5->DIER &= ~TIM_DIER_CC4IE; +} /** - * cputime set ocmp - * - * Set the OCMP used by the cputime module to the desired cputime. - * + * cputime set ocmp + * + * Set the OCMP used by the cputime module to the desired cputime. + * * @param timer Pointer to timer. */ -static void +void cputime_set_ocmp(struct cpu_timer *timer) { TIM5->DIER &= ~TIM_DIER_CC4IE; @@ -66,44 +58,10 @@ cputime_set_ocmp(struct cpu_timer *timer) } /** - * cputime chk expiration - * - * Iterates through the cputimer queue to determine if any timers have expired. - * If the timer has expired the timer is removed from the queue and the timer - * callback function is executed. - * - */ -static void -cputime_chk_expiration(void) -{ - uint32_t ctx; - struct cpu_timer *timer; - - __HAL_DISABLE_INTERRUPTS(ctx); - while ((timer = TAILQ_FIRST(&g_cputimer_q)) != NULL) { - if ((int32_t)(cputime_get32() - timer->cputime) >= 0) { - TAILQ_REMOVE(&g_cputimer_q, timer, link); - timer->cb(timer->arg); - } else { - break; - } - } - - /* Any timers left on queue? If so, we need to set OCMP */ - timer = TAILQ_FIRST(&g_cputimer_q); - if (timer) { - cputime_set_ocmp(timer); - } else { - TIM5->DIER &= ~TIM_DIER_CC4IE; - } - __HAL_ENABLE_INTERRUPTS(ctx); -} - -/** - * tim5 isr - * - * This is the global timer interrupt routine. - * + * tim5 isr + * + * This is the global timer interrupt routine. + * */ static void cputime_isr(void) @@ -133,18 +91,17 @@ cputime_isr(void) } /** - * cputime init - * - * Initialize the cputime module. This must be called after os_init is called - * and before any other timer API are used. This should be called only once - * and should be called before the hardware timer is used. - * + * cputime hw init + * + * Initialize the cputime hw. This should be called only once and should be + * called before the hardware timer is used. + * * @param clock_freq The desired cputime frequency, in hertz (Hz). - * + * * @return int 0 on success; -1 on error. */ int -cputime_init(uint32_t clock_freq) +cputime_hw_init(uint32_t clock_freq) { uint32_t ctx; uint32_t max_freq; @@ -167,9 +124,6 @@ cputime_init(uint32_t clock_freq) return -1; } - /* Initialize the timer queue */ - TAILQ_INIT(&g_cputimer_q); - /* disable interrupts */ __HAL_DISABLE_INTERRUPTS(ctx); @@ -184,10 +138,10 @@ cputime_init(uint32_t clock_freq) /* In debug mode, we want this timer to be halted */ DBGMCU->APB1FZ |= DBGMCU_APB1_FZ_DBG_TIM5_STOP; - /* + /* * Counter is an up counter with event generation disabled. We disable the * timer with this first write, just in case. - */ + */ TIM5->DIER = 0; TIM5->CR1 = 0; TIM5->CR2 = 0; @@ -228,12 +182,12 @@ cputime_init(uint32_t clock_freq) /** * cputime get64 - * - * Returns cputime as a 64-bit number. - * + * + * Returns cputime as a 64-bit number. + * * @return uint64_t The 64-bit representation of cputime. */ -uint64_t +uint64_t cputime_get64(void) { uint32_t ctx; @@ -256,10 +210,10 @@ cputime_get64(void) } /** - * cputime get32 - * - * Returns the low 32 bits of cputime. - * + * cputime get32 + * + * Returns the low 32 bits of cputime. + * * @return uint32_t The lower 32 bits of cputime */ uint32_t @@ -267,250 +221,3 @@ cputime_get32(void) { return TIM5->CNT; } - -/** - * cputime nsecs to ticks - * - * Converts the given number of nanoseconds into cputime ticks. - * - * @param usecs The number of nanoseconds to convert to ticks - * - * @return uint32_t The number of ticks corresponding to 'nsecs' - */ -uint32_t -cputime_nsecs_to_ticks(uint32_t nsecs) -{ - uint32_t ticks; - - ticks = ((nsecs * g_cputime.ticks_per_usec) + 999) / 1000; - return ticks; -} - -/** - * cputime ticks to nsecs - * - * Convert the given number of ticks into nanoseconds. - * - * @param ticks The number of ticks to convert to nanoseconds. - * - * @return uint32_t The number of nanoseconds corresponding to 'ticks' - */ -uint32_t -cputime_ticks_to_nsecs(uint32_t ticks) -{ - uint32_t nsecs; - - nsecs = ((ticks * 1000) + (g_cputime.ticks_per_usec - 1)) / - g_cputime.ticks_per_usec; - - return nsecs; -} - -/** - * cputime usecs to ticks - * - * Converts the given number of microseconds into cputime ticks. - * - * @param usecs The number of microseconds to convert to ticks - * - * @return uint32_t The number of ticks corresponding to 'usecs' - */ -uint32_t -cputime_usecs_to_ticks(uint32_t usecs) -{ - uint32_t ticks; - - ticks = (usecs * g_cputime.ticks_per_usec); - return ticks; -} - -/** - * cputime ticks to usecs - * - * Convert the given number of ticks into microseconds. - * - * @param ticks The number of ticks to convert to microseconds. - * - * @return uint32_t The number of microseconds corresponding to 'ticks' - */ -uint32_t -cputime_ticks_to_usecs(uint32_t ticks) -{ - uint32_t us; - - us = (ticks + (g_cputime.ticks_per_usec - 1)) / g_cputime.ticks_per_usec; - return us; -} - -/** - * cputime delay ticks - * - * Wait until the number of ticks has elapsed. This is a blocking delay. - * - * @param ticks The number of ticks to wait. - */ -void -cputime_delay_ticks(uint32_t ticks) -{ - uint32_t until; - - until = cputime_get32() + ticks; - while ((int32_t)(cputime_get32() - until) < 0) { - /* Loop here till finished */ - } -} - -/** - * cputime delay nsecs - * - * Wait until 'nsecs' nanoseconds has elapsed. This is a blocking delay. - * - * @param nsecs The number of nanoseconds to wait. - */ -void -cputime_delay_nsecs(uint32_t nsecs) -{ - uint32_t ticks; - - ticks = cputime_nsecs_to_ticks(nsecs); - cputime_delay_ticks(ticks); -} - -/** - * cputime delay usecs - * - * Wait until 'usecs' microseconds has elapsed. This is a blocking delay. - * - * @param usecs The number of usecs to wait. - */ -void -cputime_delay_usecs(uint32_t usecs) -{ - uint32_t ticks; - - ticks = cputime_usecs_to_ticks(usecs); - cputime_delay_ticks(ticks); -} - -/** - * cputime timer init - * - * - * @param timer The timer to initialize. Cannot be NULL. - * @param fp The timer callback function. Cannot be NULL. - * @param arg Pointer to data object to pass to timer. - */ -void -cputime_timer_init(struct cpu_timer *timer, cputimer_func fp, void *arg) -{ - assert(timer != NULL); - assert(fp != NULL); - - timer->cb = fp; - timer->arg = arg; - timer->link.tqe_prev = (void *) NULL; -} - -/** - * cputime timer start - * - * Start a cputimer that will expire at 'cputime'. If cputime has already - * passed, the timer callback will still be called (at interrupt context). - * - * @param timer Pointer to timer to start. Cannot be NULL. - * @param cputime The cputime at which the timer should expire. - */ -void -cputime_timer_start(struct cpu_timer *timer, uint32_t cputime) -{ - struct cpu_timer *entry; - uint32_t ctx; - - assert(timer != NULL); - - /* XXX: should this use a mutex? not sure... */ - __HAL_DISABLE_INTERRUPTS(ctx); - - timer->cputime = cputime; - if (TAILQ_EMPTY(&g_cputimer_q)) { - TAILQ_INSERT_HEAD(&g_cputimer_q, timer, link); - } else { - TAILQ_FOREACH(entry, &g_cputimer_q, link) { - if ((int32_t)(timer->cputime - entry->cputime) < 0) { - TAILQ_INSERT_BEFORE(entry, timer, link); - break; - } - } - if (!entry) { - TAILQ_INSERT_TAIL(&g_cputimer_q, timer, link); - } - } - - /* If this is the head, we need to set new OCMP */ - if (timer == TAILQ_FIRST(&g_cputimer_q)) { - cputime_set_ocmp(timer); - } - - __HAL_ENABLE_INTERRUPTS(ctx); -} - -/** - * cputimer timer relative - * - * Sets a cpu timer that will expire 'usecs' microseconds from the current - * cputime. - * - * @param timer Pointer to timer. Cannot be NULL. - * @param usecs The number of usecs from now at which the timer will expire. - */ -void -cputime_timer_relative(struct cpu_timer *timer, uint32_t usecs) -{ - uint32_t cputime; - - assert(timer != NULL); - - cputime = cputime_get32() + cputime_usecs_to_ticks(usecs); - cputime_timer_start(timer, cputime); -} - -/** - * cputime timer stop - * - * Stops a cputimer from running. The timer is removed from the timer queue - * and interrupts are disabled if no timers are left on the queue. Can be - * called even if timer is running. - * - * @param timer Pointer to cputimer to stop. Cannot be NULL. - */ -void -cputime_timer_stop(struct cpu_timer *timer) -{ - int reset_ocmp; - uint32_t ctx; - struct cpu_timer *entry; - - assert(timer != NULL); - - __HAL_DISABLE_INTERRUPTS(ctx); - - /* If first on queue, we will need to reset OCMP */ - if (timer->link.tqe_prev != NULL) { - reset_ocmp = 0; - if (timer == TAILQ_FIRST(&g_cputimer_q)) { - entry = TAILQ_NEXT(timer, link); - reset_ocmp = 1; - } - TAILQ_REMOVE(&g_cputimer_q, timer, link); - if (reset_ocmp) { - if (entry) { - cputime_set_ocmp(entry); - } else { - TIM5->DIER &= ~TIM_DIER_CC4IE; - } - } - } - - __HAL_ENABLE_INTERRUPTS(ctx); -} -