SAM3/4: Enhanced timer/counter driver from Bob Doiron
This commit is contained in:
parent
d897b4de76
commit
aa44b8b588
@ -475,45 +475,54 @@ config SAM34_SSC
|
|||||||
config SAM34_TC0
|
config SAM34_TC0
|
||||||
bool "Timer/Counter 0 (TC0)"
|
bool "Timer/Counter 0 (TC0)"
|
||||||
default n
|
default n
|
||||||
|
select SAM34_TC
|
||||||
|
|
||||||
config SAM34_TC1
|
config SAM34_TC1
|
||||||
bool "Timer/Counter 1 (TC1)"
|
bool "Timer/Counter 1 (TC1)"
|
||||||
default n
|
default n
|
||||||
|
select SAM34_TC
|
||||||
|
|
||||||
config SAM34_TC2
|
config SAM34_TC2
|
||||||
bool "Timer/Counter 2 (TC2)"
|
bool "Timer/Counter 2 (TC2)"
|
||||||
default n
|
default n
|
||||||
depends on ARCH_CHIP_SAM3U || ARCH_CHIP_SAM3X || ARCH_CHIP_SAM3A || ARCH_CHIP_SAM4S || ARCH_CHIP_SAM4E
|
depends on ARCH_CHIP_SAM3U || ARCH_CHIP_SAM3X || ARCH_CHIP_SAM3A || ARCH_CHIP_SAM4S || ARCH_CHIP_SAM4E
|
||||||
|
select SAM34_TC
|
||||||
|
|
||||||
config SAM34_TC3
|
config SAM34_TC3
|
||||||
bool "Timer/Counter 3 (TC3)"
|
bool "Timer/Counter 3 (TC3)"
|
||||||
default n
|
default n
|
||||||
depends on ARCH_CHIP_SAM3X || ARCH_CHIP_SAM3A || ARCH_CHIP_SAM4S || ARCH_CHIP_SAM4E
|
depends on ARCH_CHIP_SAM3X || ARCH_CHIP_SAM3A || ARCH_CHIP_SAM4S || ARCH_CHIP_SAM4E
|
||||||
|
select SAM34_TC
|
||||||
|
|
||||||
config SAM34_TC4
|
config SAM34_TC4
|
||||||
bool "Timer/Counter 4 (TC4)"
|
bool "Timer/Counter 4 (TC4)"
|
||||||
default n
|
default n
|
||||||
depends on ARCH_CHIP_SAM3X || ARCH_CHIP_SAM3A || ARCH_CHIP_SAM4S || ARCH_CHIP_SAM4E
|
depends on ARCH_CHIP_SAM3X || ARCH_CHIP_SAM3A || ARCH_CHIP_SAM4S || ARCH_CHIP_SAM4E
|
||||||
|
select SAM34_TC
|
||||||
|
|
||||||
config SAM34_TC5
|
config SAM34_TC5
|
||||||
bool "Timer/Counter 5 (TC5)"
|
bool "Timer/Counter 5 (TC5)"
|
||||||
default n
|
default n
|
||||||
depends on ARCH_CHIP_SAM3X || ARCH_CHIP_SAM3A || ARCH_CHIP_SAM4S || ARCH_CHIP_SAM4E
|
depends on ARCH_CHIP_SAM3X || ARCH_CHIP_SAM3A || ARCH_CHIP_SAM4S || ARCH_CHIP_SAM4E
|
||||||
|
select SAM34_TC
|
||||||
|
|
||||||
config SAM34_TC6
|
config SAM34_TC6
|
||||||
bool "Timer/Counter 6 (TC6)"
|
bool "Timer/Counter 6 (TC6)"
|
||||||
default n
|
default n
|
||||||
depends on ARCH_CHIP_SAM3X || ARCH_CHIP_SAM3A || ARCH_CHIP_SAM4E
|
depends on ARCH_CHIP_SAM3X || ARCH_CHIP_SAM3A || ARCH_CHIP_SAM4E
|
||||||
|
select SAM34_TC
|
||||||
|
|
||||||
config SAM34_TC7
|
config SAM34_TC7
|
||||||
bool "Timer/Counter 7 (TC7)"
|
bool "Timer/Counter 7 (TC7)"
|
||||||
default n
|
default n
|
||||||
depends on ARCH_CHIP_SAM3X || ARCH_CHIP_SAM3A || ARCH_CHIP_SAM4E
|
depends on ARCH_CHIP_SAM3X || ARCH_CHIP_SAM3A || ARCH_CHIP_SAM4E
|
||||||
|
select SAM34_TC
|
||||||
|
|
||||||
config SAM34_TC8
|
config SAM34_TC8
|
||||||
bool "Timer/Counter 6 (TC8)"
|
bool "Timer/Counter 6 (TC8)"
|
||||||
default n
|
default n
|
||||||
depends on ARCH_CHIP_SAM3X || ARCH_CHIP_SAM3A || ARCH_CHIP_SAM4E
|
depends on ARCH_CHIP_SAM3X || ARCH_CHIP_SAM3A || ARCH_CHIP_SAM4E
|
||||||
|
select SAM34_TC
|
||||||
|
|
||||||
config SAM34_TRNG
|
config SAM34_TRNG
|
||||||
bool "True Random Number Generator (TRNG)"
|
bool "True Random Number Generator (TRNG)"
|
||||||
@ -1177,8 +1186,8 @@ config SAM34_HSMCI_CMDDEBUG
|
|||||||
endmenu # HSMCI device driver options
|
endmenu # HSMCI device driver options
|
||||||
endif # SAM34_HSMCI
|
endif # SAM34_HSMCI
|
||||||
|
|
||||||
if SAM34_UDP
|
|
||||||
menu "AT91SAM3/4 USB Full Speed Device Controller driver (DCD) options"
|
menu "AT91SAM3/4 USB Full Speed Device Controller driver (DCD) options"
|
||||||
|
depends on SAM34_UDP
|
||||||
|
|
||||||
config SAM34_UDP_REGDEBUG
|
config SAM34_UDP_REGDEBUG
|
||||||
bool "Enable low-level UDP register debug"
|
bool "Enable low-level UDP register debug"
|
||||||
@ -1186,10 +1195,23 @@ config SAM34_UDP_REGDEBUG
|
|||||||
depends on DEBUG
|
depends on DEBUG
|
||||||
|
|
||||||
endmenu # USB Full Speed Device Controller driver (DCD) options
|
endmenu # USB Full Speed Device Controller driver (DCD) options
|
||||||
endif # SAM34_UDP
|
|
||||||
|
|
||||||
if SAM34_WDT
|
config SAM34_TC
|
||||||
|
bool
|
||||||
|
default n
|
||||||
|
|
||||||
|
menu "AT91SAM3/4 Timer/Counter options"
|
||||||
|
depends on SAM34_TC
|
||||||
|
|
||||||
|
config SAM34_TC_REGDEBUG
|
||||||
|
bool "Enable low-level timer/counter register debug"
|
||||||
|
default n
|
||||||
|
depends on DEBUG
|
||||||
|
|
||||||
|
endmenu # USB Full Speed Device Controller driver (DCD) options
|
||||||
|
|
||||||
menu "AT91SAM3/4 Watchdog Configuration"
|
menu "AT91SAM3/4 Watchdog Configuration"
|
||||||
|
depends on SAM34_WDT
|
||||||
|
|
||||||
config WDT_ENABLED_ON_RESET
|
config WDT_ENABLED_ON_RESET
|
||||||
bool "Watchdog Enabled on reset"
|
bool "Watchdog Enabled on reset"
|
||||||
@ -1248,6 +1270,6 @@ config WDT_THREAD_PRIORITY
|
|||||||
config WDT_THREAD_STACKSIZE
|
config WDT_THREAD_STACKSIZE
|
||||||
int "Watchdog Thread Stacksize"
|
int "Watchdog Thread Stacksize"
|
||||||
default 1024
|
default 1024
|
||||||
|
|
||||||
endif # WDT_THREAD
|
endif # WDT_THREAD
|
||||||
endmenu #"AT91SAM3/4 Watchdog device driver options"
|
endmenu #"AT91SAM3/4 Watchdog device driver options"
|
||||||
endif # SAM34_WDT
|
|
||||||
|
@ -54,8 +54,6 @@
|
|||||||
#include "sam_tc.h"
|
#include "sam_tc.h"
|
||||||
#include "sam_periphclks.h"
|
#include "sam_periphclks.h"
|
||||||
|
|
||||||
//#define CONFIG_SAM34_TC_REGDEBUG
|
|
||||||
|
|
||||||
#if defined(CONFIG_TIMER) && (defined(CONFIG_SAM34_TC0) || \
|
#if defined(CONFIG_TIMER) && (defined(CONFIG_SAM34_TC0) || \
|
||||||
defined(CONFIG_SAM34_TC1) || defined(CONFIG_SAM34_TC2) || \
|
defined(CONFIG_SAM34_TC1) || defined(CONFIG_SAM34_TC2) || \
|
||||||
defined(CONFIG_SAM34_TC3) || defined(CONFIG_SAM34_TC4) || \
|
defined(CONFIG_SAM34_TC3) || defined(CONFIG_SAM34_TC4) || \
|
||||||
@ -98,10 +96,15 @@
|
|||||||
struct sam34_lowerhalf_s
|
struct sam34_lowerhalf_s
|
||||||
{
|
{
|
||||||
FAR const struct timer_ops_s *ops; /* Lower half operations */
|
FAR const struct timer_ops_s *ops; /* Lower half operations */
|
||||||
xcpt_t handler; /* Current user interrupt handler */
|
|
||||||
uint32_t timeout; /* The actual timeout value (us) */
|
/* Private data */
|
||||||
bool started; /* The timer has been started */
|
|
||||||
uint16_t reload; /* The 12-bit reload field reset value (WDV) */
|
uint32_t base; /* Base address of the timer */
|
||||||
|
tccb_t handler; /* Current user interrupt handler */
|
||||||
|
uint32_t timeout; /* The current timeout value (us) */
|
||||||
|
uint32_t adjustment; /* time lost due to clock resolution truncation (us) */
|
||||||
|
uint32_t clkticks; /* actual clock ticks for current interval */
|
||||||
|
bool started; /* The timer has been started */
|
||||||
uint16_t debug;
|
uint16_t debug;
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -118,7 +121,7 @@ static void sam34_putreg(uint32_t val, uint32_t addr);
|
|||||||
# define sam34_putreg(val,addr) putreg32(val,addr)
|
# define sam34_putreg(val,addr) putreg32(val,addr)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* Interrupt hanlding *******************************************************/
|
/* Interrupt handling *******************************************************/
|
||||||
|
|
||||||
static int sam34_interrupt(int irq, FAR void *context);
|
static int sam34_interrupt(int irq, FAR void *context);
|
||||||
|
|
||||||
@ -130,8 +133,8 @@ static int sam34_getstatus(FAR struct timer_lowerhalf_s *lower,
|
|||||||
FAR struct timer_status_s *status);
|
FAR struct timer_status_s *status);
|
||||||
static int sam34_settimeout(FAR struct timer_lowerhalf_s *lower,
|
static int sam34_settimeout(FAR struct timer_lowerhalf_s *lower,
|
||||||
uint32_t timeout);
|
uint32_t timeout);
|
||||||
static xcpt_t sam34_capture(FAR struct timer_lowerhalf_s *lower,
|
static tccb_t sam34_capture(FAR struct timer_lowerhalf_s *lower,
|
||||||
xcpt_t handler);
|
tccb_t handler);
|
||||||
static int sam34_ioctl(FAR struct timer_lowerhalf_s *lower, int cmd,
|
static int sam34_ioctl(FAR struct timer_lowerhalf_s *lower, int cmd,
|
||||||
unsigned long arg);
|
unsigned long arg);
|
||||||
|
|
||||||
@ -269,12 +272,27 @@ static int sam34_interrupt(int irq, FAR void *context)
|
|||||||
regval = sam34_getreg(SAM_TC0_SR);
|
regval = sam34_getreg(SAM_TC0_SR);
|
||||||
if ((regval & TC_INT_CPCS) != 0)
|
if ((regval & TC_INT_CPCS) != 0)
|
||||||
{
|
{
|
||||||
|
uint32_t timeout;
|
||||||
|
|
||||||
/* Is there a registered handler? */
|
/* Is there a registered handler? */
|
||||||
|
|
||||||
if (priv->handler)
|
if (priv->handler && priv->handler(&priv->timeout))
|
||||||
{
|
{
|
||||||
priv->handler(irq, context);
|
/* Calculate new ticks */
|
||||||
}
|
|
||||||
|
priv->clkticks = ((uint64_t)(priv->adjustment + priv->timeout))*TC_FCLK / 1000000;
|
||||||
|
|
||||||
|
/* Set next interval interval. TODO: make sure the interval is not so soon it will be missed! */
|
||||||
|
|
||||||
|
sam34_putreg(priv->clkticks, SAM_TC0_RC);
|
||||||
|
|
||||||
|
timeout = (1000000ULL * priv->clkticks) / TC_FCLK; /* trucated timeout */
|
||||||
|
priv->adjustment = (priv->adjustment + priv->timeout) - timeout; /* truncated time to be added to next interval (dither) */
|
||||||
|
}
|
||||||
|
else /* stop */
|
||||||
|
{
|
||||||
|
sam34_stop((FAR struct timer_lowerhalf_s *)&g_tcdev);
|
||||||
|
}
|
||||||
|
|
||||||
/* TC_INT_CPCS is cleared by reading SAM_TC0_SR */
|
/* TC_INT_CPCS is cleared by reading SAM_TC0_SR */
|
||||||
}
|
}
|
||||||
@ -305,9 +323,14 @@ static int sam34_start(FAR struct timer_lowerhalf_s *lower)
|
|||||||
tcvdbg("Entry\n");
|
tcvdbg("Entry\n");
|
||||||
DEBUGASSERT(priv);
|
DEBUGASSERT(priv);
|
||||||
|
|
||||||
|
if(priv->started)
|
||||||
|
{
|
||||||
|
return -EINVAL;
|
||||||
|
}
|
||||||
|
|
||||||
sam_tc0_enableclk();
|
sam_tc0_enableclk();
|
||||||
|
|
||||||
sam34_putreg(TC_CCR_CLKDIS, SAM_TC0_CCR); // disable counter
|
sam34_putreg(TC_CCR_CLKDIS, SAM_TC0_CCR); /* Disable counter */
|
||||||
|
|
||||||
/* TC_CMR_WAVE - waveform mode
|
/* TC_CMR_WAVE - waveform mode
|
||||||
* TC_CMR_WAVSEL_UPAUTO - reset on RC compare (interval timer)
|
* TC_CMR_WAVSEL_UPAUTO - reset on RC compare (interval timer)
|
||||||
@ -317,19 +340,17 @@ static int sam34_start(FAR struct timer_lowerhalf_s *lower)
|
|||||||
mr_val |= (TC_CMR_WAVE + TC_CMR_WAVSEL_UPAUTO + TC_CMR_TCCLKS_TIMERCLOCK5);
|
mr_val |= (TC_CMR_WAVE + TC_CMR_WAVSEL_UPAUTO + TC_CMR_TCCLKS_TIMERCLOCK5);
|
||||||
sam34_putreg(mr_val, SAM_TC0_CMR);
|
sam34_putreg(mr_val, SAM_TC0_CMR);
|
||||||
|
|
||||||
sam34_putreg(priv->reload, SAM_TC0_RC); // set interval
|
sam34_putreg(priv->clkticks, SAM_TC0_RC); /* Set interval */
|
||||||
|
|
||||||
/* TODO: isr active without user handle for now... */
|
if (priv->handler)
|
||||||
// if (priv->handler)
|
|
||||||
{
|
{
|
||||||
/* Clear status */
|
/* Clear status and enable interrupt */
|
||||||
|
|
||||||
sam34_getreg(SAM_TC0_SR);
|
sam34_getreg(SAM_TC0_SR);
|
||||||
sam34_putreg(TC_INT_CPCS, SAM_TC0_IMR);
|
|
||||||
sam34_putreg(TC_INT_CPCS, SAM_TC0_IER);
|
sam34_putreg(TC_INT_CPCS, SAM_TC0_IER);
|
||||||
}
|
}
|
||||||
|
|
||||||
sam34_putreg(TC_CCR_SWTRG + TC_CCR_CLKEN, SAM_TC0_CCR); // start counter
|
sam34_putreg(TC_CCR_SWTRG + TC_CCR_CLKEN, SAM_TC0_CCR); /* Start counter */
|
||||||
|
|
||||||
priv->started = true;
|
priv->started = true;
|
||||||
return OK;
|
return OK;
|
||||||
@ -352,10 +373,19 @@ static int sam34_start(FAR struct timer_lowerhalf_s *lower)
|
|||||||
|
|
||||||
static int sam34_stop(FAR struct timer_lowerhalf_s *lower)
|
static int sam34_stop(FAR struct timer_lowerhalf_s *lower)
|
||||||
{
|
{
|
||||||
|
FAR struct sam34_lowerhalf_s *priv = (FAR struct sam34_lowerhalf_s *)lower;
|
||||||
tcvdbg("Entry\n");
|
tcvdbg("Entry\n");
|
||||||
sam34_putreg(TC_CCR_CLKDIS, SAM_TC0_CCR); // disable counter
|
DEBUGASSERT(priv);
|
||||||
sam34_putreg(TC_INT_ALL, SAM_TC0_IDR); // disable all ints
|
|
||||||
|
if(!priv->started)
|
||||||
|
{
|
||||||
|
return -EINVAL;
|
||||||
|
}
|
||||||
|
|
||||||
|
sam34_putreg(TC_CCR_CLKDIS, SAM_TC0_CCR); /* Disable counter */
|
||||||
|
sam34_putreg(TC_INT_ALL, SAM_TC0_IDR); /* Disable all ints */
|
||||||
sam_tc0_disableclk();
|
sam_tc0_disableclk();
|
||||||
|
priv->started = false;
|
||||||
|
|
||||||
return OK;
|
return OK;
|
||||||
}
|
}
|
||||||
@ -367,9 +397,9 @@ static int sam34_stop(FAR struct timer_lowerhalf_s *lower)
|
|||||||
* Get the current timer status
|
* Get the current timer status
|
||||||
*
|
*
|
||||||
* Input Parameters:
|
* Input Parameters:
|
||||||
* lower - A pointer the publicly visible representation of the "lower-half"
|
* lower - A pointer the publicly visible representation of the "lower-half"
|
||||||
* driver state structure.
|
* driver state structure.
|
||||||
* stawtus - The location to return the status information.
|
* status - The location to return the status information.
|
||||||
*
|
*
|
||||||
* Returned Values:
|
* Returned Values:
|
||||||
* Zero on success; a negated errno value on failure.
|
* Zero on success; a negated errno value on failure.
|
||||||
@ -405,7 +435,7 @@ static int sam34_getstatus(FAR struct timer_lowerhalf_s *lower,
|
|||||||
/* Get the time remaining until the timer expires (in microseconds) */
|
/* Get the time remaining until the timer expires (in microseconds) */
|
||||||
|
|
||||||
elapsed = sam34_getreg(SAM_TC0_CV);
|
elapsed = sam34_getreg(SAM_TC0_CV);
|
||||||
status->timeleft = (priv->timeout * elapsed) / (priv->reload + 1);
|
status->timeleft = (priv->timeout * elapsed) / (priv->clkticks + 1); /* TODO - check on this +1 */
|
||||||
|
|
||||||
tcvdbg(" flags : %08x\n", status->flags);
|
tcvdbg(" flags : %08x\n", status->flags);
|
||||||
tcvdbg(" timeout : %d\n", status->timeout);
|
tcvdbg(" timeout : %d\n", status->timeout);
|
||||||
@ -422,7 +452,7 @@ static int sam34_getstatus(FAR struct timer_lowerhalf_s *lower,
|
|||||||
* Input Parameters:
|
* Input Parameters:
|
||||||
* lower - A pointer the publicly visible representation of the "lower-half"
|
* lower - A pointer the publicly visible representation of the "lower-half"
|
||||||
* driver state structure.
|
* driver state structure.
|
||||||
* timeout - The new timeout value in millisecnds.
|
* timeout - The new timeout value in milliseconds.
|
||||||
*
|
*
|
||||||
* Returned Values:
|
* Returned Values:
|
||||||
* Zero on success; a negated errno value on failure.
|
* Zero on success; a negated errno value on failure.
|
||||||
@ -433,7 +463,6 @@ static int sam34_settimeout(FAR struct timer_lowerhalf_s *lower,
|
|||||||
uint32_t timeout)
|
uint32_t timeout)
|
||||||
{
|
{
|
||||||
FAR struct sam34_lowerhalf_s *priv = (FAR struct sam34_lowerhalf_s *)lower;
|
FAR struct sam34_lowerhalf_s *priv = (FAR struct sam34_lowerhalf_s *)lower;
|
||||||
uint32_t reload;
|
|
||||||
|
|
||||||
DEBUGASSERT(priv);
|
DEBUGASSERT(priv);
|
||||||
tcvdbg("Entry: timeout=%d\n", timeout);
|
tcvdbg("Entry: timeout=%d\n", timeout);
|
||||||
@ -447,32 +476,13 @@ static int sam34_settimeout(FAR struct timer_lowerhalf_s *lower,
|
|||||||
return -ERANGE;
|
return -ERANGE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
priv->timeout = timeout; /* Intended timeout */
|
||||||
|
priv->clkticks = (((uint64_t)timeout * TC_FCLK) / 1000000); /* Actual clock ticks */
|
||||||
|
timeout = (1000000ULL * priv->clkticks) / TC_FCLK; /* Truncated timeout */
|
||||||
|
priv->adjustment = priv->timeout - timeout; /* Truncated time to be added to next interval (dither) */
|
||||||
|
|
||||||
/* TODOR: -1 or no? */
|
tcvdbg("fwdt=%d reload=%d timout=%d, adjustment=%d\n",
|
||||||
|
TC_FCLK, reload, priv->timeout, priv->adjustment);
|
||||||
reload = (((uint64_t)timeout * TC_FCLK) / 1000000) - 1;
|
|
||||||
|
|
||||||
/* Make sure that the final reload value is within range */
|
|
||||||
/* TODOR: +1 or no? */
|
|
||||||
|
|
||||||
if (reload > TC_CV_MASK)
|
|
||||||
{
|
|
||||||
reload = TC_CV_MASK;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Calculate and save the actual timeout value in milliseconds:
|
|
||||||
*
|
|
||||||
* timeout = 1000 * (reload + 1) / Fwdt
|
|
||||||
*/
|
|
||||||
|
|
||||||
priv->timeout = 1000 * (reload + 1) / TC_FCLK;
|
|
||||||
|
|
||||||
/* Remember the selected values */
|
|
||||||
|
|
||||||
priv->reload = reload;
|
|
||||||
|
|
||||||
tcvdbg("fwdt=%d reload=%d timout=%d\n",
|
|
||||||
TC_FCLK, reload, priv->timeout);
|
|
||||||
|
|
||||||
/* Don't commit to MR register until started! */
|
/* Don't commit to MR register until started! */
|
||||||
|
|
||||||
@ -501,53 +511,28 @@ static int sam34_settimeout(FAR struct timer_lowerhalf_s *lower,
|
|||||||
*
|
*
|
||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
|
|
||||||
static xcpt_t sam34_capture(FAR struct timer_lowerhalf_s *lower,
|
static tccb_t sam34_capture(FAR struct timer_lowerhalf_s *lower,
|
||||||
xcpt_t handler)
|
tccb_t handler)
|
||||||
{
|
{
|
||||||
#if 0 // TODO
|
|
||||||
FAR struct sam34_lowerhalf_s *priv = (FAR struct sam34_lowerhalf_s *)lower;
|
FAR struct sam34_lowerhalf_s *priv = (FAR struct sam34_lowerhalf_s *)lower;
|
||||||
irqstate_t flags;
|
irqstate_t flags;
|
||||||
xcpt_t oldhandler;
|
tccb_t oldhandler;
|
||||||
uint16_t regval;
|
|
||||||
|
flags = irqsave();
|
||||||
|
|
||||||
DEBUGASSERT(priv);
|
DEBUGASSERT(priv);
|
||||||
tcvdbg("Entry: handler=%p\n", handler);
|
tcvdbg("Entry: handler=%p\n", handler);
|
||||||
|
|
||||||
/* Get the old handler return value */
|
/* Get the old handler return value */
|
||||||
flags = irqsave();
|
|
||||||
oldhandler = priv->handler;
|
oldhandler = priv->handler;
|
||||||
|
|
||||||
/* Save the new handler */
|
/* Save the new handler */
|
||||||
|
|
||||||
priv->handler = handler;
|
priv->handler = handler;
|
||||||
|
|
||||||
/* Are we attaching or detaching the handler? */
|
|
||||||
|
|
||||||
regval = sam34_getreg(SAM_TC_CFR);
|
|
||||||
if (handler)
|
|
||||||
{
|
|
||||||
/* Attaching... Enable the EWI interrupt */
|
|
||||||
|
|
||||||
regval |= WWDG_CFR_EWI;
|
|
||||||
sam34_putreg(regval, SAM_TC_CFR);
|
|
||||||
|
|
||||||
up_enable_irq(STM32_IRQ_WWDG);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
/* Detaching... Disable the EWI interrupt */
|
|
||||||
|
|
||||||
regval &= ~WWDG_CFR_EWI;
|
|
||||||
sam34_putreg(regval, SAM_TC_CFR);
|
|
||||||
|
|
||||||
up_disable_irq(STM32_IRQ_WWDG);
|
|
||||||
}
|
|
||||||
|
|
||||||
irqrestore(flags);
|
irqrestore(flags);
|
||||||
return oldhandler;
|
return oldhandler;
|
||||||
#endif
|
|
||||||
ASSERT(0);
|
|
||||||
return NULL;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
@ -560,7 +545,7 @@ static xcpt_t sam34_capture(FAR struct timer_lowerhalf_s *lower,
|
|||||||
* Input Parameters:
|
* Input Parameters:
|
||||||
* lower - A pointer the publicly visible representation of the "lower-half"
|
* lower - A pointer the publicly visible representation of the "lower-half"
|
||||||
* driver state structure.
|
* driver state structure.
|
||||||
* cmd - The ioctol command value
|
* cmd - The ioctl command value
|
||||||
* arg - The optional argument that accompanies the 'cmd'. The
|
* arg - The optional argument that accompanies the 'cmd'. The
|
||||||
* interpretation of this argument depends on the particular
|
* interpretation of this argument depends on the particular
|
||||||
* command.
|
* command.
|
||||||
|
Loading…
Reference in New Issue
Block a user