137 lines
3.2 KiB
C++
137 lines
3.2 KiB
C++
/**
|
|
* @file can_msg_tx.cpp
|
|
*
|
|
* CAN message transmission
|
|
*
|
|
* @date Mar 13, 2020
|
|
* @author Matthew Kennedy, (c) 2012-2020
|
|
*/
|
|
|
|
#include "pch.h"
|
|
|
|
#include "can_msg_tx.h"
|
|
#include "auto_generated_can_category.h"
|
|
|
|
#include "can.h"
|
|
|
|
#if EFI_SIMULATOR
|
|
#include "fifo_buffer.h"
|
|
fifo_buffer<CANTxFrame, 1024> txCanBuffer;
|
|
#endif // EFI_SIMULATOR
|
|
|
|
#if EFI_CAN_SUPPORT
|
|
/*static*/ CANDriver* CanTxMessage::s_devices[2] = {nullptr, nullptr};
|
|
|
|
/*static*/ void CanTxMessage::setDevice(CANDriver* device1, CANDriver* device2) {
|
|
s_devices[0] = device1;
|
|
s_devices[1] = device2;
|
|
}
|
|
#endif // EFI_CAN_SUPPORT
|
|
|
|
CanTxMessage::CanTxMessage(CanCategory p_category, uint32_t eid, uint8_t dlc, size_t bus, bool isExtended) {
|
|
category = p_category;
|
|
#if HAS_CAN_FRAME
|
|
#ifndef STM32H7XX
|
|
// ST bxCAN device
|
|
m_frame.IDE = isExtended ? CAN_IDE_EXT : CAN_IDE_STD;
|
|
m_frame.RTR = CAN_RTR_DATA;
|
|
#else /* if STM32H7XX */
|
|
// Bosch M_CAN FDCAN device
|
|
m_frame.common.XTD = isExtended;
|
|
m_frame.common.RTR = 0;
|
|
#endif
|
|
|
|
if (isExtended) {
|
|
CAN_EID(m_frame) = eid;
|
|
} else {
|
|
if (eid >= 0x800) {
|
|
criticalError("Looks like extended CAN ID %x %s", eid, getCanCategory(category));
|
|
return;
|
|
}
|
|
CAN_SID(m_frame) = eid;
|
|
}
|
|
|
|
setDlc(dlc);
|
|
|
|
setBus(bus);
|
|
|
|
memset(m_frame.data8, 0, sizeof(m_frame.data8));
|
|
#endif // HAS_CAN_FRAME
|
|
}
|
|
|
|
CanTxMessage::~CanTxMessage() {
|
|
#if EFI_SIMULATOR
|
|
txCanBuffer.put(m_frame);
|
|
#endif // EFI_SIMULATOR
|
|
|
|
#if EFI_CAN_SUPPORT
|
|
auto device = s_devices[busIndex];
|
|
|
|
if (!device) {
|
|
criticalError("Send: CAN device not configured busIndex=%d", busIndex);
|
|
return;
|
|
}
|
|
|
|
if (!engine->allowCanTx) {
|
|
return;
|
|
}
|
|
|
|
if (engineConfiguration->verboseCan) {
|
|
efiPrintf("%s Sending CAN bus%d message: ID=%x/l=%x %x %x %x %x %x %x %x %x",
|
|
getCanCategory(category),
|
|
busIndex,
|
|
#ifndef STM32H7XX
|
|
(unsigned int)((m_frame.IDE == CAN_IDE_EXT) ? CAN_EID(m_frame) : CAN_SID(m_frame)),
|
|
#else
|
|
(unsigned int)(m_frame.common.XTD ? CAN_EID(m_frame) : CAN_SID(m_frame)),
|
|
#endif
|
|
m_frame.DLC,
|
|
m_frame.data8[0], m_frame.data8[1],
|
|
m_frame.data8[2], m_frame.data8[3],
|
|
m_frame.data8[4], m_frame.data8[5],
|
|
m_frame.data8[6], m_frame.data8[7]);
|
|
}
|
|
|
|
// 100 ms timeout
|
|
msg_t msg = canTransmit(device, CAN_ANY_MAILBOX, &m_frame, TIME_MS2I(100));
|
|
#if EFI_TUNER_STUDIO
|
|
if (msg == MSG_OK) {
|
|
engine->outputChannels.canWriteOk++;
|
|
} else {
|
|
engine->outputChannels.canWriteNotOk++;
|
|
}
|
|
#endif // EFI_TUNER_STUDIO
|
|
#endif /* EFI_CAN_SUPPORT */
|
|
}
|
|
|
|
#if HAS_CAN_FRAME
|
|
void CanTxMessage::setDlc(uint8_t dlc) {
|
|
m_frame.DLC = dlc;
|
|
}
|
|
|
|
void CanTxMessage::setBus(size_t bus) {
|
|
busIndex = bus;
|
|
}
|
|
|
|
// LSB Little-endian System, "Intel"
|
|
void CanTxMessage::setShortValue(uint16_t value, size_t offset) {
|
|
m_frame.data8[offset] = value & 0xFF;
|
|
m_frame.data8[offset + 1] = value >> 8;
|
|
}
|
|
|
|
// MOTOROLA order, MSB (Most Significant Byte/Big Endian) comes first.
|
|
void CanTxMessage::setShortValueMsb(uint16_t value, size_t offset) {
|
|
m_frame.data8[offset] = value >> 8;
|
|
m_frame.data8[offset + 1] = value & 0xFF;
|
|
}
|
|
|
|
void CanTxMessage::setBit(size_t byteIdx, size_t bitIdx) {
|
|
m_frame.data8[byteIdx] |= 1 << bitIdx;
|
|
}
|
|
|
|
uint8_t& CanTxMessage::operator[](size_t index) {
|
|
return m_frame.data8[index];
|
|
}
|
|
#endif // HAS_CAN_FRAME
|
|
|