diff options
| -rw-r--r-- | demos/STM32/RT-STM32H743I-NUCLEO144/debug/RT-STM32H743I-NUCLEO144 (OpenOCD, Just Run).launch | 104 | ||||
| -rw-r--r-- | os/hal/include/hal_can.h | 69 | ||||
| -rw-r--r-- | os/hal/ports/STM32/LLD/CANv1/hal_can_lld.c | 106 | ||||
| -rw-r--r-- | os/hal/ports/STM32/LLD/CANv1/hal_can_lld.h | 51 | ||||
| -rw-r--r-- | os/hal/src/hal_can.c | 17 | ||||
| -rw-r--r-- | os/hal/templates/hal_can_lld.h | 51 | ||||
| -rw-r--r-- | readme.txt | 2 | 
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
monitor reset init
monitor sleep 50
"/>
 -<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="<?xml version="1.0" encoding="UTF-8" standalone="no"?><contentList><content id="r3-(format)" val="4"/><content id="vt_delta-null-chVTDoSetI-(format)" val="4"/></contentList>"/>
 -<stringAttribute key="org.eclipse.cdt.launch.GLOBAL_VARIABLES" value="<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<globalVariableList/>
"/>
 -<stringAttribute key="org.eclipse.cdt.launch.MEMORY_BLOCKS" value="<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<memoryBlockExpressionList/>
"/>
 -<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
monitor reset init
monitor sleep 50
"/> +<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="<?xml version="1.0" encoding="UTF-8" standalone="no"?><contentList><content id="r3-(format)" val="4"/><content id="vt_delta-null-chVTDoSetI-(format)" val="4"/></contentList>"/> +<stringAttribute key="org.eclipse.cdt.launch.GLOBAL_VARIABLES" value="<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<globalVariableList/>
"/> +<stringAttribute key="org.eclipse.cdt.launch.MEMORY_BLOCKS" value="<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<memoryBlockExpressionList/>
"/> +<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.
 | 
