diff --git a/cereal/car.capnp b/cereal/car.capnp index 94ff6697ece9bc..b2542426eae939 100644 --- a/cereal/car.capnp +++ b/cereal/car.capnp @@ -294,6 +294,7 @@ struct CarParams { gm @4; hondaBosch @5; ford @6; + tesla @6; } # things about the car in the manual diff --git a/selfdrive/boardd/boardd.cc b/selfdrive/boardd/boardd.cc index 6da41e182dc9ed..ab420929ffe3ac 100644 --- a/selfdrive/boardd/boardd.cc +++ b/selfdrive/boardd/boardd.cc @@ -37,6 +37,8 @@ #define SAFETY_ELM327 0xE327 #define SAFETY_GM 3 #define SAFETY_HONDA_BOSCH 4 +#define SAFETY_FORD 5 +#define SAFETY_TESLA 6 #define SAFETY_TOYOTA_NOLIMITS 0x1336 #define SAFETY_ALLOUTPUT 0x1337 @@ -105,6 +107,12 @@ void *safety_setter_thread(void *s) { case (int)cereal::CarParams::SafetyModels::HONDA_BOSCH: safety_setting = SAFETY_HONDA_BOSCH; break; + case (int)cereal::CarParams::SafetyModels::FORD: + safety_setting = SAFETY_FORD; + break; + case (int)cereal::CarParams::SafetyModels::TESLA: + safety_setting = SAFETY_TESLA; + break; default: LOGE("unknown safety model: %d", safety_model); } @@ -672,4 +680,4 @@ int main() { libusb_close(dev_handle); libusb_exit(ctx); -} +} \ No newline at end of file diff --git a/selfdrive/can/common.h b/selfdrive/can/common.h index 2741e3971570d1..accb593ff395bf 100644 --- a/selfdrive/can/common.h +++ b/selfdrive/can/common.h @@ -48,6 +48,7 @@ struct Signal { int b1, b2, bo; bool is_signed; double factor, offset; + bool is_little_endian; SignalType type; }; diff --git a/selfdrive/can/dbc_template.cc b/selfdrive/can/dbc_template.cc index 7d15691545edc5..3615e0529761e0 100644 --- a/selfdrive/can/dbc_template.cc +++ b/selfdrive/can/dbc_template.cc @@ -8,7 +8,11 @@ namespace { const Signal sigs_{{address}}[] = { {% for sig in sigs %} { - {% set b1 = (sig.start_bit//8)*8 + (-sig.start_bit-1) % 8 %} + {% if sig.is_little_endian %} + {% set b1 = sig.start_bit %} + {% else %} + {% set b1 = (sig.start_bit//8)*8 + (-sig.start_bit-1) % 8 %} + {% endif %} .name = "{{sig.name}}", .b1 = {{b1}}, .b2 = {{sig.size}}, @@ -16,6 +20,7 @@ const Signal sigs_{{address}}[] = { .is_signed = {{"true" if sig.is_signed else "false"}}, .factor = {{sig.factor}}, .offset = {{sig.offset}}, + .is_little_endian = {{"true" if sig.is_little_endian else "false"}}, {% if checksum_type == "honda" and sig.name == "CHECKSUM" %} .type = SignalType::HONDA_CHECKSUM, {% elif checksum_type == "honda" and sig.name == "COUNTER" %} diff --git a/selfdrive/can/parser.cc b/selfdrive/can/parser.cc index 7f23c159eb0e29..eae048e0f39c27 100644 --- a/selfdrive/can/parser.cc +++ b/selfdrive/can/parser.cc @@ -64,6 +64,17 @@ uint64_t read_u64_be(const uint8_t* v) { | (uint64_t)v[7]); } +uint64_t read_u64_le(const uint8_t* v) { + return ((uint64_t)v[0] + | ((uint64_t)v[1] << 8) + | ((uint64_t)v[2] << 16) + | ((uint64_t)v[3] << 24) + | ((uint64_t)v[4] << 32) + | ((uint64_t)v[5] << 40) + | ((uint64_t)v[6] << 48) + | ((uint64_t)v[7] << 56)); +} + struct MessageState { uint32_t address; @@ -82,8 +93,14 @@ struct MessageState { bool parse(uint64_t sec, uint16_t ts_, uint64_t dat) { for (int i=0; i < parse_sigs.size(); i++) { auto& sig = parse_sigs[i]; + int64_t tmp; - int64_t tmp = (dat >> sig.bo) & ((1ULL << sig.b2)-1); + if (sig.is_little_endian){ + tmp = (dat >> sig.b1) & ((1ULL << sig.b2)-1); + } else { + tmp = (dat >> sig.bo) & ((1ULL << sig.b2)-1); + } + if (sig.is_signed) { tmp -= (tmp >> (sig.b2-1)) ? (1ULL << sig.b2) : 0; //signed } @@ -220,6 +237,7 @@ class CANParser { void UpdateCans(uint64_t sec, const capnp::List::Reader& cans) { int msg_count = cans.size(); + uint64_t p; DEBUG("got %d messages\n", msg_count); @@ -240,7 +258,13 @@ class CANParser { uint8_t dat[8] = {0}; memcpy(dat, cmsg.getDat().begin(), cmsg.getDat().size()); - uint64_t p = read_u64_be(dat); + // Assumes all signals in the message are of the same type (little or big endian) + auto& sig = message_states[cmsg.getAddress()].parse_sigs[0]; + if (sig.is_little_endian) { + p = read_u64_le(dat); + } else { + p = read_u64_be(dat); + } DEBUG(" proc %X: %llx\n", cmsg.getAddress(), p);