panda/python/__init__.py

938 lines
30 KiB
Python
Raw Normal View History

2017-04-07 09:11:36 +08:00
# python library to interface with panda
2017-07-18 06:29:31 +08:00
import os
import sys
2017-07-18 06:29:31 +08:00
import time
import usb1
import struct
import hashlib
import binascii
import datetime
import warnings
import logging
from functools import wraps
2022-05-12 20:22:58 +08:00
from typing import Optional
from itertools import accumulate
from .base import BaseHandle
from .constants import McuType
from .dfu import PandaDFU
2022-11-22 08:59:21 +08:00
from .isotp import isotp_send, isotp_recv
from .spi import PandaSpiHandle, PandaSpiException
from .usb import PandaUsbHandle
2017-04-07 09:11:36 +08:00
CAN_FIFOMailBox to CANPacket struct + USB dynamic packet size (#739) * Squashed commits, no cleanup * Few fixes * No init = garbage * Only receive with new canpacket * Add send with canpacket * Revert "Add send with canpacket" This reverts commit 7d06686ddd6d447c714b5289d31af24403d36931. * Packet must be aligned to word, or bad performance * Cleaner * Fix tests * Tests... * MISRA 10.4 * More MISRA * libpandasafety_py * cffi * even more tests... * typo * ... * ... * ... * Slight cleanup * MISRA 6.1 * MISRA 17.7 * Bug in bxcan + even style * MISRA 10.1 * Revert "MISRA 10.1" This reverts commit 404ae7fcc39556f80f528de9015702e69f4ea0a5. * ... * MISRA 10.1 and 10.4 suppress until next PR * MISRA 20.1 * ... * test_honda * ... * ... * test_toyota * test_volkswagen_mqb * test_volkswagen_pq * Sketchy thing... * Revert "Sketchy thing..." This reverts commit 3b2e5715bdc1954f7b7b3b7469ba3d0eaa06bdf9. * remove comment * bxcan extended address bug * Concept, experimental dynamic usb packet size * increase each buffer to 10240 bytes * raise python bulk read/write limits * ... * Move packet size to start * Experimental send, stream-like * New receive test, stream-like * cleanup * cleanup + rebase fixes * MISRA * Extra receive method, stream-like, commented out * type change * Revert back to buffer for send, stream commented * forgot ZLP * lower buffer, add rx failsafe * ... remove ZLP * return ZLP back * Add tx checks to panda fw * TX stream with counter * fix counter overflow * 13 free slots should be enough * limit tx usb packet * ... * Revert max_bulk_msg doubling * python lib improve speed * Stream with counter for RX, dirty, needs cleanup * Increase chunk length to 4096 bytes * cleanup fdcan.h * cleanup __init__.py * MISRA 12.1 * MISRA 10.8 * remove non-streaming usb functions * more main.c cleanup * MISRA 15.6 * MISRA 15.5 * MISRA 18.4 and suppress objectIndex * handling usb pakcets > 63bytes, naming and cleanup * Cleanup old from tests and update CANPacket_t struct * Switch to 4 bit DLC instead of 6 bit length * ops) * ... * pylint * receive python buffer increase * USB increase receive packet len * tweak buffers * No need for so high limits * MISRA 20.1 workaround * performance tweaks * cleanup, dlc to data_len_code naming * main.c naming * comments and cleanup for main.c usb * clean py lib * pylint * do not discard good rx messages on stream fail * cleanups * naming * remove bitstruct lib and lower tx limit * bitstruct lefovers * fix bug in VW test * remove adjusting data size and assert on wrong len * ... * test new memcpy before merging * Revert "test new memcpy before merging" This reverts commit 399465a264835061adabdd785718c4b6fc18c267. * macros for to/fromuint8_t array * MISRA hates me! * tests.c include macros instead * move CANPacket to can_definitions.h * vw_pq python test fix * new memcpy test, REMOVE * check without alignment * revert macros for uint8 arrays * Revert "revert macros for uint8 arrays" This reverts commit 581a9db735a42d0d68200bd270d87a8fd34e43fe. * check assert * Revert "check assert" This reverts commit 9e970d029a50597a1718b2bb0260196c050fd77f. * one more variation * Revert "one more variation" This reverts commit f6c0528b7ac7e125750dc0d9445c7ce97f6954b5. * what about read performance * Revert "what about read performance" This reverts commit d2610f90958a816fe7f1822157a84f85e97d9249. * check struct alignment to word * check for aligned memcpy again * cleanup * add CANPacket structure diagram * update CANPacket and add USB packet struct * bugfix + refactoring of EP1 * move dlc_to_len to header * missed include * typo... * MISRA * fk * lower MAX_CAN_MSGS_PER_BULK_TRANSFER * bump CAN_PACKET_VERSION to 2 * bump python lib CAN_PACKET_VERSION to 2 * rename parse_can_buffer to unpack_can_buffer * CANPacket_t const fields * Revert "CANPacket_t const fields" This reverts commit cf91c035b7706a14e317550c5f0501ae3fce7c70. * test.c relative path * cleanup * move macros to safety_declarations * Refactor pack/unpack funcs and add unittest * usb_protocol.h * oops * Update .github/workflows/test.yaml Co-authored-by: Adeeb Shihadeh <adeebshihadeh@gmail.com> * remove print from unittest Co-authored-by: Adeeb Shihadeh <adeebshihadeh@gmail.com>
2021-11-13 08:36:34 +08:00
__version__ = '0.0.10'
# setup logging
LOGLEVEL = os.environ.get('LOGLEVEL', 'INFO').upper()
logging.basicConfig(level=LOGLEVEL, format='%(message)s')
USBPACKET_MAX_SIZE = 0x40
CANPACKET_HEAD_SIZE = 0x6
CAN_FIFOMailBox to CANPacket struct + USB dynamic packet size (#739) * Squashed commits, no cleanup * Few fixes * No init = garbage * Only receive with new canpacket * Add send with canpacket * Revert "Add send with canpacket" This reverts commit 7d06686ddd6d447c714b5289d31af24403d36931. * Packet must be aligned to word, or bad performance * Cleaner * Fix tests * Tests... * MISRA 10.4 * More MISRA * libpandasafety_py * cffi * even more tests... * typo * ... * ... * ... * Slight cleanup * MISRA 6.1 * MISRA 17.7 * Bug in bxcan + even style * MISRA 10.1 * Revert "MISRA 10.1" This reverts commit 404ae7fcc39556f80f528de9015702e69f4ea0a5. * ... * MISRA 10.1 and 10.4 suppress until next PR * MISRA 20.1 * ... * test_honda * ... * ... * test_toyota * test_volkswagen_mqb * test_volkswagen_pq * Sketchy thing... * Revert "Sketchy thing..." This reverts commit 3b2e5715bdc1954f7b7b3b7469ba3d0eaa06bdf9. * remove comment * bxcan extended address bug * Concept, experimental dynamic usb packet size * increase each buffer to 10240 bytes * raise python bulk read/write limits * ... * Move packet size to start * Experimental send, stream-like * New receive test, stream-like * cleanup * cleanup + rebase fixes * MISRA * Extra receive method, stream-like, commented out * type change * Revert back to buffer for send, stream commented * forgot ZLP * lower buffer, add rx failsafe * ... remove ZLP * return ZLP back * Add tx checks to panda fw * TX stream with counter * fix counter overflow * 13 free slots should be enough * limit tx usb packet * ... * Revert max_bulk_msg doubling * python lib improve speed * Stream with counter for RX, dirty, needs cleanup * Increase chunk length to 4096 bytes * cleanup fdcan.h * cleanup __init__.py * MISRA 12.1 * MISRA 10.8 * remove non-streaming usb functions * more main.c cleanup * MISRA 15.6 * MISRA 15.5 * MISRA 18.4 and suppress objectIndex * handling usb pakcets > 63bytes, naming and cleanup * Cleanup old from tests and update CANPacket_t struct * Switch to 4 bit DLC instead of 6 bit length * ops) * ... * pylint * receive python buffer increase * USB increase receive packet len * tweak buffers * No need for so high limits * MISRA 20.1 workaround * performance tweaks * cleanup, dlc to data_len_code naming * main.c naming * comments and cleanup for main.c usb * clean py lib * pylint * do not discard good rx messages on stream fail * cleanups * naming * remove bitstruct lib and lower tx limit * bitstruct lefovers * fix bug in VW test * remove adjusting data size and assert on wrong len * ... * test new memcpy before merging * Revert "test new memcpy before merging" This reverts commit 399465a264835061adabdd785718c4b6fc18c267. * macros for to/fromuint8_t array * MISRA hates me! * tests.c include macros instead * move CANPacket to can_definitions.h * vw_pq python test fix * new memcpy test, REMOVE * check without alignment * revert macros for uint8 arrays * Revert "revert macros for uint8 arrays" This reverts commit 581a9db735a42d0d68200bd270d87a8fd34e43fe. * check assert * Revert "check assert" This reverts commit 9e970d029a50597a1718b2bb0260196c050fd77f. * one more variation * Revert "one more variation" This reverts commit f6c0528b7ac7e125750dc0d9445c7ce97f6954b5. * what about read performance * Revert "what about read performance" This reverts commit d2610f90958a816fe7f1822157a84f85e97d9249. * check struct alignment to word * check for aligned memcpy again * cleanup * add CANPacket structure diagram * update CANPacket and add USB packet struct * bugfix + refactoring of EP1 * move dlc_to_len to header * missed include * typo... * MISRA * fk * lower MAX_CAN_MSGS_PER_BULK_TRANSFER * bump CAN_PACKET_VERSION to 2 * bump python lib CAN_PACKET_VERSION to 2 * rename parse_can_buffer to unpack_can_buffer * CANPacket_t const fields * Revert "CANPacket_t const fields" This reverts commit cf91c035b7706a14e317550c5f0501ae3fce7c70. * test.c relative path * cleanup * move macros to safety_declarations * Refactor pack/unpack funcs and add unittest * usb_protocol.h * oops * Update .github/workflows/test.yaml Co-authored-by: Adeeb Shihadeh <adeebshihadeh@gmail.com> * remove print from unittest Co-authored-by: Adeeb Shihadeh <adeebshihadeh@gmail.com>
2021-11-13 08:36:34 +08:00
DLC_TO_LEN = [0, 1, 2, 3, 4, 5, 6, 7, 8, 12, 16, 20, 24, 32, 48, 64]
LEN_TO_DLC = {length: dlc for (dlc, length) in enumerate(DLC_TO_LEN)}
def calculate_checksum(data):
res = 0
for b in data:
res ^= b
return res
CAN_FIFOMailBox to CANPacket struct + USB dynamic packet size (#739) * Squashed commits, no cleanup * Few fixes * No init = garbage * Only receive with new canpacket * Add send with canpacket * Revert "Add send with canpacket" This reverts commit 7d06686ddd6d447c714b5289d31af24403d36931. * Packet must be aligned to word, or bad performance * Cleaner * Fix tests * Tests... * MISRA 10.4 * More MISRA * libpandasafety_py * cffi * even more tests... * typo * ... * ... * ... * Slight cleanup * MISRA 6.1 * MISRA 17.7 * Bug in bxcan + even style * MISRA 10.1 * Revert "MISRA 10.1" This reverts commit 404ae7fcc39556f80f528de9015702e69f4ea0a5. * ... * MISRA 10.1 and 10.4 suppress until next PR * MISRA 20.1 * ... * test_honda * ... * ... * test_toyota * test_volkswagen_mqb * test_volkswagen_pq * Sketchy thing... * Revert "Sketchy thing..." This reverts commit 3b2e5715bdc1954f7b7b3b7469ba3d0eaa06bdf9. * remove comment * bxcan extended address bug * Concept, experimental dynamic usb packet size * increase each buffer to 10240 bytes * raise python bulk read/write limits * ... * Move packet size to start * Experimental send, stream-like * New receive test, stream-like * cleanup * cleanup + rebase fixes * MISRA * Extra receive method, stream-like, commented out * type change * Revert back to buffer for send, stream commented * forgot ZLP * lower buffer, add rx failsafe * ... remove ZLP * return ZLP back * Add tx checks to panda fw * TX stream with counter * fix counter overflow * 13 free slots should be enough * limit tx usb packet * ... * Revert max_bulk_msg doubling * python lib improve speed * Stream with counter for RX, dirty, needs cleanup * Increase chunk length to 4096 bytes * cleanup fdcan.h * cleanup __init__.py * MISRA 12.1 * MISRA 10.8 * remove non-streaming usb functions * more main.c cleanup * MISRA 15.6 * MISRA 15.5 * MISRA 18.4 and suppress objectIndex * handling usb pakcets > 63bytes, naming and cleanup * Cleanup old from tests and update CANPacket_t struct * Switch to 4 bit DLC instead of 6 bit length * ops) * ... * pylint * receive python buffer increase * USB increase receive packet len * tweak buffers * No need for so high limits * MISRA 20.1 workaround * performance tweaks * cleanup, dlc to data_len_code naming * main.c naming * comments and cleanup for main.c usb * clean py lib * pylint * do not discard good rx messages on stream fail * cleanups * naming * remove bitstruct lib and lower tx limit * bitstruct lefovers * fix bug in VW test * remove adjusting data size and assert on wrong len * ... * test new memcpy before merging * Revert "test new memcpy before merging" This reverts commit 399465a264835061adabdd785718c4b6fc18c267. * macros for to/fromuint8_t array * MISRA hates me! * tests.c include macros instead * move CANPacket to can_definitions.h * vw_pq python test fix * new memcpy test, REMOVE * check without alignment * revert macros for uint8 arrays * Revert "revert macros for uint8 arrays" This reverts commit 581a9db735a42d0d68200bd270d87a8fd34e43fe. * check assert * Revert "check assert" This reverts commit 9e970d029a50597a1718b2bb0260196c050fd77f. * one more variation * Revert "one more variation" This reverts commit f6c0528b7ac7e125750dc0d9445c7ce97f6954b5. * what about read performance * Revert "what about read performance" This reverts commit d2610f90958a816fe7f1822157a84f85e97d9249. * check struct alignment to word * check for aligned memcpy again * cleanup * add CANPacket structure diagram * update CANPacket and add USB packet struct * bugfix + refactoring of EP1 * move dlc_to_len to header * missed include * typo... * MISRA * fk * lower MAX_CAN_MSGS_PER_BULK_TRANSFER * bump CAN_PACKET_VERSION to 2 * bump python lib CAN_PACKET_VERSION to 2 * rename parse_can_buffer to unpack_can_buffer * CANPacket_t const fields * Revert "CANPacket_t const fields" This reverts commit cf91c035b7706a14e317550c5f0501ae3fce7c70. * test.c relative path * cleanup * move macros to safety_declarations * Refactor pack/unpack funcs and add unittest * usb_protocol.h * oops * Update .github/workflows/test.yaml Co-authored-by: Adeeb Shihadeh <adeebshihadeh@gmail.com> * remove print from unittest Co-authored-by: Adeeb Shihadeh <adeebshihadeh@gmail.com>
2021-11-13 08:36:34 +08:00
def pack_can_buffer(arr):
snds = [b'']
CAN_FIFOMailBox to CANPacket struct + USB dynamic packet size (#739) * Squashed commits, no cleanup * Few fixes * No init = garbage * Only receive with new canpacket * Add send with canpacket * Revert "Add send with canpacket" This reverts commit 7d06686ddd6d447c714b5289d31af24403d36931. * Packet must be aligned to word, or bad performance * Cleaner * Fix tests * Tests... * MISRA 10.4 * More MISRA * libpandasafety_py * cffi * even more tests... * typo * ... * ... * ... * Slight cleanup * MISRA 6.1 * MISRA 17.7 * Bug in bxcan + even style * MISRA 10.1 * Revert "MISRA 10.1" This reverts commit 404ae7fcc39556f80f528de9015702e69f4ea0a5. * ... * MISRA 10.1 and 10.4 suppress until next PR * MISRA 20.1 * ... * test_honda * ... * ... * test_toyota * test_volkswagen_mqb * test_volkswagen_pq * Sketchy thing... * Revert "Sketchy thing..." This reverts commit 3b2e5715bdc1954f7b7b3b7469ba3d0eaa06bdf9. * remove comment * bxcan extended address bug * Concept, experimental dynamic usb packet size * increase each buffer to 10240 bytes * raise python bulk read/write limits * ... * Move packet size to start * Experimental send, stream-like * New receive test, stream-like * cleanup * cleanup + rebase fixes * MISRA * Extra receive method, stream-like, commented out * type change * Revert back to buffer for send, stream commented * forgot ZLP * lower buffer, add rx failsafe * ... remove ZLP * return ZLP back * Add tx checks to panda fw * TX stream with counter * fix counter overflow * 13 free slots should be enough * limit tx usb packet * ... * Revert max_bulk_msg doubling * python lib improve speed * Stream with counter for RX, dirty, needs cleanup * Increase chunk length to 4096 bytes * cleanup fdcan.h * cleanup __init__.py * MISRA 12.1 * MISRA 10.8 * remove non-streaming usb functions * more main.c cleanup * MISRA 15.6 * MISRA 15.5 * MISRA 18.4 and suppress objectIndex * handling usb pakcets > 63bytes, naming and cleanup * Cleanup old from tests and update CANPacket_t struct * Switch to 4 bit DLC instead of 6 bit length * ops) * ... * pylint * receive python buffer increase * USB increase receive packet len * tweak buffers * No need for so high limits * MISRA 20.1 workaround * performance tweaks * cleanup, dlc to data_len_code naming * main.c naming * comments and cleanup for main.c usb * clean py lib * pylint * do not discard good rx messages on stream fail * cleanups * naming * remove bitstruct lib and lower tx limit * bitstruct lefovers * fix bug in VW test * remove adjusting data size and assert on wrong len * ... * test new memcpy before merging * Revert "test new memcpy before merging" This reverts commit 399465a264835061adabdd785718c4b6fc18c267. * macros for to/fromuint8_t array * MISRA hates me! * tests.c include macros instead * move CANPacket to can_definitions.h * vw_pq python test fix * new memcpy test, REMOVE * check without alignment * revert macros for uint8 arrays * Revert "revert macros for uint8 arrays" This reverts commit 581a9db735a42d0d68200bd270d87a8fd34e43fe. * check assert * Revert "check assert" This reverts commit 9e970d029a50597a1718b2bb0260196c050fd77f. * one more variation * Revert "one more variation" This reverts commit f6c0528b7ac7e125750dc0d9445c7ce97f6954b5. * what about read performance * Revert "what about read performance" This reverts commit d2610f90958a816fe7f1822157a84f85e97d9249. * check struct alignment to word * check for aligned memcpy again * cleanup * add CANPacket structure diagram * update CANPacket and add USB packet struct * bugfix + refactoring of EP1 * move dlc_to_len to header * missed include * typo... * MISRA * fk * lower MAX_CAN_MSGS_PER_BULK_TRANSFER * bump CAN_PACKET_VERSION to 2 * bump python lib CAN_PACKET_VERSION to 2 * rename parse_can_buffer to unpack_can_buffer * CANPacket_t const fields * Revert "CANPacket_t const fields" This reverts commit cf91c035b7706a14e317550c5f0501ae3fce7c70. * test.c relative path * cleanup * move macros to safety_declarations * Refactor pack/unpack funcs and add unittest * usb_protocol.h * oops * Update .github/workflows/test.yaml Co-authored-by: Adeeb Shihadeh <adeebshihadeh@gmail.com> * remove print from unittest Co-authored-by: Adeeb Shihadeh <adeebshihadeh@gmail.com>
2021-11-13 08:36:34 +08:00
for address, _, dat, bus in arr:
assert len(dat) in LEN_TO_DLC
#logging.debug(" W 0x%x: 0x%s", address, dat.hex())
CAN_FIFOMailBox to CANPacket struct + USB dynamic packet size (#739) * Squashed commits, no cleanup * Few fixes * No init = garbage * Only receive with new canpacket * Add send with canpacket * Revert "Add send with canpacket" This reverts commit 7d06686ddd6d447c714b5289d31af24403d36931. * Packet must be aligned to word, or bad performance * Cleaner * Fix tests * Tests... * MISRA 10.4 * More MISRA * libpandasafety_py * cffi * even more tests... * typo * ... * ... * ... * Slight cleanup * MISRA 6.1 * MISRA 17.7 * Bug in bxcan + even style * MISRA 10.1 * Revert "MISRA 10.1" This reverts commit 404ae7fcc39556f80f528de9015702e69f4ea0a5. * ... * MISRA 10.1 and 10.4 suppress until next PR * MISRA 20.1 * ... * test_honda * ... * ... * test_toyota * test_volkswagen_mqb * test_volkswagen_pq * Sketchy thing... * Revert "Sketchy thing..." This reverts commit 3b2e5715bdc1954f7b7b3b7469ba3d0eaa06bdf9. * remove comment * bxcan extended address bug * Concept, experimental dynamic usb packet size * increase each buffer to 10240 bytes * raise python bulk read/write limits * ... * Move packet size to start * Experimental send, stream-like * New receive test, stream-like * cleanup * cleanup + rebase fixes * MISRA * Extra receive method, stream-like, commented out * type change * Revert back to buffer for send, stream commented * forgot ZLP * lower buffer, add rx failsafe * ... remove ZLP * return ZLP back * Add tx checks to panda fw * TX stream with counter * fix counter overflow * 13 free slots should be enough * limit tx usb packet * ... * Revert max_bulk_msg doubling * python lib improve speed * Stream with counter for RX, dirty, needs cleanup * Increase chunk length to 4096 bytes * cleanup fdcan.h * cleanup __init__.py * MISRA 12.1 * MISRA 10.8 * remove non-streaming usb functions * more main.c cleanup * MISRA 15.6 * MISRA 15.5 * MISRA 18.4 and suppress objectIndex * handling usb pakcets > 63bytes, naming and cleanup * Cleanup old from tests and update CANPacket_t struct * Switch to 4 bit DLC instead of 6 bit length * ops) * ... * pylint * receive python buffer increase * USB increase receive packet len * tweak buffers * No need for so high limits * MISRA 20.1 workaround * performance tweaks * cleanup, dlc to data_len_code naming * main.c naming * comments and cleanup for main.c usb * clean py lib * pylint * do not discard good rx messages on stream fail * cleanups * naming * remove bitstruct lib and lower tx limit * bitstruct lefovers * fix bug in VW test * remove adjusting data size and assert on wrong len * ... * test new memcpy before merging * Revert "test new memcpy before merging" This reverts commit 399465a264835061adabdd785718c4b6fc18c267. * macros for to/fromuint8_t array * MISRA hates me! * tests.c include macros instead * move CANPacket to can_definitions.h * vw_pq python test fix * new memcpy test, REMOVE * check without alignment * revert macros for uint8 arrays * Revert "revert macros for uint8 arrays" This reverts commit 581a9db735a42d0d68200bd270d87a8fd34e43fe. * check assert * Revert "check assert" This reverts commit 9e970d029a50597a1718b2bb0260196c050fd77f. * one more variation * Revert "one more variation" This reverts commit f6c0528b7ac7e125750dc0d9445c7ce97f6954b5. * what about read performance * Revert "what about read performance" This reverts commit d2610f90958a816fe7f1822157a84f85e97d9249. * check struct alignment to word * check for aligned memcpy again * cleanup * add CANPacket structure diagram * update CANPacket and add USB packet struct * bugfix + refactoring of EP1 * move dlc_to_len to header * missed include * typo... * MISRA * fk * lower MAX_CAN_MSGS_PER_BULK_TRANSFER * bump CAN_PACKET_VERSION to 2 * bump python lib CAN_PACKET_VERSION to 2 * rename parse_can_buffer to unpack_can_buffer * CANPacket_t const fields * Revert "CANPacket_t const fields" This reverts commit cf91c035b7706a14e317550c5f0501ae3fce7c70. * test.c relative path * cleanup * move macros to safety_declarations * Refactor pack/unpack funcs and add unittest * usb_protocol.h * oops * Update .github/workflows/test.yaml Co-authored-by: Adeeb Shihadeh <adeebshihadeh@gmail.com> * remove print from unittest Co-authored-by: Adeeb Shihadeh <adeebshihadeh@gmail.com>
2021-11-13 08:36:34 +08:00
extended = 1 if address >= 0x800 else 0
data_len_code = LEN_TO_DLC[len(dat)]
header = bytearray(CANPACKET_HEAD_SIZE)
CAN_FIFOMailBox to CANPacket struct + USB dynamic packet size (#739) * Squashed commits, no cleanup * Few fixes * No init = garbage * Only receive with new canpacket * Add send with canpacket * Revert "Add send with canpacket" This reverts commit 7d06686ddd6d447c714b5289d31af24403d36931. * Packet must be aligned to word, or bad performance * Cleaner * Fix tests * Tests... * MISRA 10.4 * More MISRA * libpandasafety_py * cffi * even more tests... * typo * ... * ... * ... * Slight cleanup * MISRA 6.1 * MISRA 17.7 * Bug in bxcan + even style * MISRA 10.1 * Revert "MISRA 10.1" This reverts commit 404ae7fcc39556f80f528de9015702e69f4ea0a5. * ... * MISRA 10.1 and 10.4 suppress until next PR * MISRA 20.1 * ... * test_honda * ... * ... * test_toyota * test_volkswagen_mqb * test_volkswagen_pq * Sketchy thing... * Revert "Sketchy thing..." This reverts commit 3b2e5715bdc1954f7b7b3b7469ba3d0eaa06bdf9. * remove comment * bxcan extended address bug * Concept, experimental dynamic usb packet size * increase each buffer to 10240 bytes * raise python bulk read/write limits * ... * Move packet size to start * Experimental send, stream-like * New receive test, stream-like * cleanup * cleanup + rebase fixes * MISRA * Extra receive method, stream-like, commented out * type change * Revert back to buffer for send, stream commented * forgot ZLP * lower buffer, add rx failsafe * ... remove ZLP * return ZLP back * Add tx checks to panda fw * TX stream with counter * fix counter overflow * 13 free slots should be enough * limit tx usb packet * ... * Revert max_bulk_msg doubling * python lib improve speed * Stream with counter for RX, dirty, needs cleanup * Increase chunk length to 4096 bytes * cleanup fdcan.h * cleanup __init__.py * MISRA 12.1 * MISRA 10.8 * remove non-streaming usb functions * more main.c cleanup * MISRA 15.6 * MISRA 15.5 * MISRA 18.4 and suppress objectIndex * handling usb pakcets > 63bytes, naming and cleanup * Cleanup old from tests and update CANPacket_t struct * Switch to 4 bit DLC instead of 6 bit length * ops) * ... * pylint * receive python buffer increase * USB increase receive packet len * tweak buffers * No need for so high limits * MISRA 20.1 workaround * performance tweaks * cleanup, dlc to data_len_code naming * main.c naming * comments and cleanup for main.c usb * clean py lib * pylint * do not discard good rx messages on stream fail * cleanups * naming * remove bitstruct lib and lower tx limit * bitstruct lefovers * fix bug in VW test * remove adjusting data size and assert on wrong len * ... * test new memcpy before merging * Revert "test new memcpy before merging" This reverts commit 399465a264835061adabdd785718c4b6fc18c267. * macros for to/fromuint8_t array * MISRA hates me! * tests.c include macros instead * move CANPacket to can_definitions.h * vw_pq python test fix * new memcpy test, REMOVE * check without alignment * revert macros for uint8 arrays * Revert "revert macros for uint8 arrays" This reverts commit 581a9db735a42d0d68200bd270d87a8fd34e43fe. * check assert * Revert "check assert" This reverts commit 9e970d029a50597a1718b2bb0260196c050fd77f. * one more variation * Revert "one more variation" This reverts commit f6c0528b7ac7e125750dc0d9445c7ce97f6954b5. * what about read performance * Revert "what about read performance" This reverts commit d2610f90958a816fe7f1822157a84f85e97d9249. * check struct alignment to word * check for aligned memcpy again * cleanup * add CANPacket structure diagram * update CANPacket and add USB packet struct * bugfix + refactoring of EP1 * move dlc_to_len to header * missed include * typo... * MISRA * fk * lower MAX_CAN_MSGS_PER_BULK_TRANSFER * bump CAN_PACKET_VERSION to 2 * bump python lib CAN_PACKET_VERSION to 2 * rename parse_can_buffer to unpack_can_buffer * CANPacket_t const fields * Revert "CANPacket_t const fields" This reverts commit cf91c035b7706a14e317550c5f0501ae3fce7c70. * test.c relative path * cleanup * move macros to safety_declarations * Refactor pack/unpack funcs and add unittest * usb_protocol.h * oops * Update .github/workflows/test.yaml Co-authored-by: Adeeb Shihadeh <adeebshihadeh@gmail.com> * remove print from unittest Co-authored-by: Adeeb Shihadeh <adeebshihadeh@gmail.com>
2021-11-13 08:36:34 +08:00
word_4b = address << 3 | extended << 2
header[0] = (data_len_code << 4) | (bus << 1)
header[1] = word_4b & 0xFF
header[2] = (word_4b >> 8) & 0xFF
header[3] = (word_4b >> 16) & 0xFF
header[4] = (word_4b >> 24) & 0xFF
header[5] = calculate_checksum(header[:5] + dat)
snds[-1] += header + dat
if len(snds[-1]) > 256: # Limit chunks to 256 bytes
snds.append(b'')
CAN_FIFOMailBox to CANPacket struct + USB dynamic packet size (#739) * Squashed commits, no cleanup * Few fixes * No init = garbage * Only receive with new canpacket * Add send with canpacket * Revert "Add send with canpacket" This reverts commit 7d06686ddd6d447c714b5289d31af24403d36931. * Packet must be aligned to word, or bad performance * Cleaner * Fix tests * Tests... * MISRA 10.4 * More MISRA * libpandasafety_py * cffi * even more tests... * typo * ... * ... * ... * Slight cleanup * MISRA 6.1 * MISRA 17.7 * Bug in bxcan + even style * MISRA 10.1 * Revert "MISRA 10.1" This reverts commit 404ae7fcc39556f80f528de9015702e69f4ea0a5. * ... * MISRA 10.1 and 10.4 suppress until next PR * MISRA 20.1 * ... * test_honda * ... * ... * test_toyota * test_volkswagen_mqb * test_volkswagen_pq * Sketchy thing... * Revert "Sketchy thing..." This reverts commit 3b2e5715bdc1954f7b7b3b7469ba3d0eaa06bdf9. * remove comment * bxcan extended address bug * Concept, experimental dynamic usb packet size * increase each buffer to 10240 bytes * raise python bulk read/write limits * ... * Move packet size to start * Experimental send, stream-like * New receive test, stream-like * cleanup * cleanup + rebase fixes * MISRA * Extra receive method, stream-like, commented out * type change * Revert back to buffer for send, stream commented * forgot ZLP * lower buffer, add rx failsafe * ... remove ZLP * return ZLP back * Add tx checks to panda fw * TX stream with counter * fix counter overflow * 13 free slots should be enough * limit tx usb packet * ... * Revert max_bulk_msg doubling * python lib improve speed * Stream with counter for RX, dirty, needs cleanup * Increase chunk length to 4096 bytes * cleanup fdcan.h * cleanup __init__.py * MISRA 12.1 * MISRA 10.8 * remove non-streaming usb functions * more main.c cleanup * MISRA 15.6 * MISRA 15.5 * MISRA 18.4 and suppress objectIndex * handling usb pakcets > 63bytes, naming and cleanup * Cleanup old from tests and update CANPacket_t struct * Switch to 4 bit DLC instead of 6 bit length * ops) * ... * pylint * receive python buffer increase * USB increase receive packet len * tweak buffers * No need for so high limits * MISRA 20.1 workaround * performance tweaks * cleanup, dlc to data_len_code naming * main.c naming * comments and cleanup for main.c usb * clean py lib * pylint * do not discard good rx messages on stream fail * cleanups * naming * remove bitstruct lib and lower tx limit * bitstruct lefovers * fix bug in VW test * remove adjusting data size and assert on wrong len * ... * test new memcpy before merging * Revert "test new memcpy before merging" This reverts commit 399465a264835061adabdd785718c4b6fc18c267. * macros for to/fromuint8_t array * MISRA hates me! * tests.c include macros instead * move CANPacket to can_definitions.h * vw_pq python test fix * new memcpy test, REMOVE * check without alignment * revert macros for uint8 arrays * Revert "revert macros for uint8 arrays" This reverts commit 581a9db735a42d0d68200bd270d87a8fd34e43fe. * check assert * Revert "check assert" This reverts commit 9e970d029a50597a1718b2bb0260196c050fd77f. * one more variation * Revert "one more variation" This reverts commit f6c0528b7ac7e125750dc0d9445c7ce97f6954b5. * what about read performance * Revert "what about read performance" This reverts commit d2610f90958a816fe7f1822157a84f85e97d9249. * check struct alignment to word * check for aligned memcpy again * cleanup * add CANPacket structure diagram * update CANPacket and add USB packet struct * bugfix + refactoring of EP1 * move dlc_to_len to header * missed include * typo... * MISRA * fk * lower MAX_CAN_MSGS_PER_BULK_TRANSFER * bump CAN_PACKET_VERSION to 2 * bump python lib CAN_PACKET_VERSION to 2 * rename parse_can_buffer to unpack_can_buffer * CANPacket_t const fields * Revert "CANPacket_t const fields" This reverts commit cf91c035b7706a14e317550c5f0501ae3fce7c70. * test.c relative path * cleanup * move macros to safety_declarations * Refactor pack/unpack funcs and add unittest * usb_protocol.h * oops * Update .github/workflows/test.yaml Co-authored-by: Adeeb Shihadeh <adeebshihadeh@gmail.com> * remove print from unittest Co-authored-by: Adeeb Shihadeh <adeebshihadeh@gmail.com>
2021-11-13 08:36:34 +08:00
return snds
def unpack_can_buffer(dat):
ret = []
while len(dat) >= CANPACKET_HEAD_SIZE:
data_len = DLC_TO_LEN[(dat[0]>>4)]
header = dat[:CANPACKET_HEAD_SIZE]
bus = (header[0] >> 1) & 0x7
address = (header[4] << 24 | header[3] << 16 | header[2] << 8 | header[1]) >> 3
if (header[1] >> 1) & 0x1:
# returned
bus += 128
if header[1] & 0x1:
# rejected
bus += 192
# we need more from the next transfer
if data_len > len(dat) - CANPACKET_HEAD_SIZE:
break
assert calculate_checksum(dat[:(CANPACKET_HEAD_SIZE+data_len)]) == 0, "CAN packet checksum incorrect"
data = dat[CANPACKET_HEAD_SIZE:(CANPACKET_HEAD_SIZE+data_len)]
dat = dat[(CANPACKET_HEAD_SIZE+data_len):]
ret.append((address, 0, data, bus))
return (ret, dat)
def ensure_health_packet_version(fn):
@wraps(fn)
def wrapper(self, *args, **kwargs):
if self.health_version < self.HEALTH_PACKET_VERSION:
raise RuntimeError("Panda firmware has outdated health packet definition. Reflash panda firmware.")
elif self.health_version > self.HEALTH_PACKET_VERSION:
raise RuntimeError("Panda python library has outdated health packet definition. Update panda python library.")
return fn(self, *args, **kwargs)
return wrapper
def ensure_can_packet_version(fn):
@wraps(fn)
def wrapper(self, *args, **kwargs):
if self.can_version < self.CAN_PACKET_VERSION:
raise RuntimeError("Panda firmware has outdated CAN packet definition. Reflash panda firmware.")
elif self.can_version > self.CAN_PACKET_VERSION:
raise RuntimeError("Panda python library has outdated CAN packet definition. Update panda python library.")
return fn(self, *args, **kwargs)
return wrapper
def ensure_can_health_packet_version(fn):
@wraps(fn)
def wrapper(self, *args, **kwargs):
if self.can_health_version < self.CAN_HEALTH_PACKET_VERSION:
raise RuntimeError("Panda firmware has outdated CAN health packet definition. Reflash panda firmware.")
elif self.can_health_version > self.CAN_HEALTH_PACKET_VERSION:
raise RuntimeError("Panda python library has outdated CAN health packet definition. Update panda python library.")
return fn(self, *args, **kwargs)
return wrapper
class ALTERNATIVE_EXPERIENCE:
DEFAULT = 0
DISABLE_DISENGAGE_ON_GAS = 1
DISABLE_STOCK_AEB = 2
RAISE_LONGITUDINAL_LIMITS_TO_ISO_MAX = 8
2022-05-12 20:22:58 +08:00
class Panda:
# matches cereal.car.CarParams.SafetyModel
SAFETY_SILENT = 0
SAFETY_HONDA_NIDEC = 1
SAFETY_TOYOTA = 2
SAFETY_ELM327 = 3
SAFETY_GM = 4
SAFETY_HONDA_BOSCH_GIRAFFE = 5
SAFETY_FORD = 6
SAFETY_HYUNDAI = 8
SAFETY_CHRYSLER = 9
SAFETY_TESLA = 10
SAFETY_SUBARU = 11
SAFETY_MAZDA = 13
SAFETY_NISSAN = 14
SAFETY_VOLKSWAGEN_MQB = 15
SAFETY_ALLOUTPUT = 17
SAFETY_GM_ASCM = 18
SAFETY_NOOUTPUT = 19
2021-11-22 06:51:47 +08:00
SAFETY_HONDA_BOSCH = 20
SAFETY_VOLKSWAGEN_PQ = 21
SAFETY_SUBARU_LEGACY = 22
2020-06-13 09:03:31 +08:00
SAFETY_HYUNDAI_LEGACY = 23
SAFETY_HYUNDAI_COMMUNITY = 24
SAFETY_STELLANTIS = 25
SAFETY_FAW = 26
SAFETY_BODY = 27
SAFETY_HYUNDAI_CANFD = 28
2017-07-18 06:29:31 +08:00
2017-07-19 03:15:19 +08:00
SERIAL_DEBUG = 0
SERIAL_ESP = 1
SERIAL_LIN1 = 2
SERIAL_LIN2 = 3
SERIAL_SOM_DEBUG = 4
2017-07-19 03:15:19 +08:00
2017-07-19 12:05:09 +08:00
GMLAN_CAN2 = 1
GMLAN_CAN3 = 2
2017-07-18 09:59:16 +08:00
REQUEST_IN = usb1.ENDPOINT_IN | usb1.TYPE_VENDOR | usb1.RECIPIENT_DEVICE
REQUEST_OUT = usb1.ENDPOINT_OUT | usb1.TYPE_VENDOR | usb1.RECIPIENT_DEVICE
HW_TYPE_UNKNOWN = b'\x00'
HW_TYPE_WHITE_PANDA = b'\x01'
HW_TYPE_GREY_PANDA = b'\x02'
HW_TYPE_BLACK_PANDA = b'\x03'
HW_TYPE_PEDAL = b'\x04'
HW_TYPE_UNO = b'\x05'
2021-07-08 15:37:14 +08:00
HW_TYPE_DOS = b'\x06'
HW_TYPE_RED_PANDA = b'\x07'
HW_TYPE_RED_PANDA_V2 = b'\x08'
HW_TYPE_TRES = b'\x09'
CAN_PACKET_VERSION = 4
HEALTH_PACKET_VERSION = 11
CAN_HEALTH_PACKET_VERSION = 4
HEALTH_STRUCT = struct.Struct("<IIIIIIIIIBBBBBBHBBBHfBB")
CAN_HEALTH_STRUCT = struct.Struct("<BIBBBBBBBBIIIIIIIHHBBB")
F2_DEVICES = (HW_TYPE_PEDAL, )
F4_DEVICES = (HW_TYPE_WHITE_PANDA, HW_TYPE_GREY_PANDA, HW_TYPE_BLACK_PANDA, HW_TYPE_UNO, HW_TYPE_DOS)
H7_DEVICES = (HW_TYPE_RED_PANDA, HW_TYPE_RED_PANDA_V2, HW_TYPE_TRES)
INTERNAL_DEVICES = (HW_TYPE_UNO, HW_TYPE_DOS)
HAS_OBD = (HW_TYPE_BLACK_PANDA, HW_TYPE_UNO, HW_TYPE_DOS, HW_TYPE_RED_PANDA, HW_TYPE_RED_PANDA_V2, HW_TYPE_TRES)
# first byte is for EPS scaling factor
2022-04-29 08:40:50 +08:00
FLAG_TOYOTA_ALT_BRAKE = (1 << 8)
FLAG_TOYOTA_STOCK_LONGITUDINAL = (2 << 8)
FLAG_HONDA_ALT_BRAKE = 1
FLAG_HONDA_BOSCH_LONG = 2
FLAG_HONDA_NIDEC_ALT = 4
2022-06-17 10:02:44 +08:00
FLAG_HONDA_RADARLESS = 8
FLAG_HYUNDAI_EV_GAS = 1
FLAG_HYUNDAI_HYBRID_GAS = 2
FLAG_HYUNDAI_LONG = 4
FLAG_HYUNDAI_CAMERA_SCC = 8
FLAG_HYUNDAI_CANFD_HDA2 = 16
FLAG_HYUNDAI_CANFD_ALT_BUTTONS = 32
FLAG_HYUNDAI_ALT_LIMITS = 64
FLAG_TESLA_POWERTRAIN = 1
FLAG_TESLA_LONG_CONTROL = 2
FLAG_VOLKSWAGEN_LONG_CONTROL = 1
FLAG_CHRYSLER_RAM_DT = 1
FLAG_CHRYSLER_RAM_HD = 2
FLAG_SUBARU_GEN2 = 1
GM: Add support for cam harness & stock ACC (#962) * Allow brake TX on PT bus * Initial Panda GM cam harness support * Complete rewrite / simplification * Add param for cam harness (default is OBD2) - Forward btw 0 and 2 - Filter LKAS and optionally ACC from cam * Add param for stock ACC - Allows ACC on PT bus when set, not otherwise - Allows ACC from cam when set, not otherwise * Add temporary WIP EPS timing workaround in ifdef * Remove keepalive; regen == braking * Fix MISRA violations * EPS timing opt-in by param * Minor clean up * remove timing code for readability fix and formatting * we only need to send one message if cam harness and stock long * Simplify params * Removed dup brake msg * revised params, split 3-ways * add test * clean up a bit, no need to send ACC yet like this * split out button enable and pcm enable into seperate tests * some formatting some formatting * GM CAM uses PCM cruise for controls_allowed * fix gas safety tests * misra * fix static analysis comment * fix brake pressed * Add OP VOACC override stock cam * Add VOACC safetyparam to init.py * Revert "Add VOACC safetyparam to init.py" This reverts commit 2e46f8746f31c399823d9fae9fb9e77e6fee6eea. * Revert "Add OP VOACC override stock cam" This reverts commit a4b096cc1e7ee572b22e5f4422b9a6d43f94479c. * better comments * better comments better comments fix * move non-base msg definitions to subclass * various comments * TODO: add button safety * add button safety * use new pcm_cruise_check * revert regen braking change * only cancel button allowed * Apply suggestions from code review * Update board/safety/safety_gm.h Co-authored-by: Adeeb Shihadeh <adeebshihadeh@gmail.com> * fix suggestion * Fix tests * Revert "Fix tests" This reverts commit 500577921f32be24934acc80af98aab3af86d028. * this is a much simpler fix, do full fix in another PR * tx button safety Co-authored-by: Shane Smiskol <shane@smiskol.com> Co-authored-by: Adeeb Shihadeh <adeebshihadeh@gmail.com>
2022-08-13 06:56:39 +08:00
FLAG_GM_HW_CAM = 1
GM: longitudinal support for camera-integrated cars (#1014) * Allow brake TX on PT bus * Initial Panda GM cam harness support * Complete rewrite / simplification * Add param for cam harness (default is OBD2) - Forward btw 0 and 2 - Filter LKAS and optionally ACC from cam * Add param for stock ACC - Allows ACC on PT bus when set, not otherwise - Allows ACC from cam when set, not otherwise * Add temporary WIP EPS timing workaround in ifdef * Remove keepalive; regen == braking * Fix MISRA violations * EPS timing opt-in by param * Minor clean up * remove timing code for readability fix and formatting * we only need to send one message if cam harness and stock long * Simplify params * Removed dup brake msg * revised params, split 3-ways * add test * clean up a bit, no need to send ACC yet like this * split out button enable and pcm enable into seperate tests * some formatting some formatting * GM CAM uses PCM cruise for controls_allowed * fix gas safety tests * misra * fix static analysis comment * fix brake pressed * Add OP VOACC override stock cam * Add VOACC safetyparam to init.py * openpilot long safety * do this in another PR * add back * add safety tests * rename * struct for safety * not used * temporary fault fix * adjust max gas * allow PSCMStatus in long mode * stash * fix max gas * fix and clean up tests * clean up longitudinal tests into a common class * fix pylint * subclass * clean that up * rm * blocking * comment * comment * lower case * brake bus Co-authored-by: Shane Smiskol <shane@smiskol.com>
2022-11-01 15:58:18 +08:00
FLAG_GM_HW_CAM_LONG = 2
GM: Add support for cam harness & stock ACC (#962) * Allow brake TX on PT bus * Initial Panda GM cam harness support * Complete rewrite / simplification * Add param for cam harness (default is OBD2) - Forward btw 0 and 2 - Filter LKAS and optionally ACC from cam * Add param for stock ACC - Allows ACC on PT bus when set, not otherwise - Allows ACC from cam when set, not otherwise * Add temporary WIP EPS timing workaround in ifdef * Remove keepalive; regen == braking * Fix MISRA violations * EPS timing opt-in by param * Minor clean up * remove timing code for readability fix and formatting * we only need to send one message if cam harness and stock long * Simplify params * Removed dup brake msg * revised params, split 3-ways * add test * clean up a bit, no need to send ACC yet like this * split out button enable and pcm enable into seperate tests * some formatting some formatting * GM CAM uses PCM cruise for controls_allowed * fix gas safety tests * misra * fix static analysis comment * fix brake pressed * Add OP VOACC override stock cam * Add VOACC safetyparam to init.py * Revert "Add VOACC safetyparam to init.py" This reverts commit 2e46f8746f31c399823d9fae9fb9e77e6fee6eea. * Revert "Add OP VOACC override stock cam" This reverts commit a4b096cc1e7ee572b22e5f4422b9a6d43f94479c. * better comments * better comments better comments fix * move non-base msg definitions to subclass * various comments * TODO: add button safety * add button safety * use new pcm_cruise_check * revert regen braking change * only cancel button allowed * Apply suggestions from code review * Update board/safety/safety_gm.h Co-authored-by: Adeeb Shihadeh <adeebshihadeh@gmail.com> * fix suggestion * Fix tests * Revert "Fix tests" This reverts commit 500577921f32be24934acc80af98aab3af86d028. * this is a much simpler fix, do full fix in another PR * tx button safety Co-authored-by: Shane Smiskol <shane@smiskol.com> Co-authored-by: Adeeb Shihadeh <adeebshihadeh@gmail.com>
2022-08-13 06:56:39 +08:00
def __init__(self, serial: Optional[str] = None, claim: bool = True, disable_checks: bool = True):
self._connect_serial = serial
self._disable_checks = disable_checks
self._handle: BaseHandle
self._handle_open = False
self.can_rx_overflow_buffer = b''
# connect and set mcu type
2017-07-25 06:16:22 +08:00
self.connect(claim)
# reset comms
self.can_reset_communications()
def __enter__(self):
return self
def __exit__(self, *args):
self.close()
2017-07-25 06:16:22 +08:00
def close(self):
if self._handle_open:
self._handle.close()
self._handle_open = False
2017-07-25 06:16:22 +08:00
2017-07-30 08:21:22 +08:00
def connect(self, claim=True, wait=False):
self.close()
2017-04-07 09:11:36 +08:00
# try USB first, then SPI
self._handle, serial, self.bootstub, bcd = self.usb_connect(self._connect_serial, claim=claim, wait=wait)
if self._handle is None:
self._handle, serial, self.bootstub, bcd = self.spi_connect(self._connect_serial)
if self._handle is None:
raise Exception("failed to connect to panda")
# Some fallback logic to determine panda and MCU type for old bootstubs,
# since we now support multiple MCUs and need to know which fw to flash.
# Three cases to consider:
# A) oldest bootstubs don't have any way to distinguish
# MCU or panda type
# B) slightly newer (~2 weeks after first C3's built) bootstubs
# have the panda type set in the USB bcdDevice
# C) latest bootstubs also implement the endpoint for panda type
self._bcd_hw_type = None
ret = self._handle.controlRead(Panda.REQUEST_IN, 0xc1, 0, 0, 0x40)
missing_hw_type_endpoint = self.bootstub and ret.startswith(b'\xff\x00\xc1\x3e\xde\xad\xd0\x0d')
if missing_hw_type_endpoint and bcd is not None:
self._bcd_hw_type = bcd
# For case A, we assume F4 MCU type, since all H7 pandas should be case B at worst
self._assume_f4_mcu = (self._bcd_hw_type is None) and missing_hw_type_endpoint
self._serial = serial
self._connect_serial = serial
self._handle_open = True
self._mcu_type = self.get_mcu_type()
self.health_version, self.can_version, self.can_health_version = self.get_packets_versions()
logging.debug("connected")
# disable openpilot's heartbeat checks
if self._disable_checks:
self.set_heartbeat_disabled()
self.set_power_save(0)
@staticmethod
def spi_connect(serial):
# get UID to confirm slave is present and up
handle = None
spi_serial = None
bootstub = None
try:
handle = PandaSpiHandle()
bootstub = Panda.flasher_present(handle)
dat = handle.controlRead(Panda.REQUEST_IN, 0xc3, 0, 0, 12)
spi_serial = binascii.hexlify(dat).decode()
except PandaSpiException:
pass
# no connection or wrong panda
if None in (spi_serial, bootstub) or (serial is not None and (spi_serial != serial)):
handle = None
spi_serial = None
bootstub = False
return handle, spi_serial, bootstub, None
@staticmethod
def usb_connect(serial, claim=True, wait=False):
handle, usb_serial, bootstub, bcd = None, None, None, None
context = usb1.USBContext()
while 1:
try:
for device in context.getDeviceList(skip_on_error=True):
2022-05-12 20:22:58 +08:00
if device.getVendorID() == 0xbbaa and device.getProductID() in (0xddcc, 0xddee):
try:
this_serial = device.getSerialNumber()
except Exception:
continue
if serial is None or this_serial == serial:
logging.debug("opening device %s %s", this_serial, hex(device.getProductID()))
usb_serial = this_serial
bootstub = device.getProductID() == 0xddee
handle = device.open()
2022-05-12 20:22:58 +08:00
if sys.platform not in ("win32", "cygwin", "msys", "darwin"):
handle.setAutoDetachKernelDriver(True)
if claim:
handle.claimInterface(0)
# handle.setInterfaceAltSetting(0, 0) # Issue in USB stack
# bcdDevice wasn't always set to the hw type, ignore if it's the old constant
this_bcd = device.getbcdDevice()
if this_bcd is not None and this_bcd != 0x2300:
bcd = bytearray([this_bcd >> 8, ])
break
except Exception:
logging.exception("USB connect error")
if not wait or handle is not None:
break
context = usb1.USBContext() # New context needed so new devices show up
usb_handle = None
if handle is not None:
usb_handle = PandaUsbHandle(handle)
return usb_handle, usb_serial, bootstub, bcd
@staticmethod
def list():
ret = Panda.usb_list()
ret += Panda.spi_list()
return list(set(ret))
@staticmethod
def usb_list():
context = usb1.USBContext()
ret = []
try:
for device in context.getDeviceList(skip_on_error=True):
if device.getVendorID() == 0xbbaa and device.getProductID() in (0xddcc, 0xddee):
try:
serial = device.getSerialNumber()
if len(serial) == 24:
ret.append(serial)
else:
warnings.warn(f"found device with panda descriptors but invalid serial: {serial}", RuntimeWarning)
except Exception:
continue
except Exception:
pass
return ret
@staticmethod
def spi_list():
_, serial, _, _ = Panda.spi_connect(None)
if serial is not None:
return [serial, ]
return []
def reset(self, enter_bootstub=False, enter_bootloader=False, reconnect=True):
2017-07-25 06:16:22 +08:00
try:
2017-07-28 05:29:07 +08:00
if enter_bootloader:
self._handle.controlWrite(Panda.REQUEST_IN, 0xd1, 0, 0, b'')
2017-07-25 06:16:22 +08:00
else:
2017-07-28 05:29:07 +08:00
if enter_bootstub:
self._handle.controlWrite(Panda.REQUEST_IN, 0xd1, 1, 0, b'')
else:
self._handle.controlWrite(Panda.REQUEST_IN, 0xd8, 0, 0, b'')
2017-07-25 06:16:22 +08:00
except Exception:
pass
if not enter_bootloader and reconnect:
2018-03-11 03:22:22 +08:00
self.reconnect()
def reconnect(self):
if self._handle_open:
self.close()
time.sleep(1.0)
2018-03-11 03:22:22 +08:00
success = False
# wait up to 15 seconds
for i in range(0, 15):
try:
self.connect()
success = True
break
except Exception:
logging.debug("reconnecting is taking %d seconds...", i + 1)
try:
dfu = PandaDFU(PandaDFU.st_serial_to_dfu_serial(self._serial, self._mcu_type))
2018-03-11 03:22:22 +08:00
dfu.recover()
except Exception:
2018-03-11 03:22:22 +08:00
pass
time.sleep(1.0)
if not success:
raise Exception("reconnect failed")
@staticmethod
def flasher_present(handle: BaseHandle) -> bool:
fr = handle.controlRead(Panda.REQUEST_IN, 0xb0, 0, 0, 0xc)
return fr[4:8] == b"\xde\xad\xd0\x0d"
2018-03-11 03:22:22 +08:00
@staticmethod
def flash_static(handle, code, mcu_type):
assert mcu_type is not None, "must set valid mcu_type to flash"
2018-03-11 03:22:22 +08:00
# confirm flasher is present
assert Panda.flasher_present(handle)
2018-03-11 03:22:22 +08:00
# determine sectors to erase
apps_sectors_cumsum = accumulate(mcu_type.config.sector_sizes[1:])
last_sector = next((i + 1 for i, v in enumerate(apps_sectors_cumsum) if v > len(code)), -1)
assert last_sector >= 1, "Binary too small? No sector to erase."
assert last_sector < 7, "Binary too large! Risk of overwriting provisioning chunk."
2018-03-11 03:22:22 +08:00
# unlock flash
logging.warning("flash: unlocking")
2018-03-11 03:22:22 +08:00
handle.controlWrite(Panda.REQUEST_IN, 0xb1, 0, 0, b'')
# erase sectors
logging.warning(f"flash: erasing sectors 1 - {last_sector}")
for i in range(1, last_sector + 1):
Black (#254) * late usb * Added type support for black panda * Added harness presence and orientation detection * harness relay driving code * Added intercept support in black panda code. Switched around can0 and can2 * Disable ADCs after orientation detection. Ignition interrupts via harness * WIP: Hardware abstraction layer + black panda bringup * Fixed bootstub build * Fixed bootstub for pedal * Fixed infinite loops * Got CAN buses working on white again * Fixed pedal build and black can interfaces * Got CAN buses working on black panda * Finished loopback test for black panda * Erase all flash sectors on the panda. Increased binary limit. Added extra python functions. * Fixed python * Made new code MISRA compliant * Cleaned up ignition. Fixed build * Fixed health packet * Fixed CAN mode on black bug. Changed OBD to switch on ELM mode * Fixes from Github review * Fixed MISRA issue for pedal * Fixed failing gmlan tests * ELM327 safety: allow diagnostic on all buses * Cleaned up EON relay code * delete only 3 sectors instead of 11 to allow a new build to be flashed. Much faster to flash * Removed CAN only can0 output mode. Does not make sense on black panda due to reversibility issues. * Added heartbeat logic for EON code on panda. Go to NOOUTPUT if EON does not send a heartbeat for 5 seconds. * Remove all CAN buses live on EON startup. Shouldn't be necessary to have this separate case * Formatting * Added file I forgot to push * Added heartbeat to testing code to make sure EON tests don't fail. Should probably find a better way to do this though. Heartbeat thread didn't work, concurrent USB connection issues... * Safety: support black panda for Honda Bosch * Disable OBD2 if setting to NOOUTPUT mode * Run safety tests for all hw_types * Fail test if subtest fails * fix safety tests
2019-07-24 06:07:06 +08:00
handle.controlWrite(Panda.REQUEST_IN, 0xb2, i, 0, b'')
2018-03-11 03:22:22 +08:00
# flash over EP2
STEP = 0x10
logging.warning("flash: flashing")
2018-03-11 03:22:22 +08:00
for i in range(0, len(code), STEP):
handle.bulkWrite(2, code[i:i + STEP])
2018-03-11 03:22:22 +08:00
# reset
logging.warning("flash: resetting")
2018-03-11 03:22:22 +08:00
try:
handle.controlWrite(Panda.REQUEST_IN, 0xd8, 0, 0, b'')
except Exception:
pass
def flash(self, fn=None, code=None, reconnect=True):
if not fn:
fn = self._mcu_type.config.app_path
assert os.path.isfile(fn)
logging.debug("flash: main version is %s", self.get_version())
2017-07-25 06:16:22 +08:00
if not self.bootstub:
2017-07-28 05:29:07 +08:00
self.reset(enter_bootstub=True)
2017-07-25 06:16:22 +08:00
assert(self.bootstub)
2017-08-23 04:36:20 +08:00
if code is None:
2019-09-26 07:52:03 +08:00
with open(fn, "rb") as f:
2017-08-23 04:36:20 +08:00
code = f.read()
2017-07-25 06:16:22 +08:00
# get version
logging.debug("flash: bootstub version is %s", self.get_version())
2018-03-11 03:22:22 +08:00
# do flash
Panda.flash_static(self._handle, code, mcu_type=self._mcu_type)
2017-07-25 06:16:22 +08:00
2018-03-11 03:22:22 +08:00
# reconnect
if reconnect:
self.reconnect()
2017-04-07 09:11:36 +08:00
2022-05-12 20:22:58 +08:00
def recover(self, timeout: Optional[int] = None, reset: bool = True) -> bool:
dfu_serial = PandaDFU.st_serial_to_dfu_serial(self._serial, self._mcu_type)
if reset:
self.reset(enter_bootstub=True)
self.reset(enter_bootloader=True)
if not self.wait_for_dfu(dfu_serial, timeout=timeout):
return False
2017-08-29 01:42:23 +08:00
dfu = PandaDFU(dfu_serial)
2017-08-29 01:42:23 +08:00
dfu.recover()
# reflash after recover
self.connect(True, True)
self.flash()
return True
2017-08-29 01:42:23 +08:00
@staticmethod
def wait_for_dfu(dfu_serial: str, timeout: Optional[int] = None) -> bool:
t_start = time.monotonic()
while dfu_serial not in PandaDFU.list():
logging.debug("waiting for DFU...")
time.sleep(0.1)
if timeout is not None and (time.monotonic() - t_start) > timeout:
return False
return True
def up_to_date(self) -> bool:
current = self.get_signature()
expected = Panda.get_signature_from_firmware(self.get_mcu_type().config.app_path)
return (current == expected)
2017-07-19 03:29:16 +08:00
def call_control_api(self, msg):
self._handle.controlWrite(Panda.REQUEST_OUT, msg, 0, 0, b'')
2017-04-07 09:11:36 +08:00
# ******************* health *******************
@ensure_health_packet_version
2017-04-07 09:11:36 +08:00
def health(self):
dat = self._handle.controlRead(Panda.REQUEST_IN, 0xd2, 0, 0, self.HEALTH_STRUCT.size)
a = self.HEALTH_STRUCT.unpack(dat)
Black (#254) * late usb * Added type support for black panda * Added harness presence and orientation detection * harness relay driving code * Added intercept support in black panda code. Switched around can0 and can2 * Disable ADCs after orientation detection. Ignition interrupts via harness * WIP: Hardware abstraction layer + black panda bringup * Fixed bootstub build * Fixed bootstub for pedal * Fixed infinite loops * Got CAN buses working on white again * Fixed pedal build and black can interfaces * Got CAN buses working on black panda * Finished loopback test for black panda * Erase all flash sectors on the panda. Increased binary limit. Added extra python functions. * Fixed python * Made new code MISRA compliant * Cleaned up ignition. Fixed build * Fixed health packet * Fixed CAN mode on black bug. Changed OBD to switch on ELM mode * Fixes from Github review * Fixed MISRA issue for pedal * Fixed failing gmlan tests * ELM327 safety: allow diagnostic on all buses * Cleaned up EON relay code * delete only 3 sectors instead of 11 to allow a new build to be flashed. Much faster to flash * Removed CAN only can0 output mode. Does not make sense on black panda due to reversibility issues. * Added heartbeat logic for EON code on panda. Go to NOOUTPUT if EON does not send a heartbeat for 5 seconds. * Remove all CAN buses live on EON startup. Shouldn't be necessary to have this separate case * Formatting * Added file I forgot to push * Added heartbeat to testing code to make sure EON tests don't fail. Should probably find a better way to do this though. Heartbeat thread didn't work, concurrent USB connection issues... * Safety: support black panda for Honda Bosch * Disable OBD2 if setting to NOOUTPUT mode * Run safety tests for all hw_types * Fail test if subtest fails * fix safety tests
2019-07-24 06:07:06 +08:00
return {
"uptime": a[0],
"voltage": a[1],
"current": a[2],
"safety_tx_blocked": a[3],
"safety_rx_invalid": a[4],
"tx_buffer_overflow": a[5],
"rx_buffer_overflow": a[6],
"gmlan_send_errs": a[7],
"faults": a[8],
"ignition_line": a[9],
"ignition_can": a[10],
"controls_allowed": a[11],
"gas_interceptor_detected": a[12],
"car_harness_status": a[13],
"safety_mode": a[14],
"safety_param": a[15],
"fault_status": a[16],
"power_save_enabled": a[17],
"heartbeat_lost": a[18],
"alternative_experience": a[19],
"interrupt_load": a[20],
"fan_power": a[21],
"safety_rx_checks_invalid": a[22],
Black (#254) * late usb * Added type support for black panda * Added harness presence and orientation detection * harness relay driving code * Added intercept support in black panda code. Switched around can0 and can2 * Disable ADCs after orientation detection. Ignition interrupts via harness * WIP: Hardware abstraction layer + black panda bringup * Fixed bootstub build * Fixed bootstub for pedal * Fixed infinite loops * Got CAN buses working on white again * Fixed pedal build and black can interfaces * Got CAN buses working on black panda * Finished loopback test for black panda * Erase all flash sectors on the panda. Increased binary limit. Added extra python functions. * Fixed python * Made new code MISRA compliant * Cleaned up ignition. Fixed build * Fixed health packet * Fixed CAN mode on black bug. Changed OBD to switch on ELM mode * Fixes from Github review * Fixed MISRA issue for pedal * Fixed failing gmlan tests * ELM327 safety: allow diagnostic on all buses * Cleaned up EON relay code * delete only 3 sectors instead of 11 to allow a new build to be flashed. Much faster to flash * Removed CAN only can0 output mode. Does not make sense on black panda due to reversibility issues. * Added heartbeat logic for EON code on panda. Go to NOOUTPUT if EON does not send a heartbeat for 5 seconds. * Remove all CAN buses live on EON startup. Shouldn't be necessary to have this separate case * Formatting * Added file I forgot to push * Added heartbeat to testing code to make sure EON tests don't fail. Should probably find a better way to do this though. Heartbeat thread didn't work, concurrent USB connection issues... * Safety: support black panda for Honda Bosch * Disable OBD2 if setting to NOOUTPUT mode * Run safety tests for all hw_types * Fail test if subtest fails * fix safety tests
2019-07-24 06:07:06 +08:00
}
2017-04-07 09:11:36 +08:00
@ensure_can_health_packet_version
def can_health(self, can_number):
LEC_ERROR_CODE = {
0: "No error",
1: "Stuff error",
2: "Form error",
3: "AckError",
4: "Bit1Error",
5: "Bit0Error",
6: "CRCError",
7: "NoChange",
}
dat = self._handle.controlRead(Panda.REQUEST_IN, 0xc2, int(can_number), 0, self.CAN_HEALTH_STRUCT.size)
a = self.CAN_HEALTH_STRUCT.unpack(dat)
return {
"bus_off": a[0],
"bus_off_cnt": a[1],
"error_warning": a[2],
"error_passive": a[3],
"last_error": LEC_ERROR_CODE[a[4]],
"last_stored_error": LEC_ERROR_CODE[a[5]],
"last_data_error": LEC_ERROR_CODE[a[6]],
"last_data_stored_error": LEC_ERROR_CODE[a[7]],
"receive_error_cnt": a[8],
"transmit_error_cnt": a[9],
"total_error_cnt": a[10],
"total_tx_lost_cnt": a[11],
"total_rx_lost_cnt": a[12],
"total_tx_cnt": a[13],
"total_rx_cnt": a[14],
"total_fwd_cnt": a[15],
"total_tx_checksum_error_cnt": a[16],
"can_speed": a[17],
"can_data_speed": a[18],
"canfd_enabled": a[19],
"brs_enabled": a[20],
"canfd_non_iso": a[21],
}
2017-04-29 07:56:40 +08:00
# ******************* control *******************
def enter_bootloader(self):
try:
self._handle.controlWrite(Panda.REQUEST_OUT, 0xd1, 0, 0, b'')
except Exception:
logging.exception("exception while entering bootloader")
2017-04-29 07:56:40 +08:00
def get_version(self):
2019-09-26 07:52:51 +08:00
return self._handle.controlRead(Panda.REQUEST_IN, 0xd6, 0, 0, 0x40).decode('utf8')
@staticmethod
2022-05-12 20:22:58 +08:00
def get_signature_from_firmware(fn) -> bytes:
f = open(fn, 'rb')
f.seek(-128, 2) # Seek from end of file
return f.read(128)
def get_signature(self) -> bytes:
part_1 = self._handle.controlRead(Panda.REQUEST_IN, 0xd3, 0, 0, 0x40)
part_2 = self._handle.controlRead(Panda.REQUEST_IN, 0xd4, 0, 0, 0x40)
return bytes(part_1 + part_2)
Black (#254) * late usb * Added type support for black panda * Added harness presence and orientation detection * harness relay driving code * Added intercept support in black panda code. Switched around can0 and can2 * Disable ADCs after orientation detection. Ignition interrupts via harness * WIP: Hardware abstraction layer + black panda bringup * Fixed bootstub build * Fixed bootstub for pedal * Fixed infinite loops * Got CAN buses working on white again * Fixed pedal build and black can interfaces * Got CAN buses working on black panda * Finished loopback test for black panda * Erase all flash sectors on the panda. Increased binary limit. Added extra python functions. * Fixed python * Made new code MISRA compliant * Cleaned up ignition. Fixed build * Fixed health packet * Fixed CAN mode on black bug. Changed OBD to switch on ELM mode * Fixes from Github review * Fixed MISRA issue for pedal * Fixed failing gmlan tests * ELM327 safety: allow diagnostic on all buses * Cleaned up EON relay code * delete only 3 sectors instead of 11 to allow a new build to be flashed. Much faster to flash * Removed CAN only can0 output mode. Does not make sense on black panda due to reversibility issues. * Added heartbeat logic for EON code on panda. Go to NOOUTPUT if EON does not send a heartbeat for 5 seconds. * Remove all CAN buses live on EON startup. Shouldn't be necessary to have this separate case * Formatting * Added file I forgot to push * Added heartbeat to testing code to make sure EON tests don't fail. Should probably find a better way to do this though. Heartbeat thread didn't work, concurrent USB connection issues... * Safety: support black panda for Honda Bosch * Disable OBD2 if setting to NOOUTPUT mode * Run safety tests for all hw_types * Fail test if subtest fails * fix safety tests
2019-07-24 06:07:06 +08:00
def get_type(self):
ret = self._handle.controlRead(Panda.REQUEST_IN, 0xc1, 0, 0, 0x40)
# old bootstubs don't implement this endpoint, see comment in Panda.device
if self._bcd_hw_type is not None and (ret is None or len(ret) != 1):
ret = self._bcd_hw_type
return ret
Black (#254) * late usb * Added type support for black panda * Added harness presence and orientation detection * harness relay driving code * Added intercept support in black panda code. Switched around can0 and can2 * Disable ADCs after orientation detection. Ignition interrupts via harness * WIP: Hardware abstraction layer + black panda bringup * Fixed bootstub build * Fixed bootstub for pedal * Fixed infinite loops * Got CAN buses working on white again * Fixed pedal build and black can interfaces * Got CAN buses working on black panda * Finished loopback test for black panda * Erase all flash sectors on the panda. Increased binary limit. Added extra python functions. * Fixed python * Made new code MISRA compliant * Cleaned up ignition. Fixed build * Fixed health packet * Fixed CAN mode on black bug. Changed OBD to switch on ELM mode * Fixes from Github review * Fixed MISRA issue for pedal * Fixed failing gmlan tests * ELM327 safety: allow diagnostic on all buses * Cleaned up EON relay code * delete only 3 sectors instead of 11 to allow a new build to be flashed. Much faster to flash * Removed CAN only can0 output mode. Does not make sense on black panda due to reversibility issues. * Added heartbeat logic for EON code on panda. Go to NOOUTPUT if EON does not send a heartbeat for 5 seconds. * Remove all CAN buses live on EON startup. Shouldn't be necessary to have this separate case * Formatting * Added file I forgot to push * Added heartbeat to testing code to make sure EON tests don't fail. Should probably find a better way to do this though. Heartbeat thread didn't work, concurrent USB connection issues... * Safety: support black panda for Honda Bosch * Disable OBD2 if setting to NOOUTPUT mode * Run safety tests for all hw_types * Fail test if subtest fails * fix safety tests
2019-07-24 06:07:06 +08:00
# Returns tuple with health packet version and CAN packet/USB packet version
def get_packets_versions(self):
dat = self._handle.controlRead(Panda.REQUEST_IN, 0xdd, 0, 0, 3)
if dat and len(dat) == 3:
a = struct.unpack("BBB", dat)
return (a[0], a[1], a[2])
else:
return (0, 0, 0)
def get_mcu_type(self) -> McuType:
hw_type = self.get_type()
if hw_type in Panda.F2_DEVICES:
return McuType.F2
elif hw_type in Panda.F4_DEVICES:
return McuType.F4
elif hw_type in Panda.H7_DEVICES:
return McuType.H7
else:
# have to assume F4, see comment in Panda.connect
if self._assume_f4_mcu:
return McuType.F4
raise ValueError(f"unknown HW type: {hw_type}")
2021-07-08 15:36:25 +08:00
2019-11-06 10:25:42 +08:00
def has_obd(self):
return self.get_type() in Panda.HAS_OBD
2021-10-08 18:10:28 +08:00
def is_internal(self):
return self.get_type() in Panda.INTERNAL_DEVICES
2017-04-29 07:56:40 +08:00
def get_serial(self):
"""
Returns the comma-issued dongle ID from our provisioning
"""
2017-07-18 09:59:16 +08:00
dat = self._handle.controlRead(Panda.REQUEST_IN, 0xd0, 0, 0, 0x20)
hashsig, calc_hash = dat[0x1c:], hashlib.sha1(dat[0:0x1c]).digest()[0:4]
2017-07-18 10:43:30 +08:00
assert(hashsig == calc_hash)
return [dat[0:0x10].decode("utf8"), dat[0x10:0x10 + 10].decode("utf8")]
2017-04-29 07:56:40 +08:00
2021-10-08 18:17:06 +08:00
def get_usb_serial(self):
"""
Returns the serial number reported from the USB descriptor;
matches the MCU UID
"""
2021-10-08 18:17:06 +08:00
return self._serial
def get_uid(self):
"""
Returns the UID from the MCU
"""
dat = self._handle.controlRead(Panda.REQUEST_IN, 0xc3, 0, 0, 12)
return binascii.hexlify(dat).decode()
2017-04-29 08:49:55 +08:00
def get_secret(self):
2017-07-18 09:59:16 +08:00
return self._handle.controlRead(Panda.REQUEST_IN, 0xd0, 1, 0, 0x10)
2017-04-29 08:49:55 +08:00
2017-04-26 06:16:23 +08:00
# ******************* configuration *******************
2017-04-07 09:11:36 +08:00
def set_power_save(self, power_save_enabled=0):
self._handle.controlWrite(Panda.REQUEST_OUT, 0xe7, int(power_save_enabled), 0, b'')
2022-03-08 06:32:14 +08:00
def enable_deepsleep(self):
self._handle.controlWrite(Panda.REQUEST_OUT, 0xfb, 0, 0, b'')
2017-07-18 06:29:31 +08:00
def set_esp_power(self, on):
self._handle.controlWrite(Panda.REQUEST_OUT, 0xd9, int(on), 0, b'')
2017-08-23 05:17:59 +08:00
def esp_reset(self, bootmode=0):
self._handle.controlWrite(Panda.REQUEST_OUT, 0xda, int(bootmode), 0, b'')
time.sleep(0.2)
def set_safety_mode(self, mode=SAFETY_SILENT, param=0):
self._handle.controlWrite(Panda.REQUEST_OUT, 0xdc, mode, param, b'')
2017-07-19 12:05:09 +08:00
def set_gmlan(self, bus=2):
Black (#254) * late usb * Added type support for black panda * Added harness presence and orientation detection * harness relay driving code * Added intercept support in black panda code. Switched around can0 and can2 * Disable ADCs after orientation detection. Ignition interrupts via harness * WIP: Hardware abstraction layer + black panda bringup * Fixed bootstub build * Fixed bootstub for pedal * Fixed infinite loops * Got CAN buses working on white again * Fixed pedal build and black can interfaces * Got CAN buses working on black panda * Finished loopback test for black panda * Erase all flash sectors on the panda. Increased binary limit. Added extra python functions. * Fixed python * Made new code MISRA compliant * Cleaned up ignition. Fixed build * Fixed health packet * Fixed CAN mode on black bug. Changed OBD to switch on ELM mode * Fixes from Github review * Fixed MISRA issue for pedal * Fixed failing gmlan tests * ELM327 safety: allow diagnostic on all buses * Cleaned up EON relay code * delete only 3 sectors instead of 11 to allow a new build to be flashed. Much faster to flash * Removed CAN only can0 output mode. Does not make sense on black panda due to reversibility issues. * Added heartbeat logic for EON code on panda. Go to NOOUTPUT if EON does not send a heartbeat for 5 seconds. * Remove all CAN buses live on EON startup. Shouldn't be necessary to have this separate case * Formatting * Added file I forgot to push * Added heartbeat to testing code to make sure EON tests don't fail. Should probably find a better way to do this though. Heartbeat thread didn't work, concurrent USB connection issues... * Safety: support black panda for Honda Bosch * Disable OBD2 if setting to NOOUTPUT mode * Run safety tests for all hw_types * Fail test if subtest fails * fix safety tests
2019-07-24 06:07:06 +08:00
# TODO: check panda type
2017-07-19 12:05:09 +08:00
if bus is None:
self._handle.controlWrite(Panda.REQUEST_OUT, 0xdb, 0, 0, b'')
2022-05-12 20:22:58 +08:00
elif bus in (Panda.GMLAN_CAN2, Panda.GMLAN_CAN3):
2017-07-19 12:05:09 +08:00
self._handle.controlWrite(Panda.REQUEST_OUT, 0xdb, 1, bus, b'')
2017-04-07 09:11:36 +08:00
Black (#254) * late usb * Added type support for black panda * Added harness presence and orientation detection * harness relay driving code * Added intercept support in black panda code. Switched around can0 and can2 * Disable ADCs after orientation detection. Ignition interrupts via harness * WIP: Hardware abstraction layer + black panda bringup * Fixed bootstub build * Fixed bootstub for pedal * Fixed infinite loops * Got CAN buses working on white again * Fixed pedal build and black can interfaces * Got CAN buses working on black panda * Finished loopback test for black panda * Erase all flash sectors on the panda. Increased binary limit. Added extra python functions. * Fixed python * Made new code MISRA compliant * Cleaned up ignition. Fixed build * Fixed health packet * Fixed CAN mode on black bug. Changed OBD to switch on ELM mode * Fixes from Github review * Fixed MISRA issue for pedal * Fixed failing gmlan tests * ELM327 safety: allow diagnostic on all buses * Cleaned up EON relay code * delete only 3 sectors instead of 11 to allow a new build to be flashed. Much faster to flash * Removed CAN only can0 output mode. Does not make sense on black panda due to reversibility issues. * Added heartbeat logic for EON code on panda. Go to NOOUTPUT if EON does not send a heartbeat for 5 seconds. * Remove all CAN buses live on EON startup. Shouldn't be necessary to have this separate case * Formatting * Added file I forgot to push * Added heartbeat to testing code to make sure EON tests don't fail. Should probably find a better way to do this though. Heartbeat thread didn't work, concurrent USB connection issues... * Safety: support black panda for Honda Bosch * Disable OBD2 if setting to NOOUTPUT mode * Run safety tests for all hw_types * Fail test if subtest fails * fix safety tests
2019-07-24 06:07:06 +08:00
def set_obd(self, obd):
# TODO: check panda type
self._handle.controlWrite(Panda.REQUEST_OUT, 0xdb, int(obd), 0, b'')
def set_can_loopback(self, enable):
2017-07-18 06:29:31 +08:00
# set can loopback mode for all buses
self._handle.controlWrite(Panda.REQUEST_OUT, 0xe5, int(enable), 0, b'')
def set_can_enable(self, bus_num, enable):
2020-09-28 22:19:09 +08:00
# sets the can transceiver enable pin
self._handle.controlWrite(Panda.REQUEST_OUT, 0xf4, int(bus_num), int(enable), b'')
2017-07-18 10:43:30 +08:00
def set_can_speed_kbps(self, bus, speed):
self._handle.controlWrite(Panda.REQUEST_OUT, 0xde, bus, int(speed * 10), b'')
2017-07-18 10:43:30 +08:00
def set_can_data_speed_kbps(self, bus, speed):
self._handle.controlWrite(Panda.REQUEST_OUT, 0xf9, bus, int(speed * 10), b'')
def set_canfd_non_iso(self, bus, non_iso):
self._handle.controlWrite(Panda.REQUEST_OUT, 0xfc, bus, int(non_iso), b'')
2017-04-26 06:16:23 +08:00
def set_uart_baud(self, uart, rate):
self._handle.controlWrite(Panda.REQUEST_OUT, 0xe4, uart, int(rate / 300), b'')
2017-04-26 06:16:23 +08:00
def set_uart_parity(self, uart, parity):
# parity, 0=off, 1=even, 2=odd
self._handle.controlWrite(Panda.REQUEST_OUT, 0xe2, uart, parity, b'')
2017-04-26 06:16:23 +08:00
2017-04-26 11:23:05 +08:00
def set_uart_callback(self, uart, install):
self._handle.controlWrite(Panda.REQUEST_OUT, 0xe3, uart, int(install), b'')
2017-04-26 11:23:05 +08:00
2017-04-26 06:16:23 +08:00
# ******************* can *******************
# The panda will NAK CAN writes when there is CAN congestion.
# libusb will try to send it again, with a max timeout.
# Timeout is in ms. If set to 0, the timeout is infinite.
CAN_SEND_TIMEOUT_MS = 10
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):
CAN_FIFOMailBox to CANPacket struct + USB dynamic packet size (#739) * Squashed commits, no cleanup * Few fixes * No init = garbage * Only receive with new canpacket * Add send with canpacket * Revert "Add send with canpacket" This reverts commit 7d06686ddd6d447c714b5289d31af24403d36931. * Packet must be aligned to word, or bad performance * Cleaner * Fix tests * Tests... * MISRA 10.4 * More MISRA * libpandasafety_py * cffi * even more tests... * typo * ... * ... * ... * Slight cleanup * MISRA 6.1 * MISRA 17.7 * Bug in bxcan + even style * MISRA 10.1 * Revert "MISRA 10.1" This reverts commit 404ae7fcc39556f80f528de9015702e69f4ea0a5. * ... * MISRA 10.1 and 10.4 suppress until next PR * MISRA 20.1 * ... * test_honda * ... * ... * test_toyota * test_volkswagen_mqb * test_volkswagen_pq * Sketchy thing... * Revert "Sketchy thing..." This reverts commit 3b2e5715bdc1954f7b7b3b7469ba3d0eaa06bdf9. * remove comment * bxcan extended address bug * Concept, experimental dynamic usb packet size * increase each buffer to 10240 bytes * raise python bulk read/write limits * ... * Move packet size to start * Experimental send, stream-like * New receive test, stream-like * cleanup * cleanup + rebase fixes * MISRA * Extra receive method, stream-like, commented out * type change * Revert back to buffer for send, stream commented * forgot ZLP * lower buffer, add rx failsafe * ... remove ZLP * return ZLP back * Add tx checks to panda fw * TX stream with counter * fix counter overflow * 13 free slots should be enough * limit tx usb packet * ... * Revert max_bulk_msg doubling * python lib improve speed * Stream with counter for RX, dirty, needs cleanup * Increase chunk length to 4096 bytes * cleanup fdcan.h * cleanup __init__.py * MISRA 12.1 * MISRA 10.8 * remove non-streaming usb functions * more main.c cleanup * MISRA 15.6 * MISRA 15.5 * MISRA 18.4 and suppress objectIndex * handling usb pakcets > 63bytes, naming and cleanup * Cleanup old from tests and update CANPacket_t struct * Switch to 4 bit DLC instead of 6 bit length * ops) * ... * pylint * receive python buffer increase * USB increase receive packet len * tweak buffers * No need for so high limits * MISRA 20.1 workaround * performance tweaks * cleanup, dlc to data_len_code naming * main.c naming * comments and cleanup for main.c usb * clean py lib * pylint * do not discard good rx messages on stream fail * cleanups * naming * remove bitstruct lib and lower tx limit * bitstruct lefovers * fix bug in VW test * remove adjusting data size and assert on wrong len * ... * test new memcpy before merging * Revert "test new memcpy before merging" This reverts commit 399465a264835061adabdd785718c4b6fc18c267. * macros for to/fromuint8_t array * MISRA hates me! * tests.c include macros instead * move CANPacket to can_definitions.h * vw_pq python test fix * new memcpy test, REMOVE * check without alignment * revert macros for uint8 arrays * Revert "revert macros for uint8 arrays" This reverts commit 581a9db735a42d0d68200bd270d87a8fd34e43fe. * check assert * Revert "check assert" This reverts commit 9e970d029a50597a1718b2bb0260196c050fd77f. * one more variation * Revert "one more variation" This reverts commit f6c0528b7ac7e125750dc0d9445c7ce97f6954b5. * what about read performance * Revert "what about read performance" This reverts commit d2610f90958a816fe7f1822157a84f85e97d9249. * check struct alignment to word * check for aligned memcpy again * cleanup * add CANPacket structure diagram * update CANPacket and add USB packet struct * bugfix + refactoring of EP1 * move dlc_to_len to header * missed include * typo... * MISRA * fk * lower MAX_CAN_MSGS_PER_BULK_TRANSFER * bump CAN_PACKET_VERSION to 2 * bump python lib CAN_PACKET_VERSION to 2 * rename parse_can_buffer to unpack_can_buffer * CANPacket_t const fields * Revert "CANPacket_t const fields" This reverts commit cf91c035b7706a14e317550c5f0501ae3fce7c70. * test.c relative path * cleanup * move macros to safety_declarations * Refactor pack/unpack funcs and add unittest * usb_protocol.h * oops * Update .github/workflows/test.yaml Co-authored-by: Adeeb Shihadeh <adeebshihadeh@gmail.com> * remove print from unittest Co-authored-by: Adeeb Shihadeh <adeebshihadeh@gmail.com>
2021-11-13 08:36:34 +08:00
snds = pack_can_buffer(arr)
while True:
2017-04-07 09:11:36 +08:00
try:
for tx in snds:
while True:
bs = self._handle.bulkWrite(3, tx, timeout=timeout)
tx = tx[bs:]
if len(tx) == 0:
break
logging.error("CAN: PARTIAL SEND MANY, RETRYING")
2017-04-07 09:11:36 +08:00
break
except (usb1.USBErrorIO, usb1.USBErrorOverflow):
logging.error("CAN: BAD SEND MANY, RETRYING")
2017-04-07 09:11:36 +08:00
def can_send(self, addr, dat, bus, timeout=CAN_SEND_TIMEOUT_MS):
self.can_send_many([[addr, None, dat, bus]], timeout=timeout)
2017-04-07 09:11:36 +08:00
@ensure_can_packet_version
2017-04-07 09:11:36 +08:00
def can_recv(self):
dat = bytearray()
while True:
2017-04-07 09:11:36 +08:00
try:
CAN_FIFOMailBox to CANPacket struct + USB dynamic packet size (#739) * Squashed commits, no cleanup * Few fixes * No init = garbage * Only receive with new canpacket * Add send with canpacket * Revert "Add send with canpacket" This reverts commit 7d06686ddd6d447c714b5289d31af24403d36931. * Packet must be aligned to word, or bad performance * Cleaner * Fix tests * Tests... * MISRA 10.4 * More MISRA * libpandasafety_py * cffi * even more tests... * typo * ... * ... * ... * Slight cleanup * MISRA 6.1 * MISRA 17.7 * Bug in bxcan + even style * MISRA 10.1 * Revert "MISRA 10.1" This reverts commit 404ae7fcc39556f80f528de9015702e69f4ea0a5. * ... * MISRA 10.1 and 10.4 suppress until next PR * MISRA 20.1 * ... * test_honda * ... * ... * test_toyota * test_volkswagen_mqb * test_volkswagen_pq * Sketchy thing... * Revert "Sketchy thing..." This reverts commit 3b2e5715bdc1954f7b7b3b7469ba3d0eaa06bdf9. * remove comment * bxcan extended address bug * Concept, experimental dynamic usb packet size * increase each buffer to 10240 bytes * raise python bulk read/write limits * ... * Move packet size to start * Experimental send, stream-like * New receive test, stream-like * cleanup * cleanup + rebase fixes * MISRA * Extra receive method, stream-like, commented out * type change * Revert back to buffer for send, stream commented * forgot ZLP * lower buffer, add rx failsafe * ... remove ZLP * return ZLP back * Add tx checks to panda fw * TX stream with counter * fix counter overflow * 13 free slots should be enough * limit tx usb packet * ... * Revert max_bulk_msg doubling * python lib improve speed * Stream with counter for RX, dirty, needs cleanup * Increase chunk length to 4096 bytes * cleanup fdcan.h * cleanup __init__.py * MISRA 12.1 * MISRA 10.8 * remove non-streaming usb functions * more main.c cleanup * MISRA 15.6 * MISRA 15.5 * MISRA 18.4 and suppress objectIndex * handling usb pakcets > 63bytes, naming and cleanup * Cleanup old from tests and update CANPacket_t struct * Switch to 4 bit DLC instead of 6 bit length * ops) * ... * pylint * receive python buffer increase * USB increase receive packet len * tweak buffers * No need for so high limits * MISRA 20.1 workaround * performance tweaks * cleanup, dlc to data_len_code naming * main.c naming * comments and cleanup for main.c usb * clean py lib * pylint * do not discard good rx messages on stream fail * cleanups * naming * remove bitstruct lib and lower tx limit * bitstruct lefovers * fix bug in VW test * remove adjusting data size and assert on wrong len * ... * test new memcpy before merging * Revert "test new memcpy before merging" This reverts commit 399465a264835061adabdd785718c4b6fc18c267. * macros for to/fromuint8_t array * MISRA hates me! * tests.c include macros instead * move CANPacket to can_definitions.h * vw_pq python test fix * new memcpy test, REMOVE * check without alignment * revert macros for uint8 arrays * Revert "revert macros for uint8 arrays" This reverts commit 581a9db735a42d0d68200bd270d87a8fd34e43fe. * check assert * Revert "check assert" This reverts commit 9e970d029a50597a1718b2bb0260196c050fd77f. * one more variation * Revert "one more variation" This reverts commit f6c0528b7ac7e125750dc0d9445c7ce97f6954b5. * what about read performance * Revert "what about read performance" This reverts commit d2610f90958a816fe7f1822157a84f85e97d9249. * check struct alignment to word * check for aligned memcpy again * cleanup * add CANPacket structure diagram * update CANPacket and add USB packet struct * bugfix + refactoring of EP1 * move dlc_to_len to header * missed include * typo... * MISRA * fk * lower MAX_CAN_MSGS_PER_BULK_TRANSFER * bump CAN_PACKET_VERSION to 2 * bump python lib CAN_PACKET_VERSION to 2 * rename parse_can_buffer to unpack_can_buffer * CANPacket_t const fields * Revert "CANPacket_t const fields" This reverts commit cf91c035b7706a14e317550c5f0501ae3fce7c70. * test.c relative path * cleanup * move macros to safety_declarations * Refactor pack/unpack funcs and add unittest * usb_protocol.h * oops * Update .github/workflows/test.yaml Co-authored-by: Adeeb Shihadeh <adeebshihadeh@gmail.com> * remove print from unittest Co-authored-by: Adeeb Shihadeh <adeebshihadeh@gmail.com>
2021-11-13 08:36:34 +08:00
dat = self._handle.bulkRead(1, 16384) # Max receive batch size + 2 extra reserve frames
2017-04-07 09:11:36 +08:00
break
except (usb1.USBErrorIO, usb1.USBErrorOverflow):
logging.error("CAN: BAD RECV, RETRYING")
time.sleep(0.1)
msgs, self.can_rx_overflow_buffer = unpack_can_buffer(self.can_rx_overflow_buffer + dat)
return msgs
2017-04-07 09:11:36 +08:00
def can_clear(self, bus):
"""Clears all messages from the specified internal CAN ringbuffer as
though it were drained.
Args:
bus (int): can bus number to clear a tx queue, or 0xFFFF to clear the
global can rx queue.
"""
self._handle.controlWrite(Panda.REQUEST_OUT, 0xf1, bus, 0, b'')
2018-03-10 09:40:03 +08:00
# ******************* isotp *******************
2018-03-11 02:16:53 +08:00
def isotp_send(self, addr, dat, bus, recvaddr=None, subaddr=None):
2018-03-10 09:40:03 +08:00
return isotp_send(self, dat, addr, bus, recvaddr, subaddr)
2018-03-11 02:16:53 +08:00
def isotp_recv(self, addr, bus=0, sendaddr=None, subaddr=None):
2018-03-11 02:17:57 +08:00
return isotp_recv(self, addr, bus, sendaddr, subaddr)
2018-03-10 09:40:03 +08:00
2017-04-07 09:11:36 +08:00
# ******************* serial *******************
def serial_read(self, port_number):
2017-07-19 03:15:19 +08:00
ret = []
while 1:
lret = bytes(self._handle.controlRead(Panda.REQUEST_IN, 0xe0, port_number, 0, 0x40))
if len(lret) == 0:
break
ret.append(lret)
return b''.join(ret)
2017-04-07 09:11:36 +08:00
def serial_write(self, port_number, ln):
2018-01-20 03:04:21 +08:00
ret = 0
if type(ln) == str:
ln = bytes(ln, 'utf-8')
2018-01-20 03:04:21 +08:00
for i in range(0, len(ln), 0x20):
ret += self._handle.bulkWrite(2, struct.pack("B", port_number) + ln[i:i + 0x20])
2018-01-20 03:04:21 +08:00
return ret
2017-04-07 09:11:36 +08:00
def serial_clear(self, port_number):
"""Clears all messages (tx and rx) from the specified internal uart
ringbuffer as though it were drained.
Args:
port_number (int): port number of the uart to clear.
"""
self._handle.controlWrite(Panda.REQUEST_OUT, 0xf2, port_number, 0, b'')
2017-04-07 09:11:36 +08:00
# ******************* kline *******************
# pulse low for wakeup
def kline_wakeup(self, k=True, l=True):
assert k or l, "must specify k-line, l-line, or both"
logging.debug("kline wakeup...")
self._handle.controlWrite(Panda.REQUEST_OUT, 0xf0, 2 if k and l else int(l), 0, b'')
logging.debug("kline wakeup done")
2017-04-07 09:11:36 +08:00
def kline_5baud(self, addr, k=True, l=True):
assert k or l, "must specify k-line, l-line, or both"
logging.debug("kline 5 baud...")
self._handle.controlWrite(Panda.REQUEST_OUT, 0xf4, 2 if k and l else int(l), addr, b'')
logging.debug("kline 5 baud done")
2017-04-07 09:11:36 +08:00
def kline_drain(self, bus=2):
# drain buffer
bret = bytearray()
while True:
2017-07-18 09:59:16 +08:00
ret = self._handle.controlRead(Panda.REQUEST_IN, 0xe0, bus, 0, 0x40)
2017-04-07 09:11:36 +08:00
if len(ret) == 0:
break
logging.debug(f"kline drain: 0x{ret.hex()}")
bret += ret
2017-06-29 05:50:00 +08:00
return bytes(bret)
2017-04-07 09:11:36 +08:00
def kline_ll_recv(self, cnt, bus=2):
echo = bytearray()
2017-04-07 09:11:36 +08:00
while len(echo) != cnt:
ret = self._handle.controlRead(Panda.REQUEST_OUT, 0xe0, bus, 0, cnt - len(echo))
if len(ret) > 0:
logging.debug(f"kline recv: 0x{ret.hex()}")
2018-03-01 09:03:04 +08:00
echo += ret
2020-06-15 00:22:39 +08:00
return bytes(echo)
2017-04-07 09:11:36 +08:00
def kline_send(self, x, bus=2, checksum=True):
self.kline_drain(bus=bus)
if checksum:
x += bytes([sum(x) % 0x100])
2017-04-18 22:34:56 +08:00
for i in range(0, len(x), 0xf):
ts = x[i:i + 0xf]
logging.debug(f"kline send: 0x{ts.hex()}")
self._handle.bulkWrite(2, bytes([bus]) + ts)
2017-04-07 09:11:36 +08:00
echo = self.kline_ll_recv(len(ts), bus=bus)
if echo != ts:
logging.error(f"**** ECHO ERROR {i} ****")
logging.error(f"0x{echo.hex()}")
logging.error(f"0x{ts.hex()}")
2017-04-07 09:11:36 +08:00
assert echo == ts
def kline_recv(self, bus=2, header_len=4):
# read header (last byte is length)
msg = self.kline_ll_recv(header_len, bus=bus)
# read data (add one byte to length for checksum)
msg += self.kline_ll_recv(msg[-1]+1, bus=bus)
2017-04-07 09:11:36 +08:00
return msg
Black (#254) * late usb * Added type support for black panda * Added harness presence and orientation detection * harness relay driving code * Added intercept support in black panda code. Switched around can0 and can2 * Disable ADCs after orientation detection. Ignition interrupts via harness * WIP: Hardware abstraction layer + black panda bringup * Fixed bootstub build * Fixed bootstub for pedal * Fixed infinite loops * Got CAN buses working on white again * Fixed pedal build and black can interfaces * Got CAN buses working on black panda * Finished loopback test for black panda * Erase all flash sectors on the panda. Increased binary limit. Added extra python functions. * Fixed python * Made new code MISRA compliant * Cleaned up ignition. Fixed build * Fixed health packet * Fixed CAN mode on black bug. Changed OBD to switch on ELM mode * Fixes from Github review * Fixed MISRA issue for pedal * Fixed failing gmlan tests * ELM327 safety: allow diagnostic on all buses * Cleaned up EON relay code * delete only 3 sectors instead of 11 to allow a new build to be flashed. Much faster to flash * Removed CAN only can0 output mode. Does not make sense on black panda due to reversibility issues. * Added heartbeat logic for EON code on panda. Go to NOOUTPUT if EON does not send a heartbeat for 5 seconds. * Remove all CAN buses live on EON startup. Shouldn't be necessary to have this separate case * Formatting * Added file I forgot to push * Added heartbeat to testing code to make sure EON tests don't fail. Should probably find a better way to do this though. Heartbeat thread didn't work, concurrent USB connection issues... * Safety: support black panda for Honda Bosch * Disable OBD2 if setting to NOOUTPUT mode * Run safety tests for all hw_types * Fail test if subtest fails * fix safety tests
2019-07-24 06:07:06 +08:00
def send_heartbeat(self, engaged=True):
self._handle.controlWrite(Panda.REQUEST_OUT, 0xf3, engaged, 0, b'')
# disable heartbeat checks for use outside of openpilot
# sending a heartbeat will reenable the checks
def set_heartbeat_disabled(self):
self._handle.controlWrite(Panda.REQUEST_OUT, 0xf8, 0, 0, b'')
# ******************* RTC *******************
def set_datetime(self, dt):
self._handle.controlWrite(Panda.REQUEST_OUT, 0xa1, int(dt.year), 0, b'')
self._handle.controlWrite(Panda.REQUEST_OUT, 0xa2, int(dt.month), 0, b'')
self._handle.controlWrite(Panda.REQUEST_OUT, 0xa3, int(dt.day), 0, b'')
self._handle.controlWrite(Panda.REQUEST_OUT, 0xa4, int(dt.isoweekday()), 0, b'')
self._handle.controlWrite(Panda.REQUEST_OUT, 0xa5, int(dt.hour), 0, b'')
self._handle.controlWrite(Panda.REQUEST_OUT, 0xa6, int(dt.minute), 0, b'')
self._handle.controlWrite(Panda.REQUEST_OUT, 0xa7, int(dt.second), 0, b'')
def get_datetime(self):
dat = self._handle.controlRead(Panda.REQUEST_IN, 0xa0, 0, 0, 8)
a = struct.unpack("HBBBBBB", dat)
return datetime.datetime(a[0], a[1], a[2], a[4], a[5], a[6])
# ****************** Timer *****************
def get_microsecond_timer(self):
dat = self._handle.controlRead(Panda.REQUEST_IN, 0xa8, 0, 0, 4)
return struct.unpack("I", dat)[0]
# ******************* IR *******************
def set_ir_power(self, percentage):
self._handle.controlWrite(Panda.REQUEST_OUT, 0xb0, int(percentage), 0, b'')
# ******************* Fan ******************
def set_fan_power(self, percentage):
self._handle.controlWrite(Panda.REQUEST_OUT, 0xb1, int(percentage), 0, b'')
def get_fan_rpm(self):
dat = self._handle.controlRead(Panda.REQUEST_IN, 0xb2, 0, 0, 2)
a = struct.unpack("H", dat)
return a[0]
# ****************** Phone *****************
def set_phone_power(self, enabled):
self._handle.controlWrite(Panda.REQUEST_OUT, 0xb3, int(enabled), 0, b'')
# ****************** Siren *****************
def set_siren(self, enabled):
self._handle.controlWrite(Panda.REQUEST_OUT, 0xf6, int(enabled), 0, b'')
# ****************** Debug *****************
def set_green_led(self, enabled):
self._handle.controlWrite(Panda.REQUEST_OUT, 0xf7, int(enabled), 0, b'')