Correct time conversion, 1000000 not 1000 to convert seconds to microseconds.

This commit is contained in:
Gregory Nutt 2014-08-11 11:14:10 -06:00
parent 6e7cb4be58
commit 304b3b547c
4 changed files with 33 additions and 20 deletions

View File

@ -56,6 +56,7 @@
#include <errno.h>
#include <arch/irq.h>
#include <nuttx/clock.h>
#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;

View File

@ -56,6 +56,7 @@
#include <errno.h>
#include <arch/irq.h>
#include <nuttx/clock.h>
#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;

View File

@ -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);

View File

@ -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