From 83c000e1a4e795b2d642eb776f2057a236cbf02d Mon Sep 17 00:00:00 2001 From: Igor Biletskyy Date: Mon, 7 Aug 2023 12:24:16 -0700 Subject: [PATCH] panda: disable transceivers while doing CAN multiplexing (#1556) init --- board/boards/black.h | 7 +++++- board/boards/dos.h | 6 +++++- board/boards/red.h | 4 ++++ board/boards/red_chiplet.h | 44 +++++++++++++++++++++++++++++++++++++- board/boards/red_v2.h | 2 +- board/boards/tres.h | 2 +- board/boards/uno.h | 6 +++++- 7 files changed, 65 insertions(+), 6 deletions(-) diff --git a/board/boards/black.h b/board/boards/black.h index d6e6bec8..80b26539 100644 --- a/board/boards/black.h +++ b/board/boards/black.h @@ -53,7 +53,9 @@ void black_set_usb_load_switch(bool enabled) { set_gpio_output(GPIOB, 1, !enabled); } -void black_set_can_mode(uint8_t mode){ +void black_set_can_mode(uint8_t mode) { + black_enable_can_transceiver(2U, false); + black_enable_can_transceiver(4U, false); switch (mode) { case CAN_MODE_NORMAL: case CAN_MODE_OBD_CAN2: @@ -65,6 +67,8 @@ void black_set_can_mode(uint8_t mode){ // B5,B6: normal CAN2 mode set_gpio_alternate(GPIOB, 5, GPIO_AF9_CAN2); set_gpio_alternate(GPIOB, 6, GPIO_AF9_CAN2); + black_enable_can_transceiver(2U, true); + } else { // B5,B6: disable normal CAN2 mode set_gpio_mode(GPIOB, 5, MODE_INPUT); @@ -73,6 +77,7 @@ void black_set_can_mode(uint8_t mode){ // B12,B13: OBD mode set_gpio_alternate(GPIOB, 12, GPIO_AF9_CAN2); set_gpio_alternate(GPIOB, 13, GPIO_AF9_CAN2); + black_enable_can_transceiver(4U, true); } break; default: diff --git a/board/boards/dos.h b/board/boards/dos.h index a5c2e4bc..7e0a2700 100644 --- a/board/boards/dos.h +++ b/board/boards/dos.h @@ -68,7 +68,9 @@ bool dos_board_tick(bool ignition, bool usb_enum, bool heartbeat_seen, bool harn return ret; } -void dos_set_can_mode(uint8_t mode){ +void dos_set_can_mode(uint8_t mode) { + dos_enable_can_transceiver(2U, false); + dos_enable_can_transceiver(4U, false); switch (mode) { case CAN_MODE_NORMAL: case CAN_MODE_OBD_CAN2: @@ -80,6 +82,7 @@ void dos_set_can_mode(uint8_t mode){ // B5,B6: normal CAN2 mode set_gpio_alternate(GPIOB, 5, GPIO_AF9_CAN2); set_gpio_alternate(GPIOB, 6, GPIO_AF9_CAN2); + dos_enable_can_transceiver(2U, true); } else { // B5,B6: disable normal CAN2 mode set_gpio_mode(GPIOB, 5, MODE_INPUT); @@ -88,6 +91,7 @@ void dos_set_can_mode(uint8_t mode){ // B12,B13: OBD mode set_gpio_alternate(GPIOB, 12, GPIO_AF9_CAN2); set_gpio_alternate(GPIOB, 13, GPIO_AF9_CAN2); + dos_enable_can_transceiver(4U, true); } break; default: diff --git a/board/boards/red.h b/board/boards/red.h index 43e71bdf..98755469 100644 --- a/board/boards/red.h +++ b/board/boards/red.h @@ -50,6 +50,8 @@ void red_set_led(uint8_t color, bool enabled) { } void red_set_can_mode(uint8_t mode) { + red_enable_can_transceiver(2U, false); + red_enable_can_transceiver(4U, false); switch (mode) { case CAN_MODE_NORMAL: case CAN_MODE_OBD_CAN2: @@ -67,6 +69,7 @@ void red_set_can_mode(uint8_t mode) { set_gpio_pullup(GPIOB, 6, PULL_NONE); set_gpio_alternate(GPIOB, 6, GPIO_AF9_FDCAN2); + red_enable_can_transceiver(2U, true); } else { // B5,B6: disable normal mode set_gpio_pullup(GPIOB, 5, PULL_NONE); @@ -80,6 +83,7 @@ void red_set_can_mode(uint8_t mode) { set_gpio_pullup(GPIOB, 13, PULL_NONE); set_gpio_alternate(GPIOB, 13, GPIO_AF9_FDCAN2); + red_enable_can_transceiver(4U, true); } break; default: diff --git a/board/boards/red_chiplet.h b/board/boards/red_chiplet.h index 8a3f8dbd..1301cd3e 100644 --- a/board/boards/red_chiplet.h +++ b/board/boards/red_chiplet.h @@ -35,6 +35,48 @@ void red_chiplet_enable_can_transceivers(bool enabled) { } } +void red_chiplet_set_can_mode(uint8_t mode) { + red_chiplet_enable_can_transceiver(2U, false); + red_chiplet_enable_can_transceiver(4U, false); + switch (mode) { + case CAN_MODE_NORMAL: + case CAN_MODE_OBD_CAN2: + if ((bool)(mode == CAN_MODE_NORMAL) != (bool)(harness.status == HARNESS_STATUS_FLIPPED)) { + // B12,B13: disable normal mode + set_gpio_pullup(GPIOB, 12, PULL_NONE); + set_gpio_mode(GPIOB, 12, MODE_ANALOG); + + set_gpio_pullup(GPIOB, 13, PULL_NONE); + set_gpio_mode(GPIOB, 13, MODE_ANALOG); + + // B5,B6: FDCAN2 mode + set_gpio_pullup(GPIOB, 5, PULL_NONE); + set_gpio_alternate(GPIOB, 5, GPIO_AF9_FDCAN2); + + set_gpio_pullup(GPIOB, 6, PULL_NONE); + set_gpio_alternate(GPIOB, 6, GPIO_AF9_FDCAN2); + red_chiplet_enable_can_transceiver(2U, true); + } else { + // B5,B6: disable normal mode + set_gpio_pullup(GPIOB, 5, PULL_NONE); + set_gpio_mode(GPIOB, 5, MODE_ANALOG); + + set_gpio_pullup(GPIOB, 6, PULL_NONE); + set_gpio_mode(GPIOB, 6, MODE_ANALOG); + // B12,B13: FDCAN2 mode + set_gpio_pullup(GPIOB, 12, PULL_NONE); + set_gpio_alternate(GPIOB, 12, GPIO_AF9_FDCAN2); + + set_gpio_pullup(GPIOB, 13, PULL_NONE); + set_gpio_alternate(GPIOB, 13, GPIO_AF9_FDCAN2); + red_chiplet_enable_can_transceiver(4U, true); + } + break; + default: + break; + } +} + void red_chiplet_set_fan_or_usb_load_switch(bool enabled) { set_gpio_output(GPIOD, 3, enabled); } @@ -89,7 +131,7 @@ void red_chiplet_init(void) { red_set_led(LED_BLUE, false); // Set normal CAN mode - red_set_can_mode(CAN_MODE_NORMAL); + red_chiplet_set_can_mode(CAN_MODE_NORMAL); // flip CAN0 and CAN2 if we are flipped if (harness.status == HARNESS_STATUS_FLIPPED) { diff --git a/board/boards/red_v2.h b/board/boards/red_v2.h index 4f0a2cb6..df663032 100644 --- a/board/boards/red_v2.h +++ b/board/boards/red_v2.h @@ -29,7 +29,7 @@ const board board_red_v2 = { .enable_can_transceiver = red_chiplet_enable_can_transceiver, .enable_can_transceivers = red_chiplet_enable_can_transceivers, .set_led = red_set_led, - .set_can_mode = red_set_can_mode, + .set_can_mode = red_chiplet_set_can_mode, .check_ignition = red_check_ignition, .read_current = unused_read_current, .set_fan_enabled = unused_set_fan_enabled, diff --git a/board/boards/tres.h b/board/boards/tres.h index 0b9b94a6..c1f1f9ec 100644 --- a/board/boards/tres.h +++ b/board/boards/tres.h @@ -104,7 +104,7 @@ const board board_tres = { .enable_can_transceiver = red_chiplet_enable_can_transceiver, .enable_can_transceivers = red_chiplet_enable_can_transceivers, .set_led = red_set_led, - .set_can_mode = red_set_can_mode, + .set_can_mode = red_chiplet_set_can_mode, .check_ignition = red_check_ignition, .read_current = unused_read_current, .set_fan_enabled = tres_set_fan_enabled, diff --git a/board/boards/uno.h b/board/boards/uno.h index e0dc0d2c..27c2e402 100644 --- a/board/boards/uno.h +++ b/board/boards/uno.h @@ -69,7 +69,9 @@ void uno_set_phone_power(bool enabled){ set_gpio_output(GPIOB, 4, enabled); } -void uno_set_can_mode(uint8_t mode){ +void uno_set_can_mode(uint8_t mode) { + uno_enable_can_transceiver(2U, false); + uno_enable_can_transceiver(4U, false); switch (mode) { case CAN_MODE_NORMAL: case CAN_MODE_OBD_CAN2: @@ -81,6 +83,7 @@ void uno_set_can_mode(uint8_t mode){ // B5,B6: normal CAN2 mode set_gpio_alternate(GPIOB, 5, GPIO_AF9_CAN2); set_gpio_alternate(GPIOB, 6, GPIO_AF9_CAN2); + uno_enable_can_transceiver(2U, true); } else { // B5,B6: disable normal CAN2 mode set_gpio_mode(GPIOB, 5, MODE_INPUT); @@ -89,6 +92,7 @@ void uno_set_can_mode(uint8_t mode){ // B12,B13: OBD mode set_gpio_alternate(GPIOB, 12, GPIO_AF9_CAN2); set_gpio_alternate(GPIOB, 13, GPIO_AF9_CAN2); + uno_enable_can_transceiver(4U, true); } break; default: