Vehicle Control Unit 0.01
This is the c library for controlling the car.
Loading...
Searching...
No Matches
Macros | 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/Systems/PrintHelpers.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.

Macros

#define ANSI_COLOR_RESET   "\x1b[0m"
 

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]
 

Macro Definition Documentation

◆ ANSI_COLOR_RESET

#define ANSI_COLOR_RESET   "\x1b[0m"

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 48 of file Can.c.

48 {
49 // Add the message to the list
52 return 0;
53}
CAN_MessageList can_messages[MAX_BUS]
Definition: Can.c:15
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 55 of file Can.c.

56{
57 // Create a CAN message template
59 message.id = id;
60 message.dlc = dlc;
61 message.ide = ide;
62 message.rtr = rtr;
63 strcpy(message.name, name);
64 strcpy(message.sender, sender);
65 message.signal_count = signal_count;
66 message.payload_length = 0;
67
68 // Copy the signals
69 for (int i = 0; i < signal_count; i++) {
70 message.signals[i] = signals[i];
71 message.payload_length += signals[i].length;
72 }
73
74 // Add the message to the list
75 return add_message(bus, message);
76}
int add_message(CANBus bus, CAN_Message_Template message)
Adds a message to the CAN message list.
Definition: Can.c:48
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 17 of file Can.c.

17 {
18 // Initialize the CAN message list
19 can_messages[bus].bus = bus;
21
22 return 0;
23}
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 25 of file Can.c.

26{
27 // Load the DBC file
28 #ifdef TEST_MODE
29 // unsigned char* dbc_contents = fopen(filename, "w");
30 #else
31 unsigned char* dbc_contents = filename;
32 #endif
33// printf("Loading DBC file: %c\r\r\n", filename[0]);
34
35 #ifndef TEST_MODE
36 // Parse the DBC file
37 parseDbcFile(&can_messages[bus], dbc_contents);
38 #endif
39
40 #ifdef TEST_MODE
41 // fclose(dbc_contents);
42 #endif
43
45 return 0;
46}
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 135 of file Can.c.

135 {
136 // Find the message in the list
137 // TODO: Implement a hash table or map for faster lookup
138 for (int i = 0; i < messages->num_messages; i++) {
139 CAN_Message_Template* msg = &messages->messages[i];
140 if (msg->id == can_message->header.StdId || msg->id == can_message->header.ExtId) {
141 // Parse the signals of the message
142 can_message->template = msg;
143 parseSignals(msg, can_message);
144 return;
145 }
146 }
147}
void parseSignals(CAN_Message_Template *message, CAN_Message *can_message)
Parses signals in a CAN message.
Definition: Can.c:150
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 160 of file Can.c.

160 {
161 can_signal->template = signal;
162
163 // Extract the raw data from the message
164 uint64_t raw_data = 0;
165 for (int i = signal->start_bit; i < signal->start_bit + signal->length; i++) {
166 raw_data |= ((can_message->data[i / 8] >> (i % 8)) & 1) << (i - signal->start_bit);
167 }
168
169 // Check if the signal is big endian
170 if (signal->endian == 1) {
171 // Reverse the bits
172 uint64_t reversed_data = 0;
173 for (int i = 0; i < signal->length; i++) {
174 reversed_data |= ((raw_data >> i) & 1) << (signal->length - i - 1);
175 }
176 raw_data = reversed_data;
177 }
178
179 // Check if the signal is signed
180 if (signal->isSigned) {
181 // Sign extend the data
182 raw_data = (raw_data << (64 - signal->length)) >> (64 - signal->length);
183 }
184
185 // Scale and offset the data
186 can_signal->value = (raw_data * signal->scale) + signal->offset;
187
188}
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 150 of file Can.c.

150 {
151 // Find the signals in the message
152 for (int i = 0; i < message->signal_count; i++) {
153 CAN_Signal_Template* signal = &message->signals[i];
154 // Parse the signal
155 parseSignal(signal, &can_message->signals[i], can_message);
156 }
157}
void parseSignal(CAN_Signal_Template *signal, CAN_Signal *can_signal, CAN_Message *can_message)
Parses a CAN signal.
Definition: Can.c:160
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 190 of file Can.c.

190 {
191 for (int i = 0; i < MAX_BUS; i++) {
192 printf("Printing CAN Message List for bus %d with %d messages\r\n", i, can_messages[i].num_messages);
193 for (int j = 0; j < can_messages[i].num_messages; j++) {
194 const CAN_Message_Template* msg = &can_messages[i].messages[j];
195 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);
196 for (int k = 0; k < msg->signal_count; k++) {
197 const CAN_Signal_Template* sig = &msg->signals[k];
198 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);
199 }
200 printf("\r\n");
201 }
202 if (can_messages[i].num_messages == 0) {
203 printf("No messages on bus %d\r\n", i);
204 }
205 }
206}
#define ANSI_COLOR_RESET
#define MAX_BUS
Definition: Can.h:94
#define ANSI_COLOR_GREEN
Definition: PrintHelpers.h:2
#define ANSI_COLOR_BLUE
Definition: PrintHelpers.h:4
char unit[MAX_UNIT_NAME_LENGTH]
Definition: Can.h:29
char reciever[MAX_NODE_NAME_LENGTH]
Definition: Can.h:30
char name[MAX_SIGNAL_NAME_LENGTH]
Definition: Can.h:20
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 112 of file Can.c.

112 {
113 CAN_Message* can_message = malloc(sizeof(CAN_Message) + sizeof(CAN_Signal) * 8);
114 can_message->header = *RxHeader;
115 memcpy(can_message->data, RxData, 8);
116
117 // Parse the message
118 parseMessage(&can_messages[bus], can_message);
119
120 // Print out the contents of the message
121 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);
122
123 // Print the signals
124 for (int i = 0; i < can_message->template->signal_count; i++) {
125 CAN_Signal* signal = &can_message->signals[i];
126 printf("\t" ANSI_COLOR_MAGENTA "Signal" ANSI_COLOR_RESET ": %s (Value: %u, Unit: %s)\r\n", signal->template->name, signal->value, signal->template->unit);
127 }
128 printf("\r\n");
129
130 // Free the message
131 free(can_message);
132}
void parseMessage(CAN_MessageList *messages, CAN_Message *can_message)
Parses a CAN message.
Definition: Can.c:135
#define ANSI_COLOR_YELLOW
Definition: PrintHelpers.h:3
#define ANSI_COLOR_MAGENTA
Definition: PrintHelpers.h: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 79 of file Can.c.

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