aboutsummaryrefslogtreecommitdiffstats
path: root/os/hal/ports/SAMA
diff options
context:
space:
mode:
authorGiovanni Di Sirio <gdisirio@gmail.com>2018-02-26 09:29:02 +0000
committerGiovanni Di Sirio <gdisirio@gmail.com>2018-02-26 09:29:02 +0000
commit50439eed0df5c61ecb70483ad7d999f0038f1b3d (patch)
tree017bb6e6d51502856b80d3c16e6ffb1a44548580 /os/hal/ports/SAMA
parent4a03cef983fcf64c8b6fbdc888dfe4b05915425e (diff)
downloadChibiOS-50439eed0df5c61ecb70483ad7d999f0038f1b3d.tar.gz
ChibiOS-50439eed0df5c61ecb70483ad7d999f0038f1b3d.tar.bz2
ChibiOS-50439eed0df5c61ecb70483ad7d999f0038f1b3d.zip
Added back missing revisions in trunk.
git-svn-id: https://svn.code.sf.net/p/chibios/svn2/trunk@11544 110e8d01-0319-4d1e-a829-52ad28d1bb01
Diffstat (limited to 'os/hal/ports/SAMA')
-rw-r--r--os/hal/ports/SAMA/SAMA5D2x/hal_st_lld.c151
-rw-r--r--os/hal/ports/SAMA/SAMA5D2x/hal_st_lld.h97
2 files changed, 182 insertions, 66 deletions
diff --git a/os/hal/ports/SAMA/SAMA5D2x/hal_st_lld.c b/os/hal/ports/SAMA/SAMA5D2x/hal_st_lld.c
index 8d286884e..83bf6e52e 100644
--- a/os/hal/ports/SAMA/SAMA5D2x/hal_st_lld.c
+++ b/os/hal/ports/SAMA/SAMA5D2x/hal_st_lld.c
@@ -31,7 +31,7 @@
/**
* @brief Periodic Interrupt Timer frequency.
*/
-#define SAMA_PIT (SAMA_MCK / 16 / SAMA_H64MX_H32MX_RATIO)
+#define SAMA_PIT (SAMA_MCK / 16 / SAMA_H64MX_H32MX_RATIO)
#if (SAMA_ST_USE_TC0 == TRUE) || (SAMA_ST_USE_TC1 == TRUE)
/**
@@ -57,6 +57,26 @@
}
#endif
+#if OSAL_ST_MODE == OSAL_ST_MODE_FREERUNNING
+
+#if SAMA_ST_USE_PIT
+#error "PIT timer doesn't support tick-less mode"
+#endif
+
+#if SAMA_ST_USE_TC0
+#if ((SAMA_TC0CLK) / (OSAL_ST_FREQUENCY) != 32)
+#error "Bad OSAL_ST_FREQUENCY value in configuration. It must be set to TC0_periph_clk / 32"
+#endif
+#endif
+
+#if SAMA_ST_USE_TC1
+#if ((SAMA_TC1CLK) / (OSAL_ST_FREQUENCY) != 32)
+#error "Bad OSAL_ST_FREQUENCY value in configuration. It must be set to TC1_periph_clk / 32"
+#endif
+#endif
+
+#endif
+
/*===========================================================================*/
/* Driver exported variables. */
/*===========================================================================*/
@@ -69,6 +89,10 @@
/* Driver local variables and types. */
/*===========================================================================*/
+#if SAMA_ST_USE_TC0 || SAMA_ST_USE_TC1
+static Tc *tcp;
+#endif
+
/*===========================================================================*/
/* Driver local functions. */
/*===========================================================================*/
@@ -77,39 +101,27 @@
/* Driver interrupt handlers. */
/*===========================================================================*/
-#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) {
+#if (SAMA_ST_USE_TC0 || SAMA_ST_USE_TC1) || defined(__DOXYGEN__)
+/**
+ * @brief System Timer vector.
+ * @details This interrupt is used for system tick in periodic or free running
+ * mode, generated by TCx timer
+ *
+ * @isr
+ */
+OSAL_IRQ_HANDLER(SAMA_ST_TC_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();
- }
+ (void)tcp->TC_CHANNEL[0].TC_SR; /* acknowledge TC interrupt */
+ osalSysLockFromISR();
+ osalOsTimerHandlerI();
+ osalSysUnlockFromISR();
aicAckInt();
OSAL_IRQ_EPILOGUE();
}
#endif
-#if (SAMA_ST_USE_PIT == TRUE)
+#if (SAMA_ST_USE_PIT) || defined(__DOXYGEN__)
/**
* @brief System Timer vector.
* @details This interrupt is used for system tick in periodic mode.
@@ -131,8 +143,6 @@ OSAL_IRQ_HANDLER(PIT_Handler) {
}
#endif /* SAMA_ST_USE_PIT == TRUE */
-#endif /* OSAL_ST_MODE == OSAL_ST_MODE_PERIODIC */
-
/*===========================================================================*/
/* Driver exported functions. */
/*===========================================================================*/
@@ -144,72 +154,81 @@ OSAL_IRQ_HANDLER(PIT_Handler) {
*/
void st_lld_init(void) {
-#if (OSAL_ST_MODE == OSAL_ST_MODE_PERIODIC)
+#if SAMA_ST_USE_TC0 || SAMA_ST_USE_TC1
+
+#if SAMA_ST_USE_TC0
+ tcp = TC0;
+ uint32_t rc = (SAMA_TC0CLK) / (OSAL_ST_FREQUENCY);
-#if (SAMA_ST_USE_TC0 == TRUE)
#if SAMA_HAL_IS_SECURE
mtxConfigPeriphSecurity(MATRIX1, ID_TC0, SECURE_PER);
#endif /* SAMA_HAL_IS_SECURE */
+
pmcEnableTC0();
aicSetSourcePriority(ID_TC0, SAMA_TC0_IRQ_PRIORITY);
- aicSetSourceHandler(ID_TC0, SAMA_ST_TC0_HANDLER);
+ aicSetSourceHandler(ID_TC0, SAMA_ST_TC_HANDLER);
aicEnableInt(ID_TC0);
+#endif
+
+#if SAMA_ST_USE_TC1
+ tcp = TC1;
+ uint32_t rc = (SAMA_TC1CLK) / (OSAL_ST_FREQUENCY);
- 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)
#if SAMA_HAL_IS_SECURE
mtxConfigPeriphSecurity(MATRIX1, ID_TC1, SECURE_PER);
#endif /* SAMA_HAL_IS_SECURE */
+
pmcEnableTC1();
aicSetSourcePriority(ID_TC1, SAMA_TC1_IRQ_PRIORITY);
- aicSetSourceHandler(ID_TC1, SAMA_ST_TC1_HANDLER);
+ aicSetSourceHandler(ID_TC1, SAMA_ST_TC_HANDLER);
aicEnableInt(ID_TC1);
+#endif
- 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 */
+ tcDisableWP(tcp);
+
+#if OSAL_ST_MODE == OSAL_ST_MODE_FREERUNNING
+
+ /* Initializing the timer counter in free running mode.
+ * The clock source is the bus clock divided by 32.*/
+ (void)rc;
+ tcp->TC_CHANNEL[0].TC_EMR = 0;
+ tcp->TC_CHANNEL[0].TC_CMR = TC_CMR_WAVE | TC_CMR_WAVSEL_UP |
+ TC_CMR_TCCLKS(TC_CMR_TCCLKS_TIMER_CLOCK3);
+ tcp->TC_CHANNEL[0].TC_RC = 0;
+ tcp->TC_CHANNEL[0].TC_CCR = TC_CCR_CLKEN | TC_CCR_SWTRG;
+ tcp->TC_CHANNEL[0].TC_IDR = 0xFFFFFFFF; /* Disable IRQs. */
+ tcp->TC_CHANNEL[0].TC_SR; /* Clear pending IRQs. */
+#endif
+
+#if OSAL_ST_MODE == OSAL_ST_MODE_PERIODIC
+ tcp->TC_CHANNEL[0].TC_EMR = TC_EMR_NODIVCLK;
+ tcp->TC_CHANNEL[0].TC_CMR = TC_CMR_WAVE | TC_CMR_WAVSEL_UP_RC;
+ tcp->TC_CHANNEL[0].TC_RC = TC_RC_RC(rc);
+ tcp->TC_CHANNEL[0].TC_CCR = TC_CCR_CLKEN | TC_CCR_SWTRG;;
+ tcp->TC_CHANNEL[0].TC_SR; /* Clear pending IRQs. */
+ tcp->TC_CHANNEL[0].TC_IER = TC_IER_CPCS;
+#endif
+
+ tcEnableWP(tcp);
+#endif /* SAMA_ST_USE_TC0 || SAMA_ST_USE_TC1 */
#if (SAMA_ST_USE_PIT == TRUE)
#if SAMA_HAL_IS_SECURE
mtxConfigPeriphSecurity(MATRIX1, ID_PIT, SECURE_PER);
#endif /* SAMA_HAL_IS_SECURE */
- /* Enabling PIT.*/
- pmcEnablePIT();
+ /* Enable PIT.*/
+ pmcEnablePIT();
PIT->PIT_MR = PIT_MR_PIV((SAMA_PIT / OSAL_ST_FREQUENCY) - 1);
PIT->PIT_MR |= PIT_MR_PITEN | PIT_MR_PITIEN;
(void) PIT->PIT_PIVR; /* reset PIT PICNT counter */
- /* IRQ enabled.*/
+ /* Enable IRQ.*/
aicSetSourcePriority(ID_PIT, SAMA_ST_IRQ_PRIORITY);
aicSetSourceHandler(ID_PIT, PIT_Handler);
aicEnableInt(ID_PIT);
-#endif /* SAMA_ST_USE_PIT == TRUE */
+#endif /* SAMA_ST_USE_PIT */
-#endif /* OSAL_ST_MODE == OSAL_ST_MODE_PERIODIC */
}
/** @} */
diff --git a/os/hal/ports/SAMA/SAMA5D2x/hal_st_lld.h b/os/hal/ports/SAMA/SAMA5D2x/hal_st_lld.h
index bce654bc9..3325d4ac8 100644
--- a/os/hal/ports/SAMA/SAMA5D2x/hal_st_lld.h
+++ b/os/hal/ports/SAMA/SAMA5D2x/hal_st_lld.h
@@ -95,6 +95,7 @@
#define SAMA_TC1_IS_USED
#endif
#endif
+
/*===========================================================================*/
/* Driver data structures and types. */
/*===========================================================================*/
@@ -128,7 +129,22 @@ extern "C" {
*/
static inline systime_t st_lld_get_counter(void) {
+#if (SAMA_ST_USE_TC0 || SAMA_ST_USE_TC1)
+
+#if SAMA_ST_USE_TC0
+
+ Tc *tcp = TC0;
+#endif
+#if SAMA_ST_USE_TC1
+
+ Tc *tcp = TC1;
+#endif
+
+ return (systime_t)tcp->TC_CHANNEL[0].TC_CV;
+#else
+
return (systime_t)0;
+#endif
}
/**
@@ -142,7 +158,26 @@ static inline systime_t st_lld_get_counter(void) {
*/
static inline void st_lld_start_alarm(systime_t time) {
+#if (SAMA_ST_USE_TC0 || SAMA_ST_USE_TC1)
+
+#if SAMA_ST_USE_TC0
+
+ Tc *tcp = TC0;
+#endif
+#if SAMA_ST_USE_TC1
+
+ Tc *tcp = TC1;
+#endif
+
+ tcp->TC_WPMR = TC_WPMR_WPKEY_PASSWD;
+ tcp->TC_CHANNEL[0].TC_RC = TC_RC_RC((uint32_t)time);
+ tcp->TC_CHANNEL[0].TC_SR;
+ tcp->TC_CHANNEL[0].TC_IER = TC_IER_CPCS;
+ tcp->TC_WPMR = TC_WPMR_WPKEY_PASSWD | TC_WPMR_WPEN;
+#else
+
(void)time;
+#endif
}
/**
@@ -152,6 +187,21 @@ static inline void st_lld_start_alarm(systime_t time) {
*/
static inline void st_lld_stop_alarm(void) {
+#if (SAMA_ST_USE_TC0 || SAMA_ST_USE_TC1)
+
+#if SAMA_ST_USE_TC0
+
+ Tc *tcp = TC0;
+#endif
+#if SAMA_ST_USE_TC1
+
+ Tc *tcp = TC1;
+#endif
+
+ tcp->TC_WPMR = TC_WPMR_WPKEY_PASSWD;
+ tcp->TC_CHANNEL[0].TC_IDR = TC_IDR_CPCS;
+ tcp->TC_WPMR = TC_WPMR_WPKEY_PASSWD | TC_WPMR_WPEN;
+#endif
}
/**
@@ -163,7 +213,24 @@ static inline void st_lld_stop_alarm(void) {
*/
static inline void st_lld_set_alarm(systime_t time) {
+#if (SAMA_ST_USE_TC0 || SAMA_ST_USE_TC1)
+
+#if SAMA_ST_USE_TC0
+
+ Tc *tcp = TC0;
+#endif
+#if SAMA_ST_USE_TC1
+
+ Tc *tcp = TC1;
+#endif
+
+ tcp->TC_WPMR = TC_WPMR_WPKEY_PASSWD;
+ tcp->TC_CHANNEL[0].TC_RC = TC_RC_RC((uint32_t)time);
+ tcp->TC_WPMR = TC_WPMR_WPKEY_PASSWD | TC_WPMR_WPEN;
+#else
+
(void)time;
+#endif
}
/**
@@ -175,7 +242,22 @@ static inline void st_lld_set_alarm(systime_t time) {
*/
static inline systime_t st_lld_get_alarm(void) {
+#if (SAMA_ST_USE_TC0 || SAMA_ST_USE_TC1)
+
+#if SAMA_ST_USE_TC0
+
+ Tc *tcp = TC0;
+#endif
+#if SAMA_ST_USE_TC1
+
+ Tc *tcp = TC1;
+#endif
+
+ return (systime_t)tcp->TC_CHANNEL[0].TC_RC;
+#else
+
return (systime_t)0;
+#endif
}
/**
@@ -189,7 +271,22 @@ static inline systime_t st_lld_get_alarm(void) {
*/
static inline bool st_lld_is_alarm_active(void) {
+#if (SAMA_ST_USE_TC0 || SAMA_ST_USE_TC1)
+
+#if SAMA_ST_USE_TC0
+
+ Tc *tcp = TC0;
+#endif
+#if SAMA_ST_USE_TC1
+
+ Tc *tcp = TC1;
+#endif
+
+ return (bool)((tcp->TC_CHANNEL[0].TC_IMR & TC_IMR_CPCS) != 0);
+#else
+
return false;
+#endif
}
#endif /* HAL_ST_LLD_H */