SAMA5 oneshot: Some clean-up and correction to the initial implementation

This commit is contained in:
Gregory Nutt
2014-08-09 16:42:04 -06:00
parent 84b86e32be
commit acb05460d0
4 changed files with 64 additions and 57 deletions
+16 -8
View File
@@ -52,14 +52,11 @@
#include <sys/types.h> #include <sys/types.h>
#include <stdint.h> #include <stdint.h>
#include <stdbool.h> #include <stdbool.h>
#include <string.h>
#include <semaphore.h>
#include <assert.h> #include <assert.h>
#include <errno.h> #include <errno.h>
#include <debug.h> #include <debug.h>
#include <nuttx/arch.h> #include <arch/irq.h>
#include <arch/board/board.h>
#include "sam_oneshot.h" #include "sam_oneshot.h"
@@ -176,8 +173,9 @@ int sam_oneshot_initialize(struct sam_oneshot_s *oneshot, int chan,
return ret; return ret;
} }
tcvdbg("frequency=%lu, divisor=%u, cmr=%08lx\n", tcvdbg("frequency=%lu, divisor=%lu, cmr=%08lx\n",
(unsigned long)frequency, oneshot->divisor, (unsigned long)cmr); (unsigned long)frequency, (unsigned long)oneshot->divisor,
(unsigned long)cmr);
/* Allocate the timer/counter and select its mode of operation /* Allocate the timer/counter and select its mode of operation
* *
@@ -290,6 +288,10 @@ int sam_oneshot_start(struct sam_oneshot_s *oneshot, oneshot_handler_t handler,
sam_tc_setregister(oneshot->handle, TC_REGC, regval); sam_tc_setregister(oneshot->handle, TC_REGC, regval);
/* Start the counter */
sam_tc_start(oneshot->handle);
/* Enable interrupts. We should get the callback when the interrupt /* Enable interrupts. We should get the callback when the interrupt
* occurs. * occurs.
*/ */
@@ -337,8 +339,14 @@ int sam_oneshot_cancel(struct sam_oneshot_s *oneshot, struct timespec *ts)
count = sam_tc_getcounter(oneshot->handle); count = sam_tc_getcounter(oneshot->handle);
rc = sam_tc_getregister(oneshot->handle, TC_REGC); rc = sam_tc_getregister(oneshot->handle, TC_REGC);
/* Now we can disable the interrupt and stop the clock */ /* Now we can disable the interrupt and stop the timer.
*
* REVISIT: The assertion is there because I do no not know if the
* counter will be reset when the RC match occurs. The counter
* clock will be disabled, so I am hoping not.
*/
DEBUGASSERT(count > 0 || (sam_tc_getpending(oneshot->handle) & TC_INT_CPCS) == 0);
sam_tc_attach(oneshot->handle, NULL, NULL, 0); sam_tc_attach(oneshot->handle, NULL, NULL, 0);
sam_tc_stop(oneshot->handle); sam_tc_stop(oneshot->handle);
@@ -358,7 +366,7 @@ int sam_oneshot_cancel(struct sam_oneshot_s *oneshot, struct timespec *ts)
sec = usec / 1000000; sec = usec / 1000000;
ts->tv_sec = sec; ts->tv_sec = sec;
ts->tv_nsec = ((usec) - (sec * 1000000)) / 1000; ts->tv_nsec = ((usec) - (sec * 1000000)) * 1000;
tcvdbg("remaining (%lu, %lu)\n", tcvdbg("remaining (%lu, %lu)\n",
(unsigned long)ts->tv_sec, (unsigned long)ts->tv_nsec); (unsigned long)ts->tv_sec, (unsigned long)ts->tv_nsec);
+1 -2
View File
@@ -119,7 +119,7 @@ extern "C"
* *
****************************************************************************/ ****************************************************************************/
int sam_oneshot_initialize(struct sam_oneshot_s *oneshot, int tc, int sam_oneshot_initialize(struct sam_oneshot_s *oneshot, int chan,
uint16_t resolution); uint16_t resolution);
/**************************************************************************** /****************************************************************************
@@ -173,4 +173,3 @@ int sam_oneshot_cancel(struct sam_oneshot_s *oneshot, struct timespec *ts);
#endif /* CONFIG_SAMA5_ONESHOT */ #endif /* CONFIG_SAMA5_ONESHOT */
#endif /* __ARCH_ARM_SRC_SAMA5_SAM_ONESHOT_H */ #endif /* __ARCH_ARM_SRC_SAMA5_SAM_ONESHOT_H */
+27 -27
View File
@@ -1204,6 +1204,30 @@ void sam_tc_start(TC_HANDLE handle)
sam_regdump(chan, "Started"); sam_regdump(chan, "Started");
} }
/****************************************************************************
* Name: sam_tc_stop
*
* Description:
* Stop TC Channel. Disables the timer clock, stopping the counting.
*
* Input Parameters:
* handle Channel handle previously allocated by sam_tc_allocate()
*
* Returned Value:
*
****************************************************************************/
void sam_tc_stop(TC_HANDLE handle)
{
struct sam_chan_s *chan = (struct sam_chan_s *)handle;
tcvdbg("Stopping channel %d inuse=%d\n", chan->chan, chan->inuse);
DEBUGASSERT(chan && chan->inuse);
sam_chan_putreg(chan, SAM_TC_CCR_OFFSET, TC_CCR_CLKDIS);
sam_regdump(chan, "Stopped");
}
/**************************************************************************** /****************************************************************************
* Name: sam_tc_attach * Name: sam_tc_attach
* *
@@ -1259,10 +1283,10 @@ tc_handler_t sam_tc_attach(TC_HANDLE handle, tc_handler_t handler,
} }
/**************************************************************************** /****************************************************************************
* Name: sam_tc_pending * Name: sam_tc_getpending
* *
* Description: * Description:
* Return the current contents of the interrutp status register, clearing * Return the current contents of the interrupt status register, clearing
* all pending interrupts. * all pending interrupts.
* *
* Input Parameters: * Input Parameters:
@@ -1273,37 +1297,13 @@ tc_handler_t sam_tc_attach(TC_HANDLE handle, tc_handler_t handler,
* *
****************************************************************************/ ****************************************************************************/
uint32_t sam_tc_pending(TC_HANDLE handle) uint32_t sam_tc_getpending(TC_HANDLE handle)
{ {
struct sam_chan_s *chan = (struct sam_chan_s *)handle; struct sam_chan_s *chan = (struct sam_chan_s *)handle;
DEBUGASSERT(chan); DEBUGASSERT(chan);
return sam_chan_getreg(chan, SAM_TC_SR_OFFSET); return sam_chan_getreg(chan, SAM_TC_SR_OFFSET);
} }
/****************************************************************************
* Name: sam_tc_stop
*
* Description:
* Stop TC Channel. Disables the timer clock, stopping the counting.
*
* Input Parameters:
* handle Channel handle previously allocated by sam_tc_allocate()
*
* Returned Value:
*
****************************************************************************/
void sam_tc_stop(TC_HANDLE handle)
{
struct sam_chan_s *chan = (struct sam_chan_s *)handle;
tcvdbg("Stopping channel %d inuse=%d\n", chan->chan, chan->inuse);
DEBUGASSERT(chan && chan->inuse);
sam_chan_putreg(chan, SAM_TC_CCR_OFFSET, TC_CCR_CLKDIS);
sam_regdump(chan, "Stopped");
}
/**************************************************************************** /****************************************************************************
* Name: sam_tc_setregister * Name: sam_tc_setregister
* *
+17 -17
View File
@@ -159,6 +159,21 @@ void sam_tc_free(TC_HANDLE handle);
void sam_tc_start(TC_HANDLE handle); void sam_tc_start(TC_HANDLE handle);
/****************************************************************************
* Name: sam_tc_stop
*
* Description:
* Stop TC Channel. Disables the timer clock, stopping the counting.
*
* Input Parameters:
* handle Channel handle previously allocated by sam_tc_allocate()
*
* Returned Value:
*
****************************************************************************/
void sam_tc_stop(TC_HANDLE handle);
/**************************************************************************** /****************************************************************************
* Name: sam_tc_attach/sam_tc_detach * Name: sam_tc_attach/sam_tc_detach
* *
@@ -187,7 +202,7 @@ tc_handler_t sam_tc_attach(TC_HANDLE handle, tc_handler_t handler,
#define sam_tc_detach(h) sam_tc_attach(h, NULL, NULL, 0) #define sam_tc_detach(h) sam_tc_attach(h, NULL, NULL, 0)
/**************************************************************************** /****************************************************************************
* Name: sam_tc_pending * Name: sam_tc_getpending
* *
* Description: * Description:
* Return the current contents of the interrutp status register, clearing * Return the current contents of the interrutp status register, clearing
@@ -201,22 +216,7 @@ tc_handler_t sam_tc_attach(TC_HANDLE handle, tc_handler_t handler,
* *
****************************************************************************/ ****************************************************************************/
uint32_t sam_tc_pending(TC_HANDLE handle); uint32_t sam_tc_getpending(TC_HANDLE handle);
/****************************************************************************
* Name: sam_tc_stop
*
* Description:
* Stop TC Channel. Disables the timer clock, stopping the counting.
*
* Input Parameters:
* handle Channel handle previously allocated by sam_tc_allocate()
*
* Returned Value:
*
****************************************************************************/
void sam_tc_stop(TC_HANDLE handle);
/**************************************************************************** /****************************************************************************
* Name: sam_tc_setregister * Name: sam_tc_setregister