SAMA5 oneshot: Some clean-up and correction to the initial implementation
This commit is contained in:
parent
84b86e32be
commit
acb05460d0
@ -52,14 +52,11 @@
|
||||
#include <sys/types.h>
|
||||
#include <stdint.h>
|
||||
#include <stdbool.h>
|
||||
#include <string.h>
|
||||
#include <semaphore.h>
|
||||
#include <assert.h>
|
||||
#include <errno.h>
|
||||
#include <debug.h>
|
||||
|
||||
#include <nuttx/arch.h>
|
||||
#include <arch/board/board.h>
|
||||
#include <arch/irq.h>
|
||||
|
||||
#include "sam_oneshot.h"
|
||||
|
||||
@ -176,8 +173,9 @@ int sam_oneshot_initialize(struct sam_oneshot_s *oneshot, int chan,
|
||||
return ret;
|
||||
}
|
||||
|
||||
tcvdbg("frequency=%lu, divisor=%u, cmr=%08lx\n",
|
||||
(unsigned long)frequency, oneshot->divisor, (unsigned long)cmr);
|
||||
tcvdbg("frequency=%lu, divisor=%lu, cmr=%08lx\n",
|
||||
(unsigned long)frequency, (unsigned long)oneshot->divisor,
|
||||
(unsigned long)cmr);
|
||||
|
||||
/* Allocate the timer/counter and select its mode of operation
|
||||
*
|
||||
@ -190,7 +188,7 @@ int sam_oneshot_initialize(struct sam_oneshot_s *oneshot, int chan,
|
||||
* TC_CMR_EEVT_TIOB - ???? REVISIT
|
||||
* TC_CMR_ENET=0 - External event trigger disabled
|
||||
* TC_CMR_WAVSEL_UPRC - TC_CV is incremented from 0 to the value of RC,
|
||||
* then automatically reset on a RC Compare
|
||||
* then automatically reset on a RC Compare
|
||||
* TC_CMR_WAVE - Waveform mode
|
||||
* TC_CMR_ACPA_NONE - RA compare has no effect on TIOA
|
||||
* TC_CMR_ACPC_NONE - RC compare has no effect on TIOA
|
||||
@ -254,7 +252,7 @@ int sam_oneshot_start(struct sam_oneshot_s *oneshot, oneshot_handler_t handler,
|
||||
uint64_t regval;
|
||||
irqstate_t flags;
|
||||
|
||||
tcvdbg("handler=%p arg=%p, ts=(%lu, %lu)\n",
|
||||
tcvdbg("handler=%p arg=%p, ts=(%lu, %lu)\n",
|
||||
handler, arg, (unsigned long)ts->tv_sec, (unsigned long)ts->tv_nsec);
|
||||
DEBUGASSERT(oneshot && handler && ts);
|
||||
|
||||
@ -278,7 +276,7 @@ int sam_oneshot_start(struct sam_oneshot_s *oneshot, oneshot_handler_t handler,
|
||||
|
||||
tcdbg("usec=%llu regval=%08llx\n", usec, regval);
|
||||
DEBUGASSERT(regval <= UINT32_MAX);
|
||||
|
||||
|
||||
/* Set up to receive the callback when the interrupt occurs */
|
||||
|
||||
(void)sam_tc_attach(oneshot->handle, sam_oneshot_handler, oneshot,
|
||||
@ -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);
|
||||
|
||||
/* Start the counter */
|
||||
|
||||
sam_tc_start(oneshot->handle);
|
||||
|
||||
/* Enable interrupts. We should get the callback when the interrupt
|
||||
* occurs.
|
||||
*/
|
||||
@ -337,8 +339,14 @@ int sam_oneshot_cancel(struct sam_oneshot_s *oneshot, struct timespec *ts)
|
||||
count = sam_tc_getcounter(oneshot->handle);
|
||||
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_stop(oneshot->handle);
|
||||
|
||||
@ -358,7 +366,7 @@ int sam_oneshot_cancel(struct sam_oneshot_s *oneshot, struct timespec *ts)
|
||||
|
||||
sec = usec / 1000000;
|
||||
ts->tv_sec = sec;
|
||||
ts->tv_nsec = ((usec) - (sec * 1000000)) / 1000;
|
||||
ts->tv_nsec = ((usec) - (sec * 1000000)) * 1000;
|
||||
|
||||
tcvdbg("remaining (%lu, %lu)\n",
|
||||
(unsigned long)ts->tv_sec, (unsigned long)ts->tv_nsec);
|
||||
|
@ -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);
|
||||
|
||||
/****************************************************************************
|
||||
@ -173,4 +173,3 @@ int sam_oneshot_cancel(struct sam_oneshot_s *oneshot, struct timespec *ts);
|
||||
|
||||
#endif /* CONFIG_SAMA5_ONESHOT */
|
||||
#endif /* __ARCH_ARM_SRC_SAMA5_SAM_ONESHOT_H */
|
||||
|
||||
|
@ -1204,6 +1204,30 @@ void sam_tc_start(TC_HANDLE handle)
|
||||
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
|
||||
*
|
||||
@ -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:
|
||||
* Return the current contents of the interrutp status register, clearing
|
||||
* Return the current contents of the interrupt status register, clearing
|
||||
* all pending interrupts.
|
||||
*
|
||||
* 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;
|
||||
DEBUGASSERT(chan);
|
||||
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
|
||||
*
|
||||
|
@ -159,6 +159,21 @@ void sam_tc_free(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
|
||||
*
|
||||
@ -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)
|
||||
|
||||
/****************************************************************************
|
||||
* Name: sam_tc_pending
|
||||
* Name: sam_tc_getpending
|
||||
*
|
||||
* Description:
|
||||
* 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);
|
||||
|
||||
/****************************************************************************
|
||||
* 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);
|
||||
uint32_t sam_tc_getpending(TC_HANDLE handle);
|
||||
|
||||
/****************************************************************************
|
||||
* Name: sam_tc_setregister
|
||||
|
Loading…
Reference in New Issue
Block a user