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
|
### 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
|
### 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.
|
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
|
## Pull Requests
|
||||||
|
|
||||||
|
|
|
@ -70,7 +70,7 @@ pipeline {
|
||||||
stage('PC tests') {
|
stage('PC tests') {
|
||||||
agent {
|
agent {
|
||||||
dockerfile {
|
dockerfile {
|
||||||
filename 'Dockerfile.openpilot'
|
filename 'Dockerfile.openpilotci'
|
||||||
args '--privileged --shm-size=1G --user=root'
|
args '--privileged --shm-size=1G --user=root'
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -132,6 +132,7 @@ pipeline {
|
||||||
["build cereal", "SCONS_CACHE=1 scons -j4 cereal/"],
|
["build cereal", "SCONS_CACHE=1 scons -j4 cereal/"],
|
||||||
["test sounds", "nosetests -s selfdrive/test/test_sounds.py"],
|
["test sounds", "nosetests -s selfdrive/test/test_sounds.py"],
|
||||||
["test boardd loopback", "nosetests -s selfdrive/boardd/tests/test_boardd_loopback.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"],
|
//["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 | Accord Hybrid 2018-20 | All | Stock | 0mph | 3mph |
|
||||||
| Honda | Civic Hatchback 2017-19 | Honda Sensing | Stock | 0mph | 12mph |
|
| 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 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 2015-16 | Touring | openpilot | 25mph<sup>1</sup> | 12mph |
|
||||||
| Honda | CR-V 2017-20 | Honda Sensing | Stock | 0mph | 12mph |
|
| Honda | CR-V 2017-20 | Honda Sensing | Stock | 0mph | 12mph |
|
||||||
| Honda | CR-V Hybrid 2017-2019 | 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 | Fit 2018-19 | Honda Sensing | openpilot | 25mph<sup>1</sup> | 12mph |
|
||||||
| Honda | HR-V 2019 | 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 | Odyssey 2018-20 | Honda Sensing | openpilot | 25mph<sup>1</sup> | 0mph |
|
||||||
| Honda | Passport 2019 | All | openpilot | 25mph<sup>1</sup> | 12mph |
|
| Honda | Passport 2019 | All | openpilot | 25mph<sup>1</sup> | 12mph |
|
||||||
| Honda | Pilot 2016-18 | Honda Sensing | openpilot | 25mph<sup>1</sup> | 12mph |
|
| Honda | Pilot 2016-19 | Honda Sensing | openpilot | 25mph<sup>1</sup> | 12mph |
|
||||||
| Honda | Pilot 2019 | All | openpilot | 25mph<sup>1</sup> | 12mph |
|
|
||||||
| Honda | Ridgeline 2017-20 | 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 |
|
| 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 2019 | All | openpilot | 0mph | 0mph |
|
||||||
| Lexus | ES Hybrid 2019 | All | openpilot | 0mph | 0mph |
|
| Lexus | ES Hybrid 2019 | All | openpilot | 0mph | 0mph |
|
||||||
| Lexus | IS 2017-2019 | All | Stock | 22mph | 0mph |
|
| Lexus | IS 2017-2019 | All | Stock | 22mph | 0mph |
|
||||||
| Lexus | IS Hybrid 2017 | All | Stock | 0mph | 0mph |
|
| Lexus | IS Hybrid 2017 | All | Stock | 0mph | 0mph |
|
||||||
| Lexus | NX Hybrid 2018 | All | Stock<sup>3</sup>| 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 2020 | All | openpilot | 0mph | 0mph |
|
||||||
| Lexus | RX Hybrid 2016-19 | All | Stock<sup>3</sup>| 0mph | 0mph |
|
| Lexus | RX Hybrid 2016-19 | All | Stock<sup>3</sup>| 0mph | 0mph |
|
||||||
| Lexus | RX Hybrid 2020 | All | openpilot | 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 2016-18 | 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 | Camry 2018-20 | All | Stock | 0mph<sup>4</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 | Camry Hybrid 2018-19 | All | Stock | 0mph<sup>4</sup> | 0mph |
|
||||||
| Toyota | C-HR 2017-19 | All | Stock | 0mph | 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 2017-19 | All | Stock<sup>3</sup>| 20mph<sup>1</sup> | 0mph |
|
||||||
| Toyota | Corolla 2020 | All | openpilot | 0mph | 0mph |
|
| Toyota | Corolla 2020 | All | openpilot | 0mph | 0mph |
|
||||||
| Toyota | Corolla Hatchback 2019-20 | 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 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 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 | Highlander Hybrid 2020 | All | openpilot | 0mph | 0mph |
|
||||||
| Toyota | Prius 2016 | TSS-P | Stock<sup>3</sup>| 0mph | 0mph |
|
| Toyota | Prius 2016-20 | TSS-P | Stock<sup>3</sup>| 0mph | 0mph |
|
||||||
| Toyota | Prius 2017-20 | All | Stock<sup>3</sup>| 0mph | 0mph |
|
|
||||||
| Toyota | Prius Prime 2017-20 | All | 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 2016-18 | 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 2019-20 | All | openpilot | 0mph | 0mph |
|
| Toyota | Rav4 2019-20 | All | openpilot | 0mph | 0mph |
|
||||||
| Toyota | Rav4 Hybrid 2016 | TSS-P | Stock<sup>3</sup>| 0mph | 0mph |
|
| Toyota | Rav4 Hybrid 2016-18 | TSS-P | Stock<sup>3</sup>| 0mph | 0mph |
|
||||||
| Toyota | Rav4 Hybrid 2017-18 | All | Stock<sup>3</sup>| 0mph | 0mph |
|
|
||||||
| Toyota | Rav4 Hybrid 2019-20 | All | openpilot | 0mph | 0mph |
|
| Toyota | Rav4 Hybrid 2019-20 | All | openpilot | 0mph | 0mph |
|
||||||
| Toyota | Sienna 2018-20 | All | Stock<sup>3</sup>| 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 |
|
| Holden | Astra 2017<sup>1</sup> | Adaptive Cruise | openpilot | 0mph | 7mph |
|
||||||
| Hyundai | Elantra 2017-19 | SCC + LKAS | Stock | 19mph | 34mph |
|
| Hyundai | Elantra 2017-19 | SCC + LKAS | Stock | 19mph | 34mph |
|
||||||
| Hyundai | Genesis 2015-16 | SCC + LKAS | Stock | 19mph | 37mph |
|
| Hyundai | Genesis 2015-16 | SCC + LKAS | Stock | 19mph | 37mph |
|
||||||
| Hyundai | Ioniq Electric Premium SE 2020| SCC + LKAS | Stock | 0mph | 32mph |
|
| Hyundai | Ioniq Electric 2019-20 | SCC + LKAS | Stock | 0mph | 32mph |
|
||||||
| Hyundai | Ioniq Electric Limited 2019 | SCC + LKAS | Stock | 0mph | 32mph |
|
|
||||||
| Hyundai | Kona 2020 | SCC + LKAS | Stock | 0mph | 0mph |
|
| Hyundai | Kona 2020 | SCC + LKAS | Stock | 0mph | 0mph |
|
||||||
| Hyundai | Kona EV 2019 | 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 | Santa Fe 2019 | All | Stock | 0mph | 0mph |
|
||||||
| Hyundai | Sonata 2019 | All | Stock | 0mph | 0mph |
|
| Hyundai | Sonata 2019 | All | Stock | 0mph | 0mph |
|
||||||
| Hyundai | Veloster 2019 | SCC + LKAS | Stock | 5mph | 0mph |
|
| Hyundai | Veloster 2019 | SCC + LKAS | Stock | 5mph | 0mph |
|
||||||
| Jeep | Grand Cherokee 2016-18 | Adaptive Cruise | Stock | 0mph | 9mph |
|
| Jeep | Grand Cherokee 2016-18 | Adaptive Cruise | Stock | 0mph | 9mph |
|
||||||
| Jeep | Grand Cherokee 2019-20 | Adaptive Cruise | Stock | 0mph | 39mph |
|
| Jeep | Grand Cherokee 2019-20 | Adaptive Cruise | Stock | 0mph | 39mph |
|
||||||
| Kia | Forte 2018-19 | SCC + LKAS | Stock | 0mph | 0mph |
|
| 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 | Optima 2019 | SCC + LKAS | Stock | 0mph | 0mph |
|
||||||
| Kia | Sorento 2018 | SCC + LKAS | Stock | 0mph | 0mph |
|
| Kia | Sorento 2018 | SCC + LKAS | Stock | 0mph | 0mph |
|
||||||
| Kia | Stinger 2018 | SCC + LKAS | Stock | 0mph | 0mph |
|
| Kia | Stinger 2018 | SCC + LKAS | Stock | 0mph | 0mph |
|
||||||
| Nissan | Leaf 2018-19 | Propilot | Stock | 0mph | 0mph |
|
| Nissan | Leaf 2018-19 | ProPILOT | Stock | 0mph | 0mph |
|
||||||
| Nissan | Rogue 2019 | Propilot | Stock | 0mph | 0mph |
|
| Nissan | Rogue 2019 | ProPILOT | Stock | 0mph | 0mph |
|
||||||
| Nissan | X-Trail 2017 | Propilot | Stock | 0mph | 0mph |
|
| Nissan | X-Trail 2017 | ProPILOT | Stock | 0mph | 0mph |
|
||||||
| Subaru | Ascent 2019 | EyeSight | Stock | 0mph | 0mph |
|
| Subaru | Ascent 2019 | EyeSight | Stock | 0mph | 0mph |
|
||||||
| Subaru | Crosstrek 2018-19 | EyeSight | Stock | 0mph | 0mph |
|
| Subaru | Crosstrek 2018-19 | EyeSight | Stock | 0mph | 0mph |
|
||||||
| Subaru | Forester 2019 | EyeSight | Stock | 0mph | 0mph |
|
| Subaru | Forester 2019 | EyeSight | Stock | 0mph | 0mph |
|
||||||
|
@ -274,8 +268,23 @@ Safety and Testing
|
||||||
|
|
||||||
Testing on PC
|
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
|
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)
|
Version 0.7.8 (2020-08-19)
|
||||||
========================
|
========================
|
||||||
* New driver monitoring model: improved face detection and better compatibility with sunglasses
|
* New driver monitoring model: improved face detection and better compatibility with sunglasses
|
||||||
|
|
71
SConstruct
|
@ -6,6 +6,8 @@ import subprocess
|
||||||
import sys
|
import sys
|
||||||
import platform
|
import platform
|
||||||
|
|
||||||
|
TICI = os.path.isfile('/TICI')
|
||||||
|
|
||||||
AddOption('--test',
|
AddOption('--test',
|
||||||
action='store_true',
|
action='store_true',
|
||||||
help='build test files')
|
help='build test files')
|
||||||
|
@ -18,10 +20,11 @@ AddOption('--asan',
|
||||||
cython_dependencies = [Value(v) for v in (sys.version, distutils.__version__, Cython.__version__)]
|
cython_dependencies = [Value(v) for v in (sys.version, distutils.__version__, Cython.__version__)]
|
||||||
Export('cython_dependencies')
|
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":
|
if platform.system() == "Darwin":
|
||||||
arch = "Darwin"
|
arch = "Darwin"
|
||||||
if arch == "aarch64" and not os.path.isdir("/system"):
|
|
||||||
|
if arch == "aarch64" and TICI:
|
||||||
arch = "larch64"
|
arch = "larch64"
|
||||||
|
|
||||||
webcam = bool(ARGUMENTS.get("use_webcam", 0))
|
webcam = bool(ARGUMENTS.get("use_webcam", 0))
|
||||||
|
@ -44,7 +47,6 @@ if arch == "aarch64" or arch == "larch64":
|
||||||
|
|
||||||
libpath = [
|
libpath = [
|
||||||
"/usr/lib",
|
"/usr/lib",
|
||||||
"/data/data/com.termux/files/usr/lib",
|
|
||||||
"/system/vendor/lib64",
|
"/system/vendor/lib64",
|
||||||
"/system/comma/usr/lib",
|
"/system/comma/usr/lib",
|
||||||
"#phonelibs/nanovg",
|
"#phonelibs/nanovg",
|
||||||
|
@ -62,11 +64,12 @@ if arch == "aarch64" or arch == "larch64":
|
||||||
else:
|
else:
|
||||||
libpath += [
|
libpath += [
|
||||||
"#phonelibs/snpe/aarch64",
|
"#phonelibs/snpe/aarch64",
|
||||||
"#phonelibs/libyuv/lib"
|
"#phonelibs/libyuv/lib",
|
||||||
|
"/system/vendor/lib64"
|
||||||
]
|
]
|
||||||
cflags = ["-DQCOM", "-mcpu=cortex-a57"]
|
cflags = ["-DQCOM", "-mcpu=cortex-a57"]
|
||||||
cxxflags = ["-DQCOM", "-mcpu=cortex-a57"]
|
cxxflags = ["-DQCOM", "-mcpu=cortex-a57"]
|
||||||
rpath = ["/system/vendor/lib64"]
|
rpath = []
|
||||||
|
|
||||||
if QCOM_REPLAY:
|
if QCOM_REPLAY:
|
||||||
cflags += ["-DQCOM_REPLAY"]
|
cflags += ["-DQCOM_REPLAY"]
|
||||||
|
@ -131,8 +134,11 @@ env = Environment(
|
||||||
"-O2",
|
"-O2",
|
||||||
"-Wunused",
|
"-Wunused",
|
||||||
"-Werror",
|
"-Werror",
|
||||||
|
"-Wno-unknown-warning-option",
|
||||||
"-Wno-deprecated-register",
|
"-Wno-deprecated-register",
|
||||||
"-Wno-inconsistent-missing-override",
|
"-Wno-inconsistent-missing-override",
|
||||||
|
"-Wno-c99-designator",
|
||||||
|
"-Wno-reorder-init-list",
|
||||||
] + cflags + ccflags_asan,
|
] + cflags + ccflags_asan,
|
||||||
|
|
||||||
CPPPATH=cpppath + [
|
CPPPATH=cpppath + [
|
||||||
|
@ -143,7 +149,6 @@ env = Environment(
|
||||||
"#phonelibs/openmax/include",
|
"#phonelibs/openmax/include",
|
||||||
"#phonelibs/json11",
|
"#phonelibs/json11",
|
||||||
"#phonelibs/curl/include",
|
"#phonelibs/curl/include",
|
||||||
#"#phonelibs/opencv/include", # use opencv4 instead
|
|
||||||
"#phonelibs/libgralloc/include",
|
"#phonelibs/libgralloc/include",
|
||||||
"#phonelibs/android_frameworks_native/include",
|
"#phonelibs/android_frameworks_native/include",
|
||||||
"#phonelibs/android_hardware_libhardware/include",
|
"#phonelibs/android_hardware_libhardware/include",
|
||||||
|
@ -156,6 +161,8 @@ env = Environment(
|
||||||
"#selfdrive/camerad/include",
|
"#selfdrive/camerad/include",
|
||||||
"#selfdrive/loggerd/include",
|
"#selfdrive/loggerd/include",
|
||||||
"#selfdrive/modeld",
|
"#selfdrive/modeld",
|
||||||
|
"#selfdrive/sensord",
|
||||||
|
"#selfdrive/ui",
|
||||||
"#cereal/messaging",
|
"#cereal/messaging",
|
||||||
"#cereal",
|
"#cereal",
|
||||||
"#opendbc/can",
|
"#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'):
|
if os.environ.get('SCONS_CACHE'):
|
||||||
cache_dir = '/tmp/scons_cache'
|
cache_dir = '/tmp/scons_cache'
|
||||||
|
|
||||||
|
@ -214,7 +259,7 @@ def abspath(x):
|
||||||
|
|
||||||
# still needed for apks
|
# still needed for apks
|
||||||
zmq = 'zmq'
|
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
|
# cereal and messaging are shared with the system
|
||||||
SConscript(['cereal/SConscript'])
|
SConscript(['cereal/SConscript'])
|
||||||
|
@ -255,16 +300,18 @@ SConscript(['selfdrive/controls/lib/longitudinal_mpc_model/SConscript'])
|
||||||
|
|
||||||
SConscript(['selfdrive/boardd/SConscript'])
|
SConscript(['selfdrive/boardd/SConscript'])
|
||||||
SConscript(['selfdrive/proclogd/SConscript'])
|
SConscript(['selfdrive/proclogd/SConscript'])
|
||||||
|
SConscript(['selfdrive/clocksd/SConscript'])
|
||||||
|
|
||||||
SConscript(['selfdrive/ui/SConscript'])
|
|
||||||
SConscript(['selfdrive/loggerd/SConscript'])
|
SConscript(['selfdrive/loggerd/SConscript'])
|
||||||
|
|
||||||
SConscript(['selfdrive/locationd/SConscript'])
|
SConscript(['selfdrive/locationd/SConscript'])
|
||||||
SConscript(['selfdrive/locationd/models/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/logcatd/SConscript'])
|
||||||
SConscript(['selfdrive/sensord/SConscript'])
|
|
||||||
SConscript(['selfdrive/clocksd/SConscript'])
|
|
||||||
else:
|
if arch == "x86_64":
|
||||||
SConscript(['tools/lib/index_log/SConscript'])
|
SConscript(['tools/lib/index_log/SConscript'])
|
||||||
|
|
|
@ -38,7 +38,6 @@ struct CarEvent @0x9b1657f34caf3ad3 {
|
||||||
pedalPressed @13;
|
pedalPressed @13;
|
||||||
cruiseDisabled @14;
|
cruiseDisabled @14;
|
||||||
radarCanError @15;
|
radarCanError @15;
|
||||||
dataNeededDEPRECATED @16;
|
|
||||||
speedTooLow @17;
|
speedTooLow @17;
|
||||||
outOfSpace @18;
|
outOfSpace @18;
|
||||||
overheat @19;
|
overheat @19;
|
||||||
|
@ -49,29 +48,22 @@ struct CarEvent @0x9b1657f34caf3ad3 {
|
||||||
pcmDisable @24;
|
pcmDisable @24;
|
||||||
noTarget @25;
|
noTarget @25;
|
||||||
radarFault @26;
|
radarFault @26;
|
||||||
modelCommIssueDEPRECATED @27;
|
|
||||||
brakeHold @28;
|
brakeHold @28;
|
||||||
parkBrake @29;
|
parkBrake @29;
|
||||||
manualRestart @30;
|
manualRestart @30;
|
||||||
lowSpeedLockout @31;
|
lowSpeedLockout @31;
|
||||||
plannerError @32;
|
plannerError @32;
|
||||||
ipasOverrideDEPRECATED @33;
|
|
||||||
debugAlert @34;
|
debugAlert @34;
|
||||||
steerTempUnavailableMute @35;
|
steerTempUnavailableMute @35;
|
||||||
resumeRequired @36;
|
resumeRequired @36;
|
||||||
preDriverDistracted @37;
|
preDriverDistracted @37;
|
||||||
promptDriverDistracted @38;
|
promptDriverDistracted @38;
|
||||||
driverDistracted @39;
|
driverDistracted @39;
|
||||||
geofenceDEPRECATED @40;
|
|
||||||
driverMonitorOnDEPRECATED @41;
|
|
||||||
driverMonitorOffDEPRECATED @42;
|
|
||||||
preDriverUnresponsive @43;
|
preDriverUnresponsive @43;
|
||||||
promptDriverUnresponsive @44;
|
promptDriverUnresponsive @44;
|
||||||
driverUnresponsive @45;
|
driverUnresponsive @45;
|
||||||
belowSteerSpeed @46;
|
belowSteerSpeed @46;
|
||||||
calibrationProgressDEPRECATED @47;
|
|
||||||
lowBattery @48;
|
lowBattery @48;
|
||||||
invalidGiraffeHondaDEPRECATED @49;
|
|
||||||
vehicleModelInvalid @50;
|
vehicleModelInvalid @50;
|
||||||
controlsFailed @51;
|
controlsFailed @51;
|
||||||
sensorDataInvalid @52;
|
sensorDataInvalid @52;
|
||||||
|
@ -104,8 +96,6 @@ struct CarEvent @0x9b1657f34caf3ad3 {
|
||||||
fcw @79;
|
fcw @79;
|
||||||
steerSaturated @80;
|
steerSaturated @80;
|
||||||
whitePandaUnsupported @81;
|
whitePandaUnsupported @81;
|
||||||
startupWhitePanda @82;
|
|
||||||
canErrorPersistentDEPRECATED @83;
|
|
||||||
belowEngageSpeed @84;
|
belowEngageSpeed @84;
|
||||||
noGps @85;
|
noGps @85;
|
||||||
focusRecoverActive @86;
|
focusRecoverActive @86;
|
||||||
|
@ -113,6 +103,17 @@ struct CarEvent @0x9b1657f34caf3ad3 {
|
||||||
neosUpdateRequired @88;
|
neosUpdateRequired @88;
|
||||||
modeldLagging @89;
|
modeldLagging @89;
|
||||||
deviceFalling @90;
|
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;
|
gyroUncalibrated @12 :SensorVec;
|
||||||
proximity @13: Float32;
|
proximity @13: Float32;
|
||||||
light @14: Float32;
|
light @14: Float32;
|
||||||
|
temperature @15: Float32;
|
||||||
}
|
}
|
||||||
source @8 :SensorSource;
|
source @8 :SensorSource;
|
||||||
|
|
||||||
|
@ -203,6 +204,8 @@ struct SensorEventData {
|
||||||
lsm6ds3 @5; # accelerometer (c2)
|
lsm6ds3 @5; # accelerometer (c2)
|
||||||
bmp280 @6; # barometer (c2)
|
bmp280 @6; # barometer (c2)
|
||||||
mmc3416x @7; # magnetometer (c2)
|
mmc3416x @7; # magnetometer (c2)
|
||||||
|
bmx055 @8;
|
||||||
|
rpr0521 @9;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -267,14 +270,15 @@ struct CanData {
|
||||||
}
|
}
|
||||||
|
|
||||||
struct ThermalData {
|
struct ThermalData {
|
||||||
cpu0 @0 :UInt16;
|
# Deprecated
|
||||||
cpu1 @1 :UInt16;
|
cpu0DEPRECATED @0 :UInt16;
|
||||||
cpu2 @2 :UInt16;
|
cpu1DEPRECATED @1 :UInt16;
|
||||||
cpu3 @3 :UInt16;
|
cpu2DEPRECATED @2 :UInt16;
|
||||||
mem @4 :UInt16;
|
cpu3DEPRECATED @3 :UInt16;
|
||||||
gpu @5 :UInt16;
|
memDEPRECATED @4 :UInt16;
|
||||||
bat @6 :UInt32;
|
gpuDEPRECATED @5 :UInt16;
|
||||||
pa0 @21 :UInt16;
|
batDEPRECATED @6 :UInt32;
|
||||||
|
pa0DEPRECATED @21 :UInt16;
|
||||||
|
|
||||||
# not thermal
|
# not thermal
|
||||||
freeSpace @7 :Float32;
|
freeSpace @7 :Float32;
|
||||||
|
@ -286,6 +290,7 @@ struct ThermalData {
|
||||||
networkType @22 :NetworkType;
|
networkType @22 :NetworkType;
|
||||||
offroadPowerUsage @23 :UInt32; # Power usage since going offroad in uWh
|
offroadPowerUsage @23 :UInt32; # Power usage since going offroad in uWh
|
||||||
networkStrength @24 :NetworkStrength;
|
networkStrength @24 :NetworkStrength;
|
||||||
|
carBatteryCapacity @25 :UInt32; # Estimated remaining car battery capacity in uWh
|
||||||
|
|
||||||
fanSpeed @10 :UInt16;
|
fanSpeed @10 :UInt16;
|
||||||
started @11 :Bool;
|
started @11 :Bool;
|
||||||
|
@ -298,6 +303,12 @@ struct ThermalData {
|
||||||
memUsedPercent @19 :Int8;
|
memUsedPercent @19 :Int8;
|
||||||
cpuPerc @20 :Int8;
|
cpuPerc @20 :Int8;
|
||||||
|
|
||||||
|
cpu @26 :List(Float32);
|
||||||
|
gpu @27 :List(Float32);
|
||||||
|
mem @28 :Float32;
|
||||||
|
bat @29 :Float32;
|
||||||
|
ambient @30 :Float32;
|
||||||
|
|
||||||
enum ThermalStatus {
|
enum ThermalStatus {
|
||||||
green @0; # all processes run
|
green @0; # all processes run
|
||||||
yellow @1; # critical processes run (kill uploader), engage still allowed
|
yellow @1; # critical processes run (kill uploader), engage still allowed
|
||||||
|
@ -373,6 +384,8 @@ struct HealthData {
|
||||||
interruptRateTim3 @17;
|
interruptRateTim3 @17;
|
||||||
registerDivergent @18;
|
registerDivergent @18;
|
||||||
interruptRateKlineInit @19;
|
interruptRateKlineInit @19;
|
||||||
|
interruptRateClockSource @20;
|
||||||
|
interruptRateTim9 @21;
|
||||||
# Update max fault type in boardd when adding faults
|
# Update max fault type in boardd when adding faults
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -602,7 +615,7 @@ struct ControlsState @0x97ff69c53601abf1 {
|
||||||
output @3 :Float32;
|
output @3 :Float32;
|
||||||
lqrOutput @4 :Float32;
|
lqrOutput @4 :Float32;
|
||||||
saturated @5 :Bool;
|
saturated @5 :Bool;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
struct LiveEventData {
|
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 {
|
struct CalibrationFeatures {
|
||||||
frameId @0 :UInt32;
|
frameId @0 :UInt32;
|
||||||
|
|
||||||
|
@ -1906,7 +1965,6 @@ struct DMonitoringState {
|
||||||
isDistracted @2 :Bool;
|
isDistracted @2 :Bool;
|
||||||
awarenessStatus @3 :Float32;
|
awarenessStatus @3 :Float32;
|
||||||
isRHD @4 :Bool;
|
isRHD @4 :Bool;
|
||||||
rhdChecked @5 :Bool;
|
|
||||||
posePitchOffset @6 :Float32;
|
posePitchOffset @6 :Float32;
|
||||||
posePitchValidCount @7 :UInt32;
|
posePitchValidCount @7 :UInt32;
|
||||||
poseYawOffset @8 :Float32;
|
poseYawOffset @8 :Float32;
|
||||||
|
@ -1917,6 +1975,8 @@ struct DMonitoringState {
|
||||||
isLowStd @13 :Bool;
|
isLowStd @13 :Bool;
|
||||||
hiStdCount @14 :UInt32;
|
hiStdCount @14 :UInt32;
|
||||||
isPreview @15 :Bool;
|
isPreview @15 :Bool;
|
||||||
|
|
||||||
|
rhdCheckedDEPRECATED @5 :Bool;
|
||||||
}
|
}
|
||||||
|
|
||||||
struct Boot {
|
struct Boot {
|
||||||
|
@ -2062,5 +2122,7 @@ struct Event {
|
||||||
dMonitoringState @71: DMonitoringState;
|
dMonitoringState @71: DMonitoringState;
|
||||||
liveLocationKalman @72 :LiveLocationKalman;
|
liveLocationKalman @72 :LiveLocationKalman;
|
||||||
sentinel @73 :Sentinel;
|
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
|
from .messaging_pyx import MultiplePublishersError, MessagingError # pylint: disable=no-name-in-module, import-error
|
||||||
import capnp
|
import capnp
|
||||||
|
|
||||||
|
from typing import Optional, List, Union
|
||||||
|
|
||||||
from cereal import log
|
from cereal import log
|
||||||
from cereal.services import service_list
|
from cereal.services import service_list
|
||||||
|
|
||||||
|
@ -19,7 +21,7 @@ except ImportError:
|
||||||
|
|
||||||
context = Context()
|
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 = log.Event.new_message()
|
||||||
dat.logMonoTime = int(sec_since_boot() * 1e9)
|
dat.logMonoTime = int(sec_since_boot() * 1e9)
|
||||||
dat.valid = True
|
dat.valid = True
|
||||||
|
@ -30,15 +32,15 @@ def new_message(service=None, size=None):
|
||||||
dat.init(service, size)
|
dat.init(service, size)
|
||||||
return dat
|
return dat
|
||||||
|
|
||||||
def pub_sock(endpoint):
|
def pub_sock(endpoint: str) -> PubSocket:
|
||||||
sock = PubSocket()
|
sock = PubSocket()
|
||||||
sock.connect(context, endpoint)
|
sock.connect(context, endpoint)
|
||||||
return sock
|
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()
|
sock = SubSocket()
|
||||||
addr = addr.encode('utf8')
|
sock.connect(context, endpoint, addr.encode('utf8'), conflate)
|
||||||
sock.connect(context, endpoint, addr, conflate)
|
|
||||||
|
|
||||||
if timeout is not None:
|
if timeout is not None:
|
||||||
sock.setTimeout(timeout)
|
sock.setTimeout(timeout)
|
||||||
|
@ -48,9 +50,9 @@ def sub_sock(endpoint, poller=None, addr="127.0.0.1", conflate=False, timeout=No
|
||||||
return sock
|
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"""
|
"""Receive all message currently available on the queue"""
|
||||||
ret = []
|
ret: List[bytes] = []
|
||||||
while 1:
|
while 1:
|
||||||
if wait_for_one and len(ret) == 0:
|
if wait_for_one and len(ret) == 0:
|
||||||
dat = sock.receive()
|
dat = sock.receive()
|
||||||
|
@ -64,9 +66,9 @@ def drain_sock_raw(sock, wait_for_one=False):
|
||||||
|
|
||||||
return ret
|
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"""
|
"""Receive all message currently available on the queue"""
|
||||||
ret = []
|
ret: List[capnp.lib.capnp._DynamicStructReader] = []
|
||||||
while 1:
|
while 1:
|
||||||
if wait_for_one and len(ret) == 0:
|
if wait_for_one and len(ret) == 0:
|
||||||
dat = sock.receive()
|
dat = sock.receive()
|
||||||
|
@ -83,7 +85,7 @@ def drain_sock(sock, wait_for_one=False):
|
||||||
|
|
||||||
|
|
||||||
# TODO: print when we drop packets?
|
# 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."""
|
"""Same as drain sock, but only returns latest message. Consider using conflate instead."""
|
||||||
dat = None
|
dat = None
|
||||||
|
|
||||||
|
@ -103,19 +105,19 @@ def recv_sock(sock, wait=False):
|
||||||
|
|
||||||
return dat
|
return dat
|
||||||
|
|
||||||
def recv_one(sock):
|
def recv_one(sock: SubSocket) -> Union[None, capnp.lib.capnp._DynamicStructReader]:
|
||||||
dat = sock.receive()
|
dat = sock.receive()
|
||||||
if dat is not None:
|
if dat is not None:
|
||||||
dat = log.Event.from_bytes(dat)
|
dat = log.Event.from_bytes(dat)
|
||||||
return 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)
|
dat = sock.receive(non_blocking=True)
|
||||||
if dat is not None:
|
if dat is not None:
|
||||||
dat = log.Event.from_bytes(dat)
|
dat = log.Event.from_bytes(dat)
|
||||||
return 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"""
|
"""Keep receiving until we get a message"""
|
||||||
while True:
|
while True:
|
||||||
dat = sock.receive()
|
dat = sock.receive()
|
||||||
|
@ -123,8 +125,8 @@ def recv_one_retry(sock):
|
||||||
return log.Event.from_bytes(dat)
|
return log.Event.from_bytes(dat)
|
||||||
|
|
||||||
class SubMaster():
|
class SubMaster():
|
||||||
def __init__(self, services, ignore_alive=None, addr="127.0.0.1"):
|
def __init__(self, services: List[str], poll: Optional[List[str]] = None,
|
||||||
self.poller = Poller()
|
ignore_alive: Optional[List[str]] = None, addr:str ="127.0.0.1"):
|
||||||
self.frame = -1
|
self.frame = -1
|
||||||
self.updated = {s: False for s in services}
|
self.updated = {s: False for s in services}
|
||||||
self.rcv_time = {s: 0. for s in services}
|
self.rcv_time = {s: 0. for s in services}
|
||||||
|
@ -133,8 +135,12 @@ class SubMaster():
|
||||||
self.sock = {}
|
self.sock = {}
|
||||||
self.freq = {}
|
self.freq = {}
|
||||||
self.data = {}
|
self.data = {}
|
||||||
self.logMonoTime = {}
|
|
||||||
self.valid = {}
|
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:
|
if ignore_alive is not None:
|
||||||
self.ignore_alive = ignore_alive
|
self.ignore_alive = ignore_alive
|
||||||
|
@ -143,30 +149,33 @@ class SubMaster():
|
||||||
|
|
||||||
for s in services:
|
for s in services:
|
||||||
if addr is not None:
|
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
|
self.freq[s] = service_list[s].frequency
|
||||||
|
|
||||||
try:
|
try:
|
||||||
data = new_message(s)
|
data = new_message(s)
|
||||||
except capnp.lib.capnp.KjException: # pylint: disable=c-extension-no-member
|
except capnp.lib.capnp.KjException: # pylint: disable=c-extension-no-member
|
||||||
# lists
|
data = new_message(s, 0) # lists
|
||||||
data = new_message(s, 0)
|
|
||||||
|
|
||||||
self.data[s] = getattr(data, s)
|
self.data[s] = getattr(data, s)
|
||||||
self.logMonoTime[s] = 0
|
self.logMonoTime[s] = 0
|
||||||
self.valid[s] = data.valid
|
self.valid[s] = data.valid
|
||||||
|
|
||||||
def __getitem__(self, s):
|
def __getitem__(self, s: str) -> capnp.lib.capnp._DynamicStructReader:
|
||||||
return self.data[s]
|
return self.data[s]
|
||||||
|
|
||||||
def update(self, timeout=1000):
|
def update(self, timeout: int = 1000) -> None:
|
||||||
msgs = []
|
msgs = []
|
||||||
for sock in self.poller.poll(timeout):
|
for sock in self.poller.poll(timeout):
|
||||||
msgs.append(recv_one_or_none(sock))
|
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)
|
self.update_msgs(sec_since_boot(), msgs)
|
||||||
|
|
||||||
def update_msgs(self, cur_time, msgs):
|
def update_msgs(self, cur_time: float, msgs: List[capnp.lib.capnp._DynamicStructReader]) -> None:
|
||||||
# TODO: add optional input that specify the service to wait for
|
|
||||||
self.frame += 1
|
self.frame += 1
|
||||||
self.updated = dict.fromkeys(self.updated, False)
|
self.updated = dict.fromkeys(self.updated, False)
|
||||||
for msg in msgs:
|
for msg in msgs:
|
||||||
|
@ -189,30 +198,28 @@ class SubMaster():
|
||||||
else:
|
else:
|
||||||
self.alive[s] = True
|
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
|
if service_list is None: # check all
|
||||||
service_list = self.alive.keys()
|
service_list = self.alive.keys()
|
||||||
return all(self.alive[s] for s in service_list if s not in self.ignore_alive)
|
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
|
if service_list is None: # check all
|
||||||
service_list = self.valid.keys()
|
service_list = self.valid.keys()
|
||||||
return all(self.valid[s] for s in service_list)
|
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
|
if service_list is None: # check all
|
||||||
service_list = self.alive.keys()
|
service_list = self.alive.keys()
|
||||||
return self.all_alive(service_list=service_list) and self.all_valid(service_list=service_list)
|
return self.all_alive(service_list=service_list) and self.all_valid(service_list=service_list)
|
||||||
|
|
||||||
|
|
||||||
class PubMaster():
|
class PubMaster():
|
||||||
def __init__(self, services):
|
def __init__(self, services: List[str]):
|
||||||
self.sock = {}
|
self.sock = {}
|
||||||
for s in services:
|
for s in services:
|
||||||
self.sock[s] = pub_sock(s)
|
self.sock[s] = pub_sock(s)
|
||||||
|
|
||||||
def send(self, s, dat):
|
def send(self, s: str, dat: Union[bytes, capnp.lib.capnp._DynamicStructBuilder]) -> None:
|
||||||
# accept either bytes or capnp builder
|
|
||||||
if not isinstance(dat, bytes):
|
if not isinstance(dat, bytes):
|
||||||
dat = dat.to_bytes()
|
dat = dat.to_bytes()
|
||||||
self.sock[s].send(dat)
|
self.sock[s].send(dat)
|
||||||
|
|
|
@ -15,6 +15,18 @@ void sig_handler(int signal) {
|
||||||
msgq_do_exit = 1;
|
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() {
|
MSGQContext::MSGQContext() {
|
||||||
}
|
}
|
||||||
|
@ -49,13 +61,12 @@ MSGQMessage::~MSGQMessage() {
|
||||||
this->close();
|
this->close();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
int MSGQSubSocket::connect(Context *context, std::string endpoint, std::string address, bool conflate){
|
int MSGQSubSocket::connect(Context *context, std::string endpoint, std::string address, bool conflate){
|
||||||
assert(context);
|
assert(context);
|
||||||
assert(address == "127.0.0.1");
|
assert(address == "127.0.0.1");
|
||||||
|
|
||||||
q = new msgq_queue_t;
|
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){
|
if (r != 0){
|
||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
|
@ -143,7 +154,7 @@ int MSGQPubSocket::connect(Context *context, std::string endpoint){
|
||||||
assert(context);
|
assert(context);
|
||||||
|
|
||||||
q = new msgq_queue_t;
|
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){
|
if (r != 0){
|
||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
|
|
|
@ -6,6 +6,10 @@
|
||||||
#include <capnp/serialize.h>
|
#include <capnp/serialize.h>
|
||||||
#include "../gen/cpp/log.capnp.h"
|
#include "../gen/cpp/log.capnp.h"
|
||||||
|
|
||||||
|
#ifdef __APPLE__
|
||||||
|
#define CLOCK_BOOTTIME CLOCK_MONOTONIC
|
||||||
|
#endif
|
||||||
|
|
||||||
#define MSG_MULTIPLE_PUBLISHERS 100
|
#define MSG_MULTIPLE_PUBLISHERS 100
|
||||||
|
|
||||||
class Context {
|
class Context {
|
||||||
|
@ -82,11 +86,34 @@ private:
|
||||||
std::map<std::string, SubMessage *> services_;
|
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 {
|
class PubMaster {
|
||||||
public:
|
public:
|
||||||
PubMaster(const std::initializer_list<const char *> &service_list);
|
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); }
|
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();
|
~PubMaster();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
|
@ -6,6 +6,7 @@ from distutils.core import Extension, setup # pylint: disable=import-error,no-n
|
||||||
from Cython.Build import cythonize
|
from Cython.Build import cythonize
|
||||||
from Cython.Distutils import build_ext
|
from Cython.Distutils import build_ext
|
||||||
|
|
||||||
|
TICI = os.path.isfile('/TICI')
|
||||||
|
|
||||||
def get_ext_filename_without_platform_suffix(filename):
|
def get_ext_filename_without_platform_suffix(filename):
|
||||||
name, ext = os.path.splitext(filename)
|
name, ext = os.path.splitext(filename)
|
||||||
|
@ -30,11 +31,11 @@ class BuildExtWithoutPlatformSuffix(build_ext):
|
||||||
|
|
||||||
|
|
||||||
sourcefiles = ['messaging_pyx.pyx']
|
sourcefiles = ['messaging_pyx.pyx']
|
||||||
extra_compile_args = ["-std=c++14"]
|
extra_compile_args = ["-std=c++14", "-Wno-nullability-completeness"]
|
||||||
libraries = ['zmq']
|
libraries = ['zmq']
|
||||||
ARCH = subprocess.check_output(["uname", "-m"], encoding='utf8').rstrip() # pylint: disable=unexpected-keyword-arg
|
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
|
# android
|
||||||
extra_compile_args += ["-Wno-deprecated-register"]
|
extra_compile_args += ["-Wno-deprecated-register"]
|
||||||
libraries += ['gnustl_shared']
|
libraries += ['gnustl_shared']
|
||||||
|
|
|
@ -21,6 +21,8 @@
|
||||||
|
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
|
||||||
|
#include "services.h"
|
||||||
|
|
||||||
#include "msgq.hpp"
|
#include "msgq.hpp"
|
||||||
|
|
||||||
void sigusr2_handler(int signal) {
|
void sigusr2_handler(int signal) {
|
||||||
|
@ -81,11 +83,20 @@ void msgq_wait_for_subscriber(msgq_queue_t *q){
|
||||||
return;
|
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){
|
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
|
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);
|
std::signal(SIGUSR2, sigusr2_handler);
|
||||||
|
|
||||||
const char * prefix = "/dev/shm/";
|
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;
|
delete[] full_path;
|
||||||
|
|
||||||
int rc = ftruncate(fd, size + sizeof(msgq_header_t));
|
int rc = ftruncate(fd, size + sizeof(msgq_header_t));
|
||||||
if (rc < 0)
|
if (rc < 0){
|
||||||
return -1;
|
return -1;
|
||||||
|
}
|
||||||
char * mem = (char*)mmap(NULL, size + sizeof(msgq_header_t), PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
|
char * mem = (char*)mmap(NULL, size + sizeof(msgq_header_t), PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
|
||||||
close(fd);
|
close(fd);
|
||||||
|
|
||||||
if (mem == NULL)
|
if (mem == NULL){
|
||||||
return -1;
|
return -1;
|
||||||
|
}
|
||||||
q->mmap_p = mem;
|
q->mmap_p = mem;
|
||||||
|
|
||||||
msgq_header_t *header = (msgq_header_t *)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){
|
int msgq_poll(msgq_pollitem_t * items, size_t nitems, int timeout){
|
||||||
assert(timeout >= 0);
|
|
||||||
|
|
||||||
int num = 0;
|
int num = 0;
|
||||||
|
|
||||||
// Check if messages ready
|
// Check if messages ready
|
||||||
|
|
|
@ -3,10 +3,6 @@
|
||||||
#include "messaging.hpp"
|
#include "messaging.hpp"
|
||||||
#include "services.h"
|
#include "services.h"
|
||||||
|
|
||||||
#ifdef __APPLE__
|
|
||||||
#define CLOCK_BOOTTIME CLOCK_MONOTONIC
|
|
||||||
#endif
|
|
||||||
|
|
||||||
static inline uint64_t nanos_since_boot() {
|
static inline uint64_t nanos_since_boot() {
|
||||||
struct timespec t;
|
struct timespec t;
|
||||||
clock_gettime(CLOCK_BOOTTIME, &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) {
|
int PubMaster::send(const char *name, MessageBuilder &msg) {
|
||||||
auto words = capnp::messageToFlatArray(msg);
|
auto bytes = msg.toBytes();
|
||||||
auto bytes = words.asBytes();
|
|
||||||
return send(name, bytes.begin(), bytes.size());
|
return send(name, bytes.begin(), bytes.size());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -78,6 +78,8 @@ frontFrame: [8072, true, 10.]
|
||||||
dMonitoringState: [8073, true, 5., 1]
|
dMonitoringState: [8073, true, 5., 1]
|
||||||
offroadLayout: [8074, false, 0.]
|
offroadLayout: [8074, false, 0.]
|
||||||
wideEncodeIdx: [8075, true, 20.]
|
wideEncodeIdx: [8075, true, 20.]
|
||||||
|
wideFrame: [8076, true, 20.]
|
||||||
|
modelV2: [8077, true, 20., 20]
|
||||||
|
|
||||||
testModel: [8040, false, 0.]
|
testModel: [8040, false, 0.]
|
||||||
testLiveLocation: [8045, 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
|
import os
|
||||||
BASEDIR = os.path.abspath(os.path.join(os.path.dirname(os.path.realpath(__file__)), "../"))
|
BASEDIR = os.path.abspath(os.path.join(os.path.dirname(os.path.realpath(__file__)), "../"))
|
||||||
|
|
||||||
from common.android import ANDROID
|
from common.hardware import PC
|
||||||
if ANDROID:
|
if PC:
|
||||||
PERSIST = "/persist"
|
|
||||||
PARAMS = "/data/params"
|
|
||||||
else:
|
|
||||||
PERSIST = os.path.join(BASEDIR, "persist")
|
PERSIST = os.path.join(BASEDIR, "persist")
|
||||||
PARAMS = os.path.join(BASEDIR, "persist", "params")
|
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],
|
"AccessToken": [TxType.CLEAR_ON_MANAGER_START],
|
||||||
"AthenadPid": [TxType.PERSISTENT],
|
"AthenadPid": [TxType.PERSISTENT],
|
||||||
"CalibrationParams": [TxType.PERSISTENT],
|
"CalibrationParams": [TxType.PERSISTENT],
|
||||||
|
"CarBatteryCapacity": [TxType.PERSISTENT],
|
||||||
"CarParams": [TxType.CLEAR_ON_MANAGER_START, TxType.CLEAR_ON_PANDA_DISCONNECT],
|
"CarParams": [TxType.CLEAR_ON_MANAGER_START, TxType.CLEAR_ON_PANDA_DISCONNECT],
|
||||||
"CarParamsCache": [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],
|
"CarVin": [TxType.CLEAR_ON_MANAGER_START, TxType.CLEAR_ON_PANDA_DISCONNECT],
|
||||||
"CommunityFeaturesToggle": [TxType.PERSISTENT],
|
"CommunityFeaturesToggle": [TxType.PERSISTENT],
|
||||||
"CompletedTrainingVersion": [TxType.PERSISTENT],
|
"CompletedTrainingVersion": [TxType.PERSISTENT],
|
||||||
"ControlsParams": [TxType.PERSISTENT],
|
|
||||||
"DisablePowerDown": [TxType.PERSISTENT],
|
"DisablePowerDown": [TxType.PERSISTENT],
|
||||||
"DisableUpdates": [TxType.PERSISTENT],
|
"DisableUpdates": [TxType.PERSISTENT],
|
||||||
"DoUninstall": [TxType.CLEAR_ON_MANAGER_START],
|
"DoUninstall": [TxType.CLEAR_ON_MANAGER_START],
|
||||||
|
@ -71,7 +71,6 @@ keys = {
|
||||||
"HasCompletedSetup": [TxType.PERSISTENT],
|
"HasCompletedSetup": [TxType.PERSISTENT],
|
||||||
"IsDriverViewEnabled": [TxType.CLEAR_ON_MANAGER_START],
|
"IsDriverViewEnabled": [TxType.CLEAR_ON_MANAGER_START],
|
||||||
"IsLdwEnabled": [TxType.PERSISTENT],
|
"IsLdwEnabled": [TxType.PERSISTENT],
|
||||||
"IsGeofenceEnabled": [TxType.PERSISTENT],
|
|
||||||
"IsMetric": [TxType.PERSISTENT],
|
"IsMetric": [TxType.PERSISTENT],
|
||||||
"IsOffroad": [TxType.CLEAR_ON_MANAGER_START],
|
"IsOffroad": [TxType.CLEAR_ON_MANAGER_START],
|
||||||
"IsRHD": [TxType.PERSISTENT],
|
"IsRHD": [TxType.PERSISTENT],
|
||||||
|
@ -81,10 +80,7 @@ keys = {
|
||||||
"LastAthenaPingTime": [TxType.PERSISTENT],
|
"LastAthenaPingTime": [TxType.PERSISTENT],
|
||||||
"LastUpdateTime": [TxType.PERSISTENT],
|
"LastUpdateTime": [TxType.PERSISTENT],
|
||||||
"LastUpdateException": [TxType.PERSISTENT],
|
"LastUpdateException": [TxType.PERSISTENT],
|
||||||
"LimitSetSpeed": [TxType.PERSISTENT],
|
|
||||||
"LimitSetSpeedNeural": [TxType.PERSISTENT],
|
|
||||||
"LiveParameters": [TxType.PERSISTENT],
|
"LiveParameters": [TxType.PERSISTENT],
|
||||||
"LongitudinalControl": [TxType.PERSISTENT],
|
|
||||||
"OpenpilotEnabledToggle": [TxType.PERSISTENT],
|
"OpenpilotEnabledToggle": [TxType.PERSISTENT],
|
||||||
"LaneChangeEnabled": [TxType.PERSISTENT],
|
"LaneChangeEnabled": [TxType.PERSISTENT],
|
||||||
"PandaFirmware": [TxType.CLEAR_ON_MANAGER_START, TxType.CLEAR_ON_PANDA_DISCONNECT],
|
"PandaFirmware": [TxType.CLEAR_ON_MANAGER_START, TxType.CLEAR_ON_PANDA_DISCONNECT],
|
||||||
|
@ -94,7 +90,6 @@ keys = {
|
||||||
"RecordFront": [TxType.PERSISTENT],
|
"RecordFront": [TxType.PERSISTENT],
|
||||||
"ReleaseNotes": [TxType.PERSISTENT],
|
"ReleaseNotes": [TxType.PERSISTENT],
|
||||||
"ShouldDoUpdate": [TxType.CLEAR_ON_MANAGER_START],
|
"ShouldDoUpdate": [TxType.CLEAR_ON_MANAGER_START],
|
||||||
"SpeedLimitOffset": [TxType.PERSISTENT],
|
|
||||||
"SubscriberInfo": [TxType.PERSISTENT],
|
"SubscriberInfo": [TxType.PERSISTENT],
|
||||||
"TermsVersion": [TxType.PERSISTENT],
|
"TermsVersion": [TxType.PERSISTENT],
|
||||||
"TrainingVersion": [TxType.PERSISTENT],
|
"TrainingVersion": [TxType.PERSISTENT],
|
||||||
|
@ -122,14 +117,15 @@ def fsync_dir(path):
|
||||||
|
|
||||||
|
|
||||||
class FileLock():
|
class FileLock():
|
||||||
def __init__(self, path, create):
|
def __init__(self, path, create, lock_ex):
|
||||||
self._path = path
|
self._path = path
|
||||||
self._create = create
|
self._create = create
|
||||||
self._fd = None
|
self._fd = None
|
||||||
|
self._lock_ex = lock_ex
|
||||||
|
|
||||||
def acquire(self):
|
def acquire(self):
|
||||||
self._fd = os.open(self._path, os.O_CREAT if self._create else 0)
|
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):
|
def release(self):
|
||||||
if self._fd is not None:
|
if self._fd is not None:
|
||||||
|
@ -157,8 +153,8 @@ class DBAccessor():
|
||||||
except KeyError:
|
except KeyError:
|
||||||
return None
|
return None
|
||||||
|
|
||||||
def _get_lock(self, create):
|
def _get_lock(self, create, lock_ex):
|
||||||
lock = FileLock(os.path.join(self._path, ".lock"), create)
|
lock = FileLock(os.path.join(self._path, ".lock"), create, lock_ex)
|
||||||
lock.acquire()
|
lock.acquire()
|
||||||
return lock
|
return lock
|
||||||
|
|
||||||
|
@ -190,7 +186,7 @@ class DBAccessor():
|
||||||
class DBReader(DBAccessor):
|
class DBReader(DBAccessor):
|
||||||
def __enter__(self):
|
def __enter__(self):
|
||||||
try:
|
try:
|
||||||
lock = self._get_lock(False)
|
lock = self._get_lock(False, False)
|
||||||
except OSError as e:
|
except OSError as e:
|
||||||
# Do not create lock if it does not exist.
|
# Do not create lock if it does not exist.
|
||||||
if e.errno == errno.ENOENT:
|
if e.errno == errno.ENOENT:
|
||||||
|
@ -228,7 +224,7 @@ class DBWriter(DBAccessor):
|
||||||
|
|
||||||
try:
|
try:
|
||||||
os.chmod(self._path, 0o777)
|
os.chmod(self._path, 0o777)
|
||||||
self._lock = self._get_lock(True)
|
self._lock = self._get_lock(True, True)
|
||||||
self._vals = self._read_values_locked()
|
self._vals = self._read_values_locked()
|
||||||
except Exception:
|
except Exception:
|
||||||
os.umask(self._prev_umask)
|
os.umask(self._prev_umask)
|
||||||
|
@ -317,7 +313,7 @@ def write_db(params_path, key, value):
|
||||||
value = value.encode('utf8')
|
value = value.encode('utf8')
|
||||||
|
|
||||||
prev_umask = os.umask(0)
|
prev_umask = os.umask(0)
|
||||||
lock = FileLock(params_path + "/.lock", True)
|
lock = FileLock(params_path + "/.lock", True, True)
|
||||||
lock.acquire()
|
lock.acquire()
|
||||||
|
|
||||||
try:
|
try:
|
||||||
|
|
|
@ -1,12 +1,10 @@
|
||||||
"""Utilities for reading real time clocks and keeping soft real time constraints."""
|
"""Utilities for reading real time clocks and keeping soft real time constraints."""
|
||||||
|
import gc
|
||||||
import os
|
import os
|
||||||
import time
|
import time
|
||||||
import platform
|
|
||||||
import subprocess
|
|
||||||
import multiprocessing
|
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
|
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
|
DT_TRML = 0.5 # thermald and manager
|
||||||
|
|
||||||
|
|
||||||
ffi = FFI()
|
class Priority:
|
||||||
ffi.cdef("long syscall(long number, ...);")
|
MIN_REALTIME = 52 # highest android process priority is 51
|
||||||
libc = ffi.dlopen(None)
|
CTRL_LOW = MIN_REALTIME
|
||||||
|
CTRL_HIGH = MIN_REALTIME + 1
|
||||||
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)
|
|
||||||
|
|
||||||
|
|
||||||
def set_realtime_priority(level):
|
def set_realtime_priority(level):
|
||||||
if os.getuid() != 0:
|
if not PC:
|
||||||
print("not setting priority, not root")
|
os.sched_setscheduler(0, os.SCHED_FIFO, os.sched_param(level))
|
||||||
return
|
|
||||||
|
|
||||||
return subprocess.call(['chrt', '-f', '-p', str(level), str(_get_tid())])
|
|
||||||
|
|
||||||
def set_core_affinity(core):
|
def set_core_affinity(core):
|
||||||
if os.getuid() != 0:
|
if not PC:
|
||||||
print("not setting affinity, not root")
|
os.sched_setaffinity(0, [core,])
|
||||||
return
|
|
||||||
|
|
||||||
if ANDROID:
|
|
||||||
return subprocess.call(['taskset', '-p', str(core), str(_get_tid())])
|
def config_rt_process(core, priority):
|
||||||
else:
|
gc.disable()
|
||||||
return -1
|
set_realtime_priority(priority)
|
||||||
|
set_core_affinity(core)
|
||||||
|
|
||||||
|
|
||||||
class Ratekeeper():
|
class Ratekeeper():
|
||||||
|
|
|
@ -5,7 +5,7 @@ import subprocess
|
||||||
from common.basedir import BASEDIR
|
from common.basedir import BASEDIR
|
||||||
|
|
||||||
|
|
||||||
class TextWindow():
|
class TextWindow:
|
||||||
def __init__(self, s, noop=False):
|
def __init__(self, s, noop=False):
|
||||||
# text window is only implemented for android currently
|
# text window is only implemented for android currently
|
||||||
self.text_proc = None
|
self.text_proc = None
|
||||||
|
|
|
@ -8,6 +8,60 @@ source "$BASEDIR/launch_env.sh"
|
||||||
|
|
||||||
DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null && pwd )"
|
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 {
|
function launch {
|
||||||
# Wifi scan
|
# Wifi scan
|
||||||
wpa_cli IFNAME=wlan0 SCAN
|
wpa_cli IFNAME=wlan0 SCAN
|
||||||
|
@ -54,56 +108,9 @@ function launch {
|
||||||
fi
|
fi
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# Android and other system processes are not permitted to run on CPU 3
|
# comma two init
|
||||||
# NEOS installed app processes can run anywhere
|
if [ -f /EON ]; then
|
||||||
echo 0-2 > /dev/cpuset/background/cpus
|
two_init
|
||||||
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
|
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# handle pythonpath
|
# handle pythonpath
|
||||||
|
|
|
@ -34,7 +34,7 @@ class BuildExtWithoutPlatformSuffix(build_ext):
|
||||||
return get_ext_filename_without_platform_suffix(filename)
|
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
|
ARCH = subprocess.check_output(["uname", "-m"], encoding='utf8').rstrip() # pylint: disable=unexpected-keyword-arg
|
||||||
if ARCH == "aarch64":
|
if ARCH == "aarch64":
|
||||||
extra_compile_args += ["-Wno-deprecated-register"]
|
extra_compile_args += ["-Wno-deprecated-register"]
|
||||||
|
|
|
@ -20,9 +20,11 @@ cdef class CANPacker:
|
||||||
map[int, int] address_to_size
|
map[int, int] address_to_size
|
||||||
|
|
||||||
def __init__(self, dbc_name):
|
def __init__(self, dbc_name):
|
||||||
self.packer = new cpp_CANPacker(dbc_name)
|
|
||||||
self.dbc = dbc_lookup(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
|
num_msgs = self.dbc[0].num_msgs
|
||||||
for i in range(num_msgs):
|
for i in range(num_msgs):
|
||||||
msg = self.dbc[0].msgs[i]
|
msg = self.dbc[0].msgs[i]
|
||||||
|
@ -37,7 +39,7 @@ cdef class CANPacker:
|
||||||
|
|
||||||
for name, value in values.iteritems():
|
for name, value in values.iteritems():
|
||||||
n = name.encode('utf8')
|
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.name = n
|
||||||
spv.value = value
|
spv.value = value
|
||||||
|
|
|
@ -187,7 +187,7 @@ void CANParser::UpdateCans(uint64_t sec, const capnp::List<cereal::CanData>::Rea
|
||||||
continue;
|
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};
|
uint8_t dat[8] = {0};
|
||||||
memcpy(dat, cmsg.getDat().begin(), cmsg.getDat().size());
|
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
|
from opendbc.can.parser_pyx import CANParser, CANDefine # pylint: disable=no-name-in-module, import-error
|
||||||
assert CANParser
|
assert CANParser, CANDefine
|
||||||
|
|
|
@ -17,7 +17,6 @@ from collections import defaultdict
|
||||||
|
|
||||||
cdef int CAN_INVALID_CNT = 5
|
cdef int CAN_INVALID_CNT = 5
|
||||||
|
|
||||||
|
|
||||||
cdef class CANParser:
|
cdef class CANParser:
|
||||||
cdef:
|
cdef:
|
||||||
cpp_CANParser *can
|
cpp_CANParser *can
|
||||||
|
@ -37,10 +36,11 @@ cdef class CANParser:
|
||||||
def __init__(self, dbc_name, signals, checks=None, bus=0):
|
def __init__(self, dbc_name, signals, checks=None, bus=0):
|
||||||
if checks is None:
|
if checks is None:
|
||||||
checks = []
|
checks = []
|
||||||
|
|
||||||
self.can_valid = True
|
self.can_valid = True
|
||||||
self.dbc_name = dbc_name
|
self.dbc_name = dbc_name
|
||||||
self.dbc = dbc_lookup(dbc_name)
|
self.dbc = dbc_lookup(dbc_name)
|
||||||
|
if not self.dbc:
|
||||||
|
raise RuntimeError("Can't lookup" + dbc_name)
|
||||||
self.vl = {}
|
self.vl = {}
|
||||||
self.ts = {}
|
self.ts = {}
|
||||||
|
|
||||||
|
@ -110,7 +110,7 @@ cdef class CANParser:
|
||||||
|
|
||||||
|
|
||||||
for cv in can_values:
|
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()
|
name = <unicode>self.address_to_msg_name[cv.address].c_str()
|
||||||
cv_name = <unicode>cv.name
|
cv_name = <unicode>cv.name
|
||||||
|
|
||||||
|
@ -148,7 +148,9 @@ cdef class CANDefine():
|
||||||
def __init__(self, dbc_name):
|
def __init__(self, dbc_name):
|
||||||
self.dbc_name = dbc_name
|
self.dbc_name = dbc_name
|
||||||
self.dbc = dbc_lookup(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
|
num_vals = self.dbc[0].num_vals
|
||||||
|
|
||||||
address_to_msg_name = {}
|
address_to_msg_name = {}
|
||||||
|
|
|
@ -81,7 +81,7 @@ def process(in_fn, out_fn):
|
||||||
if sig.start_bit % 8 != checksum_start_bit:
|
if sig.start_bit % 8 != checksum_start_bit:
|
||||||
sys.exit("%s: CHECKSUM starts at wrong bit" % dbc_msg_name)
|
sys.exit("%s: CHECKSUM starts at wrong bit" % dbc_msg_name)
|
||||||
if little_endian != sig.is_little_endian:
|
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
|
# counter rules
|
||||||
if sig.name == "COUNTER":
|
if sig.name == "COUNTER":
|
||||||
if counter_size is not None and sig.size != counter_size:
|
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)
|
print(counter_start_bit, sig.start_bit)
|
||||||
sys.exit("%s: COUNTER starts at wrong bit" % dbc_msg_name)
|
sys.exit("%s: COUNTER starts at wrong bit" % dbc_msg_name)
|
||||||
if little_endian != sig.is_little_endian:
|
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
|
# pedal rules
|
||||||
if address in [0x200, 0x201]:
|
if address in [0x200, 0x201]:
|
||||||
if sig.name == "COUNTER_PEDAL" and sig.size != 4:
|
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_ 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_ 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_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_ 308 ACCEL_134 "only set when human presses accel pedal";
|
||||||
CM_ SG_ 532 NOISY_SLOWLY_DECREASING "perhaps battery but do not know";
|
CM_ SG_ 532 NOISY_SLOWLY_DECREASING "perhaps battery but do not know";
|
||||||
CM_ SG_ 816 TRACTION_OFF "set when traction off button is enabled";
|
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_ RangeMode 1 "Active" 0 "Inactive" ;
|
||||||
VAL_TABLE_ TrkConf 3 "Confident" 2 "Speculative" 1 "Highly speculative" 0 "Invalid" ;
|
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_ 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_ FrntVsnInPthVehBrkNwSt 10 "Active" 5 "Inactive" ;
|
||||||
VAL_TABLE_ FrntVsnClostPedBrkNwSt 10 "Active" 5 "Inactive" ;
|
VAL_TABLE_ FrntVsnClostPedBrkNwSt 10 "Active" 5 "Inactive" ;
|
||||||
VAL_TABLE_ LaneSnsLLnPosValid 1 "Invalid" 0 "Valid" ;
|
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_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_ 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_ 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_ 467 LOW_SPEED_LOCKOUT "in low speed lockout, system would always disengage below 28mph";
|
||||||
CM_ SG_ 560 BRAKE_PRESSED "another brake pressed?";
|
CM_ SG_ 560 BRAKE_PRESSED "another brake pressed?";
|
||||||
CM_ SG_ 608 STEER_TORQUE_DRIVER "driver torque";
|
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_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_ 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_ 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_ 467 LOW_SPEED_LOCKOUT "in low speed lockout, system would always disengage below 28mph";
|
||||||
CM_ SG_ 560 BRAKE_PRESSED "another brake pressed?";
|
CM_ SG_ 560 BRAKE_PRESSED "another brake pressed?";
|
||||||
CM_ SG_ 608 STEER_TORQUE_DRIVER "driver torque";
|
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_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_ 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_ 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_ 467 LOW_SPEED_LOCKOUT "in low speed lockout, system would always disengage below 28mph";
|
||||||
CM_ SG_ 560 BRAKE_PRESSED "another brake pressed?";
|
CM_ SG_ 560 BRAKE_PRESSED "another brake pressed?";
|
||||||
CM_ SG_ 608 STEER_TORQUE_DRIVER "driver torque";
|
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_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_ 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_ 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_ 467 LOW_SPEED_LOCKOUT "in low speed lockout, system would always disengage below 28mph";
|
||||||
CM_ SG_ 560 BRAKE_PRESSED "another brake pressed?";
|
CM_ SG_ 560 BRAKE_PRESSED "another brake pressed?";
|
||||||
CM_ SG_ 608 STEER_TORQUE_DRIVER "driver torque";
|
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_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_ 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_ 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_ 467 LOW_SPEED_LOCKOUT "in low speed lockout, system would always disengage below 28mph";
|
||||||
CM_ SG_ 560 BRAKE_PRESSED "another brake pressed?";
|
CM_ SG_ 560 BRAKE_PRESSED "another brake pressed?";
|
||||||
CM_ SG_ 608 STEER_TORQUE_DRIVER "driver torque";
|
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_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_ 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_ 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_ 467 LOW_SPEED_LOCKOUT "in low speed lockout, system would always disengage below 28mph";
|
||||||
CM_ SG_ 560 BRAKE_PRESSED "another brake pressed?";
|
CM_ SG_ 560 BRAKE_PRESSED "another brake pressed?";
|
||||||
CM_ SG_ 608 STEER_TORQUE_DRIVER "driver torque";
|
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_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_ 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_ 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_ 467 LOW_SPEED_LOCKOUT "in low speed lockout, system would always disengage below 28mph";
|
||||||
CM_ SG_ 560 BRAKE_PRESSED "another brake pressed?";
|
CM_ SG_ 560 BRAKE_PRESSED "another brake pressed?";
|
||||||
CM_ SG_ 608 STEER_TORQUE_DRIVER "driver torque";
|
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_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_ 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_ 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_ 467 LOW_SPEED_LOCKOUT "in low speed lockout, system would always disengage below 28mph";
|
||||||
CM_ SG_ 560 BRAKE_PRESSED "another brake pressed?";
|
CM_ SG_ 560 BRAKE_PRESSED "another brake pressed?";
|
||||||
CM_ SG_ 608 STEER_TORQUE_DRIVER "driver torque";
|
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
|
SG_ GAS_PEDAL : 55|8@0+ (0.005,0) [0|1] "" XXX
|
||||||
|
|
||||||
BO_ 608 STEER_TORQUE_SENSOR: 8 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_TORQUE_DRIVER : 15|16@0- (1,0) [-32768|32767] "" XXX
|
||||||
SG_ STEER_OVERRIDE : 0|1@0+ (1,0) [0|1] "" XXX
|
SG_ STEER_OVERRIDE : 0|1@0+ (1,0) [0|1] "" XXX
|
||||||
SG_ CHECKSUM : 63|8@0+ (1,0) [0|255] "" 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_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_ 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_ 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_ 467 LOW_SPEED_LOCKOUT "in low speed lockout, system would always disengage below 28mph";
|
||||||
CM_ SG_ 560 BRAKE_PRESSED "another brake pressed?";
|
CM_ SG_ 560 BRAKE_PRESSED "another brake pressed?";
|
||||||
CM_ SG_ 608 STEER_TORQUE_DRIVER "driver torque";
|
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_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_ 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_ 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_ 467 LOW_SPEED_LOCKOUT "in low speed lockout, system would always disengage below 28mph";
|
||||||
CM_ SG_ 560 BRAKE_PRESSED "another brake pressed?";
|
CM_ SG_ 560 BRAKE_PRESSED "another brake pressed?";
|
||||||
CM_ SG_ 608 STEER_TORQUE_DRIVER "driver torque";
|
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_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_ 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_ 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_ 467 LOW_SPEED_LOCKOUT "in low speed lockout, system would always disengage below 28mph";
|
||||||
CM_ SG_ 560 BRAKE_PRESSED "another brake pressed?";
|
CM_ SG_ 560 BRAKE_PRESSED "another brake pressed?";
|
||||||
CM_ SG_ 608 STEER_TORQUE_DRIVER "driver torque";
|
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_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_ 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_ 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_ 467 LOW_SPEED_LOCKOUT "in low speed lockout, system would always disengage below 28mph";
|
||||||
CM_ SG_ 560 BRAKE_PRESSED "another brake pressed?";
|
CM_ SG_ 560 BRAKE_PRESSED "another brake pressed?";
|
||||||
CM_ SG_ 608 STEER_TORQUE_DRIVER "driver torque";
|
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_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_ 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_ 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_ 467 LOW_SPEED_LOCKOUT "in low speed lockout, system would always disengage below 28mph";
|
||||||
CM_ SG_ 560 BRAKE_PRESSED "another brake pressed?";
|
CM_ SG_ 560 BRAKE_PRESSED "another brake pressed?";
|
||||||
CM_ SG_ 608 STEER_TORQUE_DRIVER "driver torque";
|
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_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_ 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_ 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_ 467 LOW_SPEED_LOCKOUT "in low speed lockout, system would always disengage below 28mph";
|
||||||
CM_ SG_ 560 BRAKE_PRESSED "another brake pressed?";
|
CM_ SG_ 560 BRAKE_PRESSED "another brake pressed?";
|
||||||
CM_ SG_ 608 STEER_TORQUE_DRIVER "driver torque";
|
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_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_ 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_ 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_ 467 LOW_SPEED_LOCKOUT "in low speed lockout, system would always disengage below 28mph";
|
||||||
CM_ SG_ 560 BRAKE_PRESSED "another brake pressed?";
|
CM_ SG_ 560 BRAKE_PRESSED "another brake pressed?";
|
||||||
CM_ SG_ 608 STEER_TORQUE_DRIVER "driver torque";
|
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_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_ 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_ 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_ 467 LOW_SPEED_LOCKOUT "in low speed lockout, system would always disengage below 28mph";
|
||||||
CM_ SG_ 560 BRAKE_PRESSED "another brake pressed?";
|
CM_ SG_ 560 BRAKE_PRESSED "another brake pressed?";
|
||||||
CM_ SG_ 608 STEER_TORQUE_DRIVER "driver torque";
|
CM_ SG_ 608 STEER_TORQUE_DRIVER "driver torque";
|
||||||
|
|
|
@ -1,3 +1,3 @@
|
||||||
# flake8: noqa
|
# flake8: noqa
|
||||||
# pylint: skip-file
|
# 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
|
#ifdef PANDA
|
||||||
#include "drivers/fan.h"
|
#include "drivers/fan.h"
|
||||||
#include "drivers/rtc.h"
|
#include "drivers/rtc.h"
|
||||||
|
#include "drivers/clock_source.h"
|
||||||
#include "boards/white.h"
|
#include "boards/white.h"
|
||||||
#include "boards/grey.h"
|
#include "boards/grey.h"
|
||||||
#include "boards/black.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)
|
// 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, 14, 1);
|
||||||
set_gpio_output(GPIOC, 5, 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;
|
hw_type = HW_TYPE_DOS;
|
||||||
current_board = &board_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))){
|
} 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 ///// //
|
// ///// Configuration detection ///// //
|
||||||
bool has_external_debug_serial = 0;
|
bool has_external_debug_serial = 0;
|
||||||
bool is_entering_bootmode = 0;
|
|
||||||
|
|
||||||
void detect_configuration(void) {
|
void detect_configuration(void) {
|
||||||
// detect if external serial debugging is present
|
// detect if external serial debugging is present
|
||||||
has_external_debug_serial = detect_with_pull(GPIOA, 3, PULL_DOWN);
|
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 ///// //
|
// ///// Board functions ///// //
|
||||||
|
|
|
@ -1,10 +1,10 @@
|
||||||
// ******************** Prototypes ********************
|
// ******************** Prototypes ********************
|
||||||
typedef void (*board_init)(void);
|
typedef void (*board_init)(void);
|
||||||
typedef void (*board_enable_can_transciever)(uint8_t transciever, bool enabled);
|
typedef void (*board_enable_can_transceiver)(uint8_t transceiver, bool enabled);
|
||||||
typedef void (*board_enable_can_transcievers)(bool enabled);
|
typedef void (*board_enable_can_transceivers)(bool enabled);
|
||||||
typedef void (*board_set_led)(uint8_t color, 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_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_set_can_mode)(uint8_t mode);
|
||||||
typedef void (*board_usb_power_mode_tick)(uint32_t uptime);
|
typedef void (*board_usb_power_mode_tick)(uint32_t uptime);
|
||||||
typedef bool (*board_check_ignition)(void);
|
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_ir_power)(uint8_t percentage);
|
||||||
typedef void (*board_set_fan_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_phone_power)(bool enabled);
|
||||||
|
typedef void (*board_set_clock_source_mode)(uint8_t mode);
|
||||||
|
typedef void (*board_set_siren)(bool enabled);
|
||||||
|
|
||||||
struct board {
|
struct board {
|
||||||
const char *board_type;
|
const char *board_type;
|
||||||
const harness_configuration *harness_config;
|
const harness_configuration *harness_config;
|
||||||
board_init init;
|
board_init init;
|
||||||
board_enable_can_transciever enable_can_transciever;
|
board_enable_can_transceiver enable_can_transceiver;
|
||||||
board_enable_can_transcievers enable_can_transcievers;
|
board_enable_can_transceivers enable_can_transceivers;
|
||||||
board_set_led set_led;
|
board_set_led set_led;
|
||||||
board_set_usb_power_mode set_usb_power_mode;
|
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_set_can_mode set_can_mode;
|
||||||
board_usb_power_mode_tick usb_power_mode_tick;
|
board_usb_power_mode_tick usb_power_mode_tick;
|
||||||
board_check_ignition check_ignition;
|
board_check_ignition check_ignition;
|
||||||
|
@ -29,6 +31,8 @@ struct board {
|
||||||
board_set_ir_power set_ir_power;
|
board_set_ir_power set_ir_power;
|
||||||
board_set_fan_power set_fan_power;
|
board_set_fan_power set_fan_power;
|
||||||
board_set_phone_power set_phone_power;
|
board_set_phone_power set_phone_power;
|
||||||
|
board_set_clock_source_mode set_clock_source_mode;
|
||||||
|
board_set_siren set_siren;
|
||||||
};
|
};
|
||||||
|
|
||||||
// ******************* Definitions ********************
|
// ******************* Definitions ********************
|
||||||
|
@ -52,10 +56,10 @@ struct board {
|
||||||
#define USB_POWER_CDP 2U
|
#define USB_POWER_CDP 2U
|
||||||
#define USB_POWER_DCP 3U
|
#define USB_POWER_DCP 3U
|
||||||
|
|
||||||
// ESP modes
|
// GPS modes
|
||||||
#define ESP_GPS_DISABLED 0U
|
#define GPS_DISABLED 0U
|
||||||
#define ESP_GPS_ENABLED 1U
|
#define GPS_ENABLED 1U
|
||||||
#define ESP_GPS_BOOTMODE 2U
|
#define GPS_BOOTMODE 2U
|
||||||
|
|
||||||
// CAN modes
|
// CAN modes
|
||||||
#define CAN_MODE_NORMAL 0U
|
#define CAN_MODE_NORMAL 0U
|
||||||
|
@ -72,4 +76,4 @@ bool board_has_gmlan(void);
|
||||||
bool board_has_obd(void);
|
bool board_has_obd(void);
|
||||||
bool board_has_lin(void);
|
bool board_has_lin(void);
|
||||||
bool board_has_rtc(void);
|
bool board_has_rtc(void);
|
||||||
bool board_has_relay(void);
|
bool board_has_relay(void);
|
||||||
|
|
|
@ -2,8 +2,8 @@
|
||||||
// Black Panda + Harness //
|
// Black Panda + Harness //
|
||||||
// ///////////////////// //
|
// ///////////////////// //
|
||||||
|
|
||||||
void black_enable_can_transciever(uint8_t transciever, bool enabled) {
|
void black_enable_can_transceiver(uint8_t transceiver, bool enabled) {
|
||||||
switch (transciever){
|
switch (transceiver){
|
||||||
case 1U:
|
case 1U:
|
||||||
set_gpio_output(GPIOC, 1, !enabled);
|
set_gpio_output(GPIOC, 1, !enabled);
|
||||||
break;
|
break;
|
||||||
|
@ -17,18 +17,18 @@ void black_enable_can_transciever(uint8_t transciever, bool enabled) {
|
||||||
set_gpio_output(GPIOB, 10, !enabled);
|
set_gpio_output(GPIOB, 10, !enabled);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
puts("Invalid CAN transciever ("); puth(transciever); puts("): enabling failed\n");
|
puts("Invalid CAN transceiver ("); puth(transceiver); puts("): enabling failed\n");
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void black_enable_can_transcievers(bool enabled) {
|
void black_enable_can_transceivers(bool enabled) {
|
||||||
for(uint8_t i=1U; i<=4U; i++){
|
for(uint8_t i=1U; i<=4U; i++){
|
||||||
// Leave main CAN always on for CAN-based ignition detection
|
// Leave main CAN always on for CAN-based ignition detection
|
||||||
if((car_harness_status == HARNESS_STATUS_FLIPPED) ? (i == 3U) : (i == 1U)){
|
if((car_harness_status == HARNESS_STATUS_FLIPPED) ? (i == 3U) : (i == 1U)){
|
||||||
black_enable_can_transciever(i, true);
|
black_enable_can_transceiver(i, true);
|
||||||
} else {
|
} 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) {
|
switch (mode) {
|
||||||
case ESP_GPS_DISABLED:
|
case GPS_DISABLED:
|
||||||
// GPS OFF
|
// GPS OFF
|
||||||
set_gpio_output(GPIOC, 14, 0);
|
set_gpio_output(GPIOC, 14, 0);
|
||||||
set_gpio_output(GPIOC, 5, 0);
|
set_gpio_output(GPIOC, 5, 0);
|
||||||
break;
|
break;
|
||||||
case ESP_GPS_ENABLED:
|
case GPS_ENABLED:
|
||||||
// GPS ON
|
// GPS ON
|
||||||
set_gpio_output(GPIOC, 14, 1);
|
set_gpio_output(GPIOC, 14, 1);
|
||||||
set_gpio_output(GPIOC, 5, 1);
|
set_gpio_output(GPIOC, 5, 1);
|
||||||
break;
|
break;
|
||||||
case ESP_GPS_BOOTMODE:
|
case GPS_BOOTMODE:
|
||||||
set_gpio_output(GPIOC, 14, 1);
|
set_gpio_output(GPIOC, 14, 1);
|
||||||
set_gpio_output(GPIOC, 5, 0);
|
set_gpio_output(GPIOC, 5, 0);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
puts("Invalid ESP/GPS mode\n");
|
puts("Invalid GPS mode\n");
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -154,6 +154,14 @@ void black_set_phone_power(bool enabled){
|
||||||
UNUSED(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) {
|
void black_init(void) {
|
||||||
common_init_gpio();
|
common_init_gpio();
|
||||||
|
|
||||||
|
@ -167,7 +175,7 @@ void black_init(void) {
|
||||||
set_gpio_mode(GPIOC, 3, MODE_ANALOG);
|
set_gpio_mode(GPIOC, 3, MODE_ANALOG);
|
||||||
|
|
||||||
// Set default state of GPS
|
// 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)
|
// C10: OBD_SBU1_RELAY (harness relay driving output)
|
||||||
// C11: OBD_SBU2_RELAY (harness relay driving output)
|
// C11: OBD_SBU2_RELAY (harness relay driving output)
|
||||||
|
@ -190,8 +198,8 @@ void black_init(void) {
|
||||||
// Initialize harness
|
// Initialize harness
|
||||||
harness_init();
|
harness_init();
|
||||||
|
|
||||||
// Enable CAN transcievers
|
// Enable CAN transceivers
|
||||||
black_enable_can_transcievers(true);
|
black_enable_can_transceivers(true);
|
||||||
|
|
||||||
// Disable LEDs
|
// Disable LEDs
|
||||||
black_set_led(LED_RED, false);
|
black_set_led(LED_RED, false);
|
||||||
|
@ -228,16 +236,18 @@ const board board_black = {
|
||||||
.board_type = "Black",
|
.board_type = "Black",
|
||||||
.harness_config = &black_harness_config,
|
.harness_config = &black_harness_config,
|
||||||
.init = black_init,
|
.init = black_init,
|
||||||
.enable_can_transciever = black_enable_can_transciever,
|
.enable_can_transceiver = black_enable_can_transceiver,
|
||||||
.enable_can_transcievers = black_enable_can_transcievers,
|
.enable_can_transceivers = black_enable_can_transceivers,
|
||||||
.set_led = black_set_led,
|
.set_led = black_set_led,
|
||||||
.set_usb_power_mode = black_set_usb_power_mode,
|
.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,
|
.set_can_mode = black_set_can_mode,
|
||||||
.usb_power_mode_tick = black_usb_power_mode_tick,
|
.usb_power_mode_tick = black_usb_power_mode_tick,
|
||||||
.check_ignition = black_check_ignition,
|
.check_ignition = black_check_ignition,
|
||||||
.read_current = black_read_current,
|
.read_current = black_read_current,
|
||||||
.set_fan_power = black_set_fan_power,
|
.set_fan_power = black_set_fan_power,
|
||||||
.set_ir_power = black_set_ir_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);
|
set_gpio_alternate(GPIOA, 12, GPIO_AF10_OTG_FS);
|
||||||
GPIOA->OSPEEDR = GPIO_OSPEEDER_OSPEEDR11 | GPIO_OSPEEDER_OSPEEDR12;
|
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, 9, GPIO_AF7_USART1);
|
||||||
set_gpio_alternate(GPIOA, 10, 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->APB1ENR |= RCC_APB1ENR_PWREN; // for RTC config
|
||||||
RCC->APB2ENR |= RCC_APB2ENR_USART1EN;
|
RCC->APB2ENR |= RCC_APB2ENR_USART1EN;
|
||||||
RCC->AHB2ENR |= RCC_AHB2ENR_OTGFSEN;
|
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_ADC1EN;
|
||||||
RCC->APB2ENR |= RCC_APB2ENR_SPI1EN;
|
RCC->APB2ENR |= RCC_APB2ENR_SPI1EN;
|
||||||
RCC->APB2ENR |= RCC_APB2ENR_SYSCFGEN;
|
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);
|
bool ret = get_gpio_input(GPIO, pin);
|
||||||
set_gpio_pullup(GPIO, pin, PULL_NONE);
|
set_gpio_pullup(GPIO, pin, PULL_NONE);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,8 +2,8 @@
|
||||||
// Dos + Harness //
|
// Dos + Harness //
|
||||||
// ///////////// //
|
// ///////////// //
|
||||||
|
|
||||||
void dos_enable_can_transciever(uint8_t transciever, bool enabled) {
|
void dos_enable_can_transceiver(uint8_t transceiver, bool enabled) {
|
||||||
switch (transciever){
|
switch (transceiver){
|
||||||
case 1U:
|
case 1U:
|
||||||
set_gpio_output(GPIOC, 1, !enabled);
|
set_gpio_output(GPIOC, 1, !enabled);
|
||||||
break;
|
break;
|
||||||
|
@ -17,18 +17,18 @@ void dos_enable_can_transciever(uint8_t transciever, bool enabled) {
|
||||||
set_gpio_output(GPIOB, 10, !enabled);
|
set_gpio_output(GPIOB, 10, !enabled);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
puts("Invalid CAN transciever ("); puth(transciever); puts("): enabling failed\n");
|
puts("Invalid CAN transceiver ("); puth(transceiver); puts("): enabling failed\n");
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void dos_enable_can_transcievers(bool enabled) {
|
void dos_enable_can_transceivers(bool enabled) {
|
||||||
for(uint8_t i=1U; i<=4U; i++){
|
for(uint8_t i=1U; i<=4U; i++){
|
||||||
// Leave main CAN always on for CAN-based ignition detection
|
// Leave main CAN always on for CAN-based ignition detection
|
||||||
if((car_harness_status == HARNESS_STATUS_FLIPPED) ? (i == 3U) : (i == 1U)){
|
if((car_harness_status == HARNESS_STATUS_FLIPPED) ? (i == 3U) : (i == 1U)){
|
||||||
uno_enable_can_transciever(i, true);
|
uno_enable_can_transceiver(i, true);
|
||||||
} else {
|
} 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){
|
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){
|
void dos_set_phone_power(bool enabled){
|
||||||
UNUSED(enabled);
|
UNUSED(enabled);
|
||||||
}
|
}
|
||||||
|
|
||||||
void dos_set_usb_power_mode(uint8_t mode) {
|
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);
|
UNUSED(mode);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -101,11 +99,6 @@ void dos_set_can_mode(uint8_t mode){
|
||||||
|
|
||||||
void dos_usb_power_mode_tick(uint32_t uptime){
|
void dos_usb_power_mode_tick(uint32_t uptime){
|
||||||
UNUSED(uptime);
|
UNUSED(uptime);
|
||||||
if(bootkick_timer != 0U){
|
|
||||||
bootkick_timer--;
|
|
||||||
} else {
|
|
||||||
dos_set_bootkick(false);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool dos_check_ignition(void){
|
bool dos_check_ignition(void){
|
||||||
|
@ -132,6 +125,14 @@ uint32_t dos_read_current(void){
|
||||||
return 0U;
|
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) {
|
void dos_init(void) {
|
||||||
common_init_gpio();
|
common_init_gpio();
|
||||||
|
|
||||||
|
@ -171,8 +172,8 @@ void dos_init(void) {
|
||||||
// Initialize RTC
|
// Initialize RTC
|
||||||
rtc_init();
|
rtc_init();
|
||||||
|
|
||||||
// Enable CAN transcievers
|
// Enable CAN transceivers
|
||||||
dos_enable_can_transcievers(true);
|
dos_enable_can_transceivers(true);
|
||||||
|
|
||||||
// Disable LEDs
|
// Disable LEDs
|
||||||
dos_set_led(LED_RED, false);
|
dos_set_led(LED_RED, false);
|
||||||
|
@ -189,6 +190,9 @@ void dos_init(void) {
|
||||||
|
|
||||||
// init multiplexer
|
// init multiplexer
|
||||||
can_set_obd(car_harness_status, false);
|
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 = {
|
const harness_configuration dos_harness_config = {
|
||||||
|
@ -209,16 +213,18 @@ const board board_dos = {
|
||||||
.board_type = "Dos",
|
.board_type = "Dos",
|
||||||
.harness_config = &dos_harness_config,
|
.harness_config = &dos_harness_config,
|
||||||
.init = dos_init,
|
.init = dos_init,
|
||||||
.enable_can_transciever = dos_enable_can_transciever,
|
.enable_can_transceiver = dos_enable_can_transceiver,
|
||||||
.enable_can_transcievers = dos_enable_can_transcievers,
|
.enable_can_transceivers = dos_enable_can_transceivers,
|
||||||
.set_led = dos_set_led,
|
.set_led = dos_set_led,
|
||||||
.set_usb_power_mode = dos_set_usb_power_mode,
|
.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,
|
.set_can_mode = dos_set_can_mode,
|
||||||
.usb_power_mode_tick = dos_usb_power_mode_tick,
|
.usb_power_mode_tick = dos_usb_power_mode_tick,
|
||||||
.check_ignition = dos_check_ignition,
|
.check_ignition = dos_check_ignition,
|
||||||
.read_current = dos_read_current,
|
.read_current = dos_read_current,
|
||||||
.set_fan_power = dos_set_fan_power,
|
.set_fan_power = dos_set_fan_power,
|
||||||
.set_ir_power = dos_set_ir_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();
|
white_grey_common_init();
|
||||||
|
|
||||||
// Set default state of GPS
|
// 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) {
|
switch (mode) {
|
||||||
case ESP_GPS_DISABLED:
|
case GPS_DISABLED:
|
||||||
// GPS OFF
|
// GPS OFF
|
||||||
set_gpio_output(GPIOC, 14, 0);
|
set_gpio_output(GPIOC, 14, 0);
|
||||||
set_gpio_output(GPIOC, 5, 0);
|
set_gpio_output(GPIOC, 5, 0);
|
||||||
break;
|
break;
|
||||||
case ESP_GPS_ENABLED:
|
case GPS_ENABLED:
|
||||||
// GPS ON
|
// GPS ON
|
||||||
set_gpio_output(GPIOC, 14, 1);
|
set_gpio_output(GPIOC, 14, 1);
|
||||||
set_gpio_output(GPIOC, 5, 1);
|
set_gpio_output(GPIOC, 5, 1);
|
||||||
break;
|
break;
|
||||||
case ESP_GPS_BOOTMODE:
|
case GPS_BOOTMODE:
|
||||||
set_gpio_output(GPIOC, 14, 1);
|
set_gpio_output(GPIOC, 14, 1);
|
||||||
set_gpio_output(GPIOC, 5, 0);
|
set_gpio_output(GPIOC, 5, 0);
|
||||||
break;
|
break;
|
||||||
|
@ -37,16 +37,18 @@ const board board_grey = {
|
||||||
.board_type = "Grey",
|
.board_type = "Grey",
|
||||||
.harness_config = &white_harness_config,
|
.harness_config = &white_harness_config,
|
||||||
.init = grey_init,
|
.init = grey_init,
|
||||||
.enable_can_transciever = white_enable_can_transciever,
|
.enable_can_transceiver = white_enable_can_transceiver,
|
||||||
.enable_can_transcievers = white_enable_can_transcievers,
|
.enable_can_transceivers = white_enable_can_transceivers,
|
||||||
.set_led = white_set_led,
|
.set_led = white_set_led,
|
||||||
.set_usb_power_mode = white_set_usb_power_mode,
|
.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,
|
.set_can_mode = white_set_can_mode,
|
||||||
.usb_power_mode_tick = white_usb_power_mode_tick,
|
.usb_power_mode_tick = white_usb_power_mode_tick,
|
||||||
.check_ignition = white_check_ignition,
|
.check_ignition = white_check_ignition,
|
||||||
.read_current = white_read_current,
|
.read_current = white_read_current,
|
||||||
.set_fan_power = white_set_fan_power,
|
.set_fan_power = white_set_fan_power,
|
||||||
.set_ir_power = white_set_ir_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 //
|
// Pedal //
|
||||||
// ///// //
|
// ///// //
|
||||||
|
|
||||||
void pedal_enable_can_transciever(uint8_t transciever, bool enabled) {
|
void pedal_enable_can_transceiver(uint8_t transceiver, bool enabled) {
|
||||||
switch (transciever){
|
switch (transceiver){
|
||||||
case 1:
|
case 1:
|
||||||
set_gpio_output(GPIOB, 3, !enabled);
|
set_gpio_output(GPIOB, 3, !enabled);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
puts("Invalid CAN transciever ("); puth(transciever); puts("): enabling failed\n");
|
puts("Invalid CAN transceiver ("); puth(transceiver); puts("): enabling failed\n");
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void pedal_enable_can_transcievers(bool enabled) {
|
void pedal_enable_can_transceivers(bool enabled) {
|
||||||
pedal_enable_can_transciever(1U, enabled);
|
pedal_enable_can_transceiver(1U, enabled);
|
||||||
}
|
}
|
||||||
|
|
||||||
void pedal_set_led(uint8_t color, bool 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");
|
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);
|
UNUSED(mode);
|
||||||
puts("Trying to set ESP/GPS mode on pedal. This is not supported.\n");
|
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);
|
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) {
|
void pedal_init(void) {
|
||||||
common_init_gpio();
|
common_init_gpio();
|
||||||
|
|
||||||
|
@ -86,8 +94,8 @@ void pedal_init(void) {
|
||||||
// DAC outputs on A4 and A5
|
// DAC outputs on A4 and A5
|
||||||
// apparently they don't need GPIO setup
|
// apparently they don't need GPIO setup
|
||||||
|
|
||||||
// Enable transciever
|
// Enable transceiver
|
||||||
pedal_enable_can_transcievers(true);
|
pedal_enable_can_transceivers(true);
|
||||||
|
|
||||||
// Disable LEDs
|
// Disable LEDs
|
||||||
pedal_set_led(LED_RED, false);
|
pedal_set_led(LED_RED, false);
|
||||||
|
@ -102,16 +110,18 @@ const board board_pedal = {
|
||||||
.board_type = "Pedal",
|
.board_type = "Pedal",
|
||||||
.harness_config = &pedal_harness_config,
|
.harness_config = &pedal_harness_config,
|
||||||
.init = pedal_init,
|
.init = pedal_init,
|
||||||
.enable_can_transciever = pedal_enable_can_transciever,
|
.enable_can_transceiver = pedal_enable_can_transceiver,
|
||||||
.enable_can_transcievers = pedal_enable_can_transcievers,
|
.enable_can_transceivers = pedal_enable_can_transceivers,
|
||||||
.set_led = pedal_set_led,
|
.set_led = pedal_set_led,
|
||||||
.set_usb_power_mode = pedal_set_usb_power_mode,
|
.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,
|
.set_can_mode = pedal_set_can_mode,
|
||||||
.usb_power_mode_tick = pedal_usb_power_mode_tick,
|
.usb_power_mode_tick = pedal_usb_power_mode_tick,
|
||||||
.check_ignition = pedal_check_ignition,
|
.check_ignition = pedal_check_ignition,
|
||||||
.read_current = pedal_read_current,
|
.read_current = pedal_read_current,
|
||||||
.set_fan_power = pedal_set_fan_power,
|
.set_fan_power = pedal_set_fan_power,
|
||||||
.set_ir_power = pedal_set_ir_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
|
#define BOOTKICK_TIME 3U
|
||||||
uint8_t bootkick_timer = 0U;
|
uint8_t bootkick_timer = 0U;
|
||||||
|
|
||||||
void uno_enable_can_transciever(uint8_t transciever, bool enabled) {
|
void uno_enable_can_transceiver(uint8_t transceiver, bool enabled) {
|
||||||
switch (transciever){
|
switch (transceiver){
|
||||||
case 1U:
|
case 1U:
|
||||||
set_gpio_output(GPIOC, 1, !enabled);
|
set_gpio_output(GPIOC, 1, !enabled);
|
||||||
break;
|
break;
|
||||||
|
@ -19,18 +19,18 @@ void uno_enable_can_transciever(uint8_t transciever, bool enabled) {
|
||||||
set_gpio_output(GPIOB, 10, !enabled);
|
set_gpio_output(GPIOB, 10, !enabled);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
puts("Invalid CAN transciever ("); puth(transciever); puts("): enabling failed\n");
|
puts("Invalid CAN transceiver ("); puth(transceiver); puts("): enabling failed\n");
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void uno_enable_can_transcievers(bool enabled) {
|
void uno_enable_can_transceivers(bool enabled) {
|
||||||
for(uint8_t i=1U; i<=4U; i++){
|
for(uint8_t i=1U; i<=4U; i++){
|
||||||
// Leave main CAN always on for CAN-based ignition detection
|
// Leave main CAN always on for CAN-based ignition detection
|
||||||
if((car_harness_status == HARNESS_STATUS_FLIPPED) ? (i == 3U) : (i == 1U)){
|
if((car_harness_status == HARNESS_STATUS_FLIPPED) ? (i == 3U) : (i == 1U)){
|
||||||
uno_enable_can_transciever(i, true);
|
uno_enable_can_transceiver(i, true);
|
||||||
} else {
|
} 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) {
|
switch (mode) {
|
||||||
case ESP_GPS_DISABLED:
|
case GPS_DISABLED:
|
||||||
// GPS OFF
|
// GPS OFF
|
||||||
set_gpio_output(GPIOB, 1, 0);
|
set_gpio_output(GPIOB, 1, 0);
|
||||||
set_gpio_output(GPIOC, 5, 0);
|
set_gpio_output(GPIOC, 5, 0);
|
||||||
uno_set_gps_load_switch(false);
|
uno_set_gps_load_switch(false);
|
||||||
break;
|
break;
|
||||||
case ESP_GPS_ENABLED:
|
case GPS_ENABLED:
|
||||||
// GPS ON
|
// GPS ON
|
||||||
set_gpio_output(GPIOB, 1, 1);
|
set_gpio_output(GPIOB, 1, 1);
|
||||||
set_gpio_output(GPIOC, 5, 1);
|
set_gpio_output(GPIOC, 5, 1);
|
||||||
uno_set_gps_load_switch(true);
|
uno_set_gps_load_switch(true);
|
||||||
break;
|
break;
|
||||||
case ESP_GPS_BOOTMODE:
|
case GPS_BOOTMODE:
|
||||||
set_gpio_output(GPIOB, 1, 1);
|
set_gpio_output(GPIOB, 1, 1);
|
||||||
set_gpio_output(GPIOC, 5, 0);
|
set_gpio_output(GPIOC, 5, 0);
|
||||||
uno_set_gps_load_switch(true);
|
uno_set_gps_load_switch(true);
|
||||||
|
@ -175,6 +175,14 @@ uint32_t uno_read_current(void){
|
||||||
return 0U;
|
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) {
|
void uno_init(void) {
|
||||||
common_init_gpio();
|
common_init_gpio();
|
||||||
|
|
||||||
|
@ -188,7 +196,7 @@ void uno_init(void) {
|
||||||
set_gpio_mode(GPIOC, 3, MODE_ANALOG);
|
set_gpio_mode(GPIOC, 3, MODE_ANALOG);
|
||||||
|
|
||||||
// Set default state of GPS
|
// 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)
|
// C10: OBD_SBU1_RELAY (harness relay driving output)
|
||||||
// C11: OBD_SBU2_RELAY (harness relay driving output)
|
// C11: OBD_SBU2_RELAY (harness relay driving output)
|
||||||
|
@ -223,8 +231,8 @@ void uno_init(void) {
|
||||||
// Initialize RTC
|
// Initialize RTC
|
||||||
rtc_init();
|
rtc_init();
|
||||||
|
|
||||||
// Enable CAN transcievers
|
// Enable CAN transceivers
|
||||||
uno_enable_can_transcievers(true);
|
uno_enable_can_transceivers(true);
|
||||||
|
|
||||||
// Disable LEDs
|
// Disable LEDs
|
||||||
uno_set_led(LED_RED, false);
|
uno_set_led(LED_RED, false);
|
||||||
|
@ -271,16 +279,18 @@ const board board_uno = {
|
||||||
.board_type = "Uno",
|
.board_type = "Uno",
|
||||||
.harness_config = &uno_harness_config,
|
.harness_config = &uno_harness_config,
|
||||||
.init = uno_init,
|
.init = uno_init,
|
||||||
.enable_can_transciever = uno_enable_can_transciever,
|
.enable_can_transceiver = uno_enable_can_transceiver,
|
||||||
.enable_can_transcievers = uno_enable_can_transcievers,
|
.enable_can_transceivers = uno_enable_can_transceivers,
|
||||||
.set_led = uno_set_led,
|
.set_led = uno_set_led,
|
||||||
.set_usb_power_mode = uno_set_usb_power_mode,
|
.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,
|
.set_can_mode = uno_set_can_mode,
|
||||||
.usb_power_mode_tick = uno_usb_power_mode_tick,
|
.usb_power_mode_tick = uno_usb_power_mode_tick,
|
||||||
.check_ignition = uno_check_ignition,
|
.check_ignition = uno_check_ignition,
|
||||||
.read_current = uno_read_current,
|
.read_current = uno_read_current,
|
||||||
.set_fan_power = uno_set_fan_power,
|
.set_fan_power = uno_set_fan_power,
|
||||||
.set_ir_power = uno_set_ir_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 //
|
// White Panda //
|
||||||
// /////////// //
|
// /////////// //
|
||||||
|
|
||||||
void white_enable_can_transciever(uint8_t transciever, bool enabled) {
|
void white_enable_can_transceiver(uint8_t transceiver, bool enabled) {
|
||||||
switch (transciever){
|
switch (transceiver){
|
||||||
case 1U:
|
case 1U:
|
||||||
set_gpio_output(GPIOC, 1, !enabled);
|
set_gpio_output(GPIOC, 1, !enabled);
|
||||||
break;
|
break;
|
||||||
|
@ -14,15 +14,15 @@ void white_enable_can_transciever(uint8_t transciever, bool enabled) {
|
||||||
set_gpio_output(GPIOA, 0, !enabled);
|
set_gpio_output(GPIOA, 0, !enabled);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
puts("Invalid CAN transciever ("); puth(transciever); puts("): enabling failed\n");
|
puts("Invalid CAN transceiver ("); puth(transceiver); puts("): enabling failed\n");
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void white_enable_can_transcievers(bool enabled) {
|
void white_enable_can_transceivers(bool enabled) {
|
||||||
uint8_t t1 = enabled ? 1U : 2U; // leave transciever 1 enabled to detect CAN ignition
|
uint8_t t1 = enabled ? 1U : 2U; // leave transceiver 1 enabled to detect CAN ignition
|
||||||
for(uint8_t i=t1; i<=3U; i++) {
|
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) {
|
switch (mode) {
|
||||||
case ESP_GPS_DISABLED:
|
case GPS_DISABLED:
|
||||||
// ESP OFF
|
// ESP OFF
|
||||||
set_gpio_output(GPIOC, 14, 0);
|
set_gpio_output(GPIOC, 14, 0);
|
||||||
set_gpio_output(GPIOC, 5, 0);
|
set_gpio_output(GPIOC, 5, 0);
|
||||||
break;
|
break;
|
||||||
#ifndef EON
|
#ifndef EON
|
||||||
case ESP_GPS_ENABLED:
|
case GPS_ENABLED:
|
||||||
// ESP ON
|
// ESP ON
|
||||||
set_gpio_output(GPIOC, 14, 1);
|
set_gpio_output(GPIOC, 14, 1);
|
||||||
set_gpio_output(GPIOC, 5, 1);
|
set_gpio_output(GPIOC, 5, 1);
|
||||||
break;
|
break;
|
||||||
#endif
|
#endif
|
||||||
case ESP_GPS_BOOTMODE:
|
case GPS_BOOTMODE:
|
||||||
set_gpio_output(GPIOC, 14, 1);
|
set_gpio_output(GPIOC, 14, 1);
|
||||||
set_gpio_output(GPIOC, 5, 0);
|
set_gpio_output(GPIOC, 5, 0);
|
||||||
break;
|
break;
|
||||||
|
@ -242,6 +242,14 @@ void white_set_phone_power(bool enabled){
|
||||||
UNUSED(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) {
|
void white_grey_common_init(void) {
|
||||||
common_init_gpio();
|
common_init_gpio();
|
||||||
|
|
||||||
|
@ -291,8 +299,8 @@ void white_grey_common_init(void) {
|
||||||
set_gpio_alternate(GPIOC, 11, GPIO_AF7_USART3);
|
set_gpio_alternate(GPIOC, 11, GPIO_AF7_USART3);
|
||||||
set_gpio_pullup(GPIOC, 11, PULL_UP);
|
set_gpio_pullup(GPIOC, 11, PULL_UP);
|
||||||
|
|
||||||
// Enable CAN transcievers
|
// Enable CAN transceivers
|
||||||
white_enable_can_transcievers(true);
|
white_enable_can_transceivers(true);
|
||||||
|
|
||||||
// Disable LEDs
|
// Disable LEDs
|
||||||
white_set_led(LED_RED, false);
|
white_set_led(LED_RED, false);
|
||||||
|
@ -316,12 +324,8 @@ void white_grey_common_init(void) {
|
||||||
void white_init(void) {
|
void white_init(void) {
|
||||||
white_grey_common_init();
|
white_grey_common_init();
|
||||||
|
|
||||||
// Set default state of ESP
|
// Set ESP off by default
|
||||||
#ifdef EON
|
current_board->set_gps_mode(GPS_DISABLED);
|
||||||
current_board->set_esp_gps_mode(ESP_GPS_DISABLED);
|
|
||||||
#else
|
|
||||||
current_board->set_esp_gps_mode(ESP_GPS_ENABLED);
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const harness_configuration white_harness_config = {
|
const harness_configuration white_harness_config = {
|
||||||
|
@ -332,16 +336,18 @@ const board board_white = {
|
||||||
.board_type = "White",
|
.board_type = "White",
|
||||||
.harness_config = &white_harness_config,
|
.harness_config = &white_harness_config,
|
||||||
.init = white_init,
|
.init = white_init,
|
||||||
.enable_can_transciever = white_enable_can_transciever,
|
.enable_can_transceiver = white_enable_can_transceiver,
|
||||||
.enable_can_transcievers = white_enable_can_transcievers,
|
.enable_can_transceivers = white_enable_can_transceivers,
|
||||||
.set_led = white_set_led,
|
.set_led = white_set_led,
|
||||||
.set_usb_power_mode = white_set_usb_power_mode,
|
.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,
|
.set_can_mode = white_set_can_mode,
|
||||||
.usb_power_mode_tick = white_usb_power_mode_tick,
|
.usb_power_mode_tick = white_usb_power_mode_tick,
|
||||||
.check_ignition = white_check_ignition,
|
.check_ignition = white_check_ignition,
|
||||||
.read_current = white_read_current,
|
.read_current = white_read_current,
|
||||||
.set_fan_power = white_set_fan_power,
|
.set_fan_power = white_set_fan_power,
|
||||||
.set_ir_power = white_set_ir_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 ********************************
|
// ******************************** UART buffers ********************************
|
||||||
|
|
||||||
// esp_gps = USART1
|
// gps = USART1
|
||||||
UART_BUFFER(esp_gps, FIFO_SIZE_DMA, FIFO_SIZE_INT, USART1, NULL, true)
|
UART_BUFFER(gps, FIFO_SIZE_DMA, FIFO_SIZE_INT, USART1, NULL, true)
|
||||||
|
|
||||||
// lin1, K-LINE = UART5
|
// lin1, K-LINE = UART5
|
||||||
// lin2, L-LINE = USART3
|
// lin2, L-LINE = USART3
|
||||||
|
@ -68,7 +68,7 @@ uart_ring *get_ring_by_number(int a) {
|
||||||
ring = &uart_ring_debug;
|
ring = &uart_ring_debug;
|
||||||
break;
|
break;
|
||||||
case 1:
|
case 1:
|
||||||
ring = &uart_ring_esp_gps;
|
ring = &uart_ring_gps;
|
||||||
break;
|
break;
|
||||||
case 2:
|
case 2:
|
||||||
ring = &uart_ring_lin1;
|
ring = &uart_ring_lin1;
|
||||||
|
@ -185,8 +185,8 @@ void uart_interrupt_handler(uart_ring *q) {
|
||||||
// Reset IDLE flag
|
// Reset IDLE flag
|
||||||
UART_READ_DR(q->uart)
|
UART_READ_DR(q->uart)
|
||||||
|
|
||||||
if(q == &uart_ring_esp_gps){
|
if(q == &uart_ring_gps){
|
||||||
dma_pointer_handler(&uart_ring_esp_gps, DMA2_Stream5->NDTR);
|
dma_pointer_handler(&uart_ring_gps, DMA2_Stream5->NDTR);
|
||||||
} else {
|
} else {
|
||||||
#ifdef DEBUG_UART
|
#ifdef DEBUG_UART
|
||||||
puts("No IDLE dma_pointer_handler implemented for this UART.");
|
puts("No IDLE dma_pointer_handler implemented for this UART.");
|
||||||
|
@ -197,7 +197,7 @@ void uart_interrupt_handler(uart_ring *q) {
|
||||||
EXIT_CRITICAL();
|
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 USART2_IRQ_Handler(void) { uart_interrupt_handler(&uart_ring_debug); }
|
||||||
void USART3_IRQ_Handler(void) { uart_interrupt_handler(&uart_ring_lin2); }
|
void USART3_IRQ_Handler(void) { uart_interrupt_handler(&uart_ring_lin2); }
|
||||||
void UART5_IRQ_Handler(void) { uart_interrupt_handler(&uart_ring_lin1); }
|
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
|
// 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;
|
DMA2->HIFCR = DMA_HIFCR_CTCIF5 | DMA_HIFCR_CHTIF5;
|
||||||
|
|
||||||
EXIT_CRITICAL();
|
EXIT_CRITICAL();
|
||||||
|
@ -229,7 +229,7 @@ void DMA2_Stream5_IRQ_Handler(void) {
|
||||||
|
|
||||||
void dma_rx_init(uart_ring *q) {
|
void dma_rx_init(uart_ring *q) {
|
||||||
// Initialization is UART-dependent
|
// Initialization is UART-dependent
|
||||||
if(q == &uart_ring_esp_gps){
|
if(q == &uart_ring_gps){
|
||||||
// DMA2, stream 5, channel 4
|
// DMA2, stream 5, channel 4
|
||||||
|
|
||||||
// Disable FIFO mode (enable direct)
|
// Disable FIFO mode (enable direct)
|
||||||
|
|
|
@ -3,26 +3,28 @@
|
||||||
#define FAULT_STATUS_PERMANENT 2U
|
#define FAULT_STATUS_PERMANENT 2U
|
||||||
|
|
||||||
// Fault types
|
// Fault types
|
||||||
#define FAULT_RELAY_MALFUNCTION (1U << 0)
|
#define FAULT_RELAY_MALFUNCTION (1U << 0)
|
||||||
#define FAULT_UNUSED_INTERRUPT_HANDLED (1U << 1)
|
#define FAULT_UNUSED_INTERRUPT_HANDLED (1U << 1)
|
||||||
#define FAULT_INTERRUPT_RATE_CAN_1 (1U << 2)
|
#define FAULT_INTERRUPT_RATE_CAN_1 (1U << 2)
|
||||||
#define FAULT_INTERRUPT_RATE_CAN_2 (1U << 3)
|
#define FAULT_INTERRUPT_RATE_CAN_2 (1U << 3)
|
||||||
#define FAULT_INTERRUPT_RATE_CAN_3 (1U << 4)
|
#define FAULT_INTERRUPT_RATE_CAN_3 (1U << 4)
|
||||||
#define FAULT_INTERRUPT_RATE_TACH (1U << 5)
|
#define FAULT_INTERRUPT_RATE_TACH (1U << 5)
|
||||||
#define FAULT_INTERRUPT_RATE_GMLAN (1U << 6)
|
#define FAULT_INTERRUPT_RATE_GMLAN (1U << 6)
|
||||||
#define FAULT_INTERRUPT_RATE_INTERRUPTS (1U << 7)
|
#define FAULT_INTERRUPT_RATE_INTERRUPTS (1U << 7)
|
||||||
#define FAULT_INTERRUPT_RATE_SPI_DMA (1U << 8)
|
#define FAULT_INTERRUPT_RATE_SPI_DMA (1U << 8)
|
||||||
#define FAULT_INTERRUPT_RATE_SPI_CS (1U << 9)
|
#define FAULT_INTERRUPT_RATE_SPI_CS (1U << 9)
|
||||||
#define FAULT_INTERRUPT_RATE_UART_1 (1U << 10)
|
#define FAULT_INTERRUPT_RATE_UART_1 (1U << 10)
|
||||||
#define FAULT_INTERRUPT_RATE_UART_2 (1U << 11)
|
#define FAULT_INTERRUPT_RATE_UART_2 (1U << 11)
|
||||||
#define FAULT_INTERRUPT_RATE_UART_3 (1U << 12)
|
#define FAULT_INTERRUPT_RATE_UART_3 (1U << 12)
|
||||||
#define FAULT_INTERRUPT_RATE_UART_5 (1U << 13)
|
#define FAULT_INTERRUPT_RATE_UART_5 (1U << 13)
|
||||||
#define FAULT_INTERRUPT_RATE_UART_DMA (1U << 14)
|
#define FAULT_INTERRUPT_RATE_UART_DMA (1U << 14)
|
||||||
#define FAULT_INTERRUPT_RATE_USB (1U << 15)
|
#define FAULT_INTERRUPT_RATE_USB (1U << 15)
|
||||||
#define FAULT_INTERRUPT_RATE_TIM1 (1U << 16)
|
#define FAULT_INTERRUPT_RATE_TIM1 (1U << 16)
|
||||||
#define FAULT_INTERRUPT_RATE_TIM3 (1U << 17)
|
#define FAULT_INTERRUPT_RATE_TIM3 (1U << 17)
|
||||||
#define FAULT_REGISTER_DIVERGENT (1U << 18)
|
#define FAULT_REGISTER_DIVERGENT (1U << 18)
|
||||||
#define FAULT_INTERRUPT_RATE_KLINE_INIT (1U << 19)
|
#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
|
// Permanent faults
|
||||||
#define PERMANENT_FAULTS 0U
|
#define PERMANENT_FAULTS 0U
|
||||||
|
|
|
@ -64,13 +64,9 @@ void early(void) {
|
||||||
|
|
||||||
if (enter_bootloader_mode == ENTER_BOOTLOADER_MAGIC) {
|
if (enter_bootloader_mode == ENTER_BOOTLOADER_MAGIC) {
|
||||||
#ifdef PANDA
|
#ifdef PANDA
|
||||||
current_board->set_esp_gps_mode(ESP_GPS_DISABLED);
|
current_board->set_gps_mode(GPS_DISABLED);
|
||||||
#endif
|
#endif
|
||||||
current_board->set_led(LED_GREEN, 1);
|
current_board->set_led(LED_GREEN, 1);
|
||||||
jump_to_bootloader();
|
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
|
// **** 0xd9: set ESP power
|
||||||
case 0xd9:
|
case 0xd9:
|
||||||
if (setup->b.wValue.w == 1U) {
|
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) {
|
} else if (setup->b.wValue.w == 2U) {
|
||||||
current_board->set_esp_gps_mode(ESP_GPS_BOOTMODE);
|
current_board->set_gps_mode(GPS_BOOTMODE);
|
||||||
} else {
|
} else {
|
||||||
current_board->set_esp_gps_mode(ESP_GPS_DISABLED);
|
current_board->set_gps_mode(GPS_DISABLED);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
// **** 0xda: reset ESP, with optional boot mode
|
// **** 0xda: reset ESP, with optional boot mode
|
||||||
case 0xda:
|
case 0xda:
|
||||||
current_board->set_esp_gps_mode(ESP_GPS_DISABLED);
|
current_board->set_gps_mode(GPS_DISABLED);
|
||||||
delay(1000000);
|
delay(1000000);
|
||||||
if (setup->b.wValue.w == 1U) {
|
if (setup->b.wValue.w == 1U) {
|
||||||
current_board->set_esp_gps_mode(ESP_GPS_BOOTMODE);
|
current_board->set_gps_mode(GPS_BOOTMODE);
|
||||||
} else {
|
} else {
|
||||||
current_board->set_esp_gps_mode(ESP_GPS_ENABLED);
|
current_board->set_gps_mode(GPS_ENABLED);
|
||||||
}
|
}
|
||||||
delay(1000000);
|
delay(1000000);
|
||||||
current_board->set_esp_gps_mode(ESP_GPS_ENABLED);
|
current_board->set_gps_mode(GPS_ENABLED);
|
||||||
break;
|
break;
|
||||||
// **** 0xdb: set GMLAN (white/grey) or OBD CAN (black) multiplexing mode
|
// **** 0xdb: set GMLAN (white/grey) or OBD CAN (black) multiplexing mode
|
||||||
case 0xdb:
|
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
|
// 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);
|
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;
|
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:
|
default:
|
||||||
puts("NO HANDLER ");
|
puts("NO HANDLER ");
|
||||||
puth(setup->b.bRequest);
|
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_ON 5U
|
||||||
#define EON_HEARTBEAT_IGNITION_CNT_OFF 2U
|
#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) {
|
void TIM1_BRK_TIM9_IRQ_Handler(void) {
|
||||||
if (TIM9->SR != 0) {
|
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
|
//puth(usart1_dma); puts(" "); puth(DMA2_Stream5->M0AR); puts(" "); puth(DMA2_Stream5->NDTR); puts("\n");
|
||||||
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
|
|
||||||
|
|
||||||
// Tick drivers
|
// reset this every 16th pass
|
||||||
fan_tick();
|
if ((uptime_cnt & 0xFU) == 0U) {
|
||||||
|
pending_can_live = 0;
|
||||||
// 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);
|
|
||||||
}
|
}
|
||||||
if (power_save_status != POWER_SAVE_STATUS_ENABLED) {
|
#ifdef DEBUG
|
||||||
set_power_save_state(POWER_SAVE_STATUS_ENABLED);
|
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
|
#ifdef EON
|
||||||
current_board->set_ir_power(0U);
|
// 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
|
// Also disable IR when the heartbeat goes missing
|
||||||
if(usb_enumerated()){
|
current_board->set_ir_power(0U);
|
||||||
current_board->set_fan_power(50U);
|
|
||||||
} else {
|
// If enumerated but no heartbeat (phone up, boardd not running), turn the fan on to cool the device
|
||||||
current_board->set_fan_power(0U);
|
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
|
loop_counter++;
|
||||||
if (check_started() && (usb_power_mode != USB_POWER_CDP)) {
|
loop_counter %= 8U;
|
||||||
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);
|
|
||||||
}
|
}
|
||||||
TIM9->SR = 0;
|
TIM9->SR = 0;
|
||||||
}
|
}
|
||||||
|
@ -753,8 +771,8 @@ int main(void) {
|
||||||
// Init interrupt table
|
// Init interrupt table
|
||||||
init_interrupts(true);
|
init_interrupts(true);
|
||||||
|
|
||||||
// 1s timer
|
// 8Hz timer
|
||||||
REGISTER_INTERRUPT(TIM1_BRK_TIM9_IRQn, TIM1_BRK_TIM9_IRQ_Handler, 2U, FAULT_INTERRUPT_RATE_TIM1)
|
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
|
// shouldn't have interrupts here, but just in case
|
||||||
disable_interrupts();
|
disable_interrupts();
|
||||||
|
@ -778,7 +796,6 @@ int main(void) {
|
||||||
puts("Config:\n");
|
puts("Config:\n");
|
||||||
puts(" Board type: "); puts(current_board->board_type); puts("\n");
|
puts(" Board type: "); puts(current_board->board_type); puts("\n");
|
||||||
puts(has_external_debug_serial ? " Real serial\n" : " USB serial\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
|
// init board
|
||||||
current_board->init();
|
current_board->init();
|
||||||
|
@ -794,10 +811,10 @@ int main(void) {
|
||||||
}
|
}
|
||||||
|
|
||||||
if (board_has_gps()) {
|
if (board_has_gps()) {
|
||||||
uart_init(&uart_ring_esp_gps, 9600);
|
uart_init(&uart_ring_gps, 9600);
|
||||||
} else {
|
} else {
|
||||||
// enable ESP uart
|
// enable ESP uart
|
||||||
uart_init(&uart_ring_esp_gps, 115200);
|
uart_init(&uart_ring_gps, 115200);
|
||||||
}
|
}
|
||||||
|
|
||||||
if(board_has_lin()){
|
if(board_has_lin()){
|
||||||
|
@ -820,14 +837,14 @@ int main(void) {
|
||||||
set_safety_mode(SAFETY_SILENT, 0);
|
set_safety_mode(SAFETY_SILENT, 0);
|
||||||
|
|
||||||
// enable CAN TXs
|
// enable CAN TXs
|
||||||
current_board->enable_can_transcievers(true);
|
current_board->enable_can_transceivers(true);
|
||||||
|
|
||||||
#ifndef EON
|
#ifndef EON
|
||||||
spi_init();
|
spi_init();
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// 1hz
|
// 8hz
|
||||||
timer_init(TIM9, 1464);
|
timer_init(TIM9, 183);
|
||||||
NVIC_EnableIRQ(TIM1_BRK_TIM9_IRQn);
|
NVIC_EnableIRQ(TIM1_BRK_TIM9_IRQn);
|
||||||
|
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
|
|
|
@ -13,3 +13,4 @@ const board *current_board;
|
||||||
bool is_enumerated = 0;
|
bool is_enumerated = 0;
|
||||||
uint32_t heartbeat_counter = 0;
|
uint32_t heartbeat_counter = 0;
|
||||||
uint32_t uptime_cnt = 0;
|
uint32_t uptime_cnt = 0;
|
||||||
|
bool siren_enabled = false;
|
||||||
|
|
|
@ -28,13 +28,13 @@ void set_power_save_state(int state) {
|
||||||
enable = true;
|
enable = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
current_board->enable_can_transcievers(enable);
|
current_board->enable_can_transceivers(enable);
|
||||||
|
|
||||||
// Switch EPS/GPS
|
// Switch EPS/GPS
|
||||||
if (enable) {
|
if (enable) {
|
||||||
current_board->set_esp_gps_mode(ESP_GPS_ENABLED);
|
current_board->set_gps_mode(GPS_ENABLED);
|
||||||
} else {
|
} else {
|
||||||
current_board->set_esp_gps_mode(ESP_GPS_DISABLED);
|
current_board->set_gps_mode(GPS_DISABLED);
|
||||||
}
|
}
|
||||||
|
|
||||||
if(board_has_gmlan()){
|
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 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 uint32_t HYUNDAI_RT_INTERVAL = 250000; // 250ms between real time checks
|
||||||
const int HYUNDAI_MAX_RATE_UP = 3;
|
const int HYUNDAI_MAX_RATE_UP = 3;
|
||||||
|
|
|
@ -290,7 +290,7 @@ void soft_flasher_start(void) {
|
||||||
// B8,B9: CAN 1
|
// B8,B9: CAN 1
|
||||||
set_gpio_alternate(GPIOB, 8, GPIO_AF9_CAN1);
|
set_gpio_alternate(GPIOB, 8, GPIO_AF9_CAN1);
|
||||||
set_gpio_alternate(GPIOB, 9, 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
|
// init can
|
||||||
llcan_set_speed(CAN1, 5000, false, false);
|
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 subprocess
|
||||||
import sys
|
import sys
|
||||||
from .dfu import PandaDFU # pylint: disable=import-error
|
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 .flash_release import flash_release # noqa pylint: disable=import-error
|
||||||
from .update import ensure_st_up_to_date # 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
|
from .serial import PandaSerial # noqa pylint: disable=import-error
|
||||||
|
@ -148,6 +147,10 @@ class Panda(object):
|
||||||
HW_TYPE_PEDAL = b'\x04'
|
HW_TYPE_PEDAL = b'\x04'
|
||||||
HW_TYPE_UNO = b'\x05'
|
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):
|
def __init__(self, serial=None, claim=True):
|
||||||
self._serial = serial
|
self._serial = serial
|
||||||
self._handle = None
|
self._handle = None
|
||||||
|
@ -458,7 +461,7 @@ class Panda(object):
|
||||||
self._handle.controlWrite(Panda.REQUEST_OUT, 0xe5, int(enable), 0, b'')
|
self._handle.controlWrite(Panda.REQUEST_OUT, 0xe5, int(enable), 0, b'')
|
||||||
|
|
||||||
def set_can_enable(self, bus_num, enable):
|
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'')
|
self._handle.controlWrite(Panda.REQUEST_OUT, 0xf4, int(bus_num), int(enable), b'')
|
||||||
|
|
||||||
def set_can_speed_kbps(self, bus, speed):
|
def set_can_speed_kbps(self, bus, speed):
|
||||||
|
@ -665,3 +668,11 @@ class Panda(object):
|
||||||
# ****************** Phone *****************
|
# ****************** Phone *****************
|
||||||
def set_phone_power(self, enabled):
|
def set_phone_power(self, enabled):
|
||||||
self._handle.controlWrite(Panda.REQUEST_OUT, 0xb3, int(enabled), 0, b'')
|
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._handle = device.open()
|
||||||
self.legacy = "07*128Kg" in self._handle.getASCIIStringDescriptor(4)
|
self.legacy = "07*128Kg" in self._handle.getASCIIStringDescriptor(4)
|
||||||
return
|
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
|
@staticmethod
|
||||||
def list():
|
def list():
|
||||||
|
|
|
@ -7,7 +7,7 @@ import json
|
||||||
import io
|
import io
|
||||||
|
|
||||||
def flash_release(path=None, st_serial=None):
|
def flash_release(path=None, st_serial=None):
|
||||||
from panda import Panda, PandaDFU, ESPROM, CesantaFlasher
|
from panda import Panda, PandaDFU
|
||||||
from zipfile import ZipFile
|
from zipfile import ZipFile
|
||||||
|
|
||||||
def status(x):
|
def status(x):
|
||||||
|
@ -23,33 +23,28 @@ def flash_release(path=None, st_serial=None):
|
||||||
st_serial = panda_list[0]
|
st_serial = panda_list[0]
|
||||||
print("Using panda with serial %s" % st_serial)
|
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")
|
print("Fetching latest firmware from github.com/commaai/panda-artifacts")
|
||||||
r = requests.get("https://raw.githubusercontent.com/commaai/panda-artifacts/master/latest.json")
|
r = requests.get("https://raw.githubusercontent.com/commaai/panda-artifacts/master/latest.json")
|
||||||
url = json.loads(r.text)['url']
|
url = json.loads(r.text)['url']
|
||||||
r = requests.get(url)
|
r = requests.get(url)
|
||||||
print("Fetching firmware from %s" % url)
|
print("Fetching firmware from %s" % url)
|
||||||
path = io.StringIO(r.content)
|
path = io.BytesIO(r.content)
|
||||||
|
|
||||||
zf = ZipFile(path)
|
zf = ZipFile(path)
|
||||||
zf.printdir()
|
zf.printdir()
|
||||||
|
|
||||||
version = zf.read("version")
|
version = zf.read("version").decode()
|
||||||
status("0. Preparing to flash " + version)
|
status("0. Preparing to flash " + str(version))
|
||||||
|
|
||||||
code_bootstub = zf.read("bootstub.panda.bin")
|
code_bootstub = zf.read("bootstub.panda.bin")
|
||||||
code_panda = zf.read("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
|
# enter DFU mode
|
||||||
status("1. Entering DFU mode")
|
status("1. Entering DFU mode")
|
||||||
panda = Panda(st_serial)
|
panda = Panda(st_serial)
|
||||||
panda.enter_bootloader()
|
panda.reset(enter_bootstub=True)
|
||||||
|
panda.reset(enter_bootloader=True)
|
||||||
time.sleep(1)
|
time.sleep(1)
|
||||||
|
|
||||||
# program bootstub
|
# program bootstub
|
||||||
|
@ -64,29 +59,8 @@ def flash_release(path=None, st_serial=None):
|
||||||
panda.flash(code=code_panda)
|
panda.flash(code=code_panda)
|
||||||
panda.close()
|
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
|
# check for connection
|
||||||
status("5. Verifying version")
|
status("4. Verifying version")
|
||||||
panda = Panda(st_serial)
|
panda = Panda(st_serial)
|
||||||
my_version = panda.get_version()
|
my_version = panda.get_version()
|
||||||
print("dongle id: %s" % panda.get_serial()[0])
|
print("dongle id: %s" % panda.get_serial()[0])
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
import os
|
import os
|
||||||
|
import platform
|
||||||
from cffi import FFI
|
from cffi import FFI
|
||||||
|
|
||||||
TEMPLATE_DIR = os.path.abspath(os.path.join(os.path.dirname(__file__), '..', 'templates'))
|
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):
|
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")
|
header_fn = os.path.join(folder, f"{name}.h")
|
||||||
|
|
||||||
with open(header_fn) as f:
|
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 |