Skip to content

Commit ca28e2b

Browse files
Merge pull request #6 from RIT-EVT/feature/actuallyzach/canpowertrain
CAN You Hear My Status
2 parents 8fe7fdd + a3b15a1 commit ca28e2b

File tree

4 files changed

+179
-24
lines changed

4 files changed

+179
-24
lines changed

CMakeLists.txt

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,11 @@ if(EVT_CORE_LOG_ENABLE)
66
endif()
77
cmake_minimum_required(VERSION 3.15)
88

9+
# Increases the number of RPDOs that CAN Open can handle.
10+
# Also able to change the number of TPDOs if RPDO in the definition
11+
# is changed to TPDO (CO_TPDO_N=50)
12+
add_compile_definitions(CO_RPDO_N=50)
13+
914
set(EVT_CORE_DIR ${CMAKE_SOURCE_DIR}/libs/EVT-core)
1015
set(TARGET_DEV "STM32F302x8")
1116

include/HUDL/HUDL.hpp

Lines changed: 134 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -70,9 +70,21 @@ class HUDL {
7070

7171
uint32_t thermTemps[4] = {};
7272

73-
static constexpr uint16_t OBJECT_DICTIONARY_SIZE = 30;
73+
/** The status word provided by the MC node over CAN. Found in the first 16 bits of the 1st PDO coming from the MC. */
74+
uint16_t statusWord = 0;
75+
/** The position actual value provided by the MC node over CAN. Found in the middle 32 bits of the 1st PDO coming from the MC. */
76+
uint32_t positionActual = 0;
77+
/** The torque actual value provided by the MC node over CAN. Found in the last 16 bits of the 1st PDO coming from the MC. */
78+
uint16_t torqueActual = 0;
79+
80+
uint16_t velocityActual = 0;
81+
82+
uint32_t rpdo4First32BitsDummyData = 0;
83+
84+
static constexpr uint16_t OBJECT_DICTIONARY_SIZE = 47;
7485
static constexpr uintptr_t TMS_NODE_ID = 0x08;
7586
static constexpr uintptr_t BMS_NODE_ID = 0x05;
87+
static constexpr uintptr_t MC_NODE_ID = 0x01;
7688

7789
CO_OBJ_T objectDictionary[OBJECT_DICTIONARY_SIZE + 1] = {
7890
// Sync ID, defaults to 0x80
@@ -192,6 +204,49 @@ class HUDL {
192204
.Data = (uintptr_t) 0xFE,
193205
},
194206

207+
/**
208+
* RPDO3 settings
209+
* 0: RPDO number in index and total number of sub indexes.
210+
* 1: The COB-ID to receive PDOs from.
211+
* 2: transmission trigger
212+
*/
213+
{
214+
.Key = CO_KEY(0x1403, 0, CO_UNSIGNED8 | CO_OBJ_D__R_),
215+
.Type = nullptr,
216+
.Data = (uintptr_t) 3,
217+
},
218+
{
219+
.Key = CO_KEY(0x1403, 1, CO_UNSIGNED32 | CO_OBJ_D__R_),
220+
.Type = nullptr,
221+
.Data = (uintptr_t) CO_COBID_TPDO_DEFAULT(0) + MC_NODE_ID,
222+
},
223+
{
224+
.Key = CO_KEY(0x1403, 2, CO_UNSIGNED8 | CO_OBJ_D__R_),
225+
.Type = nullptr,
226+
.Data = (uintptr_t) 0xFE,
227+
},
228+
/**
229+
* RPDO4 settings
230+
* 0: RPDO number in index and total number of sub indexes.
231+
* 1: The COB-ID to receive PDOs from.
232+
* 2: transmission trigger
233+
*/
234+
{
235+
.Key = CO_KEY(0x1404, 0, CO_UNSIGNED8 | CO_OBJ_D__R_),
236+
.Type = nullptr,
237+
.Data = (uintptr_t) 3,
238+
},
239+
{
240+
.Key = CO_KEY(0x1404, 1, CO_UNSIGNED32 | CO_OBJ_D__R_),
241+
.Type = nullptr,
242+
.Data = (uintptr_t) CO_COBID_TPDO_DEFAULT(3) + MC_NODE_ID,
243+
},
244+
{
245+
.Key = CO_KEY(0x1404, 2, CO_UNSIGNED8 | CO_OBJ_D__R_),
246+
.Type = nullptr,
247+
.Data = (uintptr_t) 0xFE,
248+
},
249+
195250
/**
196251
* RPDO0 mapping, determines the PDO messages to receive when RPDO0 is triggered
197252
* 0: The number of PDO message associated with the RPDO
@@ -252,9 +307,58 @@ class HUDL {
252307
.Data = CO_LINK(0x2101, 0, 32),
253308
},
254309

310+
/**
311+
* RPDO3 mapping, determines the PDO messages to receive when RPDO3 is triggered
312+
* 0: The number of PDO message associated with the RPDO
313+
* 1: Link to the first PDO message - statusWord
314+
* 2: Link to the second PD0 message - positionActual
315+
* 3: Link to the third PD0 message - torqueActual
316+
*/
317+
{
318+
.Key = CO_KEY(0x1603, 0, CO_UNSIGNED8 | CO_OBJ_D__R_),
319+
.Type = nullptr,
320+
.Data = (uintptr_t) 3,
321+
},
322+
{
323+
.Key = CO_KEY(0x1603, 1, CO_UNSIGNED32 | CO_OBJ_D__R_),
324+
.Type = nullptr,
325+
.Data = CO_LINK(0x2103, 0, 16),
326+
},
327+
{
328+
.Key = CO_KEY(0x1603, 2, CO_UNSIGNED32 | CO_OBJ_D__R_),
329+
.Type = nullptr,
330+
.Data = CO_LINK(0x2103, 1, 32),
331+
},
332+
{
333+
.Key = CO_KEY(0x1603, 3, CO_UNSIGNED32 | CO_OBJ_D__R_),
334+
.Type = nullptr,
335+
.Data = CO_LINK(0x2103, 2, 16),
336+
},
337+
338+
/**
339+
* RPDO4 mapping, determines the PDO messages to receive when RPDO4 is triggered
340+
* 0: The number of PDO message associated with the RPDO
341+
* 1: Link to the first PDO message - empty value
342+
* 2: Link to the second PDO message - velocityActual
343+
*/
344+
{
345+
.Key = CO_KEY(0x1604, 0, CO_UNSIGNED8 | CO_OBJ_D__R_),
346+
.Type = nullptr,
347+
.Data = (uintptr_t) 2,
348+
},
349+
{
350+
.Key = CO_KEY(0x1604, 1, CO_UNSIGNED32 | CO_OBJ_D__R_),
351+
.Type = nullptr,
352+
.Data = CO_LINK(0x2104, 0, 32),
353+
},
354+
{
355+
.Key = CO_KEY(0x1604, 2, CO_UNSIGNED32 | CO_OBJ_D__R_),
356+
.Type = nullptr,
357+
.Data = CO_LINK(0x2104, 1, 32),
358+
},
255359
/**
256360
* User defined data. Put elements that can be accessed via SDO
257-
* and depdning on the configuration PDO
361+
* and depending on the configuration PDO
258362
*/
259363
{
260364
.Key = CO_KEY(0x2100, 0, CO_UNSIGNED32 | CO_OBJ___PRW),
@@ -281,19 +385,43 @@ class HUDL {
281385
.Type = nullptr,
282386
.Data = (uintptr_t) &totalVoltage,
283387
},
284-
388+
{
389+
.Key = CO_KEY(0x2103, 0, CO_UNSIGNED16 | CO_OBJ___PRW),
390+
.Type = nullptr,
391+
.Data = (uintptr_t) &statusWord,
392+
},
393+
{
394+
.Key = CO_KEY(0x2103, 1, CO_UNSIGNED32 | CO_OBJ___PRW),
395+
.Type = nullptr,
396+
.Data = (uintptr_t) &positionActual,
397+
},
398+
{
399+
.Key = CO_KEY(0x2103, 2, CO_UNSIGNED16 | CO_OBJ___PRW),
400+
.Type = nullptr,
401+
.Data = (uintptr_t) &torqueActual,
402+
},
403+
{
404+
.Key = CO_KEY(0x2104, 0, CO_UNSIGNED32 | CO_OBJ___PRW),
405+
.Type = nullptr,
406+
.Data = (uintptr_t) &rpdo4First32BitsDummyData,
407+
},
408+
{
409+
.Key = CO_KEY(0x2104, 1, CO_UNSIGNED32 | CO_OBJ___PRW),
410+
.Type = nullptr,
411+
.Data = (uintptr_t) &velocityActual,
412+
},
285413
CO_OBJ_DIR_ENDMARK,
286414
};
287415

288416
static constexpr char* SECTION_TITLES[9]{
289417
"B Voltage",
290-
"Speed",
418+
"Velocity",
291419
"RPM",
292420
"Temp 1",
293421
"Temp 2",
294422
"Temp 3",
295-
"Status 1",
296-
"Pre Stat",
423+
"MC Stat",
424+
"Position",
297425
"Torque"};
298426
};
299427

src/HUDL/HUDL.cpp

Lines changed: 34 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -36,30 +36,46 @@ uint16_t HUDL::getObjectDictionarySize() const {
3636
}
3737

3838
void HUDL::updateLCD() {
39-
char tempOne[32];
40-
std::sprintf(tempOne, "%lu C", *(this->thermTemps + 0));
39+
char temps[32][4];
40+
for (int i = 0; i < sizeof(thermTemps) / sizeof(uint32_t); i++) {
41+
std::sprintf(temps[i], "%d C", thermTemps[i]);
42+
}
4143

42-
char tempTwo[32];
43-
std::sprintf(tempTwo, "%lu C", *(this->thermTemps + 1));
44+
char voltage[32];
45+
std::sprintf(voltage, "%d v", totalVoltage);
4446

45-
char tempThree[32];
46-
std::sprintf(tempThree, "%lu C", *(this->thermTemps + 2));
47+
char status[32];
48+
std::sprintf(status, "0x%X", statusWord);
4749

48-
char tempFour[32];
49-
std::sprintf(tempFour, "%lu C", *(this->thermTemps + 3));
50+
char position[32];
51+
std::sprintf(position, "0x%X", positionActual);
5052

51-
char voltage[32];
52-
std::sprintf(voltage, "%lu v", totalVoltage);
53+
char torque[32];
54+
std::sprintf(torque, "0x%X", torqueActual);
55+
56+
char velocity[32];
57+
std::sprintf(velocity, "0x%X", velocityActual);
5358

5459
lcd.setTextForSection(0, voltage);
55-
// setTextForSection(2g "25 MPH");
56-
// setTextForSection(2, "3000");
57-
lcd.setTextForSection(3, tempOne);
58-
lcd.setTextForSection(4, tempTwo);
59-
lcd.setTextForSection(5, tempThree);
60-
// setTextForSection(6, "ON");
61-
// setTextForSection(7, "Ready");
62-
// setTextForSection(8, "100 NM");
60+
lcd.setTextForSection(1, velocity);
61+
lcd.setTextForSection(2, "3000");
62+
lcd.setTextForSection(3, temps[0]);
63+
lcd.setTextForSection(4, temps[1]);
64+
lcd.setTextForSection(5, temps[2]);
65+
lcd.setTextForSection(6, status);
66+
lcd.setTextForSection(7, position);
67+
lcd.setTextForSection(8, torque);
68+
69+
for (int i = 0; i < sizeof(thermTemps) / sizeof(uint32_t); i++) {
70+
log::LOGGER.log(log::Logger::LogLevel::DEBUG, "Temp %d: %d\n\r", i, thermTemps[i]);
71+
}
72+
log::LOGGER.log(log::Logger::LogLevel::DEBUG, "Total Voltage: %d\n\r", totalVoltage);
73+
74+
log::LOGGER.log(log::Logger::LogLevel::DEBUG, "Status Word: 0x%X\n\r", statusWord);
75+
log::LOGGER.log(log::Logger::LogLevel::DEBUG, "Position Actual: 0x%X\n\r", positionActual);
76+
log::LOGGER.log(log::Logger::LogLevel::DEBUG, "Torque Actual: 0x%X\n\r", torqueActual);
77+
log::LOGGER.log(log::Logger::LogLevel::DEBUG, "Velocity Value: 0x%X\n\r", velocityActual);
78+
log::LOGGER.log(log::Logger::LogLevel::DEBUG, "Dummy Data: 0x%X\n\r", rpdo4First32BitsDummyData);
6379
}
6480

6581
}// namespace HUDL

targets/HUDL/main.cpp

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -131,8 +131,14 @@ int main() {
131131
log::LOGGER.log(log::Logger::LogLevel::ERROR, "Failed to connect to CAN network\r\n");
132132

133133
return 1;
134+
} else {
135+
log::LOGGER.log(log::Logger::LogLevel::INFO, "Connected to CAN network\r\n");
134136
}
135137

138+
// Crashes the HUDL
139+
// IO::UART& uart = IO::getUART<IO::Pin::UART_TX, IO::Pin::UART_RX>(9600);
140+
// log::LOGGER.setUART(&uart);
141+
136142
///////////////////////////////////////////////////////////////////////////
137143
// Setup CAN configuration, this handles making drivers, applying settings.
138144
// And generally creating the CANopen stack node which is the interface

0 commit comments

Comments
 (0)