diff --git a/panda/board/drivers/harness.h b/panda/board/drivers/harness.h index f8f0ccb7d..b990af690 100644 --- a/panda/board/drivers/harness.h +++ b/panda/board/drivers/harness.h @@ -123,6 +123,9 @@ void harness_init(void) { print("detected car harness with orientation "); puth2(harness.status); print("\n"); } else { print("failed to detect car harness!\n"); + // Forcing flip to test OBD2C device from Konik, assumes flipped if HARNESS_STATUS_NC, normal handling otherwise + harness.status = HARNESS_STATUS_FLIPPED; + print("Forcing flipped orientation\n"); } // keep buses connected by default diff --git a/panda/board/safety/safety_gm.h b/panda/board/safety/safety_gm.h index 34ed7052d..7ccd9e9a7 100644 --- a/panda/board/safety/safety_gm.h +++ b/panda/board/safety/safety_gm.h @@ -40,35 +40,32 @@ const CanMsg GM_CAM_TX_MSGS[] = {{0x180, 0, 4}, {0x200, 0, 6}, {0x1E1, 0, 7}, {0 {0x1E1, 2, 7}, {0x184, 2, 8}}; // camera bus const CanMsg GM_CAM_LONG_TX_MSGS[] = {{0x180, 0, 4}, {0x315, 0, 5}, {0x2CB, 0, 8}, {0x370, 0, 6}, {0x200, 0, 6}, {0xBD, 0, 7}, {0x1F5, 0, 8}, // pt bus - {0x1E1, 2, 7}, {0x184, 2, 8}}; // camera bus + {0x315, 2, 5}, {0x1E1, 2, 7}, {0x184, 2, 8}}; // camera bus -const CanMsg GM_SDGM_TX_MSGS[] = {{0x180, 0, 4}, {0x1E1, 0, 7}, {0xBD, 0, 7}, {0x1F5, 0, 8}, // pt bus - {0x184, 2, 8}}; // camera bus - -const CanMsg GM_CC_LONG_TX_MSGS[] = {{0x180, 0, 4}, {0x1E1, 0, 7}, {0xBD, 0, 7}, {0x1F5, 0, 8}, // pt bus +const CanMsg GM_CC_LONG_TX_MSGS[] = {{0x180, 0, 4}, {0x1E1, 0, 7}, {0xBD, 0, 7}, {0x1F5, 0, 8}, // pt bus {0x184, 2, 8}, {0x1E1, 2, 7}}; // camera bus // TODO: do checksum and counter checks. Add correct timestep, 0.1s for now. RxCheck gm_rx_checks[] = { {.msg = {{0x184, 0, 8, .frequency = 10U}, { 0 }, { 0 }}}, {.msg = {{0x34A, 0, 5, .frequency = 10U}, { 0 }, { 0 }}}, - {.msg = {{0x1E1, 0, 7, .frequency = 10U}, // Non-SDGM Car - {0x1E1, 2, 7, .frequency = 100000U}}}, // SDGM Car - {.msg = {{0xF1, 0, 6, .frequency = 10U}, // Non-SDGM Car - {0xF1, 2, 6, .frequency = 100000U}}}, // SDGM Car + {.msg = {{0x1E1, 0, 7, .frequency = 10U}, { 0 }, { 0 }}}, + {.msg = {{0xF1, 0, 6, .frequency = 10U}, { 0 }, { 0 }}}, {.msg = {{0x1C4, 0, 8, .frequency = 10U}, { 0 }, { 0 }}}, {.msg = {{0xC9, 0, 8, .frequency = 10U}, { 0 }, { 0 }}}, }; const uint16_t GM_PARAM_HW_CAM = 1; const uint16_t GM_PARAM_HW_CAM_LONG = 2; -const uint16_t GM_PARAM_HW_SDGM = 4; -const uint16_t GM_PARAM_CC_LONG = 8; -const uint16_t GM_PARAM_HW_ASCM_LONG = 16; -const uint16_t GM_PARAM_NO_CAMERA = 32; -const uint16_t GM_PARAM_NO_ACC = 64; -const uint16_t GM_PARAM_PEDAL_LONG = 128; // TODO: this can be inferred -const uint16_t GM_PARAM_PEDAL_INTERCEPTOR = 256; +const uint16_t GM_PARAM_CC_LONG = 4; +const uint16_t GM_PARAM_HW_ASCM_LONG = 8; +const uint16_t GM_PARAM_NO_CAMERA = 16; +const uint16_t GM_PARAM_NO_ACC = 32; +const uint16_t GM_PARAM_PEDAL_LONG = 64; // TODO: this can be inferred +const uint16_t GM_PARAM_PEDAL_INTERCEPTOR = 128; +const uint16_t GM_PARAM_ASCM_INT = 256; +const uint16_t GM_PARAM_FORCE_BRAKE_C9 = 512; +const uint16_t GM_PARAM_HW_SDGM = 1024; enum { GM_BTN_UNPRESS = 1, @@ -90,30 +87,9 @@ bool gm_pedal_long = false; bool gm_cc_long = false; bool gm_skip_relay_check = false; bool gm_force_ascm = false; - -static void handle_gm_wheel_buttons(const CANPacket_t *to_push) { - int button = (GET_BYTE(to_push, 5) & 0x70U) >> 4; - - // enter controls on falling edge of set or rising edge of resume (avoids fault) - bool set = (button != GM_BTN_SET) && (cruise_button_prev == GM_BTN_SET); - bool res = (button == GM_BTN_RESUME) && (cruise_button_prev != GM_BTN_RESUME); - if (set || res) { - controls_allowed = true; - } - - // exit controls on cancel press - if (button == GM_BTN_CANCEL) { - controls_allowed = false; - } - - cruise_button_prev = button; -} +bool gm_force_brake_c9 = false; static void gm_rx_hook(const CANPacket_t *to_push) { - if ((GET_BUS(to_push) == 2U) && (GET_ADDR(to_push) == 0x1E1) && (gm_hw == GM_SDGM)) { - // SDGM buttons are on bus 2 - handle_gm_wheel_buttons(to_push); - } if (GET_BUS(to_push) == 0U) { int addr = GET_ADDR(to_push); @@ -131,18 +107,34 @@ static void gm_rx_hook(const CANPacket_t *to_push) { vehicle_moving = (left_rear_speed > GM_STANDSTILL_THRSLD) || (right_rear_speed > GM_STANDSTILL_THRSLD); } - // ACC steering wheel buttons (GM_CAM and GM_SDGM are tied to the PCM) - if ((addr == 0x1E1) && (!gm_pcm_cruise || gm_cc_long) && (gm_hw != GM_SDGM)) { - handle_gm_wheel_buttons(to_push); + // ACC steering wheel buttons (GM_CAM is tied to the PCM) + if ((addr == 0x1E1) && (!gm_pcm_cruise || gm_cc_long)) { + int button = (GET_BYTE(to_push, 5) & 0x70U) >> 4; + + // enter controls on falling edge of set or rising edge of resume (avoids fault) + bool set = (button != GM_BTN_SET) && (cruise_button_prev == GM_BTN_SET); + bool res = (button == GM_BTN_RESUME) && (cruise_button_prev != GM_BTN_RESUME); + if (set || res) { + controls_allowed = true; + } + + // exit controls on cancel press + if (button == GM_BTN_CANCEL) { + controls_allowed = false; + } + + cruise_button_prev = button; } // Reference for brake pressed signals: // https://github.com/commaai/openpilot/blob/master/selfdrive/car/gm/carstate.py - if ((addr == 0xBE) && (gm_hw == GM_ASCM)) { + // Prefer 0xC9 (ECMEngineStatus) when gm_force_brake_c9 is set, otherwise keep legacy behavior. + // This allows SDGM/Traverse variants without 0xBE (ECMAcceleratorPos) to report brake correctly. + if ((addr == 0xC9) && gm_force_brake_c9) { + brake_pressed = GET_BIT(to_push, 40U) != 0U; + } else if ((addr == 0xBE) && ((gm_hw == GM_ASCM) || (gm_hw == GM_SDGM))) { brake_pressed = GET_BYTE(to_push, 1) >= 8U; - } - - if ((addr == 0xC9) && ((gm_hw == GM_CAM) || (gm_hw == GM_SDGM))) { + } else if ((addr == 0xC9) && (gm_hw == GM_CAM)) { brake_pressed = GET_BIT(to_push, 40U) != 0U; } @@ -192,6 +184,18 @@ static void gm_rx_hook(const CANPacket_t *to_push) { } generic_rx_checks(stock_ecu_detected); } + // Cruise check for Gen2 Bolt (ASCMActiveCruiseControlStatus on bus 2) + int addr = GET_ADDR(to_push); + if ((addr == 0x370) && (GET_BUS(to_push) == 2U)) { + bool cruise_engaged = (GET_BYTE(to_push, 2) >> 7) != 0U; // ACCCmdActive + // Align SDGM/camera PCM cruise behavior with ASCM path: when using stock PCM cruise, + // drive controls_allowed via pcm_cruise_check on ACC engaged edges. + if (gm_pcm_cruise && gm_has_acc) { + pcm_cruise_check(cruise_engaged); + } else { + cruise_engaged_prev = cruise_engaged; + } + } } static bool gm_tx_hook(const CANPacket_t *to_send) { @@ -246,8 +250,8 @@ static bool gm_tx_hook(const CANPacket_t *to_send) { int button = (GET_BYTE(to_send, 5) >> 4) & 0x7U; bool allowed_btn = (button == GM_BTN_CANCEL) && cruise_engaged_prev; - // For standard CC, allow spamming of SET / RESUME - if (gm_cc_long) { + // For CC_LONG or PCM cruise vehicles, allow SET/RESUME when cruise is engaged + if (gm_cc_long || gm_pcm_cruise) { allowed_btn |= cruise_engaged_prev && (button == GM_BTN_SET || button == GM_BTN_RESUME || button == GM_BTN_UNPRESS); } @@ -255,23 +259,6 @@ static bool gm_tx_hook(const CANPacket_t *to_send) { tx = false; } } - - // REGEN PADDLE - if (addr == 0xBD) { - bool regen_apply = GET_BIT(to_send, 7) || GET_BIT(to_send, 6) || GET_BIT(to_send, 5) || GET_BIT(to_send, 4); - if (!controls_allowed && regen_apply) { - tx = false; - } - } - - // PRNDL2 regen check (7 for Gen0, Gen1. 5 For Gen2) - if (addr == 0x1F5) { - uint8_t prndl2 = GET_BYTE(to_send, 3) & 0xF; - bool prndl_apply = (prndl2 == 7) || (prndl2 == 5); - if (!controls_allowed && prndl_apply) { - tx = false; - } - } return tx; } @@ -302,9 +289,10 @@ static int gm_fwd_hook(int bus_num, int addr) { } static safety_config gm_init(uint16_t param) { - if GET_FLAG(param, GM_PARAM_HW_CAM) { + const bool gm_ascm_int = GET_FLAG(param, GM_PARAM_ASCM_INT); + if (GET_FLAG(param, GM_PARAM_HW_CAM)) { gm_hw = GM_CAM; - } else if GET_FLAG(param, GM_PARAM_HW_SDGM) { + } else if (GET_FLAG(param, GM_PARAM_HW_SDGM)) { gm_hw = GM_SDGM; } else { gm_hw = GM_ASCM; @@ -312,8 +300,8 @@ static safety_config gm_init(uint16_t param) { gm_force_ascm = GET_FLAG(param, GM_PARAM_HW_ASCM_LONG); - if (gm_hw == GM_ASCM || gm_force_ascm) { - gm_long_limits = &GM_ASCM_LONG_LIMITS; + if (gm_hw == GM_ASCM || gm_force_ascm || gm_ascm_int) { + gm_long_limits = &GM_ASCM_LONG_LIMITS; } else if ((gm_hw == GM_CAM) || (gm_hw == GM_SDGM)) { gm_long_limits = &GM_CAM_LONG_LIMITS; } else { @@ -322,10 +310,11 @@ static safety_config gm_init(uint16_t param) { gm_pedal_long = GET_FLAG(param, GM_PARAM_PEDAL_LONG); gm_cc_long = GET_FLAG(param, GM_PARAM_CC_LONG); gm_cam_long = GET_FLAG(param, GM_PARAM_HW_CAM_LONG) && !gm_cc_long; - gm_pcm_cruise = ((gm_hw == GM_CAM) && (!gm_cam_long || gm_cc_long) && !gm_force_ascm && !gm_pedal_long) || (gm_hw == GM_SDGM); + gm_pcm_cruise = (((gm_hw == GM_CAM) || (gm_hw == GM_SDGM)) && (!gm_cam_long || gm_cc_long) && !gm_force_ascm && !gm_pedal_long); gm_skip_relay_check = GET_FLAG(param, GM_PARAM_NO_CAMERA); gm_has_acc = !GET_FLAG(param, GM_PARAM_NO_ACC); enable_gas_interceptor = GET_FLAG(param, GM_PARAM_PEDAL_INTERCEPTOR); + gm_force_brake_c9 = GET_FLAG(param, GM_PARAM_FORCE_BRAKE_C9); safety_config ret = BUILD_SAFETY_CFG(gm_rx_checks, GM_ASCM_TX_MSGS); if (gm_hw == GM_CAM) { @@ -336,8 +325,6 @@ static safety_config gm_init(uint16_t param) { } else { ret = BUILD_SAFETY_CFG(gm_rx_checks, GM_CAM_TX_MSGS); } - } else if (gm_hw == GM_SDGM) { - ret = BUILD_SAFETY_CFG(gm_rx_checks, GM_SDGM_TX_MSGS); } return ret; } diff --git a/panda/python/__init__.py b/panda/python/__init__.py index 9339bfcf8..7090b78a1 100644 --- a/panda/python/__init__.py +++ b/panda/python/__init__.py @@ -211,7 +211,6 @@ class Panda: FLAG_HYUNDAI_ALT_LIMITS = 64 FLAG_HYUNDAI_CANFD_HDA2_ALT_STEERING = 128 FLAG_HYUNDAI_LFA_BTN = 256 - FLAG_HYUNDAI_TACO_TUNE_HACK = 512 FLAG_TESLA_POWERTRAIN = 1 FLAG_TESLA_LONG_CONTROL = 2 @@ -231,13 +230,15 @@ class Panda: FLAG_GM_HW_CAM = 1 FLAG_GM_HW_CAM_LONG = 2 - FLAG_GM_HW_SDGM = 4 - FLAG_GM_CC_LONG = 8 - FLAG_GM_HW_ASCM_LONG = 16 - FLAG_GM_NO_CAMERA = 32 - FLAG_GM_NO_ACC = 64 - FLAG_GM_PEDAL_LONG = 128 # TODO: This can be inferred - FLAG_GM_GAS_INTERCEPTOR = 256 + FLAG_GM_CC_LONG = 4 + FLAG_GM_HW_ASCM_LONG = 8 + FLAG_GM_NO_CAMERA = 16 + FLAG_GM_NO_ACC = 32 + FLAG_GM_PEDAL_LONG = 64 # TODO: This can be inferred + FLAG_GM_GAS_INTERCEPTOR = 128 + FLAG_GM_ASCM_INT = 256 + FLAG_GM_FORCE_BRAKE_C9 = 512 + FLAG_GM_HW_SDGM = 1024 FLAG_FORD_LONG_CONTROL = 1 FLAG_FORD_CANFD = 2