cancel
Showing results for 
Search instead for 
Did you mean: 

CAN -> How to send overload frame?

valentin
Senior
Posted on August 15, 2017 at 05:00

Hi,

has anyone ever managed to send a standard CAN overload frame on an stm32?

So far, I could only find error handling for incoming frames but no way to send one myself.

#can #overload
1 REPLY 1
valentin
Senior
Posted on October 26, 2017 at 05:48

Ok, so I found a workaround:

/**
 * @brief A bus blocker message with ID=0 and DLC=8 -> prevents any other node from accessing the bus
 */
static const CanTxMsgTypeDef CAN_blockerMsg = { 0, 0, CAN_ID_EXT, 0, 8, 0, 0, 0, 0, 0, 0, 0, 0 };
/**
 * Receive interrupt handler
 * -> pushes received CAN message into CAN_Reader rx_fifo for further processing
 * @param hcanCAN peripheral handle
 * 
elates imed::helmbus::io::subclasses::CANReader
 * \link HAL_CAN_RxCpltCallback \endlink
 */
extern 'C' void HAL_CAN_RxCpltCallback(CAN_HandleTypeDef* hcan) {
using namespace imed::helmbus::io;
/* construct can_message struct */
const auto msg = static_cast<CAN_message_CPP>(std::move(HAL_CAN_ReadRxMsg(hcan->pRxMsg)));
auto const& bus = CANBus::get_instance(*hcan);
bus->reader.led.startFlashing();
const uint8_t fifo = (__HAL_CAN_GET_IT_SOURCE(hcan, CAN_IT_FMP1));
if (HAL_CAN_rxFiFoUsed(hcan, fifo) > 1 || bus->getUsedFiFoSlots() > 1) {
/* queue filled > 1 */
imed::CritGuard crit;
if (HAL_CAN_txRdy(hcan)) {
const CanTxMsgTypeDef* const backup = hcan->pTxMsg;
hcan->pTxMsg = (CanTxMsgTypeDef*) &CAN_blockerMsg;
/* transmit */
uint8_t ret = static_cast<uint8_t>(HAL_CAN_Transmit_IT(hcan));
if (!ret) /* ret == HAL_OK */
HAL_CAN_Transmit_IT(hcan);
if (!ret) /* ret == HAL_OK */
HAL_CAN_Transmit_IT(hcan);
hcan->pTxMsg = (CanTxMsgTypeDef*) backup;
}
}
bus->push(msg, 0, true);
}�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?

Basically, this callback does one extra check:

If the hardware RX fifo in the CAN controller is 2/3 filled OR if the software fifo has a backlog, the ISR sends 3 long blocker messages to the bus (ID=0, DLC=8, IDE=1). Because of this message being max priority, this keeps the bus free for about ~1ms @ 500K and gives me some time to work through the fifo.

Luckily, the actual transmit is done in hardware, so the three calls to Transmit_IT return immediately after copying the blocker message into the TX mailboxes.

I can do this because the code is working in a 1:n configuration on the bus, this being the 1.