diff --git a/os/hal/include/can.h b/os/hal/include/can.h
index 1d8492d28..a62aba3da 100644
--- a/os/hal/include/can.h
+++ b/os/hal/include/can.h
@@ -62,9 +62,9 @@
/** @} */
/**
- * @brief Special TX mailbox identifier.
+ * @brief Special mailbox identifier.
*/
-#define CAN_ANY_TX_MAILBOX 0
+#define CAN_ANY_MAILBOX 0
/*===========================================================================*/
/* Driver pre-compile time settings. */
diff --git a/os/hal/platforms/STM32/can_lld.c b/os/hal/platforms/STM32/can_lld.c
index 89d1b25ac..456e3e53a 100644
--- a/os/hal/platforms/STM32/can_lld.c
+++ b/os/hal/platforms/STM32/can_lld.c
@@ -172,16 +172,31 @@ static void can_lld_rx0_handler(CANDriver *canp) {
/**
* @brief Common RX1 ISR handler.
- * @note Not used, must not be invoked, defaulted to an halt.
*
* @param[in] canp pointer to the @p CANDriver object
*
* @notapi
*/
static void can_lld_rx1_handler(CANDriver *canp) {
+ uint32_t rf1r;
- (void)canp;
- chSysHalt();
+ rf1r = canp->can->RF1R;
+ if ((rf1r & CAN_RF1R_FMP1) > 0) {
+ /* No more receive events until the queue 0 has been emptied.*/
+ canp->can->IER &= ~CAN_IER_FMPIE1;
+ chSysLockFromIsr();
+ while (chSemGetCounterI(&canp->rxsem) < 0)
+ chSemSignalI(&canp->rxsem);
+ chEvtBroadcastFlagsI(&canp->rxfull_event, CAN_MAILBOX_TO_MASK(1));
+ chSysUnlockFromIsr();
+ }
+ if ((rf1r & CAN_RF1R_FOVR1) > 0) {
+ /* Overflow events handling.*/
+ canp->can->RF1R = CAN_RF1R_FOVR1;
+ chSysLockFromIsr();
+ chEvtBroadcastFlagsI(&canp->error_event, CAN_OVERFLOW_ERROR);
+ chSysUnlockFromIsr();
+ }
}
/**
@@ -467,7 +482,7 @@ void can_lld_stop(CANDriver *canp) {
* @brief Determines whether a frame can be transmitted.
*
* @param[in] canp pointer to the @p CANDriver object
- * @param[in] mailbox mailbox number, @p CAN_ANY_TX_MAILBOX for any mailbox
+ * @param[in] mailbox mailbox number, @p CAN_ANY_MAILBOX for any mailbox
*
* @return The queue space availability.
* @retval FALSE no space in the transmit queue.
@@ -478,7 +493,7 @@ void can_lld_stop(CANDriver *canp) {
bool_t can_lld_is_tx_empty(CANDriver *canp, canmbx_t mailbox) {
switch (mailbox) {
- case CAN_ANY_TX_MAILBOX:
+ case CAN_ANY_MAILBOX:
return (canp->can->TSR & CAN_TSR_TME) != 0;
case 1:
return (canp->can->TSR & CAN_TSR_TME0) != 0;
@@ -496,7 +511,7 @@ bool_t can_lld_is_tx_empty(CANDriver *canp, canmbx_t mailbox) {
*
* @param[in] canp pointer to the @p CANDriver object
* @param[in] ctfp pointer to the CAN frame to be transmitted
- * @param[in] mailbox mailbox number, @p CAN_ANY_TX_MAILBOX for any mailbox
+ * @param[in] mailbox mailbox number, @p CAN_ANY_MAILBOX for any mailbox
*
* @notapi
*/
@@ -508,7 +523,7 @@ void can_lld_transmit(CANDriver *canp,
/* Pointer to a free transmission mailbox.*/
switch (mailbox) {
- case CAN_ANY_TX_MAILBOX:
+ case CAN_ANY_MAILBOX:
tmbp = &canp->can->sTxMailBox[(canp->can->TSR & CAN_TSR_CODE) >> 24];
break;
case 1:
@@ -540,7 +555,7 @@ void can_lld_transmit(CANDriver *canp,
* @brief Determines whether a frame has been received.
*
* @param[in] canp pointer to the @p CANDriver object
- * @param[in] mailbox mailbox number
+ * @param[in] mailbox mailbox number, @p CAN_ANY_MAILBOX for any mailbox
*
* @return The queue space availability.
* @retval FALSE no space in the transmit queue.
@@ -551,10 +566,12 @@ void can_lld_transmit(CANDriver *canp,
bool_t can_lld_is_rx_nonempty(CANDriver *canp, canmbx_t mailbox) {
switch (mailbox) {
+ case CAN_ANY_MAILBOX:
+ return (canp->can->RF0R & (CAN_RF0R_FMP0 | CAN_RF1R_FMP1)) != 0;
case 1:
- return (canp->can->RF0R & CAN_RF0R_FMP0) > 0;
+ return (canp->can->RF0R & CAN_RF0R_FMP0) != 0;
case 2:
- return (canp->can->RF1R & CAN_RF1R_FMP1) > 0;
+ return (canp->can->RF1R & CAN_RF1R_FMP1) != 0;
default:
return FALSE;
}
@@ -564,8 +581,8 @@ bool_t can_lld_is_rx_nonempty(CANDriver *canp, canmbx_t mailbox) {
* @brief Receives a frame from the input queue.
*
* @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
- * @param[in] mailbox mailbox number
*
* @notapi
*/
@@ -574,6 +591,16 @@ void can_lld_receive(CANDriver *canp,
CANRxFrame *crfp) {
uint32_t rir, rdtr;
+ if (mailbox == CAN_ANY_MAILBOX) {
+ if ((canp->can->RF0R & CAN_RF0R_FMP0) != 0)
+ mailbox = 1;
+ else if ((canp->can->RF1R & CAN_RF1R_FMP1) != 0)
+ mailbox = 2;
+ else {
+ /* Should not happen, do nothing.*/
+ return;
+ }
+ }
switch (mailbox) {
case 1:
/* Fetches the message.*/
@@ -606,6 +633,7 @@ void can_lld_receive(CANDriver *canp,
canp->can->IER |= CAN_IER_FMPIE1;
break;
default:
+ /* Should not happen, do nothing.*/
return;
}
diff --git a/os/hal/src/can.c b/os/hal/src/can.c
index e0d47d5c5..64aaa45c8 100644
--- a/os/hal/src/can.c
+++ b/os/hal/src/can.c
@@ -145,7 +145,7 @@ void canStop(CANDriver *canp) {
* @note Trying to transmit while in sleep mode simply enqueues the thread.
*
* @param[in] canp pointer to the @p CANDriver object
- * @param[in] mailbox mailbox number, @p CAN_ANY_TX_MAILBOX for any mailbox
+ * @param[in] mailbox mailbox number, @p CAN_ANY_MAILBOX for any mailbox
* @param[in] ctfp pointer to the CAN frame to be transmitted
* @param[in] timeout the number of ticks before the operation timeouts,
* the following special values are allowed:
@@ -164,8 +164,7 @@ msg_t canTransmit(CANDriver *canp,
const CANTxFrame *ctfp,
systime_t timeout) {
- chDbgCheck((canp != NULL) && (ctfp != NULL) &&
- (mailbox <= CAN_TX_MAILBOXES),
+ chDbgCheck((canp != NULL) && (ctfp != NULL) && (mailbox <= CAN_TX_MAILBOXES),
"canTransmit");
chSysLock();
@@ -189,7 +188,7 @@ msg_t canTransmit(CANDriver *canp,
* @note Trying to receive while in sleep mode simply enqueues the thread.
*
* @param[in] canp pointer to the @p CANDriver object
- * @param[in] mailbox mailbox number
+ * @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
* @param[in] timeout the number of ticks before the operation timeouts,
* the following special values are allowed:
@@ -210,8 +209,7 @@ msg_t canReceive(CANDriver *canp,
CANRxFrame *crfp,
systime_t timeout) {
- chDbgCheck((canp != NULL) && (crfp != NULL) &&
- (mailbox >= 1) && (mailbox < CAN_RX_MAILBOXES),
+ chDbgCheck((canp != NULL) && (crfp != NULL) && (mailbox < CAN_RX_MAILBOXES),
"canReceive");
chSysLock();
diff --git a/readme.txt b/readme.txt
index 76c513c19..a41f50c19 100644
--- a/readme.txt
+++ b/readme.txt
@@ -117,6 +117,8 @@
(backported to 2.4.3).
- FIX: Fixed wrong SPI path in platform_f105_f107.mk (bug 3598151).
- FIX: Fixed PHY powerdown issues not fixed (bug 3596911).
+- NEW: Enhanced CAN driver model, support for mailboxes has been added. STM32
+ driver implementation upgraded.
- NEW: Added ADC and PWM drivers for the AT91SAM7 platform, both donated
by Andrew Hannam.
- NEW: Added kernel support for the SAM4L, an Atmel Studio 6 demo for the
diff --git a/testhal/STM32F1xx/CAN/main.c b/testhal/STM32F1xx/CAN/main.c
index 2ea6b7dec..3fbda37c8 100644
--- a/testhal/STM32F1xx/CAN/main.c
+++ b/testhal/STM32F1xx/CAN/main.c
@@ -29,9 +29,7 @@
static const CANConfig cancfg = {
CAN_MCR_ABOM | CAN_MCR_AWUM | CAN_MCR_TXFP,
CAN_BTR_LBKM | CAN_BTR_SJW(0) | CAN_BTR_TS2(1) |
- CAN_BTR_TS1(8) | CAN_BTR_BRP(6),
- 0,
- NULL
+ CAN_BTR_TS1(8) | CAN_BTR_BRP(6)
};
/*
@@ -48,7 +46,7 @@ static msg_t can_rx(void *p) {
while(!chThdShouldTerminate()) {
if (chEvtWaitAnyTimeout(ALL_EVENTS, MS2ST(100)) == 0)
continue;
- while (canReceive(&CAND1, &rxmsg, TIME_IMMEDIATE) == RDY_OK) {
+ while (canReceive(&CAND1, CAN_ANY_MAILBOX, &rxmsg, TIME_IMMEDIATE) == RDY_OK) {
/* Process message.*/
palTogglePad(IOPORT3, GPIOC_LED);
}
@@ -74,7 +72,7 @@ static msg_t can_tx(void * p) {
txmsg.data32[1] = 0x00FF00FF;
while (!chThdShouldTerminate()) {
- canTransmit(&CAND1, &txmsg, MS2ST(100));
+ canTransmit(&CAND1, CAN_ANY_MAILBOX, &txmsg, MS2ST(100));
chThdSleepMilliseconds(500);
}
return 0;
diff --git a/testhal/STM32F30x/CAN/.project b/testhal/STM32F30x/CAN/.project
index a2e4698ac..a01f8a133 100644
--- a/testhal/STM32F30x/CAN/.project
+++ b/testhal/STM32F30x/CAN/.project
@@ -9,6 +9,58 @@
org.eclipse.cdt.managedbuilder.core.genmakebuilder
clean,full,incremental,
+
+ ?name?
+
+
+
+ org.eclipse.cdt.make.core.append_environment
+ true
+
+
+ org.eclipse.cdt.make.core.autoBuildTarget
+ all
+
+
+ org.eclipse.cdt.make.core.buildArguments
+ -j1
+
+
+ org.eclipse.cdt.make.core.buildCommand
+ make
+
+
+ org.eclipse.cdt.make.core.cleanBuildTarget
+ clean
+
+
+ org.eclipse.cdt.make.core.contents
+ org.eclipse.cdt.make.core.activeConfigSettings
+
+
+ org.eclipse.cdt.make.core.enableAutoBuild
+ false
+
+
+ org.eclipse.cdt.make.core.enableCleanBuild
+ true
+
+
+ org.eclipse.cdt.make.core.enableFullBuild
+ true
+
+
+ org.eclipse.cdt.make.core.fullBuildTarget
+ all
+
+
+ org.eclipse.cdt.make.core.stopOnError
+ true
+
+
+ org.eclipse.cdt.make.core.useDefaultBuildCmd
+ true
+
diff --git a/testhal/STM32F30x/CAN/main.c b/testhal/STM32F30x/CAN/main.c
index 978c31c1b..59e0c99d7 100644
--- a/testhal/STM32F30x/CAN/main.c
+++ b/testhal/STM32F30x/CAN/main.c
@@ -45,7 +45,7 @@ static msg_t can_rx(void *p) {
while(!chThdShouldTerminate()) {
if (chEvtWaitAnyTimeout(ALL_EVENTS, MS2ST(100)) == 0)
continue;
- while (canReceive(&CAND1, 1, &rxmsg, TIME_IMMEDIATE) == RDY_OK) {
+ while (canReceive(&CAND1, CAN_ANY_MAILBOX, &rxmsg, TIME_IMMEDIATE) == RDY_OK) {
/* Process message.*/
palTogglePad(GPIOE, GPIOE_LED3_RED);
}
@@ -71,7 +71,7 @@ static msg_t can_tx(void * p) {
txmsg.data32[1] = 0x00FF00FF;
while (!chThdShouldTerminate()) {
- canTransmit(&CAND1, CAN_ANY_TX_MAILBOX, &txmsg, MS2ST(100));
+ canTransmit(&CAND1, CAN_ANY_MAILBOX, &txmsg, MS2ST(100));
chThdSleepMilliseconds(500);
}
return 0;
diff --git a/testhal/STM32F4xx/CAN/.project b/testhal/STM32F4xx/CAN/.project
index 91c2aa2ca..3c1df9502 100644
--- a/testhal/STM32F4xx/CAN/.project
+++ b/testhal/STM32F4xx/CAN/.project
@@ -9,6 +9,58 @@
org.eclipse.cdt.managedbuilder.core.genmakebuilder
clean,full,incremental,
+
+ ?name?
+
+
+
+ org.eclipse.cdt.make.core.append_environment
+ true
+
+
+ org.eclipse.cdt.make.core.autoBuildTarget
+ all
+
+
+ org.eclipse.cdt.make.core.buildArguments
+ -j1
+
+
+ org.eclipse.cdt.make.core.buildCommand
+ make
+
+
+ org.eclipse.cdt.make.core.cleanBuildTarget
+ clean
+
+
+ org.eclipse.cdt.make.core.contents
+ org.eclipse.cdt.make.core.activeConfigSettings
+
+
+ org.eclipse.cdt.make.core.enableAutoBuild
+ false
+
+
+ org.eclipse.cdt.make.core.enableCleanBuild
+ true
+
+
+ org.eclipse.cdt.make.core.enableFullBuild
+ true
+
+
+ org.eclipse.cdt.make.core.fullBuildTarget
+ all
+
+
+ org.eclipse.cdt.make.core.stopOnError
+ true
+
+
+ org.eclipse.cdt.make.core.useDefaultBuildCmd
+ true
+
diff --git a/testhal/STM32F4xx/CAN/main.c b/testhal/STM32F4xx/CAN/main.c
index e095da4d5..2ff2025e0 100644
--- a/testhal/STM32F4xx/CAN/main.c
+++ b/testhal/STM32F4xx/CAN/main.c
@@ -56,7 +56,8 @@ static msg_t can_rx(void *p) {
while(!chThdShouldTerminate()) {
if (chEvtWaitAnyTimeout(ALL_EVENTS, MS2ST(100)) == 0)
continue;
- while (canReceive(cip->canp, 1, &rxmsg, TIME_IMMEDIATE) == RDY_OK) {
+ while (canReceive(cip->canp, CAN_ANY_MAILBOX,
+ &rxmsg, TIME_IMMEDIATE) == RDY_OK) {
/* Process message.*/
palTogglePad(GPIOD, cip->led);
}
@@ -82,8 +83,8 @@ static msg_t can_tx(void * p) {
txmsg.data32[1] = 0x00FF00FF;
while (!chThdShouldTerminate()) {
- canTransmit(&CAND1, CAN_ANY_TX_MAILBOX, &txmsg, MS2ST(100));
- canTransmit(&CAND2, CAN_ANY_TX_MAILBOX, &txmsg, MS2ST(100));
+ canTransmit(&CAND1, CAN_ANY_MAILBOX, &txmsg, MS2ST(100));
+ canTransmit(&CAND2, CAN_ANY_MAILBOX, &txmsg, MS2ST(100));
chThdSleepMilliseconds(500);
}
return 0;