diff options
-rw-r--r-- | os/hal/include/can.h | 6 | ||||
-rw-r--r-- | os/hal/src/can.c | 71 | ||||
-rw-r--r-- | readme.txt | 2 | ||||
-rw-r--r-- | testhal/STM32/STM32L4xx/CAN/debug/STM32L4xx-CAN (OpenOCD, Flash and Run).launch | 2 |
4 files changed, 80 insertions, 1 deletions
diff --git a/os/hal/include/can.h b/os/hal/include/can.h index fe4386089..975a04362 100644 --- a/os/hal/include/can.h +++ b/os/hal/include/can.h @@ -127,6 +127,12 @@ extern "C" { void canObjectInit(CANDriver *canp);
void canStart(CANDriver *canp, const CANConfig *config);
void canStop(CANDriver *canp);
+ bool canTryTransmitI(CANDriver *canp,
+ canmbx_t mailbox,
+ const CANTxFrame *ctfp);
+ bool canTryReceiveI(CANDriver *canp,
+ canmbx_t mailbox,
+ CANRxFrame *crfp);
msg_t canTransmit(CANDriver *canp,
canmbx_t mailbox,
const CANTxFrame *ctfp,
diff --git a/os/hal/src/can.c b/os/hal/src/can.c index cfaa7264e..a87a2a43e 100644 --- a/os/hal/src/can.c +++ b/os/hal/src/can.c @@ -140,6 +140,75 @@ void canStop(CANDriver *canp) { }
/**
+ * @brief Can frame transmission attempt.
+ * @details The specified frame is queued for transmission, if the hardware
+ * queue is full then the function fails.
+ *
+ * @param[in] canp pointer to the @p CANDriver object
+ * @param[in] mailbox mailbox number, @p CAN_ANY_MAILBOX for any mailbox
+ * @param[in] ctfp pointer to the CAN frame to be transmitted
+ * @return The operation result.
+ * @retval false Frame transmitted.
+ * @retval true Mailbox full.
+ *
+ * @iclass
+ */
+bool canTryTransmitI(CANDriver *canp,
+ canmbx_t mailbox,
+ const CANTxFrame *ctfp) {
+
+ osalDbgCheckClassI();
+ osalDbgCheck((canp != NULL) && (ctfp != NULL) &&
+ (mailbox <= (canmbx_t)CAN_TX_MAILBOXES));
+ osalDbgAssert((canp->state == CAN_READY) || (canp->state == CAN_SLEEP),
+ "invalid state");
+
+ /* If the RX mailbox is full then the function fails.*/
+ if (!can_lld_is_tx_empty(canp, mailbox)) {
+ return true;
+ }
+
+ /* Transmitting frame.*/
+ can_lld_transmit(canp, mailbox, ctfp);
+
+ return false;
+}
+
+/**
+ * @brief Can frame receive attempt.
+ * @details The function tries to fetch a frame from a mailbox.
+ *
+ * @param[in] canp pointer to the @p CANDriver object
+ * @param[in] mailbox mailbox number, @p CAN_ANY_MAILBOX for any mailbox
+ * @param[out] crfp pointer to the buffer where the CAN frame is copied
+ * @return The operation result.
+ * @retval false Frame fetched.
+ * @retval true Mailbox empty.
+ *
+ * @iclass
+ */
+bool canTryReceiveI(CANDriver *canp,
+ canmbx_t mailbox,
+ CANRxFrame *crfp) {
+
+ osalDbgCheckClassI();
+ osalDbgCheck((canp != NULL) && (crfp != NULL) &&
+ (mailbox <= (canmbx_t)CAN_RX_MAILBOXES));
+ osalDbgAssert((canp->state == CAN_READY) || (canp->state == CAN_SLEEP),
+ "invalid state");
+
+ /* If the RX mailbox is empty then the function fails.*/
+ if (!can_lld_is_rx_nonempty(canp, mailbox)) {
+ return true;
+ }
+
+ /* Fetching the frame.*/
+ can_lld_receive(canp, mailbox, crfp);
+
+ return false;
+}
+
+/**
* @brief Can frame transmission.
* @details The specified frame is queued for transmission, if the hardware
* queue is full then the invoking thread is queued.
@@ -171,6 +240,7 @@ msg_t canTransmit(CANDriver *canp, osalSysLock();
osalDbgAssert((canp->state == CAN_READY) || (canp->state == CAN_SLEEP),
"invalid state");
+
/*lint -save -e9007 [13.5] Right side is supposed to be pure.*/
while ((canp->state == CAN_SLEEP) || !can_lld_is_tx_empty(canp, mailbox)) {
/*lint -restore*/
@@ -218,6 +288,7 @@ msg_t canReceive(CANDriver *canp, osalSysLock();
osalDbgAssert((canp->state == CAN_READY) || (canp->state == CAN_SLEEP),
"invalid state");
+
/*lint -save -e9007 [13.5] Right side is supposed to be pure.*/
while ((canp->state == CAN_SLEEP) || !can_lld_is_rx_nonempty(canp, mailbox)) {
/*lint -restore*/
diff --git a/readme.txt b/readme.txt index 32290427a..a424c2d0f 100644 --- a/readme.txt +++ b/readme.txt @@ -77,6 +77,8 @@ - HAL: Introduced preliminary support for STM32F7xx devices.
- HAL: Introduced preliminary support for STM32L4xx devices.
- HAL: Introduced preliminary support for STM32L0xx devices.
+- HAL: Enhanced the CAN driver with I-class functions. Now it is possible
+ to exchange frames from ISRs.
- HAL: Added watchdog driver model (WDG) and STM32 implementation on IWDG.
- HAL: Added synchronous API and mutual exclusion to the UART driver.
- HAL: Added PAL driver for STM32L4xx GPIOv3 peripheral.
diff --git a/testhal/STM32/STM32L4xx/CAN/debug/STM32L4xx-CAN (OpenOCD, Flash and Run).launch b/testhal/STM32/STM32L4xx/CAN/debug/STM32L4xx-CAN (OpenOCD, Flash and Run).launch index f3fc038e1..30b653f3f 100644 --- a/testhal/STM32/STM32L4xx/CAN/debug/STM32L4xx-CAN (OpenOCD, Flash and Run).launch +++ b/testhal/STM32/STM32L4xx/CAN/debug/STM32L4xx-CAN (OpenOCD, Flash and Run).launch @@ -33,7 +33,7 @@ <intAttribute key="org.eclipse.cdt.launch.ATTR_BUILD_BEFORE_LAUNCH_ATTR" value="2"/>
<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="cr2-adc_lld_start_conversion-(format)" val="4"/><content id="CR2-adc-null-port_wait_for_interrupt-(format)" val="4"/><content id="CR2-adc-adcp-adc_lld_start_conversion-(format)" val="4"/></contentList>"/>
+<stringAttribute key="org.eclipse.cdt.launch.FORMAT" value="<?xml version="1.0" encoding="UTF-8" standalone="no"?><contentList><content id="CR2-adc-adcp-adc_lld_start_conversion-(format)" val="4"/><content id="CR2-adc-null-port_wait_for_interrupt-(format)" val="4"/><content id="cr2-adc_lld_start_conversion-(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"/>
|