diff --git a/board/can_declarations.h b/board/can_declarations.h index 569e2939ac..878d9c77e2 100644 --- a/board/can_declarations.h +++ b/board/can_declarations.h @@ -13,7 +13,7 @@ #endif typedef struct { - unsigned char reserved : 1; + unsigned char fd : 1; unsigned char bus : 3; unsigned char data_len_code : 4; // lookup length with dlc_to_len unsigned char rejected : 1; diff --git a/board/drivers/bxcan.h b/board/drivers/bxcan.h index e4c72c61aa..721a7ee492 100644 --- a/board/drivers/bxcan.h +++ b/board/drivers/bxcan.h @@ -89,6 +89,7 @@ void process_can(uint8_t can_number) { if ((CANx->TSR & CAN_TSR_RQCP0) == CAN_TSR_RQCP0) { if ((CANx->TSR & CAN_TSR_TXOK0) == CAN_TSR_TXOK0) { CANPacket_t to_push; + to_push.fd = 0U; to_push.returned = 1U; to_push.rejected = 0U; to_push.extended = (CANx->sTxMailBox[0].TIR >> 2) & 0x1U; @@ -144,6 +145,7 @@ void can_rx(uint8_t can_number) { // add to my fifo CANPacket_t to_push; + to_push.fd = 0U; to_push.returned = 0U; to_push.rejected = 0U; to_push.extended = (CANx->sFIFOMailBox[0].RIR >> 2) & 0x1U; @@ -159,6 +161,7 @@ void can_rx(uint8_t can_number) { if (bus_fwd_num != -1) { CANPacket_t to_send; + to_send.fd = 0U; to_send.returned = 0U; to_send.rejected = 0U; to_send.extended = to_push.extended; // TXRQ diff --git a/board/drivers/can_common.h b/board/drivers/can_common.h index 5a074e775c..0f24a77c1b 100644 --- a/board/drivers/can_common.h +++ b/board/drivers/can_common.h @@ -131,10 +131,10 @@ void can_clear(can_ring *q) { // Helpers // Panda: Bus 0=CAN1 Bus 1=CAN2 Bus 2=CAN3 bus_config_t bus_config[BUS_CONFIG_ARRAY_SIZE] = { - { .bus_lookup = 0U, .can_num_lookup = 0U, .forwarding_bus = -1, .can_speed = 5000U, .can_data_speed = 20000U, .canfd_enabled = false, .brs_enabled = false, .canfd_non_iso = false }, - { .bus_lookup = 1U, .can_num_lookup = 1U, .forwarding_bus = -1, .can_speed = 5000U, .can_data_speed = 20000U, .canfd_enabled = false, .brs_enabled = false, .canfd_non_iso = false }, - { .bus_lookup = 2U, .can_num_lookup = 2U, .forwarding_bus = -1, .can_speed = 5000U, .can_data_speed = 20000U, .canfd_enabled = false, .brs_enabled = false, .canfd_non_iso = false }, - { .bus_lookup = 0xFFU, .can_num_lookup = 0xFFU, .forwarding_bus = -1, .can_speed = 333U, .can_data_speed = 333U, .canfd_enabled = false, .brs_enabled = false, .canfd_non_iso = false }, + { .bus_lookup = 0U, .can_num_lookup = 0U, .forwarding_bus = -1, .can_speed = 5000U, .can_data_speed = 20000U, .canfd_auto = false, .canfd_enabled = false, .brs_enabled = false, .canfd_non_iso = false }, + { .bus_lookup = 1U, .can_num_lookup = 1U, .forwarding_bus = -1, .can_speed = 5000U, .can_data_speed = 20000U, .canfd_auto = false, .canfd_enabled = false, .brs_enabled = false, .canfd_non_iso = false }, + { .bus_lookup = 2U, .can_num_lookup = 2U, .forwarding_bus = -1, .can_speed = 5000U, .can_data_speed = 20000U, .canfd_auto = false, .canfd_enabled = false, .brs_enabled = false, .canfd_non_iso = false }, + { .bus_lookup = 0xFFU, .can_num_lookup = 0xFFU, .forwarding_bus = -1, .can_speed = 333U, .can_data_speed = 333U, .canfd_auto = false, .canfd_enabled = false, .brs_enabled = false, .canfd_non_iso = false }, }; void can_init_all(void) { @@ -165,7 +165,7 @@ void ignition_can_hook(CANPacket_t *to_push) { if (bus == 0) { int addr = GET_ADDR(to_push); int len = GET_LEN(to_push); - + // GM exception if ((addr == 0x1F1) && (len == 8)) { // SystemPowerMode (2=Run, 3=Crank Request) diff --git a/board/drivers/can_common_declarations.h b/board/drivers/can_common_declarations.h index 1a3518c2a8..57bf87d9c7 100644 --- a/board/drivers/can_common_declarations.h +++ b/board/drivers/can_common_declarations.h @@ -13,6 +13,7 @@ typedef struct { int8_t forwarding_bus; uint32_t can_speed; uint32_t can_data_speed; + bool canfd_auto; bool canfd_enabled; bool brs_enabled; bool canfd_non_iso; diff --git a/board/drivers/fdcan.h b/board/drivers/fdcan.h index 0144aa17c2..eaf50caaab 100644 --- a/board/drivers/fdcan.h +++ b/board/drivers/fdcan.h @@ -100,7 +100,11 @@ void process_can(uint8_t can_number) { fifo = (canfd_fifo *)(TxFIFOSA + (tx_index * FDCAN_TX_FIFO_EL_SIZE)); fifo->header[0] = (to_send.extended << 30) | ((to_send.extended != 0U) ? (to_send.addr) : (to_send.addr << 18)); - uint32_t canfd_enabled_header = bus_config[can_number].canfd_enabled ? (1UL << 21) : 0UL; + + // If canfd_auto is set, outgoing packets will be automatically sent as CAN-FD if an incoming CAN-FD packet was seen + bool fd = bus_config[can_number].canfd_auto ? bus_config[can_number].canfd_enabled : (bool)(to_send.fd > 0U); + uint32_t canfd_enabled_header = fd ? (1UL << 21) : 0UL; + uint32_t brs_enabled_header = bus_config[can_number].brs_enabled ? (1UL << 20) : 0UL; fifo->header[1] = (to_send.data_len_code << 16) | canfd_enabled_header | brs_enabled_header; @@ -115,6 +119,7 @@ void process_can(uint8_t can_number) { // Send back to USB CANPacket_t to_push; + to_push.fd = fd; to_push.returned = 1U; to_push.rejected = 0U; to_push.extended = to_send.extended; @@ -168,6 +173,10 @@ void can_rx(uint8_t can_number) { // getting address fifo = (canfd_fifo *)(RxFIFO0SA + (rx_fifo_idx * FDCAN_RX_FIFO_0_EL_SIZE)); + bool canfd_frame = ((fifo->header[1] >> 21) & 0x1U); + bool brs_frame = ((fifo->header[1] >> 20) & 0x1U); + + to_push.fd = canfd_frame; to_push.returned = 0U; to_push.rejected = 0U; to_push.extended = (fifo->header[0] >> 30) & 0x1U; @@ -175,9 +184,6 @@ void can_rx(uint8_t can_number) { to_push.bus = bus_number; to_push.data_len_code = ((fifo->header[1] >> 16) & 0xFU); - bool canfd_frame = ((fifo->header[1] >> 21) & 0x1U); - bool brs_frame = ((fifo->header[1] >> 20) & 0x1U); - uint8_t data_len_w = (dlc_to_len[to_push.data_len_code] / 4U); data_len_w += ((dlc_to_len[to_push.data_len_code] % 4U) > 0U) ? 1U : 0U; for (unsigned int i = 0; i < data_len_w; i++) { @@ -193,6 +199,7 @@ void can_rx(uint8_t can_number) { if (bus_fwd_num != -1) { CANPacket_t to_send; + to_send.fd = to_push.fd; to_send.returned = 0U; to_send.rejected = 0U; to_send.extended = to_push.extended; diff --git a/board/main_comms.h b/board/main_comms.h index 7d754d050f..6cc2e429c3 100644 --- a/board/main_comms.h +++ b/board/main_comms.h @@ -317,6 +317,10 @@ int comms_control_handler(ControlPacket_t *req, uint8_t *resp) { case 0xe7: set_power_save_state(req->param1); break; + // **** 0xe8: set can-fd auto swithing mode + case 0xe8: + bus_config[req->param1].canfd_auto = req->param2 > 0U; + break; // **** 0xf1: Clear CAN ring buffer. case 0xf1: if (req->param1 == 0xFFFFU) { diff --git a/python/__init__.py b/python/__init__.py index 14d324ab93..d6d3ebc594 100644 --- a/python/__init__.py +++ b/python/__init__.py @@ -31,7 +31,7 @@ def calculate_checksum(data): res ^= b return res -def pack_can_buffer(arr): +def pack_can_buffer(arr, fd=False): snds = [b''] for address, dat, bus in arr: assert len(dat) in LEN_TO_DLC @@ -41,7 +41,7 @@ def pack_can_buffer(arr): data_len_code = LEN_TO_DLC[len(dat)] header = bytearray(CANPACKET_HEAD_SIZE) word_4b = address << 3 | extended << 2 - header[0] = (data_len_code << 4) | (bus << 1) + header[0] = (data_len_code << 4) | (bus << 1) | int(fd) header[1] = word_4b & 0xFF header[2] = (word_4b >> 8) & 0xFF header[3] = (word_4b >> 16) & 0xFF @@ -807,6 +807,9 @@ def set_can_data_speed_kbps(self, bus, speed): def set_canfd_non_iso(self, bus, non_iso): self._handle.controlWrite(Panda.REQUEST_OUT, 0xfc, bus, int(non_iso), b'') + def set_canfd_auto(self, bus, auto): + self._handle.controlWrite(Panda.REQUEST_OUT, 0xe8, bus, int(auto), b'') + def set_uart_baud(self, uart, rate): self._handle.controlWrite(Panda.REQUEST_OUT, 0xe4, uart, int(rate / 300), b'') @@ -828,15 +831,15 @@ def can_reset_communications(self): self._handle.controlWrite(Panda.REQUEST_OUT, 0xc0, 0, 0, b'') @ensure_can_packet_version - def can_send_many(self, arr, timeout=CAN_SEND_TIMEOUT_MS): - snds = pack_can_buffer(arr) + def can_send_many(self, arr, *, fd=False, timeout=CAN_SEND_TIMEOUT_MS): + snds = pack_can_buffer(arr, fd=fd) for tx in snds: while len(tx) > 0: bs = self._handle.bulkWrite(3, tx, timeout=timeout) tx = tx[bs:] - def can_send(self, addr, dat, bus, timeout=CAN_SEND_TIMEOUT_MS): - self.can_send_many([[addr, dat, bus]], timeout=timeout) + def can_send(self, addr, dat, bus, *, fd=False, timeout=CAN_SEND_TIMEOUT_MS): + self.can_send_many([[addr, dat, bus]], fd=fd, timeout=timeout) @ensure_can_packet_version def can_recv(self): diff --git a/tests/libpanda/libpanda_py.py b/tests/libpanda/libpanda_py.py index 6f888ac60e..d24640b9dc 100644 --- a/tests/libpanda/libpanda_py.py +++ b/tests/libpanda/libpanda_py.py @@ -12,7 +12,7 @@ ffi.cdef(""" typedef struct { - unsigned char reserved : 1; + unsigned char fd : 1; unsigned char bus : 3; unsigned char data_len_code : 4; unsigned char rejected : 1;