mirror of
https://github.com/apache/nuttx.git
synced 2026-05-31 23:40:19 +08:00
SAMA5 oneshot: Some clean-up and correction to the initial implementation
This commit is contained in:
@@ -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
|
||||||
*
|
*
|
||||||
@@ -190,7 +188,7 @@ int sam_oneshot_initialize(struct sam_oneshot_s *oneshot, int chan,
|
|||||||
* TC_CMR_EEVT_TIOB - ???? REVISIT
|
* TC_CMR_EEVT_TIOB - ???? REVISIT
|
||||||
* TC_CMR_ENET=0 - External event trigger disabled
|
* TC_CMR_ENET=0 - External event trigger disabled
|
||||||
* TC_CMR_WAVSEL_UPRC - TC_CV is incremented from 0 to the value of RC,
|
* 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_WAVE - Waveform mode
|
||||||
* TC_CMR_ACPA_NONE - RA compare has no effect on TIOA
|
* TC_CMR_ACPA_NONE - RA compare has no effect on TIOA
|
||||||
* TC_CMR_ACPC_NONE - RC compare has no effect on TIOA
|
* TC_CMR_ACPC_NONE - RC compare has no effect on TIOA
|
||||||
@@ -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);
|
||||||
|
|||||||
@@ -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
@@ -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
@@ -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
|
||||||
|
|||||||
Reference in New Issue
Block a user