From 930154ba9c89c6734835515cad93231c346caac2 Mon Sep 17 00:00:00 2001 From: Gregory Nutt Date: Fri, 9 Jan 2015 15:01:49 -0600 Subject: Tiva Timer: Add logic to acknowledge Tiva Timer interrupts --- nuttx/arch/arm/src/tiva/tiva_timer.c | 131 +++++++++++++++++++++++++++++------ nuttx/arch/arm/src/tiva/tiva_timer.h | 120 ++++++++++++++++++++++++++++++-- 2 files changed, 226 insertions(+), 25 deletions(-) diff --git a/nuttx/arch/arm/src/tiva/tiva_timer.c b/nuttx/arch/arm/src/tiva/tiva_timer.c index d7cfe0841..a7e289f7c 100644 --- a/nuttx/arch/arm/src/tiva/tiva_timer.c +++ b/nuttx/arch/arm/src/tiva/tiva_timer.c @@ -442,23 +442,37 @@ static int tiva_timer32_interrupt(struct tiva_gptmstate_s *priv) { const struct tiva_gptm32config_s *config32; const struct tiva_timer32config_s *timer32; - - /* Get the timer configuration from the private state structure */ + uint32_t status; DEBUGASSERT(priv && priv->attr && priv->config); - config32 = (const struct tiva_gptm32config_s *)priv->config; - timer32 = &config32->config; - /* Forward the interrupt to the handler. There should always be a non- - * NULL handler in this case. + /* Status flags are cleared by writing to the corresponding bits in the + * GPTMICR register. */ - DEBUGASSERT(timer32->handler); - if (timer32->handler) + status = tiva_getreg(priv, TIVA_TIMER_MIS_OFFSET); + DEBUGASSERT(status != 0); + + if (status != 0) { - timer32->handler((TIMER_HANDLE)priv, config32); + tiva_putreg(priv, TIVA_TIMER_ICR_OFFSET, status); + + /* Get the timer configuration from the private state structure */ + + config32 = (const struct tiva_gptm32config_s *)priv->config; + timer32 = &config32->config; + + /* Forward the interrupt to the handler. There should always be a non- + * NULL handler in this case. + */ + + DEBUGASSERT(timer32->handler); + if (timer32->handler) + { + timer32->handler((TIMER_HANDLE)priv, config32, status); + } } -#warning Do I need to clear the interrupt here? + return OK; } @@ -538,23 +552,39 @@ static int tiva_timer16_interrupt(struct tiva_gptmstate_s *priv, int tmndx) { const struct tiva_gptm16config_s *config16; const struct tiva_timer16config_s *timer16; - - /* Get the timer configuration from the private state structure */ + uint32_t intmask; + uint32_t status; DEBUGASSERT(priv && priv->attr && priv->config && (unsigned)tmndx < 2); - config16 = (const struct tiva_gptm16config_s *)priv->config; - timer16 = &config16->config[tmndx]; - /* Forward the interrupt to the handler. There should always be a non- - * NULL handler in this case. + /* Status flags are cleared by writing to the corresponding bits in the + * GPTMICR register. */ - DEBUGASSERT(timer16->handler); - if (timer16->handler) + intmask = tmndx ? TIMERB_INTS : TIMERA_INTS; + status = tiva_getreg(priv, TIVA_TIMER_MIS_OFFSET) & intmask; + DEBUGASSERT(status != 0); + + if (status != 0) { - timer16->handler((TIMER_HANDLE)priv, config16, tmndx); + tiva_putreg(priv, TIVA_TIMER_ICR_OFFSET, status); + + /* Get the timer configuration from the private state structure */ + + config16 = (const struct tiva_gptm16config_s *)priv->config; + timer16 = &config16->config[tmndx]; + + /* Forward the interrupt to the handler. There should always be a + * non-NULL handler in this context. + */ + + DEBUGASSERT(timer16->handler); + if (timer16->handler) + { + timer16->handler((TIMER_HANDLE)priv, config16, status, tmndx); + } } -#warning Do I need to clear the interrupt here? + return OK; } @@ -918,7 +948,7 @@ static int tiva_oneshot_periodic_mode16(struct tiva_gptmstate_s *priv, if (timer->handler) { /* Select the interrupt mask that will enable the timer interrupt. - * Any non-zero value of imr indicates that interrupts are expected. + * Any non-zero value of 'imr' indicates that interrupts are expected. */ priv->imr |= tmndx ? TIMER_INT_TBTO : TIMER_INT_TATO; @@ -1316,6 +1346,14 @@ static int tiva_timer16_configure(struct tiva_gptmstate_s *priv, * Configure a general purpose timer module to operate in the provided * modes. * + * Input Parameters: + * gptm - Describes the configure of the GPTM timer resources + * + * Returned Value: + * On success, a non-NULL handle is returned that can be used with the + * other timer interfaces. NULL is returned on any failure to initialize + * the timer. + * ****************************************************************************/ TIMER_HANDLE tiva_gptm_configure(const struct tiva_gptmconfig_s *config) @@ -1545,6 +1583,14 @@ TIMER_HANDLE tiva_gptm_configure(const struct tiva_gptmconfig_s *config) * the timer block. Its primary purpose is to support inline functions * defined in this header file. * + * Input Parameters: + * handle - The handle value returned by tiva_gptm_configure() + * offset - The offset to the timer register to be written + * value - The value to write to the timer register + * + * Returned Value: + * None. + * ****************************************************************************/ void tiva_gptm_putreg(TIMER_HANDLE handle, unsigned int offset, uint32_t value) @@ -1561,6 +1607,14 @@ void tiva_gptm_putreg(TIMER_HANDLE handle, unsigned int offset, uint32_t value) * the timer block. Its primary purpose is to support inline functions * defined in this header file. * + * Input Parameters: + * handle - The handle value returned by tiva_gptm_configure() + * offset - The offset to the timer register to be written + * + * Returned Value: + * The 32-bit value read at the provided offset into the timer register base + * address. + * ****************************************************************************/ uint32_t tiva_gptm_getreg(TIMER_HANDLE handle, unsigned int offset) @@ -1577,6 +1631,15 @@ uint32_t tiva_gptm_getreg(TIMER_HANDLE handle, unsigned int offset) * the timer block. Its primary purpose is to support inline functions * defined in this header file. * + * Input Parameters: + * handle - The handle value returned by tiva_gptm_configure() + * offset - The offset to the timer register to be written + * clrbits - The collection of bits to be cleared in the register + * setbits - The collection of bits to be set in the register + * + * Returned Value: + * None. + * ****************************************************************************/ void tiva_gptm_modifyreg(TIMER_HANDLE handle, unsigned int offset, @@ -1595,6 +1658,12 @@ void tiva_gptm_modifyreg(TIMER_HANDLE handle, unsigned int offset, * After tiva_gptm_configure() has been called to configure a 32-bit timer, * this function must be called to start the timer(s). * + * Input Parameters: + * handle - The handle value returned by tiva_gptm_configure() + * + * Returned Value: + * None. + * ****************************************************************************/ void tiva_timer32_start(TIMER_HANDLE handle) @@ -1624,6 +1693,13 @@ void tiva_timer32_start(TIMER_HANDLE handle) * After tiva_gptm_configure() has been called to configure 16-bit timer(s), * this function must be called to start one 16-bit timer. * + * Input Parameters: + * handle - The handle value returned by tiva_gptm_configure() + * tmndx - Either TIMER16A or TIMER16B to select the 16-bit timer + * + * Returned Value: + * None. + * ****************************************************************************/ void tiva_timer16_start(TIMER_HANDLE handle, int tmndx) @@ -1657,6 +1733,12 @@ void tiva_timer16_start(TIMER_HANDLE handle, int tmndx) * After tiva_timer32_start() has been called to start a 32-bit timer, * this function may be called to stop the timer. * + * Input Parameters: + * handle - The handle value returned by tiva_gptm_configure() + * + * Returned Value: + * None. + * ****************************************************************************/ void tiva_timer32_stop(TIMER_HANDLE handle) @@ -1681,6 +1763,13 @@ void tiva_timer32_stop(TIMER_HANDLE handle) * After tiva_timer32_start() has been called to start a 16-bit timer, * this function may be called to stop the timer. * + * Input Parameters: + * handle - The handle value returned by tiva_gptm_configure() + * tmndx - Either TIMER16A or TIMER16B to select the 16-bit timer + * + * Returned Value: + * None. + * ****************************************************************************/ void tiva_timer16_stop(TIMER_HANDLE handle, int tmndx) diff --git a/nuttx/arch/arm/src/tiva/tiva_timer.h b/nuttx/arch/arm/src/tiva/tiva_timer.h index 902790576..5b9f8a3e6 100644 --- a/nuttx/arch/arm/src/tiva/tiva_timer.h +++ b/nuttx/arch/arm/src/tiva/tiva_timer.h @@ -124,11 +124,19 @@ enum tiva_timer16mode_e typedef FAR void *TIMER_HANDLE; -/* This type describes the 32-bit timer interrupt handler */ +/* This type describes the 32-bit timer interrupt handler. + * + * Input Parameters: + * handle - The same value as returned by tiva_gptm_configure() + * config - The same value provided as as an input to tiva_gptm_configure() + * status - The value of the GPTM masked status register that caused the + * interrupt + */ struct tiva_gptm32config_s; typedef void (*timer32_handler_t)(TIMER_HANDLE handle, - const struct tiva_gptm32config_s *config); + const struct tiva_gptm32config_s *config, + uint32_t status); /* This structure describes the configuration of one 32-bit timer */ @@ -158,12 +166,21 @@ struct tiva_timer32config_s } u; }; -/* This type describes the 16-bit timer interrupt handler */ +/* This type describes the 16-bit timer interrupt handler + * + * Input Parameters: + * handle - The same value as returned by tiva_gptm_configure() + * config - The same value provided as as an input to tiva_gptm_configure() + * status - The value of the GPTM masked status register that caused the + * interrupt. + * tmndx - Either TIMER16A or TIMER16B. This may be useful in the + * event that the same handler is used for Timer A and B. + */ struct tiva_gptm16config_s; typedef void (*timer16_handler_t)(TIMER_HANDLE handle, const struct tiva_gptm16config_s *config, - int tmndx); + uint32_t status, int tmndx); /* This structure describes the configuration of one 16-bit timer A/B */ @@ -250,6 +267,14 @@ struct tiva_gptm16config_s * Configure a general purpose timer module to operate in the provided * modes. * + * Input Parameters: + * gptm - Describes the configure of the GPTM timer resources + * + * Returned Value: + * On success, a non-NULL handle is returned that can be used with the + * other timer interfaces. NULL is returned on any failure to initialize + * the timer. + * ****************************************************************************/ TIMER_HANDLE tiva_gptm_configure(const struct tiva_gptmconfig_s *gptm); @@ -262,6 +287,14 @@ TIMER_HANDLE tiva_gptm_configure(const struct tiva_gptmconfig_s *gptm); * the timer block. Its primary purpose is to support inline functions * defined in this header file. * + * Input Parameters: + * handle - The handle value returned by tiva_gptm_configure() + * offset - The offset to the timer register to be written + * value - The value to write to the timer register + * + * Returned Value: + * None. + * ****************************************************************************/ void tiva_gptm_putreg(TIMER_HANDLE handle, unsigned int offset, uint32_t value); @@ -274,6 +307,14 @@ void tiva_gptm_putreg(TIMER_HANDLE handle, unsigned int offset, uint32_t value); * the timer block. Its primary purpose is to support inline functions * defined in this header file. * + * Input Parameters: + * handle - The handle value returned by tiva_gptm_configure() + * offset - The offset to the timer register to be written + * + * Returned Value: + * The 32-bit value read at the provided offset into the timer register base + * address. + * ****************************************************************************/ uint32_t tiva_gptm_getreg(TIMER_HANDLE handle, unsigned int offset); @@ -286,6 +327,15 @@ uint32_t tiva_gptm_getreg(TIMER_HANDLE handle, unsigned int offset); * the timer block. Its primary purpose is to support inline functions * defined in this header file. * + * Input Parameters: + * handle - The handle value returned by tiva_gptm_configure() + * offset - The offset to the timer register to be written + * clrbits - The collection of bits to be cleared in the register + * setbits - The collection of bits to be set in the register + * + * Returned Value: + * None. + * ****************************************************************************/ void tiva_gptm_modifyreg(TIMER_HANDLE handle, unsigned int offset, @@ -298,6 +348,12 @@ void tiva_gptm_modifyreg(TIMER_HANDLE handle, unsigned int offset, * After tiva_gptm_configure() has been called to configure a 32-bit timer, * this function must be called to start the timer(s). * + * Input Parameters: + * handle - The handle value returned by tiva_gptm_configure() + * + * Returned Value: + * None. + * ****************************************************************************/ void tiva_timer32_start(TIMER_HANDLE handle); @@ -309,6 +365,13 @@ void tiva_timer32_start(TIMER_HANDLE handle); * After tiva_gptm_configure() has been called to configure 16-bit timer(s), * this function must be called to start one 16-bit timer. * + * Input Parameters: + * handle - The handle value returned by tiva_gptm_configure() + * tmndx - Either TIMER16A or TIMER16B to select the 16-bit timer + * + * Returned Value: + * None. + * ****************************************************************************/ void tiva_timer16_start(TIMER_HANDLE handle, int tmndx); @@ -323,6 +386,12 @@ void tiva_timer16_start(TIMER_HANDLE handle, int tmndx); * After tiva_timer32_start() has been called to start a 32-bit timer, * this function may be called to stop the timer. * + * Input Parameters: + * handle - The handle value returned by tiva_gptm_configure() + * + * Returned Value: + * None. + * ****************************************************************************/ void tiva_timer32_stop(TIMER_HANDLE handle); @@ -334,6 +403,13 @@ void tiva_timer32_stop(TIMER_HANDLE handle); * After tiva_timer32_start() has been called to start a 16-bit timer, * this function may be called to stop the timer. * + * Input Parameters: + * handle - The handle value returned by tiva_gptm_configure() + * tmndx - Either TIMER16A or TIMER16B to select the 16-bit timer + * + * Returned Value: + * None. + * ****************************************************************************/ void tiva_timer16_stop(TIMER_HANDLE handle, int tmndx); @@ -348,6 +424,13 @@ void tiva_timer16_stop(TIMER_HANDLE handle, int tmndx); * This function may be called at any time to change the timer interval * load value of a 32-bit timer. * + * Input Parameters: + * handle - The handle value returned by tiva_gptm_configure() + * load - The value to write to the timer interval load register + * + * Returned Value: + * None. + * ****************************************************************************/ static inline void tiva_timer32_setload(TIMER_HANDLE handle, uint32_t load) @@ -362,6 +445,14 @@ static inline void tiva_timer32_setload(TIMER_HANDLE handle, uint32_t load) * This function may be called at any time to change the timer interval * load value of a 16-bit timer. * + * Input Parameters: + * handle - The handle value returned by tiva_gptm_configure() + * load - The value to write to the timer interval load register + * tmndx - Either TIMER16A or TIMER16B to select the 16-bit timer + * + * Returned Value: + * None. + * ****************************************************************************/ static inline void tiva_timer16_setload(TIMER_HANDLE handle, uint16_t load, @@ -390,6 +481,13 @@ static inline void tiva_timer16b_setload(TIMER_HANDLE handle, uint16_t load) * This function may be called at any time to change the timer interval * match value of a 32-bit timer. * + * Input Parameters: + * handle - The handle value returned by tiva_gptm_configure() + * match - The value to write to the timer match register + * + * Returned Value: + * None. + * ****************************************************************************/ static inline void tiva_timer32_setmatch(TIMER_HANDLE handle, uint32_t match) @@ -404,6 +502,14 @@ static inline void tiva_timer32_setmatch(TIMER_HANDLE handle, uint32_t match) * This function may be called at any time to change the timer interval * match value of a 16-bit timer. * + * Input Parameters: + * handle - The handle value returned by tiva_gptm_configure() + * match - The value to write to the timer match register + * tmndx - Either TIMER16A or TIMER16B to select the 16-bit timer + * + * Returned Value: + * None. + * ****************************************************************************/ static inline void tiva_timer16_setmatch(TIMER_HANDLE handle, uint16_t match, @@ -432,6 +538,12 @@ static inline void tiva_timer16b_setmatch(TIMER_HANDLE handle, uint16_t match) * Trigger timers from GPTM0 output. This is part of the timer * configuration logic and should be called before timers are enabled. * + * Input Parameters: + * sync - The value to write to the GPTM0 SYNC register + * + * Returned Value: + * None. + * ****************************************************************************/ static inline void tiva_gptm0_synchronize(uint32_t sync) -- cgit v1.2.3