Added callbacks capability to the CAN driver.

git-svn-id: svn://svn.code.sf.net/p/chibios/svn/trunk@11213 35acf78f-673a-0410-8e92-d51de3d6d3f4
This commit is contained in:
Giovanni Di Sirio 2018-01-02 11:17:31 +00:00
parent e5b7a9f723
commit bb806fe4c1
7 changed files with 266 additions and 134 deletions

View File

@ -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>

View File

@ -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. */
/*===========================================================================*/

View File

@ -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

View File

@ -188,11 +188,27 @@
/* Driver data structures and types. */
/*===========================================================================*/
/**
* @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. */

View File

@ -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();
}

View File

@ -67,11 +67,27 @@
/* Driver data structures and types. */
/*===========================================================================*/
/**
* @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;
/**
@ -183,9 +199,38 @@ typedef struct {
* @brief Exiting sleep state event.
*/
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. */

View File

@ -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.