aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--demos/STM32/RT-STM32H743I-NUCLEO144/debug/RT-STM32H743I-NUCLEO144 (OpenOCD, Just Run).launch104
-rw-r--r--os/hal/include/hal_can.h69
-rw-r--r--os/hal/ports/STM32/LLD/CANv1/hal_can_lld.c106
-rw-r--r--os/hal/ports/STM32/LLD/CANv1/hal_can_lld.h51
-rw-r--r--os/hal/src/hal_can.c17
-rw-r--r--os/hal/templates/hal_can_lld.h51
-rw-r--r--readme.txt2
7 files changed, 266 insertions, 134 deletions
diff --git a/demos/STM32/RT-STM32H743I-NUCLEO144/debug/RT-STM32H743I-NUCLEO144 (OpenOCD, Just Run).launch b/demos/STM32/RT-STM32H743I-NUCLEO144/debug/RT-STM32H743I-NUCLEO144 (OpenOCD, Just Run).launch
index 5bfe1e7cd..ce45f3107 100644
--- a/demos/STM32/RT-STM32H743I-NUCLEO144/debug/RT-STM32H743I-NUCLEO144 (OpenOCD, Just Run).launch
+++ b/demos/STM32/RT-STM32H743I-NUCLEO144/debug/RT-STM32H743I-NUCLEO144 (OpenOCD, Just Run).launch
@@ -1,52 +1,52 @@
-<?xml version="1.0" encoding="UTF-8" standalone="no"?>
-<launchConfiguration type="org.eclipse.cdt.debug.gdbjtag.launchConfigurationType">
-<stringAttribute key="bad_container_name" value="\RT-STM32H743I-NUCLEO144\debug"/>
-<intAttribute key="org.eclipse.cdt.debug.gdbjtag.core.delay" value="1"/>
-<booleanAttribute key="org.eclipse.cdt.debug.gdbjtag.core.doHalt" value="true"/>
-<booleanAttribute key="org.eclipse.cdt.debug.gdbjtag.core.doReset" value="true"/>
-<stringAttribute key="org.eclipse.cdt.debug.gdbjtag.core.imageFileName" value=""/>
-<stringAttribute key="org.eclipse.cdt.debug.gdbjtag.core.imageOffset" value=""/>
-<stringAttribute key="org.eclipse.cdt.debug.gdbjtag.core.initCommands" value="set remotetimeout 20&#13;&#10;monitor reset init&#13;&#10;monitor sleep 50&#13;&#10;"/>
-<stringAttribute key="org.eclipse.cdt.debug.gdbjtag.core.ipAddress" value="localhost"/>
-<stringAttribute key="org.eclipse.cdt.debug.gdbjtag.core.jtagDevice" value="Generic TCP/IP"/>
-<booleanAttribute key="org.eclipse.cdt.debug.gdbjtag.core.loadImage" value="false"/>
-<booleanAttribute key="org.eclipse.cdt.debug.gdbjtag.core.loadSymbols" value="true"/>
-<stringAttribute key="org.eclipse.cdt.debug.gdbjtag.core.pcRegister" value=""/>
-<intAttribute key="org.eclipse.cdt.debug.gdbjtag.core.portNumber" value="3333"/>
-<stringAttribute key="org.eclipse.cdt.debug.gdbjtag.core.runCommands" value=""/>
-<booleanAttribute key="org.eclipse.cdt.debug.gdbjtag.core.setPcRegister" value="false"/>
-<booleanAttribute key="org.eclipse.cdt.debug.gdbjtag.core.setResume" value="true"/>
-<booleanAttribute key="org.eclipse.cdt.debug.gdbjtag.core.setStopAt" value="true"/>
-<stringAttribute key="org.eclipse.cdt.debug.gdbjtag.core.stopAt" value="main"/>
-<stringAttribute key="org.eclipse.cdt.debug.gdbjtag.core.symbolsFileName" value=""/>
-<stringAttribute key="org.eclipse.cdt.debug.gdbjtag.core.symbolsOffset" value=""/>
-<booleanAttribute key="org.eclipse.cdt.debug.gdbjtag.core.useFileForImage" value="false"/>
-<booleanAttribute key="org.eclipse.cdt.debug.gdbjtag.core.useFileForSymbols" value="false"/>
-<booleanAttribute key="org.eclipse.cdt.debug.gdbjtag.core.useProjBinaryForImage" value="true"/>
-<booleanAttribute key="org.eclipse.cdt.debug.gdbjtag.core.useProjBinaryForSymbols" value="true"/>
-<booleanAttribute key="org.eclipse.cdt.debug.gdbjtag.core.useRemoteTarget" value="true"/>
-<stringAttribute key="org.eclipse.cdt.debug.mi.core.DEBUG_NAME" value="arm-none-eabi-gdb"/>
-<stringAttribute key="org.eclipse.cdt.debug.mi.core.commandFactory" value="Standard"/>
-<stringAttribute key="org.eclipse.cdt.debug.mi.core.protocol" value="mi"/>
-<booleanAttribute key="org.eclipse.cdt.debug.mi.core.verboseMode" value="false"/>
-<stringAttribute key="org.eclipse.cdt.dsf.gdb.DEBUG_NAME" value="arm-none-eabi-gdb"/>
-<intAttribute key="org.eclipse.cdt.launch.ATTR_BUILD_BEFORE_LAUNCH_ATTR" value="0"/>
-<stringAttribute key="org.eclipse.cdt.launch.COREFILE_PATH" value=""/>
-<stringAttribute key="org.eclipse.cdt.launch.DEBUGGER_REGISTER_GROUPS" value=""/>
-<stringAttribute key="org.eclipse.cdt.launch.FORMAT" value="&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot; standalone=&quot;no&quot;?&gt;&lt;contentList&gt;&lt;content id=&quot;r3-(format)&quot; val=&quot;4&quot;/&gt;&lt;content id=&quot;vt_delta-null-chVTDoSetI-(format)&quot; val=&quot;4&quot;/&gt;&lt;/contentList&gt;"/>
-<stringAttribute key="org.eclipse.cdt.launch.GLOBAL_VARIABLES" value="&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot; standalone=&quot;no&quot;?&gt;&#13;&#10;&lt;globalVariableList/&gt;&#13;&#10;"/>
-<stringAttribute key="org.eclipse.cdt.launch.MEMORY_BLOCKS" value="&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot; standalone=&quot;no&quot;?&gt;&#13;&#10;&lt;memoryBlockExpressionList/&gt;&#13;&#10;"/>
-<stringAttribute key="org.eclipse.cdt.launch.PROGRAM_NAME" value="./build/ch.elf"/>
-<stringAttribute key="org.eclipse.cdt.launch.PROJECT_ATTR" value="RT-STM32H743I-NUCLEO144"/>
-<booleanAttribute key="org.eclipse.cdt.launch.PROJECT_BUILD_CONFIG_AUTO_ATTR" value="true"/>
-<stringAttribute key="org.eclipse.cdt.launch.PROJECT_BUILD_CONFIG_ID_ATTR" value="0.114656749"/>
-<listAttribute key="org.eclipse.debug.core.MAPPED_RESOURCE_PATHS">
-<listEntry value="/RT-STM32H743I-NUCLEO144"/>
-</listAttribute>
-<listAttribute key="org.eclipse.debug.core.MAPPED_RESOURCE_TYPES">
-<listEntry value="4"/>
-</listAttribute>
-<listAttribute key="org.eclipse.debug.ui.favoriteGroups">
-<listEntry value="org.eclipse.debug.ui.launchGroup.debug"/>
-</listAttribute>
-</launchConfiguration>
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<launchConfiguration type="org.eclipse.cdt.debug.gdbjtag.launchConfigurationType">
+<stringAttribute key="bad_container_name" value="\RT-STM32H743I-NUCLEO144\debug"/>
+<intAttribute key="org.eclipse.cdt.debug.gdbjtag.core.delay" value="1"/>
+<booleanAttribute key="org.eclipse.cdt.debug.gdbjtag.core.doHalt" value="true"/>
+<booleanAttribute key="org.eclipse.cdt.debug.gdbjtag.core.doReset" value="true"/>
+<stringAttribute key="org.eclipse.cdt.debug.gdbjtag.core.imageFileName" value=""/>
+<stringAttribute key="org.eclipse.cdt.debug.gdbjtag.core.imageOffset" value=""/>
+<stringAttribute key="org.eclipse.cdt.debug.gdbjtag.core.initCommands" value="set remotetimeout 20&#13;&#10;monitor reset init&#13;&#10;monitor sleep 50&#13;&#10;"/>
+<stringAttribute key="org.eclipse.cdt.debug.gdbjtag.core.ipAddress" value="localhost"/>
+<stringAttribute key="org.eclipse.cdt.debug.gdbjtag.core.jtagDevice" value="Generic TCP/IP"/>
+<booleanAttribute key="org.eclipse.cdt.debug.gdbjtag.core.loadImage" value="false"/>
+<booleanAttribute key="org.eclipse.cdt.debug.gdbjtag.core.loadSymbols" value="true"/>
+<stringAttribute key="org.eclipse.cdt.debug.gdbjtag.core.pcRegister" value=""/>
+<intAttribute key="org.eclipse.cdt.debug.gdbjtag.core.portNumber" value="3333"/>
+<stringAttribute key="org.eclipse.cdt.debug.gdbjtag.core.runCommands" value=""/>
+<booleanAttribute key="org.eclipse.cdt.debug.gdbjtag.core.setPcRegister" value="false"/>
+<booleanAttribute key="org.eclipse.cdt.debug.gdbjtag.core.setResume" value="true"/>
+<booleanAttribute key="org.eclipse.cdt.debug.gdbjtag.core.setStopAt" value="true"/>
+<stringAttribute key="org.eclipse.cdt.debug.gdbjtag.core.stopAt" value="main"/>
+<stringAttribute key="org.eclipse.cdt.debug.gdbjtag.core.symbolsFileName" value=""/>
+<stringAttribute key="org.eclipse.cdt.debug.gdbjtag.core.symbolsOffset" value=""/>
+<booleanAttribute key="org.eclipse.cdt.debug.gdbjtag.core.useFileForImage" value="false"/>
+<booleanAttribute key="org.eclipse.cdt.debug.gdbjtag.core.useFileForSymbols" value="false"/>
+<booleanAttribute key="org.eclipse.cdt.debug.gdbjtag.core.useProjBinaryForImage" value="true"/>
+<booleanAttribute key="org.eclipse.cdt.debug.gdbjtag.core.useProjBinaryForSymbols" value="true"/>
+<booleanAttribute key="org.eclipse.cdt.debug.gdbjtag.core.useRemoteTarget" value="true"/>
+<stringAttribute key="org.eclipse.cdt.debug.mi.core.DEBUG_NAME" value="arm-none-eabi-gdb"/>
+<stringAttribute key="org.eclipse.cdt.debug.mi.core.commandFactory" value="Standard"/>
+<stringAttribute key="org.eclipse.cdt.debug.mi.core.protocol" value="mi"/>
+<booleanAttribute key="org.eclipse.cdt.debug.mi.core.verboseMode" value="false"/>
+<stringAttribute key="org.eclipse.cdt.dsf.gdb.DEBUG_NAME" value="arm-none-eabi-gdb"/>
+<intAttribute key="org.eclipse.cdt.launch.ATTR_BUILD_BEFORE_LAUNCH_ATTR" value="0"/>
+<stringAttribute key="org.eclipse.cdt.launch.COREFILE_PATH" value=""/>
+<stringAttribute key="org.eclipse.cdt.launch.DEBUGGER_REGISTER_GROUPS" value=""/>
+<stringAttribute key="org.eclipse.cdt.launch.FORMAT" value="&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot; standalone=&quot;no&quot;?&gt;&lt;contentList&gt;&lt;content id=&quot;r3-(format)&quot; val=&quot;4&quot;/&gt;&lt;content id=&quot;vt_delta-null-chVTDoSetI-(format)&quot; val=&quot;4&quot;/&gt;&lt;/contentList&gt;"/>
+<stringAttribute key="org.eclipse.cdt.launch.GLOBAL_VARIABLES" value="&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot; standalone=&quot;no&quot;?&gt;&#10;&lt;globalVariableList/&gt;&#10;"/>
+<stringAttribute key="org.eclipse.cdt.launch.MEMORY_BLOCKS" value="&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot; standalone=&quot;no&quot;?&gt;&#10;&lt;memoryBlockExpressionList/&gt;&#10;"/>
+<stringAttribute key="org.eclipse.cdt.launch.PROGRAM_NAME" value="./build/ch.elf"/>
+<stringAttribute key="org.eclipse.cdt.launch.PROJECT_ATTR" value="RT-STM32H743I-NUCLEO144"/>
+<booleanAttribute key="org.eclipse.cdt.launch.PROJECT_BUILD_CONFIG_AUTO_ATTR" value="true"/>
+<stringAttribute key="org.eclipse.cdt.launch.PROJECT_BUILD_CONFIG_ID_ATTR" value="0.114656749"/>
+<listAttribute key="org.eclipse.debug.core.MAPPED_RESOURCE_PATHS">
+<listEntry value="/RT-STM32H743I-NUCLEO144"/>
+</listAttribute>
+<listAttribute key="org.eclipse.debug.core.MAPPED_RESOURCE_TYPES">
+<listEntry value="4"/>
+</listAttribute>
+<listAttribute key="org.eclipse.debug.ui.favoriteGroups">
+<listEntry value="org.eclipse.debug.ui.launchGroup.debug"/>
+</listAttribute>
+</launchConfiguration>
diff --git a/os/hal/include/hal_can.h b/os/hal/include/hal_can.h
index 78bd12a20..16b487d46 100644
--- a/os/hal/include/hal_can.h
+++ b/os/hal/include/hal_can.h
@@ -60,7 +60,7 @@
/**
* @brief Special mailbox identifier.
*/
-#define CAN_ANY_MAILBOX 0
+#define CAN_ANY_MAILBOX 0U
/*===========================================================================*/
/* Driver pre-compile time settings. */
@@ -132,6 +132,73 @@ typedef enum {
canReceiveTimeout(canp, mailbox, crfp, timeout)
/** @} */
+/**
+ * @name Low level driver helper macros
+ * @{
+ */
+#if !defined(CAN_ENFORCE_USE_CALLBACKS)
+/**
+ * @brief TX mailbox empty event.
+ */
+#define _can_tx_empty_isr(canp, flags) { \
+ osalSysLockFromISR(); \
+ osalThreadDequeueAllI(&(canp)->txqueue, MSG_OK); \
+ osalEventBroadcastFlagsI(&(canp)->txempty_event, flags); \
+ osalSysUnlockFromISR(); \
+}
+
+/**
+ * @brief RX mailbox empty full event.
+ */
+#define _can_rx_full_isr(canp, flags) { \
+ osalSysLockFromISR(); \
+ osalThreadDequeueAllI(&(canp)->rxqueue, MSG_OK); \
+ osalEventBroadcastFlagsI(&(canp)->rxfull_event, flags); \
+ osalSysUnlockFromISR(); \
+}
+
+/**
+ * @brief Error event.
+ */
+#define _can_wakeup_isr(canp) { \
+ osalSysLockFromISR(); \
+ osalEventBroadcastFlagsI(&(canp)->wakeup_event, 0U); \
+ osalSysUnlockFromISR(); \
+}
+
+/**
+ * @brief Error event.
+ */
+#define _can_error_isr(canp, flags) { \
+ osalSysLockFromISR(); \
+ osalEventBroadcastFlagsI(&(canp)->error_event, flags); \
+ osalSysUnlockFromISR(); \
+}
+#else /* defined(CAN_ENFORCE_USE_CALLBACKS) */
+#define _can_tx_empty_isr(canp, flags) { \
+ (canp)->txempty_cb(canp, flags); \
+ osalSysLockFromISR(); \
+ osalThreadDequeueAllI(&(canp)->txqueue, MSG_OK); \
+ osalSysUnlockFromISR(); \
+}
+
+#define _can_rx_full_isr(canp, flags) { \
+ (canp)->rxfull_cb(canp, flags); \
+ osalSysLockFromISR(); \
+ osalThreadDequeueAllI(&(canp)->rxqueue, MSG_OK); \
+ osalSysUnlockFromISR(); \
+}
+
+#define _can_wakeup_isr(canp) { \
+ (canp)->wakeup_cb(canp, 0U); \
+}
+
+#define _can_error_isr(canp, flags) { \
+ (canp)->error_cb(canp, flags); \
+}
+#endif /* defined(CAN_ENFORCE_USE_CALLBACKS) */
+/** @} */
+
/*===========================================================================*/
/* External declarations. */
/*===========================================================================*/
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 d0a25fb77..064e4d3b0 100644
--- a/os/hal/ports/STM32/LLD/CANv1/hal_can_lld.c
+++ b/os/hal/ports/STM32/LLD/CANv1/hal_can_lld.c
@@ -236,10 +236,7 @@ static void can_lld_tx_handler(CANDriver *canp) {
}
/* Signaling flags and waking up threads waiting for a transmission slot.*/
- osalSysLockFromISR();
- osalThreadDequeueAllI(&canp->txqueue, MSG_OK);
- osalEventBroadcastFlagsI(&canp->txempty_event, flags);
- osalSysUnlockFromISR();
+ _can_tx_empty_isr(canp, flags);
}
/**
@@ -256,17 +253,12 @@ static void can_lld_rx0_handler(CANDriver *canp) {
if ((rf0r & CAN_RF0R_FMP0) > 0) {
/* No more receive events until the queue 0 has been emptied.*/
canp->can->IER &= ~CAN_IER_FMPIE0;
- osalSysLockFromISR();
- osalThreadDequeueAllI(&canp->rxqueue, MSG_OK);
- osalEventBroadcastFlagsI(&canp->rxfull_event, CAN_MAILBOX_TO_MASK(1U));
- osalSysUnlockFromISR();
+ _can_rx_full_isr(canp, CAN_MAILBOX_TO_MASK(1U));
}
if ((rf0r & CAN_RF0R_FOVR0) > 0) {
/* Overflow events handling.*/
canp->can->RF0R = CAN_RF0R_FOVR0;
- osalSysLockFromISR();
- osalEventBroadcastFlagsI(&canp->error_event, CAN_OVERFLOW_ERROR);
- osalSysUnlockFromISR();
+ _can_error_isr(canp, CAN_OVERFLOW_ERROR);
}
}
@@ -284,17 +276,12 @@ static void can_lld_rx1_handler(CANDriver *canp) {
if ((rf1r & CAN_RF1R_FMP1) > 0) {
/* No more receive events until the queue 0 has been emptied.*/
canp->can->IER &= ~CAN_IER_FMPIE1;
- osalSysLockFromISR();
- osalThreadDequeueAllI(&canp->rxqueue, MSG_OK);
- osalEventBroadcastFlagsI(&canp->rxfull_event, CAN_MAILBOX_TO_MASK(2U));
- osalSysUnlockFromISR();
+ _can_rx_full_isr(canp, CAN_MAILBOX_TO_MASK(2U));
}
if ((rf1r & CAN_RF1R_FOVR1) > 0) {
/* Overflow events handling.*/
canp->can->RF1R = CAN_RF1R_FOVR1;
- osalSysLockFromISR();
- osalEventBroadcastFlagsI(&canp->error_event, CAN_OVERFLOW_ERROR);
- osalSysUnlockFromISR();
+ _can_error_isr(canp, CAN_OVERFLOW_ERROR);
}
}
@@ -317,9 +304,7 @@ static void can_lld_sce_handler(CANDriver *canp) {
if (msr & CAN_MSR_WKUI) {
canp->state = CAN_READY;
canp->can->MCR &= ~CAN_MCR_SLEEP;
- osalSysLockFromISR();
- osalEventBroadcastFlagsI(&canp->wakeup_event, 0);
- osalSysUnlockFromISR();
+ _can_wakeup_isr(canp);
}
#endif /* CAN_USE_SLEEP_MODE */
/* Error event.*/
@@ -335,12 +320,9 @@ static void can_lld_sce_handler(CANDriver *canp) {
flags = 0;
#endif
- osalSysLockFromISR();
/* The content of the ESR register is copied unchanged in the upper
half word of the listener flags mask.*/
- osalEventBroadcastFlagsI(&canp->error_event,
- flags | (eventflags_t)(esr << 16U));
- osalSysUnlockFromISR();
+ _can_error_isr(canp, flags | (eventflags_t)(esr << 16U));
}
}
@@ -636,16 +618,42 @@ void can_lld_init(void) {
/* Driver initialization.*/
canObjectInit(&CAND1);
CAND1.can = CAN1;
+#if defined(STM32_CAN1_UNIFIED_NUMBER)
+ nvicEnableVector(STM32_CAN1_UNIFIED_NUMBER, STM32_CAN_CAN1_IRQ_PRIORITY);
+#else
+ nvicEnableVector(STM32_CAN1_TX_NUMBER, STM32_CAN_CAN1_IRQ_PRIORITY);
+ nvicEnableVector(STM32_CAN1_RX0_NUMBER, STM32_CAN_CAN1_IRQ_PRIORITY);
+ nvicEnableVector(STM32_CAN1_RX1_NUMBER, STM32_CAN_CAN1_IRQ_PRIORITY);
+ nvicEnableVector(STM32_CAN1_SCE_NUMBER, STM32_CAN_CAN1_IRQ_PRIORITY);
+#endif
#endif
+
#if STM32_CAN_USE_CAN2
/* Driver initialization.*/
canObjectInit(&CAND2);
CAND2.can = CAN2;
+#if defined(STM32_CAN2_UNIFIED_NUMBER)
+ nvicEnableVector(STM32_CAN2_UNIFIED_NUMBER, STM32_CAN_CAN2_IRQ_PRIORITY);
+#else
+ nvicEnableVector(STM32_CAN2_TX_NUMBER, STM32_CAN_CAN2_IRQ_PRIORITY);
+ nvicEnableVector(STM32_CAN2_RX0_NUMBER, STM32_CAN_CAN2_IRQ_PRIORITY);
+ nvicEnableVector(STM32_CAN2_RX1_NUMBER, STM32_CAN_CAN2_IRQ_PRIORITY);
+ nvicEnableVector(STM32_CAN2_SCE_NUMBER, STM32_CAN_CAN2_IRQ_PRIORITY);
+#endif
#endif
+
#if STM32_CAN_USE_CAN3
/* Driver initialization.*/
canObjectInit(&CAND3);
CAND3.can = CAN3;
+#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
#endif
/* Filters initialization.*/
@@ -674,14 +682,6 @@ void can_lld_start(CANDriver *canp) {
/* Clock activation.*/
#if STM32_CAN_USE_CAN1
if (&CAND1 == canp) {
-#if defined(STM32_CAN1_UNIFIED_NUMBER)
- nvicEnableVector(STM32_CAN1_UNIFIED_NUMBER, STM32_CAN_CAN1_IRQ_PRIORITY);
-#else
- nvicEnableVector(STM32_CAN1_TX_NUMBER, STM32_CAN_CAN1_IRQ_PRIORITY);
- nvicEnableVector(STM32_CAN1_RX0_NUMBER, STM32_CAN_CAN1_IRQ_PRIORITY);
- nvicEnableVector(STM32_CAN1_RX1_NUMBER, STM32_CAN_CAN1_IRQ_PRIORITY);
- nvicEnableVector(STM32_CAN1_SCE_NUMBER, STM32_CAN_CAN1_IRQ_PRIORITY);
-#endif
rccEnableCAN1(FALSE);
}
#endif
@@ -691,28 +691,12 @@ void can_lld_start(CANDriver *canp) {
osalDbgAssert(CAND1.state != CAN_STOP, "CAN1 must be started");
-#if defined(STM32_CAN2_UNIFIED_NUMBER)
- nvicEnableVector(STM32_CAN2_UNIFIED_NUMBER, STM32_CAN_CAN2_IRQ_PRIORITY);
-#else
- nvicEnableVector(STM32_CAN2_TX_NUMBER, STM32_CAN_CAN2_IRQ_PRIORITY);
- nvicEnableVector(STM32_CAN2_RX0_NUMBER, STM32_CAN_CAN2_IRQ_PRIORITY);
- nvicEnableVector(STM32_CAN2_RX1_NUMBER, STM32_CAN_CAN2_IRQ_PRIORITY);
- nvicEnableVector(STM32_CAN2_SCE_NUMBER, STM32_CAN_CAN2_IRQ_PRIORITY);
-#endif
rccEnableCAN2(FALSE);
}
#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
@@ -758,14 +742,6 @@ void can_lld_stop(CANDriver *canp) {
CAN1->MCR = 0x00010002; /* Register reset value. */
CAN1->IER = 0x00000000; /* All sources disabled. */
-#if defined(STM32_CAN1_UNIFIED_NUMBER)
- nvicDisableVector(STM32_CAN1_UNIFIED_NUMBER);
-#else
- nvicDisableVector(STM32_CAN1_TX_NUMBER);
- nvicDisableVector(STM32_CAN1_RX0_NUMBER);
- nvicDisableVector(STM32_CAN1_RX1_NUMBER);
- nvicDisableVector(STM32_CAN1_SCE_NUMBER);
-#endif
rccDisableCAN1(FALSE);
}
#endif
@@ -774,14 +750,6 @@ void can_lld_stop(CANDriver *canp) {
if (&CAND2 == canp) {
CAN2->MCR = 0x00010002; /* Register reset value. */
CAN2->IER = 0x00000000; /* All sources disabled. */
-#if defined(STM32_CAN2_UNIFIED_NUMBER)
- nvicDisableVector(STM32_CAN2_UNIFIED_NUMBER);
-#else
- nvicDisableVector(STM32_CAN2_TX_NUMBER);
- nvicDisableVector(STM32_CAN2_RX0_NUMBER);
- nvicDisableVector(STM32_CAN2_RX1_NUMBER);
- nvicDisableVector(STM32_CAN2_SCE_NUMBER);
-#endif
rccDisableCAN2(FALSE);
}
#endif
@@ -790,14 +758,6 @@ void can_lld_stop(CANDriver *canp) {
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
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 c6c10dc12..a26377f24 100644
--- a/os/hal/ports/STM32/LLD/CANv1/hal_can_lld.h
+++ b/os/hal/ports/STM32/LLD/CANv1/hal_can_lld.h
@@ -189,10 +189,26 @@
/*===========================================================================*/
/**
+ * @brief Type of a structure representing an CAN driver.
+ */
+typedef struct CANDriver CANDriver;
+
+/**
* @brief Type of a transmission mailbox index.
*/
typedef uint32_t canmbx_t;
+#if defined(CAN_ENFORCE_USE_CALLBACKS) || defined(__DOXYGEN__)
+/**
+ * @brief Type of a CAN notification callback.
+ *
+ * @param[in] canp pointer to the @p CANDriver object triggering the
+ * callback
+ * @param[in] flags flags associated to the mailbox callback
+ */
+typedef void (*can_callback_t)(CANDriver *canp, uint32_t flags);
+#endif
+
/**
* @brief CAN transmission frame.
* @note Accessing the frame data as word16 or word32 is not portable because
@@ -309,7 +325,7 @@ typedef struct {
/**
* @brief Structure representing an CAN driver.
*/
-typedef struct {
+struct CANDriver {
/**
* @brief Driver state.
*/
@@ -326,6 +342,7 @@ typedef struct {
* @brief Receive threads queue.
*/
threads_queue_t rxqueue;
+#if !defined(CAN_ENFORCE_USE_CALLBACKS)
/**
* @brief One or more frames become available.
* @note After broadcasting this event it will not be broadcasted again
@@ -345,7 +362,6 @@ typedef struct {
* transmit mailboxes become empty.
* @note The upper 16 bits are transmission error flags associated
* to the transmit mailboxes.
- *
*/
event_source_t txempty_event;
/**
@@ -366,12 +382,41 @@ typedef struct {
*/
event_source_t wakeup_event;
#endif /* CAN_USE_SLEEP_MODE */
+#else /* defined(CAN_ENFORCE_USE_CALLBACKS) */
+ /**
+ * @brief One or more frames become available.
+ * @note After calling this function it will not be called again
+ * until the received frames queue has been completely emptied. It
+ * is <b>not</b> called for each received frame. It is
+ * responsibility of the application to empty the queue by
+ * repeatedly invoking @p chTryReceiveI().
+ * This behavior minimizes the interrupt served by the system
+ * because CAN traffic.
+ */
+ can_callback_t rxfull_cb;
+ /**
+ * @brief One or more transmission mailbox become available.
+ * @note The flags associated to the callback will indicate which
+ * transmit mailboxes become empty.
+ */
+ can_callback_t txempty_cb;
+ /**
+ * @brief A CAN bus error happened.
+ */
+ can_callback_t error_cb;
+#if (CAN_USE_SLEEP_MODE == TRUE) || defined (__DOXYGEN__)
+ /**
+ * @brief Exiting sleep state.
+ */
+ can_callback_t wakeup_cb;
+#endif
+#endif
/* End of the mandatory fields.*/
/**
* @brief Pointer to the CAN registers.
*/
CAN_TypeDef *can;
-} CANDriver;
+};
/*===========================================================================*/
/* Driver macros. */
diff --git a/os/hal/src/hal_can.c b/os/hal/src/hal_can.c
index 122e5eb76..6d174f7b6 100644
--- a/os/hal/src/hal_can.c
+++ b/os/hal/src/hal_can.c
@@ -67,10 +67,11 @@ void canInit(void) {
*/
void canObjectInit(CANDriver *canp) {
- canp->state = CAN_STOP;
- canp->config = NULL;
+ canp->state = CAN_STOP;
+ canp->config = NULL;
osalThreadQueueObjectInit(&canp->txqueue);
osalThreadQueueObjectInit(&canp->rxqueue);
+#if !defined(CAN_ENFORCE_USE_CALLBACKS)
osalEventObjectInit(&canp->rxfull_event);
osalEventObjectInit(&canp->txempty_event);
osalEventObjectInit(&canp->error_event);
@@ -78,6 +79,14 @@ void canObjectInit(CANDriver *canp) {
osalEventObjectInit(&canp->sleep_event);
osalEventObjectInit(&canp->wakeup_event);
#endif
+#else /* defined(CAN_ENFORCE_USE_CALLBACKS) */
+ canp->rxfull_cb = NULL;
+ canp->txempty_cb = NULL;
+ canp->error_cb = NULL;
+#if CAN_USE_SLEEP_MODE == TRUE
+ canp->wakeup_cb = NULL;
+#endif
+#endif /* defined(CAN_ENFORCE_USE_CALLBACKS) */
}
/**
@@ -327,8 +336,10 @@ void canSleep(CANDriver *canp) {
if (canp->state == CAN_READY) {
can_lld_sleep(canp);
canp->state = CAN_SLEEP;
+#if !defined(CAN_ENFORCE_USE_CALLBACKS)
osalEventBroadcastFlagsI(&canp->sleep_event, (eventflags_t)0);
osalOsRescheduleS();
+#endif
}
osalSysUnlock();
}
@@ -350,8 +361,10 @@ void canWakeup(CANDriver *canp) {
if (canp->state == CAN_SLEEP) {
can_lld_wakeup(canp);
canp->state = CAN_READY;
+#if !defined(CAN_ENFORCE_USE_CALLBACKS)
osalEventBroadcastFlagsI(&canp->wakeup_event, (eventflags_t)0);
osalOsRescheduleS();
+#endif
}
osalSysUnlock();
}
diff --git a/os/hal/templates/hal_can_lld.h b/os/hal/templates/hal_can_lld.h
index 14e631a1b..ca64835eb 100644
--- a/os/hal/templates/hal_can_lld.h
+++ b/os/hal/templates/hal_can_lld.h
@@ -68,10 +68,26 @@
/*===========================================================================*/
/**
+ * @brief Type of a structure representing an CAN driver.
+ */
+typedef struct CANDriver CANDriver;
+
+/**
* @brief Type of a transmission mailbox index.
*/
typedef uint32_t canmbx_t;
+#if defined(CAN_ENFORCE_USE_CALLBACKS) || defined(__DOXYGEN__)
+/**
+ * @brief Type of a CAN notification callback.
+ *
+ * @param[in] canp pointer to the @p CANDriver object triggering the
+ * callback
+ * @param[in] flags flags associated to the mailbox callback
+ */
+typedef void (*can_callback_t)(CANDriver *canp, uint32_t flags);
+#endif
+
/**
* @brief CAN transmission frame.
* @note Accessing the frame data as word16 or word32 is not portable because
@@ -131,7 +147,7 @@ typedef struct {
/**
* @brief Structure representing an CAN driver.
*/
-typedef struct {
+struct CANDriver {
/**
* @brief Driver state.
*/
@@ -148,6 +164,7 @@ typedef struct {
* @brief Receive threads queue.
*/
threads_queue_t rxqueue;
+#if !defined(CAN_ENFORCE_USE_CALLBACKS)
/**
* @brief One or more frames become available.
* @note After broadcasting this event it will not be broadcasted again
@@ -165,7 +182,6 @@ typedef struct {
* @brief One or more transmission mailbox become available.
* @note The flags associated to the listeners will indicate which
* transmit mailboxes become empty.
- *
*/
event_source_t txempty_event;
/**
@@ -184,8 +200,37 @@ typedef struct {
*/
event_source_t wakeup_event;
#endif
+#else /* defined(CAN_ENFORCE_USE_CALLBACKS) */
+ /**
+ * @brief One or more frames become available.
+ * @note After calling this function it will not be called again
+ * until the received frames queue has been completely emptied. It
+ * is <b>not</b> called for each received frame. It is
+ * responsibility of the application to empty the queue by
+ * repeatedly invoking @p chTryReceiveI().
+ * This behavior minimizes the interrupt served by the system
+ * because CAN traffic.
+ */
+ can_callback_t rxfull_cb;
+ /**
+ * @brief One or more transmission mailbox become available.
+ * @note The flags associated to the callback will indicate which
+ * transmit mailboxes become empty.
+ */
+ can_callback_t txempty_cb;
+ /**
+ * @brief A CAN bus error happened.
+ */
+ can_callback_t error_cb;
+#if (CAN_USE_SLEEP_MODE == TRUE) || defined (__DOXYGEN__)
+ /**
+ * @brief Exiting sleep state.
+ */
+ can_callback_t wakeup_cb;
+#endif
+#endif
/* End of the mandatory fields.*/
-} CANDriver;
+};
/*===========================================================================*/
/* Driver macros. */
diff --git a/readme.txt b/readme.txt
index ef218e421..d800ceb81 100644
--- a/readme.txt
+++ b/readme.txt
@@ -89,6 +89,8 @@
*****************************************************************************
*** Next ***
+- NEW: Added callbacks capability to the CAN driver.
+- NEW: Added initial STM32H7xx support.
- NEW: Added GHS compiler support to the Power e200 port.
- NEW: Added tool for board files generation from command line.
- NEW: Added STM32L496xx/STM32L4A6xx support.