Compare commits

..

36 Commits

Author SHA1 Message Date
Willem Melching f6e8ef2754 Merge pull request #660 from commaai/devel
Openpilot 0.5.12
2019-05-22 15:36:17 -07:00
Nigel Armstrong d1866845df Merge pull request #634 from commaai/devel 0.5.11 Release
0.5.11 Devel -> Release2
2019-05-09 16:45:28 -07:00
Nigel Armstrong ff4c1557d8 Merge pull request #589 from commaai/devel
0.5.10 Devel -> Release2
2019-04-02 00:30:34 -07:00
Nigel Armstrong ad145da3bc Merge pull request #540 from commaai/devel
0.5.9 Release
2019-02-25 10:54:11 -08:00
rbiasini 2cee2e05ba Merge pull request #519 from commaai/devel
release 0.5.8
2019-01-31 17:01:04 -08:00
rbiasini 9ce3045f13 Merge pull request #470 from commaai/devel
0.5.7 release
2018-12-17 20:36:42 -07:00
rbiasini 9398a28be2 Merge pull request #448 from commaai/devel
0.5.6 release
2018-11-29 20:56:55 -08:00
rbiasini 9a42f2f1ad Merge pull request #434 from commaai/devel
calibration improvements and devel synch up
2018-11-13 18:50:56 -08:00
rbiasini 7c0202a101 Merge pull request #410 from commaai/devel
Improve Toyota radar filtering (#409)
2018-10-26 20:37:50 -07:00
rbiasini 18801659c5 Merge pull request #405 from commaai/devel
0.5.5 release
2018-10-25 17:34:53 -07:00
Willem Melching a488442402 Revert the changes to GM in 0.5.4 (#380) (#386)
* Revert 0.5.4 changes for GM for 18ers

* Redo the refactor of stock control msgs

* Fixed missing CONTROL_MSGS -> STOCK_CONTROL_MSGS

* Remove spacing

* Need candidate array idx
2018-10-03 21:03:09 +02:00
rbiasini ed6957540f Merge pull request #379 from commaai/devel
Release 0.5.4
2018-09-28 08:14:14 +02:00
rbiasini 999edf243e Merge pull request #359 from commaai/devel
0.5.3
2018-09-11 07:15:58 +02:00
rbiasini 63adcfc28c Merge pull request #329 from commaai/devel
0.5.2
2018-08-27 12:49:11 -07:00
Vehicle Researcher 8f22f52235 openpilot v0.5.1 release (#315)
Merge commit '2cfdc676101c387524246f789c8429647069b827' into release2
2018-08-27 12:21:14 -07:00
George Hotz 0ea21f3545 Merge pull request #293 from commaai/devel
0.5.0 release
2018-07-13 22:37:09 -07:00
George Hotz 27c7425b94 Merge pull request #277 from commaai/devel
openpilot 0.4.7.2
2018-06-28 11:22:35 -07:00
George Hotz 30b72e4be1 Merge pull request #267 from commaai/devel
openpilot 0.4.7.1
2018-06-19 09:18:12 -07:00
George Hotz afdda0e5fc Merge pull request #256 from commaai/devel
0.4.6 Release
2018-05-30 11:19:03 -07:00
George Hotz 88d1dd2bad Merge pull request #239 from commaai/devel
openpilot 0.4.5.1 release
2018-05-01 18:13:46 -07:00
George Hotz 3e491431a3 Merge pull request #226 from commaai/revert-220-devel
Revert "openpilot 0.4.3.1"
2018-03-26 15:18:53 -06:00
George Hotz f550656ee8 Revert "openpilot 0.4.3.1 (#220)"
This reverts commit 640ab12c72.
2018-03-26 14:13:40 -07:00
George Hotz 640ab12c72 openpilot 0.4.3.1 (#220)
* Honda Pilot 2017 Port (#161)

* Update README.md

* Update fingerprints.py

* Update carstate.py

* Update hondacan.py

* Update interface.py

* Update interface.py

* Update interface.py

* Update README.md

* Update README.md

* Update README.md

* Update fingerprints.py

* Update carstate.py

* Update hondacan.py

* Update interface.py

* Update carstate.py

* Update hondacan.py

* Update README.md

* Update fingerprints.py

* Update carstate.py

* Update carstate.py

* Update carstate.py

* Update hondacan.py

* Update interface.py

* Update carstate.py

* Update carstate.py

* Update Pilot Fingerprint

* Update fingerprints.py

* Give pilot its own definition and not use ILX

* add pilot argument

* Add Pilot interface

* Add pilot argument

* Update interface.py

* Parse Different gear on pilot

* Add steer max

* Fixed duplication of steer max value

* Adjust PID's for steering

* Update carcontroller.py

* Change Steer Ratio and wheelbase

* Update Steer fault values

Steer fault value of 3, does not seem to effect anything

* Update Kp,Ki Ratio

* Update interface.py

* Update readme for Pilot

* add pilot

* Update fingerprints.py

* Update carstate.py

* add signals

* add signal

* fix restricting video upload to wifi

* Dibs on SAFETY_GM numerical value

To match Panda repo.

* Safety Reference for Honda Bosch

* Update fingerprints.py (#210)

Consolidated my fingerprint and removed duplicates and ordered the fingerprint for the RAV4H. Double Checked.

* Interpolate ki/kp for steering PID loop (#200)

* Interpolate ki/kp for steering PID loop

Very much needed for the Volt port: car ping-pongs with low kp
on high speeeds, and the loop is unstable with high kp on
low speeds.

Also, removes "number or array?" logic from PIController,
now that all the callers use interpolation ofr ki/kp.

* Pass speed to steering PID loop for ki/kp interpolation

* Remove unused numbers import

* Slight changes to UI and Fingerprint for Odyssey Elite (#196)

* Adding back drive time to UI

* Add fingerprint for Odyssey Elite

* Removed extended fingerprint for Elite

* Revert "Adding back drive time to UI"

This reverts commit b9b02f7ff2511f28922f0bea47cd8c70bb9f4010.

* Squashed 'panda/' changes from 98f29a4..67d5208

67d5208 fix signedness issue in toyota safety
fe15d3f bump pandacan
11c2b08 add fault invalid
2c26e45 add sleep
27c7637 forgot the counter
3a6d7db don't hang
bfa7d2e canloader works
b259e2a can flasher is close to working
83f2edf isotp can support in softloader
7ae7c79 typo
e85cc47 forgot the selfs
190b4f6 start work on canflasher
5c655c9 add recover support
ae3457f usbflash is reliable
f7a0ab0 pedal usbflash works
585d0f9 add way to call isotp
be82899 despite it being bad code, move isotp
000715b start work on pedal canloader
626e312 pedal has a bootstub now
3662d1e redundant check
81e6b0d fix bug
083cd12 should have bounty to refactor that ish
b65d30c bad asserts
b2e6c3f isotp untested support for subaddr
30fd66a Merge pull request #93 from vntarasov/volt
06f5109 Merge pull request #94 from gregjhogan/can-printer-hex
c7d098c Merge pull request #95 from gregjhogan/setup-script
22fe250 Merge pull request #99 from gregjhogan/bit-transition-example
ba16ba3 Merge pull request #100 from gregjhogan/j2534-troubleshooting-instructions
ad08ea4 Merge pull request #90 from gregjhogan/can-forwarding
f3b6f5d added j2534 troubleshooting instructions
858d150 added script to find bits that transition from 0 to 1
c6acac8 added checking pedal interceptor message length
f7226ff added brake safety checks
d0c2634 added gas safety checks
d378e4a removed bosch safety forwarding restriction on 29 bit addresses
5c7ef9e added bosch safety hooks and forwarding
90c64b6 add note
23de8d4 Merge pull request #97 from commaai/pedal_improvements
0261641 added missing python packages
b92b235 fix bytearray encode issue
2434f1c Tweak Volt's brake pedal stickiness
e2f73d2 enable has a whole byte to itself
d5a9e1e correct checksum
f8ed9fa better names
986a14c don't alias pointers
9b8472e add watchdog support
8f0add9 handle faults
1d917f8 split gas set into 2 values, and have a fault state
1b77026 j2534 isn't alpha anymore
fbcc872 Merge pull request #92 from commaai/pedal
8a6f44b pedal is sending messages
08f464c python 3 bro is bad bro
9390961 kline checksum algo was broken...
3b7c33b add kline debug support
aa622bc init values
631ea9f better refactor
eb1fd75 add PEDAL adc sets
ccaa310 don't build with usb
8d4d763 debug console works
bd09883 comma pedal is building
75a29d5 Merge pull request #84 from gregjhogan/j2534-hds
eece37d only the panda has gmlan
9f43abe Merge pull request #89 from vntarasov/volt
5364d43 Merge pull request #88 from vntarasov/smaller-firmware
377a1ec bump version for descriptor fix
4fabdf0 Merge pull request #87 from gregjhogan/usb-multi-packet-control
8580773 fix sending WinUSB Extended Properties Feature Descriptor
6908feb Chevy Volt safety
786a004 Enable optimization to reduce firmware size
d70f43b hack to fix thinkpad
95ab1ae fixed flow control message padding
bbd04d1 updated installer
62216d0 single standalone DLL for J2534 driver
5c9138d fixed 11 bit address issue
f3b0ad2 fix LOOPBACK getting set when DATA_RATE is set
b750d36 updated README
a9a097f lowered CPU utilization
7c26a70 TIS needs unsupported protocols to return an error
42692b4 TIS doesn't like ChannelID being zero
cf126bb SET_CONFIG return error for reserved parameters
2e99dbf fix HDS issues
8203cc8 add is_grey
e946a54 add insecure_okay flag
4363b3e check webpage
4f59ded add secure mode note
6b11fb5 add autosecuring to tests
b27d185 Merge pull request #86 from commaai/better_pairing
4b53b42 elm wifi isn't an automated test
99f85cb Merge pull request #85 from gregjhogan/usb-wcid
0d38060 auto-install WinUSB device driver
c6653ca from python import
38cc0ee add wifi_secure_mode, boots in insecure mode

git-subtree-dir: panda
git-subtree-split: 67d52089a1300b86800d897f2b271e0a24cf6dd6

* Squashed 'opendbc/' changes from 81d9871..aa067f7

aa067f7 Chevy Volt tweaks (#83)
a60c6c4 Toyota: change signal name in EPS_STATUS msg
ce70b1a extra setme field toyota LKAS_HUD
df2a552 toyota missing ACC_CONTROL checksum
48bb293 Revert "Toyota Prius: added a comma specific message to control the speed sent to the EPS"
5f42439 Toyota Prius: added a comma specific message to control the speed sent to the EPS
6f5e8b6 Pedal Interceptor: fault state VAL moved to _comma
efd5f5c add setme to honda ACC_HUD
97fc335 add interceptor to civic
6f40f16 update generator script to allow for multiple imports
9ca956b add setme to toyota STEERING_IPAS
e5afa57 run generator for ipas scaling
8bd1182 Toyota IPAS: proper steer angle unit
f57511e acceleration pedal for gasPressed
c8d1dbc high beams also. likely dashboard message.
9f1c78b high beams for genericToggle
f037d42 turn signal lights (and thus hazard lights)
b35bb08 turn signals
78986cf Revert "turn signals"
ba946c9 turn signals
2af3ecc Speed, braking, and distance signals
f40ab87 Set packet lengths, adding steering rate, adjusted speed
cd59bfa units for speed_right
c2fcce2 speed of right vs left side of car
4ef5fae value table for gear status
97c48e2 tighten up speed bits. brake pressue max comment.
a0cbfd1 add gear status PRNDL
0c82865 initial signals for chrysler pacifica 2017 hybrid
5ed0540 add set me to toyota LKAS_HUD
aecac5d add set me fields to toyota ACC_HUD
5417013 update toyota ACC_CONTROL fields
e91e967 Comma Pedal: made GAS_COMMAND 6 bytes
d04434a Comma Pedal: added state byte and enable bit
c30b2cd Comma Pedal: sending 2 tracks on 0x200
8f72467 Volt doors and belts status (#70)
60f8b6c add set me to lkas hud honda
3c9e335 fix honda pcm gas message size
7ca471d Add 2018 Toyota CHR dbc (#78)
637fe00 set scaling to 1 for brake and gas which have no real unit
62a88d4 Volt: switch to parsing ACC buttons from powertrain CAN (#74)
3fdd47b Volt's gas pedal only and combined gas/acc (#76)
45ec9c9 Add 2017 Honda Ridgeline (#77)
cbd186a Add 2018 Camry Hybrid DBC's (#73)
974eeaf Toyota: re-generated the files after cfbc9ae363f98ef
19ea195 Toyota: more vals for LKA_STATE
cfbc9ae fixed inconsistent factor for speed in Honda dbc files
e7db803 convert all line endings to unix style

git-subtree-dir: opendbc
git-subtree-split: aa067f7079aa12617f7a37d85233e51af44e1bb2

* openpilot v0.4.3 release

* Squashed 'panda/' changes from 67d5208..3125232

3125232 bump version
703c0b4 Gas Interceptor: another fix to gas pressed logic
196d383 Interceptor: fixed gas pressed logic

git-subtree-dir: panda
git-subtree-split: 31252324d98e701c33cb6aeda20af6b549175764

* Squashed 'opendbc/' changes from aa067f7..91e882d

91e882d Updating bosch dbcs to use new format and bringing in new honda changes (#82)
9b32e2e Fix Checksum errors for CH-R (#86)

git-subtree-dir: opendbc
git-subtree-split: 91e882d4a04c129e12d39bcff0bbe56b75166e0f

* openpilot v0.4.3 release

* openpilot v0.4.3.1 release

* fix bug in canpacker for Toyotas with DSU connected (#221)

* update year on civic
2018-03-22 22:11:57 -07:00
George Hotz affc00df1f Merge pull request #188 from commaai/devel
0.4.2
2018-02-08 17:09:41 -08:00
ErichMoraga e343c95720 Update fingerprints.py
Taiwanese Prius Prime fingerprint was identical to the regular prime (107 msgs.), but should really have 110.  I have the correct one in there now.
2018-02-05 14:11:35 -08:00
George Hotz 89605ed88a Merge pull request #184 from commaai/devel
openpilot v0.4.1 hotfix
2018-02-02 19:46:57 -08:00
George Hotz 10cb834c39 Merge pull request #183 from commaai/devel
openpilot v0.4.1
2018-02-02 15:51:53 -08:00
George Hotz 675d9feb0b Merge pull request #176 from commaai/devel
openpilot v0.4.0.2
2018-01-22 09:55:06 -08:00
espes c2e120c362 Merge pull request #165 from commaai/devel
openpilot v0.4.0.1
2018-01-17 01:08:47 -08:00
George Hotz 5ae7119646 Merge pull request #154 from commaai/devel
openpilot v0.3.9
2017-12-07 19:22:41 -08:00
espes 5864323c7d Merge pull request #146 from commaai/devel
openpilot v0.3.8.2
2017-11-04 05:32:49 -07:00
espes 577608be57 Merge pull request #137 from commaai/devel
openpilot v0.3.7
2017-10-04 03:51:03 -07:00
espes 606c21bca4 Merge pull request #126 from commaai/devel
openpilot v0.3.6.1
2017-08-17 08:59:30 +02:00
espes cd25fac75d Merge pull request #123 from commaai/devel
openpilot v0.3.6
2017-08-11 09:00:23 +02:00
espes b111277f46 Merge pull request #121 from commaai/devel
openpilot v0.3.5 release
2017-07-31 09:02:27 +02:00
espes 0fba33b093 Merge pull request #120 from commaai/devel
openpilot 0.3.4
2017-07-29 07:41:31 +02:00
1435 changed files with 179148 additions and 98020 deletions
-4
View File
@@ -1,4 +1,3 @@
venv/
.DS_Store
.tags
.ipynb_checkpoints
@@ -35,6 +34,3 @@ selfdrive/visiond/visiond
/src/
one
openpilot
xx
+2 -2
View File
@@ -10,9 +10,9 @@ script:
- docker run
tmppilot /bin/sh -c 'cd /tmp/openpilot/selfdrive/test/ && ./test_fingerprints.py'
- docker run
tmppilot /bin/sh -c 'cd /tmp/openpilot/ && pyflakes $(find . -iname "*.py" | grep -vi "^\./pyextra.*" | grep -vi "^\./panda" | grep -vi "^\./tools")'
tmppilot /bin/sh -c 'cd /tmp/openpilot/ && pyflakes $(find . -iname "*.py" | grep -vi "^\./pyextra.*" | grep -vi "^\./panda")'
- docker run
tmppilot /bin/sh -c 'cd /tmp/openpilot/ && pylint $(find . -iname "*.py" | grep -vi "^\./pyextra.*" | grep -vi "^\./panda" | grep -vi "^\./tools"); exit $(($? & 3))'
tmppilot /bin/sh -c 'cd /tmp/openpilot/ && pylint $(find . -iname "*.py" | grep -vi "^\./pyextra.*" | grep -vi "^\./panda"); exit $(($? & 3))'
- docker run tmppilot /bin/sh -c 'cd /tmp/openpilot/ && make -C cereal && python -m unittest discover common'
- docker run tmppilot /bin/sh -c 'cd /tmp/openpilot/ && make -C cereal && python -m unittest discover selfdrive/can'
- docker run tmppilot /bin/sh -c 'cd /tmp/openpilot/ && make -C cereal && python -m unittest discover selfdrive/boardd'
+10 -23
View File
@@ -4,45 +4,32 @@ ENV PYTHONUNBUFFERED 1
RUN apt-get update && apt-get install -y \
autoconf \
build-essential \
bzip2 \
clang \
wget \
bzip2 \
git \
libarchive-dev \
libavcodec-dev \
libavdevice-dev \
libavfilter-dev \
libavresample-dev \
libavutil-dev \
libffi-dev \
libglib2.0-0 \
libssl-dev \
libswscale-dev \
libtool \
libusb-1.0-0 \
python-pip \
libzmq5-dev \
libffi-dev \
libusb-1.0-0 \
libssl-dev \
ocl-icd-libopencl1 \
ocl-icd-opencl-dev \
opencl-headers \
pkg-config \
python-pip \
wget
opencl-headers
COPY phonelibs/install_capnp.sh /tmp/install_capnp.sh
RUN /tmp/install_capnp.sh
RUN pip install --upgrade pip==18.0
RUN pip install pipenv==2018.11.26
RUN pip install numpy==1.11.2 scipy==0.18.1 matplotlib==2.1.2
COPY Pipfile /tmp/
COPY Pipfile.lock /tmp/
RUN cd /tmp && pipenv install --deploy --system
COPY requirements_openpilot.txt /tmp/
RUN pip install -r /tmp/requirements_openpilot.txt
ENV PYTHONPATH /tmp/openpilot:$PYTHONPATH
RUN git clone --branch v0.6 https://github.com/commaai/openpilot-tools.git /tmp/openpilot/tools
RUN pip install -r /tmp/openpilot/tools/requirements.txt
RUN pip install fastcluster==1.1.20 scipy==0.19.1
COPY ./.pylintrc /tmp/openpilot/.pylintrc
COPY ./common /tmp/openpilot/common
COPY ./cereal /tmp/openpilot/cereal
-140
View File
@@ -1,140 +0,0 @@
[[source]]
name = "pypi"
url = "https://pypi.org/simple"
verify_ssl = true
[dev-packages]
ipython = "<6.0"
aenum = "*"
azure-batch = "==4.1.3"
azure-common = "==1.1.16"
azure-nspkg = "==3.0.1"
azure-storage-blob = "==1.3.1"
azure-storage-common = "==1.3.0"
azure-storage-nspkg = "==3.0.0"
bincopy = "*"
bleach = "==1.5.0"
boto = "*"
"boto3" = "*"
celery = "*"
control = "*"
datadog = "*"
decorator = "*"
dlib = "*"
dominate = "*"
elasticsearch = "*"
entium = "==0.1.4"
fasteners = "*"
future = "*"
futures = "*"
gevent = "*"
pycocotools = {git = "https://github.com/cocodataset/cocoapi.git",subdirectory = "PythonAPI"}
gunicorn = "*"
"h5py" = "*"
hexdump = "*"
"html5lib" = "==0.9999999"
imageio = "*"
intervaltree = "*"
ipykernel = "<5.0"
joblib = "*"
json-logging-py = "*"
jupyter = "*"
libarchive = "*"
lru-dict = "*"
lxml = "*"
matplotlib = "==2.2.3"
"mpld3" = "*"
msgpack-python = "*"
nbstripout = "*"
nose-parameterized = "*"
numpy = "==1.14.5"
osmium = "==2.15.0"
pbr = "==5.1.3"
percache = "*"
pprofile = "*"
psutil = "*"
pycurl = "*"
git-pylint-commit-hook = "==2.5.1"
pymongo = "*"
"pynmea2" = "*"
pypolyline = "==0.1.17"
pysendfile = "*"
python-logstash = "*"
pyvcd = "*"
redis = "*"
redlock = "*"
"s2sphere" = "*"
scikit-image = "*"
"subprocess32" = "*"
supervisor = "*"
tenacity = "*"
tensorflow-gpu = "==1.13.0rc0"
"transforms3d" = "*"
utm = "*"
"v4l2" = "*"
visdom = "*"
PyJWT = "==1.4.1"
PyMySQL = "==0.9.2"
Theano = "*"
Werkzeug = "*"
"backports.lzma" = "*"
Flask-Cors = "*"
Flask-SocketIO = "*"
"GeoAlchemy2" = "*"
Keras = ">=2.1.6"
keras-maskrcnn = "*"
keras-retinanet = "*"
Pygments = "*"
PyNaCl = "*"
"PySDL2" = "*"
reverse_geocoder = "*"
Shapely = "*"
SQLAlchemy = "==1.2.7"
uWSGI = "*"
scipy = "*"
fastcluster = "==1.1.25"
backports-abc = "*"
pygame = "*"
simplejson = "*"
[packages]
overpy = {git = "https://github.com/commaai/python-overpy.git",ref = "f86529af402d4642e1faeb146671c40284007323"}
atomicwrites = "*"
cffi = "*"
crcmod = "*"
hexdump = "*"
libusb1 = "*"
numpy = "*"
psutil = "*"
pycapnp = "*"
cryptography = "*"
pyserial = "*"
python-dateutil = "*"
pyzmq = "*"
raven = "*"
requests = "*"
setproctitle = "*"
six = "*"
smbus2 = "*"
sympy = "*"
tqdm = "*"
Cython = "*"
PyYAML = "*"
websocket_client = "*"
Logentries = {git = "https://github.com/commaai/le_python.git",ref = "5eef8f5be5929d33973e1b10e686fa0cdcd6792f"}
urllib3 = "*"
chardet = "*"
idna = "*"
gunicorn = "*"
utm = "*"
json-rpc = "*"
Flask = "*"
PyJWT = "*"
"Jinja2" = "*"
nose = "*"
pyflakes = "*"
pylint = "*"
pycryptodome = "*"
[requires]
python_version = "2.7"
Generated
-2810
View File
File diff suppressed because it is too large Load Diff
+16 -17
View File
@@ -1,4 +1,4 @@
[![](https://i.imgur.com/UetIFyH.jpg)](#)
[![](https://i.imgur.com/xY2gdHv.png)](#)
Welcome to openpilot
======
@@ -77,8 +77,8 @@ Supported Cars
| Honda | Civic Hatchback 2017-19 | Honda Sensing | Yes | Stock | 0mph | 12mph | Bosch |
| Honda | CR-V 2015-16 | Touring | Yes | Yes | 25mph<sup>1</sup>| 12mph | Nidec |
| Honda | CR-V 2017-19 | Honda Sensing | Yes | Stock | 0mph | 12mph | Bosch |
| Honda | CR-V Hybrid 2017-2019 | Honda Sensing | Yes | Stock | 0mph | 12mph | Bosch |
| Honda | Odyssey 2018-19 | Honda Sensing | Yes | Yes | 25mph<sup>1</sup>| 0mph | Inverted Nidec |
| Honda | CR-V Hybrid 2019 | All | Yes | Stock | 0mph | 12mph | Bosch |
| Honda | Odyssey 2017-19 | Honda Sensing | Yes | Yes | 25mph<sup>1</sup>| 0mph | Inverted Nidec |
| Honda | Passport 2019 | All | Yes | Yes | 25mph<sup>1</sup>| 12mph | Inverted Nidec |
| Honda | Pilot 2016-18 | Honda Sensing | Yes | Yes | 25mph<sup>1</sup>| 12mph | Nidec |
| Honda | Pilot 2019 | All | Yes | Yes | 25mph<sup>1</sup>| 12mph | Inverted Nidec |
@@ -91,15 +91,13 @@ Supported Cars
| Kia | Optima 2019 | SCC + LKAS | Yes | Stock | 0mph | 0mph | Custom<sup>6</sup>|
| Kia | Sorento 2018 | All | Yes | Stock | 0mph | 0mph | Custom<sup>6</sup>|
| Kia | Stinger 2018 | SCC + LKAS | Yes | Stock | 0mph | 0mph | Custom<sup>6</sup>|
| Lexus | ES Hybrid 2019 | All | Yes | Yes | 0mph | 0mph | Toyota |
| Lexus | RX Hybrid 2016-19 | All | Yes | Yes<sup>2</sup>| 0mph | 0mph | Toyota |
| Subaru | Crosstrek 2018 | EyeSight | Yes | Stock | 0mph | 0mph | Custom<sup>4</sup>|
| Subaru | Impreza 2019 | EyeSight | Yes | Stock | 0mph | 0mph | Custom<sup>4</sup>|
| Subaru | Crosstrek 2018 | EyeSight | Yes | Stock | 0mph | 0mph | Subaru |
| Subaru | Impreza 2019 | EyeSight | Yes | Stock | 0mph | 0mph | Subaru |
| Toyota | Avalon 2016 | TSS-P | Yes | Yes<sup>2</sup>| 20mph<sup>1</sup>| 0mph | Toyota |
| Toyota | Camry 2018 | All | Yes | Stock | 0mph<sup>5</sup> | 0mph | Toyota |
| Toyota | C-HR 2017-18 | All | Yes | Stock | 0mph | 0mph | Toyota |
| Toyota | Corolla 2017-19 | All | Yes | Yes<sup>2</sup>| 20mph<sup>1</sup>| 0mph | Toyota |
| Toyota | Corolla 2020 | All | Yes | Yes | 0mph | 0mph | Toyota |
| Toyota | Camry 2018<sup>4</sup> | All | Yes | Stock | 0mph<sup>5</sup> | 0mph | Toyota |
| Toyota | C-HR 2017-18<sup>4</sup> | All | Yes | Stock | 0mph | 0mph | Toyota |
| Toyota | Corolla 2017-18 | All | Yes | Yes<sup>2</sup>| 20mph<sup>1</sup>| 0mph | Toyota |
| Toyota | Corolla Hatchback 2019 | All | Yes | Yes | 0mph | 0mph | Toyota |
| Toyota | Highlander 2017-18 | All | Yes | Yes<sup>2</sup>| 0mph | 0mph | Toyota |
| Toyota | Highlander Hybrid 2018 | All | Yes | Yes<sup>2</sup>| 0mph | 0mph | Toyota |
@@ -111,13 +109,13 @@ Supported Cars
| Toyota | Rav4 2019 | All | Yes | Yes | 0mph | 0mph | Toyota |
| Toyota | Rav4 Hybrid 2017-18 | All | Yes | Yes<sup>2</sup>| 0mph | 0mph | Toyota |
<sup>1</sup>[Comma Pedal](https://community.comma.ai/wiki/index.php/Comma_Pedal) is used to provide stop-and-go capability to some of the openpilot-supported cars that don't currently support stop-and-go. Here is how to [build a Comma Pedal](https://medium.com/@jfrux/comma-pedal-building-with-macrofab-6328bea791e8). ***NOTE: The Comma Pedal is not officially supported by [comma.ai](https://comma.ai).*** <br />
<sup>2</sup>When disconnecting the Driver Support Unit (DSU), otherwise longitudinal control is stock ACC. For DSU locations, see [Toyota Wiki page](https://community.comma.ai/wiki/index.php/Toyota). <br />
<sup>3</sup>[GM installation guide](https://zoneos.com/volt/). <br />
<sup>4</sup>Subaru Giraffe is DIY. <br />
<sup>5</sup>28mph for Camry 4CYL L, 4CYL LE and 4CYL SE which don't have Full-Speed Range Dynamic Radar Cruise Control. <br />
<sup>6</sup>Open sourced [Hyundai Giraffe](https://github.com/commaai/neo/tree/master/giraffe/hyundai) is designed for the 2019 Sante Fe; pinout may differ for other Hyundais. <br />
<sup>7</sup>Community built Giraffe, find more information [here](https://zoneos.com/shop/). <br />
<sup>1</sup>[Comma Pedal](https://community.comma.ai/wiki/index.php/Comma_Pedal) is used to provide stop-and-go capability to some of the openpilot-supported cars that don't currently support stop-and-go. Here is how to [build a Comma Pedal](https://medium.com/@jfrux/comma-pedal-building-with-macrofab-6328bea791e8). ***NOTE: The Comma Pedal is not officially supported by [comma.ai](https://comma.ai)***
<sup>2</sup>When disconnecting the Driver Support Unit (DSU), otherwise longitudinal control is stock ACC. For DSU locations, see [Toyota Wiki page](https://community.comma.ai/wiki/index.php/Toyota)
<sup>3</sup>[GM installation guide](https://zoneos.com/volt/).
<sup>4</sup>It needs an extra 120Ohm resistor ([pic1](https://i.imgur.com/CmdKtTP.jpg), [pic2](https://i.imgur.com/s2etUo6.jpg)) on bus 3 and giraffe switches set to 01X1 (11X1 for stock LKAS), where X depends on if you have the [comma power](https://comma.ai/shop/products/power/).
<sup>5</sup>28mph for Camry 4CYL L, 4CYL LE and 4CYL SE which don't have Full-Speed Range Dynamic Radar Cruise Control.
<sup>6</sup>Open sourced [Hyundai Giraffe](https://github.com/commaai/neo/tree/master/giraffe/hyundai) is designed for the 2019 Sante Fe; pinout may differ for other Hyundais.
<sup>7</sup>Community built Giraffe, find more information [here](https://zoneos.com/shop/).
Community Maintained Cars
------
@@ -175,6 +173,7 @@ Directory structure
├── locationd # Soon to be home of precise location
├── logcatd # Android logcat as a service
├── loggerd # Logger and uploader of car data
├── mapd # Fetches map data and computes next global path
├── proclogd # Logs information from proc
├── sensord # IMU / GPS interface code
├── test # Car simulator running code through virtual maneuvers
+2 -25
View File
@@ -1,26 +1,3 @@
Version 0.6 (2019-07-01)
========================
* New model, with double the pixels and ten times the temporal context!
* Car should not take exits when in the right lane
* openpilot uses only ~65% of the CPU (down from 75%)
* Routes visible in connect/explorer after only 0.2% is uploaded (qlogs)
* loggerd and sensord are open source, every line of openpilot is now open
* Panda safety code is MISRA compliant and ships with a signed version on release2
* New NEOS is 500MB smaller and has a reproducible usr/pipenv
* Lexus ES Hybrid support thanks to wocsor!
* Improve tuning for supported Toyota with TSS2
* Various other stability improvements
Version 0.5.13 (2019-05-31)
==========================
* Reduce panda power consumption by 70%, down to 80mW, when car is off (not for GM)
* Reduce EON power consumption by 40%, down to 1100mW, when car is off
* Reduce CPU utilization by 20% and improve stability
* Temporarily remove mapd functionalities to improve stability
* Add openpilot record-only mode for unsupported cars
* Synchronize controlsd to boardd to reduce latency
* Remove panda support for Subaru giraffe
Version 0.5.12 (2019-05-16)
==========================
* Improve lateral control for the Prius and Prius Prime
@@ -32,8 +9,8 @@ Version 0.5.12 (2019-05-16)
* Add default speed limits for Estonia thanks to martinl!
* Subaru Crosstrek support thanks to martinl!
* Toyota Avalon support thanks to njbrown09!
* Toyota Rav4 with TSS 2.0 support thanks to wocsor!
* Toyota Corolla with TSS 2.0 support thanks to wocsor!
* Toyota Rav4 with TSS 2.0 support thansk to wocsor!
* Toyota Corolla with TSS 2.0 support thansk to wocsor!
Version 0.5.11 (2019-04-17)
========================
Binary file not shown.
Binary file not shown.
Binary file not shown.
-3
View File
@@ -1,6 +1,3 @@
gen
node_modules
package-lock.json
*.pyc
__pycache__
+7 -11
View File
@@ -22,7 +22,7 @@ struct CarEvent @0x9b1657f34caf3ad3 {
enum EventName @0xbaa8c5d505f727de {
# TODO: copy from error list
canError @0;
commIssue @0;
steerUnavailable @1;
brakeUnavailable @2;
gasUnavailable @3;
@@ -37,7 +37,7 @@ struct CarEvent @0x9b1657f34caf3ad3 {
buttonEnable @12;
pedalPressed @13;
cruiseDisabled @14;
radarCanError @15;
radarCommIssue @15;
dataNeeded @16;
speedTooLow @17;
outOfSpace @18;
@@ -49,7 +49,7 @@ struct CarEvent @0x9b1657f34caf3ad3 {
pcmDisable @24;
noTarget @25;
radarFault @26;
modelCommIssueDEPRECATED @27;
modelCommIssue @27;
brakeHold @28;
parkBrake @29;
manualRestart @30;
@@ -74,8 +74,6 @@ struct CarEvent @0x9b1657f34caf3ad3 {
invalidGiraffeHonda @49;
vehicleModelInvalid @50;
controlsFailed @51;
sensorDataInvalid @52;
commIssue @53;
}
}
@@ -124,7 +122,6 @@ struct CarState {
# lock info
doorOpen @24 :Bool;
seatbeltUnlatched @25 :Bool;
canValid @26 :Bool;
# which packets this state came from
canMonoTimes @12: List(UInt64);
@@ -178,7 +175,7 @@ struct CarState {
# ******* radar state @ 20hz *******
struct RadarData @0x888ad6581cf0aacb {
struct RadarState {
errors @0 :List(Error);
points @1 :List(RadarPoint);
@@ -186,7 +183,7 @@ struct RadarData @0x888ad6581cf0aacb {
canMonoTimes @2 :List(UInt64);
enum Error {
canError @0;
commIssue @0;
fault @1;
wrongConfig @2;
}
@@ -295,7 +292,7 @@ struct CarParams {
minEnableSpeed @7 :Float32;
minSteerSpeed @8 :Float32;
safetyModel @9 :SafetyModel;
safetyModel @9 :Int16;
safetyParam @10 :Int16;
steerMaxBP @11 :List(Float32);
@@ -336,7 +333,6 @@ struct CarParams {
steerActuatorDelay @36 :Float32; # Steering wheel actuator delay in seconds
openpilotLongitudinalControl @37 :Bool; # is openpilot doing the longitudinal control?
carVin @38 :Text; # VIN number queried during fingerprinting
struct LateralPIDTuning {
kpBP @0 :List(Float32);
@@ -364,7 +360,7 @@ struct CarParams {
}
enum SafetyModel {
enum SafetyModels {
# does NOT match board setting
noOutput @0;
honda @1;
-26
View File
@@ -1,26 +0,0 @@
#!/bin/bash
rm -r gen/ts
rm -r gen/js
mkdir gen/ts
mkdir gen/js
echo "Installing needed npm modules"
npm i capnpc-ts capnp-ts
capnpc -o node_modules/.bin/capnpc-ts:gen/ts log.capnp car.capnp
capnpc -o node_modules/.bin/capnpc-ts:gen/ts car.capnp
cat log.capnp | egrep '\([a-zA-Z]*\.[^\s]+\.[^s]+\)' | sed 's/^.*([a-zA-Z]*\.\([a-zA-Z.]*\)).*/\1/' | while read line
do
TOKEN=`echo $line | sed 's/\./_/g'`
ROOT=`echo $line | sed 's/\..*$//g'`
cat gen/ts/log.capnp.ts | grep '^import.*'${TOKEN}
if [[ "$?" == "1" ]]
then
sed -i 's/^\(import {.*\)'${ROOT}'\(,*\) \(.*\)$/\1'${ROOT}', '${TOKEN}'\2 \3/' ./gen/ts/log.capnp.ts
fi
done
tsc ./gen/ts/* --lib es2015 --outDir ./gen/js
-39
View File
@@ -1,39 +0,0 @@
set -e
echo "Installing capnp"
cd /tmp
VERSION=0.6.1
wget https://capnproto.org/capnproto-c++-${VERSION}.tar.gz
tar xvf capnproto-c++-${VERSION}.tar.gz
cd capnproto-c++-${VERSION}
CXXFLAGS="-fPIC" ./configure
make -j4
# manually build binaries statically
g++ -std=gnu++11 -I./src -I./src -DKJ_HEADER_WARNINGS -DCAPNP_HEADER_WARNINGS -DCAPNP_INCLUDE_DIR=\"/usr/local/include\" -pthread -O2 -DNDEBUG -pthread -pthread -o .libs/capnp src/capnp/compiler/module-loader.o src/capnp/compiler/capnp.o ./.libs/libcapnpc.a ./.libs/libcapnp.a ./.libs/libkj.a -lpthread -pthread
g++ -std=gnu++11 -I./src -I./src -DKJ_HEADER_WARNINGS -DCAPNP_HEADER_WARNINGS -DCAPNP_INCLUDE_DIR=\"/usr/local/include\" -pthread -O2 -DNDEBUG -pthread -pthread -o .libs/capnpc-c++ src/capnp/compiler/capnpc-c++.o ./.libs/libcapnp.a ./.libs/libkj.a -lpthread -pthread
g++ -std=gnu++11 -I./src -I./src -DKJ_HEADER_WARNINGS -DCAPNP_HEADER_WARNINGS -DCAPNP_INCLUDE_DIR=\"/usr/local/include\" -pthread -O2 -DNDEBUG -pthread -pthread -o .libs/capnpc-capnp src/capnp/compiler/capnpc-capnp.o ./.libs/libcapnp.a ./.libs/libkj.a -lpthread -pthread
cp .libs/capnp /usr/local/bin/
ln -s /usr/local/bin/capnp /usr/local/bin/capnpc
cp .libs/capnpc-c++ /usr/local/bin/
cp .libs/capnpc-capnp /usr/local/bin/
cp .libs/*.a /usr/local/lib
cd /tmp
echo "Installing c-capnp"
git clone https://github.com/commaai/c-capnproto.git
cd c-capnproto
git submodule update --init --recursive
autoreconf -f -i -s
CXXFLAGS="-fPIC" ./configure
make -j4
# manually build binaries statically
gcc -fPIC -o .libs/capnpc-c compiler/capnpc-c.o compiler/schema.capnp.o compiler/str.o ./.libs/libcapnp_c.a
cp .libs/capnpc-c /usr/local/bin/
cp .libs/*.a /usr/local/lib
+13 -33
View File
@@ -150,12 +150,6 @@ struct FrameData {
}
}
struct Thumbnail {
frameId @0 :UInt32;
timestampEof @1 :UInt64;
thumbnail @2 :Data;
}
struct GPSNMEAData {
timestamp @0 :Int64;
localWallTime @1 :UInt64;
@@ -311,12 +305,12 @@ struct LiveUI {
awarenessStatus @3 :Float32;
}
struct RadarState @0x9a185389d6fdd05f {
struct Live20Data {
canMonoTimes @10 :List(UInt64);
mdMonoTime @6 :UInt64;
ftMonoTimeDEPRECATED @7 :UInt64;
controlsStateMonoTime @11 :UInt64;
radarErrors @12 :List(Car.RadarData.Error);
l100MonoTime @11 :UInt64;
radarErrors @12 :List(Car.RadarState.Error);
# all deprecated
warpMatrixDEPRECATED @0 :List(Float32);
@@ -374,15 +368,15 @@ struct LiveTracks {
oncoming @9 :Bool;
}
struct ControlsState @0x97ff69c53601abf1 {
struct Live100Data {
canMonoTimeDEPRECATED @16 :UInt64;
canMonoTimes @21 :List(UInt64);
radarStateMonoTimeDEPRECATED @17 :UInt64;
l20MonoTimeDEPRECATED @17 :UInt64;
mdMonoTimeDEPRECATED @18 :UInt64;
planMonoTime @28 :UInt64;
pathPlanMonoTime @50 :UInt64;
state @31 :OpenpilotState;
state @31 :ControlState;
vEgo @0 :Float32;
vEgoRaw @32 :Float32;
aEgoDEPRECATED @1 :Float32;
@@ -439,7 +433,7 @@ struct ControlsState @0x97ff69c53601abf1 {
pidState @53 :LateralPIDState;
}
enum OpenpilotState @0xdbe58b96d2d1ac61 {
enum ControlState {
disabled @0;
preEnabled @1;
enabled @2;
@@ -513,16 +507,12 @@ struct ModelData {
points @0 :List(Float32);
prob @1 :Float32;
std @2 :Float32;
stds @3 :List(Float32);
poly @4 :List(Float32);
}
struct LeadData {
dist @0 :Float32;
prob @1 :Float32;
std @2 :Float32;
relVel @3 :Float32;
relVelStd @4 :Float32;
}
struct ModelSettings {
@@ -584,9 +574,7 @@ struct LogRotate {
struct Plan {
mdMonoTime @9 :UInt64;
radarStateMonoTime @10 :UInt64;
commIssue @31 :Bool;
l20MonoTime @10 :UInt64;
eventsDEPRECATED @13 :List(Car.CarEvent);
# lateral, 3rd order polynomial
@@ -625,7 +613,7 @@ struct Plan {
decelForTurn @22 :Bool;
mapValid @25 :Bool;
radarValid @28 :Bool;
radarCanError @30 :Bool;
radarCommIssue @30 :Bool;
processingDelay @29 :Float32;
@@ -656,12 +644,10 @@ struct PathPlan {
angleSteers @8 :Float32; # deg
rateSteers @13 :Float32; # deg/s
mpcSolutionValid @9 :Bool;
valid @9 :Bool;
paramsValid @10 :Bool;
modelValidDEPRECATED @12 :Bool;
modelValid @12 :Bool;
angleOffset @11 :Float32;
sensorValid @14 :Bool;
commIssue @15 :Bool;
}
struct LiveLocationData {
@@ -1657,8 +1643,6 @@ struct LiveParametersData {
angleOffsetAverage @3 :Float32;
stiffnessFactor @4 :Float32;
steerRatio @5 :Float32;
sensorValid @6 :Bool;
yawRate @7 :Float32;
}
struct LiveMapData {
@@ -1698,7 +1682,6 @@ struct KalmanOdometry {
struct Event {
# in nanoseconds?
logMonoTime @0 :UInt64;
valid @67 :Bool = true;
union {
initData @1 :InitData;
@@ -1707,13 +1690,13 @@ struct Event {
sensorEventDEPRECATED @4 :SensorEventData;
can @5 :List(CanData);
thermal @6 :ThermalData;
controlsState @7 :ControlsState;
live100 @7 :Live100Data;
liveEventDEPRECATED @8 :List(LiveEventData);
model @9 :ModelData;
features @10 :CalibrationFeatures;
sensorEvents @11 :List(SensorEventData);
health @12 :HealthData;
radarState @13 :RadarState;
live20 @13 :Live20Data;
liveUIDEPRECATED @14 :LiveUI;
encodeIdx @15 :EncodeIndex;
liveTracks @16 :List(LiveTracks);
@@ -1766,8 +1749,5 @@ struct Event {
cameraOdometry @63 :CameraOdometry;
pathPlan @64 :PathPlan;
kalmanOdometry @65 :KalmanOdometry;
thumbnail @66: Thumbnail;
carEvents @68: List(Car.CarEvent);
carParams @69: Car.CarParams;
}
}
-53
View File
@@ -1,53 +0,0 @@
using Cxx = import "./include/c++.capnp";
$Cxx.namespace("cereal");
using Java = import "./include/java.capnp";
$Java.package("ai.comma.openpilot.cereal");
$Java.outerClassname("Map");
@0xa086df597ef5d7a0;
# Geometry
struct Point {
x @0: Float64;
y @1: Float64;
z @2: Float64;
}
struct PolyLine {
points @0: List(Point);
}
# Map features
struct Lane {
id @0 :Text;
leftBoundary @1 :LaneBoundary;
rightBoundary @2 :LaneBoundary;
leftAdjacentId @3 :Text;
rightAdjacentId @4 :Text;
inboundIds @5 :List(Text);
outboundIds @6 :List(Text);
struct LaneBoundary {
polyLine @0 :PolyLine;
startHeading @1 :Float32; # WRT north
}
}
# Map tiles
struct TileSummary {
version @0 :Text;
updatedAt @1 :UInt64; # Millis since epoch
level @2 :UInt8;
x @3 :UInt16;
y @4 :UInt16;
}
struct MapTile {
summary @0 :TileSummary;
lanes @1 :List(Lane);
}
-16
View File
@@ -1,16 +0,0 @@
from posix.time cimport clock_gettime, timespec, CLOCK_BOOTTIME, CLOCK_MONOTONIC_RAW
cdef double readclock(int clock_id):
cdef timespec ts
cdef double current
clock_gettime(clock_id, &ts)
current = ts.tv_sec + (ts.tv_nsec / 1000000000.)
return current
def monotonic_time():
return readclock(CLOCK_MONOTONIC_RAW)
def sec_since_boot():
return readclock(CLOCK_BOOTTIME)
-103
View File
@@ -1,103 +0,0 @@
import os
import shutil
import tempfile
from atomicwrites import AtomicWriter
def mkdirs_exists_ok(path):
try:
os.makedirs(path)
except OSError:
if not os.path.isdir(path):
raise
def rm_not_exists_ok(path):
try:
os.remove(path)
except OSError:
if os.path.exists(path):
raise
def rm_tree_or_link(path):
if os.path.islink(path):
os.unlink(path)
elif os.path.isdir(path):
shutil.rmtree(path)
def get_tmpdir_on_same_filesystem(path):
# TODO(mgraczyk): HACK, we should actually check for which filesystem.
normpath = os.path.normpath(path)
parts = normpath.split("/")
if len(parts) > 1:
if parts[1].startswith("raid"):
if len(parts) > 2 and parts[2] == "runner":
return "/{}/runner/tmp".format(parts[1])
elif len(parts) > 2 and parts[2] == "aws":
return "/{}/aws/tmp".format(parts[1])
else:
return "/{}/tmp".format(parts[1])
elif parts[1] == "aws":
return "/aws/tmp"
elif parts[1] == "scratch":
return "/scratch/tmp"
return "/tmp"
class AutoMoveTempdir(object):
def __init__(self, target_path, temp_dir=None):
self._target_path = target_path
self._path = tempfile.mkdtemp(dir=temp_dir)
@property
def name(self):
return self._path
def close(self):
os.rename(self._path, self._target_path)
def __enter__(self): return self
def __exit__(self, type, value, traceback):
if type is None:
self.close()
else:
shutil.rmtree(self._path)
class NamedTemporaryDir(object):
def __init__(self, temp_dir=None):
self._path = tempfile.mkdtemp(dir=temp_dir)
@property
def name(self):
return self._path
def close(self):
shutil.rmtree(self._path)
def __enter__(self): return self
def __exit__(self, type, value, traceback):
self.close()
def _get_fileobject_func(writer, temp_dir):
def _get_fileobject():
file_obj = writer.get_fileobject(dir=temp_dir)
os.chmod(file_obj.name, 0o644)
return file_obj
return _get_fileobject
def atomic_write_on_fs_tmp(path, **kwargs):
"""Creates an atomic writer using a temporary file in a temporary directory
on the same filesystem as path.
"""
# TODO(mgraczyk): This use of AtomicWriter relies on implementation details to set the temp
# directory.
writer = AtomicWriter(path, **kwargs)
return writer._open(_get_fileobject_func(writer, get_tmpdir_on_same_filesystem(path)))
def atomic_write_in_dir(path, **kwargs):
"""Creates an atomic writer using a temporary file in the same directory
as the destination file.
"""
writer = AtomicWriter(path, **kwargs)
return writer._open(_get_fileobject_func(writer, os.path.dirname(path)))
+1 -1
View File
@@ -4,7 +4,7 @@ from common.basedir import BASEDIR
def get_fingerprint_list():
# read all the folders in selfdrive/car and return a dict where:
# - keys are all the car models for which we have a fingerprint
# - values are lists dicts of messages that constitute the unique
# - values are lists dicts of messages that constitute the unique
# CAN fingerprint of each car model and all its variants
fingerprints = {}
for car_folder in [x[0] for x in os.walk(BASEDIR + '/selfdrive/car')]:
+1 -1
View File
@@ -1,7 +1,7 @@
all: simple_kalman_impl.so
simple_kalman_impl.so: simple_kalman_impl.pyx simple_kalman_impl.pxd simple_kalman_setup.py
python2 simple_kalman_setup.py build_ext --inplace
python simple_kalman_setup.py build_ext --inplace
rm -rf build
rm simple_kalman_impl.c
+30 -32
View File
@@ -41,7 +41,7 @@ def mkdirs_exists_ok(path):
class TxType(Enum):
PERSISTENT = 1
CLEAR_ON_MANAGER_START = 2
CLEAR_ON_PANDA_DISCONNECT = 3
CLEAR_ON_CAR_START = 3
class UnknownKeyName(Exception):
@@ -49,34 +49,32 @@ class UnknownKeyName(Exception):
keys = {
"AccessToken": [TxType.PERSISTENT],
"CalibrationParams": [TxType.PERSISTENT],
"CarParams": [TxType.CLEAR_ON_MANAGER_START, TxType.CLEAR_ON_PANDA_DISCONNECT],
"CompletedTrainingVersion": [TxType.PERSISTENT],
"ControlsParams": [TxType.PERSISTENT],
"DoUninstall": [TxType.CLEAR_ON_MANAGER_START],
"DongleId": [TxType.PERSISTENT],
"GitBranch": [TxType.PERSISTENT],
"GitCommit": [TxType.PERSISTENT],
"GitRemote": [TxType.PERSISTENT],
"HasAcceptedTerms": [TxType.PERSISTENT],
"IsDriverMonitoringEnabled": [TxType.PERSISTENT],
"IsFcwEnabled": [TxType.PERSISTENT],
"IsGeofenceEnabled": [TxType.PERSISTENT],
"IsMetric": [TxType.PERSISTENT],
"IsUpdateAvailable": [TxType.PERSISTENT],
"IsUploadRawEnabled": [TxType.PERSISTENT],
"IsUploadVideoOverCellularEnabled": [TxType.PERSISTENT],
"LimitSetSpeed": [TxType.PERSISTENT],
"LiveParameters": [TxType.PERSISTENT],
"LongitudinalControl": [TxType.PERSISTENT],
"Passive": [TxType.PERSISTENT],
"RecordFront": [TxType.PERSISTENT],
"ShouldDoUpdate": [TxType.CLEAR_ON_MANAGER_START],
"SpeedLimitOffset": [TxType.PERSISTENT],
"SubscriberInfo": [TxType.PERSISTENT],
"TrainingVersion": [TxType.PERSISTENT],
"Version": [TxType.PERSISTENT],
"AccessToken": TxType.PERSISTENT,
"CalibrationParams": TxType.PERSISTENT,
"CarParams": TxType.CLEAR_ON_CAR_START,
"CompletedTrainingVersion": TxType.PERSISTENT,
"ControlsParams": TxType.PERSISTENT,
"DoUninstall": TxType.CLEAR_ON_MANAGER_START,
"DongleId": TxType.PERSISTENT,
"GitBranch": TxType.PERSISTENT,
"GitCommit": TxType.PERSISTENT,
"GitRemote": TxType.PERSISTENT,
"HasAcceptedTerms": TxType.PERSISTENT,
"IsDriverMonitoringEnabled": TxType.PERSISTENT,
"IsFcwEnabled": TxType.PERSISTENT,
"IsGeofenceEnabled": TxType.PERSISTENT,
"IsMetric": TxType.PERSISTENT,
"IsUpdateAvailable": TxType.PERSISTENT,
"IsUploadVideoOverCellularEnabled": TxType.PERSISTENT,
"LimitSetSpeed": TxType.PERSISTENT,
"LiveParameters": TxType.PERSISTENT,
"LongitudinalControl": TxType.PERSISTENT,
"Passive": TxType.PERSISTENT,
"RecordFront": TxType.PERSISTENT,
"ShouldDoUpdate": TxType.CLEAR_ON_MANAGER_START,
"SpeedLimitOffset": TxType.PERSISTENT,
"TrainingVersion": TxType.PERSISTENT,
"Version": TxType.PERSISTENT,
}
@@ -310,14 +308,14 @@ class Params(object):
def _clear_keys_with_type(self, tx_type):
with self.transaction(write=True) as txn:
for key in keys:
if tx_type in keys[key]:
if keys[key] == tx_type:
txn.delete(key)
def manager_start(self):
self._clear_keys_with_type(TxType.CLEAR_ON_MANAGER_START)
def panda_disconnect(self):
self._clear_keys_with_type(TxType.CLEAR_ON_PANDA_DISCONNECT)
def car_start(self):
self._clear_keys_with_type(TxType.CLEAR_ON_CAR_START)
def delete(self, key):
with self.transaction(write=True) as txn:
+47 -19
View File
@@ -2,31 +2,58 @@
import os
import time
import platform
import threading
import subprocess
import multiprocessing
from cffi import FFI
# Build and load cython module
import pyximport
installer = pyximport.install(inplace=True, build_dir='/tmp')
from common.clock import monotonic_time, sec_since_boot # pylint: disable=no-name-in-module, import-error
pyximport.uninstall(*installer)
assert monotonic_time
assert sec_since_boot
# time step for each process
DT_CTRL = 0.01 # controlsd
DT_PLAN = 0.05 # mpc
DT_MDL = 0.05 # model
DT_DMON = 0.1 # driver monitoring
ffi = FFI()
ffi.cdef("long syscall(long number, ...);")
ffi.cdef("""
typedef int clockid_t;
struct timespec {
long tv_sec; /* Seconds. */
long tv_nsec; /* Nanoseconds. */
};
int clock_gettime (clockid_t clk_id, struct timespec *tp);
long syscall(long number, ...);
"""
)
libc = ffi.dlopen(None)
# see <linux/time.h>
CLOCK_MONOTONIC_RAW = 4
CLOCK_BOOTTIME = 7
if platform.system() != 'Darwin' and hasattr(libc, 'clock_gettime'):
c_clock_gettime = libc.clock_gettime
tlocal = threading.local()
def clock_gettime(clk_id):
if not hasattr(tlocal, 'ts'):
tlocal.ts = ffi.new('struct timespec *')
ts = tlocal.ts
r = c_clock_gettime(clk_id, ts)
if r != 0:
raise OSError("clock_gettime")
return ts.tv_sec + ts.tv_nsec * 1e-9
else:
# hack. only for OS X < 10.12
def clock_gettime(clk_id):
return time.time()
def monotonic_time():
return clock_gettime(CLOCK_MONOTONIC_RAW)
def sec_since_boot():
return clock_gettime(CLOCK_BOOTTIME)
def set_realtime_priority(level):
if os.getuid() != 0:
print("not setting priority, not root")
@@ -72,9 +99,10 @@ class Ratekeeper(object):
lagged = False
remaining = self._next_frame_time - sec_since_boot()
self._next_frame_time += self._interval
if self._print_delay_threshold is not None and remaining < -self._print_delay_threshold:
if remaining < -self._print_delay_threshold:
print("%s lagging by %.2f ms" % (self._process_name, -remaining * 1000))
lagged = True
self._frame += 1
self._remaining = remaining
return lagged
+2 -5
View File
@@ -1,5 +1,6 @@
import numpy as np
import common.transformations.orientation as orient
import cv2
import math
FULL_FRAME_SIZE = (1164, 874)
@@ -125,8 +126,6 @@ def img_from_device(pt_device):
#TODO please use generic img transform below
def rotate_img(img, eulers, crop=None, intrinsics=eon_intrinsics):
import cv2
size = img.shape[:2]
rot = orient.rot_from_euler(eulers)
quadrangle = np.array([[0, 0],
@@ -163,8 +162,6 @@ def transform_img(base_img,
output_size=None,
pretransform=None,
top_hacks=True):
import cv2
size = base_img.shape[:2]
if not output_size:
output_size = size[::-1]
@@ -207,10 +204,10 @@ def transform_img(base_img,
def yuv_crop(frame, output_size, center=None):
# output_size in camera coordinates so u,v
# center in array coordinates so row, column
import cv2
rgb = cv2.cvtColor(frame, cv2.COLOR_YUV2RGB_I420)
if not center:
center = (rgb.shape[0]/2, rgb.shape[1]/2)
rgb_crop = rgb[center[0] - output_size[1]/2: center[0] + output_size[1]/2,
center[1] - output_size[0]/2: center[1] + output_size[0]/2]
return cv2.cvtColor(rgb_crop, cv2.COLOR_RGB2YUV_I420)
-95
View File
@@ -1,95 +0,0 @@
#!/usr/bin/env python
import time
from common.realtime import sec_since_boot
import selfdrive.messaging as messaging
from selfdrive.boardd.boardd import can_list_to_can_capnp
def get_vin(logcan, sendcan):
# works on standard 11-bit addresses for diagnostic. Tested on Toyota and Subaru;
# Honda uses the extended 29-bit addresses, and unfortunately only works from OBDII
query_msg = [[0x7df, 0, '\x02\x09\x02'.ljust(8, "\x00"), 0],
[0x7e0, 0, '\x30'.ljust(8, "\x00"), 0]]
cnts = [1, 2] # Number of messages to wait for at each iteration
vin_valid = True
dat = []
for i in range(len(query_msg)):
cnt = 0
sendcan.send(can_list_to_can_capnp([query_msg[i]], msgtype='sendcan'))
got_response = False
t_start = sec_since_boot()
while sec_since_boot() - t_start < 0.05 and not got_response:
for a in messaging.drain_sock(logcan):
for can in a.can:
if can.src == 0 and can.address == 0x7e8:
vin_valid = vin_valid and is_vin_response_valid(can.dat, i, cnt)
dat += can.dat[2:] if i == 0 else can.dat[1:]
cnt += 1
if cnt == cnts[i]:
got_response = True
time.sleep(0.01)
return "".join(dat[3:]) if vin_valid else ""
"""
if 'vin' not in gctx:
print "getting vin"
gctx['vin'] = query_vin()[3:]
print "got VIN %s" % (gctx['vin'],)
cloudlog.info("got VIN %s" % (gctx['vin'],))
# *** determine platform based on VIN ****
if vin.startswith("19UDE2F36G"):
print "ACURA ILX 2016"
self.civic = False
else:
# TODO: add Honda check explicitly
print "HONDA CIVIC 2016"
self.civic = True
# *** special case VIN of Acura test platform
if vin == "19UDE2F36GA001322":
print "comma.ai test platform detected"
# it has a gas interceptor and a torque mod
self.torque_mod = True
"""
# sanity checks on response messages from vin query
def is_vin_response_valid(can_dat, step, cnt):
can_dat = [ord(i) for i in can_dat]
if len(can_dat) != 8:
# ISO-TP meesages are all 8 bytes
return False
if step == 0:
# VIN does not fit in a single message and it's 20 bytes of data
if can_dat[0] != 0x10 or can_dat[1] != 0x14:
return False
if step == 1 and cnt == 0:
# first response after a CONTINUE query is sent
if can_dat[0] != 0x21:
return False
if step == 1 and cnt == 1:
# second response after a CONTINUE query is sent
if can_dat[0] != 0x22:
return False
return True
if __name__ == "__main__":
import zmq
from selfdrive.services import service_list
context = zmq.Context()
logcan = messaging.sub_sock(context, service_list['can'].port)
sendcan = messaging.pub_sock(context, service_list['sendcan'].port)
time.sleep(1.) # give time to sendcan socket to start
print get_vin(logcan, sendcan)
-88
View File
@@ -1,88 +0,0 @@
CC = clang
CXX = clang++
PHONELIBS = ../../phonelibs
WARN_FLAGS = -Werror=implicit-function-declaration \
-Werror=incompatible-pointer-types \
-Werror=int-conversion \
-Werror=return-type \
-Werror=format-extra-args
CFLAGS = -std=gnu11 -g -fPIC -O2 $(WARN_FLAGS)
CXXFLAGS = -std=c++11 -g -fPIC -O2 $(WARN_FLAGS)
CURL_FLAGS = -I$(PHONELIBS)/curl/include
CURL_LIBS = $(PHONELIBS)/curl/lib/libcurl.a \
$(PHONELIBS)/zlib/lib/libz.a
BORINGSSL_FLAGS = -I$(PHONELIBS)/boringssl/include
BORINGSSL_LIBS = $(PHONELIBS)/boringssl/lib/libssl_static.a \
$(PHONELIBS)/boringssl/lib/libcrypto_static.a \
NANOVG_FLAGS = -I$(PHONELIBS)/nanovg
JSON11_FLAGS = -I$(PHONELIBS)/json11
OPENGL_LIBS = -lGLESv3
FRAMEBUFFER_LIBS = -lutils -lgui -lEGL
.PHONY: all
all: updater
OBJS = courbd.ttf.o \
../../selfdrive/common/touch.o \
../../selfdrive/common/framebuffer.o \
$(PHONELIBS)/json11/json11.o \
$(PHONELIBS)/nanovg/nanovg.o
DEPS := $(OBJS:.o=.d)
updater: updater.o $(OBJS)
@echo "[ LINK ] $@"
$(CXX) $(CPPFLAGS) -fPIC -o 'updater' $^ \
$(FRAMEBUFFER_LIBS) \
$(CURL_LIBS) \
$(BORINGSSL_LIBS) \
-L/system/vendor/lib64 \
$(OPENGL_LIBS) \
-lcutils -lm -llog
strip updater
courbd.ttf.o: ../../selfdrive/assets/courbd.ttf
@echo "[ bin2o ] $@"
cd '$(dir $<)' && ld -r -b binary '$(notdir $<)' -o '$(abspath $@)'
%.o: %.c
mkdir -p $(@D)
@echo "[ CC ] $@"
$(CC) $(CPPFLAGS) $(CFLAGS) \
-I../.. \
-I$(PHONELIBS)/android_frameworks_native/include \
-I$(PHONELIBS)/android_system_core/include \
-I$(PHONELIBS)/android_hardware_libhardware/include \
$(NANOVG_FLAGS) \
-c -o '$@' '$<'
%.o: %.cc
mkdir -p $(@D)
@echo "[ CXX ] $@"
$(CXX) $(CPPFLAGS) $(CXXFLAGS) \
-I../../selfdrive \
-I../../ \
-I$(PHONELIBS)/android_frameworks_native/include \
-I$(PHONELIBS)/android_system_core/include \
-I$(PHONELIBS)/android_hardware_libhardware/include \
$(NANOVG_FLAGS) \
$(JSON11_FLAGS) \
$(CURL_FLAGS) \
$(BORINGSSL_FLAGS) \
-c -o '$@' '$<'
.PHONY: clean
clean:
rm -f $(OBJS) $(DEPS)
-include $(DEPS)
-7
View File
@@ -1,7 +0,0 @@
{
"ota_url": "https://commadist.azureedge.net/neosupdate/ota-signed-c992abb59cbaf6588f51055db52db619061107851773fc8480acb8bb5d77a28f.zip",
"ota_hash": "c992abb59cbaf6588f51055db52db619061107851773fc8480acb8bb5d77a28f",
"recovery_url": "https://commadist.azureedge.net/neosupdate/recovery-af099a84cfd7b91266090779238ac358278948dcde2dcfa0fbca6e8397366f0a.img",
"recovery_len": 15136044,
"recovery_hash": "af099a84cfd7b91266090779238ac358278948dcde2dcfa0fbca6e8397366f0a"
}
Binary file not shown.
-675
View File
@@ -1,675 +0,0 @@
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <cassert>
#include <unistd.h>
#include <sys/stat.h>
#include <sys/statvfs.h>
#include <string>
#include <sstream>
#include <fstream>
#include <mutex>
#include <thread>
#include <curl/curl.h>
#include <openssl/sha.h>
#include <GLES3/gl3.h>
#include <EGL/egl.h>
#include <EGL/eglext.h>
#include "nanovg.h"
#define NANOVG_GLES3_IMPLEMENTATION
#include "nanovg_gl.h"
#include "nanovg_gl_utils.h"
#include "json11.hpp"
#include "common/framebuffer.h"
#include "common/touch.h"
#include "common/utilpp.h"
#define USER_AGENT "NEOSUpdater-0.2"
#define MANIFEST_URL_EON_STAGING "https://github.com/commaai/eon-neos/raw/master/update.staging.json"
#define MANIFEST_URL_EON_LOCAL "http://192.168.5.1:8000/neosupdate/update.local.json"
#define MANIFEST_URL_EON "https://github.com/commaai/eon-neos/raw/master/update.json"
const char *manifest_url = MANIFEST_URL_EON;
#define RECOVERY_DEV "/dev/block/bootdevice/by-name/recovery"
#define RECOVERY_COMMAND "/cache/recovery/command"
#define UPDATE_DIR "/data/neoupdate"
extern const uint8_t bin_courbd[] asm("_binary_courbd_ttf_start");
extern const uint8_t bin_courbd_end[] asm("_binary_courbd_ttf_end");
namespace {
std::string sha256_file(std::string fn, size_t limit=0) {
SHA256_CTX ctx;
SHA256_Init(&ctx);
FILE *file = fopen(fn.c_str(), "rb");
if (!file) return "";
const size_t buf_size = 8192;
std::unique_ptr<char[]> buffer( new char[ buf_size ] );
bool read_limit = (limit != 0);
while (true) {
size_t read_size = buf_size;
if (read_limit) read_size = std::min(read_size, limit);
size_t bytes_read = fread(buffer.get(), 1, read_size, file);
if (!bytes_read) break;
SHA256_Update(&ctx, buffer.get(), bytes_read);
if (read_limit) {
limit -= bytes_read;
if (limit == 0) break;
}
}
uint8_t hash[SHA256_DIGEST_LENGTH];
SHA256_Final(hash, &ctx);
fclose(file);
return util::tohex(hash, sizeof(hash));
}
size_t download_string_write(void *ptr, size_t size, size_t nmeb, void *up) {
size_t sz = size * nmeb;
((std::string*)up)->append((char*)ptr, sz);
return sz;
}
std::string download_string(CURL *curl, std::string url) {
std::string os;
curl_easy_setopt(curl, CURLOPT_URL, url.c_str());
curl_easy_setopt(curl, CURLOPT_FOLLOWLOCATION, 1);
curl_easy_setopt(curl, CURLOPT_NOSIGNAL, 1);
curl_easy_setopt(curl, CURLOPT_USERAGENT, USER_AGENT);
curl_easy_setopt(curl, CURLOPT_FAILONERROR, 1);
curl_easy_setopt(curl, CURLOPT_RESUME_FROM, 0);
curl_easy_setopt(curl, CURLOPT_NOPROGRESS, 1);
curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, download_string_write);
curl_easy_setopt(curl, CURLOPT_WRITEDATA, &os);
CURLcode res = curl_easy_perform(curl);
if (res != CURLE_OK) {
return "";
}
return os;
}
size_t download_file_write(void *ptr, size_t size, size_t nmeb, void *up) {
return fwrite(ptr, size, nmeb, (FILE*)up);
}
bool check_battery() {
std::string bat_cap_s = util::read_file("/sys/class/power_supply/battery/capacity");
int bat_cap = atoi(bat_cap_s.c_str());
std::string current_now_s = util::read_file("/sys/class/power_supply/battery/current_now");
int current_now = atoi(current_now_s.c_str());
return bat_cap > 35 || (current_now < 0 && bat_cap > 10);
}
bool check_space() {
struct statvfs stat;
if (statvfs("/data/", &stat) != 0) {
return false;
}
size_t space = stat.f_bsize * stat.f_bavail;
return space > 2000000000ULL; // 2GB
}
static void start_settings_activity(const char* name) {
char launch_cmd[1024];
snprintf(launch_cmd, sizeof(launch_cmd),
"am start -W --ez :settings:show_fragment_as_subsetting true -n 'com.android.settings/.%s'", name);
system(launch_cmd);
}
struct Updater {
bool do_exit = false;
TouchState touch;
int fb_w, fb_h;
EGLDisplay display;
EGLSurface surface;
FramebufferState *fb = NULL;
NVGcontext *vg = NULL;
int font;
std::thread update_thread_handle;
std::mutex lock;
// i hate state machines give me coroutines already
enum UpdateState {
CONFIRMATION,
RUNNING,
ERROR,
};
UpdateState state;
std::string progress_text;
float progress_frac;
std::string error_text;
// button
int b_x, b_w, b_y, b_h;
int balt_x;
CURL *curl = NULL;
Updater() {
touch_init(&touch);
fb = framebuffer_init("updater", 0x00001000, false,
&display, &surface, &fb_w, &fb_h);
assert(fb);
vg = nvgCreateGLES3(NVG_ANTIALIAS | NVG_STENCIL_STROKES | NVG_DEBUG);
assert(vg);
font = nvgCreateFontMem(vg, "courbd", (unsigned char*)bin_courbd, (bin_courbd_end - bin_courbd), 0);
assert(font >= 0);
b_w = 600;
balt_x = 200;
b_x = fb_w-b_w-200;
b_y = 700;
b_h = 250;
state = CONFIRMATION;
}
int download_file_xferinfo(curl_off_t dltotal, curl_off_t dlno,
curl_off_t ultotal, curl_off_t ulnow) {
{
std::lock_guard<std::mutex> guard(lock);
if (dltotal != 0) {
progress_frac = (float) dlno / dltotal;
}
}
// printf("info: %ld %ld %f\n", dltotal, dlno, progress_frac);
return 0;
}
bool download_file(std::string url, std::string out_fn) {
FILE *of = fopen(out_fn.c_str(), "ab");
assert(of);
CURLcode res;
long last_resume_from = 0;
fseek(of, 0, SEEK_END);
int tries = 4;
bool ret = false;
while (true) {
long resume_from = ftell(of);
curl_easy_setopt(curl, CURLOPT_URL, url.c_str());
curl_easy_setopt(curl, CURLOPT_FOLLOWLOCATION, 1);
curl_easy_setopt(curl, CURLOPT_NOSIGNAL, 1);
curl_easy_setopt(curl, CURLOPT_USERAGENT, USER_AGENT);
curl_easy_setopt(curl, CURLOPT_FAILONERROR, 1);
curl_easy_setopt(curl, CURLOPT_RESUME_FROM, resume_from);
curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, download_file_write);
curl_easy_setopt(curl, CURLOPT_WRITEDATA, of);
curl_easy_setopt(curl, CURLOPT_NOPROGRESS, 0);
curl_easy_setopt(curl, CURLOPT_XFERINFODATA, this);
curl_easy_setopt(curl, CURLOPT_XFERINFOFUNCTION, &Updater::download_file_xferinfo);
CURLcode res = curl_easy_perform(curl);
long response_code = 0;
curl_easy_getinfo(curl, CURLINFO_RESPONSE_CODE, &response_code);
// double content_length = 0.0;
// curl_easy_getinfo(curl, CURLINFO_CONTENT_LENGTH_DOWNLOAD, &content_length);
printf("download %s res %d, code %ld, resume from %ld\n", url.c_str(), res, response_code, resume_from);
if (res == CURLE_OK) {
ret = true;
break;
} else if (res == CURLE_HTTP_RETURNED_ERROR && response_code == 416) {
// failed because the file is already complete?
ret = true;
break;
} else if (resume_from == last_resume_from) {
// failed and dind't make make forward progress. only retry a couple times
tries--;
if (tries <= 0) {
break;
}
}
last_resume_from = resume_from;
}
// printf("res %d\n", res);
// printf("- %ld %f\n", response_code, content_length);
fclose(of);
return ret;
}
void set_progress(std::string text) {
std::lock_guard<std::mutex> guard(lock);
progress_text = text;
}
void set_error(std::string text) {
std::lock_guard<std::mutex> guard(lock);
error_text = text;
state = ERROR;
}
std::string stage_download(std::string url, std::string hash, std::string name) {
std::string out_fn = UPDATE_DIR "/" + util::base_name(url);
set_progress("downloading " + name + "...");
bool r = download_file(url, out_fn);
if (!r) {
set_error("failed to download " + name);
return "";
}
set_progress("verifying " + name + "...");
std::string fn_hash = sha256_file(out_fn);
printf("got %s hash: %s\n", name.c_str(), hash.c_str());
if (fn_hash != hash) {
set_error(name + " was corrupt");
unlink(out_fn.c_str());
return "";
}
return out_fn;
}
void run_stages() {
curl = curl_easy_init();
assert(curl);
if (!check_battery()) {
set_error("Please plug power in to your EON and wait for charge");
return;
}
if (!check_space()) {
set_error("2GB of free space required to update");
return;
}
mkdir(UPDATE_DIR, 0777);
const int EON = (access("/EON", F_OK) != -1);
set_progress("finding latest version...");
std::string manifest_s;
if (EON) {
manifest_s = download_string(curl, manifest_url);
} else {
// don't update NEO
exit(0);
}
printf("manifest: %s\n", manifest_s.c_str());
std::string err;
auto manifest = json11::Json::parse(manifest_s, err);
if (manifest.is_null() || !err.empty()) {
set_error("failed to load update manifest");
return;
}
std::string ota_url = manifest["ota_url"].string_value();
std::string ota_hash = manifest["ota_hash"].string_value();
std::string recovery_url = manifest["recovery_url"].string_value();
std::string recovery_hash = manifest["recovery_hash"].string_value();
int recovery_len = manifest["recovery_len"].int_value();
// std::string installer_url = manifest["installer_url"].string_value();
// std::string installer_hash = manifest["installer_hash"].string_value();
if (ota_url.empty() || ota_hash.empty()) {
set_error("invalid update manifest");
return;
}
// std::string installer_fn = stage_download(installer_url, installer_hash, "installer");
// if (installer_fn.empty()) {
// //error'd
// return;
// }
std::string recovery_fn;
if (recovery_url.empty() || recovery_hash.empty() || recovery_len == 0) {
set_progress("skipping recovery flash...");
} else {
// only download the recovery if it differs from what's flashed
set_progress("checking recovery...");
std::string existing_recovery_hash = sha256_file(RECOVERY_DEV, recovery_len);
printf("existing recovery hash: %s\n", existing_recovery_hash.c_str());
if (existing_recovery_hash != recovery_hash) {
recovery_fn = stage_download(recovery_url, recovery_hash, "recovery");
if (recovery_fn.empty()) {
// error'd
return;
}
}
}
std::string ota_fn = stage_download(ota_url, ota_hash, "update");
if (ota_fn.empty()) {
//error'd
return;
}
if (!check_battery()) {
set_error("must have at least 35% battery to update");
return;
}
if (!recovery_fn.empty()) {
// flash recovery
set_progress("flashing recovery...");
FILE *flash_file = fopen(recovery_fn.c_str(), "rb");
if (!flash_file) {
set_error("failed to flash recovery");
return;
}
FILE *recovery_dev = fopen(RECOVERY_DEV, "w+b");
if (!recovery_dev) {
fclose(flash_file);
set_error("failed to flash recovery");
return;
}
const size_t buf_size = 4096;
std::unique_ptr<char[]> buffer( new char[ buf_size ] );
while (true) {
size_t bytes_read = fread(buffer.get(), 1, buf_size, flash_file);
if (!bytes_read) break;
size_t bytes_written = fwrite(buffer.get(), 1, bytes_read, recovery_dev);
if (bytes_read != bytes_written) {
fclose(recovery_dev);
fclose(flash_file);
set_error("failed to flash recovery: write failed");
return;
}
}
fclose(recovery_dev);
fclose(flash_file);
set_progress("verifying flash...");
std::string new_recovery_hash = sha256_file(RECOVERY_DEV, recovery_len);
printf("new recovery hash: %s\n", new_recovery_hash.c_str());
if (new_recovery_hash != recovery_hash) {
set_error("recovery flash corrupted");
return;
}
}
// write arguments to recovery
FILE *cmd_file = fopen(RECOVERY_COMMAND, "wb");
if (!cmd_file) {
set_error("failed to reboot into recovery");
return;
}
fprintf(cmd_file, "--update_package=%s\n", ota_fn.c_str());
fclose(cmd_file);
set_progress("rebooting");
// remove the continue.sh so we come back into the setup.
// maybe we should go directly into the installer, but what if we don't come back with internet? :/
//unlink("/data/data/com.termux/files/continue.sh");
// TODO: this should be generic between android versions
// IPowerManager.reboot(confirm=false, reason="recovery", wait=true)
system("service call power 16 i32 0 s16 recovery i32 1");
while(1) pause();
// execl("/system/bin/reboot", "recovery");
// set_error("failed to reboot into recovery");
}
void draw_ack_screen(const char *message, const char *button, const char *altbutton) {
nvgFontSize(vg, 96.0f);
nvgFillColor(vg, nvgRGBA(255,255,255,255));
nvgTextAlign(vg, NVG_ALIGN_LEFT | NVG_ALIGN_BASELINE);
nvgTextBox(vg, 50, 100, fb_w-100, message, NULL);
// draw button
if (button) {
nvgBeginPath(vg);
nvgFillColor(vg, nvgRGBA(0, 0, 0, 255));
nvgRoundedRect(vg, b_x, b_y, b_w, b_h, 20);
nvgFill(vg);
nvgFillColor(vg, nvgRGBA(255, 255, 255, 255));
nvgTextAlign(vg, NVG_ALIGN_CENTER | NVG_ALIGN_MIDDLE);
nvgText(vg, b_x+b_w/2, b_y+b_h/2, button, NULL);
nvgBeginPath(vg);
nvgStrokeColor(vg, nvgRGBA(255, 255, 255, 255));
nvgStrokeWidth(vg, 5);
nvgRoundedRect(vg, b_x, b_y, b_w, b_h, 20);
nvgStroke(vg);
}
// draw button
if (altbutton) {
nvgBeginPath(vg);
nvgFillColor(vg, nvgRGBA(0, 0, 0, 255));
nvgRoundedRect(vg, balt_x, b_y, b_w, b_h, 20);
nvgFill(vg);
nvgFillColor(vg, nvgRGBA(255, 255, 255, 255));
nvgTextAlign(vg, NVG_ALIGN_CENTER | NVG_ALIGN_MIDDLE);
nvgText(vg, balt_x+b_w/2, b_y+b_h/2, altbutton, NULL);
nvgBeginPath(vg);
nvgStrokeColor(vg, nvgRGBA(255, 255, 255, 255));
nvgStrokeWidth(vg, 5);
nvgRoundedRect(vg, balt_x, b_y, b_w, b_h, 20);
nvgStroke(vg);
}
}
void draw_progress_screen() {
// draw progress message
nvgFontSize(vg, 64.0f);
nvgFillColor(vg, nvgRGBA(255,255,255,255));
nvgTextAlign(vg, NVG_ALIGN_CENTER | NVG_ALIGN_BASELINE);
nvgTextBox(vg, 0, 700, fb_w, progress_text.c_str(), NULL);
// draw progress bar
{
int progress_width = 800;
int progress_x = fb_w/2-progress_width/2;
int progress_y = 768;
int progress_height = 15;
int powerprompt_y = 512;
nvgText(vg, fb_w/2, powerprompt_y, "Ensure EON is connected to power", NULL);
NVGpaint paint = nvgBoxGradient(
vg, progress_x + 1, progress_y + 1,
progress_width - 2, progress_height, 3, 4, nvgRGB(0, 32, 0), nvgRGB(0, 92, 0));
nvgBeginPath(vg);
nvgRoundedRect(vg, progress_x, progress_y, progress_width, progress_height, 3);
nvgFillPaint(vg, paint);
nvgFill(vg);
float value = std::min(std::max(0.0f, progress_frac), 1.0f);
int bar_pos = ((progress_width - 2) * value);
paint = nvgBoxGradient(
vg, progress_x, progress_y,
bar_pos+1.5f, progress_height-1, 3, 4,
nvgRGB(220, 100, 0), nvgRGB(128, 100, 0));
nvgBeginPath(vg);
nvgRoundedRect(
vg, progress_x+1, progress_y+1,
bar_pos, progress_height-2, 3);
nvgFillPaint(vg, paint);
nvgFill(vg);
}
}
void ui_draw() {
std::lock_guard<std::mutex> guard(lock);
nvgBeginFrame(vg, fb_w, fb_h, 1.0f);
switch (state) {
case CONFIRMATION:
draw_ack_screen("An upgrade to NEOS is required.\n\n"
"Your device will now be reset and upgraded. You may want to connect to wifi as download is around 1 GB\nData on device shouldn't be lost.",
"continue",
"wifi");
break;
case RUNNING:
draw_progress_screen();
break;
case ERROR:
draw_ack_screen(("ERROR: " + error_text + "\n\nYou will need to retry").c_str(), NULL, "exit");
break;
}
nvgEndFrame(vg);
}
void ui_update() {
std::lock_guard<std::mutex> guard(lock);
switch (state) {
case ERROR:
case CONFIRMATION: {
int touch_x = -1, touch_y = -1;
int res = touch_poll(&touch, &touch_x, &touch_y, 0);
if (res == 1 && !is_settings_active()) {
if (touch_x >= b_x && touch_x < b_x+b_w && touch_y >= b_y && touch_y < b_y+b_h) {
if (state == CONFIRMATION) {
state = RUNNING;
update_thread_handle = std::thread(&Updater::run_stages, this);
}
}
if (touch_x >= balt_x && touch_x < balt_x+b_w && touch_y >= b_y && touch_y < b_y+b_h) {
if (state == CONFIRMATION) {
start_settings_activity("Settings$WifiSettingsActivity");
} else if (state == ERROR) {
do_exit = 1;
}
}
}
}
default:
break;
}
}
void go() {
while (!do_exit) {
ui_update();
glClearColor(0.19, 0.09, 0.2, 1.0);
glClear(GL_STENCIL_BUFFER_BIT | GL_COLOR_BUFFER_BIT);
glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
ui_draw();
glDisable(GL_BLEND);
eglSwapBuffers(display, surface);
assert(glGetError() == GL_NO_ERROR);
// no simple way to do 30fps vsync with surfaceflinger...
usleep(30000);
}
if (update_thread_handle.joinable()) {
update_thread_handle.join();
}
system("service call power 16 i32 0 i32 0 i32 1");
}
bool is_settings_active() {
FILE *fp;
char sys_output[4096];
fp = popen("/bin/dumpsys window windows", "r");
if (fp == NULL) {
return false;
}
bool active = false;
while (fgets(sys_output, sizeof(sys_output), fp) != NULL) {
if (strstr(sys_output, "mCurrentFocus=null") != NULL) {
break;
}
if (strstr(sys_output, "mCurrentFocus=Window") != NULL) {
active = true;
break;
}
}
pclose(fp);
return active;
}
};
}
int main(int argc, char *argv[]) {
if (argc > 1) {
if (strcmp(argv[1], "local") == 0) {
manifest_url = MANIFEST_URL_EON_LOCAL;
} else if (strcmp(argv[1], "staging") == 0) {
manifest_url = MANIFEST_URL_EON_STAGING;
} else {
manifest_url = argv[1];
}
}
printf("updating from %s\n", manifest_url);
Updater updater;
updater.go();
return 0;
}
+3 -16
View File
@@ -1,11 +1,5 @@
#!/usr/bin/bash
export OMP_NUM_THREADS=1
export MKL_NUM_THREADS=1
export NUMEXPR_NUM_THREADS=1
export OPENBLAS_NUM_THREADS=1
export VECLIB_MAXIMUM_THREADS=1
if [ -z "$PASSIVE" ]; then
export PASSIVE="1"
fi
@@ -13,16 +7,9 @@ fi
function launch {
# apply update
if [ "$(git rev-parse HEAD)" != "$(git rev-parse @{u})" ]; then
git reset --hard @{u} &&
git clean -xdf &&
# Touch all files on release2 after checkout to prevent rebuild
BRANCH=$(git rev-parse --abbrev-ref HEAD)
if [[ "$BRANCH" == "release2" ]]; then
touch **
fi
exec "${BASH_SOURCE[0]}"
git reset --hard @{u} &&
git clean -xdf &&
exec "${BASH_SOURCE[0]}"
fi
# no cpu rationing for now
Binary file not shown.
+2 -3
View File
@@ -164,15 +164,14 @@ BO_ 780 ACC_HUD: 8 ADAS
SG_ FCM_PROBLEM : 34|1@0+ (1,0) [0|1] "" BDY
SG_ RADAR_OBSTRUCTED : 33|1@0+ (1,0) [0|1] "" BDY
SG_ ENABLE_MINI_CAR : 32|1@0+ (1,0) [0|1] "" BDY
SG_ HUD_DISTANCE : 47|2@0+ (1,0) [0|3] "" BDY
SG_ SET_ME_X03 : 47|2@0+ (1,0) [0|3] "" BDY
SG_ HUD_LEAD : 45|2@0+ (1,0) [0|3] "" BDY
SG_ BOH_3 : 43|1@0+ (1,0) [0|3] "" BDY
SG_ BOH_4 : 42|1@0+ (1,0) [0|3] "" BDY
SG_ BOH_5 : 41|1@0+ (1,0) [0|3] "" BDY
SG_ CRUISE_CONTROL_LABEL : 40|1@0+ (1,0) [0|3] "" BDY
SG_ HUD_DISTANCE_3 : 52|1@0+ (1,0) [0|1] "" BDY
SG_ IMPERIAL_UNIT : 54|1@0+ (1,0) [0|1] "" BDY
SG_ SET_ME_X01_2 : 55|1@0+ (1,0) [0|1] "" BDY
SG_ SET_ME_X03_2 : 55|2@0+ (1,0) [0|3] "" BDY
SG_ SET_ME_X01 : 48|1@0+ (1,0) [0|1] "" BDY
SG_ COUNTER : 61|2@0+ (1,0) [0|3] "" BDY
SG_ CHECKSUM : 59|4@0+ (1,0) [0|3] "" BDY
+2 -3
View File
@@ -164,15 +164,14 @@ BO_ 780 ACC_HUD: 8 ADAS
SG_ FCM_PROBLEM : 34|1@0+ (1,0) [0|1] "" BDY
SG_ RADAR_OBSTRUCTED : 33|1@0+ (1,0) [0|1] "" BDY
SG_ ENABLE_MINI_CAR : 32|1@0+ (1,0) [0|1] "" BDY
SG_ HUD_DISTANCE : 47|2@0+ (1,0) [0|3] "" BDY
SG_ SET_ME_X03 : 47|2@0+ (1,0) [0|3] "" BDY
SG_ HUD_LEAD : 45|2@0+ (1,0) [0|3] "" BDY
SG_ BOH_3 : 43|1@0+ (1,0) [0|3] "" BDY
SG_ BOH_4 : 42|1@0+ (1,0) [0|3] "" BDY
SG_ BOH_5 : 41|1@0+ (1,0) [0|3] "" BDY
SG_ CRUISE_CONTROL_LABEL : 40|1@0+ (1,0) [0|3] "" BDY
SG_ HUD_DISTANCE_3 : 52|1@0+ (1,0) [0|1] "" BDY
SG_ IMPERIAL_UNIT : 54|1@0+ (1,0) [0|1] "" BDY
SG_ SET_ME_X01_2 : 55|1@0+ (1,0) [0|1] "" BDY
SG_ SET_ME_X03_2 : 55|2@0+ (1,0) [0|3] "" BDY
SG_ SET_ME_X01 : 48|1@0+ (1,0) [0|1] "" BDY
SG_ COUNTER : 61|2@0+ (1,0) [0|3] "" BDY
SG_ CHECKSUM : 59|4@0+ (1,0) [0|3] "" BDY
+2 -3
View File
@@ -196,8 +196,7 @@ BO_ 780 ACC_HUD: 8 ADAS
SG_ ACC_PROBLEM : 37|1@0+ (1,0) [0|1] "" BDY
SG_ ACC_ON : 52|1@0+ (1,0) [0|1] "" XXX
SG_ BOH_6 : 51|4@0+ (1,0) [0|15] "" XXX
SG_ IMPERIAL_UNIT : 55|1@0+ (1,0) [0|1] "" XXX
SG_ SET_TO_X1 : 56|1@0+ (1,0) [0|1] "" XXX
SG_ SET_TO_X3 : 55|2@0+ (1,0) [0|3] "" XXX
SG_ COUNTER : 61|2@0+ (1,0) [0|3] "" XXX
SG_ CHECKSUM : 59|4@0+ (1,0) [0|15] "" XXX
@@ -261,4 +260,4 @@ BO_ 891 STALK_STATUS_2: 8 XXX
SG_ CHECKSUM : 59|4@0+ (1,0) [0|3] "" EON
SG_ COUNTER : 61|2@0+ (1,0) [0|3] "" EON
VAL_ 399 STEER_STATUS 6 "tmp_fault" 5 "fault_1" 4 "no_torque_alert_2" 3 "low_speed_lockout" 2 "no_torque_alert_1" 0 "normal" ;
VAL_ 399 STEER_STATUS 6 "tmp_fault" 5 "fault_1" 4 "no_torque_alert_2" 3 "low_speed_lockout" 2 "no_torque_alert_1" 0 "normal" ;
+2 -3
View File
@@ -142,15 +142,14 @@ BO_ 780 ACC_HUD: 8 ADAS
SG_ FCM_PROBLEM : 34|1@0+ (1,0) [0|1] "" BDY
SG_ RADAR_OBSTRUCTED : 33|1@0+ (1,0) [0|1] "" BDY
SG_ ENABLE_MINI_CAR : 32|1@0+ (1,0) [0|1] "" BDY
SG_ HUD_DISTANCE : 47|2@0+ (1,0) [0|3] "" BDY
SG_ SET_ME_X03 : 47|2@0+ (1,0) [0|3] "" BDY
SG_ HUD_LEAD : 45|2@0+ (1,0) [0|3] "" BDY
SG_ BOH_3 : 43|1@0+ (1,0) [0|3] "" BDY
SG_ BOH_4 : 42|1@0+ (1,0) [0|3] "" BDY
SG_ BOH_5 : 41|1@0+ (1,0) [0|3] "" BDY
SG_ CRUISE_CONTROL_LABEL : 40|1@0+ (1,0) [0|3] "" BDY
SG_ HUD_DISTANCE_3 : 52|1@0+ (1,0) [0|1] "" BDY
SG_ IMPERIAL_UNIT : 54|1@0+ (1,0) [0|1] "" BDY
SG_ SET_ME_X01_2 : 55|1@0+ (1,0) [0|1] "" BDY
SG_ SET_ME_X03_2 : 55|2@0+ (1,0) [0|3] "" BDY
SG_ SET_ME_X01 : 48|1@0+ (1,0) [0|1] "" BDY
SG_ COUNTER : 61|2@0+ (1,0) [0|3] "" BDY
SG_ CHECKSUM : 59|4@0+ (1,0) [0|3] "" BDY
@@ -50,8 +50,8 @@ BO_ 450 EPB_STATUS: 8 EPB
SG_ COUNTER : 61|2@0+ (1,0) [0|3] "" EON
SG_ CHECKSUM : 59|4@0+ (1,0) [0|3] "" EON
BO_ 493 HUD_SETTING: 5 XXX
SG_ IMPERIAL_UNIT : 5|1@0+ (1,0) [0|1] "" EON
BO_ 493 HUD_SETTING: 8 XXX
SG_ SPEED_UNIT : 5|1@0+ (1,0) [0|1] "" EON
BO_ 487 BRAKE_PRESSURE: 4 VSA
SG_ BRAKE_PRESSURE1 : 7|10@0+ (0.015625,-103) [0|1000] "" EON
@@ -128,6 +128,7 @@ VAL_ 399 STEER_STATUS 6 "tmp_fault" 5 "fault_1" 4 "no_torque_alert_2" 3 "low_spe
VAL_ 401 GEAR_SHIFTER 32 "L" 16 "S" 8 "D" 4 "N" 2 "R" 1 "P" ;
VAL_ 401 GEAR 7 "L" 10 "S" 4 "D" 3 "N" 2 "R" 1 "P" ;
VAL_ 450 EPB_STATE 3 "engaged" 2 "disengaging" 1 "engaging" 0 "disengaged" ;
VAL_ 493 SPEED_UNIT 1 "mph" 0 "kph" ;
VAL_ 545 ECON_ON_2 0 "off" 3 "on" ;
VAL_ 662 CRUISE_BUTTONS 7 "tbd" 6 "tbd" 5 "tbd" 4 "accel_res" 3 "decel_set" 2 "cancel" 1 "main" 0 "none" ;
VAL_ 662 CRUISE_SETTING 3 "distance_adj" 2 "tbd" 1 "lkas_button" 0 "none" ;
+1 -1
View File
@@ -91,7 +91,7 @@ BO_ 614 STEERING_IPAS: 8 IPAS
SG_ SET_ME_X00 : 31|8@0+ (1,0) [0|255] "" XXX
SG_ DIRECTION_CMD : 38|2@0+ (1,0) [0|3] "" XXX
SG_ SET_ME_X40 : 47|8@0+ (1,0) [0|255] "" XXX
SG_ SET_ME_X00_1 : 55|8@0+ (1,0) [0|255] "" XXX
SG_ SET_ME_X00 : 55|8@0+ (1,0) [0|255] "" XXX
SG_ CHECKSUM : 63|8@0+ (1,0) [0|255] "" XXX
BO_ 643 PRE_COLLISION: 8 XXX
@@ -16,7 +16,7 @@ BO_ 581 GAS_PEDAL: 8 XXX
SG_ GAS_PEDAL : 23|8@0+ (0.005,0) [0|1] "" XXX
BO_ 608 STEER_TORQUE_SENSOR: 8 XXX
SG_ STEER_TORQUE_EPS : 47|16@0- (0.73,0) [-20000|20000] "" XXX
SG_ STEER_TORQUE_EPS : 47|16@0- (0.66,0) [-20000|20000] "" XXX
SG_ STEER_TORQUE_DRIVER : 15|16@0- (1,0) [-32768|32767] "" XXX
SG_ STEER_OVERRIDE : 0|1@0+ (1,0) [0|1] "" XXX
SG_ CHECKSUM : 63|8@0+ (1,0) [0|255] "" XXX
@@ -1,17 +1,6 @@
CM_ "IMPORT _toyota_2017.dbc"
CM_ "IMPORT _comma.dbc"
BO_ 401 STEERING_LTA: 8 XXX
SG_ COUNTER : 7|8@0+ (1,0) [0|255] "" XXX
SG_ CHECKSUM : 63|8@0+ (1,0) [0|255] "" XXX
SG_ SETME_X3 : 29|2@0+ (1,0) [0|3] "" XXX
SG_ PERCENTAGE : 39|8@0+ (1,0) [0|255] "" XXX
SG_ SETME_X64 : 47|8@0+ (1,0) [0|255] "" XXX
SG_ ANGLE : 55|8@0- (0.5,0) [0|255] "" XXX
SG_ STEER_ANGLE_CMD : 15|16@0- (0.056,0) [-540|540] "" XXX
SG_ STEER_REQUEST : 25|1@0+ (1,0) [0|1] "" XXX
SG_ BIT : 30|1@0+ (1,0) [0|1] "" XXX
BO_ 550 BRAKE_MODULE: 8 XXX
SG_ BRAKE_PRESSURE : 0|9@0+ (1,0) [0|511] "" XXX
SG_ BRAKE_POSITION : 16|9@0+ (1,0) [0|511] "" XXX
@@ -26,7 +15,6 @@ BO_ 608 STEER_TORQUE_SENSOR: 8 XXX
SG_ STEER_TORQUE_DRIVER : 15|16@0- (1,0) [-32768|32767] "" XXX
SG_ STEER_OVERRIDE : 0|1@0+ (1,0) [0|1] "" XXX
SG_ CHECKSUM : 63|8@0+ (1,0) [0|255] "" XXX
SG_ STEER_ANGLE : 31|16@0- (0.056,0) [-500|500] "" XXX
BO_ 610 EPS_STATUS: 8 EPS
SG_ IPAS_STATE : 3|4@0+ (1,0) [0|15] "" XXX
@@ -20,7 +20,6 @@ BO_ 608 STEER_TORQUE_SENSOR: 8 XXX
SG_ STEER_TORQUE_DRIVER : 15|16@0- (1,0) [-32768|32767] "" XXX
SG_ STEER_OVERRIDE : 0|1@0+ (1,0) [0|1] "" XXX
SG_ CHECKSUM : 63|8@0+ (1,0) [0|255] "" XXX
SG_ STEER_ANGLE : 31|16@0- (0.056,0) [-500|500] "" XXX
BO_ 610 EPS_STATUS: 8 EPS
SG_ IPAS_STATE : 3|4@0+ (1,0) [0|15] "" XXX
@@ -200,8 +200,7 @@ BO_ 780 ACC_HUD: 8 ADAS
SG_ ACC_PROBLEM : 37|1@0+ (1,0) [0|1] "" BDY
SG_ ACC_ON : 52|1@0+ (1,0) [0|1] "" XXX
SG_ BOH_6 : 51|4@0+ (1,0) [0|15] "" XXX
SG_ IMPERIAL_UNIT : 55|1@0+ (1,0) [0|1] "" XXX
SG_ SET_TO_X1 : 56|1@0+ (1,0) [0|1] "" XXX
SG_ SET_TO_X3 : 55|2@0+ (1,0) [0|3] "" XXX
SG_ COUNTER : 61|2@0+ (1,0) [0|3] "" XXX
SG_ CHECKSUM : 59|4@0+ (1,0) [0|15] "" XXX
@@ -266,7 +265,6 @@ BO_ 891 STALK_STATUS_2: 8 XXX
SG_ COUNTER : 61|2@0+ (1,0) [0|3] "" EON
VAL_ 399 STEER_STATUS 6 "tmp_fault" 5 "fault_1" 4 "no_torque_alert_2" 3 "low_speed_lockout" 2 "no_torque_alert_1" 0 "normal" ;
CM_ "honda_accord_lx15t_2018_can.dbc starts here"
@@ -200,8 +200,7 @@ BO_ 780 ACC_HUD: 8 ADAS
SG_ ACC_PROBLEM : 37|1@0+ (1,0) [0|1] "" BDY
SG_ ACC_ON : 52|1@0+ (1,0) [0|1] "" XXX
SG_ BOH_6 : 51|4@0+ (1,0) [0|15] "" XXX
SG_ IMPERIAL_UNIT : 55|1@0+ (1,0) [0|1] "" XXX
SG_ SET_TO_X1 : 56|1@0+ (1,0) [0|1] "" XXX
SG_ SET_TO_X3 : 55|2@0+ (1,0) [0|3] "" XXX
SG_ COUNTER : 61|2@0+ (1,0) [0|3] "" XXX
SG_ CHECKSUM : 59|4@0+ (1,0) [0|15] "" XXX
@@ -266,7 +265,6 @@ BO_ 891 STALK_STATUS_2: 8 XXX
SG_ COUNTER : 61|2@0+ (1,0) [0|3] "" EON
VAL_ 399 STEER_STATUS 6 "tmp_fault" 5 "fault_1" 4 "no_torque_alert_2" 3 "low_speed_lockout" 2 "no_torque_alert_1" 0 "normal" ;
CM_ "honda_accord_s2t_2018_can.dbc starts here"
@@ -200,8 +200,7 @@ BO_ 780 ACC_HUD: 8 ADAS
SG_ ACC_PROBLEM : 37|1@0+ (1,0) [0|1] "" BDY
SG_ ACC_ON : 52|1@0+ (1,0) [0|1] "" XXX
SG_ BOH_6 : 51|4@0+ (1,0) [0|15] "" XXX
SG_ IMPERIAL_UNIT : 55|1@0+ (1,0) [0|1] "" XXX
SG_ SET_TO_X1 : 56|1@0+ (1,0) [0|1] "" XXX
SG_ SET_TO_X3 : 55|2@0+ (1,0) [0|3] "" XXX
SG_ COUNTER : 61|2@0+ (1,0) [0|3] "" XXX
SG_ CHECKSUM : 59|4@0+ (1,0) [0|15] "" XXX
@@ -266,7 +265,6 @@ BO_ 891 STALK_STATUS_2: 8 XXX
SG_ COUNTER : 61|2@0+ (1,0) [0|3] "" EON
VAL_ 399 STEER_STATUS 6 "tmp_fault" 5 "fault_1" 4 "no_torque_alert_2" 3 "low_speed_lockout" 2 "no_torque_alert_1" 0 "normal" ;
CM_ "honda_civic_hatchback_ex_2017_can.dbc starts here"
@@ -164,15 +164,14 @@ BO_ 780 ACC_HUD: 8 ADAS
SG_ FCM_PROBLEM : 34|1@0+ (1,0) [0|1] "" BDY
SG_ RADAR_OBSTRUCTED : 33|1@0+ (1,0) [0|1] "" BDY
SG_ ENABLE_MINI_CAR : 32|1@0+ (1,0) [0|1] "" BDY
SG_ HUD_DISTANCE : 47|2@0+ (1,0) [0|3] "" BDY
SG_ SET_ME_X03 : 47|2@0+ (1,0) [0|3] "" BDY
SG_ HUD_LEAD : 45|2@0+ (1,0) [0|3] "" BDY
SG_ BOH_3 : 43|1@0+ (1,0) [0|3] "" BDY
SG_ BOH_4 : 42|1@0+ (1,0) [0|3] "" BDY
SG_ BOH_5 : 41|1@0+ (1,0) [0|3] "" BDY
SG_ CRUISE_CONTROL_LABEL : 40|1@0+ (1,0) [0|3] "" BDY
SG_ HUD_DISTANCE_3 : 52|1@0+ (1,0) [0|1] "" BDY
SG_ IMPERIAL_UNIT : 54|1@0+ (1,0) [0|1] "" BDY
SG_ SET_ME_X01_2 : 55|1@0+ (1,0) [0|1] "" BDY
SG_ SET_ME_X03_2 : 55|2@0+ (1,0) [0|3] "" BDY
SG_ SET_ME_X01 : 48|1@0+ (1,0) [0|1] "" BDY
SG_ COUNTER : 61|2@0+ (1,0) [0|3] "" BDY
SG_ CHECKSUM : 59|4@0+ (1,0) [0|3] "" BDY
@@ -289,8 +288,8 @@ BO_ 450 EPB_STATUS: 8 EPB
SG_ COUNTER : 61|2@0+ (1,0) [0|3] "" EON
SG_ CHECKSUM : 59|4@0+ (1,0) [0|3] "" EON
BO_ 493 HUD_SETTING: 5 XXX
SG_ IMPERIAL_UNIT : 5|1@0+ (1,0) [0|1] "" EON
BO_ 493 HUD_SETTING: 8 XXX
SG_ SPEED_UNIT : 5|1@0+ (1,0) [0|1] "" EON
BO_ 487 BRAKE_PRESSURE: 4 VSA
SG_ BRAKE_PRESSURE1 : 7|10@0+ (0.015625,-103) [0|1000] "" EON
@@ -367,6 +366,7 @@ VAL_ 399 STEER_STATUS 6 "tmp_fault" 5 "fault_1" 4 "no_torque_alert_2" 3 "low_spe
VAL_ 401 GEAR_SHIFTER 32 "L" 16 "S" 8 "D" 4 "N" 2 "R" 1 "P" ;
VAL_ 401 GEAR 7 "L" 10 "S" 4 "D" 3 "N" 2 "R" 1 "P" ;
VAL_ 450 EPB_STATE 3 "engaged" 2 "disengaging" 1 "engaging" 0 "disengaged" ;
VAL_ 493 SPEED_UNIT 1 "mph" 0 "kph" ;
VAL_ 545 ECON_ON_2 0 "off" 3 "on" ;
VAL_ 662 CRUISE_BUTTONS 7 "tbd" 6 "tbd" 5 "tbd" 4 "accel_res" 3 "decel_set" 2 "cancel" 1 "main" 0 "none" ;
VAL_ 662 CRUISE_SETTING 3 "distance_adj" 2 "tbd" 1 "lkas_button" 0 "none" ;
+1 -3
View File
@@ -200,8 +200,7 @@ BO_ 780 ACC_HUD: 8 ADAS
SG_ ACC_PROBLEM : 37|1@0+ (1,0) [0|1] "" BDY
SG_ ACC_ON : 52|1@0+ (1,0) [0|1] "" XXX
SG_ BOH_6 : 51|4@0+ (1,0) [0|15] "" XXX
SG_ IMPERIAL_UNIT : 55|1@0+ (1,0) [0|1] "" XXX
SG_ SET_TO_X1 : 56|1@0+ (1,0) [0|1] "" XXX
SG_ SET_TO_X3 : 55|2@0+ (1,0) [0|3] "" XXX
SG_ COUNTER : 61|2@0+ (1,0) [0|3] "" XXX
SG_ CHECKSUM : 59|4@0+ (1,0) [0|15] "" XXX
@@ -266,7 +265,6 @@ BO_ 891 STALK_STATUS_2: 8 XXX
SG_ COUNTER : 61|2@0+ (1,0) [0|3] "" EON
VAL_ 399 STEER_STATUS 6 "tmp_fault" 5 "fault_1" 4 "no_torque_alert_2" 3 "low_speed_lockout" 2 "no_torque_alert_1" 0 "normal" ;
CM_ "honda_crv_ex_2017_can.dbc starts here"
@@ -200,8 +200,7 @@ BO_ 780 ACC_HUD: 8 ADAS
SG_ ACC_PROBLEM : 37|1@0+ (1,0) [0|1] "" BDY
SG_ ACC_ON : 52|1@0+ (1,0) [0|1] "" XXX
SG_ BOH_6 : 51|4@0+ (1,0) [0|15] "" XXX
SG_ IMPERIAL_UNIT : 55|1@0+ (1,0) [0|1] "" XXX
SG_ SET_TO_X1 : 56|1@0+ (1,0) [0|1] "" XXX
SG_ SET_TO_X3 : 55|2@0+ (1,0) [0|3] "" XXX
SG_ COUNTER : 61|2@0+ (1,0) [0|3] "" XXX
SG_ CHECKSUM : 59|4@0+ (1,0) [0|15] "" XXX
@@ -266,7 +265,6 @@ BO_ 891 STALK_STATUS_2: 8 XXX
SG_ COUNTER : 61|2@0+ (1,0) [0|3] "" EON
VAL_ 399 STEER_STATUS 6 "tmp_fault" 5 "fault_1" 4 "no_torque_alert_2" 3 "low_speed_lockout" 2 "no_torque_alert_1" 0 "normal" ;
CM_ "honda_crv_hybrid_2019_can.dbc starts here"
@@ -164,15 +164,14 @@ BO_ 780 ACC_HUD: 8 ADAS
SG_ FCM_PROBLEM : 34|1@0+ (1,0) [0|1] "" BDY
SG_ RADAR_OBSTRUCTED : 33|1@0+ (1,0) [0|1] "" BDY
SG_ ENABLE_MINI_CAR : 32|1@0+ (1,0) [0|1] "" BDY
SG_ HUD_DISTANCE : 47|2@0+ (1,0) [0|3] "" BDY
SG_ SET_ME_X03 : 47|2@0+ (1,0) [0|3] "" BDY
SG_ HUD_LEAD : 45|2@0+ (1,0) [0|3] "" BDY
SG_ BOH_3 : 43|1@0+ (1,0) [0|3] "" BDY
SG_ BOH_4 : 42|1@0+ (1,0) [0|3] "" BDY
SG_ BOH_5 : 41|1@0+ (1,0) [0|3] "" BDY
SG_ CRUISE_CONTROL_LABEL : 40|1@0+ (1,0) [0|3] "" BDY
SG_ HUD_DISTANCE_3 : 52|1@0+ (1,0) [0|1] "" BDY
SG_ IMPERIAL_UNIT : 54|1@0+ (1,0) [0|1] "" BDY
SG_ SET_ME_X01_2 : 55|1@0+ (1,0) [0|1] "" BDY
SG_ SET_ME_X03_2 : 55|2@0+ (1,0) [0|3] "" BDY
SG_ SET_ME_X01 : 48|1@0+ (1,0) [0|1] "" BDY
SG_ COUNTER : 61|2@0+ (1,0) [0|3] "" BDY
SG_ CHECKSUM : 59|4@0+ (1,0) [0|3] "" BDY
+2 -3
View File
@@ -164,15 +164,14 @@ BO_ 780 ACC_HUD: 8 ADAS
SG_ FCM_PROBLEM : 34|1@0+ (1,0) [0|1] "" BDY
SG_ RADAR_OBSTRUCTED : 33|1@0+ (1,0) [0|1] "" BDY
SG_ ENABLE_MINI_CAR : 32|1@0+ (1,0) [0|1] "" BDY
SG_ HUD_DISTANCE : 47|2@0+ (1,0) [0|3] "" BDY
SG_ SET_ME_X03 : 47|2@0+ (1,0) [0|3] "" BDY
SG_ HUD_LEAD : 45|2@0+ (1,0) [0|3] "" BDY
SG_ BOH_3 : 43|1@0+ (1,0) [0|3] "" BDY
SG_ BOH_4 : 42|1@0+ (1,0) [0|3] "" BDY
SG_ BOH_5 : 41|1@0+ (1,0) [0|3] "" BDY
SG_ CRUISE_CONTROL_LABEL : 40|1@0+ (1,0) [0|3] "" BDY
SG_ HUD_DISTANCE_3 : 52|1@0+ (1,0) [0|1] "" BDY
SG_ IMPERIAL_UNIT : 54|1@0+ (1,0) [0|1] "" BDY
SG_ SET_ME_X01_2 : 55|1@0+ (1,0) [0|1] "" BDY
SG_ SET_ME_X03_2 : 55|2@0+ (1,0) [0|3] "" BDY
SG_ SET_ME_X01 : 48|1@0+ (1,0) [0|1] "" BDY
SG_ COUNTER : 61|2@0+ (1,0) [0|3] "" BDY
SG_ CHECKSUM : 59|4@0+ (1,0) [0|3] "" BDY
@@ -200,8 +200,7 @@ BO_ 780 ACC_HUD: 8 ADAS
SG_ ACC_PROBLEM : 37|1@0+ (1,0) [0|1] "" BDY
SG_ ACC_ON : 52|1@0+ (1,0) [0|1] "" XXX
SG_ BOH_6 : 51|4@0+ (1,0) [0|15] "" XXX
SG_ IMPERIAL_UNIT : 55|1@0+ (1,0) [0|1] "" XXX
SG_ SET_TO_X1 : 56|1@0+ (1,0) [0|1] "" XXX
SG_ SET_TO_X3 : 55|2@0+ (1,0) [0|3] "" XXX
SG_ COUNTER : 61|2@0+ (1,0) [0|3] "" XXX
SG_ CHECKSUM : 59|4@0+ (1,0) [0|15] "" XXX
@@ -266,7 +265,6 @@ BO_ 891 STALK_STATUS_2: 8 XXX
SG_ COUNTER : 61|2@0+ (1,0) [0|3] "" EON
VAL_ 399 STEER_STATUS 6 "tmp_fault" 5 "fault_1" 4 "no_torque_alert_2" 3 "low_speed_lockout" 2 "no_torque_alert_1" 0 "normal" ;
CM_ "honda_insight_ex_2019_can.dbc starts here"
+2 -3
View File
@@ -164,15 +164,14 @@ BO_ 780 ACC_HUD: 8 ADAS
SG_ FCM_PROBLEM : 34|1@0+ (1,0) [0|1] "" BDY
SG_ RADAR_OBSTRUCTED : 33|1@0+ (1,0) [0|1] "" BDY
SG_ ENABLE_MINI_CAR : 32|1@0+ (1,0) [0|1] "" BDY
SG_ HUD_DISTANCE : 47|2@0+ (1,0) [0|3] "" BDY
SG_ SET_ME_X03 : 47|2@0+ (1,0) [0|3] "" BDY
SG_ HUD_LEAD : 45|2@0+ (1,0) [0|3] "" BDY
SG_ BOH_3 : 43|1@0+ (1,0) [0|3] "" BDY
SG_ BOH_4 : 42|1@0+ (1,0) [0|3] "" BDY
SG_ BOH_5 : 41|1@0+ (1,0) [0|3] "" BDY
SG_ CRUISE_CONTROL_LABEL : 40|1@0+ (1,0) [0|3] "" BDY
SG_ HUD_DISTANCE_3 : 52|1@0+ (1,0) [0|1] "" BDY
SG_ IMPERIAL_UNIT : 54|1@0+ (1,0) [0|1] "" BDY
SG_ SET_ME_X01_2 : 55|1@0+ (1,0) [0|1] "" BDY
SG_ SET_ME_X03_2 : 55|2@0+ (1,0) [0|3] "" BDY
SG_ SET_ME_X01 : 48|1@0+ (1,0) [0|1] "" BDY
SG_ COUNTER : 61|2@0+ (1,0) [0|3] "" BDY
SG_ CHECKSUM : 59|4@0+ (1,0) [0|3] "" BDY
@@ -150,15 +150,14 @@ BO_ 780 ACC_HUD: 8 ADAS
SG_ FCM_PROBLEM : 34|1@0+ (1,0) [0|1] "" BDY
SG_ RADAR_OBSTRUCTED : 33|1@0+ (1,0) [0|1] "" BDY
SG_ ENABLE_MINI_CAR : 32|1@0+ (1,0) [0|1] "" BDY
SG_ HUD_DISTANCE : 47|2@0+ (1,0) [0|3] "" BDY
SG_ SET_ME_X03 : 47|2@0+ (1,0) [0|3] "" BDY
SG_ HUD_LEAD : 45|2@0+ (1,0) [0|3] "" BDY
SG_ BOH_3 : 43|1@0+ (1,0) [0|3] "" BDY
SG_ BOH_4 : 42|1@0+ (1,0) [0|3] "" BDY
SG_ BOH_5 : 41|1@0+ (1,0) [0|3] "" BDY
SG_ CRUISE_CONTROL_LABEL : 40|1@0+ (1,0) [0|3] "" BDY
SG_ HUD_DISTANCE_3 : 52|1@0+ (1,0) [0|1] "" BDY
SG_ IMPERIAL_UNIT : 54|1@0+ (1,0) [0|1] "" BDY
SG_ SET_ME_X01_2 : 55|1@0+ (1,0) [0|1] "" BDY
SG_ SET_ME_X03_2 : 55|2@0+ (1,0) [0|3] "" BDY
SG_ SET_ME_X01 : 48|1@0+ (1,0) [0|1] "" BDY
SG_ COUNTER : 61|2@0+ (1,0) [0|3] "" BDY
SG_ CHECKSUM : 59|4@0+ (1,0) [0|3] "" BDY
@@ -164,15 +164,14 @@ BO_ 780 ACC_HUD: 8 ADAS
SG_ FCM_PROBLEM : 34|1@0+ (1,0) [0|1] "" BDY
SG_ RADAR_OBSTRUCTED : 33|1@0+ (1,0) [0|1] "" BDY
SG_ ENABLE_MINI_CAR : 32|1@0+ (1,0) [0|1] "" BDY
SG_ HUD_DISTANCE : 47|2@0+ (1,0) [0|3] "" BDY
SG_ SET_ME_X03 : 47|2@0+ (1,0) [0|3] "" BDY
SG_ HUD_LEAD : 45|2@0+ (1,0) [0|3] "" BDY
SG_ BOH_3 : 43|1@0+ (1,0) [0|3] "" BDY
SG_ BOH_4 : 42|1@0+ (1,0) [0|3] "" BDY
SG_ BOH_5 : 41|1@0+ (1,0) [0|3] "" BDY
SG_ CRUISE_CONTROL_LABEL : 40|1@0+ (1,0) [0|3] "" BDY
SG_ HUD_DISTANCE_3 : 52|1@0+ (1,0) [0|1] "" BDY
SG_ IMPERIAL_UNIT : 54|1@0+ (1,0) [0|1] "" BDY
SG_ SET_ME_X01_2 : 55|1@0+ (1,0) [0|1] "" BDY
SG_ SET_ME_X03_2 : 55|2@0+ (1,0) [0|3] "" BDY
SG_ SET_ME_X01 : 48|1@0+ (1,0) [0|1] "" BDY
SG_ COUNTER : 61|2@0+ (1,0) [0|3] "" BDY
SG_ CHECKSUM : 59|4@0+ (1,0) [0|3] "" BDY
@@ -164,15 +164,14 @@ BO_ 780 ACC_HUD: 8 ADAS
SG_ FCM_PROBLEM : 34|1@0+ (1,0) [0|1] "" BDY
SG_ RADAR_OBSTRUCTED : 33|1@0+ (1,0) [0|1] "" BDY
SG_ ENABLE_MINI_CAR : 32|1@0+ (1,0) [0|1] "" BDY
SG_ HUD_DISTANCE : 47|2@0+ (1,0) [0|3] "" BDY
SG_ SET_ME_X03 : 47|2@0+ (1,0) [0|3] "" BDY
SG_ HUD_LEAD : 45|2@0+ (1,0) [0|3] "" BDY
SG_ BOH_3 : 43|1@0+ (1,0) [0|3] "" BDY
SG_ BOH_4 : 42|1@0+ (1,0) [0|3] "" BDY
SG_ BOH_5 : 41|1@0+ (1,0) [0|3] "" BDY
SG_ CRUISE_CONTROL_LABEL : 40|1@0+ (1,0) [0|3] "" BDY
SG_ HUD_DISTANCE_3 : 52|1@0+ (1,0) [0|1] "" BDY
SG_ IMPERIAL_UNIT : 54|1@0+ (1,0) [0|1] "" BDY
SG_ SET_ME_X01_2 : 55|1@0+ (1,0) [0|1] "" BDY
SG_ SET_ME_X03_2 : 55|2@0+ (1,0) [0|3] "" BDY
SG_ SET_ME_X01 : 48|1@0+ (1,0) [0|1] "" BDY
SG_ COUNTER : 61|2@0+ (1,0) [0|3] "" BDY
SG_ CHECKSUM : 59|4@0+ (1,0) [0|3] "" BDY
+1 -1
View File
@@ -125,7 +125,7 @@ BO_ 614 STEERING_IPAS: 8 IPAS
SG_ SET_ME_X00 : 31|8@0+ (1,0) [0|255] "" XXX
SG_ DIRECTION_CMD : 38|2@0+ (1,0) [0|3] "" XXX
SG_ SET_ME_X40 : 47|8@0+ (1,0) [0|255] "" XXX
SG_ SET_ME_X00_1 : 55|8@0+ (1,0) [0|255] "" XXX
SG_ SET_ME_X00 : 55|8@0+ (1,0) [0|255] "" XXX
SG_ CHECKSUM : 63|8@0+ (1,0) [0|255] "" XXX
BO_ 643 PRE_COLLISION: 8 XXX
+1 -1
View File
@@ -125,7 +125,7 @@ BO_ 614 STEERING_IPAS: 8 IPAS
SG_ SET_ME_X00 : 31|8@0+ (1,0) [0|255] "" XXX
SG_ DIRECTION_CMD : 38|2@0+ (1,0) [0|3] "" XXX
SG_ SET_ME_X40 : 47|8@0+ (1,0) [0|255] "" XXX
SG_ SET_ME_X00_1 : 55|8@0+ (1,0) [0|255] "" XXX
SG_ SET_ME_X00 : 55|8@0+ (1,0) [0|255] "" XXX
SG_ CHECKSUM : 63|8@0+ (1,0) [0|255] "" XXX
BO_ 643 PRE_COLLISION: 8 XXX
@@ -125,7 +125,7 @@ BO_ 614 STEERING_IPAS: 8 IPAS
SG_ SET_ME_X00 : 31|8@0+ (1,0) [0|255] "" XXX
SG_ DIRECTION_CMD : 38|2@0+ (1,0) [0|3] "" XXX
SG_ SET_ME_X40 : 47|8@0+ (1,0) [0|255] "" XXX
SG_ SET_ME_X00_1 : 55|8@0+ (1,0) [0|255] "" XXX
SG_ SET_ME_X00 : 55|8@0+ (1,0) [0|255] "" XXX
SG_ CHECKSUM : 63|8@0+ (1,0) [0|255] "" XXX
BO_ 643 PRE_COLLISION: 8 XXX
@@ -125,7 +125,7 @@ BO_ 614 STEERING_IPAS: 8 IPAS
SG_ SET_ME_X00 : 31|8@0+ (1,0) [0|255] "" XXX
SG_ DIRECTION_CMD : 38|2@0+ (1,0) [0|3] "" XXX
SG_ SET_ME_X40 : 47|8@0+ (1,0) [0|255] "" XXX
SG_ SET_ME_X00_1 : 55|8@0+ (1,0) [0|255] "" XXX
SG_ SET_ME_X00 : 55|8@0+ (1,0) [0|255] "" XXX
SG_ CHECKSUM : 63|8@0+ (1,0) [0|255] "" XXX
BO_ 643 PRE_COLLISION: 8 XXX
+1 -1
View File
@@ -125,7 +125,7 @@ BO_ 614 STEERING_IPAS: 8 IPAS
SG_ SET_ME_X00 : 31|8@0+ (1,0) [0|255] "" XXX
SG_ DIRECTION_CMD : 38|2@0+ (1,0) [0|3] "" XXX
SG_ SET_ME_X40 : 47|8@0+ (1,0) [0|255] "" XXX
SG_ SET_ME_X00_1 : 55|8@0+ (1,0) [0|255] "" XXX
SG_ SET_ME_X00 : 55|8@0+ (1,0) [0|255] "" XXX
SG_ CHECKSUM : 63|8@0+ (1,0) [0|255] "" XXX
BO_ 643 PRE_COLLISION: 8 XXX
@@ -125,7 +125,7 @@ BO_ 614 STEERING_IPAS: 8 IPAS
SG_ SET_ME_X00 : 31|8@0+ (1,0) [0|255] "" XXX
SG_ DIRECTION_CMD : 38|2@0+ (1,0) [0|3] "" XXX
SG_ SET_ME_X40 : 47|8@0+ (1,0) [0|255] "" XXX
SG_ SET_ME_X00_1 : 55|8@0+ (1,0) [0|255] "" XXX
SG_ SET_ME_X00 : 55|8@0+ (1,0) [0|255] "" XXX
SG_ CHECKSUM : 63|8@0+ (1,0) [0|255] "" XXX
BO_ 643 PRE_COLLISION: 8 XXX
@@ -314,7 +314,7 @@ BO_ 581 GAS_PEDAL: 8 XXX
SG_ GAS_PEDAL : 23|8@0+ (0.005,0) [0|1] "" XXX
BO_ 608 STEER_TORQUE_SENSOR: 8 XXX
SG_ STEER_TORQUE_EPS : 47|16@0- (0.73,0) [-20000|20000] "" XXX
SG_ STEER_TORQUE_EPS : 47|16@0- (0.66,0) [-20000|20000] "" XXX
SG_ STEER_TORQUE_DRIVER : 15|16@0- (1,0) [-32768|32767] "" XXX
SG_ STEER_OVERRIDE : 0|1@0+ (1,0) [0|1] "" XXX
SG_ CHECKSUM : 63|8@0+ (1,0) [0|255] "" XXX
@@ -125,7 +125,7 @@ BO_ 614 STEERING_IPAS: 8 IPAS
SG_ SET_ME_X00 : 31|8@0+ (1,0) [0|255] "" XXX
SG_ DIRECTION_CMD : 38|2@0+ (1,0) [0|3] "" XXX
SG_ SET_ME_X40 : 47|8@0+ (1,0) [0|255] "" XXX
SG_ SET_ME_X00_1 : 55|8@0+ (1,0) [0|255] "" XXX
SG_ SET_ME_X00 : 55|8@0+ (1,0) [0|255] "" XXX
SG_ CHECKSUM : 63|8@0+ (1,0) [0|255] "" XXX
BO_ 643 PRE_COLLISION: 8 XXX
@@ -295,21 +295,10 @@ VAL_ 1162 SPLSGN3 15 "conditional blank" 4 "wet road" 5 "rain" 0 "none";
CM_ "CHFFR_METRIC 37 STEER_ANGLE STEER_ANGLE 0.36 180";
CM_ "toyota_nodsu_pt.dbc starts here"
CM_ "toyota_chr_2018_pt.dbc starts here"
BO_ 401 STEERING_LTA: 8 XXX
SG_ COUNTER : 7|8@0+ (1,0) [0|255] "" XXX
SG_ CHECKSUM : 63|8@0+ (1,0) [0|255] "" XXX
SG_ SETME_X3 : 29|2@0+ (1,0) [0|3] "" XXX
SG_ PERCENTAGE : 39|8@0+ (1,0) [0|255] "" XXX
SG_ SETME_X64 : 47|8@0+ (1,0) [0|255] "" XXX
SG_ ANGLE : 55|8@0- (0.5,0) [0|255] "" XXX
SG_ STEER_ANGLE_CMD : 15|16@0- (0.056,0) [-540|540] "" XXX
SG_ STEER_REQUEST : 25|1@0+ (1,0) [0|1] "" XXX
SG_ BIT : 30|1@0+ (1,0) [0|1] "" XXX
BO_ 550 BRAKE_MODULE: 8 XXX
SG_ BRAKE_PRESSURE : 0|9@0+ (1,0) [0|511] "" XXX
SG_ BRAKE_POSITION : 16|9@0+ (1,0) [0|511] "" XXX
@@ -324,7 +313,6 @@ BO_ 608 STEER_TORQUE_SENSOR: 8 XXX
SG_ STEER_TORQUE_DRIVER : 15|16@0- (1,0) [-32768|32767] "" XXX
SG_ STEER_OVERRIDE : 0|1@0+ (1,0) [0|1] "" XXX
SG_ CHECKSUM : 63|8@0+ (1,0) [0|255] "" XXX
SG_ STEER_ANGLE : 31|16@0- (0.056,0) [-500|500] "" XXX
BO_ 610 EPS_STATUS: 8 EPS
SG_ IPAS_STATE : 3|4@0+ (1,0) [0|15] "" XXX
@@ -125,7 +125,7 @@ BO_ 614 STEERING_IPAS: 8 IPAS
SG_ SET_ME_X00 : 31|8@0+ (1,0) [0|255] "" XXX
SG_ DIRECTION_CMD : 38|2@0+ (1,0) [0|3] "" XXX
SG_ SET_ME_X40 : 47|8@0+ (1,0) [0|255] "" XXX
SG_ SET_ME_X00_1 : 55|8@0+ (1,0) [0|255] "" XXX
SG_ SET_ME_X00 : 55|8@0+ (1,0) [0|255] "" XXX
SG_ CHECKSUM : 63|8@0+ (1,0) [0|255] "" XXX
BO_ 643 PRE_COLLISION: 8 XXX
@@ -295,7 +295,7 @@ VAL_ 1162 SPLSGN3 15 "conditional blank" 4 "wet road" 5 "rain" 0 "none";
CM_ "CHFFR_METRIC 37 STEER_ANGLE STEER_ANGLE 0.36 180";
CM_ "toyota_nodsu_hybrid_pt.dbc starts here"
CM_ "toyota_chr_hybrid_2018_pt.dbc starts here"
@@ -318,7 +318,6 @@ BO_ 608 STEER_TORQUE_SENSOR: 8 XXX
SG_ STEER_TORQUE_DRIVER : 15|16@0- (1,0) [-32768|32767] "" XXX
SG_ STEER_OVERRIDE : 0|1@0+ (1,0) [0|1] "" XXX
SG_ CHECKSUM : 63|8@0+ (1,0) [0|255] "" XXX
SG_ STEER_ANGLE : 31|16@0- (0.056,0) [-500|500] "" XXX
BO_ 610 EPS_STATUS: 8 EPS
SG_ IPAS_STATE : 3|4@0+ (1,0) [0|15] "" XXX
+1 -1
View File
@@ -125,7 +125,7 @@ BO_ 614 STEERING_IPAS: 8 IPAS
SG_ SET_ME_X00 : 31|8@0+ (1,0) [0|255] "" XXX
SG_ DIRECTION_CMD : 38|2@0+ (1,0) [0|3] "" XXX
SG_ SET_ME_X40 : 47|8@0+ (1,0) [0|255] "" XXX
SG_ SET_ME_X00_1 : 55|8@0+ (1,0) [0|255] "" XXX
SG_ SET_ME_X00 : 55|8@0+ (1,0) [0|255] "" XXX
SG_ CHECKSUM : 63|8@0+ (1,0) [0|255] "" XXX
BO_ 643 PRE_COLLISION: 8 XXX
@@ -125,7 +125,7 @@ BO_ 614 STEERING_IPAS: 8 IPAS
SG_ SET_ME_X00 : 31|8@0+ (1,0) [0|255] "" XXX
SG_ DIRECTION_CMD : 38|2@0+ (1,0) [0|3] "" XXX
SG_ SET_ME_X40 : 47|8@0+ (1,0) [0|255] "" XXX
SG_ SET_ME_X00_1 : 55|8@0+ (1,0) [0|255] "" XXX
SG_ SET_ME_X00 : 55|8@0+ (1,0) [0|255] "" XXX
SG_ CHECKSUM : 63|8@0+ (1,0) [0|255] "" XXX
BO_ 643 PRE_COLLISION: 8 XXX
@@ -125,7 +125,7 @@ BO_ 614 STEERING_IPAS: 8 IPAS
SG_ SET_ME_X00 : 31|8@0+ (1,0) [0|255] "" XXX
SG_ DIRECTION_CMD : 38|2@0+ (1,0) [0|3] "" XXX
SG_ SET_ME_X40 : 47|8@0+ (1,0) [0|255] "" XXX
SG_ SET_ME_X00_1 : 55|8@0+ (1,0) [0|255] "" XXX
SG_ SET_ME_X00 : 55|8@0+ (1,0) [0|255] "" XXX
SG_ CHECKSUM : 63|8@0+ (1,0) [0|255] "" XXX
BO_ 643 PRE_COLLISION: 8 XXX
+1 -1
View File
@@ -125,7 +125,7 @@ BO_ 614 STEERING_IPAS: 8 IPAS
SG_ SET_ME_X00 : 31|8@0+ (1,0) [0|255] "" XXX
SG_ DIRECTION_CMD : 38|2@0+ (1,0) [0|3] "" XXX
SG_ SET_ME_X40 : 47|8@0+ (1,0) [0|255] "" XXX
SG_ SET_ME_X00_1 : 55|8@0+ (1,0) [0|255] "" XXX
SG_ SET_ME_X00 : 55|8@0+ (1,0) [0|255] "" XXX
SG_ CHECKSUM : 63|8@0+ (1,0) [0|255] "" XXX
BO_ 643 PRE_COLLISION: 8 XXX
+1 -1
View File
@@ -125,7 +125,7 @@ BO_ 614 STEERING_IPAS: 8 IPAS
SG_ SET_ME_X00 : 31|8@0+ (1,0) [0|255] "" XXX
SG_ DIRECTION_CMD : 38|2@0+ (1,0) [0|3] "" XXX
SG_ SET_ME_X40 : 47|8@0+ (1,0) [0|255] "" XXX
SG_ SET_ME_X00_1 : 55|8@0+ (1,0) [0|255] "" XXX
SG_ SET_ME_X00 : 55|8@0+ (1,0) [0|255] "" XXX
SG_ CHECKSUM : 63|8@0+ (1,0) [0|255] "" XXX
BO_ 643 PRE_COLLISION: 8 XXX
@@ -125,7 +125,7 @@ BO_ 614 STEERING_IPAS: 8 IPAS
SG_ SET_ME_X00 : 31|8@0+ (1,0) [0|255] "" XXX
SG_ DIRECTION_CMD : 38|2@0+ (1,0) [0|3] "" XXX
SG_ SET_ME_X40 : 47|8@0+ (1,0) [0|255] "" XXX
SG_ SET_ME_X00_1 : 55|8@0+ (1,0) [0|255] "" XXX
SG_ SET_ME_X00 : 55|8@0+ (1,0) [0|255] "" XXX
SG_ CHECKSUM : 63|8@0+ (1,0) [0|255] "" XXX
BO_ 643 PRE_COLLISION: 8 XXX
@@ -125,7 +125,7 @@ BO_ 614 STEERING_IPAS: 8 IPAS
SG_ SET_ME_X00 : 31|8@0+ (1,0) [0|255] "" XXX
SG_ DIRECTION_CMD : 38|2@0+ (1,0) [0|3] "" XXX
SG_ SET_ME_X40 : 47|8@0+ (1,0) [0|255] "" XXX
SG_ SET_ME_X00_1 : 55|8@0+ (1,0) [0|255] "" XXX
SG_ SET_ME_X00 : 55|8@0+ (1,0) [0|255] "" XXX
SG_ CHECKSUM : 63|8@0+ (1,0) [0|255] "" XXX
BO_ 643 PRE_COLLISION: 8 XXX
+690 -777
View File
File diff suppressed because it is too large Load Diff
+4 -57
View File
@@ -12,47 +12,6 @@ jobs:
name: Run safety test
command: |
docker run panda_safety /bin/bash -c "cd /panda/tests/safety; ./test.sh"
misra-c2012:
machine:
docker_layer_caching: true
steps:
- checkout
- run:
name: Build image
command: "docker build -t panda_misra -f tests/misra/Dockerfile ."
- run:
name: Run Misra C 2012 test
command: |
mkdir /tmp/misra
docker run -v /tmp/misra:/tmp/misra panda_misra /bin/bash -c "cd /panda/tests/misra; ./test_misra.sh"
- store_artifacts:
name: Store cppcheck test output
path: /tmp/misra/cppcheck_output.txt
- store_artifacts:
name: Store misra test output
path: /tmp/misra/misra_output.txt
- store_artifacts:
name: Store cppcheck safety test output
path: /tmp/misra/cppcheck_safety_output.txt
- store_artifacts:
name: Store misra safety test output
path: /tmp/misra/misra_safety_output.txt
strict-compiler:
machine:
docker_layer_caching: true
steps:
- checkout
- run:
name: Build image
command: "docker build -t panda_strict_compiler -f tests/build_strict/Dockerfile ."
- run:
name: Build Panda with strict compiler rules
command: |
docker run panda_strict_compiler /bin/bash -c "cd /panda/tests/build_strict; ./test_build_strict.sh"
build:
machine:
docker_layer_caching: true
@@ -81,30 +40,18 @@ jobs:
name: Build Pedal STM bootstub image
command: |
docker run panda_build /bin/bash -c "cd /panda/board/pedal; make obj/bootstub.bin"
- run:
name: Build NEO STM image
command: |
docker run panda_build /bin/bash -c "cd /panda/board; make clean; make -f Makefile.legacy obj/comma.bin"
- run:
name: Build ESP image
command: |
docker run panda_build /bin/bash -c "cd /panda/boardesp; make user1.bin"
safety_replay:
machine:
docker_layer_caching: true
steps:
- checkout
- run:
name: Build image
command: "docker build -t panda_safety_replay -f tests/safety_replay/Dockerfile ."
- run:
name: Replay drives
command: |
docker run panda_safety_replay /bin/bash -c "cd /openpilot/panda/tests/safety_replay; PYTHONPATH=/openpilot ./test_safety_replay.py"
workflows:
version: 2
main:
jobs:
- safety
- misra-c2012
- strict-compiler
- build
- safety_replay
+2 -3
View File
@@ -10,6 +10,5 @@ a.out
dist/
pandacan.egg-info/
board/obj/
examples/output.csv
.DS_Store
nosetests.xml
examples/output.csv
.DS_Store
+2
View File
@@ -59,4 +59,6 @@ USER pandauser
RUN cd /tmp/panda/boardesp && ./get_sdk_ci.sh
USER root
COPY ./xx/pandaextra /tmp/pandaextra
ADD ./panda.tar.gz /tmp/panda
+2
View File
@@ -14,6 +14,8 @@ pipeline {
steps {
timeout(time: 60, unit: 'MINUTES') {
script {
sh 'git clone --no-checkout --depth 1 git@github.com:commaai/xx.git || true'
sh 'cd xx && git fetch origin && git checkout origin/master -- pandaextra && cd ..' // Needed for certs for panda flashing
sh 'git archive -v -o panda.tar.gz --format=tar.gz HEAD'
dockerImage = docker.build("${env.DOCKER_IMAGE_TAG}")
}
+1 -1
View File
@@ -1 +1 @@
v1.4.0
v1.2.1
+9
View File
@@ -0,0 +1,9 @@
# :set noet
PROJ_NAME = comma
CFLAGS = -g -Wall
CFLAGS += -mlittle-endian -mthumb -mcpu=cortex-m3
CFLAGS += -msoft-float -DSTM32F2 -DSTM32F205xx
STARTUP_FILE = startup_stm32f205xx
include build.mk
-8
View File
@@ -1,8 +0,0 @@
PROJ_NAME = panda
CFLAGS = -g -Wall -Wextra -Wstrict-prototypes
CFLAGS += -mlittle-endian -mthumb -mcpu=cortex-m4
CFLAGS += -mhard-float -DSTM32F4 -DSTM32F413xx -mfpu=fpv4-sp-d16 -fsingle-precision-constant
STARTUP_FILE = startup_stm32f413xx
include build.mk
+6
View File
@@ -23,6 +23,12 @@ Programming
make
```
**NEO**
```
make -f Makefile.legacy
```
Troubleshooting
----
+11 -5
View File
@@ -12,14 +12,11 @@
#include "stm32f2xx_hal_gpio_ex.h"
#endif
// default since there's no serial
void puts(const char *a) {}
void puth(unsigned int i) {}
#include "libc.h"
#include "provision.h"
#include "drivers/clock.h"
#include "drivers/drivers.h"
#include "drivers/llgpio.h"
#include "gpio.h"
@@ -27,6 +24,15 @@ void puth(unsigned int i) {}
#include "drivers/usb.h"
//#include "drivers/uart.h"
#ifdef PEDAL
#define CUSTOM_CAN_INTERRUPTS
#include "safety.h"
#include "drivers/can.h"
#endif
int puts(const char *a) { return 0; }
void puth(unsigned int i) {}
#include "crypto/rsa.h"
#include "crypto/sha.h"
+1 -3
View File
@@ -2,15 +2,12 @@ CFLAGS += -I inc -I ../ -nostdlib -fno-builtin -std=gnu11 -Os
CFLAGS += -Tstm32_flash.ld
DFU_UTIL = "dfu-util"
# Compile fast charge (DCP) only not on EON
ifeq (,$(wildcard /EON))
BUILDER = DEV
else
CFLAGS += "-DEON"
BUILDER = EON
DFU_UTIL = "tools/dfu-util-aarch64"
endif
CC = arm-none-eabi-gcc
@@ -25,6 +22,7 @@ else
CFLAGS += "-DALLOW_DEBUG"
endif
DFU_UTIL = "dfu-util"
DEPDIR = generated_dependencies
$(shell mkdir -p -m 777 $(DEPDIR) >/dev/null)
+5 -5
View File
@@ -22,17 +22,17 @@
#include <stdbool.h>
#define NULL ((void*)0)
#define COMPILE_TIME_ASSERT(pred) ((void)sizeof(char[1 - (2 * (!(pred)))]))
#define COMPILE_TIME_ASSERT(pred) switch(0){case 0:case pred:;}
#define MIN(a,b) \
#define min(a,b) \
({ __typeof__ (a) _a = (a); \
__typeof__ (b) _b = (b); \
(_a < _b) ? _a : _b; })
_a < _b ? _a : _b; })
#define MAX(a,b) \
#define max(a,b) \
({ __typeof__ (a) _a = (a); \
__typeof__ (b) _b = (b); \
(_a > _b) ? _a : _b; })
_a > _b ? _a : _b; })
#define MAX_RESP_LEN 0x40
+1 -1
View File
@@ -8,7 +8,7 @@
#define ADCCHAN_VOLTAGE 12
#define ADCCHAN_CURRENT 13
void adc_init(void) {
void adc_init() {
// global setup
ADC->CCR = ADC_CCR_TSVREFE | ADC_CCR_VBATE;
//ADC1->CR2 = ADC_CR2_ADON | ADC_CR2_EOCS | ADC_CR2_DDS;
+299 -140
View File
@@ -1,38 +1,10 @@
// IRQs: CAN1_TX, CAN1_RX0, CAN1_SCE
// CAN2_TX, CAN2_RX0, CAN2_SCE
// CAN3_TX, CAN3_RX0, CAN3_SCE
typedef struct {
volatile uint32_t w_ptr;
volatile uint32_t r_ptr;
uint32_t fifo_size;
CAN_FIFOMailBox_TypeDef *elems;
} can_ring;
#define CAN_BUS_RET_FLAG 0x80
#define CAN_BUS_NUM_MASK 0x7F
#define BUS_MAX 4
extern int can_live, pending_can_live;
// must reinit after changing these
extern int can_loopback, can_silent;
extern uint32_t can_speed[4];
void can_set_forwarding(int from, int to);
void can_init(uint8_t can_number);
void can_init_all(void);
void can_send(CAN_FIFOMailBox_TypeDef *to_push, uint8_t bus_number);
bool can_pop(can_ring *q, CAN_FIFOMailBox_TypeDef *elem);
// end API
// IRQs: CAN1_TX, CAN1_RX0, CAN1_SCE, CAN2_TX, CAN2_RX0, CAN2_SCE, CAN3_TX, CAN3_RX0, CAN3_SCE
#define ALL_CAN_SILENT 0xFF
#define ALL_CAN_BUT_MAIN_SILENT 0xFE
#define ALL_CAN_LIVE 0
#include "lline_relay.h"
int can_live = 0, pending_can_live = 0, can_loopback = 0, can_silent = ALL_CAN_SILENT;
// ********************* instantiate queues *********************
@@ -44,21 +16,24 @@ int can_live = 0, pending_can_live = 0, can_loopback = 0, can_silent = ALL_CAN_S
can_buffer(rx_q, 0x1000)
can_buffer(tx1_q, 0x100)
can_buffer(tx2_q, 0x100)
can_buffer(tx3_q, 0x100)
can_buffer(txgmlan_q, 0x100)
can_ring *can_queues[] = {&can_tx1_q, &can_tx2_q, &can_tx3_q, &can_txgmlan_q};
// global CAN stats
int can_rx_cnt = 0;
int can_tx_cnt = 0;
int can_txd_cnt = 0;
int can_err_cnt = 0;
int can_overflow_cnt = 0;
#ifdef PANDA
can_buffer(tx3_q, 0x100)
can_buffer(txgmlan_q, 0x100)
can_ring *can_queues[] = {&can_tx1_q, &can_tx2_q, &can_tx3_q, &can_txgmlan_q};
#else
can_ring *can_queues[] = {&can_tx1_q, &can_tx2_q};
#endif
#ifdef PANDA
// Forward declare
void power_save_reset_timer();
#endif
// ********************* interrupt safe queue *********************
bool can_pop(can_ring *q, CAN_FIFOMailBox_TypeDef *elem) {
bool ret = 0;
int can_pop(can_ring *q, CAN_FIFOMailBox_TypeDef *elem) {
int ret = 0;
enter_critical_section();
if (q->w_ptr != q->r_ptr) {
@@ -85,12 +60,7 @@ int can_push(can_ring *q, CAN_FIFOMailBox_TypeDef *elem) {
ret = 1;
}
exit_critical_section();
if (ret == 0) {
can_overflow_cnt++;
#ifdef DEBUG
puts("can_push failed!\n");
#endif
}
if (ret == 0) puts("can_push failed!\n");
return ret;
}
@@ -110,54 +80,181 @@ void can_clear(can_ring *q) {
// can_num_lookup: Translates from 'bus number' to 'can number'.
// can_forwarding: Given a bus num, lookup bus num to forward to. -1 means no forward.
int can_rx_cnt = 0;
int can_tx_cnt = 0;
int can_txd_cnt = 0;
int can_err_cnt = 0;
// NEO: Bus 1=CAN1 Bus 2=CAN2
// Panda: Bus 0=CAN1 Bus 1=CAN2 Bus 2=CAN3
CAN_TypeDef *cans[] = {CAN1, CAN2, CAN3};
uint8_t bus_lookup[] = {0,1,2};
uint8_t can_num_lookup[] = {0,1,2,-1};
int8_t can_forwarding[] = {-1,-1,-1,-1};
uint32_t can_speed[] = {5000, 5000, 5000, 333};
#define CAN_MAX 3
#ifdef PANDA
CAN_TypeDef *cans[] = {CAN1, CAN2, CAN3};
uint8_t bus_lookup[] = {0,1,2};
uint8_t can_num_lookup[] = {0,1,2,-1};
int8_t can_forwarding[] = {-1,-1,-1,-1};
uint32_t can_speed[] = {5000, 5000, 5000, 333};
bool can_autobaud_enabled[] = {false, false, false, false};
#define CAN_MAX 3
#else
CAN_TypeDef *cans[] = {CAN1, CAN2};
uint8_t bus_lookup[] = {1,0};
uint8_t can_num_lookup[] = {1,0};
int8_t can_forwarding[] = {-1,-1};
uint32_t can_speed[] = {5000, 5000};
bool can_autobaud_enabled[] = {false, false};
#define CAN_MAX 2
#endif
uint32_t can_autobaud_speeds[] = {5000, 2500, 1250, 1000, 10000};
#define AUTOBAUD_SPEEDS_LEN (sizeof(can_autobaud_speeds) / sizeof(can_autobaud_speeds[0]))
#define CANIF_FROM_CAN_NUM(num) (cans[num])
#define CAN_NUM_FROM_CANIF(CAN) ((CAN)==CAN1 ? 0 : ((CAN) == CAN2 ? 1 : 2))
#define CAN_NAME_FROM_CANIF(CAN) ((CAN)==CAN1 ? "CAN1" : ((CAN) == CAN2 ? "CAN2" : "CAN3"))
#ifdef PANDA
#define CAN_NUM_FROM_CANIF(CAN) (CAN==CAN1 ? 0 : (CAN==CAN2 ? 1 : 2))
#define CAN_NAME_FROM_CANIF(CAN) (CAN==CAN1 ? "CAN1" : (CAN==CAN2 ? "CAN2" : "CAN3"))
#else
#define CAN_NUM_FROM_CANIF(CAN) (CAN==CAN1 ? 0 : 1)
#define CAN_NAME_FROM_CANIF(CAN) (CAN==CAN1 ? "CAN1" : "CAN2")
#endif
#define BUS_NUM_FROM_CAN_NUM(num) (bus_lookup[num])
#define CAN_NUM_FROM_BUS_NUM(num) (can_num_lookup[num])
// other option
/*#define CAN_QUANTA 16
#define CAN_SEQ1 13
#define CAN_SEQ2 2*/
// this is needed for 1 mbps support
#define CAN_QUANTA 8
#define CAN_SEQ1 6 // roundf(quanta * 0.875f) - 1;
#define CAN_SEQ2 1 // roundf(quanta * 0.125f);
#define CAN_PCLK 24000
// 333 = 33.3 kbps
// 5000 = 500 kbps
#define can_speed_to_prescaler(x) (CAN_PCLK / CAN_QUANTA * 10 / (x))
void can_autobaud_speed_increment(uint8_t can_number) {
uint32_t autobaud_speed = can_autobaud_speeds[0];
uint8_t bus_number = BUS_NUM_FROM_CAN_NUM(can_number);
for (int i = 0; i < AUTOBAUD_SPEEDS_LEN; i++) {
if (can_speed[bus_number] == can_autobaud_speeds[i]) {
if (i+1 < AUTOBAUD_SPEEDS_LEN) {
autobaud_speed = can_autobaud_speeds[i+1];
}
break;
}
}
can_speed[bus_number] = autobaud_speed;
#ifdef DEBUG
CAN_TypeDef* CAN = CANIF_FROM_CAN_NUM(can_number);
puts(CAN_NAME_FROM_CANIF(CAN));
puts(" auto-baud test ");
putui(can_speed[bus_number]);
puts(" cbps\n");
#endif
}
void process_can(uint8_t can_number);
void can_set_speed(uint8_t can_number) {
CAN_TypeDef *CAN = CANIF_FROM_CAN_NUM(can_number);
uint8_t bus_number = BUS_NUM_FROM_CAN_NUM(can_number);
if (!llcan_set_speed(CAN, can_speed[bus_number], can_loopback, can_silent & (1 << can_number))) {
puts("CAN init FAILED!!!!!\n");
puth(can_number); puts(" ");
puth(BUS_NUM_FROM_CAN_NUM(can_number)); puts("\n");
while (true) {
// initialization mode
CAN->MCR = CAN_MCR_TTCM | CAN_MCR_INRQ;
while((CAN->MSR & CAN_MSR_INAK) != CAN_MSR_INAK);
// set time quanta from defines
CAN->BTR = (CAN_BTR_TS1_0 * (CAN_SEQ1-1)) |
(CAN_BTR_TS2_0 * (CAN_SEQ2-1)) |
(can_speed_to_prescaler(can_speed[bus_number]) - 1);
// silent loopback mode for debugging
if (can_loopback) {
CAN->BTR |= CAN_BTR_SILM | CAN_BTR_LBKM;
}
if (can_silent & (1 << can_number)) {
CAN->BTR |= CAN_BTR_SILM;
}
// reset
CAN->MCR = CAN_MCR_TTCM | CAN_MCR_ABOM;
#define CAN_TIMEOUT 1000000
int tmp = 0;
while((CAN->MSR & CAN_MSR_INAK) == CAN_MSR_INAK && tmp < CAN_TIMEOUT) tmp++;
if (tmp < CAN_TIMEOUT) {
return;
}
if (can_autobaud_enabled[bus_number]) {
can_autobaud_speed_increment(can_number);
} else {
puts("CAN init FAILED!!!!!\n");
puth(can_number); puts(" ");
puth(BUS_NUM_FROM_CAN_NUM(can_number)); puts("\n");
return;
}
}
}
void can_init(uint8_t can_number) {
if (can_number != 0xff) {
CAN_TypeDef *CAN = CANIF_FROM_CAN_NUM(can_number);
set_can_enable(CAN, 1);
can_set_speed(can_number);
if (can_number == 0xff) return;
llcan_init(CAN);
CAN_TypeDef *CAN = CANIF_FROM_CAN_NUM(can_number);
set_can_enable(CAN, 1);
can_set_speed(can_number);
// in case there are queued up messages
process_can(can_number);
// accept all filter
CAN->FMR |= CAN_FMR_FINIT;
// no mask
CAN->sFilterRegister[0].FR1 = 0;
CAN->sFilterRegister[0].FR2 = 0;
CAN->sFilterRegister[14].FR1 = 0;
CAN->sFilterRegister[14].FR2 = 0;
CAN->FA1R |= 1 | (1 << 14);
CAN->FMR &= ~(CAN_FMR_FINIT);
// enable certain CAN interrupts
CAN->IER |= CAN_IER_TMEIE | CAN_IER_FMPIE0 | CAN_IER_WKUIE;
switch (can_number) {
case 0:
NVIC_EnableIRQ(CAN1_TX_IRQn);
NVIC_EnableIRQ(CAN1_RX0_IRQn);
NVIC_EnableIRQ(CAN1_SCE_IRQn);
break;
case 1:
NVIC_EnableIRQ(CAN2_TX_IRQn);
NVIC_EnableIRQ(CAN2_RX0_IRQn);
NVIC_EnableIRQ(CAN2_SCE_IRQn);
break;
#ifdef CAN3
case 2:
NVIC_EnableIRQ(CAN3_TX_IRQn);
NVIC_EnableIRQ(CAN3_RX0_IRQn);
NVIC_EnableIRQ(CAN3_SCE_IRQn);
break;
#endif
}
// in case there are queued up messages
process_can(can_number);
}
void can_init_all(void) {
void can_init_all() {
for (int i=0; i < CAN_MAX; i++) {
can_init(i);
}
}
void can_set_gmlan(int bus) {
if ((bus == -1) || (bus != can_num_lookup[3])) {
#ifdef PANDA
if (bus == -1 || bus != can_num_lookup[3]) {
// GMLAN OFF
switch (can_num_lookup[3]) {
case 1:
@@ -176,9 +273,6 @@ void can_set_gmlan(int bus) {
can_num_lookup[3] = -1;
can_init(2);
break;
default:
puts("GMLAN bus value invalid\n");
break;
}
}
@@ -190,7 +284,7 @@ void can_set_gmlan(int bus) {
can_num_lookup[1] = -1;
can_num_lookup[3] = 1;
can_init(1);
} else if (bus == 2) {
} else if (bus == 2 && revision == PANDA_REV_C) {
puts("GMLAN on CAN3\n");
// GMLAN on CAN3
set_can_mode(2, 1);
@@ -199,6 +293,7 @@ void can_set_gmlan(int bus) {
can_num_lookup[3] = 2;
can_init(2);
}
#endif
}
// CAN error
@@ -224,74 +319,125 @@ void can_sce(CAN_TypeDef *CAN) {
puts("\n");
#endif
can_err_cnt += 1;
llcan_clear_send(CAN);
uint8_t can_number = CAN_NUM_FROM_CANIF(CAN);
uint8_t bus_number = BUS_NUM_FROM_CAN_NUM(can_number);
if (CAN->MSR & CAN_MSR_WKUI) {
//Waking from sleep
#ifdef DEBUG
puts("WAKE\n");
#endif
set_can_enable(CAN, 1);
CAN->MSR &= ~(CAN_MSR_WKUI);
CAN->MSR = CAN->MSR;
#ifdef PANDA
power_save_reset_timer();
#endif
} else {
can_err_cnt += 1;
if (can_autobaud_enabled[bus_number] && (CAN->ESR & CAN_ESR_LEC)) {
can_autobaud_speed_increment(can_number);
can_set_speed(can_number);
}
// clear current send
CAN->TSR |= CAN_TSR_ABRQ0;
CAN->MSR &= ~(CAN_MSR_ERRI);
CAN->MSR = CAN->MSR;
}
exit_critical_section();
}
// ***************************** CAN *****************************
void process_can(uint8_t can_number) {
if (can_number != 0xff) {
if (can_number == 0xff) return;
#ifdef PANDA
power_save_reset_timer();
#endif
enter_critical_section();
enter_critical_section();
CAN_TypeDef *CAN = CANIF_FROM_CAN_NUM(can_number);
uint8_t bus_number = BUS_NUM_FROM_CAN_NUM(can_number);
CAN_TypeDef *CAN = CANIF_FROM_CAN_NUM(can_number);
uint8_t bus_number = BUS_NUM_FROM_CAN_NUM(can_number);
#ifdef DEBUG
puts("process CAN TX\n");
#endif
// check for empty mailbox
CAN_FIFOMailBox_TypeDef to_send;
if ((CAN->TSR & CAN_TSR_TME0) == CAN_TSR_TME0) {
// add successfully transmitted message to my fifo
if ((CAN->TSR & CAN_TSR_RQCP0) == CAN_TSR_RQCP0) {
can_txd_cnt += 1;
// check for empty mailbox
CAN_FIFOMailBox_TypeDef to_send;
if ((CAN->TSR & CAN_TSR_TME0) == CAN_TSR_TME0) {
// add successfully transmitted message to my fifo
if ((CAN->TSR & CAN_TSR_RQCP0) == CAN_TSR_RQCP0) {
can_txd_cnt += 1;
if ((CAN->TSR & CAN_TSR_TXOK0) == CAN_TSR_TXOK0) {
CAN_FIFOMailBox_TypeDef to_push;
to_push.RIR = CAN->sTxMailBox[0].TIR;
to_push.RDTR = (CAN->sTxMailBox[0].TDTR & 0xFFFF000F) | ((CAN_BUS_RET_FLAG | bus_number) << 4);
to_push.RDLR = CAN->sTxMailBox[0].TDLR;
to_push.RDHR = CAN->sTxMailBox[0].TDHR;
can_push(&can_rx_q, &to_push);
}
if ((CAN->TSR & CAN_TSR_TERR0) == CAN_TSR_TERR0) {
#ifdef DEBUG
puts("CAN TX ERROR!\n");
#endif
}
if ((CAN->TSR & CAN_TSR_ALST0) == CAN_TSR_ALST0) {
#ifdef DEBUG
puts("CAN TX ARBITRATION LOST!\n");
#endif
}
// clear interrupt
// careful, this can also be cleared by requesting a transmission
CAN->TSR |= CAN_TSR_RQCP0;
if ((CAN->TSR & CAN_TSR_TXOK0) == CAN_TSR_TXOK0) {
CAN_FIFOMailBox_TypeDef to_push;
to_push.RIR = CAN->sTxMailBox[0].TIR;
to_push.RDTR = (CAN->sTxMailBox[0].TDTR & 0xFFFF000F) | ((CAN_BUS_RET_FLAG | bus_number) << 4);
to_push.RDLR = CAN->sTxMailBox[0].TDLR;
to_push.RDHR = CAN->sTxMailBox[0].TDHR;
can_push(&can_rx_q, &to_push);
}
if (can_pop(can_queues[bus_number], &to_send)) {
can_tx_cnt += 1;
// only send if we have received a packet
CAN->sTxMailBox[0].TDLR = to_send.RDLR;
CAN->sTxMailBox[0].TDHR = to_send.RDHR;
CAN->sTxMailBox[0].TDTR = to_send.RDTR;
CAN->sTxMailBox[0].TIR = to_send.RIR;
if ((CAN->TSR & CAN_TSR_TERR0) == CAN_TSR_TERR0) {
#ifdef DEBUG
puts("CAN TX ERROR!\n");
#endif
}
if ((CAN->TSR & CAN_TSR_ALST0) == CAN_TSR_ALST0) {
#ifdef DEBUG
puts("CAN TX ARBITRATION LOST!\n");
#endif
}
// clear interrupt
// careful, this can also be cleared by requesting a transmission
CAN->TSR |= CAN_TSR_RQCP0;
}
exit_critical_section();
if (can_pop(can_queues[bus_number], &to_send)) {
if (CAN->MCR & CAN_MCR_SLEEP) {
set_can_enable(CAN, 1);
CAN->MCR &= ~(CAN_MCR_SLEEP);
CAN->MCR |= CAN_MCR_INRQ;
while((CAN->MSR & CAN_MSR_INAK) != CAN_MSR_INAK);
CAN->MCR &= ~(CAN_MCR_INRQ);
}
can_tx_cnt += 1;
// only send if we have received a packet
CAN->sTxMailBox[0].TDLR = to_send.RDLR;
CAN->sTxMailBox[0].TDHR = to_send.RDHR;
CAN->sTxMailBox[0].TDTR = to_send.RDTR;
CAN->sTxMailBox[0].TIR = to_send.RIR;
}
}
exit_critical_section();
}
// CAN receive handlers
// blink blue when we are receiving CAN messages
void can_rx(uint8_t can_number) {
#ifdef PANDA
power_save_reset_timer();
#endif
CAN_TypeDef *CAN = CANIF_FROM_CAN_NUM(can_number);
uint8_t bus_number = BUS_NUM_FROM_CAN_NUM(can_number);
while ((CAN->RF0R & CAN_RF0R_FMP0) != 0) {
while (CAN->RF0R & CAN_RF0R_FMP0) {
if (can_autobaud_enabled[bus_number]) {
can_autobaud_enabled[bus_number] = false;
puts(CAN_NAME_FROM_CANIF(CAN));
#ifdef DEBUG
puts(" auto-baud ");
putui(can_speed[bus_number]);
puts(" cbps\n");
#endif
}
can_rx_cnt += 1;
// can is live
@@ -308,19 +454,25 @@ void can_rx(uint8_t can_number) {
to_push.RDTR = (to_push.RDTR & 0xFFFF000F) | (bus_number << 4);
// forwarding (panda only)
int bus_fwd_num = (can_forwarding[bus_number] != -1) ? can_forwarding[bus_number] : safety_fwd_hook(bus_number, &to_push);
if (bus_fwd_num != -1) {
CAN_FIFOMailBox_TypeDef to_send;
to_send.RIR = to_push.RIR | 1; // TXRQ
to_send.RDTR = to_push.RDTR;
to_send.RDLR = to_push.RDLR;
to_send.RDHR = to_push.RDHR;
can_send(&to_send, bus_fwd_num);
}
#ifdef PANDA
if ((get_lline_status() != 0) || !relay_control) { //Relay engaged or relay isn't controlled, allow fwd
int bus_fwd_num = can_forwarding[bus_number] != -1 ? can_forwarding[bus_number] : safety_fwd_hook(bus_number, &to_push);
if (bus_fwd_num != -1) {
CAN_FIFOMailBox_TypeDef to_send;
to_send.RIR = to_push.RIR | 1; // TXRQ
to_send.RDTR = to_push.RDTR;
to_send.RDLR = to_push.RDLR;
to_send.RDHR = to_push.RDHR;
can_send(&to_send, bus_fwd_num);
}
}
#endif
safety_rx_hook(&to_push);
set_led(LED_BLUE, 1);
#ifdef PANDA
set_led(LED_BLUE, 1);
#endif
can_push(&can_rx_q, &to_push);
// next
@@ -328,27 +480,35 @@ void can_rx(uint8_t can_number) {
}
}
void CAN1_TX_IRQHandler(void) { process_can(0); }
void CAN1_RX0_IRQHandler(void) { can_rx(0); }
void CAN1_SCE_IRQHandler(void) { can_sce(CAN1); }
#ifndef CUSTOM_CAN_INTERRUPTS
void CAN2_TX_IRQHandler(void) { process_can(1); }
void CAN2_RX0_IRQHandler(void) { can_rx(1); }
void CAN2_SCE_IRQHandler(void) { can_sce(CAN2); }
void CAN1_TX_IRQHandler() { process_can(0); }
void CAN1_RX0_IRQHandler() { can_rx(0); }
void CAN1_SCE_IRQHandler() { can_sce(CAN1); }
void CAN3_TX_IRQHandler(void) { process_can(2); }
void CAN3_RX0_IRQHandler(void) { can_rx(2); }
void CAN3_SCE_IRQHandler(void) { can_sce(CAN3); }
void CAN2_TX_IRQHandler() { process_can(1); }
void CAN2_RX0_IRQHandler() { can_rx(1); }
void CAN2_SCE_IRQHandler() { can_sce(CAN2); }
#ifdef CAN3
void CAN3_TX_IRQHandler() { process_can(2); }
void CAN3_RX0_IRQHandler() { can_rx(2); }
void CAN3_SCE_IRQHandler() { can_sce(CAN3); }
#endif
#endif
void can_send(CAN_FIFOMailBox_TypeDef *to_push, uint8_t bus_number) {
if (safety_tx_hook(to_push) != 0) {
if (safety_tx_hook(to_push) && !can_autobaud_enabled[bus_number]) {
if (bus_number < BUS_MAX) {
// add CAN packet to send queue
// bus number isn't passed through
to_push->RDTR &= 0xF;
if ((bus_number == 3) && (can_num_lookup[3] == 0xFF)) {
if (bus_number == 3 && can_num_lookup[3] == 0xFF) {
#ifdef PANDA
// TODO: why uint8 bro? only int8?
bitbang_gmlan(to_push);
#endif
} else {
can_push(can_queues[bus_number], to_push);
process_can(CAN_NUM_FROM_BUS_NUM(bus_number));
@@ -360,4 +520,3 @@ void can_send(CAN_FIFOMailBox_TypeDef *to_push, uint8_t bus_number) {
void can_set_forwarding(int from, int to) {
can_forwarding[from] = to;
}
-40
View File
@@ -1,40 +0,0 @@
void clock_init(void) {
// enable external oscillator
RCC->CR |= RCC_CR_HSEON;
while ((RCC->CR & RCC_CR_HSERDY) == 0);
// divide shit
RCC->CFGR = RCC_CFGR_HPRE_DIV1 | RCC_CFGR_PPRE2_DIV2 | RCC_CFGR_PPRE1_DIV4;
// 16mhz crystal
RCC->PLLCFGR = RCC_PLLCFGR_PLLQ_2 | RCC_PLLCFGR_PLLM_3 |
RCC_PLLCFGR_PLLN_6 | RCC_PLLCFGR_PLLN_5 | RCC_PLLCFGR_PLLSRC_HSE;
// start PLL
RCC->CR |= RCC_CR_PLLON;
while ((RCC->CR & RCC_CR_PLLRDY) == 0);
// Configure Flash prefetch, Instruction cache, Data cache and wait state
// *** without this, it breaks ***
FLASH->ACR = FLASH_ACR_ICEN | FLASH_ACR_DCEN | FLASH_ACR_LATENCY_5WS;
// switch to PLL
RCC->CFGR |= RCC_CFGR_SW_PLL;
while ((RCC->CFGR & RCC_CFGR_SWS) != RCC_CFGR_SWS_PLL);
// *** running on PLL ***
}
void watchdog_init(void) {
// setup watchdog
IWDG->KR = 0x5555;
IWDG->PR = 0; // divider /4
// 0 = 0.125 ms, let's have a 50ms watchdog
IWDG->RLR = 400 - 1;
IWDG->KR = 0xCCCC;
}
void watchdog_feed(void) {
IWDG->KR = 0xAAAA;
}
+141
View File
@@ -0,0 +1,141 @@
#ifndef PANDA_DRIVERS_H
#define PANDA_DRIVERS_H
// ********************* LLGPIO *********************
#define MODE_INPUT 0
#define MODE_OUTPUT 1
#define MODE_ALTERNATE 2
#define MODE_ANALOG 3
#define PULL_NONE 0
#define PULL_UP 1
#define PULL_DOWN 2
void set_gpio_mode(GPIO_TypeDef *GPIO, int pin, int mode);
void set_gpio_output(GPIO_TypeDef *GPIO, int pin, int val);
void set_gpio_alternate(GPIO_TypeDef *GPIO, int pin, int mode);
void set_gpio_pullup(GPIO_TypeDef *GPIO, int pin, int mode);
int get_gpio_input(GPIO_TypeDef *GPIO, int pin);
// ********************* USB *********************
// IRQs: OTG_FS
typedef union {
uint16_t w;
struct BW {
uint8_t msb;
uint8_t lsb;
}
bw;
}
uint16_t_uint8_t;
typedef union _USB_Setup {
uint32_t d8[2];
struct _SetupPkt_Struc
{
uint8_t bmRequestType;
uint8_t bRequest;
uint16_t_uint8_t wValue;
uint16_t_uint8_t wIndex;
uint16_t_uint8_t wLength;
} b;
}
USB_Setup_TypeDef;
void usb_init();
int usb_cb_control_msg(USB_Setup_TypeDef *setup, uint8_t *resp, int hardwired);
int usb_cb_ep1_in(uint8_t *usbdata, int len, int hardwired);
void usb_cb_ep2_out(uint8_t *usbdata, int len, int hardwired);
void usb_cb_ep3_out(uint8_t *usbdata, int len, int hardwired);
void usb_cb_enumeration_complete();
// ********************* UART *********************
// IRQs: USART1, USART2, USART3, UART5
#define FIFO_SIZE 0x400
typedef struct uart_ring {
uint16_t w_ptr_tx;
uint16_t r_ptr_tx;
uint8_t elems_tx[FIFO_SIZE];
uint16_t w_ptr_rx;
uint16_t r_ptr_rx;
uint8_t elems_rx[FIFO_SIZE];
USART_TypeDef *uart;
void (*callback)(struct uart_ring*);
} uart_ring;
void uart_init(USART_TypeDef *u, int baud);
int getc(uart_ring *q, char *elem);
int putc(uart_ring *q, char elem);
int puts(const char *a);
void puth(unsigned int i);
void hexdump(const void *a, int l);
// ********************* ADC *********************
void adc_init();
uint32_t adc_get(int channel);
// ********************* DAC *********************
void dac_init();
void dac_set(int channel, uint32_t value);
// ********************* TIMER *********************
void timer_init(TIM_TypeDef *TIM, int psc);
// ********************* SPI *********************
// IRQs: DMA2_Stream2, DMA2_Stream3, EXTI4
void spi_init();
int spi_cb_rx(uint8_t *data, int len, uint8_t *data_out);
// ********************* CAN *********************
// IRQs: CAN1_TX, CAN1_RX0, CAN1_SCE
// CAN2_TX, CAN2_RX0, CAN2_SCE
// CAN3_TX, CAN3_RX0, CAN3_SCE
typedef struct {
uint32_t w_ptr;
uint32_t r_ptr;
uint32_t fifo_size;
CAN_FIFOMailBox_TypeDef *elems;
} can_ring;
#define CAN_BUS_RET_FLAG 0x80
#define CAN_BUS_NUM_MASK 0x7F
#ifdef PANDA
#define BUS_MAX 4
#else
#define BUS_MAX 2
#endif
extern int can_live, pending_can_live;
// must reinit after changing these
extern int can_loopback, can_silent;
extern uint32_t can_speed[];
void can_set_forwarding(int from, int to);
void can_init(uint8_t can_number);
void can_init_all();
void can_send(CAN_FIFOMailBox_TypeDef *to_push, uint8_t bus_number);
int can_pop(can_ring *q, CAN_FIFOMailBox_TypeDef *elem);
#endif
+36 -39
View File
@@ -9,7 +9,7 @@
#define MAX_BITS_CAN_PACKET (200)
int gmlan_alt_mode = DISABLED;
int gmlan_alt_mode = DISABLED;
// returns out_len
int do_bitstuff(char *out, char *in, int in_len) {
@@ -18,8 +18,7 @@ int do_bitstuff(char *out, char *in, int in_len) {
int j = 0;
for (int i = 0; i < in_len; i++) {
char bit = in[i];
out[j] = bit;
j++;
out[j++] = bit;
// do the stuffing
if (bit == last_bit) {
@@ -27,8 +26,7 @@ int do_bitstuff(char *out, char *in, int in_len) {
if (bit_cnt == 5) {
// 5 in a row the same, do stuff
last_bit = !bit;
out[j] = last_bit;
j++;
out[j++] = last_bit;
bit_cnt = 1;
}
} else {
@@ -44,30 +42,27 @@ int append_crc(char *in, int in_len) {
int crc = 0;
for (int i = 0; i < in_len; i++) {
crc <<= 1;
if ((in[i] ^ ((crc >> 15) & 1)) != 0) {
if (in[i] ^ ((crc>>15)&1)) {
crc = crc ^ 0x4599;
}
crc &= 0x7fff;
}
for (int i = 14; i >= 0; i--) {
in[in_len] = (crc>>i)&1;
in_len++;
in[in_len++] = (crc>>i)&1;
}
return in_len;
}
int append_bits(char *in, int in_len, char *app, int app_len) {
for (int i = 0; i < app_len; i++) {
in[in_len] = app[i];
in_len++;
in[in_len++] = app[i];
}
return in_len;
}
int append_int(char *in, int in_len, int val, int val_len) {
for (int i = val_len-1; i >= 0; i--) {
in[in_len] = (val&(1<<i)) != 0;
in_len++;
in[in_len++] = (val&(1<<i)) != 0;
}
return in_len;
}
@@ -87,8 +82,8 @@ int get_bit_message(char *out, CAN_FIFOMailBox_TypeDef *to_bang) {
// test packet
int dlc_len = to_bang->RDTR & 0xF;
len = append_int(pkt, len, 0, 1); // Start-of-frame
if ((to_bang->RIR & 4) != 0) {
if (to_bang->RIR & 4) {
// extended identifier
len = append_int(pkt, len, to_bang->RIR >> 21, 11); // Identifier
len = append_int(pkt, len, 3, 2); // SRR+IDE
@@ -119,7 +114,9 @@ int get_bit_message(char *out, CAN_FIFOMailBox_TypeDef *to_bang) {
return len;
}
void setup_timer4(void) {
#ifdef PANDA
void setup_timer4() {
// setup
TIM4->PSC = 48-1; // tick on 1 us
TIM4->CR1 = TIM_CR1_CEN; // enable
@@ -136,7 +133,7 @@ void setup_timer4(void) {
int gmlan_timeout_counter = GMLAN_TICKS_PER_TIMEOUT_TICKLE; //GMLAN transceiver times out every 17ms held high; tickle every 15ms
int can_timeout_counter = GMLAN_TICKS_PER_SECOND; //1 second
int inverted_bit_to_send = GMLAN_HIGH;
int inverted_bit_to_send = GMLAN_HIGH;
int gmlan_switch_below_timeout = -1;
int gmlan_switch_timeout_enable = 0;
@@ -145,9 +142,9 @@ void gmlan_switch_init(int timeout_enable) {
gmlan_alt_mode = GPIO_SWITCH;
gmlan_switch_below_timeout = 1;
set_gpio_mode(GPIOB, 13, MODE_OUTPUT);
setup_timer4();
inverted_bit_to_send = GMLAN_LOW; //We got initialized, set the output low
}
@@ -167,7 +164,7 @@ void reset_gmlan_switch_timeout(void) {
}
void set_bitbanged_gmlan(int val) {
if (val != 0) {
if (val) {
GPIOB->ODR |= (1 << 13);
} else {
GPIOB->ODR &= ~(1 << 13);
@@ -185,7 +182,7 @@ int gmlan_fail_count = 0;
void TIM4_IRQHandler(void) {
if (gmlan_alt_mode == BITBANG) {
if ((TIM4->SR & TIM_SR_UIF) && (gmlan_sendmax != -1)) {
if (TIM4->SR & TIM_SR_UIF && gmlan_sendmax != -1) {
int read = get_gpio_input(GPIOB, 12);
if (gmlan_silent_count < REQUIRED_SILENT_TIME) {
if (read == 0) {
@@ -194,16 +191,16 @@ void TIM4_IRQHandler(void) {
gmlan_silent_count++;
}
} else if (gmlan_silent_count == REQUIRED_SILENT_TIME) {
bool retry = 0;
int retry = 0;
// in send loop
if ((gmlan_sending > 0) && // not first bit
((read == 0) && (pkt_stuffed[gmlan_sending-1] == 1)) && // bus wrongly dominant
(gmlan_sending != (gmlan_sendmax - 11))) { //not ack bit
if (gmlan_sending > 0 && // not first bit
(read == 0 && pkt_stuffed[gmlan_sending-1] == 1) && // bus wrongly dominant
gmlan_sending != (gmlan_sendmax-11)) { //not ack bit
puts("GMLAN ERR: bus driven at ");
puth(gmlan_sending);
puts("\n");
retry = 1;
} else if ((read == 1) && (gmlan_sending == (gmlan_sendmax - 11))) { // recessive during ACK
} else if (read == 1 && gmlan_sending == (gmlan_sendmax-11)) { // recessive during ACK
puts("GMLAN ERR: didn't recv ACK\n");
retry = 1;
}
@@ -221,7 +218,7 @@ void TIM4_IRQHandler(void) {
gmlan_sending++;
}
}
if ((gmlan_sending == gmlan_sendmax) || (gmlan_fail_count == MAX_FAIL_COUNT)) {
if (gmlan_sending == gmlan_sendmax || gmlan_fail_count == MAX_FAIL_COUNT) {
set_bitbanged_gmlan(1); // recessive
set_gpio_mode(GPIOB, 13, MODE_INPUT);
TIM4->DIER = 0; // no update interrupt
@@ -233,8 +230,8 @@ void TIM4_IRQHandler(void) {
} //bit bang mode
else if (gmlan_alt_mode == GPIO_SWITCH) {
if ((TIM4->SR & TIM_SR_UIF) && (gmlan_switch_below_timeout != -1)) {
if ((can_timeout_counter == 0) && gmlan_switch_timeout_enable) {
if (TIM4->SR & TIM_SR_UIF && gmlan_switch_below_timeout != -1) {
if (can_timeout_counter == 0 && gmlan_switch_timeout_enable) {
//it has been more than 1 second since timeout was reset; disable timer and restore the GMLAN output
set_gpio_output(GPIOB, 13, GMLAN_LOW);
gmlan_switch_below_timeout = -1;
@@ -261,19 +258,19 @@ void TIM4_IRQHandler(void) {
void bitbang_gmlan(CAN_FIFOMailBox_TypeDef *to_bang) {
gmlan_alt_mode = BITBANG;
// TODO: make failure less silent
if (gmlan_sendmax == -1) {
if (gmlan_sendmax != -1) return;
int len = get_bit_message(pkt_stuffed, to_bang);
gmlan_fail_count = 0;
gmlan_silent_count = 0;
gmlan_sending = 0;
gmlan_sendmax = len;
int len = get_bit_message(pkt_stuffed, to_bang);
gmlan_fail_count = 0;
gmlan_silent_count = 0;
gmlan_sending = 0;
gmlan_sendmax = len;
// setup for bitbang loop
set_bitbanged_gmlan(1); // recessive
set_gpio_mode(GPIOB, 13, MODE_OUTPUT);
// setup for bitbang loop
set_bitbanged_gmlan(1); // recessive
set_gpio_mode(GPIOB, 13, MODE_OUTPUT);
setup_timer4();
}
setup_timer4();
}
#endif
-81
View File
@@ -1,81 +0,0 @@
// this is needed for 1 mbps support
#define CAN_QUANTA 8
#define CAN_SEQ1 6 // roundf(quanta * 0.875f) - 1;
#define CAN_SEQ2 1 // roundf(quanta * 0.125f);
#define CAN_PCLK 24000
// 333 = 33.3 kbps
// 5000 = 500 kbps
#define can_speed_to_prescaler(x) (CAN_PCLK / CAN_QUANTA * 10 / (x))
bool llcan_set_speed(CAN_TypeDef *CAN, uint32_t speed, bool loopback, bool silent) {
// initialization mode
CAN->MCR = CAN_MCR_TTCM | CAN_MCR_INRQ;
while((CAN->MSR & CAN_MSR_INAK) != CAN_MSR_INAK);
// set time quanta from defines
CAN->BTR = (CAN_BTR_TS1_0 * (CAN_SEQ1-1)) |
(CAN_BTR_TS2_0 * (CAN_SEQ2-1)) |
(can_speed_to_prescaler(speed) - 1);
// silent loopback mode for debugging
if (loopback) {
CAN->BTR |= CAN_BTR_SILM | CAN_BTR_LBKM;
}
if (silent) {
CAN->BTR |= CAN_BTR_SILM;
}
// reset
CAN->MCR = CAN_MCR_TTCM | CAN_MCR_ABOM;
#define CAN_TIMEOUT 1000000
int tmp = 0;
bool ret = false;
while(((CAN->MSR & CAN_MSR_INAK) == CAN_MSR_INAK) && (tmp < CAN_TIMEOUT)) tmp++;
if (tmp < CAN_TIMEOUT) {
ret = true;
}
return ret;
}
void llcan_init(CAN_TypeDef *CAN) {
// accept all filter
CAN->FMR |= CAN_FMR_FINIT;
// no mask
CAN->sFilterRegister[0].FR1 = 0;
CAN->sFilterRegister[0].FR2 = 0;
CAN->sFilterRegister[14].FR1 = 0;
CAN->sFilterRegister[14].FR2 = 0;
CAN->FA1R |= 1 | (1U << 14);
CAN->FMR &= ~(CAN_FMR_FINIT);
// enable certain CAN interrupts
CAN->IER |= CAN_IER_TMEIE | CAN_IER_FMPIE0 | CAN_IER_WKUIE;
if (CAN == CAN1) {
NVIC_EnableIRQ(CAN1_TX_IRQn);
NVIC_EnableIRQ(CAN1_RX0_IRQn);
NVIC_EnableIRQ(CAN1_SCE_IRQn);
} else if (CAN == CAN2) {
NVIC_EnableIRQ(CAN2_TX_IRQn);
NVIC_EnableIRQ(CAN2_RX0_IRQn);
NVIC_EnableIRQ(CAN2_SCE_IRQn);
#ifdef CAN3
} else if (CAN == CAN3) {
NVIC_EnableIRQ(CAN3_TX_IRQn);
NVIC_EnableIRQ(CAN3_RX0_IRQn);
NVIC_EnableIRQ(CAN3_SCE_IRQn);
#endif
}
}
void llcan_clear_send(CAN_TypeDef *CAN) {
CAN->TSR |= CAN_TSR_ABRQ0;
CAN->MSR &= ~(CAN_MSR_ERRI);
CAN->MSR = CAN->MSR;
}
+3 -12
View File
@@ -1,12 +1,3 @@
#define MODE_INPUT 0
#define MODE_OUTPUT 1
#define MODE_ALTERNATE 2
#define MODE_ANALOG 3
#define PULL_NONE 0
#define PULL_UP 1
#define PULL_DOWN 2
void set_gpio_mode(GPIO_TypeDef *GPIO, int pin, int mode) {
uint32_t tmp = GPIO->MODER;
tmp &= ~(3 << (pin*2));
@@ -14,8 +5,8 @@ void set_gpio_mode(GPIO_TypeDef *GPIO, int pin, int mode) {
GPIO->MODER = tmp;
}
void set_gpio_output(GPIO_TypeDef *GPIO, int pin, bool enabled) {
if (enabled) {
void set_gpio_output(GPIO_TypeDef *GPIO, int pin, int val) {
if (val) {
GPIO->ODR |= (1 << pin);
} else {
GPIO->ODR &= ~(1 << pin);
@@ -39,6 +30,6 @@ void set_gpio_pullup(GPIO_TypeDef *GPIO, int pin, int mode) {
}
int get_gpio_input(GPIO_TypeDef *GPIO, int pin) {
return (GPIO->IDR & (1U << pin)) == (1U << pin);
return (GPIO->IDR & (1 << pin)) == (1 << pin);
}
+88
View File
@@ -0,0 +1,88 @@
#ifdef PANDA
int relay_control = 0; // True if relay is controlled through l-line
/* Conrol a relay connected to l-line pin */
// 160us cycles, 1 high, 25 low
volatile int turn_on_relay = 0;
volatile int on_cycles = 25;
//5s timeout
#define LLINE_TIMEOUT_CYCLES 31250
volatile int timeout_cycles = LLINE_TIMEOUT_CYCLES;
void TIM5_IRQHandler(void) {
if (TIM5->SR & TIM_SR_UIF) {
on_cycles--;
timeout_cycles--;
if (timeout_cycles == 0) {
turn_on_relay = 0;
}
if (on_cycles > 0) {
if (turn_on_relay) {
set_gpio_output(GPIOC, 10, 0);
}
}
else {
set_gpio_output(GPIOC, 10, 1);
on_cycles = 25;
}
}
TIM5->ARR = 160-1;
TIM5->SR = 0;
}
void lline_relay_init (void) {
set_lline_output(0);
relay_control = 1;
set_gpio_output(GPIOC, 10, 1);
// setup
TIM5->PSC = 48-1; // tick on 1 us
TIM5->CR1 = TIM_CR1_CEN; // enable
TIM5->ARR = 50-1; // 50 us
TIM5->DIER = TIM_DIER_UIE; // update interrupt
TIM5->CNT = 0;
NVIC_EnableIRQ(TIM5_IRQn);
#ifdef DEBUG
puts("INIT LLINE\n");
puts(" SR ");
putui(TIM5->SR);
puts(" PSC ");
putui(TIM5->PSC);
puts(" CR1 ");
putui(TIM5->CR1);
puts(" ARR ");
putui(TIM5->ARR);
puts(" DIER ");
putui(TIM5->DIER);
puts(" SR ");
putui(TIM5->SR);
puts(" CNT ");
putui(TIM5->CNT);
puts("\n");
#endif
}
void lline_relay_release (void) {
set_lline_output(0);
relay_control = 0;
puts("RELEASE LLINE\n");
set_gpio_alternate(GPIOC, 10, GPIO_AF7_USART3);
NVIC_DisableIRQ(TIM5_IRQn);
}
void set_lline_output(int to_set) {
timeout_cycles = LLINE_TIMEOUT_CYCLES;
turn_on_relay = to_set;
}
int get_lline_status() {
return turn_on_relay;
}
#endif
+5 -10
View File
@@ -1,16 +1,11 @@
// IRQs: DMA2_Stream2, DMA2_Stream3, EXTI4
void spi_init(void);
int spi_cb_rx(uint8_t *data, int len, uint8_t *data_out);
// end API
#define SPI_BUF_SIZE 256
uint8_t spi_buf[SPI_BUF_SIZE];
int spi_buf_count = 0;
int spi_total_count = 0;
void spi_init(void) {
void spi_init() {
//puts("SPI init\n");
SPI1->CR1 = SPI_CR1_SPE;
@@ -28,8 +23,8 @@ void spi_init(void) {
// setup interrupt on falling edge of SPI enable (on PA4)
SYSCFG->EXTICR[2] = SYSCFG_EXTICR2_EXTI4_PA;
EXTI->IMR |= (1 << 4);
EXTI->FTSR |= (1 << 4);
EXTI->IMR = (1 << 4);
EXTI->FTSR = (1 << 4);
NVIC_EnableIRQ(EXTI4_IRQn);
}
@@ -113,12 +108,12 @@ void DMA2_Stream3_IRQHandler(void) {
}
void EXTI4_IRQHandler(void) {
volatile int pr = EXTI->PR & (1 << 4);
volatile int pr = EXTI->PR;
#ifdef DEBUG_SPI
puts("exti4\n");
#endif
// SPI CS falling
if ((pr & (1 << 4)) != 0) {
if (pr & (1 << 4)) {
spi_total_count = 0;
spi_rx_dma(spi_buf, 0x14);
}
+37 -86
View File
@@ -1,27 +1,5 @@
// IRQs: USART1, USART2, USART3, UART5
#define FIFO_SIZE 0x400
typedef struct uart_ring {
volatile uint16_t w_ptr_tx;
volatile uint16_t r_ptr_tx;
uint8_t elems_tx[FIFO_SIZE];
volatile uint16_t w_ptr_rx;
volatile uint16_t r_ptr_rx;
uint8_t elems_rx[FIFO_SIZE];
USART_TypeDef *uart;
void (*callback)(struct uart_ring*);
} uart_ring;
void uart_init(USART_TypeDef *u, int baud);
bool getc(uart_ring *q, char *elem);
bool putc(uart_ring *q, char elem);
void puts(const char *a);
void puth(unsigned int i);
void hexdump(const void *a, int l);
// ***************************** serial port queues *****************************
// esp = USART1
@@ -50,25 +28,18 @@ uart_ring debug_ring = { .w_ptr_tx = 0, .r_ptr_tx = 0,
uart_ring *get_ring_by_number(int a) {
uart_ring *ring = NULL;
switch(a) {
case 0:
ring = &debug_ring;
break;
return &debug_ring;
case 1:
ring = &esp_ring;
break;
return &esp_ring;
case 2:
ring = &lin1_ring;
break;
return &lin1_ring;
case 3:
ring = &lin2_ring;
break;
return &lin2_ring;
default:
ring = NULL;
break;
return NULL;
}
return ring;
}
// ***************************** serial port *****************************
@@ -79,32 +50,31 @@ void uart_ring_process(uart_ring *q) {
int sr = q->uart->SR;
if (q->w_ptr_tx != q->r_ptr_tx) {
if ((sr & USART_SR_TXE) != 0) {
if (sr & USART_SR_TXE) {
q->uart->DR = q->elems_tx[q->r_ptr_tx];
q->r_ptr_tx = (q->r_ptr_tx + 1) % FIFO_SIZE;
} else {
// push on interrupt later
q->uart->CR1 |= USART_CR1_TXEIE;
}
// there could be more to send
q->uart->CR1 |= USART_CR1_TXEIE;
} else {
// nothing to send
q->uart->CR1 &= ~USART_CR1_TXEIE;
}
if ((sr & USART_SR_RXNE) || (sr & USART_SR_ORE)) {
if (sr & USART_SR_RXNE || sr & USART_SR_ORE) {
uint8_t c = q->uart->DR; // TODO: can drop packets
if (q != &esp_ring) {
uint16_t next_w_ptr = (q->w_ptr_rx + 1) % FIFO_SIZE;
if (next_w_ptr != q->r_ptr_rx) {
q->elems_rx[q->w_ptr_rx] = c;
q->w_ptr_rx = next_w_ptr;
if (q->callback != NULL) {
q->callback(q);
}
if (q->callback) q->callback(q);
}
}
}
if ((sr & USART_SR_ORE) != 0) {
if (sr & USART_SR_ORE) {
// set dropped packet flag?
}
@@ -118,22 +88,22 @@ void USART2_IRQHandler(void) { uart_ring_process(&debug_ring); }
void USART3_IRQHandler(void) { uart_ring_process(&lin2_ring); }
void UART5_IRQHandler(void) { uart_ring_process(&lin1_ring); }
bool getc(uart_ring *q, char *elem) {
bool ret = false;
int getc(uart_ring *q, char *elem) {
int ret = 0;
enter_critical_section();
if (q->w_ptr_rx != q->r_ptr_rx) {
if (elem != NULL) *elem = q->elems_rx[q->r_ptr_rx];
*elem = q->elems_rx[q->r_ptr_rx];
q->r_ptr_rx = (q->r_ptr_rx + 1) % FIFO_SIZE;
ret = true;
ret = 1;
}
exit_critical_section();
return ret;
}
bool injectc(uart_ring *q, char elem) {
int ret = false;
int injectc(uart_ring *q, char elem) {
int ret = 0;
uint16_t next_w_ptr;
enter_critical_section();
@@ -141,15 +111,15 @@ bool injectc(uart_ring *q, char elem) {
if (next_w_ptr != q->r_ptr_rx) {
q->elems_rx[q->w_ptr_rx] = elem;
q->w_ptr_rx = next_w_ptr;
ret = true;
ret = 1;
}
exit_critical_section();
return ret;
}
bool putc(uart_ring *q, char elem) {
bool ret = false;
int putc(uart_ring *q, char elem) {
int ret = 0;
uint16_t next_w_ptr;
enter_critical_section();
@@ -157,7 +127,7 @@ bool putc(uart_ring *q, char elem) {
if (next_w_ptr != q->r_ptr_tx) {
q->elems_tx[q->w_ptr_tx] = elem;
q->w_ptr_tx = next_w_ptr;
ret = true;
ret = 1;
}
exit_critical_section();
@@ -166,24 +136,6 @@ bool putc(uart_ring *q, char elem) {
return ret;
}
void uart_flush(uart_ring *q) {
while (q->w_ptr_tx != q->r_ptr_tx) {
__WFI();
}
}
void uart_flush_sync(uart_ring *q) {
// empty the TX buffer
while (q->w_ptr_tx != q->r_ptr_tx) {
uart_ring_process(q);
}
}
void uart_send_break(uart_ring *u) {
while ((u->uart->CR1 & USART_CR1_SBK) != 0);
u->uart->CR1 |= USART_CR1_SBK;
}
void clear_uart_buff(uart_ring *q) {
enter_critical_section();
q->w_ptr_tx = 0;
@@ -195,10 +147,10 @@ void clear_uart_buff(uart_ring *q) {
// ***************************** start UART code *****************************
#define __DIV(_PCLK_, _BAUD_) (((_PCLK_) * 25) / (4 * (_BAUD_)))
#define __DIVMANT(_PCLK_, _BAUD_) (__DIV((_PCLK_), (_BAUD_)) / 100)
#define __DIVFRAQ(_PCLK_, _BAUD_) ((((__DIV((_PCLK_), (_BAUD_)) - (__DIVMANT((_PCLK_), (_BAUD_)) * 100)) * 16) + 50) / 100)
#define __USART_BRR(_PCLK_, _BAUD_) ((__DIVMANT((_PCLK_), (_BAUD_)) << 4) | (__DIVFRAQ((_PCLK_), (_BAUD_)) & 0x0F))
#define __DIV(_PCLK_, _BAUD_) (((_PCLK_)*25)/(4*(_BAUD_)))
#define __DIVMANT(_PCLK_, _BAUD_) (__DIV((_PCLK_), (_BAUD_))/100)
#define __DIVFRAQ(_PCLK_, _BAUD_) (((__DIV((_PCLK_), (_BAUD_)) - (__DIVMANT((_PCLK_), (_BAUD_)) * 100)) * 16 + 50) / 100)
#define __USART_BRR(_PCLK_, _BAUD_) ((__DIVMANT((_PCLK_), (_BAUD_)) << 4)|(__DIVFRAQ((_PCLK_), (_BAUD_)) & 0x0F))
void uart_set_baud(USART_TypeDef *u, int baud) {
if (u == USART1) {
@@ -212,19 +164,19 @@ void uart_set_baud(USART_TypeDef *u, int baud) {
#define USART1_DMA_LEN 0x20
char usart1_dma[USART1_DMA_LEN];
void uart_dma_drain(void) {
void uart_dma_drain() {
uart_ring *q = &esp_ring;
enter_critical_section();
if ((DMA2->HISR & DMA_HISR_TCIF5) || (DMA2->HISR & DMA_HISR_HTIF5) || (DMA2_Stream5->NDTR != USART1_DMA_LEN)) {
if (DMA2->HISR & DMA_HISR_TCIF5 || DMA2->HISR & DMA_HISR_HTIF5 || DMA2_Stream5->NDTR != USART1_DMA_LEN) {
// disable DMA
q->uart->CR3 &= ~USART_CR3_DMAR;
DMA2_Stream5->CR &= ~DMA_SxCR_EN;
while ((DMA2_Stream5->CR & DMA_SxCR_EN) != 0);
while (DMA2_Stream5->CR & DMA_SxCR_EN);
unsigned int i;
for (i = 0; i < (USART1_DMA_LEN - DMA2_Stream5->NDTR); i++) {
int i;
for (i = 0; i < USART1_DMA_LEN - DMA2_Stream5->NDTR; i++) {
char c = usart1_dma[i];
uint16_t next_w_ptr = (q->w_ptr_rx + 1) % FIFO_SIZE;
if (next_w_ptr != q->r_ptr_rx) {
@@ -306,23 +258,22 @@ void putch(const char a) {
}
}
void puts(const char *a) {
int puts(const char *a) {
for (;*a;a++) {
if (*a == '\n') putch('\r');
putch(*a);
}
return 0;
}
void putui(uint32_t i) {
char str[11];
uint8_t idx = 10;
str[idx] = '\0';
idx--;
str[idx--] = '\0';
do {
str[idx] = (i % 10) + 0x30;
idx--;
str[idx--] = (i % 10) + 0x30;
i /= 10;
} while (i != 0);
} while (i);
puts(str + idx + 1);
}
@@ -345,7 +296,7 @@ void puth2(unsigned int i) {
void hexdump(const void *a, int l) {
int i;
for (i=0;i<l;i++) {
if ((i != 0) && ((i & 0xf) == 0)) puts("\n");
if (i != 0 && (i&0xf) == 0) puts("\n");
puth2(((const unsigned char*)a)[i]);
puts(" ");
}
+68 -89
View File
@@ -1,35 +1,5 @@
// IRQs: OTG_FS
typedef union {
uint16_t w;
struct BW {
uint8_t msb;
uint8_t lsb;
}
bw;
}
uint16_t_uint8_t;
typedef union _USB_Setup {
uint32_t d8[2];
struct _SetupPkt_Struc
{
uint8_t bmRequestType;
uint8_t bRequest;
uint16_t_uint8_t wValue;
uint16_t_uint8_t wIndex;
uint16_t_uint8_t wLength;
} b;
}
USB_Setup_TypeDef;
void usb_init(void);
int usb_cb_control_msg(USB_Setup_TypeDef *setup, uint8_t *resp, bool hardwired);
int usb_cb_ep1_in(uint8_t *usbdata, int len, bool hardwired);
void usb_cb_ep2_out(uint8_t *usbdata, int len, bool hardwired);
void usb_cb_ep3_out(uint8_t *usbdata, int len, bool hardwired);
void usb_cb_enumeration_complete(void);
// **** supporting defines ****
typedef struct
@@ -43,9 +13,9 @@ USB_OTG_GlobalTypeDef *USBx = USB_OTG_FS;
#define USBx_HOST ((USB_OTG_HostTypeDef *)((uint32_t)USBx + USB_OTG_HOST_BASE))
#define USBx_HOST_PORT ((USB_OTG_HostPortTypeDef *)((uint32_t)USBx + USB_OTG_HOST_PORT_BASE))
#define USBx_DEVICE ((USB_OTG_DeviceTypeDef *)((uint32_t)USBx + USB_OTG_DEVICE_BASE))
#define USBx_INEP(i) ((USB_OTG_INEndpointTypeDef *)((uint32_t)USBx + USB_OTG_IN_ENDPOINT_BASE + ((i) * USB_OTG_EP_REG_SIZE)))
#define USBx_OUTEP(i) ((USB_OTG_OUTEndpointTypeDef *)((uint32_t)USBx + USB_OTG_OUT_ENDPOINT_BASE + ((i) * USB_OTG_EP_REG_SIZE)))
#define USBx_DFIFO(i) *(__IO uint32_t *)((uint32_t)USBx + USB_OTG_FIFO_BASE + ((i) * USB_OTG_FIFO_SIZE))
#define USBx_INEP(i) ((USB_OTG_INEndpointTypeDef *)((uint32_t)USBx + USB_OTG_IN_ENDPOINT_BASE + (i)*USB_OTG_EP_REG_SIZE))
#define USBx_OUTEP(i) ((USB_OTG_OUTEndpointTypeDef *)((uint32_t)USBx + USB_OTG_OUT_ENDPOINT_BASE + (i)*USB_OTG_EP_REG_SIZE))
#define USBx_DFIFO(i) *(__IO uint32_t *)((uint32_t)USBx + USB_OTG_FIFO_BASE + (i) * USB_OTG_FIFO_SIZE)
#define USBx_PCGCCTL *(__IO uint32_t *)((uint32_t)USBx + USB_OTG_PCGCCTL_BASE)
#define USB_REQ_GET_STATUS 0x00
@@ -125,11 +95,11 @@ uint8_t resp[MAX_RESP_LEN];
// Convert machine byte order to USB byte order
#define TOUSBORDER(num)\
((num) & 0xFF), (((num) >> 8) & 0xFF)
(num&0xFF), ((num>>8)&0xFF)
// take in string length and return the first 2 bytes of a string descriptor
#define STRING_DESCRIPTOR_HEADER(size)\
(((((size) * 2) + 2) & 0xFF) | 0x0300)
(((size * 2 + 2)&0xFF) | 0x0300)
uint8_t device_desc[] = {
DSCR_DEVICE_LEN, USB_DESC_TYPE_DEVICE, //Length, Type
@@ -216,10 +186,17 @@ uint16_t string_manufacturer_desc[] = {
'c', 'o', 'm', 'm', 'a', '.', 'a', 'i'
};
#ifdef PANDA
uint16_t string_product_desc[] = {
STRING_DESCRIPTOR_HEADER(5),
'p', 'a', 'n', 'd', 'a'
};
#else
uint16_t string_product_desc[] = {
STRING_DESCRIPTOR_HEADER(5),
'N', 'E', 'O', 'v', '1'
};
#endif
// default serial number when we're not a panda
uint16_t string_serial_desc[] = {
@@ -233,6 +210,7 @@ uint16_t string_configuration_desc[] = {
'0', '1' // "01"
};
#ifdef PANDA
// WCID (auto install WinUSB driver)
// https://github.com/pbatard/libwdi/wiki/WCID-Devices
// https://docs.microsoft.com/en-us/windows-hardware/drivers/usbcon/winusb-installation#automatic-installation-of--winusb-without-an-inf-file
@@ -382,6 +360,8 @@ uint8_t winusb_20_desc[WINUSB_PLATFORM_DESCRIPTOR_LENGTH] = {
'1', 0x00, 'a', 0x00, 'd', 0x00, 'e', 0x00, '9', 0x00, '}', 0x00, 0x00, 0x00 // 78 bytes
};
#endif
// current packet
USB_Setup_TypeDef setup;
uint8_t usbdata[0x100];
@@ -397,10 +377,9 @@ void *USB_ReadPacket(void *dest, uint16_t len) {
uint32_t i=0;
uint32_t count32b = (len + 3) / 4;
for ( i = 0; i < count32b; i++) {
for ( i = 0; i < count32b; i++, dest += 4 ) {
// packed?
*(__attribute__((__packed__)) uint32_t *)dest = USBx_DFIFO(0);
dest += 4;
}
return ((void *)dest);
}
@@ -421,9 +400,8 @@ void USB_WritePacket(const uint8_t *src, uint16_t len, uint32_t ep) {
USBx_INEP(ep)->DIEPCTL |= (USB_OTG_DIEPCTL_CNAK | USB_OTG_DIEPCTL_EPENA);
// load the FIFO
for (i = 0; i < count32b; i++) {
for (i = 0; i < count32b; i++, src += 4) {
USBx_DFIFO(ep) = *((__attribute__((__packed__)) uint32_t *)src);
src += 4;
}
}
@@ -435,7 +413,7 @@ void USB_WritePacket_EP0(uint8_t *src, uint16_t len) {
hexdump(src, len);
#endif
uint16_t wplen = MIN(len, 0x40);
uint16_t wplen = min(len, 0x40);
USB_WritePacket(src, wplen, 0);
if (wplen < len) {
@@ -447,7 +425,7 @@ void USB_WritePacket_EP0(uint8_t *src, uint16_t len) {
}
}
void usb_reset(void) {
void usb_reset() {
// unmask endpoint interrupts, so many sets
USBx_DEVICE->DAINT = 0xFFFFFFFF;
USBx_DEVICE->DAINTMSK = 0xFFFFFFFF;
@@ -491,16 +469,14 @@ void usb_reset(void) {
}
char to_hex_char(int a) {
char ret;
if (a < 10) {
ret = '0' + a;
return '0' + a;
} else {
ret = 'a' + (a - 10);
return 'a' + (a-10);
}
return ret;
}
void usb_setup(void) {
void usb_setup() {
int resp_len;
// setup packet is ready
switch (setup.b.bRequest) {
@@ -549,32 +525,32 @@ void usb_setup(void) {
//puts(" writing device descriptor\n");
// setup transfer
USB_WritePacket(device_desc, MIN(sizeof(device_desc), setup.b.wLength.w), 0);
USB_WritePacket(device_desc, min(sizeof(device_desc), setup.b.wLength.w), 0);
USBx_OUTEP(0)->DOEPCTL |= USB_OTG_DOEPCTL_CNAK;
//puts("D");
break;
case USB_DESC_TYPE_CONFIGURATION:
USB_WritePacket(configuration_desc, MIN(sizeof(configuration_desc), setup.b.wLength.w), 0);
USB_WritePacket(configuration_desc, min(sizeof(configuration_desc), setup.b.wLength.w), 0);
USBx_OUTEP(0)->DOEPCTL |= USB_OTG_DOEPCTL_CNAK;
break;
case USB_DESC_TYPE_DEVICE_QUALIFIER:
USB_WritePacket(device_qualifier, MIN(sizeof(device_qualifier), setup.b.wLength.w), 0);
USB_WritePacket(device_qualifier, min(sizeof(device_qualifier), setup.b.wLength.w), 0);
USBx_OUTEP(0)->DOEPCTL |= USB_OTG_DOEPCTL_CNAK;
break;
case USB_DESC_TYPE_STRING:
switch (setup.b.wValue.bw.msb) {
case STRING_OFFSET_LANGID:
USB_WritePacket((uint8_t*)string_language_desc, MIN(sizeof(string_language_desc), setup.b.wLength.w), 0);
USB_WritePacket((uint8_t*)string_language_desc, min(sizeof(string_language_desc), setup.b.wLength.w), 0);
break;
case STRING_OFFSET_IMANUFACTURER:
USB_WritePacket((uint8_t*)string_manufacturer_desc, MIN(sizeof(string_manufacturer_desc), setup.b.wLength.w), 0);
USB_WritePacket((uint8_t*)string_manufacturer_desc, min(sizeof(string_manufacturer_desc), setup.b.wLength.w), 0);
break;
case STRING_OFFSET_IPRODUCT:
USB_WritePacket((uint8_t*)string_product_desc, MIN(sizeof(string_product_desc), setup.b.wLength.w), 0);
USB_WritePacket((uint8_t*)string_product_desc, min(sizeof(string_product_desc), setup.b.wLength.w), 0);
break;
case STRING_OFFSET_ISERIAL:
#ifdef UID_BASE
#ifdef PANDA
resp[0] = 0x02 + 12*4;
resp[1] = 0x03;
@@ -587,17 +563,19 @@ void usb_setup(void) {
resp[2 + i*4 + 3] = '\0';
}
USB_WritePacket(resp, MIN(resp[0], setup.b.wLength.w), 0);
USB_WritePacket(resp, min(resp[0], setup.b.wLength.w), 0);
#else
USB_WritePacket((const uint8_t *)string_serial_desc, MIN(sizeof(string_serial_desc), setup.b.wLength.w), 0);
USB_WritePacket((const uint8_t *)string_serial_desc, min(sizeof(string_serial_desc), setup.b.wLength.w), 0);
#endif
break;
#ifdef PANDA
case STRING_OFFSET_ICONFIGURATION:
USB_WritePacket((uint8_t*)string_configuration_desc, MIN(sizeof(string_configuration_desc), setup.b.wLength.w), 0);
USB_WritePacket((uint8_t*)string_configuration_desc, min(sizeof(string_configuration_desc), setup.b.wLength.w), 0);
break;
case 238:
USB_WritePacket((uint8_t*)string_238_desc, MIN(sizeof(string_238_desc), setup.b.wLength.w), 0);
USB_WritePacket((uint8_t*)string_238_desc, min(sizeof(string_238_desc), setup.b.wLength.w), 0);
break;
#endif
default:
// nothing
USB_WritePacket(0, 0, 0);
@@ -605,10 +583,12 @@ void usb_setup(void) {
}
USBx_OUTEP(0)->DOEPCTL |= USB_OTG_DOEPCTL_CNAK;
break;
#ifdef PANDA
case USB_DESC_TYPE_BINARY_OBJECT_STORE:
USB_WritePacket(binary_object_store_desc, MIN(sizeof(binary_object_store_desc), setup.b.wLength.w), 0);
USB_WritePacket(binary_object_store_desc, min(sizeof(binary_object_store_desc), setup.b.wLength.w), 0);
USBx_OUTEP(0)->DOEPCTL |= USB_OTG_DOEPCTL_CNAK;
break;
#endif
default:
// nothing here?
USB_WritePacket(0, 0, 0);
@@ -629,10 +609,11 @@ void usb_setup(void) {
USB_WritePacket(0, 0, 0);
USBx_OUTEP(0)->DOEPCTL |= USB_OTG_DOEPCTL_CNAK;
break;
#ifdef PANDA
case WEBUSB_VENDOR_CODE:
switch (setup.b.wIndex.w) {
case WEBUSB_REQ_GET_URL:
USB_WritePacket(webusb_url_descriptor, MIN(sizeof(webusb_url_descriptor), setup.b.wLength.w), 0);
USB_WritePacket(webusb_url_descriptor, min(sizeof(webusb_url_descriptor), setup.b.wLength.w), 0);
USBx_OUTEP(0)->DOEPCTL |= USB_OTG_DOEPCTL_CNAK;
break;
default:
@@ -646,28 +627,29 @@ void usb_setup(void) {
switch (setup.b.wIndex.w) {
// winusb 2.0 descriptor from BOS
case WINUSB_REQ_GET_DESCRIPTOR:
USB_WritePacket_EP0((uint8_t*)winusb_20_desc, MIN(sizeof(winusb_20_desc), setup.b.wLength.w));
USB_WritePacket_EP0((uint8_t*)winusb_20_desc, min(sizeof(winusb_20_desc), setup.b.wLength.w));
break;
// Extended Compat ID OS Descriptor
case WINUSB_REQ_GET_COMPATID_DESCRIPTOR:
USB_WritePacket_EP0((uint8_t*)winusb_ext_compatid_os_desc, MIN(sizeof(winusb_ext_compatid_os_desc), setup.b.wLength.w));
USB_WritePacket_EP0((uint8_t*)winusb_ext_compatid_os_desc, min(sizeof(winusb_ext_compatid_os_desc), setup.b.wLength.w));
break;
// Extended Properties OS Descriptor
case WINUSB_REQ_GET_EXT_PROPS_OS:
USB_WritePacket_EP0((uint8_t*)winusb_ext_prop_os_desc, MIN(sizeof(winusb_ext_prop_os_desc), setup.b.wLength.w));
USB_WritePacket_EP0((uint8_t*)winusb_ext_prop_os_desc, min(sizeof(winusb_ext_prop_os_desc), setup.b.wLength.w));
break;
default:
USB_WritePacket_EP0(0, 0);
}
break;
#endif
default:
resp_len = usb_cb_control_msg(&setup, resp, 1);
USB_WritePacket(resp, MIN(resp_len, setup.b.wLength.w), 0);
USB_WritePacket(resp, min(resp_len, setup.b.wLength.w), 0);
USBx_OUTEP(0)->DOEPCTL |= USB_OTG_DOEPCTL_CNAK;
}
}
void usb_init(void) {
void usb_init() {
// full speed PHY, do reset and remove power down
/*puth(USBx->GRSTCTL);
puts(" resetting PHY\n");*/
@@ -760,27 +742,27 @@ void usb_irqhandler(void) {
puts(" USB interrupt!\n");
#endif
if ((gintsts & USB_OTG_GINTSTS_CIDSCHG) != 0) {
if (gintsts & USB_OTG_GINTSTS_CIDSCHG) {
puts("connector ID status change\n");
}
if ((gintsts & USB_OTG_GINTSTS_ESUSP) != 0) {
if (gintsts & USB_OTG_GINTSTS_ESUSP) {
puts("ESUSP detected\n");
}
if ((gintsts & USB_OTG_GINTSTS_USBRST) != 0) {
if (gintsts & USB_OTG_GINTSTS_USBRST) {
puts("USB reset\n");
usb_reset();
}
if ((gintsts & USB_OTG_GINTSTS_ENUMDNE) != 0) {
if (gintsts & USB_OTG_GINTSTS_ENUMDNE) {
puts("enumeration done");
// Full speed, ENUMSPD
//puth(USBx_DEVICE->DSTS);
puts("\n");
}
if ((gintsts & USB_OTG_GINTSTS_OTGINT) != 0) {
if (gintsts & USB_OTG_GINTSTS_OTGINT) {
puts("OTG int:");
puth(USBx->GOTGINT);
puts("\n");
@@ -790,7 +772,7 @@ void usb_irqhandler(void) {
}
// RX FIFO first
if ((gintsts & USB_OTG_GINTSTS_RXFLVL) != 0) {
if (gintsts & USB_OTG_GINTSTS_RXFLVL) {
// 1. Read the Receive status pop register
volatile unsigned int rxst = USBx->GRXSTSP;
@@ -852,7 +834,7 @@ void usb_irqhandler(void) {
USBx_DEVICE->DCTL |= USB_OTG_DCTL_CGONAK | USB_OTG_DCTL_CGINAK;
}
if ((gintsts & USB_OTG_GINTSTS_SRQINT) != 0) {
if (gintsts & USB_OTG_GINTSTS_SRQINT) {
// we want to do "A-device host negotiation protocol" since we are the A-device
/*puts("start request\n");
puth(USBx->GOTGCTL);
@@ -863,7 +845,7 @@ void usb_irqhandler(void) {
}
// out endpoint hit
if ((gintsts & USB_OTG_GINTSTS_OEPINT) != 0) {
if (gintsts & USB_OTG_GINTSTS_OEPINT) {
#ifdef DEBUG_USB
puts(" 0:");
puth(USBx_OUTEP(0)->DOEPINT);
@@ -878,7 +860,7 @@ void usb_irqhandler(void) {
puts(" OUT ENDPOINT\n");
#endif
if ((USBx_OUTEP(2)->DOEPINT & USB_OTG_DOEPINT_XFRC) != 0) {
if (USBx_OUTEP(2)->DOEPINT & USB_OTG_DOEPINT_XFRC) {
#ifdef DEBUG_USB
puts(" OUT2 PACKET XFRC\n");
#endif
@@ -886,32 +868,32 @@ void usb_irqhandler(void) {
USBx_OUTEP(2)->DOEPCTL |= USB_OTG_DOEPCTL_EPENA | USB_OTG_DOEPCTL_CNAK;
}
if ((USBx_OUTEP(3)->DOEPINT & USB_OTG_DOEPINT_XFRC) != 0) {
if (USBx_OUTEP(3)->DOEPINT & USB_OTG_DOEPINT_XFRC) {
#ifdef DEBUG_USB
puts(" OUT3 PACKET XFRC\n");
#endif
USBx_OUTEP(3)->DOEPTSIZ = (1 << 19) | 0x40;
USBx_OUTEP(3)->DOEPCTL |= USB_OTG_DOEPCTL_EPENA | USB_OTG_DOEPCTL_CNAK;
} else if ((USBx_OUTEP(3)->DOEPINT & 0x2000) != 0) {
} else if (USBx_OUTEP(3)->DOEPINT & 0x2000) {
#ifdef DEBUG_USB
puts(" OUT3 PACKET WTF\n");
#endif
// if NAK was set trigger this, unknown interrupt
USBx_OUTEP(3)->DOEPTSIZ = (1 << 19) | 0x40;
USBx_OUTEP(3)->DOEPCTL |= USB_OTG_DOEPCTL_CNAK;
} else if ((USBx_OUTEP(3)->DOEPINT) != 0) {
} else if (USBx_OUTEP(3)->DOEPINT) {
puts("OUTEP3 error ");
puth(USBx_OUTEP(3)->DOEPINT);
puts("\n");
}
if ((USBx_OUTEP(0)->DOEPINT & USB_OTG_DIEPINT_XFRC) != 0) {
if (USBx_OUTEP(0)->DOEPINT & USB_OTG_DIEPINT_XFRC) {
// ready for next packet
USBx_OUTEP(0)->DOEPTSIZ = USB_OTG_DOEPTSIZ_STUPCNT | (USB_OTG_DOEPTSIZ_PKTCNT & (1 << 19)) | (1 * 8);
}
// respond to setup packets
if ((USBx_OUTEP(0)->DOEPINT & USB_OTG_DOEPINT_STUP) != 0) {
if (USBx_OUTEP(0)->DOEPINT & USB_OTG_DOEPINT_STUP) {
usb_setup();
}
@@ -921,7 +903,7 @@ void usb_irqhandler(void) {
}
// interrupt endpoint hit (Page 1221)
if ((gintsts & USB_OTG_GINTSTS_IEPINT) != 0) {
if (gintsts & USB_OTG_GINTSTS_IEPINT) {
#ifdef DEBUG_USB
puts(" ");
puth(USBx_INEP(0)->DIEPINT);
@@ -936,8 +918,8 @@ void usb_irqhandler(void) {
// No need to set NAK in OTG_DIEPCTL0 when nothing to send,
// Appears USB core automatically sets NAK. WritePacket clears it.
// Handle the two interface alternate settings. Setting 0 has EP1
// as bulk. Setting 1 has EP1 as interrupt. The code to handle
// Handle the two interface alternate settings. Setting 0 is has
// EP1 as bulk. Setting 1 has EP1 as interrupt. The code to handle
// these two EP variations are very similar and can be
// restructured for smaller code footprint. Keeping split out for
// now for clarity.
@@ -946,7 +928,7 @@ void usb_irqhandler(void) {
switch (current_int0_alt_setting) {
case 0: ////// Bulk config
// *** IN token received when TxFIFO is empty
if ((USBx_INEP(1)->DIEPINT & USB_OTG_DIEPMSK_ITTXFEMSK) != 0) {
if (USBx_INEP(1)->DIEPINT & USB_OTG_DIEPMSK_ITTXFEMSK) {
#ifdef DEBUG_USB
puts(" IN PACKET QUEUE\n");
#endif
@@ -957,7 +939,7 @@ void usb_irqhandler(void) {
case 1: ////// Interrupt config
// *** IN token received when TxFIFO is empty
if ((USBx_INEP(1)->DIEPINT & USB_OTG_DIEPMSK_ITTXFEMSK) != 0) {
if (USBx_INEP(1)->DIEPINT & USB_OTG_DIEPMSK_ITTXFEMSK) {
#ifdef DEBUG_USB
puts(" IN PACKET QUEUE\n");
#endif
@@ -968,18 +950,15 @@ void usb_irqhandler(void) {
}
}
break;
default:
puts("current_int0_alt_setting value invalid\n");
break;
}
if ((USBx_INEP(0)->DIEPINT & USB_OTG_DIEPMSK_ITTXFEMSK) != 0) {
if (USBx_INEP(0)->DIEPINT & USB_OTG_DIEPMSK_ITTXFEMSK) {
#ifdef DEBUG_USB
puts(" IN PACKET QUEUE\n");
#endif
if ((ep0_txlen != 0) && ((USBx_INEP(0)->DTXFSTS & USB_OTG_DTXFSTS_INEPTFSAV) >= 0x40)) {
uint16_t len = MIN(ep0_txlen, 0x40);
if (ep0_txlen != 0 && (USBx_INEP(0)->DTXFSTS & USB_OTG_DTXFSTS_INEPTFSAV) >= 0x40) {
uint16_t len = min(ep0_txlen, 0x40);
USB_WritePacket(ep0_txdata, len, 0);
ep0_txdata += len;
ep0_txlen -= len;
+81 -47
View File
@@ -1,5 +1,3 @@
// this is last place with ifdef PANDA
#ifdef STM32F4
#include "stm32f4xx_hal_gpio_ex.h"
#else
@@ -13,25 +11,23 @@
#define PULL_EFFECTIVE_DELAY 10
void puts(const char *a);
bool has_external_debug_serial = 0;
bool is_giant_panda = 0;
bool is_entering_bootmode = 0;
int has_external_debug_serial = 0;
int is_giant_panda = 0;
int is_entering_bootmode = 0;
int revision = PANDA_REV_AB;
bool is_grey_panda = 0;
int is_grey_panda = 0;
bool detect_with_pull(GPIO_TypeDef *GPIO, int pin, int mode) {
int detect_with_pull(GPIO_TypeDef *GPIO, int pin, int mode) {
set_gpio_mode(GPIO, pin, MODE_INPUT);
set_gpio_pullup(GPIO, pin, mode);
for (volatile int i=0; i<PULL_EFFECTIVE_DELAY; i++);
bool ret = get_gpio_input(GPIO, pin);
int ret = get_gpio_input(GPIO, pin);
set_gpio_pullup(GPIO, pin, PULL_NONE);
return ret;
}
// must call again from main because BSS is zeroed
void detect(void) {
void detect() {
// detect has_external_debug_serial
has_external_debug_serial = detect_with_pull(GPIOA, 3, PULL_DOWN);
@@ -65,7 +61,44 @@ void detect(void) {
// ********************* bringup *********************
void periph_init(void) {
void clock_init() {
// enable external oscillator
RCC->CR |= RCC_CR_HSEON;
while ((RCC->CR & RCC_CR_HSERDY) == 0);
// divide shit
RCC->CFGR = RCC_CFGR_HPRE_DIV1 | RCC_CFGR_PPRE2_DIV2 | RCC_CFGR_PPRE1_DIV4;
#ifdef PANDA
RCC->PLLCFGR = RCC_PLLCFGR_PLLQ_2 | RCC_PLLCFGR_PLLM_3 |
RCC_PLLCFGR_PLLN_6 | RCC_PLLCFGR_PLLN_5 | RCC_PLLCFGR_PLLSRC_HSE;
#else
#ifdef PEDAL
// comma pedal has a 16mhz crystal
RCC->PLLCFGR = RCC_PLLCFGR_PLLQ_2 | RCC_PLLCFGR_PLLM_3 |
RCC_PLLCFGR_PLLN_6 | RCC_PLLCFGR_PLLN_5 | RCC_PLLCFGR_PLLSRC_HSE;
#else
// NEO board has a 8mhz crystal
RCC->PLLCFGR = RCC_PLLCFGR_PLLQ_2 | RCC_PLLCFGR_PLLM_3 |
RCC_PLLCFGR_PLLN_7 | RCC_PLLCFGR_PLLN_6 | RCC_PLLCFGR_PLLSRC_HSE;
#endif
#endif
// start PLL
RCC->CR |= RCC_CR_PLLON;
while ((RCC->CR & RCC_CR_PLLRDY) == 0);
// Configure Flash prefetch, Instruction cache, Data cache and wait state
// *** without this, it breaks ***
FLASH->ACR = FLASH_ACR_ICEN | FLASH_ACR_DCEN | FLASH_ACR_LATENCY_5WS;
// switch to PLL
RCC->CFGR |= RCC_CFGR_SW_PLL;
while ((RCC->CFGR & RCC_CFGR_SWS) != RCC_CFGR_SWS_PLL);
// *** running on PLL ***
}
void periph_init() {
// enable GPIOB, UART2, CAN, USB clock
RCC->AHB1ENR |= RCC_AHB1ENR_GPIOAEN;
RCC->AHB1ENR |= RCC_AHB1ENR_GPIOBEN;
@@ -84,22 +117,24 @@ void periph_init(void) {
RCC->APB1ENR |= RCC_APB1ENR_CAN3EN;
#endif
RCC->APB1ENR |= RCC_APB1ENR_DACEN;
RCC->APB1ENR |= RCC_APB1ENR_TIM2EN; // main counter
RCC->APB1ENR |= RCC_APB1ENR_TIM3EN; // slow loop and pedal
RCC->APB1ENR |= RCC_APB1ENR_TIM4EN; // gmlan_alt
//RCC->APB1ENR |= RCC_APB1ENR_TIM5EN;
//RCC->APB1ENR |= RCC_APB1ENR_TIM6EN;
RCC->APB1ENR |= RCC_APB1ENR_TIM2EN;
RCC->APB1ENR |= RCC_APB1ENR_TIM3EN;
RCC->APB1ENR |= RCC_APB1ENR_TIM4EN;
RCC->APB1ENR |= RCC_APB1ENR_TIM5EN;
RCC->APB1ENR |= RCC_APB1ENR_TIM6EN;
RCC->APB2ENR |= RCC_APB2ENR_USART1EN;
RCC->AHB2ENR |= RCC_AHB2ENR_OTGFSEN;
//RCC->APB2ENR |= RCC_APB2ENR_TIM1EN;
RCC->APB2ENR |= RCC_APB2ENR_TIM1EN;
RCC->APB2ENR |= RCC_APB2ENR_ADC1EN;
RCC->APB2ENR |= RCC_APB2ENR_SPI1EN;
// needed?
RCC->APB2ENR |= RCC_APB2ENR_SYSCFGEN;
}
// ********************* setters *********************
void set_can_enable(CAN_TypeDef *CAN, bool enabled) {
void set_can_enable(CAN_TypeDef *CAN, int enabled) {
// enable CAN busses
if (CAN == CAN1) {
#ifdef PANDA
@@ -141,16 +176,16 @@ void set_can_enable(CAN_TypeDef *CAN, bool enabled) {
#endif
void set_led(int led_num, int on) {
if (led_num != -1) {
if (led_num == -1) return;
#ifdef PANDA
set_gpio_output(GPIOC, led_num, !on);
#else
set_gpio_output(GPIOB, led_num, !on);
#endif
}
}
void set_can_mode(int can, bool use_gmlan) {
void set_can_mode(int can, int use_gmlan) {
// connects to CAN2 xcvr or GMLAN xcvr
if (use_gmlan) {
if (can == 1) {
@@ -162,7 +197,7 @@ void set_can_mode(int can, bool use_gmlan) {
set_gpio_alternate(GPIOB, 12, GPIO_AF9_CAN2);
set_gpio_alternate(GPIOB, 13, GPIO_AF9_CAN2);
#ifdef CAN3
} else if (can == 2) {
} else if (revision == PANDA_REV_C && can == 2) {
// A8,A15: disable normal mode
set_gpio_mode(GPIOA, 8, MODE_INPUT);
set_gpio_mode(GPIOA, 15, MODE_INPUT);
@@ -183,9 +218,11 @@ void set_can_mode(int can, bool use_gmlan) {
set_gpio_alternate(GPIOB, 6, GPIO_AF9_CAN2);
#ifdef CAN3
} else if (can == 2) {
// B3,B4: disable gmlan mode
set_gpio_mode(GPIOB, 3, MODE_INPUT);
set_gpio_mode(GPIOB, 4, MODE_INPUT);
if(revision == PANDA_REV_C){
// B3,B4: disable gmlan mode
set_gpio_mode(GPIOB, 3, MODE_INPUT);
set_gpio_mode(GPIOB, 4, MODE_INPUT);
}
// A8,A15: normal mode
set_gpio_alternate(GPIOA, 8, GPIO_AF11_CAN3);
set_gpio_alternate(GPIOA, 15, GPIO_AF11_CAN3);
@@ -202,7 +239,6 @@ void set_can_mode(int can, bool use_gmlan) {
int usb_power_mode = USB_POWER_NONE;
void set_usb_power_mode(int mode) {
bool valid_mode = true;
switch (mode) {
case USB_POWER_CLIENT:
// B2,A13: set client mode
@@ -219,15 +255,8 @@ void set_usb_power_mode(int mode) {
set_gpio_output(GPIOB, 2, 0);
set_gpio_output(GPIOA, 13, 0);
break;
default:
valid_mode = false;
puts("Invalid usb power mode\n");
break;
}
if (valid_mode) {
usb_power_mode = mode;
}
usb_power_mode = mode;
}
#define ESP_DISABLED 0
@@ -250,16 +279,13 @@ void set_esp_mode(int mode) {
set_gpio_output(GPIOC, 14, 1);
set_gpio_output(GPIOC, 5, 0);
break;
default:
puts("Invalid esp mode\n");
break;
}
}
// ********************* big init function *********************
// board specific
void gpio_init(void) {
void gpio_init() {
// pull low to hold ESP in reset??
// enable OTG out tied to ground
GPIOA->ODR = 0;
@@ -351,7 +377,11 @@ void gpio_init(void) {
#ifdef PANDA
// K-line enable moved from B4->B7 to make room for GMLAN on CAN3
set_gpio_output(GPIOB, 7, 1); // REV C
if (revision == PANDA_REV_C) {
set_gpio_output(GPIOB, 7, 1); // REV C
} else {
set_gpio_output(GPIOB, 4, 1); // REV AB
}
// C12,D2: K-Line setup on UART 5
set_gpio_alternate(GPIOC, 12, GPIO_AF8_UART5);
@@ -362,12 +392,16 @@ void gpio_init(void) {
set_gpio_output(GPIOA, 14, 1);
// C10,C11: L-Line setup on USART 3
set_gpio_alternate(GPIOC, 10, GPIO_AF7_USART3);
// LLine now used for relay output
set_gpio_output(GPIOC, 10, 1);
//set_gpio_alternate(GPIOC, 10, GPIO_AF7_USART3);
set_gpio_alternate(GPIOC, 11, GPIO_AF7_USART3);
set_gpio_pullup(GPIOC, 11, PULL_UP);
#endif
set_usb_power_mode(USB_POWER_CLIENT);
if (revision == PANDA_REV_C) {
set_usb_power_mode(USB_POWER_CLIENT);
}
}
// ********************* early bringup *********************
@@ -379,7 +413,7 @@ void gpio_init(void) {
extern void *g_pfnVectors;
extern uint32_t enter_bootloader_mode;
void jump_to_bootloader(void) {
void jump_to_bootloader() {
// do enter bootloader
enter_bootloader_mode = 0;
void (*bootloader)(void) = (void (*)(void)) (*((uint32_t *)0x1fff0004));
@@ -392,11 +426,11 @@ void jump_to_bootloader(void) {
NVIC_SystemReset();
}
void early(void) {
void early() {
// after it's been in the bootloader, things are initted differently, so we reset
if ((enter_bootloader_mode != BOOT_NORMAL) &&
(enter_bootloader_mode != ENTER_BOOTLOADER_MAGIC) &&
(enter_bootloader_mode != ENTER_SOFTLOADER_MAGIC)) {
if (enter_bootloader_mode != BOOT_NORMAL &&
enter_bootloader_mode != ENTER_BOOTLOADER_MAGIC &&
enter_bootloader_mode != ENTER_SOFTLOADER_MAGIC) {
enter_bootloader_mode = BOOT_NORMAL;
NVIC_SystemReset();
}
+10 -20
View File
@@ -1,12 +1,12 @@
// **** libc ****
// **** shitty libc ****
void delay(int a) {
volatile int i;
for (i = 0; i < a; i++);
for (i=0;i<a;i++);
}
void *memset(void *str, int c, unsigned int n) {
unsigned int i;
int i;
for (i = 0; i < n; i++) {
*((uint8_t*)str) = c;
++str;
@@ -15,7 +15,7 @@ void *memset(void *str, int c, unsigned int n) {
}
void *memcpy(void *dest, const void *src, unsigned int n) {
unsigned int i;
int i;
// TODO: make not slow
for (i = 0; i < n; i++) {
((uint8_t*)dest)[i] = *(uint8_t*)src;
@@ -25,36 +25,26 @@ void *memcpy(void *dest, const void *src, unsigned int n) {
}
int memcmp(const void * ptr1, const void * ptr2, unsigned int num) {
unsigned int i;
int ret = 0;
int i;
for (i = 0; i < num; i++) {
if ( ((uint8_t*)ptr1)[i] != ((uint8_t*)ptr2)[i] ) {
ret = -1;
break;
}
if ( ((uint8_t*)ptr1)[i] != ((uint8_t*)ptr2)[i] ) return -1;
}
return ret;
return 0;
}
// ********************* IRQ helpers *********************
int interrupts_enabled = 0;
void enable_interrupts(void) {
interrupts_enabled = 1;
__enable_irq();
}
int critical_depth = 0;
void enter_critical_section(void) {
void enter_critical_section() {
__disable_irq();
// this is safe because interrupts are disabled
critical_depth += 1;
}
void exit_critical_section(void) {
void exit_critical_section() {
// this is safe because interrupts are disabled
critical_depth -= 1;
if ((critical_depth == 0) && interrupts_enabled) {
if (critical_depth == 0) {
__enable_irq();
}
}
+275 -302
View File
@@ -1,15 +1,14 @@
//#define EON
#include "config.h"
#include "obj/gitversion.h"
// ********************* includes *********************
#include "libc.h"
#include "safety.h"
#include "provision.h"
#include "drivers/llcan.h"
#include "drivers/drivers.h"
#include "drivers/llgpio.h"
#include "gpio.h"
@@ -17,16 +16,25 @@
#include "drivers/adc.h"
#include "drivers/usb.h"
#include "drivers/gmlan_alt.h"
#include "drivers/timer.h"
#include "drivers/clock.h"
#ifndef EON
#include "drivers/can.h"
#include "drivers/spi.h"
#endif
#include "drivers/timer.h"
#include "power_saving.h"
#include "safety.h"
#include "drivers/can.h"
// ***************************** fan *****************************
void fan_init() {
// timer for fan PWM
TIM3->CCMR2 = TIM_CCMR2_OC3M_2 | TIM_CCMR2_OC3M_1;
TIM3->CCER = TIM_CCER_CC3E;
timer_init(TIM3, 10);
}
void fan_set_speed(int fan_speed) {
TIM3->CCR3 = fan_speed;
}
// ********************* serial debugging *********************
@@ -62,38 +70,6 @@ void debug_ring_callback(uart_ring *ring) {
}
}
// ***************************** started logic *****************************
bool is_gpio_started(void) {
// ignition is on PA1
return (GPIOA->IDR & (1U << 1)) == 0;
}
void EXTI1_IRQHandler(void) {
volatile int pr = EXTI->PR & (1U << 1);
if ((pr & (1U << 1)) != 0) {
#ifdef DEBUG
puts("got started interrupt\n");
#endif
// jenky debounce
delay(100000);
// set power savings mode here
int power_save_state = is_gpio_started() ? POWER_SAVE_STATUS_DISABLED : POWER_SAVE_STATUS_ENABLED;
set_power_save_state(power_save_state);
EXTI->PR = (1U << 1);
}
}
void started_interrupt_init(void) {
SYSCFG->EXTICR[1] = SYSCFG_EXTICR1_EXTI1_PA;
EXTI->IMR |= (1U << 1);
EXTI->RTSR |= (1U << 1);
EXTI->FTSR |= (1U << 1);
NVIC_EnableIRQ(EXTI1_IRQn);
}
// ***************************** USB port *****************************
int get_health_pkt(void *dat) {
@@ -109,25 +85,40 @@ int get_health_pkt(void *dat) {
//Voltage will be measured in mv. 5000 = 5V
uint32_t voltage = adc_get(ADCCHAN_VOLTAGE);
if (revision == PANDA_REV_AB) {
//REVB has a 100, 27 (27/127) voltage divider
//Here is the calculation for the scale
//ADCV = VIN_S * (27/127) * (4095/3.3)
//RETVAL = ADCV * s = VIN_S*1000
//s = 1000/((4095/3.3)*(27/127)) = 3.79053046
// REVC has a 10, 1 (1/11) voltage divider
// Here is the calculation for the scale (s)
// ADCV = VIN_S * (1/11) * (4095/3.3)
// RETVAL = ADCV * s = VIN_S*1000
// s = 1000/((4095/3.3)*(1/11)) = 8.8623046875
//Avoid needing floating point math
health->voltage = (voltage * 3791) / 1000;
} else {
//REVC has a 10, 1 (1/11) voltage divider
//Here is the calculation for the scale (s)
//ADCV = VIN_S * (1/11) * (4095/3.3)
//RETVAL = ADCV * s = VIN_S*1000
//s = 1000/((4095/3.3)*(1/11)) = 8.8623046875
// Avoid needing floating point math
health->voltage = (voltage * 8862) / 1000;
//Avoid needing floating point math
health->voltage = (voltage * 8862) / 1000;
}
#ifdef PANDA
health->current = adc_get(ADCCHAN_CURRENT);
int safety_ignition = safety_ignition_hook();
if (safety_ignition < 0) {
//Use the GPIO pin to determine ignition
health->started = is_gpio_started();
health->started = (GPIOA->IDR & (1 << 1)) == 0;
} else {
//Current safety hooks want to determine ignition (ex: GM)
health->started = safety_ignition;
}
#else
health->current = 0;
health->started = (GPIOC->IDR & (1 << 13)) != 0;
#endif
health->controls_allowed = controls_allowed;
health->gas_interceptor_detected = gas_interceptor_detected;
@@ -139,34 +130,26 @@ int get_health_pkt(void *dat) {
return sizeof(*health);
}
int usb_cb_ep1_in(uint8_t *usbdata, int len, bool hardwired) {
UNUSED(hardwired);
int usb_cb_ep1_in(uint8_t *usbdata, int len, int hardwired) {
CAN_FIFOMailBox_TypeDef *reply = (CAN_FIFOMailBox_TypeDef *)usbdata;
int ilen = 0;
while (ilen < MIN(len/0x10, 4) && can_pop(&can_rx_q, &reply[ilen])) {
ilen++;
}
while (ilen < min(len/0x10, 4) && can_pop(&can_rx_q, &reply[ilen])) ilen++;
return ilen*0x10;
}
// send on serial, first byte to select the ring
void usb_cb_ep2_out(uint8_t *usbdata, int len, bool hardwired) {
UNUSED(hardwired);
void usb_cb_ep2_out(uint8_t *usbdata, int len, int hardwired) {
if (len == 0) return;
uart_ring *ur = get_ring_by_number(usbdata[0]);
if ((len != 0) && (ur != NULL)) {
if ((usbdata[0] < 2) || safety_tx_lin_hook(usbdata[0]-2, usbdata+1, len-1)) {
for (int i = 1; i < len; i++) {
while (!putc(ur, usbdata[i])) {
// wait
}
}
}
if (!ur) return;
if ((usbdata[0] < 2) || safety_tx_lin_hook(usbdata[0]-2, usbdata+1, len-1)) {
if (ur == &esp_ring) power_save_reset_timer();
for (int i = 1; i < len; i++) while (!putc(ur, usbdata[i]));
}
}
// send on CAN
void usb_cb_ep3_out(uint8_t *usbdata, int len, bool hardwired) {
UNUSED(hardwired);
void usb_cb_ep3_out(uint8_t *usbdata, int len, int hardwired) {
int dpkt = 0;
for (dpkt = 0; dpkt < len; dpkt += 0x10) {
uint32_t *tf = (uint32_t*)(&usbdata[dpkt]);
@@ -180,17 +163,25 @@ void usb_cb_ep3_out(uint8_t *usbdata, int len, bool hardwired) {
uint8_t bus_number = (to_push.RDTR >> 4) & CAN_BUS_NUM_MASK;
can_send(&to_push, bus_number);
#ifdef PANDA
// Enable relay on can message if allowed.
// Temporary until OP has support for relay
if (safety_relay_hook()) {
set_lline_output(1);
}
#endif
}
}
bool is_enumerated = 0;
int is_enumerated = 0;
void usb_cb_enumeration_complete() {
puts("USB enumeration complete\n");
is_enumerated = 1;
}
int usb_cb_control_msg(USB_Setup_TypeDef *setup, uint8_t *resp, bool hardwired) {
int usb_cb_control_msg(USB_Setup_TypeDef *setup, uint8_t *resp, int hardwired) {
int resp_len = 0;
uart_ring *ur = NULL;
int i;
@@ -210,14 +201,16 @@ int usb_cb_control_msg(USB_Setup_TypeDef *setup, uint8_t *resp, bool hardwired)
break;
// **** 0xd0: fetch serial number
case 0xd0:
// addresses are OTP
if (setup->b.wValue.w == 1) {
memcpy(resp, (void *)0x1fff79c0, 0x10);
resp_len = 0x10;
} else {
get_provision_chunk(resp);
resp_len = PROVISION_CHUNK_LEN;
}
#ifdef PANDA
// addresses are OTP
if (setup->b.wValue.w == 1) {
memcpy(resp, (void *)0x1fff79c0, 0x10);
resp_len = 0x10;
} else {
get_provision_chunk(resp);
resp_len = PROVISION_CHUNK_LEN;
}
#endif
break;
// **** 0xd1: enter bootloader mode
case 0xd1:
@@ -236,18 +229,19 @@ int usb_cb_control_msg(USB_Setup_TypeDef *setup, uint8_t *resp, bool hardwired)
enter_bootloader_mode = ENTER_SOFTLOADER_MAGIC;
NVIC_SystemReset();
break;
default:
puts("Bootloader mode invalid\n");
break;
}
break;
// **** 0xd2: get health packet
case 0xd2:
resp_len = get_health_pkt(resp);
break;
// **** 0xd3: set fan speed
case 0xd3:
fan_set_speed(setup->b.wValue.w);
break;
// **** 0xd6: get version
case 0xd6:
COMPILE_TIME_ASSERT(sizeof(gitversion) <= MAX_RESP_LEN);
COMPILE_TIME_ASSERT(sizeof(gitversion) <= MAX_RESP_LEN)
memcpy(resp, gitversion, sizeof(gitversion));
resp_len = sizeof(gitversion)-1;
break;
@@ -279,43 +273,44 @@ int usb_cb_control_msg(USB_Setup_TypeDef *setup, uint8_t *resp, bool hardwired)
break;
// **** 0xdb: set GMLAN multiplexing mode
case 0xdb:
if (setup->b.wValue.w == 1) {
// GMLAN ON
if (setup->b.wIndex.w == 1) {
can_set_gmlan(1);
} else if (setup->b.wIndex.w == 2) {
can_set_gmlan(2);
#ifdef PANDA
if (setup->b.wValue.w == 1) {
// GMLAN ON
if (setup->b.wIndex.w == 1) {
can_set_gmlan(1);
} else if (setup->b.wIndex.w == 2) {
// might be ignored on rev b panda
can_set_gmlan(2);
}
} else {
can_set_gmlan(-1);
}
} else {
can_set_gmlan(-1);
}
#endif
break;
// **** 0xdc: set safety mode
case 0xdc:
// this is the only way to leave silent mode
// and it's blocked over WiFi
// Allow ELM security mode to be set over wifi.
if (hardwired || (setup->b.wValue.w == SAFETY_NOOUTPUT) || (setup->b.wValue.w == SAFETY_ELM327)) {
if (hardwired || setup->b.wValue.w == SAFETY_NOOUTPUT || setup->b.wValue.w == SAFETY_ELM327) {
safety_set_mode(setup->b.wValue.w, (int16_t)setup->b.wIndex.w);
if (safety_ignition_hook() != -1) {
// if the ignition hook depends on something other than the started GPIO
// we have to disable power savings (fix for GM and Tesla)
set_power_save_state(POWER_SAVE_STATUS_DISABLED);
switch (setup->b.wValue.w) {
case SAFETY_NOOUTPUT:
can_silent = ALL_CAN_SILENT;
break;
case SAFETY_ELM327:
can_silent = ALL_CAN_BUT_MAIN_SILENT;
can_autobaud_enabled[0] = false;
break;
default:
can_silent = ALL_CAN_LIVE;
can_autobaud_enabled[0] = false;
can_autobaud_enabled[1] = false;
#ifdef PANDA
can_autobaud_enabled[2] = false;
#endif
break;
}
#ifndef EON
// always LIVE on EON
switch (setup->b.wValue.w) {
case SAFETY_NOOUTPUT:
can_silent = ALL_CAN_SILENT;
break;
case SAFETY_ELM327:
can_silent = ALL_CAN_BUT_MAIN_SILENT;
break;
default:
can_silent = ALL_CAN_LIVE;
break;
}
#endif
can_init_all();
}
break;
@@ -323,37 +318,28 @@ int usb_cb_control_msg(USB_Setup_TypeDef *setup, uint8_t *resp, bool hardwired)
case 0xdd:
// wValue = Can Bus Num to forward from
// wIndex = Can Bus Num to forward to
if ((setup->b.wValue.w < BUS_MAX) && (setup->b.wIndex.w < BUS_MAX) &&
(setup->b.wValue.w != setup->b.wIndex.w)) { // set forwarding
if (setup->b.wValue.w < BUS_MAX && setup->b.wIndex.w < BUS_MAX &&
setup->b.wValue.w != setup->b.wIndex.w) { // set forwarding
can_set_forwarding(setup->b.wValue.w, setup->b.wIndex.w & CAN_BUS_NUM_MASK);
} else if((setup->b.wValue.w < BUS_MAX) && (setup->b.wIndex.w == 0xFF)){ //Clear Forwarding
} else if(setup->b.wValue.w < BUS_MAX && setup->b.wIndex.w == 0xFF){ //Clear Forwarding
can_set_forwarding(setup->b.wValue.w, -1);
}
break;
// **** 0xde: set can bitrate
case 0xde:
if (setup->b.wValue.w < BUS_MAX) {
can_autobaud_enabled[setup->b.wValue.w] = false;
can_speed[setup->b.wValue.w] = setup->b.wIndex.w;
can_init(CAN_NUM_FROM_BUS_NUM(setup->b.wValue.w));
}
break;
// **** 0xdf: set long controls allowed
case 0xdf:
if (hardwired) {
long_controls_allowed = setup->b.wValue.w & 1;
}
break;
// **** 0xe0: uart read
case 0xe0:
ur = get_ring_by_number(setup->b.wValue.w);
if (!ur) {
break;
}
if (ur == &esp_ring) {
uart_dma_drain();
}
if (!ur) break;
if (ur == &esp_ring) uart_dma_drain();
// read
while ((resp_len < MIN(setup->b.wLength.w, MAX_RESP_LEN)) &&
while ((resp_len < min(setup->b.wLength.w, MAX_RESP_LEN)) &&
getc(ur, (char*)&resp[resp_len])) {
++resp_len;
}
@@ -361,17 +347,13 @@ int usb_cb_control_msg(USB_Setup_TypeDef *setup, uint8_t *resp, bool hardwired)
// **** 0xe1: uart set baud rate
case 0xe1:
ur = get_ring_by_number(setup->b.wValue.w);
if (!ur) {
break;
}
if (!ur) break;
uart_set_baud(ur->uart, setup->b.wIndex.w);
break;
// **** 0xe2: uart set parity
case 0xe2:
ur = get_ring_by_number(setup->b.wValue.w);
if (!ur) {
break;
}
if (!ur) break;
switch (setup->b.wIndex.w) {
case 0:
// disable parity, 8-bit
@@ -394,9 +376,7 @@ int usb_cb_control_msg(USB_Setup_TypeDef *setup, uint8_t *resp, bool hardwired)
// **** 0xe4: uart set baud rate extended
case 0xe4:
ur = get_ring_by_number(setup->b.wValue.w);
if (!ur) {
break;
}
if (!ur) break;
uart_set_baud(ur->uart, (int)setup->b.wIndex.w*300);
break;
// **** 0xe5: set CAN loopback (for testing)
@@ -406,25 +386,27 @@ int usb_cb_control_msg(USB_Setup_TypeDef *setup, uint8_t *resp, bool hardwired)
break;
// **** 0xe6: set USB power
case 0xe6:
if (setup->b.wValue.w == 1) {
puts("user setting CDP mode\n");
set_usb_power_mode(USB_POWER_CDP);
} else if (setup->b.wValue.w == 2) {
puts("user setting DCP mode\n");
set_usb_power_mode(USB_POWER_DCP);
} else {
puts("user setting CLIENT mode\n");
set_usb_power_mode(USB_POWER_CLIENT);
if (revision == PANDA_REV_C) {
if (setup->b.wValue.w == 1) {
puts("user setting CDP mode\n");
set_usb_power_mode(USB_POWER_CDP);
} else if (setup->b.wValue.w == 2) {
puts("user setting DCP mode\n");
set_usb_power_mode(USB_POWER_DCP);
} else {
puts("user setting CLIENT mode\n");
set_usb_power_mode(USB_POWER_CLIENT);
}
}
break;
// **** 0xf0: do k-line wValue pulse on uart2 for Acura
case 0xf0:
if (setup->b.wValue.w == 1) {
GPIOC->ODR &= ~(1U << 10);
GPIOC->ODR &= ~(1 << 10);
GPIOC->MODER &= ~GPIO_MODER_MODER10_1;
GPIOC->MODER |= GPIO_MODER_MODER10_0;
} else {
GPIOC->ODR &= ~(1U << 12);
GPIOC->ODR &= ~(1 << 12);
GPIOC->MODER &= ~GPIO_MODER_MODER12_1;
GPIOC->MODER |= GPIO_MODER_MODER12_0;
}
@@ -432,11 +414,11 @@ int usb_cb_control_msg(USB_Setup_TypeDef *setup, uint8_t *resp, bool hardwired)
for (i = 0; i < 80; i++) {
delay(8000);
if (setup->b.wValue.w == 1) {
GPIOC->ODR |= (1U << 10);
GPIOC->ODR &= ~(1U << 10);
GPIOC->ODR |= (1 << 10);
GPIOC->ODR &= ~(1 << 10);
} else {
GPIOC->ODR |= (1U << 12);
GPIOC->ODR &= ~(1U << 12);
GPIOC->ODR |= (1 << 12);
GPIOC->ODR &= ~(1 << 12);
}
}
@@ -464,12 +446,22 @@ int usb_cb_control_msg(USB_Setup_TypeDef *setup, uint8_t *resp, bool hardwired)
case 0xf2:
{
uart_ring * rb = get_ring_by_number(setup->b.wValue.w);
if (rb != NULL) {
if (rb) {
puts("Clearing UART queue.\n");
clear_uart_buff(rb);
}
break;
}
// **** 0xf3: set l-line relay
case 0xf3:
{
#ifdef PANDA
if (safety_relay_hook()) {
set_lline_output(setup->b.wValue.w == 1);
}
#endif
break;
}
default:
puts("NO HANDLER ");
puth(setup->b.bRequest);
@@ -479,11 +471,12 @@ int usb_cb_control_msg(USB_Setup_TypeDef *setup, uint8_t *resp, bool hardwired)
return resp_len;
}
#ifdef PANDA
int spi_cb_rx(uint8_t *data, int len, uint8_t *data_out) {
// data[0] = endpoint
// data[2] = length
// data[4:] = data
UNUSED(len);
int resp_len = 0;
switch (data[0]) {
case 0:
@@ -502,122 +495,29 @@ int spi_cb_rx(uint8_t *data, int len, uint8_t *data_out) {
// ep 3, send CAN
usb_cb_ep3_out(data+4, data[2], 0);
break;
default:
puts("SPI data invalid");
break;
}
return resp_len;
}
#else
int spi_cb_rx(uint8_t *data, int len, uint8_t *data_out) { return 0; };
#endif
// ***************************** main code *****************************
void __initialize_hardware_early(void) {
void __initialize_hardware_early() {
early();
}
void __attribute__ ((noinline)) enable_fpu(void) {
void __attribute__ ((noinline)) enable_fpu() {
// enable the FPU
SCB->CPACR |= ((3UL << (10U * 2)) | (3UL << (11U * 2)));
SCB->CPACR |= ((3UL << 10*2) | (3UL << 11*2));
}
uint64_t tcnt = 0;
uint64_t marker = 0;
// called once per second
void TIM3_IRQHandler(void) {
#define CURRENT_THRESHOLD 0xF00
#define CLICKS 5 // 5 seconds to switch modes
if (TIM3->SR != 0) {
can_live = pending_can_live;
//puth(usart1_dma); puts(" "); puth(DMA2_Stream5->M0AR); puts(" "); puth(DMA2_Stream5->NDTR); puts("\n");
uint32_t current = adc_get(ADCCHAN_CURRENT);
switch (usb_power_mode) {
case USB_POWER_CLIENT:
if ((tcnt-marker) >= CLICKS) {
if (!is_enumerated) {
puts("USBP: didn't enumerate, switching to CDP mode\n");
// switch to CDP
set_usb_power_mode(USB_POWER_CDP);
marker = tcnt;
}
}
// keep resetting the timer if it's enumerated
if (is_enumerated) {
marker = tcnt;
}
break;
case USB_POWER_CDP:
// On the EON, if we get into CDP mode we stay here. No need to go to DCP.
#ifndef EON
// been CLICKS clicks since we switched to CDP
if ((tcnt-marker) >= CLICKS) {
// measure current draw, if positive and no enumeration, switch to DCP
if (!is_enumerated && (current < CURRENT_THRESHOLD)) {
puts("USBP: no enumeration with current draw, switching to DCP mode\n");
set_usb_power_mode(USB_POWER_DCP);
marker = tcnt;
}
}
// keep resetting the timer if there's no current draw in CDP
if (current >= CURRENT_THRESHOLD) {
marker = tcnt;
}
#endif
break;
case USB_POWER_DCP:
// been at least CLICKS clicks since we switched to DCP
if ((tcnt-marker) >= CLICKS) {
// if no current draw, switch back to CDP
if (current >= CURRENT_THRESHOLD) {
puts("USBP: no current draw, switching back to CDP mode\n");
set_usb_power_mode(USB_POWER_CDP);
marker = tcnt;
}
}
// keep resetting the timer if there's current draw in DCP
if (current < CURRENT_THRESHOLD) {
marker = tcnt;
}
break;
default:
puts("USB power mode invalid\n"); // set_usb_power_mode prevents assigning invalid values
break;
}
// ~0x9a = 500 ma
/*puth(current);
puts("\n");*/
// reset this every 16th pass
if ((tcnt&0xF) == 0) {
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
// set green LED to be controls allowed
set_led(LED_GREEN, controls_allowed);
// turn off the blue LED, turned on by CAN
// unless we are in power saving mode
set_led(LED_BLUE, (tcnt & 1) && (power_save_status == POWER_SAVE_STATUS_ENABLED));
// on to the next one
tcnt += 1;
}
TIM3->SR = 0;
}
int main(void) {
int main() {
// shouldn't have interrupts here, but just in case
__disable_irq();
@@ -631,21 +531,21 @@ int main(void) {
// detect the revision and init the GPIOs
puts("config:\n");
puts((revision == PANDA_REV_C) ? " panda rev c\n" : " panda rev a or b\n");
#ifdef PANDA
puts(revision == PANDA_REV_C ? " panda rev c\n" : " panda rev a or b\n");
#else
puts(" legacy\n");
#endif
puts(has_external_debug_serial ? " real serial\n" : " USB serial\n");
puts(is_giant_panda ? " GIANTpanda detected\n" : " not GIANTpanda\n");
puts(is_grey_panda ? " gray panda detected!\n" : " white panda\n");
puts(is_entering_bootmode ? " ESP wants bootmode\n" : " no bootmode\n");
// non rev c panda are no longer supported
while (revision != PANDA_REV_C) {
// hang
}
gpio_init();
#ifdef PANDA
// panda has an FPU, let's use it!
enable_fpu();
#endif
// enable main uart if it's connected
if (has_external_debug_serial) {
@@ -654,18 +554,22 @@ int main(void) {
uart_init(USART2, 115200);
}
#ifdef PANDA
if (is_grey_panda) {
uart_init(USART1, 9600);
} else {
// enable ESP uart
uart_init(USART1, 115200);
#ifdef EON
set_esp_mode(ESP_DISABLED);
#endif
}
// enable LIN
uart_init(UART5, 10400);
UART5->CR2 |= USART_CR2_LINEN;
uart_init(USART3, 10400);
USART3->CR2 |= USART_CR2_LINEN;
#endif
// init microsecond system timer
// increments 1000000 times per second
@@ -681,67 +585,136 @@ int main(void) {
// default to silent mode to prevent issues with Ford
// hardcode a specific safety mode if you want to force the panda to be in a specific mode
safety_set_mode(SAFETY_NOOUTPUT, 0);
#ifdef EON
// if we're on an EON, it's fine for CAN to be live for fingerprinting
can_silent = ALL_CAN_LIVE;
#else
can_silent = ALL_CAN_SILENT;
#endif
can_init_all();
adc_init();
#ifndef EON
#ifdef PANDA
spi_init();
#endif
#ifdef EON
// have to save power
if (!is_grey_panda) {
set_esp_mode(ESP_DISABLED);
}
// only enter power save after the first cycle
/*if (is_gpio_started()) {
set_power_save_state(POWER_SAVE_STATUS_ENABLED);
}*/
// interrupt on started line
started_interrupt_init();
#endif
// 48mhz / 65536 ~= 732 / 732 = 1
timer_init(TIM3, 732);
NVIC_EnableIRQ(TIM3_IRQn);
#ifdef DEBUG
puts("DEBUG ENABLED\n");
#endif
// set PWM
fan_init();
fan_set_speed(0);
puts("**** INTERRUPTS ON ****\n");
enable_interrupts();
__enable_irq();
power_save_init();
// if the error interrupt is enabled to quickly when the CAN bus is active
// something bad happens and you can't connect to the device over USB
delay(10000000);
CAN1->IER |= CAN_IER_ERRIE | CAN_IER_LECIE;
// LED should keep on blinking all the time
uint64_t cnt = 0;
for (cnt=0;;cnt++) {
if (power_save_status == POWER_SAVE_STATUS_DISABLED) {
int div_mode = ((usb_power_mode == USB_POWER_DCP) ? 4 : 1);
#ifdef PANDA
uint64_t marker = 0;
#define CURRENT_THRESHOLD 0xF00
#define CLICKS 8
#endif
// useful for debugging, fade breaks = panda is overloaded
for (int div_mode_loop = 0; div_mode_loop < div_mode; div_mode_loop++) {
for (int fade = 0; fade < 1024; fade += 8) {
for (int i = 0; i < (128/div_mode); i++) {
set_led(LED_RED, 1);
if (fade < 512) { delay(fade); } else { delay(1024-fade); }
set_led(LED_RED, 0);
if (fade < 512) { delay(512-fade); } else { delay(fade-512); }
for (cnt=0;;cnt++) {
can_live = pending_can_live;
//puth(usart1_dma); puts(" "); puth(DMA2_Stream5->M0AR); puts(" "); puth(DMA2_Stream5->NDTR); puts("\n");
#ifdef PANDA
uint32_t current = adc_get(ADCCHAN_CURRENT);
switch (usb_power_mode) {
case USB_POWER_CLIENT:
if ((cnt-marker) >= CLICKS) {
if (!is_enumerated) {
puts("USBP: didn't enumerate, switching to CDP mode\n");
// switch to CDP
set_usb_power_mode(USB_POWER_CDP);
marker = cnt;
}
}
// keep resetting the timer if it's enumerated
if (is_enumerated) {
marker = cnt;
}
break;
case USB_POWER_CDP:
#ifndef EON
// been CLICKS clicks since we switched to CDP
if ((cnt-marker) >= CLICKS) {
// measure current draw, if positive and no enumeration, switch to DCP
if (!is_enumerated && current < CURRENT_THRESHOLD) {
puts("USBP: no enumeration with current draw, switching to DCP mode\n");
set_usb_power_mode(USB_POWER_DCP);
marker = cnt;
}
}
// keep resetting the timer if there's no current draw in CDP
if (current >= CURRENT_THRESHOLD) {
marker = cnt;
}
#endif
break;
case USB_POWER_DCP:
// been at least CLICKS clicks since we switched to DCP
if ((cnt-marker) >= CLICKS) {
// if no current draw, switch back to CDP
if (current >= CURRENT_THRESHOLD) {
puts("USBP: no current draw, switching back to CDP mode\n");
set_usb_power_mode(USB_POWER_CDP);
marker = cnt;
}
}
// keep resetting the timer if there's current draw in DCP
if (current < CURRENT_THRESHOLD) {
marker = cnt;
}
break;
}
// ~0x9a = 500 ma
/*puth(current);
puts("\n");*/
#endif
// reset this every 16th pass
if ((cnt&0xF) == 0) 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
// set green LED to be controls allowed
set_led(LED_GREEN, controls_allowed);
// blink the red LED
int div_mode = ((usb_power_mode == USB_POWER_DCP) ? 4 : 1);
for (int div_mode_loop = 0; div_mode_loop < div_mode; div_mode_loop++) {
for (int fade = 0; fade < 1024; fade += 8) {
for (int i = 0; i < 128/div_mode; i++) {
set_led(LED_RED, 0);
if (fade < 512) { delay(512-fade); } else { delay(fade-512); }
set_led(LED_RED, 1);
if (fade < 512) { delay(fade); } else { delay(1024-fade); }
}
}
} else {
__WFI();
}
// turn off the blue LED, turned on by CAN
#ifdef PANDA
set_led(LED_BLUE, 0);
#endif
}
return 0;
}
+35 -25
View File
@@ -1,26 +1,29 @@
//#define DEBUG
//#define CAN_LOOPBACK_MODE
//#define USE_INTERNAL_OSC
#include "../config.h"
#include "drivers/llcan.h"
#include "drivers/drivers.h"
#include "drivers/llgpio.h"
#include "drivers/clock.h"
#include "drivers/adc.h"
#include "drivers/dac.h"
#include "drivers/timer.h"
#include "gpio.h"
#define CUSTOM_CAN_INTERRUPTS
#include "libc.h"
#include "safety.h"
#include "drivers/adc.h"
#include "drivers/uart.h"
#include "drivers/dac.h"
#include "drivers/can.h"
#include "drivers/timer.h"
#define CAN CAN1
//#define PEDAL_USB
#ifdef PEDAL_USB
#include "drivers/uart.h"
#include "drivers/usb.h"
#else
// no serial either
void puts(const char *a) {}
void puth(unsigned int i) {}
#endif
#define ENTER_BOOTLOADER_MAGIC 0xdeadbeef
@@ -32,8 +35,6 @@ void __initialize_hardware_early() {
// ********************* serial debugging *********************
#ifdef PEDAL_USB
void debug_ring_callback(uart_ring *ring) {
char rcv;
while (getc(ring, &rcv)) {
@@ -41,12 +42,14 @@ void debug_ring_callback(uart_ring *ring) {
}
}
int usb_cb_ep1_in(uint8_t *usbdata, int len, bool hardwired) { return 0; }
void usb_cb_ep2_out(uint8_t *usbdata, int len, bool hardwired) {}
void usb_cb_ep3_out(uint8_t *usbdata, int len, bool hardwired) {}
#ifdef PEDAL_USB
int usb_cb_ep1_in(uint8_t *usbdata, int len, int hardwired) { return 0; }
void usb_cb_ep2_out(uint8_t *usbdata, int len, int hardwired) {}
void usb_cb_ep3_out(uint8_t *usbdata, int len, int hardwired) {}
void usb_cb_enumeration_complete() {}
int usb_cb_control_msg(USB_Setup_TypeDef *setup, uint8_t *resp, bool hardwired) {
int usb_cb_control_msg(USB_Setup_TypeDef *setup, uint8_t *resp, int hardwired) {
int resp_len = 0;
uart_ring *ur = NULL;
switch (setup->b.bRequest) {
@@ -56,7 +59,7 @@ int usb_cb_control_msg(USB_Setup_TypeDef *setup, uint8_t *resp, bool hardwired)
if (!ur) break;
if (ur == &esp_ring) uart_dma_drain();
// read
while ((resp_len < MIN(setup->b.wLength.w, MAX_RESP_LEN)) &&
while ((resp_len < min(setup->b.wLength.w, MAX_RESP_LEN)) &&
getc(ur, (char*)&resp[resp_len])) {
++resp_len;
}
@@ -182,7 +185,7 @@ void CAN1_RX0_IRQHandler() {
void CAN1_SCE_IRQHandler() {
state = FAULT_SCE;
llcan_clear_send(CAN);
can_sce(CAN);
}
int pdl0 = 0, pdl1 = 0;
@@ -246,14 +249,15 @@ void pedal() {
// write the pedal to the DAC
if (state == NO_FAULT) {
dac_set(0, MAX(gas_set_0, pdl0));
dac_set(1, MAX(gas_set_1, pdl1));
dac_set(0, max(gas_set_0, pdl0));
dac_set(1, max(gas_set_1, pdl1));
} else {
dac_set(0, pdl0);
dac_set(1, pdl1);
}
watchdog_feed();
// feed the watchdog
IWDG->KR = 0xAAAA;
}
int main() {
@@ -274,18 +278,24 @@ int main() {
adc_init();
// init can
llcan_set_speed(CAN1, 5000, false, false);
llcan_init(CAN1);
can_silent = ALL_CAN_LIVE;
can_init(0);
// 48mhz / 65536 ~= 732
timer_init(TIM3, 15);
NVIC_EnableIRQ(TIM3_IRQn);
watchdog_init();
// setup watchdog
IWDG->KR = 0x5555;
IWDG->PR = 0; // divider /4
// 0 = 0.125 ms, let's have a 50ms watchdog
IWDG->RLR = 400 - 1;
IWDG->KR = 0xCCCC;
puts("**** INTERRUPTS ON ****\n");
__enable_irq();
// main pedal loop
while (1) {
pedal();
+147 -33
View File
@@ -1,43 +1,157 @@
#define POWER_SAVE_STATUS_DISABLED 0
#define POWER_SAVE_STATUS_ENABLED 1
//Moving to enabled, but can wakeup not yet enabled
#define POWER_SAVE_STATUS_SWITCHING 1
#define POWER_SAVE_STATUS_ENABLED 2
int power_save_status = POWER_SAVE_STATUS_DISABLED;
volatile int power_save_status = POWER_SAVE_STATUS_DISABLED;
void set_power_save_state(int state) {
void power_save_enable(void) {
power_save_status = POWER_SAVE_STATUS_SWITCHING;
puts("Saving power\n");
//Turn off can transciever
set_can_enable(CAN1, 0);
set_can_enable(CAN2, 0);
#ifdef PANDA
set_can_enable(CAN3, 0);
#endif
bool is_valid_state = (state == POWER_SAVE_STATUS_ENABLED) || (state == POWER_SAVE_STATUS_DISABLED);
if (is_valid_state && (state != power_save_status)) {
bool enable = false;
if (state == POWER_SAVE_STATUS_ENABLED) {
puts("enable power savings\n");
if (is_grey_panda) {
char UBLOX_SLEEP_MSG[] = "\xb5\x62\x06\x04\x04\x00\x01\x00\x08\x00\x17\x78";
uart_ring *ur = get_ring_by_number(1);
for (unsigned int i = 0; i < sizeof(UBLOX_SLEEP_MSG) - 1; i++) while (!putc(ur, UBLOX_SLEEP_MSG[i]));
}
} else {
puts("disable power savings\n");
if (is_grey_panda) {
char UBLOX_WAKE_MSG[] = "\xb5\x62\x06\x04\x04\x00\x01\x00\x09\x00\x18\x7a";
uart_ring *ur = get_ring_by_number(1);
for (unsigned int i = 0; i < sizeof(UBLOX_WAKE_MSG) - 1; i++) while (!putc(ur, UBLOX_WAKE_MSG[i]));
}
enable = true;
}
//Turn off GMLAN
set_gpio_output(GPIOB, 14, 0);
set_gpio_output(GPIOB, 15, 0);
// turn on can
set_can_enable(CAN1, enable);
set_can_enable(CAN2, enable);
set_can_enable(CAN3, enable);
#ifdef PANDA
//Turn off LIN K
if (revision == PANDA_REV_C) {
set_gpio_output(GPIOB, 7, 0); // REV C
} else {
set_gpio_output(GPIOB, 4, 0); // REV AB
}
// LIN L
set_gpio_output(GPIOA, 14, 0);
#endif
// turn on GMLAN
set_gpio_output(GPIOB, 14, enable);
set_gpio_output(GPIOB, 15, enable);
if (is_grey_panda) {
char* UBLOX_SLEEP_MSG = "\xb5\x62\x06\x04\x04\x00\x01\x00\x08\x00\x17\x78";
int len = 12;
uart_ring *ur = get_ring_by_number(1);
for (int i = 0; i < len; i++) while (!putc(ur, UBLOX_SLEEP_MSG[i]));
}
// turn on LIN
set_gpio_output(GPIOB, 7, enable);
set_gpio_output(GPIOA, 14, enable);
//Setup timer for can enable
TIM6->PSC = 48-1; // tick on 1 us
power_save_status = state;
TIM6->ARR = 12; // 12us
// Enable, One-Pulse Mode, Only overflow interrupt
TIM6->CR1 = TIM_CR1_CEN | TIM_CR1_OPM | TIM_CR1_URS;
TIM6->EGR = TIM_EGR_UG;
TIM6->CR1 |= TIM_CR1_CEN;
}
void power_save_enable_can_wake(void) {
// CAN Automatic Wake must be done a little while after the sleep
// On some cars turning off the can transciver can trigger the wakeup
power_save_status = POWER_SAVE_STATUS_ENABLED;
puts("Turning can off\n");
CAN1->MCR |= CAN_MCR_SLEEP;
CAN1->MCR |= CAN_MCR_AWUM;
CAN2->MCR |= CAN_MCR_SLEEP;
CAN2->MCR |= CAN_MCR_AWUM;
#ifdef PANDA
CAN3->MCR |= CAN_MCR_SLEEP;
CAN3->MCR |= CAN_MCR_AWUM;
#endif
//set timer back
TIM6->PSC = 48000-1; // tick on 1 ms
TIM6->ARR = 10000; // 10s
// Enable, One-Pulse Mode, Only overflow interrupt
TIM6->CR1 = TIM_CR1_OPM | TIM_CR1_URS;
TIM6->EGR = TIM_EGR_UG;
}
void power_save_disable(void) {
power_save_status = POWER_SAVE_STATUS_DISABLED;
puts("not Saving power\n");
TIM6->CR1 |= TIM_CR1_CEN; //Restart timer
TIM6->CNT = 0;
//Turn on can
set_can_enable(CAN1, 1);
set_can_enable(CAN2, 1);
#ifdef PANDA
set_can_enable(CAN3, 1);
#endif
//Turn on GMLAN
set_gpio_output(GPIOB, 14, 1);
set_gpio_output(GPIOB, 15, 1);
#ifdef PANDA
//Turn on LIN K
if (revision == PANDA_REV_C) {
set_gpio_output(GPIOB, 7, 1); // REV C
} else {
set_gpio_output(GPIOB, 4, 1); // REV AB
}
// LIN L
set_gpio_output(GPIOA, 14, 1);
#endif
if (is_grey_panda) {
char* UBLOX_WAKE_MSG = "\xb5\x62\x06\x04\x04\x00\x01\x00\x09\x00\x18\x7a";
int len = 12;
uart_ring *ur = get_ring_by_number(1);
for (int i = 0; i < len; i++) while (!putc(ur, UBLOX_WAKE_MSG[i]));
}
//set timer back
TIM6->PSC = 48000-1; // tick on 1 ms
TIM6->ARR = 10000; // 10s
// Enable, One-Pulse Mode, Only overflow interrupt
TIM6->CR1 = TIM_CR1_CEN | TIM_CR1_OPM | TIM_CR1_URS;
TIM6->EGR = TIM_EGR_UG;
TIM6->CR1 |= TIM_CR1_CEN;
}
// Reset timer when activity
void power_save_reset_timer() {
TIM6->CNT = 0;
if (power_save_status != POWER_SAVE_STATUS_DISABLED){
power_save_disable();
}
}
void power_save_init(void) {
puts("Saving power init\n");
TIM6->PSC = 48000-1; // tick on 1 ms
TIM6->ARR = 10000; // 10s
// Enable, One-Pulse Mode, Only overflow interrupt
TIM6->CR1 = TIM_CR1_CEN | TIM_CR1_OPM | TIM_CR1_URS;
TIM6->EGR = TIM_EGR_UG;
NVIC_EnableIRQ(TIM6_DAC_IRQn);
puts("Saving power init done\n");
TIM6->DIER = TIM_DIER_UIE;
TIM6->CR1 |= TIM_CR1_CEN;
}
void TIM6_DAC_IRQHandler(void) {
//Timeout switch to power saving mode.
if (TIM6->SR & TIM_SR_UIF) {
TIM6->SR = 0;
#ifdef EON
if (power_save_status == POWER_SAVE_STATUS_DISABLED) {
power_save_enable();
} else if (power_save_status == POWER_SAVE_STATUS_SWITCHING) {
power_save_enable_can_wake();
}
#endif
} else {
TIM6->CR1 |= TIM_CR1_CEN;
}
}
+112 -60
View File
@@ -1,12 +1,70 @@
// include first, needed by safety policies
#include "safety_declarations.h"
// sample struct that keeps 3 samples in memory
struct sample_t {
int values[6];
int min;
int max;
} sample_t_default = {{0}, 0, 0};
// no float support in STM32F2 micros (cortex-m3)
#ifdef PANDA
struct lookup_t {
float x[3];
float y[3];
};
#endif
void safety_rx_hook(CAN_FIFOMailBox_TypeDef *to_push);
int safety_tx_hook(CAN_FIFOMailBox_TypeDef *to_send);
int safety_tx_lin_hook(int lin_num, uint8_t *data, int len);
int safety_ignition_hook();
uint32_t get_ts_elapsed(uint32_t ts, uint32_t ts_last);
int to_signed(int d, int bits);
void update_sample(struct sample_t *sample, int sample_new);
int max_limit_check(int val, const int MAX, const int MIN);
int dist_to_meas_check(int val, int val_last, struct sample_t *val_meas,
const int MAX_RATE_UP, const int MAX_RATE_DOWN, const int MAX_ERROR);
int driver_limit_check(int val, int val_last, struct sample_t *val_driver,
const int MAX, const int MAX_RATE_UP, const int MAX_RATE_DOWN,
const int MAX_ALLOWANCE, const int DRIVER_FACTOR);
int rt_rate_limit_check(int val, int val_last, const int MAX_RT_DELTA);
#ifdef PANDA
float interpolate(struct lookup_t xy, float x);
void lline_relay_init (void);
void lline_relay_release (void);
void set_lline_output(int to_set);
#endif
typedef void (*safety_hook_init)(int16_t param);
typedef void (*rx_hook)(CAN_FIFOMailBox_TypeDef *to_push);
typedef int (*tx_hook)(CAN_FIFOMailBox_TypeDef *to_send);
typedef int (*tx_lin_hook)(int lin_num, uint8_t *data, int len);
typedef int (*ign_hook)();
typedef int (*fwd_hook)(int bus_num, CAN_FIFOMailBox_TypeDef *to_fwd);
typedef int (*relay_hook)();
typedef struct {
safety_hook_init init;
ign_hook ignition;
rx_hook rx;
tx_hook tx;
tx_lin_hook tx_lin;
fwd_hook fwd;
relay_hook relay;
} safety_hooks;
// This can be set by the safety hooks.
int controls_allowed = 0;
// Include the actual safety policies.
#include "safety/safety_defaults.h"
#include "safety/safety_honda.h"
#include "safety/safety_toyota.h"
#ifdef PANDA
#include "safety/safety_toyota_ipas.h"
#include "safety/safety_tesla.h"
#include "safety/safety_gm_ascm.h"
#endif
#include "safety/safety_gm.h"
#include "safety/safety_ford.h"
#include "safety/safety_cadillac.h"
@@ -39,6 +97,10 @@ int safety_fwd_hook(int bus_num, CAN_FIFOMailBox_TypeDef *to_fwd) {
return current_hooks->fwd(bus_num, to_fwd);
}
int safety_relay_hook(void) {
return current_hooks->relay();
}
typedef struct {
uint16_t id;
const safety_hooks *hooks;
@@ -57,6 +119,7 @@ typedef struct {
#define SAFETY_SUBARU 10
#define SAFETY_GM_ASCM 0x1334
#define SAFETY_TOYOTA_IPAS 0x1335
#define SAFETY_TOYOTA_NOLIMITS 0x1336
#define SAFETY_ALLOUTPUT 0x1337
#define SAFETY_ELM327 0xE327
@@ -71,101 +134,93 @@ const safety_hook_config safety_hook_registry[] = {
{SAFETY_HYUNDAI, &hyundai_hooks},
{SAFETY_CHRYSLER, &chrysler_hooks},
{SAFETY_SUBARU, &subaru_hooks},
{SAFETY_TOYOTA_NOLIMITS, &toyota_nolimits_hooks},
#ifdef PANDA
{SAFETY_TOYOTA_IPAS, &toyota_ipas_hooks},
{SAFETY_GM_ASCM, &gm_ascm_hooks},
{SAFETY_TESLA, &tesla_hooks},
#endif
{SAFETY_ALLOUTPUT, &alloutput_hooks},
{SAFETY_ELM327, &elm327_hooks},
};
#define HOOK_CONFIG_COUNT (sizeof(safety_hook_registry)/sizeof(safety_hook_config))
int safety_set_mode(uint16_t mode, int16_t param) {
int set_status = -1; // not set
int hook_config_count = sizeof(safety_hook_registry) / sizeof(safety_hook_config);
for (int i = 0; i < hook_config_count; i++) {
for (int i = 0; i < HOOK_CONFIG_COUNT; i++) {
if (safety_hook_registry[i].id == mode) {
current_hooks = safety_hook_registry[i].hooks;
set_status = 0; // set
break;
if (current_hooks->init) current_hooks->init(param);
return 0;
}
}
if ((set_status == 0) && (current_hooks->init != NULL)) {
current_hooks->init(param);
}
return set_status;
return -1;
}
// compute the time elapsed (in microseconds) from 2 counter samples
// case where ts < ts_last is ok: overflow is properly re-casted into uint32_t
uint32_t get_ts_elapsed(uint32_t ts, uint32_t ts_last) {
return ts - ts_last;
return ts > ts_last ? ts - ts_last : (0xFFFFFFFF - ts_last) + 1 + ts;
}
// convert a trimmed integer to signed 32 bit int
int to_signed(int d, int bits) {
int d_signed = d;
if (d >= (1 << MAX((bits - 1), 0))) {
d_signed = d - (1 << MAX(bits, 0));
if (d >= (1 << (bits - 1))) {
d -= (1 << bits);
}
return d_signed;
return d;
}
// given a new sample, update the smaple_t struct
void update_sample(struct sample_t *sample, int sample_new) {
int sample_size = sizeof(sample->values) / sizeof(sample->values[0]);
for (int i = sample_size - 1; i > 0; i--) {
for (int i = sizeof(sample->values)/sizeof(sample->values[0]) - 1; i > 0; i--) {
sample->values[i] = sample->values[i-1];
}
sample->values[0] = sample_new;
// get the minimum and maximum measured samples
sample->min = sample->values[0];
sample->max = sample->values[0];
for (int i = 1; i < sample_size; i++) {
if (sample->values[i] < sample->min) {
sample->min = sample->values[i];
}
if (sample->values[i] > sample->max) {
sample->max = sample->values[i];
}
sample->min = sample->max = sample->values[0];
for (int i = 1; i < sizeof(sample->values)/sizeof(sample->values[0]); i++) {
if (sample->values[i] < sample->min) sample->min = sample->values[i];
if (sample->values[i] > sample->max) sample->max = sample->values[i];
}
}
bool max_limit_check(int val, const int MAX_VAL, const int MIN_VAL) {
return (val > MAX_VAL) || (val < MIN_VAL);
int max_limit_check(int val, const int MAX, const int MIN) {
return (val > MAX) || (val < MIN);
}
// check that commanded value isn't too far from measured
bool dist_to_meas_check(int val, int val_last, struct sample_t *val_meas,
int dist_to_meas_check(int val, int val_last, struct sample_t *val_meas,
const int MAX_RATE_UP, const int MAX_RATE_DOWN, const int MAX_ERROR) {
// *** val rate limit check ***
int highest_allowed_rl = MAX(val_last, 0) + MAX_RATE_UP;
int lowest_allowed_rl = MIN(val_last, 0) - MAX_RATE_UP;
int highest_allowed_val = max(val_last, 0) + MAX_RATE_UP;
int lowest_allowed_val = min(val_last, 0) - MAX_RATE_UP;
// if we've exceeded the meas val, we must start moving toward 0
int highest_allowed = MIN(highest_allowed_rl, MAX(val_last - MAX_RATE_DOWN, MAX(val_meas->max, 0) + MAX_ERROR));
int lowest_allowed = MAX(lowest_allowed_rl, MIN(val_last + MAX_RATE_DOWN, MIN(val_meas->min, 0) - MAX_ERROR));
highest_allowed_val = min(highest_allowed_val, max(val_last - MAX_RATE_DOWN, max(val_meas->max, 0) + MAX_ERROR));
lowest_allowed_val = max(lowest_allowed_val, min(val_last + MAX_RATE_DOWN, min(val_meas->min, 0) - MAX_ERROR));
// check for violation
return (val < lowest_allowed) || (val > highest_allowed);
return (val < lowest_allowed_val) || (val > highest_allowed_val);
}
// check that commanded value isn't fighting against driver
bool driver_limit_check(int val, int val_last, struct sample_t *val_driver,
const int MAX_VAL, const int MAX_RATE_UP, const int MAX_RATE_DOWN,
int driver_limit_check(int val, int val_last, struct sample_t *val_driver,
const int MAX, const int MAX_RATE_UP, const int MAX_RATE_DOWN,
const int MAX_ALLOWANCE, const int DRIVER_FACTOR) {
int highest_allowed_rl = MAX(val_last, 0) + MAX_RATE_UP;
int lowest_allowed_rl = MIN(val_last, 0) - MAX_RATE_UP;
int highest_allowed = max(val_last, 0) + MAX_RATE_UP;
int lowest_allowed = min(val_last, 0) - MAX_RATE_UP;
int driver_max_limit = MAX_VAL + (MAX_ALLOWANCE + val_driver->max) * DRIVER_FACTOR;
int driver_min_limit = -MAX_VAL + (-MAX_ALLOWANCE + val_driver->min) * DRIVER_FACTOR;
int driver_max_limit = MAX + (MAX_ALLOWANCE + val_driver->max) * DRIVER_FACTOR;
int driver_min_limit = -MAX + (-MAX_ALLOWANCE + val_driver->min) * DRIVER_FACTOR;
// if we've exceeded the applied torque, we must start moving toward 0
int highest_allowed = MIN(highest_allowed_rl, MAX(val_last - MAX_RATE_DOWN,
MAX(driver_max_limit, 0)));
int lowest_allowed = MAX(lowest_allowed_rl, MIN(val_last + MAX_RATE_DOWN,
MIN(driver_min_limit, 0)));
highest_allowed = min(highest_allowed, max(val_last - MAX_RATE_DOWN,
max(driver_max_limit, 0)));
lowest_allowed = max(lowest_allowed, min(val_last + MAX_RATE_DOWN,
min(driver_min_limit, 0)));
// check for violation
return (val < lowest_allowed) || (val > highest_allowed);
@@ -173,43 +228,40 @@ bool driver_limit_check(int val, int val_last, struct sample_t *val_driver,
// real time check, mainly used for steer torque rate limiter
bool rt_rate_limit_check(int val, int val_last, const int MAX_RT_DELTA) {
int rt_rate_limit_check(int val, int val_last, const int MAX_RT_DELTA) {
// *** torque real time rate limit check ***
int highest_val = MAX(val_last, 0) + MAX_RT_DELTA;
int lowest_val = MIN(val_last, 0) - MAX_RT_DELTA;
int highest_val = max(val_last, 0) + MAX_RT_DELTA;
int lowest_val = min(val_last, 0) - MAX_RT_DELTA;
// check for violation
return (val < lowest_val) || (val > highest_val);
}
#ifdef PANDA
// interp function that holds extreme values
float interpolate(struct lookup_t xy, float x) {
int size = sizeof(xy.x) / sizeof(xy.x[0]);
float ret = xy.y[size - 1]; // default output is last point
// x is lower than the first point in the x array. Return the first point
if (x <= xy.x[0]) {
ret = xy.y[0];
return xy.y[0];
} else {
// find the index such that (xy.x[i] <= x < xy.x[i+1]) and linearly interp
for (int i=0; i < (size - 1); i++) {
for (int i=0; i < size-1; i++) {
if (x < xy.x[i+1]) {
float x0 = xy.x[i];
float y0 = xy.y[i];
float dx = xy.x[i+1] - x0;
float dy = xy.y[i+1] - y0;
// dx should not be zero as xy.x is supposed ot be monotonic
if (dx <= 0.) {
dx = 0.0001;
}
ret = (dy * (x - x0) / dx) + y0;
break;
if (dx <= 0.) dx = 0.0001;
return dy * (x - x0) / dx + y0;
}
}
// if no such point is found, then x > xy.x[size-1]. Return last point
return xy.y[size - 1];
}
return ret;
}
#endif
+23 -22
View File
@@ -1,10 +1,8 @@
#define CADILLAC_TORQUE_MSG_N 4 // 4 torque messages: 0x151, 0x152, 0x153, 0x154
const int CADILLAC_MAX_STEER = 150; // 1s
// real time torque limit to prevent controls spamming
// the real time limit is 1500/sec
const int CADILLAC_MAX_RT_DELTA = 75; // max delta torque allowed for real time checks
const uint32_t CADILLAC_RT_INTERVAL = 250000; // 250ms between real time checks
const int32_t CADILLAC_RT_INTERVAL = 250000; // 250ms between real time checks
const int CADILLAC_MAX_RATE_UP = 2;
const int CADILLAC_MAX_RATE_DOWN = 5;
const int CADILLAC_DRIVER_TORQUE_ALLOWANCE = 50;
@@ -13,19 +11,21 @@ const int CADILLAC_DRIVER_TORQUE_FACTOR = 4;
int cadillac_ign = 0;
int cadillac_cruise_engaged_last = 0;
int cadillac_rt_torque_last = 0;
const int cadillac_torque_msgs_n = 4;
int cadillac_desired_torque_last[CADILLAC_TORQUE_MSG_N] = {0};
int cadillac_desired_torque_last[4] = {0}; // 4 torque messages
uint32_t cadillac_ts_last = 0;
int cadillac_supercruise_on = 0;
struct sample_t cadillac_torque_driver; // last few driver torques measured
int cadillac_get_torque_idx(int addr, int array_size) {
return MIN(MAX(addr - 0x151, 0), array_size); // 0x151 is id 0, 0x152 is id 1 and so on...
int cadillac_get_torque_idx(uint32_t addr) {
if (addr==0x151) return 0;
else if (addr==0x152) return 1;
else if (addr==0x153) return 2;
else return 3;
}
static void cadillac_rx_hook(CAN_FIFOMailBox_TypeDef *to_push) {
int bus = GET_BUS(to_push);
int addr = GET_ADDR(to_push);
int bus_number = (to_push->RDTR >> 4) & 0xFF;
uint32_t addr = to_push->RIR >> 21;
if (addr == 356) {
int torque_driver_new = ((to_push->RDLR & 0x7) << 8) | ((to_push->RDLR >> 8) & 0xFF);
@@ -35,17 +35,16 @@ static void cadillac_rx_hook(CAN_FIFOMailBox_TypeDef *to_push) {
}
// this message isn't all zeros when ignition is on
if ((addr == 0x160) && (bus == 0)) {
if (addr == 0x160 && bus_number == 0) {
cadillac_ign = to_push->RDLR > 0;
}
// enter controls on rising edge of ACC, exit controls on ACC off
if ((addr == 0x370) && (bus == 0)) {
if ((addr == 0x370) && (bus_number == 0)) {
int cruise_engaged = to_push->RDLR & 0x800000; // bit 23
if (cruise_engaged && !cadillac_cruise_engaged_last) {
controls_allowed = 1;
}
if (!cruise_engaged) {
} else if (!cruise_engaged) {
controls_allowed = 0;
}
cadillac_cruise_engaged_last = cruise_engaged;
@@ -58,15 +57,14 @@ static void cadillac_rx_hook(CAN_FIFOMailBox_TypeDef *to_push) {
}
static int cadillac_tx_hook(CAN_FIFOMailBox_TypeDef *to_send) {
int tx = 1;
int addr = GET_ADDR(to_send);
uint32_t addr = to_send->RIR >> 21;
// steer cmd checks
if ((addr == 0x151) || (addr == 0x152) || (addr == 0x153) || (addr == 0x154)) {
if (addr == 0x151 || addr == 0x152 || addr == 0x153 || addr == 0x154) {
int desired_torque = ((to_send->RDLR & 0x3f) << 8) + ((to_send->RDLR & 0xff00) >> 8);
int violation = 0;
uint32_t ts = TIM2->CNT;
int idx = cadillac_get_torque_idx(addr, CADILLAC_TORQUE_MSG_N);
int idx = cadillac_get_torque_idx(addr);
desired_torque = to_signed(desired_torque, 14);
if (controls_allowed) {
@@ -107,20 +105,22 @@ static int cadillac_tx_hook(CAN_FIFOMailBox_TypeDef *to_send) {
}
if (violation || cadillac_supercruise_on) {
tx = 0;
return false;
}
}
return tx;
return true;
}
static void cadillac_init(int16_t param) {
UNUSED(param);
controls_allowed = 0;
cadillac_ign = 0;
#ifdef PANDA
lline_relay_release();
#endif
}
static int cadillac_ign_hook(void) {
static int cadillac_ign_hook() {
return cadillac_ign;
}
@@ -130,5 +130,6 @@ const safety_hooks cadillac_hooks = {
.tx = cadillac_tx_hook,
.tx_lin = nooutput_tx_lin_hook,
.ignition = cadillac_ign_hook,
.fwd = default_fwd_hook,
.fwd = alloutput_fwd_hook,
.relay = nooutput_relay_hook,
};
+44 -30
View File
@@ -1,11 +1,11 @@
const int CHRYSLER_MAX_STEER = 261;
const int CHRYSLER_MAX_RT_DELTA = 112; // max delta torque allowed for real time checks
const uint32_t CHRYSLER_RT_INTERVAL = 250000; // 250ms between real time checks
const int32_t CHRYSLER_RT_INTERVAL = 250000; // 250ms between real time checks
const int CHRYSLER_MAX_RATE_UP = 3;
const int CHRYSLER_MAX_RATE_DOWN = 3;
const int CHRYSLER_MAX_TORQUE_ERROR = 80; // max torque cmd in excess of torque motor
bool chrysler_camera_detected = 0; // is giraffe switch 2 high?
int chrysler_camera_detected = 0; // is giraffe switch 2 high?
int chrysler_rt_torque_last = 0;
int chrysler_desired_torque_last = 0;
int chrysler_cruise_engaged_last = 0;
@@ -13,32 +13,40 @@ uint32_t chrysler_ts_last = 0;
struct sample_t chrysler_torque_meas; // last few torques measured
static void chrysler_rx_hook(CAN_FIFOMailBox_TypeDef *to_push) {
int bus = GET_BUS(to_push);
int addr = GET_ADDR(to_push);
int bus = (to_push->RDTR >> 4) & 0xFF;
uint32_t addr;
if (to_push->RIR & 4) {
// Extended
// Not looked at, but have to be separated
// to avoid address collision
addr = to_push->RIR >> 3;
} else {
// Normal
addr = to_push->RIR >> 21;
}
// Measured eps torque
if (addr == 544) {
uint32_t rdhr = to_push->RDHR;
int torque_meas_new = ((rdhr & 0x7U) << 8) + ((rdhr & 0xFF00U) >> 8) - 1024U;
int rdhr = to_push->RDHR;
int torque_meas_new = ((rdhr & 0x7) << 8) + ((rdhr & 0xFF00) >> 8) - 1024;
// update array of samples
update_sample(&chrysler_torque_meas, torque_meas_new);
}
// enter controls on rising edge of ACC, exit controls on ACC off
if (addr == 0x1F4) {
if (addr == 0x1f4) {
int cruise_engaged = ((to_push->RDLR & 0x380000) >> 19) == 7;
if (cruise_engaged && !chrysler_cruise_engaged_last) {
controls_allowed = 1;
}
if (!cruise_engaged) {
} else if (!cruise_engaged) {
controls_allowed = 0;
}
chrysler_cruise_engaged_last = cruise_engaged;
}
// check if stock camera ECU is still online
if ((bus == 0) && (addr == 0x292)) {
if (bus == 0 && addr == 0x292) {
chrysler_camera_detected = 1;
controls_allowed = 0;
}
@@ -46,21 +54,27 @@ static void chrysler_rx_hook(CAN_FIFOMailBox_TypeDef *to_push) {
static int chrysler_tx_hook(CAN_FIFOMailBox_TypeDef *to_send) {
int tx = 1;
// If camera is on bus 0, then nothing can be sent
// There can be only one! (camera)
if (chrysler_camera_detected) {
tx = 0;
return 0;
}
uint32_t addr;
if (to_send->RIR & 4) {
// Extended
addr = to_send->RIR >> 3;
} else {
// Normal
addr = to_send->RIR >> 21;
}
int addr = GET_ADDR(to_send);
// LKA STEER
if (addr == 0x292) {
uint32_t rdlr = to_send->RDLR;
int desired_torque = ((rdlr & 0x7U) << 8) + ((rdlr & 0xFF00U) >> 8) - 1024U;
int rdlr = to_send->RDLR;
int desired_torque = ((rdlr & 0x7) << 8) + ((rdlr & 0xFF00) >> 8) - 1024;
uint32_t ts = TIM2->CNT;
bool violation = 0;
int violation = 0;
if (controls_allowed) {
@@ -98,7 +112,7 @@ static int chrysler_tx_hook(CAN_FIFOMailBox_TypeDef *to_send) {
}
if (violation) {
tx = 0;
return false;
}
}
@@ -108,28 +122,27 @@ static int chrysler_tx_hook(CAN_FIFOMailBox_TypeDef *to_send) {
// TODO: fix bug preventing the button msg to be fwd'd on bus 2
// 1 allows the message through
return tx;
return true;
}
static void chrysler_init(int16_t param) {
UNUSED(param);
controls_allowed = 0;
chrysler_camera_detected = 0;
#ifdef PANDA
lline_relay_release();
#endif
}
static int chrysler_fwd_hook(int bus_num, CAN_FIFOMailBox_TypeDef *to_fwd) {
int bus_fwd = -1;
int addr = GET_ADDR(to_fwd);
int32_t addr = to_fwd->RIR >> 21;
// forward CAN 0 -> 2 so stock LKAS camera sees messages
if ((bus_num == 0) && !chrysler_camera_detected) {
bus_fwd = 2;
if (bus_num == 0 && !chrysler_camera_detected) {
return 2;
}
// forward all messages from camera except LKAS_COMMAND and LKAS_HUD
if ((bus_num == 2) && !chrysler_camera_detected && (addr != 658) && (addr != 678)) {
bus_fwd = 0;
if (bus_num == 2 && !chrysler_camera_detected && addr != 658 && addr != 678) {
return 0;
}
return bus_fwd;
return -1; // do not forward
}
@@ -140,4 +153,5 @@ const safety_hooks chrysler_hooks = {
.tx_lin = nooutput_tx_lin_hook,
.ignition = default_ign_hook,
.fwd = chrysler_fwd_hook,
.relay = nooutput_relay_hook,
};

Some files were not shown because too many files have changed in this diff Show More