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