openpilot v0.7.9 release
|
@ -18,7 +18,7 @@ You can test your changes on your machine by running `run_docker_tests.sh`. This
|
|||
|
||||
### Automated Testing
|
||||
|
||||
All PRs and commits are automatically checked by Github Actions. Check out `.github/workflows/` for what Github Actions runs. Any new tests sould be added to Github Actions.
|
||||
All PRs and commits are automatically checked by Github Actions. Check out `.github/workflows/` for what Github Actions runs. Any new tests should be added to Github Actions.
|
||||
|
||||
### Code Style and Linting
|
||||
|
||||
|
@ -28,7 +28,7 @@ Code is automatically checked for style by Github Actions as part of the automat
|
|||
|
||||
We've released a [Model Port guide](https://medium.com/@comma_ai/openpilot-port-guide-for-toyota-models-e5467f4b5fe6) for porting to Toyota/Lexus models.
|
||||
|
||||
If you port openpilot to a substantially new car brand, see this more generic [Brand Port guide](https://medium.com/@comma_ai/how-to-write-a-car-port-for-openpilot-7ce0785eda84). You might also be eligible for a bounty. See our bounties at [comma.ai/bounties.html](https://comma.ai/bounties.html)
|
||||
If you port openpilot to a substantially new car brand, see this more generic [Brand Port guide](https://medium.com/@comma_ai/how-to-write-a-car-port-for-openpilot-7ce0785eda84). You might also be eligible for a bounty.
|
||||
|
||||
## Pull Requests
|
||||
|
||||
|
|
|
@ -70,7 +70,7 @@ pipeline {
|
|||
stage('PC tests') {
|
||||
agent {
|
||||
dockerfile {
|
||||
filename 'Dockerfile.openpilot'
|
||||
filename 'Dockerfile.openpilotci'
|
||||
args '--privileged --shm-size=1G --user=root'
|
||||
}
|
||||
}
|
||||
|
@ -132,6 +132,7 @@ pipeline {
|
|||
["build cereal", "SCONS_CACHE=1 scons -j4 cereal/"],
|
||||
["test sounds", "nosetests -s selfdrive/test/test_sounds.py"],
|
||||
["test boardd loopback", "nosetests -s selfdrive/boardd/tests/test_boardd_loopback.py"],
|
||||
["test loggerd", "CI=1 python selfdrive/loggerd/tests/test_loggerd.py"],
|
||||
//["test updater", "python installer/updater/test_updater.py"],
|
||||
])
|
||||
}
|
||||
|
@ -140,6 +141,13 @@ pipeline {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
post {
|
||||
always {
|
||||
cleanWs()
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
|
57
README.md
|
@ -70,31 +70,30 @@ Supported Cars
|
|||
| Honda | Accord Hybrid 2018-20 | All | Stock | 0mph | 3mph |
|
||||
| Honda | Civic Hatchback 2017-19 | Honda Sensing | Stock | 0mph | 12mph |
|
||||
| Honda | Civic Sedan/Coupe 2016-18 | Honda Sensing | openpilot | 0mph | 12mph |
|
||||
| Honda | Civic Sedan/Coupe 2019-20 | Honda Sensing | Stock | 0mph | 2mph<sup>2</sup> |
|
||||
| Honda | Civic Sedan/Coupe 2019-20 | All | Stock | 0mph | 2mph<sup>2</sup> |
|
||||
| Honda | CR-V 2015-16 | Touring | openpilot | 25mph<sup>1</sup> | 12mph |
|
||||
| Honda | CR-V 2017-20 | Honda Sensing | Stock | 0mph | 12mph |
|
||||
| Honda | CR-V Hybrid 2017-2019 | Honda Sensing | Stock | 0mph | 12mph |
|
||||
| Honda | Fit 2018-19 | Honda Sensing | openpilot | 25mph<sup>1</sup> | 12mph |
|
||||
| Honda | HR-V 2019 | Honda Sensing | openpilot | 25mph<sup>1</sup> | 12mph |
|
||||
| Honda | Insight 2019-20 | Honda Sensing | Stock | 0mph | 3mph |
|
||||
| Honda | Insight 2019-20 | All | Stock | 0mph | 3mph |
|
||||
| Honda | Odyssey 2018-20 | Honda Sensing | openpilot | 25mph<sup>1</sup> | 0mph |
|
||||
| Honda | Passport 2019 | All | openpilot | 25mph<sup>1</sup> | 12mph |
|
||||
| Honda | Pilot 2016-18 | Honda Sensing | openpilot | 25mph<sup>1</sup> | 12mph |
|
||||
| Honda | Pilot 2019 | All | openpilot | 25mph<sup>1</sup> | 12mph |
|
||||
| Honda | Pilot 2016-19 | Honda Sensing | openpilot | 25mph<sup>1</sup> | 12mph |
|
||||
| Honda | Ridgeline 2017-20 | Honda Sensing | openpilot | 25mph<sup>1</sup> | 12mph |
|
||||
| Hyundai | Palisade 2020 | All | Stock | 0mph | 0mph |
|
||||
| Hyundai | Sonata 2020 | All | Stock | 0mph | 0mph |
|
||||
| Lexus | CT Hybrid 2017-18 | All | Stock<sup>3</sup>| 0mph | 0mph |
|
||||
| Lexus | CT Hybrid 2017-18 | LSS | Stock<sup>3</sup>| 0mph | 0mph |
|
||||
| Lexus | ES 2019 | All | openpilot | 0mph | 0mph |
|
||||
| Lexus | ES Hybrid 2019 | All | openpilot | 0mph | 0mph |
|
||||
| Lexus | IS 2017-2019 | All | Stock | 22mph | 0mph |
|
||||
| Lexus | IS Hybrid 2017 | All | Stock | 0mph | 0mph |
|
||||
| Lexus | NX Hybrid 2018 | All | Stock<sup>3</sup>| 0mph | 0mph |
|
||||
| Lexus | RX 2016-17 | All | Stock<sup>3</sup>| 0mph | 0mph |
|
||||
| Lexus | RX 2016-18 | All | Stock<sup>3</sup>| 0mph | 0mph |
|
||||
| Lexus | RX 2020 | All | openpilot | 0mph | 0mph |
|
||||
| Lexus | RX Hybrid 2016-19 | All | Stock<sup>3</sup>| 0mph | 0mph |
|
||||
| Lexus | RX Hybrid 2020 | All | openpilot | 0mph | 0mph |
|
||||
| Toyota | Avalon 2016 | TSS-P | Stock<sup>3</sup>| 20mph<sup>1</sup> | 0mph |
|
||||
| Toyota | Avalon 2017-18 | All | Stock<sup>3</sup>| 20mph<sup>1</sup> | 0mph |
|
||||
| Toyota | Avalon 2016-18 | TSS-P | Stock<sup>3</sup>| 20mph<sup>1</sup> | 0mph |
|
||||
| Toyota | Camry 2018-20 | All | Stock | 0mph<sup>4</sup> | 0mph |
|
||||
| Toyota | Camry Hybrid 2018-19 | All | Stock | 0mph<sup>4</sup> | 0mph |
|
||||
| Toyota | C-HR 2017-19 | All | Stock | 0mph | 0mph |
|
||||
|
@ -102,19 +101,16 @@ Supported Cars
|
|||
| Toyota | Corolla 2017-19 | All | Stock<sup>3</sup>| 20mph<sup>1</sup> | 0mph |
|
||||
| Toyota | Corolla 2020 | All | openpilot | 0mph | 0mph |
|
||||
| Toyota | Corolla Hatchback 2019-20 | All | openpilot | 0mph | 0mph |
|
||||
| Toyota | Corolla Hybrid 2020 | All | openpilot | 0mph | 0mph |
|
||||
| Toyota | Corolla Hybrid 2020-21 | All | openpilot | 0mph | 0mph |
|
||||
| Toyota | Highlander 2017-19 | All | Stock<sup>3</sup>| 0mph | 0mph |
|
||||
| Toyota | Highlander Hybrid 2017-19 | All | Stock<sup>3</sup>| 0mph | 0mph |
|
||||
| Toyota | Highlander 2020 | All | openpilot | 0mph | 0mph |
|
||||
| Toyota | Highlander Hybrid 2017-19 | All | Stock<sup>3</sup>| 0mph | 0mph |
|
||||
| Toyota | Highlander Hybrid 2020 | All | openpilot | 0mph | 0mph |
|
||||
| Toyota | Prius 2016 | TSS-P | Stock<sup>3</sup>| 0mph | 0mph |
|
||||
| Toyota | Prius 2017-20 | All | Stock<sup>3</sup>| 0mph | 0mph |
|
||||
| Toyota | Prius 2016-20 | TSS-P | Stock<sup>3</sup>| 0mph | 0mph |
|
||||
| Toyota | Prius Prime 2017-20 | All | Stock<sup>3</sup>| 0mph | 0mph |
|
||||
| Toyota | Rav4 2016 | TSS-P | Stock<sup>3</sup>| 20mph<sup>1</sup> | 0mph |
|
||||
| Toyota | Rav4 2017-18 | All | Stock<sup>3</sup>| 20mph<sup>1</sup> | 0mph |
|
||||
| Toyota | Rav4 2016-18 | TSS-P | Stock<sup>3</sup>| 20mph<sup>1</sup> | 0mph |
|
||||
| Toyota | Rav4 2019-20 | All | openpilot | 0mph | 0mph |
|
||||
| Toyota | Rav4 Hybrid 2016 | TSS-P | Stock<sup>3</sup>| 0mph | 0mph |
|
||||
| Toyota | Rav4 Hybrid 2017-18 | All | Stock<sup>3</sup>| 0mph | 0mph |
|
||||
| Toyota | Rav4 Hybrid 2016-18 | TSS-P | Stock<sup>3</sup>| 0mph | 0mph |
|
||||
| Toyota | Rav4 Hybrid 2019-20 | All | openpilot | 0mph | 0mph |
|
||||
| Toyota | Sienna 2018-20 | All | Stock<sup>3</sup>| 0mph | 0mph |
|
||||
|
||||
|
@ -143,24 +139,22 @@ Community Maintained Cars and Features
|
|||
| Holden | Astra 2017<sup>1</sup> | Adaptive Cruise | openpilot | 0mph | 7mph |
|
||||
| Hyundai | Elantra 2017-19 | SCC + LKAS | Stock | 19mph | 34mph |
|
||||
| Hyundai | Genesis 2015-16 | SCC + LKAS | Stock | 19mph | 37mph |
|
||||
| Hyundai | Ioniq Electric Premium SE 2020| SCC + LKAS | Stock | 0mph | 32mph |
|
||||
| Hyundai | Ioniq Electric Limited 2019 | SCC + LKAS | Stock | 0mph | 32mph |
|
||||
| Hyundai | Ioniq Electric 2019-20 | SCC + LKAS | Stock | 0mph | 32mph |
|
||||
| Hyundai | Kona 2020 | SCC + LKAS | Stock | 0mph | 0mph |
|
||||
| Hyundai | Kona EV 2019 | SCC + LKAS | Stock | 0mph | 0mph |
|
||||
| Hyundai | Palisade 2020 | All | Stock | 0mph | 0mph |
|
||||
| Hyundai | Santa Fe 2019 | All | Stock | 0mph | 0mph |
|
||||
| Hyundai | Sonata 2019 | All | Stock | 0mph | 0mph |
|
||||
| Hyundai | Veloster 2019 | SCC + LKAS | Stock | 5mph | 0mph |
|
||||
| Jeep | Grand Cherokee 2016-18 | Adaptive Cruise | Stock | 0mph | 9mph |
|
||||
| Jeep | Grand Cherokee 2019-20 | Adaptive Cruise | Stock | 0mph | 39mph |
|
||||
| Kia | Forte 2018-19 | SCC + LKAS | Stock | 0mph | 0mph |
|
||||
| Kia | Optima 2017 | SCC + LKAS/LDWS | Stock | 0mph | 32mph |
|
||||
| Kia | Optima 2017 | SCC + LKAS | Stock | 0mph | 32mph |
|
||||
| Kia | Optima 2019 | SCC + LKAS | Stock | 0mph | 0mph |
|
||||
| Kia | Sorento 2018 | SCC + LKAS | Stock | 0mph | 0mph |
|
||||
| Kia | Stinger 2018 | SCC + LKAS | Stock | 0mph | 0mph |
|
||||
| Nissan | Leaf 2018-19 | Propilot | Stock | 0mph | 0mph |
|
||||
| Nissan | Rogue 2019 | Propilot | Stock | 0mph | 0mph |
|
||||
| Nissan | X-Trail 2017 | Propilot | Stock | 0mph | 0mph |
|
||||
| Nissan | Leaf 2018-19 | ProPILOT | Stock | 0mph | 0mph |
|
||||
| Nissan | Rogue 2019 | ProPILOT | Stock | 0mph | 0mph |
|
||||
| Nissan | X-Trail 2017 | ProPILOT | Stock | 0mph | 0mph |
|
||||
| Subaru | Ascent 2019 | EyeSight | Stock | 0mph | 0mph |
|
||||
| Subaru | Crosstrek 2018-19 | EyeSight | Stock | 0mph | 0mph |
|
||||
| Subaru | Forester 2019 | EyeSight | Stock | 0mph | 0mph |
|
||||
|
@ -274,8 +268,23 @@ Safety and Testing
|
|||
|
||||
Testing on PC
|
||||
------
|
||||
For simplified development and experimentation, openpilot runs in the CARLA driving simulator, which allows you to develop openpilot without a car.
|
||||
|
||||
Steps:
|
||||
1) Start the CARLA server on first terminal
|
||||
```
|
||||
bash -c "$(curl https://raw.githubusercontent.com/commaai/openpilot/master/tools/sim/start_carla.sh)"
|
||||
```
|
||||
2) Start openpilot on second terminal
|
||||
```
|
||||
bash -c "$(curl https://raw.githubusercontent.com/commaai/openpilot/master/tools/sim/start_openpilot_docker.sh)"
|
||||
```
|
||||
3) Press 1 to engage openpilot
|
||||
|
||||
See the full [README](tools/sim/README.md)
|
||||
|
||||
You should also take a look at the tools directory in master: lots of tools you can use to replay driving data, test, and develop openpilot from your PC.
|
||||
|
||||
Check out the tools directory in master: lots of tools you can use to replay driving data, test and develop openpilot from your pc.
|
||||
|
||||
Community and Contributing
|
||||
------
|
||||
|
|
|
@ -1,3 +1,11 @@
|
|||
Version 0.7.9 (2020-10-09)
|
||||
========================
|
||||
* Improved car battery power management
|
||||
* Improved updater robustness
|
||||
* Improved realtime performance
|
||||
* Reduced UI and modeld lags
|
||||
* Increased torque on 2020 Hyundai Sonata and Palisade
|
||||
|
||||
Version 0.7.8 (2020-08-19)
|
||||
========================
|
||||
* New driver monitoring model: improved face detection and better compatibility with sunglasses
|
||||
|
|
71
SConstruct
|
@ -6,6 +6,8 @@ import subprocess
|
|||
import sys
|
||||
import platform
|
||||
|
||||
TICI = os.path.isfile('/TICI')
|
||||
|
||||
AddOption('--test',
|
||||
action='store_true',
|
||||
help='build test files')
|
||||
|
@ -18,10 +20,11 @@ AddOption('--asan',
|
|||
cython_dependencies = [Value(v) for v in (sys.version, distutils.__version__, Cython.__version__)]
|
||||
Export('cython_dependencies')
|
||||
|
||||
arch = subprocess.check_output(["uname", "-m"], encoding='utf8').rstrip()
|
||||
real_arch = arch = subprocess.check_output(["uname", "-m"], encoding='utf8').rstrip()
|
||||
if platform.system() == "Darwin":
|
||||
arch = "Darwin"
|
||||
if arch == "aarch64" and not os.path.isdir("/system"):
|
||||
|
||||
if arch == "aarch64" and TICI:
|
||||
arch = "larch64"
|
||||
|
||||
webcam = bool(ARGUMENTS.get("use_webcam", 0))
|
||||
|
@ -44,7 +47,6 @@ if arch == "aarch64" or arch == "larch64":
|
|||
|
||||
libpath = [
|
||||
"/usr/lib",
|
||||
"/data/data/com.termux/files/usr/lib",
|
||||
"/system/vendor/lib64",
|
||||
"/system/comma/usr/lib",
|
||||
"#phonelibs/nanovg",
|
||||
|
@ -62,11 +64,12 @@ if arch == "aarch64" or arch == "larch64":
|
|||
else:
|
||||
libpath += [
|
||||
"#phonelibs/snpe/aarch64",
|
||||
"#phonelibs/libyuv/lib"
|
||||
"#phonelibs/libyuv/lib",
|
||||
"/system/vendor/lib64"
|
||||
]
|
||||
cflags = ["-DQCOM", "-mcpu=cortex-a57"]
|
||||
cxxflags = ["-DQCOM", "-mcpu=cortex-a57"]
|
||||
rpath = ["/system/vendor/lib64"]
|
||||
rpath = []
|
||||
|
||||
if QCOM_REPLAY:
|
||||
cflags += ["-DQCOM_REPLAY"]
|
||||
|
@ -131,8 +134,11 @@ env = Environment(
|
|||
"-O2",
|
||||
"-Wunused",
|
||||
"-Werror",
|
||||
"-Wno-unknown-warning-option",
|
||||
"-Wno-deprecated-register",
|
||||
"-Wno-inconsistent-missing-override",
|
||||
"-Wno-c99-designator",
|
||||
"-Wno-reorder-init-list",
|
||||
] + cflags + ccflags_asan,
|
||||
|
||||
CPPPATH=cpppath + [
|
||||
|
@ -143,7 +149,6 @@ env = Environment(
|
|||
"#phonelibs/openmax/include",
|
||||
"#phonelibs/json11",
|
||||
"#phonelibs/curl/include",
|
||||
#"#phonelibs/opencv/include", # use opencv4 instead
|
||||
"#phonelibs/libgralloc/include",
|
||||
"#phonelibs/android_frameworks_native/include",
|
||||
"#phonelibs/android_hardware_libhardware/include",
|
||||
|
@ -156,6 +161,8 @@ env = Environment(
|
|||
"#selfdrive/camerad/include",
|
||||
"#selfdrive/loggerd/include",
|
||||
"#selfdrive/modeld",
|
||||
"#selfdrive/sensord",
|
||||
"#selfdrive/ui",
|
||||
"#cereal/messaging",
|
||||
"#cereal",
|
||||
"#opendbc/can",
|
||||
|
@ -176,6 +183,44 @@ env = Environment(
|
|||
]
|
||||
)
|
||||
|
||||
qt_env = None
|
||||
if arch in ["x86_64", "Darwin", "larch64"]:
|
||||
qt_env = env.Clone()
|
||||
|
||||
if arch == "Darwin":
|
||||
qt_env['QTDIR'] = "/usr/local/opt/qt"
|
||||
QT_BASE = "/usr/local/opt/qt/"
|
||||
qt_dirs = [
|
||||
QT_BASE + "include/",
|
||||
QT_BASE + "include/QtWidgets",
|
||||
QT_BASE + "include/QtGui",
|
||||
QT_BASE + "include/QtCore",
|
||||
QT_BASE + "include/QtDBus",
|
||||
QT_BASE + "include/QtMultimedia",
|
||||
]
|
||||
qt_env["LINKFLAGS"] += ["-F" + QT_BASE + "lib"]
|
||||
else:
|
||||
qt_dirs = [
|
||||
f"/usr/include/{real_arch}-linux-gnu/qt5",
|
||||
f"/usr/include/{real_arch}-linux-gnu/qt5/QtWidgets",
|
||||
f"/usr/include/{real_arch}-linux-gnu/qt5/QtGui",
|
||||
f"/usr/include/{real_arch}-linux-gnu/qt5/QtCore",
|
||||
f"/usr/include/{real_arch}-linux-gnu/qt5/QtDBus",
|
||||
f"/usr/include/{real_arch}-linux-gnu/qt5/QtMultimedia",
|
||||
f"/usr/include/{real_arch}-linux-gnu/qt5/QtGui/5.5.1/QtGui",
|
||||
]
|
||||
|
||||
qt_env.Tool('qt')
|
||||
qt_env['CPPPATH'] += qt_dirs
|
||||
qt_flags = [
|
||||
"-D_REENTRANT",
|
||||
"-DQT_NO_DEBUG",
|
||||
"-DQT_WIDGETS_LIB",
|
||||
"-DQT_GUI_LIB",
|
||||
"-DQT_CORE_LIB"
|
||||
]
|
||||
qt_env['CXXFLAGS'] += qt_flags
|
||||
|
||||
if os.environ.get('SCONS_CACHE'):
|
||||
cache_dir = '/tmp/scons_cache'
|
||||
|
||||
|
@ -214,7 +259,7 @@ def abspath(x):
|
|||
|
||||
# still needed for apks
|
||||
zmq = 'zmq'
|
||||
Export('env', 'arch', 'zmq', 'SHARED', 'webcam', 'QCOM_REPLAY')
|
||||
Export('env', 'qt_env', 'arch', 'zmq', 'SHARED', 'webcam', 'QCOM_REPLAY')
|
||||
|
||||
# cereal and messaging are shared with the system
|
||||
SConscript(['cereal/SConscript'])
|
||||
|
@ -255,16 +300,18 @@ SConscript(['selfdrive/controls/lib/longitudinal_mpc_model/SConscript'])
|
|||
|
||||
SConscript(['selfdrive/boardd/SConscript'])
|
||||
SConscript(['selfdrive/proclogd/SConscript'])
|
||||
SConscript(['selfdrive/clocksd/SConscript'])
|
||||
|
||||
SConscript(['selfdrive/ui/SConscript'])
|
||||
SConscript(['selfdrive/loggerd/SConscript'])
|
||||
|
||||
SConscript(['selfdrive/locationd/SConscript'])
|
||||
SConscript(['selfdrive/locationd/models/SConscript'])
|
||||
SConscript(['selfdrive/sensord/SConscript'])
|
||||
SConscript(['selfdrive/ui/SConscript'])
|
||||
|
||||
if arch == "aarch64":
|
||||
if arch != "Darwin":
|
||||
SConscript(['selfdrive/logcatd/SConscript'])
|
||||
SConscript(['selfdrive/sensord/SConscript'])
|
||||
SConscript(['selfdrive/clocksd/SConscript'])
|
||||
else:
|
||||
|
||||
|
||||
if arch == "x86_64":
|
||||
SConscript(['tools/lib/index_log/SConscript'])
|
||||
|
|
|
@ -38,7 +38,6 @@ struct CarEvent @0x9b1657f34caf3ad3 {
|
|||
pedalPressed @13;
|
||||
cruiseDisabled @14;
|
||||
radarCanError @15;
|
||||
dataNeededDEPRECATED @16;
|
||||
speedTooLow @17;
|
||||
outOfSpace @18;
|
||||
overheat @19;
|
||||
|
@ -49,29 +48,22 @@ struct CarEvent @0x9b1657f34caf3ad3 {
|
|||
pcmDisable @24;
|
||||
noTarget @25;
|
||||
radarFault @26;
|
||||
modelCommIssueDEPRECATED @27;
|
||||
brakeHold @28;
|
||||
parkBrake @29;
|
||||
manualRestart @30;
|
||||
lowSpeedLockout @31;
|
||||
plannerError @32;
|
||||
ipasOverrideDEPRECATED @33;
|
||||
debugAlert @34;
|
||||
steerTempUnavailableMute @35;
|
||||
resumeRequired @36;
|
||||
preDriverDistracted @37;
|
||||
promptDriverDistracted @38;
|
||||
driverDistracted @39;
|
||||
geofenceDEPRECATED @40;
|
||||
driverMonitorOnDEPRECATED @41;
|
||||
driverMonitorOffDEPRECATED @42;
|
||||
preDriverUnresponsive @43;
|
||||
promptDriverUnresponsive @44;
|
||||
driverUnresponsive @45;
|
||||
belowSteerSpeed @46;
|
||||
calibrationProgressDEPRECATED @47;
|
||||
lowBattery @48;
|
||||
invalidGiraffeHondaDEPRECATED @49;
|
||||
vehicleModelInvalid @50;
|
||||
controlsFailed @51;
|
||||
sensorDataInvalid @52;
|
||||
|
@ -104,8 +96,6 @@ struct CarEvent @0x9b1657f34caf3ad3 {
|
|||
fcw @79;
|
||||
steerSaturated @80;
|
||||
whitePandaUnsupported @81;
|
||||
startupWhitePanda @82;
|
||||
canErrorPersistentDEPRECATED @83;
|
||||
belowEngageSpeed @84;
|
||||
noGps @85;
|
||||
focusRecoverActive @86;
|
||||
|
@ -113,6 +103,17 @@ struct CarEvent @0x9b1657f34caf3ad3 {
|
|||
neosUpdateRequired @88;
|
||||
modeldLagging @89;
|
||||
deviceFalling @90;
|
||||
|
||||
dataNeededDEPRECATED @16;
|
||||
modelCommIssueDEPRECATED @27;
|
||||
ipasOverrideDEPRECATED @33;
|
||||
geofenceDEPRECATED @40;
|
||||
driverMonitorOnDEPRECATED @41;
|
||||
driverMonitorOffDEPRECATED @42;
|
||||
calibrationProgressDEPRECATED @47;
|
||||
invalidGiraffeHondaDEPRECATED @49;
|
||||
canErrorPersistentDEPRECATED @83;
|
||||
startupWhitePandaDEPRECATED @82;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -186,6 +186,7 @@ struct SensorEventData {
|
|||
gyroUncalibrated @12 :SensorVec;
|
||||
proximity @13: Float32;
|
||||
light @14: Float32;
|
||||
temperature @15: Float32;
|
||||
}
|
||||
source @8 :SensorSource;
|
||||
|
||||
|
@ -203,6 +204,8 @@ struct SensorEventData {
|
|||
lsm6ds3 @5; # accelerometer (c2)
|
||||
bmp280 @6; # barometer (c2)
|
||||
mmc3416x @7; # magnetometer (c2)
|
||||
bmx055 @8;
|
||||
rpr0521 @9;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -267,14 +270,15 @@ struct CanData {
|
|||
}
|
||||
|
||||
struct ThermalData {
|
||||
cpu0 @0 :UInt16;
|
||||
cpu1 @1 :UInt16;
|
||||
cpu2 @2 :UInt16;
|
||||
cpu3 @3 :UInt16;
|
||||
mem @4 :UInt16;
|
||||
gpu @5 :UInt16;
|
||||
bat @6 :UInt32;
|
||||
pa0 @21 :UInt16;
|
||||
# Deprecated
|
||||
cpu0DEPRECATED @0 :UInt16;
|
||||
cpu1DEPRECATED @1 :UInt16;
|
||||
cpu2DEPRECATED @2 :UInt16;
|
||||
cpu3DEPRECATED @3 :UInt16;
|
||||
memDEPRECATED @4 :UInt16;
|
||||
gpuDEPRECATED @5 :UInt16;
|
||||
batDEPRECATED @6 :UInt32;
|
||||
pa0DEPRECATED @21 :UInt16;
|
||||
|
||||
# not thermal
|
||||
freeSpace @7 :Float32;
|
||||
|
@ -286,6 +290,7 @@ struct ThermalData {
|
|||
networkType @22 :NetworkType;
|
||||
offroadPowerUsage @23 :UInt32; # Power usage since going offroad in uWh
|
||||
networkStrength @24 :NetworkStrength;
|
||||
carBatteryCapacity @25 :UInt32; # Estimated remaining car battery capacity in uWh
|
||||
|
||||
fanSpeed @10 :UInt16;
|
||||
started @11 :Bool;
|
||||
|
@ -298,6 +303,12 @@ struct ThermalData {
|
|||
memUsedPercent @19 :Int8;
|
||||
cpuPerc @20 :Int8;
|
||||
|
||||
cpu @26 :List(Float32);
|
||||
gpu @27 :List(Float32);
|
||||
mem @28 :Float32;
|
||||
bat @29 :Float32;
|
||||
ambient @30 :Float32;
|
||||
|
||||
enum ThermalStatus {
|
||||
green @0; # all processes run
|
||||
yellow @1; # critical processes run (kill uploader), engage still allowed
|
||||
|
@ -373,6 +384,8 @@ struct HealthData {
|
|||
interruptRateTim3 @17;
|
||||
registerDivergent @18;
|
||||
interruptRateKlineInit @19;
|
||||
interruptRateClockSource @20;
|
||||
interruptRateTim9 @21;
|
||||
# Update max fault type in boardd when adding faults
|
||||
}
|
||||
|
||||
|
@ -602,7 +615,7 @@ struct ControlsState @0x97ff69c53601abf1 {
|
|||
output @3 :Float32;
|
||||
lqrOutput @4 :Float32;
|
||||
saturated @5 :Bool;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
struct LiveEventData {
|
||||
|
@ -675,6 +688,52 @@ struct ModelData {
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
struct ModelDataV2 {
|
||||
frameId @0 :UInt32;
|
||||
frameAge @1 :UInt32;
|
||||
frameDropPerc @2 :Float32;
|
||||
timestampEof @3 :UInt64;
|
||||
|
||||
position @4 :XYZTData;
|
||||
orientation @5 :XYZTData;
|
||||
velocity @6 :XYZTData;
|
||||
orientationRate @7 :XYZTData;
|
||||
laneLines @8 :List(XYZTData);
|
||||
laneLineProbs @9 :List(Float32);
|
||||
roadEdges @10 :List(XYZTData);
|
||||
leads @11 :List(LeadDataV2);
|
||||
|
||||
meta @12 :MetaData;
|
||||
|
||||
struct XYZTData {
|
||||
x @0 :List(Float32);
|
||||
y @1 :List(Float32);
|
||||
z @2 :List(Float32);
|
||||
t @3 :List(Float32);
|
||||
xStd @4 :List(Float32);
|
||||
yStd @5 :List(Float32);
|
||||
zStd @6 :List(Float32);
|
||||
}
|
||||
|
||||
struct LeadDataV2 {
|
||||
prob @0 :Float32;
|
||||
t @1 :Float32;
|
||||
xyva @2 :List(Float32);
|
||||
xyvaStd @3 :List(Float32);
|
||||
}
|
||||
|
||||
struct MetaData {
|
||||
engagedProb @0 :Float32;
|
||||
desirePrediction @1 :List(Float32);
|
||||
brakeDisengageProb @2 :Float32;
|
||||
gasDisengageProb @3 :Float32;
|
||||
steerOverrideProb @4 :Float32;
|
||||
desireState @5 :List(Float32);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
struct CalibrationFeatures {
|
||||
frameId @0 :UInt32;
|
||||
|
||||
|
@ -1906,7 +1965,6 @@ struct DMonitoringState {
|
|||
isDistracted @2 :Bool;
|
||||
awarenessStatus @3 :Float32;
|
||||
isRHD @4 :Bool;
|
||||
rhdChecked @5 :Bool;
|
||||
posePitchOffset @6 :Float32;
|
||||
posePitchValidCount @7 :UInt32;
|
||||
poseYawOffset @8 :Float32;
|
||||
|
@ -1917,6 +1975,8 @@ struct DMonitoringState {
|
|||
isLowStd @13 :Bool;
|
||||
hiStdCount @14 :UInt32;
|
||||
isPreview @15 :Bool;
|
||||
|
||||
rhdCheckedDEPRECATED @5 :Bool;
|
||||
}
|
||||
|
||||
struct Boot {
|
||||
|
@ -2062,5 +2122,7 @@ struct Event {
|
|||
dMonitoringState @71: DMonitoringState;
|
||||
liveLocationKalman @72 :LiveLocationKalman;
|
||||
sentinel @73 :Sentinel;
|
||||
wideFrame @74: FrameData;
|
||||
modelV2 @75 :ModelDataV2;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -3,6 +3,8 @@ from .messaging_pyx import Context, Poller, SubSocket, PubSocket # pylint: disa
|
|||
from .messaging_pyx import MultiplePublishersError, MessagingError # pylint: disable=no-name-in-module, import-error
|
||||
import capnp
|
||||
|
||||
from typing import Optional, List, Union
|
||||
|
||||
from cereal import log
|
||||
from cereal.services import service_list
|
||||
|
||||
|
@ -19,7 +21,7 @@ except ImportError:
|
|||
|
||||
context = Context()
|
||||
|
||||
def new_message(service=None, size=None):
|
||||
def new_message(service: Optional[str] = None, size: Optional[int] = None) -> capnp.lib.capnp._DynamicStructBuilder:
|
||||
dat = log.Event.new_message()
|
||||
dat.logMonoTime = int(sec_since_boot() * 1e9)
|
||||
dat.valid = True
|
||||
|
@ -30,15 +32,15 @@ def new_message(service=None, size=None):
|
|||
dat.init(service, size)
|
||||
return dat
|
||||
|
||||
def pub_sock(endpoint):
|
||||
def pub_sock(endpoint: str) -> PubSocket:
|
||||
sock = PubSocket()
|
||||
sock.connect(context, endpoint)
|
||||
return sock
|
||||
|
||||
def sub_sock(endpoint, poller=None, addr="127.0.0.1", conflate=False, timeout=None):
|
||||
def sub_sock(endpoint: str, poller: Optional[Poller] = None, addr: str = "127.0.0.1",
|
||||
conflate: bool = False, timeout: Optional[int] = None) -> SubSocket:
|
||||
sock = SubSocket()
|
||||
addr = addr.encode('utf8')
|
||||
sock.connect(context, endpoint, addr, conflate)
|
||||
sock.connect(context, endpoint, addr.encode('utf8'), conflate)
|
||||
|
||||
if timeout is not None:
|
||||
sock.setTimeout(timeout)
|
||||
|
@ -48,9 +50,9 @@ def sub_sock(endpoint, poller=None, addr="127.0.0.1", conflate=False, timeout=No
|
|||
return sock
|
||||
|
||||
|
||||
def drain_sock_raw(sock, wait_for_one=False):
|
||||
def drain_sock_raw(sock: SubSocket, wait_for_one: bool = False) -> List[bytes]:
|
||||
"""Receive all message currently available on the queue"""
|
||||
ret = []
|
||||
ret: List[bytes] = []
|
||||
while 1:
|
||||
if wait_for_one and len(ret) == 0:
|
||||
dat = sock.receive()
|
||||
|
@ -64,9 +66,9 @@ def drain_sock_raw(sock, wait_for_one=False):
|
|||
|
||||
return ret
|
||||
|
||||
def drain_sock(sock, wait_for_one=False):
|
||||
def drain_sock(sock: SubSocket, wait_for_one: bool = False) -> List[capnp.lib.capnp._DynamicStructReader]:
|
||||
"""Receive all message currently available on the queue"""
|
||||
ret = []
|
||||
ret: List[capnp.lib.capnp._DynamicStructReader] = []
|
||||
while 1:
|
||||
if wait_for_one and len(ret) == 0:
|
||||
dat = sock.receive()
|
||||
|
@ -83,7 +85,7 @@ def drain_sock(sock, wait_for_one=False):
|
|||
|
||||
|
||||
# TODO: print when we drop packets?
|
||||
def recv_sock(sock, wait=False):
|
||||
def recv_sock(sock: SubSocket, wait: bool = False) -> Union[None, capnp.lib.capnp._DynamicStructReader]:
|
||||
"""Same as drain sock, but only returns latest message. Consider using conflate instead."""
|
||||
dat = None
|
||||
|
||||
|
@ -103,19 +105,19 @@ def recv_sock(sock, wait=False):
|
|||
|
||||
return dat
|
||||
|
||||
def recv_one(sock):
|
||||
def recv_one(sock: SubSocket) -> Union[None, capnp.lib.capnp._DynamicStructReader]:
|
||||
dat = sock.receive()
|
||||
if dat is not None:
|
||||
dat = log.Event.from_bytes(dat)
|
||||
return dat
|
||||
|
||||
def recv_one_or_none(sock):
|
||||
def recv_one_or_none(sock: SubSocket) -> Union[None, capnp.lib.capnp._DynamicStructReader]:
|
||||
dat = sock.receive(non_blocking=True)
|
||||
if dat is not None:
|
||||
dat = log.Event.from_bytes(dat)
|
||||
return dat
|
||||
|
||||
def recv_one_retry(sock):
|
||||
def recv_one_retry(sock: SubSocket) -> capnp.lib.capnp._DynamicStructReader:
|
||||
"""Keep receiving until we get a message"""
|
||||
while True:
|
||||
dat = sock.receive()
|
||||
|
@ -123,8 +125,8 @@ def recv_one_retry(sock):
|
|||
return log.Event.from_bytes(dat)
|
||||
|
||||
class SubMaster():
|
||||
def __init__(self, services, ignore_alive=None, addr="127.0.0.1"):
|
||||
self.poller = Poller()
|
||||
def __init__(self, services: List[str], poll: Optional[List[str]] = None,
|
||||
ignore_alive: Optional[List[str]] = None, addr:str ="127.0.0.1"):
|
||||
self.frame = -1
|
||||
self.updated = {s: False for s in services}
|
||||
self.rcv_time = {s: 0. for s in services}
|
||||
|
@ -133,8 +135,12 @@ class SubMaster():
|
|||
self.sock = {}
|
||||
self.freq = {}
|
||||
self.data = {}
|
||||
self.logMonoTime = {}
|
||||
self.valid = {}
|
||||
self.logMonoTime = {}
|
||||
|
||||
self.poller = Poller()
|
||||
self.non_polled_services = [s for s in services if poll is not None and
|
||||
len(poll) and s not in poll]
|
||||
|
||||
if ignore_alive is not None:
|
||||
self.ignore_alive = ignore_alive
|
||||
|
@ -143,30 +149,33 @@ class SubMaster():
|
|||
|
||||
for s in services:
|
||||
if addr is not None:
|
||||
self.sock[s] = sub_sock(s, poller=self.poller, addr=addr, conflate=True)
|
||||
p = self.poller if s not in self.non_polled_services else None
|
||||
self.sock[s] = sub_sock(s, poller=p, addr=addr, conflate=True)
|
||||
self.freq[s] = service_list[s].frequency
|
||||
|
||||
try:
|
||||
data = new_message(s)
|
||||
except capnp.lib.capnp.KjException: # pylint: disable=c-extension-no-member
|
||||
# lists
|
||||
data = new_message(s, 0)
|
||||
data = new_message(s, 0) # lists
|
||||
|
||||
self.data[s] = getattr(data, s)
|
||||
self.logMonoTime[s] = 0
|
||||
self.valid[s] = data.valid
|
||||
|
||||
def __getitem__(self, s):
|
||||
def __getitem__(self, s: str) -> capnp.lib.capnp._DynamicStructReader:
|
||||
return self.data[s]
|
||||
|
||||
def update(self, timeout=1000):
|
||||
def update(self, timeout: int = 1000) -> None:
|
||||
msgs = []
|
||||
for sock in self.poller.poll(timeout):
|
||||
msgs.append(recv_one_or_none(sock))
|
||||
|
||||
# non-blocking receive for non-polled sockets
|
||||
for s in self.non_polled_services:
|
||||
msgs.append(recv_one_or_none(self.sock[s]))
|
||||
self.update_msgs(sec_since_boot(), msgs)
|
||||
|
||||
def update_msgs(self, cur_time, msgs):
|
||||
# TODO: add optional input that specify the service to wait for
|
||||
def update_msgs(self, cur_time: float, msgs: List[capnp.lib.capnp._DynamicStructReader]) -> None:
|
||||
self.frame += 1
|
||||
self.updated = dict.fromkeys(self.updated, False)
|
||||
for msg in msgs:
|
||||
|
@ -189,30 +198,28 @@ class SubMaster():
|
|||
else:
|
||||
self.alive[s] = True
|
||||
|
||||
def all_alive(self, service_list=None):
|
||||
def all_alive(self, service_list=None) -> bool:
|
||||
if service_list is None: # check all
|
||||
service_list = self.alive.keys()
|
||||
return all(self.alive[s] for s in service_list if s not in self.ignore_alive)
|
||||
|
||||
def all_valid(self, service_list=None):
|
||||
def all_valid(self, service_list=None) -> bool:
|
||||
if service_list is None: # check all
|
||||
service_list = self.valid.keys()
|
||||
return all(self.valid[s] for s in service_list)
|
||||
|
||||
def all_alive_and_valid(self, service_list=None):
|
||||
def all_alive_and_valid(self, service_list=None) -> bool:
|
||||
if service_list is None: # check all
|
||||
service_list = self.alive.keys()
|
||||
return self.all_alive(service_list=service_list) and self.all_valid(service_list=service_list)
|
||||
|
||||
|
||||
class PubMaster():
|
||||
def __init__(self, services):
|
||||
def __init__(self, services: List[str]):
|
||||
self.sock = {}
|
||||
for s in services:
|
||||
self.sock[s] = pub_sock(s)
|
||||
|
||||
def send(self, s, dat):
|
||||
# accept either bytes or capnp builder
|
||||
def send(self, s: str, dat: Union[bytes, capnp.lib.capnp._DynamicStructBuilder]) -> None:
|
||||
if not isinstance(dat, bytes):
|
||||
dat = dat.to_bytes()
|
||||
self.sock[s].send(dat)
|
||||
|
|
|
@ -15,6 +15,18 @@ void sig_handler(int signal) {
|
|||
msgq_do_exit = 1;
|
||||
}
|
||||
|
||||
static size_t get_size(std::string endpoint){
|
||||
size_t sz = DEFAULT_SEGMENT_SIZE;
|
||||
|
||||
#if !defined(QCOM) && !defined(QCOM2)
|
||||
if (endpoint == "frame" || endpoint == "frontFrame" || endpoint == "wideFrame"){
|
||||
sz *= 10;
|
||||
}
|
||||
#endif
|
||||
|
||||
return sz;
|
||||
}
|
||||
|
||||
|
||||
MSGQContext::MSGQContext() {
|
||||
}
|
||||
|
@ -49,13 +61,12 @@ MSGQMessage::~MSGQMessage() {
|
|||
this->close();
|
||||
}
|
||||
|
||||
|
||||
int MSGQSubSocket::connect(Context *context, std::string endpoint, std::string address, bool conflate){
|
||||
assert(context);
|
||||
assert(address == "127.0.0.1");
|
||||
|
||||
q = new msgq_queue_t;
|
||||
int r = msgq_new_queue(q, endpoint.c_str(), DEFAULT_SEGMENT_SIZE);
|
||||
int r = msgq_new_queue(q, endpoint.c_str(), get_size(endpoint));
|
||||
if (r != 0){
|
||||
return r;
|
||||
}
|
||||
|
@ -143,7 +154,7 @@ int MSGQPubSocket::connect(Context *context, std::string endpoint){
|
|||
assert(context);
|
||||
|
||||
q = new msgq_queue_t;
|
||||
int r = msgq_new_queue(q, endpoint.c_str(), DEFAULT_SEGMENT_SIZE);
|
||||
int r = msgq_new_queue(q, endpoint.c_str(), get_size(endpoint));
|
||||
if (r != 0){
|
||||
return r;
|
||||
}
|
||||
|
|
|
@ -6,6 +6,10 @@
|
|||
#include <capnp/serialize.h>
|
||||
#include "../gen/cpp/log.capnp.h"
|
||||
|
||||
#ifdef __APPLE__
|
||||
#define CLOCK_BOOTTIME CLOCK_MONOTONIC
|
||||
#endif
|
||||
|
||||
#define MSG_MULTIPLE_PUBLISHERS 100
|
||||
|
||||
class Context {
|
||||
|
@ -82,11 +86,34 @@ private:
|
|||
std::map<std::string, SubMessage *> services_;
|
||||
};
|
||||
|
||||
class MessageBuilder : public capnp::MallocMessageBuilder {
|
||||
public:
|
||||
MessageBuilder() = default;
|
||||
|
||||
cereal::Event::Builder initEvent(bool valid = true) {
|
||||
cereal::Event::Builder event = initRoot<cereal::Event>();
|
||||
struct timespec t;
|
||||
clock_gettime(CLOCK_BOOTTIME, &t);
|
||||
uint64_t current_time = t.tv_sec * 1000000000ULL + t.tv_nsec;
|
||||
event.setLogMonoTime(current_time);
|
||||
event.setValid(valid);
|
||||
return event;
|
||||
}
|
||||
|
||||
kj::ArrayPtr<capnp::byte> toBytes() {
|
||||
heapArray_ = capnp::messageToFlatArray(*this);
|
||||
return heapArray_.asBytes();
|
||||
}
|
||||
|
||||
private:
|
||||
kj::Array<capnp::word> heapArray_;
|
||||
};
|
||||
|
||||
class PubMaster {
|
||||
public:
|
||||
PubMaster(const std::initializer_list<const char *> &service_list);
|
||||
inline int send(const char *name, capnp::byte *data, size_t size) { return sockets_.at(name)->send((char *)data, size); }
|
||||
int send(const char *name, capnp::MessageBuilder &msg);
|
||||
int send(const char *name, MessageBuilder &msg);
|
||||
~PubMaster();
|
||||
|
||||
private:
|
||||
|
|
|
@ -6,6 +6,7 @@ from distutils.core import Extension, setup # pylint: disable=import-error,no-n
|
|||
from Cython.Build import cythonize
|
||||
from Cython.Distutils import build_ext
|
||||
|
||||
TICI = os.path.isfile('/TICI')
|
||||
|
||||
def get_ext_filename_without_platform_suffix(filename):
|
||||
name, ext = os.path.splitext(filename)
|
||||
|
@ -30,11 +31,11 @@ class BuildExtWithoutPlatformSuffix(build_ext):
|
|||
|
||||
|
||||
sourcefiles = ['messaging_pyx.pyx']
|
||||
extra_compile_args = ["-std=c++14"]
|
||||
extra_compile_args = ["-std=c++14", "-Wno-nullability-completeness"]
|
||||
libraries = ['zmq']
|
||||
ARCH = subprocess.check_output(["uname", "-m"], encoding='utf8').rstrip() # pylint: disable=unexpected-keyword-arg
|
||||
|
||||
if ARCH == "aarch64" and os.path.isdir("/system"):
|
||||
if ARCH == "aarch64" and not TICI:
|
||||
# android
|
||||
extra_compile_args += ["-Wno-deprecated-register"]
|
||||
libraries += ['gnustl_shared']
|
||||
|
|
|
@ -21,6 +21,8 @@
|
|||
|
||||
#include <stdio.h>
|
||||
|
||||
#include "services.h"
|
||||
|
||||
#include "msgq.hpp"
|
||||
|
||||
void sigusr2_handler(int signal) {
|
||||
|
@ -81,11 +83,20 @@ void msgq_wait_for_subscriber(msgq_queue_t *q){
|
|||
return;
|
||||
}
|
||||
|
||||
|
||||
bool service_exists(std::string path){
|
||||
for (const auto& it : services) {
|
||||
if (it.name == path) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
int msgq_new_queue(msgq_queue_t * q, const char * path, size_t size){
|
||||
assert(size < 0xFFFFFFFF); // Buffer must be smaller than 2^32 bytes
|
||||
|
||||
if (!service_exists(std::string(path))){
|
||||
std::cout << "Warning, " << std::string(path) << " is not in service list." << std::endl;
|
||||
}
|
||||
std::signal(SIGUSR2, sigusr2_handler);
|
||||
|
||||
const char * prefix = "/dev/shm/";
|
||||
|
@ -102,15 +113,15 @@ int msgq_new_queue(msgq_queue_t * q, const char * path, size_t size){
|
|||
delete[] full_path;
|
||||
|
||||
int rc = ftruncate(fd, size + sizeof(msgq_header_t));
|
||||
if (rc < 0)
|
||||
if (rc < 0){
|
||||
return -1;
|
||||
|
||||
}
|
||||
char * mem = (char*)mmap(NULL, size + sizeof(msgq_header_t), PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
|
||||
close(fd);
|
||||
|
||||
if (mem == NULL)
|
||||
if (mem == NULL){
|
||||
return -1;
|
||||
|
||||
}
|
||||
q->mmap_p = mem;
|
||||
|
||||
msgq_header_t *header = (msgq_header_t *)mem;
|
||||
|
@ -418,8 +429,6 @@ int msgq_msg_recv(msgq_msg_t * msg, msgq_queue_t * q){
|
|||
|
||||
|
||||
int msgq_poll(msgq_pollitem_t * items, size_t nitems, int timeout){
|
||||
assert(timeout >= 0);
|
||||
|
||||
int num = 0;
|
||||
|
||||
// Check if messages ready
|
||||
|
|
|
@ -3,10 +3,6 @@
|
|||
#include "messaging.hpp"
|
||||
#include "services.h"
|
||||
|
||||
#ifdef __APPLE__
|
||||
#define CLOCK_BOOTTIME CLOCK_MONOTONIC
|
||||
#endif
|
||||
|
||||
static inline uint64_t nanos_since_boot() {
|
||||
struct timespec t;
|
||||
clock_gettime(CLOCK_BOOTTIME, &t);
|
||||
|
@ -164,9 +160,8 @@ PubMaster::PubMaster(const std::initializer_list<const char *> &service_list) {
|
|||
}
|
||||
}
|
||||
|
||||
int PubMaster::send(const char *name, capnp::MessageBuilder &msg) {
|
||||
auto words = capnp::messageToFlatArray(msg);
|
||||
auto bytes = words.asBytes();
|
||||
int PubMaster::send(const char *name, MessageBuilder &msg) {
|
||||
auto bytes = msg.toBytes();
|
||||
return send(name, bytes.begin(), bytes.size());
|
||||
}
|
||||
|
||||
|
|
|
@ -78,6 +78,8 @@ frontFrame: [8072, true, 10.]
|
|||
dMonitoringState: [8073, true, 5., 1]
|
||||
offroadLayout: [8074, false, 0.]
|
||||
wideEncodeIdx: [8075, true, 20.]
|
||||
wideFrame: [8076, true, 20.]
|
||||
modelV2: [8077, true, 20., 20]
|
||||
|
||||
testModel: [8040, false, 0.]
|
||||
testLiveLocation: [8045, false, 0.]
|
||||
|
|
|
@ -1,286 +0,0 @@
|
|||
import os
|
||||
import binascii
|
||||
import itertools
|
||||
import re
|
||||
import struct
|
||||
import subprocess
|
||||
import random
|
||||
from cereal import log
|
||||
|
||||
NetworkType = log.ThermalData.NetworkType
|
||||
NetworkStrength = log.ThermalData.NetworkStrength
|
||||
|
||||
ANDROID = os.path.isfile('/EON')
|
||||
|
||||
def get_sound_card_online():
|
||||
return (os.path.isfile('/proc/asound/card0/state') and
|
||||
open('/proc/asound/card0/state').read().strip() == 'ONLINE')
|
||||
|
||||
def getprop(key):
|
||||
if not ANDROID:
|
||||
return ""
|
||||
return subprocess.check_output(["getprop", key], encoding='utf8').strip()
|
||||
|
||||
def get_imei(slot):
|
||||
slot = str(slot)
|
||||
if slot not in ("0", "1"):
|
||||
raise ValueError("SIM slot must be 0 or 1")
|
||||
|
||||
ret = parse_service_call_string(service_call(["iphonesubinfo", "3" , "i32", str(slot)]))
|
||||
if not ret:
|
||||
# allow non android to be identified differently
|
||||
ret = "%015d" % random.randint(0, 1 << 32)
|
||||
return ret
|
||||
|
||||
def get_serial():
|
||||
ret = getprop("ro.serialno")
|
||||
if ret == "":
|
||||
ret = "cccccccc"
|
||||
return ret
|
||||
|
||||
def get_subscriber_info():
|
||||
ret = parse_service_call_string(service_call(["iphonesubinfo", "7"]))
|
||||
if ret is None or len(ret) < 8:
|
||||
return ""
|
||||
return ret
|
||||
|
||||
def reboot(reason=None):
|
||||
if reason is None:
|
||||
reason_args = ["null"]
|
||||
else:
|
||||
reason_args = ["s16", reason]
|
||||
|
||||
subprocess.check_output([
|
||||
"service", "call", "power", "16", # IPowerManager.reboot
|
||||
"i32", "0", # no confirmation,
|
||||
*reason_args,
|
||||
"i32", "1" # wait
|
||||
])
|
||||
|
||||
def service_call(call):
|
||||
if not ANDROID:
|
||||
return None
|
||||
|
||||
ret = subprocess.check_output(["service", "call", *call], encoding='utf8').strip()
|
||||
if 'Parcel' not in ret:
|
||||
return None
|
||||
|
||||
return parse_service_call_bytes(ret)
|
||||
|
||||
def parse_service_call_unpack(r, fmt):
|
||||
try:
|
||||
return struct.unpack(fmt, r)[0]
|
||||
except Exception:
|
||||
return None
|
||||
|
||||
def parse_service_call_string(r):
|
||||
try:
|
||||
r = r[8:] # Cut off length field
|
||||
r = r.decode('utf_16_be')
|
||||
|
||||
# All pairs of two characters seem to be swapped. Not sure why
|
||||
result = ""
|
||||
for a, b, in itertools.zip_longest(r[::2], r[1::2], fillvalue='\x00'):
|
||||
result += b + a
|
||||
|
||||
result = result.replace('\x00', '')
|
||||
|
||||
return result
|
||||
except Exception:
|
||||
return None
|
||||
|
||||
def parse_service_call_bytes(ret):
|
||||
try:
|
||||
r = b""
|
||||
for hex_part in re.findall(r'[ (]([0-9a-f]{8})', ret):
|
||||
r += binascii.unhexlify(hex_part)
|
||||
return r
|
||||
except Exception:
|
||||
return None
|
||||
|
||||
def get_network_type():
|
||||
if not ANDROID:
|
||||
return NetworkType.none
|
||||
|
||||
wifi_check = parse_service_call_string(service_call(["connectivity", "2"]))
|
||||
if wifi_check is None:
|
||||
return NetworkType.none
|
||||
elif 'WIFI' in wifi_check:
|
||||
return NetworkType.wifi
|
||||
else:
|
||||
cell_check = parse_service_call_unpack(service_call(['phone', '59']), ">q")
|
||||
# from TelephonyManager.java
|
||||
cell_networks = {
|
||||
0: NetworkType.none,
|
||||
1: NetworkType.cell2G,
|
||||
2: NetworkType.cell2G,
|
||||
3: NetworkType.cell3G,
|
||||
4: NetworkType.cell2G,
|
||||
5: NetworkType.cell3G,
|
||||
6: NetworkType.cell3G,
|
||||
7: NetworkType.cell3G,
|
||||
8: NetworkType.cell3G,
|
||||
9: NetworkType.cell3G,
|
||||
10: NetworkType.cell3G,
|
||||
11: NetworkType.cell2G,
|
||||
12: NetworkType.cell3G,
|
||||
13: NetworkType.cell4G,
|
||||
14: NetworkType.cell4G,
|
||||
15: NetworkType.cell3G,
|
||||
16: NetworkType.cell2G,
|
||||
17: NetworkType.cell3G,
|
||||
18: NetworkType.cell4G,
|
||||
19: NetworkType.cell4G
|
||||
}
|
||||
return cell_networks.get(cell_check, NetworkType.none)
|
||||
|
||||
def get_network_strength(network_type):
|
||||
network_strength = NetworkStrength.unknown
|
||||
|
||||
# from SignalStrength.java
|
||||
def get_lte_level(rsrp, rssnr):
|
||||
INT_MAX = 2147483647
|
||||
if rsrp == INT_MAX:
|
||||
lvl_rsrp = NetworkStrength.unknown
|
||||
elif rsrp >= -95:
|
||||
lvl_rsrp = NetworkStrength.great
|
||||
elif rsrp >= -105:
|
||||
lvl_rsrp = NetworkStrength.good
|
||||
elif rsrp >= -115:
|
||||
lvl_rsrp = NetworkStrength.moderate
|
||||
else:
|
||||
lvl_rsrp = NetworkStrength.poor
|
||||
if rssnr == INT_MAX:
|
||||
lvl_rssnr = NetworkStrength.unknown
|
||||
elif rssnr >= 45:
|
||||
lvl_rssnr = NetworkStrength.great
|
||||
elif rssnr >= 10:
|
||||
lvl_rssnr = NetworkStrength.good
|
||||
elif rssnr >= -30:
|
||||
lvl_rssnr = NetworkStrength.moderate
|
||||
else:
|
||||
lvl_rssnr = NetworkStrength.poor
|
||||
return max(lvl_rsrp, lvl_rssnr)
|
||||
|
||||
def get_tdscdma_level(tdscmadbm):
|
||||
lvl = NetworkStrength.unknown
|
||||
if tdscmadbm > -25:
|
||||
lvl = NetworkStrength.unknown
|
||||
elif tdscmadbm >= -49:
|
||||
lvl = NetworkStrength.great
|
||||
elif tdscmadbm >= -73:
|
||||
lvl = NetworkStrength.good
|
||||
elif tdscmadbm >= -97:
|
||||
lvl = NetworkStrength.moderate
|
||||
elif tdscmadbm >= -110:
|
||||
lvl = NetworkStrength.poor
|
||||
return lvl
|
||||
|
||||
def get_gsm_level(asu):
|
||||
if asu <= 2 or asu == 99:
|
||||
lvl = NetworkStrength.unknown
|
||||
elif asu >= 12:
|
||||
lvl = NetworkStrength.great
|
||||
elif asu >= 8:
|
||||
lvl = NetworkStrength.good
|
||||
elif asu >= 5:
|
||||
lvl = NetworkStrength.moderate
|
||||
else:
|
||||
lvl = NetworkStrength.poor
|
||||
return lvl
|
||||
|
||||
def get_evdo_level(evdodbm, evdosnr):
|
||||
lvl_evdodbm = NetworkStrength.unknown
|
||||
lvl_evdosnr = NetworkStrength.unknown
|
||||
if evdodbm >= -65:
|
||||
lvl_evdodbm = NetworkStrength.great
|
||||
elif evdodbm >= -75:
|
||||
lvl_evdodbm = NetworkStrength.good
|
||||
elif evdodbm >= -90:
|
||||
lvl_evdodbm = NetworkStrength.moderate
|
||||
elif evdodbm >= -105:
|
||||
lvl_evdodbm = NetworkStrength.poor
|
||||
if evdosnr >= 7:
|
||||
lvl_evdosnr = NetworkStrength.great
|
||||
elif evdosnr >= 5:
|
||||
lvl_evdosnr = NetworkStrength.good
|
||||
elif evdosnr >= 3:
|
||||
lvl_evdosnr = NetworkStrength.moderate
|
||||
elif evdosnr >= 1:
|
||||
lvl_evdosnr = NetworkStrength.poor
|
||||
return max(lvl_evdodbm, lvl_evdosnr)
|
||||
|
||||
def get_cdma_level(cdmadbm, cdmaecio):
|
||||
lvl_cdmadbm = NetworkStrength.unknown
|
||||
lvl_cdmaecio = NetworkStrength.unknown
|
||||
if cdmadbm >= -75:
|
||||
lvl_cdmadbm = NetworkStrength.great
|
||||
elif cdmadbm >= -85:
|
||||
lvl_cdmadbm = NetworkStrength.good
|
||||
elif cdmadbm >= -95:
|
||||
lvl_cdmadbm = NetworkStrength.moderate
|
||||
elif cdmadbm >= -100:
|
||||
lvl_cdmadbm = NetworkStrength.poor
|
||||
if cdmaecio >= -90:
|
||||
lvl_cdmaecio = NetworkStrength.great
|
||||
elif cdmaecio >= -110:
|
||||
lvl_cdmaecio = NetworkStrength.good
|
||||
elif cdmaecio >= -130:
|
||||
lvl_cdmaecio = NetworkStrength.moderate
|
||||
elif cdmaecio >= -150:
|
||||
lvl_cdmaecio = NetworkStrength.poor
|
||||
return max(lvl_cdmadbm, lvl_cdmaecio)
|
||||
|
||||
if network_type == NetworkType.none:
|
||||
return network_strength
|
||||
if network_type == NetworkType.wifi:
|
||||
out = subprocess.check_output('dumpsys connectivity', shell=True).decode('utf-8')
|
||||
network_strength = NetworkStrength.unknown
|
||||
for line in out.split('\n'):
|
||||
signal_str = "SignalStrength: "
|
||||
if signal_str in line:
|
||||
lvl_idx_start = line.find(signal_str) + len(signal_str)
|
||||
lvl_idx_end = line.find(']', lvl_idx_start)
|
||||
lvl = int(line[lvl_idx_start : lvl_idx_end])
|
||||
if lvl >= -50:
|
||||
network_strength = NetworkStrength.great
|
||||
elif lvl >= -60:
|
||||
network_strength = NetworkStrength.good
|
||||
elif lvl >= -70:
|
||||
network_strength = NetworkStrength.moderate
|
||||
else:
|
||||
network_strength = NetworkStrength.poor
|
||||
return network_strength
|
||||
else:
|
||||
# check cell strength
|
||||
out = subprocess.check_output('dumpsys telephony.registry', shell=True).decode('utf-8')
|
||||
for line in out.split('\n'):
|
||||
if "mSignalStrength" in line:
|
||||
arr = line.split(' ')
|
||||
ns = 0
|
||||
if ("gsm" in arr[14]):
|
||||
rsrp = int(arr[9])
|
||||
rssnr = int(arr[11])
|
||||
ns = get_lte_level(rsrp, rssnr)
|
||||
if ns == NetworkStrength.unknown:
|
||||
tdscmadbm = int(arr[13])
|
||||
ns = get_tdscdma_level(tdscmadbm)
|
||||
if ns == NetworkStrength.unknown:
|
||||
asu = int(arr[1])
|
||||
ns = get_gsm_level(asu)
|
||||
else:
|
||||
cdmadbm = int(arr[3])
|
||||
cdmaecio = int(arr[4])
|
||||
evdodbm = int(arr[5])
|
||||
evdosnr = int(arr[7])
|
||||
lvl_cdma = get_cdma_level(cdmadbm, cdmaecio)
|
||||
lvl_edmo = get_evdo_level(evdodbm, evdosnr)
|
||||
if lvl_edmo == NetworkStrength.unknown:
|
||||
ns = lvl_cdma
|
||||
elif lvl_cdma == NetworkStrength.unknown:
|
||||
ns = lvl_edmo
|
||||
else:
|
||||
ns = min(lvl_cdma, lvl_edmo)
|
||||
network_strength = max(network_strength, ns)
|
||||
|
||||
return network_strength
|
|
@ -1,10 +1,10 @@
|
|||
import os
|
||||
BASEDIR = os.path.abspath(os.path.join(os.path.dirname(os.path.realpath(__file__)), "../"))
|
||||
|
||||
from common.android import ANDROID
|
||||
if ANDROID:
|
||||
PERSIST = "/persist"
|
||||
PARAMS = "/data/params"
|
||||
else:
|
||||
from common.hardware import PC
|
||||
if PC:
|
||||
PERSIST = os.path.join(BASEDIR, "persist")
|
||||
PARAMS = os.path.join(BASEDIR, "persist", "params")
|
||||
else:
|
||||
PERSIST = "/persist"
|
||||
PARAMS = "/data/params"
|
||||
|
|
|
@ -0,0 +1,22 @@
|
|||
GPIO_HUB_RST_N = 30
|
||||
GPIO_UBLOX_RST_N = 32
|
||||
GPIO_UBLOX_SAFEBOOT_N = 33
|
||||
GPIO_UBLOX_PWR_EN = 34
|
||||
GPIO_STM_RST_N = 124
|
||||
GPIO_STM_BOOT0 = 134
|
||||
|
||||
|
||||
def gpio_init(pin, output):
|
||||
try:
|
||||
with open(f"/sys/class/gpio/gpio{pin}/direction", 'wb') as f:
|
||||
f.write(b"out" if output else b"in")
|
||||
except Exception as e:
|
||||
print(f"Failed to set gpio {pin} direction: {e}")
|
||||
|
||||
|
||||
def gpio_set(pin, high):
|
||||
try:
|
||||
with open(f"/sys/class/gpio/gpio{pin}/value", 'wb') as f:
|
||||
f.write(b"1" if high else b"0")
|
||||
except Exception as e:
|
||||
print(f"Failed to set gpio {pin} value: {e}")
|
|
@ -0,0 +1,57 @@
|
|||
import os
|
||||
import random
|
||||
from typing import cast
|
||||
|
||||
from cereal import log
|
||||
from common.hardware_android import Android
|
||||
from common.hardware_tici import Tici
|
||||
from common.hardware_base import HardwareBase
|
||||
|
||||
EON = os.path.isfile('/EON')
|
||||
TICI = os.path.isfile('/TICI')
|
||||
PC = not (EON or TICI)
|
||||
ANDROID = EON
|
||||
|
||||
|
||||
NetworkType = log.ThermalData.NetworkType
|
||||
NetworkStrength = log.ThermalData.NetworkStrength
|
||||
|
||||
|
||||
class Pc(HardwareBase):
|
||||
def get_sound_card_online(self):
|
||||
return True
|
||||
|
||||
def get_imei(self, slot):
|
||||
return "%015d" % random.randint(0, 1 << 32)
|
||||
|
||||
def get_serial(self):
|
||||
return "cccccccc"
|
||||
|
||||
def get_subscriber_info(self):
|
||||
return ""
|
||||
|
||||
def reboot(self, reason=None):
|
||||
print("REBOOT!")
|
||||
|
||||
def get_network_type(self):
|
||||
return NetworkType.wifi
|
||||
|
||||
def get_sim_info(self):
|
||||
return {
|
||||
'sim_id': '',
|
||||
'mcc_mnc': None,
|
||||
'network_type': ["Unknown"],
|
||||
'sim_state': ["ABSENT"],
|
||||
'data_connected': False
|
||||
}
|
||||
|
||||
def get_network_strength(self, network_type):
|
||||
return NetworkStrength.unknown
|
||||
|
||||
|
||||
if EON:
|
||||
HARDWARE = cast(HardwareBase, Android())
|
||||
elif TICI:
|
||||
HARDWARE = cast(HardwareBase, Tici())
|
||||
else:
|
||||
HARDWARE = cast(HardwareBase, Pc())
|
|
@ -0,0 +1,302 @@
|
|||
import binascii
|
||||
import itertools
|
||||
import os
|
||||
import re
|
||||
import struct
|
||||
import subprocess
|
||||
|
||||
from cereal import log
|
||||
from common.hardware_base import HardwareBase
|
||||
|
||||
NetworkType = log.ThermalData.NetworkType
|
||||
NetworkStrength = log.ThermalData.NetworkStrength
|
||||
|
||||
|
||||
def service_call(call):
|
||||
try:
|
||||
ret = subprocess.check_output(["service", "call", *call], encoding='utf8').strip()
|
||||
if 'Parcel' not in ret:
|
||||
return None
|
||||
return parse_service_call_bytes(ret)
|
||||
except subprocess.CalledProcessError:
|
||||
return None
|
||||
|
||||
|
||||
def parse_service_call_unpack(r, fmt):
|
||||
try:
|
||||
return struct.unpack(fmt, r)[0]
|
||||
except Exception:
|
||||
return None
|
||||
|
||||
|
||||
def parse_service_call_string(r):
|
||||
try:
|
||||
r = r[8:] # Cut off length field
|
||||
r = r.decode('utf_16_be')
|
||||
|
||||
# All pairs of two characters seem to be swapped. Not sure why
|
||||
result = ""
|
||||
for a, b, in itertools.zip_longest(r[::2], r[1::2], fillvalue='\x00'):
|
||||
result += b + a
|
||||
|
||||
result = result.replace('\x00', '')
|
||||
|
||||
return result
|
||||
except Exception:
|
||||
return None
|
||||
|
||||
|
||||
def parse_service_call_bytes(ret):
|
||||
try:
|
||||
r = b""
|
||||
for hex_part in re.findall(r'[ (]([0-9a-f]{8})', ret):
|
||||
r += binascii.unhexlify(hex_part)
|
||||
return r
|
||||
except Exception:
|
||||
return None
|
||||
|
||||
|
||||
def getprop(key):
|
||||
return subprocess.check_output(["getprop", key], encoding='utf8').strip()
|
||||
|
||||
|
||||
class Android(HardwareBase):
|
||||
def get_sound_card_online(self):
|
||||
return (os.path.isfile('/proc/asound/card0/state') and
|
||||
open('/proc/asound/card0/state').read().strip() == 'ONLINE')
|
||||
|
||||
def get_imei(self, slot):
|
||||
slot = str(slot)
|
||||
if slot not in ("0", "1"):
|
||||
raise ValueError("SIM slot must be 0 or 1")
|
||||
|
||||
return parse_service_call_string(service_call(["iphonesubinfo", "3", "i32", str(slot)]))
|
||||
|
||||
def get_serial(self):
|
||||
ret = getprop("ro.serialno")
|
||||
if ret == "":
|
||||
ret = "cccccccc"
|
||||
return ret
|
||||
|
||||
def get_subscriber_info(self):
|
||||
ret = parse_service_call_string(service_call(["iphonesubinfo", "7"]))
|
||||
if ret is None or len(ret) < 8:
|
||||
return ""
|
||||
return ret
|
||||
|
||||
def reboot(self, reason=None):
|
||||
# e.g. reason="recovery" to go into recover mode
|
||||
if reason is None:
|
||||
reason_args = ["null"]
|
||||
else:
|
||||
reason_args = ["s16", reason]
|
||||
|
||||
subprocess.check_output([
|
||||
"service", "call", "power", "16", # IPowerManager.reboot
|
||||
"i32", "0", # no confirmation,
|
||||
*reason_args,
|
||||
"i32", "1" # wait
|
||||
])
|
||||
|
||||
def get_sim_info(self):
|
||||
# Used for athena
|
||||
# TODO: build using methods from this class
|
||||
sim_state = getprop("gsm.sim.state").split(",")
|
||||
network_type = getprop("gsm.network.type").split(',')
|
||||
mcc_mnc = getprop("gsm.sim.operator.numeric") or None
|
||||
|
||||
sim_id = parse_service_call_string(service_call(['iphonesubinfo', '11']))
|
||||
cell_data_state = parse_service_call_unpack(service_call(['phone', '46']), ">q")
|
||||
cell_data_connected = (cell_data_state == 2)
|
||||
|
||||
return {
|
||||
'sim_id': sim_id,
|
||||
'mcc_mnc': mcc_mnc,
|
||||
'network_type': network_type,
|
||||
'sim_state': sim_state,
|
||||
'data_connected': cell_data_connected
|
||||
}
|
||||
|
||||
def get_network_type(self):
|
||||
wifi_check = parse_service_call_string(service_call(["connectivity", "2"]))
|
||||
if wifi_check is None:
|
||||
return NetworkType.none
|
||||
elif 'WIFI' in wifi_check:
|
||||
return NetworkType.wifi
|
||||
else:
|
||||
cell_check = parse_service_call_unpack(service_call(['phone', '59']), ">q")
|
||||
# from TelephonyManager.java
|
||||
cell_networks = {
|
||||
0: NetworkType.none,
|
||||
1: NetworkType.cell2G,
|
||||
2: NetworkType.cell2G,
|
||||
3: NetworkType.cell3G,
|
||||
4: NetworkType.cell2G,
|
||||
5: NetworkType.cell3G,
|
||||
6: NetworkType.cell3G,
|
||||
7: NetworkType.cell3G,
|
||||
8: NetworkType.cell3G,
|
||||
9: NetworkType.cell3G,
|
||||
10: NetworkType.cell3G,
|
||||
11: NetworkType.cell2G,
|
||||
12: NetworkType.cell3G,
|
||||
13: NetworkType.cell4G,
|
||||
14: NetworkType.cell4G,
|
||||
15: NetworkType.cell3G,
|
||||
16: NetworkType.cell2G,
|
||||
17: NetworkType.cell3G,
|
||||
18: NetworkType.cell4G,
|
||||
19: NetworkType.cell4G
|
||||
}
|
||||
return cell_networks.get(cell_check, NetworkType.none)
|
||||
|
||||
def get_network_strength(self, network_type):
|
||||
network_strength = NetworkStrength.unknown
|
||||
|
||||
# from SignalStrength.java
|
||||
def get_lte_level(rsrp, rssnr):
|
||||
INT_MAX = 2147483647
|
||||
if rsrp == INT_MAX:
|
||||
lvl_rsrp = NetworkStrength.unknown
|
||||
elif rsrp >= -95:
|
||||
lvl_rsrp = NetworkStrength.great
|
||||
elif rsrp >= -105:
|
||||
lvl_rsrp = NetworkStrength.good
|
||||
elif rsrp >= -115:
|
||||
lvl_rsrp = NetworkStrength.moderate
|
||||
else:
|
||||
lvl_rsrp = NetworkStrength.poor
|
||||
if rssnr == INT_MAX:
|
||||
lvl_rssnr = NetworkStrength.unknown
|
||||
elif rssnr >= 45:
|
||||
lvl_rssnr = NetworkStrength.great
|
||||
elif rssnr >= 10:
|
||||
lvl_rssnr = NetworkStrength.good
|
||||
elif rssnr >= -30:
|
||||
lvl_rssnr = NetworkStrength.moderate
|
||||
else:
|
||||
lvl_rssnr = NetworkStrength.poor
|
||||
return max(lvl_rsrp, lvl_rssnr)
|
||||
|
||||
def get_tdscdma_level(tdscmadbm):
|
||||
lvl = NetworkStrength.unknown
|
||||
if tdscmadbm > -25:
|
||||
lvl = NetworkStrength.unknown
|
||||
elif tdscmadbm >= -49:
|
||||
lvl = NetworkStrength.great
|
||||
elif tdscmadbm >= -73:
|
||||
lvl = NetworkStrength.good
|
||||
elif tdscmadbm >= -97:
|
||||
lvl = NetworkStrength.moderate
|
||||
elif tdscmadbm >= -110:
|
||||
lvl = NetworkStrength.poor
|
||||
return lvl
|
||||
|
||||
def get_gsm_level(asu):
|
||||
if asu <= 2 or asu == 99:
|
||||
lvl = NetworkStrength.unknown
|
||||
elif asu >= 12:
|
||||
lvl = NetworkStrength.great
|
||||
elif asu >= 8:
|
||||
lvl = NetworkStrength.good
|
||||
elif asu >= 5:
|
||||
lvl = NetworkStrength.moderate
|
||||
else:
|
||||
lvl = NetworkStrength.poor
|
||||
return lvl
|
||||
|
||||
def get_evdo_level(evdodbm, evdosnr):
|
||||
lvl_evdodbm = NetworkStrength.unknown
|
||||
lvl_evdosnr = NetworkStrength.unknown
|
||||
if evdodbm >= -65:
|
||||
lvl_evdodbm = NetworkStrength.great
|
||||
elif evdodbm >= -75:
|
||||
lvl_evdodbm = NetworkStrength.good
|
||||
elif evdodbm >= -90:
|
||||
lvl_evdodbm = NetworkStrength.moderate
|
||||
elif evdodbm >= -105:
|
||||
lvl_evdodbm = NetworkStrength.poor
|
||||
if evdosnr >= 7:
|
||||
lvl_evdosnr = NetworkStrength.great
|
||||
elif evdosnr >= 5:
|
||||
lvl_evdosnr = NetworkStrength.good
|
||||
elif evdosnr >= 3:
|
||||
lvl_evdosnr = NetworkStrength.moderate
|
||||
elif evdosnr >= 1:
|
||||
lvl_evdosnr = NetworkStrength.poor
|
||||
return max(lvl_evdodbm, lvl_evdosnr)
|
||||
|
||||
def get_cdma_level(cdmadbm, cdmaecio):
|
||||
lvl_cdmadbm = NetworkStrength.unknown
|
||||
lvl_cdmaecio = NetworkStrength.unknown
|
||||
if cdmadbm >= -75:
|
||||
lvl_cdmadbm = NetworkStrength.great
|
||||
elif cdmadbm >= -85:
|
||||
lvl_cdmadbm = NetworkStrength.good
|
||||
elif cdmadbm >= -95:
|
||||
lvl_cdmadbm = NetworkStrength.moderate
|
||||
elif cdmadbm >= -100:
|
||||
lvl_cdmadbm = NetworkStrength.poor
|
||||
if cdmaecio >= -90:
|
||||
lvl_cdmaecio = NetworkStrength.great
|
||||
elif cdmaecio >= -110:
|
||||
lvl_cdmaecio = NetworkStrength.good
|
||||
elif cdmaecio >= -130:
|
||||
lvl_cdmaecio = NetworkStrength.moderate
|
||||
elif cdmaecio >= -150:
|
||||
lvl_cdmaecio = NetworkStrength.poor
|
||||
return max(lvl_cdmadbm, lvl_cdmaecio)
|
||||
|
||||
if network_type == NetworkType.none:
|
||||
return network_strength
|
||||
if network_type == NetworkType.wifi:
|
||||
out = subprocess.check_output('dumpsys connectivity', shell=True).decode('utf-8')
|
||||
network_strength = NetworkStrength.unknown
|
||||
for line in out.split('\n'):
|
||||
signal_str = "SignalStrength: "
|
||||
if signal_str in line:
|
||||
lvl_idx_start = line.find(signal_str) + len(signal_str)
|
||||
lvl_idx_end = line.find(']', lvl_idx_start)
|
||||
lvl = int(line[lvl_idx_start : lvl_idx_end])
|
||||
if lvl >= -50:
|
||||
network_strength = NetworkStrength.great
|
||||
elif lvl >= -60:
|
||||
network_strength = NetworkStrength.good
|
||||
elif lvl >= -70:
|
||||
network_strength = NetworkStrength.moderate
|
||||
else:
|
||||
network_strength = NetworkStrength.poor
|
||||
return network_strength
|
||||
else:
|
||||
# check cell strength
|
||||
out = subprocess.check_output('dumpsys telephony.registry', shell=True).decode('utf-8')
|
||||
for line in out.split('\n'):
|
||||
if "mSignalStrength" in line:
|
||||
arr = line.split(' ')
|
||||
ns = 0
|
||||
if ("gsm" in arr[14]):
|
||||
rsrp = int(arr[9])
|
||||
rssnr = int(arr[11])
|
||||
ns = get_lte_level(rsrp, rssnr)
|
||||
if ns == NetworkStrength.unknown:
|
||||
tdscmadbm = int(arr[13])
|
||||
ns = get_tdscdma_level(tdscmadbm)
|
||||
if ns == NetworkStrength.unknown:
|
||||
asu = int(arr[1])
|
||||
ns = get_gsm_level(asu)
|
||||
else:
|
||||
cdmadbm = int(arr[3])
|
||||
cdmaecio = int(arr[4])
|
||||
evdodbm = int(arr[5])
|
||||
evdosnr = int(arr[7])
|
||||
lvl_cdma = get_cdma_level(cdmadbm, cdmaecio)
|
||||
lvl_edmo = get_evdo_level(evdodbm, evdosnr)
|
||||
if lvl_edmo == NetworkStrength.unknown:
|
||||
ns = lvl_cdma
|
||||
elif lvl_cdma == NetworkStrength.unknown:
|
||||
ns = lvl_edmo
|
||||
else:
|
||||
ns = min(lvl_cdma, lvl_edmo)
|
||||
network_strength = max(network_strength, ns)
|
||||
|
||||
return network_strength
|
|
@ -0,0 +1,41 @@
|
|||
from abc import abstractmethod
|
||||
|
||||
|
||||
class HardwareBase:
|
||||
@staticmethod
|
||||
def get_cmdline():
|
||||
with open('/proc/cmdline') as f:
|
||||
cmdline = f.read()
|
||||
return {kv[0]: kv[1] for kv in [s.split('=') for s in cmdline.split(' ')] if len(kv) == 2}
|
||||
|
||||
@abstractmethod
|
||||
def get_sound_card_online(self):
|
||||
pass
|
||||
|
||||
@abstractmethod
|
||||
def get_imei(self, slot):
|
||||
pass
|
||||
|
||||
@abstractmethod
|
||||
def get_serial(self):
|
||||
pass
|
||||
|
||||
@abstractmethod
|
||||
def get_subscriber_info(self):
|
||||
pass
|
||||
|
||||
@abstractmethod
|
||||
def reboot(self, reason=None):
|
||||
pass
|
||||
|
||||
@abstractmethod
|
||||
def get_network_type(self):
|
||||
pass
|
||||
|
||||
@abstractmethod
|
||||
def get_sim_info(self):
|
||||
pass
|
||||
|
||||
@abstractmethod
|
||||
def get_network_strength(self, network_type):
|
||||
pass
|
|
@ -0,0 +1,58 @@
|
|||
import serial
|
||||
|
||||
from common.hardware_base import HardwareBase
|
||||
from cereal import log
|
||||
|
||||
|
||||
NetworkType = log.ThermalData.NetworkType
|
||||
NetworkStrength = log.ThermalData.NetworkStrength
|
||||
|
||||
|
||||
def run_at_command(cmd, timeout=0.1):
|
||||
with serial.Serial("/dev/ttyUSB2", timeout=timeout) as ser:
|
||||
ser.write(cmd + b"\r\n")
|
||||
ser.readline() # Modem echos request
|
||||
return ser.readline().decode().rstrip()
|
||||
|
||||
|
||||
class Tici(HardwareBase):
|
||||
def get_sound_card_online(self):
|
||||
return True
|
||||
|
||||
def get_imei(self, slot):
|
||||
if slot != 0:
|
||||
return ""
|
||||
|
||||
for _ in range(10):
|
||||
try:
|
||||
imei = run_at_command(b"AT+CGSN")
|
||||
if len(imei) == 15:
|
||||
return imei
|
||||
except serial.SerialException:
|
||||
pass
|
||||
|
||||
raise RuntimeError("Error getting IMEI")
|
||||
|
||||
def get_serial(self):
|
||||
return self.get_cmdline()['androidboot.serialno']
|
||||
|
||||
def get_subscriber_info(self):
|
||||
return ""
|
||||
|
||||
def reboot(self, reason=None):
|
||||
print("REBOOT!")
|
||||
|
||||
def get_network_type(self):
|
||||
return NetworkType.wifi
|
||||
|
||||
def get_sim_info(self):
|
||||
return {
|
||||
'sim_id': '',
|
||||
'mcc_mnc': None,
|
||||
'network_type': ["Unknown"],
|
||||
'sim_state': ["ABSENT"],
|
||||
'data_connected': False
|
||||
}
|
||||
|
||||
def get_network_strength(self, network_type):
|
||||
return NetworkStrength.unknown
|
|
@ -53,12 +53,12 @@ keys = {
|
|||
"AccessToken": [TxType.CLEAR_ON_MANAGER_START],
|
||||
"AthenadPid": [TxType.PERSISTENT],
|
||||
"CalibrationParams": [TxType.PERSISTENT],
|
||||
"CarBatteryCapacity": [TxType.PERSISTENT],
|
||||
"CarParams": [TxType.CLEAR_ON_MANAGER_START, TxType.CLEAR_ON_PANDA_DISCONNECT],
|
||||
"CarParamsCache": [TxType.CLEAR_ON_MANAGER_START, TxType.CLEAR_ON_PANDA_DISCONNECT],
|
||||
"CarVin": [TxType.CLEAR_ON_MANAGER_START, TxType.CLEAR_ON_PANDA_DISCONNECT],
|
||||
"CommunityFeaturesToggle": [TxType.PERSISTENT],
|
||||
"CompletedTrainingVersion": [TxType.PERSISTENT],
|
||||
"ControlsParams": [TxType.PERSISTENT],
|
||||
"DisablePowerDown": [TxType.PERSISTENT],
|
||||
"DisableUpdates": [TxType.PERSISTENT],
|
||||
"DoUninstall": [TxType.CLEAR_ON_MANAGER_START],
|
||||
|
@ -71,7 +71,6 @@ keys = {
|
|||
"HasCompletedSetup": [TxType.PERSISTENT],
|
||||
"IsDriverViewEnabled": [TxType.CLEAR_ON_MANAGER_START],
|
||||
"IsLdwEnabled": [TxType.PERSISTENT],
|
||||
"IsGeofenceEnabled": [TxType.PERSISTENT],
|
||||
"IsMetric": [TxType.PERSISTENT],
|
||||
"IsOffroad": [TxType.CLEAR_ON_MANAGER_START],
|
||||
"IsRHD": [TxType.PERSISTENT],
|
||||
|
@ -81,10 +80,7 @@ keys = {
|
|||
"LastAthenaPingTime": [TxType.PERSISTENT],
|
||||
"LastUpdateTime": [TxType.PERSISTENT],
|
||||
"LastUpdateException": [TxType.PERSISTENT],
|
||||
"LimitSetSpeed": [TxType.PERSISTENT],
|
||||
"LimitSetSpeedNeural": [TxType.PERSISTENT],
|
||||
"LiveParameters": [TxType.PERSISTENT],
|
||||
"LongitudinalControl": [TxType.PERSISTENT],
|
||||
"OpenpilotEnabledToggle": [TxType.PERSISTENT],
|
||||
"LaneChangeEnabled": [TxType.PERSISTENT],
|
||||
"PandaFirmware": [TxType.CLEAR_ON_MANAGER_START, TxType.CLEAR_ON_PANDA_DISCONNECT],
|
||||
|
@ -94,7 +90,6 @@ keys = {
|
|||
"RecordFront": [TxType.PERSISTENT],
|
||||
"ReleaseNotes": [TxType.PERSISTENT],
|
||||
"ShouldDoUpdate": [TxType.CLEAR_ON_MANAGER_START],
|
||||
"SpeedLimitOffset": [TxType.PERSISTENT],
|
||||
"SubscriberInfo": [TxType.PERSISTENT],
|
||||
"TermsVersion": [TxType.PERSISTENT],
|
||||
"TrainingVersion": [TxType.PERSISTENT],
|
||||
|
@ -122,14 +117,15 @@ def fsync_dir(path):
|
|||
|
||||
|
||||
class FileLock():
|
||||
def __init__(self, path, create):
|
||||
def __init__(self, path, create, lock_ex):
|
||||
self._path = path
|
||||
self._create = create
|
||||
self._fd = None
|
||||
self._lock_ex = lock_ex
|
||||
|
||||
def acquire(self):
|
||||
self._fd = os.open(self._path, os.O_CREAT if self._create else 0)
|
||||
fcntl.flock(self._fd, fcntl.LOCK_EX)
|
||||
fcntl.flock(self._fd, fcntl.LOCK_EX if self._lock_ex else fcntl.LOCK_SH)
|
||||
|
||||
def release(self):
|
||||
if self._fd is not None:
|
||||
|
@ -157,8 +153,8 @@ class DBAccessor():
|
|||
except KeyError:
|
||||
return None
|
||||
|
||||
def _get_lock(self, create):
|
||||
lock = FileLock(os.path.join(self._path, ".lock"), create)
|
||||
def _get_lock(self, create, lock_ex):
|
||||
lock = FileLock(os.path.join(self._path, ".lock"), create, lock_ex)
|
||||
lock.acquire()
|
||||
return lock
|
||||
|
||||
|
@ -190,7 +186,7 @@ class DBAccessor():
|
|||
class DBReader(DBAccessor):
|
||||
def __enter__(self):
|
||||
try:
|
||||
lock = self._get_lock(False)
|
||||
lock = self._get_lock(False, False)
|
||||
except OSError as e:
|
||||
# Do not create lock if it does not exist.
|
||||
if e.errno == errno.ENOENT:
|
||||
|
@ -228,7 +224,7 @@ class DBWriter(DBAccessor):
|
|||
|
||||
try:
|
||||
os.chmod(self._path, 0o777)
|
||||
self._lock = self._get_lock(True)
|
||||
self._lock = self._get_lock(True, True)
|
||||
self._vals = self._read_values_locked()
|
||||
except Exception:
|
||||
os.umask(self._prev_umask)
|
||||
|
@ -317,7 +313,7 @@ def write_db(params_path, key, value):
|
|||
value = value.encode('utf8')
|
||||
|
||||
prev_umask = os.umask(0)
|
||||
lock = FileLock(params_path + "/.lock", True)
|
||||
lock = FileLock(params_path + "/.lock", True, True)
|
||||
lock.acquire()
|
||||
|
||||
try:
|
||||
|
|
|
@ -1,12 +1,10 @@
|
|||
"""Utilities for reading real time clocks and keeping soft real time constraints."""
|
||||
import gc
|
||||
import os
|
||||
import time
|
||||
import platform
|
||||
import subprocess
|
||||
import multiprocessing
|
||||
from cffi import FFI
|
||||
|
||||
from common.android import ANDROID
|
||||
from common.hardware import PC
|
||||
from common.common_pyx import sec_since_boot # pylint: disable=no-name-in-module, import-error
|
||||
|
||||
|
||||
|
@ -17,37 +15,26 @@ DT_DMON = 0.1 # driver monitoring
|
|||
DT_TRML = 0.5 # thermald and manager
|
||||
|
||||
|
||||
ffi = FFI()
|
||||
ffi.cdef("long syscall(long number, ...);")
|
||||
libc = ffi.dlopen(None)
|
||||
|
||||
def _get_tid():
|
||||
if platform.machine() == "x86_64":
|
||||
NR_gettid = 186
|
||||
elif platform.machine() == "aarch64":
|
||||
NR_gettid = 178
|
||||
else:
|
||||
raise NotImplementedError
|
||||
|
||||
return libc.syscall(NR_gettid)
|
||||
class Priority:
|
||||
MIN_REALTIME = 52 # highest android process priority is 51
|
||||
CTRL_LOW = MIN_REALTIME
|
||||
CTRL_HIGH = MIN_REALTIME + 1
|
||||
|
||||
|
||||
def set_realtime_priority(level):
|
||||
if os.getuid() != 0:
|
||||
print("not setting priority, not root")
|
||||
return
|
||||
if not PC:
|
||||
os.sched_setscheduler(0, os.SCHED_FIFO, os.sched_param(level))
|
||||
|
||||
return subprocess.call(['chrt', '-f', '-p', str(level), str(_get_tid())])
|
||||
|
||||
def set_core_affinity(core):
|
||||
if os.getuid() != 0:
|
||||
print("not setting affinity, not root")
|
||||
return
|
||||
if not PC:
|
||||
os.sched_setaffinity(0, [core,])
|
||||
|
||||
if ANDROID:
|
||||
return subprocess.call(['taskset', '-p', str(core), str(_get_tid())])
|
||||
else:
|
||||
return -1
|
||||
|
||||
def config_rt_process(core, priority):
|
||||
gc.disable()
|
||||
set_realtime_priority(priority)
|
||||
set_core_affinity(core)
|
||||
|
||||
|
||||
class Ratekeeper():
|
||||
|
|
|
@ -5,7 +5,7 @@ import subprocess
|
|||
from common.basedir import BASEDIR
|
||||
|
||||
|
||||
class TextWindow():
|
||||
class TextWindow:
|
||||
def __init__(self, s, noop=False):
|
||||
# text window is only implemented for android currently
|
||||
self.text_proc = None
|
||||
|
|
|
@ -8,6 +8,60 @@ source "$BASEDIR/launch_env.sh"
|
|||
|
||||
DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null && pwd )"
|
||||
|
||||
function two_init {
|
||||
# Restrict Android and other system processes to the first two cores
|
||||
echo 0-1 > /dev/cpuset/background/cpus
|
||||
echo 0-1 > /dev/cpuset/system-background/cpus
|
||||
echo 0-1 > /dev/cpuset/foreground/boost/cpus
|
||||
echo 0-1 > /dev/cpuset/foreground/cpus
|
||||
echo 0-1 > /dev/cpuset/android/cpus
|
||||
|
||||
# openpilot gets all the cores
|
||||
echo 0-3 > /dev/cpuset/app/cpus
|
||||
|
||||
# Collect RIL and other possibly long-running I/O interrupts onto CPU 1
|
||||
echo 1 > /proc/irq/78/smp_affinity_list # qcom,smd-modem (LTE radio)
|
||||
echo 1 > /proc/irq/33/smp_affinity_list # ufshcd (flash storage)
|
||||
echo 1 > /proc/irq/35/smp_affinity_list # wifi (wlan_pci)
|
||||
# USB traffic needs realtime handling on cpu 3
|
||||
[ -d "/proc/irq/733" ] && echo 3 > /proc/irq/733/smp_affinity_list # USB for LeEco
|
||||
[ -d "/proc/irq/736" ] && echo 3 > /proc/irq/736/smp_affinity_list # USB for OP3T
|
||||
|
||||
|
||||
# Check for NEOS update
|
||||
if [ $(< /VERSION) != "$REQUIRED_NEOS_VERSION" ]; then
|
||||
if [ -f "$DIR/scripts/continue.sh" ]; then
|
||||
cp "$DIR/scripts/continue.sh" "/data/data/com.termux/files/continue.sh"
|
||||
fi
|
||||
|
||||
if [ ! -f "$BASEDIR/prebuilt" ]; then
|
||||
# Clean old build products, but preserve the scons cache
|
||||
cd $DIR
|
||||
scons --clean
|
||||
git clean -xdf
|
||||
git submodule foreach --recursive git clean -xdf
|
||||
fi
|
||||
|
||||
"$DIR/installer/updater/updater" "file://$DIR/installer/updater/update.json"
|
||||
else
|
||||
if [[ $(uname -v) == "#1 SMP PREEMPT Wed Jun 10 12:40:53 PDT 2020" ]]; then
|
||||
"$DIR/installer/updater/updater" "file://$DIR/installer/updater/update_kernel.json"
|
||||
fi
|
||||
fi
|
||||
|
||||
# One-time fix for a subset of OP3T with gyro orientation offsets.
|
||||
# Remove and regenerate qcom sensor registry. Only done on OP3T mainboards.
|
||||
# Performed exactly once. The old registry is preserved just-in-case, and
|
||||
# doubles as a flag denoting we've already done the reset.
|
||||
if ! $(grep -q "letv" /proc/cmdline) && [ ! -f "/persist/comma/op3t-sns-reg-backup" ]; then
|
||||
echo "Performing OP3T sensor registry reset"
|
||||
mv /persist/sensors/sns.reg /persist/comma/op3t-sns-reg-backup &&
|
||||
rm -f /persist/sensors/sensors_settings /persist/sensors/error_log /persist/sensors/gyro_sensitity_cal &&
|
||||
echo "restart" > /sys/kernel/debug/msm_subsys/slpi &&
|
||||
sleep 5 # Give Android sensor subsystem a moment to recover
|
||||
fi
|
||||
}
|
||||
|
||||
function launch {
|
||||
# Wifi scan
|
||||
wpa_cli IFNAME=wlan0 SCAN
|
||||
|
@ -54,56 +108,9 @@ function launch {
|
|||
fi
|
||||
fi
|
||||
|
||||
# Android and other system processes are not permitted to run on CPU 3
|
||||
# NEOS installed app processes can run anywhere
|
||||
echo 0-2 > /dev/cpuset/background/cpus
|
||||
echo 0-2 > /dev/cpuset/system-background/cpus
|
||||
[ -d "/dev/cpuset/foreground/boost/cpus" ] && echo 0-2 > /dev/cpuset/foreground/boost/cpus # Not present in < NEOS 15
|
||||
echo 0-2 > /dev/cpuset/foreground/cpus
|
||||
echo 0-2 > /dev/cpuset/android/cpus
|
||||
echo 0-3 > /dev/cpuset/app/cpus
|
||||
|
||||
# Collect RIL and other possibly long-running I/O interrupts onto CPU 1
|
||||
echo 1 > /proc/irq/78/smp_affinity_list # qcom,smd-modem (LTE radio)
|
||||
echo 1 > /proc/irq/33/smp_affinity_list # ufshcd (flash storage)
|
||||
echo 1 > /proc/irq/35/smp_affinity_list # wifi (wlan_pci)
|
||||
# USB traffic needs realtime handling on cpu 3
|
||||
[ -d "/proc/irq/733" ] && echo 3 > /proc/irq/733/smp_affinity_list # USB for LeEco
|
||||
[ -d "/proc/irq/736" ] && echo 3 > /proc/irq/736/smp_affinity_list # USB for OP3T
|
||||
|
||||
|
||||
# Check for NEOS update
|
||||
if [ $(< /VERSION) != "$REQUIRED_NEOS_VERSION" ]; then
|
||||
if [ -f "$DIR/scripts/continue.sh" ]; then
|
||||
cp "$DIR/scripts/continue.sh" "/data/data/com.termux/files/continue.sh"
|
||||
fi
|
||||
|
||||
if [ ! -f "$BASEDIR/prebuilt" ]; then
|
||||
# Clean old build products, but preserve the scons cache
|
||||
cd $DIR
|
||||
scons --clean
|
||||
git clean -xdf
|
||||
git submodule foreach --recursive git clean -xdf
|
||||
fi
|
||||
|
||||
"$DIR/installer/updater/updater" "file://$DIR/installer/updater/update.json"
|
||||
else
|
||||
if [[ $(uname -v) == "#1 SMP PREEMPT Wed Jun 10 12:40:53 PDT 2020" ]]; then
|
||||
"$DIR/installer/updater/updater" "file://$DIR/installer/updater/update_kernel.json"
|
||||
fi
|
||||
fi
|
||||
|
||||
# One-time fix for a subset of OP3T with gyro orientation offsets.
|
||||
# Remove and regenerate qcom sensor registry. Only done on OP3T mainboards.
|
||||
# Performed exactly once. The old registry is preserved just-in-case, and
|
||||
# doubles as a flag denoting we've already done the reset.
|
||||
# TODO: we should really grow per-platform detect and setup routines
|
||||
if ! $(grep -q "letv" /proc/cmdline) && [ ! -f "/persist/comma/op3t-sns-reg-backup" ]; then
|
||||
echo "Performing OP3T sensor registry reset"
|
||||
mv /persist/sensors/sns.reg /persist/comma/op3t-sns-reg-backup &&
|
||||
rm -f /persist/sensors/sensors_settings /persist/sensors/error_log /persist/sensors/gyro_sensitity_cal &&
|
||||
echo "restart" > /sys/kernel/debug/msm_subsys/slpi &&
|
||||
sleep 5 # Give Android sensor subsystem a moment to recover
|
||||
# comma two init
|
||||
if [ -f /EON ]; then
|
||||
two_init
|
||||
fi
|
||||
|
||||
# handle pythonpath
|
||||
|
|
|
@ -34,7 +34,7 @@ class BuildExtWithoutPlatformSuffix(build_ext):
|
|||
return get_ext_filename_without_platform_suffix(filename)
|
||||
|
||||
|
||||
extra_compile_args = ["-std=c++14"]
|
||||
extra_compile_args = ["-std=c++14", "-Wno-nullability-completeness"]
|
||||
ARCH = subprocess.check_output(["uname", "-m"], encoding='utf8').rstrip() # pylint: disable=unexpected-keyword-arg
|
||||
if ARCH == "aarch64":
|
||||
extra_compile_args += ["-Wno-deprecated-register"]
|
||||
|
|
|
@ -20,9 +20,11 @@ cdef class CANPacker:
|
|||
map[int, int] address_to_size
|
||||
|
||||
def __init__(self, dbc_name):
|
||||
self.packer = new cpp_CANPacker(dbc_name)
|
||||
self.dbc = dbc_lookup(dbc_name)
|
||||
|
||||
if not self.dbc:
|
||||
raise RuntimeError("Can't lookup" + dbc_name)
|
||||
|
||||
self.packer = new cpp_CANPacker(dbc_name)
|
||||
num_msgs = self.dbc[0].num_msgs
|
||||
for i in range(num_msgs):
|
||||
msg = self.dbc[0].msgs[i]
|
||||
|
@ -37,7 +39,7 @@ cdef class CANPacker:
|
|||
|
||||
for name, value in values.iteritems():
|
||||
n = name.encode('utf8')
|
||||
names.append(n) # TODO: find better way to keep reference to temp string arround
|
||||
names.append(n) # TODO: find better way to keep reference to temp string around
|
||||
|
||||
spv.name = n
|
||||
spv.value = value
|
||||
|
|
|
@ -187,7 +187,7 @@ void CANParser::UpdateCans(uint64_t sec, const capnp::List<cereal::CanData>::Rea
|
|||
continue;
|
||||
}
|
||||
|
||||
if (cmsg.getDat().size() > 8) continue; //shouldnt ever happen
|
||||
if (cmsg.getDat().size() > 8) continue; //shouldn't ever happen
|
||||
uint8_t dat[8] = {0};
|
||||
memcpy(dat, cmsg.getDat().begin(), cmsg.getDat().size());
|
||||
|
||||
|
|
|
@ -1,2 +1,2 @@
|
|||
from opendbc.can.parser_pyx import CANParser # pylint: disable=no-name-in-module, import-error
|
||||
assert CANParser
|
||||
from opendbc.can.parser_pyx import CANParser, CANDefine # pylint: disable=no-name-in-module, import-error
|
||||
assert CANParser, CANDefine
|
||||
|
|
|
@ -17,7 +17,6 @@ from collections import defaultdict
|
|||
|
||||
cdef int CAN_INVALID_CNT = 5
|
||||
|
||||
|
||||
cdef class CANParser:
|
||||
cdef:
|
||||
cpp_CANParser *can
|
||||
|
@ -37,10 +36,11 @@ cdef class CANParser:
|
|||
def __init__(self, dbc_name, signals, checks=None, bus=0):
|
||||
if checks is None:
|
||||
checks = []
|
||||
|
||||
self.can_valid = True
|
||||
self.dbc_name = dbc_name
|
||||
self.dbc = dbc_lookup(dbc_name)
|
||||
if not self.dbc:
|
||||
raise RuntimeError("Can't lookup" + dbc_name)
|
||||
self.vl = {}
|
||||
self.ts = {}
|
||||
|
||||
|
@ -110,7 +110,7 @@ cdef class CANParser:
|
|||
|
||||
|
||||
for cv in can_values:
|
||||
# Cast char * directly to unicde
|
||||
# Cast char * directly to unicode
|
||||
name = <unicode>self.address_to_msg_name[cv.address].c_str()
|
||||
cv_name = <unicode>cv.name
|
||||
|
||||
|
@ -148,7 +148,9 @@ cdef class CANDefine():
|
|||
def __init__(self, dbc_name):
|
||||
self.dbc_name = dbc_name
|
||||
self.dbc = dbc_lookup(dbc_name)
|
||||
|
||||
if not self.dbc:
|
||||
raise RuntimeError("Can't lookup" + dbc_name)
|
||||
|
||||
num_vals = self.dbc[0].num_vals
|
||||
|
||||
address_to_msg_name = {}
|
||||
|
|
|
@ -81,7 +81,7 @@ def process(in_fn, out_fn):
|
|||
if sig.start_bit % 8 != checksum_start_bit:
|
||||
sys.exit("%s: CHECKSUM starts at wrong bit" % dbc_msg_name)
|
||||
if little_endian != sig.is_little_endian:
|
||||
sys.exit("%s: CHECKSUM has wrong endianess" % dbc_msg_name)
|
||||
sys.exit("%s: CHECKSUM has wrong endianness" % dbc_msg_name)
|
||||
# counter rules
|
||||
if sig.name == "COUNTER":
|
||||
if counter_size is not None and sig.size != counter_size:
|
||||
|
@ -90,7 +90,7 @@ def process(in_fn, out_fn):
|
|||
print(counter_start_bit, sig.start_bit)
|
||||
sys.exit("%s: COUNTER starts at wrong bit" % dbc_msg_name)
|
||||
if little_endian != sig.is_little_endian:
|
||||
sys.exit("%s: COUNTER has wrong endianess" % dbc_msg_name)
|
||||
sys.exit("%s: COUNTER has wrong endianness" % dbc_msg_name)
|
||||
# pedal rules
|
||||
if address in [0x200, 0x201]:
|
||||
if sig.name == "COUNTER_PEDAL" and sig.size != 4:
|
||||
|
|
|
@ -409,7 +409,7 @@ CM_ SG_ 571 CHECKSUM "standard checksum";
|
|||
CM_ SG_ 825 BEEP_339 "sent every 0.5s. 0050 is no beep. To beep send 4355 or 4155. Used by ParkSense warning.";
|
||||
CM_ SG_ 270 ELECTRIC_MOTOR "0x7fff indicates electric motor not in use";
|
||||
CM_ SG_ 291 ENERGY_GAIN_LOSS "unsure what this actually is";
|
||||
CM_ SG_ 291 ENERGY_SMOOTHER_CURVE "unusre what it is, but smoother";
|
||||
CM_ SG_ 291 ENERGY_SMOOTHER_CURVE "unsure what it is, but smoother";
|
||||
CM_ SG_ 308 ACCEL_134 "only set when human presses accel pedal";
|
||||
CM_ SG_ 532 NOISY_SLOWLY_DECREASING "perhaps battery but do not know";
|
||||
CM_ SG_ 816 TRACTION_OFF "set when traction off button is enabled";
|
||||
|
|
|
@ -37,7 +37,7 @@ BU_: K109_FCM B233B_LRR NEO VIS_FO VIS2_FO K124_ASCM Vector__XXX EOCM_F_FO EOCM2
|
|||
VAL_TABLE_ RangeMode 1 "Active" 0 "Inactive" ;
|
||||
VAL_TABLE_ TrkConf 3 "Confident" 2 "Speculative" 1 "Highly speculative" 0 "Invalid" ;
|
||||
VAL_TABLE_ TrkMeasStatus 3 "Measured current cycle" 2 "Latent track not detected" 1 "New object" 0 "No object" ;
|
||||
VAL_TABLE_ TrkDynProp 4 "Moving in opposite direction" 3 "Moving in same direction" 2 "Has moved but currenty stopped" 1 "Has never moved," 0 "Unkown" ;
|
||||
VAL_TABLE_ TrkDynProp 4 "Moving in opposite direction" 3 "Moving in same direction" 2 "Has moved but currently stopped" 1 "Has never moved," 0 "Unknown" ;
|
||||
VAL_TABLE_ FrntVsnInPthVehBrkNwSt 10 "Active" 5 "Inactive" ;
|
||||
VAL_TABLE_ FrntVsnClostPedBrkNwSt 10 "Active" 5 "Inactive" ;
|
||||
VAL_TABLE_ LaneSnsLLnPosValid 1 "Invalid" 0 "Valid" ;
|
||||
|
|
|
@ -311,7 +311,7 @@ CM_ SG_ 36 STEERING_TORQUE "does not seem the steer torque, tbd";
|
|||
CM_ SG_ 37 STEER_FRACTION "1/15th of the signal STEER_ANGLE, which is 1.5 deg; note that 0x8 is never set";
|
||||
CM_ SG_ 37 STEER_RATE "factor is tbd";
|
||||
CM_ SG_ 466 ACCEL_NET "net acceleration produced by the system, given ACCEL_CMD, road grade and other factors";
|
||||
CM_ SG_ 467 SET_SPEED "43 kph are shown as 28mph, so conversion isnt perfect";
|
||||
CM_ SG_ 467 SET_SPEED "43 kph are shown as 28mph, so conversion isn't perfect";
|
||||
CM_ SG_ 467 LOW_SPEED_LOCKOUT "in low speed lockout, system would always disengage below 28mph";
|
||||
CM_ SG_ 560 BRAKE_PRESSED "another brake pressed?";
|
||||
CM_ SG_ 608 STEER_TORQUE_DRIVER "driver torque";
|
||||
|
|
|
@ -311,7 +311,7 @@ CM_ SG_ 36 STEERING_TORQUE "does not seem the steer torque, tbd";
|
|||
CM_ SG_ 37 STEER_FRACTION "1/15th of the signal STEER_ANGLE, which is 1.5 deg; note that 0x8 is never set";
|
||||
CM_ SG_ 37 STEER_RATE "factor is tbd";
|
||||
CM_ SG_ 466 ACCEL_NET "net acceleration produced by the system, given ACCEL_CMD, road grade and other factors";
|
||||
CM_ SG_ 467 SET_SPEED "43 kph are shown as 28mph, so conversion isnt perfect";
|
||||
CM_ SG_ 467 SET_SPEED "43 kph are shown as 28mph, so conversion isn't perfect";
|
||||
CM_ SG_ 467 LOW_SPEED_LOCKOUT "in low speed lockout, system would always disengage below 28mph";
|
||||
CM_ SG_ 560 BRAKE_PRESSED "another brake pressed?";
|
||||
CM_ SG_ 608 STEER_TORQUE_DRIVER "driver torque";
|
||||
|
|
|
@ -311,7 +311,7 @@ CM_ SG_ 36 STEERING_TORQUE "does not seem the steer torque, tbd";
|
|||
CM_ SG_ 37 STEER_FRACTION "1/15th of the signal STEER_ANGLE, which is 1.5 deg; note that 0x8 is never set";
|
||||
CM_ SG_ 37 STEER_RATE "factor is tbd";
|
||||
CM_ SG_ 466 ACCEL_NET "net acceleration produced by the system, given ACCEL_CMD, road grade and other factors";
|
||||
CM_ SG_ 467 SET_SPEED "43 kph are shown as 28mph, so conversion isnt perfect";
|
||||
CM_ SG_ 467 SET_SPEED "43 kph are shown as 28mph, so conversion isn't perfect";
|
||||
CM_ SG_ 467 LOW_SPEED_LOCKOUT "in low speed lockout, system would always disengage below 28mph";
|
||||
CM_ SG_ 560 BRAKE_PRESSED "another brake pressed?";
|
||||
CM_ SG_ 608 STEER_TORQUE_DRIVER "driver torque";
|
||||
|
|
|
@ -311,7 +311,7 @@ CM_ SG_ 36 STEERING_TORQUE "does not seem the steer torque, tbd";
|
|||
CM_ SG_ 37 STEER_FRACTION "1/15th of the signal STEER_ANGLE, which is 1.5 deg; note that 0x8 is never set";
|
||||
CM_ SG_ 37 STEER_RATE "factor is tbd";
|
||||
CM_ SG_ 466 ACCEL_NET "net acceleration produced by the system, given ACCEL_CMD, road grade and other factors";
|
||||
CM_ SG_ 467 SET_SPEED "43 kph are shown as 28mph, so conversion isnt perfect";
|
||||
CM_ SG_ 467 SET_SPEED "43 kph are shown as 28mph, so conversion isn't perfect";
|
||||
CM_ SG_ 467 LOW_SPEED_LOCKOUT "in low speed lockout, system would always disengage below 28mph";
|
||||
CM_ SG_ 560 BRAKE_PRESSED "another brake pressed?";
|
||||
CM_ SG_ 608 STEER_TORQUE_DRIVER "driver torque";
|
||||
|
|
|
@ -311,7 +311,7 @@ CM_ SG_ 36 STEERING_TORQUE "does not seem the steer torque, tbd";
|
|||
CM_ SG_ 37 STEER_FRACTION "1/15th of the signal STEER_ANGLE, which is 1.5 deg; note that 0x8 is never set";
|
||||
CM_ SG_ 37 STEER_RATE "factor is tbd";
|
||||
CM_ SG_ 466 ACCEL_NET "net acceleration produced by the system, given ACCEL_CMD, road grade and other factors";
|
||||
CM_ SG_ 467 SET_SPEED "43 kph are shown as 28mph, so conversion isnt perfect";
|
||||
CM_ SG_ 467 SET_SPEED "43 kph are shown as 28mph, so conversion isn't perfect";
|
||||
CM_ SG_ 467 LOW_SPEED_LOCKOUT "in low speed lockout, system would always disengage below 28mph";
|
||||
CM_ SG_ 560 BRAKE_PRESSED "another brake pressed?";
|
||||
CM_ SG_ 608 STEER_TORQUE_DRIVER "driver torque";
|
||||
|
|
|
@ -311,7 +311,7 @@ CM_ SG_ 36 STEERING_TORQUE "does not seem the steer torque, tbd";
|
|||
CM_ SG_ 37 STEER_FRACTION "1/15th of the signal STEER_ANGLE, which is 1.5 deg; note that 0x8 is never set";
|
||||
CM_ SG_ 37 STEER_RATE "factor is tbd";
|
||||
CM_ SG_ 466 ACCEL_NET "net acceleration produced by the system, given ACCEL_CMD, road grade and other factors";
|
||||
CM_ SG_ 467 SET_SPEED "43 kph are shown as 28mph, so conversion isnt perfect";
|
||||
CM_ SG_ 467 SET_SPEED "43 kph are shown as 28mph, so conversion isn't perfect";
|
||||
CM_ SG_ 467 LOW_SPEED_LOCKOUT "in low speed lockout, system would always disengage below 28mph";
|
||||
CM_ SG_ 560 BRAKE_PRESSED "another brake pressed?";
|
||||
CM_ SG_ 608 STEER_TORQUE_DRIVER "driver torque";
|
||||
|
|
|
@ -311,7 +311,7 @@ CM_ SG_ 36 STEERING_TORQUE "does not seem the steer torque, tbd";
|
|||
CM_ SG_ 37 STEER_FRACTION "1/15th of the signal STEER_ANGLE, which is 1.5 deg; note that 0x8 is never set";
|
||||
CM_ SG_ 37 STEER_RATE "factor is tbd";
|
||||
CM_ SG_ 466 ACCEL_NET "net acceleration produced by the system, given ACCEL_CMD, road grade and other factors";
|
||||
CM_ SG_ 467 SET_SPEED "43 kph are shown as 28mph, so conversion isnt perfect";
|
||||
CM_ SG_ 467 SET_SPEED "43 kph are shown as 28mph, so conversion isn't perfect";
|
||||
CM_ SG_ 467 LOW_SPEED_LOCKOUT "in low speed lockout, system would always disengage below 28mph";
|
||||
CM_ SG_ 560 BRAKE_PRESSED "another brake pressed?";
|
||||
CM_ SG_ 608 STEER_TORQUE_DRIVER "driver torque";
|
||||
|
|
|
@ -311,7 +311,7 @@ CM_ SG_ 36 STEERING_TORQUE "does not seem the steer torque, tbd";
|
|||
CM_ SG_ 37 STEER_FRACTION "1/15th of the signal STEER_ANGLE, which is 1.5 deg; note that 0x8 is never set";
|
||||
CM_ SG_ 37 STEER_RATE "factor is tbd";
|
||||
CM_ SG_ 466 ACCEL_NET "net acceleration produced by the system, given ACCEL_CMD, road grade and other factors";
|
||||
CM_ SG_ 467 SET_SPEED "43 kph are shown as 28mph, so conversion isnt perfect";
|
||||
CM_ SG_ 467 SET_SPEED "43 kph are shown as 28mph, so conversion isn't perfect";
|
||||
CM_ SG_ 467 LOW_SPEED_LOCKOUT "in low speed lockout, system would always disengage below 28mph";
|
||||
CM_ SG_ 560 BRAKE_PRESSED "another brake pressed?";
|
||||
CM_ SG_ 608 STEER_TORQUE_DRIVER "driver torque";
|
||||
|
@ -375,7 +375,7 @@ BO_ 705 GAS_PEDAL: 8 XXX
|
|||
SG_ GAS_PEDAL : 55|8@0+ (0.005,0) [0|1] "" XXX
|
||||
|
||||
BO_ 608 STEER_TORQUE_SENSOR: 8 XXX
|
||||
SG_ STEER_TORQUE_EPS : 47|16@0- (1.0,0) [-20000|20000] "" XXX
|
||||
SG_ STEER_TORQUE_EPS : 47|16@0- (0.88,0) [-20000|20000] "" XXX
|
||||
SG_ STEER_TORQUE_DRIVER : 15|16@0- (1,0) [-32768|32767] "" XXX
|
||||
SG_ STEER_OVERRIDE : 0|1@0+ (1,0) [0|1] "" XXX
|
||||
SG_ CHECKSUM : 63|8@0+ (1,0) [0|255] "" XXX
|
||||
|
|
|
@ -311,7 +311,7 @@ CM_ SG_ 36 STEERING_TORQUE "does not seem the steer torque, tbd";
|
|||
CM_ SG_ 37 STEER_FRACTION "1/15th of the signal STEER_ANGLE, which is 1.5 deg; note that 0x8 is never set";
|
||||
CM_ SG_ 37 STEER_RATE "factor is tbd";
|
||||
CM_ SG_ 466 ACCEL_NET "net acceleration produced by the system, given ACCEL_CMD, road grade and other factors";
|
||||
CM_ SG_ 467 SET_SPEED "43 kph are shown as 28mph, so conversion isnt perfect";
|
||||
CM_ SG_ 467 SET_SPEED "43 kph are shown as 28mph, so conversion isn't perfect";
|
||||
CM_ SG_ 467 LOW_SPEED_LOCKOUT "in low speed lockout, system would always disengage below 28mph";
|
||||
CM_ SG_ 560 BRAKE_PRESSED "another brake pressed?";
|
||||
CM_ SG_ 608 STEER_TORQUE_DRIVER "driver torque";
|
||||
|
|
|
@ -311,7 +311,7 @@ CM_ SG_ 36 STEERING_TORQUE "does not seem the steer torque, tbd";
|
|||
CM_ SG_ 37 STEER_FRACTION "1/15th of the signal STEER_ANGLE, which is 1.5 deg; note that 0x8 is never set";
|
||||
CM_ SG_ 37 STEER_RATE "factor is tbd";
|
||||
CM_ SG_ 466 ACCEL_NET "net acceleration produced by the system, given ACCEL_CMD, road grade and other factors";
|
||||
CM_ SG_ 467 SET_SPEED "43 kph are shown as 28mph, so conversion isnt perfect";
|
||||
CM_ SG_ 467 SET_SPEED "43 kph are shown as 28mph, so conversion isn't perfect";
|
||||
CM_ SG_ 467 LOW_SPEED_LOCKOUT "in low speed lockout, system would always disengage below 28mph";
|
||||
CM_ SG_ 560 BRAKE_PRESSED "another brake pressed?";
|
||||
CM_ SG_ 608 STEER_TORQUE_DRIVER "driver torque";
|
||||
|
|
|
@ -328,7 +328,7 @@ CM_ SG_ 36 STEERING_TORQUE "does not seem the steer torque, tbd";
|
|||
CM_ SG_ 37 STEER_FRACTION "1/15th of the signal STEER_ANGLE, which is 1.5 deg; note that 0x8 is never set";
|
||||
CM_ SG_ 37 STEER_RATE "factor is tbd";
|
||||
CM_ SG_ 466 ACCEL_NET "net acceleration produced by the system, given ACCEL_CMD, road grade and other factors";
|
||||
CM_ SG_ 467 SET_SPEED "43 kph are shown as 28mph, so conversion isnt perfect";
|
||||
CM_ SG_ 467 SET_SPEED "43 kph are shown as 28mph, so conversion isn't perfect";
|
||||
CM_ SG_ 467 LOW_SPEED_LOCKOUT "in low speed lockout, system would always disengage below 28mph";
|
||||
CM_ SG_ 560 BRAKE_PRESSED "another brake pressed?";
|
||||
CM_ SG_ 608 STEER_TORQUE_DRIVER "driver torque";
|
||||
|
|
|
@ -328,7 +328,7 @@ CM_ SG_ 36 STEERING_TORQUE "does not seem the steer torque, tbd";
|
|||
CM_ SG_ 37 STEER_FRACTION "1/15th of the signal STEER_ANGLE, which is 1.5 deg; note that 0x8 is never set";
|
||||
CM_ SG_ 37 STEER_RATE "factor is tbd";
|
||||
CM_ SG_ 466 ACCEL_NET "net acceleration produced by the system, given ACCEL_CMD, road grade and other factors";
|
||||
CM_ SG_ 467 SET_SPEED "43 kph are shown as 28mph, so conversion isnt perfect";
|
||||
CM_ SG_ 467 SET_SPEED "43 kph are shown as 28mph, so conversion isn't perfect";
|
||||
CM_ SG_ 467 LOW_SPEED_LOCKOUT "in low speed lockout, system would always disengage below 28mph";
|
||||
CM_ SG_ 560 BRAKE_PRESSED "another brake pressed?";
|
||||
CM_ SG_ 608 STEER_TORQUE_DRIVER "driver torque";
|
||||
|
|
|
@ -311,7 +311,7 @@ CM_ SG_ 36 STEERING_TORQUE "does not seem the steer torque, tbd";
|
|||
CM_ SG_ 37 STEER_FRACTION "1/15th of the signal STEER_ANGLE, which is 1.5 deg; note that 0x8 is never set";
|
||||
CM_ SG_ 37 STEER_RATE "factor is tbd";
|
||||
CM_ SG_ 466 ACCEL_NET "net acceleration produced by the system, given ACCEL_CMD, road grade and other factors";
|
||||
CM_ SG_ 467 SET_SPEED "43 kph are shown as 28mph, so conversion isnt perfect";
|
||||
CM_ SG_ 467 SET_SPEED "43 kph are shown as 28mph, so conversion isn't perfect";
|
||||
CM_ SG_ 467 LOW_SPEED_LOCKOUT "in low speed lockout, system would always disengage below 28mph";
|
||||
CM_ SG_ 560 BRAKE_PRESSED "another brake pressed?";
|
||||
CM_ SG_ 608 STEER_TORQUE_DRIVER "driver torque";
|
||||
|
|
|
@ -311,7 +311,7 @@ CM_ SG_ 36 STEERING_TORQUE "does not seem the steer torque, tbd";
|
|||
CM_ SG_ 37 STEER_FRACTION "1/15th of the signal STEER_ANGLE, which is 1.5 deg; note that 0x8 is never set";
|
||||
CM_ SG_ 37 STEER_RATE "factor is tbd";
|
||||
CM_ SG_ 466 ACCEL_NET "net acceleration produced by the system, given ACCEL_CMD, road grade and other factors";
|
||||
CM_ SG_ 467 SET_SPEED "43 kph are shown as 28mph, so conversion isnt perfect";
|
||||
CM_ SG_ 467 SET_SPEED "43 kph are shown as 28mph, so conversion isn't perfect";
|
||||
CM_ SG_ 467 LOW_SPEED_LOCKOUT "in low speed lockout, system would always disengage below 28mph";
|
||||
CM_ SG_ 560 BRAKE_PRESSED "another brake pressed?";
|
||||
CM_ SG_ 608 STEER_TORQUE_DRIVER "driver torque";
|
||||
|
|
|
@ -311,7 +311,7 @@ CM_ SG_ 36 STEERING_TORQUE "does not seem the steer torque, tbd";
|
|||
CM_ SG_ 37 STEER_FRACTION "1/15th of the signal STEER_ANGLE, which is 1.5 deg; note that 0x8 is never set";
|
||||
CM_ SG_ 37 STEER_RATE "factor is tbd";
|
||||
CM_ SG_ 466 ACCEL_NET "net acceleration produced by the system, given ACCEL_CMD, road grade and other factors";
|
||||
CM_ SG_ 467 SET_SPEED "43 kph are shown as 28mph, so conversion isnt perfect";
|
||||
CM_ SG_ 467 SET_SPEED "43 kph are shown as 28mph, so conversion isn't perfect";
|
||||
CM_ SG_ 467 LOW_SPEED_LOCKOUT "in low speed lockout, system would always disengage below 28mph";
|
||||
CM_ SG_ 560 BRAKE_PRESSED "another brake pressed?";
|
||||
CM_ SG_ 608 STEER_TORQUE_DRIVER "driver torque";
|
||||
|
|
|
@ -311,7 +311,7 @@ CM_ SG_ 36 STEERING_TORQUE "does not seem the steer torque, tbd";
|
|||
CM_ SG_ 37 STEER_FRACTION "1/15th of the signal STEER_ANGLE, which is 1.5 deg; note that 0x8 is never set";
|
||||
CM_ SG_ 37 STEER_RATE "factor is tbd";
|
||||
CM_ SG_ 466 ACCEL_NET "net acceleration produced by the system, given ACCEL_CMD, road grade and other factors";
|
||||
CM_ SG_ 467 SET_SPEED "43 kph are shown as 28mph, so conversion isnt perfect";
|
||||
CM_ SG_ 467 SET_SPEED "43 kph are shown as 28mph, so conversion isn't perfect";
|
||||
CM_ SG_ 467 LOW_SPEED_LOCKOUT "in low speed lockout, system would always disengage below 28mph";
|
||||
CM_ SG_ 560 BRAKE_PRESSED "another brake pressed?";
|
||||
CM_ SG_ 608 STEER_TORQUE_DRIVER "driver torque";
|
||||
|
|
|
@ -1,3 +1,3 @@
|
|||
# flake8: noqa
|
||||
# pylint: skip-file
|
||||
from .python import Panda, PandaWifiStreaming, PandaDFU, ESPROM, CesantaFlasher, flash_release, BASEDIR, ensure_st_up_to_date, build_st, PandaSerial
|
||||
from .python import Panda, PandaWifiStreaming, PandaDFU, flash_release, BASEDIR, ensure_st_up_to_date, build_st, PandaSerial
|
||||
|
|
|
@ -9,6 +9,7 @@
|
|||
#ifdef PANDA
|
||||
#include "drivers/fan.h"
|
||||
#include "drivers/rtc.h"
|
||||
#include "drivers/clock_source.h"
|
||||
#include "boards/white.h"
|
||||
#include "boards/grey.h"
|
||||
#include "boards/black.h"
|
||||
|
@ -23,7 +24,7 @@ void detect_board_type(void) {
|
|||
// SPI lines floating: white (TODO: is this reliable? Not really, we have to enable ESP/GPS to be able to detect this on the UART)
|
||||
set_gpio_output(GPIOC, 14, 1);
|
||||
set_gpio_output(GPIOC, 5, 1);
|
||||
if(!detect_with_pull(GPIOB, 1, PULL_UP) && detect_with_pull(GPIOB, 15, PULL_UP)){
|
||||
if(!detect_with_pull(GPIOB, 1, PULL_UP) && !detect_with_pull(GPIOB, 7, PULL_UP)){
|
||||
hw_type = HW_TYPE_DOS;
|
||||
current_board = &board_dos;
|
||||
} else if((detect_with_pull(GPIOA, 4, PULL_DOWN)) || (detect_with_pull(GPIOA, 5, PULL_DOWN)) || (detect_with_pull(GPIOA, 6, PULL_DOWN)) || (detect_with_pull(GPIOA, 7, PULL_DOWN))){
|
||||
|
@ -53,22 +54,10 @@ void detect_board_type(void) {
|
|||
|
||||
// ///// Configuration detection ///// //
|
||||
bool has_external_debug_serial = 0;
|
||||
bool is_entering_bootmode = 0;
|
||||
|
||||
void detect_configuration(void) {
|
||||
// detect if external serial debugging is present
|
||||
has_external_debug_serial = detect_with_pull(GPIOA, 3, PULL_DOWN);
|
||||
|
||||
#ifdef PANDA
|
||||
if(hw_type == HW_TYPE_WHITE_PANDA) {
|
||||
// check if the ESP is trying to put me in boot mode
|
||||
is_entering_bootmode = !detect_with_pull(GPIOB, 0, PULL_UP);
|
||||
} else {
|
||||
is_entering_bootmode = 0;
|
||||
}
|
||||
#else
|
||||
is_entering_bootmode = 0;
|
||||
#endif
|
||||
}
|
||||
|
||||
// ///// Board functions ///// //
|
||||
|
|
|
@ -1,10 +1,10 @@
|
|||
// ******************** Prototypes ********************
|
||||
typedef void (*board_init)(void);
|
||||
typedef void (*board_enable_can_transciever)(uint8_t transciever, bool enabled);
|
||||
typedef void (*board_enable_can_transcievers)(bool enabled);
|
||||
typedef void (*board_enable_can_transceiver)(uint8_t transceiver, bool enabled);
|
||||
typedef void (*board_enable_can_transceivers)(bool enabled);
|
||||
typedef void (*board_set_led)(uint8_t color, bool enabled);
|
||||
typedef void (*board_set_usb_power_mode)(uint8_t mode);
|
||||
typedef void (*board_set_esp_gps_mode)(uint8_t mode);
|
||||
typedef void (*board_set_gps_mode)(uint8_t mode);
|
||||
typedef void (*board_set_can_mode)(uint8_t mode);
|
||||
typedef void (*board_usb_power_mode_tick)(uint32_t uptime);
|
||||
typedef bool (*board_check_ignition)(void);
|
||||
|
@ -12,16 +12,18 @@ typedef uint32_t (*board_read_current)(void);
|
|||
typedef void (*board_set_ir_power)(uint8_t percentage);
|
||||
typedef void (*board_set_fan_power)(uint8_t percentage);
|
||||
typedef void (*board_set_phone_power)(bool enabled);
|
||||
typedef void (*board_set_clock_source_mode)(uint8_t mode);
|
||||
typedef void (*board_set_siren)(bool enabled);
|
||||
|
||||
struct board {
|
||||
const char *board_type;
|
||||
const harness_configuration *harness_config;
|
||||
board_init init;
|
||||
board_enable_can_transciever enable_can_transciever;
|
||||
board_enable_can_transcievers enable_can_transcievers;
|
||||
board_enable_can_transceiver enable_can_transceiver;
|
||||
board_enable_can_transceivers enable_can_transceivers;
|
||||
board_set_led set_led;
|
||||
board_set_usb_power_mode set_usb_power_mode;
|
||||
board_set_esp_gps_mode set_esp_gps_mode;
|
||||
board_set_gps_mode set_gps_mode;
|
||||
board_set_can_mode set_can_mode;
|
||||
board_usb_power_mode_tick usb_power_mode_tick;
|
||||
board_check_ignition check_ignition;
|
||||
|
@ -29,6 +31,8 @@ struct board {
|
|||
board_set_ir_power set_ir_power;
|
||||
board_set_fan_power set_fan_power;
|
||||
board_set_phone_power set_phone_power;
|
||||
board_set_clock_source_mode set_clock_source_mode;
|
||||
board_set_siren set_siren;
|
||||
};
|
||||
|
||||
// ******************* Definitions ********************
|
||||
|
@ -52,10 +56,10 @@ struct board {
|
|||
#define USB_POWER_CDP 2U
|
||||
#define USB_POWER_DCP 3U
|
||||
|
||||
// ESP modes
|
||||
#define ESP_GPS_DISABLED 0U
|
||||
#define ESP_GPS_ENABLED 1U
|
||||
#define ESP_GPS_BOOTMODE 2U
|
||||
// GPS modes
|
||||
#define GPS_DISABLED 0U
|
||||
#define GPS_ENABLED 1U
|
||||
#define GPS_BOOTMODE 2U
|
||||
|
||||
// CAN modes
|
||||
#define CAN_MODE_NORMAL 0U
|
||||
|
@ -72,4 +76,4 @@ bool board_has_gmlan(void);
|
|||
bool board_has_obd(void);
|
||||
bool board_has_lin(void);
|
||||
bool board_has_rtc(void);
|
||||
bool board_has_relay(void);
|
||||
bool board_has_relay(void);
|
||||
|
|
|
@ -2,8 +2,8 @@
|
|||
// Black Panda + Harness //
|
||||
// ///////////////////// //
|
||||
|
||||
void black_enable_can_transciever(uint8_t transciever, bool enabled) {
|
||||
switch (transciever){
|
||||
void black_enable_can_transceiver(uint8_t transceiver, bool enabled) {
|
||||
switch (transceiver){
|
||||
case 1U:
|
||||
set_gpio_output(GPIOC, 1, !enabled);
|
||||
break;
|
||||
|
@ -17,18 +17,18 @@ void black_enable_can_transciever(uint8_t transciever, bool enabled) {
|
|||
set_gpio_output(GPIOB, 10, !enabled);
|
||||
break;
|
||||
default:
|
||||
puts("Invalid CAN transciever ("); puth(transciever); puts("): enabling failed\n");
|
||||
puts("Invalid CAN transceiver ("); puth(transceiver); puts("): enabling failed\n");
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void black_enable_can_transcievers(bool enabled) {
|
||||
void black_enable_can_transceivers(bool enabled) {
|
||||
for(uint8_t i=1U; i<=4U; i++){
|
||||
// Leave main CAN always on for CAN-based ignition detection
|
||||
if((car_harness_status == HARNESS_STATUS_FLIPPED) ? (i == 3U) : (i == 1U)){
|
||||
black_enable_can_transciever(i, true);
|
||||
black_enable_can_transceiver(i, true);
|
||||
} else {
|
||||
black_enable_can_transciever(i, enabled);
|
||||
black_enable_can_transceiver(i, enabled);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -77,24 +77,24 @@ void black_set_usb_power_mode(uint8_t mode) {
|
|||
}
|
||||
}
|
||||
|
||||
void black_set_esp_gps_mode(uint8_t mode) {
|
||||
void black_set_gps_mode(uint8_t mode) {
|
||||
switch (mode) {
|
||||
case ESP_GPS_DISABLED:
|
||||
case GPS_DISABLED:
|
||||
// GPS OFF
|
||||
set_gpio_output(GPIOC, 14, 0);
|
||||
set_gpio_output(GPIOC, 5, 0);
|
||||
break;
|
||||
case ESP_GPS_ENABLED:
|
||||
case GPS_ENABLED:
|
||||
// GPS ON
|
||||
set_gpio_output(GPIOC, 14, 1);
|
||||
set_gpio_output(GPIOC, 5, 1);
|
||||
break;
|
||||
case ESP_GPS_BOOTMODE:
|
||||
case GPS_BOOTMODE:
|
||||
set_gpio_output(GPIOC, 14, 1);
|
||||
set_gpio_output(GPIOC, 5, 0);
|
||||
break;
|
||||
default:
|
||||
puts("Invalid ESP/GPS mode\n");
|
||||
puts("Invalid GPS mode\n");
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -154,6 +154,14 @@ void black_set_phone_power(bool enabled){
|
|||
UNUSED(enabled);
|
||||
}
|
||||
|
||||
void black_set_clock_source_mode(uint8_t mode){
|
||||
UNUSED(mode);
|
||||
}
|
||||
|
||||
void black_set_siren(bool enabled){
|
||||
UNUSED(enabled);
|
||||
}
|
||||
|
||||
void black_init(void) {
|
||||
common_init_gpio();
|
||||
|
||||
|
@ -167,7 +175,7 @@ void black_init(void) {
|
|||
set_gpio_mode(GPIOC, 3, MODE_ANALOG);
|
||||
|
||||
// Set default state of GPS
|
||||
current_board->set_esp_gps_mode(ESP_GPS_ENABLED);
|
||||
current_board->set_gps_mode(GPS_ENABLED);
|
||||
|
||||
// C10: OBD_SBU1_RELAY (harness relay driving output)
|
||||
// C11: OBD_SBU2_RELAY (harness relay driving output)
|
||||
|
@ -190,8 +198,8 @@ void black_init(void) {
|
|||
// Initialize harness
|
||||
harness_init();
|
||||
|
||||
// Enable CAN transcievers
|
||||
black_enable_can_transcievers(true);
|
||||
// Enable CAN transceivers
|
||||
black_enable_can_transceivers(true);
|
||||
|
||||
// Disable LEDs
|
||||
black_set_led(LED_RED, false);
|
||||
|
@ -228,16 +236,18 @@ const board board_black = {
|
|||
.board_type = "Black",
|
||||
.harness_config = &black_harness_config,
|
||||
.init = black_init,
|
||||
.enable_can_transciever = black_enable_can_transciever,
|
||||
.enable_can_transcievers = black_enable_can_transcievers,
|
||||
.enable_can_transceiver = black_enable_can_transceiver,
|
||||
.enable_can_transceivers = black_enable_can_transceivers,
|
||||
.set_led = black_set_led,
|
||||
.set_usb_power_mode = black_set_usb_power_mode,
|
||||
.set_esp_gps_mode = black_set_esp_gps_mode,
|
||||
.set_gps_mode = black_set_gps_mode,
|
||||
.set_can_mode = black_set_can_mode,
|
||||
.usb_power_mode_tick = black_usb_power_mode_tick,
|
||||
.check_ignition = black_check_ignition,
|
||||
.read_current = black_read_current,
|
||||
.set_fan_power = black_set_fan_power,
|
||||
.set_ir_power = black_set_ir_power,
|
||||
.set_phone_power = black_set_phone_power
|
||||
.set_phone_power = black_set_phone_power,
|
||||
.set_clock_source_mode = black_set_clock_source_mode,
|
||||
.set_siren = black_set_siren
|
||||
};
|
||||
|
|
|
@ -23,7 +23,7 @@ void common_init_gpio(void){
|
|||
set_gpio_alternate(GPIOA, 12, GPIO_AF10_OTG_FS);
|
||||
GPIOA->OSPEEDR = GPIO_OSPEEDER_OSPEEDR11 | GPIO_OSPEEDER_OSPEEDR12;
|
||||
|
||||
// A9,A10: USART 1 for talking to the ESP / GPS
|
||||
// A9,A10: USART 1 for talking to the GPS
|
||||
set_gpio_alternate(GPIOA, 9, GPIO_AF7_USART1);
|
||||
set_gpio_alternate(GPIOA, 10, GPIO_AF7_USART1);
|
||||
|
||||
|
@ -65,7 +65,7 @@ void peripherals_init(void){
|
|||
RCC->APB1ENR |= RCC_APB1ENR_PWREN; // for RTC config
|
||||
RCC->APB2ENR |= RCC_APB2ENR_USART1EN;
|
||||
RCC->AHB2ENR |= RCC_AHB2ENR_OTGFSEN;
|
||||
//RCC->APB2ENR |= RCC_APB2ENR_TIM1EN;
|
||||
RCC->APB2ENR |= RCC_APB2ENR_TIM1EN; // clock source timer
|
||||
RCC->APB2ENR |= RCC_APB2ENR_ADC1EN;
|
||||
RCC->APB2ENR |= RCC_APB2ENR_SPI1EN;
|
||||
RCC->APB2ENR |= RCC_APB2ENR_SYSCFGEN;
|
||||
|
@ -81,4 +81,4 @@ bool detect_with_pull(GPIO_TypeDef *GPIO, int pin, int mode) {
|
|||
bool ret = get_gpio_input(GPIO, pin);
|
||||
set_gpio_pullup(GPIO, pin, PULL_NONE);
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -2,8 +2,8 @@
|
|||
// Dos + Harness //
|
||||
// ///////////// //
|
||||
|
||||
void dos_enable_can_transciever(uint8_t transciever, bool enabled) {
|
||||
switch (transciever){
|
||||
void dos_enable_can_transceiver(uint8_t transceiver, bool enabled) {
|
||||
switch (transceiver){
|
||||
case 1U:
|
||||
set_gpio_output(GPIOC, 1, !enabled);
|
||||
break;
|
||||
|
@ -17,18 +17,18 @@ void dos_enable_can_transciever(uint8_t transciever, bool enabled) {
|
|||
set_gpio_output(GPIOB, 10, !enabled);
|
||||
break;
|
||||
default:
|
||||
puts("Invalid CAN transciever ("); puth(transciever); puts("): enabling failed\n");
|
||||
puts("Invalid CAN transceiver ("); puth(transceiver); puts("): enabling failed\n");
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void dos_enable_can_transcievers(bool enabled) {
|
||||
void dos_enable_can_transceivers(bool enabled) {
|
||||
for(uint8_t i=1U; i<=4U; i++){
|
||||
// Leave main CAN always on for CAN-based ignition detection
|
||||
if((car_harness_status == HARNESS_STATUS_FLIPPED) ? (i == 3U) : (i == 1U)){
|
||||
uno_enable_can_transciever(i, true);
|
||||
uno_enable_can_transceiver(i, true);
|
||||
} else {
|
||||
uno_enable_can_transciever(i, enabled);
|
||||
uno_enable_can_transceiver(i, enabled);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -54,20 +54,18 @@ void dos_set_gps_load_switch(bool enabled) {
|
|||
}
|
||||
|
||||
void dos_set_bootkick(bool enabled){
|
||||
UNUSED(enabled);
|
||||
set_gpio_output(GPIOC, 4, !enabled);
|
||||
}
|
||||
|
||||
void dos_bootkick(void) {}
|
||||
|
||||
void dos_set_phone_power(bool enabled){
|
||||
UNUSED(enabled);
|
||||
}
|
||||
|
||||
void dos_set_usb_power_mode(uint8_t mode) {
|
||||
UNUSED(mode);
|
||||
dos_set_bootkick(mode == USB_POWER_CDP);
|
||||
}
|
||||
|
||||
void dos_set_esp_gps_mode(uint8_t mode) {
|
||||
void dos_set_gps_mode(uint8_t mode) {
|
||||
UNUSED(mode);
|
||||
}
|
||||
|
||||
|
@ -101,11 +99,6 @@ void dos_set_can_mode(uint8_t mode){
|
|||
|
||||
void dos_usb_power_mode_tick(uint32_t uptime){
|
||||
UNUSED(uptime);
|
||||
if(bootkick_timer != 0U){
|
||||
bootkick_timer--;
|
||||
} else {
|
||||
dos_set_bootkick(false);
|
||||
}
|
||||
}
|
||||
|
||||
bool dos_check_ignition(void){
|
||||
|
@ -132,6 +125,14 @@ uint32_t dos_read_current(void){
|
|||
return 0U;
|
||||
}
|
||||
|
||||
void dos_set_clock_source_mode(uint8_t mode){
|
||||
clock_source_init(mode);
|
||||
}
|
||||
|
||||
void dos_set_siren(bool enabled){
|
||||
set_gpio_output(GPIOC, 12, enabled);
|
||||
}
|
||||
|
||||
void dos_init(void) {
|
||||
common_init_gpio();
|
||||
|
||||
|
@ -171,8 +172,8 @@ void dos_init(void) {
|
|||
// Initialize RTC
|
||||
rtc_init();
|
||||
|
||||
// Enable CAN transcievers
|
||||
dos_enable_can_transcievers(true);
|
||||
// Enable CAN transceivers
|
||||
dos_enable_can_transceivers(true);
|
||||
|
||||
// Disable LEDs
|
||||
dos_set_led(LED_RED, false);
|
||||
|
@ -189,6 +190,9 @@ void dos_init(void) {
|
|||
|
||||
// init multiplexer
|
||||
can_set_obd(car_harness_status, false);
|
||||
|
||||
// Init clock source as internal free running
|
||||
dos_set_clock_source_mode(CLOCK_SOURCE_MODE_FREE_RUNNING);
|
||||
}
|
||||
|
||||
const harness_configuration dos_harness_config = {
|
||||
|
@ -209,16 +213,18 @@ const board board_dos = {
|
|||
.board_type = "Dos",
|
||||
.harness_config = &dos_harness_config,
|
||||
.init = dos_init,
|
||||
.enable_can_transciever = dos_enable_can_transciever,
|
||||
.enable_can_transcievers = dos_enable_can_transcievers,
|
||||
.enable_can_transceiver = dos_enable_can_transceiver,
|
||||
.enable_can_transceivers = dos_enable_can_transceivers,
|
||||
.set_led = dos_set_led,
|
||||
.set_usb_power_mode = dos_set_usb_power_mode,
|
||||
.set_esp_gps_mode = dos_set_esp_gps_mode,
|
||||
.set_gps_mode = dos_set_gps_mode,
|
||||
.set_can_mode = dos_set_can_mode,
|
||||
.usb_power_mode_tick = dos_usb_power_mode_tick,
|
||||
.check_ignition = dos_check_ignition,
|
||||
.read_current = dos_read_current,
|
||||
.set_fan_power = dos_set_fan_power,
|
||||
.set_ir_power = dos_set_ir_power,
|
||||
.set_phone_power = dos_set_phone_power
|
||||
.set_phone_power = dos_set_phone_power,
|
||||
.set_clock_source_mode = dos_set_clock_source_mode,
|
||||
.set_siren = dos_set_siren
|
||||
};
|
||||
|
|
|
@ -8,22 +8,22 @@ void grey_init(void) {
|
|||
white_grey_common_init();
|
||||
|
||||
// Set default state of GPS
|
||||
current_board->set_esp_gps_mode(ESP_GPS_ENABLED);
|
||||
current_board->set_gps_mode(GPS_ENABLED);
|
||||
}
|
||||
|
||||
void grey_set_esp_gps_mode(uint8_t mode) {
|
||||
void grey_set_gps_mode(uint8_t mode) {
|
||||
switch (mode) {
|
||||
case ESP_GPS_DISABLED:
|
||||
case GPS_DISABLED:
|
||||
// GPS OFF
|
||||
set_gpio_output(GPIOC, 14, 0);
|
||||
set_gpio_output(GPIOC, 5, 0);
|
||||
break;
|
||||
case ESP_GPS_ENABLED:
|
||||
case GPS_ENABLED:
|
||||
// GPS ON
|
||||
set_gpio_output(GPIOC, 14, 1);
|
||||
set_gpio_output(GPIOC, 5, 1);
|
||||
break;
|
||||
case ESP_GPS_BOOTMODE:
|
||||
case GPS_BOOTMODE:
|
||||
set_gpio_output(GPIOC, 14, 1);
|
||||
set_gpio_output(GPIOC, 5, 0);
|
||||
break;
|
||||
|
@ -37,16 +37,18 @@ const board board_grey = {
|
|||
.board_type = "Grey",
|
||||
.harness_config = &white_harness_config,
|
||||
.init = grey_init,
|
||||
.enable_can_transciever = white_enable_can_transciever,
|
||||
.enable_can_transcievers = white_enable_can_transcievers,
|
||||
.enable_can_transceiver = white_enable_can_transceiver,
|
||||
.enable_can_transceivers = white_enable_can_transceivers,
|
||||
.set_led = white_set_led,
|
||||
.set_usb_power_mode = white_set_usb_power_mode,
|
||||
.set_esp_gps_mode = grey_set_esp_gps_mode,
|
||||
.set_gps_mode = grey_set_gps_mode,
|
||||
.set_can_mode = white_set_can_mode,
|
||||
.usb_power_mode_tick = white_usb_power_mode_tick,
|
||||
.check_ignition = white_check_ignition,
|
||||
.read_current = white_read_current,
|
||||
.set_fan_power = white_set_fan_power,
|
||||
.set_ir_power = white_set_ir_power,
|
||||
.set_phone_power = white_set_phone_power
|
||||
};
|
||||
.set_phone_power = white_set_phone_power,
|
||||
.set_clock_source_mode = white_set_clock_source_mode,
|
||||
.set_siren = white_set_siren
|
||||
};
|
||||
|
|
|
@ -2,19 +2,19 @@
|
|||
// Pedal //
|
||||
// ///// //
|
||||
|
||||
void pedal_enable_can_transciever(uint8_t transciever, bool enabled) {
|
||||
switch (transciever){
|
||||
void pedal_enable_can_transceiver(uint8_t transceiver, bool enabled) {
|
||||
switch (transceiver){
|
||||
case 1:
|
||||
set_gpio_output(GPIOB, 3, !enabled);
|
||||
break;
|
||||
default:
|
||||
puts("Invalid CAN transciever ("); puth(transciever); puts("): enabling failed\n");
|
||||
puts("Invalid CAN transceiver ("); puth(transceiver); puts("): enabling failed\n");
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void pedal_enable_can_transcievers(bool enabled) {
|
||||
pedal_enable_can_transciever(1U, enabled);
|
||||
void pedal_enable_can_transceivers(bool enabled) {
|
||||
pedal_enable_can_transceiver(1U, enabled);
|
||||
}
|
||||
|
||||
void pedal_set_led(uint8_t color, bool enabled) {
|
||||
|
@ -35,7 +35,7 @@ void pedal_set_usb_power_mode(uint8_t mode){
|
|||
puts("Trying to set USB power mode on pedal. This is not supported.\n");
|
||||
}
|
||||
|
||||
void pedal_set_esp_gps_mode(uint8_t mode) {
|
||||
void pedal_set_gps_mode(uint8_t mode) {
|
||||
UNUSED(mode);
|
||||
puts("Trying to set ESP/GPS mode on pedal. This is not supported.\n");
|
||||
}
|
||||
|
@ -77,6 +77,14 @@ void pedal_set_phone_power(bool enabled){
|
|||
UNUSED(enabled);
|
||||
}
|
||||
|
||||
void pedal_set_clock_source_mode(uint8_t mode){
|
||||
UNUSED(mode);
|
||||
}
|
||||
|
||||
void pedal_set_siren(bool enabled){
|
||||
UNUSED(enabled);
|
||||
}
|
||||
|
||||
void pedal_init(void) {
|
||||
common_init_gpio();
|
||||
|
||||
|
@ -86,8 +94,8 @@ void pedal_init(void) {
|
|||
// DAC outputs on A4 and A5
|
||||
// apparently they don't need GPIO setup
|
||||
|
||||
// Enable transciever
|
||||
pedal_enable_can_transcievers(true);
|
||||
// Enable transceiver
|
||||
pedal_enable_can_transceivers(true);
|
||||
|
||||
// Disable LEDs
|
||||
pedal_set_led(LED_RED, false);
|
||||
|
@ -102,16 +110,18 @@ const board board_pedal = {
|
|||
.board_type = "Pedal",
|
||||
.harness_config = &pedal_harness_config,
|
||||
.init = pedal_init,
|
||||
.enable_can_transciever = pedal_enable_can_transciever,
|
||||
.enable_can_transcievers = pedal_enable_can_transcievers,
|
||||
.enable_can_transceiver = pedal_enable_can_transceiver,
|
||||
.enable_can_transceivers = pedal_enable_can_transceivers,
|
||||
.set_led = pedal_set_led,
|
||||
.set_usb_power_mode = pedal_set_usb_power_mode,
|
||||
.set_esp_gps_mode = pedal_set_esp_gps_mode,
|
||||
.set_gps_mode = pedal_set_gps_mode,
|
||||
.set_can_mode = pedal_set_can_mode,
|
||||
.usb_power_mode_tick = pedal_usb_power_mode_tick,
|
||||
.check_ignition = pedal_check_ignition,
|
||||
.read_current = pedal_read_current,
|
||||
.set_fan_power = pedal_set_fan_power,
|
||||
.set_ir_power = pedal_set_ir_power,
|
||||
.set_phone_power = pedal_set_phone_power
|
||||
};
|
||||
.set_phone_power = pedal_set_phone_power,
|
||||
.set_clock_source_mode = pedal_set_clock_source_mode,
|
||||
.set_siren = pedal_set_siren
|
||||
};
|
||||
|
|
|
@ -4,8 +4,8 @@
|
|||
#define BOOTKICK_TIME 3U
|
||||
uint8_t bootkick_timer = 0U;
|
||||
|
||||
void uno_enable_can_transciever(uint8_t transciever, bool enabled) {
|
||||
switch (transciever){
|
||||
void uno_enable_can_transceiver(uint8_t transceiver, bool enabled) {
|
||||
switch (transceiver){
|
||||
case 1U:
|
||||
set_gpio_output(GPIOC, 1, !enabled);
|
||||
break;
|
||||
|
@ -19,18 +19,18 @@ void uno_enable_can_transciever(uint8_t transciever, bool enabled) {
|
|||
set_gpio_output(GPIOB, 10, !enabled);
|
||||
break;
|
||||
default:
|
||||
puts("Invalid CAN transciever ("); puth(transciever); puts("): enabling failed\n");
|
||||
puts("Invalid CAN transceiver ("); puth(transceiver); puts("): enabling failed\n");
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void uno_enable_can_transcievers(bool enabled) {
|
||||
void uno_enable_can_transceivers(bool enabled) {
|
||||
for(uint8_t i=1U; i<=4U; i++){
|
||||
// Leave main CAN always on for CAN-based ignition detection
|
||||
if((car_harness_status == HARNESS_STATUS_FLIPPED) ? (i == 3U) : (i == 1U)){
|
||||
uno_enable_can_transciever(i, true);
|
||||
uno_enable_can_transceiver(i, true);
|
||||
} else {
|
||||
uno_enable_can_transciever(i, enabled);
|
||||
uno_enable_can_transceiver(i, enabled);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -89,21 +89,21 @@ void uno_set_usb_power_mode(uint8_t mode) {
|
|||
}
|
||||
}
|
||||
|
||||
void uno_set_esp_gps_mode(uint8_t mode) {
|
||||
void uno_set_gps_mode(uint8_t mode) {
|
||||
switch (mode) {
|
||||
case ESP_GPS_DISABLED:
|
||||
case GPS_DISABLED:
|
||||
// GPS OFF
|
||||
set_gpio_output(GPIOB, 1, 0);
|
||||
set_gpio_output(GPIOC, 5, 0);
|
||||
uno_set_gps_load_switch(false);
|
||||
break;
|
||||
case ESP_GPS_ENABLED:
|
||||
case GPS_ENABLED:
|
||||
// GPS ON
|
||||
set_gpio_output(GPIOB, 1, 1);
|
||||
set_gpio_output(GPIOC, 5, 1);
|
||||
uno_set_gps_load_switch(true);
|
||||
break;
|
||||
case ESP_GPS_BOOTMODE:
|
||||
case GPS_BOOTMODE:
|
||||
set_gpio_output(GPIOB, 1, 1);
|
||||
set_gpio_output(GPIOC, 5, 0);
|
||||
uno_set_gps_load_switch(true);
|
||||
|
@ -175,6 +175,14 @@ uint32_t uno_read_current(void){
|
|||
return 0U;
|
||||
}
|
||||
|
||||
void uno_set_clock_source_mode(uint8_t mode){
|
||||
UNUSED(mode);
|
||||
}
|
||||
|
||||
void uno_set_siren(bool enabled){
|
||||
UNUSED(enabled);
|
||||
}
|
||||
|
||||
void uno_init(void) {
|
||||
common_init_gpio();
|
||||
|
||||
|
@ -188,7 +196,7 @@ void uno_init(void) {
|
|||
set_gpio_mode(GPIOC, 3, MODE_ANALOG);
|
||||
|
||||
// Set default state of GPS
|
||||
current_board->set_esp_gps_mode(ESP_GPS_ENABLED);
|
||||
current_board->set_gps_mode(GPS_ENABLED);
|
||||
|
||||
// C10: OBD_SBU1_RELAY (harness relay driving output)
|
||||
// C11: OBD_SBU2_RELAY (harness relay driving output)
|
||||
|
@ -223,8 +231,8 @@ void uno_init(void) {
|
|||
// Initialize RTC
|
||||
rtc_init();
|
||||
|
||||
// Enable CAN transcievers
|
||||
uno_enable_can_transcievers(true);
|
||||
// Enable CAN transceivers
|
||||
uno_enable_can_transceivers(true);
|
||||
|
||||
// Disable LEDs
|
||||
uno_set_led(LED_RED, false);
|
||||
|
@ -271,16 +279,18 @@ const board board_uno = {
|
|||
.board_type = "Uno",
|
||||
.harness_config = &uno_harness_config,
|
||||
.init = uno_init,
|
||||
.enable_can_transciever = uno_enable_can_transciever,
|
||||
.enable_can_transcievers = uno_enable_can_transcievers,
|
||||
.enable_can_transceiver = uno_enable_can_transceiver,
|
||||
.enable_can_transceivers = uno_enable_can_transceivers,
|
||||
.set_led = uno_set_led,
|
||||
.set_usb_power_mode = uno_set_usb_power_mode,
|
||||
.set_esp_gps_mode = uno_set_esp_gps_mode,
|
||||
.set_gps_mode = uno_set_gps_mode,
|
||||
.set_can_mode = uno_set_can_mode,
|
||||
.usb_power_mode_tick = uno_usb_power_mode_tick,
|
||||
.check_ignition = uno_check_ignition,
|
||||
.read_current = uno_read_current,
|
||||
.set_fan_power = uno_set_fan_power,
|
||||
.set_ir_power = uno_set_ir_power,
|
||||
.set_phone_power = uno_set_phone_power
|
||||
.set_phone_power = uno_set_phone_power,
|
||||
.set_clock_source_mode = uno_set_clock_source_mode,
|
||||
.set_siren = uno_set_siren
|
||||
};
|
||||
|
|
|
@ -2,8 +2,8 @@
|
|||
// White Panda //
|
||||
// /////////// //
|
||||
|
||||
void white_enable_can_transciever(uint8_t transciever, bool enabled) {
|
||||
switch (transciever){
|
||||
void white_enable_can_transceiver(uint8_t transceiver, bool enabled) {
|
||||
switch (transceiver){
|
||||
case 1U:
|
||||
set_gpio_output(GPIOC, 1, !enabled);
|
||||
break;
|
||||
|
@ -14,15 +14,15 @@ void white_enable_can_transciever(uint8_t transciever, bool enabled) {
|
|||
set_gpio_output(GPIOA, 0, !enabled);
|
||||
break;
|
||||
default:
|
||||
puts("Invalid CAN transciever ("); puth(transciever); puts("): enabling failed\n");
|
||||
puts("Invalid CAN transceiver ("); puth(transceiver); puts("): enabling failed\n");
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void white_enable_can_transcievers(bool enabled) {
|
||||
uint8_t t1 = enabled ? 1U : 2U; // leave transciever 1 enabled to detect CAN ignition
|
||||
void white_enable_can_transceivers(bool enabled) {
|
||||
uint8_t t1 = enabled ? 1U : 2U; // leave transceiver 1 enabled to detect CAN ignition
|
||||
for(uint8_t i=t1; i<=3U; i++) {
|
||||
white_enable_can_transciever(i, enabled);
|
||||
white_enable_can_transceiver(i, enabled);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -71,21 +71,21 @@ void white_set_usb_power_mode(uint8_t mode){
|
|||
}
|
||||
}
|
||||
|
||||
void white_set_esp_gps_mode(uint8_t mode) {
|
||||
void white_set_gps_mode(uint8_t mode) {
|
||||
switch (mode) {
|
||||
case ESP_GPS_DISABLED:
|
||||
case GPS_DISABLED:
|
||||
// ESP OFF
|
||||
set_gpio_output(GPIOC, 14, 0);
|
||||
set_gpio_output(GPIOC, 5, 0);
|
||||
break;
|
||||
#ifndef EON
|
||||
case ESP_GPS_ENABLED:
|
||||
case GPS_ENABLED:
|
||||
// ESP ON
|
||||
set_gpio_output(GPIOC, 14, 1);
|
||||
set_gpio_output(GPIOC, 5, 1);
|
||||
break;
|
||||
#endif
|
||||
case ESP_GPS_BOOTMODE:
|
||||
case GPS_BOOTMODE:
|
||||
set_gpio_output(GPIOC, 14, 1);
|
||||
set_gpio_output(GPIOC, 5, 0);
|
||||
break;
|
||||
|
@ -242,6 +242,14 @@ void white_set_phone_power(bool enabled){
|
|||
UNUSED(enabled);
|
||||
}
|
||||
|
||||
void white_set_clock_source_mode(uint8_t mode){
|
||||
UNUSED(mode);
|
||||
}
|
||||
|
||||
void white_set_siren(bool enabled){
|
||||
UNUSED(enabled);
|
||||
}
|
||||
|
||||
void white_grey_common_init(void) {
|
||||
common_init_gpio();
|
||||
|
||||
|
@ -291,8 +299,8 @@ void white_grey_common_init(void) {
|
|||
set_gpio_alternate(GPIOC, 11, GPIO_AF7_USART3);
|
||||
set_gpio_pullup(GPIOC, 11, PULL_UP);
|
||||
|
||||
// Enable CAN transcievers
|
||||
white_enable_can_transcievers(true);
|
||||
// Enable CAN transceivers
|
||||
white_enable_can_transceivers(true);
|
||||
|
||||
// Disable LEDs
|
||||
white_set_led(LED_RED, false);
|
||||
|
@ -316,12 +324,8 @@ void white_grey_common_init(void) {
|
|||
void white_init(void) {
|
||||
white_grey_common_init();
|
||||
|
||||
// Set default state of ESP
|
||||
#ifdef EON
|
||||
current_board->set_esp_gps_mode(ESP_GPS_DISABLED);
|
||||
#else
|
||||
current_board->set_esp_gps_mode(ESP_GPS_ENABLED);
|
||||
#endif
|
||||
// Set ESP off by default
|
||||
current_board->set_gps_mode(GPS_DISABLED);
|
||||
}
|
||||
|
||||
const harness_configuration white_harness_config = {
|
||||
|
@ -332,16 +336,18 @@ const board board_white = {
|
|||
.board_type = "White",
|
||||
.harness_config = &white_harness_config,
|
||||
.init = white_init,
|
||||
.enable_can_transciever = white_enable_can_transciever,
|
||||
.enable_can_transcievers = white_enable_can_transcievers,
|
||||
.enable_can_transceiver = white_enable_can_transceiver,
|
||||
.enable_can_transceivers = white_enable_can_transceivers,
|
||||
.set_led = white_set_led,
|
||||
.set_usb_power_mode = white_set_usb_power_mode,
|
||||
.set_esp_gps_mode = white_set_esp_gps_mode,
|
||||
.set_gps_mode = white_set_gps_mode,
|
||||
.set_can_mode = white_set_can_mode,
|
||||
.usb_power_mode_tick = white_usb_power_mode_tick,
|
||||
.check_ignition = white_check_ignition,
|
||||
.read_current = white_read_current,
|
||||
.set_fan_power = white_set_fan_power,
|
||||
.set_ir_power = white_set_ir_power,
|
||||
.set_phone_power = white_set_phone_power
|
||||
.set_phone_power = white_set_phone_power,
|
||||
.set_clock_source_mode = white_set_clock_source_mode,
|
||||
.set_siren = white_set_siren
|
||||
};
|
||||
|
|
|
@ -0,0 +1,100 @@
|
|||
|
||||
#define CLOCK_SOURCE_MODE_DISABLED 0U
|
||||
#define CLOCK_SOURCE_MODE_FREE_RUNNING 1U
|
||||
#define CLOCK_SOURCE_MODE_EXTERNAL_SYNC 2U
|
||||
|
||||
#define CLOCK_SOURCE_PERIOD_MS 50U
|
||||
#define CLOCK_SOURCE_PULSE_LEN_MS 2U
|
||||
|
||||
uint8_t clock_source_mode = CLOCK_SOURCE_MODE_DISABLED;
|
||||
|
||||
void EXTI0_IRQ_Handler(void) {
|
||||
volatile unsigned int pr = EXTI->PR & (1U << 0);
|
||||
if (pr != 0U) {
|
||||
if(clock_source_mode == CLOCK_SOURCE_MODE_EXTERNAL_SYNC){
|
||||
// TODO: Implement!
|
||||
}
|
||||
}
|
||||
EXTI->PR = (1U << 0);
|
||||
}
|
||||
|
||||
void TIM1_UP_TIM10_IRQ_Handler(void) {
|
||||
if((TIM1->SR & TIM_SR_UIF) != 0) {
|
||||
if(clock_source_mode != CLOCK_SOURCE_MODE_DISABLED) {
|
||||
// Start clock pulse
|
||||
set_gpio_output(GPIOB, 14, true);
|
||||
set_gpio_output(GPIOB, 15, true);
|
||||
}
|
||||
|
||||
// Reset interrupt
|
||||
TIM1->SR &= ~(TIM_SR_UIF);
|
||||
}
|
||||
}
|
||||
|
||||
void TIM1_CC_IRQ_Handler(void) {
|
||||
if((TIM1->SR & TIM_SR_CC1IF) != 0) {
|
||||
if(clock_source_mode != CLOCK_SOURCE_MODE_DISABLED) {
|
||||
// End clock pulse
|
||||
set_gpio_output(GPIOB, 14, false);
|
||||
set_gpio_output(GPIOB, 15, false);
|
||||
}
|
||||
|
||||
// Reset interrupt
|
||||
TIM1->SR &= ~(TIM_SR_CC1IF);
|
||||
}
|
||||
}
|
||||
|
||||
void clock_source_init(uint8_t mode){
|
||||
// Setup external clock signal interrupt
|
||||
REGISTER_INTERRUPT(EXTI0_IRQn, EXTI0_IRQ_Handler, 110U, FAULT_INTERRUPT_RATE_CLOCK_SOURCE)
|
||||
register_set(&(SYSCFG->EXTICR[0]), SYSCFG_EXTICR1_EXTI0_PB, 0xFU);
|
||||
register_set_bits(&(EXTI->IMR), (1U << 0));
|
||||
register_set_bits(&(EXTI->RTSR), (1U << 0));
|
||||
register_clear_bits(&(EXTI->FTSR), (1U << 0));
|
||||
|
||||
// Setup timer
|
||||
REGISTER_INTERRUPT(TIM1_UP_TIM10_IRQn, TIM1_UP_TIM10_IRQ_Handler, (1200U / CLOCK_SOURCE_PERIOD_MS) , FAULT_INTERRUPT_RATE_TIM1)
|
||||
REGISTER_INTERRUPT(TIM1_CC_IRQn, TIM1_CC_IRQ_Handler, (1200U / CLOCK_SOURCE_PERIOD_MS) , FAULT_INTERRUPT_RATE_TIM1)
|
||||
register_set(&(TIM1->PSC), (9600-1), 0xFFFFU); // Tick on 0.1 ms
|
||||
register_set(&(TIM1->ARR), ((CLOCK_SOURCE_PERIOD_MS*10U) - 1U), 0xFFFFU); // Period
|
||||
register_set(&(TIM1->CCMR1), 0U, 0xFFFFU); // No output on compare
|
||||
register_set_bits(&(TIM1->CCER), TIM_CCER_CC1E); // Enable compare 1
|
||||
register_set(&(TIM1->CCR1), (CLOCK_SOURCE_PULSE_LEN_MS*10U), 0xFFFFU); // Compare 1 value
|
||||
register_set_bits(&(TIM1->DIER), TIM_DIER_UIE | TIM_DIER_CC1IE); // Enable interrupts
|
||||
register_set(&(TIM1->CR1), TIM_CR1_CEN, 0x3FU); // Enable timer
|
||||
|
||||
// Set mode
|
||||
switch(mode) {
|
||||
case CLOCK_SOURCE_MODE_DISABLED:
|
||||
// No clock signal
|
||||
NVIC_DisableIRQ(EXTI0_IRQn);
|
||||
NVIC_DisableIRQ(TIM1_UP_TIM10_IRQn);
|
||||
NVIC_DisableIRQ(TIM1_CC_IRQn);
|
||||
|
||||
// Disable pulse if we were in the middle of it
|
||||
set_gpio_output(GPIOB, 14, false);
|
||||
set_gpio_output(GPIOB, 15, false);
|
||||
|
||||
clock_source_mode = CLOCK_SOURCE_MODE_DISABLED;
|
||||
break;
|
||||
case CLOCK_SOURCE_MODE_FREE_RUNNING:
|
||||
// Clock signal is based on internal timer
|
||||
NVIC_DisableIRQ(EXTI0_IRQn);
|
||||
NVIC_EnableIRQ(TIM1_UP_TIM10_IRQn);
|
||||
NVIC_EnableIRQ(TIM1_CC_IRQn);
|
||||
|
||||
clock_source_mode = CLOCK_SOURCE_MODE_FREE_RUNNING;
|
||||
break;
|
||||
case CLOCK_SOURCE_MODE_EXTERNAL_SYNC:
|
||||
// Clock signal is based on external timer
|
||||
NVIC_EnableIRQ(EXTI0_IRQn);
|
||||
NVIC_EnableIRQ(TIM1_UP_TIM10_IRQn);
|
||||
NVIC_EnableIRQ(TIM1_CC_IRQn);
|
||||
|
||||
clock_source_mode = CLOCK_SOURCE_MODE_EXTERNAL_SYNC;
|
||||
break;
|
||||
default:
|
||||
puts("Unknown clock source mode: "); puth(mode); puts("\n");
|
||||
break;
|
||||
}
|
||||
}
|
|
@ -50,8 +50,8 @@ void debug_ring_callback(uart_ring *ring);
|
|||
|
||||
// ******************************** UART buffers ********************************
|
||||
|
||||
// esp_gps = USART1
|
||||
UART_BUFFER(esp_gps, FIFO_SIZE_DMA, FIFO_SIZE_INT, USART1, NULL, true)
|
||||
// gps = USART1
|
||||
UART_BUFFER(gps, FIFO_SIZE_DMA, FIFO_SIZE_INT, USART1, NULL, true)
|
||||
|
||||
// lin1, K-LINE = UART5
|
||||
// lin2, L-LINE = USART3
|
||||
|
@ -68,7 +68,7 @@ uart_ring *get_ring_by_number(int a) {
|
|||
ring = &uart_ring_debug;
|
||||
break;
|
||||
case 1:
|
||||
ring = &uart_ring_esp_gps;
|
||||
ring = &uart_ring_gps;
|
||||
break;
|
||||
case 2:
|
||||
ring = &uart_ring_lin1;
|
||||
|
@ -185,8 +185,8 @@ void uart_interrupt_handler(uart_ring *q) {
|
|||
// Reset IDLE flag
|
||||
UART_READ_DR(q->uart)
|
||||
|
||||
if(q == &uart_ring_esp_gps){
|
||||
dma_pointer_handler(&uart_ring_esp_gps, DMA2_Stream5->NDTR);
|
||||
if(q == &uart_ring_gps){
|
||||
dma_pointer_handler(&uart_ring_gps, DMA2_Stream5->NDTR);
|
||||
} else {
|
||||
#ifdef DEBUG_UART
|
||||
puts("No IDLE dma_pointer_handler implemented for this UART.");
|
||||
|
@ -197,7 +197,7 @@ void uart_interrupt_handler(uart_ring *q) {
|
|||
EXIT_CRITICAL();
|
||||
}
|
||||
|
||||
void USART1_IRQ_Handler(void) { uart_interrupt_handler(&uart_ring_esp_gps); }
|
||||
void USART1_IRQ_Handler(void) { uart_interrupt_handler(&uart_ring_gps); }
|
||||
void USART2_IRQ_Handler(void) { uart_interrupt_handler(&uart_ring_debug); }
|
||||
void USART3_IRQ_Handler(void) { uart_interrupt_handler(&uart_ring_lin2); }
|
||||
void UART5_IRQ_Handler(void) { uart_interrupt_handler(&uart_ring_lin1); }
|
||||
|
@ -219,7 +219,7 @@ void DMA2_Stream5_IRQ_Handler(void) {
|
|||
}
|
||||
|
||||
// Re-calculate write pointer and reset flags
|
||||
dma_pointer_handler(&uart_ring_esp_gps, DMA2_Stream5->NDTR);
|
||||
dma_pointer_handler(&uart_ring_gps, DMA2_Stream5->NDTR);
|
||||
DMA2->HIFCR = DMA_HIFCR_CTCIF5 | DMA_HIFCR_CHTIF5;
|
||||
|
||||
EXIT_CRITICAL();
|
||||
|
@ -229,7 +229,7 @@ void DMA2_Stream5_IRQ_Handler(void) {
|
|||
|
||||
void dma_rx_init(uart_ring *q) {
|
||||
// Initialization is UART-dependent
|
||||
if(q == &uart_ring_esp_gps){
|
||||
if(q == &uart_ring_gps){
|
||||
// DMA2, stream 5, channel 4
|
||||
|
||||
// Disable FIFO mode (enable direct)
|
||||
|
|
|
@ -3,26 +3,28 @@
|
|||
#define FAULT_STATUS_PERMANENT 2U
|
||||
|
||||
// Fault types
|
||||
#define FAULT_RELAY_MALFUNCTION (1U << 0)
|
||||
#define FAULT_UNUSED_INTERRUPT_HANDLED (1U << 1)
|
||||
#define FAULT_INTERRUPT_RATE_CAN_1 (1U << 2)
|
||||
#define FAULT_INTERRUPT_RATE_CAN_2 (1U << 3)
|
||||
#define FAULT_INTERRUPT_RATE_CAN_3 (1U << 4)
|
||||
#define FAULT_INTERRUPT_RATE_TACH (1U << 5)
|
||||
#define FAULT_INTERRUPT_RATE_GMLAN (1U << 6)
|
||||
#define FAULT_INTERRUPT_RATE_INTERRUPTS (1U << 7)
|
||||
#define FAULT_INTERRUPT_RATE_SPI_DMA (1U << 8)
|
||||
#define FAULT_INTERRUPT_RATE_SPI_CS (1U << 9)
|
||||
#define FAULT_INTERRUPT_RATE_UART_1 (1U << 10)
|
||||
#define FAULT_INTERRUPT_RATE_UART_2 (1U << 11)
|
||||
#define FAULT_INTERRUPT_RATE_UART_3 (1U << 12)
|
||||
#define FAULT_INTERRUPT_RATE_UART_5 (1U << 13)
|
||||
#define FAULT_INTERRUPT_RATE_UART_DMA (1U << 14)
|
||||
#define FAULT_INTERRUPT_RATE_USB (1U << 15)
|
||||
#define FAULT_INTERRUPT_RATE_TIM1 (1U << 16)
|
||||
#define FAULT_INTERRUPT_RATE_TIM3 (1U << 17)
|
||||
#define FAULT_REGISTER_DIVERGENT (1U << 18)
|
||||
#define FAULT_INTERRUPT_RATE_KLINE_INIT (1U << 19)
|
||||
#define FAULT_RELAY_MALFUNCTION (1U << 0)
|
||||
#define FAULT_UNUSED_INTERRUPT_HANDLED (1U << 1)
|
||||
#define FAULT_INTERRUPT_RATE_CAN_1 (1U << 2)
|
||||
#define FAULT_INTERRUPT_RATE_CAN_2 (1U << 3)
|
||||
#define FAULT_INTERRUPT_RATE_CAN_3 (1U << 4)
|
||||
#define FAULT_INTERRUPT_RATE_TACH (1U << 5)
|
||||
#define FAULT_INTERRUPT_RATE_GMLAN (1U << 6)
|
||||
#define FAULT_INTERRUPT_RATE_INTERRUPTS (1U << 7)
|
||||
#define FAULT_INTERRUPT_RATE_SPI_DMA (1U << 8)
|
||||
#define FAULT_INTERRUPT_RATE_SPI_CS (1U << 9)
|
||||
#define FAULT_INTERRUPT_RATE_UART_1 (1U << 10)
|
||||
#define FAULT_INTERRUPT_RATE_UART_2 (1U << 11)
|
||||
#define FAULT_INTERRUPT_RATE_UART_3 (1U << 12)
|
||||
#define FAULT_INTERRUPT_RATE_UART_5 (1U << 13)
|
||||
#define FAULT_INTERRUPT_RATE_UART_DMA (1U << 14)
|
||||
#define FAULT_INTERRUPT_RATE_USB (1U << 15)
|
||||
#define FAULT_INTERRUPT_RATE_TIM1 (1U << 16)
|
||||
#define FAULT_INTERRUPT_RATE_TIM3 (1U << 17)
|
||||
#define FAULT_REGISTER_DIVERGENT (1U << 18)
|
||||
#define FAULT_INTERRUPT_RATE_KLINE_INIT (1U << 19)
|
||||
#define FAULT_INTERRUPT_RATE_CLOCK_SOURCE (1U << 20)
|
||||
#define FAULT_INTERRUPT_RATE_TIM9 (1U << 21)
|
||||
|
||||
// Permanent faults
|
||||
#define PERMANENT_FAULTS 0U
|
||||
|
|
|
@ -64,13 +64,9 @@ void early(void) {
|
|||
|
||||
if (enter_bootloader_mode == ENTER_BOOTLOADER_MAGIC) {
|
||||
#ifdef PANDA
|
||||
current_board->set_esp_gps_mode(ESP_GPS_DISABLED);
|
||||
current_board->set_gps_mode(GPS_DISABLED);
|
||||
#endif
|
||||
current_board->set_led(LED_GREEN, 1);
|
||||
jump_to_bootloader();
|
||||
}
|
||||
|
||||
if (is_entering_bootmode) {
|
||||
enter_bootloader_mode = ENTER_SOFTLOADER_MAGIC;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -400,24 +400,24 @@ int usb_cb_control_msg(USB_Setup_TypeDef *setup, uint8_t *resp, bool hardwired)
|
|||
// **** 0xd9: set ESP power
|
||||
case 0xd9:
|
||||
if (setup->b.wValue.w == 1U) {
|
||||
current_board->set_esp_gps_mode(ESP_GPS_ENABLED);
|
||||
current_board->set_gps_mode(GPS_ENABLED);
|
||||
} else if (setup->b.wValue.w == 2U) {
|
||||
current_board->set_esp_gps_mode(ESP_GPS_BOOTMODE);
|
||||
current_board->set_gps_mode(GPS_BOOTMODE);
|
||||
} else {
|
||||
current_board->set_esp_gps_mode(ESP_GPS_DISABLED);
|
||||
current_board->set_gps_mode(GPS_DISABLED);
|
||||
}
|
||||
break;
|
||||
// **** 0xda: reset ESP, with optional boot mode
|
||||
case 0xda:
|
||||
current_board->set_esp_gps_mode(ESP_GPS_DISABLED);
|
||||
current_board->set_gps_mode(GPS_DISABLED);
|
||||
delay(1000000);
|
||||
if (setup->b.wValue.w == 1U) {
|
||||
current_board->set_esp_gps_mode(ESP_GPS_BOOTMODE);
|
||||
current_board->set_gps_mode(GPS_BOOTMODE);
|
||||
} else {
|
||||
current_board->set_esp_gps_mode(ESP_GPS_ENABLED);
|
||||
current_board->set_gps_mode(GPS_ENABLED);
|
||||
}
|
||||
delay(1000000);
|
||||
current_board->set_esp_gps_mode(ESP_GPS_ENABLED);
|
||||
current_board->set_gps_mode(GPS_ENABLED);
|
||||
break;
|
||||
// **** 0xdb: set GMLAN (white/grey) or OBD CAN (black) multiplexing mode
|
||||
case 0xdb:
|
||||
|
@ -493,7 +493,7 @@ int usb_cb_control_msg(USB_Setup_TypeDef *setup, uint8_t *resp, bool hardwired)
|
|||
}
|
||||
|
||||
// TODO: Remove this again and fix boardd code to hande the message bursts instead of single chars
|
||||
if (ur == &uart_ring_esp_gps) {
|
||||
if (ur == &uart_ring_gps) {
|
||||
dma_pointer_handler(ur, DMA2_Stream5->NDTR);
|
||||
}
|
||||
|
||||
|
@ -606,6 +606,14 @@ int usb_cb_control_msg(USB_Setup_TypeDef *setup, uint8_t *resp, bool hardwired)
|
|||
}
|
||||
}
|
||||
break;
|
||||
// **** 0xf5: set clock source mode
|
||||
case 0xf5:
|
||||
current_board->set_clock_source_mode(setup->b.wValue.w);
|
||||
break;
|
||||
// **** 0xf6: set siren enabled
|
||||
case 0xf6:
|
||||
siren_enabled = (setup->b.wValue.w != 0U);
|
||||
break;
|
||||
default:
|
||||
puts("NO HANDLER ");
|
||||
puth(setup->b.bRequest);
|
||||
|
@ -663,87 +671,97 @@ void __attribute__ ((noinline)) enable_fpu(void) {
|
|||
#define EON_HEARTBEAT_IGNITION_CNT_ON 5U
|
||||
#define EON_HEARTBEAT_IGNITION_CNT_OFF 2U
|
||||
|
||||
// called at 1Hz
|
||||
// called at 8Hz
|
||||
uint8_t loop_counter = 0U;
|
||||
void TIM1_BRK_TIM9_IRQ_Handler(void) {
|
||||
if (TIM9->SR != 0) {
|
||||
can_live = pending_can_live;
|
||||
// siren
|
||||
current_board->set_siren((loop_counter & 1U) && siren_enabled);
|
||||
|
||||
current_board->usb_power_mode_tick(uptime_cnt);
|
||||
// decimated to 1Hz
|
||||
if(loop_counter == 0U){
|
||||
can_live = pending_can_live;
|
||||
|
||||
//puth(usart1_dma); puts(" "); puth(DMA2_Stream5->M0AR); puts(" "); puth(DMA2_Stream5->NDTR); puts("\n");
|
||||
current_board->usb_power_mode_tick(uptime_cnt);
|
||||
|
||||
// reset this every 16th pass
|
||||
if ((uptime_cnt & 0xFU) == 0U) {
|
||||
pending_can_live = 0;
|
||||
}
|
||||
#ifdef DEBUG
|
||||
puts("** blink ");
|
||||
puth(can_rx_q.r_ptr); puts(" "); puth(can_rx_q.w_ptr); puts(" ");
|
||||
puth(can_tx1_q.r_ptr); puts(" "); puth(can_tx1_q.w_ptr); puts(" ");
|
||||
puth(can_tx2_q.r_ptr); puts(" "); puth(can_tx2_q.w_ptr); puts("\n");
|
||||
#endif
|
||||
//puth(usart1_dma); puts(" "); puth(DMA2_Stream5->M0AR); puts(" "); puth(DMA2_Stream5->NDTR); puts("\n");
|
||||
|
||||
// Tick drivers
|
||||
fan_tick();
|
||||
|
||||
// set green LED to be controls allowed
|
||||
current_board->set_led(LED_GREEN, controls_allowed);
|
||||
|
||||
// turn off the blue LED, turned on by CAN
|
||||
// unless we are in power saving mode
|
||||
current_board->set_led(LED_BLUE, (uptime_cnt & 1U) && (power_save_status == POWER_SAVE_STATUS_ENABLED));
|
||||
|
||||
// increase heartbeat counter and cap it at the uint32 limit
|
||||
if (heartbeat_counter < __UINT32_MAX__) {
|
||||
heartbeat_counter += 1U;
|
||||
}
|
||||
|
||||
#ifdef EON
|
||||
// check heartbeat counter if we are running EON code.
|
||||
// if the heartbeat has been gone for a while, go to SILENT safety mode and enter power save
|
||||
if (heartbeat_counter >= (check_started() ? EON_HEARTBEAT_IGNITION_CNT_ON : EON_HEARTBEAT_IGNITION_CNT_OFF)) {
|
||||
puts("EON hasn't sent a heartbeat for 0x");
|
||||
puth(heartbeat_counter);
|
||||
puts(" seconds. Safety is set to SILENT mode.\n");
|
||||
if (current_safety_mode != SAFETY_SILENT) {
|
||||
set_safety_mode(SAFETY_SILENT, 0U);
|
||||
// reset this every 16th pass
|
||||
if ((uptime_cnt & 0xFU) == 0U) {
|
||||
pending_can_live = 0;
|
||||
}
|
||||
if (power_save_status != POWER_SAVE_STATUS_ENABLED) {
|
||||
set_power_save_state(POWER_SAVE_STATUS_ENABLED);
|
||||
#ifdef DEBUG
|
||||
puts("** blink ");
|
||||
puth(can_rx_q.r_ptr); puts(" "); puth(can_rx_q.w_ptr); puts(" ");
|
||||
puth(can_tx1_q.r_ptr); puts(" "); puth(can_tx1_q.w_ptr); puts(" ");
|
||||
puth(can_tx2_q.r_ptr); puts(" "); puth(can_tx2_q.w_ptr); puts("\n");
|
||||
#endif
|
||||
|
||||
// Tick drivers
|
||||
fan_tick();
|
||||
|
||||
// set green LED to be controls allowed
|
||||
current_board->set_led(LED_GREEN, controls_allowed);
|
||||
|
||||
// turn off the blue LED, turned on by CAN
|
||||
// unless we are in power saving mode
|
||||
current_board->set_led(LED_BLUE, (uptime_cnt & 1U) && (power_save_status == POWER_SAVE_STATUS_ENABLED));
|
||||
|
||||
// increase heartbeat counter and cap it at the uint32 limit
|
||||
if (heartbeat_counter < __UINT32_MAX__) {
|
||||
heartbeat_counter += 1U;
|
||||
}
|
||||
|
||||
// Also disable IR when the heartbeat goes missing
|
||||
current_board->set_ir_power(0U);
|
||||
#ifdef EON
|
||||
// check heartbeat counter if we are running EON code.
|
||||
// if the heartbeat has been gone for a while, go to SILENT safety mode and enter power save
|
||||
if (heartbeat_counter >= (check_started() ? EON_HEARTBEAT_IGNITION_CNT_ON : EON_HEARTBEAT_IGNITION_CNT_OFF)) {
|
||||
puts("EON hasn't sent a heartbeat for 0x");
|
||||
puth(heartbeat_counter);
|
||||
puts(" seconds. Safety is set to SILENT mode.\n");
|
||||
if (current_safety_mode != SAFETY_SILENT) {
|
||||
set_safety_mode(SAFETY_SILENT, 0U);
|
||||
}
|
||||
if (power_save_status != POWER_SAVE_STATUS_ENABLED) {
|
||||
set_power_save_state(POWER_SAVE_STATUS_ENABLED);
|
||||
}
|
||||
|
||||
// If enumerated but no heartbeat (phone up, boardd not running), turn the fan on to cool the device
|
||||
if(usb_enumerated()){
|
||||
current_board->set_fan_power(50U);
|
||||
} else {
|
||||
current_board->set_fan_power(0U);
|
||||
// Also disable IR when the heartbeat goes missing
|
||||
current_board->set_ir_power(0U);
|
||||
|
||||
// If enumerated but no heartbeat (phone up, boardd not running), turn the fan on to cool the device
|
||||
if(usb_enumerated()){
|
||||
current_board->set_fan_power(50U);
|
||||
} else {
|
||||
current_board->set_fan_power(0U);
|
||||
}
|
||||
}
|
||||
|
||||
// enter CDP mode when car starts to ensure we are charging a turned off EON
|
||||
if (check_started() && (usb_power_mode != USB_POWER_CDP)) {
|
||||
current_board->set_usb_power_mode(USB_POWER_CDP);
|
||||
}
|
||||
#endif
|
||||
|
||||
// check registers
|
||||
check_registers();
|
||||
|
||||
// set ignition_can to false after 2s of no CAN seen
|
||||
if (ignition_can_cnt > 2U) {
|
||||
ignition_can = false;
|
||||
};
|
||||
|
||||
// on to the next one
|
||||
uptime_cnt += 1U;
|
||||
safety_mode_cnt += 1U;
|
||||
ignition_can_cnt += 1U;
|
||||
|
||||
// synchronous safety check
|
||||
safety_tick(current_hooks);
|
||||
}
|
||||
|
||||
// enter CDP mode when car starts to ensure we are charging a turned off EON
|
||||
if (check_started() && (usb_power_mode != USB_POWER_CDP)) {
|
||||
current_board->set_usb_power_mode(USB_POWER_CDP);
|
||||
}
|
||||
#endif
|
||||
|
||||
// check registers
|
||||
check_registers();
|
||||
|
||||
// set ignition_can to false after 2s of no CAN seen
|
||||
if (ignition_can_cnt > 2U) {
|
||||
ignition_can = false;
|
||||
};
|
||||
|
||||
// on to the next one
|
||||
uptime_cnt += 1U;
|
||||
safety_mode_cnt += 1U;
|
||||
ignition_can_cnt += 1U;
|
||||
|
||||
// synchronous safety check
|
||||
safety_tick(current_hooks);
|
||||
loop_counter++;
|
||||
loop_counter %= 8U;
|
||||
}
|
||||
TIM9->SR = 0;
|
||||
}
|
||||
|
@ -753,8 +771,8 @@ int main(void) {
|
|||
// Init interrupt table
|
||||
init_interrupts(true);
|
||||
|
||||
// 1s timer
|
||||
REGISTER_INTERRUPT(TIM1_BRK_TIM9_IRQn, TIM1_BRK_TIM9_IRQ_Handler, 2U, FAULT_INTERRUPT_RATE_TIM1)
|
||||
// 8Hz timer
|
||||
REGISTER_INTERRUPT(TIM1_BRK_TIM9_IRQn, TIM1_BRK_TIM9_IRQ_Handler, 10U, FAULT_INTERRUPT_RATE_TIM9)
|
||||
|
||||
// shouldn't have interrupts here, but just in case
|
||||
disable_interrupts();
|
||||
|
@ -778,7 +796,6 @@ int main(void) {
|
|||
puts("Config:\n");
|
||||
puts(" Board type: "); puts(current_board->board_type); puts("\n");
|
||||
puts(has_external_debug_serial ? " Real serial\n" : " USB serial\n");
|
||||
puts(is_entering_bootmode ? " ESP wants bootmode\n" : " No bootmode\n");
|
||||
|
||||
// init board
|
||||
current_board->init();
|
||||
|
@ -794,10 +811,10 @@ int main(void) {
|
|||
}
|
||||
|
||||
if (board_has_gps()) {
|
||||
uart_init(&uart_ring_esp_gps, 9600);
|
||||
uart_init(&uart_ring_gps, 9600);
|
||||
} else {
|
||||
// enable ESP uart
|
||||
uart_init(&uart_ring_esp_gps, 115200);
|
||||
uart_init(&uart_ring_gps, 115200);
|
||||
}
|
||||
|
||||
if(board_has_lin()){
|
||||
|
@ -820,14 +837,14 @@ int main(void) {
|
|||
set_safety_mode(SAFETY_SILENT, 0);
|
||||
|
||||
// enable CAN TXs
|
||||
current_board->enable_can_transcievers(true);
|
||||
current_board->enable_can_transceivers(true);
|
||||
|
||||
#ifndef EON
|
||||
spi_init();
|
||||
#endif
|
||||
|
||||
// 1hz
|
||||
timer_init(TIM9, 1464);
|
||||
// 8hz
|
||||
timer_init(TIM9, 183);
|
||||
NVIC_EnableIRQ(TIM1_BRK_TIM9_IRQn);
|
||||
|
||||
#ifdef DEBUG
|
||||
|
|
|
@ -13,3 +13,4 @@ const board *current_board;
|
|||
bool is_enumerated = 0;
|
||||
uint32_t heartbeat_counter = 0;
|
||||
uint32_t uptime_cnt = 0;
|
||||
bool siren_enabled = false;
|
||||
|
|
|
@ -28,13 +28,13 @@ void set_power_save_state(int state) {
|
|||
enable = true;
|
||||
}
|
||||
|
||||
current_board->enable_can_transcievers(enable);
|
||||
current_board->enable_can_transceivers(enable);
|
||||
|
||||
// Switch EPS/GPS
|
||||
if (enable) {
|
||||
current_board->set_esp_gps_mode(ESP_GPS_ENABLED);
|
||||
current_board->set_gps_mode(GPS_ENABLED);
|
||||
} else {
|
||||
current_board->set_esp_gps_mode(ESP_GPS_DISABLED);
|
||||
current_board->set_gps_mode(GPS_DISABLED);
|
||||
}
|
||||
|
||||
if(board_has_gmlan()){
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
const int HYUNDAI_MAX_STEER = 255; // like stock
|
||||
const int HYUNDAI_MAX_STEER = 384; // like stock
|
||||
const int HYUNDAI_MAX_RT_DELTA = 112; // max delta torque allowed for real time checks
|
||||
const uint32_t HYUNDAI_RT_INTERVAL = 250000; // 250ms between real time checks
|
||||
const int HYUNDAI_MAX_RATE_UP = 3;
|
||||
|
|
|
@ -290,7 +290,7 @@ void soft_flasher_start(void) {
|
|||
// B8,B9: CAN 1
|
||||
set_gpio_alternate(GPIOB, 8, GPIO_AF9_CAN1);
|
||||
set_gpio_alternate(GPIOB, 9, GPIO_AF9_CAN1);
|
||||
current_board->enable_can_transciever(1, true);
|
||||
current_board->enable_can_transceiver(1, true);
|
||||
|
||||
// init can
|
||||
llcan_set_speed(CAN1, 5000, false, false);
|
||||
|
|
|
@ -1,15 +0,0 @@
|
|||
-----BEGIN RSA PRIVATE KEY-----
|
||||
MIICXAIBAAKBgQCjIHvrSCWN0Nec6ozbImYik30PIF7JSWgdwDKTxSJ05RM3pj5E
|
||||
LQEGt3qcaVrTokO68tpt5Gu1p6ZsNqWg7iVTW9M7Qj7IH45YDzQP/PSRjgSosQA6
|
||||
6f5Gokba5QrW38myqimvj+0p+YH+CNGCBRlTUQGCO8uLCspMZneRSLPW9QIDAQAB
|
||||
AoGADaUn+HRef9BaWMvd4G6uMHI54cwJYbj8NpDfKjExQqnuw5bqWnWRQmiSnwbJ
|
||||
DC7kj3zE/LBAuj890ot3q1CAWqh47ZICZfoX9Qbi5TpvIHFCGy6YkOliF6iIQhR2
|
||||
4+zNKTAA0zNKskOM25PdI+grK1Ni/bEofSA6TrqvEwsmxnkCQQDVp9FUUor2Bo/h
|
||||
/3oAIP51LTw7vfpztYbJr+BDV63czV2DLXzSwzeNrwH4sA3oy1mjUgMBBgAarNGE
|
||||
DYlc4H5jAkEAw3UCHzzXPlxkw2QGp7nBly5y3p80Uqc31NuYz8rdX/U8KTngi2No
|
||||
Ft/SGCEXNpeYbToj+WK3RJJ2Ey0mK8+IxwJAcpGd/5CPsaQNLcw4WK9Yo+8Q2Jxk
|
||||
G/4gfDCSmqn+smNxnLEcuUwzkwdgkEGgA9BfjeOhdsAH+EXpx90WZrZ/LwJBAK0k
|
||||
jq+rTqUQZbZsejTEKYjJ/bnV4BzDwoKN0Q1pkLc7X4LJoW74rTFuLgdv8MdMfRtt
|
||||
IIb/eoeFEpGkMicnHesCQHgR7BTUGBM6Uxam7RCdsgVsxoHBma21E/44ivWUMZzN
|
||||
3oVt0mPnjS4speOlqwED5pCJ7yw7jwLPFMs8kNxuIKU=
|
||||
-----END RSA PRIVATE KEY-----
|
|
@ -1 +0,0 @@
|
|||
ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAAAgQCjIHvrSCWN0Nec6ozbImYik30PIF7JSWgdwDKTxSJ05RM3pj5ELQEGt3qcaVrTokO68tpt5Gu1p6ZsNqWg7iVTW9M7Qj7IH45YDzQP/PSRjgSosQA66f5Gokba5QrW38myqimvj+0p+YH+CNGCBRlTUQGCO8uLCspMZneRSLPW9Q== batman@y840
|
|
@ -1 +0,0 @@
|
|||
ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAAAgQDN4pVyGuJJSde1l3Fjay8qPxog09DsAJZtYPk+armoYO1L6YKReUTcMNyHQYZZMZFmhCdgjCgTIF2QYWMoP4KSe8l6JF04YPP51dIgefc6UXjtlSI8Pyutr0v9xXjSfsVm3RAJxDSHgzs9AoMsluKCL+LhAR1nd7cuHXITJ80O4w== batman@y840
|
|
@ -10,7 +10,6 @@ import traceback
|
|||
import subprocess
|
||||
import sys
|
||||
from .dfu import PandaDFU # pylint: disable=import-error
|
||||
from .esptool import ESPROM, CesantaFlasher # noqa pylint: disable=import-error
|
||||
from .flash_release import flash_release # noqa pylint: disable=import-error
|
||||
from .update import ensure_st_up_to_date # noqa pylint: disable=import-error
|
||||
from .serial import PandaSerial # noqa pylint: disable=import-error
|
||||
|
@ -148,6 +147,10 @@ class Panda(object):
|
|||
HW_TYPE_PEDAL = b'\x04'
|
||||
HW_TYPE_UNO = b'\x05'
|
||||
|
||||
CLOCK_SOURCE_MODE_DISABLED = 0
|
||||
CLOCK_SOURCE_MODE_FREE_RUNNING = 1
|
||||
CLOCK_SOURCE_MODE_EXTERNAL_SYNC = 2
|
||||
|
||||
def __init__(self, serial=None, claim=True):
|
||||
self._serial = serial
|
||||
self._handle = None
|
||||
|
@ -458,7 +461,7 @@ class Panda(object):
|
|||
self._handle.controlWrite(Panda.REQUEST_OUT, 0xe5, int(enable), 0, b'')
|
||||
|
||||
def set_can_enable(self, bus_num, enable):
|
||||
# sets the can transciever enable pin
|
||||
# sets the can transceiver enable pin
|
||||
self._handle.controlWrite(Panda.REQUEST_OUT, 0xf4, int(bus_num), int(enable), b'')
|
||||
|
||||
def set_can_speed_kbps(self, bus, speed):
|
||||
|
@ -665,3 +668,11 @@ class Panda(object):
|
|||
# ****************** Phone *****************
|
||||
def set_phone_power(self, enabled):
|
||||
self._handle.controlWrite(Panda.REQUEST_OUT, 0xb3, int(enabled), 0, b'')
|
||||
|
||||
# ************** Clock Source **************
|
||||
def set_clock_source_mode(self, mode):
|
||||
self._handle.controlWrite(Panda.REQUEST_OUT, 0xf5, int(mode), 0, b'')
|
||||
|
||||
# ****************** Siren *****************
|
||||
def set_siren(self, enabled):
|
||||
self._handle.controlWrite(Panda.REQUEST_OUT, 0xf6, int(enabled), 0, b'')
|
||||
|
|
|
@ -24,7 +24,7 @@ class PandaDFU(object):
|
|||
self._handle = device.open()
|
||||
self.legacy = "07*128Kg" in self._handle.getASCIIStringDescriptor(4)
|
||||
return
|
||||
raise Exception("failed to open " + dfu_serial)
|
||||
raise Exception("failed to open " + dfu_serial if dfu_serial is not None else "DFU device")
|
||||
|
||||
@staticmethod
|
||||
def list():
|
||||
|
|
|
@ -7,7 +7,7 @@ import json
|
|||
import io
|
||||
|
||||
def flash_release(path=None, st_serial=None):
|
||||
from panda import Panda, PandaDFU, ESPROM, CesantaFlasher
|
||||
from panda import Panda, PandaDFU
|
||||
from zipfile import ZipFile
|
||||
|
||||
def status(x):
|
||||
|
@ -23,33 +23,28 @@ def flash_release(path=None, st_serial=None):
|
|||
st_serial = panda_list[0]
|
||||
print("Using panda with serial %s" % st_serial)
|
||||
|
||||
if path is not None:
|
||||
if path is None:
|
||||
print("Fetching latest firmware from github.com/commaai/panda-artifacts")
|
||||
r = requests.get("https://raw.githubusercontent.com/commaai/panda-artifacts/master/latest.json")
|
||||
url = json.loads(r.text)['url']
|
||||
r = requests.get(url)
|
||||
print("Fetching firmware from %s" % url)
|
||||
path = io.StringIO(r.content)
|
||||
path = io.BytesIO(r.content)
|
||||
|
||||
zf = ZipFile(path)
|
||||
zf.printdir()
|
||||
|
||||
version = zf.read("version")
|
||||
status("0. Preparing to flash " + version)
|
||||
version = zf.read("version").decode()
|
||||
status("0. Preparing to flash " + str(version))
|
||||
|
||||
code_bootstub = zf.read("bootstub.panda.bin")
|
||||
code_panda = zf.read("panda.bin")
|
||||
|
||||
code_boot_15 = zf.read("boot_v1.5.bin")
|
||||
code_boot_15 = code_boot_15[0:2] + "\x00\x30" + code_boot_15[4:]
|
||||
|
||||
code_user1 = zf.read("user1.bin")
|
||||
code_user2 = zf.read("user2.bin")
|
||||
|
||||
# enter DFU mode
|
||||
status("1. Entering DFU mode")
|
||||
panda = Panda(st_serial)
|
||||
panda.enter_bootloader()
|
||||
panda.reset(enter_bootstub=True)
|
||||
panda.reset(enter_bootloader=True)
|
||||
time.sleep(1)
|
||||
|
||||
# program bootstub
|
||||
|
@ -64,29 +59,8 @@ def flash_release(path=None, st_serial=None):
|
|||
panda.flash(code=code_panda)
|
||||
panda.close()
|
||||
|
||||
# flashing ESP
|
||||
if panda.is_white():
|
||||
status("4. Flashing ESP (slow!)")
|
||||
|
||||
def align(x, sz=0x1000):
|
||||
x + "\xFF" * ((sz - len(x)) % sz)
|
||||
|
||||
esp = ESPROM(st_serial)
|
||||
esp.connect()
|
||||
flasher = CesantaFlasher(esp, 230400)
|
||||
flasher.flash_write(0x0, align(code_boot_15), True)
|
||||
flasher.flash_write(0x1000, align(code_user1), True)
|
||||
flasher.flash_write(0x81000, align(code_user2), True)
|
||||
flasher.flash_write(0x3FE000, "\xFF" * 0x1000)
|
||||
flasher.boot_fw()
|
||||
del flasher
|
||||
del esp
|
||||
time.sleep(1)
|
||||
else:
|
||||
status("4. No ESP in non-white panda")
|
||||
|
||||
# check for connection
|
||||
status("5. Verifying version")
|
||||
status("4. Verifying version")
|
||||
panda = Panda(st_serial)
|
||||
my_version = panda.get_version()
|
||||
print("dongle id: %s" % panda.get_serial()[0])
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
import os
|
||||
import platform
|
||||
from cffi import FFI
|
||||
|
||||
TEMPLATE_DIR = os.path.abspath(os.path.join(os.path.dirname(__file__), '..', 'templates'))
|
||||
|
@ -13,7 +14,8 @@ def write_code(folder, name, code, header):
|
|||
|
||||
|
||||
def load_code(folder, name):
|
||||
shared_fn = os.path.join(folder, f"lib{name}.so")
|
||||
shared_ext = "dylib" if platform.system() == "Darwin" else "so"
|
||||
shared_fn = os.path.join(folder, f"lib{name}.{shared_ext}")
|
||||
header_fn = os.path.join(folder, f"{name}.h")
|
||||
|
||||
with open(header_fn) as f:
|
||||
|
|
After Width: | Height: | Size: 2.2 KiB |
After Width: | Height: | Size: 12 KiB |
After Width: | Height: | Size: 8.7 KiB |
After Width: | Height: | Size: 4.4 KiB |
After Width: | Height: | Size: 1.4 KiB |
After Width: | Height: | Size: 24 KiB |
After Width: | Height: | Size: 8.4 KiB |
After Width: | Height: | Size: 28 KiB |
After Width: | Height: | Size: 29 KiB |
After Width: | Height: | Size: 635 B |
After Width: | Height: | Size: 604 B |
After Width: | Height: | Size: 2.5 KiB |
After Width: | Height: | Size: 57 KiB |
After Width: | Height: | Size: 39 KiB |
After Width: | Height: | Size: 42 KiB |
After Width: | Height: | Size: 18 KiB |
After Width: | Height: | Size: 14 KiB |
After Width: | Height: | Size: 2.8 KiB |
After Width: | Height: | Size: 6.5 KiB |
After Width: | Height: | Size: 13 KiB |
After Width: | Height: | Size: 42 KiB |
After Width: | Height: | Size: 3.2 KiB |
After Width: | Height: | Size: 15 KiB |
After Width: | Height: | Size: 7.8 KiB |