aboutsummaryrefslogtreecommitdiffstats
path: root/os/hal/ports
diff options
context:
space:
mode:
authorisiora <none@example.com>2018-01-10 22:44:49 +0000
committerisiora <none@example.com>2018-01-10 22:44:49 +0000
commiteb94f80aa35fc9b316ddcc722249ba826c1dc349 (patch)
tree60eac7088de58ac3220b1628151d947b4907a056 /os/hal/ports
parent4fb646059d3ad81d462bba8becf025e1e44ca2de (diff)
downloadChibiOS-eb94f80aa35fc9b316ddcc722249ba826c1dc349.tar.gz
ChibiOS-eb94f80aa35fc9b316ddcc722249ba826c1dc349.tar.bz2
ChibiOS-eb94f80aa35fc9b316ddcc722249ba826c1dc349.zip
ST time source is now configurable between PIT, TC0 and TC1.
git-svn-id: svn://svn.code.sf.net/p/chibios/svn/trunk@11260 35acf78f-673a-0410-8e92-d51de3d6d3f4
Diffstat (limited to 'os/hal/ports')
-rw-r--r--os/hal/ports/SAMA/SAMA5D2x/hal_st_lld.c102
1 files changed, 102 insertions, 0 deletions
diff --git a/os/hal/ports/SAMA/SAMA5D2x/hal_st_lld.c b/os/hal/ports/SAMA/SAMA5D2x/hal_st_lld.c
index 21e7e8df2..981ebca11 100644
--- a/os/hal/ports/SAMA/SAMA5D2x/hal_st_lld.c
+++ b/os/hal/ports/SAMA/SAMA5D2x/hal_st_lld.c
@@ -33,6 +33,30 @@
*/
#define SAMA_PIT (SAMA_MCK / 16 / SAMA_H64MX_H32MX_RATIO)
+#if (SAMA_ST_USE_TC0 == TRUE) || (SAMA_ST_USE_TC1 == TRUE)
+/**
+ * @brief Enable write protection on TC registers block.
+ *
+ * @param[in] tc pointer to a TC
+ *
+ * @notapi
+ */
+#define tcEnableWP(tc) { \
+ tc->TC_WPMR = TC_WPMR_WPKEY_PASSWD | TC_WPMR_WPEN; \
+}
+
+/**
+ * @brief Disable write protection on TC registers block.
+ *
+ * @param[in] tc pointer to a TC
+ *
+ * @notapi
+ */
+#define tcDisableWP(tc) { \
+ tc->TC_WPMR = TC_WPMR_WPKEY_PASSWD; \
+}
+#endif
+
/*===========================================================================*/
/* Driver exported variables. */
/*===========================================================================*/
@@ -54,6 +78,38 @@
/*===========================================================================*/
#if (OSAL_ST_MODE == OSAL_ST_MODE_PERIODIC) || defined(__DOXYGEN__)
+
+#if (SAMA_ST_USE_TC0)
+OSAL_IRQ_HANDLER(SAMA_ST_TC0_HANDLER) {
+
+ OSAL_IRQ_PROLOGUE();
+ if (((TC0->TC_CHANNEL[0].TC_SR & TC_SR_CPCS) != 0) &&
+ ((TC0->TC_CHANNEL[0].TC_IMR & TC_IMR_CPCS) != 0)) {
+ osalSysLockFromISR();
+ osalOsTimerHandlerI();
+ osalSysUnlockFromISR();
+ }
+ aicAckInt();
+ OSAL_IRQ_EPILOGUE();
+}
+#endif
+
+#if (SAMA_ST_USE_TC1)
+OSAL_IRQ_HANDLER(SAMA_ST_TC1_HANDLER) {
+
+ OSAL_IRQ_PROLOGUE();
+ if (((TC1->TC_CHANNEL[0].TC_SR & TC_SR_CPCS) != 0) &&
+ ((TC1->TC_CHANNEL[0].TC_IMR & TC_IMR_CPCS) != 0)) {
+ osalSysLockFromISR();
+ osalOsTimerHandlerI();
+ osalSysUnlockFromISR();
+ }
+ aicAckInt();
+ OSAL_IRQ_EPILOGUE();
+}
+#endif
+
+#if (SAMA_ST_USE_PIT == TRUE)
/**
* @brief System Timer vector.
* @details This interrupt is used for system tick in periodic mode.
@@ -73,6 +129,8 @@ OSAL_IRQ_HANDLER(PIT_Handler) {
aicAckInt();
OSAL_IRQ_EPILOGUE();
}
+#endif /* SAMA_ST_USE_PIT == TRUE */
+
#endif /* OSAL_ST_MODE == OSAL_ST_MODE_PERIODIC */
/*===========================================================================*/
@@ -87,6 +145,48 @@ OSAL_IRQ_HANDLER(PIT_Handler) {
void st_lld_init(void) {
#if (OSAL_ST_MODE == OSAL_ST_MODE_PERIODIC)
+
+#if (SAMA_ST_USE_TC0 == TRUE)
+ pmcEnableTC0();
+ aicSetSourcePriority(ID_TC0, SAMA_TC0_IRQ_PRIORITY);
+ aicSetSourceHandler(ID_TC0, SAMA_ST_TC0_HANDLER);
+ aicEnableInt(ID_TC0);
+
+ tcDisableWP(TC0);
+ uint32_t rc = (SAMA_TC0CLK) / (OSAL_ST_FREQUENCY);
+ TC0->TC_CHANNEL[0].TC_EMR = TC_EMR_NODIVCLK;
+ TC0->TC_CHANNEL[0].TC_CMR = TC_CMR_WAVE | TC_CMR_ACPA_SET |
+ TC_CMR_ACPC_CLEAR | TC_CMR_WAVSEL_UP_RC;
+ TC0->TC_CHANNEL[0].TC_RC = TC_RC_RC(rc);
+ TC0->TC_CHANNEL[0].TC_RA = TC_RA_RA(rc);
+ TC0->TC_CHANNEL[0].TC_CCR = TC_CCR_CLKEN;
+ TC0->TC_CHANNEL[0].TC_CCR = TC_CCR_SWTRG;
+ TC0->TC_CHANNEL[0].TC_SR; /* Clear pending IRQs. */
+ TC0->TC_CHANNEL[0].TC_IER |= TC_IER_CPCS;
+ tcEnableWP(TC0);
+#endif /* SAMA_ST_USE_TC0 == TRUE */
+
+#if (SAMA_ST_USE_TC1 == TRUE)
+ pmcEnableTC1();
+ aicSetSourcePriority(ID_TC1, SAMA_TC1_IRQ_PRIORITY);
+ aicSetSourceHandler(ID_TC1, SAMA_ST_TC1_HANDLER);
+ aicEnableInt(ID_TC1);
+
+ tcDisableWP(TC1);
+ uint32_t rc = (SAMA_TC1CLK) / (OSAL_ST_FREQUENCY);
+ TC1->TC_CHANNEL[0].TC_EMR = TC_EMR_NODIVCLK;
+ TC1->TC_CHANNEL[0].TC_CMR = TC_CMR_WAVE | TC_CMR_ACPA_SET |
+ TC_CMR_ACPC_CLEAR | TC_CMR_WAVSEL_UP_RC;
+ TC1->TC_CHANNEL[0].TC_RC = TC_RC_RC(rc);
+ TC1->TC_CHANNEL[0].TC_RA = TC_RA_RA(rc);
+ TC1->TC_CHANNEL[0].TC_CCR = TC_CCR_CLKEN;
+ TC1->TC_CHANNEL[0].TC_CCR = TC_CCR_SWTRG;
+ TC1->TC_CHANNEL[0].TC_SR; /* Clear pending IRQs. */
+ TC1->TC_CHANNEL[0].TC_IER |= TC_IER_CPCS;
+ tcEnableWP(TC1);
+#endif /* SAMA_ST_USE_TC1 == TRUE */
+
+#if (SAMA_ST_USE_PIT == TRUE)
/* Enabling PIT.*/
pmcEnablePIT();
@@ -98,6 +198,8 @@ void st_lld_init(void) {
aicSetSourcePriority(ID_PIT, SAMA_ST_IRQ_PRIORITY);
aicSetSourceHandler(ID_PIT, PIT_Handler);
aicEnableInt(ID_PIT);
+#endif /* SAMA_ST_USE_PIT == TRUE */
+
#endif /* OSAL_ST_MODE == OSAL_ST_MODE_PERIODIC */
}