From 734bd055a1fd06fbf2e6645e2ce2c8f0cd82e71b Mon Sep 17 00:00:00 2001 From: Gregory Nutt Date: Mon, 11 Aug 2014 11:14:10 -0600 Subject: Correct time conversion, 1000000 not 1000 to convert seconds to microseconds. --- nuttx/arch/arm/src/sama5/sam_freerun.c | 13 +++++++------ nuttx/arch/arm/src/sama5/sam_oneshot.c | 22 +++++++++++----------- nuttx/arch/arm/src/sama5/sam_tc.c | 15 ++++++++++++++- nuttx/arch/arm/src/sama5/sam_tc.h | 3 +-- 4 files changed, 33 insertions(+), 20 deletions(-) diff --git a/nuttx/arch/arm/src/sama5/sam_freerun.c b/nuttx/arch/arm/src/sama5/sam_freerun.c index 94cd7cb9d..b3c4c323c 100644 --- a/nuttx/arch/arm/src/sama5/sam_freerun.c +++ b/nuttx/arch/arm/src/sama5/sam_freerun.c @@ -56,6 +56,7 @@ #include #include +#include #include "sam_freerun.h" @@ -142,7 +143,7 @@ int sam_freerun_initialize(struct sam_freerun_s *freerun, int chan, /* Get the TC frequency the corresponds to the requested resolution */ - frequency = 1000000 / (uint32_t)resolution; + frequency = USEC_PER_SEC / (uint32_t)resolution; /* The pre-calculate values to use when we start the timer */ @@ -276,19 +277,19 @@ int sam_freerun_counter(struct sam_freerun_s *freerun, struct timespec *ts) * * frequency = ticks / second * seconds = ticks * frequency - * usecs = (ticks * 1000) / frequency; + * usecs = (ticks * USEC_PER_SEC) / frequency; */ - usec = ((((uint64_t)overflow << 32) + (uint64_t)counter) * 1000) / + usec = ((((uint64_t)overflow << 32) + (uint64_t)counter) * USEC_PER_SEC) / sam_tc_divfreq(freerun->tch); /* And return the value of the timer */ - sec = (uint32_t)(usec / 1000000); + sec = (uint32_t)(usec / USEC_PER_SEC); ts->tv_sec = sec; - ts->tv_nsec = (usec - (sec * 1000000)) * 1000; + ts->tv_nsec = (usec - (sec * USEC_PER_SEC)) * NSEC_PER_USEC; - tcvdbg("usec=%016llx ts=(%lu, %lu)\n", + tcvdbg("usec=%llu ts=(%lu, %lu)\n", usec, (unsigned long)ts->tv_sec, (unsigned long)ts->tv_nsec); return OK; diff --git a/nuttx/arch/arm/src/sama5/sam_oneshot.c b/nuttx/arch/arm/src/sama5/sam_oneshot.c index 0ff07054f..af31dec00 100644 --- a/nuttx/arch/arm/src/sama5/sam_oneshot.c +++ b/nuttx/arch/arm/src/sama5/sam_oneshot.c @@ -56,6 +56,7 @@ #include #include +#include #include "sam_oneshot.h" @@ -167,7 +168,7 @@ int sam_oneshot_initialize(struct sam_oneshot_s *oneshot, int chan, /* Get the TC frequency the corresponds to the requested resolution */ - frequency = 1000000 / (uint32_t)resolution; + frequency = USEC_PER_SEC / (uint32_t)resolution; /* The pre-calculate values to use when we start the timer */ @@ -278,16 +279,16 @@ int sam_oneshot_start(struct sam_oneshot_s *oneshot, oneshot_handler_t handler, /* Express the delay in microseconds */ - usec = (uint64_t)ts->tv_sec * 1000000 + (uint64_t)(ts->tv_nsec / 1000); + usec = (uint64_t)ts->tv_sec * USEC_PER_SEC + (uint64_t)(ts->tv_nsec / NSEC_PER_USEC); /* Get the timer counter frequency and determine the number of counts need to achieve the requested delay. * * frequency = ticks / second * ticks = seconds * frequency - * = (usecs * frequency) / 1000000; + * = (usecs * frequency) / USEC_PER_SEC; */ - regval = (usec * (uint64_t)sam_tc_divfreq(oneshot->tch)) / 1000000; + regval = (usec * (uint64_t)sam_tc_divfreq(oneshot->tch)) / USEC_PER_SEC; tcvdbg("usec=%lu regval=%08lx\n", (unsigned long)usec, (unsigned long)regval); @@ -403,9 +404,8 @@ int sam_oneshot_cancel(struct sam_oneshot_s *oneshot, struct timespec *ts) * oneshot timer. */ - tcvdbg("rc=%lu count=%lu resolution=%u usec=%lu\n", - (unsigned long)rc, (unsigned long)count, oneshot->resolution, - (unsigned long)usec); + tcvdbg("rc=%lu count=%lu usec=%lu\n", + (unsigned long)rc, (unsigned long)count, (unsigned long)usec); /* REVISIT: I am not certain why the timer counter value sometimes * exceeds RC. Might be a bug, or perhaps the counter does not stop @@ -426,16 +426,16 @@ int sam_oneshot_cancel(struct sam_oneshot_s *oneshot, struct timespec *ts) * * frequency = ticks / second * seconds = ticks * frequency - * usecs = (ticks * 1000) / frequency; + * usecs = (ticks * USEC_PER_SEC) / frequency; */ - usec = (((uint64_t)(rc - count)) * 1000) / + usec = (((uint64_t)(rc - count)) * USEC_PER_SEC) / sam_tc_divfreq(oneshot->tch); /* Return the time remaining in the correct form */ - sec = usec / 1000000; - nsec = ((usec) - (sec * 1000000)) * 1000; + sec = usec / USEC_PER_SEC; + nsec = ((usec) - (sec * USEC_PER_SEC)) * NSEC_PER_USEC; ts->tv_sec = (time_t)sec; ts->tv_nsec = (unsigned long)nsec; diff --git a/nuttx/arch/arm/src/sama5/sam_tc.c b/nuttx/arch/arm/src/sama5/sam_tc.c index 2e0c85f08..dd80c38f1 100644 --- a/nuttx/arch/arm/src/sama5/sam_tc.c +++ b/nuttx/arch/arm/src/sama5/sam_tc.c @@ -843,6 +843,11 @@ static int sam_tc_freqdiv_lookup(uint32_t ftcin, int ndx) if (ndx >= TC_NDIVIDERS) { + /* Not really a divider. In this case, the board is actually driven + * by the 32.768KHz slow clock. This returns a value that looks like + * correct divider if MCK were the input. + */ + return ftcin / BOARD_SLOWCLK_FREQUENCY; } else @@ -1180,6 +1185,14 @@ void sam_tc_start(TC_HANDLE handle) tcvdbg("Starting channel %d inuse=%d\n", chan->chan, chan->inuse); DEBUGASSERT(chan && chan->inuse); + /* Read the SR to clear any pending interrupts on this channel */ + + (void)sam_chan_getreg(chan, SAM_TC_SR_OFFSET); + + /* Then enable the timer (by setting the CLKEN bit). Setting SWTRIG + * will also reset the timer counter and starting the timer. + */ + sam_chan_putreg(chan, SAM_TC_CCR_OFFSET, TC_CCR_CLKEN | TC_CCR_SWTRG); sam_regdump(chan, "Started"); } @@ -1308,7 +1321,7 @@ void sam_tc_setregister(TC_HANDLE handle, int regid, uint32_t regval) DEBUGASSERT(chan && regid < TC_NREGISTERS); - tcvdbg("Channel %d: Set register RC%d to 0x08lx\n", + tcvdbg("Channel %d: Set register RC%d to %08lx\n", chan->chan, regid, (unsigned long)regval); sam_chan_putreg(chan, g_regoffset[regid], regval); diff --git a/nuttx/arch/arm/src/sama5/sam_tc.h b/nuttx/arch/arm/src/sama5/sam_tc.h index 46681ce32..311f6d329 100644 --- a/nuttx/arch/arm/src/sama5/sam_tc.h +++ b/nuttx/arch/arm/src/sama5/sam_tc.h @@ -79,8 +79,7 @@ # undef CONFIG_SAMA5_TC_REGDEBUG #endif -#undef CONFIG_SAMA5_TC_DEBUG -#if defined(CONFIG_SAMA5_ADC) && defined(CONFIG_DEBUG_ANALOG) +#if !defined(CONFIG_SAMA5_TC_DEBUG) && defined(CONFIG_SAMA5_ADC) && defined(CONFIG_DEBUG_ANALOG) # define CONFIG_SAMA5_TC_DEBUG 1 #endif -- cgit v1.2.3