diff --git a/board/drivers/can_common.h b/board/drivers/can_common.h index 0dba9afa4c..af2fcd6f31 100644 --- a/board/drivers/can_common.h +++ b/board/drivers/can_common.h @@ -12,6 +12,7 @@ typedef struct { uint32_t can_data_speed; bool canfd_enabled; bool brs_enabled; + bool canfd_non_iso; } bus_config_t; uint32_t safety_tx_blocked = 0; @@ -155,10 +156,10 @@ void can_clear(can_ring *q) { // Helpers // Panda: Bus 0=CAN1 Bus 1=CAN2 Bus 2=CAN3 bus_config_t bus_config[] = { - { .bus_lookup = 0U, .can_num_lookup = 0U, .can_speed = 5000U, .can_data_speed = 20000U, .canfd_enabled = false, .brs_enabled = false }, - { .bus_lookup = 1U, .can_num_lookup = 1U, .can_speed = 5000U, .can_data_speed = 20000U, .canfd_enabled = false, .brs_enabled = false }, - { .bus_lookup = 2U, .can_num_lookup = 2U, .can_speed = 5000U, .can_data_speed = 20000U, .canfd_enabled = false, .brs_enabled = false }, - { .bus_lookup = 0xFFU, .can_num_lookup = 0xFFU, .can_speed = 333U, .can_data_speed = 333U, .canfd_enabled = false, .brs_enabled = false }, + { .bus_lookup = 0U, .can_num_lookup = 0U, .can_speed = 5000U, .can_data_speed = 20000U, .canfd_enabled = false, .brs_enabled = false, .canfd_non_iso = false }, + { .bus_lookup = 1U, .can_num_lookup = 1U, .can_speed = 5000U, .can_data_speed = 20000U, .canfd_enabled = false, .brs_enabled = false, .canfd_non_iso = false }, + { .bus_lookup = 2U, .can_num_lookup = 2U, .can_speed = 5000U, .can_data_speed = 20000U, .canfd_enabled = false, .brs_enabled = false, .canfd_non_iso = false }, + { .bus_lookup = 0xFFU, .can_num_lookup = 0xFFU, .can_speed = 333U, .can_data_speed = 333U, .canfd_enabled = false, .brs_enabled = false, .canfd_non_iso = false }, }; #define CANIF_FROM_CAN_NUM(num) (cans[num]) diff --git a/board/drivers/fdcan.h b/board/drivers/fdcan.h index ad59381d52..0d3aa16878 100644 --- a/board/drivers/fdcan.h +++ b/board/drivers/fdcan.h @@ -20,6 +20,7 @@ bool can_set_speed(uint8_t can_number) { CANx, bus_config[bus_number].can_speed, bus_config[bus_number].can_data_speed, + bus_config[bus_number].canfd_non_iso, can_loopback, (unsigned int)(can_silent) & (1U << can_number) ); diff --git a/board/health.h b/board/health.h index 6e78328017..32b9bdd149 100644 --- a/board/health.h +++ b/board/health.h @@ -28,7 +28,7 @@ struct __attribute__((packed)) health_t { uint8_t safety_rx_checks_invalid; }; -#define CAN_HEALTH_PACKET_VERSION 2 +#define CAN_HEALTH_PACKET_VERSION 3 typedef struct __attribute__((packed)) { uint8_t bus_off; uint32_t bus_off_cnt; @@ -50,4 +50,5 @@ typedef struct __attribute__((packed)) { uint16_t can_data_speed; uint8_t canfd_enabled; uint8_t brs_enabled; + uint8_t canfd_non_iso; } can_health_t; diff --git a/board/main_comms.h b/board/main_comms.h index c08f0b144e..640685ba07 100644 --- a/board/main_comms.h +++ b/board/main_comms.h @@ -254,6 +254,7 @@ int comms_control_handler(ControlPacket_t *req, uint8_t *resp) { can_health[req->param1].can_data_speed = (bus_config[req->param1].can_data_speed / 10U); can_health[req->param1].canfd_enabled = bus_config[req->param1].canfd_enabled; can_health[req->param1].brs_enabled = bus_config[req->param1].brs_enabled; + can_health[req->param1].canfd_non_iso = bus_config[req->param1].canfd_non_iso; resp_len = sizeof(can_health[req->param1]); (void)memcpy(resp, &can_health[req->param1], resp_len); } @@ -534,7 +535,7 @@ int comms_control_handler(ControlPacket_t *req, uint8_t *resp) { heartbeat_disabled = true; } break; - // **** 0xde: set CAN FD data bitrate + // **** 0xf9: set CAN FD data bitrate case 0xf9: if ((req->param1 < CAN_CNT) && current_board->has_canfd && @@ -546,18 +547,18 @@ int comms_control_handler(ControlPacket_t *req, uint8_t *resp) { UNUSED(ret); } break; - // **** 0xfa: check if CAN FD and BRS are enabled - case 0xfa: - if (req->param1 < CAN_CNT) { - resp[0] = bus_config[req->param1].canfd_enabled; - resp[1] = bus_config[req->param1].brs_enabled; - resp_len = 2; - } - break; // **** 0xfb: allow highest power saving mode (stop) to be entered case 0xfb: deepsleep_allowed = true; break; + // **** 0xfc: set CAN FD non-ISO mode + case 0xfc: + if ((req->param1 < CAN_CNT) && current_board->has_canfd) { + bus_config[req->param1].canfd_non_iso = (req->param2 != 0U); + bool ret = can_init(CAN_NUM_FROM_BUS_NUM(req->param1)); + UNUSED(ret); + } + break; default: puts("NO HANDLER "); puth(req->request); diff --git a/board/safety/safety_hyundai.h b/board/safety/safety_hyundai.h index d64345ac57..c1ebbe6978 100644 --- a/board/safety/safety_hyundai.h +++ b/board/safety/safety_hyundai.h @@ -84,14 +84,9 @@ AddrCheckStruct hyundai_legacy_addr_checks[] = { }; #define HYUNDAI_LEGACY_ADDR_CHECK_LEN (sizeof(hyundai_legacy_addr_checks) / sizeof(hyundai_legacy_addr_checks[0])) -const int HYUNDAI_PARAM_EV_GAS = 1; -const int HYUNDAI_PARAM_HYBRID_GAS = 2; -const int HYUNDAI_PARAM_LONGITUDINAL = 4; const int HYUNDAI_PARAM_CAMERA_SCC = 8; bool hyundai_legacy = false; -bool hyundai_ev_gas_signal = false; -bool hyundai_hybrid_gas_signal = false; bool hyundai_camera_scc = false; addr_checks hyundai_rx_checks = {hyundai_addr_checks, HYUNDAI_ADDR_CHECK_LEN}; @@ -200,12 +195,12 @@ static int hyundai_rx_hook(CANPacket_t *to_push) { hyundai_common_cruise_buttons_check(cruise_button, main_button); } - // read gas pressed signal + // gas press, different for EV, hybrid, and ICE models if ((addr == 881) && hyundai_ev_gas_signal) { gas_pressed = (((GET_BYTE(to_push, 4) & 0x7FU) << 1) | GET_BYTE(to_push, 3) >> 7) != 0U; } else if ((addr == 881) && hyundai_hybrid_gas_signal) { gas_pressed = GET_BYTE(to_push, 7) != 0U; - } else if (addr == 608) { // ICE + } else if ((addr == 608) && !hyundai_ev_gas_signal && !hyundai_hybrid_gas_signal) { gas_pressed = (GET_BYTE(to_push, 7) >> 6) != 0U; } else { } @@ -331,18 +326,13 @@ static int hyundai_fwd_hook(int bus_num, CANPacket_t *to_fwd) { } static const addr_checks* hyundai_init(uint16_t param) { + hyundai_common_init(param); hyundai_legacy = false; - hyundai_ev_gas_signal = GET_FLAG(param, HYUNDAI_PARAM_EV_GAS); - hyundai_hybrid_gas_signal = !hyundai_ev_gas_signal && GET_FLAG(param, HYUNDAI_PARAM_HYBRID_GAS); hyundai_camera_scc = GET_FLAG(param, HYUNDAI_PARAM_CAMERA_SCC); - hyundai_last_button_interaction = HYUNDAI_PREV_BUTTON_SAMPLES; -#ifdef ALLOW_DEBUG - // TODO: add longitudinal support for camera-based SCC platform - hyundai_longitudinal = GET_FLAG(param, HYUNDAI_PARAM_LONGITUDINAL) && !hyundai_camera_scc; -#else - hyundai_longitudinal = false; -#endif + if (hyundai_camera_scc) { + hyundai_longitudinal = false; + } if (hyundai_longitudinal) { hyundai_rx_checks = (addr_checks){hyundai_long_addr_checks, HYUNDAI_LONG_ADDR_CHECK_LEN}; @@ -355,12 +345,11 @@ static const addr_checks* hyundai_init(uint16_t param) { } static const addr_checks* hyundai_legacy_init(uint16_t param) { + hyundai_common_init(param); hyundai_legacy = true; hyundai_longitudinal = false; hyundai_camera_scc = false; - hyundai_ev_gas_signal = GET_FLAG(param, HYUNDAI_PARAM_EV_GAS); - hyundai_hybrid_gas_signal = !hyundai_ev_gas_signal && GET_FLAG(param, HYUNDAI_PARAM_HYBRID_GAS); - hyundai_last_button_interaction = HYUNDAI_PREV_BUTTON_SAMPLES; + hyundai_rx_checks = (addr_checks){hyundai_legacy_addr_checks, HYUNDAI_LEGACY_ADDR_CHECK_LEN}; return &hyundai_rx_checks; } diff --git a/board/safety/safety_hyundai_canfd.h b/board/safety/safety_hyundai_canfd.h index 4eb0e7dd96..baff625ed5 100644 --- a/board/safety/safety_hyundai_canfd.h +++ b/board/safety/safety_hyundai_canfd.h @@ -49,7 +49,8 @@ const CanMsg HYUNDAI_CANFD_HDA1_TX_MSGS[] = { AddrCheckStruct hyundai_canfd_addr_checks[] = { {.msg = {{0x35, 1, 32, .check_checksum = true, .max_counter = 0xffU, .expected_timestep = 10000U}, - {0x105, 0, 32, .check_checksum = true, .max_counter = 0xffU, .expected_timestep = 10000U}, { 0 }}}, + {0x35, 0, 32, .check_checksum = true, .max_counter = 0xffU, .expected_timestep = 10000U}, + {0x105, 0, 32, .check_checksum = true, .max_counter = 0xffU, .expected_timestep = 10000U}}}, {.msg = {{0x65, 1, 32, .check_checksum = true, .max_counter = 0xffU, .expected_timestep = 10000U}, {0x65, 0, 32, .check_checksum = true, .max_counter = 0xffU, .expected_timestep = 10000U}, { 0 }}}, {.msg = {{0xa0, 1, 24, .check_checksum = true, .max_counter = 0xffU, .expected_timestep = 10000U}, @@ -70,9 +71,8 @@ addr_checks hyundai_canfd_rx_checks = {hyundai_canfd_addr_checks, HYUNDAI_CANFD_ uint16_t hyundai_canfd_crc_lut[256]; -const int HYUNDAI_PARAM_CANFD_HDA2 = 1; -const int HYUNDAI_PARAM_CANFD_ALT_BUTTONS = 2; -const int HYUNDAI_PARAM_CANFD_LONG = 4; +const int HYUNDAI_PARAM_CANFD_HDA2 = 8; +const int HYUNDAI_PARAM_CANFD_ALT_BUTTONS = 16; bool hyundai_canfd_hda2 = false; bool hyundai_canfd_alt_buttons = false; @@ -160,10 +160,10 @@ static int hyundai_canfd_rx_hook(CANPacket_t *to_push) { hyundai_common_cruise_state_check(cruise_engaged); } - // gas press - if ((addr == 0x35) && hyundai_canfd_hda2) { + // gas press, different for EV, hybrid, and ICE models + if ((addr == 0x35) && hyundai_ev_gas_signal) { gas_pressed = GET_BYTE(to_push, 5) != 0U; - } else if ((addr == 0x105) && !hyundai_canfd_hda2) { + } else if ((addr == 0x105) && !hyundai_ev_gas_signal && !hyundai_hybrid_gas_signal) { gas_pressed = (GET_BIT(to_push, 103U) != 0U) || (GET_BYTE(to_push, 13) != 0U) || (GET_BIT(to_push, 112U) != 0U); } else { } @@ -210,7 +210,8 @@ static int hyundai_canfd_tx_hook(CANPacket_t *to_send, bool longitudinal_allowed } // steering - if ((addr == 0x50) || (addr == 0x12a)) { + const int steer_addr = (hyundai_canfd_hda2 && !hyundai_longitudinal) ? 0x50 : 0x12a; + if (addr == steer_addr) { int desired_torque = (((GET_BYTE(to_send, 6) & 0xFU) << 7U) | (GET_BYTE(to_send, 5) >> 1U)) - 1024; bool steer_req = GET_BIT(to_send, 52U) != 0U; @@ -294,16 +295,15 @@ static int hyundai_canfd_fwd_hook(int bus_num, CANPacket_t *to_fwd) { } static const addr_checks* hyundai_canfd_init(uint16_t param) { + hyundai_common_init(param); + gen_crc_lookup_table_16(0x1021, hyundai_canfd_crc_lut); - hyundai_last_button_interaction = HYUNDAI_PREV_BUTTON_SAMPLES; hyundai_canfd_hda2 = GET_FLAG(param, HYUNDAI_PARAM_CANFD_HDA2); hyundai_canfd_alt_buttons = GET_FLAG(param, HYUNDAI_PARAM_CANFD_ALT_BUTTONS); -#ifdef ALLOW_DEBUG - hyundai_longitudinal = GET_FLAG(param, HYUNDAI_PARAM_CANFD_LONG) && hyundai_canfd_hda2; -#else - hyundai_longitudinal = false; -#endif + if (!hyundai_canfd_hda2) { + hyundai_longitudinal = false; + } return &hyundai_canfd_rx_checks; } diff --git a/board/safety/safety_hyundai_common.h b/board/safety/safety_hyundai_common.h index 256c5df8ee..e56f6f465b 100644 --- a/board/safety/safety_hyundai_common.h +++ b/board/safety/safety_hyundai_common.h @@ -1,6 +1,10 @@ #ifndef SAFETY_HYUNDAI_COMMON_H #define SAFETY_HYUNDAI_COMMON_H +const int HYUNDAI_PARAM_EV_GAS = 1; +const int HYUNDAI_PARAM_HYBRID_GAS = 2; +const int HYUNDAI_PARAM_LONGITUDINAL = 4; + const uint8_t HYUNDAI_PREV_BUTTON_SAMPLES = 8; // roughly 160 ms const uint32_t HYUNDAI_STANDSTILL_THRSLD = 30; // ~1kph @@ -12,9 +16,23 @@ enum { }; // common state +bool hyundai_ev_gas_signal = false; +bool hyundai_hybrid_gas_signal = false; bool hyundai_longitudinal = false; uint8_t hyundai_last_button_interaction; // button messages since the user pressed an enable button +void hyundai_common_init(uint16_t param) { + hyundai_ev_gas_signal = GET_FLAG(param, HYUNDAI_PARAM_EV_GAS); + hyundai_hybrid_gas_signal = !hyundai_ev_gas_signal && GET_FLAG(param, HYUNDAI_PARAM_HYBRID_GAS); + + hyundai_last_button_interaction = HYUNDAI_PREV_BUTTON_SAMPLES; + +#ifdef ALLOW_DEBUG + hyundai_longitudinal = GET_FLAG(param, HYUNDAI_PARAM_LONGITUDINAL); +#else + hyundai_longitudinal = false; +#endif +} void hyundai_common_cruise_state_check(const int cruise_engaged) { // some newer HKG models can re-enable after spamming cancel button, diff --git a/board/stm32h7/llfdcan.h b/board/stm32h7/llfdcan.h index d9b24e8a96..d21f415ce0 100644 --- a/board/stm32h7/llfdcan.h +++ b/board/stm32h7/llfdcan.h @@ -84,7 +84,7 @@ bool fdcan_exit_init(FDCAN_GlobalTypeDef *CANx) { return ret; } -bool llcan_set_speed(FDCAN_GlobalTypeDef *CANx, uint32_t speed, uint32_t data_speed, bool loopback, bool silent) { +bool llcan_set_speed(FDCAN_GlobalTypeDef *CANx, uint32_t speed, uint32_t data_speed, bool non_iso, bool loopback, bool silent) { UNUSED(speed); bool ret = fdcan_request_init(CANx); @@ -97,6 +97,7 @@ bool llcan_set_speed(FDCAN_GlobalTypeDef *CANx, uint32_t speed, uint32_t data_sp CANx->TEST &= ~(FDCAN_TEST_LBCK); CANx->CCCR &= ~(FDCAN_CCCR_MON); CANx->CCCR &= ~(FDCAN_CCCR_ASM); + CANx->CCCR &= ~(FDCAN_CCCR_NISO); // TODO: add as a separate safety mode // Enable ASM restricted operation(for debug or automatic bitrate switching) @@ -130,6 +131,11 @@ bool llcan_set_speed(FDCAN_GlobalTypeDef *CANx, uint32_t speed, uint32_t data_sp CANx->DBTP = (((sjw & 0xFU)-1U)<CCCR |= FDCAN_CCCR_NISO; + } + // Silent loopback is known as internal loopback in the docs if (loopback) { CANx->CCCR |= FDCAN_CCCR_TEST; diff --git a/python/__init__.py b/python/__init__.py index 991f69ea01..0024efdbaf 100644 --- a/python/__init__.py +++ b/python/__init__.py @@ -186,9 +186,9 @@ class Panda: CAN_PACKET_VERSION = 2 HEALTH_PACKET_VERSION = 11 - CAN_HEALTH_PACKET_VERSION = 2 + CAN_HEALTH_PACKET_VERSION = 3 HEALTH_STRUCT = struct.Struct("