aboutsummaryrefslogtreecommitdiffstats
path: root/os/hal/ports
diff options
context:
space:
mode:
Diffstat (limited to 'os/hal/ports')
-rw-r--r--os/hal/ports/STM32/LLD/CANv1/hal_can_lld.c282
-rw-r--r--os/hal/ports/STM32/LLD/CANv1/hal_can_lld.h49
-rw-r--r--os/hal/ports/STM32/STM32F0xx/stm32_registry.h10
-rw-r--r--os/hal/ports/STM32/STM32F1xx/stm32_registry.h6
-rw-r--r--os/hal/ports/STM32/STM32F37x/stm32_registry.h2
-rw-r--r--os/hal/ports/STM32/STM32F3xx/stm32_registry.h12
-rw-r--r--os/hal/ports/STM32/STM32F4xx/stm32_registry.h8
-rw-r--r--os/hal/ports/STM32/STM32F7xx/stm32_rcc.h25
-rw-r--r--os/hal/ports/STM32/STM32F7xx/stm32_registry.h12
-rw-r--r--os/hal/ports/STM32/STM32L0xx/stm32_registry.h6
-rw-r--r--os/hal/ports/STM32/STM32L1xx/stm32_registry.h2
-rw-r--r--os/hal/ports/STM32/STM32L4xx/stm32_registry.h2
12 files changed, 368 insertions, 48 deletions
diff --git a/os/hal/ports/STM32/LLD/CANv1/hal_can_lld.c b/os/hal/ports/STM32/LLD/CANv1/hal_can_lld.c
index bc9190984..c28613a03 100644
--- a/os/hal/ports/STM32/LLD/CANv1/hal_can_lld.c
+++ b/os/hal/ports/STM32/LLD/CANv1/hal_can_lld.c
@@ -53,6 +53,11 @@ CANDriver CAND1;
CANDriver CAND2;
#endif
+/** @brief CAN3 driver identifier.*/
+#if STM32_CAN_USE_CAN3 || defined(__DOXYGEN__)
+CANDriver CAND3;
+#endif
+
/*===========================================================================*/
/* Driver local variables and types. */
/*===========================================================================*/
@@ -60,9 +65,8 @@ CANDriver CAND2;
/*===========================================================================*/
/* Driver local functions. */
/*===========================================================================*/
-
/**
- * @brief Programs the filters.
+ * @brief Programs the filters of CAN 1 and CAN 2.
*
* @param[in] can2sb number of the first filter assigned to CAN2
* @param[in] num number of entries in the filters array, if zero then
@@ -72,67 +76,111 @@ CANDriver CAND2;
*
* @notapi
*/
-static void can_lld_set_filters(uint32_t can2sb,
+static void can_lld_set_filters(CANDriver* canp,
+ uint32_t can2sb,
uint32_t num,
const CANFilter *cfp) {
+#if STM32_CAN_USE_CAN2
+ if(canp == &CAND2) {
+ /* Set handle to CAN1, because CAN1 manages the filters of CAN2.*/
+ canp = &CAND1;
+ }
+#endif
- /* Temporarily enabling CAN1 clock.*/
- rccEnableCAN1(FALSE);
+ /* Temporarily enabling CAN clock.*/
+#if STM32_CAN_USE_CAN1
+ if(canp == &CAND1) {
+ rccEnableCAN1(FALSE);
+ /* Filters initialization.*/
+ canp->can->FMR = (canp->can->FMR & 0xFFFF0000) | CAN_FMR_FINIT;
+ canp->can->FMR = (canp->can->FMR & 0xFFFF0000) | (can2sb << 8) | CAN_FMR_FINIT;
+ }
+#endif
+#if STM32_CAN_USE_CAN3
+ if(canp == &CAND3) {
+ rccEnableCAN3(FALSE);
+ /* Filters initialization.*/
+ canp->can->FMR = (canp->can->FMR & 0xFFFF0000) | CAN_FMR_FINIT;
+ }
+#endif
- /* Filters initialization.*/
- CAN1->FMR = (CAN1->FMR & 0xFFFF0000) | CAN_FMR_FINIT;
- CAN1->FMR |= (can2sb << 8);
if (num > 0) {
uint32_t i, fmask;
/* All filters cleared.*/
- CAN1->FA1R = 0;
- CAN1->FM1R = 0;
- CAN1->FS1R = 0;
- CAN1->FFA1R = 0;
- for (i = 0; i < STM32_CAN_MAX_FILTERS; i++) {
- CAN1->sFilterRegister[i].FR1 = 0;
- CAN1->sFilterRegister[i].FR2 = 0;
- }
+ canp->can->FA1R = 0;
+ canp->can->FM1R = 0;
+ canp->can->FS1R = 0;
+ canp->can->FFA1R = 0;
+#if STM32_CAN_USE_CAN1
+ if(canp == &CAND1) {
+ for (i = 0; i < STM32_CAN_MAX_FILTERS; i++) {
+ canp->can->sFilterRegister[i].FR1 = 0;
+ canp->can->sFilterRegister[i].FR2 = 0;
+ }
+ }
+#endif
+#if STM32_CAN_USE_CAN3
+ if(canp == &CAND3) {
+ for (i = 0; i < STM32_CAN3_MAX_FILTERS; i++) {
+ canp->can->sFilterRegister[i].FR1 = 0;
+ canp->can->sFilterRegister[i].FR2 = 0;
+ }
+ }
+#endif
/* Scanning the filters array.*/
for (i = 0; i < num; i++) {
fmask = 1 << cfp->filter;
if (cfp->mode)
- CAN1->FM1R |= fmask;
+ canp->can->FM1R |= fmask;
if (cfp->scale)
- CAN1->FS1R |= fmask;
+ canp->can->FS1R |= fmask;
if (cfp->assignment)
- CAN1->FFA1R |= fmask;
- CAN1->sFilterRegister[cfp->filter].FR1 = cfp->register1;
- CAN1->sFilterRegister[cfp->filter].FR2 = cfp->register2;
- CAN1->FA1R |= fmask;
+ canp->can->FFA1R |= fmask;
+ canp->can->sFilterRegister[cfp->filter].FR1 = cfp->register1;
+ canp->can->sFilterRegister[cfp->filter].FR2 = cfp->register2;
+ canp->can->FA1R |= fmask;
cfp++;
}
}
else {
/* Setting up a single default filter that enables everything for both
CANs.*/
- CAN1->sFilterRegister[0].FR1 = 0;
- CAN1->sFilterRegister[0].FR2 = 0;
-#if STM32_HAS_CAN2
- CAN1->sFilterRegister[can2sb].FR1 = 0;
- CAN1->sFilterRegister[can2sb].FR2 = 0;
+ canp->can->sFilterRegister[0].FR1 = 0;
+ canp->can->sFilterRegister[0].FR2 = 0;
+#if STM32_CAN_USE_CAN2
+ if(canp == &CAND1) {
+ canp->can->sFilterRegister[can2sb].FR1 = 0;
+ canp->can->sFilterRegister[can2sb].FR2 = 0;
+ }
#endif
- CAN1->FM1R = 0;
- CAN1->FFA1R = 0;
-#if STM32_HAS_CAN2
- CAN1->FS1R = 1 | (1 << can2sb);
- CAN1->FA1R = 1 | (1 << can2sb);
+ canp->can->FM1R = 0;
+ canp->can->FFA1R = 0;
+#if STM32_CAN_USE_CAN2
+ if(canp == &CAND1) {
+ canp->can->FS1R = 1 | (1 << can2sb);
+ canp->can->FA1R = 1 | (1 << can2sb);
+ }
#else
- CAN1->FS1R = 1;
- CAN1->FA1R = 1;
+ canp->can->FS1R = 1;
+ canp->can->FA1R = 1;
#endif
}
- CAN1->FMR &= ~CAN_FMR_FINIT;
+ canp->can->FMR &= ~CAN_FMR_FINIT;
/* Clock disabled, it will be enabled again in can_lld_start().*/
- rccDisableCAN1(FALSE);
+ /* Temporarily enabling CAN clock.*/
+#if STM32_CAN_USE_CAN1
+ if(canp == &CAND1) {
+ rccDisableCAN1(FALSE);
+ }
+#endif
+#if STM32_CAN_USE_CAN3
+ if(canp == &CAND3) {
+ rccDisableCAN3(FALSE);
+ }
+#endif
}
/**
@@ -343,7 +391,7 @@ OSAL_IRQ_HANDLER(STM32_CAN1_TX_HANDLER) {
OSAL_IRQ_EPILOGUE();
}
-/*
+/**
* @brief CAN1 RX0 interrupt handler.
*
* @isr
@@ -434,7 +482,7 @@ OSAL_IRQ_HANDLER(STM32_CAN2_TX_HANDLER) {
OSAL_IRQ_EPILOGUE();
}
-/*
+/**
* @brief CAN2 RX0 interrupt handler.
*
* @isr
@@ -478,6 +526,97 @@ OSAL_IRQ_HANDLER(STM32_CAN2_SCE_HANDLER) {
#endif /* !defined(STM32_CAN2_UNIFIED_HANDLER) */
#endif /* STM32_CAN_USE_CAN2 */
+#if STM32_CAN_USE_CAN3 || defined(__DOXYGEN__)
+#if defined(STM32_CAN3_UNIFIED_HANDLER)
+/**
+ * @brief CAN1 unified interrupt handler.
+ *
+ * @isr
+ */
+OSAL_IRQ_HANDLER(STM32_CAN3_UNIFIED_HANDLER) {
+
+ OSAL_IRQ_PROLOGUE();
+
+ can_lld_tx_handler(&CAND3);
+ can_lld_rx0_handler(&CAND3);
+ can_lld_rx1_handler(&CAND3);
+ can_lld_sce_handler(&CAND3);
+
+ OSAL_IRQ_EPILOGUE();
+}
+#else /* !defined(STM32_CAN3_UNIFIED_HANDLER) */
+
+#if !defined(STM32_CAN3_TX_HANDLER)
+#error "STM32_CAN3_TX_HANDLER not defined"
+#endif
+#if !defined(STM32_CAN3_RX0_HANDLER)
+#error "STM32_CAN3_RX0_HANDLER not defined"
+#endif
+#if !defined(STM32_CAN3_RX1_HANDLER)
+#error "STM32_CAN3_RX1_HANDLER not defined"
+#endif
+#if !defined(STM32_CAN3_SCE_HANDLER)
+#error "STM32_CAN3_SCE_HANDLER not defined"
+#endif
+
+/**
+ * @brief CAN3 TX interrupt handler.
+ *
+ * @isr
+ */
+OSAL_IRQ_HANDLER(STM32_CAN3_TX_HANDLER) {
+
+ OSAL_IRQ_PROLOGUE();
+
+ can_lld_tx_handler(&CAND3);
+
+ OSAL_IRQ_EPILOGUE();
+}
+
+/**
+ * @brief CAN3 RX0 interrupt handler.
+ *
+ * @isr
+ */
+OSAL_IRQ_HANDLER(STM32_CAN3_RX0_HANDLER) {
+
+ OSAL_IRQ_PROLOGUE();
+
+ can_lld_rx0_handler(&CAND3);
+
+ OSAL_IRQ_EPILOGUE();
+}
+
+/**
+ * @brief CAN1 RX3 interrupt handler.
+ *
+ * @isr
+ */
+OSAL_IRQ_HANDLER(STM32_CAN3_RX1_HANDLER) {
+
+ OSAL_IRQ_PROLOGUE();
+
+ can_lld_rx1_handler(&CAND3);
+
+ OSAL_IRQ_EPILOGUE();
+}
+
+/**
+ * @brief CAN1 SCE interrupt handler.
+ *
+ * @isr
+ */
+OSAL_IRQ_HANDLER(STM32_CAN3_SCE_HANDLER) {
+
+ OSAL_IRQ_PROLOGUE();
+
+ can_lld_sce_handler(&CAND3);
+
+ OSAL_IRQ_EPILOGUE();
+}
+#endif /* !defined(STM32_CAN1_UNIFIED_HANDLER) */
+#endif /* STM32_CAN_USE_CAN1 */
+
/*===========================================================================*/
/* Driver exported functions. */
/*===========================================================================*/
@@ -499,12 +638,23 @@ void can_lld_init(void) {
canObjectInit(&CAND2);
CAND2.can = CAN2;
#endif
+#if STM32_CAN_USE_CAN3
+ /* Driver initialization.*/
+ canObjectInit(&CAND3);
+ CAND3.can = CAN3;
+#endif
/* Filters initialization.*/
#if STM32_HAS_CAN2
- can_lld_set_filters(STM32_CAN_MAX_FILTERS / 2, 0, NULL);
+ can_lld_set_filters(&CAND1, STM32_CAN_MAX_FILTERS / 2, 0, NULL);
#else
- can_lld_set_filters(STM32_CAN_MAX_FILTERS, 0, NULL);
+ can_lld_set_filters(&CAND1, STM32_CAN_MAX_FILTERS, 0, NULL);
+#endif
+
+#if STM32_HAS_CAN3
+#if STM32_CAN_USE_CAN3
+ can_lld_set_filters(&CAND3, STM32_CAN3_MAX_FILTERS, 0, NULL);
+#endif
#endif
}
@@ -531,6 +681,7 @@ void can_lld_start(CANDriver *canp) {
rccEnableCAN1(FALSE);
}
#endif
+
#if STM32_CAN_USE_CAN2
if (&CAND2 == canp) {
@@ -548,6 +699,20 @@ void can_lld_start(CANDriver *canp) {
}
#endif
+#if STM32_CAN_USE_CAN3
+ if (&CAND3 == canp) {
+#if defined(STM32_CAN3_UNIFIED_NUMBER)
+ nvicEnableVector(STM32_CAN3_UNIFIED_NUMBER, STM32_CAN_CAN3_IRQ_PRIORITY);
+#else
+ nvicEnableVector(STM32_CAN3_TX_NUMBER, STM32_CAN_CAN3_IRQ_PRIORITY);
+ nvicEnableVector(STM32_CAN3_RX0_NUMBER, STM32_CAN_CAN3_IRQ_PRIORITY);
+ nvicEnableVector(STM32_CAN3_RX1_NUMBER, STM32_CAN_CAN3_IRQ_PRIORITY);
+ nvicEnableVector(STM32_CAN3_SCE_NUMBER, STM32_CAN_CAN3_IRQ_PRIORITY);
+#endif
+ rccEnableCAN3(FALSE);
+ }
+#endif
+
/* Configuring CAN. */
canp->can->MCR = CAN_MCR_INRQ;
while ((canp->can->MSR & CAN_MSR_INAK) == 0)
@@ -600,6 +765,7 @@ void can_lld_stop(CANDriver *canp) {
rccDisableCAN1(FALSE);
}
#endif
+
#if STM32_CAN_USE_CAN2
if (&CAND2 == canp) {
CAN2->MCR = 0x00010002; /* Register reset value. */
@@ -615,6 +781,22 @@ void can_lld_stop(CANDriver *canp) {
rccDisableCAN2(FALSE);
}
#endif
+
+#if STM32_CAN_USE_CAN3
+ if (&CAND3 == canp) {
+ CAN3->MCR = 0x00010002; /* Register reset value. */
+ CAN3->IER = 0x00000000; /* All sources disabled. */
+#if defined(STM32_CAN3_UNIFIED_NUMBER)
+ nvicDisableVector(STM32_CAN3_UNIFIED_NUMBER);
+#else
+ nvicDisableVector(STM32_CAN3_TX_NUMBER);
+ nvicDisableVector(STM32_CAN3_RX0_NUMBER);
+ nvicDisableVector(STM32_CAN3_RX1_NUMBER);
+ nvicDisableVector(STM32_CAN3_SCE_NUMBER);
+#endif
+ rccDisableCAN3(FALSE);
+ }
+#endif
}
}
@@ -828,10 +1010,12 @@ void can_lld_wakeup(CANDriver *canp) {
*
* @api
*/
-void canSTM32SetFilters(uint32_t can2sb, uint32_t num, const CANFilter *cfp) {
+void canSTM32SetFilters(CANDriver *canp, uint32_t can2sb, uint32_t num, const CANFilter *cfp) {
- osalDbgCheck((can2sb >= 1) && (can2sb < STM32_CAN_MAX_FILTERS) &&
+#if STM32_CAN_USE_CAN2
+ osalDbgCheck((can2sb >= 0) && (can2sb <= STM32_CAN_MAX_FILTERS) &&
(num <= STM32_CAN_MAX_FILTERS));
+#endif
#if STM32_CAN_USE_CAN1
osalDbgAssert(CAND1.state == CAN_STOP, "invalid state");
@@ -839,8 +1023,20 @@ void canSTM32SetFilters(uint32_t can2sb, uint32_t num, const CANFilter *cfp) {
#if STM32_CAN_USE_CAN2
osalDbgAssert(CAND2.state == CAN_STOP, "invalid state");
#endif
+#if STM32_CAN_USE_CAN3
+ osalDbgAssert(CAND3.state == CAN_STOP, "invalid state");
+#endif
- can_lld_set_filters(can2sb, num, cfp);
+#if STM32_CAN_USE_CAN1
+ if(canp == &CAND1) {
+ can_lld_set_filters(canp, can2sb, num, cfp);
+ }
+#endif
+#if STM32_CAN_USE_CAN3
+ if(canp == &CAND3) {
+ can_lld_set_filters(canp, can2sb, num, cfp);
+ }
+#endif
}
#endif /* HAL_USE_CAN */
diff --git a/os/hal/ports/STM32/LLD/CANv1/hal_can_lld.h b/os/hal/ports/STM32/LLD/CANv1/hal_can_lld.h
index d44ccf4ee..c6c10dc12 100644
--- a/os/hal/ports/STM32/LLD/CANv1/hal_can_lld.h
+++ b/os/hal/ports/STM32/LLD/CANv1/hal_can_lld.h
@@ -105,6 +105,14 @@
#endif
/**
+ * @brief CAN3 driver enable switch.
+ * @details If set to @p TRUE the support for CAN3 is included.
+ */
+#if !defined(STM32_CAN_USE_CAN3) || defined(__DOXYGEN__)
+#define STM32_CAN_USE_CAN3 FALSE
+#endif
+
+/**
* @brief CAN1 interrupt priority level setting.
*/
#if !defined(STM32_CAN_CAN1_IRQ_PRIORITY) || defined(__DOXYGEN__)
@@ -120,10 +128,38 @@
#endif
/** @} */
+/**
+ * @brief CAN3 interrupt priority level setting.
+ */
+#if !defined(STM32_CAN_CAN3_IRQ_PRIORITY) || defined(__DOXYGEN__)
+#define STM32_CAN_CAN3_IRQ_PRIORITY 11
+#endif
+/** @} */
+
/*===========================================================================*/
/* Derived constants and error checks. */
/*===========================================================================*/
+#if !defined(STM32_HAS_CAN1)
+#error "STM32_HAS_CAN1 not defined in registry"
+#endif
+
+#if !defined(STM32_HAS_CAN2)
+#error "STM32_HAS_CAN2 not defined in registry"
+#endif
+
+#if !defined(STM32_HAS_CAN3)
+#error "STM32_HAS_CAN3 not defined in registry"
+#endif
+
+#if (STM32_HAS_CAN1 | STM32_HAS_CAN2) && !defined(STM32_CAN_MAX_FILTERS)
+#error "STM32_CAN_MAX_FILTERS not defined in registry"
+#endif
+
+#if STM32_HAS_CAN3 && !defined(STM32_CAN3_MAX_FILTERS)
+#error "STM32_CAN3_MAX_FILTERS not defined in registry"
+#endif
+
#if STM32_CAN_USE_CAN1 && !STM32_HAS_CAN1
#error "CAN1 not present in the selected device"
#endif
@@ -132,7 +168,11 @@
#error "CAN2 not present in the selected device"
#endif
-#if !STM32_CAN_USE_CAN1 && !STM32_CAN_USE_CAN2
+#if STM32_CAN_USE_CAN3 && !STM32_HAS_CAN3
+#error "CAN2 not present in the selected device"
+#endif
+
+#if !STM32_CAN_USE_CAN1 && !STM32_CAN_USE_CAN2 && !STM32_CAN_USE_CAN3
#error "CAN driver activated but no CAN peripheral assigned"
#endif
@@ -349,6 +389,10 @@ extern CANDriver CAND1;
extern CANDriver CAND2;
#endif
+#if STM32_CAN_USE_CAN3 && !defined(__DOXYGEN__)
+extern CANDriver CAND3;
+#endif
+
#ifdef __cplusplus
extern "C" {
#endif
@@ -367,7 +411,8 @@ extern "C" {
void can_lld_sleep(CANDriver *canp);
void can_lld_wakeup(CANDriver *canp);
#endif /* CAN_USE_SLEEP_MODE */
- void canSTM32SetFilters(uint32_t can2sb, uint32_t num, const CANFilter *cfp);
+ void canSTM32SetFilters(CANDriver *canp, uint32_t can2sb,
+ uint32_t num, const CANFilter *cfp);
#ifdef __cplusplus
}
#endif
diff --git a/os/hal/ports/STM32/STM32F0xx/stm32_registry.h b/os/hal/ports/STM32/STM32F0xx/stm32_registry.h
index 56b138e65..a830042f6 100644
--- a/os/hal/ports/STM32/STM32F0xx/stm32_registry.h
+++ b/os/hal/ports/STM32/STM32F0xx/stm32_registry.h
@@ -64,6 +64,7 @@
/* CAN attributes.*/
#define STM32_HAS_CAN1 FALSE
#define STM32_HAS_CAN2 FALSE
+#define STM32_HAS_CAN3 FALSE
/* DAC attributes.*/
#define STM32_HAS_DAC1_CH1 FALSE
@@ -362,6 +363,7 @@
/* CAN attributes.*/
#define STM32_HAS_CAN1 FALSE
#define STM32_HAS_CAN2 FALSE
+#define STM32_HAS_CAN3 FALSE
/* DAC attributes.*/
#define STM32_HAS_DAC1_CH1 FALSE
@@ -565,6 +567,7 @@
/* CAN attributes.*/
#define STM32_HAS_CAN1 TRUE
#define STM32_HAS_CAN2 FALSE
+#define STM32_HAS_CAN3 FALSE
#define STM32_CAN_MAX_FILTERS 14
/* DAC attributes.*/
@@ -778,6 +781,7 @@
/* CAN attributes.*/
#define STM32_HAS_CAN1 FALSE
#define STM32_HAS_CAN2 FALSE
+#define STM32_HAS_CAN3 FALSE
/* DAC attributes.*/
#define STM32_HAS_DAC1_CH1 FALSE
@@ -995,6 +999,7 @@
/* CAN attributes.*/
#define STM32_HAS_CAN1 FALSE
#define STM32_HAS_CAN2 FALSE
+#define STM32_HAS_CAN3 FALSE
/* DAC attributes.*/
#define STM32_HAS_DAC1_CH1 TRUE
@@ -1228,6 +1233,7 @@
/* CAN attributes.*/
#define STM32_HAS_CAN1 FALSE
#define STM32_HAS_CAN2 FALSE
+#define STM32_HAS_CAN3 FALSE
/* DAC attributes.*/
#define STM32_HAS_DAC1_CH1 FALSE
@@ -1479,6 +1485,7 @@
#define STM32_HAS_CAN1 FALSE
#endif
#define STM32_HAS_CAN2 FALSE
+#define STM32_HAS_CAN3 FALSE
/* DAC attributes.*/
#define STM32_HAS_DAC1_CH1 TRUE
@@ -1737,10 +1744,9 @@
/* CAN attributes.*/
#define STM32_HAS_CAN1 TRUE
#define STM32_HAS_CAN2 FALSE
+#define STM32_HAS_CAN3 FALSE
#define STM32_CAN_MAX_FILTERS 14
-#define STM32_HAS_CAN2 FALSE
-
/* DAC attributes.*/
#define STM32_HAS_DAC1_CH1 TRUE
#define STM32_DAC1_CH1_DMA_MSK (STM32_DMA_STREAM_ID_MSK(1, 3) |\
diff --git a/os/hal/ports/STM32/STM32F1xx/stm32_registry.h b/os/hal/ports/STM32/STM32F1xx/stm32_registry.h
index 55adec556..e1e3d5e8e 100644
--- a/os/hal/ports/STM32/STM32F1xx/stm32_registry.h
+++ b/os/hal/ports/STM32/STM32F1xx/stm32_registry.h
@@ -72,6 +72,7 @@
/* CAN attributes.*/
#define STM32_HAS_CAN1 FALSE
#define STM32_HAS_CAN2 FALSE
+#define STM32_HAS_CAN3 FALSE
#define STM32_CAN_MAX_FILTERS 0
/* DAC attributes.*/
@@ -280,6 +281,7 @@
/* CAN attributes.*/
#define STM32_HAS_CAN1 TRUE
#define STM32_HAS_CAN2 FALSE
+#define STM32_HAS_CAN3 FALSE
#define STM32_CAN_MAX_FILTERS 14
/* DAC attributes.*/
@@ -456,6 +458,7 @@
/* CAN attributes.*/
#define STM32_HAS_CAN1 TRUE
#define STM32_HAS_CAN2 FALSE
+#define STM32_HAS_CAN3 FALSE
#define STM32_CAN_MAX_FILTERS 14
/* DAC attributes.*/
@@ -648,6 +651,7 @@
/* CAN attributes.*/
#define STM32_HAS_CAN1 TRUE
#define STM32_HAS_CAN2 FALSE
+#define STM32_HAS_CAN3 FALSE
#define STM32_CAN_MAX_FILTERS 14
/* DAC attributes.*/
@@ -900,6 +904,7 @@
/* CAN attributes.*/
#define STM32_HAS_CAN1 TRUE
#define STM32_HAS_CAN2 FALSE
+#define STM32_HAS_CAN3 FALSE
#define STM32_CAN_MAX_FILTERS 14
/* DAC attributes.*/
@@ -1149,6 +1154,7 @@
/* CAN attributes.*/
#define STM32_HAS_CAN1 TRUE
#define STM32_HAS_CAN2 TRUE
+#define STM32_HAS_CAN3 FALSE
#define STM32_CAN_MAX_FILTERS 28
/* DAC attributes.*/
diff --git a/os/hal/ports/STM32/STM32F37x/stm32_registry.h b/os/hal/ports/STM32/STM32F37x/stm32_registry.h
index f9bd0ba7d..3f22e5c79 100644
--- a/os/hal/ports/STM32/STM32F37x/stm32_registry.h
+++ b/os/hal/ports/STM32/STM32F37x/stm32_registry.h
@@ -50,6 +50,7 @@
/* CAN attributes.*/
#define STM32_HAS_CAN1 TRUE
#define STM32_HAS_CAN2 FALSE
+#define STM32_HAS_CAN3 FALSE
#define STM32_CAN_MAX_FILTERS 14
/* DAC attributes.*/
@@ -301,6 +302,7 @@
/* CAN attributes.*/
#define STM32_HAS_CAN1 TRUE
#define STM32_HAS_CAN2 FALSE
+#define STM32_HAS_CAN3 FALSE
#define STM32_CAN_MAX_FILTERS 14
/* DAC attributes.*/
diff --git a/os/hal/ports/STM32/STM32F3xx/stm32_registry.h b/os/hal/ports/STM32/STM32F3xx/stm32_registry.h
index f0c83fe22..3e3da573e 100644
--- a/os/hal/ports/STM32/STM32F3xx/stm32_registry.h
+++ b/os/hal/ports/STM32/STM32F3xx/stm32_registry.h
@@ -82,6 +82,7 @@
/* CAN attributes.*/
#define STM32_HAS_CAN1 TRUE
#define STM32_HAS_CAN2 FALSE
+#define STM32_HAS_CAN3 FALSE
#define STM32_CAN_MAX_FILTERS 14
/* DAC attributes.*/
@@ -343,6 +344,7 @@
/* CAN attributes.*/
#define STM32_HAS_CAN1 TRUE
#define STM32_HAS_CAN2 FALSE
+#define STM32_HAS_CAN3 FALSE
#define STM32_CAN_MAX_FILTERS 14
/* DAC attributes.*/
@@ -606,6 +608,7 @@
/* CAN attributes.*/
#define STM32_HAS_CAN1 TRUE
#define STM32_HAS_CAN2 FALSE
+#define STM32_HAS_CAN3 FALSE
#define STM32_CAN_MAX_FILTERS 14
/* DAC attributes.*/
@@ -820,6 +823,7 @@
/* CAN attributes.*/
#define STM32_HAS_CAN1 FALSE
#define STM32_HAS_CAN2 FALSE
+#define STM32_HAS_CAN3 FALSE
#define STM32_CAN_MAX_FILTERS 14
/* DAC attributes.*/
@@ -1033,6 +1037,7 @@
/* CAN attributes.*/
#define STM32_HAS_CAN1 TRUE
#define STM32_HAS_CAN2 FALSE
+#define STM32_HAS_CAN3 FALSE
#define STM32_CAN_MAX_FILTERS 14
/* DAC attributes.*/
@@ -1255,6 +1260,7 @@
/* CAN attributes.*/
#define STM32_HAS_CAN1 TRUE
#define STM32_HAS_CAN2 FALSE
+#define STM32_HAS_CAN3 FALSE
#define STM32_CAN_MAX_FILTERS 14
/* DAC attributes.*/
@@ -1499,6 +1505,7 @@
/* CAN attributes.*/
#define STM32_HAS_CAN1 TRUE
#define STM32_HAS_CAN2 FALSE
+#define STM32_HAS_CAN3 FALSE
#define STM32_CAN_MAX_FILTERS 14
/* DAC attributes.*/
@@ -1746,6 +1753,7 @@
/* CAN attributes.*/
#define STM32_HAS_CAN1 TRUE
#define STM32_HAS_CAN2 FALSE
+#define STM32_HAS_CAN3 FALSE
#define STM32_CAN_MAX_FILTERS 14
/* DAC attributes.*/
@@ -1964,6 +1972,7 @@
/* CAN attributes.*/
#define STM32_HAS_CAN1 TRUE
#define STM32_HAS_CAN2 FALSE
+#define STM32_HAS_CAN3 FALSE
#define STM32_CAN_MAX_FILTERS 14
/* DAC attributes.*/
@@ -2181,6 +2190,7 @@
/* CAN attributes.*/
#define STM32_HAS_CAN1 TRUE
#define STM32_HAS_CAN2 FALSE
+#define STM32_HAS_CAN3 FALSE
#define STM32_CAN_MAX_FILTERS 14
/* DAC attributes.*/
@@ -2427,6 +2437,7 @@
/* CAN attributes.*/
#define STM32_HAS_CAN1 TRUE
#define STM32_HAS_CAN2 FALSE
+#define STM32_HAS_CAN3 FALSE
#define STM32_CAN_MAX_FILTERS 14
/* DAC attributes.*/
@@ -2654,6 +2665,7 @@
/* CAN attributes.*/
#define STM32_HAS_CAN1 TRUE
#define STM32_HAS_CAN2 FALSE
+#define STM32_HAS_CAN3 FALSE
#define STM32_CAN_MAX_FILTERS 14
/* DAC attributes.*/
diff --git a/os/hal/ports/STM32/STM32F4xx/stm32_registry.h b/os/hal/ports/STM32/STM32F4xx/stm32_registry.h
index 159a911c0..25be1e4ed 100644
--- a/os/hal/ports/STM32/STM32F4xx/stm32_registry.h
+++ b/os/hal/ports/STM32/STM32F4xx/stm32_registry.h
@@ -114,6 +114,7 @@
/* CAN attributes.*/
#define STM32_HAS_CAN1 TRUE
#define STM32_HAS_CAN2 TRUE
+#define STM32_HAS_CAN3 FALSE
#define STM32_CAN_MAX_FILTERS 28
/* DAC attributes.*/
@@ -484,6 +485,7 @@
/* CAN attributes.*/
#define STM32_HAS_CAN1 TRUE
#define STM32_HAS_CAN2 TRUE
+#define STM32_HAS_CAN3 FALSE
#define STM32_CAN_MAX_FILTERS 28
/* DAC attributes.*/
@@ -829,6 +831,7 @@
/* CAN attributes.*/
#define STM32_HAS_CAN1 TRUE
#define STM32_HAS_CAN2 TRUE
+#define STM32_HAS_CAN3 FALSE
#define STM32_CAN_MAX_FILTERS 28
/* DAC attributes.*/
@@ -1187,6 +1190,7 @@
/* CAN attributes.*/
#define STM32_HAS_CAN1 TRUE
#define STM32_HAS_CAN2 TRUE
+#define STM32_HAS_CAN3 FALSE
#define STM32_CAN_MAX_FILTERS 28
/* DAC attributes.*/
@@ -1510,6 +1514,7 @@
/* CAN attributes.*/
#define STM32_HAS_CAN1 FALSE
#define STM32_HAS_CAN2 FALSE
+#define STM32_HAS_CAN3 FALSE
/* DAC attributes.*/
#define STM32_HAS_DAC1_CH1 FALSE
@@ -1804,6 +1809,7 @@
/* CAN attributes.*/
#define STM32_HAS_CAN1 FALSE
#define STM32_HAS_CAN2 FALSE
+#define STM32_HAS_CAN3 FALSE
/* DAC attributes.*/
#define STM32_HAS_DAC1_CH1 TRUE
@@ -2079,6 +2085,7 @@
/* CAN attributes.*/
#define STM32_HAS_CAN1 TRUE
#define STM32_HAS_CAN2 TRUE
+#define STM32_HAS_CAN3 FALSE
#define STM32_CAN_MAX_FILTERS 28
/* DAC attributes.*/
@@ -2421,6 +2428,7 @@
/* CAN attributes.*/
#define STM32_HAS_CAN1 TRUE
#define STM32_HAS_CAN2 TRUE
+#define STM32_HAS_CAN3 FALSE
#define STM32_CAN_MAX_FILTERS 28
/* DAC attributes.*/
diff --git a/os/hal/ports/STM32/STM32F7xx/stm32_rcc.h b/os/hal/ports/STM32/STM32F7xx/stm32_rcc.h
index d55e4afa5..27e52e3a4 100644
--- a/os/hal/ports/STM32/STM32F7xx/stm32_rcc.h
+++ b/os/hal/ports/STM32/STM32F7xx/stm32_rcc.h
@@ -522,6 +522,31 @@
* @api
*/
#define rccResetCAN2() rccResetAPB1(RCC_APB1RSTR_CAN2RST)
+
+/**
+ * @brief Resets the CAN3 peripheral.
+ *
+ * @api
+ */
+#define rccResetCAN3() rccResetAPB1(RCC_APB1RSTR_CAN3RST)
+
+/**
+ * @brief Enables the CAN3 peripheral clock.
+ *
+ * @param[in] lp low power enable flag
+ *
+ * @api
+ */
+#define rccEnableCAN3(lp) rccEnableAPB1(RCC_APB1ENR_CAN3EN, lp)
+
+/**
+ * @brief Disables the CAN3 peripheral clock.
+ *
+ * @param[in] lp low power enable flag
+ *
+ * @api
+ */
+#define rccDisableCAN3(lp) rccDisableAPB1(RCC_APB1ENR_CAN3EN, lp)
/** @} */
/**
diff --git a/os/hal/ports/STM32/STM32F7xx/stm32_registry.h b/os/hal/ports/STM32/STM32F7xx/stm32_registry.h
index 30a361151..ff06fe86e 100644
--- a/os/hal/ports/STM32/STM32F7xx/stm32_registry.h
+++ b/os/hal/ports/STM32/STM32F7xx/stm32_registry.h
@@ -86,6 +86,18 @@
#define STM32_CAN2_RX1_NUMBER 65
#define STM32_CAN2_SCE_NUMBER 66
+#define STM32_CAN3_MAX_FILTERS 14
+
+#define STM32_HAS_CAN3 TRUE
+#define STM32_CAN3_TX_HANDLER Vector1E0
+#define STM32_CAN3_RX0_HANDLER Vector1E4
+#define STM32_CAN3_RX1_HANDLER Vector1E8
+#define STM32_CAN3_SCE_HANDLER Vector1EC
+#define STM32_CAN3_TX_NUMBER 104
+#define STM32_CAN3_RX0_NUMBER 105
+#define STM32_CAN3_RX1_NUMBER 106
+#define STM32_CAN3_SCE_NUMBER 107
+
/* DAC attributes.*/
#define STM32_HAS_DAC1_CH1 TRUE
#define STM32_DAC1_CH1_DMA_MSK STM32_DMA_STREAM_ID_MSK(1, 5)
diff --git a/os/hal/ports/STM32/STM32L0xx/stm32_registry.h b/os/hal/ports/STM32/STM32L0xx/stm32_registry.h
index 5ec62184f..c7f3c1dfd 100644
--- a/os/hal/ports/STM32/STM32L0xx/stm32_registry.h
+++ b/os/hal/ports/STM32/STM32L0xx/stm32_registry.h
@@ -56,6 +56,7 @@
/* CAN attributes.*/
#define STM32_HAS_CAN1 FALSE
#define STM32_HAS_CAN2 FALSE
+#define STM32_HAS_CAN3 FALSE
/* DAC attributes.*/
#define STM32_HAS_DAC1_CH1 FALSE
@@ -270,6 +271,7 @@
/* CAN attributes.*/
#define STM32_HAS_CAN1 FALSE
#define STM32_HAS_CAN2 FALSE
+#define STM32_HAS_CAN3 FALSE
/* DAC attributes.*/
#define STM32_HAS_DAC1_CH1 FALSE
@@ -488,6 +490,7 @@
/* CAN attributes.*/
#define STM32_HAS_CAN1 FALSE
#define STM32_HAS_CAN2 FALSE
+#define STM32_HAS_CAN3 FALSE
/* DAC attributes.*/
#define STM32_HAS_DAC1_CH1 FALSE
@@ -737,6 +740,7 @@
/* CAN attributes.*/
#define STM32_HAS_CAN1 FALSE
#define STM32_HAS_CAN2 FALSE
+#define STM32_HAS_CAN3 FALSE
/* DAC attributes.*/
#define STM32_HAS_DAC1_CH1 TRUE
@@ -995,6 +999,7 @@
/* CAN attributes.*/
#define STM32_HAS_CAN1 FALSE
#define STM32_HAS_CAN2 FALSE
+#define STM32_HAS_CAN3 FALSE
/* DAC attributes.*/
#define STM32_HAS_DAC1_CH1 FALSE
@@ -1252,6 +1257,7 @@
/* CAN attributes.*/
#define STM32_HAS_CAN1 FALSE
#define STM32_HAS_CAN2 FALSE
+#define STM32_HAS_CAN3 FALSE
/* DAC attributes.*/
#define STM32_HAS_DAC1_CH1 TRUE
diff --git a/os/hal/ports/STM32/STM32L1xx/stm32_registry.h b/os/hal/ports/STM32/STM32L1xx/stm32_registry.h
index 4107527cf..fe5f0bb68 100644
--- a/os/hal/ports/STM32/STM32L1xx/stm32_registry.h
+++ b/os/hal/ports/STM32/STM32L1xx/stm32_registry.h
@@ -70,7 +70,7 @@
/* CAN attributes.*/
#define STM32_HAS_CAN1 FALSE
#define STM32_HAS_CAN2 FALSE
-#define STM32_CAN_MAX_FILTERS 0
+#define STM32_HAS_CAN3 FALSE
/* DAC attributes.*/
#define STM32_HAS_DAC1_CH1 TRUE
diff --git a/os/hal/ports/STM32/STM32L4xx/stm32_registry.h b/os/hal/ports/STM32/STM32L4xx/stm32_registry.h
index 3b48d81ce..9e0bb36f6 100644
--- a/os/hal/ports/STM32/STM32L4xx/stm32_registry.h
+++ b/os/hal/ports/STM32/STM32L4xx/stm32_registry.h
@@ -65,6 +65,7 @@
/* CAN attributes.*/
#define STM32_HAS_CAN1 FALSE
#define STM32_HAS_CAN2 FALSE
+#define STM32_HAS_CAN3 FALSE
/* DAC attributes.*/
#define STM32_HAS_DAC1_CH1 TRUE
@@ -394,6 +395,7 @@
#define STM32_CAN1_SCE_NUMBER 22
#define STM32_HAS_CAN2 FALSE
+#define STM32_HAS_CAN3 FALSE
/* DAC attributes.*/
#define STM32_HAS_DAC1_CH1 TRUE