aboutsummaryrefslogtreecommitdiffstats
path: root/os
diff options
context:
space:
mode:
authoracirillo87 <acirillo87@35acf78f-673a-0410-8e92-d51de3d6d3f4>2013-03-07 17:27:30 +0000
committeracirillo87 <acirillo87@35acf78f-673a-0410-8e92-d51de3d6d3f4>2013-03-07 17:27:30 +0000
commit8b2210052f08f6053939ce65fc3921c2c23bc497 (patch)
tree8f062da88d4c8b6681029d71d3a80f2e78a7488d /os
parent5d9422111caf8a71ec8acfee598b12e4fc8e76ca (diff)
downloadChibiOS-8b2210052f08f6053939ce65fc3921c2c23bc497.tar.gz
ChibiOS-8b2210052f08f6053939ce65fc3921c2c23bc497.tar.bz2
ChibiOS-8b2210052f08f6053939ce65fc3921c2c23bc497.zip
git-svn-id: svn://svn.code.sf.net/p/chibios/svn/trunk@5379 35acf78f-673a-0410-8e92-d51de3d6d3f4
Diffstat (limited to 'os')
-rw-r--r--os/hal/platforms/SPC560Pxx/spc560p_registry.h2
-rw-r--r--os/hal/platforms/SPC5xx/FlexPWM_v1/pwm_lld.c669
-rw-r--r--os/hal/platforms/SPC5xx/FlexPWM_v1/pwm_lld.h128
-rw-r--r--os/hal/platforms/SPC5xx/eTimer_v1/icu_lld.c1068
-rw-r--r--os/hal/platforms/SPC5xx/eTimer_v1/icu_lld.h323
5 files changed, 1532 insertions, 658 deletions
diff --git a/os/hal/platforms/SPC560Pxx/spc560p_registry.h b/os/hal/platforms/SPC560Pxx/spc560p_registry.h
index 2ebc3c9c2..794767d02 100644
--- a/os/hal/platforms/SPC560Pxx/spc560p_registry.h
+++ b/os/hal/platforms/SPC560Pxx/spc560p_registry.h
@@ -136,6 +136,8 @@
#define SPC5_ETIMER1_RCF_NUMBER 178
#define SPC5_ETIMER1_CLK SPC5_MCONTROL_CLK
+#define SPC5_HAS_ETIMER2 FALSE
+
#endif /* _SPC560P_REGISTRY_H_ */
/** @} */
diff --git a/os/hal/platforms/SPC5xx/FlexPWM_v1/pwm_lld.c b/os/hal/platforms/SPC5xx/FlexPWM_v1/pwm_lld.c
index 864a43540..ebeb56d66 100644
--- a/os/hal/platforms/SPC5xx/FlexPWM_v1/pwm_lld.c
+++ b/os/hal/platforms/SPC5xx/FlexPWM_v1/pwm_lld.c
@@ -61,6 +61,38 @@ PWMDriver PWMD3;
PWMDriver PWMD4;
#endif
+/**
+ * @brief PWMD5 driver identifier.
+ * @note The driver PWMD5 allocates the timer TIM5 when enabled.
+ */
+#if SPC5_PWM_USE_SMOD4 || defined(__DOXYGEN__)
+PWMDriver PWMD5;
+#endif
+
+/**
+ * @brief PWMD6 driver identifier.
+ * @note The driver PWMD6 allocates the timer TIM4 when enabled.
+ */
+#if SPC5_PWM_USE_SMOD5 || defined(__DOXYGEN__)
+PWMDriver PWMD6;
+#endif
+
+/**
+ * @brief PWMD7 driver identifier.
+ * @note The driver PWMD7 allocates the timer TIM4 when enabled.
+ */
+#if SPC5_PWM_USE_SMOD6 || defined(__DOXYGEN__)
+PWMDriver PWMD7;
+#endif
+
+/**
+ * @brief PWMD8 driver identifier.
+ * @note The driver PWMD8 allocates the timer TIM4 when enabled.
+ */
+#if SPC5_PWM_USE_SMOD7 || defined(__DOXYGEN__)
+PWMDriver PWMD8;
+#endif
+
/*===========================================================================*/
/* Driver local variables. */
/*===========================================================================*/
@@ -498,8 +530,76 @@ static void pwm_lld_serve_interrupt(PWMDriver *pwmp) {
}
}
#endif
+#if SPC5_PWM_USE_SMOD4
+ if (&PWMD5 == pwmp) {
+ sr = pwmp->flexpwmp->SUB[0].STS.R & pwmp->flexpwmp->SUB[0].INTEN.R;
+ if ((sr & SPC5_STS_CMPF3) != 0) {
+ pwmp->flexpwmp->SUB[0].STS.B.CMPF |= 0b001000;
+ pwmp->config->channels[0].callback(pwmp);
+ }
+ if ((sr & SPC5_STS_CMPF5) != 0) {
+ pwmp->flexpwmp->SUB[0].STS.B.CMPF |= 0b100000;
+ pwmp->config->channels[1].callback(pwmp);
+ }
+ if ((sr & SPC5_STS_RF) != 0) {
+ pwmp->flexpwmp->SUB[0].STS.B.RF = 1U;
+ pwmp->config->callback(pwmp);
+ }
+ }
+#endif
+#if SPC5_PWM_USE_SMOD5
+ if (&PWMD6 == pwmp) {
+ sr = pwmp->flexpwmp->SUB[1].STS.R & pwmp->flexpwmp->SUB[1].INTEN.R;
+ if ((sr & SPC5_STS_CMPF3) != 0) {
+ pwmp->flexpwmp->SUB[1].STS.B.CMPF |= 0b001000;
+ pwmp->config->channels[0].callback(pwmp);
+ }
+ if ((sr & SPC5_STS_CMPF5) != 0) {
+ pwmp->flexpwmp->SUB[1].STS.B.CMPF |= 0b100000;
+ pwmp->config->channels[1].callback(pwmp);
+ }
+ if ((sr & SPC5_STS_RF) != 0) {
+ pwmp->flexpwmp->SUB[1].STS.B.RF = 1U;
+ pwmp->config->callback(pwmp);
+ }
+ }
+#endif
+#if SPC5_PWM_USE_SMOD6
+ if (&PWMD7 == pwmp) {
+ sr = pwmp->flexpwmp->SUB[2].STS.R & pwmp->flexpwmp->SUB[2].INTEN.R;
+ if ((sr & SPC5_STS_CMPF3) != 0) {
+ pwmp->flexpwmp->SUB[2].STS.B.CMPF |= 0b001000;
+ pwmp->config->channels[0].callback(pwmp);
+ }
+ if ((sr & SPC5_STS_CMPF5) != 0) {
+ pwmp->flexpwmp->SUB[2].STS.B.CMPF |= 0b100000;
+ pwmp->config->channels[1].callback(pwmp);
+ }
+ if ((sr & SPC5_STS_RF) != 0) {
+ pwmp->flexpwmp->SUB[2].STS.B.RF = 1U;
+ pwmp->config->callback(pwmp);
+ }
+ }
+#endif
+#if SPC5_PWM_USE_SMOD7
+ if (&PWMD8 == pwmp) {
+ sr = pwmp->flexpwmp->SUB[3].STS.R & pwmp->flexpwmp->SUB[3].INTEN.R;
+ if ((sr & SPC5_STS_CMPF3) != 0) {
+ pwmp->flexpwmp->SUB[3].STS.B.CMPF |= 0b001000;
+ pwmp->config->channels[0].callback(pwmp);
+ }
+ if ((sr & SPC5_STS_CMPF5) != 0) {
+ pwmp->flexpwmp->SUB[3].STS.B.CMPF |= 0b100000;
+ pwmp->config->channels[1].callback(pwmp);
+ }
+ if ((sr & SPC5_STS_RF) != 0) {
+ pwmp->flexpwmp->SUB[3].STS.B.RF = 1U;
+ pwmp->config->callback(pwmp);
+ }
+ }
+#endif
}
-#endif /* SPC5_PWM_USE_SMOD0 || ... || SPC5_PWM_USE_SMOD3 */
+#endif /* SPC5_PWM_USE_SMOD0 || ... || SPC5_PWM_USE_SMOD7 */
/*===========================================================================*/
/* Driver interrupt handlers. */
@@ -649,6 +749,150 @@ CH_IRQ_HANDLER(SPC5_FLEXPWM0_COF3_HANDLER) {
}
#endif
+#if SPC5_PWM_USE_SMOD4 || defined(__DOXYGEN__)
+#if !defined(SPC5_FLEXPWM1_RF0_HANDLER)
+#error "SPC5_FLEXPWM0_RF1_HANDLER not defined"
+#endif
+/**
+ * @brief FlexPWM1-SMOD0 RF0 interrupt handler.
+ *
+ * @isr
+ */
+CH_IRQ_HANDLER(SPC5_FLEXPWM1_RF0_HANDLER) {
+
+ CH_IRQ_PROLOGUE();
+
+ pwm_lld_serve_interrupt(&PWMD5);
+
+ CH_IRQ_EPILOGUE();
+}
+
+#if !defined(SPC5_FLEXPWM1_COF0_HANDLER)
+#error "SPC5_FLEXPWM1_COF0_HANDLER not defined"
+#endif
+/**
+ * @brief FlexPWM1-SMOD0 COF0 interrupt handler.
+ *
+ * @isr
+ */
+CH_IRQ_HANDLER(SPC5_FLEXPWM1_COF0_HANDLER) {
+
+ CH_IRQ_PROLOGUE();
+
+ pwm_lld_serve_interrupt(&PWMD5);
+
+ CH_IRQ_EPILOGUE();
+}
+#endif
+
+#if SPC5_PWM_USE_SMOD5 || defined(__DOXYGEN__)
+#if !defined(SPC5_FLEXPWM1_RF1_HANDLER)
+#error "SPC5_FLEXPWM1_RF1_HANDLER not defined"
+#endif
+/**
+ * @brief FlexPWM1-SMOD1 RF1 interrupt handler.
+ *
+ * @isr
+ */
+CH_IRQ_HANDLER(SPC5_FLEXPWM1_RF1_HANDLER) {
+
+ CH_IRQ_PROLOGUE();
+
+ pwm_lld_serve_interrupt(&PWMD6);
+
+ CH_IRQ_EPILOGUE();
+}
+
+#if !defined(SPC5_FLEXPWM1_COF1_HANDLER)
+#error "SPC5_FLEXPWM1_COF1_HANDLER not defined"
+#endif
+/**
+ * @brief FlexPWM1-SMOD1 COF1 interrupt handler.
+ *
+ * @isr
+ */
+CH_IRQ_HANDLER(SPC5_FLEXPWM1_COF1_HANDLER) {
+
+ CH_IRQ_PROLOGUE();
+
+ pwm_lld_serve_interrupt(&PWMD6);
+
+ CH_IRQ_EPILOGUE();
+}
+#endif
+
+#if SPC5_PWM_USE_SMOD6 || defined(__DOXYGEN__)
+#if !defined(SPC5_FLEXPWM1_RF2_HANDLER)
+#error "SPC5_FLEXPWM1_RF2_HANDLER not defined"
+#endif
+/**
+ * @brief FlexPWM1-SMOD2 RF2 interrupt handler.
+ *
+ * @isr
+ */
+CH_IRQ_HANDLER(SPC5_FLEXPWM1_RF2_HANDLER) {
+
+ CH_IRQ_PROLOGUE();
+
+ pwm_lld_serve_interrupt(&PWMD7);
+
+ CH_IRQ_EPILOGUE();
+}
+
+#if !defined(SPC5_FLEXPWM1_COF2_HANDLER)
+#error "SPC5_FLEXPWM1_COF2_HANDLER not defined"
+#endif
+/**
+ * @brief FlexPWM1-SMOD2 COF2 interrupt handler.
+ *
+ * @isr
+ */
+CH_IRQ_HANDLER(SPC5_FLEXPWM1_COF2_HANDLER) {
+
+ CH_IRQ_PROLOGUE();
+
+ pwm_lld_serve_interrupt(&PWMD7);
+
+ CH_IRQ_EPILOGUE();
+}
+#endif
+
+#if SPC5_PWM_USE_SMOD7 || defined(__DOXYGEN__)
+#if !defined(SPC5_FLEXPWM1_RF3_HANDLER)
+#error "SPC5_FLEXPWM1_RF3_HANDLER not defined"
+#endif
+/**
+ * @brief FlexPWM1-SMOD3 RF3 interrupt handler.
+ *
+ * @isr
+ */
+CH_IRQ_HANDLER(SPC5_FLEXPWM1_RF3_HANDLER) {
+
+ CH_IRQ_PROLOGUE();
+
+ pwm_lld_serve_interrupt(&PWMD8);
+
+ CH_IRQ_EPILOGUE();
+}
+
+#if !defined(SPC5_FLEXPWM1_COF3_HANDLER)
+#error "SPC5_FLEXPWM1_COF3_HANDLER not defined"
+#endif
+/**
+ * @brief FlexPWM1-SMOD3 COF3 interrupt handler.
+ *
+ * @isr
+ */
+CH_IRQ_HANDLER(SPC5_FLEXPWM1_COF3_HANDLER) {
+
+ CH_IRQ_PROLOGUE();
+
+ pwm_lld_serve_interrupt(&PWMD8);
+
+ CH_IRQ_EPILOGUE();
+}
+#endif
+
/*===========================================================================*/
/* Driver exported functions. */
/*===========================================================================*/
@@ -703,6 +947,50 @@ void pwm_lld_init(void) {
INTC.PSR[SPC5_FLEXPWM0_FFLAG_NUMBER].R = SPC5_PWM_SMOD3_PRIORITY;
INTC.PSR[SPC5_FLEXPWM0_REF_NUMBER].R = SPC5_PWM_SMOD3_PRIORITY;
#endif
+
+#if (SPC5_PWM_USE_SMOD4)
+ /* Driver initialization.*/
+ pwmObjectInit(&PWMD5);
+ PWMD5.flexpwmp = &FLEXPWM_1;
+ INTC.PSR[SPC5_FLEXPWM1_RF0_NUMBER].R = SPC5_PWM_SMOD4_PRIORITY;
+ INTC.PSR[SPC5_FLEXPWM1_COF0_NUMBER].R = SPC5_PWM_SMOD4_PRIORITY;
+ INTC.PSR[SPC5_FLEXPWM1_CAF0_NUMBER].R = SPC5_PWM_SMOD4_PRIORITY;
+ INTC.PSR[SPC5_FLEXPWM1_FFLAG_NUMBER].R = SPC5_PWM_SMOD4_PRIORITY;
+ INTC.PSR[SPC5_FLEXPWM1_REF_NUMBER].R = SPC5_PWM_SMOD4_PRIORITY;
+#endif
+
+#if (SPC5_PWM_USE_SMOD5)
+ /* Driver initialization.*/
+ pwmObjectInit(&PWMD6);
+ PWMD6.flexpwmp = &FLEXPWM_1;
+ INTC.PSR[SPC5_FLEXPWM1_RF1_NUMBER].R = SPC5_PWM_SMOD5_PRIORITY;
+ INTC.PSR[SPC5_FLEXPWM1_COF1_NUMBER].R = SPC5_PWM_SMOD5_PRIORITY;
+ INTC.PSR[SPC5_FLEXPWM1_CAF1_NUMBER].R = SPC5_PWM_SMOD5_PRIORITY;
+ INTC.PSR[SPC5_FLEXPWM1_FFLAG_NUMBER].R = SPC5_PWM_SMOD5_PRIORITY;
+ INTC.PSR[SPC5_FLEXPWM1_REF_NUMBER].R = SPC5_PWM_SMOD5_PRIORITY;
+#endif
+
+#if (SPC5_PWM_USE_SMOD6)
+ /* Driver initialization.*/
+ pwmObjectInit(&PWMD3);
+ PWMD7.flexpwmp = &FLEXPWM_1;
+ INTC.PSR[SPC5_FLEXPWM1_RF2_NUMBER].R = SPC5_PWM_SMOD6_PRIORITY;
+ INTC.PSR[SPC5_FLEXPWM1_COF2_NUMBER].R = SPC5_PWM_SMOD6_PRIORITY;
+ INTC.PSR[SPC5_FLEXPWM1_CAF2_NUMBER].R = SPC5_PWM_SMOD6_PRIORITY;
+ INTC.PSR[SPC5_FLEXPWM1_FFLAG_NUMBER].R = SPC5_PWM_SMOD6_PRIORITY;
+ INTC.PSR[SPC5_FLEXPWM1_REF_NUMBER].R = SPC5_PWM_SMOD6_PRIORITY;
+#endif
+
+#if (SPC5_PWM_USE_SMOD7)
+ /* Driver initialization.*/
+ pwmObjectInit(&PWMD4);
+ PWMD8.flexpwmp = &FLEXPWM_1;
+ INTC.PSR[SPC5_FLEXPWM1_RF3_NUMBER].R = SPC5_PWM_SMOD7_PRIORITY;
+ INTC.PSR[SPC5_FLEXPWM1_COF3_NUMBER].R = SPC5_PWM_SMOD7_PRIORITY;
+ INTC.PSR[SPC5_FLEXPWM1_CAF3_NUMBER].R = SPC5_PWM_SMOD7_PRIORITY;
+ INTC.PSR[SPC5_FLEXPWM1_FFLAG_NUMBER].R = SPC5_PWM_SMOD7_PRIORITY;
+ INTC.PSR[SPC5_FLEXPWM1_REF_NUMBER].R = SPC5_PWM_SMOD7_PRIORITY;
+#endif
}
/**
@@ -717,10 +1005,20 @@ void pwm_lld_init(void) {
void pwm_lld_start(PWMDriver *pwmp) {
if (pwmp->state == PWM_STOP) {
+#if SPC5_PWM_USE_SMOD0 || SPC5_PWM_USE_SMOD1 || \
+ SPC5_PWM_USE_SMOD2 || SPC5_PWM_USE_SMO3
uint8_t SMOD0 = 0;
uint8_t SMOD1 = 0;
uint8_t SMOD2 = 0;
uint8_t SMOD3 = 0;
+#endif
+#if SPC5_PWM_USE_SMOD4 || SPC5_PWM_USE_SMOD5 || \
+ SPC5_PWM_USE_SMOD6 || SPC5_PWM_USE_SMO7
+ uint8_t SMOD4 = 0;
+ uint8_t SMOD5 = 0;
+ uint8_t SMOD6 = 0;
+ uint8_t SMOD7 = 0;
+#endif
#if SPC5_PWM_USE_SMOD0
if (PWMD1.state == PWM_READY)
@@ -738,12 +1036,40 @@ void pwm_lld_start(PWMDriver *pwmp) {
if (PWMD4.state == PWM_READY)
SMOD3 = 1U;
#endif
+#if SPC5_PWM_USE_SMOD4
+ if (PWMD5.state == PWM_READY)
+ SMOD4 = 1U;
+#endif
+#if SPC5_PWM_USE_SMOD5
+ if (PWMD6.state == PWM_READY)
+ SMOD5 = 1U;
+#endif
+#if SPC5_PWM_USE_SMOD6
+ if (PWMD7.state == PWM_READY)
+ SMOD6 = 1U;
+#endif
+#if SPC5_PWM_USE_SMOD7
+ if (PWMD8.state == PWM_READY)
+ SMOD7 = 1U;
+#endif
+#if SPC5_PWM_USE_SMOD0 || SPC5_PWM_USE_SMOD1 || \
+ SPC5_PWM_USE_SMOD2 || SPC5_PWM_USE_SMOD3
/* Set Peripheral Clock.*/
- if (!(SMOD0 || SMOD1 || SMOD2 || SMOD3)) {
+ if(!(SMOD0 || SMOD1 || SMOD2 || SMOD3)) {
halSPCSetPeripheralClockMode(SPC5_FLEXPWM0_PCTL,
SPC5_PWM_FLEXPWM0_START_PCTL);
}
+#endif
+
+#if SPC5_PWM_USE_SMOD4 || SPC5_PWM_USE_SMOD5 || \
+ SPC5_PWM_USE_SMOD6 || SPC5_PWM_USE_SMOD7
+ /* Set Peripheral Clock.*/
+ if(!(SMOD4 || SMOD5 || SMOD6 || SMOD7)) {
+ halSPCSetPeripheralClockMode(SPC5_FLEXPWM1_PCTL,
+ SPC5_PWM_FLEXPWM1_START_PCTL);
+ }
+#endif
#if SPC5_PWM_USE_SMOD0
if (&PWMD1 == pwmp) {
@@ -765,6 +1091,26 @@ void pwm_lld_start(PWMDriver *pwmp) {
pwm_lld_start_submodule(pwmp, 3);
}
#endif
+#if SPC5_PWM_USE_SMOD4
+ if (&PWMD5 == pwmp) {
+ pwm_lld_start_submodule(pwmp, 0);
+ }
+#endif
+#if SPC5_PWM_USE_SMOD5
+ if (&PWMD6 == pwmp) {
+ pwm_lld_start_submodule(pwmp, 1);
+ }
+#endif
+#if SPC5_PWM_USE_SMOD6
+ if (&PWMD7 == pwmp) {
+ pwm_lld_start_submodule(pwmp, 2);
+ }
+#endif
+#if SPC5_PWM_USE_SMOD7
+ if (&PWMD8 == pwmp) {
+ pwm_lld_start_submodule(pwmp, 3);
+ }
+#endif
}
else {
/* Driver re-configuration scenario, it must be stopped first.*/
@@ -844,6 +1190,82 @@ void pwm_lld_start(PWMDriver *pwmp) {
pwmp->flexpwmp->SUB[3].CTRL2.B.FORCE = 1U;
}
#endif
+#if SPC5_PWM_USE_SMOD4
+ if (&PWMD5 == pwmp) {
+ /* Disable the interrupts.*/
+ pwmp->flexpwmp->SUB[0].INTEN.R = 0x0000;
+
+ /* Disable the submodule.*/
+ pwmp->flexpwmp->OUTEN.B.PWMA_EN &= 0b1110;
+ pwmp->flexpwmp->OUTEN.B.PWMB_EN &= 0b1110;
+
+ /* Active the submodule masks.*/
+ pwmp->flexpwmp->MASK.B.MASKA &= 0b1110;
+ pwmp->flexpwmp->MASK.B.MASKB &= 0b1110;
+
+ /* Sets the MASK registers.*/
+ pwmp->flexpwmp->SUB[0].CTRL2.B.FRCEN = 1U;
+ pwmp->flexpwmp->SUB[0].CTRL2.B.FORCE_SEL = 0b000;
+ pwmp->flexpwmp->SUB[0].CTRL2.B.FORCE = 1U;
+ }
+#endif
+#if SPC5_PWM_USE_SMOD5
+ if (&PWMD6 == pwmp) {
+ /* Disable the interrupts.*/
+ pwmp->flexpwmp->SUB[1].INTEN.R = 0x0000;
+
+ /* Disable the submodule.*/
+ pwmp->flexpwmp->OUTEN.B.PWMA_EN &= 0b1101;
+ pwmp->flexpwmp->OUTEN.B.PWMB_EN &= 0b1101;
+
+ /* Active the submodule masks.*/
+ pwmp->flexpwmp->MASK.B.MASKA &= 0b1101;
+ pwmp->flexpwmp->MASK.B.MASKB &= 0b1101;
+
+ /* Sets the MASK registers.*/
+ pwmp->flexpwmp->SUB[1].CTRL2.B.FRCEN = 1U;
+ pwmp->flexpwmp->SUB[1].CTRL2.B.FORCE_SEL = 0b000;
+ pwmp->flexpwmp->SUB[1].CTRL2.B.FORCE = 1U;
+ }
+#endif
+#if SPC5_PWM_USE_SMOD6
+ if (&PWMD7 == pwmp) {
+ /* Disable the interrupts.*/
+ pwmp->flexpwmp->SUB[2].INTEN.R = 0x0000;
+
+ /* Disable the submodule.*/
+ pwmp->flexpwmp->OUTEN.B.PWMA_EN &= 0b1011;
+ pwmp->flexpwmp->OUTEN.B.PWMB_EN &= 0b1011;
+
+ /* Active the submodule masks.*/
+ pwmp->flexpwmp->MASK.B.MASKA &= 0b1011;
+ pwmp->flexpwmp->MASK.B.MASKB &= 0b1011;
+
+ /* Sets the MASK registers.*/
+ pwmp->flexpwmp->SUB[2].CTRL2.B.FRCEN = 1U;
+ pwmp->flexpwmp->SUB[2].CTRL2.B.FORCE_SEL = 0b000;
+ pwmp->flexpwmp->SUB[2].CTRL2.B.FORCE = 1U;
+ }
+#endif
+#if SPC5_PWM_USE_SMOD7
+ if (&PWMD8 == pwmp) {
+ /* Disable the interrupts.*/
+ pwmp->flexpwmp->SUB[3].INTEN.R = 0x0000;
+
+ /* Disable the submodule.*/
+ pwmp->flexpwmp->OUTEN.B.PWMA_EN &= 0b0111;
+ pwmp->flexpwmp->OUTEN.B.PWMB_EN &= 0b0111;
+
+ /* Active the submodule masks.*/
+ pwmp->flexpwmp->MASK.B.MASKA &= 0b0111;
+ pwmp->flexpwmp->MASK.B.MASKB &= 0b0111;
+
+ /* Sets the MASK registers.*/
+ pwmp->flexpwmp->SUB[3].CTRL2.B.FRCEN = 1U;
+ pwmp->flexpwmp->SUB[3].CTRL2.B.FORCE_SEL = 0b000;
+ pwmp->flexpwmp->SUB[3].CTRL2.B.FORCE = 1U;
+ }
+#endif
}
}
@@ -858,6 +1280,21 @@ void pwm_lld_stop(PWMDriver *pwmp) {
/* If in ready state then disables the PWM clock.*/
if (pwmp->state == PWM_READY) {
+#if SPC5_PWM_USE_SMOD0 || SPC5_PWM_USE_SMOD1 || \
+ SPC5_PWM_USE_SMOD2 || SPC5_PWM_USE_SMO3
+ uint8_t SMOD0 = 0;
+ uint8_t SMOD1 = 0;
+ uint8_t SMOD2 = 0;
+ uint8_t SMOD3 = 0;
+#endif
+#if SPC5_PWM_USE_SMOD4 || SPC5_PWM_USE_SMOD5 || \
+ SPC5_PWM_USE_SMOD6 || SPC5_PWM_USE_SMO7
+ uint8_t SMOD4 = 0;
+ uint8_t SMOD5 = 0;
+ uint8_t SMOD6 = 0;
+ uint8_t SMOD7 = 0;
+#endif
+
#if SPC5_PWM_USE_SMOD0
if (&PWMD1 == pwmp) {
/* SMOD stop.*/
@@ -868,6 +1305,8 @@ void pwm_lld_stop(PWMDriver *pwmp) {
pwmp->flexpwmp->OUTEN.B.PWMB_EN &= 0b1110;
pwmp->flexpwmp->MCTRL.B.RUN &= 0b1110;
+
+ SMOD0 = 1;
}
#endif
#if SPC5_PWM_USE_SMOD1
@@ -880,6 +1319,8 @@ void pwm_lld_stop(PWMDriver *pwmp) {
pwmp->flexpwmp->OUTEN.B.PWMB_EN &= 0b1101;
pwmp->flexpwmp->MCTRL.B.RUN &= 0b1101;
+
+ SMOD1 = 1;
}
#endif
#if SPC5_PWM_USE_SMOD2
@@ -892,6 +1333,8 @@ void pwm_lld_stop(PWMDriver *pwmp) {
pwmp->flexpwmp->OUTEN.B.PWMB_EN &= 0b1011;
pwmp->flexpwmp->MCTRL.B.RUN &= 0b1011;
+
+ SMOD2 = 1;
}
#endif
#if SPC5_PWM_USE_SMOD3
@@ -904,17 +1347,95 @@ void pwm_lld_stop(PWMDriver *pwmp) {
pwmp->flexpwmp->OUTEN.B.PWMB_EN &= 0b0111;
pwmp->flexpwmp->MCTRL.B.RUN &= 0b0111;
+
+ SMOD3 = 1;
}
#endif
+#if SPC5_PWM_USE_SMOD4
+ if (&PWMD5 == pwmp) {
+ /* SMOD stop.*/
+ pwmp->flexpwmp->MCTRL.B.CLDOK |= 0b0001;
+ pwmp->flexpwmp->SUB[0].INTEN.R = 0x0000;
+ pwmp->flexpwmp->SUB[0].STS.R = 0xFFFF;
+ pwmp->flexpwmp->OUTEN.B.PWMA_EN &= 0b1110;
+ pwmp->flexpwmp->OUTEN.B.PWMB_EN &= 0b1110;
- /* Disable peripheral clock if there is not an activated module.*/
- if ((pwmp->flexpwmp->MCTRL.B.RUN & 0b0001) ||
- (pwmp->flexpwmp->MCTRL.B.RUN & 0b0010) ||
- (pwmp->flexpwmp->MCTRL.B.RUN & 0b0100) ||
- (pwmp->flexpwmp->MCTRL.B.RUN & 0b1000) == 0) {
- halSPCSetPeripheralClockMode(SPC5_FLEXPWM0_PCTL,
- SPC5_PWM_FLEXPWM0_STOP_PCTL);
+ pwmp->flexpwmp->MCTRL.B.RUN &= 0b1110;
+
+ SMOD4 = 1;
+ }
+#endif
+#if SPC5_PWM_USE_SMOD5
+ if (&PWMD6 == pwmp) {
+ /* SMOD stop.*/
+ pwmp->flexpwmp->MCTRL.B.CLDOK |= 0b0010;
+ pwmp->flexpwmp->SUB[1].INTEN.R = 0x0000;
+ pwmp->flexpwmp->SUB[1].STS.R = 0xFFFF;
+ pwmp->flexpwmp->OUTEN.B.PWMA_EN &= 0b1101;
+ pwmp->flexpwmp->OUTEN.B.PWMB_EN &= 0b1101;
+
+ pwmp->flexpwmp->MCTRL.B.RUN &= 0b1101;
+
+ SMOD5 = 1;
+ }
+#endif
+#if SPC5_PWM_USE_SMOD6
+ if (&PWMD7 == pwmp) {
+ /* SMOD stop.*/
+ pwmp->flexpwmp->MCTRL.B.CLDOK |= 0b0100;
+ pwmp->flexpwmp->SUB[2].INTEN.R = 0x0000;
+ pwmp->flexpwmp->SUB[2].STS.R = 0xFFFF;
+ pwmp->flexpwmp->OUTEN.B.PWMA_EN &= 0b1011;
+ pwmp->flexpwmp->OUTEN.B.PWMB_EN &= 0b1011;
+
+ pwmp->flexpwmp->MCTRL.B.RUN &= 0b1011;
+
+ SMOD6 = 1;
+ }
+#endif
+#if SPC5_PWM_USE_SMOD7
+ if (&PWMD8 == pwmp) {
+ /* SMOD stop.*/
+ pwmp->flexpwmp->MCTRL.B.CLDOK |= 0b1000;
+ pwmp->flexpwmp->SUB[3].INTEN.R = 0x0000;
+ pwmp->flexpwmp->SUB[3].STS.R = 0xFFFF;
+ pwmp->flexpwmp->OUTEN.B.PWMA_EN &= 0b0111;
+ pwmp->flexpwmp->OUTEN.B.PWMB_EN &= 0b0111;
+
+ pwmp->flexpwmp->MCTRL.B.RUN &= 0b0111;
+
+ SMOD7 = 1;
+ }
+#endif
+
+#if SPC5_PWM_USE_SMOD0 || SPC5_PWM_USE_SMOD1 || \
+ SPC5_PWM_USE_SMOD2 || SPC5_PWM_USE_SMOD3
+ if (SMOD0 || SMOD1 || SMOD2 || SMOD3) {
+ /* Disable peripheral clock if there is not an activated module.*/
+ if ((pwmp->flexpwmp->MCTRL.B.RUN & 0b0001) ||
+ (pwmp->flexpwmp->MCTRL.B.RUN & 0b0010) ||
+ (pwmp->flexpwmp->MCTRL.B.RUN & 0b0100) ||
+ (pwmp->flexpwmp->MCTRL.B.RUN & 0b1000) == 0) {
+ halSPCSetPeripheralClockMode(SPC5_FLEXPWM0_PCTL,
+ SPC5_PWM_FLEXPWM0_STOP_PCTL);
+ }
}
+#endif
+
+#if SPC5_PWM_USE_SMOD4 || SPC5_PWM_USE_SMOD5 || \
+ SPC5_PWM_USE_SMOD6 || SPC5_PWM_USE_SMOD7
+ if (SMOD4 || SMOD5 || SMOD6 || SMOD7) {
+ /* Disable peripheral clock if there is not an activated module.*/
+ if ((pwmp->flexpwmp->MCTRL.B.RUN & 0b0001) ||
+ (pwmp->flexpwmp->MCTRL.B.RUN & 0b0010) ||
+ (pwmp->flexpwmp->MCTRL.B.RUN & 0b0100) ||
+ (pwmp->flexpwmp->MCTRL.B.RUN & 0b1000) == 0) {
+ halSPCSetPeripheralClockMode(SPC5_FLEXPWM1_PCTL,
+ SPC5_PWM_FLEXPWM1_STOP_PCTL);
+ }
+ }
+#endif
+
}
}
@@ -954,6 +1475,26 @@ void pwm_lld_enable_channel(PWMDriver *pwmp,
pwm_lld_enable_submodule_channel(pwmp, channel, width, 3);
}
#endif
+#if SPC5_PWM_USE_SMOD4
+ if (&PWMD5 == pwmp) {
+ pwm_lld_enable_submodule_channel(pwmp, channel, width, 0);
+ }
+#endif
+#if SPC5_PWM_USE_SMOD5
+ if (&PWMD6 == pwmp) {
+ pwm_lld_enable_submodule_channel(pwmp, channel, width, 1);
+ }
+#endif
+#if SPC5_PWM_USE_SMOD6
+ if (&PWMD7 == pwmp) {
+ pwm_lld_enable_submodule_channel(pwmp, channel, width, 2);
+ }
+#endif
+#if SPC5_PWM_USE_SMOD7
+ if (&PWMD8 == pwmp) {
+ pwm_lld_enable_submodule_channel(pwmp, channel, width, 3);
+ }
+#endif
}
/**
@@ -990,6 +1531,26 @@ void pwm_lld_disable_channel(PWMDriver *pwmp, pwmchannel_t channel) {
pwm_lld_disable_submodule_channel(pwmp, channel, 3);
}
#endif
+#if SPC5_PWM_USE_SMOD4
+ if (&PWMD5 == pwmp) {
+ pwm_lld_disable_submodule_channel(pwmp, channel, 0);
+ }
+#endif
+#if SPC5_PWM_USE_SMOD5
+ if (&PWMD6 == pwmp) {
+ pwm_lld_disable_submodule_channel(pwmp, channel, 1);
+ }
+#endif
+#if SPC5_PWM_USE_SMOD6
+ if (&PWMD7 == pwmp) {
+ pwm_lld_disable_submodule_channel(pwmp, channel, 2);
+ }
+#endif
+#if SPC5_PWM_USE_SMOD7
+ if (&PWMD8 == pwmp) {
+ pwm_lld_disable_submodule_channel(pwmp, channel, 3);
+ }
+#endif
}
/**
@@ -1010,8 +1571,7 @@ void pwm_lld_disable_channel(PWMDriver *pwmp, pwmchannel_t channel) {
*/
void pwm_lld_change_period(PWMDriver *pwmp, pwmcnt_t period) {
- pwmcnt_t pwmperiod;
- pwmperiod = period;
+ pwmcnt_t pwmperiod = period;
#if SPC5_PWM_USE_SMOD0
if (&PWMD1 == pwmp) {
pwmp->flexpwmp->MCTRL.B.CLDOK |= 0b0001;
@@ -1099,6 +1659,93 @@ void pwm_lld_change_period(PWMDriver *pwmp, pwmcnt_t period) {
pwmp->flexpwmp->MCTRL.B.LDOK |= 0b1000;
}
#endif
+#if SPC5_PWM_USE_SMOD4
+ if (&PWMD5 == pwmp) {
+ pwmp->flexpwmp->MCTRL.B.CLDOK |= 0b0001;
+
+ /* Setting PWM period.*/
+ pwmp->flexpwmp->SUB[0].INIT.R = ~(pwmperiod / 2) + 1U;
+ pwmp->flexpwmp->SUB[0].VAL[0].R = 0x0000;
+ pwmp->flexpwmp->SUB[0].VAL[1].R = pwmperiod / 2;
+
+ switch (pwmp->config->mode & PWM_OUTPUT_MASK) {
+ case EDGE_ALIGNED_PWM:
+
+ /* Setting active front of PWM channels.*/
+ pwmp->flexpwmp->SUB[0].VAL[2].R = ~(pwmperiod / 2) + 1U;
+ pwmp->flexpwmp->SUB[0].VAL[4].R = ~(pwmperiod / 2) + 1U;
+ break;
+ default:
+ ;
+ }
+ pwmp->flexpwmp->MCTRL.B.LDOK |= 0b0001;
+ }
+#endif
+#if SPC5_PWM_USE_SMOD5
+ if (&PWMD6 == pwmp) {
+ pwmp->flexpwmp->MCTRL.B.CLDOK |= 0b0010;
+
+ /* Setting PWM period.*/
+ pwmp->flexpwmp->SUB[1].INIT.R = ~(pwmperiod / 2) + 1U;
+ pwmp->flexpwmp->SUB[1].VAL[0].R = 0x0000;
+ pwmp->flexpwmp->SUB[1].VAL[1].R = pwmperiod / 2;
+
+ switch (pwmp->config->mode & PWM_OUTPUT_MASK) {
+ case EDGE_ALIGNED_PWM:
+
+ /* Setting active front of PWM channels.*/
+ pwmp->flexpwmp->SUB[1].VAL[2].R = ~(pwmperiod / 2) + 1U;
+ pwmp->flexpwmp->SUB[1].VAL[4].R = ~(pwmperiod / 2) + 1U;
+ break;
+ default:
+ ;
+ }
+ pwmp->flexpwmp->MCTRL.B.LDOK |= 0b0010;
+ }
+#endif
+#if SPC5_PWM_USE_SMOD6
+ if (&PWMD7 == pwmp) {
+ pwmp->flexpwmp->MCTRL.B.CLDOK |= 0b0100;
+
+ /* Setting PWM period.*/
+ pwmp->flexpwmp->SUB[2].INIT.R = ~(pwmperiod / 2) + 1U;
+ pwmp->flexpwmp->SUB[2].VAL[0].R = 0x0000;
+ pwmp->flexpwmp->SUB[2].VAL[1].R = pwmperiod / 2;
+
+ switch (pwmp->config->mode & PWM_OUTPUT_MASK) {
+ case EDGE_ALIGNED_PWM:
+
+ /* Setting active front of PWM channels.*/
+ pwmp->flexpwmp->SUB[2].VAL[2].R = ~(pwmperiod / 2) + 1U;
+ pwmp->flexpwmp->SUB[2].VAL[4].R = ~(pwmperiod / 2) + 1U;
+ break;
+ default:
+ ;
+ }
+ pwmp->flexpwmp->MCTRL.B.LDOK |= 0b0100;
+ }
+#endif
+#if SPC5_PWM_USE_SMOD7
+ if (&PWMD8 == pwmp) {
+ pwmp->flexpwmp->MCTRL.B.CLDOK |= 0b1000;
+
+ /* Setting PWM period.*/
+ pwmp->flexpwmp->SUB[3].INIT.R = ~(pwmperiod / 2) + 1U;
+ pwmp->flexpwmp->SUB[3].VAL[0].R = 0x0000;
+ pwmp->flexpwmp->SUB[3].VAL[1].R = pwmperiod / 2;
+
+ switch (pwmp->config->mode & PWM_OUTPUT_MASK) {
+ case EDGE_ALIGNED_PWM:
+ /* Setting active front of PWM channels.*/
+ pwmp->flexpwmp->SUB[3].VAL[2].R = ~(pwmperiod / 2) + 1U;
+ pwmp->flexpwmp->SUB[3].VAL[4].R = ~(pwmperiod / 2) + 1U;
+ break;
+ default:
+ ;
+ }
+ pwmp->flexpwmp->MCTRL.B.LDOK |= 0b1000;
+ }
+#endif
}
#endif /* HAL_USE_PWM */
diff --git a/os/hal/platforms/SPC5xx/FlexPWM_v1/pwm_lld.h b/os/hal/platforms/SPC5xx/FlexPWM_v1/pwm_lld.h
index cc1ee0dc1..7bb0d6b83 100644
--- a/os/hal/platforms/SPC5xx/FlexPWM_v1/pwm_lld.h
+++ b/os/hal/platforms/SPC5xx/FlexPWM_v1/pwm_lld.h
@@ -95,7 +95,7 @@
* @name Configuration options
* @{
*/
-
+#if SPC5_HAS_FLEXPWM0
/**
* @brief PWMD1 driver enable switch.
* @details If set to @p TRUE the support for PWMD1 is included.
@@ -181,6 +181,95 @@
#define SPC5_PWM_FLEXPWM0_STOP_PCTL (SPC5_ME_PCTL_RUN(0) | \
SPC5_ME_PCTL_LP(0))
#endif
+#endif
+
+#if SPC5_HAS_FLEXPWM1
+/**
+ * @brief PWMD5 driver enable switch.
+ * @details If set to @p TRUE the support for PWMD4 is included.
+ * @note The default is @p TRUE.
+ */
+#if !defined(SPC5_PWM_USE_SMOD4) || defined(__DOXYGEN__)
+#define SPC5_PWM_USE_SMOD4 TRUE
+#endif
+
+/**
+ * @brief PWMD6 driver enable switch.
+ * @details If set to @p TRUE the support for PWMD4 is included.
+ * @note The default is @p TRUE.
+ */
+#if !defined(SPC5_PWM_USE_SMOD5) || defined(__DOXYGEN__)
+#define SPC5_PWM_USE_SMOD5 TRUE
+#endif
+
+/**
+ * @brief PWMD7 driver enable switch.
+ * @details If set to @p TRUE the support for PWMD4 is included.
+ * @note The default is @p TRUE.
+ */
+#if !defined(SPC5_PWM_USE_SMOD6) || defined(__DOXYGEN__)
+#define SPC5_PWM_USE_SMOD6 FALSE
+#endif
+
+/**
+ * @brief PWMD8 driver enable switch.
+ * @details If set to @p TRUE the support for PWMD4 is included.
+ * @note The default is @p TRUE.
+ */
+#if !defined(SPC5_PWM_USE_SMOD7) || defined(__DOXYGEN__)
+#define SPC5_PWM_USE_SMOD7 TRUE
+#endif
+
+/**
+ * @brief PWMD5 interrupt priority level setting.
+ */
+#if !defined(SPC5_PWM_SMOD4_PRIORITY) || defined(__DOXYGEN__)
+#define SPC5_PWM_SMOD4_PRIORITY 7
+#endif
+
+/**
+ * @brief PWMD6 interrupt priority level setting.
+ */
+#if !defined(SPC5_PWM_SMOD5_PRIORITY) || defined(__DOXYGEN__)
+#define SPC5_PWM_SMOD5_PRIORITY 7
+#endif
+
+/**
+ * @brief PWMD7 interrupt priority level setting.
+ */
+#if !defined(SPC5_PWM_SMOD6_PRIORITY) || defined(__DOXYGEN__)
+#define SPC5_PWM_SMOD6_PRIORITY 7
+#endif
+
+/**
+ * @brief PWMD8 interrupt priority level setting.
+ */
+#if !defined(SPC5_PWM_SMOD7_PRIORITY) || defined(__DOXYGEN__)
+#define SPC5_PWM_SMOD7_PRIORITY 7
+#endif
+
+/**
+ * @brief FlexPWM-1 peripheral configuration when started.
+ * @note The default configuration is 1 (always run) in run mode and
+ * 2 (only halt) in low power mode. The defaults of the run modes
+ * are defined in @p hal_lld.h.
+ */
+#if !defined(SPC5_PWM_FLEXPWM1_START_PCTL) || defined(__DOXYGEN__)
+#define SPC5_PWM_FLEXPWM1_START_PCTL (SPC5_ME_PCTL_RUN(1) | \
+ SPC5_ME_PCTL_LP(2))
+#endif
+
+/**
+ * @brief FlexPWM-1 peripheral configuration when stopped.
+ * @note The default configuration is 0 (never run) in run mode and
+ * 0 (never run) in low power mode. The defaults of the run modes
+ * are defined in @p hal_lld.h.
+ */
+#if !defined(SPC5_PWM_FLEXPWM1_STOP_PCTL) || defined(__DOXYGEN__)
+#define SPC5_PWM_FLEXPWM1_STOP_PCTL (SPC5_ME_PCTL_RUN(0) | \
+ SPC5_ME_PCTL_LP(0))
+#endif
+#endif
/*===========================================================================*/
/* Configuration checks. */
@@ -207,6 +296,27 @@
#error "PWM driver activated but no SubModule assigned"
#endif
+#if SPC5_PWM_USE_SMOD4 && !SPC5_HAS_FLEXPWM1
+#error "SMOD4 not present in the selected device"
+#endif
+
+#if SPC5_PWM_USE_SMOD5 && !SPC5_HAS_FLEXPWM1
+#error "SMOD5 not present in the selected device"
+#endif
+
+#if SPC5_PWM_USE_SMDO6 && !SPC5_HAS_FLEXPWM1
+#error "SMOD6 not present in the selected device"
+#endif
+
+#if SPC5_PWM_USE_SMOD7 && !SPC5_HAS_FLEXPWM1
+#error "SMOD7 not present in the selected device"
+#endif
+
+#if (!SPC5_PWM_USE_SMOD4 && !SPC5_PWM_USE_SMOD5 && \
+ !SPC5_PWM_USE_SMOD6 && !SPC5_PWM_USE_SMOD7) && SPC5_PWM_USE_FLEXPWM1
+#error "PWM driver activated but no SubModule assigned"
+#endif
+
/*===========================================================================*/
/* Driver data structures and types. */
/*===========================================================================*/
@@ -327,6 +437,22 @@ extern PWMDriver PWMD3;
extern PWMDriver PWMD4;
#endif
+#if SPC5_PWM_USE_SMOD4 && !defined(__DOXYGEN__)
+extern PWMDriver PWMD5;
+#endif
+
+#if SPC5_PWM_USE_SMOD5 && !defined(__DOXYGEN__)
+extern PWMDriver PWMD6;
+#endif
+
+#if SPC5_PWM_USE_SMOD6 && !defined(__DOXYGEN__)
+extern PWMDriver PWMD7;
+#endif
+
+#if SPC5_PWM_USE_SMOD7 && !defined(__DOXYGEN__)
+extern PWMDriver PWMD8;
+#endif
+
#ifdef __cplusplus
extern "C" {
#endif
diff --git a/os/hal/platforms/SPC5xx/eTimer_v1/icu_lld.c b/os/hal/platforms/SPC5xx/eTimer_v1/icu_lld.c
index 19445b1c6..a2bd437e0 100644
--- a/os/hal/platforms/SPC5xx/eTimer_v1/icu_lld.c
+++ b/os/hal/platforms/SPC5xx/eTimer_v1/icu_lld.c
@@ -129,125 +129,124 @@ ICUDriver ICUD11;
ICUDriver ICUD12;
#endif
-/*===========================================================================*/
-/* Driver local variables. */
-/*===========================================================================*/
-
-/*===========================================================================*/
-/* Driver local functions. */
-/*===========================================================================*/
-
/**
- * @brief ICU eTimer channel enable.
- *
- * @param[in] icup pointer to the @p ICUDriver object
- * @param[in] index ICU channel index
+ * @brief ICUD13 driver identifier.
+ * @note The driver ICUD13 allocates the complex timer SMD12 when enabled.
*/
-static void spc5_icu_channel_enable(ICUDriver *icup, uint8_t index) {
-
- /* Clear pending IRQs (if any).*/
- icup->etimerp->CHANNEL[index].STS.R = 0xFFFF;
-
- /* Set Capture 1 and Capture 2 Mode.*/
- icup->etimerp->CHANNEL[index].CCCTRL.B.CPT1MODE = 0b10;
- icup->etimerp->CHANNEL[index].CCCTRL.B.CPT2MODE = 0b01;
-
- /* Active interrupts.*/
- if (icup->config->period_cb != NULL || icup->config->width_cb != NULL) {
- icup->etimerp->CHANNEL[index].INTDMA.B.ICF1IE = 1U;
- icup->etimerp->CHANNEL[index].INTDMA.B.ICF2IE = 1U;
- }
- if (icup->config->overflow_cb != NULL) {
- icup->etimerp->CHANNEL[index].INTDMA.B.TOFIE = 1U;
- }
-
- /* Set Capture FIFO Water Mark.*/
- icup->etimerp->CHANNEL[index].CCCTRL.B.CFWM = 0b00;
+#if SPC5_ICU_USE_SMOD12 || defined(__DOXYGEN__)
+ICUDriver ICUD13;
+#endif
- /* Enable Counter.*/
- if (ICU_SKIP_FIRST_CAPTURE) {
- icup->etimerp->CHANNEL[index].CTRL.B.CNTMODE = 0b011;
- }
- else {
- icup->etimerp->CHANNEL[index].CTRL.B.CNTMODE = 0b001;
- }
+/**
+ * @brief ICUD14 driver identifier.
+ * @note The driver ICUD14 allocates the complex timer SMD13 when enabled.
+ */
+#if SPC5_ICU_USE_SMOD13 || defined(__DOXYGEN__)
+ICUDriver ICUD14;
+#endif
- /* Enable Capture process.*/
- icup->etimerp->CHANNEL[index].CCCTRL.B.ARM = 1U;
-}
+/**
+ * @brief ICUD15 driver identifier.
+ * @note The driver ICUD15 allocates the complex timer SMD14 when enabled.
+ */
+#if SPC5_ICU_USE_SMOD14 || defined(__DOXYGEN__)
+ICUDriver ICUD15;
+#endif
/**
- * @brief ICU eTimer channel disable.
- *
- * @param[in] icup pointer to the @p ICUDriver object
- * @param[in] index ICU channel index
+ * @brief ICUD16 driver identifier.
+ * @note The driver ICUD16 allocates the complex timer SMD15 when enabled.
*/
-static void spc5_icu_channel_disable(ICUDriver *icup, uint8_t index) {
+#if SPC5_ICU_USE_SMOD15 || defined(__DOXYGEN__)
+ICUDriver ICUD16;
+#endif
- /* Disable Capture process.*/
- icup->etimerp->CHANNEL[index].CCCTRL.B.ARM = 0;
+/**
+ * @brief ICUD17 driver identifier.
+ * @note The driver ICUD17 allocates the complex timer SMD16 when enabled.
+ */
+#if SPC5_ICU_USE_SMOD16 || defined(__DOXYGEN__)
+ICUDriver ICUD17;
+#endif
- /* Clear pending IRQs (if any).*/
- icup->etimerp->CHANNEL[index].STS.R = 0xFFFF;
+/**
+ * @brief ICUD18 driver identifier.
+ * @note The driver ICUD18 allocates the complex timer SMD17 when enabled.
+ */
+#if SPC5_ICU_USE_SMOD17 || defined(__DOXYGEN__)
+ICUDriver ICUD18;
+#endif
- /* Set Capture 1 and Capture 2 Mode to Disabled.*/
- icup->etimerp->CHANNEL[index].CCCTRL.B.CPT1MODE = 0b00;
- icup->etimerp->CHANNEL[index].CCCTRL.B.CPT2MODE = 0b00;
+/*===========================================================================*/
+/* Driver local variables. */
+/*===========================================================================*/
- /* Disable interrupts.*/
- if (icup->config->period_cb != NULL || icup->config->width_cb != NULL) {
- icup->etimerp->CHANNEL[index].INTDMA.B.ICF1IE = 0;
- icup->etimerp->CHANNEL[index].INTDMA.B.ICF2IE = 0;
- }
- if (icup->config->overflow_cb != NULL)
- icup->etimerp->CHANNEL[index].INTDMA.B.TOFIE = 0;
-}
+/*===========================================================================*/
+/* Driver local functions. */
+/*===========================================================================*/
/**
- * @brief ICU eTimer channel start.
+ * @brief Shared IRQ handler.
*
* @param[in] icup pointer to the @p ICUDriver object
- * @param[in] index ICU channel index
*/
-static void spc5_icu_channel_start(ICUDriver *icup, uint8_t index) {
-
- /* Timer disabled.*/
- icup->etimerp->CHANNEL[index].CTRL.B.CNTMODE = 0b000;
-
- /* Clear pending IRQs (if any).*/
- icup->etimerp->CHANNEL[index].STS.R = 0xFFFF;
-
- /* All IRQs and DMA requests disabled.*/
- icup->etimerp->CHANNEL[index].INTDMA.R = 0x0000;
-
- /* Compare Load 1 disabled.*/
- icup->etimerp->CHANNEL[index].CCCTRL.B.CLC1 = 0b000;
-
- /* Compare Load 2 disabled.*/
- icup->etimerp->CHANNEL[index].CCCTRL.B.CLC2 = 0b000;
-
- /* Capture 1 disabled.*/
- icup->etimerp->CHANNEL[index].CCCTRL.B.CPT1MODE = 0b00;
+static void icu_lld_serve_interrupt(ICUDriver *icup) {
- /* Capture 2 disabled.*/
- icup->etimerp->CHANNEL[index].CCCTRL.B.CPT2MODE = 0b00;
+ uint16_t sr = icup->etimerp->CHANNEL[icup->smod_number].STS.R &
+ icup->etimerp->CHANNEL[icup->smod_number].INTDMA.R;
- /* Counter reset to zero.*/
- icup->etimerp->CHANNEL[index].CNTR.R = 0x0000;
+ if (ICU_SKIP_FIRST_CAPTURE) {
+ if ((sr & 0x0008) != 0) { /* TOF */
+ icup->etimerp->CHANNEL[icup->smod_number].STS.B.TOF = 1U;
+ _icu_isr_invoke_overflow_cb(icup);
+ }
+ if ((sr & 0x0040) != 0) { /* ICF1 */
+ if (icup->etimerp->CHANNEL[icup->smod_number].CTRL.B.CNTMODE == 0b011) {
+ icup->etimerp->CHANNEL[icup->smod_number].STS.B.ICF1 = 1U;
+ icup->etimerp->CHANNEL[icup->smod_number].CTRL.B.CNTMODE = 0b001;
+ }
+ else {
+ icup->etimerp->CHANNEL[icup->smod_number].STS.B.ICF1 = 1U;
+ icup->etimerp->CHANNEL[icup->smod_number].CNTR.R = 0x0000;
+ _icu_isr_invoke_period_cb(icup);
+ }
+ }
+ else if ((sr & 0x0080) != 0) { /* ICF2 */
+ if (icup->etimerp->CHANNEL[icup->smod_number].CTRL.B.CNTMODE == 0b011) {
+ icup->etimerp->CHANNEL[icup->smod_number].STS.B.ICF2 = 1U;
+ icup->etimerp->CHANNEL[icup->smod_number].CNTR.R = 0x0000;
+ }
+ else {
+ icup->etimerp->CHANNEL[icup->smod_number].STS.B.ICF2 = 1U;
+ _icu_isr_invoke_width_cb(icup);
+ }
+ }
+ } else { /* ICU_SKIP_FIRST_CAPTURE = TRUE*/
+ if ((sr & 0x0008) != 0) { /* TOF */
+ icup->etimerp->CHANNEL[icup->smod_number].STS.B.TOF = 1U;
+ _icu_isr_invoke_overflow_cb(icup);
+ }
+ if ((sr & 0x0040) != 0) { /* ICF1 */
+ icup->etimerp->CHANNEL[icup->smod_number].STS.B.ICF1 = 1U;
+ icup->etimerp->CHANNEL[icup->smod_number].CNTR.R = 0x0000;
+ _icu_isr_invoke_period_cb(icup);
+ }
+ else if ((sr & 0x0080) != 0) { /* ICF2 */
+ icup->etimerp->CHANNEL[icup->smod_number].STS.B.ICF2 = 1U;
+ _icu_isr_invoke_width_cb(icup);
+ }
+ } /* ICU_SKIP_FIRST_CAPTURE = FALSE */
}
/**
- * @brief ICU eTimer channel initialization.
+ * @brief eTimer SubModules initialization.
+ * @details This function must be invoked with interrupts disabled.
*
- * @param[in] icup pointer to the @p ICUDriver object
- * @param[in] index ICU channel index
+ * @param[in] sdp pointer to a @p ICUDriver object
+ * @param[in] config the architecture-dependent ICU driver configuration
*/
-static void spc5_icu_channel_init(ICUDriver *icup, uint8_t index) {
-
-#if !defined(psc)
- uint32_t psc;
-#endif
- psc = (icup->clock / icup->config->frequency);
+static void spc5_icu_smod_init(ICUDriver *icup) {
+ uint32_t psc = (icup->clock / icup->config->frequency);
chDbgAssert((psc <= 0xFFFF) &&
(((psc) * icup->config->frequency) == icup->clock) &&
((psc == 1) || (psc == 2) || (psc == 4) ||
@@ -258,304 +257,74 @@ static void spc5_icu_channel_init(ICUDriver *icup, uint8_t index) {
/* Set primary source and clock prescaler.*/
switch (psc) {
case 1:
- icup->etimerp->CHANNEL[index].CTRL.B.PRISRC = 0b11000;
+ icup->etimerp->CHANNEL[icup->smod_number].CTRL.B.PRISRC = 0b11000;
break;
case 2:
- icup->etimerp->CHANNEL[index].CTRL.B.PRISRC = 0b11001;
+ icup->etimerp->CHANNEL[icup->smod_number].CTRL.B.PRISRC = 0b11001;
break;
case 4:
- icup->etimerp->CHANNEL[index].CTRL.B.PRISRC = 0b11010;
+ icup->etimerp->CHANNEL[icup->smod_number].CTRL.B.PRISRC = 0b11010;
break;
case 8:
- icup->etimerp->CHANNEL[index].CTRL.B.PRISRC = 0b11011;
+ icup->etimerp->CHANNEL[icup->smod_number].CTRL.B.PRISRC = 0b11011;
break;
case 16:
- icup->etimerp->CHANNEL[index].CTRL.B.PRISRC = 0b11100;
+ icup->etimerp->CHANNEL[icup->smod_number].CTRL.B.PRISRC = 0b11100;
break;
case 32:
- icup->etimerp->CHANNEL[index].CTRL.B.PRISRC = 0b11101;
+ icup->etimerp->CHANNEL[icup->smod_number].CTRL.B.PRISRC = 0b11101;
break;
case 64:
- icup->etimerp->CHANNEL[index].CTRL.B.PRISRC = 0b11110;
+ icup->etimerp->CHANNEL[icup->smod_number].CTRL.B.PRISRC = 0b11110;
break;
case 128:
- icup->etimerp->CHANNEL[index].CTRL.B.PRISRC = 0b11111;
+ icup->etimerp->CHANNEL[icup->smod_number].CTRL.B.PRISRC = 0b11111;
break;
}
/* Set control registers.*/
- icup->etimerp->CHANNEL[index].CTRL.B.ONCE = 0;
- icup->etimerp->CHANNEL[index].CTRL.B.LENGTH = 0;
- icup->etimerp->CHANNEL[index].CTRL.B.DIR = 0;
- icup->etimerp->CHANNEL[index].CTRL2.B.PIPS = 0;
+ icup->etimerp->CHANNEL[icup->smod_number].CTRL.B.ONCE = 0;
+ icup->etimerp->CHANNEL[icup->smod_number].CTRL.B.LENGTH = 0;
+ icup->etimerp->CHANNEL[icup->smod_number].CTRL.B.DIR = 0;
+ icup->etimerp->CHANNEL[icup->smod_number].CTRL2.B.PIPS = 0;
/* Set secondary source.*/
switch (icup->config->channel) {
case ICU_CHANNEL_1:
- icup->etimerp->CHANNEL[index].CTRL.B.SECSRC = 0b00000;
+ icup->etimerp->CHANNEL[icup->smod_number].CTRL.B.SECSRC = 0b00000;
break;
case ICU_CHANNEL_2:
- icup->etimerp->CHANNEL[index].CTRL.B.SECSRC = 0b00001;
+ icup->etimerp->CHANNEL[icup->smod_number].CTRL.B.SECSRC = 0b00001;
break;
case ICU_CHANNEL_3:
- icup->etimerp->CHANNEL[index].CTRL.B.SECSRC = 0b00010;
+ icup->etimerp->CHANNEL[icup->smod_number].CTRL.B.SECSRC = 0b00010;
break;
case ICU_CHANNEL_4:
- icup->etimerp->CHANNEL[index].CTRL.B.SECSRC = 0b00011;
+ icup->etimerp->CHANNEL[icup->smod_number].CTRL.B.SECSRC = 0b00011;
break;
case ICU_CHANNEL_5:
- icup->etimerp->CHANNEL[index].CTRL.B.SECSRC = 0b00100;
+ icup->etimerp->CHANNEL[icup->smod_number].CTRL.B.SECSRC = 0b00100;
break;
case ICU_CHANNEL_6:
- icup->etimerp->CHANNEL[index].CTRL.B.SECSRC = 0b00101;
+ icup->etimerp->CHANNEL[icup->smod_number].CTRL.B.SECSRC = 0b00101;
break;
}
/* Set secondary source polarity.*/
if (icup->config->mode == ICU_INPUT_ACTIVE_HIGH) {
- icup->etimerp->CHANNEL[index].CTRL2.B.SIPS = 0;
+ icup->etimerp->CHANNEL[icup->smod_number].CTRL2.B.SIPS = 0;
}
else {
- icup->etimerp->CHANNEL[index].CTRL2.B.SIPS = 1U;
+ icup->etimerp->CHANNEL[icup->smod_number].CTRL2.B.SIPS = 1U;
}
/* Direct pointers to the capture registers in order to make reading
data faster from within callbacks.*/
- icup->pccrp = &icup->etimerp->CHANNEL[index].CAPT1.R;
- icup->wccrp = &icup->etimerp->CHANNEL[index].CAPT2.R;
+ icup->pccrp = &icup->etimerp->CHANNEL[icup->smod_number].CAPT1.R;
+ icup->wccrp = &icup->etimerp->CHANNEL[icup->smod_number].CAPT2.R;
/* Enable channel.*/
- icup->etimerp->ENBL.B.ENBL |= 1U << index;
-}
-
-/**
- * @brief Interrupt Management.
- *
- * @param[in] icup pointer to the @p ICUDriver object
- * @param[in] index ICU channel index
- */
-static void icu_lld_interrupt_management(ICUDriver *icup, uint8_t index) {
-
-#if !defined(sr)
- uint16_t sr;
-#endif
- sr = icup->etimerp->CHANNEL[index].STS.R
- & icup->etimerp->CHANNEL[index].INTDMA.R;
- if (ICU_SKIP_FIRST_CAPTURE) {
- if ((sr & 0x0008) != 0) { /* TOF */
- icup->etimerp->CHANNEL[index].STS.B.TOF = 1U;
- _icu_isr_invoke_overflow_cb(icup);
- }
- if ((sr & 0x0040) != 0) { /* ICF1 */
- if (icup->etimerp->CHANNEL[index].CTRL.B.CNTMODE == 0b011) {
- icup->etimerp->CHANNEL[index].STS.B.ICF1 = 1U;
- icup->etimerp->CHANNEL[index].CTRL.B.CNTMODE = 0b001;
- }
- else {
- icup->etimerp->CHANNEL[index].STS.B.ICF1 = 1U;
- icup->etimerp->CHANNEL[index].CNTR.R = 0x0000;
- _icu_isr_invoke_period_cb(icup);
- }
- }
- else if ((sr & 0x0080) != 0) { /* ICF2 */
- if (icup->etimerp->CHANNEL[index].CTRL.B.CNTMODE == 0b011) {
- icup->etimerp->CHANNEL[index].STS.B.ICF2 = 1U;
- icup->etimerp->CHANNEL[index].CNTR.R = 0x0000;
- }
- else {
- icup->etimerp->CHANNEL[index].STS.B.ICF2 = 1U;
- _icu_isr_invoke_width_cb(icup);
- }
- }
- } else { /* ICU_SKIP_FIRST_CAPTURE = TRUE*/
- if ((sr & 0x0008) != 0) { /* TOF */
- icup->etimerp->CHANNEL[index].STS.B.TOF = 1U;
- _icu_isr_invoke_overflow_cb(icup);
- }
- if ((sr & 0x0040) != 0) { /* ICF1 */
- icup->etimerp->CHANNEL[index].STS.B.ICF1 = 1U;
- icup->etimerp->CHANNEL[index].CNTR.R = 0x0000;
- _icu_isr_invoke_period_cb(icup);
- }
- else if ((sr & 0x0080) != 0) { /* ICF2 */
- icup->etimerp->CHANNEL[index].STS.B.ICF2 = 1U;
- _icu_isr_invoke_width_cb(icup);
- }
- } /* ICU_SKIP_FIRST_CAPTURE = FALSE */
-}
-
-/**
- * @brief Shared IRQ handler.
- *
- * @param[in] icup pointer to the @p ICUDriver object
- */
-static void icu_lld_serve_interrupt(ICUDriver *icup) {
-
-#if SPC5_ICU_USE_SMOD0
- if (&ICUD1 == icup) {
- icu_lld_interrupt_management(icup, 0);
- }
-#endif
-
-#if SPC5_ICU_USE_SMOD1
- if (&ICUD2 == icup) {
- icu_lld_interrupt_management(icup, 1);
- }
-#endif
-
-#if SPC5_ICU_USE_SMOD2
- if (&ICUD3 == icup) {
- icu_lld_interrupt_management(icup, 2);
- }
-#endif
-
-#if SPC5_ICU_USE_SMOD3
- if (&ICUD4 == icup) {
- icu_lld_interrupt_management(icup, 3);
- }
-#endif
-
-#if SPC5_ICU_USE_SMOD4
- if (&ICUD5 == icup) {
- icu_lld_interrupt_management(icup, 4);
- }
-#endif
-
-#if SPC5_ICU_USE_SMOD5
- if (&ICUD6 == icup) {
- icu_lld_interrupt_management(icup, 5);
- }
-#endif
-
-#if SPC5_ICU_USE_SMOD6
- if (&ICUD7 == icup) {
- icu_lld_interrupt_management(icup, 0);
- }
-#endif
-
-#if SPC5_ICU_USE_SMOD7
- if (&ICUD8 == icup) {
- icu_lld_interrupt_management(icup, 1);
- }
-#endif
-
-#if SPC5_ICU_USE_SMOD8
- if (&ICUD9 == icup) {
- icu_lld_interrupt_management(icup, 2);
- }
-#endif
-
-#if SPC5_ICU_USE_SMOD9
- if (&ICUD10 == icup) {
- icu_lld_interrupt_management(icup, 3);
- }
-#endif
-
-#if SPC5_ICU_USE_SMOD10
- if (&ICUD11 == icup) {
- icu_lld_interrupt_management(icup, 4);
- }
-#endif
-
-#if SPC5_ICU_USE_SMOD11
- if (&ICUD12 == icup) {
- icu_lld_interrupt_management(icup, 5);
- }
-#endif
-}
-
-/**
- * @brief eTimer SubModules initialization.
- * @details This function must be invoked with interrupts disabled.
- *
- * @param[in] sdp pointer to a @p ICUDriver object
- * @param[in] config the architecture-dependent ICU driver configuration
- */
-static void spc5_icu_smod_init(ICUDriver *icup) {
-
-#if SPC5_ICU_USE_SMOD0
- if (&ICUD1 == icup) {
- icup->clock = SPC5_ETIMER0_CLK;
- spc5_icu_channel_init(icup, 0);
- }
-#endif
-
-#if SPC5_ICU_USE_SMOD1
- if (&ICUD2 == icup) {
- icup->clock = SPC5_ETIMER0_CLK;
- spc5_icu_channel_init(icup, 1);
- }
-#endif
-
-#if SPC5_ICU_USE_SMOD2
- if (&ICUD3 == icup) {
- icup->clock = SPC5_ETIMER0_CLK;
- spc5_icu_channel_init(icup, 2);
- }
-#endif
-
-#if SPC5_ICU_USE_SMOD3
- if (&ICUD4 == icup) {
- icup->clock = SPC5_ETIMER0_CLK;
- spc5_icu_channel_init(icup, 3);
- }
-#endif
-
-#if SPC5_ICU_USE_SMOD4
- if (&ICUD5 == icup) {
- icup->clock = SPC5_ETIMER0_CLK;
- spc5_icu_channel_init(icup, 4);
- }
-#endif
-
-#if SPC5_ICU_USE_SMOD5
- if (&ICUD6 == icup) {
- icup->clock = SPC5_ETIMER0_CLK;
- spc5_icu_channel_init(icup, 5);
- }
-#endif
-
-#if SPC5_ICU_USE_SMOD6
- if (&ICUD7 == icup) {
- icup->clock = SPC5_ETIMER1_CLK;
- spc5_icu_channel_init(icup, 0);
- }
-#endif
-
-#if SPC5_ICU_USE_SMOD7
- if (&ICUD8 == icup) {
- icup->clock = SPC5_ETIMER1_CLK;
- spc5_icu_channel_init(icup, 1);
- }
-#endif
-
-#if SPC5_ICU_USE_SMOD8
- if (&ICUD9 == icup) {
- icup->clock = SPC5_ETIMER1_CLK;
- spc5_icu_channel_init(icup, 2);
- }
-#endif
-
-#if SPC5_ICU_USE_SMOD9
- if (&ICUD10 == icup) {
- icup->clock = SPC5_ETIMER1_CLK;
- spc5_icu_channel_init(icup, 3);
- }
-#endif
-
-#if SPC5_ICU_USE_SMOD10
- if (&ICUD11 == icup) {
- icup->clock = SPC5_ETIMER1_CLK;
- spc5_icu_channel_init(icup, 4);
- }
-#endif
-
-#if SPC5_ICU_USE_SMOD11
- if (&ICUD12 == icup) {
- icup->clock = SPC5_ETIMER1_CLK;
- spc5_icu_channel_init(icup, 5);
- }
-#endif
+ icup->etimerp->ENBL.B.ENBL |= 1U << (icup->smod_number);
}
/*===========================================================================*/
@@ -707,9 +476,6 @@ CH_IRQ_HANDLER(SPC5_ETIMER0_TC5IR_HANDLER) {
*/
CH_IRQ_HANDLER(SPC5_ETIMER1_TC0IR_HANDLER) {
-//SIU.PCR[3*16+5].R = 556;
-//SIU.GPDO[3*16+5].R = 0;
-
CH_IRQ_PROLOGUE();
icu_lld_serve_interrupt(&ICUD7);
@@ -764,7 +530,7 @@ CH_IRQ_HANDLER(SPC5_ETIMER1_TC2IR_HANDLER) {
#if SPC5_ICU_USE_SMOD9
#if !defined(SPC5_ETIMER1_TC3IR_HANDLER)
-#error "SPC5_ETIMER0_TC3IR_HANDLER not defined"
+#error "SPC5_ETIMER1_TC3IR_HANDLER not defined"
#endif
/**
* @brief eTimer1 Channel 3 interrupt handler.
@@ -828,6 +594,138 @@ CH_IRQ_HANDLER(SPC5_ETIMER1_TC5IR_HANDLER) {
}
#endif /* SPC5_ICU_USE_SMOD11 */
+#if SPC5_ICU_USE_SMOD12
+#if !defined(SPC5_ETIMER2_TC0IR_HANDLER)
+#error "SPC5_ETIMER2_TC0IR_HANDLER not defined"
+#endif
+/**
+ * @brief eTimer2 Channel 0 interrupt handler.
+ * @note It is assumed that the various sources are only activated if the
+ * associated callback pointer is not equal to @p NULL in order to not
+ * perform an extra check in a potentially critical interrupt handler.
+ *
+ * @isr
+ */
+CH_IRQ_HANDLER(SPC5_ETIMER2_TC0IR_HANDLER) {
+
+ CH_IRQ_PROLOGUE();
+
+ icu_lld_serve_interrupt(&ICUD13);
+
+ CH_IRQ_EPILOGUE();
+}
+#endif /* SPC5_ICU_USE_SMOD12 */
+
+#if SPC5_ICU_USE_SMOD13
+#if !defined(SPC5_ETIMER2_TC1IR_HANDLER)
+#error "SPC5_ETIMER2_TC1IR_HANDLER not defined"
+#endif
+/**
+ * @brief eTimer2 Channel 1 interrupt handler.
+ * @note It is assumed that the various sources are only activated if the
+ * associated callback pointer is not equal to @p NULL in order to not
+ * perform an extra check in a potentially critical interrupt handler.
+ *
+ * @isr
+ */
+CH_IRQ_HANDLER(SPC5_ETIMER2_TC1IR_HANDLER) {
+
+ CH_IRQ_PROLOGUE();
+
+ icu_lld_serve_interrupt(&ICUD14);
+
+ CH_IRQ_EPILOGUE();
+}
+#endif /* SPC5_ICU_USE_SMOD13 */
+
+#if SPC5_ICU_USE_SMOD14
+#if !defined(SPC5_ETIMER2_TC2IR_HANDLER)
+#error "SPC5_ETIMER2_TC2IR_HANDLER not defined"
+#endif
+/**
+ * @brief eTimer2 Channel 2 interrupt handler.
+ * @note It is assumed that the various sources are only activated if the
+ * associated callback pointer is not equal to @p NULL in order to not
+ * perform an extra check in a potentially critical interrupt handler.
+ *
+ * @isr
+ */
+CH_IRQ_HANDLER(SPC5_ETIMER2_TC2IR_HANDLER) {
+
+ CH_IRQ_PROLOGUE();
+
+ icu_lld_serve_interrupt(&ICUD15);
+
+ CH_IRQ_EPILOGUE();
+}
+#endif /* SPC5_ICU_USE_SMOD14 */
+
+#if SPC5_ICU_USE_SMOD15
+#if !defined(SPC5_ETIMER2_TC3IR_HANDLER)
+#error "SPC5_ETIMER2_TC3IR_HANDLER not defined"
+#endif
+/**
+ * @brief eTimer2 Channel 3 interrupt handler.
+ * @note It is assumed that the various sources are only activated if the
+ * associated callback pointer is not equal to @p NULL in order to not
+ * perform an extra check in a potentially critical interrupt handler.
+ *
+ * @isr
+ */
+CH_IRQ_HANDLER(SPC5_ETIMER2_TC3IR_HANDLER) {
+
+ CH_IRQ_PROLOGUE();
+
+ icu_lld_serve_interrupt(&ICUD16);
+
+ CH_IRQ_EPILOGUE();
+}
+#endif /* SPC5_ICU_USE_SMOD15 */
+
+#if SPC5_ICU_USE_SMOD16
+#if !defined(SPC5_ETIMER2_TC4IR_HANDLER)
+#error "SPC5_ETIMER2_TC4IR_HANDLER not defined"
+#endif
+/**
+ * @brief eTimer2 Channel 4 interrupt handler.
+ * @note It is assumed that the various sources are only activated if the
+ * associated callback pointer is not equal to @p NULL in order to not
+ * perform an extra check in a potentially critical interrupt handler.
+ *
+ * @isr
+ */
+CH_IRQ_HANDLER(SPC5_ETIMER2_TC4IR_HANDLER) {
+
+ CH_IRQ_PROLOGUE();
+
+ icu_lld_serve_interrupt(&ICUD17);
+
+ CH_IRQ_EPILOGUE();
+}
+#endif /* SPC5_ICU_USE_SMOD16 */
+
+#if SPC5_ICU_USE_SMOD17
+#if !defined(SPC5_ETIMER2_TC5IR_HANDLER)
+#error "SPC5_ETIMER2_TC5IR_HANDLER not defined"
+#endif
+/**
+ * @brief eTimer2 Channel 5 interrupt handler.
+ * @note It is assumed that the various sources are only activated if the
+ * associated callback pointer is not equal to @p NULL in order to not
+ * perform an extra check in a potentially critical interrupt handler.
+ *
+ * @isr
+ */
+CH_IRQ_HANDLER(SPC5_ETIMER2_TC5IR_HANDLER) {
+
+ CH_IRQ_PROLOGUE();
+
+ icu_lld_serve_interrupt(&ICUD18);
+
+ CH_IRQ_EPILOGUE();
+}
+#endif /* SPC5_ICU_USE_SMOD17 */
+
/*===========================================================================*/
/* Driver exported functions. */
/*===========================================================================*/
@@ -843,72 +741,126 @@ void icu_lld_init(void) {
/* Driver initialization.*/
icuObjectInit(&ICUD1);
ICUD1.etimerp = &ETIMER_0;
+ ICUD1.smod_number = 0;
#endif
#if SPC5_ICU_USE_SMOD1
/* Driver initialization.*/
icuObjectInit(&ICUD2);
ICUD2.etimerp = &ETIMER_0;
+ ICUD2.smod_number = 1;
#endif
#if SPC5_ICU_USE_SMOD2
/* Driver initialization.*/
icuObjectInit(&ICUD3);
ICUD3.etimerp = &ETIMER_0;
+ ICUD3.smod_number = 2;
#endif
#if SPC5_ICU_USE_SMOD3
/* Driver initialization.*/
icuObjectInit(&ICUD4);
ICUD4.etimerp = &ETIMER_0;
+ ICUD4.smod_number = 3;
#endif
#if SPC5_ICU_USE_SMOD4
/* Driver initialization.*/
icuObjectInit(&ICUD5);
ICUD5.etimerp = &ETIMER_0;
+ ICUD5.smod_number = 4;
#endif
#if SPC5_ICU_USE_SMOD5
/* Driver initialization.*/
icuObjectInit(&ICUD6);
ICUD6.etimerp = &ETIMER_0;
+ ICUD6.smod_number = 5;
#endif
#if SPC5_ICU_USE_SMOD6
/* Driver initialization.*/
icuObjectInit(&ICUD7);
ICUD7.etimerp = &ETIMER_1;
+ ICUD7.smod_number = 0;
#endif
#if SPC5_ICU_USE_SMOD7
/* Driver initialization.*/
icuObjectInit(&ICUD8);
ICUD8.etimerp = &ETIMER_1;
+ ICUD8.smod_number = 1;
#endif
#if SPC5_ICU_USE_SMOD8
/* Driver initialization.*/
icuObjectInit(&ICUD9);
ICUD9.etimerp = &ETIMER_1;
+ ICUD9.smod_number = 2;
#endif
#if SPC5_ICU_USE_SMOD9
/* Driver initialization.*/
icuObjectInit(&ICUD10);
ICUD10.etimerp = &ETIMER_1;
+ ICUD10.smod_number = 3;
#endif
#if SPC5_ICU_USE_SMOD10
/* Driver initialization.*/
icuObjectInit(&ICUD11);
ICUD11.etimerp = &ETIMER_1;
+ ICUD11.smod_number = 4;
#endif
#if SPC5_ICU_USE_SMOD11
/* Driver initialization.*/
icuObjectInit(&ICUD12);
ICUD12.etimerp = &ETIMER_1;
+ ICUD12.smod_number = 5;
+#endif
+
+#if SPC5_ICU_USE_SMOD12
+ /* Driver initialization.*/
+ icuObjectInit(&ICUD13);
+ ICUD13.etimerp = &ETIMER_2;
+ ICUD13.smod_number = 0;
+#endif
+
+#if SPC5_ICU_USE_SMOD13
+ /* Driver initialization.*/
+ icuObjectInit(&ICUD14);
+ ICUD14.etimerp = &ETIMER_2;
+ ICUD14.smod_number = 1;
+#endif
+
+#if SPC5_ICU_USE_SMOD14
+ /* Driver initialization.*/
+ icuObjectInit(&ICUD15);
+ ICUD15.etimerp = &ETIMER_2;
+ ICUD15.smod_number = 2;
+#endif
+
+#if SPC5_ICU_USE_SMOD15
+ /* Driver initialization.*/
+ icuObjectInit(&ICUD16);
+ ICUD16.etimerp = &ETIMER_2;
+ ICUD16.smod_number = 3;
+#endif
+
+#if SPC5_ICU_USE_SMOD16
+ /* Driver initialization.*/
+ icuObjectInit(&ICUD17);
+ ICUD17.etimerp = &ETIMER_2;
+ ICUD17.smod_number = 4;
+#endif
+
+#if SPC5_ICU_USE_SMOD17
+ /* Driver initialization.*/
+ icuObjectInit(&ICUD18);
+ ICUD18.etimerp = &ETIMER_2;
+ ICUD18.smod_number = 5;
#endif
#if SPC5_ICU_USE_SMOD0 || SPC5_ICU_USE_SMOD1 || \
@@ -939,6 +891,20 @@ void icu_lld_init(void) {
INTC.PSR[SPC5_ETIMER1_RCF_NUMBER].R = SPC5_ICU_ETIMER1_PRIORITY;
#endif
+
+#if SPC5_ICU_USE_SMOD12 || SPC5_ICU_USE_SMOD13 || \
+ SPC5_ICU_USE_SMOD14 || SPC5_ICU_USE_SMOD15 || \
+ SPC5_ICU_USE_SMOD16 || SPC5_ICU_USE_SMOD17
+
+ INTC.PSR[SPC5_ETIMER2_TC0IR_NUMBER].R = SPC5_ICU_ETIMER2_PRIORITY;
+ INTC.PSR[SPC5_ETIMER2_TC1IR_NUMBER].R = SPC5_ICU_ETIMER2_PRIORITY;
+ INTC.PSR[SPC5_ETIMER2_TC2IR_NUMBER].R = SPC5_ICU_ETIMER2_PRIORITY;
+ INTC.PSR[SPC5_ETIMER2_TC3IR_NUMBER].R = SPC5_ICU_ETIMER2_PRIORITY;
+ INTC.PSR[SPC5_ETIMER2_TC4IR_NUMBER].R = SPC5_ICU_ETIMER2_PRIORITY;
+ INTC.PSR[SPC5_ETIMER2_TC5IR_NUMBER].R = SPC5_ICU_ETIMER2_PRIORITY;
+ INTC.PSR[SPC5_ETIMER2_RCF_NUMBER].R = SPC5_ICU_ETIMER2_PRIORITY;
+
+#endif
}
/**
@@ -958,7 +924,7 @@ void icu_lld_start(ICUDriver *icup) {
(icup->config->channel == ICU_CHANNEL_6),
"icu_lld_start(), #1", "invalid input");
-#if SPC5_ICU_USE_SMOD0 || SPC5_ICU_USE_SMOD1 || SPC5_ICU_USE_SMOD2 || \
+#if SPC5_ICU_USE_SMOD0 || SPC5_ICU_USE_SMOD1 || SPC5_ICU_USE_SMOD2 || \
SPC5_ICU_USE_SMOD3 || SPC5_ICU_USE_SMOD4 || SPC5_ICU_USE_SMOD5
uint8_t SMOD0 = 0;
uint8_t SMOD1 = 0;
@@ -968,7 +934,7 @@ void icu_lld_start(ICUDriver *icup) {
uint8_t SMOD5 = 0;
#endif
-#if SPC5_ICU_USE_SMOD6 || SPC5_ICU_USE_SMOD7 || SPC5_ICU_USE_SMOD8 || \
+#if SPC5_ICU_USE_SMOD6 || SPC5_ICU_USE_SMOD7 || SPC5_ICU_USE_SMOD8 || \
SPC5_ICU_USE_SMOD9 || SPC5_ICU_USE_SMOD10 || SPC5_ICU_USE_SMOD11
uint8_t SMOD6 = 0;
uint8_t SMOD7 = 0;
@@ -978,6 +944,16 @@ void icu_lld_start(ICUDriver *icup) {
uint8_t SMOD11 = 0;
#endif
+#if SPC5_ICU_USE_SMOD12 || SPC5_ICU_USE_SMOD13 || SPC5_ICU_USE_SMOD14 || \
+ SPC5_ICU_USE_SMOD15 || SPC5_ICU_USE_SMOD16 || SPC5_ICU_USE_SMOD17
+ uint8_t SMOD12 = 0;
+ uint8_t SMOD13 = 0;
+ uint8_t SMOD14 = 0;
+ uint8_t SMOD15 = 0;
+ uint8_t SMOD16 = 0;
+ uint8_t SMOD17 = 0;
+#endif
+
#if SPC5_ICU_USE_SMOD0
if (ICUD1.state == ICU_READY)
SMOD0 = 1U;
@@ -1026,6 +1002,30 @@ void icu_lld_start(ICUDriver *icup) {
if (ICUD12.state == ICU_READY)
SMOD11 = 1U;
#endif
+#if SPC5_ICU_USE_SMOD12
+ if (ICUD13.state == ICU_READY)
+ SMOD12 = 1U;
+#endif
+#if SPC5_ICU_USE_SMOD13
+ if (ICUD14.state == ICU_READY)
+ SMOD13 = 1U;
+#endif
+#if SPC5_ICU_USE_SMOD14
+ if (ICUD15.state == ICU_READY)
+ SMOD14 = 1U;
+#endif
+#if SPC5_ICU_USE_SMOD15
+ if (ICUD16.state == ICU_READY)
+ SMOD15 = 1U;
+#endif
+#if SPC5_ICU_USE_SMOD16
+ if (ICUD17.state == ICU_READY)
+ SMOD16 = 1U;
+#endif
+#if SPC5_ICU_USE_SMOD17
+ if (ICUD18.state == ICU_READY)
+ SMOD17 = 1U;
+#endif
#if SPC5_ICU_USE_SMOD0 || SPC5_ICU_USE_SMOD1 || SPC5_ICU_USE_SMOD2 || \
SPC5_ICU_USE_SMOD3 || SPC5_ICU_USE_SMOD4 || SPC5_ICU_USE_SMOD5
@@ -1043,72 +1043,41 @@ void icu_lld_start(ICUDriver *icup) {
SPC5_ICU_ETIMER1_START_PCTL);
}
#endif
-
- /* Disable all channels.*/
- //icup->etimerp->ENBL.B.ENBL = 0x00;
+#if SPC5_ICU_USE_SMOD12 || SPC5_ICU_USE_SMOD13 || SPC5_ICU_USE_SMOD14 || \
+ SPC5_ICU_USE_SMOD15 || SPC5_ICU_USE_SMOD16 || SPC5_ICU_USE_SMOD17
+ /* Set Peripheral Clock.*/
+ if (!(SMOD12 || SMOD13 || SMOD14 || SMOD15 || SMOD16 || SMOD17)) {
+ halSPCSetPeripheralClockMode(SPC5_ETIMER2_PCTL,
+ SPC5_ICU_ETIMER2_START_PCTL);
+ }
+#endif
if (icup->state == ICU_STOP) {
-#if SPC5_ICU_USE_SMOD0
- if (&ICUD1 == icup) {
- spc5_icu_channel_start(icup, 0);
- }
-#endif
-#if SPC5_ICU_USE_SMOD1
- if (&ICUD2 == icup) {
- spc5_icu_channel_start(icup, 1);
- }
-#endif
-#if SPC5_ICU_USE_SMOD2
- if (&ICUD3 == icup) {
- spc5_icu_channel_start(icup, 2);
- }
-#endif
-#if SPC5_ICU_USE_SMOD3
- if (&ICUD4 == icup) {
- spc5_icu_channel_start(icup, 3);
- }
-#endif
-#if SPC5_ICU_USE_SMOD4
- if (&ICUD5 == icup) {
- spc5_icu_channel_start(icup, 4);
- }
-#endif
-#if SPC5_ICU_USE_SMOD5
- if (&ICUD6 == icup) {
- spc5_icu_channel_start(icup, 5);
- }
-#endif
-#if SPC5_ICU_USE_SMOD6
- if (&ICUD7 == icup) {
- spc5_icu_channel_start(icup, 0);
- }
-#endif
-#if SPC5_ICU_USE_SMOD7
- if (&ICUD8 == icup) {
- spc5_icu_channel_start(icup, 1);
- }
-#endif
-#if SPC5_ICU_USE_SMOD8
- if (&ICUD9 == icup) {
- spc5_icu_channel_start(icup, 2);
- }
-#endif
-#if SPC5_ICU_USE_SMOD9
- if (&ICUD10 == icup) {
- spc5_icu_channel_start(icup, 3);
- }
-#endif
-#if SPC5_ICU_USE_SMOD10
- if (&ICUD11 == icup) {
- spc5_icu_channel_start(icup, 4);
- }
-#endif
-#if SPC5_ICU_USE_SMOD11
- if (&ICUD12 == icup) {
- spc5_icu_channel_start(icup, 5);
- }
-#endif
+ /* Timer disabled.*/
+ icup->etimerp->CHANNEL[icup->smod_number].CTRL.B.CNTMODE = 0b000;
+
+ /* Clear pending IRQs (if any).*/
+ icup->etimerp->CHANNEL[icup->smod_number].STS.R = 0xFFFF;
+
+ /* All IRQs and DMA requests disabled.*/
+ icup->etimerp->CHANNEL[icup->smod_number].INTDMA.R = 0x0000;
+
+ /* Compare Load 1 disabled.*/
+ icup->etimerp->CHANNEL[icup->smod_number].CCCTRL.B.CLC1 = 0b000;
+
+ /* Compare Load 2 disabled.*/
+ icup->etimerp->CHANNEL[icup->smod_number].CCCTRL.B.CLC2 = 0b000;
+
+ /* Capture 1 disabled.*/
+ icup->etimerp->CHANNEL[icup->smod_number].CCCTRL.B.CPT1MODE = 0b00;
+
+ /* Capture 2 disabled.*/
+ icup->etimerp->CHANNEL[icup->smod_number].CCCTRL.B.CPT2MODE = 0b00;
+
+ /* Counter reset to zero.*/
+ icup->etimerp->CHANNEL[icup->smod_number].CNTR.R = 0x0000;
}
+
/* Configuration.*/
spc5_icu_smod_init(icup);
}
@@ -1124,7 +1093,7 @@ void icu_lld_stop(ICUDriver *icup) {
if (icup->state == ICU_READY) {
-#if SPC5_ICU_USE_SMOD0 || SPC5_ICU_USE_SMOD1 || SPC5_ICU_USE_SMOD2 || \
+#if SPC5_ICU_USE_SMOD0 || SPC5_ICU_USE_SMOD1 || SPC5_ICU_USE_SMOD2 || \
SPC5_ICU_USE_SMOD3 || SPC5_ICU_USE_SMOD4 || SPC5_ICU_USE_SMOD5
uint8_t SMOD0 = 0;
uint8_t SMOD1 = 0;
@@ -1134,7 +1103,7 @@ void icu_lld_stop(ICUDriver *icup) {
uint8_t SMOD5 = 0;
#endif
-#if SPC5_ICU_USE_SMOD6 || SPC5_ICU_USE_SMOD7 || SPC5_ICU_USE_SMOD8 || \
+#if SPC5_ICU_USE_SMOD6 || SPC5_ICU_USE_SMOD7 || SPC5_ICU_USE_SMOD8 || \
SPC5_ICU_USE_SMOD9 || SPC5_ICU_USE_SMOD10 || SPC5_ICU_USE_SMOD11
uint8_t SMOD6 = 0;
uint8_t SMOD7 = 0;
@@ -1144,6 +1113,16 @@ void icu_lld_stop(ICUDriver *icup) {
uint8_t SMOD11 = 0;
#endif
+#if SPC5_ICU_USE_SMOD12 || SPC5_ICU_USE_SMOD13 || SPC5_ICU_USE_SMOD14 || \
+ SPC5_ICU_USE_SMOD15 || SPC5_ICU_USE_SMOD16 || SPC5_ICU_USE_SMOD17
+ uint8_t SMOD12 = 0;
+ uint8_t SMOD13 = 0;
+ uint8_t SMOD14 = 0;
+ uint8_t SMOD15 = 0;
+ uint8_t SMOD16 = 0;
+ uint8_t SMOD17 = 0;
+#endif
+
#if SPC5_ICU_USE_SMOD0
if (&ICUD1 == icup) {
/* Disable channel.*/
@@ -1228,8 +1207,50 @@ void icu_lld_stop(ICUDriver *icup) {
SMOD11 = 1U;
}
#endif
+#if SPC5_ICU_USE_SMOD12
+ if (&ICUD13 == icup) {
+ /* Disable channel.*/
+ icup->etimerp->ENBL.B.ENBL &= 0b11111110;
+ SMOD12 = 1U;
+ }
+#endif
+#if SPC5_ICU_USE_SMOD13
+ if (&ICUD14 == icup) {
+ /* Disable channel.*/
+ icup->etimerp->ENBL.B.ENBL &= 0b11111101;
+ SMOD13 = 1U;
+ }
+#endif
+#if SPC5_ICU_USE_SMOD14
+ if (&ICUD15 == icup) {
+ /* Disable channel.*/
+ icup->etimerp->ENBL.B.ENBL &= 0b11111011;
+ SMOD14 = 1U;
+ }
+#endif
+#if SPC5_ICU_USE_SMOD15
+ if (&ICUD16 == icup) {
+ /* Disable channel.*/
+ icup->etimerp->ENBL.B.ENBL &= 0b11110111;
+ SMOD5 = 1U;
+ }
+#endif
+#if SPC5_ICU_USE_SMOD16
+ if (&ICUD17 == icup) {
+ /* Disable channel.*/
+ icup->etimerp->ENBL.B.ENBL &= 0b11101111;
+ SMOD16 = 1U;
+ }
+#endif
+#if SPC5_ICU_USE_SMOD17
+ if (&ICUD18 == icup) {
+ /* Disable channel.*/
+ icup->etimerp->ENBL.B.ENBL &= 0b11011111;
+ SMOD17 = 1U;
+ }
+#endif
-#if SPC5_ICU_USE_SMOD0 || SPC5_ICU_USE_SMOD1 || SPC5_ICU_USE_SMOD2 || \
+#if SPC5_ICU_USE_SMOD0 || SPC5_ICU_USE_SMOD1 || SPC5_ICU_USE_SMOD2 || \
SPC5_ICU_USE_SMOD3 || SPC5_ICU_USE_SMOD4 || SPC5_ICU_USE_SMOD5
if (SMOD0 || SMOD1 || SMOD2 || SMOD3 || SMOD4 || SMOD5) {
/* Clock deactivation.*/
@@ -1240,7 +1261,7 @@ void icu_lld_stop(ICUDriver *icup) {
}
#endif
-#if SPC5_ICU_USE_SMOD6 || SPC5_ICU_USE_SMOD7 || SPC5_ICU_USE_SMOD8 || \
+#if SPC5_ICU_USE_SMOD6 || SPC5_ICU_USE_SMOD7 || SPC5_ICU_USE_SMOD8 || \
SPC5_ICU_USE_SMOD9 || SPC5_ICU_USE_SMOD10 || SPC5_ICU_USE_SMOD11
if (SMOD6 || SMOD7 || SMOD8 || SMOD9 || SMOD10 || SMOD11) {
/* Clock deactivation.*/
@@ -1250,6 +1271,17 @@ void icu_lld_stop(ICUDriver *icup) {
}
}
#endif
+
+#if SPC5_ICU_USE_SMOD12 || SPC5_ICU_USE_SMOD13 || SPC5_ICU_USE_SMOD14 || \
+ SPC5_ICU_USE_SMOD15 || SPC5_ICU_USE_SMOD16 || SPC5_ICU_USE_SMOD17
+ if (SMOD12 || SMOD13 || SMOD14 || SMOD15 || SMOD16 || SMOD17) {
+ /* Clock deactivation.*/
+ if (icup->etimerp->ENBL.B.ENBL == 0x00) {
+ halSPCSetPeripheralClockMode(SPC5_ETIMER2_PCTL,
+ SPC5_ICU_ETIMER2_STOP_PCTL);
+ }
+ }
+#endif
}
}
@@ -1262,77 +1294,35 @@ void icu_lld_stop(ICUDriver *icup) {
*/
void icu_lld_enable(ICUDriver *icup) {
-#if SPC5_ICU_USE_SMOD0
- if (&ICUD1 == icup) {
- spc5_icu_channel_enable(icup, 0);
- }
-#endif
-
-#if SPC5_ICU_USE_SMOD1
- if (&ICUD2 == icup) {
- spc5_icu_channel_enable(icup, 1);
- }
-#endif
-
-#if SPC5_ICU_USE_SMOD2
- if (&ICUD3 == icup) {
- spc5_icu_channel_enable(icup, 2);
- }
-#endif
-
-#if SPC5_ICU_USE_SMOD3
- if (&ICUD4 == icup) {
- spc5_icu_channel_enable(icup, 3);
- }
-#endif
-
-#if SPC5_ICU_USE_SMOD4
- if (&ICUD5 == icup) {
- spc5_icu_channel_enable(icup, 4);
- }
-#endif
+ /* Clear pending IRQs (if any).*/
+ icup->etimerp->CHANNEL[icup->smod_number].STS.R = 0xFFFF;
-#if SPC5_ICU_USE_SMOD5
- if (&ICUD6 == icup) {
- spc5_icu_channel_enable(icup, 5);
- }
-#endif
+ /* Set Capture 1 and Capture 2 Mode.*/
+ icup->etimerp->CHANNEL[icup->smod_number].CCCTRL.B.CPT1MODE = 0b10;
+ icup->etimerp->CHANNEL[icup->smod_number].CCCTRL.B.CPT2MODE = 0b01;
-#if SPC5_ICU_USE_SMOD6
- if (&ICUD7 == icup) {
- spc5_icu_channel_enable(icup, 0);
+ /* Active interrupts.*/
+ if (icup->config->period_cb != NULL || icup->config->width_cb != NULL) {
+ icup->etimerp->CHANNEL[icup->smod_number].INTDMA.B.ICF1IE = 1U;
+ icup->etimerp->CHANNEL[icup->smod_number].INTDMA.B.ICF2IE = 1U;
}
-#endif
-
-#if SPC5_ICU_USE_SMOD7
- if (&ICUD8 == icup) {
- spc5_icu_channel_enable(icup, 1);
+ if (icup->config->overflow_cb != NULL) {
+ icup->etimerp->CHANNEL[icup->smod_number].INTDMA.B.TOFIE = 1U;
}
-#endif
-#if SPC5_ICU_USE_SMOD8
- if (&ICUD9 == icup) {
- spc5_icu_channel_enable(icup, 2);
- }
-#endif
+ /* Set Capture FIFO Water Mark.*/
+ icup->etimerp->CHANNEL[icup->smod_number].CCCTRL.B.CFWM = 0b00;
-#if SPC5_ICU_USE_SMOD9
- if (&ICUD10 == icup) {
- spc5_icu_channel_enable(icup, 3);
+ /* Enable Counter.*/
+ if (ICU_SKIP_FIRST_CAPTURE) {
+ icup->etimerp->CHANNEL[icup->smod_number].CTRL.B.CNTMODE = 0b011;
}
-#endif
-
-#if SPC5_ICU_USE_SMOD10
- if (&ICUD11 == icup) {
- spc5_icu_channel_enable(icup, 4);
+ else {
+ icup->etimerp->CHANNEL[icup->smod_number].CTRL.B.CNTMODE = 0b001;
}
-#endif
-#if SPC5_ICU_USE_SMOD11
- if (&ICUD12 == icup) {
- spc5_icu_channel_enable(icup, 5);
- }
-#endif
+ /* Enable Capture process.*/
+ icup->etimerp->CHANNEL[icup->smod_number].CCCTRL.B.ARM = 1U;
}
/**
@@ -1344,107 +1334,23 @@ void icu_lld_enable(ICUDriver *icup) {
*/
void icu_lld_disable(ICUDriver *icup) {
-#if SPC5_ICU_USE_SMOD0
- if (&ICUD1 == icup) {
- spc5_icu_channel_disable(icup, 0);
- }
-#endif
-
-#if SPC5_ICU_USE_SMOD1
- if (&ICUD2 == icup) {
- spc5_icu_channel_disable(icup, 1);
- }
-#endif
-
-#if SPC5_ICU_USE_SMOD2
- if (&ICUD3 == icup) {
- spc5_icu_channel_disable(icup, 2);
- }
-#endif
-
-#if SPC5_ICU_USE_SMOD3
- if (&ICUD4 == icup) {
- spc5_icu_channel_disable(icup, 3);
- }
-#endif
-
-#if SPC5_ICU_USE_SMOD4
- if (&ICUD5 == icup) {
- spc5_icu_channel_disable(icup, 4);
- }
-#endif
-
-#if SPC5_ICU_USE_SMOD5
- if (&ICUD6 == icup) {
- spc5_icu_channel_disable(icup, 5);
- }
-#endif
-
-#if SPC5_ICU_USE_SMOD6
- if (&ICUD7 == icup) {
- spc5_icu_channel_disable(icup, 0);
- }
-#endif
-
-#if SPC5_ICU_USE_SMOD7
- if (&ICUD8 == icup) {
- spc5_icu_channel_disable(icup, 1);
- }
-#endif
-
-#if SPC5_ICU_USE_SMOD8
- if (&ICUD9 == icup) {
- spc5_icu_channel_disable(icup, 2);
- }
-#endif
+ /* Disable Capture process.*/
+ icup->etimerp->CHANNEL[icup->smod_number].CCCTRL.B.ARM = 0;
-#if SPC5_ICU_USE_SMOD9
- if (&ICUD10 == icup) {
- spc5_icu_channel_disable(icup, 3);
- }
-#endif
+ /* Clear pending IRQs (if any).*/
+ icup->etimerp->CHANNEL[icup->smod_number].STS.R = 0xFFFF;
-#if SPC5_ICU_USE_SMOD10
- if (&ICUD11 == icup) {
- spc5_icu_channel_disable(icup, 4);
- }
-#endif
+ /* Set Capture 1 and Capture 2 Mode to Disabled.*/
+ icup->etimerp->CHANNEL[icup->smod_number].CCCTRL.B.CPT1MODE = 0b00;
+ icup->etimerp->CHANNEL[icup->smod_number].CCCTRL.B.CPT2MODE = 0b00;
-#if SPC5_ICU_USE_SMOD11
- if (&ICUD12 == icup) {
- spc5_icu_channel_disable(icup, 5);
+ /* Disable interrupts.*/
+ if (icup->config->period_cb != NULL || icup->config->width_cb != NULL) {
+ icup->etimerp->CHANNEL[icup->smod_number].INTDMA.B.ICF1IE = 0;
+ icup->etimerp->CHANNEL[icup->smod_number].INTDMA.B.ICF2IE = 0;
}
-#endif
-}
-
-/**
- * @brief Returns the width of the latest pulse.
- * @details The pulse width is defined as number of ticks between the start
- * edge and the stop edge.
- *
- * @param[in] icup pointer to the @p ICUDriver object
- * @return The number of ticks.
- *
- * @notapi
- */
-icucnt_t icu_lld_get_width(ICUDriver *icup) {
-
- return (icucnt_t)*icup->wccrp + 1;
-}
-
-/**
- * @brief Returns the width of the latest cycle.
- * @details The cycle width is defined as number of ticks between a start
- * edge and the next start edge.
- *
- * @param[in] icup pointer to the @p ICUDriver object
- * @return The number of ticks.
- *
- * @notapi
- */
-icucnt_t icu_lld_get_period(ICUDriver *icup) {
-
- return (icucnt_t)*icup->pccrp + 1;
+ if (icup->config->overflow_cb != NULL)
+ icup->etimerp->CHANNEL[icup->smod_number].INTDMA.B.TOFIE = 0;
}
#endif /* HAL_USE_ICU */
diff --git a/os/hal/platforms/SPC5xx/eTimer_v1/icu_lld.h b/os/hal/platforms/SPC5xx/eTimer_v1/icu_lld.h
index 4090648e8..041eb95e9 100644
--- a/os/hal/platforms/SPC5xx/eTimer_v1/icu_lld.h
+++ b/os/hal/platforms/SPC5xx/eTimer_v1/icu_lld.h
@@ -50,6 +50,7 @@
* @name Configuration options
* @{
*/
+#if SPC5_HAS_ETIMER0
/**
* @brief ICUD0 driver enable switch.
* @details If set to @p TRUE the support for ICUD0 is included.
@@ -105,6 +106,79 @@
#endif
/**
+ * @brief eTimer0 interrupt priority level setting.
+ */
+#if !defined(SPC5_ICU_ETIMER0_PRIORITY) || defined(__DOXYGEN__)
+#define SPC5_ICU_ETIMER0_PRIORITY 7
+#endif
+
+/**
+ * @brief ICUD1 interrupt priority level setting.
+ */
+#if !defined(SPC5_ICU_SMOD0_IRQ_PRIORITY) || defined(__DOXYGEN__)
+#define SPC5_ICU_SMOD0_IRQ_PRIORITY 7
+#endif
+
+/**
+ * @brief ICUD2 interrupt priority level setting.
+ */
+#if !defined(SPC5_ICU_SMOD1_IRQ_PRIORITY) || defined(__DOXYGEN__)
+#define SPC5_ICU_SMOD1_IRQ_PRIORITY 7
+#endif
+
+/**
+ * @brief ICUD3 interrupt priority level setting.
+ */
+#if !defined(SPC5_ICU_SMOD2_IRQ_PRIORITY) || defined(__DOXYGEN__)
+#define SPC5_ICU_SMOD2_IRQ_PRIORITY 7
+#endif
+
+/**
+ * @brief ICUD4 interrupt priority level setting.
+ */
+#if !defined(SPC5_ICU_SMOD3_IRQ_PRIORITY) || defined(__DOXYGEN__)
+#define SPC5_ICU_SMOD3_IRQ_PRIORITY 7
+#endif
+
+/**
+ * @brief ICUD5 interrupt priority level setting.
+ */
+#if !defined(SPC5_ICU_SMOD4_IRQ_PRIORITY) || defined(__DOXYGEN__)
+#define SPC5_ICU_SMOD4_IRQ_PRIORITY 7
+#endif
+
+/**
+ * @brief ICUD6 interrupt priority level setting.
+ */
+#if !defined(SPC5_ICU_SMOD5_IRQ_PRIORITY) || defined(__DOXYGEN__)
+#define SPC5_ICU_SMOD5_IRQ_PRIORITY 7
+#endif
+
+/**
+ * @brief eTIMER0 peripheral configuration when started.
+ * @note The default configuration is 1 (always run) in run mode and
+ * 2 (only halt) in low power mode. The defaults of the run modes
+ * are defined in @p hal_lld.h.
+ */
+#if !defined(SPC5_ICU_ETIMER0_START_PCTL) || defined(__DOXYGEN__)
+#define SPC5_ICU_ETIMER0_START_PCTL (SPC5_ME_PCTL_RUN(1) | \
+ SPC5_ME_PCTL_LP(2))
+#endif
+
+/**
+ * @brief eTIMER0 peripheral configuration when stopped.
+ * @note The default configuration is 0 (never run) in run mode and
+ * 0 (never run) in low power mode. The defaults of the run modes
+ * are defined in @p hal_lld.h.
+ */
+#if !defined(SPC5_ICU_ETIMER0_STOP_PCTL) || defined(__DOXYGEN__)
+#define SPC5_ICU_ETIMER0_STOP_PCTL (SPC5_ME_PCTL_RUN(0) | \
+ SPC5_ME_PCTL_LP(0))
+#endif
+#endif
+
+#if SPC5_HAS_ETIMER1
+/**
* @brief ICUD6 driver enable switch.
* @details If set to @p TRUE the support for ICUD6 is included.
* @note The default is @p TRUE.
@@ -159,146 +233,203 @@
#endif
/**
- * @brief eTimer0 interrupt priority level setting.
+ * @brief eTimer1 interrupt priority level setting.
*/
-#if !defined(SPC5_ICU_ETIMER0_PRIORITY) || defined(__DOXYGEN__)
-#define SPC5_ICU_ETIMER0_PRIORITY 7
+#if !defined(SPC5_ICU_ETIMER1_PRIORITY) || defined(__DOXYGEN__)
+#define SPC5_ICU_ETIMER1_PRIORITY 7
#endif
/**
- * @brief eTimer1 interrupt priority level setting.
+ * @brief ICUD7 interrupt priority level setting.
*/
-#if !defined(SPC5_ICU_ETIMER1_PRIORITY) || defined(__DOXYGEN__)
-#define SPC5_ICU_ETIMER1_PRIORITY 7
+#if !defined(SPC5_ICU_SMOD6_IRQ_PRIORITY) || defined(__DOXYGEN__)
+#define SPC5_ICU_SMOD6_IRQ_PRIORITY 7
#endif
/**
- * @brief ICUD0 interrupt priority level setting.
+ * @brief ICUD8 interrupt priority level setting.
*/
-#if !defined(SPC5_ICU_SMOD0_IRQ_PRIORITY) || defined(__DOXYGEN__)
-#define SPC5_ICU_SMOD0_IRQ_PRIORITY 7
+#if !defined(SPC5_ICU_SMOD7_IRQ_PRIORITY) || defined(__DOXYGEN__)
+#define SPC5_ICU_SMOD7_IRQ_PRIORITY 7
#endif
/**
- * @brief ICUD1 interrupt priority level setting.
+ * @brief ICUD9 interrupt priority level setting.
*/
-#if !defined(SPC5_ICU_SMOD1_IRQ_PRIORITY) || defined(__DOXYGEN__)
-#define SPC5_ICU_SMOD1_IRQ_PRIORITY 7
+#if !defined(SPC5_ICU_SMOD8_IRQ_PRIORITY) || defined(__DOXYGEN__)
+#define SPC5_ICU_SMOD8_IRQ_PRIORITY 7
#endif
/**
- * @brief ICUD2 interrupt priority level setting.
+ * @brief ICUD10 interrupt priority level setting.
*/
-#if !defined(SPC5_ICU_SMOD2_IRQ_PRIORITY) || defined(__DOXYGEN__)
-#define SPC5_ICU_SMOD2_IRQ_PRIORITY 7
+#if !defined(SPC5_ICU_SMOD9_IRQ_PRIORITY) || defined(__DOXYGEN__)
+#define SPC5_ICU_SMOD9_IRQ_PRIORITY 7
#endif
/**
- * @brief ICUD3 interrupt priority level setting.
+ * @brief ICUD11 interrupt priority level setting.
*/
-#if !defined(SPC5_ICU_SMOD3_IRQ_PRIORITY) || defined(__DOXYGEN__)
-#define SPC5_ICU_SMOD3_IRQ_PRIORITY 7
+#if !defined(SPC5_ICU_SMOD10_IRQ_PRIORITY) || defined(__DOXYGEN__)
+#define SPC5_ICU_SMOD10_IRQ_PRIORITY 7
#endif
/**
- * @brief ICUD4 interrupt priority level setting.
+ * @brief ICUD12 interrupt priority level setting.
*/
-#if !defined(SPC5_ICU_SMOD4_IRQ_PRIORITY) || defined(__DOXYGEN__)
-#define SPC5_ICU_SMOD4_IRQ_PRIORITY 7
+#if !defined(SPC5_ICU_SMOD11_IRQ_PRIORITY) || defined(__DOXYGEN__)
+#define SPC5_ICU_SMOD11_IRQ_PRIORITY 7
#endif
/**
- * @brief ICUD5 interrupt priority level setting.
+ * @brief eTIMER1 peripheral configuration when started.
+ * @note The default configuration is 1 (always run) in run mode and
+ * 2 (only halt) in low power mode. The defaults of the run modes
+ * are defined in @p hal_lld.h.
*/
-#if !defined(SPC5_ICU_SMOD5_IRQ_PRIORITY) || defined(__DOXYGEN__)
-#define SPC5_ICU_SMOD5_IRQ_PRIORITY 7
+#if !defined(SPC5_ICU_ETIMER1_START_PCTL) || defined(__DOXYGEN__)
+#define SPC5_ICU_ETIMER1_START_PCTL (SPC5_ME_PCTL_RUN(1) | \
+ SPC5_ME_PCTL_LP(2))
#endif
/**
- * @brief ICUD6 interrupt priority level setting.
+ * @brief eTIMER1 peripheral configuration when stopped.
+ * @note The default configuration is 0 (never run) in run mode and
+ * 0 (never run) in low power mode. The defaults of the run modes
+ * are defined in @p hal_lld.h.
*/
-#if !defined(SPC5_ICU_SMOD6_IRQ_PRIORITY) || defined(__DOXYGEN__)
-#define SPC5_ICU_SMOD5_IRQ_PRIORITY 7
+#if !defined(SPC5_ICU_ETIMER1_STOP_PCTL) || defined(__DOXYGEN__)
+#define SPC5_ICU_ETIMER1_STOP_PCTL (SPC5_ME_PCTL_RUN(0) | \
+ SPC5_ME_PCTL_LP(0))
+#endif
#endif
+#if SPC5_HAS_ETIMER2
/**
- * @brief ICUD7 interrupt priority level setting.
+ * @brief ICUD13 driver enable switch.
+ * @details If set to @p TRUE the support for ICUD13 is included.
+ * @note The default is @p TRUE.
*/
-#if !defined(SPC5_ICU_SMOD7_IRQ_PRIORITY) || defined(__DOXYGEN__)
-#define SPC5_ICU_SMOD5_IRQ_PRIORITY 7
+#if !defined(SPC5_ICU_USE_SMOD12) || defined(__DOXYGEN__)
+#define SPC5_ICU_USE_SMOD12 TRUE
#endif
/**
- * @brief ICUD8 interrupt priority level setting.
+ * @brief ICUD14 driver enable switch.
+ * @details If set to @p TRUE the support for ICUD14 is included.
+ * @note The default is @p TRUE.
*/
-#if !defined(SPC5_ICU_SMOD8_IRQ_PRIORITY) || defined(__DOXYGEN__)
-#define SPC5_ICU_SMOD5_IRQ_PRIORITY 7
+#if !defined(SPC5_ICU_USE_SMOD13) || defined(__DOXYGEN__)
+#define SPC5_ICU_USE_SMOD13 TRUE
#endif
/**
- * @brief ICUD9 interrupt priority level setting.
+ * @brief ICUD15 driver enable switch.
+ * @details If set to @p TRUE the support for ICUD15 is included.
+ * @note The default is @p TRUE.
*/
-#if !defined(SPC5_ICU_SMOD9_IRQ_PRIORITY) || defined(__DOXYGEN__)
-#define SPC5_ICU_SMOD5_IRQ_PRIORITY 7
+#if !defined(SPC5_ICU_USE_SMOD14) || defined(__DOXYGEN__)
+#define SPC5_ICU_USE_SMOD14 TRUE
#endif
/**
- * @brief ICUD10 interrupt priority level setting.
+ * @brief ICUD16 driver enable switch.
+ * @details If set to @p TRUE the support for ICUD16 is included.
+ * @note The default is @p TRUE.
*/
-#if !defined(SPC5_ICU_SMOD10_IRQ_PRIORITY) || defined(__DOXYGEN__)
-#define SPC5_ICU_SMOD5_IRQ_PRIORITY 7
+#if !defined(SPC5_ICU_USE_SMOD15) || defined(__DOXYGEN__)
+#define SPC5_ICU_USE_SMOD15 TRUE
#endif
/**
- * @brief ICUD11 interrupt priority level setting.
+ * @brief ICUD17 driver enable switch.
+ * @details If set to @p TRUE the support for ICUD17 is included.
+ * @note The default is @p TRUE.
*/
-#if !defined(SPC5_ICU_SMOD11_IRQ_PRIORITY) || defined(__DOXYGEN__)
-#define SPC5_ICU_SMOD5_IRQ_PRIORITY 7
+#if !defined(SPC5_ICU_USE_SMOD16) || defined(__DOXYGEN__)
+#define SPC5_ICU_USE_SMOD16 TRUE
#endif
/**
- * @brief eTIMER0 peripheral configuration when started.
- * @note The default configuration is 1 (always run) in run mode and
- * 2 (only halt) in low power mode. The defaults of the run modes
- * are defined in @p hal_lld.h.
+ * @brief ICUD18 driver enable switch.
+ * @details If set to @p TRUE the support for ICUD18 is included.
+ * @note The default is @p TRUE.
*/
-#if !defined(SPC5_ICU_ETIMER0_START_PCTL) || defined(__DOXYGEN__)
-#define SPC5_ICU_ETIMER0_START_PCTL (SPC5_ME_PCTL_RUN(1) | \
- SPC5_ME_PCTL_LP(2))
+#if !defined(SPC5_ICU_USE_SMOD17) || defined(__DOXYGEN__)
+#define SPC5_ICU_USE_SMOD17 TRUE
#endif
/**
- * @brief eTIMER0 peripheral configuration when stopped.
- * @note The default configuration is 0 (never run) in run mode and
- * 0 (never run) in low power mode. The defaults of the run modes
- * are defined in @p hal_lld.h.
+ * @brief eTimer2 interrupt priority level setting.
*/
-#if !defined(SPC5_ICU_ETIMER0_STOP_PCTL) || defined(__DOXYGEN__)
-#define SPC5_ICU_ETIMER0_STOP_PCTL (SPC5_ME_PCTL_RUN(0) | \
- SPC5_ME_PCTL_LP(0))
+#if !defined(SPC5_ICU_ETIMER12_PRIORITY) || defined(__DOXYGEN__)
+#define SPC5_ICU_ETIMER2_PRIORITY 7
#endif
/**
- * @brief eTIMER1 peripheral configuration when started.
+ * @brief ICUD13 interrupt priority level setting.
+ */
+#if !defined(SPC5_ICU_SMOD12_IRQ_PRIORITY) || defined(__DOXYGEN__)
+#define SPC5_ICU_SMOD12_IRQ_PRIORITY 7
+#endif
+
+/**
+ * @brief ICUD14 interrupt priority level setting.
+ */
+#if !defined(SPC5_ICU_SMOD13_IRQ_PRIORITY) || defined(__DOXYGEN__)
+#define SPC5_ICU_SMOD13_IRQ_PRIORITY 7
+#endif
+
+/**
+ * @brief ICUD15 interrupt priority level setting.
+ */
+#if !defined(SPC5_ICU_SMOD14_IRQ_PRIORITY) || defined(__DOXYGEN__)
+#define SPC5_ICU_SMOD14_IRQ_PRIORITY 7
+#endif
+
+/**
+ * @brief ICUD16 interrupt priority level setting.
+ */
+#if !defined(SPC5_ICU_SMOD15_IRQ_PRIORITY) || defined(__DOXYGEN__)
+#define SPC5_ICU_SMOD15_IRQ_PRIORITY 7
+#endif
+
+/**
+ * @brief ICUD17 interrupt priority level setting.
+ */
+#if !defined(SPC5_ICU_SMOD16_IRQ_PRIORITY) || defined(__DOXYGEN__)
+#define SPC5_ICU_SMOD16_IRQ_PRIORITY 7
+#endif
+
+/**
+ * @brief ICUD18 interrupt priority level setting.
+ */
+#if !defined(SPC5_ICU_SMOD17_IRQ_PRIORITY) || defined(__DOXYGEN__)
+#define SPC5_ICU_SMOD17_IRQ_PRIORITY 7
+#endif
+
+/**
+ * @brief eTIMER2 peripheral configuration when started.
* @note The default configuration is 1 (always run) in run mode and
* 2 (only halt) in low power mode. The defaults of the run modes
* are defined in @p hal_lld.h.
*/
-#if !defined(SPC5_ICU_ETIMER1_START_PCTL) || defined(__DOXYGEN__)
-#define SPC5_ICU_ETIMER1_START_PCTL (SPC5_ME_PCTL_RUN(1) | \
- SPC5_ME_PCTL_LP(2))
+#if !defined(SPC5_ICU_ETIMER2_START_PCTL) || defined(__DOXYGEN__)
+#define SPC5_ICU_ETIMER2_START_PCTL (SPC5_ME_PCTL_RUN(1) | \
+ SPC5_ME_PCTL_LP(2))
#endif
/**
- * @brief eTIMER1 peripheral configuration when stopped.
+ * @brief eTIMER2 peripheral configuration when stopped.
* @note The default configuration is 0 (never run) in run mode and
* 0 (never run) in low power mode. The defaults of the run modes
* are defined in @p hal_lld.h.
*/
-#if !defined(SPC5_ICU_ETIMER1_STOP_PCTL) || defined(__DOXYGEN__)
-#define SPC5_ICU_ETIMER1_STOP_PCTL (SPC5_ME_PCTL_RUN(0) | \
+#if !defined(SPC5_ICU_ETIMER2_STOP_PCTL) || defined(__DOXYGEN__)
+#define SPC5_ICU_ETIMER2_STOP_PCTL (SPC5_ME_PCTL_RUN(0) | \
SPC5_ME_PCTL_LP(0))
#endif
+#endif
/** @} */
/*===========================================================================*/
@@ -317,6 +448,12 @@
#error "ETIMER1 not present in the selected device"
#endif
+#if (SPC5_ICU_USE_SMOD12 || SPC5_ICU_USE_SMOD13 || \
+ SPC5_ICU_USE_SMOD14 || SPC5_ICU_USE_SMOD15 || \
+ SPC5_ICU_USE_SMOD116 || SPC5_ICU_USE_SMOD17) && !SPC5_HAS_ETIMER2
+#error "ETIMER2 not present in the selected device"
+#endif
+
#if (!SPC5_ICU_USE_SMOD0 && !SPC5_ICU_USE_SMOD1 && \
!SPC5_ICU_USE_SMOD2 && !SPC5_ICU_USE_SMOD3 && \
!SPC5_ICU_USE_SMOD4 && !SPC5_ICU_USE_SMOD5) && SPC5_ICU_USE_ETIMER0
@@ -329,6 +466,12 @@
#error "ICU driver activated but no SMOD peripheral assigned"
#endif
+#if (!SPC5_ICU_USE_SMOD12 && !SPC5_ICU_USE_SMOD13 && \
+ !SPC5_ICU_USE_SMOD14 && !SPC5_ICU_USE_SMOD15 && \
+ !SPC5_ICU_USE_SMOD16 && !SPC5_ICU_USE_SMOD17) && SPC5_ICU_USE_ETIMER2
+#error "ICU driver activated but no SMOD peripheral assigned"
+#endif
+
/*===========================================================================*/
/* Driver data structures and types. */
/*===========================================================================*/
@@ -407,6 +550,10 @@ struct ICUDriver {
*/
icustate_t state;
/**
+ * @brief eTimer submodule number.
+ */
+ uint8_t smod_number;
+ /**
* @brief Current configuration data.
*/
const ICUConfig *config;
@@ -439,6 +586,30 @@ struct ICUDriver {
/* Driver macros. */
/*===========================================================================*/
+/**
+ * @brief Returns the width of the latest pulse.
+ * @details The pulse width is defined as number of ticks between the start
+ * edge and the stop edge.
+ *
+ * @param[in] icup pointer to the @p ICUDriver object
+ * @return The number of ticks.
+ *
+ * @notapi
+ */
+#define icu_lld_get_width(icup) (*((icup)->wccrp) + 1)
+
+/**
+ * @brief Returns the width of the latest cycle.
+ * @details The cycle width is defined as number of ticks between a start
+ * edge and the next start edge.
+ *
+ * @param[in] icup pointer to the @p ICUDriver object
+ * @return The number of ticks.
+ *
+ * @notapi
+ */
+#define icu_lld_get_period(icup) (*((icup)->pccrp) + 1)
+
/*===========================================================================*/
/* External declarations. */
/*===========================================================================*/
@@ -491,6 +662,30 @@ extern ICUDriver ICUD11;
extern ICUDriver ICUD12;
#endif
+#if SPC5_ICU_USE_SMOD12 && !defined(__DOXYGEN__)
+extern ICUDriver ICUD13;
+#endif
+
+#if SPC5_ICU_USE_SMOD13 && !defined(__DOXYGEN__)
+extern ICUDriver ICUD14;
+#endif
+
+#if SPC5_ICU_USE_SMOD14 && !defined(__DOXYGEN__)
+extern ICUDriver ICUD15;
+#endif
+
+#if SPC5_ICU_USE_SMOD15 && !defined(__DOXYGEN__)
+extern ICUDriver ICUD16;
+#endif
+
+#if SPC5_ICU_USE_SMOD16 && !defined(__DOXYGEN__)
+extern ICUDriver ICUD17;
+#endif
+
+#if SPC5_ICU_USE_SMOD17 && !defined(__DOXYGEN__)
+extern ICUDriver ICUD18;
+#endif
+
#ifdef __cplusplus
extern "C" {
#endif
@@ -499,8 +694,6 @@ extern "C" {
void icu_lld_stop(ICUDriver *icup);
void icu_lld_enable(ICUDriver *icup);
void icu_lld_disable(ICUDriver *icup);
- icucnt_t icu_lld_get_width(ICUDriver *icup);
- icucnt_t icu_lld_get_period(ICUDriver *icup);
#ifdef __cplusplus
}
#endif