diff --git a/board/drivers/can_common.h b/board/drivers/can_common.h index 0dba9afa..af2fcd6f 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 ad59381d..0d3aa168 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 6e783280..32b9bdd1 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 c08f0b14..640685ba 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/stm32h7/llfdcan.h b/board/stm32h7/llfdcan.h index d9b24e8a..d21f415c 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 991f69ea..2df84b97 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("