rusEFI
The most advanced open source ECU
Loading...
Searching...
No Matches
openblt_can.cpp
Go to the documentation of this file.
1#include "pch.h"
2
3#include "hal.h"
4
5#include "can.h"
6#include "can_hw.h"
7
8extern "C" {
9 #include "boot.h"
10}
11
12// CAN1 PB8+PB9 and CAN2 PB5+PB6 pins are commonly used by Hellen.
13// CAN2 PB5+PB13 pins can be used for ST-bootloader compatibility.
14//
15// Other STM32 CAN pin combinations:
16// CAN1_RX: { PI9, PA11, PH14, PD0, PB8 }, CAN1_TX: { PA12, PH13, PD1, PB9 }
17// CAN2_RX: { PB5, PB12 }, CAN2_TX: { PB6, PB13 }
18
19#ifndef BOOT_COM_CAN_CHANNEL_INDEX
20 #error BOOT_COM_CAN_CHANNEL_INDEX is not defined.
21#elif (BOOT_COM_CAN_CHANNEL_INDEX == 0)
22 #if defined(STM32_CAN_USE_CAN1) || defined(STM32_CAN_USE_FDCAN1)
23 #define OPENBLT_CAND CAND1
24 #else
25 #error STM32_CAN_USE_CAN1/STM32_CAN_USE_FDCAN1 is not enabled for CAN index 0
26 #endif
27#elif (BOOT_COM_CAN_CHANNEL_INDEX == 1)
28 #if defined(STM32_CAN_USE_CAN2) || defined(STM32_CAN_USE_FDCAN2)
29 #define OPENBLT_CAND CAND2
30 #else
31 #error STM32_CAN_USE_CAN2/STM32_CAN_USE_FDCAN2 is not enabled for CAN index 1
32 #endif
33#else
34 #error Unknown BOOT_COM_CAN_CHANNEL_INDEX.
35#endif
36
37#ifndef CAN_IDE_STD
38#define CAN_IDE_STD 0
39#endif
40
41#ifndef CAN_IDE_EXT
42#define CAN_IDE_EXT 1
43#endif
44
45#if !defined(OPENBLT_CAN_RX_PIN) || !defined(OPENBLT_CAN_RX_PORT) || !defined(OPENBLT_CAN_TX_PIN) || !defined(OPENBLT_CAN_TX_PORT)
46#if (BOOT_COM_CAN_CHANNEL_INDEX == 0)
47 // default pins for CAN1 (compatible with Hellen)
48 #define OPENBLT_CAN_RX_PORT GPIOB
49 #define OPENBLT_CAN_RX_PIN 8
50 #define OPENBLT_CAN_TX_PORT GPIOB
51 #define OPENBLT_CAN_TX_PIN 9
52#elif (BOOT_COM_CAN_CHANNEL_INDEX == 1)
53 // default pins for CAN2 (compatible with ST-bootloader)
54 #define OPENBLT_CAN_RX_PORT GPIOB
55 #define OPENBLT_CAN_RX_PIN 5
56 #define OPENBLT_CAN_TX_PORT GPIOB
57 #define OPENBLT_CAN_TX_PIN 13
58#endif
59#endif
60
61extern const CANConfig *findCanConfig(can_baudrate_e rate);
62
63/************************************************************************************//**
64** \brief Initializes the CAN controller and synchronizes it to the CAN bus.
65** \return none.
66**
67****************************************************************************************/
68extern "C" void CanInit(void) {
69 // init pins
70 palSetPadMode(OPENBLT_CAN_TX_PORT, OPENBLT_CAN_TX_PIN, PAL_MODE_ALTERNATE(EFI_CAN_TX_AF));
71 palSetPadMode(OPENBLT_CAN_RX_PORT, OPENBLT_CAN_RX_PIN, PAL_MODE_ALTERNATE(EFI_CAN_RX_AF));
72
73 auto cfg = findCanConfig(B500KBPS);
74 canStart(&OPENBLT_CAND, cfg);
75}
76
77
78/************************************************************************************//**
79** \brief Transmits a packet formatted for the communication interface.
80** \param data Pointer to byte array with data that it to be transmitted.
81** \param len Number of bytes that are to be transmitted.
82** \return none.
83**
84****************************************************************************************/
85extern "C" void CanTransmitPacket(blt_int8u *data, blt_int8u len)
86{
87 blt_int32u txMsgId = BOOT_COM_CAN_TX_MSG_ID;
88 CANTxFrame frame = {};
89
90 if ((txMsgId & 0x80000000) == 0)
91 {
92 /* set the 11-bit CAN identifier. */
93 CAN_SID(frame) = txMsgId;
94 CAN_ISX(frame) = CAN_IDE_STD;
95 }
96 else
97 {
98 txMsgId &= ~0x80000000;
99 /* set the 29-bit CAN identifier. */
100 CAN_EID(frame) = txMsgId;
101 CAN_ISX(frame) = CAN_IDE_EXT;
102 }
103
104 // Copy data/DLC
105 frame.DLC = len;
106 memcpy(frame.data8, data, len);
107
108 canTransmitTimeout(&OPENBLT_CAND, CAN_ANY_MAILBOX, &frame, TIME_MS2I(100));
109}
110
111/************************************************************************************//**
112** \brief Receives a communication interface packet if one is present.
113** \param data Pointer to byte array where the data is to be stored.
114** \param len Pointer where the length of the packet is to be stored.
115** \return BLT_TRUE is a packet was received, BLT_FALSE otherwise.
116**
117****************************************************************************************/
118
119#ifdef BOOTLOADER_CAN_LISTENER
120extern void boardCanListener(CANRxFrame *frame);
121#endif
122
124{
125 constexpr blt_int32u rxMsgId = BOOT_COM_CAN_RX_MSG_ID;
126 CANRxFrame frame;
127
128 if (MSG_OK != canReceiveTimeout(&OPENBLT_CAND, CAN_ANY_MAILBOX, &frame, TIME_IMMEDIATE)) {
129 // no message was waiting
130 return BLT_FALSE;
131 }
132
133 // Check that the ID type matches this frame (std vs ext)
134 constexpr bool configuredAsExt = (rxMsgId & 0x80000000) != 0;
135 if (configuredAsExt != CAN_ISX(frame)) {
136 // Wrong frame type
137 goto wrong;
138 }
139
140 // Check that the frame's ID matches
141 if (CAN_ISX(frame)) {
142 if (CAN_EID(frame) != (rxMsgId & ~0x80000000)) {
143 // Wrong ID
144 goto wrong;
145 }
146 } else {
147 if (CAN_SID(frame) != rxMsgId) {
148 // Wrong ID
149 goto wrong;
150 }
151 }
152
153 // Copy data and length out
154 *len = frame.DLC;
155 memcpy(data, frame.data8, frame.DLC);
156
157 return BLT_TRUE;
158
159wrong:
160
161#ifdef BOOTLOADER_CAN_LISTENER
162 boardCanListener(&frame);
163#endif
164
165 return BLT_FALSE;
166}
uint32_t rate
Definition bluetooth.cpp:39
void CanInit(void)
Initializes the CAN controller and synchronizes it to the CAN bus.
void boardCanListener(CANRxFrame *frame)
Receives a communication interface packet if one is present.
const CANConfig * findCanConfig(can_baudrate_e rate)
Definition can_hw.cpp:36
blt_bool CanReceivePacket(blt_int8u *data, blt_int8u *len)
void CanTransmitPacket(blt_int8u *data, blt_int8u len)
Transmits a packet formatted for the communication interface.
can_baudrate_e
uint8_t data8[8]
Frame data.
Definition can_mocks.h:55
uint8_t DLC
Data length.
Definition can_mocks.h:42
uint8_t data8[8]
Frame data.
Definition can_mocks.h:27
uint8_t DLC
Data length.
Definition can_mocks.h:14
unsigned char blt_int8u
Definition types.h:49
unsigned char blt_bool
Definition types.h:46
unsigned int blt_int32u
Definition types.h:53