2017-04-06 18:11:36 -07:00
|
|
|
# python library to interface with panda
|
2017-07-17 15:29:31 -07:00
|
|
|
import os
|
2022-08-23 22:29:35 -07:00
|
|
|
import sys
|
2017-07-17 15:29:31 -07:00
|
|
|
import time
|
2022-08-23 22:29:35 -07:00
|
|
|
import usb1
|
|
|
|
|
import struct
|
|
|
|
|
import hashlib
|
2023-01-15 20:13:26 -08:00
|
|
|
import binascii
|
2022-08-23 22:29:35 -07:00
|
|
|
import datetime
|
2022-11-10 21:34:43 -08:00
|
|
|
import logging
|
2023-08-30 10:56:30 -07:00
|
|
|
from functools import wraps, partial
|
2022-05-12 14:22:58 +02:00
|
|
|
from typing import Optional
|
2022-08-03 06:58:56 +02:00
|
|
|
from itertools import accumulate
|
2022-11-03 22:18:12 -07:00
|
|
|
|
2023-03-07 13:47:55 -08:00
|
|
|
from .base import BaseHandle
|
2023-05-21 21:19:19 -07:00
|
|
|
from .constants import FW_PATH, McuType
|
2023-01-26 20:54:11 -08:00
|
|
|
from .dfu import PandaDFU
|
2022-11-21 16:59:21 -08:00
|
|
|
from .isotp import isotp_send, isotp_recv
|
2023-07-16 19:33:18 -07:00
|
|
|
from .spi import PandaSpiHandle, PandaSpiException, PandaProtocolMismatch
|
2023-01-28 16:01:54 -08:00
|
|
|
from .usb import PandaUsbHandle
|
2017-04-06 18:11:36 -07: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-12 16:36:34 -08:00
|
|
|
__version__ = '0.0.10'
|
2017-06-13 18:50:47 -07:00
|
|
|
|
2022-11-10 21:34:43 -08:00
|
|
|
# setup logging
|
|
|
|
|
LOGLEVEL = os.environ.get('LOGLEVEL', 'INFO').upper()
|
|
|
|
|
logging.basicConfig(level=LOGLEVEL, format='%(message)s')
|
|
|
|
|
|
2023-01-13 10:59:58 -08:00
|
|
|
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-12 16: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)}
|
2024-01-25 22:17:19 +01:00
|
|
|
PANDA_BUS_CNT = 4
|
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-12 16:36:34 -08:00
|
|
|
|
2023-03-07 14:55:15 -08:00
|
|
|
|
2023-01-13 10:59:58 -08:00
|
|
|
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-12 16:36:34 -08:00
|
|
|
def pack_can_buffer(arr):
|
2023-01-13 10:59:58 -08:00
|
|
|
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-12 16:36:34 -08:00
|
|
|
for address, _, dat, bus in arr:
|
|
|
|
|
assert len(dat) in LEN_TO_DLC
|
2022-12-01 08:38:00 +01:00
|
|
|
#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-12 16:36:34 -08:00
|
|
|
extended = 1 if address >= 0x800 else 0
|
|
|
|
|
data_len_code = LEN_TO_DLC[len(dat)]
|
2023-01-13 10:59:58 -08:00
|
|
|
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-12 16: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
|
2023-01-13 10:59:58 -08:00
|
|
|
header[5] = calculate_checksum(header[:5] + dat)
|
2022-12-01 08:38:00 +01:00
|
|
|
|
|
|
|
|
snds[-1] += header + dat
|
|
|
|
|
if len(snds[-1]) > 256: # Limit chunks to 256 bytes
|
2023-01-13 10:59:58 -08:00
|
|
|
snds.append(b'')
|
2022-12-01 08:38:00 +01: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-12 16:36:34 -08:00
|
|
|
return snds
|
|
|
|
|
|
|
|
|
|
def unpack_can_buffer(dat):
|
|
|
|
|
ret = []
|
2022-12-01 08:38:00 +01:00
|
|
|
|
|
|
|
|
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
|
|
|
|
|
|
2023-01-13 10:59:58 -08:00
|
|
|
# we need more from the next transfer
|
|
|
|
|
if data_len > len(dat) - CANPACKET_HEAD_SIZE:
|
|
|
|
|
break
|
2022-12-01 08:38:00 +01:00
|
|
|
|
2023-01-13 10:59:58 -08:00
|
|
|
assert calculate_checksum(dat[:(CANPACKET_HEAD_SIZE+data_len)]) == 0, "CAN packet checksum incorrect"
|
2022-12-01 08:38:00 +01:00
|
|
|
|
2023-01-13 10:59:58 -08:00
|
|
|
data = dat[CANPACKET_HEAD_SIZE:(CANPACKET_HEAD_SIZE+data_len)]
|
|
|
|
|
dat = dat[(CANPACKET_HEAD_SIZE+data_len):]
|
2022-12-01 08:38:00 +01:00
|
|
|
|
2023-01-13 10:59:58 -08:00
|
|
|
ret.append((address, 0, data, bus))
|
2022-12-01 08:38:00 +01:00
|
|
|
|
2023-01-13 10:59:58 -08:00
|
|
|
return (ret, dat)
|
2017-05-16 17:01:29 -07:00
|
|
|
|
2021-11-11 05:30:52 -08:00
|
|
|
|
2023-08-30 10:56:30 -07:00
|
|
|
def ensure_version(desc, lib_field, panda_field, fn):
|
2021-11-11 05:30:52 -08:00
|
|
|
@wraps(fn)
|
|
|
|
|
def wrapper(self, *args, **kwargs):
|
2023-08-30 10:56:30 -07:00
|
|
|
lib_version = getattr(self, lib_field)
|
|
|
|
|
panda_version = getattr(self, panda_field)
|
|
|
|
|
if lib_version != panda_version:
|
|
|
|
|
raise RuntimeError(f"{desc} packet version mismatch: panda's firmware v{panda_version}, library v{lib_version}. Reflash panda.")
|
2021-11-11 05:30:52 -08:00
|
|
|
return fn(self, *args, **kwargs)
|
|
|
|
|
return wrapper
|
2023-08-30 10:56:30 -07:00
|
|
|
ensure_can_packet_version = partial(ensure_version, "CAN", "CAN_PACKET_VERSION", "can_version")
|
|
|
|
|
ensure_can_health_packet_version = partial(ensure_version, "CAN health", "CAN_HEALTH_PACKET_VERSION", "can_health_version")
|
|
|
|
|
ensure_health_packet_version = partial(ensure_version, "health", "HEALTH_PACKET_VERSION", "health_version")
|
|
|
|
|
|
2021-11-11 05:30:52 -08:00
|
|
|
|
2022-09-15 13:04:10 -07:00
|
|
|
|
2022-04-04 18:49:56 -07:00
|
|
|
class ALTERNATIVE_EXPERIENCE:
|
|
|
|
|
DEFAULT = 0
|
|
|
|
|
DISABLE_DISENGAGE_ON_GAS = 1
|
|
|
|
|
DISABLE_STOCK_AEB = 2
|
|
|
|
|
RAISE_LONGITUDINAL_LIMITS_TO_ISO_MAX = 8
|
2024-01-11 15:37:43 -08:00
|
|
|
ALLOW_AEB = 16
|
2022-04-04 18:49:56 -07:00
|
|
|
|
2022-05-12 14:22:58 +02:00
|
|
|
class Panda:
|
2019-10-02 18:20:32 -07:00
|
|
|
|
|
|
|
|
# matches cereal.car.CarParams.SafetyModel
|
2019-11-20 11:56:26 -08:00
|
|
|
SAFETY_SILENT = 0
|
2019-12-20 15:51:32 -08:00
|
|
|
SAFETY_HONDA_NIDEC = 1
|
2017-09-30 19:20:33 -07:00
|
|
|
SAFETY_TOYOTA = 2
|
2019-10-02 18:20:32 -07:00
|
|
|
SAFETY_ELM327 = 3
|
|
|
|
|
SAFETY_GM = 4
|
2019-12-20 15:51:32 -08:00
|
|
|
SAFETY_HONDA_BOSCH_GIRAFFE = 5
|
2019-10-02 18:20:32 -07:00
|
|
|
SAFETY_FORD = 6
|
|
|
|
|
SAFETY_HYUNDAI = 8
|
2018-11-06 12:28:33 -08:00
|
|
|
SAFETY_CHRYSLER = 9
|
2019-10-02 18:20:32 -07:00
|
|
|
SAFETY_TESLA = 10
|
|
|
|
|
SAFETY_SUBARU = 11
|
|
|
|
|
SAFETY_MAZDA = 13
|
2020-02-27 04:11:56 +09:00
|
|
|
SAFETY_NISSAN = 14
|
2020-02-19 15:37:38 -05:00
|
|
|
SAFETY_VOLKSWAGEN_MQB = 15
|
2019-10-02 18:20:32 -07:00
|
|
|
SAFETY_ALLOUTPUT = 17
|
|
|
|
|
SAFETY_GM_ASCM = 18
|
2019-11-20 11:56:26 -08:00
|
|
|
SAFETY_NOOUTPUT = 19
|
2021-11-21 14:51:47 -08:00
|
|
|
SAFETY_HONDA_BOSCH = 20
|
2020-04-01 12:38:27 -07:00
|
|
|
SAFETY_VOLKSWAGEN_PQ = 21
|
2023-05-15 20:22:40 -04:00
|
|
|
SAFETY_SUBARU_PREGLOBAL = 22
|
2020-06-12 18:03:31 -07:00
|
|
|
SAFETY_HYUNDAI_LEGACY = 23
|
2022-03-31 12:02:19 -07:00
|
|
|
SAFETY_HYUNDAI_COMMUNITY = 24
|
|
|
|
|
SAFETY_STELLANTIS = 25
|
|
|
|
|
SAFETY_FAW = 26
|
|
|
|
|
SAFETY_BODY = 27
|
2022-08-11 22:06:54 -07:00
|
|
|
SAFETY_HYUNDAI_CANFD = 28
|
2017-07-17 15:29:31 -07:00
|
|
|
|
2017-07-18 12:15:19 -07:00
|
|
|
SERIAL_DEBUG = 0
|
|
|
|
|
SERIAL_ESP = 1
|
|
|
|
|
SERIAL_LIN1 = 2
|
|
|
|
|
SERIAL_LIN2 = 3
|
2022-11-17 17:59:11 +01:00
|
|
|
SERIAL_SOM_DEBUG = 4
|
2017-07-18 12:15:19 -07:00
|
|
|
|
2017-07-18 21:05:09 -07:00
|
|
|
GMLAN_CAN2 = 1
|
|
|
|
|
GMLAN_CAN3 = 2
|
|
|
|
|
|
2023-08-03 23:55:13 -07:00
|
|
|
USB_PIDS = (0xddee, 0xddcc)
|
2017-07-17 18:59:16 -07:00
|
|
|
REQUEST_IN = usb1.ENDPOINT_IN | usb1.TYPE_VENDOR | usb1.RECIPIENT_DEVICE
|
2017-07-17 18:58:04 -07:00
|
|
|
REQUEST_OUT = usb1.ENDPOINT_OUT | usb1.TYPE_VENDOR | usb1.RECIPIENT_DEVICE
|
2017-06-13 18:50:47 -07:00
|
|
|
|
2019-09-27 15:22:13 -07:00
|
|
|
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'
|
2019-10-25 16:22:42 -07:00
|
|
|
HW_TYPE_UNO = b'\x05'
|
2021-07-08 00:37:14 -07:00
|
|
|
HW_TYPE_DOS = b'\x06'
|
2021-08-02 20:26:15 -07:00
|
|
|
HW_TYPE_RED_PANDA = b'\x07'
|
2022-09-09 20:13:06 -07:00
|
|
|
HW_TYPE_RED_PANDA_V2 = b'\x08'
|
2022-11-03 16:34:18 -07:00
|
|
|
HW_TYPE_TRES = b'\x09'
|
2024-01-24 13:07:47 -08:00
|
|
|
HW_TYPE_CUATRO = b'\x0a'
|
2021-08-02 20:26:15 -07:00
|
|
|
|
2023-01-13 10:59:58 -08:00
|
|
|
CAN_PACKET_VERSION = 4
|
2023-12-14 15:22:17 -08:00
|
|
|
HEALTH_PACKET_VERSION = 15
|
2023-06-28 14:40:00 -07:00
|
|
|
CAN_HEALTH_PACKET_VERSION = 5
|
2023-12-14 15:22:17 -08:00
|
|
|
HEALTH_STRUCT = struct.Struct("<IIIIIIIIIBBBBBHBBBHfBBHBHHB")
|
2023-06-28 14:40:00 -07:00
|
|
|
CAN_HEALTH_STRUCT = struct.Struct("<BIBBBBBBBBIIIIIIIHHBBBIIII")
|
2021-11-11 05:30:52 -08:00
|
|
|
|
2023-08-03 23:55:13 -07:00
|
|
|
F4_DEVICES = [HW_TYPE_WHITE_PANDA, HW_TYPE_GREY_PANDA, HW_TYPE_BLACK_PANDA, HW_TYPE_UNO, HW_TYPE_DOS]
|
2024-01-24 13:07:47 -08:00
|
|
|
H7_DEVICES = [HW_TYPE_RED_PANDA, HW_TYPE_RED_PANDA_V2, HW_TYPE_TRES, HW_TYPE_CUATRO]
|
2019-08-28 12:57:42 -07:00
|
|
|
|
2024-01-24 13:07:47 -08:00
|
|
|
INTERNAL_DEVICES = (HW_TYPE_UNO, HW_TYPE_DOS, HW_TYPE_TRES, HW_TYPE_CUATRO)
|
|
|
|
|
HAS_OBD = (HW_TYPE_BLACK_PANDA, HW_TYPE_UNO, HW_TYPE_DOS, HW_TYPE_RED_PANDA, HW_TYPE_RED_PANDA_V2, HW_TYPE_TRES, HW_TYPE_CUATRO)
|
2022-08-30 10:46:12 -07:00
|
|
|
|
2023-04-18 14:15:06 -07:00
|
|
|
MAX_FAN_RPMs = {
|
|
|
|
|
HW_TYPE_UNO: 5100,
|
|
|
|
|
HW_TYPE_DOS: 6500,
|
|
|
|
|
HW_TYPE_TRES: 6600,
|
2024-01-24 13:07:47 -08:00
|
|
|
HW_TYPE_CUATRO: 6600,
|
2023-04-18 14:15:06 -07:00
|
|
|
}
|
|
|
|
|
|
2023-05-08 13:30:23 +02:00
|
|
|
HARNESS_STATUS_NC = 0
|
|
|
|
|
HARNESS_STATUS_NORMAL = 1
|
|
|
|
|
HARNESS_STATUS_FLIPPED = 2
|
|
|
|
|
|
2022-04-28 22:29:29 -07:00
|
|
|
# first byte is for EPS scaling factor
|
2022-04-28 17:40:50 -07:00
|
|
|
FLAG_TOYOTA_ALT_BRAKE = (1 << 8)
|
2022-04-28 22:29:29 -07:00
|
|
|
FLAG_TOYOTA_STOCK_LONGITUDINAL = (2 << 8)
|
2023-03-16 22:32:56 -07:00
|
|
|
FLAG_TOYOTA_LTA = (4 << 8)
|
2023-12-14 15:22:17 -08:00
|
|
|
FLAG_TOYOTA_GAS_INTERCEPTOR = (8 << 8)
|
2022-04-27 11:31:24 -07:00
|
|
|
|
2021-06-22 15:29:47 +02:00
|
|
|
FLAG_HONDA_ALT_BRAKE = 1
|
|
|
|
|
FLAG_HONDA_BOSCH_LONG = 2
|
2021-11-17 17:27:24 -08:00
|
|
|
FLAG_HONDA_NIDEC_ALT = 4
|
2022-06-16 19:02:44 -07:00
|
|
|
FLAG_HONDA_RADARLESS = 8
|
2023-12-14 15:22:17 -08:00
|
|
|
FLAG_HONDA_GAS_INTERCEPTOR = 16
|
2021-11-17 17:27:24 -08:00
|
|
|
|
|
|
|
|
FLAG_HYUNDAI_EV_GAS = 1
|
|
|
|
|
FLAG_HYUNDAI_HYBRID_GAS = 2
|
2021-09-13 20:41:10 -07:00
|
|
|
FLAG_HYUNDAI_LONG = 4
|
2022-08-03 03:54:41 -04:00
|
|
|
FLAG_HYUNDAI_CAMERA_SCC = 8
|
2022-11-07 22:13:17 -08:00
|
|
|
FLAG_HYUNDAI_CANFD_HDA2 = 16
|
|
|
|
|
FLAG_HYUNDAI_CANFD_ALT_BUTTONS = 32
|
2022-12-02 23:34:06 -08:00
|
|
|
FLAG_HYUNDAI_ALT_LIMITS = 64
|
2023-08-30 02:40:14 -04:00
|
|
|
FLAG_HYUNDAI_CANFD_HDA2_ALT_STEERING = 128
|
2022-08-19 22:43:58 -04:00
|
|
|
|
2021-11-18 13:50:10 +01:00
|
|
|
FLAG_TESLA_POWERTRAIN = 1
|
|
|
|
|
FLAG_TESLA_LONG_CONTROL = 2
|
2021-06-22 15:29:47 +02:00
|
|
|
|
2022-08-12 21:50:00 -04:00
|
|
|
FLAG_VOLKSWAGEN_LONG_CONTROL = 1
|
|
|
|
|
|
2022-07-06 22:50:29 -07:00
|
|
|
FLAG_CHRYSLER_RAM_DT = 1
|
2022-08-11 14:41:46 -07:00
|
|
|
FLAG_CHRYSLER_RAM_HD = 2
|
2022-07-06 22:50:29 -07:00
|
|
|
|
2022-07-29 20:44:41 -07:00
|
|
|
FLAG_SUBARU_GEN2 = 1
|
2023-08-15 18:51:13 -07:00
|
|
|
FLAG_SUBARU_LONG = 2
|
2022-07-29 20:44:41 -07:00
|
|
|
|
2023-11-08 18:27:20 -05:00
|
|
|
FLAG_SUBARU_PREGLOBAL_REVERSED_DRIVER_TORQUE = 1
|
|
|
|
|
|
2023-09-06 03:46:33 -04:00
|
|
|
FLAG_NISSAN_ALT_EPS_BUS = 1
|
|
|
|
|
|
2022-08-12 18:56:39 -04:00
|
|
|
FLAG_GM_HW_CAM = 1
|
2022-11-01 03:58:18 -04:00
|
|
|
FLAG_GM_HW_CAM_LONG = 2
|
2022-08-12 18:56:39 -04:00
|
|
|
|
2023-05-18 00:21:29 -07:00
|
|
|
FLAG_FORD_LONG_CONTROL = 1
|
2023-07-16 15:09:37 +01:00
|
|
|
FLAG_FORD_CANFD = 2
|
2023-05-18 00:21:29 -07:00
|
|
|
|
2024-01-25 22:17:19 +01:00
|
|
|
def __init__(self, serial: Optional[str] = None, claim: bool = True, disable_checks: bool = True, can_speed_kbps: int = 500):
|
2023-03-05 20:19:27 -08:00
|
|
|
self._connect_serial = serial
|
2022-08-18 22:01:12 -07:00
|
|
|
self._disable_checks = disable_checks
|
|
|
|
|
|
2023-03-07 13:47:55 -08:00
|
|
|
self._handle: BaseHandle
|
|
|
|
|
self._handle_open = False
|
2023-01-13 10:59:58 -08:00
|
|
|
self.can_rx_overflow_buffer = b''
|
2024-01-25 22:17:19 +01:00
|
|
|
self._can_speed_kbps = can_speed_kbps
|
2023-01-13 10:59:58 -08:00
|
|
|
|
2022-08-02 22:28:54 -07:00
|
|
|
# connect and set mcu type
|
2017-07-24 15:16:22 -07:00
|
|
|
self.connect(claim)
|
|
|
|
|
|
2023-01-13 16:17:20 -08:00
|
|
|
def __enter__(self):
|
|
|
|
|
return self
|
|
|
|
|
|
|
|
|
|
def __exit__(self, *args):
|
|
|
|
|
self.close()
|
|
|
|
|
|
2017-07-24 15:16:22 -07:00
|
|
|
def close(self):
|
2023-03-07 13:47:55 -08:00
|
|
|
if self._handle_open:
|
|
|
|
|
self._handle.close()
|
|
|
|
|
self._handle_open = False
|
2023-08-24 19:15:37 -07:00
|
|
|
if self._context is not None:
|
|
|
|
|
self._context.close()
|
2017-07-24 15:16:22 -07:00
|
|
|
|
2017-07-29 17:21:22 -07:00
|
|
|
def connect(self, claim=True, wait=False):
|
2023-03-07 13:47:55 -08:00
|
|
|
self.close()
|
2017-04-06 18:11:36 -07:00
|
|
|
|
2023-06-11 19:06:46 -07:00
|
|
|
self._handle = None
|
|
|
|
|
while self._handle is None:
|
|
|
|
|
# try USB first, then SPI
|
2023-08-24 19:15:37 -07:00
|
|
|
self._context, self._handle, serial, self.bootstub, bcd = self.usb_connect(self._connect_serial, claim=claim)
|
2023-06-11 19:06:46 -07:00
|
|
|
if self._handle is None:
|
2023-08-24 19:15:37 -07:00
|
|
|
self._context, self._handle, serial, self.bootstub, bcd = self.spi_connect(self._connect_serial)
|
2023-06-11 19:06:46 -07:00
|
|
|
if not wait:
|
|
|
|
|
break
|
2022-11-03 22:18:12 -07:00
|
|
|
|
2023-01-22 21:49:14 -08:00
|
|
|
if self._handle is None:
|
|
|
|
|
raise Exception("failed to connect to panda")
|
|
|
|
|
|
2023-01-28 14:41:52 -08:00
|
|
|
# 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
|
|
|
|
|
|
2023-01-22 21:49:14 -08:00
|
|
|
self._serial = serial
|
2023-03-05 20:19:27 -08:00
|
|
|
self._connect_serial = serial
|
2023-03-07 13:47:55 -08:00
|
|
|
self._handle_open = True
|
2022-11-03 22:18:12 -07:00
|
|
|
self._mcu_type = self.get_mcu_type()
|
|
|
|
|
self.health_version, self.can_version, self.can_health_version = self.get_packets_versions()
|
2023-01-15 23:51:25 -08:00
|
|
|
logging.debug("connected")
|
2022-11-03 22:18:12 -07:00
|
|
|
|
|
|
|
|
# disable openpilot's heartbeat checks
|
|
|
|
|
if self._disable_checks:
|
|
|
|
|
self.set_heartbeat_disabled()
|
|
|
|
|
self.set_power_save(0)
|
|
|
|
|
|
2024-01-25 22:17:19 +01:00
|
|
|
# reset comms
|
|
|
|
|
self.can_reset_communications()
|
|
|
|
|
|
|
|
|
|
# set CAN speed
|
|
|
|
|
for bus in range(PANDA_BUS_CNT):
|
|
|
|
|
self.set_can_speed_kbps(bus, self._can_speed_kbps)
|
|
|
|
|
|
2023-08-03 23:55:13 -07:00
|
|
|
@classmethod
|
|
|
|
|
def spi_connect(cls, serial, ignore_version=False):
|
2023-01-15 23:30:24 -08:00
|
|
|
# get UID to confirm slave is present and up
|
2023-01-22 21:49:14 -08:00
|
|
|
handle = None
|
2023-01-15 23:30:24 -08:00
|
|
|
spi_serial = None
|
2023-03-07 14:55:15 -08:00
|
|
|
bootstub = None
|
2023-07-16 19:33:18 -07:00
|
|
|
spi_version = None
|
2023-01-15 23:30:24 -08:00
|
|
|
try:
|
2023-01-28 16:01:54 -08:00
|
|
|
handle = PandaSpiHandle()
|
2023-07-16 19:33:18 -07:00
|
|
|
|
|
|
|
|
# connect by protcol version
|
|
|
|
|
try:
|
|
|
|
|
dat = handle.get_protocol_version()
|
|
|
|
|
spi_serial = binascii.hexlify(dat[:12]).decode()
|
|
|
|
|
pid = dat[13]
|
|
|
|
|
if pid not in (0xcc, 0xee):
|
|
|
|
|
raise PandaSpiException("invalid bootstub status")
|
|
|
|
|
bootstub = pid == 0xee
|
|
|
|
|
spi_version = dat[14]
|
|
|
|
|
except PandaSpiException:
|
|
|
|
|
# fallback, we'll raise a protocol mismatch below
|
|
|
|
|
dat = handle.controlRead(Panda.REQUEST_IN, 0xc3, 0, 0, 12, timeout=100)
|
|
|
|
|
spi_serial = binascii.hexlify(dat).decode()
|
|
|
|
|
bootstub = Panda.flasher_present(handle)
|
|
|
|
|
spi_version = 0
|
2023-01-15 23:30:24 -08:00
|
|
|
except PandaSpiException:
|
|
|
|
|
pass
|
|
|
|
|
|
2023-01-22 21:49:14 -08:00
|
|
|
# no connection or wrong panda
|
2023-03-07 14:55:15 -08:00
|
|
|
if None in (spi_serial, bootstub) or (serial is not None and (spi_serial != serial)):
|
2023-01-22 21:49:14 -08:00
|
|
|
handle = None
|
|
|
|
|
spi_serial = None
|
2023-03-07 14:55:15 -08:00
|
|
|
bootstub = False
|
2023-01-15 23:30:24 -08:00
|
|
|
|
2023-07-16 19:33:18 -07:00
|
|
|
# ensure our protocol version matches the panda
|
|
|
|
|
if handle is not None and not ignore_version:
|
|
|
|
|
if spi_version != handle.PROTOCOL_VERSION:
|
|
|
|
|
err = f"panda protocol mismatch: expected {handle.PROTOCOL_VERSION}, got {spi_version}. reflash panda"
|
|
|
|
|
raise PandaProtocolMismatch(err)
|
|
|
|
|
|
2023-08-24 19:15:37 -07:00
|
|
|
return None, handle, spi_serial, bootstub, None
|
2023-01-22 21:49:14 -08:00
|
|
|
|
2023-08-03 23:55:13 -07:00
|
|
|
@classmethod
|
|
|
|
|
def usb_connect(cls, serial, claim=True):
|
2023-01-22 21:49:14 -08:00
|
|
|
handle, usb_serial, bootstub, bcd = None, None, None, None
|
2023-06-11 19:06:46 -07:00
|
|
|
context = usb1.USBContext()
|
|
|
|
|
context.open()
|
|
|
|
|
try:
|
|
|
|
|
for device in context.getDeviceList(skip_on_error=True):
|
2023-08-03 23:55:13 -07:00
|
|
|
if device.getVendorID() == 0xbbaa and device.getProductID() in cls.USB_PIDS:
|
2023-06-11 19:06:46 -07:00
|
|
|
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
|
2023-08-03 23:55:13 -07:00
|
|
|
bootstub = (device.getProductID() & 0xF0) == 0xe0
|
2023-06-11 19:06:46 -07:00
|
|
|
handle = device.open()
|
|
|
|
|
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")
|
2022-08-02 22:28:54 -07:00
|
|
|
|
2023-01-28 16:01:54 -08:00
|
|
|
usb_handle = None
|
|
|
|
|
if handle is not None:
|
|
|
|
|
usb_handle = PandaUsbHandle(handle)
|
2023-06-11 19:06:46 -07:00
|
|
|
else:
|
|
|
|
|
context.close()
|
2023-01-28 16:01:54 -08:00
|
|
|
|
2023-08-24 19:15:37 -07:00
|
|
|
return context, usb_handle, usb_serial, bootstub, bcd
|
2023-01-22 21:49:14 -08:00
|
|
|
|
2023-08-03 23:55:13 -07:00
|
|
|
@classmethod
|
2024-01-17 11:35:20 -08:00
|
|
|
def list(cls):
|
2023-08-03 23:55:13 -07:00
|
|
|
ret = cls.usb_list()
|
|
|
|
|
ret += cls.spi_list()
|
2023-01-22 21:49:14 -08:00
|
|
|
return list(set(ret))
|
|
|
|
|
|
2023-08-03 23:55:13 -07:00
|
|
|
@classmethod
|
|
|
|
|
def usb_list(cls):
|
2023-01-22 21:49:14 -08:00
|
|
|
ret = []
|
|
|
|
|
try:
|
2023-04-01 23:09:12 -07:00
|
|
|
with usb1.USBContext() as context:
|
|
|
|
|
for device in context.getDeviceList(skip_on_error=True):
|
2023-08-03 23:55:13 -07:00
|
|
|
if device.getVendorID() == 0xbbaa and device.getProductID() in cls.USB_PIDS:
|
2023-04-01 23:09:12 -07:00
|
|
|
try:
|
|
|
|
|
serial = device.getSerialNumber()
|
2024-02-16 22:58:01 -08:00
|
|
|
if len(serial) == 24:
|
2023-04-01 23:09:12 -07:00
|
|
|
ret.append(serial)
|
|
|
|
|
else:
|
2023-08-05 14:10:33 -07:00
|
|
|
logging.warning(f"found device with panda descriptors but invalid serial: {serial}", RuntimeWarning)
|
2023-04-01 23:09:12 -07:00
|
|
|
except Exception:
|
|
|
|
|
continue
|
2023-01-22 21:49:14 -08:00
|
|
|
except Exception:
|
2023-04-01 23:09:12 -07:00
|
|
|
logging.exception("exception while listing pandas")
|
2023-01-22 21:49:14 -08:00
|
|
|
return ret
|
|
|
|
|
|
2023-08-03 23:55:13 -07:00
|
|
|
@classmethod
|
|
|
|
|
def spi_list(cls):
|
2023-08-24 19:15:37 -07:00
|
|
|
_, _, serial, _, _ = cls.spi_connect(None, ignore_version=True)
|
2023-01-22 21:49:14 -08:00
|
|
|
if serial is not None:
|
|
|
|
|
return [serial, ]
|
|
|
|
|
return []
|
|
|
|
|
|
2022-08-02 17:05:47 -07:00
|
|
|
def reset(self, enter_bootstub=False, enter_bootloader=False, reconnect=True):
|
2023-05-19 22:43:34 -07:00
|
|
|
# no response is expected since it resets right away
|
|
|
|
|
timeout = 5000 if isinstance(self._handle, PandaSpiHandle) else 15000
|
2017-07-24 15:16:22 -07:00
|
|
|
try:
|
2017-07-27 14:29:07 -07:00
|
|
|
if enter_bootloader:
|
2023-06-09 16:25:49 +02:00
|
|
|
self._handle.controlWrite(Panda.REQUEST_IN, 0xd1, 0, 0, b'', timeout=timeout, expect_disconnect=True)
|
2017-07-24 15:16:22 -07:00
|
|
|
else:
|
2017-07-27 14:29:07 -07:00
|
|
|
if enter_bootstub:
|
2023-06-09 16:25:49 +02:00
|
|
|
self._handle.controlWrite(Panda.REQUEST_IN, 0xd1, 1, 0, b'', timeout=timeout, expect_disconnect=True)
|
2017-07-27 14:29:07 -07:00
|
|
|
else:
|
2023-06-09 16:25:49 +02:00
|
|
|
self._handle.controlWrite(Panda.REQUEST_IN, 0xd8, 0, 0, b'', timeout=timeout, expect_disconnect=True)
|
2017-07-24 15:16:22 -07:00
|
|
|
except Exception:
|
|
|
|
|
pass
|
2022-08-02 17:05:47 -07:00
|
|
|
if not enter_bootloader and reconnect:
|
2018-03-10 11:22:22 -08:00
|
|
|
self.reconnect()
|
|
|
|
|
|
2023-03-22 21:38:37 -07:00
|
|
|
@property
|
|
|
|
|
def connected(self) -> bool:
|
|
|
|
|
return self._handle_open
|
|
|
|
|
|
2018-03-10 11:22:22 -08:00
|
|
|
def reconnect(self):
|
2023-03-07 13:47:55 -08:00
|
|
|
if self._handle_open:
|
2022-08-02 22:28:54 -07:00
|
|
|
self.close()
|
|
|
|
|
|
2018-03-10 11:22:22 -08:00
|
|
|
success = False
|
|
|
|
|
# wait up to 15 seconds
|
2023-09-07 19:10:30 -07:00
|
|
|
for _ in range(15*10):
|
2018-03-10 11:22:22 -08:00
|
|
|
try:
|
|
|
|
|
self.connect()
|
|
|
|
|
success = True
|
|
|
|
|
break
|
|
|
|
|
except Exception:
|
2023-08-06 23:06:26 -07:00
|
|
|
pass
|
2023-08-04 23:52:18 -07:00
|
|
|
time.sleep(0.1)
|
2018-03-10 11:22:22 -08:00
|
|
|
if not success:
|
|
|
|
|
raise Exception("reconnect failed")
|
|
|
|
|
|
2023-03-07 14:55:15 -08:00
|
|
|
@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-10 11:22:22 -08:00
|
|
|
@staticmethod
|
2022-08-03 06:58:56 +02:00
|
|
|
def flash_static(handle, code, mcu_type):
|
|
|
|
|
assert mcu_type is not None, "must set valid mcu_type to flash"
|
|
|
|
|
|
2018-03-10 11:22:22 -08:00
|
|
|
# confirm flasher is present
|
2023-03-07 14:55:15 -08:00
|
|
|
assert Panda.flasher_present(handle)
|
2018-03-10 11:22:22 -08:00
|
|
|
|
2022-08-03 06:58:56 +02:00
|
|
|
# determine sectors to erase
|
2023-01-26 20:54:11 -08:00
|
|
|
apps_sectors_cumsum = accumulate(mcu_type.config.sector_sizes[1:])
|
2022-08-03 06:58:56 +02:00
|
|
|
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-10 11:22:22 -08:00
|
|
|
# unlock flash
|
2023-01-15 23:51:25 -08:00
|
|
|
logging.warning("flash: unlocking")
|
2018-03-10 11:22:22 -08:00
|
|
|
handle.controlWrite(Panda.REQUEST_IN, 0xb1, 0, 0, b'')
|
|
|
|
|
|
2022-08-03 06:58:56 +02:00
|
|
|
# erase sectors
|
2023-01-15 23:51:25 -08:00
|
|
|
logging.warning(f"flash: erasing sectors 1 - {last_sector}")
|
2022-08-03 06:58:56 +02:00
|
|
|
for i in range(1, last_sector + 1):
|
2019-07-23 15:07:06 -07:00
|
|
|
handle.controlWrite(Panda.REQUEST_IN, 0xb2, i, 0, b'')
|
2018-03-10 11:22:22 -08:00
|
|
|
|
|
|
|
|
# flash over EP2
|
|
|
|
|
STEP = 0x10
|
2023-01-15 23:51:25 -08:00
|
|
|
logging.warning("flash: flashing")
|
2023-08-30 10:38:12 -07:00
|
|
|
for i in range(0, len(code), STEP):
|
2020-06-01 01:49:26 -07:00
|
|
|
handle.bulkWrite(2, code[i:i + STEP])
|
2018-03-10 11:22:22 -08:00
|
|
|
|
|
|
|
|
# reset
|
2023-01-15 23:51:25 -08:00
|
|
|
logging.warning("flash: resetting")
|
2018-03-10 11:22:22 -08:00
|
|
|
try:
|
2023-06-09 16:25:49 +02:00
|
|
|
handle.controlWrite(Panda.REQUEST_IN, 0xd8, 0, 0, b'', expect_disconnect=True)
|
2018-03-10 11:22:22 -08:00
|
|
|
except Exception:
|
|
|
|
|
pass
|
2017-08-22 09:30:44 -07:00
|
|
|
|
2022-08-15 20:11:38 -07:00
|
|
|
def flash(self, fn=None, code=None, reconnect=True):
|
2023-10-05 13:13:40 -07:00
|
|
|
if self.up_to_date(fn=fn):
|
|
|
|
|
logging.debug("flash: already up to date")
|
|
|
|
|
return
|
|
|
|
|
|
2022-08-15 20:11:38 -07:00
|
|
|
if not fn:
|
2023-05-21 21:19:19 -07:00
|
|
|
fn = os.path.join(FW_PATH, self._mcu_type.config.app_fn)
|
2022-08-15 20:11:38 -07:00
|
|
|
assert os.path.isfile(fn)
|
2023-01-15 23:51:25 -08:00
|
|
|
logging.debug("flash: main version is %s", self.get_version())
|
2017-07-24 15:16:22 -07:00
|
|
|
if not self.bootstub:
|
2017-07-27 14:29:07 -07:00
|
|
|
self.reset(enter_bootstub=True)
|
2017-07-24 15:16:22 -07:00
|
|
|
assert(self.bootstub)
|
|
|
|
|
|
2017-08-22 13:36:20 -07:00
|
|
|
if code is None:
|
2019-09-25 16:52:03 -07:00
|
|
|
with open(fn, "rb") as f:
|
2017-08-22 13:36:20 -07:00
|
|
|
code = f.read()
|
2017-07-24 15:16:22 -07:00
|
|
|
|
2017-08-22 09:30:44 -07:00
|
|
|
# get version
|
2023-01-15 23:51:25 -08:00
|
|
|
logging.debug("flash: bootstub version is %s", self.get_version())
|
2017-08-22 09:30:44 -07:00
|
|
|
|
2018-03-10 11:22:22 -08:00
|
|
|
# do flash
|
2022-08-03 06:58:56 +02:00
|
|
|
Panda.flash_static(self._handle, code, mcu_type=self._mcu_type)
|
2017-07-24 15:16:22 -07:00
|
|
|
|
2018-03-10 11:22:22 -08:00
|
|
|
# reconnect
|
|
|
|
|
if reconnect:
|
|
|
|
|
self.reconnect()
|
2017-04-06 18:11:36 -07:00
|
|
|
|
2023-05-03 14:15:34 -07:00
|
|
|
def recover(self, timeout: Optional[int] = 60, reset: bool = True) -> bool:
|
2023-04-16 14:43:58 -07:00
|
|
|
dfu_serial = self.get_dfu_serial()
|
2022-08-15 20:11:49 -07:00
|
|
|
|
2022-04-25 17:11:27 -07:00
|
|
|
if reset:
|
|
|
|
|
self.reset(enter_bootstub=True)
|
|
|
|
|
self.reset(enter_bootloader=True)
|
|
|
|
|
|
2022-08-15 20:11:49 -07:00
|
|
|
if not self.wait_for_dfu(dfu_serial, timeout=timeout):
|
|
|
|
|
return False
|
2017-08-28 10:42:23 -07:00
|
|
|
|
2022-08-15 20:11:49 -07:00
|
|
|
dfu = PandaDFU(dfu_serial)
|
2017-08-28 10:42:23 -07:00
|
|
|
dfu.recover()
|
|
|
|
|
|
|
|
|
|
# reflash after recover
|
|
|
|
|
self.connect(True, True)
|
|
|
|
|
self.flash()
|
2019-04-09 14:09:18 -07:00
|
|
|
return True
|
2017-08-28 10:42:23 -07:00
|
|
|
|
2022-08-15 20:11:49 -07:00
|
|
|
@staticmethod
|
2023-05-23 20:50:09 -07:00
|
|
|
def wait_for_dfu(dfu_serial: Optional[str], timeout: Optional[int] = None) -> bool:
|
2022-08-15 20:11:49 -07:00
|
|
|
t_start = time.monotonic()
|
2023-05-23 20:50:09 -07:00
|
|
|
dfu_list = PandaDFU.list()
|
|
|
|
|
while (dfu_serial is None and len(dfu_list) == 0) or (dfu_serial is not None and dfu_serial not in dfu_list):
|
2023-01-15 23:51:25 -08:00
|
|
|
logging.debug("waiting for DFU...")
|
2022-08-15 20:11:49 -07:00
|
|
|
time.sleep(0.1)
|
|
|
|
|
if timeout is not None and (time.monotonic() - t_start) > timeout:
|
|
|
|
|
return False
|
2023-05-23 20:50:09 -07:00
|
|
|
dfu_list = PandaDFU.list()
|
2022-08-15 20:11:49 -07:00
|
|
|
return True
|
|
|
|
|
|
2023-06-07 19:43:43 -07:00
|
|
|
@staticmethod
|
|
|
|
|
def wait_for_panda(serial: Optional[str], timeout: int) -> bool:
|
|
|
|
|
t_start = time.monotonic()
|
|
|
|
|
serials = Panda.list()
|
|
|
|
|
while (serial is None and len(serials) == 0) or (serial is not None and serial not in serials):
|
|
|
|
|
logging.debug("waiting for panda...")
|
|
|
|
|
time.sleep(0.1)
|
|
|
|
|
if timeout is not None and (time.monotonic() - t_start) > timeout:
|
|
|
|
|
return False
|
|
|
|
|
serials = Panda.list()
|
|
|
|
|
return True
|
|
|
|
|
|
2023-10-05 13:13:40 -07:00
|
|
|
def up_to_date(self, fn=None) -> bool:
|
2023-03-07 13:47:55 -08:00
|
|
|
current = self.get_signature()
|
2023-10-05 13:13:40 -07:00
|
|
|
if fn is None:
|
|
|
|
|
fn = os.path.join(FW_PATH, self.get_mcu_type().config.app_fn)
|
2023-05-21 21:19:19 -07:00
|
|
|
expected = Panda.get_signature_from_firmware(fn)
|
2023-03-07 13:47:55 -08:00
|
|
|
return (current == expected)
|
|
|
|
|
|
2017-07-18 12:29:16 -07:00
|
|
|
def call_control_api(self, msg):
|
|
|
|
|
self._handle.controlWrite(Panda.REQUEST_OUT, msg, 0, 0, b'')
|
|
|
|
|
|
2017-04-06 18:11:36 -07:00
|
|
|
# ******************* health *******************
|
|
|
|
|
|
2021-11-11 05:30:52 -08:00
|
|
|
@ensure_health_packet_version
|
2017-04-06 18:11:36 -07:00
|
|
|
def health(self):
|
2022-01-27 17:46:24 -08:00
|
|
|
dat = self._handle.controlRead(Panda.REQUEST_IN, 0xd2, 0, 0, self.HEALTH_STRUCT.size)
|
|
|
|
|
a = self.HEALTH_STRUCT.unpack(dat)
|
2019-07-23 15:07:06 -07:00
|
|
|
return {
|
2019-11-21 16:47:49 -08:00
|
|
|
"uptime": a[0],
|
|
|
|
|
"voltage": a[1],
|
|
|
|
|
"current": a[2],
|
2022-09-15 13:08:46 -07:00
|
|
|
"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],
|
2023-12-14 15:22:17 -08:00
|
|
|
"car_harness_status": a[12],
|
|
|
|
|
"safety_mode": a[13],
|
|
|
|
|
"safety_param": a[14],
|
|
|
|
|
"fault_status": a[15],
|
|
|
|
|
"power_save_enabled": a[16],
|
|
|
|
|
"heartbeat_lost": a[17],
|
|
|
|
|
"alternative_experience": a[18],
|
|
|
|
|
"interrupt_load": a[19],
|
|
|
|
|
"fan_power": a[20],
|
|
|
|
|
"safety_rx_checks_invalid": a[21],
|
|
|
|
|
"spi_checksum_error_count": a[22],
|
|
|
|
|
"fan_stall_count": a[23],
|
|
|
|
|
"sbu1_voltage_mV": a[24],
|
|
|
|
|
"sbu2_voltage_mV": a[25],
|
|
|
|
|
"som_reset_triggered": a[26],
|
2019-07-23 15:07:06 -07:00
|
|
|
}
|
2017-04-06 18:11:36 -07:00
|
|
|
|
2022-09-15 13:04:10 -07: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],
|
2023-01-13 10:59:58 -08:00
|
|
|
"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],
|
2023-06-28 14:40:00 -07:00
|
|
|
"irq0_call_rate": a[22],
|
|
|
|
|
"irq1_call_rate": a[23],
|
|
|
|
|
"irq2_call_rate": a[24],
|
|
|
|
|
"can_core_reset_count": a[25],
|
2022-09-15 13:04:10 -07:00
|
|
|
}
|
|
|
|
|
|
2017-04-28 16:56:40 -07:00
|
|
|
# ******************* control *******************
|
|
|
|
|
|
2017-08-22 09:30:44 -07:00
|
|
|
def get_version(self):
|
2019-09-25 16:52:51 -07:00
|
|
|
return self._handle.controlRead(Panda.REQUEST_IN, 0xd6, 0, 0, 0x40).decode('utf8')
|
2017-08-22 09:30:44 -07:00
|
|
|
|
2019-12-09 10:54:48 -08:00
|
|
|
@staticmethod
|
2022-05-12 14:22:58 +02:00
|
|
|
def get_signature_from_firmware(fn) -> bytes:
|
2023-04-02 09:33:35 -07:00
|
|
|
with open(fn, 'rb') as f:
|
|
|
|
|
f.seek(-128, 2) # Seek from end of file
|
|
|
|
|
return f.read(128)
|
2019-12-09 10:54:48 -08:00
|
|
|
|
2023-03-07 13:47:55 -08:00
|
|
|
def get_signature(self) -> bytes:
|
2019-12-09 10:54:48 -08:00
|
|
|
part_1 = self._handle.controlRead(Panda.REQUEST_IN, 0xd3, 0, 0, 0x40)
|
|
|
|
|
part_2 = self._handle.controlRead(Panda.REQUEST_IN, 0xd4, 0, 0, 0x40)
|
2019-12-18 17:03:31 -08:00
|
|
|
return bytes(part_1 + part_2)
|
2019-12-09 10:54:48 -08:00
|
|
|
|
2019-07-23 15:07:06 -07:00
|
|
|
def get_type(self):
|
2022-08-02 22:28:54 -07:00
|
|
|
ret = self._handle.controlRead(Panda.REQUEST_IN, 0xc1, 0, 0, 0x40)
|
|
|
|
|
|
2023-01-28 14:41:52 -08:00
|
|
|
# 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
|
2022-08-02 22:28:54 -07:00
|
|
|
|
|
|
|
|
return ret
|
2019-07-23 15:07:06 -07:00
|
|
|
|
2021-11-11 05:30:52 -08:00
|
|
|
# Returns tuple with health packet version and CAN packet/USB packet version
|
|
|
|
|
def get_packets_versions(self):
|
2022-09-15 13:04:10 -07:00
|
|
|
dat = self._handle.controlRead(Panda.REQUEST_IN, 0xdd, 0, 0, 3)
|
2022-09-15 14:54:38 -07:00
|
|
|
if dat and len(dat) == 3:
|
2022-09-15 13:04:10 -07:00
|
|
|
a = struct.unpack("BBB", dat)
|
|
|
|
|
return (a[0], a[1], a[2])
|
2021-11-11 05:30:52 -08:00
|
|
|
else:
|
2022-09-15 13:04:10 -07:00
|
|
|
return (0, 0, 0)
|
2021-11-11 05:30:52 -08:00
|
|
|
|
2023-01-26 20:54:11 -08:00
|
|
|
def get_mcu_type(self) -> McuType:
|
2021-08-02 20:26:15 -07:00
|
|
|
hw_type = self.get_type()
|
2024-02-16 22:58:01 -08:00
|
|
|
if hw_type in Panda.F4_DEVICES:
|
2023-01-26 20:54:11 -08:00
|
|
|
return McuType.F4
|
2021-08-02 20:26:15 -07:00
|
|
|
elif hw_type in Panda.H7_DEVICES:
|
2023-01-26 20:54:11 -08:00
|
|
|
return McuType.H7
|
2023-01-28 14:41:52 -08:00
|
|
|
else:
|
|
|
|
|
# have to assume F4, see comment in Panda.connect
|
|
|
|
|
if self._assume_f4_mcu:
|
|
|
|
|
return McuType.F4
|
|
|
|
|
|
2023-01-26 20:54:11 -08:00
|
|
|
raise ValueError(f"unknown HW type: {hw_type}")
|
2021-07-08 00:36:25 -07:00
|
|
|
|
2019-11-05 18:25:42 -08:00
|
|
|
def has_obd(self):
|
2022-08-30 10:46:12 -07:00
|
|
|
return self.get_type() in Panda.HAS_OBD
|
2021-10-08 12:10:28 +02:00
|
|
|
|
2022-08-31 10:39:05 -07:00
|
|
|
def is_internal(self):
|
|
|
|
|
return self.get_type() in Panda.INTERNAL_DEVICES
|
|
|
|
|
|
2017-04-28 16:56:40 -07:00
|
|
|
def get_serial(self):
|
2023-01-15 20:13:26 -08:00
|
|
|
"""
|
|
|
|
|
Returns the comma-issued dongle ID from our provisioning
|
|
|
|
|
"""
|
2017-07-17 18:59:16 -07:00
|
|
|
dat = self._handle.controlRead(Panda.REQUEST_IN, 0xd0, 0, 0, 0x20)
|
2017-06-13 18:50:47 -07:00
|
|
|
hashsig, calc_hash = dat[0x1c:], hashlib.sha1(dat[0:0x1c]).digest()[0:4]
|
2017-07-17 19:43:30 -07:00
|
|
|
assert(hashsig == calc_hash)
|
2020-06-01 01:49:26 -07:00
|
|
|
return [dat[0:0x10].decode("utf8"), dat[0x10:0x10 + 10].decode("utf8")]
|
2017-04-28 16:56:40 -07:00
|
|
|
|
2021-10-08 12:17:06 +02:00
|
|
|
def get_usb_serial(self):
|
2023-01-15 20:13:26 -08:00
|
|
|
"""
|
|
|
|
|
Returns the serial number reported from the USB descriptor;
|
|
|
|
|
matches the MCU UID
|
|
|
|
|
"""
|
2021-10-08 12:17:06 +02:00
|
|
|
return self._serial
|
|
|
|
|
|
2023-04-16 14:43:58 -07:00
|
|
|
def get_dfu_serial(self):
|
|
|
|
|
return PandaDFU.st_serial_to_dfu_serial(self._serial, self._mcu_type)
|
|
|
|
|
|
2023-01-15 20:13:26 -08:00
|
|
|
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-28 17:49:55 -07:00
|
|
|
def get_secret(self):
|
2017-07-17 18:59:16 -07:00
|
|
|
return self._handle.controlRead(Panda.REQUEST_IN, 0xd0, 1, 0, 0x10)
|
2017-04-28 17:49:55 -07:00
|
|
|
|
2023-06-20 11:47:43 -07:00
|
|
|
def get_interrupt_call_rate(self, irqnum):
|
|
|
|
|
dat = self._handle.controlRead(Panda.REQUEST_IN, 0xc4, int(irqnum), 0, 4)
|
|
|
|
|
return struct.unpack("I", dat)[0]
|
|
|
|
|
|
2017-04-25 15:16:23 -07:00
|
|
|
# ******************* configuration *******************
|
2017-04-06 18:11:36 -07:00
|
|
|
|
2019-11-21 16:47:49 -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-07 14:32:14 -08:00
|
|
|
def enable_deepsleep(self):
|
2022-03-07 14:24:04 -08:00
|
|
|
self._handle.controlWrite(Panda.REQUEST_OUT, 0xfb, 0, 0, b'')
|
|
|
|
|
|
2022-08-17 22:42:18 -07:00
|
|
|
def set_safety_mode(self, mode=SAFETY_SILENT, param=0):
|
2022-02-20 19:38:08 -08:00
|
|
|
self._handle.controlWrite(Panda.REQUEST_OUT, 0xdc, mode, param, b'')
|
2017-07-14 21:59:23 -07:00
|
|
|
|
2017-07-18 21:05:09 -07:00
|
|
|
def set_gmlan(self, bus=2):
|
2019-07-23 15:07:06 -07:00
|
|
|
# TODO: check panda type
|
2017-07-18 21:05:09 -07:00
|
|
|
if bus is None:
|
|
|
|
|
self._handle.controlWrite(Panda.REQUEST_OUT, 0xdb, 0, 0, b'')
|
2022-05-12 14:22:58 +02:00
|
|
|
elif bus in (Panda.GMLAN_CAN2, Panda.GMLAN_CAN3):
|
2017-07-18 21:05:09 -07:00
|
|
|
self._handle.controlWrite(Panda.REQUEST_OUT, 0xdb, 1, bus, b'')
|
2017-04-06 18:11:36 -07:00
|
|
|
|
2019-07-23 15:07:06 -07:00
|
|
|
def set_obd(self, obd):
|
|
|
|
|
# TODO: check panda type
|
|
|
|
|
self._handle.controlWrite(Panda.REQUEST_OUT, 0xdb, int(obd), 0, b'')
|
|
|
|
|
|
2017-07-14 20:25:13 -07:00
|
|
|
def set_can_loopback(self, enable):
|
2017-07-17 15:29:31 -07:00
|
|
|
# set can loopback mode for all buses
|
2017-07-17 18:58:04 -07:00
|
|
|
self._handle.controlWrite(Panda.REQUEST_OUT, 0xe5, int(enable), 0, b'')
|
2017-07-14 20:25:13 -07:00
|
|
|
|
2019-04-01 22:45:00 -07:00
|
|
|
def set_can_enable(self, bus_num, enable):
|
2020-09-28 16:19:09 +02:00
|
|
|
# sets the can transceiver enable pin
|
2019-04-01 22:45:00 -07:00
|
|
|
self._handle.controlWrite(Panda.REQUEST_OUT, 0xf4, int(bus_num), int(enable), b'')
|
|
|
|
|
|
2017-07-17 19:43:30 -07:00
|
|
|
def set_can_speed_kbps(self, bus, speed):
|
2020-06-01 01:49:26 -07:00
|
|
|
self._handle.controlWrite(Panda.REQUEST_OUT, 0xde, bus, int(speed * 10), b'')
|
2017-07-17 19:43:30 -07:00
|
|
|
|
2021-08-02 20:26:15 -07:00
|
|
|
def set_can_data_speed_kbps(self, bus, speed):
|
|
|
|
|
self._handle.controlWrite(Panda.REQUEST_OUT, 0xf9, bus, int(speed * 10), b'')
|
|
|
|
|
|
2022-10-12 15:28:20 -07:00
|
|
|
def set_canfd_non_iso(self, bus, non_iso):
|
|
|
|
|
self._handle.controlWrite(Panda.REQUEST_OUT, 0xfc, bus, int(non_iso), b'')
|
2021-11-15 16:27:16 -08:00
|
|
|
|
2017-04-25 15:16:23 -07:00
|
|
|
def set_uart_baud(self, uart, rate):
|
2020-06-01 01:49:26 -07:00
|
|
|
self._handle.controlWrite(Panda.REQUEST_OUT, 0xe4, uart, int(rate / 300), b'')
|
2017-04-25 15:16:23 -07:00
|
|
|
|
|
|
|
|
def set_uart_parity(self, uart, parity):
|
|
|
|
|
# parity, 0=off, 1=even, 2=odd
|
2017-07-17 18:58:04 -07:00
|
|
|
self._handle.controlWrite(Panda.REQUEST_OUT, 0xe2, uart, parity, b'')
|
2017-04-25 15:16:23 -07:00
|
|
|
|
2017-04-25 20:23:05 -07:00
|
|
|
def set_uart_callback(self, uart, install):
|
2017-07-17 18:58:04 -07:00
|
|
|
self._handle.controlWrite(Panda.REQUEST_OUT, 0xe3, uart, int(install), b'')
|
2017-04-25 20:23:05 -07:00
|
|
|
|
2017-04-25 15:16:23 -07:00
|
|
|
# ******************* can *******************
|
|
|
|
|
|
2020-04-13 15:12:06 -07:00
|
|
|
# The panda will NAK CAN writes when there is CAN congestion.
|
2020-04-06 16:49:42 -07:00
|
|
|
# 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
|
|
|
|
|
|
2023-01-13 10:59:58 -08:00
|
|
|
def can_reset_communications(self):
|
|
|
|
|
self._handle.controlWrite(Panda.REQUEST_OUT, 0xc0, 0, 0, b'')
|
|
|
|
|
|
2021-11-11 05:30:52 -08:00
|
|
|
@ensure_can_packet_version
|
2020-04-06 16:49:42 -07:00
|
|
|
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-12 16:36:34 -08:00
|
|
|
snds = pack_can_buffer(arr)
|
2017-06-13 18:50:47 -07:00
|
|
|
while True:
|
2017-04-06 18:11:36 -07:00
|
|
|
try:
|
2021-12-06 14:39:28 -08:00
|
|
|
for tx in snds:
|
|
|
|
|
while True:
|
|
|
|
|
bs = self._handle.bulkWrite(3, tx, timeout=timeout)
|
|
|
|
|
tx = tx[bs:]
|
|
|
|
|
if len(tx) == 0:
|
|
|
|
|
break
|
2023-01-15 23:51:25 -08:00
|
|
|
logging.error("CAN: PARTIAL SEND MANY, RETRYING")
|
2017-04-06 18:11:36 -07:00
|
|
|
break
|
2017-06-13 18:50:47 -07:00
|
|
|
except (usb1.USBErrorIO, usb1.USBErrorOverflow):
|
2023-01-15 23:51:25 -08:00
|
|
|
logging.error("CAN: BAD SEND MANY, RETRYING")
|
2017-04-06 18:11:36 -07:00
|
|
|
|
2020-04-06 16:49:42 -07: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-06 18:11:36 -07:00
|
|
|
|
2021-11-11 05:30:52 -08:00
|
|
|
@ensure_can_packet_version
|
2017-04-06 18:11:36 -07:00
|
|
|
def can_recv(self):
|
2017-06-13 18:50:47 -07:00
|
|
|
dat = bytearray()
|
|
|
|
|
while True:
|
2017-04-06 18:11:36 -07: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-12 16:36:34 -08:00
|
|
|
dat = self._handle.bulkRead(1, 16384) # Max receive batch size + 2 extra reserve frames
|
2017-04-06 18:11:36 -07:00
|
|
|
break
|
2017-06-13 18:50:47 -07:00
|
|
|
except (usb1.USBErrorIO, usb1.USBErrorOverflow):
|
2023-01-15 23:51:25 -08:00
|
|
|
logging.error("CAN: BAD RECV, RETRYING")
|
2019-09-25 14:34:28 -07:00
|
|
|
time.sleep(0.1)
|
2023-01-13 10:59:58 -08:00
|
|
|
msgs, self.can_rx_overflow_buffer = unpack_can_buffer(self.can_rx_overflow_buffer + dat)
|
|
|
|
|
return msgs
|
2017-04-06 18:11:36 -07:00
|
|
|
|
2017-08-17 02:03:08 -07: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-09 17:40:03 -08:00
|
|
|
# ******************* isotp *******************
|
|
|
|
|
|
2018-03-10 10:16:53 -08:00
|
|
|
def isotp_send(self, addr, dat, bus, recvaddr=None, subaddr=None):
|
2018-03-09 17:40:03 -08:00
|
|
|
return isotp_send(self, dat, addr, bus, recvaddr, subaddr)
|
|
|
|
|
|
2018-03-10 10:16:53 -08:00
|
|
|
def isotp_recv(self, addr, bus=0, sendaddr=None, subaddr=None):
|
2018-03-10 10:17:57 -08:00
|
|
|
return isotp_recv(self, addr, bus, sendaddr, subaddr)
|
2018-03-09 17:40:03 -08:00
|
|
|
|
2017-04-06 18:11:36 -07:00
|
|
|
# ******************* serial *******************
|
|
|
|
|
|
|
|
|
|
def serial_read(self, port_number):
|
2017-07-18 12:15:19 -07: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-06 18:11:36 -07:00
|
|
|
|
2017-04-18 01:12:04 -07:00
|
|
|
def serial_write(self, port_number, ln):
|
2018-01-19 11:04:21 -08:00
|
|
|
ret = 0
|
2023-08-01 11:14:27 -07:00
|
|
|
if isinstance(ln, str):
|
2023-01-10 15:09:51 -08:00
|
|
|
ln = bytes(ln, 'utf-8')
|
2023-08-30 10:38:12 -07:00
|
|
|
for i in range(0, len(ln), 0x20):
|
2023-01-10 15:09:51 -08:00
|
|
|
ret += self._handle.bulkWrite(2, struct.pack("B", port_number) + ln[i:i + 0x20])
|
2018-01-19 11:04:21 -08:00
|
|
|
return ret
|
2017-04-06 18:11:36 -07:00
|
|
|
|
2017-08-17 02:03:08 -07: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-06 18:11:36 -07:00
|
|
|
|
2021-12-15 17:28:57 -08:00
|
|
|
def send_heartbeat(self, engaged=True):
|
|
|
|
|
self._handle.controlWrite(Panda.REQUEST_OUT, 0xf3, engaged, 0, b'')
|
2019-10-25 16:22:42 -07:00
|
|
|
|
2021-06-21 13:54:09 -07:00
|
|
|
# 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'')
|
|
|
|
|
|
2019-10-25 16:22:42 -07:00
|
|
|
# ******************* 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)
|
2023-09-30 12:49:46 -07:00
|
|
|
a = struct.unpack("HBBBBBB", dat)
|
|
|
|
|
return datetime.datetime(a[0], a[1], a[2], a[4], a[5], a[6])
|
2019-10-25 16:22:42 -07:00
|
|
|
|
2023-02-14 12:16:15 +01:00
|
|
|
# ****************** Timer *****************
|
|
|
|
|
def get_microsecond_timer(self):
|
|
|
|
|
dat = self._handle.controlRead(Panda.REQUEST_IN, 0xa8, 0, 0, 4)
|
|
|
|
|
return struct.unpack("I", dat)[0]
|
|
|
|
|
|
2019-10-25 16:22:42 -07:00
|
|
|
# ******************* 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)
|
2019-11-04 17:26:37 -08:00
|
|
|
return a[0]
|
|
|
|
|
|
2020-08-17 15:04:01 +02:00
|
|
|
# ****************** Siren *****************
|
|
|
|
|
def set_siren(self, enabled):
|
|
|
|
|
self._handle.controlWrite(Panda.REQUEST_OUT, 0xf6, int(enabled), 0, b'')
|
2023-01-10 15:09:51 -08:00
|
|
|
|
|
|
|
|
# ****************** Debug *****************
|
|
|
|
|
def set_green_led(self, enabled):
|
|
|
|
|
self._handle.controlWrite(Panda.REQUEST_OUT, 0xf7, int(enabled), 0, b'')
|
2023-06-13 17:00:56 +02:00
|
|
|
|
2023-08-01 16:17:42 -07:00
|
|
|
def set_clock_source_period(self, period):
|
|
|
|
|
self._handle.controlWrite(Panda.REQUEST_OUT, 0xe6, period, 0, b'')
|
|
|
|
|
|
2023-08-01 16:33:34 -07:00
|
|
|
def force_relay_drive(self, intercept_relay_drive, ignition_relay_drive):
|
|
|
|
|
self._handle.controlWrite(Panda.REQUEST_OUT, 0xc5, (int(intercept_relay_drive) | int(ignition_relay_drive) << 1), 0, b'')
|
2023-10-06 13:38:35 -07:00
|
|
|
|
|
|
|
|
def read_som_gpio(self) -> bool:
|
|
|
|
|
r = self._handle.controlRead(Panda.REQUEST_IN, 0xc6, 0, 0, 1)
|
|
|
|
|
return r[0] == 1
|