Vehicle Control Unit 0.01
This is the c library for controlling the car.
Loading...
Searching...
No Matches
Functions | Variables
Can.c File Reference
#include "stm32f7xx_it.h"
#include "../../../../Inc/Systems/Comms/Can/Can.h"
#include "../../../../Inc/Systems/Comms/Can/DBCParser.h"
#include "../../../../Inc/Utils/Common.h"
#include "../../../../Inc/Utils/MessageFormat.h"
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <inttypes.h>
Include dependency graph for Can.c:

Go to the source code of this file.

Functions

int init_CANBus (CANBus bus)
 Initializes the CANBus struct. More...
 
int load_dbc_file (CANBus bus, const unsigned char *filename)
 Loads a DBC file into the CAN database. Makes the messages and signals and stores them in the list. More...
 
int add_message (CANBus bus, CAN_Message_Template message)
 Adds a message to the CAN message list. More...
 
int add_message_lop (CANBus bus, int id, int dlc, int ide, int rtr, const char *name, const char *sender, int signal_count, CAN_Signal_Template *signals)
 Adds a message to the CAN message list by passing in the individual message parameters hence "LOP" (List of Parameters) More...
 
int send_CAN_message (CANBus bus, CANProtocol protocol, uint32_t id, uint8_t *data, uint8_t len)
 Sends a CAN message. More...
 
void receive_CAN_message (CAN_RxHeaderTypeDef *RxHeader, uint8_t *RxData, CANBus bus)
 Receives a CAN message. More...
 
void parseMessage (CAN_MessageList *messages, CAN_Message *can_message)
 Parses a CAN message. More...
 
void parseSignals (CAN_Message_Template *message, CAN_Message *can_message)
 Parses signals in a CAN message. More...
 
void parseSignal (CAN_Signal_Template *signal, CAN_Signal *can_signal, CAN_Message *can_message)
 Parses a CAN signal. More...
 
void print_CAN_Messages_Lists ()
 Prints the CAN message list. More...
 

Variables

CAN_MessageList can_messages [MAX_BUS]
 

Function Documentation

◆ add_message()

int add_message ( CANBus  bus,
CAN_Message_Template  message 
)

Adds a message to the CAN message list.

Parameters
busThe CAN bus to add the message to
messageThe message to add
Returns
int 0 if the message was added successfully, -1 if the bus is invalid

Definition at line 49 of file Can.c.

49 {
50 // Add the message to the list
53 return 0;
54}
CAN_MessageList can_messages[MAX_BUS]
Definition: Can.c:16
CAN_Message_Template messages[MAX_MESSAGES]
Definition: Can.h:123
int num_messages
Definition: Can.h:124
Here is the caller graph for this function:

◆ add_message_lop()

int add_message_lop ( CANBus  bus,
int  id,
int  dlc,
int  ide,
int  rtr,
const char *  name,
const char *  sender,
int  signal_count,
CAN_Signal_Template signals 
)

Adds a message to the CAN message list by passing in the individual message parameters hence "LOP" (List of Parameters)

Parameters
busThe CAN bus to add the message to
idThe ID of the message
dlcThe Data Length Code of the message
ideThe Identifier Extension of the message
rtrThe Remote Transmission Request of the message
nameThe name of the message
senderThe sender of the message
signal_countThe number of signals in the message
signalsThe signals in the message
Returns
int 0 if the message was added successfully, -1 if the bus is invalid

Definition at line 56 of file Can.c.

57{
58 // Create a CAN message template
60 message.id = id;
61 message.dlc = dlc;
62 message.ide = ide;
63 message.rtr = rtr;
64 strcpy(message.name, name);
65 strcpy(message.sender, sender);
66 message.signal_count = signal_count;
67 message.payload_length = 0;
68
69 // Copy the signals
70 for (int i = 0; i < signal_count; i++) {
71 message.signals[i] = signals[i];
72 message.payload_length += signals[i].length;
73 }
74
75 // Add the message to the list
76 return add_message(bus, message);
77}
int add_message(CANBus bus, CAN_Message_Template message)
Adds a message to the CAN message list.
Definition: Can.c:49
static TelemetrySignal signals[MAX_TELEMETRY_SIGNALS]
Definition: Telemetry.c:8
char sender[MAX_NODE_NAME_LENGTH]
Definition: Can.h:78
int signal_count
Definition: Can.h:80
int payload_length
Definition: Can.h:81
CAN_Signal_Template signals[MAX_SIGNALS]
Definition: Can.h:79
char name[MAX_MESSAGE_NAME_LENGTH]
Definition: Can.h:77
Here is the call graph for this function:
Here is the caller graph for this function:

◆ init_CANBus()

int init_CANBus ( CANBus  bus)

Initializes the CANBus struct.

Parameters
busThe CAN bus to initialize
Returns
int 0 if the CAN bus was initialized successfully, -1 if the bus is invalid

Definition at line 18 of file Can.c.

18 {
19 // Initialize the CAN message list
20 can_messages[bus].bus = bus;
22
23 return 0;
24}
CANBus bus
Definition: Can.h:122
Here is the caller graph for this function:

◆ load_dbc_file()

int load_dbc_file ( CANBus  bus,
const unsigned char *  filename 
)

Loads a DBC file into the CAN database. Makes the messages and signals and stores them in the list.

Parameters
busThe CAN bus to load the DBC file into
filenameThe name of the DBC file to load
Returns
int 0 if the DBC file was loaded successfully, -1 if the file could not be opened

Definition at line 26 of file Can.c.

27{
28 // Load the DBC file
29 #ifdef TEST_MODE
30 // unsigned char* dbc_contents = fopen(filename, "w");
31 #else
32 unsigned char* dbc_contents = filename;
33 #endif
34// //printf("Loading DBC file: %c\r\r\n", filename[0]);
35
36 #ifndef TEST_MODE
37 // Parse the DBC file
38 parseDbcFile(&can_messages[bus], dbc_contents);
39 #endif
40
41 #ifdef TEST_MODE
42 // fclose(dbc_contents);
43 #endif
44
46 return 0;
47}
int parseDbcFile(CAN_MessageList *messages, const unsigned char *dbc_contents)
Parses a DBC (CAN database) file and populates the DBC structure.
Definition: DBCParser.c:31
void print_CAN_MessageList(const CAN_MessageList *messages)
Prints the contents of a CAN message list (aka DBC file).
Definition: DBCParser.c:44
Here is the call graph for this function:

◆ parseMessage()

void parseMessage ( CAN_MessageList messages,
CAN_Message can_message 
)

Parses a CAN message.

Parameters
messagesThe CAN message list
can_messageThe CAN message to parse

Definition at line 147 of file Can.c.

147 {
148 // Find the message in the list
149 // TODO: Implement a hash table or map for faster lookup
150 for (int i = 0; i < messages->num_messages; i++) {
151 CAN_Message_Template* msg = &messages->messages[i];
152 if (msg->id == can_message->header.StdId || msg->id == can_message->header.ExtId) {
153 // Parse the signals of the message
154 can_message->template = msg;
155 parseSignals(msg, can_message);
156 return;
157 }
158 }
159}
void parseSignals(CAN_Message_Template *message, CAN_Message *can_message)
Parses signals in a CAN message.
Definition: Can.c:162
CAN_Message_Template * template
Definition: Can.h:87
CAN_RxHeaderTypeDef header
Definition: Can.h:85
Here is the call graph for this function:
Here is the caller graph for this function:

◆ parseSignal()

void parseSignal ( CAN_Signal_Template signal,
CAN_Signal can_signal,
CAN_Message can_message 
)

Parses a CAN signal.

Parameters
signalThe CAN signal template
can_signalThe CAN signal to parse
can_messageThe CAN message to parse

Definition at line 172 of file Can.c.

172 {
173 can_signal->template = signal;
174
175 // Extract the raw data from the message
176 uint64_t raw_data = 0;
177 for (int i = signal->start_bit; i < signal->start_bit + signal->length; i++) {
178 raw_data |= ((can_message->data[i / 8] >> (i % 8)) & 1) << (i - signal->start_bit);
179 }
180
181 // Check if the signal is big endian
182 if (signal->endian == 1) {
183 // Reverse the bits
184 uint64_t reversed_data = 0;
185 for (int i = 0; i < signal->length; i++) {
186 reversed_data |= ((raw_data >> i) & 1) << (signal->length - i - 1);
187 }
188 raw_data = reversed_data;
189 }
190
191 // Check if the signal is signed
192 if (signal->isSigned) {
193 // Sign extend the data
194 raw_data = (raw_data << (64 - signal->length)) >> (64 - signal->length);
195 }
196
197 // Scale and offset the data
198 can_signal->value = (raw_data * signal->scale) + signal->offset;
199
200}
uint8_t data[8]
Definition: Can.h:86
float offset
Definition: Can.h:26
float scale
Definition: Can.h:25
int value
Definition: Can.h:34
CAN_Signal_Template * template
Definition: Can.h:35
Here is the caller graph for this function:

◆ parseSignals()

void parseSignals ( CAN_Message_Template message,
CAN_Message can_message 
)

Parses signals in a CAN message.

Parameters
messageThe CAN message template
can_messageThe CAN message to parse

Definition at line 162 of file Can.c.

162 {
163 // Find the signals in the message
164 for (int i = 0; i < message->signal_count; i++) {
165 CAN_Signal_Template* signal = &message->signals[i];
166 // Parse the signal
167 parseSignal(signal, &can_message->signals[i], can_message);
168 }
169}
void parseSignal(CAN_Signal_Template *signal, CAN_Signal *can_signal, CAN_Message *can_message)
Parses a CAN signal.
Definition: Can.c:172
CAN_Signal signals[]
Definition: Can.h:88
Here is the call graph for this function:
Here is the caller graph for this function:

◆ print_CAN_Messages_Lists()

void print_CAN_Messages_Lists ( )

Prints the CAN message list.

Definition at line 202 of file Can.c.

202 {
203 for (int i = 0; i < MAX_BUS; i++) {
204 //printf("Printing CAN Message List for bus %d with %d messages\r\n", i, can_messages[i].num_messages);
205 for (int j = 0; j < can_messages[i].num_messages; j++) {
206 const CAN_Message_Template* msg = &can_messages[i].messages[j];
207 //printf(ANSI_COLOR_GREEN "Message" ANSI_COLOR_RESET ": %s (ID: %d, DLC: %d, Sender: %s, SIGs: %d)\r\n", msg->name, msg->id, msg->dlc, msg->sender, msg->signal_count);
208 for (int k = 0; k < msg->signal_count; k++) {
209 const CAN_Signal_Template* sig = &msg->signals[k];
210 //printf("\t" ANSI_COLOR_BLUE "Signal" ANSI_COLOR_RESET ": %s (Start bit: %d, Length: %d, Endain: %d, Signed: %c,\r\n\t\tScale: %f, Offset: %f, Min: %f, Max: %f, \r\n\t\tUnit: %s, Reciever: %s)\r\n", sig->name, sig->start_bit, sig->length, sig->endian, sig->isSigned, sig->scale, sig->offset, sig->min, sig->max, sig->unit, sig->reciever);
211 }
212 //printf("\r\n");
213 }
214 if (can_messages[i].num_messages == 0) {
215 //printf("No messages on bus %d\r\n", i);
216 }
217 }
218}
#define MAX_BUS
Definition: Can.h:94
Here is the caller graph for this function:

◆ receive_CAN_message()

void receive_CAN_message ( CAN_RxHeaderTypeDef *  header,
uint8_t *  data,
CANBus  bus 
)

Receives a CAN message.

Parameters
RxHeaderThe CAN Rx header
RxDataThe CAN Rx data
busThe CAN bus to receive the message on

Definition at line 113 of file Can.c.

113 {
114 CAN_Message* can_message = malloc(sizeof(CAN_Message) + sizeof(CAN_Signal) * 8);
115 can_message->header = *RxHeader;
116 memcpy(can_message->data, RxData, 8);
117
118 // Send telemetry message for received CAN data
119 char data_hex[17]; // 8 bytes * 2 hex chars + null terminator
120 for (int i = 0; i < RxHeader->DLC && i < 8; i++) {
121 sprintf(&data_hex[i*2], "%02X", RxData[i]);
122 }
123 data_hex[RxHeader->DLC * 2] = '\0';
124
125 // Send properly formatted CAN RX message
126 sendMessage("CAN", MSG_CAN_RX, "ID:0x%lX;DLC:%lu;Data:%s",
127 RxHeader->StdId, RxHeader->DLC, data_hex);
128
129 // Parse the message
130 parseMessage(&can_messages[bus], can_message);
131
132 // Print out the contents of the message
133 //printf(ANSI_COLOR_YELLOW "Received CAN Message" ANSI_COLOR_RESET ": %s (ID: %d, DLC: %d, Sender: %s)\r\n", can_message->template->name, can_message->header.StdId, can_message->header.DLC, can_message->template->sender);
134
135 // Print the signals
136 for (int i = 0; i < can_message->template->signal_count; i++) {
137 CAN_Signal* signal = &can_message->signals[i];
138 //printf("\t" ANSI_COLOR_MAGENTA "Signal" ANSI_COLOR_RESET ": %s (Value: %u, Unit: %s)\r\n", signal->template->name, signal->value, signal->template->unit);
139 }
140 //printf("\r\n");
141
142 // Free the message
143 free(can_message);
144}
void parseMessage(CAN_MessageList *messages, CAN_Message *can_message)
Parses a CAN message.
Definition: Can.c:147
@ MSG_CAN_RX
Definition: MessageFormat.h:16
void sendMessage(const char *sender, MessageType type, const char *format,...)
Definition: MessageFormat.c:5
Definition: Can.h:33
Here is the call graph for this function:
Here is the caller graph for this function:

◆ send_CAN_message()

int send_CAN_message ( CANBus  bus,
CANProtocol  protocol,
uint32_t  id,
uint8_t *  data,
uint8_t  len 
)

Sends a CAN message.

Parameters
busThe CAN bus to send the message on
protocolThe CAN protocol to use
idThe ID of the message
dataThe data to send
lenThe length of the data
Returns
int 0 if the message was sent successfully, -1 if the bus is invalid

Definition at line 80 of file Can.c.

80 {
81 CAN_TxHeaderTypeDef TxHeader;
82 if (protocol == CAN_2A) {
83 TxHeader.StdId = id;
84 TxHeader.IDE = CAN_ID_STD;
85 } else if (protocol == CAN_2B) {
86 TxHeader.ExtId = id;
87 TxHeader.IDE = CAN_ID_EXT;
88 } else {
89 //printf("Invalid CAN protocol\r\n");
90 return -1;
91 }
92
93 TxHeader.RTR = CAN_RTR_DATA;
94 TxHeader.DLC = len;
95
96 // Print the message
97 printf(ANSI_COLOR_YELLOW "Sending CAN Message" ANSI_COLOR_RESET ": ID: %d, DLC: %d, Data: ", id, len);
98 for (int i = 0; i < len; i++) {
99 printf("%02X ", data[i]);
100 }
101 printf("\r\n");
102
103 #ifndef TEST_MODE
104 // Send the CAN message
105 if (send_CAN_message_helper(bus, &TxHeader, data) != 0) {
106 return -2;
107 }
108 #endif
109 return 0;
110}
@ CAN_2A
Definition: Can.h:105
@ CAN_2B
Definition: Can.h:106
#define ANSI_COLOR_YELLOW
Definition: Common.h:11
#define ANSI_COLOR_RESET
Definition: Common.h:15
int send_CAN_message_helper(CANBus bus, CAN_TxHeaderTypeDef *TxHeader, uint8_t *data)
Definition: stm32f7xx_it.c:382
Here is the call graph for this function:
Here is the caller graph for this function:

Variable Documentation

◆ can_messages

CAN_MessageList can_messages[MAX_BUS]

Definition at line 16 of file Can.c.