You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
145 lines
2.8 KiB
145 lines
2.8 KiB
#ifndef SELFDRIVE_CAN_COMMON_H
|
|
#define SELFDRIVE_CAN_COMMON_H
|
|
|
|
#include <cstddef>
|
|
#include <cstdint>
|
|
#include <string>
|
|
#include <unordered_map>
|
|
#include <vector>
|
|
|
|
#include <capnp/serialize.h>
|
|
#include "cereal/gen/cpp/log.capnp.h"
|
|
|
|
#define MAX_BAD_COUNTER 5
|
|
#define ARRAYSIZE(x) (sizeof(x)/sizeof(x[0]))
|
|
|
|
// Helper functions
|
|
unsigned int honda_checksum(unsigned int address, uint64_t d, int l);
|
|
unsigned int toyota_checksum(unsigned int address, uint64_t d, int l);
|
|
void init_crc_lookup_tables();
|
|
unsigned int volkswagen_crc(unsigned int address, uint64_t d, int l);
|
|
unsigned int pedal_checksum(uint64_t d, int l);
|
|
uint64_t read_u64_be(const uint8_t* v);
|
|
uint64_t read_u64_le(const uint8_t* v);
|
|
|
|
struct SignalPackValue {
|
|
const char* name;
|
|
double value;
|
|
};
|
|
|
|
struct SignalParseOptions {
|
|
uint32_t address;
|
|
const char* name;
|
|
double default_value;
|
|
};
|
|
|
|
struct MessageParseOptions {
|
|
uint32_t address;
|
|
int check_frequency;
|
|
};
|
|
|
|
struct SignalValue {
|
|
uint32_t address;
|
|
uint16_t ts;
|
|
const char* name;
|
|
double value;
|
|
};
|
|
|
|
|
|
enum SignalType {
|
|
DEFAULT,
|
|
HONDA_CHECKSUM,
|
|
HONDA_COUNTER,
|
|
TOYOTA_CHECKSUM,
|
|
PEDAL_CHECKSUM,
|
|
PEDAL_COUNTER,
|
|
VOLKSWAGEN_CHECKSUM,
|
|
VOLKSWAGEN_COUNTER,
|
|
};
|
|
|
|
struct Signal {
|
|
const char* name;
|
|
int b1, b2, bo;
|
|
bool is_signed;
|
|
double factor, offset;
|
|
bool is_little_endian;
|
|
SignalType type;
|
|
};
|
|
|
|
struct Msg {
|
|
const char* name;
|
|
uint32_t address;
|
|
unsigned int size;
|
|
size_t num_sigs;
|
|
const Signal *sigs;
|
|
};
|
|
|
|
struct Val {
|
|
const char* name;
|
|
uint32_t address;
|
|
const char* def_val;
|
|
const Signal *sigs;
|
|
};
|
|
|
|
struct DBC {
|
|
const char* name;
|
|
size_t num_msgs;
|
|
const Msg *msgs;
|
|
const Val *vals;
|
|
size_t num_vals;
|
|
};
|
|
|
|
|
|
class MessageState {
|
|
public:
|
|
uint32_t address;
|
|
unsigned int size;
|
|
|
|
std::vector<Signal> parse_sigs;
|
|
std::vector<double> vals;
|
|
|
|
uint16_t ts;
|
|
uint64_t seen;
|
|
uint64_t check_threshold;
|
|
|
|
uint8_t counter;
|
|
uint8_t counter_fail;
|
|
|
|
bool parse(uint64_t sec, uint16_t ts_, uint8_t * dat);
|
|
bool update_counter_generic(int64_t v, int cnt_size);
|
|
};
|
|
|
|
class CANParser {
|
|
private:
|
|
const int bus;
|
|
|
|
const DBC *dbc = NULL;
|
|
std::unordered_map<uint32_t, MessageState> message_states;
|
|
|
|
public:
|
|
bool can_valid = false;
|
|
uint64_t last_sec = 0;
|
|
|
|
CANParser(int abus, const std::string& dbc_name,
|
|
const std::vector<MessageParseOptions> &options,
|
|
const std::vector<SignalParseOptions> &sigoptions);
|
|
void UpdateCans(uint64_t sec, const capnp::List<cereal::CanData>::Reader& cans);
|
|
void UpdateValid(uint64_t sec);
|
|
void update_string(std::string data);
|
|
std::vector<SignalValue> query_latest();
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
const DBC* dbc_lookup(const std::string& dbc_name);
|
|
|
|
void dbc_register(const DBC* dbc);
|
|
|
|
#define dbc_init(dbc) \
|
|
static void __attribute__((constructor)) do_dbc_init_ ## dbc(void) { \
|
|
dbc_register(&dbc); \
|
|
}
|
|
|
|
#endif
|
|
|