Skip to content
This repository was archived by the owner on Jul 16, 2021. It is now read-only.
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
26 changes: 26 additions & 0 deletions Libraries/mcp_can/mcp_can.h
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,16 @@

#define MAX_CHAR_IN_MESSAGE 8

// This is not part of the actual library. Added as FlexCAN-style interface.
typedef struct CAN_message_t {
uint32_t id; // can identifier
uint8_t ext; // identifier is extended
uint8_t rtr; // remote transmission request packet type
uint8_t len; // length of data
uint16_t timeout; // milliseconds, zero will disable waiting
uint8_t buf[8];
} CAN_message_t;

class MCP_CAN
{
private:
Expand Down Expand Up @@ -131,6 +141,22 @@ class MCP_CAN
unsigned long getCanId(void); // get can id when receive
byte isRemoteRequest(void); // get RR flag when receive
byte isExtendedFrame(void); // did we recieve 29bit frame?

// This is not part of the actual library. Added as FlexCAN-style interface.
inline int read(CAN_message_t& msg) {
if (checkReceive() != CAN_MSGAVAIL)
return false;
readMsgBuf(&msg.len, msg.buf);
msg.id = can_id;
msg.ext = ext_flg;
msg.rtr = rtr;
msg.timeout = 0;
return true;
}

inline int write(CAN_message_t& msg) {
return sendMsgBuf(msg.id, msg.ext, msg.rtr, msg.len, msg.buf);
}
};

#endif
Expand Down
14 changes: 14 additions & 0 deletions Utilities/flexcan_tester_rev2/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
This utility operates on the assumption that you have two Teensy controllers, one running the transmitter code and one running the receiver code.

Switch between send and receive configurations by switching which header is included in [flexcan_tester_rev2.ino](./flexcan_tester_rev2.ino).

[receiver.h](./receiver.h) and [transmitter.h](./transmitter.h) each defines two functions:

```
void synchronize();
template<typename T> inline T handle_message(unsigned id, T data);
```

This utility is capable of transmitting a series of messages and validating the ouput. `synchronize()` is used to ensure that both programs are on the same page regarding which frame is being sent. `handle_message(id, data)` is used to actually send or receive a message over FlexCAN. data should always be a member class of the [HyTech_CAN](../Libraries/HyTech_CAN) library.

There is a `print()` helper function defined in [flexcan_tester_rev2.h](./flexcan_tester_rev2.h). This prints the ID and length of the messages received. There is no provision for printing the contents of the message - it is recommended that users either extend the `print()` function to suit their purposes or print the data in `loop()` using the data returned by `handle_message()`. If the [tcu-refactor](https://github.com/hytech-racing/code-2020/tree/tcu-refactor) branch has been merged in, then most classes should already have some kind of `print()` member function, which can be activated by uncommenting `#define HT_DEBUG_EN` in [flexcan_tester_rev2.ino](./flexcan_tester_rev2.ino).
42 changes: 42 additions & 0 deletions Utilities/flexcan_tester_rev2/flexcan_tester_rev2.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
#pragma once

#include <HyTech_CAN.h>

// I'm lazy so this is how we're handling CAN library switching
#ifdef HT_CAN_MODE_FLEXCAN
#include <HyTech_FlexCAN.h>
extern FlexCAN CAN;

#elif defined(HT_CAN_MODE_FLEXCAN_T4)
#include <FlexCAN_T4.h>
extern FlexCAN_T4<CAN1> CAN;

#elif defined(HT_CAN_MODE_MCP)
#include <mcp_can.h>
extern MCP_CAN CAN;
#endif

#define SYNC 0x90
#define ACK 0x91
#define BEGIN 0x92

template<typename T>
inline void print(CAN_message_t& message, unsigned id, T& data) {
Serial.println ("CAN Message");
Serial.println ("-----------");
Serial.print ("ID = "); Serial.println (message.id, HEX);
Serial.print ("LEN = "); Serial.println (message.len);

if (id != message.id) {
Serial.println("Warning: ID Mismatch -- Expected ");
Serial.println(id, HEX);
}
if (sizeof(T) != message.len) {
Serial.println("Warning: Length Mismatch -- Expected ");
Serial.println(sizeof(T));
}
// this may not exist yet if you haven't merged in the tcu-refactor branch as an alternative, add if/elses here or print in the loop() function
#ifdef HT_DEBUG_EN
data.print();
#endif
}
77 changes: 77 additions & 0 deletions Utilities/flexcan_tester_rev2/flexcan_tester_rev2.ino
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
// #define HT_DEBUG_EN // only uncomment this line if tcu-refactor merged in

#define HT_CAN_MODE_FLEXCAN

#define TRANSMIT "transmitter.h"
#define RECEIVE "receiver.h"

//Choose mode here
#define MODE TRANSMIT

#include MODE

#ifdef HT_CAN_MODE_FLEXCAN
FlexCAN CAN(500000);
void setupCAN() {
CAN.begin();
}

#elif defined(HT_CAN_MODE_FLEXCAN_T4)
FlexCAN_T4<CAN1> CAN;
void setupCAN() {
CAN.begin();
CAN.setBaudRate(500000);
}

#elif defined(HT_CAN_MODE_MCP)
MCP_CAN CAN(11);
void setupCAN() {
while (CAN_OK != CAN.begin(CAN_500KBPS))
delay(200);
}
#endif

void setup() {
setupCAN();
Serial.begin(9600);
}

void loop() {
synchronize();

GLV_current_readings glv = handle_message(ID_GLV_CURRENT_READINGS, GLV_current_readings(100, 200));
Serial.println(glv.get_cooling_current_value());
Serial.println(glv.get_ecu_current_value());

MCU_pedal_readings mpr = handle_message(ID_MCU_PEDAL_READINGS, MCU_pedal_readings(1, 2, 3, 4, 5));
Serial.println(mpr.get_accelerator_implausibility());
Serial.println(mpr.get_accelerator_pedal_raw_1());
Serial.println(mpr.get_accelerator_pedal_raw_2());
Serial.println(mpr.get_brake_implausibility());
Serial.println(mpr.get_brake_pedal_active());
Serial.println(mpr.get_brake_pedal_raw());
Serial.println(mpr.get_pedal_flags());
Serial.println(mpr.get_torque_map_mode());

MCU_status ms = handle_message(ID_MCU_STATUS, MCU_status(10,20,30,40));
Serial.println(ms.get_bms_ok_high());
Serial.println(ms.get_flags());
Serial.println(ms.get_glv_battery_voltage());
Serial.println(ms.get_inverter_powered());
Serial.println(ms.get_shutdown_b_above_threshold());
Serial.println(ms.get_shutdown_c_above_threshold());
Serial.println(ms.get_shutdown_d_above_threshold());
Serial.println(ms.get_shutdown_e_above_threshold());
Serial.println(ms.get_shutdown_f_above_threshold());
Serial.println(ms.get_shutdown_f_above_threshold());
Serial.println(ms.get_state());
Serial.println(ms.get_temperature());

BMS_coulomb_counts bcc = handle_message(ID_BMS_COULOMB_COUNTS, BMS_coulomb_counts(123456, 987654));
Serial.println(bcc.get_total_charge());
Serial.println(bcc.get_total_discharge());

BMS_balancing_status bbs = handle_message(ID_BMS_BALANCING_STATUS, BMS_balancing_status(5, 0XDEADBEEF));
Serial.println(bbs.get_group_id());
//Serial.println(bbs.get_balancing());
}
27 changes: 27 additions & 0 deletions Utilities/flexcan_tester_rev2/receiver.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
#include "flexcan_tester_rev2.h"

void synchronize() {
CAN_message_t message;
Serial.println("before the SYNC\n");
message.timeout = 0;
while (!(CAN.read(message) && message.id == SYNC)) { // wait for sync message
Serial.println("waiting on SYNC");
delay(500);
}
Serial.println("got the SYNC, send the ACK\n");
message.id = ACK;
message.len = 0;
CAN.write(message); // send response
while (!(CAN.read(message) && message.id == BEGIN)); // clear extra syncs from mailbox
Serial.println("got BEGIN\n");
}

template <typename T>
inline T handle_message(unsigned id, T data) {
CAN_message_t message;
while (!CAN.read(message));

data.load(message.buf);
print(message, id, data);
return data;
}
39 changes: 39 additions & 0 deletions Utilities/flexcan_tester_rev2/transmitter.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
#include "flexcan_tester_rev2.h"
#include <Metro.h>

Metro timer(1000);

void synchronize() {
CAN_message_t message;
message.id = SYNC;
message.len = 0;
message.timeout = 0;
Serial.println("before sending the SYNC\n");
do {
Serial.println("sending the SYNC\n");
CAN.write(message); // send sync message
delay(500);
} while (!(CAN.read(message) && message.id == ACK));
Serial.println("received the ACK\n");
message.id = BEGIN;
message.len = 0;
CAN.write(message);
Serial.println("sent BEGIN\n");
timer.reset(); // reset send timer
}



template<typename T>
inline T handle_message(unsigned id, T data) {
CAN_message_t message;

while (!timer.check());
message.id = id;
message.len = sizeof(T);
data.write(message.buf);

print(message, id, data);
CAN.write(message);
return data;
}