rusEFI
The most advanced open source ECU
Loading...
Searching...
No Matches
can_msg_tx.cpp
Go to the documentation of this file.
1/**
2 * @file can_msg_tx.cpp
3 *
4 * CAN message transmission
5 *
6 * @date Mar 13, 2020
7 * @author Matthew Kennedy, (c) 2012-2020
8 */
9
10#include "pch.h"
11
12#include "can_msg_tx.h"
14
15#include "can.h"
16
17#if EFI_SIMULATOR || EFI_UNIT_TEST
18#include "fifo_buffer.h"
19fifo_buffer<CANTxFrame, 1024> txCanBuffer;
20#endif // EFI_SIMULATOR
21
22#if EFI_CAN_SUPPORT
23/*static*/ CANDriver* CanTxMessage::s_devices[2] = {nullptr, nullptr};
24
25/*static*/ void CanTxMessage::setDevice(CANDriver* device1, CANDriver* device2) {
26 s_devices[0] = device1;
27 s_devices[1] = device2;
28}
29#endif // EFI_CAN_SUPPORT
30
31CanTxMessage::CanTxMessage(CanCategory p_category, uint32_t eid, uint8_t dlc, size_t bus, bool isExtended) {
32 category = p_category;
33#if HAS_CAN_FRAME
34#ifndef STM32H7XX
35 // ST bxCAN device
36 m_frame.IDE = isExtended ? CAN_IDE_EXT : CAN_IDE_STD;
37 m_frame.RTR = CAN_RTR_DATA;
38#else /* if STM32H7XX */
39 // Bosch M_CAN FDCAN device
40 m_frame.common.XTD = isExtended;
41 m_frame.common.RTR = 0;
42#endif
43
44 if (isExtended) {
45 CAN_EID(m_frame) = eid;
46 } else {
47 if (eid >= 0x800) {
48 criticalError("Looks like extended CAN ID %x %s", eid, getCanCategory(category));
49 return;
50 }
51 CAN_SID(m_frame) = eid;
52 }
53
54 setDlc(dlc);
55
56 setBus(bus);
57
59#endif // HAS_CAN_FRAME
60}
61
63#if EFI_SIMULATOR || EFI_UNIT_TEST
65
66#if EFI_UNIT_TEST
67 printf("%s Sending CAN%d message: ID=%x/l=%x %x %x %x %x %x %x %x %x \n",
69 busIndex + 1,
70 (unsigned int)CAN_ID(m_frame),
75 m_frame.data8[6], m_frame.data8[7]);
76#endif
77#endif // EFI_SIMULATOR
78
79#if EFI_CAN_SUPPORT
81
82 if (!engine->allowCanTx) {
83 return;
84 }
85
87 if (!device) {
88 criticalError("Send: CAN%d device not configured %s %x", busIndex + 1, getCanCategory(category),
89 (unsigned int)CAN_ID(m_frame));
90 return;
91 }
92
93 bool verboseCan0 = engineConfiguration->verboseCan && busIndex == 0;
94 bool verboseCan1 = engineConfiguration->verboseCan2 && busIndex == 1;
95
96 if (verboseCan0 || verboseCan1) {
97 efiPrintf("%s Sending CAN%d message: ID=%x/l=%x %x %x %x %x %x %x %x %x",
99 busIndex + 1,
100 (unsigned int)CAN_ID(m_frame),
101 m_frame.DLC,
102 m_frame.data8[0], m_frame.data8[1],
103 m_frame.data8[2], m_frame.data8[3],
104 m_frame.data8[4], m_frame.data8[5],
105 m_frame.data8[6], m_frame.data8[7]);
106 }
107
108 // 100 ms timeout
109 msg_t msg = canTransmit(device, CAN_ANY_MAILBOX, &m_frame, TIME_MS2I(100));
110#if EFI_TUNER_STUDIO
111 if (msg == MSG_OK) {
113 } else {
115 }
116#endif // EFI_TUNER_STUDIO
117#endif /* EFI_CAN_SUPPORT */
118}
119
120#if HAS_CAN_FRAME
121void CanTxMessage::setDlc(uint8_t dlc) {
122 m_frame.DLC = dlc;
123}
124
125void CanTxMessage::setBus(size_t bus) {
126 busIndex = bus;
127}
128
129// LSB Little-endian System, "Intel"
130void CanTxMessage::setShortValue(uint16_t value, size_t offset) {
131 m_frame.data8[offset] = value & 0xFF;
132 m_frame.data8[offset + 1] = value >> 8;
133}
134
135// MOTOROLA order, MSB (Most Significant Byte/Big Endian) comes first.
136void CanTxMessage::setShortValueMsb(uint16_t value, size_t offset) {
137 m_frame.data8[offset] = value >> 8;
138 m_frame.data8[offset + 1] = value & 0xFF;
139}
140
141void CanTxMessage::setBit(size_t byteIdx, size_t bitIdx) {
142 m_frame.data8[byteIdx] |= 1 << bitIdx;
143}
144
145uint8_t& CanTxMessage::operator[](size_t index) {
146 return m_frame.data8[index];
147}
148#endif // HAS_CAN_FRAME
149
const char * getCanCategory(CanCategory value)
CanCategory
Definition can_category.h:7
fifo_buffer< CANTxFrame, 1024 > txCanBuffer
fifo_buffer< CANTxFrame, 1024 > txCanBuffer
uint8_t & operator[](size_t)
Read & write the raw underlying 8-byte buffer.
static void setDevice(CANDriver *device1, CANDriver *device2)
void setBit(size_t byteIdx, size_t bitIdx)
Set a single bit in the transmit buffer. Useful for single-bit flags.
void setShortValueMsb(uint16_t value, size_t offset)
void setBus(size_t bus)
static CANDriver * s_devices[2]
Definition can_msg_tx.h:23
CanTxMessage(CanCategory category, uint32_t eid, uint8_t dlc=8, size_t bus=0, bool isExtended=false)
void setShortValue(uint16_t value, size_t offset)
Write a 16-bit short value to the buffer. Note: this writes in Intel little endian byte order.
void setDlc(uint8_t dlc)
size_t busIndex
Definition can_msg_tx.h:53
CanCategory category
Definition can_msg_tx.h:44
CANTxFrame m_frame
Definition can_msg_tx.h:100
bool allowCanTx
Definition engine.h:114
TunerStudioOutputChannels outputChannels
Definition engine.h:109
static EngineAccessor engine
Definition engine.h:413
static constexpr engine_configuration_s * engineConfiguration
static Lps25 device
Definition init_baro.cpp:4
@ CanDriverTx
uint8_t data8[8]
Frame data.
Definition can_mocks.h:27
uint8_t DLC
Data length.
Definition can_mocks.h:14
uint8_t RTR
Frame type.
Definition can_mocks.h:15
uint8_t IDE
Identifier type.
Definition can_mocks.h:16
void setArrayValues(TValue(&array)[TSize], float value)
uint16_t offset
Definition tunerstudio.h:0
printf("\n")