Compare commits
No commits in common. "v0.1" and "spacecruft" have entirely different histories.
v0.1
...
spacecruft
|
@ -0,0 +1,19 @@
|
|||
---
|
||||
Checks: '
|
||||
bugprone-*,
|
||||
-bugprone-integer-division,
|
||||
-bugprone-narrowing-conversions,
|
||||
performance-*,
|
||||
clang-analyzer-*,
|
||||
misc-*,
|
||||
-misc-unused-parameters,
|
||||
modernize-*,
|
||||
-modernize-avoid-c-arrays,
|
||||
-modernize-deprecated-headers,
|
||||
-modernize-use-auto,
|
||||
-modernize-use-using,
|
||||
-modernize-use-nullptr,
|
||||
-modernize-use-trailing-return-type,
|
||||
'
|
||||
CheckOptions:
|
||||
...
|
|
@ -0,0 +1,3 @@
|
|||
((c++-mode (flycheck-gcc-language-standard . "c++11")
|
||||
(flycheck-clang-language-standard . "c++11")
|
||||
))
|
|
@ -0,0 +1,40 @@
|
|||
**/.git
|
||||
.DS_Store
|
||||
*.dylib
|
||||
*.DSYM
|
||||
*.d
|
||||
*.pyc
|
||||
*.pyo
|
||||
.*.swp
|
||||
.*.swo
|
||||
.*.un~
|
||||
*.tmp
|
||||
*.o
|
||||
*.o-*
|
||||
*.os
|
||||
*.os-*
|
||||
*.so
|
||||
*.a
|
||||
|
||||
notebooks
|
||||
phone
|
||||
massivemap
|
||||
neos
|
||||
installer
|
||||
chffr/app2
|
||||
chffr/backend/env
|
||||
selfdrive/nav
|
||||
selfdrive/baseui
|
||||
chffr/lib/vidindex/vidindex
|
||||
selfdrive/test/simulator2
|
||||
**/cache_data
|
||||
xx/chffr/lib/vidindex/vidindex
|
||||
xx/plus
|
||||
xx/community
|
||||
xx/projects
|
||||
!xx/projects/eon_testing_master
|
||||
!xx/projects/map3d
|
||||
xx/ops
|
||||
xx/junk
|
||||
tools/sim/carla
|
||||
tools/sim/*.tar.gz
|
|
@ -0,0 +1,11 @@
|
|||
root = true
|
||||
|
||||
[*]
|
||||
end_of_line = lf
|
||||
insert_final_newline = true
|
||||
trim_trailing_whitespace = true
|
||||
|
||||
[{*.py, *.pyx, *.pxd}]
|
||||
charset = utf-8
|
||||
indent_style = space
|
||||
indent_size = 2
|
|
@ -0,0 +1,23 @@
|
|||
*.keras filter=lfs diff=lfs merge=lfs -text
|
||||
*.dlc filter=lfs diff=lfs merge=lfs -text
|
||||
*.onnx filter=lfs diff=lfs merge=lfs -text
|
||||
*.pb filter=lfs diff=lfs merge=lfs -text
|
||||
*.bin filter=lfs diff=lfs merge=lfs -text
|
||||
*.jpg filter=lfs diff=lfs merge=lfs -text
|
||||
*.ipynb filter=nbstripout -diff
|
||||
external/ffmpeg/bin/ffmpeg_cuda filter=lfs diff=lfs merge=lfs -text
|
||||
models/segnet.keras filter=lfs diff=lfs merge=lfs -text
|
||||
phonelibs/acado/x86_64/lib/libacado_toolkit.a filter=lfs diff=lfs merge=lfs -text
|
||||
phonelibs/acado/x86_64/lib/libacado_toolkit_s.so.1.2.2beta filter=lfs diff=lfs merge=lfs -text
|
||||
phonelibs/acado/x86_64/lib/libacado_casadi.a filter=lfs diff=lfs merge=lfs -text
|
||||
phonelibs/acado/x86_64/lib/libacado_csparse.a filter=lfs diff=lfs merge=lfs -text
|
||||
phonelibs/acado/x86_64/lib/libacado_qpoases.a filter=lfs diff=lfs merge=lfs -text
|
||||
phonelibs/acado/aarch64/lib/libacado_toolkit.a filter=lfs diff=lfs merge=lfs -text
|
||||
phonelibs/acado/aarch64/lib/libacado_toolkit_s.so.1.2.2beta filter=lfs diff=lfs merge=lfs -text
|
||||
phonelibs/acado/aarch64/lib/libacado_casadi.a filter=lfs diff=lfs merge=lfs -text
|
||||
phonelibs/acado/aarch64/lib/libacado_csparse.a filter=lfs diff=lfs merge=lfs -text
|
||||
phonelibs/acado/aarch64/lib/libacado_qpoases.a filter=lfs diff=lfs merge=lfs -text
|
||||
phonelibs/fastcv/aarch64/libfastcvopt.so filter=lfs diff=lfs merge=lfs -text
|
||||
phonelibs/fastcv/aarch64/libfastcvadsp_stub.so filter=lfs diff=lfs merge=lfs -text
|
||||
models/segnet2.keras filter=lfs diff=lfs merge=lfs -text
|
||||
phonelibs/zmq/aarch64-linux/lib/libzmq.a filter=lfs diff=lfs merge=lfs -text
|
|
@ -0,0 +1,31 @@
|
|||
---
|
||||
name: Bug report
|
||||
about: For issues with running openpilot on your comma device
|
||||
title: ''
|
||||
labels: 'bug'
|
||||
assignees: ''
|
||||
---
|
||||
|
||||
**Describe the bug**
|
||||
|
||||
<!-- A clear and concise description of what the bug is. -->
|
||||
|
||||
**How to reproduce or log data**
|
||||
|
||||
<!-- Steps to reproduce the behavior. -->
|
||||
|
||||
**Expected behavior**
|
||||
|
||||
<!-- A clear and concise description of what you expected to happen. -->
|
||||
|
||||
**Device/Version information (please complete the following information):**
|
||||
- Device: [e.g. EON/EON Gold/comma two]
|
||||
- Dongle ID: [e.g. 77611a1fac303767, can be found in Settings -> Device -> Dongle ID or my.comma.ai/useradmin]
|
||||
- Route: [e.g. 77611a1fac303767|2020-05-11--16-37-07, can be found in my.comma.ai/useradmin]
|
||||
- Timestamp: [When in the route the bug occurs (e.g. 4min 30s into the drive)]
|
||||
- Version: [commit hash when on a non-release branch, or version number when on devel or release2 (e.g. 0.7.6)]
|
||||
- Car make/model: [e.g. Toyota Prius 2016]
|
||||
|
||||
**Additional context**
|
||||
|
||||
<!-- Add any other context about the problem here. -->
|
|
@ -0,0 +1,31 @@
|
|||
---
|
||||
name: Car bug report
|
||||
about: For issues with a particular car or make
|
||||
title: ''
|
||||
labels: 'car bug'
|
||||
assignees: ''
|
||||
---
|
||||
|
||||
**Describe the bug**
|
||||
|
||||
<!-- A clear and concise description of what the bug is. -->
|
||||
|
||||
**How to reproduce or log data**
|
||||
|
||||
<!-- Steps to reproduce the behavior. -->
|
||||
|
||||
**Expected behavior**
|
||||
|
||||
<!-- A clear and concise description of what you expected to happen. -->
|
||||
|
||||
**Device/Version information (please complete the following information):**
|
||||
- Device: [e.g. EON/EON Gold/comma two]
|
||||
- Dongle ID: [e.g. 77611a1fac303767, can be found in Settings -> Device -> Dongle ID or my.comma.ai/useradmin]
|
||||
- Route: [e.g. 77611a1fac303767|2020-05-11--16-37-07, can be found in my.comma.ai/useradmin]
|
||||
- Timestamp: [When in the route the bug occurs (e.g. 4min 30s into the drive)]
|
||||
- Version: [commit hash when on a non-release branch, or version number when on devel or release2 (e.g. 0.7.6)]
|
||||
- Car make/model: [e.g. Toyota Prius 2016]
|
||||
|
||||
**Additional context**
|
||||
|
||||
<!-- Add any other context about the problem here. -->
|
|
@ -0,0 +1,11 @@
|
|||
blank_issues_enabled: false
|
||||
contact_links:
|
||||
- name: Discussions
|
||||
url: https://github.com/commaai/openpilot/discussions
|
||||
about: For questions and discussion about openpilot
|
||||
- name: Community Wiki
|
||||
url: https://github.com/commaai/openpilot/wiki
|
||||
about: Check out our community wiki
|
||||
- name: Community Discord
|
||||
url: https://discord.comma.ai
|
||||
about: Check out our community discord
|
|
@ -0,0 +1,8 @@
|
|||
---
|
||||
name: Enhancement
|
||||
about: For openpilot enhancement suggestions
|
||||
title: ''
|
||||
labels: 'enhancement'
|
||||
assignees: ''
|
||||
---
|
||||
|
|
@ -0,0 +1,25 @@
|
|||
---
|
||||
name: PC Bug report
|
||||
about: For issues with running openpilot on PC
|
||||
title: ''
|
||||
labels: 'PC'
|
||||
assignees: ''
|
||||
---
|
||||
|
||||
**Describe the bug**
|
||||
|
||||
<!-- A clear and concise description of what the bug is. Add the `simulation` label if running in an environment like CARLA. -->
|
||||
|
||||
**How to reproduce or log data**
|
||||
|
||||
<!-- Steps to reproduce the behavior. -->
|
||||
|
||||
**Expected behavior**
|
||||
|
||||
<!-- A clear and concise description of what you expected to happen. -->
|
||||
|
||||
**Additional context**
|
||||
|
||||
<!-- Add any other context about the problem here. -->
|
||||
|
||||
Operating system: [e.g. Ubuntu 16.04]
|
|
@ -0,0 +1,15 @@
|
|||
---
|
||||
name: Bug fix
|
||||
about: For openpilot bug fixes
|
||||
title: ''
|
||||
labels: 'bugfix'
|
||||
assignees: ''
|
||||
---
|
||||
|
||||
**Description**
|
||||
|
||||
<!-- A description of the bug and the fix. Also link the issue if it exists. -->
|
||||
|
||||
**Verification**
|
||||
|
||||
<!-- Explain how you tested this bug fix. -->
|
|
@ -0,0 +1,19 @@
|
|||
---
|
||||
name: Car Bug fix
|
||||
about: For vehicle/brand specifc bug fixes
|
||||
title: ''
|
||||
labels: 'car bug fix'
|
||||
assignees: ''
|
||||
---
|
||||
|
||||
**Description**
|
||||
|
||||
<!-- A description of the bug and the fix. Also link the issue if it exists. -->
|
||||
|
||||
**Verification**
|
||||
|
||||
<!-- Explain how you tested this bug fix. -->
|
||||
|
||||
**Route**
|
||||
|
||||
Route: [a route with the bug fix]
|
|
@ -0,0 +1,14 @@
|
|||
---
|
||||
name: Car port
|
||||
about: For new car ports
|
||||
title: ''
|
||||
labels: 'car port'
|
||||
assignees: ''
|
||||
---
|
||||
|
||||
**Checklist**
|
||||
|
||||
- [ ] added to README
|
||||
- [ ] test route added to [test_routes.py](../../selfdrive/test/test_routes.py)
|
||||
- [ ] route with openpilot:
|
||||
- [ ] route with stock system:
|
|
@ -0,0 +1,11 @@
|
|||
---
|
||||
name: Fingerprint
|
||||
about: For adding fingerprints to existing cars
|
||||
title: ''
|
||||
labels: 'fingerprint'
|
||||
assignees: ''
|
||||
---
|
||||
|
||||
Discord username: []
|
||||
|
||||
Route: []
|
|
@ -0,0 +1,15 @@
|
|||
---
|
||||
name: Refactor
|
||||
about: For code refactors
|
||||
title: ''
|
||||
labels: 'refactor'
|
||||
assignees: ''
|
||||
---
|
||||
|
||||
**Description**
|
||||
|
||||
<!-- A description of the refactor, including the goals it accomplishes. -->
|
||||
|
||||
**Verification**
|
||||
|
||||
<!-- Explain how you tested the refactor for regressions. -->
|
|
@ -0,0 +1,8 @@
|
|||
version: 2
|
||||
updates:
|
||||
- package-ecosystem: pip
|
||||
directory: "/"
|
||||
schedule:
|
||||
interval: daily
|
||||
time: '15:00'
|
||||
open-pull-requests-limit: 10
|
|
@ -0,0 +1,38 @@
|
|||
<!-- Please copy and paste the relevant template -->
|
||||
|
||||
<!--- ***** Template: Car bug fix *****
|
||||
|
||||
**Description** [](A description of the bug and the fix. Also link any relevant issues.)
|
||||
|
||||
**Verification** [](Explain how you tested this bug fix.)
|
||||
|
||||
**Route**
|
||||
Route: [a route with the bug fix]
|
||||
|
||||
-->
|
||||
|
||||
<!--- ***** Template: Bug fix *****
|
||||
|
||||
**Description** [](A description of the bug and the fix. Also link any relevant issues.)
|
||||
|
||||
**Verification** [](Explain how you tested this bug fix.)
|
||||
|
||||
-->
|
||||
|
||||
<!--- ***** Template: Car port *****
|
||||
|
||||
**Checklist**
|
||||
- [ ] added to README
|
||||
- [ ] test route added to [test_routes.py](../../selfdrive/test/test_routes.py)
|
||||
- [ ] route with openpilot:
|
||||
- [ ] route with stock system:
|
||||
|
||||
-->
|
||||
|
||||
<!--- ***** Template: Refactor *****
|
||||
|
||||
**Description** [](A description of the refactor, including the goals it accomplishes.)
|
||||
|
||||
**Verification** [](Explain how you tested the refactor for regressions.)
|
||||
|
||||
-->
|
|
@ -0,0 +1,42 @@
|
|||
name: prebuilt
|
||||
on:
|
||||
schedule:
|
||||
- cron: '0 * * * *'
|
||||
|
||||
env:
|
||||
BASE_IMAGE: openpilot-base
|
||||
DOCKER_REGISTRY: ghcr.io/commaai
|
||||
|
||||
DOCKER_LOGIN: docker login ghcr.io -u adeebshihadeh -p ${{ secrets.CONTAINER_TOKEN }}
|
||||
BUILD: |
|
||||
docker pull $(grep -iohP '(?<=^from)\s+\S+' Dockerfile.openpilot_base) || true
|
||||
docker pull $DOCKER_REGISTRY/$BASE_IMAGE:latest || true
|
||||
docker build --cache-from $DOCKER_REGISTRY/$BASE_IMAGE:latest -t $DOCKER_REGISTRY/$BASE_IMAGE:latest -t $BASE_IMAGE:latest -f Dockerfile.openpilot_base .
|
||||
|
||||
jobs:
|
||||
build_prebuilt:
|
||||
name: build prebuilt
|
||||
runs-on: ubuntu-20.04
|
||||
timeout-minutes: 60
|
||||
if: github.repository == 'commaai/openpilot'
|
||||
env:
|
||||
IMAGE_NAME: openpilot-prebuilt
|
||||
steps:
|
||||
- name: Wait for green check mark
|
||||
uses: lewagon/wait-on-check-action@v0.2
|
||||
with:
|
||||
ref: master
|
||||
wait-interval: 30
|
||||
running-workflow-name: 'build prebuilt'
|
||||
- uses: actions/checkout@v2
|
||||
with:
|
||||
submodules: true
|
||||
- name: Build Docker image
|
||||
run: |
|
||||
eval "$BUILD"
|
||||
docker pull $DOCKER_REGISTRY/$IMAGE_NAME:latest || true
|
||||
docker build --cache-from $DOCKER_REGISTRY/$IMAGE_NAME:latest -t $DOCKER_REGISTRY/$IMAGE_NAME:latest -f Dockerfile.openpilot .
|
||||
- name: Push to container registry
|
||||
run: |
|
||||
$DOCKER_LOGIN
|
||||
docker push $DOCKER_REGISTRY/$IMAGE_NAME:latest
|
|
@ -0,0 +1,293 @@
|
|||
name: selfdrive
|
||||
on:
|
||||
push:
|
||||
branches-ignore:
|
||||
- 'testing-closet*'
|
||||
pull_request:
|
||||
|
||||
env:
|
||||
BASE_IMAGE: openpilot-base
|
||||
DOCKER_REGISTRY: ghcr.io/commaai
|
||||
|
||||
DOCKER_LOGIN: docker login ghcr.io -u adeebshihadeh -p ${{ secrets.CONTAINER_TOKEN }}
|
||||
BUILD: |
|
||||
docker pull $(grep -iohP '(?<=^from)\s+\S+' Dockerfile.openpilot_base) || true
|
||||
docker pull $DOCKER_REGISTRY/$BASE_IMAGE:latest || true
|
||||
docker build --cache-from $DOCKER_REGISTRY/$BASE_IMAGE:latest -t $DOCKER_REGISTRY/$BASE_IMAGE:latest -t $BASE_IMAGE:latest -f Dockerfile.openpilot_base .
|
||||
|
||||
RUN: docker run --shm-size 1G -v $PWD:/tmp/openpilot -w /tmp/openpilot -e PYTHONPATH=/tmp/openpilot -e SCONS_CACHE=1 -e GITHUB_ACTION -e GITHUB_REF -e GITHUB_HEAD_REF -e GITHUB_SHA -e GITHUB_REPOSITORY -e GITHUB_RUN_ID -v /tmp/scons_cache:/tmp/scons_cache -v /tmp/comma_download_cache:/tmp/comma_download_cache $BASE_IMAGE /bin/sh -c
|
||||
UNIT_TEST: coverage run --append -m unittest discover
|
||||
|
||||
jobs:
|
||||
# TODO: once actions/cache supports read only mode, use the cache for all jobs
|
||||
build_release:
|
||||
name: build release
|
||||
runs-on: ubuntu-20.04
|
||||
timeout-minutes: 50
|
||||
env:
|
||||
STRIPPED_DIR: tmppilot
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
with:
|
||||
submodules: true
|
||||
- name: Cache dependencies
|
||||
id: dependency-cache
|
||||
uses: actions/cache@v2
|
||||
with:
|
||||
path: /tmp/scons_cache
|
||||
key: scons-cache-${{ hashFiles('selfdrive/**') }}
|
||||
restore-keys: scons-cache-
|
||||
- name: Strip non-release files
|
||||
run: |
|
||||
mkdir $STRIPPED_DIR
|
||||
cp -pR --parents $(cat release/files_common) $STRIPPED_DIR
|
||||
cp Dockerfile.openpilot_base $STRIPPED_DIR
|
||||
|
||||
# need this to build on x86
|
||||
cp -pR --parents phonelibs/libyuv phonelibs/snpe selfdrive/modeld/runners $STRIPPED_DIR
|
||||
- name: Build Docker image
|
||||
run: eval "$BUILD"
|
||||
- name: Build openpilot and run checks
|
||||
run: |
|
||||
cd $STRIPPED_DIR
|
||||
${{ env.RUN }} "python selfdrive/manager/build.py && \
|
||||
python -m unittest discover selfdrive/car"
|
||||
- name: Cleanup scons cache
|
||||
run: |
|
||||
cd $STRIPPED_DIR
|
||||
${{ env.RUN }} "scons -j$(nproc) && \
|
||||
rm -rf /tmp/scons_cache/* && \
|
||||
scons -j$(nproc) --cache-populate"
|
||||
|
||||
build_mac:
|
||||
name: build macos
|
||||
runs-on: macos-10.15
|
||||
timeout-minutes: 60
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
with:
|
||||
submodules: true
|
||||
- name: Determine pre-existing Homebrew packages
|
||||
if: steps.dependency-cache.outputs.cache-hit != 'true'
|
||||
run: |
|
||||
echo 'EXISTING_CELLAR<<EOF' >> $GITHUB_ENV
|
||||
ls -1 /usr/local/Cellar >> $GITHUB_ENV
|
||||
echo 'EOF' >> $GITHUB_ENV
|
||||
- name: Cache dependencies
|
||||
id: dependency-cache
|
||||
uses: actions/cache@v2
|
||||
with:
|
||||
path: |
|
||||
~/.pyenv
|
||||
~/Library/Caches/pip
|
||||
~/Library/Caches/pipenv
|
||||
/usr/local/Cellar
|
||||
~/github_brew_cache_entries.txt
|
||||
key: macos-cache-${{ hashFiles('tools/mac_setup.sh') }}
|
||||
- name: Brew link restored dependencies
|
||||
if: steps.dependency-cache.outputs.cache-hit == 'true'
|
||||
run: |
|
||||
while read pkg; do
|
||||
brew link --force "$pkg" # `--force` for keg-only packages
|
||||
done < ~/github_brew_cache_entries.txt
|
||||
- name: Install dependencies
|
||||
run: ./tools/mac_setup.sh
|
||||
- name: Build openpilot
|
||||
run: eval "$(pyenv init -)" && scons -j$(nproc)
|
||||
- name: Remove pre-existing Homebrew packages for caching
|
||||
if: steps.dependency-cache.outputs.cache-hit != 'true'
|
||||
run: |
|
||||
cd /usr/local/Cellar
|
||||
new_cellar=$(ls -1)
|
||||
comm -12 <(echo "$EXISTING_CELLAR") <(echo "$new_cellar") | while read pkg; do
|
||||
if [[ $pkg != "zstd" ]]; then # caching step needs zstd
|
||||
rm -rf "$pkg"
|
||||
fi
|
||||
done
|
||||
comm -13 <(echo "$EXISTING_CELLAR") <(echo "$new_cellar") | tee ~/github_brew_cache_entries.txt
|
||||
|
||||
build_webcam:
|
||||
name: build webcam
|
||||
runs-on: ubuntu-20.04
|
||||
timeout-minutes: 90
|
||||
env:
|
||||
IMAGE_NAME: openpilotwebcamci
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
with:
|
||||
submodules: true
|
||||
- name: Build Docker image
|
||||
run: |
|
||||
eval "$BUILD"
|
||||
docker pull $DOCKER_REGISTRY/$IMAGE_NAME:latest || true
|
||||
docker build --cache-from $DOCKER_REGISTRY/$IMAGE_NAME:latest -t $DOCKER_REGISTRY/$IMAGE_NAME:latest -f tools/webcam/Dockerfile .
|
||||
- name: Build openpilot
|
||||
run: docker run --shm-size 1G --rm -v $PWD:/tmp/openpilot -e PYTHONPATH=/tmp/openpilot $DOCKER_REGISTRY/$IMAGE_NAME /bin/sh -c "cd /tmp/openpilot && USE_WEBCAM=1 scons -j$(nproc)"
|
||||
- name: Push to container registry
|
||||
if: github.ref == 'refs/heads/master' && github.repository == 'commaai/openpilot'
|
||||
run: |
|
||||
$DOCKER_LOGIN
|
||||
docker push $DOCKER_REGISTRY/$IMAGE_NAME:latest
|
||||
|
||||
docker_push:
|
||||
name: docker push
|
||||
runs-on: ubuntu-20.04
|
||||
timeout-minutes: 50
|
||||
if: github.ref == 'refs/heads/master' && github.event_name != 'pull_request' && github.repository == 'commaai/openpilot'
|
||||
needs: static_analysis # hack to ensure slow tests run first since this and static_analysis are fast
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
with:
|
||||
submodules: true
|
||||
- name: Build Docker image
|
||||
run: eval "$BUILD"
|
||||
- name: Push to container registry
|
||||
run: |
|
||||
$DOCKER_LOGIN
|
||||
docker push $DOCKER_REGISTRY/$BASE_IMAGE:latest
|
||||
|
||||
static_analysis:
|
||||
name: static analysis
|
||||
runs-on: ubuntu-20.04
|
||||
timeout-minutes: 50
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
with:
|
||||
submodules: true
|
||||
- name: Build Docker image
|
||||
run: eval "$BUILD"
|
||||
- name: pre-commit
|
||||
run: ${{ env.RUN }} "git init && git add -A && pre-commit run --all"
|
||||
|
||||
valgrind:
|
||||
name: valgrind
|
||||
runs-on: ubuntu-20.04
|
||||
timeout-minutes: 50
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
with:
|
||||
submodules: true
|
||||
- name: Cache dependencies
|
||||
id: dependency-cache
|
||||
uses: actions/cache@v2
|
||||
with:
|
||||
path: /tmp/comma_download_cache
|
||||
key: ${{ hashFiles('.github/workflows/test.yaml', 'selfdrive/test/test_valgrind_replay.py') }}
|
||||
- name: Build Docker image
|
||||
run: eval "$BUILD"
|
||||
- name: Run valgrind
|
||||
run: |
|
||||
${{ env.RUN }} "scons -j$(nproc) && \
|
||||
FILEREADER_CACHE=1 python selfdrive/test/test_valgrind_replay.py"
|
||||
- name: Print logs
|
||||
if: always()
|
||||
run: cat selfdrive/test/valgrind_logs.txt
|
||||
|
||||
unit_tests:
|
||||
name: unit tests
|
||||
runs-on: ubuntu-20.04
|
||||
timeout-minutes: 50
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
with:
|
||||
submodules: true
|
||||
- name: Build Docker image
|
||||
run: eval "$BUILD"
|
||||
- name: Run unit tests
|
||||
run: |
|
||||
${{ env.RUN }} "scons -j$(nproc) --test && \
|
||||
coverage run selfdrive/test/test_fingerprints.py && \
|
||||
$UNIT_TEST common && \
|
||||
$UNIT_TEST opendbc/can && \
|
||||
$UNIT_TEST selfdrive/boardd && \
|
||||
$UNIT_TEST selfdrive/controls && \
|
||||
$UNIT_TEST selfdrive/monitoring && \
|
||||
$UNIT_TEST selfdrive/loggerd && \
|
||||
$UNIT_TEST selfdrive/car && \
|
||||
$UNIT_TEST selfdrive/locationd && \
|
||||
$UNIT_TEST selfdrive/athena && \
|
||||
$UNIT_TEST selfdrive/thermald && \
|
||||
$UNIT_TEST tools/lib/tests && \
|
||||
./selfdrive/camerad/test/ae_gray_test"
|
||||
- name: Upload coverage to Codecov
|
||||
run: bash <(curl -s https://codecov.io/bash) -v -F unit_tests
|
||||
|
||||
process_replay:
|
||||
name: process replay
|
||||
runs-on: ubuntu-20.04
|
||||
timeout-minutes: 50
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
with:
|
||||
submodules: true
|
||||
- name: Cache dependencies
|
||||
id: dependency-cache
|
||||
uses: actions/cache@v2
|
||||
with:
|
||||
path: /tmp/comma_download_cache
|
||||
key: ${{ hashFiles('.github/workflows/test.yaml', 'selfdrive/test/process_replay/test_processes.py') }}
|
||||
- name: Build Docker image
|
||||
run: eval "$BUILD"
|
||||
- name: Run replay
|
||||
run: |
|
||||
${{ env.RUN }} "scons -j$(nproc) && \
|
||||
FILEREADER_CACHE=1 CI=1 coverage run selfdrive/test/process_replay/test_processes.py"
|
||||
- name: Upload coverage to Codecov
|
||||
run: bash <(curl -s https://codecov.io/bash) -v -F process_replay
|
||||
- name: Print diff
|
||||
if: always()
|
||||
run: cat selfdrive/test/process_replay/diff.txt
|
||||
- uses: actions/upload-artifact@v2
|
||||
if: always()
|
||||
continue-on-error: true
|
||||
with:
|
||||
name: process_replay_diff.txt
|
||||
path: selfdrive/test/process_replay/diff.txt
|
||||
|
||||
test_longitudinal:
|
||||
name: longitudinal
|
||||
runs-on: ubuntu-20.04
|
||||
timeout-minutes: 50
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
with:
|
||||
submodules: true
|
||||
- name: Build Docker image
|
||||
run: eval "$BUILD"
|
||||
- name: Test longitudinal
|
||||
run: |
|
||||
${{ env.RUN }} "mkdir -p selfdrive/test/out && \
|
||||
scons -j$(nproc) && \
|
||||
cd selfdrive/test/longitudinal_maneuvers && \
|
||||
./test_longitudinal.py"
|
||||
- uses: actions/upload-artifact@v2
|
||||
if: always()
|
||||
continue-on-error: true
|
||||
with:
|
||||
name: longitudinal
|
||||
path: selfdrive/test/longitudinal_maneuvers/out/longitudinal/
|
||||
|
||||
test_car_models:
|
||||
name: car models
|
||||
runs-on: ubuntu-20.04
|
||||
timeout-minutes: 50
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
with:
|
||||
submodules: true
|
||||
- name: Cache dependencies
|
||||
id: dependency-cache
|
||||
uses: actions/cache@v2
|
||||
with:
|
||||
path: /tmp/comma_download_cache
|
||||
key: ${{ hashFiles('.github/workflows/test.yaml', 'selfdrive/test/test_routes.py') }}
|
||||
- name: Build Docker image
|
||||
run: eval "$BUILD"
|
||||
- name: Test car models
|
||||
run: |
|
||||
${{ env.RUN }} "scons -j$(nproc) && \
|
||||
FILEREADER_CACHE=1 coverage run --parallel-mode -m nose --processes=4 --process-timeout=60 \
|
||||
selfdrive/test/test_models.py && \
|
||||
coverage combine"
|
||||
- name: Upload coverage to Codecov
|
||||
run: bash <(curl -s https://codecov.io/bash) -v -F test_car_models
|
|
@ -0,0 +1,58 @@
|
|||
name: tools
|
||||
on:
|
||||
push:
|
||||
pull_request:
|
||||
|
||||
env:
|
||||
BASE_IMAGE: openpilot-base
|
||||
DOCKER_REGISTRY: ghcr.io/commaai
|
||||
DOCKER_LOGIN: docker login ghcr.io -u adeebshihadeh -p ${{ secrets.CONTAINER_TOKEN }}
|
||||
|
||||
BUILD: |
|
||||
docker pull $(grep -iohP '(?<=^from)\s+\S+' Dockerfile.openpilot_base) || true
|
||||
docker pull $DOCKER_REGISTRY/$BASE_IMAGE:latest || true
|
||||
docker build --cache-from $DOCKER_REGISTRY/$BASE_IMAGE:latest -t $DOCKER_REGISTRY/$BASE_IMAGE:latest -t $BASE_IMAGE:latest -f Dockerfile.openpilot_base .
|
||||
RUN: docker run --shm-size 1G -v $PWD:/tmp/openpilot -e PYTHONPATH=/tmp/openpilot -e GITHUB_ACTION -e GITHUB_REF -e GITHUB_HEAD_REF -e GITHUB_SHA -e \
|
||||
GITHUB_REPOSITORY -e GITHUB_RUN_ID -v /tmp/comma_download_cache:/tmp/comma_download_cache $BASE_IMAGE /bin/sh -c
|
||||
|
||||
jobs:
|
||||
plotjuggler:
|
||||
name: plotjuggler
|
||||
runs-on: ubuntu-20.04
|
||||
timeout-minutes: 30
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
with:
|
||||
submodules: true
|
||||
- name: Build Docker image
|
||||
run: eval "$BUILD"
|
||||
- name: Unit test
|
||||
run: |
|
||||
${{ env.RUN }} "scons -j$(nproc) --directory=/tmp/openpilot/cereal && \
|
||||
apt-get update && \
|
||||
apt-get install -y libdw-dev libqt5svg5-dev libqt5x11extras5-dev && \
|
||||
cd /tmp/openpilot/tools/plotjuggler && \
|
||||
./test_plotjuggler.py"
|
||||
|
||||
simulator:
|
||||
name: simulator
|
||||
runs-on: ubuntu-20.04
|
||||
timeout-minutes: 50
|
||||
env:
|
||||
IMAGE_NAME: openpilot-sim
|
||||
if: github.repository == 'commaai/openpilot'
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
with:
|
||||
submodules: true
|
||||
lfs: true
|
||||
- name: Build Docker image
|
||||
run: |
|
||||
eval "$BUILD"
|
||||
docker pull $DOCKER_REGISTRY/$IMAGE_NAME:latest || true
|
||||
docker build --cache-from $DOCKER_REGISTRY/$IMAGE_NAME:latest -t $DOCKER_REGISTRY/$IMAGE_NAME:latest -f tools/sim/Dockerfile.sim .
|
||||
- name: Push to container registry
|
||||
if: github.ref == 'refs/heads/master' && github.repository == 'commaai/openpilot'
|
||||
run: |
|
||||
$DOCKER_LOGIN
|
||||
docker push $DOCKER_REGISTRY/$IMAGE_NAME:latest
|
|
@ -0,0 +1,77 @@
|
|||
venv/
|
||||
.clang-format
|
||||
.DS_Store
|
||||
.tags
|
||||
.ipynb_checkpoints
|
||||
.idea
|
||||
.overlay_init
|
||||
.overlay_consistent
|
||||
.sconsign.dblite
|
||||
.vscode*
|
||||
model2.png
|
||||
a.out
|
||||
.hypothesis
|
||||
|
||||
*.dylib
|
||||
*.DSYM
|
||||
*.d
|
||||
*.pyc
|
||||
*.pyo
|
||||
.*.swp
|
||||
.*.swo
|
||||
.*.un~
|
||||
*.tmp
|
||||
*.o
|
||||
*.o-*
|
||||
*.os
|
||||
*.os-*
|
||||
*.so
|
||||
*.a
|
||||
*.clb
|
||||
*.class
|
||||
*.pyxbldc
|
||||
*.vcd
|
||||
config.json
|
||||
clcache
|
||||
compile_commands.json
|
||||
|
||||
persist
|
||||
board/obj/
|
||||
selfdrive/boardd/boardd
|
||||
selfdrive/logcatd/logcatd
|
||||
selfdrive/mapd/default_speeds_by_region.json
|
||||
selfdrive/proclogd/proclogd
|
||||
selfdrive/ui/_ui
|
||||
selfdrive/test/longitudinal_maneuvers/out
|
||||
selfdrive/visiond/visiond
|
||||
selfdrive/loggerd/loggerd
|
||||
selfdrive/loggerd/bootlog
|
||||
selfdrive/sensord/_gpsd
|
||||
selfdrive/sensord/_sensord
|
||||
selfdrive/camerad/camerad
|
||||
selfdrive/camerad/test/ae_gray_test
|
||||
selfdrive/modeld/_modeld
|
||||
selfdrive/modeld/_dmonitoringmodeld
|
||||
/src/
|
||||
|
||||
one
|
||||
openpilot
|
||||
notebooks
|
||||
xx
|
||||
hyperthneed
|
||||
panda_jungle
|
||||
provisioning
|
||||
|
||||
.coverage*
|
||||
coverage.xml
|
||||
htmlcov
|
||||
pandaextra
|
||||
|
||||
.mypy_cache/
|
||||
flycheck_*
|
||||
|
||||
cppcheck_report.txt
|
||||
comma*.sh
|
||||
|
||||
selfdrive/modeld/thneed/compile
|
||||
models/*.thneed
|
|
@ -0,0 +1,15 @@
|
|||
[submodule "panda"]
|
||||
path = panda
|
||||
url = ../../RetroPilot/panda.git
|
||||
[submodule "opendbc"]
|
||||
path = opendbc
|
||||
url = ../../RetroPilot/opendbc.git
|
||||
[submodule "laika_repo"]
|
||||
path = laika_repo
|
||||
url = ../../RetroPilot/laika.git
|
||||
[submodule "cereal"]
|
||||
path = cereal
|
||||
url = ../../RetroPilot/cereal.git
|
||||
[submodule "rednose_repo"]
|
||||
path = rednose_repo
|
||||
url = ../../RetroPilot/rednose.git
|
|
@ -0,0 +1,47 @@
|
|||
repos:
|
||||
- repo: https://github.com/pre-commit/pre-commit-hooks
|
||||
rev: v3.4.0
|
||||
hooks:
|
||||
- id: check-ast
|
||||
- id: check-json
|
||||
- id: check-xml
|
||||
- id: check-yaml
|
||||
- id: check-merge-conflict
|
||||
- id: check-symlinks
|
||||
- repo: https://github.com/pre-commit/mirrors-mypy
|
||||
rev: v0.800
|
||||
hooks:
|
||||
- id: mypy
|
||||
exclude: '^(pyextra)|(cereal)|(rednose)|(panda)|(laika)|(opendbc)|(laika_repo)|(rednose_repo)/'
|
||||
additional_dependencies: ['git+https://github.com/numpy/numpy-stubs']
|
||||
- repo: https://github.com/PyCQA/flake8
|
||||
rev: 3.8.4
|
||||
hooks:
|
||||
- id: flake8
|
||||
exclude: '^(pyextra)|(cereal)|(rednose)|(panda)|(laika)|(opendbc)|(laika_repo)|(rednose_repo)|(selfdrive/debug)/'
|
||||
args:
|
||||
- --select=F,E112,E113,E304,E501,E502,E701,E702,E703,E71,E72,E731,W191,W6
|
||||
- --max-line-length=240
|
||||
- --statistics
|
||||
- repo: local
|
||||
hooks:
|
||||
- id: pylint
|
||||
name: pylint
|
||||
entry: pylint
|
||||
language: system
|
||||
types: [python]
|
||||
exclude: '^(pyextra)|(cereal)|(rednose)|(panda)|(laika)|(laika_repo)|(rednose_repo)/'
|
||||
- repo: local
|
||||
hooks:
|
||||
- id: cppcheck
|
||||
name: cppcheck
|
||||
entry: cppcheck
|
||||
language: system
|
||||
types: [c++]
|
||||
exclude: '^(phonelibs)|(cereal)|(opendbc)|(panda)|(tools)|(selfdrive/modeld/thneed/debug)|(selfdrive/modeld/test)|(selfdrive/camerad/test)/|(installer)'
|
||||
args:
|
||||
- --error-exitcode=1
|
||||
- --language=c++
|
||||
- --quiet
|
||||
- --force
|
||||
- -j8
|
|
@ -0,0 +1,471 @@
|
|||
[MASTER]
|
||||
|
||||
# A comma-separated list of package or module names from where C extensions may
|
||||
# be loaded. Extensions are loading into the active Python interpreter and may
|
||||
# run arbitrary code
|
||||
extension-pkg-whitelist=scipy cereal.messaging.messaging_pyx
|
||||
|
||||
# Add files or directories to the blacklist. They should be base names, not
|
||||
# paths.
|
||||
ignore=CVS
|
||||
|
||||
# Add files or directories matching the regex patterns to the blacklist. The
|
||||
# regex matches against base names, not paths.
|
||||
ignore-patterns=
|
||||
|
||||
# Python code to execute, usually for sys.path manipulation such as
|
||||
# pygtk.require().
|
||||
#init-hook=
|
||||
|
||||
# Use multiple processes to speed up Pylint.
|
||||
jobs=4
|
||||
|
||||
# List of plugins (as comma separated values of python modules names) to load,
|
||||
# usually to register additional checkers.
|
||||
load-plugins=
|
||||
|
||||
# Pickle collected data for later comparisons.
|
||||
persistent=yes
|
||||
|
||||
# Specify a configuration file.
|
||||
#rcfile=
|
||||
|
||||
# When enabled, pylint would attempt to guess common misconfiguration and emit
|
||||
# user-friendly hints instead of false-positive error messages
|
||||
suggestion-mode=yes
|
||||
|
||||
# Allow loading of arbitrary C extensions. Extensions are imported into the
|
||||
# active Python interpreter and may run arbitrary code.
|
||||
unsafe-load-any-extension=no
|
||||
|
||||
|
||||
[MESSAGES CONTROL]
|
||||
|
||||
# Only show warnings with the listed confidence levels. Leave empty to show
|
||||
# all. Valid levels: HIGH, INFERENCE, INFERENCE_FAILURE, UNDEFINED
|
||||
confidence=
|
||||
|
||||
# Disable the message, report, category or checker with the given id(s). You
|
||||
# can either give multiple identifiers separated by comma (,) or put this
|
||||
# option multiple times (only on the command line, not in the configuration
|
||||
# file where it should appear only once).You can also use "--disable=all" to
|
||||
# disable everything first and then reenable specific checks. For example, if
|
||||
# you want to run only the similarities checker, you can use "--disable=all
|
||||
# --enable=similarities". If you want to run only the classes checker, but have
|
||||
# no Warning level messages displayed, use"--disable=all --enable=classes
|
||||
# --disable=W"
|
||||
disable=C,R,W0613,W0511,W0212,W0201,W0311,W0106,W0603,W0621,W0703,W1201,W1203,E1136
|
||||
|
||||
|
||||
# Enable the message, report, category or checker with the given id(s). You can
|
||||
# either give multiple identifier separated by comma (,) or put this option
|
||||
# multiple time (only on the command line, not in the configuration file where
|
||||
# it should appear only once). See also the "--disable" option for examples.
|
||||
enable=c-extension-no-member
|
||||
|
||||
|
||||
[REPORTS]
|
||||
|
||||
# Python expression which should return a note less than 10 (10 is the highest
|
||||
# note). You have access to the variables errors warning, statement which
|
||||
# respectively contain the number of errors / warnings messages and the total
|
||||
# number of statements analyzed. This is used by the global evaluation report
|
||||
# (RP0004).
|
||||
evaluation=10.0 - ((float(5 * error + warning + refactor + convention) / statement) * 10)
|
||||
|
||||
# Template used to display messages. This is a python new-style format string
|
||||
# used to format the message information. See doc for all details
|
||||
#msg-template=
|
||||
|
||||
# Set the output format. Available formats are text, parseable, colorized, json
|
||||
# and msvs (visual studio).You can also give a reporter class, eg
|
||||
# mypackage.mymodule.MyReporterClass.
|
||||
output-format=text
|
||||
|
||||
# Tells whether to display a full report or only the messages
|
||||
reports=no
|
||||
|
||||
# Activate the evaluation score.
|
||||
score=yes
|
||||
|
||||
|
||||
[REFACTORING]
|
||||
|
||||
# Maximum number of nested blocks for function / method body
|
||||
max-nested-blocks=5
|
||||
|
||||
# Complete name of functions that never returns. When checking for
|
||||
# inconsistent-return-statements if a never returning function is called then
|
||||
# it will be considered as an explicit return statement and no message will be
|
||||
# printed.
|
||||
never-returning-functions=optparse.Values,sys.exit
|
||||
|
||||
|
||||
[LOGGING]
|
||||
|
||||
# Logging modules to check that the string format arguments are in logging
|
||||
# function parameter format
|
||||
logging-modules=logging
|
||||
|
||||
|
||||
[SPELLING]
|
||||
|
||||
# Limits count of emitted suggestions for spelling mistakes
|
||||
max-spelling-suggestions=4
|
||||
|
||||
# Spelling dictionary name. Available dictionaries: none. To make it working
|
||||
# install python-enchant package.
|
||||
spelling-dict=
|
||||
|
||||
# List of comma separated words that should not be checked.
|
||||
spelling-ignore-words=
|
||||
|
||||
# A path to a file that contains private dictionary; one word per line.
|
||||
spelling-private-dict-file=
|
||||
|
||||
# Tells whether to store unknown words to indicated private dictionary in
|
||||
# --spelling-private-dict-file option instead of raising a message.
|
||||
spelling-store-unknown-words=no
|
||||
|
||||
|
||||
[MISCELLANEOUS]
|
||||
|
||||
# List of note tags to take in consideration, separated by a comma.
|
||||
notes=FIXME,
|
||||
XXX,
|
||||
TODO
|
||||
|
||||
|
||||
[SIMILARITIES]
|
||||
|
||||
# Ignore comments when computing similarities.
|
||||
ignore-comments=yes
|
||||
|
||||
# Ignore docstrings when computing similarities.
|
||||
ignore-docstrings=yes
|
||||
|
||||
# Ignore imports when computing similarities.
|
||||
ignore-imports=no
|
||||
|
||||
# Minimum lines number of a similarity.
|
||||
min-similarity-lines=4
|
||||
|
||||
|
||||
[TYPECHECK]
|
||||
|
||||
# List of decorators that produce context managers, such as
|
||||
# contextlib.contextmanager. Add to this list to register other decorators that
|
||||
# produce valid context managers.
|
||||
contextmanager-decorators=contextlib.contextmanager
|
||||
|
||||
# List of members which are set dynamically and missed by pylint inference
|
||||
# system, and so shouldn't trigger E1101 when accessed. Python regular
|
||||
# expressions are accepted.
|
||||
generated-members=capnp.* cereal.* pygame.* zmq.* setproctitle.* smbus2.* usb1.* serial.* cv2.* ft4222.*
|
||||
|
||||
# Tells whether missing members accessed in mixin class should be ignored. A
|
||||
# mixin class is detected if its name ends with "mixin" (case insensitive).
|
||||
ignore-mixin-members=yes
|
||||
|
||||
# This flag controls whether pylint should warn about no-member and similar
|
||||
# checks whenever an opaque object is returned when inferring. The inference
|
||||
# can return multiple potential results while evaluating a Python object, but
|
||||
# some branches might not be evaluated, which results in partial inference. In
|
||||
# that case, it might be useful to still emit no-member and other checks for
|
||||
# the rest of the inferred objects.
|
||||
ignore-on-opaque-inference=yes
|
||||
|
||||
# List of class names for which member attributes should not be checked (useful
|
||||
# for classes with dynamically set attributes). This supports the use of
|
||||
# qualified names.
|
||||
ignored-classes=optparse.Values,thread._local,_thread._local
|
||||
|
||||
# List of module names for which member attributes should not be checked
|
||||
# (useful for modules/projects where namespaces are manipulated during runtime
|
||||
# and thus existing member attributes cannot be deduced by static analysis. It
|
||||
# supports qualified module names, as well as Unix pattern matching.
|
||||
ignored-modules=flask setproctitle usb1 flask.ext.socketio smbus2 usb1.*
|
||||
|
||||
# Show a hint with possible names when a member name was not found. The aspect
|
||||
# of finding the hint is based on edit distance.
|
||||
missing-member-hint=yes
|
||||
|
||||
# The minimum edit distance a name should have in order to be considered a
|
||||
# similar match for a missing member name.
|
||||
missing-member-hint-distance=1
|
||||
|
||||
# The total number of similar names that should be taken in consideration when
|
||||
# showing a hint for a missing member.
|
||||
missing-member-max-choices=1
|
||||
|
||||
|
||||
[VARIABLES]
|
||||
|
||||
# List of additional names supposed to be defined in builtins. Remember that
|
||||
# you should avoid to define new builtins when possible.
|
||||
additional-builtins=
|
||||
|
||||
# Tells whether unused global variables should be treated as a violation.
|
||||
allow-global-unused-variables=yes
|
||||
|
||||
# List of strings which can identify a callback function by name. A callback
|
||||
# name must start or end with one of those strings.
|
||||
callbacks=cb_,
|
||||
_cb
|
||||
|
||||
# A regular expression matching the name of dummy variables (i.e. expectedly
|
||||
# not used).
|
||||
dummy-variables-rgx=_+$|(_[a-zA-Z0-9_]*[a-zA-Z0-9]+?$)|dummy|^ignored_|^unused_
|
||||
|
||||
# Argument names that match this expression will be ignored. Default to name
|
||||
# with leading underscore
|
||||
ignored-argument-names=_.*|^ignored_|^unused_
|
||||
|
||||
# Tells whether we should check for unused import in __init__ files.
|
||||
init-import=no
|
||||
|
||||
# List of qualified module names which can have objects that can redefine
|
||||
# builtins.
|
||||
redefining-builtins-modules=six.moves,past.builtins,future.builtins
|
||||
|
||||
|
||||
[FORMAT]
|
||||
|
||||
# Expected format of line ending, e.g. empty (any line ending), LF or CRLF.
|
||||
expected-line-ending-format=
|
||||
|
||||
# Regexp for a line that is allowed to be longer than the limit.
|
||||
ignore-long-lines=^\s*(# )?<?https?://\S+>?$
|
||||
|
||||
# Number of spaces of indent required inside a hanging or continued line.
|
||||
indent-after-paren=4
|
||||
|
||||
# String used as indentation unit. This is usually " " (4 spaces) or "\t" (1
|
||||
# tab).
|
||||
indent-string=' '
|
||||
|
||||
# Maximum number of characters on a single line.
|
||||
max-line-length=100
|
||||
|
||||
# Maximum number of lines in a module
|
||||
max-module-lines=1000
|
||||
|
||||
# List of optional constructs for which whitespace checking is disabled. `dict-
|
||||
# separator` is used to allow tabulation in dicts, etc.: {1 : 1,\n222: 2}.
|
||||
# `trailing-comma` allows a space between comma and closing bracket: (a, ).
|
||||
# `empty-line` allows space-only lines.
|
||||
no-space-check=trailing-comma,
|
||||
dict-separator
|
||||
|
||||
# Allow the body of a class to be on the same line as the declaration if body
|
||||
# contains single statement.
|
||||
single-line-class-stmt=no
|
||||
|
||||
# Allow the body of an if to be on the same line as the test if there is no
|
||||
# else.
|
||||
single-line-if-stmt=no
|
||||
|
||||
|
||||
[BASIC]
|
||||
|
||||
# Naming style matching correct argument names
|
||||
argument-naming-style=snake_case
|
||||
|
||||
# Regular expression matching correct argument names. Overrides argument-
|
||||
# naming-style
|
||||
#argument-rgx=
|
||||
|
||||
# Naming style matching correct attribute names
|
||||
attr-naming-style=snake_case
|
||||
|
||||
# Regular expression matching correct attribute names. Overrides attr-naming-
|
||||
# style
|
||||
#attr-rgx=
|
||||
|
||||
# Bad variable names which should always be refused, separated by a comma
|
||||
bad-names=foo,
|
||||
bar,
|
||||
baz,
|
||||
toto,
|
||||
tutu,
|
||||
tata
|
||||
|
||||
# Naming style matching correct class attribute names
|
||||
class-attribute-naming-style=any
|
||||
|
||||
# Regular expression matching correct class attribute names. Overrides class-
|
||||
# attribute-naming-style
|
||||
#class-attribute-rgx=
|
||||
|
||||
# Naming style matching correct class names
|
||||
class-naming-style=PascalCase
|
||||
|
||||
# Regular expression matching correct class names. Overrides class-naming-style
|
||||
#class-rgx=
|
||||
|
||||
# Naming style matching correct constant names
|
||||
const-naming-style=UPPER_CASE
|
||||
|
||||
# Regular expression matching correct constant names. Overrides const-naming-
|
||||
# style
|
||||
#const-rgx=
|
||||
|
||||
# Minimum line length for functions/classes that require docstrings, shorter
|
||||
# ones are exempt.
|
||||
docstring-min-length=-1
|
||||
|
||||
# Naming style matching correct function names
|
||||
function-naming-style=snake_case
|
||||
|
||||
# Regular expression matching correct function names. Overrides function-
|
||||
# naming-style
|
||||
#function-rgx=
|
||||
|
||||
# Good variable names which should always be accepted, separated by a comma
|
||||
good-names=i,
|
||||
j,
|
||||
k,
|
||||
ex,
|
||||
Run,
|
||||
_
|
||||
|
||||
# Include a hint for the correct naming format with invalid-name
|
||||
include-naming-hint=no
|
||||
|
||||
# Naming style matching correct inline iteration names
|
||||
inlinevar-naming-style=any
|
||||
|
||||
# Regular expression matching correct inline iteration names. Overrides
|
||||
# inlinevar-naming-style
|
||||
#inlinevar-rgx=
|
||||
|
||||
# Naming style matching correct method names
|
||||
method-naming-style=snake_case
|
||||
|
||||
# Regular expression matching correct method names. Overrides method-naming-
|
||||
# style
|
||||
#method-rgx=
|
||||
|
||||
# Naming style matching correct module names
|
||||
module-naming-style=snake_case
|
||||
|
||||
# Regular expression matching correct module names. Overrides module-naming-
|
||||
# style
|
||||
#module-rgx=
|
||||
|
||||
# Colon-delimited sets of names that determine each other's naming style when
|
||||
# the name regexes allow several styles.
|
||||
name-group=
|
||||
|
||||
# Regular expression which should only match function or class names that do
|
||||
# not require a docstring.
|
||||
no-docstring-rgx=^_
|
||||
|
||||
# List of decorators that produce properties, such as abc.abstractproperty. Add
|
||||
# to this list to register other decorators that produce valid properties.
|
||||
property-classes=abc.abstractproperty
|
||||
|
||||
# Naming style matching correct variable names
|
||||
variable-naming-style=snake_case
|
||||
|
||||
# Regular expression matching correct variable names. Overrides variable-
|
||||
# naming-style
|
||||
#variable-rgx=
|
||||
|
||||
|
||||
[DESIGN]
|
||||
|
||||
# Maximum number of arguments for function / method
|
||||
max-args=5
|
||||
|
||||
# Maximum number of attributes for a class (see R0902).
|
||||
max-attributes=7
|
||||
|
||||
# Maximum number of boolean expressions in a if statement
|
||||
max-bool-expr=5
|
||||
|
||||
# Maximum number of branch for function / method body
|
||||
max-branches=12
|
||||
|
||||
# Maximum number of locals for function / method body
|
||||
max-locals=15
|
||||
|
||||
# Maximum number of parents for a class (see R0901).
|
||||
max-parents=7
|
||||
|
||||
# Maximum number of public methods for a class (see R0904).
|
||||
max-public-methods=20
|
||||
|
||||
# Maximum number of return / yield for function / method body
|
||||
max-returns=6
|
||||
|
||||
# Maximum number of statements in function / method body
|
||||
max-statements=50
|
||||
|
||||
# Minimum number of public methods for a class (see R0903).
|
||||
min-public-methods=2
|
||||
|
||||
|
||||
[CLASSES]
|
||||
|
||||
# List of method names used to declare (i.e. assign) instance attributes.
|
||||
defining-attr-methods=__init__,
|
||||
__new__,
|
||||
setUp
|
||||
|
||||
# List of member names, which should be excluded from the protected access
|
||||
# warning.
|
||||
exclude-protected=_asdict,
|
||||
_fields,
|
||||
_replace,
|
||||
_source,
|
||||
_make
|
||||
|
||||
# List of valid names for the first argument in a class method.
|
||||
valid-classmethod-first-arg=cls
|
||||
|
||||
# List of valid names for the first argument in a metaclass class method.
|
||||
valid-metaclass-classmethod-first-arg=mcs
|
||||
|
||||
|
||||
[IMPORTS]
|
||||
|
||||
# Allow wildcard imports from modules that define __all__.
|
||||
allow-wildcard-with-all=no
|
||||
|
||||
# Analyse import fallback blocks. This can be used to support both Python 2 and
|
||||
# 3 compatible code, which means that the block might have code that exists
|
||||
# only in one or another interpreter, leading to false positives when analysed.
|
||||
analyse-fallback-blocks=no
|
||||
|
||||
# Deprecated modules which should not be used, separated by a comma
|
||||
deprecated-modules=regsub,
|
||||
TERMIOS,
|
||||
Bastion,
|
||||
rexec
|
||||
|
||||
# Create a graph of external dependencies in the given file (report RP0402 must
|
||||
# not be disabled)
|
||||
ext-import-graph=
|
||||
|
||||
# Create a graph of every (i.e. internal and external) dependencies in the
|
||||
# given file (report RP0402 must not be disabled)
|
||||
import-graph=
|
||||
|
||||
# Create a graph of internal dependencies in the given file (report RP0402 must
|
||||
# not be disabled)
|
||||
int-import-graph=
|
||||
|
||||
# Force import order to recognize a module as part of the standard
|
||||
# compatibility libraries.
|
||||
known-standard-library=
|
||||
|
||||
# Force import order to recognize a module as part of a third party library.
|
||||
known-third-party=enchant
|
||||
|
||||
|
||||
[EXCEPTIONS]
|
||||
|
||||
# Exceptions that will emit a warning when being caught. Defaults to
|
||||
# "Exception"
|
||||
overgeneral-exceptions=Exception
|
|
@ -0,0 +1 @@
|
|||
3.8.5
|
|
@ -0,0 +1,45 @@
|
|||
# How to contribute
|
||||
|
||||
Our software is open source so you can solve your own problems without needing help from others. And if you solve a problem and are so kind, you can upstream it for the rest of the world to use.
|
||||
|
||||
Most open source development activity is coordinated through our [GitHub Discussions](https://github.com/commaai/openpilot/discussions) and [Discord](https://discord.comma.ai). A lot of documentation is available on our [medium](https://medium.com/@comma_ai/).
|
||||
|
||||
## Getting Started
|
||||
|
||||
* Join our [Discord](https://discord.comma.ai)
|
||||
* Make sure you have a [GitHub account](https://github.com/signup/free)
|
||||
* Fork [our repositories](https://github.com/commaai) on GitHub
|
||||
|
||||
## Testing
|
||||
|
||||
### Automated Testing
|
||||
|
||||
All PRs and commits are automatically checked by GitHub Actions. Check out `.github/workflows/` for what GitHub Actions runs. Any new tests should be added to GitHub Actions.
|
||||
|
||||
### Code Style and Linting
|
||||
|
||||
Code is automatically checked for style by GitHub Actions as part of the automated tests. You can also run these tests yourself by running `pre-commit run --all`.
|
||||
|
||||
## Car Ports (openpilot)
|
||||
|
||||
We've released a [Model Port guide](https://medium.com/@comma_ai/openpilot-port-guide-for-toyota-models-e5467f4b5fe6) for porting to Toyota/Lexus models.
|
||||
|
||||
If you port openpilot to a substantially new car brand, see this more generic [Brand Port guide](https://medium.com/@comma_ai/how-to-write-a-car-port-for-openpilot-7ce0785eda84).
|
||||
|
||||
## Pull Requests
|
||||
|
||||
Pull requests should be against the master branch. Before running master on in-car hardware, you'll need to clone the submodules too. That can be done by recursively cloning the repository:
|
||||
```
|
||||
git clone https://github.com/commaai/openpilot.git --recursive
|
||||
```
|
||||
Or alternatively, when on the master branch:
|
||||
```
|
||||
git submodule update --init
|
||||
```
|
||||
The reasons for having submodules on a dedicated repository and our new development philosophy can be found in our [post about externalization](https://medium.com/@comma_ai/a-2020-theme-externalization-13b33326d8b3).
|
||||
Modules that are in seperate repositories include:
|
||||
* cereal
|
||||
* laika
|
||||
* opendbc
|
||||
* panda
|
||||
* rednose
|
|
@ -0,0 +1,32 @@
|
|||
FROM ghcr.io/commaai/openpilot-base:latest
|
||||
|
||||
ENV PYTHONUNBUFFERED 1
|
||||
|
||||
ENV OPENPILOT_PATH /home/batman/openpilot/
|
||||
ENV PYTHONPATH ${OPENPILOT_PATH}:${PYTHONPATH}
|
||||
|
||||
RUN mkdir -p ${OPENPILOT_PATH}
|
||||
WORKDIR ${OPENPILOT_PATH}
|
||||
|
||||
COPY Pipfile Pipfile.lock $OPENPILOT_PATH
|
||||
RUN pip install --no-cache-dir pipenv==2020.8.13 && \
|
||||
pipenv install --system --deploy --dev --clear && \
|
||||
pip uninstall -y pipenv
|
||||
|
||||
COPY SConstruct ${OPENPILOT_PATH}
|
||||
|
||||
COPY ./pyextra ${OPENPILOT_PATH}/pyextra
|
||||
COPY ./phonelibs ${OPENPILOT_PATH}/phonelibs
|
||||
COPY ./site_scons ${OPENPILOT_PATH}/site_scons
|
||||
COPY ./laika ${OPENPILOT_PATH}/laika
|
||||
COPY ./laika_repo ${OPENPILOT_PATH}/laika_repo
|
||||
COPY ./rednose ${OPENPILOT_PATH}/rednose
|
||||
COPY ./tools ${OPENPILOT_PATH}/tools
|
||||
COPY ./release ${OPENPILOT_PATH}/release
|
||||
COPY ./common ${OPENPILOT_PATH}/common
|
||||
COPY ./opendbc ${OPENPILOT_PATH}/opendbc
|
||||
COPY ./cereal ${OPENPILOT_PATH}/cereal
|
||||
COPY ./panda ${OPENPILOT_PATH}/panda
|
||||
COPY ./selfdrive ${OPENPILOT_PATH}/selfdrive
|
||||
|
||||
RUN scons -j$(nproc)
|
|
@ -0,0 +1,70 @@
|
|||
FROM ubuntu:20.04
|
||||
ENV PYTHONUNBUFFERED 1
|
||||
|
||||
ENV DEBIAN_FRONTEND=noninteractive
|
||||
RUN apt-get update && apt-get install -y --no-install-recommends \
|
||||
autoconf \
|
||||
build-essential \
|
||||
bzip2 \
|
||||
ca-certificates \
|
||||
capnproto \
|
||||
clang \
|
||||
cmake \
|
||||
cppcheck \
|
||||
curl \
|
||||
ffmpeg \
|
||||
gcc-arm-none-eabi \
|
||||
git \
|
||||
iputils-ping \
|
||||
libarchive-dev \
|
||||
libbz2-dev \
|
||||
libcapnp-dev \
|
||||
libcurl4-openssl-dev \
|
||||
libeigen3-dev \
|
||||
libffi-dev \
|
||||
libgles2-mesa-dev \
|
||||
libglew-dev \
|
||||
libglib2.0-0 \
|
||||
liblzma-dev \
|
||||
libomp-dev \
|
||||
libopencv-dev \
|
||||
libqt5sql5-sqlite \
|
||||
libqt5svg5-dev \
|
||||
libsqlite3-dev \
|
||||
libssl-dev \
|
||||
libsystemd-dev \
|
||||
libusb-1.0-0-dev \
|
||||
libzmq3-dev \
|
||||
locales \
|
||||
ocl-icd-libopencl1 \
|
||||
ocl-icd-opencl-dev \
|
||||
opencl-headers \
|
||||
python-dev \
|
||||
qml-module-qtquick2 \
|
||||
qt5-default \
|
||||
qtlocation5-dev \
|
||||
qtmultimedia5-dev \
|
||||
qtpositioning5-dev \
|
||||
qtwebengine5-dev \
|
||||
sudo \
|
||||
valgrind \
|
||||
wget \
|
||||
&& rm -rf /var/lib/apt/lists/*
|
||||
|
||||
RUN sed -i -e 's/# en_US.UTF-8 UTF-8/en_US.UTF-8 UTF-8/' /etc/locale.gen && locale-gen
|
||||
ENV LANG en_US.UTF-8
|
||||
ENV LANGUAGE en_US:en
|
||||
ENV LC_ALL en_US.UTF-8
|
||||
|
||||
RUN curl -L https://github.com/pyenv/pyenv-installer/raw/master/bin/pyenv-installer | bash
|
||||
ENV PATH="/root/.pyenv/bin:/root/.pyenv/shims:${PATH}"
|
||||
|
||||
COPY Pipfile Pipfile.lock /tmp/
|
||||
RUN pyenv install 3.8.5 && \
|
||||
pyenv global 3.8.5 && \
|
||||
pyenv rehash && \
|
||||
pip install --no-cache-dir --upgrade pip==20.1.1 && \
|
||||
pip install --no-cache-dir pipenv==2020.8.13 && \
|
||||
cd /tmp && \
|
||||
pipenv install --system --deploy --dev --clear && \
|
||||
pip uninstall -y pipenv
|
|
@ -0,0 +1,246 @@
|
|||
def phone(String ip, String step_label, String cmd) {
|
||||
withCredentials([file(credentialsId: 'id_rsa', variable: 'key_file')]) {
|
||||
def ssh_cmd = """
|
||||
ssh -tt -o StrictHostKeyChecking=no -i ${key_file} -p 8022 'comma@${ip}' /usr/bin/bash <<'EOF'
|
||||
|
||||
set -e
|
||||
|
||||
export CI=1
|
||||
export TEST_DIR=${env.TEST_DIR}
|
||||
export GIT_BRANCH=${env.GIT_BRANCH}
|
||||
export GIT_COMMIT=${env.GIT_COMMIT}
|
||||
|
||||
source ~/.bash_profile
|
||||
if [ -f /TICI ]; then
|
||||
source /etc/profile
|
||||
fi
|
||||
|
||||
ln -snf ${env.TEST_DIR} /data/pythonpath
|
||||
|
||||
if [ -f /EON ]; then
|
||||
echo \$\$ > /dev/cpuset/app/tasks || true
|
||||
echo \$PPID > /dev/cpuset/app/tasks || true
|
||||
mkdir -p /dev/shm
|
||||
chmod 777 /dev/shm
|
||||
fi
|
||||
|
||||
cd ${env.TEST_DIR} || true
|
||||
${cmd}
|
||||
exit 0
|
||||
|
||||
EOF"""
|
||||
|
||||
sh script: ssh_cmd, label: step_label
|
||||
}
|
||||
}
|
||||
|
||||
def phone_steps(String device_type, steps) {
|
||||
lock(resource: "", label: device_type, inversePrecedence: true, variable: 'device_ip', quantity: 1) {
|
||||
timeout(time: 90, unit: 'MINUTES') {
|
||||
phone(device_ip, "git checkout", readFile("selfdrive/test/setup_device_ci.sh"),)
|
||||
steps.each { item ->
|
||||
phone(device_ip, item[0], item[1])
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pipeline {
|
||||
agent none
|
||||
environment {
|
||||
COMMA_JWT = credentials('athena-test-jwt')
|
||||
TEST_DIR = "/data/openpilot"
|
||||
}
|
||||
options {
|
||||
timeout(time: 2, unit: 'HOURS')
|
||||
}
|
||||
|
||||
stages {
|
||||
|
||||
stage('Build release2') {
|
||||
agent {
|
||||
docker {
|
||||
image 'python:3.7.3'
|
||||
args '--user=root'
|
||||
}
|
||||
}
|
||||
when {
|
||||
branch 'devel-staging'
|
||||
}
|
||||
steps {
|
||||
phone_steps("eon-build", [
|
||||
["build release2-staging and dashcam-staging", "cd release && PUSH=1 ./build_release2.sh"],
|
||||
])
|
||||
}
|
||||
}
|
||||
|
||||
stage('openpilot tests') {
|
||||
when {
|
||||
not {
|
||||
anyOf {
|
||||
branch 'master-ci'; branch 'devel'; branch 'devel-staging'; branch 'release2'; branch 'release2-staging'; branch 'dashcam'; branch 'dashcam-staging'; branch 'testing-closet*'
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
stages {
|
||||
|
||||
/*
|
||||
stage('PC tests') {
|
||||
agent {
|
||||
dockerfile {
|
||||
filename 'Dockerfile.openpilotci'
|
||||
args '--privileged --shm-size=1G --user=root'
|
||||
}
|
||||
}
|
||||
stages {
|
||||
stage('Build') {
|
||||
steps {
|
||||
sh 'scons -j$(nproc)'
|
||||
}
|
||||
}
|
||||
}
|
||||
post {
|
||||
always {
|
||||
// fix permissions since docker runs as another user
|
||||
sh "chmod -R 777 ."
|
||||
}
|
||||
}
|
||||
}
|
||||
*/
|
||||
|
||||
stage('On-device Tests') {
|
||||
agent {
|
||||
docker {
|
||||
/*
|
||||
filename 'Dockerfile.ondevice_ci'
|
||||
args "--privileged -v /dev:/dev --shm-size=1G --user=root"
|
||||
*/
|
||||
image 'python:3.7.3'
|
||||
args '--user=root'
|
||||
}
|
||||
}
|
||||
|
||||
stages {
|
||||
stage('parallel tests') {
|
||||
parallel {
|
||||
stage('Devel Tests') {
|
||||
steps {
|
||||
phone_steps("eon-build", [
|
||||
["build devel", "cd release && SCONS_CACHE=1 DEVEL_TEST=1 ./build_devel.sh"],
|
||||
["test manager", "python selfdrive/manager/test/test_manager.py"],
|
||||
["onroad tests", "cd selfdrive/test/ && ./test_onroad.py"],
|
||||
["test car interfaces", "cd selfdrive/car/tests/ && ./test_car_interfaces.py"],
|
||||
])
|
||||
}
|
||||
}
|
||||
|
||||
stage('Replay Tests') {
|
||||
steps {
|
||||
phone_steps("eon2", [
|
||||
["build QCOM_REPLAY", "SCONS_CACHE=1 QCOM_REPLAY=1 scons -j4"],
|
||||
["camerad/modeld replay", "cd selfdrive/test/process_replay && ./camera_replay.py"],
|
||||
])
|
||||
}
|
||||
}
|
||||
|
||||
stage('HW + Unit Tests') {
|
||||
steps {
|
||||
phone_steps("eon", [
|
||||
["build", "SCONS_CACHE=1 scons -j4"],
|
||||
["test athena", "nosetests -s selfdrive/athena/tests/test_athenad_old.py"],
|
||||
["test sounds", "nosetests -s selfdrive/test/test_sounds.py"],
|
||||
["test boardd loopback", "nosetests -s selfdrive/boardd/tests/test_boardd_loopback.py"],
|
||||
["test loggerd", "python selfdrive/loggerd/tests/test_loggerd.py"],
|
||||
["test encoder", "python selfdrive/loggerd/tests/test_encoder.py"],
|
||||
["test logcatd", "python selfdrive/logcatd/tests/test_logcatd_android.py"],
|
||||
//["test updater", "python installer/updater/test_updater.py"],
|
||||
])
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
stage('Power Consumption Tests') {
|
||||
steps {
|
||||
lock(resource: "", label: "c2-zookeeper", inversePrecedence: true, variable: 'device_ip', quantity: 1) {
|
||||
timeout(time: 90, unit: 'MINUTES') {
|
||||
sh script: "/home/batman/tools/zookeeper/enable_and_wait.py $device_ip 120", label: "turn on device"
|
||||
phone(device_ip, "git checkout", readFile("selfdrive/test/setup_device_ci.sh"),)
|
||||
phone(device_ip, "build", "SCONS_CACHE=1 scons -j4 && sync")
|
||||
sh script: "/home/batman/tools/zookeeper/disable.py $device_ip", label: "turn off device"
|
||||
sh script: "/home/batman/tools/zookeeper/enable_and_wait.py $device_ip 120", label: "turn on device"
|
||||
sh script: "/home/batman/tools/zookeeper/check_consumption.py 60 3", label: "idle power consumption after boot"
|
||||
sh script: "/home/batman/tools/zookeeper/ignition.py 1", label: "go onroad"
|
||||
sh script: "/home/batman/tools/zookeeper/check_consumption.py 60 10", label: "onroad power consumption"
|
||||
sh script: "/home/batman/tools/zookeeper/ignition.py 0", label: "go offroad"
|
||||
sh script: "/home/batman/tools/zookeeper/check_consumption.py 60 2", label: "idle power consumption offroad"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
*/
|
||||
|
||||
stage('Tici Build') {
|
||||
environment {
|
||||
R3_PUSH = "${env.BRANCH_NAME == 'master' ? '1' : ' '}"
|
||||
}
|
||||
steps {
|
||||
phone_steps("tici", [
|
||||
["build", "SCONS_CACHE=1 scons -j8"],
|
||||
["test loggerd", "python selfdrive/loggerd/tests/test_loggerd.py"],
|
||||
["test encoder", "LD_LIBRARY_PATH=/usr/local/lib python selfdrive/loggerd/tests/test_encoder.py"],
|
||||
["onroad tests", "cd selfdrive/test/ && ./test_onroad.py"],
|
||||
//["build release3-staging", "cd release && PUSH=${env.R3_PUSH} ./build_release3.sh"],
|
||||
])
|
||||
}
|
||||
}
|
||||
|
||||
stage('camerad') {
|
||||
steps {
|
||||
phone_steps("eon-party", [
|
||||
["build", "SCONS_CACHE=1 scons -j8"],
|
||||
["test camerad", "python selfdrive/camerad/test/test_camerad.py"],
|
||||
// ["test exposure", "python selfdrive/camerad/test/test_exposure.py"],
|
||||
])
|
||||
}
|
||||
}
|
||||
|
||||
stage('Tici camerad') {
|
||||
steps {
|
||||
phone_steps("tici-party", [
|
||||
["build", "SCONS_CACHE=1 scons -j8"],
|
||||
["test camerad", "python selfdrive/camerad/test/test_camerad.py"],
|
||||
// ["test exposure", "python selfdrive/camerad/test/test_exposure.py"],
|
||||
])
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
stage('Push master-ci') {
|
||||
when {
|
||||
branch 'master'
|
||||
}
|
||||
steps {
|
||||
phone_steps("eon-build", [
|
||||
["push devel", "cd release && CI_PUSH='master-ci' ./build_devel.sh"],
|
||||
])
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
post {
|
||||
always {
|
||||
cleanWs()
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,4 +1,4 @@
|
|||
Copyright (c) 2016, comma.ai
|
||||
Copyright (c) 2018, Comma.ai, Inc.
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
|
||||
|
|
@ -0,0 +1,119 @@
|
|||
[[source]]
|
||||
name = "pypi"
|
||||
url = "https://pypi.org/simple"
|
||||
verify_ssl = true
|
||||
|
||||
[dev-packages]
|
||||
opencv-python= "*"
|
||||
ipython = "*"
|
||||
networkx = "~=2.3"
|
||||
azure-core = "*"
|
||||
azure-common = "*"
|
||||
azure-nspkg = "~=3.0"
|
||||
azure-storage-blob = "~=2.1"
|
||||
azure-storage-common = "~=2.1"
|
||||
azure-storage-nspkg = "~=3.1"
|
||||
boto = "*"
|
||||
"boto3" = "*"
|
||||
control = "*"
|
||||
datadog = "*"
|
||||
elasticsearch = "*"
|
||||
gunicorn = "*"
|
||||
"h5py" = "*"
|
||||
hexdump = "*"
|
||||
imageio = "*"
|
||||
ipykernel = "*"
|
||||
joblib = "*"
|
||||
json-logging-py = "*"
|
||||
jupyter = "*"
|
||||
"mpld3" = "*"
|
||||
msgpack-python = "*"
|
||||
numpy = "*"
|
||||
osmium = "*"
|
||||
pycurl = "*"
|
||||
git-pylint-commit-hook = "*"
|
||||
pymongo = "*"
|
||||
"pynmea2" = "*"
|
||||
python-logstash = "*"
|
||||
redis = "*"
|
||||
"s2sphere" = "*"
|
||||
"subprocess32" = "*"
|
||||
tenacity = "*"
|
||||
keras_applications = "*"
|
||||
PyMySQL = "~=0.9"
|
||||
Werkzeug = "*"
|
||||
"backports.lzma" = "*"
|
||||
Flask-Cors = "*"
|
||||
Flask-SocketIO = "*"
|
||||
"GeoAlchemy2" = "*"
|
||||
Pygments = "*"
|
||||
reverse_geocoder = "*"
|
||||
Shapely = "*"
|
||||
SQLAlchemy = "*"
|
||||
scipy = "*"
|
||||
fastcluster = "*"
|
||||
simplejson = "*"
|
||||
seaborn = "*"
|
||||
pyproj = "*"
|
||||
mock = "*"
|
||||
matplotlib = "*"
|
||||
dictdiffer = "*"
|
||||
aenum = "*"
|
||||
coverage = "*"
|
||||
azure-cli-core = "*"
|
||||
paramiko = "*"
|
||||
aiohttp = "*"
|
||||
lru-dict = "*"
|
||||
scikit-image = "*"
|
||||
pygame = "==2.0.0.dev8"
|
||||
pprofile = "*"
|
||||
pyprof2calltree = "*"
|
||||
pre-commit = "*"
|
||||
mypy = "*"
|
||||
parameterized = "*"
|
||||
ft4222 = "*"
|
||||
hypothesis = "*"
|
||||
|
||||
[packages]
|
||||
atomicwrites = "*"
|
||||
cffi = "*"
|
||||
crcmod = "*"
|
||||
hexdump = "*"
|
||||
libusb1 = "*"
|
||||
numpy = "*"
|
||||
psutil = "*"
|
||||
pycapnp = "==1.0.0"
|
||||
cryptography = "*"
|
||||
python-dateutil = "*"
|
||||
pyzmq = "*"
|
||||
requests = "*"
|
||||
setproctitle = "*"
|
||||
six = "*"
|
||||
smbus2 = "*"
|
||||
sympy = "!=1.6.1"
|
||||
tqdm = "*"
|
||||
Cython = "*"
|
||||
PyYAML = "*"
|
||||
websocket_client = "*"
|
||||
urllib3 = "*"
|
||||
gunicorn = "*"
|
||||
utm = "*"
|
||||
json-rpc = "*"
|
||||
Flask = "*"
|
||||
nose = "*"
|
||||
flake8 = "*"
|
||||
pylint = "*"
|
||||
pillow = "*"
|
||||
scons = "*"
|
||||
cysignals = "*"
|
||||
pycryptodome = "*"
|
||||
"Jinja2" = "*"
|
||||
PyJWT = "*"
|
||||
pyserial = "*"
|
||||
onnx = "*"
|
||||
onnxruntime = "*"
|
||||
timezonefinder = "*"
|
||||
sentry-sdk = "*"
|
||||
|
||||
[requires]
|
||||
python_version = "3.8"
|
File diff suppressed because it is too large
Load Diff
386
README.md
386
README.md
|
@ -1,93 +1,377 @@
|
|||
Welcome to openpilot
|
||||
======
|
||||
[![](https://i.imgur.com/UelUjKAh.png)](#)
|
||||
|
||||
[openpilot](http://github.com/commaai/openpilot) is an open source driving agent.
|
||||
Table of Contents
|
||||
=======================
|
||||
|
||||
Currently it performs the functions of Adaptive Cruise Control (ACC) and Lane Keeping Assist System (LKAS) for Hondas and Acuras. It's about on par with Tesla Autopilot at launch, and better than [all other manufacturers](http://www.thedrive.com/tech/5707/the-war-for-autonomous-driving-part-iii-us-vs-germany-vs-japan).
|
||||
* [What is openpilot?](#what-is-openpilot)
|
||||
* [Integration with Stock Features](#integration-with-stock-features)
|
||||
* [Supported Hardware](#supported-hardware)
|
||||
* [Supported Cars](#supported-cars)
|
||||
* [Community Maintained Cars and Features](#community-maintained-cars-and-features)
|
||||
* [Installation Instructions](#installation-instructions)
|
||||
* [Limitations of openpilot ALC and LDW](#limitations-of-openpilot-alc-and-ldw)
|
||||
* [Limitations of openpilot ACC and FCW](#limitations-of-openpilot-acc-and-fcw)
|
||||
* [Limitations of openpilot DM](#limitations-of-openpilot-dm)
|
||||
* [User Data and comma Account](#user-data-and-comma-account)
|
||||
* [Safety and Testing](#safety-and-testing)
|
||||
* [Testing on PC](#testing-on-pc)
|
||||
* [Community and Contributing](#community-and-contributing)
|
||||
* [Directory Structure](#directory-structure)
|
||||
* [Licensing](#licensing)
|
||||
|
||||
The openpilot codebase has been written to be concise and enable rapid prototyping. We look forward to your contributions - improving real vehicle automation has never been easier.
|
||||
---
|
||||
|
||||
Hardware
|
||||
What is openpilot?
|
||||
------
|
||||
|
||||
Right now openpilot supports the [neo research platform](http://github.com/commaai/neo) for vehicle control. We'd like to support [Open Source Car Control](https://github.com/PolySync/OSCC) as well.
|
||||
[openpilot](http://github.com/commaai/openpilot) is an open source driver assistance system. Currently, openpilot performs the functions of Adaptive Cruise Control (ACC), Automated Lane Centering (ALC), Forward Collision Warning (FCW) and Lane Departure Warning (LDW) for a growing variety of supported [car makes, models and model years](#supported-cars). In addition, while openpilot is engaged, a camera based Driver Monitoring (DM) feature alerts distracted and asleep drivers.
|
||||
|
||||
To install it on the NEO:
|
||||
<table>
|
||||
<tr>
|
||||
<td><a href="https://www.youtube.com/watch?v=mgAbfr42oI8" title="YouTube" rel="noopener"><img src="https://i.imgur.com/kAtT6Ei.png"></a></td>
|
||||
<td><a href="https://www.youtube.com/watch?v=394rJKeh76k" title="YouTube" rel="noopener"><img src="https://i.imgur.com/lTt8cS2.png"></a></td>
|
||||
<td><a href="https://www.youtube.com/watch?v=1iNOc3cq8cs" title="YouTube" rel="noopener"><img src="https://i.imgur.com/ANnuSpe.png"></a></td>
|
||||
<td><a href="https://www.youtube.com/watch?v=Vr6NgrB-zHw" title="YouTube" rel="noopener"><img src="https://i.imgur.com/Qypanuq.png"></a></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><a href="https://www.youtube.com/watch?v=Ug41KIKF0oo" title="YouTube" rel="noopener"><img src="https://i.imgur.com/3caZ7xM.png"></a></td>
|
||||
<td><a href="https://www.youtube.com/watch?v=NVR_CdG1FRg" title="YouTube" rel="noopener"><img src="https://i.imgur.com/bAZOwql.png"></a></td>
|
||||
<td><a href="https://www.youtube.com/watch?v=tkEvIdzdfUE" title="YouTube" rel="noopener"><img src="https://i.imgur.com/EFINEzG.png"></a></td>
|
||||
<td><a href="https://www.youtube.com/watch?v=_P-N1ewNne4" title="YouTube" rel="noopener"><img src="https://i.imgur.com/gAyAq22.png"></a></td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
```bash
|
||||
# Requires working adb in PATH
|
||||
cd installation
|
||||
./install.sh
|
||||
```
|
||||
Integration with Stock Features
|
||||
------
|
||||
|
||||
In all supported cars:
|
||||
* Stock Lane Keep Assist (LKA) and stock ALC are replaced by openpilot ALC, which only functions when openpilot is engaged by the user.
|
||||
* Stock LDW is replaced by openpilot LDW.
|
||||
|
||||
Additionally, on specific supported cars (see ACC column in [supported cars](#supported-cars)):
|
||||
* Stock ACC is replaced by openpilot ACC.
|
||||
* openpilot FCW operates in addition to stock FCW.
|
||||
|
||||
openpilot should preserve all other vehicle's stock features, including, but are not limited to: FCW, Automatic Emergency Braking (AEB), auto high-beam, blind spot warning, and side collision warning.
|
||||
|
||||
Supported Hardware
|
||||
------
|
||||
|
||||
At the moment, openpilot supports the [EON DevKit](https://comma.ai/shop/products/eon-dashcam-devkit) and the [comma two](https://comma.ai/shop/products/comma-two-devkit). A [car harness](https://comma.ai/shop/products/car-harness) is recommended to connect the EON or comma two to the car. For experimental purposes, openpilot can also run on an Ubuntu computer with external [webcams](https://github.com/commaai/openpilot/tree/master/tools/webcam).
|
||||
|
||||
Supported Cars
|
||||
------
|
||||
|
||||
- Acura ILX 2016 with AcuraWatch Plus
|
||||
- Limitations: Due to use of the cruise control for gas, it can only be enabled above 25 mph
|
||||
| Make | Model (US Market Reference) | Supported Package | ACC | No ACC accel below | No ALC below |
|
||||
| ----------| ------------------------------| ------------------| -----------------| -------------------| ------------------|
|
||||
| Acura | ILX 2016-19 | AcuraWatch Plus | openpilot | 25mph<sup>1</sup> | 25mph |
|
||||
| Acura | RDX 2016-18 | AcuraWatch Plus | openpilot | 25mph<sup>1</sup> | 12mph |
|
||||
| Acura | RDX 2019-21 | All | Stock | 0mph | 3mph |
|
||||
| Honda | Accord 2018-20 | All | Stock | 0mph | 3mph |
|
||||
| Honda | Accord Hybrid 2018-20 | All | Stock | 0mph | 3mph |
|
||||
| Honda | Civic Hatchback 2017-21 | Honda Sensing | Stock | 0mph | 12mph |
|
||||
| Honda | Civic Sedan/Coupe 2016-18 | Honda Sensing | openpilot | 0mph | 12mph |
|
||||
| Honda | Civic Sedan/Coupe 2019-20 | All | Stock | 0mph | 2mph<sup>2</sup> |
|
||||
| Honda | CR-V 2015-16 | Touring | openpilot | 25mph<sup>1</sup> | 12mph |
|
||||
| Honda | CR-V 2017-20 | Honda Sensing | Stock | 0mph | 12mph |
|
||||
| Honda | CR-V Hybrid 2017-2019 | Honda Sensing | Stock | 0mph | 12mph |
|
||||
| Honda | Fit 2018-19 | Honda Sensing | openpilot | 25mph<sup>1</sup> | 12mph |
|
||||
| Honda | HR-V 2019-20 | Honda Sensing | openpilot | 25mph<sup>1</sup> | 12mph |
|
||||
| Honda | Insight 2019-21 | All | Stock | 0mph | 3mph |
|
||||
| Honda | Inspire 2018 | All | Stock | 0mph | 3mph |
|
||||
| Honda | Odyssey 2018-20 | Honda Sensing | openpilot | 25mph<sup>1</sup> | 0mph |
|
||||
| Honda | Passport 2019 | All | openpilot | 25mph<sup>1</sup> | 12mph |
|
||||
| Honda | Pilot 2016-19 | Honda Sensing | openpilot | 25mph<sup>1</sup> | 12mph |
|
||||
| Honda | Ridgeline 2017-21 | Honda Sensing | openpilot | 25mph<sup>1</sup> | 12mph |
|
||||
| Hyundai | Palisade 2020-21 | All | Stock | 0mph | 0mph |
|
||||
| Hyundai | Sonata 2020-21 | All | Stock | 0mph | 0mph |
|
||||
| Lexus | CT Hybrid 2017-18 | LSS | Stock<sup>3</sup>| 0mph | 0mph |
|
||||
| Lexus | ES 2019-21 | All | openpilot | 0mph | 0mph |
|
||||
| Lexus | ES Hybrid 2017-18 | LSS | Stock<sup>3</sup>| 0mph | 0mph |
|
||||
| Lexus | ES Hybrid 2019-21 | All | openpilot | 0mph | 0mph |
|
||||
| Lexus | IS 2017-2019 | All | Stock | 22mph | 0mph |
|
||||
| Lexus | NX 2018 | All | Stock<sup>3</sup>| 0mph | 0mph |
|
||||
| Lexus | NX 2020 | All | openpilot | 0mph | 0mph |
|
||||
| Lexus | NX Hybrid 2018 | All | Stock<sup>3</sup>| 0mph | 0mph |
|
||||
| Lexus | RX 2016-18 | All | Stock<sup>3</sup>| 0mph | 0mph |
|
||||
| Lexus | RX 2020-21 | All | openpilot | 0mph | 0mph |
|
||||
| Lexus | RX Hybrid 2016-19 | All | Stock<sup>3</sup>| 0mph | 0mph |
|
||||
| Lexus | RX Hybrid 2020 | All | openpilot | 0mph | 0mph |
|
||||
| Toyota | Avalon 2016-21 | TSS-P | Stock<sup>3</sup>| 20mph<sup>1</sup> | 0mph |
|
||||
| Toyota | Camry 2018-20 | All | Stock | 0mph<sup>4</sup> | 0mph |
|
||||
| Toyota | Camry 2021 | All | openpilot | 0mph | 0mph |
|
||||
| Toyota | Camry Hybrid 2018-20 | All | Stock | 0mph<sup>4</sup> | 0mph |
|
||||
| Toyota | Camry Hybrid 2021 | All | openpilot | 0mph | 0mph |
|
||||
| Toyota | C-HR 2017-20 | All | Stock | 0mph | 0mph |
|
||||
| Toyota | C-HR Hybrid 2017-19 | All | Stock | 0mph | 0mph |
|
||||
| Toyota | Corolla 2017-19 | All | Stock<sup>3</sup>| 20mph<sup>1</sup> | 0mph |
|
||||
| Toyota | Corolla 2020-21 | All | openpilot | 0mph | 0mph |
|
||||
| Toyota | Corolla Hatchback 2019-21 | All | openpilot | 0mph | 0mph |
|
||||
| Toyota | Corolla Hybrid 2020-21 | All | openpilot | 0mph | 0mph |
|
||||
| Toyota | Highlander 2017-19 | All | Stock<sup>3</sup>| 0mph | 0mph |
|
||||
| Toyota | Highlander 2020-21 | All | openpilot | 0mph | 0mph |
|
||||
| Toyota | Highlander Hybrid 2017-19 | All | Stock<sup>3</sup>| 0mph | 0mph |
|
||||
| Toyota | Highlander Hybrid 2020-21 | All | openpilot | 0mph | 0mph |
|
||||
| Toyota | Mirai 2021 | All | openpilot | 0mph | 0mph |
|
||||
| Toyota | Prius 2016-20 | TSS-P | Stock<sup>3</sup>| 0mph | 0mph |
|
||||
| Toyota | Prius 2021 | All | openpilot | 0mph | 0mph |
|
||||
| Toyota | Prius Prime 2017-20 | All | Stock<sup>3</sup>| 0mph | 0mph |
|
||||
| Toyota | Prius Prime 2021 | All | openpilot | 0mph | 0mph |
|
||||
| Toyota | Rav4 2016-18 | TSS-P | Stock<sup>3</sup>| 20mph<sup>1</sup> | 0mph |
|
||||
| Toyota | Rav4 2019-21 | All | openpilot | 0mph | 0mph |
|
||||
| Toyota | Rav4 Hybrid 2016-18 | TSS-P | Stock<sup>3</sup>| 0mph | 0mph |
|
||||
| Toyota | Rav4 Hybrid 2019-21 | All | openpilot | 0mph | 0mph |
|
||||
| Toyota | Sienna 2018-20 | All | Stock<sup>3</sup>| 0mph | 0mph |
|
||||
|
||||
- Honda Civic 2016 Touring Edition
|
||||
- Limitations: Due to limitations in steering firmware, steering is disabled below 18 mph
|
||||
<sup>1</sup>[Comma Pedal](https://github.com/commaai/openpilot/wiki/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. ***NOTE: The Comma Pedal is not officially supported by [comma](https://comma.ai).*** <br />
|
||||
<sup>2</sup>2019 Honda Civic 1.6L Diesel Sedan does not have ALC below 12mph. <br />
|
||||
<sup>3</sup>When disconnecting the Driver Support Unit (DSU), openpilot ACC will replace stock ACC. ***NOTE: disconnecting the DSU disables Automatic Emergency Braking (AEB).*** <br />
|
||||
<sup>4</sup>28mph for Camry 4CYL L, 4CYL LE and 4CYL SE which don't have Full-Speed Range Dynamic Radar Cruise Control. <br />
|
||||
|
||||
Directory structure
|
||||
Community Maintained Cars and Features
|
||||
------
|
||||
|
||||
- board -- Code that runs on the USB interface board
|
||||
- cereal -- The messaging spec used for all logs on the phone
|
||||
- common -- Library like functionality we've developed here
|
||||
- dbcs -- Files showing how to interpret data from cars
|
||||
- installation -- Installation on the neo platform
|
||||
- phonelibs -- Libraries used on the phone
|
||||
- selfdrive -- Code needed to drive the car
|
||||
- assets -- Fonts for ui
|
||||
- boardd -- Daemon to talk to the board
|
||||
- calibrationd -- Camera calibration server
|
||||
- common -- Shared C/C++ code for the daemons
|
||||
- controls -- Python controls (PID loops etc) for the car
|
||||
- logcatd -- Android logcat as a service
|
||||
- loggerd -- Logger and uploader of car data
|
||||
- sensord -- IMU / GPS interface code
|
||||
- ui -- The UI
|
||||
- visiond -- embedded vision pipeline
|
||||
| Make | Model (US Market Reference) | Supported Package | ACC | No ACC accel below | No ALC below |
|
||||
| ----------| ------------------------------| ------------------| -----------------| -------------------| -------------|
|
||||
| Audi | A3 2014-17 | Prestige | Stock | 0mph | 0mph |
|
||||
| Audi | A3 Sportback e-tron 2017-18 | Prestige | Stock | 0mph | 0mph |
|
||||
| Buick | Regal 2018<sup>1</sup> | Adaptive Cruise | openpilot | 0mph | 7mph |
|
||||
| Cadillac | ATS 2018<sup>1</sup> | Adaptive Cruise | openpilot | 0mph | 7mph |
|
||||
| Chevrolet | Malibu 2017<sup>1</sup> | Adaptive Cruise | openpilot | 0mph | 7mph |
|
||||
| Chevrolet | Volt 2017-18<sup>1</sup> | Adaptive Cruise | openpilot | 0mph | 7mph |
|
||||
| Chrysler | Pacifica 2017-18 | Adaptive Cruise | Stock | 0mph | 9mph |
|
||||
| Chrysler | Pacifica 2020 | Adaptive Cruise | Stock | 0mph | 39mph |
|
||||
| Chrysler | Pacifica Hybrid 2017-18 | Adaptive Cruise | Stock | 0mph | 9mph |
|
||||
| Chrysler | Pacifica Hybrid 2019-21 | Adaptive Cruise | Stock | 0mph | 39mph |
|
||||
| Genesis | G70 2018 | All | Stock | 0mph | 0mph |
|
||||
| Genesis | G80 2018 | All | Stock | 0mph | 0mph |
|
||||
| Genesis | G90 2018 | All | Stock | 0mph | 0mph |
|
||||
| GMC | Acadia 2018<sup>1</sup> | Adaptive Cruise | openpilot | 0mph | 7mph |
|
||||
| Holden | Astra 2017<sup>1</sup> | Adaptive Cruise | openpilot | 0mph | 7mph |
|
||||
| Hyundai | Elantra 2017-19 | SCC + LKAS | Stock | 19mph | 34mph |
|
||||
| Hyundai | Genesis 2015-16 | SCC + LKAS | Stock | 19mph | 37mph |
|
||||
| Hyundai | Ioniq Electric 2019 | SCC + LKAS | Stock | 0mph | 32mph |
|
||||
| Hyundai | Ioniq Electric 2020 | SCC + LKAS | Stock | 0mph | 0mph |
|
||||
| Hyundai | Kona 2020 | SCC + LKAS | Stock | 0mph | 0mph |
|
||||
| Hyundai | Kona EV 2019 | SCC + LKAS | Stock | 0mph | 0mph |
|
||||
| Hyundai | Santa Fe 2019-20 | All | Stock | 0mph | 0mph |
|
||||
| Hyundai | Sonata 2018-2019 | SCC + LKAS | Stock | 0mph | 0mph |
|
||||
| Hyundai | Veloster 2019 | SCC + LKAS | Stock | 5mph | 0mph |
|
||||
| Jeep | Grand Cherokee 2016-18 | Adaptive Cruise | Stock | 0mph | 9mph |
|
||||
| Jeep | Grand Cherokee 2019-20 | Adaptive Cruise | Stock | 0mph | 39mph |
|
||||
| Kia | Forte 2018-2021 | SCC + LKAS | Stock | 0mph | 0mph |
|
||||
| Kia | Niro EV 2020 | SCC + LKAS | Stock | 0mph | 0mph |
|
||||
| Kia | Optima 2017 | SCC + LKAS | Stock | 0mph | 32mph |
|
||||
| Kia | Optima 2019 | SCC + LKAS | Stock | 0mph | 0mph |
|
||||
| Kia | Seltos 2021 | SCC + LKAS | Stock | 0mph | 0mph |
|
||||
| Kia | Sorento 2018-19 | SCC + LKAS | Stock | 0mph | 0mph |
|
||||
| Kia | Stinger 2018 | SCC + LKAS | Stock | 0mph | 0mph |
|
||||
| Kia | Ceed 2019 | SCC + LKAS | Stock | 0mph | 0mph |
|
||||
| Nissan | Altima 2020 | ProPILOT | Stock | 0mph | 0mph |
|
||||
| Nissan | Leaf 2018-20 | ProPILOT | Stock | 0mph | 0mph |
|
||||
| Nissan | Rogue 2018-20 | ProPILOT | Stock | 0mph | 0mph |
|
||||
| Nissan | X-Trail 2017 | ProPILOT | Stock | 0mph | 0mph |
|
||||
| SEAT | Ateca 2018 | Driver Assistance | Stock | 0mph | 0mph |
|
||||
| Ĺ koda | Kodiaq 2018 | Driver Assistance | Stock | 0mph | 0mph |
|
||||
| Ĺ koda | Scala 2020 | Driver Assistance | Stock | 0mph | 0mph |
|
||||
| Ĺ koda | Superb 2015-18 | Driver Assistance | Stock | 0mph | 0mph |
|
||||
| Subaru | Ascent 2019 | EyeSight | Stock | 0mph | 0mph |
|
||||
| Subaru | Crosstrek 2018-19 | EyeSight | Stock | 0mph | 0mph |
|
||||
| Subaru | Forester 2019-21 | EyeSight | Stock | 0mph | 0mph |
|
||||
| Subaru | Impreza 2017-19 | EyeSight | Stock | 0mph | 0mph |
|
||||
| Volkswagen| Atlas 2018-19 | Driver Assistance | Stock | 0mph | 0mph |
|
||||
| Volkswagen| e-Golf 2014, 2019-20 | Driver Assistance | Stock | 0mph | 0mph |
|
||||
| Volkswagen| Golf 2015-19 | Driver Assistance | Stock | 0mph | 0mph |
|
||||
| Volkswagen| Golf Alltrack 2017-18 | Driver Assistance | Stock | 0mph | 0mph |
|
||||
| Volkswagen| Golf GTE 2016 | Driver Assistance | Stock | 0mph | 0mph |
|
||||
| Volkswagen| Golf GTI 2018-19 | Driver Assistance | Stock | 0mph | 0mph |
|
||||
| Volkswagen| Golf R 2016-19 | Driver Assistance | Stock | 0mph | 0mph |
|
||||
| Volkswagen| Golf SportsVan 2016 | Driver Assistance | Stock | 0mph | 0mph |
|
||||
| Volkswagen| Jetta 2018-20 | Driver Assistance | Stock | 0mph | 0mph |
|
||||
| Volkswagen| Jetta GLI 2021 | Driver Assistance | Stock | 0mph | 0mph |
|
||||
| Volkswagen| Passat 2016-17<sup>2</sup> | Driver Assistance | Stock | 0mph | 0mph |
|
||||
| Volkswagen| Tiguan 2020 | Driver Assistance | Stock | 0mph | 0mph |
|
||||
|
||||
To understand how the services interact, see `common/services.py`
|
||||
<sup>1</sup>Requires an [OBD-II car harness](https://comma.ai/shop/products/comma-car-harness) and [community built ASCM harness](https://github.com/commaai/openpilot/wiki/GM#hardware). ***NOTE: disconnecting the ASCM disables Automatic Emergency Braking (AEB).*** <br />
|
||||
<sup>2</sup>Only includes the MQB Passat sold outside of North America. The NMS Passat made in Chattanooga TN is not yet supported.
|
||||
|
||||
Adding Car Support
|
||||
Community Maintained Cars and Features are not verified by comma to meet our [safety model](SAFETY.md). Be extra cautious using them. They are only available after enabling the toggle in `Settings->Developer->Enable Community Features`.
|
||||
|
||||
To promote a car from community maintained, it must meet a few requirements. We must own one from the brand, we must sell the harness for it, has full ISO26262 in both panda and openpilot, there must be a path forward for longitudinal control, it must have AEB still enabled, and it must support fingerprinting 2.0
|
||||
|
||||
Although they're not upstream, the community has openpilot running on other makes and models. See the 'Community Supported Models' section of each make [on our wiki](https://wiki.comma.ai/).
|
||||
|
||||
Installation Instructions
|
||||
------
|
||||
|
||||
It should be relatively easy to add support for the Honda CR-V Touring. The brake message is the same. Steering has a slightly different message with a different message id. Sniff CAN while using LKAS to find it.
|
||||
Install openpilot on an EON or comma two by entering ``https://openpilot.comma.ai`` during the installer setup.
|
||||
|
||||
The Honda Accord uses different signalling for the steering and probably requires new hardware.
|
||||
Follow these [video instructions](https://youtu.be/lcjqxCymins) to properly mount the device on the windshield. Note: openpilot features an automatic pose calibration routine and openpilot performance should not be affected by small pitch and yaw misalignments caused by imprecise device mounting.
|
||||
|
||||
Adding other manufacturers besides Honda/Acura is doable but will be more of an undertaking.
|
||||
Before placing the device on your windshield, check the state and local laws and ordinances where you drive. Some state laws prohibit or restrict the placement of objects on the windshield of a motor vehicle.
|
||||
|
||||
You will be able to engage openpilot after reviewing the onboarding screens and finishing the calibration procedure.
|
||||
|
||||
User Data / chffr Account / Crash Reporting
|
||||
Limitations of openpilot ALC and LDW
|
||||
------
|
||||
|
||||
By default openpilot creates an account and includes a client for chffr, our dashcam app. We use your data to train better models and improve openpilot for everyone.
|
||||
openpilot ALC and openpilot LDW do not automatically drive the vehicle or reduce the amount of attention that must be paid to operate your vehicle. The driver must always keep control of the steering wheel and be ready to correct the openpilot ALC action at all times.
|
||||
|
||||
It's open source software, so you are free to disable it if you wish.
|
||||
While changing lanes, openpilot is not capable of looking next to you or checking your blind spot. Only nudge the wheel to initiate a lane change after you have confirmed it's safe to do so.
|
||||
|
||||
It logs the road facing camera, CAN, GPS, IMU, magnetometer, thermal sensors, crashes, and operating system logs.
|
||||
It does not log the user facing camera or the microphone.
|
||||
Many factors can impact the performance of openpilot ALC and openpilot LDW, causing them to be unable to function as intended. These include, but are not limited to:
|
||||
|
||||
By using it, you agree to [our privacy policy](https://beta.comma.ai/privacy.html). You understand that use of this software or its related services will generate certain types of user data, which may be logged and stored at the sole discretion of comma.ai. By accepting this agreement, you grant an irrevocable, perpetual, worldwide right to comma.ai for the use of this data.
|
||||
* Poor visibility (heavy rain, snow, fog, etc.) or weather conditions that may interfere with sensor operation.
|
||||
* The road facing camera is obstructed, covered or damaged by mud, ice, snow, etc.
|
||||
* Obstruction caused by applying excessive paint or adhesive products (such as wraps, stickers, rubber coating, etc.) onto the vehicle.
|
||||
* The device is mounted incorrectly.
|
||||
* When in sharp curves, like on-off ramps, intersections etc...; openpilot is designed to be limited in the amount of steering torque it can produce.
|
||||
* In the presence of restricted lanes or construction zones.
|
||||
* When driving on highly banked roads or in presence of strong cross-wind.
|
||||
* Extremely hot or cold temperatures.
|
||||
* Bright light (due to oncoming headlights, direct sunlight, etc.).
|
||||
* Driving on hills, narrow, or winding roads.
|
||||
|
||||
Contributing
|
||||
The list above does not represent an exhaustive list of situations that may interfere with proper operation of openpilot components. It is the driver's responsibility to be in control of the vehicle at all times.
|
||||
|
||||
Limitations of openpilot ACC and FCW
|
||||
------
|
||||
|
||||
We welcome both pull requests and issues on
|
||||
[github](http://github.com/commaai/openpilot). See the TODO file for a list of
|
||||
good places to start.
|
||||
openpilot ACC and openpilot FCW are not systems that allow careless or inattentive driving. It is still necessary for the driver to pay close attention to the vehicle’s surroundings and to be ready to re-take control of the gas and the brake at all times.
|
||||
|
||||
Many factors can impact the performance of openpilot ACC and openpilot FCW, causing them to be unable to function as intended. These include, but are not limited to:
|
||||
|
||||
* Poor visibility (heavy rain, snow, fog, etc.) or weather conditions that may interfere with sensor operation.
|
||||
* The road facing camera or radar are obstructed, covered, or damaged by mud, ice, snow, etc.
|
||||
* Obstruction caused by applying excessive paint or adhesive products (such as wraps, stickers, rubber coating, etc.) onto the vehicle.
|
||||
* The device is mounted incorrectly.
|
||||
* Approaching a toll booth, a bridge or a large metal plate.
|
||||
* When driving on roads with pedestrians, cyclists, etc...
|
||||
* In presence of traffic signs or stop lights, which are not detected by openpilot at this time.
|
||||
* When the posted speed limit is below the user selected set speed. openpilot does not detect speed limits at this time.
|
||||
* In presence of vehicles in the same lane that are not moving.
|
||||
* When abrupt braking maneuvers are required. openpilot is designed to be limited in the amount of deceleration and acceleration that it can produce.
|
||||
* When surrounding vehicles perform close cut-ins from neighbor lanes.
|
||||
* Driving on hills, narrow, or winding roads.
|
||||
* Extremely hot or cold temperatures.
|
||||
* Bright light (due to oncoming headlights, direct sunlight, etc.).
|
||||
* Interference from other equipment that generates radar waves.
|
||||
|
||||
The list above does not represent an exhaustive list of situations that may interfere with proper operation of openpilot components. It is the driver's responsibility to be in control of the vehicle at all times.
|
||||
|
||||
Limitations of openpilot DM
|
||||
------
|
||||
|
||||
openpilot DM should not be considered an exact measurement of the alertness of the driver.
|
||||
|
||||
Many factors can impact the performance of openpilot DM, causing it to be unable to function as intended. These include, but are not limited to:
|
||||
|
||||
* Low light conditions, such as driving at night or in dark tunnels.
|
||||
* Bright light (due to oncoming headlights, direct sunlight, etc.).
|
||||
* The driver's face is partially or completely outside field of view of the driver facing camera.
|
||||
* The driver facing camera is obstructed, covered, or damaged.
|
||||
|
||||
The list above does not represent an exhaustive list of situations that may interfere with proper operation of openpilot components. A driver should not rely on openpilot DM to assess their level of attention.
|
||||
|
||||
User Data and comma Account
|
||||
------
|
||||
|
||||
By default, openpilot uploads the driving data to our servers. You can also access your data by pairing with the comma connect app ([iOS](https://apps.apple.com/us/app/comma-connect/id1456551889), [Android](https://play.google.com/store/apps/details?id=ai.comma.connect&hl=en_US)). We use your data to train better models and improve openpilot for everyone.
|
||||
|
||||
openpilot is open source software: the user is free to disable data collection if they wish to do so.
|
||||
|
||||
openpilot logs the road facing camera, CAN, GPS, IMU, magnetometer, thermal sensors, crashes, and operating system logs.
|
||||
The driver facing camera is only logged if you explicitly opt-in in settings. The microphone is not recorded.
|
||||
|
||||
By using openpilot, you agree to [our Privacy Policy](https://my.comma.ai/privacy). You understand that use of this software or its related services will generate certain types of user data, which may be logged and stored at the sole discretion of comma. By accepting this agreement, you grant an irrevocable, perpetual, worldwide right to comma for the use of this data.
|
||||
|
||||
Safety and Testing
|
||||
----
|
||||
|
||||
* openpilot observes ISO26262 guidelines, see [SAFETY.md](SAFETY.md) for more details.
|
||||
* openpilot has software in the loop [tests](.github/workflows/test.yaml) that run on every commit.
|
||||
* The safety model code lives in panda and is written in C, see [code rigor](https://github.com/commaai/panda#code-rigor) for more details.
|
||||
* panda has software in the loop [safety tests](https://github.com/commaai/panda/tree/master/tests/safety).
|
||||
* Internally, we have a hardware in the loop Jenkins test suite that builds and unit tests the various processes.
|
||||
* panda has additional hardware in the loop [tests](https://github.com/commaai/panda/blob/master/Jenkinsfile).
|
||||
* We run the latest openpilot in a testing closet containing 10 EONs continuously replaying routes.
|
||||
|
||||
Testing on PC
|
||||
------
|
||||
For simplified development and experimentation, openpilot can be run in the CARLA driving simulator, which allows you to develop openpilot without a car. The whole setup should only take a few minutes.
|
||||
|
||||
Steps:
|
||||
1) Start the CARLA server on first terminal
|
||||
```
|
||||
bash -c "$(curl https://raw.githubusercontent.com/commaai/openpilot/master/tools/sim/start_carla.sh)"
|
||||
```
|
||||
2) Start openpilot on second terminal
|
||||
```
|
||||
bash -c "$(curl https://raw.githubusercontent.com/commaai/openpilot/master/tools/sim/start_openpilot_docker.sh)"
|
||||
```
|
||||
3) Press 1 to engage openpilot
|
||||
|
||||
See the full [README](tools/sim/README.md)
|
||||
|
||||
You should also take a look at the tools directory in master: lots of tools you can use to replay driving data, test, and develop openpilot from your PC.
|
||||
|
||||
|
||||
Community and Contributing
|
||||
------
|
||||
|
||||
openpilot is developed by [comma](https://comma.ai/) and by users like you. We welcome both pull requests and issues on [GitHub](http://github.com/commaai/openpilot). Bug fixes and new car ports are encouraged.
|
||||
|
||||
You can add support for your car by following guides we have written for [Brand](https://medium.com/@comma_ai/how-to-write-a-car-port-for-openpilot-7ce0785eda84) and [Model](https://medium.com/@comma_ai/openpilot-port-guide-for-toyota-models-e5467f4b5fe6) ports. Generally, a car with adaptive cruise control and lane keep assist is a good candidate. [Join our Discord](https://discord.comma.ai) to discuss car ports: most car makes have a dedicated channel.
|
||||
|
||||
Want to get paid to work on openpilot? [comma is hiring](https://comma.ai/jobs/).
|
||||
|
||||
And [follow us on Twitter](https://twitter.com/comma_ai).
|
||||
|
||||
Directory Structure
|
||||
------
|
||||
.
|
||||
├── cereal # The messaging spec and libs used for all logs
|
||||
├── common # Library like functionality we've developed here
|
||||
├── installer/updater # Manages auto-updates of NEOS
|
||||
├── opendbc # Files showing how to interpret data from cars
|
||||
├── panda # Code used to communicate on CAN
|
||||
├── phonelibs # Libraries used on NEOS devices
|
||||
├── pyextra # Libraries used on NEOS devices
|
||||
└── selfdrive # Code needed to drive the car
|
||||
├── assets # Fonts, images and sounds for UI
|
||||
├── athena # Allows communication with the app
|
||||
├── boardd # Daemon to talk to the board
|
||||
├── camerad # Driver to capture images from the camera sensors
|
||||
├── car # Car specific code to read states and control actuators
|
||||
├── common # Shared C/C++ code for the daemons
|
||||
├── controls # Perception, planning and controls
|
||||
├── debug # Tools to help you debug and do car ports
|
||||
├── locationd # Soon to be home of precise location
|
||||
├── logcatd # Android logcat as a service
|
||||
├── loggerd # Logger and uploader of car data
|
||||
├── modeld # Driving and monitoring model runners
|
||||
├── proclogd # Logs information from proc
|
||||
├── sensord # IMU / GPS interface code
|
||||
├── test # Unit tests, system tests and a car simulator
|
||||
└── ui # The UI
|
||||
|
||||
Licensing
|
||||
------
|
||||
|
||||
openpilot is released under the MIT license.
|
||||
openpilot is released under the MIT license. Some parts of the software are released under other licenses as specified.
|
||||
|
||||
Any user of this software shall indemnify and hold harmless comma.ai, Inc. and its directors, officers, employees, agents, stockholders, affiliates, subcontractors and customers from and against all allegations, claims, actions, suits, demands, damages, liabilities, obligations, losses, settlements, judgments, costs and expenses (including without limitation attorneys’ fees and costs) which arise out of, relate to or result from any use of this software by user.
|
||||
|
||||
**THIS IS ALPHA QUALITY SOFTWARE FOR RESEARCH PURPOSES ONLY. THIS IS NOT A PRODUCT.
|
||||
YOU ARE RESPONSIBLE FOR COMPLYING WITH LOCAL LAWS AND REGULATIONS.
|
||||
NO WARRANTY EXPRESSED OR IMPLIED.**
|
||||
|
||||
---
|
||||
|
||||
<img src="https://d1qb2nb5cznatu.cloudfront.net/startups/i/1061157-bc7e9bf3b246ece7322e6ffe653f6af8-medium_jpg.jpg?buster=1458363130" width="75"></img> <img src="https://cdn-images-1.medium.com/max/1600/1*C87EjxGeMPrkTuVRVWVg4w.png" width="225"></img>
|
||||
|
||||
[![openpilot tests](https://github.com/commaai/openpilot/workflows/openpilot%20tests/badge.svg?event=push)](https://github.com/commaai/openpilot/actions)
|
||||
[![Total alerts](https://img.shields.io/lgtm/alerts/g/commaai/openpilot.svg?logo=lgtm&logoWidth=18)](https://lgtm.com/projects/g/commaai/openpilot/alerts/)
|
||||
[![Language grade: Python](https://img.shields.io/lgtm/grade/python/g/commaai/openpilot.svg?logo=lgtm&logoWidth=18)](https://lgtm.com/projects/g/commaai/openpilot/context:python)
|
||||
[![Language grade: C/C++](https://img.shields.io/lgtm/grade/cpp/g/commaai/openpilot.svg?logo=lgtm&logoWidth=18)](https://lgtm.com/projects/g/commaai/openpilot/context:cpp)
|
||||
[![codecov](https://codecov.io/gh/commaai/openpilot/branch/master/graph/badge.svg)](https://codecov.io/gh/commaai/openpilot)
|
||||
|
|
|
@ -0,0 +1,653 @@
|
|||
Version 0.8.5 (2021-XX-XX)
|
||||
========================
|
||||
|
||||
Version 0.8.4 (2021-05-17)
|
||||
========================
|
||||
* Delay controls start until system is ready
|
||||
* Fuzzy car identification, enabled with Community Features toggle
|
||||
* Localizer optimized for increased precision and less CPU usage
|
||||
* Retuned lateral control to be more aggressive when model is confident
|
||||
* Toyota Mirai 2021 support
|
||||
* Lexus NX 300 2020 support thanks to goesreallyfast!
|
||||
* Volkswagen Atlas 2018-19 support thanks to jyoung8607!
|
||||
|
||||
Version 0.8.3 (2021-04-01)
|
||||
========================
|
||||
* New model
|
||||
* Trained on new diverse dataset from 2000+ users from 30+ countries
|
||||
* Trained with improved segnet from the comma-pencil community project
|
||||
* 🥬 Dramatically improved end-to-end lateral performance 🥬
|
||||
* Toggle added to disable the use of lanelines
|
||||
* NEOS update: update packages and support for new UI
|
||||
* New offroad UI based on Qt
|
||||
* Default SSH key only used for setup
|
||||
* Kia Ceed 2019 support thanks to ZanZaD13!
|
||||
* Kia Seltos 2021 support thanks to speedking456!
|
||||
* Added support for many Volkswagen and Ĺ koda models thanks to jyoung8607!
|
||||
|
||||
Version 0.8.2 (2021-02-26)
|
||||
========================
|
||||
* Use model points directly in MPC (no more polyfits), making lateral planning more accurate
|
||||
* Use model heading prediction for smoother lateral control
|
||||
* Smarter actuator delay compensation
|
||||
* Improve qcamera resolution for improved video in explorer and connect
|
||||
* Adjust maximum engagement speed to better fit the model's training distribution
|
||||
* New driver monitoring model trained with 3x more diverse data
|
||||
* Improved face detection with masks
|
||||
* More predictable DM alerts when visibility is bad
|
||||
* Rewritten video streaming between openpilot processes
|
||||
* Improved longitudinal tuning on TSS2 Corolla and Rav4 thanks to briskspirit!
|
||||
* Audi A3 2015 and 2017 support thanks to keeleysam!
|
||||
* Nissan Altima 2020 support thanks to avolmensky!
|
||||
* Lexus ES Hybrid 2018 support thanks to TheInventorMan!
|
||||
* Toyota Camry Hybrid 2021 support thanks to alancyau!
|
||||
|
||||
Version 0.8.1 (2020-12-21)
|
||||
========================
|
||||
* Original EON is deprecated, upgrade to comma two
|
||||
* Better model performance in heavy rain
|
||||
* Better lane positioning in turns
|
||||
* Fixed bug where model would cut turns on empty roads at night
|
||||
* Fixed issue where some Toyotas would not completely stop thanks to briskspirit!
|
||||
* Toyota Camry 2021 with TSS2.5 support
|
||||
* Hyundai Ioniq Electric 2020 support thanks to baldwalker!
|
||||
|
||||
Version 0.8.0 (2020-11-30)
|
||||
========================
|
||||
* New driving model: fully 3D and improved cut-in detection
|
||||
* UI draws 2 road edges, 4 lanelines and paths in 3D
|
||||
* Major fixes to cut-in detection for openpilot longitudinal
|
||||
* Grey panda is no longer supported, upgrade to comma two or black panda
|
||||
* Lexus NX 2018 support thanks to matt12eagles!
|
||||
* Kia Niro EV 2020 support thanks to nickn17!
|
||||
* Toyota Prius 2021 support thanks to rav4kumar!
|
||||
* Improved lane positioning with uncertain lanelines, wide lanes and exits
|
||||
* Improved lateral control for Prius and Subaru
|
||||
|
||||
Version 0.7.10 (2020-10-29)
|
||||
========================
|
||||
* Grey panda is deprecated, upgrade to comma two or black panda
|
||||
* NEOS update: update to Python 3.8.2 and lower CPU frequency
|
||||
* Improved thermals due to reduced CPU frequency
|
||||
* Update SNPE to 1.41.0
|
||||
* Reduced offroad power consumption
|
||||
* Various system stability improvements
|
||||
* Acura RDX 2020 support thanks to csouers!
|
||||
|
||||
Version 0.7.9 (2020-10-09)
|
||||
========================
|
||||
* Improved car battery power management
|
||||
* Improved updater robustness
|
||||
* Improved realtime performance
|
||||
* Reduced UI and modeld lags
|
||||
* Increased torque on 2020 Hyundai Sonata and Palisade
|
||||
|
||||
Version 0.7.8 (2020-08-19)
|
||||
========================
|
||||
* New driver monitoring model: improved face detection and better compatibility with sunglasses
|
||||
* Download NEOS operating system updates in the background
|
||||
* Improved updater reliability and responsiveness
|
||||
* Hyundai Kona 2020, Veloster 2019, and Genesis G70 2018 support thanks to xps-genesis!
|
||||
|
||||
Version 0.7.7 (2020-07-20)
|
||||
========================
|
||||
* White panda is no longer supported, upgrade to comma two or black panda
|
||||
* Improved vehicle model estimation using high precision localizer
|
||||
* Improved thermal management on comma two
|
||||
* Improved autofocus for road-facing camera
|
||||
* Improved noise performance for driver-facing camera
|
||||
* Block lane change start using blindspot monitor on select Toyota, Hyundai, and Subaru
|
||||
* Fix GM ignition detection
|
||||
* Code cleanup and smaller release sizes
|
||||
* Hyundai Sonata 2020 promoted to officially supported car
|
||||
* Hyundai Ioniq Electric Limited 2019 and Ioniq SE 2020 support thanks to baldwalker!
|
||||
* Subaru Forester 2019 and Ascent 2019 support thanks to martinl!
|
||||
|
||||
Version 0.7.6.1 (2020-06-16)
|
||||
========================
|
||||
* Hotfix: update kernel on some comma twos (orders #8570-#8680)
|
||||
|
||||
Version 0.7.6 (2020-06-05)
|
||||
========================
|
||||
* White panda is deprecated, upgrade to comma two or black panda
|
||||
* 2017 Nissan X-Trail, 2018-19 Leaf and 2019 Rogue support thanks to avolmensky!
|
||||
* 2017 Mazda CX-5 support in dashcam mode thanks to Jafaral!
|
||||
* Huge CPU savings in modeld by using thneed!
|
||||
* Lots of code cleanup and refactors
|
||||
|
||||
Version 0.7.5 (2020-05-13)
|
||||
========================
|
||||
* Right-Hand Drive support for both driving and driver monitoring!
|
||||
* New driving model: improved at sharp turns and lead speed estimation
|
||||
* New driver monitoring model: overall improvement on comma two
|
||||
* Driver camera preview in settings to improve mounting position
|
||||
* Added support for many Hyundai, Kia, Genesis models thanks to xx979xx!
|
||||
* Improved lateral tuning for 2020 Toyota Rav 4 (hybrid)
|
||||
|
||||
Version 0.7.4 (2020-03-20)
|
||||
========================
|
||||
* New driving model: improved lane changes and lead car detection
|
||||
* Improved driver monitoring model: improve eye detection
|
||||
* Improved calibration stability
|
||||
* Improved lateral control on some 2019 and 2020 Toyota Prius
|
||||
* Improved lateral control on VW Golf: 20% more steering torque
|
||||
* Fixed bug where some 2017 and 2018 Toyota C-HR would use the wrong steering angle sensor
|
||||
* Support for Honda Insight thanks to theantihero!
|
||||
* Code cleanup in car abstraction layers and ui
|
||||
|
||||
Version 0.7.3 (2020-02-21)
|
||||
========================
|
||||
* Support for 2020 Highlander thanks to che220!
|
||||
* Support for 2018 Lexus NX 300h thanks to kengggg!
|
||||
* Speed up ECU firmware query
|
||||
* Fix bug where manager would sometimes hang after shutting down the car
|
||||
|
||||
Version 0.7.2 (2020-02-07)
|
||||
========================
|
||||
* ECU firmware version based fingerprinting for Honda & Toyota
|
||||
* New driving model: improved path prediction during turns and lane changes and better lead speed tracking
|
||||
* Improve driver monitoring under extreme lighting and add low accuracy alert
|
||||
* Support for 2019 Rav4 Hybrid thanks to illumiN8i!
|
||||
* Support for 2016, 2017 and 2020 Lexus RX thanks to illumiN8i!
|
||||
* Support for 2020 Chrysler Pacifica Hybrid thanks to adhintz!
|
||||
|
||||
Version 0.7.1 (2020-01-20)
|
||||
========================
|
||||
* comma two support!
|
||||
* Lane Change Assist above 45 mph!
|
||||
* Replace zmq with custom messaging library, msgq!
|
||||
* Supercombo model: calibration and driving models are combined for better lead estimate
|
||||
* More robust updater thanks to jyoung8607! Requires NEOS update
|
||||
* Improve low speed ACC tuning
|
||||
|
||||
Version 0.7 (2019-12-13)
|
||||
========================
|
||||
* Move to SCons build system!
|
||||
* Add Lane Departure Warning (LDW) for all supported vehicles!
|
||||
* NEOS update: increase wifi speed thanks to jyoung8607!
|
||||
* Adaptive driver monitoring based on scene
|
||||
* New driving model trained end-to-end: improve lane lines and lead detection
|
||||
* Smarter torque limit alerts for all cars
|
||||
* Improve GM longitudinal control: proper computations for 15Hz radar
|
||||
* Move GM port, Toyota with DSU removed, comma pedal in community features; toggle switch required
|
||||
* Remove upload over cellular toggle: only upload qlog and qcamera files if not on wifi
|
||||
* Refactor Panda code towards ISO26262 and SIL2 compliancy
|
||||
* Forward stock FCW for Honda Nidec
|
||||
* Volkswagen port now standard: comma Harness intercepts stock camera
|
||||
|
||||
Version 0.6.6 (2019-11-05)
|
||||
========================
|
||||
* Volkswagen support thanks to jyoung8607!
|
||||
* Toyota Corolla Hybrid with TSS 2.0 support thanks to u8511049!
|
||||
* Lexus ES with TSS 2.0 support thanks to energee!
|
||||
* Fix GM ignition detection and lock safety mode not required anymore
|
||||
* Log panda firmware and dongle ID thanks to martinl!
|
||||
* New driving model: improve path prediction and lead detection
|
||||
* New driver monitoring model, 4x smaller and running on DSP
|
||||
* Display an alert and don't start openpilot if panda has wrong firmware
|
||||
* Fix bug preventing EON from terminating processes after a drive
|
||||
* Remove support for Toyota giraffe without the 120Ohm resistor
|
||||
|
||||
Version 0.6.5 (2019-10-07)
|
||||
========================
|
||||
* NEOS update: upgrade to Python3 and new installer!
|
||||
* comma Harness support!
|
||||
* New driving model: improve path prediction
|
||||
* New driver monitoring model: more accurate face and eye detection
|
||||
* Redesign offroad screen to display updates and alerts
|
||||
* Increase maximum allowed acceleration
|
||||
* Prevent car 12V battery drain by cutting off EON charge after 3 days of no drive
|
||||
* Lexus CT Hybrid support thanks to thomaspich!
|
||||
* Louder chime for critical alerts
|
||||
* Add toggle to switch to dashcam mode
|
||||
* Fix "invalid vehicle params" error on DSU-less Toyota
|
||||
|
||||
Version 0.6.4 (2019-09-08)
|
||||
========================
|
||||
* Forward stock AEB for Honda Nidec
|
||||
* Improve lane centering on banked roads
|
||||
* Always-on forward collision warning
|
||||
* Always-on driver monitoring, except for right hand drive countries
|
||||
* Driver monitoring learns the user's normal driving position
|
||||
* Honda Fit support thanks to energee!
|
||||
* Lexus IS support
|
||||
|
||||
Version 0.6.3 (2019-08-12)
|
||||
========================
|
||||
* Alert sounds from EON: requires NEOS update
|
||||
* Improve driver monitoring: eye tracking and improved awareness logic
|
||||
* Improve path prediction with new driving model
|
||||
* Improve lane positioning with wide lanes and exits
|
||||
* Improve lateral control on RAV4
|
||||
* Slow down for turns using model
|
||||
* Open sourced regression test to verify outputs against reference logs
|
||||
* Open sourced regression test to sanity check all car models
|
||||
|
||||
Version 0.6.2 (2019-07-29)
|
||||
========================
|
||||
* New driving model!
|
||||
* Improve lane tracking with double lines
|
||||
* Strongly improve stationary vehicle detection
|
||||
* Strongly reduce cases of braking due to false leads
|
||||
* Better lead tracking around turns
|
||||
* Improve cut-in prediction by using neural network
|
||||
* Improve lateral control on Toyota Camry and C-HR thanks to zorrobyte!
|
||||
* Fix unintended openpilot disengagements on Jeep thanks to adhintz!
|
||||
* Fix delayed transition to offroad when car is turned off
|
||||
|
||||
Version 0.6.1 (2019-07-21)
|
||||
========================
|
||||
* Remote SSH with comma prime and [ssh.comma.ai](https://ssh.comma.ai)
|
||||
* Panda code Misra-c2012 compliance, tested against cppcheck coverage
|
||||
* Lockout openpilot after 3 terminal alerts for driver distracted or unresponsive
|
||||
* Toyota Sienna support thanks to wocsor!
|
||||
|
||||
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 TSS 2.0
|
||||
* 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
|
||||
* Compress logs before writing to disk
|
||||
* Remove old driving data when storage reaches 90% full
|
||||
* Fix small offset in following distance
|
||||
* Various small CPU optimizations
|
||||
* Improve offroad power consumption: require NEOS Update
|
||||
* 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!
|
||||
|
||||
Version 0.5.11 (2019-04-17)
|
||||
========================
|
||||
* Add support for Subaru
|
||||
* Reduce panda power consumption by 60% when car is off
|
||||
* Fix controlsd lag every 6 minutes. This would sometimes cause disengagements
|
||||
* Fix bug in controls with new angle-offset learner in MPC
|
||||
* Reduce cpu consumption of ubloxd by rewriting it in C++
|
||||
* Improve driver monitoring model and face detection
|
||||
* Improve performance of visiond and ui
|
||||
* Honda Passport 2019 support
|
||||
* Lexus RX Hybrid 2019 support thanks to schomems!
|
||||
* Improve road selection heuristic in mapd
|
||||
* Add Lane Departure Warning to dashboard for Toyota thanks to arne182
|
||||
|
||||
Version 0.5.10 (2019-03-19)
|
||||
========================
|
||||
* Self-tuning vehicle parameters: steering offset, tire stiffness and steering ratio
|
||||
* Improve longitudinal control at low speed when lead vehicle harshly decelerates
|
||||
* Fix panda bug going unexpectedly in DCP mode when EON is connected
|
||||
* Reduce white panda power consumption by 500mW when EON is disconnected by turning off WIFI
|
||||
* New Driver Monitoring Model
|
||||
* Support QR codes for login using comma connect
|
||||
* Refactor comma pedal FW and use CRC-8 checksum algorithm for safety. Reflashing pedal is required.
|
||||
Please see `#hw-pedal` on [discord](discord.comma.ai) for assistance updating comma pedal.
|
||||
* Additional speed limit rules for Germany thanks to arne182
|
||||
* Allow negative speed limit offsets
|
||||
|
||||
Version 0.5.9 (2019-02-10)
|
||||
========================
|
||||
* Improve calibration using a dedicated neural network
|
||||
* Abstract planner in its own process to remove lags in controls process
|
||||
* Improve speed limits with country/region defaults by road type
|
||||
* Reduce mapd data usage with gzip thanks to eFiniLan
|
||||
* Zip log files in the background to reduce disk usage
|
||||
* Kia Optima support thanks to emmertex!
|
||||
* Buick Regal 2018 support thanks to HOYS!
|
||||
* Comma pedal support for Toyota thanks to wocsor! Note: tuning needed and not maintained by comma
|
||||
* Chrysler Pacifica and Jeep Grand Cherokee support thanks to adhintz!
|
||||
|
||||
Version 0.5.8 (2019-01-17)
|
||||
========================
|
||||
* Open sourced visiond
|
||||
* Auto-slowdown for upcoming turns
|
||||
* Chrysler/Jeep/Fiat support thanks to adhintz!
|
||||
* Honda Civic 2019 support thanks to csouers!
|
||||
* Improve use of car display in Toyota thanks to arne182!
|
||||
* No data upload when connected to Android or iOS hotspots and "Enable Upload Over Cellular" setting is off
|
||||
* EON stops charging when 12V battery drops below 11.8V
|
||||
|
||||
Version 0.5.7 (2018-12-06)
|
||||
========================
|
||||
* Speed limit from OpenStreetMap added to UI
|
||||
* Highlight speed limit when speed exceeds road speed limit plus a delta
|
||||
* Option to limit openpilot max speed to road speed limit plus a delta
|
||||
* Cadillac ATS support thanks to vntarasov!
|
||||
* GMC Acadia support thanks to CryptoKylan!
|
||||
* Decrease GPU power consumption
|
||||
* NEOSv8 autoupdate
|
||||
|
||||
Version 0.5.6 (2018-11-16)
|
||||
========================
|
||||
* Refresh settings layout and add feature descriptions
|
||||
* In Honda, keep stock camera on for logging and extra stock features; new openpilot giraffe setting is 0111!
|
||||
* In Toyota, option to keep stock camera on for logging and extra stock features (e.g. AHB); 120Ohm resistor required on giraffe.
|
||||
* Improve camera calibration stability
|
||||
* More tuning to Honda positive accelerations
|
||||
* Reduce brake pump use on Hondas
|
||||
* Chevrolet Malibu support thanks to tylergets!
|
||||
* Holden Astra support thanks to AlexHill!
|
||||
|
||||
Version 0.5.5 (2018-10-20)
|
||||
========================
|
||||
* Increase allowed Honda positive accelerations
|
||||
* Fix sporadic unexpected braking when passing semi-trucks in Toyota
|
||||
* Fix gear reading bug in Hyundai Elantra thanks to emmertex!
|
||||
|
||||
Version 0.5.4 (2018-09-25)
|
||||
========================
|
||||
* New Driving Model
|
||||
* New Driver Monitoring Model
|
||||
* Improve longitudinal mpc in mid-low speed braking
|
||||
* Honda Accord hybrid support thanks to energee!
|
||||
* Ship mpc binaries and sensibly reduce build time
|
||||
* Calibration more stable
|
||||
* More Hyundai and Kia cars supported thanks to emmertex!
|
||||
* Various GM Volt improvements thanks to vntarasov!
|
||||
|
||||
Version 0.5.3 (2018-09-03)
|
||||
========================
|
||||
* Hyundai Santa Fe support!
|
||||
* Honda Pilot 2019 support thanks to energee!
|
||||
* Toyota Highlander support thanks to daehahn!
|
||||
* Improve steering tuning for Honda Odyssey
|
||||
|
||||
Version 0.5.2 (2018-08-16)
|
||||
========================
|
||||
* New calibration: more accurate, a lot faster, open source!
|
||||
* Enable orbd
|
||||
* Add little endian support to CAN packer
|
||||
* Fix fingerprint for Honda Accord 1.5T
|
||||
* Improve driver monitoring model
|
||||
|
||||
Version 0.5.1 (2018-08-01)
|
||||
========================
|
||||
* Fix radar error on Civic sedan 2018
|
||||
* Improve thermal management logic
|
||||
* Alpha Toyota C-HR and Camry support!
|
||||
* Auto-switch Driver Monitoring to 3 min counter when inaccurate
|
||||
|
||||
Version 0.5 (2018-07-11)
|
||||
========================
|
||||
* Driver Monitoring (beta) option in settings!
|
||||
* Make visiond, loggerd and UI use less resources
|
||||
* 60 FPS UI
|
||||
* Better car parameters for most cars
|
||||
* New sidebar with stats
|
||||
* Remove Waze and Spotify to free up system resources
|
||||
* Remove rear view mirror option
|
||||
* Calibration 3x faster
|
||||
|
||||
Version 0.4.7.2 (2018-06-25)
|
||||
==========================
|
||||
* Fix loggerd lag issue
|
||||
* No longer prompt for updates
|
||||
* Mitigate right lane hugging for properly mounted EON (procedure on wiki)
|
||||
|
||||
Version 0.4.7.1 (2018-06-18)
|
||||
==========================
|
||||
* Fix Acura ILX steer faults
|
||||
* Fix bug in mock car
|
||||
|
||||
Version 0.4.7 (2018-06-15)
|
||||
==========================
|
||||
* New model!
|
||||
* GM Volt (and CT6 lateral) support!
|
||||
* Honda Bosch lateral support!
|
||||
* Improve actuator modeling to reduce lateral wobble
|
||||
* Minor refactor of car abstraction layer
|
||||
* Hack around orbd startup issue
|
||||
|
||||
Version 0.4.6 (2018-05-18)
|
||||
==========================
|
||||
* NEOSv6 required! Will autoupdate
|
||||
* Stability improvements
|
||||
* Fix all memory leaks
|
||||
* Update C++ compiler to clang6
|
||||
* Improve front camera exposure
|
||||
|
||||
Version 0.4.5 (2018-04-27)
|
||||
==========================
|
||||
* Release notes added to the update popup
|
||||
* Improve auto shut-off logic to disallow empty battery
|
||||
* Added onboarding instructions
|
||||
* Include orbd, the first piece of new calibration algorithm
|
||||
* Show remaining upload data instead of file numbers
|
||||
* Fix UI bugs
|
||||
* Fix memory leaks
|
||||
|
||||
Version 0.4.4 (2018-04-13)
|
||||
==========================
|
||||
* EON are flipped! Flip your EON's mount!
|
||||
* Alpha Honda Ridgeline support thanks to energee!
|
||||
* Support optional front camera recording
|
||||
* Upload over cellular toggle now applies to all files, not just video
|
||||
* Increase acceleration when closing lead gap
|
||||
* User now prompted for future updates
|
||||
* NEO no longer supported :(
|
||||
|
||||
Version 0.4.3.2 (2018-03-29)
|
||||
============================
|
||||
* Improve autofocus
|
||||
* Improve driving when only one lane line is detected
|
||||
* Added fingerprint for Toyota Corolla LE
|
||||
* Fixed Toyota Corolla steer error
|
||||
* Full-screen driving UI
|
||||
* Improved path drawing
|
||||
|
||||
Version 0.4.3.1 (2018-03-19)
|
||||
============================
|
||||
* Improve autofocus
|
||||
* Add check for MPC solution error
|
||||
* Make first distracted warning visual only
|
||||
|
||||
Version 0.4.3 (2018-03-13)
|
||||
==========================
|
||||
* Add HDR and autofocus
|
||||
* Update UI aesthetic
|
||||
* Grey panda works in Waze
|
||||
* Add alpha support for 2017 Honda Pilot
|
||||
* Slight increase in acceleration response from stop
|
||||
* Switch CAN sending to use CANPacker
|
||||
* Fix pulsing acceleration regression on Honda
|
||||
* Fix openpilot bugs when stock system is in use
|
||||
* Change starting logic for chffrplus to use battery voltage
|
||||
|
||||
Version 0.4.2 (2018-02-05)
|
||||
==========================
|
||||
* Add alpha support for 2017 Lexus RX Hybrid
|
||||
* Add alpha support for 2018 ACURA RDX
|
||||
* Updated fingerprint to include Toyota Rav4 SE and Prius Prime
|
||||
* Bugfixes for Acura ILX and Honda Odyssey
|
||||
|
||||
Version 0.4.1 (2018-01-30)
|
||||
==========================
|
||||
* Add alpha support for 2017 Toyota Corolla
|
||||
* Add alpha support for 2018 Honda Odyssey with Honda Sensing
|
||||
* Add alpha support for Grey Panda
|
||||
* Refactored car abstraction layer to make car ports easier
|
||||
* Increased steering torque limit on Honda CR-V by 30%
|
||||
|
||||
Version 0.4.0.2 (2018-01-18)
|
||||
==========================
|
||||
* Add focus adjustment slider
|
||||
* Minor bugfixes
|
||||
|
||||
Version 0.4.0.1 (2017-12-21)
|
||||
==========================
|
||||
* New UI to match chffrplus
|
||||
* Improved lateral control tuning to fix oscillations on Civic
|
||||
* Add alpha support for 2017 Toyota Rav4 Hybrid
|
||||
* Reduced CPU usage
|
||||
* Removed unnecessary utilization of fan at max speed
|
||||
* Minor bug fixes
|
||||
|
||||
Version 0.3.9 (2017-11-21)
|
||||
==========================
|
||||
* Add alpha support for 2017 Toyota Prius
|
||||
* Improved longitudinal control using model predictive control
|
||||
* Enable Forward Collision Warning
|
||||
* Acura ILX now maintains openpilot engaged at standstill when brakes are applied
|
||||
|
||||
Version 0.3.8.2 (2017-10-30)
|
||||
==========================
|
||||
* Add alpha support for 2017 Toyota RAV4
|
||||
* Smoother lateral control
|
||||
* Stay silent if stock system is connected through giraffe
|
||||
* Minor bug fixes
|
||||
|
||||
Version 0.3.7 (2017-09-30)
|
||||
==========================
|
||||
* Improved lateral control using model predictive control
|
||||
* Improved lane centering
|
||||
* Improved GPS
|
||||
* Reduced tendency of path deviation near right side exits
|
||||
* Enable engagement while the accelerator pedal is pressed
|
||||
* Enable engagement while the brake pedal is pressed, when stationary and with lead vehicle within 5m
|
||||
* Disable engagement when park brake or brake hold are active
|
||||
* Fixed sporadic longitudinal pulsing in Civic
|
||||
* Cleanups to vehicle interface
|
||||
|
||||
Version 0.3.6.1 (2017-08-15)
|
||||
============================
|
||||
* Mitigate low speed steering oscillations on some vehicles
|
||||
* Include board steering check for CR-V
|
||||
|
||||
Version 0.3.6 (2017-08-08)
|
||||
==========================
|
||||
* Fix alpha CR-V support
|
||||
* Improved GPS
|
||||
* Fix display of target speed not always matching HUD
|
||||
* Increased acceleration after stop
|
||||
* Mitigated some vehicles driving too close to the right line
|
||||
|
||||
Version 0.3.5 (2017-07-30)
|
||||
==========================
|
||||
* Fix bug where new devices would not begin calibration
|
||||
* Minor robustness improvements
|
||||
|
||||
Version 0.3.4 (2017-07-28)
|
||||
==========================
|
||||
* Improved model trained on more data
|
||||
* Much improved controls tuning
|
||||
* Performance improvements
|
||||
* Bugfixes and improvements to calibration
|
||||
* Driving log can play back video
|
||||
* Acura only: system now stays engaged below 25mph as long as brakes are applied
|
||||
|
||||
Version 0.3.3 (2017-06-28)
|
||||
===========================
|
||||
* Improved model trained on more data
|
||||
* Alpha CR-V support thanks to energee and johnnwvs!
|
||||
* Using the opendbc project for DBC files
|
||||
* Minor performance improvements
|
||||
* UI update thanks to pjlao307
|
||||
* Power off button
|
||||
* 6% more torque on the Civic
|
||||
|
||||
Version 0.3.2 (2017-05-22)
|
||||
===========================
|
||||
* Minor stability bugfixes
|
||||
* Added metrics and rear view mirror disable to settings
|
||||
* Update model with more crowdsourced data
|
||||
|
||||
Version 0.3.1 (2017-05-17)
|
||||
===========================
|
||||
* visiond stability bugfix
|
||||
* Add logging for angle and flashing
|
||||
|
||||
Version 0.3.0 (2017-05-12)
|
||||
===========================
|
||||
* Add CarParams struct to improve the abstraction layer
|
||||
* Refactor visiond IPC to support multiple clients
|
||||
* Add raw GPS and beginning support for navigation
|
||||
* Improve model in visiond using crowdsourced data
|
||||
* Add improved system logging to diagnose instability
|
||||
* Rewrite baseui in React Native
|
||||
* Moved calibration to the cloud
|
||||
|
||||
Version 0.2.9 (2017-03-01)
|
||||
===========================
|
||||
* Retain compatibility with NEOS v1
|
||||
|
||||
Version 0.2.8 (2017-02-27)
|
||||
===========================
|
||||
* Fix bug where frames were being dropped in minute 71
|
||||
|
||||
Version 0.2.7 (2017-02-08)
|
||||
===========================
|
||||
* Better performance and pictures at night
|
||||
* Fix ptr alignment issue in boardd
|
||||
* Fix brake error light, fix crash if too cold
|
||||
|
||||
Version 0.2.6 (2017-01-31)
|
||||
===========================
|
||||
* Fix bug in visiond model execution
|
||||
|
||||
Version 0.2.5 (2017-01-30)
|
||||
===========================
|
||||
* Fix race condition in manager
|
||||
|
||||
Version 0.2.4 (2017-01-27)
|
||||
===========================
|
||||
* OnePlus 3T support
|
||||
* Enable installation as NEOS app
|
||||
* Various minor bugfixes
|
||||
|
||||
Version 0.2.3 (2017-01-11)
|
||||
===========================
|
||||
* Reduce space usage by 80%
|
||||
* Add better logging
|
||||
* Add Travis CI
|
||||
|
||||
Version 0.2.2 (2017-01-10)
|
||||
===========================
|
||||
* Board triggers started signal on CAN messages
|
||||
* Improved autoexposure
|
||||
* Handle out of space, improve upload status
|
||||
|
||||
Version 0.2.1 (2016-12-14)
|
||||
===========================
|
||||
* Performance improvements, removal of more numpy
|
||||
* Fix boardd process priority
|
||||
* Make counter timer reset on use of steering wheel
|
||||
|
||||
Version 0.2 (2016-12-12)
|
||||
=========================
|
||||
* Car/Radar abstraction layers have shipped, see cereal/car.capnp
|
||||
* controlsd has been refactored
|
||||
* Shipped plant model and testing maneuvers
|
||||
* visiond exits more gracefully now
|
||||
* Hardware encoder in visiond should always init
|
||||
* ui now turns off the screen after 30 seconds
|
||||
* Switch to openpilot release branch for future releases
|
||||
* Added preliminary Docker container to run tests on PC
|
||||
|
||||
Version 0.1 (2016-11-29)
|
||||
=========================
|
||||
* Initial release of openpilot
|
||||
* Adaptive cruise control is working
|
||||
* Lane keep assist is working
|
||||
* Support for Acura ILX 2016 with AcuraWatch Plus
|
||||
* Support for Honda Civic 2016 Touring Edition
|
54
SAFETY.md
54
SAFETY.md
|
@ -1,36 +1,34 @@
|
|||
openpilot Safety
|
||||
======
|
||||
|
||||
openpilot is an Adaptive Cruise Control and Lane Keeping Assist System. Like
|
||||
other ACC and LKAS systems, openpilot requires the driver to be alert and to pay
|
||||
attention at all times. We repeat, **driver alertness is necessary, but not
|
||||
sufficient, for openpilot to be used safely**.
|
||||
openpilot is an Adaptive Cruise Control (ACC) and Automated Lane Centering (ALC) system.
|
||||
Like other ACC and ALC systems, openpilot is a failsafe passive system and it requires the
|
||||
driver to be alert and to pay attention at all times.
|
||||
|
||||
Even with an attentive driver, we must make further efforts for the system to be
|
||||
safe. We have designed openpilot with two other safety considerations.
|
||||
In order to enforce driver alertness, openpilot includes a driver monitoring feature
|
||||
that alerts the driver when distracted.
|
||||
|
||||
1. The vehicle must always be controllable by the driver.
|
||||
However, even with an attentive driver, we must make further efforts for the system to be
|
||||
safe. We repeat, **driver alertness is necessary, but not sufficient, for openpilot to be
|
||||
used safely** and openpilot is provided with no warranty of fitness for any purpose.
|
||||
|
||||
openpilot is developed in good faith to be compliant with FMVSS requirements and to follow
|
||||
industry standards of safety for Level 2 Driver Assistance Systems. In particular, we observe
|
||||
ISO26262 guidelines, including those from [pertinent documents](https://www.nhtsa.gov/sites/nhtsa.dot.gov/files/documents/13498a_812_573_alcsystemreport.pdf)
|
||||
released by NHTSA. In addition, we impose strict coding guidelines (like [MISRA C : 2012](https://www.misra.org.uk/MISRAHome/MISRAC2012/tabid/196/Default.aspx))
|
||||
on parts of openpilot that are safety relevant. We also perform software-in-the-loop,
|
||||
hardware-in-the-loop and in-vehicle tests before each software release.
|
||||
|
||||
Following Hazard and Risk Analysis and FMEA, at a very high level, we have designed openpilot
|
||||
ensuring two main safety requirements.
|
||||
|
||||
1. The driver must always be capable to immediately retake manual control of the vehicle,
|
||||
by stepping on either pedal or by pressing the cancel button.
|
||||
2. The vehicle must not alter its trajectory too quickly for the driver to safely
|
||||
react.
|
||||
react. This means that while the system is engaged, the actuators are constrained
|
||||
to operate within reasonable limits.
|
||||
|
||||
To address these, we came up with two safety principles.
|
||||
For vehicle specific implementation of the safety concept, refer to `panda/board/safety/`.
|
||||
|
||||
1. Enforced disengagements. Step on either pedal or press the cancel button to
|
||||
retake manual control of the car immediately.
|
||||
- These are hard enforced by the board, and soft enforced by the software. The
|
||||
green led on the board signifies if the board is allowing control messages.
|
||||
- Honda CAN uses both a counter and a checksum to ensure integrity and prevent
|
||||
replay of the same message.
|
||||
|
||||
2. Actuation limits. While the system is engaged, the actuators are constrained
|
||||
to operate within reasonable limits; the same limits used by the stock system on
|
||||
the Honda.
|
||||
- Without an interceptor, the gas is controlled by the PCM. The PCM limits
|
||||
acceleration to what is reasonable for a cruise control system. With an
|
||||
interceptor, the gas is clipped to 60% in longcontrol.py
|
||||
- The brake is controlled by the 0x1FA CAN message. This message allows full
|
||||
braking, although the board and the software clip it to 1/4th of the max.
|
||||
This is around .3g of braking.
|
||||
- Steering is controlled by the 0xE4 CAN message. The EPS controller in the
|
||||
car limits the torque to a very small amount, so regardless of the message,
|
||||
the controller cannot jerk the wheel.
|
||||
**Extra note**: comma.ai strongly discourages the use of openpilot forks with safety code either missing or
|
||||
not fully meeting the above requirements.
|
||||
|
|
|
@ -0,0 +1,426 @@
|
|||
import os
|
||||
import shutil
|
||||
import subprocess
|
||||
import sys
|
||||
import sysconfig
|
||||
import platform
|
||||
import numpy as np
|
||||
|
||||
TICI = os.path.isfile('/TICI')
|
||||
Decider('MD5-timestamp')
|
||||
|
||||
AddOption('--test',
|
||||
action='store_true',
|
||||
help='build test files')
|
||||
|
||||
AddOption('--kaitai',
|
||||
action='store_true',
|
||||
help='Regenerate kaitai struct parsers')
|
||||
|
||||
AddOption('--asan',
|
||||
action='store_true',
|
||||
help='turn on ASAN')
|
||||
|
||||
AddOption('--ubsan',
|
||||
action='store_true',
|
||||
help='turn on UBSan')
|
||||
|
||||
AddOption('--clazy',
|
||||
action='store_true',
|
||||
help='build with clazy')
|
||||
|
||||
AddOption('--compile_db',
|
||||
action='store_true',
|
||||
help='build clang compilation database')
|
||||
|
||||
AddOption('--mpc-generate',
|
||||
action='store_true',
|
||||
help='regenerates the mpc sources')
|
||||
|
||||
AddOption('--external-sconscript',
|
||||
action='store',
|
||||
metavar='FILE',
|
||||
dest='external_sconscript',
|
||||
help='add an external SConscript to the build')
|
||||
|
||||
real_arch = arch = subprocess.check_output(["uname", "-m"], encoding='utf8').rstrip()
|
||||
if platform.system() == "Darwin":
|
||||
arch = "Darwin"
|
||||
|
||||
if arch == "aarch64" and TICI:
|
||||
arch = "larch64"
|
||||
|
||||
USE_WEBCAM = os.getenv("USE_WEBCAM") is not None
|
||||
QCOM_REPLAY = arch == "aarch64" and os.getenv("QCOM_REPLAY") is not None
|
||||
|
||||
lenv = {
|
||||
"PATH": os.environ['PATH'],
|
||||
}
|
||||
|
||||
if arch == "aarch64" or arch == "larch64":
|
||||
lenv["LD_LIBRARY_PATH"] = '/data/data/com.termux/files/usr/lib'
|
||||
|
||||
if arch == "aarch64":
|
||||
# android
|
||||
lenv["ANDROID_DATA"] = os.environ['ANDROID_DATA']
|
||||
lenv["ANDROID_ROOT"] = os.environ['ANDROID_ROOT']
|
||||
|
||||
cpppath = [
|
||||
"#phonelibs/opencl/include",
|
||||
]
|
||||
|
||||
libpath = [
|
||||
"/usr/local/lib",
|
||||
"/usr/lib",
|
||||
"/system/vendor/lib64",
|
||||
"/system/comma/usr/lib",
|
||||
"#phonelibs/nanovg",
|
||||
]
|
||||
|
||||
if arch == "larch64":
|
||||
libpath += [
|
||||
"#phonelibs/snpe/larch64",
|
||||
"#phonelibs/libyuv/larch64/lib",
|
||||
"/usr/lib/aarch64-linux-gnu"
|
||||
]
|
||||
cpppath += [
|
||||
"#selfdrive/camerad/include",
|
||||
]
|
||||
cflags = ["-DQCOM2", "-mcpu=cortex-a57"]
|
||||
cxxflags = ["-DQCOM2", "-mcpu=cortex-a57"]
|
||||
rpath = ["/usr/local/lib"]
|
||||
else:
|
||||
libpath += [
|
||||
"#phonelibs/snpe/aarch64",
|
||||
"#phonelibs/libyuv/lib",
|
||||
"/system/vendor/lib64"
|
||||
]
|
||||
cflags = ["-DQCOM", "-mcpu=cortex-a57"]
|
||||
cxxflags = ["-DQCOM", "-mcpu=cortex-a57"]
|
||||
rpath = []
|
||||
|
||||
if QCOM_REPLAY:
|
||||
cflags += ["-DQCOM_REPLAY"]
|
||||
cxxflags += ["-DQCOM_REPLAY"]
|
||||
else:
|
||||
cflags = []
|
||||
cxxflags = []
|
||||
cpppath = []
|
||||
|
||||
if arch == "Darwin":
|
||||
yuv_dir = "mac" if real_arch != "arm64" else "mac_arm64"
|
||||
libpath = [
|
||||
f"#phonelibs/libyuv/{yuv_dir}/lib",
|
||||
"/usr/local/lib",
|
||||
"/opt/homebrew/lib",
|
||||
"/usr/local/opt/openssl/lib",
|
||||
"/opt/homebrew/opt/openssl/lib",
|
||||
"/System/Library/Frameworks/OpenGL.framework/Libraries",
|
||||
]
|
||||
cflags += ["-DGL_SILENCE_DEPRECATION"]
|
||||
cxxflags += ["-DGL_SILENCE_DEPRECATION"]
|
||||
cpppath += [
|
||||
"/opt/homebrew/include",
|
||||
"/usr/local/opt/openssl/include",
|
||||
"/opt/homebrew/opt/openssl/include"
|
||||
]
|
||||
else:
|
||||
libpath = [
|
||||
"#phonelibs/snpe/x86_64-linux-clang",
|
||||
"#phonelibs/libyuv/x64/lib",
|
||||
"#phonelibs/mapbox-gl-native-qt/x86_64",
|
||||
"#cereal",
|
||||
"#selfdrive/common",
|
||||
"/usr/lib",
|
||||
"/usr/local/lib",
|
||||
]
|
||||
|
||||
rpath = [
|
||||
"phonelibs/snpe/x86_64-linux-clang",
|
||||
"cereal",
|
||||
"selfdrive/common"
|
||||
]
|
||||
|
||||
# allows shared libraries to work globally
|
||||
rpath = [os.path.join(os.getcwd(), x) for x in rpath]
|
||||
|
||||
if GetOption('asan'):
|
||||
ccflags = ["-fsanitize=address", "-fno-omit-frame-pointer"]
|
||||
ldflags = ["-fsanitize=address"]
|
||||
elif GetOption('ubsan'):
|
||||
ccflags = ["-fsanitize=undefined"]
|
||||
ldflags = ["-fsanitize=undefined"]
|
||||
else:
|
||||
ccflags = []
|
||||
ldflags = []
|
||||
|
||||
# no --as-needed on mac linker
|
||||
if arch != "Darwin":
|
||||
ldflags += ["-Wl,--as-needed"]
|
||||
|
||||
# change pythonpath to this
|
||||
lenv["PYTHONPATH"] = Dir("#").path
|
||||
|
||||
env = Environment(
|
||||
ENV=lenv,
|
||||
CCFLAGS=[
|
||||
"-g",
|
||||
"-fPIC",
|
||||
"-O2",
|
||||
"-Wunused",
|
||||
"-Werror",
|
||||
"-Wno-unknown-warning-option",
|
||||
"-Wno-deprecated-register",
|
||||
"-Wno-register",
|
||||
"-Wno-inconsistent-missing-override",
|
||||
"-Wno-c99-designator",
|
||||
"-Wno-reorder-init-list",
|
||||
] + cflags + ccflags,
|
||||
|
||||
CPPPATH=cpppath + [
|
||||
"#",
|
||||
"#phonelibs/catch2/include",
|
||||
"#phonelibs/bzip2",
|
||||
"#phonelibs/libyuv/include",
|
||||
"#phonelibs/openmax/include",
|
||||
"#phonelibs/json11",
|
||||
"#phonelibs/curl/include",
|
||||
"#phonelibs/libgralloc/include",
|
||||
"#phonelibs/android_frameworks_native/include",
|
||||
"#phonelibs/android_hardware_libhardware/include",
|
||||
"#phonelibs/android_system_core/include",
|
||||
"#phonelibs/linux/include",
|
||||
"#phonelibs/snpe/include",
|
||||
"#phonelibs/mapbox-gl-native-qt/include",
|
||||
"#phonelibs/nanovg",
|
||||
"#phonelibs/qrcode",
|
||||
"#phonelibs",
|
||||
"#cereal",
|
||||
"#cereal/messaging",
|
||||
"#cereal/visionipc",
|
||||
"#opendbc/can",
|
||||
],
|
||||
|
||||
CC='clang',
|
||||
CXX='clang++',
|
||||
LINKFLAGS=ldflags,
|
||||
|
||||
RPATH=rpath,
|
||||
|
||||
CFLAGS=["-std=gnu11"] + cflags,
|
||||
CXXFLAGS=["-std=c++1z"] + cxxflags,
|
||||
LIBPATH=libpath + [
|
||||
"#cereal",
|
||||
"#phonelibs",
|
||||
"#opendbc/can",
|
||||
"#selfdrive/boardd",
|
||||
"#selfdrive/common",
|
||||
],
|
||||
CYTHONCFILESUFFIX=".cpp",
|
||||
COMPILATIONDB_USE_ABSPATH=True,
|
||||
tools=["default", "cython", "compilation_db"],
|
||||
)
|
||||
|
||||
if GetOption('compile_db'):
|
||||
env.CompilationDatabase('compile_commands.json')
|
||||
|
||||
if os.environ.get('SCONS_CACHE'):
|
||||
cache_dir = '/tmp/scons_cache'
|
||||
if TICI:
|
||||
cache_dir = '/data/scons_cache'
|
||||
|
||||
if QCOM_REPLAY:
|
||||
cache_dir = '/tmp/scons_cache_qcom_replay'
|
||||
|
||||
CacheDir(cache_dir)
|
||||
|
||||
node_interval = 5
|
||||
node_count = 0
|
||||
def progress_function(node):
|
||||
global node_count
|
||||
node_count += node_interval
|
||||
sys.stderr.write("progress: %d\n" % node_count)
|
||||
|
||||
if os.environ.get('SCONS_PROGRESS'):
|
||||
Progress(progress_function, interval=node_interval)
|
||||
|
||||
SHARED = False
|
||||
|
||||
def abspath(x):
|
||||
if arch == 'aarch64':
|
||||
pth = os.path.join("/data/pythonpath", x[0].path)
|
||||
env.Depends(pth, x)
|
||||
return File(pth)
|
||||
else:
|
||||
# rpath works elsewhere
|
||||
return x[0].path.rsplit("/", 1)[1][:-3]
|
||||
|
||||
# Cython build enviroment
|
||||
py_include = sysconfig.get_paths()['include']
|
||||
envCython = env.Clone()
|
||||
envCython["CPPPATH"] += [py_include, np.get_include()]
|
||||
envCython["CCFLAGS"] += ["-Wno-#warnings", "-Wno-deprecated-declarations"]
|
||||
|
||||
envCython["LIBS"] = []
|
||||
if arch == "Darwin":
|
||||
envCython["LINKFLAGS"] = ["-bundle", "-undefined", "dynamic_lookup"]
|
||||
elif arch == "aarch64":
|
||||
envCython["LINKFLAGS"] = ["-shared"]
|
||||
envCython["LIBS"] = [os.path.basename(py_include)]
|
||||
else:
|
||||
envCython["LINKFLAGS"] = ["-pthread", "-shared"]
|
||||
|
||||
Export('envCython')
|
||||
|
||||
# Qt build environment
|
||||
qt_env = env.Clone()
|
||||
qt_modules = ["Widgets", "Gui", "Core", "Network", "Concurrent", "Multimedia", "Quick", "Qml", "QuickWidgets", "Location", "Positioning"]
|
||||
if arch != "aarch64":
|
||||
qt_modules += ["DBus"]
|
||||
|
||||
qt_libs = []
|
||||
if arch == "Darwin":
|
||||
if real_arch == "arm64":
|
||||
qt_env['QTDIR'] = "/opt/homebrew/opt/qt@5"
|
||||
else:
|
||||
qt_env['QTDIR'] = "/usr/local/opt/qt@5"
|
||||
qt_dirs = [
|
||||
os.path.join(qt_env['QTDIR'], "include"),
|
||||
]
|
||||
qt_dirs += [f"{qt_env['QTDIR']}/include/Qt{m}" for m in qt_modules]
|
||||
qt_env["LINKFLAGS"] += ["-F" + os.path.join(qt_env['QTDIR'], "lib")]
|
||||
qt_env["FRAMEWORKS"] += [f"Qt{m}" for m in qt_modules] + ["OpenGL"]
|
||||
elif arch == "aarch64":
|
||||
qt_env['QTDIR'] = "/system/comma/usr"
|
||||
qt_dirs = [
|
||||
f"/system/comma/usr/include/qt",
|
||||
]
|
||||
qt_dirs += [f"/system/comma/usr/include/qt/Qt{m}" for m in qt_modules]
|
||||
|
||||
qt_libs = [f"Qt5{m}" for m in qt_modules]
|
||||
qt_libs += ['EGL', 'GLESv3', 'c++_shared']
|
||||
else:
|
||||
qt_env['QTDIR'] = "/usr"
|
||||
qt_dirs = [
|
||||
f"/usr/include/{real_arch}-linux-gnu/qt5",
|
||||
f"/usr/include/{real_arch}-linux-gnu/qt5/QtGui/5.12.8/QtGui",
|
||||
]
|
||||
qt_dirs += [f"/usr/include/{real_arch}-linux-gnu/qt5/Qt{m}" for m in qt_modules]
|
||||
|
||||
qt_libs = [f"Qt5{m}" for m in qt_modules]
|
||||
if arch == "larch64":
|
||||
qt_libs += ["GLESv2", "wayland-client"]
|
||||
elif arch != "Darwin":
|
||||
qt_libs += ["GL"]
|
||||
|
||||
qt_env.Tool('qt')
|
||||
qt_env['CPPPATH'] += qt_dirs + ["#selfdrive/ui/qt/"]
|
||||
qt_flags = [
|
||||
"-D_REENTRANT",
|
||||
"-DQT_NO_DEBUG",
|
||||
"-DQT_WIDGETS_LIB",
|
||||
"-DQT_GUI_LIB",
|
||||
"-DQT_QUICK_LIB",
|
||||
"-DQT_QUICKWIDGETS_LIB",
|
||||
"-DQT_QML_LIB",
|
||||
"-DQT_CORE_LIB"
|
||||
]
|
||||
qt_env['CXXFLAGS'] += qt_flags
|
||||
qt_env['LIBPATH'] += ['#selfdrive/ui']
|
||||
qt_env['LIBS'] = qt_libs
|
||||
|
||||
if GetOption("clazy"):
|
||||
checks = [
|
||||
"level0",
|
||||
"level1",
|
||||
"no-range-loop",
|
||||
"no-non-pod-global-static",
|
||||
]
|
||||
qt_env['CXX'] = 'clazy'
|
||||
qt_env['ENV']['CLAZY_IGNORE_DIRS'] = qt_dirs[0]
|
||||
qt_env['ENV']['CLAZY_CHECKS'] = ','.join(checks)
|
||||
|
||||
Export('env', 'qt_env', 'arch', 'real_arch', 'SHARED', 'USE_WEBCAM', 'QCOM_REPLAY')
|
||||
|
||||
# cereal and messaging are shared with the system
|
||||
SConscript(['cereal/SConscript'])
|
||||
if SHARED:
|
||||
cereal = abspath([File('cereal/libcereal_shared.so')])
|
||||
messaging = abspath([File('cereal/libmessaging_shared.so')])
|
||||
else:
|
||||
cereal = [File('#cereal/libcereal.a')]
|
||||
messaging = [File('#cereal/libmessaging.a')]
|
||||
visionipc = [File('#cereal/libvisionipc.a')]
|
||||
|
||||
Export('cereal', 'messaging')
|
||||
|
||||
SConscript(['selfdrive/common/SConscript'])
|
||||
Import('_common', '_gpucommon', '_gpu_libs')
|
||||
|
||||
if SHARED:
|
||||
common, gpucommon = abspath(common), abspath(gpucommon)
|
||||
else:
|
||||
common = [_common, 'json11']
|
||||
gpucommon = [_gpucommon] + _gpu_libs
|
||||
|
||||
Export('common', 'gpucommon', 'visionipc')
|
||||
|
||||
# Build rednose library and ekf models
|
||||
|
||||
rednose_config = {
|
||||
'generated_folder': '#selfdrive/locationd/models/generated',
|
||||
'to_build': {
|
||||
'live': ('#selfdrive/locationd/models/live_kf.py', True, ['live_kf_constants.h']),
|
||||
'car': ('#selfdrive/locationd/models/car_kf.py', True, []),
|
||||
},
|
||||
}
|
||||
|
||||
if arch != "aarch64":
|
||||
rednose_config['to_build'].update({
|
||||
'gnss': ('#selfdrive/locationd/models/gnss_kf.py', True, []),
|
||||
'loc_4': ('#selfdrive/locationd/models/loc_kf.py', True, []),
|
||||
'pos_computer_4': ('#rednose/helpers/lst_sq_computer.py', False, []),
|
||||
'pos_computer_5': ('#rednose/helpers/lst_sq_computer.py', False, []),
|
||||
'feature_handler_5': ('#rednose/helpers/feature_handler.py', False, []),
|
||||
'lane': ('#xx/pipeline/lib/ekf/lane_kf.py', True, []),
|
||||
})
|
||||
|
||||
Export('rednose_config')
|
||||
SConscript(['rednose/SConscript'])
|
||||
|
||||
# Build openpilot
|
||||
|
||||
SConscript(['cereal/SConscript'])
|
||||
SConscript(['panda/board/SConscript'])
|
||||
SConscript(['opendbc/can/SConscript'])
|
||||
|
||||
SConscript(['phonelibs/SConscript'])
|
||||
|
||||
SConscript(['common/SConscript'])
|
||||
SConscript(['common/kalman/SConscript'])
|
||||
SConscript(['common/transformations/SConscript'])
|
||||
|
||||
SConscript(['selfdrive/camerad/SConscript'])
|
||||
SConscript(['selfdrive/modeld/SConscript'])
|
||||
|
||||
SConscript(['selfdrive/controls/lib/cluster/SConscript'])
|
||||
SConscript(['selfdrive/controls/lib/lateral_mpc/SConscript'])
|
||||
SConscript(['selfdrive/controls/lib/longitudinal_mpc/SConscript'])
|
||||
SConscript(['selfdrive/controls/lib/longitudinal_mpc_model/SConscript'])
|
||||
|
||||
SConscript(['selfdrive/boardd/SConscript'])
|
||||
SConscript(['selfdrive/proclogd/SConscript'])
|
||||
SConscript(['selfdrive/clocksd/SConscript'])
|
||||
|
||||
SConscript(['selfdrive/loggerd/SConscript'])
|
||||
|
||||
SConscript(['selfdrive/locationd/SConscript'])
|
||||
SConscript(['selfdrive/sensord/SConscript'])
|
||||
SConscript(['selfdrive/ui/SConscript'])
|
||||
|
||||
if arch != "Darwin":
|
||||
SConscript(['selfdrive/logcatd/SConscript'])
|
||||
|
||||
external_sconscript = GetOption('external_sconscript')
|
||||
if external_sconscript:
|
||||
SConscript([external_sconscript])
|
14
TODO.md
14
TODO.md
|
@ -1,14 +0,0 @@
|
|||
TODO
|
||||
======
|
||||
|
||||
An incomplete list of known issues and desired featues.
|
||||
|
||||
- TX and RX amounts on UI are wrong for a few frames at startup because we
|
||||
subtract (total sent - 0). We should initialize sent bytes before displaying.
|
||||
|
||||
- Rewrite common/dbc.py to be faster and cleaner, potentially in C++.
|
||||
|
||||
- Add module and class level documentation where appropriate.
|
||||
|
||||
- Fix lock file cleanup so there isn't always 1 pending upload when the vehicle
|
||||
shuts off.
|
|
@ -1,43 +0,0 @@
|
|||
# :set noet
|
||||
PROJ_NAME = comma
|
||||
|
||||
CFLAGS = -g -O0 -Wall
|
||||
CFLAGS += -mlittle-endian -mthumb -mcpu=cortex-m3
|
||||
CFLAGS += -msoft-float -DSTM32F2 -DSTM32F205xx
|
||||
CFLAGS += -I inc -nostdlib
|
||||
CFLAGS += -Tstm32_flash.ld
|
||||
|
||||
CC = arm-none-eabi-gcc
|
||||
OBJCOPY = arm-none-eabi-objcopy
|
||||
OBJDUMP = arm-none-eabi-objdump
|
||||
|
||||
MACHINE = $(shell uname -m)
|
||||
|
||||
all: obj/$(PROJ_NAME).bin
|
||||
#$(OBJDUMP) -d obj/$(PROJ_NAME).elf
|
||||
./tools/enter_download_mode.py
|
||||
./tools/dfu-util-$(MACHINE) -a 0 -s 0x08000000 -D $<
|
||||
./tools/dfu-util-$(MACHINE) --reset-stm32 -a 0 -s 0x08000000
|
||||
|
||||
ifneq ($(wildcard ../.git/HEAD),)
|
||||
obj/gitversion.h: ../.git/HEAD ../.git/index
|
||||
echo "const uint8_t gitversion[] = \"$(shell git rev-parse HEAD)\";" > $@
|
||||
else
|
||||
obj/gitversion.h:
|
||||
echo "const uint8_t gitversion[] = \"RELEASE\";" > $@
|
||||
endif
|
||||
|
||||
obj/main.o: main.c *.h obj/gitversion.h
|
||||
$(CC) $(CFLAGS) -o $@ -c $<
|
||||
|
||||
obj/startup_stm32f205xx.o: startup_stm32f205xx.s
|
||||
mkdir -p obj
|
||||
$(CC) $(CFLAGS) -o $@ -c $<
|
||||
|
||||
obj/$(PROJ_NAME).bin: obj/startup_stm32f205xx.o obj/main.o
|
||||
$(CC) $(CFLAGS) -o obj/$(PROJ_NAME).elf $^
|
||||
$(OBJCOPY) -v -O binary obj/$(PROJ_NAME).elf $@
|
||||
|
||||
clean:
|
||||
rm -f obj/*
|
||||
|
38
board/adc.h
38
board/adc.h
|
@ -1,38 +0,0 @@
|
|||
// ACCEL1 = ADC10
|
||||
// ACCEL2 = ADC11
|
||||
// VOLT_S = ADC12
|
||||
// CURR_S = ADC13
|
||||
|
||||
#define ADCCHAN_ACCEL0 10
|
||||
#define ADCCHAN_ACCEL1 11
|
||||
#define ADCCHAN_VOLTAGE 12
|
||||
#define ADCCHAN_CURRENT 13
|
||||
|
||||
void adc_init() {
|
||||
// global setup
|
||||
ADC->CCR = ADC_CCR_TSVREFE | ADC_CCR_VBATE;
|
||||
//ADC1->CR2 = ADC_CR2_ADON | ADC_CR2_EOCS | ADC_CR2_DDS;
|
||||
ADC1->CR2 = ADC_CR2_ADON;
|
||||
|
||||
// long
|
||||
ADC1->SMPR1 = ADC_SMPR1_SMP10 | ADC_SMPR1_SMP11 | ADC_SMPR1_SMP12 | ADC_SMPR1_SMP13;
|
||||
}
|
||||
|
||||
uint32_t adc_get(int channel) {
|
||||
|
||||
// includes length
|
||||
//ADC1->SQR1 = 0;
|
||||
|
||||
// select channel
|
||||
ADC1->JSQR = channel << 15;
|
||||
|
||||
//ADC1->CR1 = ADC_CR1_DISCNUM_0;
|
||||
//ADC1->CR1 = ADC_CR1_EOCIE;
|
||||
|
||||
ADC1->SR &= ~(ADC_SR_JEOC);
|
||||
ADC1->CR2 |= ADC_CR2_JSWSTART;
|
||||
while (!(ADC1->SR & ADC_SR_JEOC));
|
||||
|
||||
return ADC1->JDR1;
|
||||
}
|
||||
|
75
board/can.h
75
board/can.h
|
@ -1,75 +0,0 @@
|
|||
void can_init(CAN_TypeDef *CAN) {
|
||||
CAN->MCR = CAN_MCR_TTCM | CAN_MCR_INRQ;
|
||||
while((CAN->MSR & CAN_MSR_INAK) != CAN_MSR_INAK);
|
||||
puts("CAN initting\n");
|
||||
|
||||
// PCLK = 24000000, 500000 is 48 clocks
|
||||
// from http://www.bittiming.can-wiki.ino/
|
||||
CAN->BTR = 0x001c0002;
|
||||
|
||||
// loopback mode for debugging
|
||||
#ifdef CAN_LOOPBACK_MODE
|
||||
CAN->BTR |= CAN_BTR_SILM | CAN_BTR_LBKM;
|
||||
#endif
|
||||
|
||||
// reset
|
||||
CAN->MCR = CAN_MCR_TTCM;
|
||||
while((CAN->MSR & CAN_MSR_INAK) == CAN_MSR_INAK);
|
||||
puts("CAN init done\n");
|
||||
|
||||
// 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 all CAN interrupts
|
||||
CAN->IER = 0xFFFFFFFF;
|
||||
//CAN->IER = CAN_IER_TMEIE | CAN_IER_FMPIE0 | CAN_IER_FMPIE1;
|
||||
}
|
||||
|
||||
// CAN error
|
||||
void can_sce(CAN_TypeDef *CAN) {
|
||||
#ifdef DEBUG
|
||||
puts("MSR:");
|
||||
puth(CAN->MSR);
|
||||
puts(" TSR:");
|
||||
puth(CAN->TSR);
|
||||
puts(" RF0R:");
|
||||
puth(CAN->RF0R);
|
||||
puts(" RF1R:");
|
||||
puth(CAN->RF1R);
|
||||
puts(" ESR:");
|
||||
puth(CAN->ESR);
|
||||
puts("\n");
|
||||
#endif
|
||||
|
||||
// clear
|
||||
//CAN->sTxMailBox[0].TIR &= ~(CAN_TI0R_TXRQ);
|
||||
CAN->TSR |= CAN_TSR_ABRQ0;
|
||||
//CAN->ESR |= CAN_ESR_LEC;
|
||||
//CAN->MSR &= ~(CAN_MSR_ERRI);
|
||||
CAN->MSR = CAN->MSR;
|
||||
}
|
||||
|
||||
int can_cksum(uint8_t *dat, int len, int addr, int idx) {
|
||||
int i;
|
||||
int s = 0;
|
||||
for (i = 0; i < len; i++) {
|
||||
s += (dat[i] >> 4);
|
||||
s += dat[i] & 0xF;
|
||||
}
|
||||
s += (addr>>0)&0xF;
|
||||
s += (addr>>4)&0xF;
|
||||
s += (addr>>8)&0xF;
|
||||
s += idx;
|
||||
s = 8-s;
|
||||
return s&0xF;
|
||||
}
|
||||
|
16
board/dac.h
16
board/dac.h
|
@ -1,16 +0,0 @@
|
|||
void dac_init() {
|
||||
// no buffers required since we have an opamp
|
||||
//DAC->CR = DAC_CR_EN1 | DAC_CR_BOFF1 | DAC_CR_EN2 | DAC_CR_BOFF2;
|
||||
DAC->DHR12R1 = 0;
|
||||
DAC->DHR12R2 = 0;
|
||||
DAC->CR = DAC_CR_EN1 | DAC_CR_EN2;
|
||||
}
|
||||
|
||||
void dac_set(int channel, uint32_t value) {
|
||||
if (channel == 0) {
|
||||
DAC->DHR12R1 = value;
|
||||
} else if (channel == 1) {
|
||||
DAC->DHR12R2 = value;
|
||||
}
|
||||
}
|
||||
|
1211
board/inc/core_cm3.h
1211
board/inc/core_cm3.h
File diff suppressed because it is too large
Load Diff
|
@ -1,609 +0,0 @@
|
|||
/**************************************************************************//**
|
||||
* @file core_cmFunc.h
|
||||
* @brief CMSIS Cortex-M Core Function Access Header File
|
||||
* @version V2.10
|
||||
* @date 26. July 2011
|
||||
*
|
||||
* @note
|
||||
* Copyright (C) 2009-2011 ARM Limited. All rights reserved.
|
||||
*
|
||||
* @par
|
||||
* ARM Limited (ARM) is supplying this software for use with Cortex-M
|
||||
* processor based microcontrollers. This file can be freely distributed
|
||||
* within development tools that are supporting such ARM based processors.
|
||||
*
|
||||
* @par
|
||||
* THIS SOFTWARE IS PROVIDED "AS IS". NO WARRANTIES, WHETHER EXPRESS, IMPLIED
|
||||
* OR STATUTORY, INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE.
|
||||
* ARM SHALL NOT, IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, OR
|
||||
* CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER.
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
#ifndef __CORE_CMFUNC_H
|
||||
#define __CORE_CMFUNC_H
|
||||
|
||||
|
||||
/* ########################### Core Function Access ########################### */
|
||||
/** \ingroup CMSIS_Core_FunctionInterface
|
||||
\defgroup CMSIS_Core_RegAccFunctions CMSIS Core Register Access Functions
|
||||
@{
|
||||
*/
|
||||
|
||||
#if defined ( __CC_ARM ) /*------------------RealView Compiler -----------------*/
|
||||
/* ARM armcc specific functions */
|
||||
|
||||
#if (__ARMCC_VERSION < 400677)
|
||||
#error "Please use ARM Compiler Toolchain V4.0.677 or later!"
|
||||
#endif
|
||||
|
||||
/* intrinsic void __enable_irq(); */
|
||||
/* intrinsic void __disable_irq(); */
|
||||
|
||||
/** \brief Get Control Register
|
||||
|
||||
This function returns the content of the Control Register.
|
||||
|
||||
\return Control Register value
|
||||
*/
|
||||
static __INLINE uint32_t __get_CONTROL(void)
|
||||
{
|
||||
register uint32_t __regControl __ASM("control");
|
||||
return(__regControl);
|
||||
}
|
||||
|
||||
|
||||
/** \brief Set Control Register
|
||||
|
||||
This function writes the given value to the Control Register.
|
||||
|
||||
\param [in] control Control Register value to set
|
||||
*/
|
||||
static __INLINE void __set_CONTROL(uint32_t control)
|
||||
{
|
||||
register uint32_t __regControl __ASM("control");
|
||||
__regControl = control;
|
||||
}
|
||||
|
||||
|
||||
/** \brief Get ISPR Register
|
||||
|
||||
This function returns the content of the ISPR Register.
|
||||
|
||||
\return ISPR Register value
|
||||
*/
|
||||
static __INLINE uint32_t __get_IPSR(void)
|
||||
{
|
||||
register uint32_t __regIPSR __ASM("ipsr");
|
||||
return(__regIPSR);
|
||||
}
|
||||
|
||||
|
||||
/** \brief Get APSR Register
|
||||
|
||||
This function returns the content of the APSR Register.
|
||||
|
||||
\return APSR Register value
|
||||
*/
|
||||
static __INLINE uint32_t __get_APSR(void)
|
||||
{
|
||||
register uint32_t __regAPSR __ASM("apsr");
|
||||
return(__regAPSR);
|
||||
}
|
||||
|
||||
|
||||
/** \brief Get xPSR Register
|
||||
|
||||
This function returns the content of the xPSR Register.
|
||||
|
||||
\return xPSR Register value
|
||||
*/
|
||||
static __INLINE uint32_t __get_xPSR(void)
|
||||
{
|
||||
register uint32_t __regXPSR __ASM("xpsr");
|
||||
return(__regXPSR);
|
||||
}
|
||||
|
||||
|
||||
/** \brief Get Process Stack Pointer
|
||||
|
||||
This function returns the current value of the Process Stack Pointer (PSP).
|
||||
|
||||
\return PSP Register value
|
||||
*/
|
||||
static __INLINE uint32_t __get_PSP(void)
|
||||
{
|
||||
register uint32_t __regProcessStackPointer __ASM("psp");
|
||||
return(__regProcessStackPointer);
|
||||
}
|
||||
|
||||
|
||||
/** \brief Set Process Stack Pointer
|
||||
|
||||
This function assigns the given value to the Process Stack Pointer (PSP).
|
||||
|
||||
\param [in] topOfProcStack Process Stack Pointer value to set
|
||||
*/
|
||||
static __INLINE void __set_PSP(uint32_t topOfProcStack)
|
||||
{
|
||||
register uint32_t __regProcessStackPointer __ASM("psp");
|
||||
__regProcessStackPointer = topOfProcStack;
|
||||
}
|
||||
|
||||
|
||||
/** \brief Get Main Stack Pointer
|
||||
|
||||
This function returns the current value of the Main Stack Pointer (MSP).
|
||||
|
||||
\return MSP Register value
|
||||
*/
|
||||
static __INLINE uint32_t __get_MSP(void)
|
||||
{
|
||||
register uint32_t __regMainStackPointer __ASM("msp");
|
||||
return(__regMainStackPointer);
|
||||
}
|
||||
|
||||
|
||||
/** \brief Set Main Stack Pointer
|
||||
|
||||
This function assigns the given value to the Main Stack Pointer (MSP).
|
||||
|
||||
\param [in] topOfMainStack Main Stack Pointer value to set
|
||||
*/
|
||||
static __INLINE void __set_MSP(uint32_t topOfMainStack)
|
||||
{
|
||||
register uint32_t __regMainStackPointer __ASM("msp");
|
||||
__regMainStackPointer = topOfMainStack;
|
||||
}
|
||||
|
||||
|
||||
/** \brief Get Priority Mask
|
||||
|
||||
This function returns the current state of the priority mask bit from the Priority Mask Register.
|
||||
|
||||
\return Priority Mask value
|
||||
*/
|
||||
static __INLINE uint32_t __get_PRIMASK(void)
|
||||
{
|
||||
register uint32_t __regPriMask __ASM("primask");
|
||||
return(__regPriMask);
|
||||
}
|
||||
|
||||
|
||||
/** \brief Set Priority Mask
|
||||
|
||||
This function assigns the given value to the Priority Mask Register.
|
||||
|
||||
\param [in] priMask Priority Mask
|
||||
*/
|
||||
static __INLINE void __set_PRIMASK(uint32_t priMask)
|
||||
{
|
||||
register uint32_t __regPriMask __ASM("primask");
|
||||
__regPriMask = (priMask);
|
||||
}
|
||||
|
||||
|
||||
#if (__CORTEX_M >= 0x03)
|
||||
|
||||
/** \brief Enable FIQ
|
||||
|
||||
This function enables FIQ interrupts by clearing the F-bit in the CPSR.
|
||||
Can only be executed in Privileged modes.
|
||||
*/
|
||||
#define __enable_fault_irq __enable_fiq
|
||||
|
||||
|
||||
/** \brief Disable FIQ
|
||||
|
||||
This function disables FIQ interrupts by setting the F-bit in the CPSR.
|
||||
Can only be executed in Privileged modes.
|
||||
*/
|
||||
#define __disable_fault_irq __disable_fiq
|
||||
|
||||
|
||||
/** \brief Get Base Priority
|
||||
|
||||
This function returns the current value of the Base Priority register.
|
||||
|
||||
\return Base Priority register value
|
||||
*/
|
||||
static __INLINE uint32_t __get_BASEPRI(void)
|
||||
{
|
||||
register uint32_t __regBasePri __ASM("basepri");
|
||||
return(__regBasePri);
|
||||
}
|
||||
|
||||
|
||||
/** \brief Set Base Priority
|
||||
|
||||
This function assigns the given value to the Base Priority register.
|
||||
|
||||
\param [in] basePri Base Priority value to set
|
||||
*/
|
||||
static __INLINE void __set_BASEPRI(uint32_t basePri)
|
||||
{
|
||||
register uint32_t __regBasePri __ASM("basepri");
|
||||
__regBasePri = (basePri & 0xff);
|
||||
}
|
||||
|
||||
|
||||
/** \brief Get Fault Mask
|
||||
|
||||
This function returns the current value of the Fault Mask register.
|
||||
|
||||
\return Fault Mask register value
|
||||
*/
|
||||
static __INLINE uint32_t __get_FAULTMASK(void)
|
||||
{
|
||||
register uint32_t __regFaultMask __ASM("faultmask");
|
||||
return(__regFaultMask);
|
||||
}
|
||||
|
||||
|
||||
/** \brief Set Fault Mask
|
||||
|
||||
This function assigns the given value to the Fault Mask register.
|
||||
|
||||
\param [in] faultMask Fault Mask value to set
|
||||
*/
|
||||
static __INLINE void __set_FAULTMASK(uint32_t faultMask)
|
||||
{
|
||||
register uint32_t __regFaultMask __ASM("faultmask");
|
||||
__regFaultMask = (faultMask & (uint32_t)1);
|
||||
}
|
||||
|
||||
#endif /* (__CORTEX_M >= 0x03) */
|
||||
|
||||
|
||||
#if (__CORTEX_M == 0x04)
|
||||
|
||||
/** \brief Get FPSCR
|
||||
|
||||
This function returns the current value of the Floating Point Status/Control register.
|
||||
|
||||
\return Floating Point Status/Control register value
|
||||
*/
|
||||
static __INLINE uint32_t __get_FPSCR(void)
|
||||
{
|
||||
#if (__FPU_PRESENT == 1) && (__FPU_USED == 1)
|
||||
register uint32_t __regfpscr __ASM("fpscr");
|
||||
return(__regfpscr);
|
||||
#else
|
||||
return(0);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
/** \brief Set FPSCR
|
||||
|
||||
This function assigns the given value to the Floating Point Status/Control register.
|
||||
|
||||
\param [in] fpscr Floating Point Status/Control value to set
|
||||
*/
|
||||
static __INLINE void __set_FPSCR(uint32_t fpscr)
|
||||
{
|
||||
#if (__FPU_PRESENT == 1) && (__FPU_USED == 1)
|
||||
register uint32_t __regfpscr __ASM("fpscr");
|
||||
__regfpscr = (fpscr);
|
||||
#endif
|
||||
}
|
||||
|
||||
#endif /* (__CORTEX_M == 0x04) */
|
||||
|
||||
|
||||
#elif defined ( __ICCARM__ ) /*------------------ ICC Compiler -------------------*/
|
||||
/* IAR iccarm specific functions */
|
||||
|
||||
#include <cmsis_iar.h>
|
||||
|
||||
#elif defined ( __GNUC__ ) /*------------------ GNU Compiler ---------------------*/
|
||||
/* GNU gcc specific functions */
|
||||
|
||||
/** \brief Enable IRQ Interrupts
|
||||
|
||||
This function enables IRQ interrupts by clearing the I-bit in the CPSR.
|
||||
Can only be executed in Privileged modes.
|
||||
*/
|
||||
__attribute__( ( always_inline ) ) static __INLINE void __enable_irq(void)
|
||||
{
|
||||
__ASM volatile ("cpsie i");
|
||||
}
|
||||
|
||||
|
||||
/** \brief Disable IRQ Interrupts
|
||||
|
||||
This function disables IRQ interrupts by setting the I-bit in the CPSR.
|
||||
Can only be executed in Privileged modes.
|
||||
*/
|
||||
__attribute__( ( always_inline ) ) static __INLINE void __disable_irq(void)
|
||||
{
|
||||
__ASM volatile ("cpsid i");
|
||||
}
|
||||
|
||||
|
||||
/** \brief Get Control Register
|
||||
|
||||
This function returns the content of the Control Register.
|
||||
|
||||
\return Control Register value
|
||||
*/
|
||||
__attribute__( ( always_inline ) ) static __INLINE uint32_t __get_CONTROL(void)
|
||||
{
|
||||
uint32_t result;
|
||||
|
||||
__ASM volatile ("MRS %0, control" : "=r" (result) );
|
||||
return(result);
|
||||
}
|
||||
|
||||
|
||||
/** \brief Set Control Register
|
||||
|
||||
This function writes the given value to the Control Register.
|
||||
|
||||
\param [in] control Control Register value to set
|
||||
*/
|
||||
__attribute__( ( always_inline ) ) static __INLINE void __set_CONTROL(uint32_t control)
|
||||
{
|
||||
__ASM volatile ("MSR control, %0" : : "r" (control) );
|
||||
}
|
||||
|
||||
|
||||
/** \brief Get ISPR Register
|
||||
|
||||
This function returns the content of the ISPR Register.
|
||||
|
||||
\return ISPR Register value
|
||||
*/
|
||||
__attribute__( ( always_inline ) ) static __INLINE uint32_t __get_IPSR(void)
|
||||
{
|
||||
uint32_t result;
|
||||
|
||||
__ASM volatile ("MRS %0, ipsr" : "=r" (result) );
|
||||
return(result);
|
||||
}
|
||||
|
||||
|
||||
/** \brief Get APSR Register
|
||||
|
||||
This function returns the content of the APSR Register.
|
||||
|
||||
\return APSR Register value
|
||||
*/
|
||||
__attribute__( ( always_inline ) ) static __INLINE uint32_t __get_APSR(void)
|
||||
{
|
||||
uint32_t result;
|
||||
|
||||
__ASM volatile ("MRS %0, apsr" : "=r" (result) );
|
||||
return(result);
|
||||
}
|
||||
|
||||
|
||||
/** \brief Get xPSR Register
|
||||
|
||||
This function returns the content of the xPSR Register.
|
||||
|
||||
\return xPSR Register value
|
||||
*/
|
||||
__attribute__( ( always_inline ) ) static __INLINE uint32_t __get_xPSR(void)
|
||||
{
|
||||
uint32_t result;
|
||||
|
||||
__ASM volatile ("MRS %0, xpsr" : "=r" (result) );
|
||||
return(result);
|
||||
}
|
||||
|
||||
|
||||
/** \brief Get Process Stack Pointer
|
||||
|
||||
This function returns the current value of the Process Stack Pointer (PSP).
|
||||
|
||||
\return PSP Register value
|
||||
*/
|
||||
__attribute__( ( always_inline ) ) static __INLINE uint32_t __get_PSP(void)
|
||||
{
|
||||
register uint32_t result;
|
||||
|
||||
__ASM volatile ("MRS %0, psp\n" : "=r" (result) );
|
||||
return(result);
|
||||
}
|
||||
|
||||
|
||||
/** \brief Set Process Stack Pointer
|
||||
|
||||
This function assigns the given value to the Process Stack Pointer (PSP).
|
||||
|
||||
\param [in] topOfProcStack Process Stack Pointer value to set
|
||||
*/
|
||||
__attribute__( ( always_inline ) ) static __INLINE void __set_PSP(uint32_t topOfProcStack)
|
||||
{
|
||||
__ASM volatile ("MSR psp, %0\n" : : "r" (topOfProcStack) );
|
||||
}
|
||||
|
||||
|
||||
/** \brief Get Main Stack Pointer
|
||||
|
||||
This function returns the current value of the Main Stack Pointer (MSP).
|
||||
|
||||
\return MSP Register value
|
||||
*/
|
||||
__attribute__( ( always_inline ) ) static __INLINE uint32_t __get_MSP(void)
|
||||
{
|
||||
register uint32_t result;
|
||||
|
||||
__ASM volatile ("MRS %0, msp\n" : "=r" (result) );
|
||||
return(result);
|
||||
}
|
||||
|
||||
|
||||
/** \brief Set Main Stack Pointer
|
||||
|
||||
This function assigns the given value to the Main Stack Pointer (MSP).
|
||||
|
||||
\param [in] topOfMainStack Main Stack Pointer value to set
|
||||
*/
|
||||
__attribute__( ( always_inline ) ) static __INLINE void __set_MSP(uint32_t topOfMainStack)
|
||||
{
|
||||
__ASM volatile ("MSR msp, %0\n" : : "r" (topOfMainStack) );
|
||||
}
|
||||
|
||||
|
||||
/** \brief Get Priority Mask
|
||||
|
||||
This function returns the current state of the priority mask bit from the Priority Mask Register.
|
||||
|
||||
\return Priority Mask value
|
||||
*/
|
||||
__attribute__( ( always_inline ) ) static __INLINE uint32_t __get_PRIMASK(void)
|
||||
{
|
||||
uint32_t result;
|
||||
|
||||
__ASM volatile ("MRS %0, primask" : "=r" (result) );
|
||||
return(result);
|
||||
}
|
||||
|
||||
|
||||
/** \brief Set Priority Mask
|
||||
|
||||
This function assigns the given value to the Priority Mask Register.
|
||||
|
||||
\param [in] priMask Priority Mask
|
||||
*/
|
||||
__attribute__( ( always_inline ) ) static __INLINE void __set_PRIMASK(uint32_t priMask)
|
||||
{
|
||||
__ASM volatile ("MSR primask, %0" : : "r" (priMask) );
|
||||
}
|
||||
|
||||
|
||||
#if (__CORTEX_M >= 0x03)
|
||||
|
||||
/** \brief Enable FIQ
|
||||
|
||||
This function enables FIQ interrupts by clearing the F-bit in the CPSR.
|
||||
Can only be executed in Privileged modes.
|
||||
*/
|
||||
__attribute__( ( always_inline ) ) static __INLINE void __enable_fault_irq(void)
|
||||
{
|
||||
__ASM volatile ("cpsie f");
|
||||
}
|
||||
|
||||
|
||||
/** \brief Disable FIQ
|
||||
|
||||
This function disables FIQ interrupts by setting the F-bit in the CPSR.
|
||||
Can only be executed in Privileged modes.
|
||||
*/
|
||||
__attribute__( ( always_inline ) ) static __INLINE void __disable_fault_irq(void)
|
||||
{
|
||||
__ASM volatile ("cpsid f");
|
||||
}
|
||||
|
||||
|
||||
/** \brief Get Base Priority
|
||||
|
||||
This function returns the current value of the Base Priority register.
|
||||
|
||||
\return Base Priority register value
|
||||
*/
|
||||
__attribute__( ( always_inline ) ) static __INLINE uint32_t __get_BASEPRI(void)
|
||||
{
|
||||
uint32_t result;
|
||||
|
||||
__ASM volatile ("MRS %0, basepri_max" : "=r" (result) );
|
||||
return(result);
|
||||
}
|
||||
|
||||
|
||||
/** \brief Set Base Priority
|
||||
|
||||
This function assigns the given value to the Base Priority register.
|
||||
|
||||
\param [in] basePri Base Priority value to set
|
||||
*/
|
||||
__attribute__( ( always_inline ) ) static __INLINE void __set_BASEPRI(uint32_t value)
|
||||
{
|
||||
__ASM volatile ("MSR basepri, %0" : : "r" (value) );
|
||||
}
|
||||
|
||||
|
||||
/** \brief Get Fault Mask
|
||||
|
||||
This function returns the current value of the Fault Mask register.
|
||||
|
||||
\return Fault Mask register value
|
||||
*/
|
||||
__attribute__( ( always_inline ) ) static __INLINE uint32_t __get_FAULTMASK(void)
|
||||
{
|
||||
uint32_t result;
|
||||
|
||||
__ASM volatile ("MRS %0, faultmask" : "=r" (result) );
|
||||
return(result);
|
||||
}
|
||||
|
||||
|
||||
/** \brief Set Fault Mask
|
||||
|
||||
This function assigns the given value to the Fault Mask register.
|
||||
|
||||
\param [in] faultMask Fault Mask value to set
|
||||
*/
|
||||
__attribute__( ( always_inline ) ) static __INLINE void __set_FAULTMASK(uint32_t faultMask)
|
||||
{
|
||||
__ASM volatile ("MSR faultmask, %0" : : "r" (faultMask) );
|
||||
}
|
||||
|
||||
#endif /* (__CORTEX_M >= 0x03) */
|
||||
|
||||
|
||||
#if (__CORTEX_M == 0x04)
|
||||
|
||||
/** \brief Get FPSCR
|
||||
|
||||
This function returns the current value of the Floating Point Status/Control register.
|
||||
|
||||
\return Floating Point Status/Control register value
|
||||
*/
|
||||
__attribute__( ( always_inline ) ) static __INLINE uint32_t __get_FPSCR(void)
|
||||
{
|
||||
#if (__FPU_PRESENT == 1) && (__FPU_USED == 1)
|
||||
uint32_t result;
|
||||
|
||||
__ASM volatile ("VMRS %0, fpscr" : "=r" (result) );
|
||||
return(result);
|
||||
#else
|
||||
return(0);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
/** \brief Set FPSCR
|
||||
|
||||
This function assigns the given value to the Floating Point Status/Control register.
|
||||
|
||||
\param [in] fpscr Floating Point Status/Control value to set
|
||||
*/
|
||||
__attribute__( ( always_inline ) ) static __INLINE void __set_FPSCR(uint32_t fpscr)
|
||||
{
|
||||
#if (__FPU_PRESENT == 1) && (__FPU_USED == 1)
|
||||
__ASM volatile ("VMSR fpscr, %0" : : "r" (fpscr) );
|
||||
#endif
|
||||
}
|
||||
|
||||
#endif /* (__CORTEX_M == 0x04) */
|
||||
|
||||
|
||||
#elif defined ( __TASKING__ ) /*------------------ TASKING Compiler --------------*/
|
||||
/* TASKING carm specific functions */
|
||||
|
||||
/*
|
||||
* The CMSIS functions have been implemented as intrinsics in the compiler.
|
||||
* Please use "carm -?i" to get an up to date list of all instrinsics,
|
||||
* Including the CMSIS ones.
|
||||
*/
|
||||
|
||||
#endif
|
||||
|
||||
/*@} end of CMSIS_Core_RegAccFunctions */
|
||||
|
||||
|
||||
#endif /* __CORE_CMFUNC_H */
|
|
@ -1,585 +0,0 @@
|
|||
/**************************************************************************//**
|
||||
* @file core_cmInstr.h
|
||||
* @brief CMSIS Cortex-M Core Instruction Access Header File
|
||||
* @version V2.10
|
||||
* @date 19. July 2011
|
||||
*
|
||||
* @note
|
||||
* Copyright (C) 2009-2011 ARM Limited. All rights reserved.
|
||||
*
|
||||
* @par
|
||||
* ARM Limited (ARM) is supplying this software for use with Cortex-M
|
||||
* processor based microcontrollers. This file can be freely distributed
|
||||
* within development tools that are supporting such ARM based processors.
|
||||
*
|
||||
* @par
|
||||
* THIS SOFTWARE IS PROVIDED "AS IS". NO WARRANTIES, WHETHER EXPRESS, IMPLIED
|
||||
* OR STATUTORY, INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE.
|
||||
* ARM SHALL NOT, IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, OR
|
||||
* CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER.
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
#ifndef __CORE_CMINSTR_H
|
||||
#define __CORE_CMINSTR_H
|
||||
|
||||
|
||||
/* ########################## Core Instruction Access ######################### */
|
||||
/** \defgroup CMSIS_Core_InstructionInterface CMSIS Core Instruction Interface
|
||||
Access to dedicated instructions
|
||||
@{
|
||||
*/
|
||||
|
||||
#if defined ( __CC_ARM ) /*------------------RealView Compiler -----------------*/
|
||||
/* ARM armcc specific functions */
|
||||
|
||||
#if (__ARMCC_VERSION < 400677)
|
||||
#error "Please use ARM Compiler Toolchain V4.0.677 or later!"
|
||||
#endif
|
||||
|
||||
|
||||
/** \brief No Operation
|
||||
|
||||
No Operation does nothing. This instruction can be used for code alignment purposes.
|
||||
*/
|
||||
#define __NOP __nop
|
||||
|
||||
|
||||
/** \brief Wait For Interrupt
|
||||
|
||||
Wait For Interrupt is a hint instruction that suspends execution
|
||||
until one of a number of events occurs.
|
||||
*/
|
||||
#define __WFI __wfi
|
||||
|
||||
|
||||
/** \brief Wait For Event
|
||||
|
||||
Wait For Event is a hint instruction that permits the processor to enter
|
||||
a low-power state until one of a number of events occurs.
|
||||
*/
|
||||
#define __WFE __wfe
|
||||
|
||||
|
||||
/** \brief Send Event
|
||||
|
||||
Send Event is a hint instruction. It causes an event to be signaled to the CPU.
|
||||
*/
|
||||
#define __SEV __sev
|
||||
|
||||
|
||||
/** \brief Instruction Synchronization Barrier
|
||||
|
||||
Instruction Synchronization Barrier flushes the pipeline in the processor,
|
||||
so that all instructions following the ISB are fetched from cache or
|
||||
memory, after the instruction has been completed.
|
||||
*/
|
||||
#define __ISB() __isb(0xF)
|
||||
|
||||
|
||||
/** \brief Data Synchronization Barrier
|
||||
|
||||
This function acts as a special kind of Data Memory Barrier.
|
||||
It completes when all explicit memory accesses before this instruction complete.
|
||||
*/
|
||||
#define __DSB() __dsb(0xF)
|
||||
|
||||
|
||||
/** \brief Data Memory Barrier
|
||||
|
||||
This function ensures the apparent order of the explicit memory operations before
|
||||
and after the instruction, without ensuring their completion.
|
||||
*/
|
||||
#define __DMB() __dmb(0xF)
|
||||
|
||||
|
||||
/** \brief Reverse byte order (32 bit)
|
||||
|
||||
This function reverses the byte order in integer value.
|
||||
|
||||
\param [in] value Value to reverse
|
||||
\return Reversed value
|
||||
*/
|
||||
#define __REV __rev
|
||||
|
||||
|
||||
/** \brief Reverse byte order (16 bit)
|
||||
|
||||
This function reverses the byte order in two unsigned short values.
|
||||
|
||||
\param [in] value Value to reverse
|
||||
\return Reversed value
|
||||
*/
|
||||
static __INLINE __ASM uint32_t __REV16(uint32_t value)
|
||||
{
|
||||
rev16 r0, r0
|
||||
bx lr
|
||||
}
|
||||
|
||||
|
||||
/** \brief Reverse byte order in signed short value
|
||||
|
||||
This function reverses the byte order in a signed short value with sign extension to integer.
|
||||
|
||||
\param [in] value Value to reverse
|
||||
\return Reversed value
|
||||
*/
|
||||
static __INLINE __ASM int32_t __REVSH(int32_t value)
|
||||
{
|
||||
revsh r0, r0
|
||||
bx lr
|
||||
}
|
||||
|
||||
|
||||
#if (__CORTEX_M >= 0x03)
|
||||
|
||||
/** \brief Reverse bit order of value
|
||||
|
||||
This function reverses the bit order of the given value.
|
||||
|
||||
\param [in] value Value to reverse
|
||||
\return Reversed value
|
||||
*/
|
||||
#define __RBIT __rbit
|
||||
|
||||
|
||||
/** \brief LDR Exclusive (8 bit)
|
||||
|
||||
This function performs a exclusive LDR command for 8 bit value.
|
||||
|
||||
\param [in] ptr Pointer to data
|
||||
\return value of type uint8_t at (*ptr)
|
||||
*/
|
||||
#define __LDREXB(ptr) ((uint8_t ) __ldrex(ptr))
|
||||
|
||||
|
||||
/** \brief LDR Exclusive (16 bit)
|
||||
|
||||
This function performs a exclusive LDR command for 16 bit values.
|
||||
|
||||
\param [in] ptr Pointer to data
|
||||
\return value of type uint16_t at (*ptr)
|
||||
*/
|
||||
#define __LDREXH(ptr) ((uint16_t) __ldrex(ptr))
|
||||
|
||||
|
||||
/** \brief LDR Exclusive (32 bit)
|
||||
|
||||
This function performs a exclusive LDR command for 32 bit values.
|
||||
|
||||
\param [in] ptr Pointer to data
|
||||
\return value of type uint32_t at (*ptr)
|
||||
*/
|
||||
#define __LDREXW(ptr) ((uint32_t ) __ldrex(ptr))
|
||||
|
||||
|
||||
/** \brief STR Exclusive (8 bit)
|
||||
|
||||
This function performs a exclusive STR command for 8 bit values.
|
||||
|
||||
\param [in] value Value to store
|
||||
\param [in] ptr Pointer to location
|
||||
\return 0 Function succeeded
|
||||
\return 1 Function failed
|
||||
*/
|
||||
#define __STREXB(value, ptr) __strex(value, ptr)
|
||||
|
||||
|
||||
/** \brief STR Exclusive (16 bit)
|
||||
|
||||
This function performs a exclusive STR command for 16 bit values.
|
||||
|
||||
\param [in] value Value to store
|
||||
\param [in] ptr Pointer to location
|
||||
\return 0 Function succeeded
|
||||
\return 1 Function failed
|
||||
*/
|
||||
#define __STREXH(value, ptr) __strex(value, ptr)
|
||||
|
||||
|
||||
/** \brief STR Exclusive (32 bit)
|
||||
|
||||
This function performs a exclusive STR command for 32 bit values.
|
||||
|
||||
\param [in] value Value to store
|
||||
\param [in] ptr Pointer to location
|
||||
\return 0 Function succeeded
|
||||
\return 1 Function failed
|
||||
*/
|
||||
#define __STREXW(value, ptr) __strex(value, ptr)
|
||||
|
||||
|
||||
/** \brief Remove the exclusive lock
|
||||
|
||||
This function removes the exclusive lock which is created by LDREX.
|
||||
|
||||
*/
|
||||
#define __CLREX __clrex
|
||||
|
||||
|
||||
/** \brief Signed Saturate
|
||||
|
||||
This function saturates a signed value.
|
||||
|
||||
\param [in] value Value to be saturated
|
||||
\param [in] sat Bit position to saturate to (1..32)
|
||||
\return Saturated value
|
||||
*/
|
||||
#define __SSAT __ssat
|
||||
|
||||
|
||||
/** \brief Unsigned Saturate
|
||||
|
||||
This function saturates an unsigned value.
|
||||
|
||||
\param [in] value Value to be saturated
|
||||
\param [in] sat Bit position to saturate to (0..31)
|
||||
\return Saturated value
|
||||
*/
|
||||
#define __USAT __usat
|
||||
|
||||
|
||||
/** \brief Count leading zeros
|
||||
|
||||
This function counts the number of leading zeros of a data value.
|
||||
|
||||
\param [in] value Value to count the leading zeros
|
||||
\return number of leading zeros in value
|
||||
*/
|
||||
#define __CLZ __clz
|
||||
|
||||
#endif /* (__CORTEX_M >= 0x03) */
|
||||
|
||||
|
||||
|
||||
#elif defined ( __ICCARM__ ) /*------------------ ICC Compiler -------------------*/
|
||||
/* IAR iccarm specific functions */
|
||||
|
||||
#include <cmsis_iar.h>
|
||||
|
||||
|
||||
#elif defined ( __GNUC__ ) /*------------------ GNU Compiler ---------------------*/
|
||||
/* GNU gcc specific functions */
|
||||
|
||||
/** \brief No Operation
|
||||
|
||||
No Operation does nothing. This instruction can be used for code alignment purposes.
|
||||
*/
|
||||
__attribute__( ( always_inline ) ) static __INLINE void __NOP(void)
|
||||
{
|
||||
__ASM volatile ("nop");
|
||||
}
|
||||
|
||||
|
||||
/** \brief Wait For Interrupt
|
||||
|
||||
Wait For Interrupt is a hint instruction that suspends execution
|
||||
until one of a number of events occurs.
|
||||
*/
|
||||
__attribute__( ( always_inline ) ) static __INLINE void __WFI(void)
|
||||
{
|
||||
__ASM volatile ("wfi");
|
||||
}
|
||||
|
||||
|
||||
/** \brief Wait For Event
|
||||
|
||||
Wait For Event is a hint instruction that permits the processor to enter
|
||||
a low-power state until one of a number of events occurs.
|
||||
*/
|
||||
__attribute__( ( always_inline ) ) static __INLINE void __WFE(void)
|
||||
{
|
||||
__ASM volatile ("wfe");
|
||||
}
|
||||
|
||||
|
||||
/** \brief Send Event
|
||||
|
||||
Send Event is a hint instruction. It causes an event to be signaled to the CPU.
|
||||
*/
|
||||
__attribute__( ( always_inline ) ) static __INLINE void __SEV(void)
|
||||
{
|
||||
__ASM volatile ("sev");
|
||||
}
|
||||
|
||||
|
||||
/** \brief Instruction Synchronization Barrier
|
||||
|
||||
Instruction Synchronization Barrier flushes the pipeline in the processor,
|
||||
so that all instructions following the ISB are fetched from cache or
|
||||
memory, after the instruction has been completed.
|
||||
*/
|
||||
__attribute__( ( always_inline ) ) static __INLINE void __ISB(void)
|
||||
{
|
||||
__ASM volatile ("isb");
|
||||
}
|
||||
|
||||
|
||||
/** \brief Data Synchronization Barrier
|
||||
|
||||
This function acts as a special kind of Data Memory Barrier.
|
||||
It completes when all explicit memory accesses before this instruction complete.
|
||||
*/
|
||||
__attribute__( ( always_inline ) ) static __INLINE void __DSB(void)
|
||||
{
|
||||
__ASM volatile ("dsb");
|
||||
}
|
||||
|
||||
|
||||
/** \brief Data Memory Barrier
|
||||
|
||||
This function ensures the apparent order of the explicit memory operations before
|
||||
and after the instruction, without ensuring their completion.
|
||||
*/
|
||||
__attribute__( ( always_inline ) ) static __INLINE void __DMB(void)
|
||||
{
|
||||
__ASM volatile ("dmb");
|
||||
}
|
||||
|
||||
|
||||
/** \brief Reverse byte order (32 bit)
|
||||
|
||||
This function reverses the byte order in integer value.
|
||||
|
||||
\param [in] value Value to reverse
|
||||
\return Reversed value
|
||||
*/
|
||||
__attribute__( ( always_inline ) ) static __INLINE uint32_t __REV(uint32_t value)
|
||||
{
|
||||
uint32_t result;
|
||||
|
||||
__ASM volatile ("rev %0, %1" : "=r" (result) : "r" (value) );
|
||||
return(result);
|
||||
}
|
||||
|
||||
|
||||
/** \brief Reverse byte order (16 bit)
|
||||
|
||||
This function reverses the byte order in two unsigned short values.
|
||||
|
||||
\param [in] value Value to reverse
|
||||
\return Reversed value
|
||||
*/
|
||||
__attribute__( ( always_inline ) ) static __INLINE uint32_t __REV16(uint32_t value)
|
||||
{
|
||||
uint32_t result;
|
||||
|
||||
__ASM volatile ("rev16 %0, %1" : "=r" (result) : "r" (value) );
|
||||
return(result);
|
||||
}
|
||||
|
||||
|
||||
/** \brief Reverse byte order in signed short value
|
||||
|
||||
This function reverses the byte order in a signed short value with sign extension to integer.
|
||||
|
||||
\param [in] value Value to reverse
|
||||
\return Reversed value
|
||||
*/
|
||||
__attribute__( ( always_inline ) ) static __INLINE int32_t __REVSH(int32_t value)
|
||||
{
|
||||
uint32_t result;
|
||||
|
||||
__ASM volatile ("revsh %0, %1" : "=r" (result) : "r" (value) );
|
||||
return((int32_t)result);
|
||||
}
|
||||
|
||||
|
||||
#if (__CORTEX_M >= 0x03)
|
||||
|
||||
/** \brief Reverse bit order of value
|
||||
|
||||
This function reverses the bit order of the given value.
|
||||
|
||||
\param [in] value Value to reverse
|
||||
\return Reversed value
|
||||
*/
|
||||
__attribute__( ( always_inline ) ) static __INLINE uint32_t __RBIT(uint32_t value)
|
||||
{
|
||||
uint32_t result;
|
||||
|
||||
__ASM volatile ("rbit %0, %1" : "=r" (result) : "r" (value) );
|
||||
return(result);
|
||||
}
|
||||
|
||||
|
||||
/** \brief LDR Exclusive (8 bit)
|
||||
|
||||
This function performs a exclusive LDR command for 8 bit value.
|
||||
|
||||
\param [in] ptr Pointer to data
|
||||
\return value of type uint8_t at (*ptr)
|
||||
*/
|
||||
__attribute__( ( always_inline ) ) static __INLINE uint8_t __LDREXB(volatile uint8_t *addr)
|
||||
{
|
||||
uint8_t result;
|
||||
|
||||
__ASM volatile ("ldrexb %0, [%1]" : "=r" (result) : "r" (addr) );
|
||||
return(result);
|
||||
}
|
||||
|
||||
|
||||
/** \brief LDR Exclusive (16 bit)
|
||||
|
||||
This function performs a exclusive LDR command for 16 bit values.
|
||||
|
||||
\param [in] ptr Pointer to data
|
||||
\return value of type uint16_t at (*ptr)
|
||||
*/
|
||||
__attribute__( ( always_inline ) ) static __INLINE uint16_t __LDREXH(volatile uint16_t *addr)
|
||||
{
|
||||
uint16_t result;
|
||||
|
||||
__ASM volatile ("ldrexh %0, [%1]" : "=r" (result) : "r" (addr) );
|
||||
return(result);
|
||||
}
|
||||
|
||||
|
||||
/** \brief LDR Exclusive (32 bit)
|
||||
|
||||
This function performs a exclusive LDR command for 32 bit values.
|
||||
|
||||
\param [in] ptr Pointer to data
|
||||
\return value of type uint32_t at (*ptr)
|
||||
*/
|
||||
__attribute__( ( always_inline ) ) static __INLINE uint32_t __LDREXW(volatile uint32_t *addr)
|
||||
{
|
||||
uint32_t result;
|
||||
|
||||
__ASM volatile ("ldrex %0, [%1]" : "=r" (result) : "r" (addr) );
|
||||
return(result);
|
||||
}
|
||||
|
||||
|
||||
/** \brief STR Exclusive (8 bit)
|
||||
|
||||
This function performs a exclusive STR command for 8 bit values.
|
||||
|
||||
\param [in] value Value to store
|
||||
\param [in] ptr Pointer to location
|
||||
\return 0 Function succeeded
|
||||
\return 1 Function failed
|
||||
*/
|
||||
__attribute__( ( always_inline ) ) static __INLINE uint32_t __STREXB(uint8_t value, volatile uint8_t *addr)
|
||||
{
|
||||
uint32_t result;
|
||||
|
||||
__ASM volatile ("strexb %0, %2, [%1]" : "=r" (result) : "r" (addr), "r" (value) );
|
||||
return(result);
|
||||
}
|
||||
|
||||
|
||||
/** \brief STR Exclusive (16 bit)
|
||||
|
||||
This function performs a exclusive STR command for 16 bit values.
|
||||
|
||||
\param [in] value Value to store
|
||||
\param [in] ptr Pointer to location
|
||||
\return 0 Function succeeded
|
||||
\return 1 Function failed
|
||||
*/
|
||||
__attribute__( ( always_inline ) ) static __INLINE uint32_t __STREXH(uint16_t value, volatile uint16_t *addr)
|
||||
{
|
||||
uint32_t result;
|
||||
|
||||
__ASM volatile ("strexh %0, %2, [%1]" : "=r" (result) : "r" (addr), "r" (value) );
|
||||
return(result);
|
||||
}
|
||||
|
||||
|
||||
/** \brief STR Exclusive (32 bit)
|
||||
|
||||
This function performs a exclusive STR command for 32 bit values.
|
||||
|
||||
\param [in] value Value to store
|
||||
\param [in] ptr Pointer to location
|
||||
\return 0 Function succeeded
|
||||
\return 1 Function failed
|
||||
*/
|
||||
__attribute__( ( always_inline ) ) static __INLINE uint32_t __STREXW(uint32_t value, volatile uint32_t *addr)
|
||||
{
|
||||
uint32_t result;
|
||||
|
||||
__ASM volatile ("strex %0, %2, [%1]" : "=r" (result) : "r" (addr), "r" (value) );
|
||||
return(result);
|
||||
}
|
||||
|
||||
|
||||
/** \brief Remove the exclusive lock
|
||||
|
||||
This function removes the exclusive lock which is created by LDREX.
|
||||
|
||||
*/
|
||||
__attribute__( ( always_inline ) ) static __INLINE void __CLREX(void)
|
||||
{
|
||||
__ASM volatile ("clrex");
|
||||
}
|
||||
|
||||
|
||||
/** \brief Signed Saturate
|
||||
|
||||
This function saturates a signed value.
|
||||
|
||||
\param [in] value Value to be saturated
|
||||
\param [in] sat Bit position to saturate to (1..32)
|
||||
\return Saturated value
|
||||
*/
|
||||
#define __SSAT(ARG1,ARG2) \
|
||||
({ \
|
||||
uint32_t __RES, __ARG1 = (ARG1); \
|
||||
__ASM ("ssat %0, %1, %2" : "=r" (__RES) : "I" (ARG2), "r" (__ARG1) ); \
|
||||
__RES; \
|
||||
})
|
||||
|
||||
|
||||
/** \brief Unsigned Saturate
|
||||
|
||||
This function saturates an unsigned value.
|
||||
|
||||
\param [in] value Value to be saturated
|
||||
\param [in] sat Bit position to saturate to (0..31)
|
||||
\return Saturated value
|
||||
*/
|
||||
#define __USAT(ARG1,ARG2) \
|
||||
({ \
|
||||
uint32_t __RES, __ARG1 = (ARG1); \
|
||||
__ASM ("usat %0, %1, %2" : "=r" (__RES) : "I" (ARG2), "r" (__ARG1) ); \
|
||||
__RES; \
|
||||
})
|
||||
|
||||
|
||||
/** \brief Count leading zeros
|
||||
|
||||
This function counts the number of leading zeros of a data value.
|
||||
|
||||
\param [in] value Value to count the leading zeros
|
||||
\return number of leading zeros in value
|
||||
*/
|
||||
__attribute__( ( always_inline ) ) static __INLINE uint8_t __CLZ(uint32_t value)
|
||||
{
|
||||
uint8_t result;
|
||||
|
||||
__ASM volatile ("clz %0, %1" : "=r" (result) : "r" (value) );
|
||||
return(result);
|
||||
}
|
||||
|
||||
#endif /* (__CORTEX_M >= 0x03) */
|
||||
|
||||
|
||||
|
||||
|
||||
#elif defined ( __TASKING__ ) /*------------------ TASKING Compiler --------------*/
|
||||
/* TASKING carm specific functions */
|
||||
|
||||
/*
|
||||
* The CMSIS functions have been implemented as intrinsics in the compiler.
|
||||
* Please use "carm -?i" to get an up to date list of all intrinsics,
|
||||
* Including the CMSIS ones.
|
||||
*/
|
||||
|
||||
#endif
|
||||
|
||||
/*@}*/ /* end of group CMSIS_Core_InstructionInterface */
|
||||
|
||||
#endif /* __CORE_CMINSTR_H */
|
File diff suppressed because it is too large
Load Diff
|
@ -1,197 +0,0 @@
|
|||
/**
|
||||
******************************************************************************
|
||||
* @file stm32f2xx.h
|
||||
* @author MCD Application Team
|
||||
* @version V2.0.1
|
||||
* @date 25-March-2014
|
||||
* @brief CMSIS STM32F2xx Device Peripheral Access Layer Header File.
|
||||
*
|
||||
* The file is the unique include file that the application programmer
|
||||
* is using in the C source code, usually in main.c. This file contains:
|
||||
* - Configuration section that allows to select:
|
||||
* - The STM32F2xx device used in the target application
|
||||
* - To use or not the peripheral's drivers in application code(i.e.
|
||||
* code will be based on direct access to peripheral's registers
|
||||
* rather than drivers API), this option is controlled by
|
||||
* "#define USE_HAL_DRIVER"
|
||||
*
|
||||
******************************************************************************
|
||||
* @attention
|
||||
*
|
||||
* <h2><center>© COPYRIGHT(c) 2014 STMicroelectronics</center></h2>
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification,
|
||||
* are permitted provided that the following conditions are met:
|
||||
* 1. Redistributions of source code must retain the above copyright notice,
|
||||
* this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
* 3. Neither the name of STMicroelectronics nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
||||
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
******************************************************************************
|
||||
*/
|
||||
|
||||
/** @addtogroup CMSIS
|
||||
* @{
|
||||
*/
|
||||
|
||||
/** @addtogroup stm32f2xx
|
||||
* @{
|
||||
*/
|
||||
|
||||
#ifndef __STM32F2xx_H
|
||||
#define __STM32F2xx_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif /* __cplusplus */
|
||||
|
||||
/** @addtogroup Library_configuration_section
|
||||
* @{
|
||||
*/
|
||||
|
||||
/* Uncomment the line below according to the target STM32 device used in your
|
||||
application
|
||||
*/
|
||||
|
||||
#if !defined (STM32F205xx) && !defined (STM32F215xx) && !defined (STM32F207xx) && !defined (STM32F217xx)
|
||||
|
||||
/* #define STM32F205xx */ /*!< STM32Fxx Devices */
|
||||
/* #define STM32F215xx */ /*!< STM32Fxx Devices */
|
||||
/* #define STM32F207xx */ /*!< STM32Fxx Devices */
|
||||
/* #define STM32F217xx */ /*!< STM32Fxx Devices */
|
||||
|
||||
#endif
|
||||
|
||||
/* Tip: To avoid modifying this file each time you need to switch between these
|
||||
devices, you can define the device in your toolchain compiler preprocessor.
|
||||
*/
|
||||
#if !defined (USE_HAL_DRIVER)
|
||||
/**
|
||||
* @brief Comment the line below if you will not use the peripherals drivers.
|
||||
In this case, these drivers will not be included and the application code will
|
||||
be based on direct access to peripherals registers
|
||||
*/
|
||||
/*#define USE_HAL_DRIVER */
|
||||
#endif /* USE_HAL_DRIVER */
|
||||
|
||||
/**
|
||||
* @brief CMSIS Device version number V2.0.1
|
||||
*/
|
||||
#define __STM32F2xx_CMSIS_DEVICE_VERSION_MAIN (0x02) /*!< [31:24] main version */
|
||||
#define __STM32F2xx_CMSIS_DEVICE_VERSION_SUB1 (0x00) /*!< [23:16] sub1 version */
|
||||
#define __STM32F2xx_CMSIS_DEVICE_VERSION_SUB2 (0x00) /*!< [15:8] sub2 version */
|
||||
#define __STM32F2xx_CMSIS_DEVICE_VERSION_RC (0x00) /*!< [7:0] release candidate */
|
||||
#define __STM32F2xx_CMSIS_DEVICE_VERSION ((__CMSIS_DEVICE_VERSION_MAIN << 24)\
|
||||
|(__CMSIS_DEVICE_HAL_VERSION_SUB1 << 16)\
|
||||
|(__CMSIS_DEVICE_HAL_VERSION_SUB2 << 8 )\
|
||||
|(__CMSIS_DEVICE_HAL_VERSION_RC))
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/** @addtogroup Device_Included
|
||||
* @{
|
||||
*/
|
||||
|
||||
#if defined(STM32F205xx)
|
||||
#include "stm32f205xx.h"
|
||||
#elif defined(STM32F215xx)
|
||||
#include "stm32f215xx.h"
|
||||
#elif defined(STM32F207xx)
|
||||
#include "stm32f207xx.h"
|
||||
#elif defined(STM32F217xx)
|
||||
#include "stm32f217xx.h"
|
||||
#else
|
||||
#error "Please select first the target STM32F2xx device used in your application (in stm32f2xx.h file)"
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/** @addtogroup Exported_types
|
||||
* @{
|
||||
*/
|
||||
typedef enum
|
||||
{
|
||||
RESET = 0,
|
||||
SET = !RESET
|
||||
} FlagStatus, ITStatus;
|
||||
|
||||
typedef enum
|
||||
{
|
||||
DISABLE = 0,
|
||||
ENABLE = !DISABLE
|
||||
} FunctionalState;
|
||||
#define IS_FUNCTIONAL_STATE(STATE) (((STATE) == DISABLE) || ((STATE) == ENABLE))
|
||||
|
||||
typedef enum
|
||||
{
|
||||
ERROR = 0,
|
||||
SUCCESS = !ERROR
|
||||
} ErrorStatus;
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
|
||||
/** @addtogroup Exported_macro
|
||||
* @{
|
||||
*/
|
||||
#define SET_BIT(REG, BIT) ((REG) |= (BIT))
|
||||
|
||||
#define CLEAR_BIT(REG, BIT) ((REG) &= ~(BIT))
|
||||
|
||||
#define READ_BIT(REG, BIT) ((REG) & (BIT))
|
||||
|
||||
#define CLEAR_REG(REG) ((REG) = (0x0))
|
||||
|
||||
#define WRITE_REG(REG, VAL) ((REG) = (VAL))
|
||||
|
||||
#define READ_REG(REG) ((REG))
|
||||
|
||||
#define MODIFY_REG(REG, CLEARMASK, SETMASK) WRITE_REG((REG), (((READ_REG(REG)) & (~(CLEARMASK))) | (SETMASK)))
|
||||
|
||||
#define POSITION_VAL(VAL) (__CLZ(__RBIT(VAL)))
|
||||
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif /* __cplusplus */
|
||||
|
||||
#endif /* __STM32F2xx_H */
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
|
||||
|
||||
|
||||
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
|
|
@ -1,99 +0,0 @@
|
|||
/**
|
||||
******************************************************************************
|
||||
* @file system_stm32f2xx.h
|
||||
* @author MCD Application Team
|
||||
* @version V1.0.0
|
||||
* @date 18-April-2011
|
||||
* @brief CMSIS Cortex-M3 Device Peripheral Access Layer System Header File.
|
||||
******************************************************************************
|
||||
* @attention
|
||||
*
|
||||
* THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS
|
||||
* WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE
|
||||
* TIME. AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY
|
||||
* DIRECT, INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING
|
||||
* FROM THE CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE
|
||||
* CODING INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS.
|
||||
*
|
||||
* <h2><center>© COPYRIGHT 2011 STMicroelectronics</center></h2>
|
||||
******************************************************************************
|
||||
*/
|
||||
|
||||
/** @addtogroup CMSIS
|
||||
* @{
|
||||
*/
|
||||
|
||||
/** @addtogroup stm32f2xx_system
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* @brief Define to prevent recursive inclusion
|
||||
*/
|
||||
#ifndef __SYSTEM_STM32F2XX_H
|
||||
#define __SYSTEM_STM32F2XX_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/** @addtogroup STM32F2xx_System_Includes
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
|
||||
/** @addtogroup STM32F2xx_System_Exported_types
|
||||
* @{
|
||||
*/
|
||||
|
||||
extern uint32_t SystemCoreClock; /*!< System Clock Frequency (Core Clock) */
|
||||
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/** @addtogroup STM32F2xx_System_Exported_Constants
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/** @addtogroup STM32F2xx_System_Exported_Macros
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/** @addtogroup STM32F2xx_System_Exported_Functions
|
||||
* @{
|
||||
*/
|
||||
|
||||
extern void SystemInit(void);
|
||||
extern void SystemCoreClockUpdate(void);
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /*__SYSTEM_STM32F2XX_H */
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
/******************* (C) COPYRIGHT 2011 STMicroelectronics *****END OF FILE****/
|
226
board/libc.h
226
board/libc.h
|
@ -1,226 +0,0 @@
|
|||
#define min(a,b) \
|
||||
({ __typeof__ (a) _a = (a); \
|
||||
__typeof__ (b) _b = (b); \
|
||||
_a < _b ? _a : _b; })
|
||||
|
||||
#define max(a,b) \
|
||||
({ __typeof__ (a) _a = (a); \
|
||||
__typeof__ (b) _b = (b); \
|
||||
_a > _b ? _a : _b; })
|
||||
|
||||
#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 GPIO_AF2_TIM3 ((uint8_t)0x02) /* TIM3 Alternate Function mapping */
|
||||
#define GPIO_AF7_USART2 ((uint8_t)0x07) /* USART2 Alternate Function mapping */
|
||||
#define GPIO_AF7_USART3 ((uint8_t)0x07) /* USART3 Alternate Function mapping */
|
||||
#define GPIO_AF9_CAN1 ((uint8_t)0x09) /* CAN1 Alternate Function mapping */
|
||||
#define GPIO_AF10_OTG_FS ((uint8_t)0xA) /* OTG_FS Alternate Function mapping */
|
||||
#define GPIO_AF12_OTG_HS_FS ((uint8_t)0xC) /* OTG HS configured in FS */
|
||||
|
||||
#ifdef OLD_BOARD
|
||||
#define USART USART2
|
||||
#else
|
||||
#define USART USART3
|
||||
#endif
|
||||
|
||||
|
||||
// **** shitty libc ****
|
||||
|
||||
void clock_init() {
|
||||
#ifdef USE_INTERNAL_OSC
|
||||
// enable internal oscillator
|
||||
RCC->CR |= RCC_CR_HSION;
|
||||
while ((RCC->CR & RCC_CR_HSIRDY) == 0);
|
||||
#else
|
||||
// enable external oscillator
|
||||
RCC->CR |= RCC_CR_HSEON;
|
||||
while ((RCC->CR & RCC_CR_HSERDY) == 0);
|
||||
#endif
|
||||
|
||||
// divide shit
|
||||
RCC->CFGR = RCC_CFGR_HPRE_DIV1 | RCC_CFGR_PPRE2_DIV2 | RCC_CFGR_PPRE1_DIV4;
|
||||
#ifdef USE_INTERNAL_OSC
|
||||
RCC->PLLCFGR = RCC_PLLCFGR_PLLQ_2 | RCC_PLLCFGR_PLLM_3 |
|
||||
RCC_PLLCFGR_PLLN_6 | RCC_PLLCFGR_PLLN_5 | RCC_PLLCFGR_PLLSRC_HSI;
|
||||
#else
|
||||
RCC->PLLCFGR = RCC_PLLCFGR_PLLQ_2 | RCC_PLLCFGR_PLLM_3 |
|
||||
RCC_PLLCFGR_PLLN_7 | RCC_PLLCFGR_PLLN_6 | RCC_PLLCFGR_PLLSRC_HSE;
|
||||
#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 ***
|
||||
|
||||
// enable GPIOB, UART2, CAN, USB clock
|
||||
RCC->AHB1ENR |= RCC_AHB1ENR_GPIOAEN;
|
||||
RCC->AHB1ENR |= RCC_AHB1ENR_GPIOBEN;
|
||||
RCC->AHB1ENR |= RCC_AHB1ENR_GPIOCEN;
|
||||
RCC->APB1ENR |= RCC_APB1ENR_USART2EN;
|
||||
RCC->APB1ENR |= RCC_APB1ENR_USART3EN;
|
||||
RCC->APB1ENR |= RCC_APB1ENR_CAN1EN;
|
||||
RCC->APB1ENR |= RCC_APB1ENR_CAN2EN;
|
||||
RCC->APB1ENR |= RCC_APB1ENR_DACEN;
|
||||
RCC->APB1ENR |= RCC_APB1ENR_TIM3EN;
|
||||
RCC->AHB2ENR |= RCC_AHB2ENR_OTGFSEN;
|
||||
//RCC->APB2ENR |= RCC_APB2ENR_TIM1EN;
|
||||
RCC->APB2ENR |= RCC_APB2ENR_ADC1EN;
|
||||
|
||||
// turn on alt USB
|
||||
RCC->AHB1ENR |= RCC_AHB1ENR_OTGHSEN;
|
||||
|
||||
// fix interrupt vectors
|
||||
}
|
||||
|
||||
// board specific
|
||||
void gpio_init() {
|
||||
// analog mode
|
||||
GPIOC->MODER = GPIO_MODER_MODER3 | GPIO_MODER_MODER2 |
|
||||
GPIO_MODER_MODER1 | GPIO_MODER_MODER0;
|
||||
|
||||
// FAN on C9, aka TIM3_CH4
|
||||
#ifdef OLD_BOARD
|
||||
GPIOC->MODER |= GPIO_MODER_MODER9_1;
|
||||
GPIOC->AFR[1] = GPIO_AF2_TIM3 << ((9-8)*4);
|
||||
#else
|
||||
GPIOC->MODER |= GPIO_MODER_MODER8_1;
|
||||
GPIOC->AFR[1] = GPIO_AF2_TIM3 << ((8-8)*4);
|
||||
#endif
|
||||
// IGNITION on C13
|
||||
|
||||
// set mode for LEDs and CAN
|
||||
GPIOB->MODER = GPIO_MODER_MODER10_0 | GPIO_MODER_MODER11_0;
|
||||
// CAN 2
|
||||
GPIOB->MODER |= GPIO_MODER_MODER5_1 | GPIO_MODER_MODER6_1;
|
||||
// CAN 1
|
||||
GPIOB->MODER |= GPIO_MODER_MODER8_1 | GPIO_MODER_MODER9_1;
|
||||
// CAN enables
|
||||
GPIOB->MODER |= GPIO_MODER_MODER3_0 | GPIO_MODER_MODER4_0;
|
||||
|
||||
// set mode for SERIAL and USB (DAC should be configured to in)
|
||||
GPIOA->MODER = GPIO_MODER_MODER2_1 | GPIO_MODER_MODER3_1;
|
||||
GPIOA->AFR[0] = GPIO_AF7_USART2 << (2*4) | GPIO_AF7_USART2 << (3*4);
|
||||
|
||||
// GPIOC USART3
|
||||
GPIOC->MODER |= GPIO_MODER_MODER10_1 | GPIO_MODER_MODER11_1;
|
||||
GPIOC->AFR[1] |= GPIO_AF7_USART3 << ((10-8)*4) | GPIO_AF7_USART3 << ((11-8)*4);
|
||||
|
||||
if (USBx == USB_OTG_FS) {
|
||||
GPIOA->MODER |= GPIO_MODER_MODER11_1 | GPIO_MODER_MODER12_1;
|
||||
GPIOA->OSPEEDR = GPIO_OSPEEDER_OSPEEDR11 | GPIO_OSPEEDER_OSPEEDR12;
|
||||
GPIOA->AFR[1] = GPIO_AF10_OTG_FS << ((11-8)*4) | GPIO_AF10_OTG_FS << ((12-8)*4);
|
||||
}
|
||||
|
||||
GPIOA->PUPDR = GPIO_PUPDR_PUPDR2_0 | GPIO_PUPDR_PUPDR3_0;
|
||||
|
||||
// set mode for CAN / USB_HS pins
|
||||
GPIOB->AFR[0] = GPIO_AF9_CAN1 << (5*4) | GPIO_AF9_CAN1 << (6*4);
|
||||
GPIOB->AFR[1] = GPIO_AF9_CAN1 << ((8-8)*4) | GPIO_AF9_CAN1 << ((9-8)*4);
|
||||
|
||||
if (USBx == USB_OTG_HS) {
|
||||
GPIOB->AFR[1] |= GPIO_AF12_OTG_HS_FS << ((15-8)*4) | GPIO_AF12_OTG_HS_FS << ((14-8)*4);
|
||||
GPIOB->MODER |= GPIO_MODER_MODER14_1 | GPIO_MODER_MODER15_1;
|
||||
}
|
||||
|
||||
GPIOB->OSPEEDR = GPIO_OSPEEDER_OSPEEDR14 | GPIO_OSPEEDER_OSPEEDR15;
|
||||
|
||||
// enable CAN busses
|
||||
GPIOB->ODR |= (1 << 3) | (1 << 4);
|
||||
|
||||
// enable OTG out tied to ground
|
||||
GPIOA->ODR = 0;
|
||||
GPIOA->MODER |= GPIO_MODER_MODER1_0;
|
||||
|
||||
// enable USB power tied to +
|
||||
GPIOA->ODR |= 1;
|
||||
GPIOA->MODER |= GPIO_MODER_MODER0_0;
|
||||
}
|
||||
|
||||
void uart_init() {
|
||||
// enable uart and tx+rx mode
|
||||
USART->CR1 = USART_CR1_UE;
|
||||
USART->BRR = __USART_BRR(24000000, 115200);
|
||||
USART->CR1 |= USART_CR1_TE | USART_CR1_RE;
|
||||
USART->CR2 = USART_CR2_STOP_0 | USART_CR2_STOP_1;
|
||||
// ** UART is ready to work **
|
||||
|
||||
// enable interrupts
|
||||
USART->CR1 |= USART_CR1_RXNEIE;
|
||||
}
|
||||
|
||||
void delay(int a) {
|
||||
volatile int i;
|
||||
for (i=0;i<a;i++);
|
||||
}
|
||||
|
||||
void putch(const char a) {
|
||||
while (!(USART->SR & USART_SR_TXE));
|
||||
USART->DR = a;
|
||||
}
|
||||
|
||||
int puts(const char *a) {
|
||||
for (;*a;a++) {
|
||||
if (*a == '\n') putch('\r');
|
||||
putch(*a);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
void puth(unsigned int i) {
|
||||
int pos;
|
||||
char c[] = "0123456789abcdef";
|
||||
for (pos = 28; pos != -4; pos -= 4) {
|
||||
putch(c[(i >> pos) & 0xF]);
|
||||
}
|
||||
}
|
||||
|
||||
void puth2(unsigned int i) {
|
||||
int pos;
|
||||
char c[] = "0123456789abcdef";
|
||||
for (pos = 4; pos != -4; pos -= 4) {
|
||||
putch(c[(i >> pos) & 0xF]);
|
||||
}
|
||||
}
|
||||
|
||||
void hexdump(void *a, int l) {
|
||||
int i;
|
||||
for (i=0;i<l;i++) {
|
||||
if (i != 0 && (i&0xf) == 0) puts("\n");
|
||||
puth2(((unsigned char*)a)[i]);
|
||||
puts(" ");
|
||||
}
|
||||
puts("\n");
|
||||
}
|
||||
|
||||
void *memset(void *str, int c, unsigned int n) {
|
||||
int i;
|
||||
for (i = 0; i < n; i++) {
|
||||
*((uint8_t*)str) = c;
|
||||
++str;
|
||||
}
|
||||
return str;
|
||||
}
|
||||
|
||||
void *memcpy(void *dest, const void *src, unsigned int n) {
|
||||
int i;
|
||||
// TODO: make not slow
|
||||
for (i = 0; i < n; i++) {
|
||||
((uint8_t*)dest)[i] = *(uint8_t*)src;
|
||||
++src;
|
||||
}
|
||||
return dest;
|
||||
}
|
||||
|
||||
|
499
board/main.c
499
board/main.c
|
@ -1,499 +0,0 @@
|
|||
//#define DEBUG
|
||||
//#define CAN_LOOPBACK_MODE
|
||||
//#define USE_INTERNAL_OSC
|
||||
//#define OLD_BOARD
|
||||
|
||||
#define USB_VID 0xbbaa
|
||||
#define USB_PID 0xddcc
|
||||
|
||||
// *** end config ***
|
||||
|
||||
#include "stm32f2xx.h"
|
||||
#include "obj/gitversion.h"
|
||||
|
||||
#define ENTER_BOOTLOADER_MAGIC 0xdeadbeef
|
||||
uint32_t enter_bootloader_mode;
|
||||
|
||||
USB_OTG_GlobalTypeDef *USBx = USB_OTG_FS;
|
||||
|
||||
#include "libc.h"
|
||||
#include "adc.h"
|
||||
#include "timer.h"
|
||||
#include "usb.h"
|
||||
#include "can.h"
|
||||
|
||||
// debug safety check: is controls allowed?
|
||||
int controls_allowed = 0;
|
||||
int gas_interceptor_detected = 0;
|
||||
|
||||
// ********************* instantiate queues *********************
|
||||
|
||||
#define FIFO_SIZE 0x100
|
||||
typedef struct {
|
||||
uint8_t w_ptr;
|
||||
uint8_t r_ptr;
|
||||
CAN_FIFOMailBox_TypeDef elems[FIFO_SIZE];
|
||||
} can_ring;
|
||||
|
||||
can_ring can_rx_q = { .w_ptr = 0, .r_ptr = 0 };
|
||||
can_ring can_tx1_q = { .w_ptr = 0, .r_ptr = 0 };
|
||||
can_ring can_tx2_q = { .w_ptr = 0, .r_ptr = 0 };
|
||||
|
||||
// ********************* interrupt safe queue *********************
|
||||
|
||||
inline int pop(can_ring *q, CAN_FIFOMailBox_TypeDef *elem) {
|
||||
if (q->w_ptr != q->r_ptr) {
|
||||
*elem = q->elems[q->r_ptr];
|
||||
q->r_ptr += 1;
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
inline int push(can_ring *q, CAN_FIFOMailBox_TypeDef *elem) {
|
||||
uint8_t next_w_ptr = q->w_ptr + 1;
|
||||
if (next_w_ptr != q->r_ptr) {
|
||||
q->elems[q->w_ptr] = *elem;
|
||||
q->w_ptr = next_w_ptr;
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
// ***************************** CAN *****************************
|
||||
|
||||
void process_can(CAN_TypeDef *CAN, can_ring *can_q, int can_number) {
|
||||
#ifdef DEBUG
|
||||
puts("process CAN TX\n");
|
||||
#endif
|
||||
|
||||
// add successfully transmitted message to my fifo
|
||||
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_number+2) << 4);
|
||||
to_push.RDLR = CAN->sTxMailBox[0].TDLR;
|
||||
to_push.RDHR = CAN->sTxMailBox[0].TDHR;
|
||||
push(&can_rx_q, &to_push);
|
||||
}
|
||||
|
||||
// check for empty mailbox
|
||||
CAN_FIFOMailBox_TypeDef to_send;
|
||||
if ((CAN->TSR & CAN_TSR_TME0) == CAN_TSR_TME0) {
|
||||
if (pop(can_q, &to_send)) {
|
||||
|
||||
// BRAKE: safety check
|
||||
if ((to_send.RIR>>21) == 0x1FA) {
|
||||
if (controls_allowed) {
|
||||
to_send.RDLR &= 0xFFFFFF3F;
|
||||
} else {
|
||||
to_send.RDLR &= 0xFFFF0000;
|
||||
}
|
||||
}
|
||||
|
||||
// STEER: safety check
|
||||
if ((to_send.RIR>>21) == 0xE4) {
|
||||
if (controls_allowed) {
|
||||
to_send.RDLR &= 0xFFFFFFFF;
|
||||
} else {
|
||||
to_send.RDLR &= 0xFFFF0000;
|
||||
}
|
||||
}
|
||||
|
||||
// GAS: safety check
|
||||
if ((to_send.RIR>>21) == 0x200) {
|
||||
if (controls_allowed) {
|
||||
to_send.RDLR &= 0xFFFFFFFF;
|
||||
} else {
|
||||
to_send.RDLR &= 0xFFFF0000;
|
||||
}
|
||||
}
|
||||
|
||||
// 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;
|
||||
}
|
||||
}
|
||||
|
||||
// clear interrupt
|
||||
CAN->TSR |= CAN_TSR_RQCP0;
|
||||
}
|
||||
|
||||
// send more, possible for these to not trigger?
|
||||
void CAN1_TX_IRQHandler() {
|
||||
process_can(CAN1, &can_tx1_q, 1);
|
||||
}
|
||||
|
||||
void CAN2_TX_IRQHandler() {
|
||||
process_can(CAN2, &can_tx2_q, 0);
|
||||
}
|
||||
|
||||
// board enforces
|
||||
// in-state
|
||||
// accel set/resume
|
||||
// out-state
|
||||
// cancel button
|
||||
|
||||
|
||||
// all commands: brake and steering
|
||||
// if controls_allowed
|
||||
// allow all commands up to limit
|
||||
// else
|
||||
// block all commands that produce actuation
|
||||
|
||||
// CAN receive handlers
|
||||
void can_rx(CAN_TypeDef *CAN, int can_number) {
|
||||
while (CAN->RF0R & CAN_RF0R_FMP0) {
|
||||
// add to my fifo
|
||||
CAN_FIFOMailBox_TypeDef to_push;
|
||||
to_push.RIR = CAN->sFIFOMailBox[0].RIR;
|
||||
// top 16-bits is the timestamp
|
||||
to_push.RDTR = (CAN->sFIFOMailBox[0].RDTR & 0xFFFF000F) | (can_number << 4);
|
||||
to_push.RDLR = CAN->sFIFOMailBox[0].RDLR;
|
||||
to_push.RDHR = CAN->sFIFOMailBox[0].RDHR;
|
||||
|
||||
// state machine to enter and exit controls
|
||||
// 0x1A6 for the ILX, 0x296 for the Civic Touring
|
||||
if ((to_push.RIR>>21) == 0x1A6 || (to_push.RIR>>21) == 0x296) {
|
||||
int buttons = (to_push.RDLR & 0xE0) >> 5;
|
||||
if (buttons == 4 || buttons == 3) {
|
||||
controls_allowed = 1;
|
||||
} else if (buttons == 2) {
|
||||
controls_allowed = 0;
|
||||
}
|
||||
}
|
||||
|
||||
// exit controls on brake press
|
||||
if ((to_push.RIR>>21) == 0x17C) {
|
||||
// bit 50
|
||||
if (to_push.RDHR & 0x200000) {
|
||||
controls_allowed = 0;
|
||||
}
|
||||
}
|
||||
|
||||
// exit controls on gas press if interceptor
|
||||
if ((to_push.RIR>>21) == 0x201) {
|
||||
gas_interceptor_detected = 1;
|
||||
int gas = ((to_push.RDLR & 0xFF) << 8) | ((to_push.RDLR & 0xFF00) >> 8);
|
||||
if (gas > 328) {
|
||||
controls_allowed = 0;
|
||||
}
|
||||
}
|
||||
|
||||
// exit controls on gas press if no interceptor
|
||||
if (!gas_interceptor_detected) {
|
||||
if ((to_push.RIR>>21) == 0x17C) {
|
||||
if (to_push.RDLR & 0xFF) {
|
||||
controls_allowed = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
push(&can_rx_q, &to_push);
|
||||
|
||||
// next
|
||||
CAN->RF0R |= CAN_RF0R_RFOM0;
|
||||
}
|
||||
}
|
||||
|
||||
void CAN1_RX0_IRQHandler() {
|
||||
//puts("CANRX1");
|
||||
//delay(10000);
|
||||
can_rx(CAN1, 1);
|
||||
}
|
||||
|
||||
void CAN2_RX0_IRQHandler() {
|
||||
//puts("CANRX0");
|
||||
//delay(10000);
|
||||
can_rx(CAN2, 0);
|
||||
}
|
||||
|
||||
void CAN1_SCE_IRQHandler() {
|
||||
//puts("CAN1_SCE\n");
|
||||
can_sce(CAN1);
|
||||
}
|
||||
|
||||
void CAN2_SCE_IRQHandler() {
|
||||
//puts("CAN2_SCE\n");
|
||||
can_sce(CAN2);
|
||||
}
|
||||
|
||||
// ***************************** serial port *****************************
|
||||
|
||||
void USART_IRQHandler(void) {
|
||||
puts("S");
|
||||
|
||||
// echo characters
|
||||
if (USART->SR & USART_SR_RXNE) {
|
||||
char rcv = USART->DR;
|
||||
putch(rcv);
|
||||
|
||||
// jump to DFU flash
|
||||
if (rcv == 'z') {
|
||||
enter_bootloader_mode = ENTER_BOOTLOADER_MAGIC;
|
||||
NVIC_SystemReset();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void USART2_IRQHandler(void) {
|
||||
USART_IRQHandler();
|
||||
}
|
||||
|
||||
void USART3_IRQHandler(void) {
|
||||
USART_IRQHandler();
|
||||
}
|
||||
|
||||
// ***************************** USB port *****************************
|
||||
|
||||
int get_health_pkt(void *dat) {
|
||||
struct {
|
||||
uint32_t voltage;
|
||||
uint32_t current;
|
||||
uint8_t started;
|
||||
uint8_t controls_allowed;
|
||||
uint8_t gas_interceptor_detected;
|
||||
} *health = dat;
|
||||
health->voltage = adc_get(ADCCHAN_VOLTAGE);
|
||||
health->current = adc_get(ADCCHAN_CURRENT);
|
||||
health->started = (GPIOC->IDR & (1 << 13)) != 0;
|
||||
health->controls_allowed = controls_allowed;
|
||||
health->gas_interceptor_detected = gas_interceptor_detected;
|
||||
return sizeof(*health);
|
||||
}
|
||||
|
||||
void set_fan_speed(int fan_speed) {
|
||||
#ifdef OLD_BOARD
|
||||
TIM3->CCR4 = fan_speed;
|
||||
#else
|
||||
TIM3->CCR3 = fan_speed;
|
||||
#endif
|
||||
}
|
||||
|
||||
void usb_cb_ep1_in(int len) {
|
||||
CAN_FIFOMailBox_TypeDef reply[4];
|
||||
|
||||
int ilen = 0;
|
||||
while (ilen < min(len/0x10, 4) && pop(&can_rx_q, &reply[ilen])) ilen++;
|
||||
|
||||
#ifdef DEBUG
|
||||
puts("FIFO SENDING ");
|
||||
puth(ilen);
|
||||
puts("\n");
|
||||
#endif
|
||||
|
||||
USB_WritePacket((void *)reply, ilen*0x10, 1);
|
||||
}
|
||||
|
||||
void usb_cb_ep2_out(uint8_t *usbdata, int len) {
|
||||
}
|
||||
|
||||
// send on CAN
|
||||
void usb_cb_ep3_out(uint8_t *usbdata, int len) {
|
||||
int dpkt = 0;
|
||||
for (dpkt = 0; dpkt < len; dpkt += 0x10) {
|
||||
uint32_t *tf = (uint32_t*)(&usbdata[dpkt]);
|
||||
|
||||
int flags = tf[1] >> 4;
|
||||
CAN_TypeDef *CAN;
|
||||
can_ring *can_q;
|
||||
int can_number = 0;
|
||||
if (flags & 1) {
|
||||
CAN=CAN1;
|
||||
can_q = &can_tx1_q;
|
||||
can_number = 1;
|
||||
} else {
|
||||
CAN=CAN2;
|
||||
can_q = &can_tx2_q;
|
||||
}
|
||||
|
||||
// add CAN packet to send queue
|
||||
CAN_FIFOMailBox_TypeDef to_push;
|
||||
to_push.RDHR = tf[3];
|
||||
to_push.RDLR = tf[2];
|
||||
to_push.RDTR = tf[1] & 0xF;
|
||||
to_push.RIR = tf[0];
|
||||
push(can_q, &to_push);
|
||||
|
||||
process_can(CAN, can_q, can_number);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void usb_cb_control_msg() {
|
||||
uint8_t resp[0x20];
|
||||
int resp_len;
|
||||
switch (setup.b.bRequest) {
|
||||
case 0xd1:
|
||||
enter_bootloader_mode = ENTER_BOOTLOADER_MAGIC;
|
||||
NVIC_SystemReset();
|
||||
break;
|
||||
case 0xd2:
|
||||
resp_len = get_health_pkt(resp);
|
||||
USB_WritePacket(resp, resp_len, 0);
|
||||
USBx_OUTEP(0)->DOEPCTL |= USB_OTG_DOEPCTL_CNAK;
|
||||
break;
|
||||
case 0xd3:
|
||||
set_fan_speed(setup.b.wValue.w);
|
||||
USB_WritePacket(0, 0, 0);
|
||||
USBx_OUTEP(0)->DOEPCTL |= USB_OTG_DOEPCTL_CNAK;
|
||||
break;
|
||||
case 0xd6: // GET_VERSION
|
||||
USB_WritePacket(gitversion, min(sizeof(gitversion), setup.b.wLength.w), 0);
|
||||
USBx_OUTEP(0)->DOEPCTL |= USB_OTG_DOEPCTL_CNAK;
|
||||
break;
|
||||
case 0xd8: // RESET
|
||||
NVIC_SystemReset();
|
||||
break;
|
||||
default:
|
||||
puts("NO HANDLER ");
|
||||
puth(setup.b.bRequest);
|
||||
puts("\n");
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void OTG_FS_IRQHandler(void) {
|
||||
NVIC_DisableIRQ(OTG_FS_IRQn);
|
||||
//__disable_irq();
|
||||
usb_irqhandler();
|
||||
//__enable_irq();
|
||||
NVIC_EnableIRQ(OTG_FS_IRQn);
|
||||
}
|
||||
|
||||
void OTG_HS_IRQHandler(void) {
|
||||
//puts("HS_IRQ\n");
|
||||
NVIC_DisableIRQ(OTG_FS_IRQn);
|
||||
//__disable_irq();
|
||||
usb_irqhandler();
|
||||
//__enable_irq();
|
||||
NVIC_EnableIRQ(OTG_FS_IRQn);
|
||||
}
|
||||
|
||||
void ADC_IRQHandler(void) {
|
||||
puts("ADC_IRQ\n");
|
||||
}
|
||||
|
||||
// ***************************** main code *****************************
|
||||
|
||||
void __initialize_hardware_early() {
|
||||
// set USB power + and OTG mode
|
||||
RCC->AHB1ENR |= RCC_AHB1ENR_GPIOAEN;
|
||||
|
||||
// enable OTG out tied to ground
|
||||
GPIOA->ODR = 0;
|
||||
GPIOA->MODER |= GPIO_MODER_MODER1_0;
|
||||
|
||||
// enable USB power tied to +
|
||||
GPIOA->ODR |= 1;
|
||||
GPIOA->MODER |= GPIO_MODER_MODER0_0;
|
||||
|
||||
// enable pull DOWN on OTG_FS_DP
|
||||
// must be done a while before reading it
|
||||
GPIOA->PUPDR = GPIO_PUPDR_PUPDR12_1;
|
||||
|
||||
if (enter_bootloader_mode == ENTER_BOOTLOADER_MAGIC) {
|
||||
enter_bootloader_mode = 0;
|
||||
void (*bootloader)(void) = (void (*)(void)) (*((uint32_t *)0x1fff0004));
|
||||
|
||||
// jump to bootloader
|
||||
bootloader();
|
||||
|
||||
// LOOP
|
||||
while(1);
|
||||
}
|
||||
}
|
||||
|
||||
int main() {
|
||||
// init devices
|
||||
clock_init();
|
||||
|
||||
// test the USB choice before GPIO init
|
||||
if (GPIOA->IDR & (1 << 12)) {
|
||||
USBx = USB_OTG_HS;
|
||||
}
|
||||
|
||||
gpio_init();
|
||||
uart_init();
|
||||
usb_init();
|
||||
can_init(CAN1);
|
||||
can_init(CAN2);
|
||||
adc_init();
|
||||
|
||||
// timer for fan PWM
|
||||
#ifdef OLD_BOARD
|
||||
TIM3->CCMR2 = TIM_CCMR2_OC4M_2 | TIM_CCMR2_OC4M_1;
|
||||
TIM3->CCER = TIM_CCER_CC4E;
|
||||
#else
|
||||
TIM3->CCMR2 = TIM_CCMR2_OC3M_2 | TIM_CCMR2_OC3M_1;
|
||||
TIM3->CCER = TIM_CCER_CC3E;
|
||||
#endif
|
||||
|
||||
// max value of the timer
|
||||
// 64 makes it above the audible range
|
||||
//TIM3->ARR = 64;
|
||||
|
||||
// 10 prescale makes it below the audible range
|
||||
timer_init(TIM3, 10);
|
||||
|
||||
// set PWM
|
||||
set_fan_speed(65535);
|
||||
|
||||
puts("**** INTERRUPTS ON ****\n");
|
||||
__disable_irq();
|
||||
NVIC_EnableIRQ(USART2_IRQn);
|
||||
NVIC_EnableIRQ(USART3_IRQn);
|
||||
NVIC_EnableIRQ(OTG_FS_IRQn);
|
||||
NVIC_EnableIRQ(OTG_HS_IRQn);
|
||||
NVIC_EnableIRQ(ADC_IRQn);
|
||||
// CAN has so many interrupts!
|
||||
|
||||
NVIC_EnableIRQ(CAN1_TX_IRQn);
|
||||
NVIC_EnableIRQ(CAN1_RX0_IRQn);
|
||||
NVIC_EnableIRQ(CAN1_SCE_IRQn);
|
||||
|
||||
NVIC_EnableIRQ(CAN2_TX_IRQn);
|
||||
NVIC_EnableIRQ(CAN2_RX0_IRQn);
|
||||
NVIC_EnableIRQ(CAN2_SCE_IRQn);
|
||||
__enable_irq();
|
||||
|
||||
|
||||
// LED should keep on blinking all the time
|
||||
while (1) {
|
||||
#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
|
||||
|
||||
/*puts("voltage: "); puth(adc_get(ADCCHAN_VOLTAGE)); puts(" ");
|
||||
puts("current: "); puth(adc_get(ADCCHAN_CURRENT)); puts("\n");*/
|
||||
|
||||
// set LED to be controls allowed
|
||||
GPIOB->ODR = (GPIOB->ODR | (1 << 11)) & ~(controls_allowed << 11);
|
||||
|
||||
// blink the other LED if in FS mode
|
||||
if (USBx == USB_OTG_FS) {
|
||||
GPIOB->ODR |= (1 << 10);
|
||||
}
|
||||
delay(1000000);
|
||||
GPIOB->ODR &= ~(1 << 10);
|
||||
delay(1000000);
|
||||
|
||||
if (GPIOC->IDR & (1 << 13)) {
|
||||
// turn on fan at half speed
|
||||
set_fan_speed(32768);
|
||||
} else {
|
||||
// turn off fan
|
||||
set_fan_speed(0);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -1,511 +0,0 @@
|
|||
/**
|
||||
******************************************************************************
|
||||
* @file startup_stm32f205xx.s
|
||||
* @author MCD Application Team
|
||||
* @version V2.0.1
|
||||
* @date 25-March-2014
|
||||
* @brief STM32F205xx Devices vector table for Atollic TrueSTUDIO toolchain.
|
||||
* This module performs:
|
||||
* - Set the initial SP
|
||||
* - Set the initial PC == Reset_Handler,
|
||||
* - Set the vector table entries with the exceptions ISR address
|
||||
* - Branches to main in the C library (which eventually
|
||||
* calls main()).
|
||||
* After Reset the Cortex-M3 processor is in Thread mode,
|
||||
* priority is Privileged, and the Stack is set to Main.
|
||||
******************************************************************************
|
||||
* @attention
|
||||
*
|
||||
* <h2><center>© COPYRIGHT 2014 STMicroelectronics</center></h2>
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification,
|
||||
* are permitted provided that the following conditions are met:
|
||||
* 1. Redistributions of source code must retain the above copyright notice,
|
||||
* this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
* 3. Neither the name of STMicroelectronics nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
||||
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
******************************************************************************
|
||||
*/
|
||||
|
||||
.syntax unified
|
||||
.cpu cortex-m3
|
||||
.thumb
|
||||
|
||||
.global g_pfnVectors
|
||||
.global Default_Handler
|
||||
|
||||
/* start address for the initialization values of the .data section.
|
||||
defined in linker script */
|
||||
.word _sidata
|
||||
/* start address for the .data section. defined in linker script */
|
||||
.word _sdata
|
||||
/* end address for the .data section. defined in linker script */
|
||||
.word _edata
|
||||
/* start address for the .bss section. defined in linker script */
|
||||
.word _sbss
|
||||
/* end address for the .bss section. defined in linker script */
|
||||
.word _ebss
|
||||
/* stack used for SystemInit_ExtMemCtl; always internal RAM used */
|
||||
|
||||
/**
|
||||
* @brief This is the code that gets called when the processor first
|
||||
* starts execution following a reset event. Only the absolutely
|
||||
* necessary set is performed, after which the application
|
||||
* supplied main() routine is called.
|
||||
* @param None
|
||||
* @retval : None
|
||||
*/
|
||||
|
||||
.section .text.Reset_Handler
|
||||
.weak Reset_Handler
|
||||
.type Reset_Handler, %function
|
||||
Reset_Handler:
|
||||
bl __initialize_hardware_early
|
||||
ldr sp, =_estack /* set stack pointer */
|
||||
|
||||
/* Copy the data segment initializers from flash to SRAM */
|
||||
movs r1, #0
|
||||
b LoopCopyDataInit
|
||||
|
||||
CopyDataInit:
|
||||
ldr r3, =_sidata
|
||||
ldr r3, [r3, r1]
|
||||
str r3, [r0, r1]
|
||||
adds r1, r1, #4
|
||||
|
||||
LoopCopyDataInit:
|
||||
ldr r0, =_sdata
|
||||
ldr r3, =_edata
|
||||
adds r2, r0, r1
|
||||
cmp r2, r3
|
||||
bcc CopyDataInit
|
||||
ldr r2, =_sbss
|
||||
b LoopFillZerobss
|
||||
/* Zero fill the bss segment. */
|
||||
FillZerobss:
|
||||
movs r3, #0
|
||||
str r3, [r2], #4
|
||||
|
||||
LoopFillZerobss:
|
||||
ldr r3, = _ebss
|
||||
cmp r2, r3
|
||||
bcc FillZerobss
|
||||
|
||||
/* Call the clock system intitialization function.*/
|
||||
/* bl SystemInit */
|
||||
/* Call static constructors */
|
||||
/* bl __libc_init_array */
|
||||
/* Call the application's entry point.*/
|
||||
bl main
|
||||
bx lr
|
||||
.size Reset_Handler, .-Reset_Handler
|
||||
|
||||
/**
|
||||
* @brief This is the code that gets called when the processor receives an
|
||||
* unexpected interrupt. This simply enters an infinite loop, preserving
|
||||
* the system state for examination by a debugger.
|
||||
* @param None
|
||||
* @retval None
|
||||
*/
|
||||
.section .text.Default_Handler,"ax",%progbits
|
||||
Default_Handler:
|
||||
Infinite_Loop:
|
||||
b Infinite_Loop
|
||||
.size Default_Handler, .-Default_Handler
|
||||
/******************************************************************************
|
||||
*
|
||||
* The minimal vector table for a Cortex M3. Note that the proper constructs
|
||||
* must be placed on this to ensure that it ends up at physical address
|
||||
* 0x0000.0000.
|
||||
*
|
||||
*******************************************************************************/
|
||||
.section .isr_vector,"a",%progbits
|
||||
.type g_pfnVectors, %object
|
||||
.size g_pfnVectors, .-g_pfnVectors
|
||||
|
||||
|
||||
|
||||
g_pfnVectors:
|
||||
.word _estack
|
||||
.word Reset_Handler
|
||||
|
||||
.word NMI_Handler
|
||||
.word HardFault_Handler
|
||||
.word MemManage_Handler
|
||||
.word BusFault_Handler
|
||||
.word UsageFault_Handler
|
||||
.word 0
|
||||
.word 0
|
||||
.word 0
|
||||
.word 0
|
||||
.word SVC_Handler
|
||||
.word DebugMon_Handler
|
||||
.word 0
|
||||
.word PendSV_Handler
|
||||
.word SysTick_Handler
|
||||
|
||||
/* External Interrupts */
|
||||
.word WWDG_IRQHandler /* Window WatchDog */
|
||||
.word PVD_IRQHandler /* PVD through EXTI Line detection */
|
||||
.word TAMP_STAMP_IRQHandler /* Tamper and TimeStamps through the EXTI line */
|
||||
.word RTC_WKUP_IRQHandler /* RTC Wakeup through the EXTI line */
|
||||
.word FLASH_IRQHandler /* FLASH */
|
||||
.word RCC_IRQHandler /* RCC */
|
||||
.word EXTI0_IRQHandler /* EXTI Line0 */
|
||||
.word EXTI1_IRQHandler /* EXTI Line1 */
|
||||
.word EXTI2_IRQHandler /* EXTI Line2 */
|
||||
.word EXTI3_IRQHandler /* EXTI Line3 */
|
||||
.word EXTI4_IRQHandler /* EXTI Line4 */
|
||||
.word DMA1_Stream0_IRQHandler /* DMA1 Stream 0 */
|
||||
.word DMA1_Stream1_IRQHandler /* DMA1 Stream 1 */
|
||||
.word DMA1_Stream2_IRQHandler /* DMA1 Stream 2 */
|
||||
.word DMA1_Stream3_IRQHandler /* DMA1 Stream 3 */
|
||||
.word DMA1_Stream4_IRQHandler /* DMA1 Stream 4 */
|
||||
.word DMA1_Stream5_IRQHandler /* DMA1 Stream 5 */
|
||||
.word DMA1_Stream6_IRQHandler /* DMA1 Stream 6 */
|
||||
.word ADC_IRQHandler /* ADC1, ADC2 and ADC3s */
|
||||
.word CAN1_TX_IRQHandler /* CAN1 TX */
|
||||
.word CAN1_RX0_IRQHandler /* CAN1 RX0 */
|
||||
.word CAN1_RX1_IRQHandler /* CAN1 RX1 */
|
||||
.word CAN1_SCE_IRQHandler /* CAN1 SCE */
|
||||
.word EXTI9_5_IRQHandler /* External Line[9:5]s */
|
||||
.word TIM1_BRK_TIM9_IRQHandler /* TIM1 Break and TIM9 */
|
||||
.word TIM1_UP_TIM10_IRQHandler /* TIM1 Update and TIM10 */
|
||||
.word TIM1_TRG_COM_TIM11_IRQHandler /* TIM1 Trigger and Commutation and TIM11 */
|
||||
.word TIM1_CC_IRQHandler /* TIM1 Capture Compare */
|
||||
.word TIM2_IRQHandler /* TIM2 */
|
||||
.word TIM3_IRQHandler /* TIM3 */
|
||||
.word TIM4_IRQHandler /* TIM4 */
|
||||
.word I2C1_EV_IRQHandler /* I2C1 Event */
|
||||
.word I2C1_ER_IRQHandler /* I2C1 Error */
|
||||
.word I2C2_EV_IRQHandler /* I2C2 Event */
|
||||
.word I2C2_ER_IRQHandler /* I2C2 Error */
|
||||
.word SPI1_IRQHandler /* SPI1 */
|
||||
.word SPI2_IRQHandler /* SPI2 */
|
||||
.word USART1_IRQHandler /* USART1 */
|
||||
.word USART2_IRQHandler /* USART2 */
|
||||
.word USART3_IRQHandler /* USART3 */
|
||||
.word EXTI15_10_IRQHandler /* External Line[15:10]s */
|
||||
.word RTC_Alarm_IRQHandler /* RTC Alarm (A and B) through EXTI Line */
|
||||
.word OTG_FS_WKUP_IRQHandler /* USB OTG FS Wakeup through EXTI line */
|
||||
.word TIM8_BRK_TIM12_IRQHandler /* TIM8 Break and TIM12 */
|
||||
.word TIM8_UP_TIM13_IRQHandler /* TIM8 Update and TIM13 */
|
||||
.word TIM8_TRG_COM_TIM14_IRQHandler /* TIM8 Trigger and Commutation and TIM14 */
|
||||
.word TIM8_CC_IRQHandler /* TIM8 Capture Compare */
|
||||
.word DMA1_Stream7_IRQHandler /* DMA1 Stream7 */
|
||||
.word FSMC_IRQHandler /* FSMC */
|
||||
.word SDIO_IRQHandler /* SDIO */
|
||||
.word TIM5_IRQHandler /* TIM5 */
|
||||
.word SPI3_IRQHandler /* SPI3 */
|
||||
.word UART4_IRQHandler /* UART4 */
|
||||
.word UART5_IRQHandler /* UART5 */
|
||||
.word TIM6_DAC_IRQHandler /* TIM6 and DAC1&2 underrun errors */
|
||||
.word TIM7_IRQHandler /* TIM7 */
|
||||
.word DMA2_Stream0_IRQHandler /* DMA2 Stream 0 */
|
||||
.word DMA2_Stream1_IRQHandler /* DMA2 Stream 1 */
|
||||
.word DMA2_Stream2_IRQHandler /* DMA2 Stream 2 */
|
||||
.word DMA2_Stream3_IRQHandler /* DMA2 Stream 3 */
|
||||
.word DMA2_Stream4_IRQHandler /* DMA2 Stream 4 */
|
||||
.word 0 /* Reserved */
|
||||
.word 0 /* Reserved */
|
||||
.word CAN2_TX_IRQHandler /* CAN2 TX */
|
||||
.word CAN2_RX0_IRQHandler /* CAN2 RX0 */
|
||||
.word CAN2_RX1_IRQHandler /* CAN2 RX1 */
|
||||
.word CAN2_SCE_IRQHandler /* CAN2 SCE */
|
||||
.word OTG_FS_IRQHandler /* USB OTG FS */
|
||||
.word DMA2_Stream5_IRQHandler /* DMA2 Stream 5 */
|
||||
.word DMA2_Stream6_IRQHandler /* DMA2 Stream 6 */
|
||||
.word DMA2_Stream7_IRQHandler /* DMA2 Stream 7 */
|
||||
.word USART6_IRQHandler /* USART6 */
|
||||
.word I2C3_EV_IRQHandler /* I2C3 event */
|
||||
.word I2C3_ER_IRQHandler /* I2C3 error */
|
||||
.word OTG_HS_EP1_OUT_IRQHandler /* USB OTG HS End Point 1 Out */
|
||||
.word OTG_HS_EP1_IN_IRQHandler /* USB OTG HS End Point 1 In */
|
||||
.word OTG_HS_WKUP_IRQHandler /* USB OTG HS Wakeup through EXTI */
|
||||
.word OTG_HS_IRQHandler /* USB OTG HS */
|
||||
.word 0 /* Reserved */
|
||||
.word 0 /* Reserved */
|
||||
.word HASH_RNG_IRQHandler /* Hash and Rng */
|
||||
|
||||
/*******************************************************************************
|
||||
*
|
||||
* Provide weak aliases for each Exception handler to the Default_Handler.
|
||||
* As they are weak aliases, any function with the same name will override
|
||||
* this definition.
|
||||
*
|
||||
*******************************************************************************/
|
||||
.weak NMI_Handler
|
||||
.thumb_set NMI_Handler,Default_Handler
|
||||
|
||||
.weak HardFault_Handler
|
||||
.thumb_set HardFault_Handler,Default_Handler
|
||||
|
||||
.weak MemManage_Handler
|
||||
.thumb_set MemManage_Handler,Default_Handler
|
||||
|
||||
.weak BusFault_Handler
|
||||
.thumb_set BusFault_Handler,Default_Handler
|
||||
|
||||
.weak UsageFault_Handler
|
||||
.thumb_set UsageFault_Handler,Default_Handler
|
||||
|
||||
.weak SVC_Handler
|
||||
.thumb_set SVC_Handler,Default_Handler
|
||||
|
||||
.weak DebugMon_Handler
|
||||
.thumb_set DebugMon_Handler,Default_Handler
|
||||
|
||||
.weak PendSV_Handler
|
||||
.thumb_set PendSV_Handler,Default_Handler
|
||||
|
||||
.weak SysTick_Handler
|
||||
.thumb_set SysTick_Handler,Default_Handler
|
||||
|
||||
.weak WWDG_IRQHandler
|
||||
.thumb_set WWDG_IRQHandler,Default_Handler
|
||||
|
||||
.weak PVD_IRQHandler
|
||||
.thumb_set PVD_IRQHandler,Default_Handler
|
||||
|
||||
.weak TAMP_STAMP_IRQHandler
|
||||
.thumb_set TAMP_STAMP_IRQHandler,Default_Handler
|
||||
|
||||
.weak RTC_WKUP_IRQHandler
|
||||
.thumb_set RTC_WKUP_IRQHandler,Default_Handler
|
||||
|
||||
.weak FLASH_IRQHandler
|
||||
.thumb_set FLASH_IRQHandler,Default_Handler
|
||||
|
||||
.weak RCC_IRQHandler
|
||||
.thumb_set RCC_IRQHandler,Default_Handler
|
||||
|
||||
.weak EXTI0_IRQHandler
|
||||
.thumb_set EXTI0_IRQHandler,Default_Handler
|
||||
|
||||
.weak EXTI1_IRQHandler
|
||||
.thumb_set EXTI1_IRQHandler,Default_Handler
|
||||
|
||||
.weak EXTI2_IRQHandler
|
||||
.thumb_set EXTI2_IRQHandler,Default_Handler
|
||||
|
||||
.weak EXTI3_IRQHandler
|
||||
.thumb_set EXTI3_IRQHandler,Default_Handler
|
||||
|
||||
.weak EXTI4_IRQHandler
|
||||
.thumb_set EXTI4_IRQHandler,Default_Handler
|
||||
|
||||
.weak DMA1_Stream0_IRQHandler
|
||||
.thumb_set DMA1_Stream0_IRQHandler,Default_Handler
|
||||
|
||||
.weak DMA1_Stream1_IRQHandler
|
||||
.thumb_set DMA1_Stream1_IRQHandler,Default_Handler
|
||||
|
||||
.weak DMA1_Stream2_IRQHandler
|
||||
.thumb_set DMA1_Stream2_IRQHandler,Default_Handler
|
||||
|
||||
.weak DMA1_Stream3_IRQHandler
|
||||
.thumb_set DMA1_Stream3_IRQHandler,Default_Handler
|
||||
|
||||
.weak DMA1_Stream4_IRQHandler
|
||||
.thumb_set DMA1_Stream4_IRQHandler,Default_Handler
|
||||
|
||||
.weak DMA1_Stream5_IRQHandler
|
||||
.thumb_set DMA1_Stream5_IRQHandler,Default_Handler
|
||||
|
||||
.weak DMA1_Stream6_IRQHandler
|
||||
.thumb_set DMA1_Stream6_IRQHandler,Default_Handler
|
||||
|
||||
.weak ADC_IRQHandler
|
||||
.thumb_set ADC_IRQHandler,Default_Handler
|
||||
|
||||
.weak CAN1_TX_IRQHandler
|
||||
.thumb_set CAN1_TX_IRQHandler,Default_Handler
|
||||
|
||||
.weak CAN1_RX0_IRQHandler
|
||||
.thumb_set CAN1_RX0_IRQHandler,Default_Handler
|
||||
|
||||
.weak CAN1_RX1_IRQHandler
|
||||
.thumb_set CAN1_RX1_IRQHandler,Default_Handler
|
||||
|
||||
.weak CAN1_SCE_IRQHandler
|
||||
.thumb_set CAN1_SCE_IRQHandler,Default_Handler
|
||||
|
||||
.weak EXTI9_5_IRQHandler
|
||||
.thumb_set EXTI9_5_IRQHandler,Default_Handler
|
||||
|
||||
.weak TIM1_BRK_TIM9_IRQHandler
|
||||
.thumb_set TIM1_BRK_TIM9_IRQHandler,Default_Handler
|
||||
|
||||
.weak TIM1_UP_TIM10_IRQHandler
|
||||
.thumb_set TIM1_UP_TIM10_IRQHandler,Default_Handler
|
||||
|
||||
.weak TIM1_TRG_COM_TIM11_IRQHandler
|
||||
.thumb_set TIM1_TRG_COM_TIM11_IRQHandler,Default_Handler
|
||||
|
||||
.weak TIM1_CC_IRQHandler
|
||||
.thumb_set TIM1_CC_IRQHandler,Default_Handler
|
||||
|
||||
.weak TIM2_IRQHandler
|
||||
.thumb_set TIM2_IRQHandler,Default_Handler
|
||||
|
||||
.weak TIM3_IRQHandler
|
||||
.thumb_set TIM3_IRQHandler,Default_Handler
|
||||
|
||||
.weak TIM4_IRQHandler
|
||||
.thumb_set TIM4_IRQHandler,Default_Handler
|
||||
|
||||
.weak I2C1_EV_IRQHandler
|
||||
.thumb_set I2C1_EV_IRQHandler,Default_Handler
|
||||
|
||||
.weak I2C1_ER_IRQHandler
|
||||
.thumb_set I2C1_ER_IRQHandler,Default_Handler
|
||||
|
||||
.weak I2C2_EV_IRQHandler
|
||||
.thumb_set I2C2_EV_IRQHandler,Default_Handler
|
||||
|
||||
.weak I2C2_ER_IRQHandler
|
||||
.thumb_set I2C2_ER_IRQHandler,Default_Handler
|
||||
|
||||
.weak SPI1_IRQHandler
|
||||
.thumb_set SPI1_IRQHandler,Default_Handler
|
||||
|
||||
.weak SPI2_IRQHandler
|
||||
.thumb_set SPI2_IRQHandler,Default_Handler
|
||||
|
||||
.weak USART1_IRQHandler
|
||||
.thumb_set USART1_IRQHandler,Default_Handler
|
||||
|
||||
.weak USART2_IRQHandler
|
||||
.thumb_set USART2_IRQHandler,Default_Handler
|
||||
|
||||
.weak USART3_IRQHandler
|
||||
.thumb_set USART3_IRQHandler,Default_Handler
|
||||
|
||||
.weak EXTI15_10_IRQHandler
|
||||
.thumb_set EXTI15_10_IRQHandler,Default_Handler
|
||||
|
||||
.weak RTC_Alarm_IRQHandler
|
||||
.thumb_set RTC_Alarm_IRQHandler,Default_Handler
|
||||
|
||||
.weak OTG_FS_WKUP_IRQHandler
|
||||
.thumb_set OTG_FS_WKUP_IRQHandler,Default_Handler
|
||||
|
||||
.weak TIM8_BRK_TIM12_IRQHandler
|
||||
.thumb_set TIM8_BRK_TIM12_IRQHandler,Default_Handler
|
||||
|
||||
.weak TIM8_UP_TIM13_IRQHandler
|
||||
.thumb_set TIM8_UP_TIM13_IRQHandler,Default_Handler
|
||||
|
||||
.weak TIM8_TRG_COM_TIM14_IRQHandler
|
||||
.thumb_set TIM8_TRG_COM_TIM14_IRQHandler,Default_Handler
|
||||
|
||||
.weak TIM8_CC_IRQHandler
|
||||
.thumb_set TIM8_CC_IRQHandler,Default_Handler
|
||||
|
||||
.weak DMA1_Stream7_IRQHandler
|
||||
.thumb_set DMA1_Stream7_IRQHandler,Default_Handler
|
||||
|
||||
.weak FSMC_IRQHandler
|
||||
.thumb_set FSMC_IRQHandler,Default_Handler
|
||||
|
||||
.weak SDIO_IRQHandler
|
||||
.thumb_set SDIO_IRQHandler,Default_Handler
|
||||
|
||||
.weak TIM5_IRQHandler
|
||||
.thumb_set TIM5_IRQHandler,Default_Handler
|
||||
|
||||
.weak SPI3_IRQHandler
|
||||
.thumb_set SPI3_IRQHandler,Default_Handler
|
||||
|
||||
.weak UART4_IRQHandler
|
||||
.thumb_set UART4_IRQHandler,Default_Handler
|
||||
|
||||
.weak UART5_IRQHandler
|
||||
.thumb_set UART5_IRQHandler,Default_Handler
|
||||
|
||||
.weak TIM6_DAC_IRQHandler
|
||||
.thumb_set TIM6_DAC_IRQHandler,Default_Handler
|
||||
|
||||
.weak TIM7_IRQHandler
|
||||
.thumb_set TIM7_IRQHandler,Default_Handler
|
||||
|
||||
.weak DMA2_Stream0_IRQHandler
|
||||
.thumb_set DMA2_Stream0_IRQHandler,Default_Handler
|
||||
|
||||
.weak DMA2_Stream1_IRQHandler
|
||||
.thumb_set DMA2_Stream1_IRQHandler,Default_Handler
|
||||
|
||||
.weak DMA2_Stream2_IRQHandler
|
||||
.thumb_set DMA2_Stream2_IRQHandler,Default_Handler
|
||||
|
||||
.weak DMA2_Stream3_IRQHandler
|
||||
.thumb_set DMA2_Stream3_IRQHandler,Default_Handler
|
||||
|
||||
.weak DMA2_Stream4_IRQHandler
|
||||
.thumb_set DMA2_Stream4_IRQHandler,Default_Handler
|
||||
|
||||
.weak CAN2_TX_IRQHandler
|
||||
.thumb_set CAN2_TX_IRQHandler,Default_Handler
|
||||
|
||||
.weak CAN2_RX0_IRQHandler
|
||||
.thumb_set CAN2_RX0_IRQHandler,Default_Handler
|
||||
|
||||
.weak CAN2_RX1_IRQHandler
|
||||
.thumb_set CAN2_RX1_IRQHandler,Default_Handler
|
||||
|
||||
.weak CAN2_SCE_IRQHandler
|
||||
.thumb_set CAN2_SCE_IRQHandler,Default_Handler
|
||||
|
||||
.weak OTG_FS_IRQHandler
|
||||
.thumb_set OTG_FS_IRQHandler,Default_Handler
|
||||
|
||||
.weak DMA2_Stream5_IRQHandler
|
||||
.thumb_set DMA2_Stream5_IRQHandler,Default_Handler
|
||||
|
||||
.weak DMA2_Stream6_IRQHandler
|
||||
.thumb_set DMA2_Stream6_IRQHandler,Default_Handler
|
||||
|
||||
.weak DMA2_Stream7_IRQHandler
|
||||
.thumb_set DMA2_Stream7_IRQHandler,Default_Handler
|
||||
|
||||
.weak USART6_IRQHandler
|
||||
.thumb_set USART6_IRQHandler,Default_Handler
|
||||
|
||||
.weak I2C3_EV_IRQHandler
|
||||
.thumb_set I2C3_EV_IRQHandler,Default_Handler
|
||||
|
||||
.weak I2C3_ER_IRQHandler
|
||||
.thumb_set I2C3_ER_IRQHandler,Default_Handler
|
||||
|
||||
.weak OTG_HS_EP1_OUT_IRQHandler
|
||||
.thumb_set OTG_HS_EP1_OUT_IRQHandler,Default_Handler
|
||||
|
||||
.weak OTG_HS_EP1_IN_IRQHandler
|
||||
.thumb_set OTG_HS_EP1_IN_IRQHandler,Default_Handler
|
||||
|
||||
.weak OTG_HS_WKUP_IRQHandler
|
||||
.thumb_set OTG_HS_WKUP_IRQHandler,Default_Handler
|
||||
|
||||
.weak OTG_HS_IRQHandler
|
||||
.thumb_set OTG_HS_IRQHandler,Default_Handler
|
||||
|
||||
.weak HASH_RNG_IRQHandler
|
||||
.thumb_set HASH_RNG_IRQHandler,Default_Handler
|
||||
|
||||
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
|
|
@ -1,163 +0,0 @@
|
|||
/*
|
||||
*****************************************************************************
|
||||
**
|
||||
** File : stm32_flash.ld
|
||||
**
|
||||
** Abstract : Linker script for STM32F407VG Device with
|
||||
** 1024KByte FLASH, 192KByte RAM
|
||||
**
|
||||
** Set heap size, stack size and stack location according
|
||||
** to application requirements.
|
||||
**
|
||||
** Set memory bank area and size if external memory is used.
|
||||
**
|
||||
** Target : STMicroelectronics STM32
|
||||
**
|
||||
** Environment : Atollic TrueSTUDIO(R)
|
||||
**
|
||||
** Distribution: The file is distributed “as is,” without any warranty
|
||||
** of any kind.
|
||||
**
|
||||
** (c)Copyright Atollic AB.
|
||||
** You may use this file as-is or modify it according to the needs of your
|
||||
** project. Distribution of this file (unmodified or modified) is not
|
||||
** permitted. Atollic AB permit registered Atollic TrueSTUDIO(R) users the
|
||||
** rights to distribute the assembled, compiled & linked contents of this
|
||||
** file as part of an application binary file, provided that it is built
|
||||
** using the Atollic TrueSTUDIO(R) toolchain.
|
||||
**
|
||||
*****************************************************************************
|
||||
*/
|
||||
|
||||
/* Entry Point */
|
||||
ENTRY(Reset_Handler)
|
||||
|
||||
/* Highest address of the user mode stack */
|
||||
_estack = 0x20020000; /* end of 128K RAM on AHB bus*/
|
||||
|
||||
/* Generate a link error if heap and stack don't fit into RAM */
|
||||
_Min_Heap_Size = 0; /* required amount of heap */
|
||||
_Min_Stack_Size = 0x400; /* required amount of stack */
|
||||
|
||||
/* Specify the memory areas */
|
||||
MEMORY
|
||||
{
|
||||
FLASH (rx) : ORIGIN = 0x08000000, LENGTH = 128K
|
||||
RAM (xrw) : ORIGIN = 0x20000000, LENGTH = 128K
|
||||
MEMORY_B1 (rx) : ORIGIN = 0x60000000, LENGTH = 0K
|
||||
}
|
||||
|
||||
/* Define output sections */
|
||||
SECTIONS
|
||||
{
|
||||
/* The startup code goes first into FLASH */
|
||||
.isr_vector :
|
||||
{
|
||||
. = ALIGN(4);
|
||||
KEEP(*(.isr_vector)) /* Startup code */
|
||||
. = ALIGN(4);
|
||||
} >FLASH
|
||||
|
||||
/* The program code and other data goes into FLASH */
|
||||
.text :
|
||||
{
|
||||
. = ALIGN(4);
|
||||
*(.text) /* .text sections (code) */
|
||||
*(.text*) /* .text* sections (code) */
|
||||
*(.rodata) /* .rodata sections (constants, strings, etc.) */
|
||||
*(.rodata*) /* .rodata* sections (constants, strings, etc.) */
|
||||
*(.glue_7) /* glue arm to thumb code */
|
||||
*(.glue_7t) /* glue thumb to arm code */
|
||||
*(.eh_frame)
|
||||
|
||||
KEEP (*(.init))
|
||||
KEEP (*(.fini))
|
||||
|
||||
. = ALIGN(4);
|
||||
_etext = .; /* define a global symbols at end of code */
|
||||
_exit = .;
|
||||
} >FLASH
|
||||
|
||||
|
||||
.ARM.extab : { *(.ARM.extab* .gnu.linkonce.armextab.*) } >FLASH
|
||||
.ARM : {
|
||||
__exidx_start = .;
|
||||
*(.ARM.exidx*)
|
||||
__exidx_end = .;
|
||||
} >FLASH
|
||||
|
||||
.preinit_array :
|
||||
{
|
||||
PROVIDE_HIDDEN (__preinit_array_start = .);
|
||||
KEEP (*(.preinit_array*))
|
||||
PROVIDE_HIDDEN (__preinit_array_end = .);
|
||||
} >FLASH
|
||||
.init_array :
|
||||
{
|
||||
PROVIDE_HIDDEN (__init_array_start = .);
|
||||
KEEP (*(SORT(.init_array.*)))
|
||||
KEEP (*(.init_array*))
|
||||
PROVIDE_HIDDEN (__init_array_end = .);
|
||||
} >FLASH
|
||||
.fini_array :
|
||||
{
|
||||
PROVIDE_HIDDEN (__fini_array_start = .);
|
||||
KEEP (*(.fini_array*))
|
||||
KEEP (*(SORT(.fini_array.*)))
|
||||
PROVIDE_HIDDEN (__fini_array_end = .);
|
||||
} >FLASH
|
||||
|
||||
/* used by the startup to initialize data */
|
||||
_sidata = .;
|
||||
|
||||
/* Initialized data sections goes into RAM, load LMA copy after code */
|
||||
.data : AT ( _sidata )
|
||||
{
|
||||
. = ALIGN(4);
|
||||
_sdata = .; /* create a global symbol at data start */
|
||||
*(.data) /* .data sections */
|
||||
*(.data*) /* .data* sections */
|
||||
|
||||
. = ALIGN(4);
|
||||
_edata = .; /* define a global symbol at data end */
|
||||
} >RAM
|
||||
|
||||
/* Uninitialized data section */
|
||||
. = ALIGN(4);
|
||||
.bss :
|
||||
{
|
||||
/* This is used by the startup in order to initialize the .bss secion */
|
||||
_sbss = .; /* define a global symbol at bss start */
|
||||
__bss_start__ = _sbss;
|
||||
*(.bss)
|
||||
*(.bss*)
|
||||
*(COMMON)
|
||||
|
||||
. = ALIGN(4);
|
||||
_ebss = .; /* define a global symbol at bss end */
|
||||
__bss_end__ = _ebss;
|
||||
} >RAM
|
||||
|
||||
/* User_heap_stack section, used to check that there is enough RAM left */
|
||||
._user_heap_stack :
|
||||
{
|
||||
. = ALIGN(4);
|
||||
PROVIDE ( end = . );
|
||||
PROVIDE ( _end = . );
|
||||
. = . + _Min_Heap_Size;
|
||||
. = . + _Min_Stack_Size;
|
||||
. = ALIGN(4);
|
||||
} >RAM
|
||||
|
||||
/* MEMORY_bank1 section, code must be located here explicitly */
|
||||
/* Example: extern int foo(void) __attribute__ ((section (".mb1text"))); */
|
||||
.memory_b1_text :
|
||||
{
|
||||
*(.mb1text) /* .mb1text sections (code) */
|
||||
*(.mb1text*) /* .mb1text* sections (code) */
|
||||
*(.mb1rodata) /* read-only data (constants) */
|
||||
*(.mb1rodata*)
|
||||
} >MEMORY_B1
|
||||
|
||||
.ARM.attributes 0 : { *(.ARM.attributes) }
|
||||
}
|
|
@ -1,7 +0,0 @@
|
|||
void timer_init(TIM_TypeDef *TIM, int psc) {
|
||||
TIM->PSC = psc-1;
|
||||
TIM->DIER = TIM_DIER_UIE;
|
||||
TIM->CR1 = TIM_CR1_CEN;
|
||||
TIM->SR = 0;
|
||||
}
|
||||
|
Binary file not shown.
Binary file not shown.
|
@ -1,20 +0,0 @@
|
|||
#!/usr/bin/env python
|
||||
import usb1
|
||||
import time
|
||||
import traceback
|
||||
|
||||
if __name__ == "__main__":
|
||||
context = usb1.USBContext()
|
||||
|
||||
for device in context.getDeviceList(skip_on_error=True):
|
||||
if device.getVendorID() == 0xbbaa and device.getProductID()&0xFF00 == 0xdd00:
|
||||
print "found device"
|
||||
handle = device.open()
|
||||
handle.claimInterface(0)
|
||||
|
||||
try:
|
||||
handle.controlWrite(usb1.TYPE_VENDOR | usb1.RECIPIENT_DEVICE, 0xd1, 0, 0, '')
|
||||
except Exception:
|
||||
traceback.print_exc()
|
||||
print "expected error, exiting cleanly"
|
||||
time.sleep(1)
|
510
board/usb.h
510
board/usb.h
|
@ -1,510 +0,0 @@
|
|||
// **** supporting defines ****
|
||||
|
||||
typedef struct
|
||||
{
|
||||
__IO uint32_t HPRT;
|
||||
}
|
||||
USB_OTG_HostPortTypeDef;
|
||||
|
||||
#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_PCGCCTL *(__IO uint32_t *)((uint32_t)USBx + USB_OTG_PCGCCTL_BASE)
|
||||
|
||||
#define USB_REQ_GET_STATUS 0x00
|
||||
#define USB_REQ_CLEAR_FEATURE 0x01
|
||||
#define USB_REQ_SET_FEATURE 0x03
|
||||
#define USB_REQ_SET_ADDRESS 0x05
|
||||
#define USB_REQ_GET_DESCRIPTOR 0x06
|
||||
#define USB_REQ_SET_DESCRIPTOR 0x07
|
||||
#define USB_REQ_GET_CONFIGURATION 0x08
|
||||
#define USB_REQ_SET_CONFIGURATION 0x09
|
||||
#define USB_REQ_GET_INTERFACE 0x0A
|
||||
#define USB_REQ_SET_INTERFACE 0x0B
|
||||
#define USB_REQ_SYNCH_FRAME 0x0C
|
||||
|
||||
#define USB_DESC_TYPE_DEVICE 1
|
||||
#define USB_DESC_TYPE_CONFIGURATION 2
|
||||
#define USB_DESC_TYPE_STRING 3
|
||||
#define USB_DESC_TYPE_INTERFACE 4
|
||||
#define USB_DESC_TYPE_ENDPOINT 5
|
||||
#define USB_DESC_TYPE_DEVICE_QUALIFIER 6
|
||||
#define USB_DESC_TYPE_OTHER_SPEED_CONFIGURATION 7
|
||||
|
||||
#define STS_GOUT_NAK 1
|
||||
#define STS_DATA_UPDT 2
|
||||
#define STS_XFER_COMP 3
|
||||
#define STS_SETUP_COMP 4
|
||||
#define STS_SETUP_UPDT 6
|
||||
|
||||
#define USBD_FS_TRDT_VALUE 5
|
||||
|
||||
// interfaces
|
||||
void usb_cb_control_msg();
|
||||
void usb_cb_ep1_in(int len);
|
||||
void usb_cb_ep2_out(uint8_t *usbdata, int len);
|
||||
void usb_cb_ep3_out(uint8_t *usbdata, int len);
|
||||
|
||||
uint8_t device_desc[] = {
|
||||
0x12,0x01,0x00,0x01,
|
||||
0xFF,0xFF,0xFF,0x40,
|
||||
(USB_VID>>0)&0xFF,(USB_VID>>8)&0xFF,
|
||||
(USB_PID>>0)&0xFF,(USB_PID>>8)&0xFF,
|
||||
0x00,0x22,0x00,0x00,
|
||||
0x00,0x01};
|
||||
|
||||
uint8_t configuration_desc[] = {
|
||||
0x09, 0x02, 0x27, 0x00,
|
||||
0x01, 0x01, 0x00, 0xc0,
|
||||
0x32,
|
||||
// interface 0
|
||||
0x09, 0x04, 0x00, 0x00,
|
||||
0x03, 0xff, 0xFF, 0xFF,
|
||||
0x00,
|
||||
// endpoint 1, read CAN
|
||||
0x07, 0x05, 0x81, 0x02, 0x40, 0x00, 0x00,
|
||||
// endpoint 2, AES load
|
||||
0x07, 0x05, 0x02, 0x02, 0x10, 0x00, 0x00,
|
||||
// endpoint 3, send CAN
|
||||
0x07, 0x05, 0x03, 0x02, 0x40, 0x00, 0x00,
|
||||
};
|
||||
|
||||
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;
|
||||
|
||||
// current packet
|
||||
USB_Setup_TypeDef setup;
|
||||
uint8_t usbdata[0x100];
|
||||
|
||||
// packet read and write
|
||||
|
||||
void *USB_ReadPacket(void *dest, uint16_t len) {
|
||||
uint32_t i=0;
|
||||
uint32_t count32b = (len + 3) / 4;
|
||||
|
||||
for ( i = 0; i < count32b; i++, dest += 4 ) {
|
||||
// packed?
|
||||
*(__attribute__((__packed__)) uint32_t *)dest = USBx_DFIFO(0);
|
||||
}
|
||||
return ((void *)dest);
|
||||
}
|
||||
|
||||
void USB_WritePacket(const uint8_t *src, uint16_t len, uint32_t ep) {
|
||||
#ifdef DEBUG
|
||||
puts("writing ");
|
||||
hexdump(src, len);
|
||||
#endif
|
||||
uint32_t count32b = 0, i = 0;
|
||||
count32b = (len + 3) / 4;
|
||||
|
||||
// bullshit
|
||||
USBx_INEP(ep)->DIEPTSIZ = (USB_OTG_DIEPTSIZ_PKTCNT & (1 << 19)) | (len & USB_OTG_DIEPTSIZ_XFRSIZ);
|
||||
USBx_INEP(ep)->DIEPCTL |= (USB_OTG_DIEPCTL_CNAK | USB_OTG_DIEPCTL_EPENA);
|
||||
|
||||
// load the FIFO
|
||||
for (i = 0; i < count32b; i++, src += 4) {
|
||||
USBx_DFIFO(ep) = *((__attribute__((__packed__)) uint32_t *)src);
|
||||
}
|
||||
}
|
||||
|
||||
void usb_reset() {
|
||||
// unmask endpoint interrupts, so many sets
|
||||
USBx_DEVICE->DAINT = 0xFFFFFFFF;
|
||||
USBx_DEVICE->DAINTMSK = 0xFFFFFFFF;
|
||||
//USBx_DEVICE->DOEPMSK = (USB_OTG_DOEPMSK_STUPM | USB_OTG_DOEPMSK_XFRCM | USB_OTG_DOEPMSK_EPDM);
|
||||
//USBx_DEVICE->DIEPMSK = (USB_OTG_DIEPMSK_TOM | USB_OTG_DIEPMSK_XFRCM | USB_OTG_DIEPMSK_EPDM | USB_OTG_DIEPMSK_ITTXFEMSK);
|
||||
//USBx_DEVICE->DIEPMSK = (USB_OTG_DIEPMSK_TOM | USB_OTG_DIEPMSK_XFRCM | USB_OTG_DIEPMSK_EPDM);
|
||||
|
||||
// all interrupts for debugging
|
||||
USBx_DEVICE->DIEPMSK = 0xFFFFFFFF;
|
||||
USBx_DEVICE->DOEPMSK = 0xFFFFFFFF;
|
||||
|
||||
// clear interrupts
|
||||
USBx_INEP(0)->DIEPINT = 0xFF;
|
||||
USBx_OUTEP(0)->DOEPINT = 0xFF;
|
||||
|
||||
// unset the address
|
||||
USBx_DEVICE->DCFG &= ~USB_OTG_DCFG_DAD;
|
||||
|
||||
// set up USB FIFOs
|
||||
// RX start address is fixed to 0
|
||||
USBx->GRXFSIZ = 0x40;
|
||||
|
||||
// 0x100 to offset past GRXFSIZ
|
||||
USBx->DIEPTXF0_HNPTXFSIZ = (0x40 << 16) | 0x40;
|
||||
|
||||
// EP1, massive
|
||||
USBx->DIEPTXF[0] = (0x40 << 16) | 0x80;
|
||||
|
||||
// flush TX fifo
|
||||
USBx->GRSTCTL = USB_OTG_GRSTCTL_TXFFLSH | USB_OTG_GRSTCTL_TXFNUM_4;
|
||||
while ((USBx->GRSTCTL & USB_OTG_GRSTCTL_TXFFLSH) == USB_OTG_GRSTCTL_TXFFLSH);
|
||||
// flush RX FIFO
|
||||
USBx->GRSTCTL = USB_OTG_GRSTCTL_RXFFLSH;
|
||||
while ((USBx->GRSTCTL & USB_OTG_GRSTCTL_RXFFLSH) == USB_OTG_GRSTCTL_RXFFLSH);
|
||||
|
||||
// no global NAK
|
||||
USBx_DEVICE->DCTL |= USB_OTG_DCTL_CGINAK;
|
||||
|
||||
// ready to receive setup packets
|
||||
USBx_OUTEP(0)->DOEPTSIZ = USB_OTG_DOEPTSIZ_STUPCNT | (USB_OTG_DOEPTSIZ_PKTCNT & (1 << 19)) | (3 * 8);
|
||||
}
|
||||
|
||||
void usb_setup() {
|
||||
uint8_t resp[0x20];
|
||||
// setup packet is ready
|
||||
switch (setup.b.bRequest) {
|
||||
case USB_REQ_SET_CONFIGURATION:
|
||||
// enable other endpoints, has to be here?
|
||||
USBx_INEP(1)->DIEPCTL = (0x40 & USB_OTG_DIEPCTL_MPSIZ) | (2 << 18) | (1 << 22) |
|
||||
USB_OTG_DIEPCTL_SD0PID_SEVNFRM | USB_OTG_DIEPCTL_USBAEP;
|
||||
USBx_INEP(1)->DIEPINT = 0xFF;
|
||||
|
||||
USBx_OUTEP(2)->DOEPTSIZ = (1 << 19) | 0x10;
|
||||
USBx_OUTEP(2)->DOEPCTL = (0x10 & USB_OTG_DOEPCTL_MPSIZ) | (2 << 18) |
|
||||
USB_OTG_DOEPCTL_SD0PID_SEVNFRM | USB_OTG_DOEPCTL_USBAEP;
|
||||
USBx_OUTEP(2)->DOEPINT = 0xFF;
|
||||
|
||||
USBx_OUTEP(3)->DOEPTSIZ = (1 << 19) | 0x40;
|
||||
USBx_OUTEP(3)->DOEPCTL = (0x40 & USB_OTG_DOEPCTL_MPSIZ) | (2 << 18) |
|
||||
USB_OTG_DOEPCTL_SD0PID_SEVNFRM | USB_OTG_DOEPCTL_USBAEP;
|
||||
USBx_OUTEP(3)->DOEPINT = 0xFF;
|
||||
|
||||
// mark ready to receive
|
||||
USBx_OUTEP(2)->DOEPCTL |= USB_OTG_DOEPCTL_EPENA | USB_OTG_DOEPCTL_CNAK;
|
||||
USBx_OUTEP(3)->DOEPCTL |= USB_OTG_DOEPCTL_EPENA | USB_OTG_DOEPCTL_CNAK;
|
||||
|
||||
USB_WritePacket(0, 0, 0);
|
||||
USBx_OUTEP(0)->DOEPCTL |= USB_OTG_DOEPCTL_CNAK;
|
||||
break;
|
||||
case USB_REQ_SET_ADDRESS:
|
||||
// set now?
|
||||
USBx_DEVICE->DCFG |= ((setup.b.wValue.w & 0x7f) << 4);
|
||||
|
||||
#ifdef DEBUG
|
||||
puts(" set address\n");
|
||||
#endif
|
||||
|
||||
|
||||
USB_WritePacket(0, 0, 0);
|
||||
USBx_OUTEP(0)->DOEPCTL |= USB_OTG_DOEPCTL_CNAK;
|
||||
|
||||
break;
|
||||
case USB_REQ_GET_DESCRIPTOR:
|
||||
switch (setup.b.wValue.bw.lsb) {
|
||||
case USB_DESC_TYPE_DEVICE:
|
||||
//puts(" writing device descriptor\n");
|
||||
|
||||
// setup transfer
|
||||
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);
|
||||
USBx_OUTEP(0)->DOEPCTL |= USB_OTG_DOEPCTL_CNAK;
|
||||
break;
|
||||
default:
|
||||
// nothing here?
|
||||
USB_WritePacket(0, 0, 0);
|
||||
USBx_OUTEP(0)->DOEPCTL |= USB_OTG_DOEPCTL_CNAK;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case USB_REQ_GET_STATUS:
|
||||
// empty resp?
|
||||
resp[0] = 0;
|
||||
resp[1] = 0;
|
||||
USB_WritePacket((void*)&resp, 2, 0);
|
||||
USBx_OUTEP(0)->DOEPCTL |= USB_OTG_DOEPCTL_CNAK;
|
||||
break;
|
||||
default:
|
||||
usb_cb_control_msg();
|
||||
}
|
||||
}
|
||||
|
||||
void usb_init() {
|
||||
// internal PHY set before reset
|
||||
USBx->GUSBCFG |= USB_OTG_GUSBCFG_PHYSEL;
|
||||
|
||||
// full speed PHY, do reset and remove power down
|
||||
puth(USBx->GRSTCTL);
|
||||
puts(" resetting PHY\n");
|
||||
while ((USBx->GRSTCTL & USB_OTG_GRSTCTL_AHBIDL) == 0);
|
||||
puts("AHB idle\n");
|
||||
|
||||
// reset PHY here?
|
||||
USBx->GRSTCTL |= USB_OTG_GRSTCTL_CSRST;
|
||||
while ((USBx->GRSTCTL & USB_OTG_GRSTCTL_CSRST) == USB_OTG_GRSTCTL_CSRST);
|
||||
puts("reset done\n");
|
||||
|
||||
// power up the PHY
|
||||
USBx->GCCFG = USB_OTG_GCCFG_PWRDWN | USB_OTG_GCCFG_NOVBUSSENS;
|
||||
|
||||
// be a device, slowest timings
|
||||
//USBx->GUSBCFG = USB_OTG_GUSBCFG_FDMOD | USB_OTG_GUSBCFG_PHYSEL | USB_OTG_GUSBCFG_TRDT | USB_OTG_GUSBCFG_TOCAL;
|
||||
USBx->GUSBCFG = USB_OTG_GUSBCFG_FDMOD | USB_OTG_GUSBCFG_PHYSEL;
|
||||
USBx->GUSBCFG |= (uint32_t)((USBD_FS_TRDT_VALUE << 10) & USB_OTG_GUSBCFG_TRDT);
|
||||
//USBx->GUSBCFG = USB_OTG_GUSBCFG_PHYSEL | USB_OTG_GUSBCFG_TRDT | USB_OTG_GUSBCFG_TOCAL;
|
||||
|
||||
// **** for debugging, doesn't seem to work ****
|
||||
//USBx->GUSBCFG |= USB_OTG_GUSBCFG_CTXPKT;
|
||||
|
||||
// reset PHY clock
|
||||
USBx_PCGCCTL = 0;
|
||||
|
||||
// enable the fancy OTG things
|
||||
USBx->GUSBCFG |= USB_OTG_GUSBCFG_HNPCAP | USB_OTG_GUSBCFG_SRPCAP;
|
||||
|
||||
USBx_DEVICE->DCFG = USB_OTG_DCFG_NZLSOHSK | USB_OTG_DCFG_DSPD;
|
||||
//USBx_DEVICE->DCFG = USB_OTG_DCFG_DSPD;
|
||||
|
||||
// setup USB interrupts
|
||||
// all interrupts except TXFIFO EMPTY
|
||||
//USBx->GINTMSK = 0xFFFFFFFF & ~(USB_OTG_GINTMSK_NPTXFEM | USB_OTG_GINTMSK_PTXFEM | USB_OTG_GINTSTS_SOF | USB_OTG_GINTSTS_EOPF);
|
||||
USBx->GINTMSK = 0xFFFFFFFF & ~(USB_OTG_GINTMSK_NPTXFEM | USB_OTG_GINTMSK_PTXFEM);
|
||||
|
||||
USBx->GAHBCFG = USB_OTG_GAHBCFG_GINT;
|
||||
USBx->GINTSTS = 0;
|
||||
}
|
||||
|
||||
// ***************************** USB port *****************************
|
||||
|
||||
void usb_irqhandler(void) {
|
||||
USBx->GINTMSK = 0;
|
||||
|
||||
unsigned int gintsts = USBx->GINTSTS;
|
||||
|
||||
// gintsts SUSPEND? 04008428
|
||||
#ifdef DEBUG
|
||||
unsigned int daint = USBx_DEVICE->DAINT;
|
||||
puth(gintsts);
|
||||
puts(" ep ");
|
||||
puth(daint);
|
||||
puts(" USB interrupt!\n");
|
||||
#endif
|
||||
|
||||
if (gintsts & USB_OTG_GINTSTS_ESUSP) {
|
||||
puts("ESUSP detected\n");
|
||||
}
|
||||
|
||||
if (gintsts & USB_OTG_GINTSTS_USBRST) {
|
||||
puts("USB reset\n");
|
||||
usb_reset();
|
||||
}
|
||||
|
||||
if (gintsts & USB_OTG_GINTSTS_ENUMDNE) {
|
||||
puts("enumeration done ");
|
||||
// Full speed, ENUMSPD
|
||||
puth(USBx_DEVICE->DSTS);
|
||||
puts("\n");
|
||||
}
|
||||
|
||||
if (gintsts & USB_OTG_GINTSTS_OTGINT) {
|
||||
puts("OTG int:");
|
||||
puth(USBx->GOTGINT);
|
||||
puts("\n");
|
||||
|
||||
// getting ADTOCHG
|
||||
USBx->GOTGINT = USBx->GOTGINT;
|
||||
}
|
||||
|
||||
// RX FIFO first
|
||||
if (gintsts & USB_OTG_GINTSTS_RXFLVL) {
|
||||
// 1. Read the Receive status pop register
|
||||
volatile unsigned int rxst = USBx->GRXSTSP;
|
||||
|
||||
#ifdef DEBUG
|
||||
puts(" RX FIFO:");
|
||||
puth(rxst);
|
||||
puts(" status: ");
|
||||
puth((rxst & USB_OTG_GRXSTSP_PKTSTS) >> 17);
|
||||
puts(" len: ");
|
||||
puth((rxst & USB_OTG_GRXSTSP_BCNT) >> 4);
|
||||
puts("\n");
|
||||
#endif
|
||||
|
||||
|
||||
if (((rxst & USB_OTG_GRXSTSP_PKTSTS) >> 17) == STS_DATA_UPDT) {
|
||||
int endpoint = (rxst & USB_OTG_GRXSTSP_EPNUM);
|
||||
int len = (rxst & USB_OTG_GRXSTSP_BCNT) >> 4;
|
||||
USB_ReadPacket(&usbdata, len);
|
||||
#ifdef DEBUG
|
||||
puts(" data ");
|
||||
puth(len);
|
||||
puts("\n");
|
||||
hexdump(&usbdata, len);
|
||||
#endif
|
||||
|
||||
if (endpoint == 2) {
|
||||
usb_cb_ep2_out(usbdata, len);
|
||||
}
|
||||
|
||||
if (endpoint == 3) {
|
||||
usb_cb_ep3_out(usbdata, len);
|
||||
}
|
||||
} else if (((rxst & USB_OTG_GRXSTSP_PKTSTS) >> 17) == STS_SETUP_UPDT) {
|
||||
USB_ReadPacket(&setup, 8);
|
||||
#ifdef DEBUG
|
||||
puts(" setup ");
|
||||
hexdump(&setup, 8);
|
||||
puts("\n");
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
if (gintsts & USB_OTG_GINTSTS_HPRTINT) {
|
||||
// host
|
||||
puts("HPRT:");
|
||||
puth(USBx_HOST_PORT->HPRT);
|
||||
puts("\n");
|
||||
if (USBx_HOST_PORT->HPRT & USB_OTG_HPRT_PCDET) {
|
||||
USBx_HOST_PORT->HPRT |= USB_OTG_HPRT_PRST;
|
||||
USBx_HOST_PORT->HPRT |= USB_OTG_HPRT_PCDET;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if (gintsts & USB_OTG_GINTSTS_BOUTNAKEFF) {
|
||||
// no global NAK, why is this getting set?
|
||||
#ifdef DEBUG
|
||||
puts("GLOBAL NAK\n");
|
||||
#endif
|
||||
USBx_DEVICE->DCTL |= USB_OTG_DCTL_CGONAK | USB_OTG_DCTL_CGINAK;
|
||||
}
|
||||
|
||||
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");
|
||||
//USBx->GUSBCFG |= USB_OTG_GUSBCFG_FDMOD;
|
||||
//USBx_HOST_PORT->HPRT = USB_OTG_HPRT_PPWR | USB_OTG_HPRT_PENA;
|
||||
}
|
||||
|
||||
// out endpoint hit
|
||||
if (gintsts & USB_OTG_GINTSTS_OEPINT) {
|
||||
#ifdef DEBUG
|
||||
puts(" 0:");
|
||||
puth(USBx_OUTEP(0)->DOEPINT);
|
||||
puts(" 2:");
|
||||
puth(USBx_OUTEP(2)->DOEPINT);
|
||||
puts(" 3:");
|
||||
puth(USBx_OUTEP(3)->DOEPINT);
|
||||
puts(" ");
|
||||
puth(USBx_OUTEP(3)->DOEPCTL);
|
||||
puts(" 4:");
|
||||
puth(USBx_OUTEP(4)->DOEPINT);
|
||||
puts(" OUT ENDPOINT\n");
|
||||
#endif
|
||||
|
||||
if (USBx_OUTEP(2)->DOEPINT & USB_OTG_DOEPINT_XFRC) {
|
||||
#ifdef DEBUG
|
||||
puts(" OUT2 PACKET XFRC\n");
|
||||
#endif
|
||||
USBx_OUTEP(2)->DOEPTSIZ = (1 << 19) | 0x10;
|
||||
USBx_OUTEP(2)->DOEPCTL |= USB_OTG_DOEPCTL_EPENA | USB_OTG_DOEPCTL_CNAK;
|
||||
}
|
||||
|
||||
if (USBx_OUTEP(3)->DOEPINT & USB_OTG_DOEPINT_XFRC) {
|
||||
#ifdef DEBUG
|
||||
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) {
|
||||
#ifdef DEBUG
|
||||
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) {
|
||||
puts("OUTEP3 error ");
|
||||
puth(USBx_OUTEP(3)->DOEPINT);
|
||||
puts("\n");
|
||||
}
|
||||
|
||||
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) {
|
||||
usb_setup();
|
||||
}
|
||||
|
||||
USBx_OUTEP(0)->DOEPINT = USBx_OUTEP(0)->DOEPINT;
|
||||
USBx_OUTEP(2)->DOEPINT = USBx_OUTEP(2)->DOEPINT;
|
||||
USBx_OUTEP(3)->DOEPINT = USBx_OUTEP(3)->DOEPINT;
|
||||
}
|
||||
|
||||
|
||||
// in endpoint hit
|
||||
if (gintsts & USB_OTG_GINTSTS_IEPINT) {
|
||||
#ifdef DEBUG
|
||||
puts(" ");
|
||||
puth(USBx_INEP(0)->DIEPINT);
|
||||
puts(" ");
|
||||
puth(USBx_INEP(1)->DIEPINT);
|
||||
puts(" IN ENDPOINT\n");
|
||||
#endif
|
||||
|
||||
// this happens first
|
||||
if (USBx_INEP(1)->DIEPINT & USB_OTG_DIEPINT_XFRC) {
|
||||
#ifdef DEBUG
|
||||
puts(" IN PACKET SEND\n");
|
||||
#endif
|
||||
//USBx_DEVICE->DIEPEMPMSK = ~(1 << 1);
|
||||
}
|
||||
|
||||
// *** IN token received when TxFIFO is empty
|
||||
if (USBx_INEP(1)->DIEPINT & USB_OTG_DIEPMSK_ITTXFEMSK) {
|
||||
#ifdef DEBUG
|
||||
puts(" IN PACKET QUEUE\n");
|
||||
#endif
|
||||
// TODO: always assuming max len, can we get the length?
|
||||
usb_cb_ep1_in(0x40);
|
||||
}
|
||||
|
||||
// clear interrupts
|
||||
USBx_INEP(0)->DIEPINT = USBx_INEP(0)->DIEPINT;
|
||||
USBx_INEP(1)->DIEPINT = USBx_INEP(1)->DIEPINT;
|
||||
}
|
||||
|
||||
|
||||
// clear all interrupts
|
||||
USBx_DEVICE->DAINT = USBx_DEVICE->DAINT;
|
||||
USBx->GINTSTS = USBx->GINTSTS;
|
||||
|
||||
USBx->GINTMSK = 0xFFFFFFFF & ~(USB_OTG_GINTMSK_NPTXFEM | USB_OTG_GINTMSK_PTXFEM | USB_OTG_GINTSTS_SOF | USB_OTG_GINTSTS_EOPF);
|
||||
}
|
||||
|
|
@ -0,0 +1 @@
|
|||
Subproject commit 7c3a2f87196f312529dae9d0ba05d6a449b14482
|
|
@ -1,7 +0,0 @@
|
|||
import os
|
||||
import capnp
|
||||
capnp.remove_import_hook()
|
||||
|
||||
CEREAL_PATH = os.path.dirname(os.path.abspath(__file__))
|
||||
log = capnp.load(os.path.join(CEREAL_PATH, "log.capnp"))
|
||||
|
|
@ -1,26 +0,0 @@
|
|||
# Copyright (c) 2013-2014 Sandstorm Development Group, Inc. and contributors
|
||||
# Licensed under the MIT License:
|
||||
#
|
||||
# Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
# of this software and associated documentation files (the "Software"), to deal
|
||||
# in the Software without restriction, including without limitation the rights
|
||||
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
# copies of the Software, and to permit persons to whom the Software is
|
||||
# furnished to do so, subject to the following conditions:
|
||||
#
|
||||
# The above copyright notice and this permission notice shall be included in
|
||||
# all copies or substantial portions of the Software.
|
||||
#
|
||||
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
# THE SOFTWARE.
|
||||
|
||||
@0xbdf87d7bb8304e81;
|
||||
$namespace("capnp::annotations");
|
||||
|
||||
annotation namespace(file): Text;
|
||||
annotation name(field, enumerant, struct, enum, interface, method, param, group, union): Text;
|
File diff suppressed because it is too large
Load Diff
|
@ -1,667 +0,0 @@
|
|||
#ifndef CAPN_F3B1F17E25A4285B
|
||||
#define CAPN_F3B1F17E25A4285B
|
||||
/* AUTO GENERATED - DO NOT EDIT */
|
||||
#include <capnp_c.h>
|
||||
|
||||
#if CAPN_VERSION != 1
|
||||
#error "version mismatch between capnp_c.h and generated code"
|
||||
#endif
|
||||
|
||||
#include "c++.capnp.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
struct cereal_InitData;
|
||||
struct cereal_FrameData;
|
||||
struct cereal_GPSNMEAData;
|
||||
struct cereal_SensorEventData;
|
||||
struct cereal_SensorEventData_SensorVec;
|
||||
struct cereal_CanData;
|
||||
struct cereal_ThermalData;
|
||||
struct cereal_HealthData;
|
||||
struct cereal_LiveUI;
|
||||
struct cereal_Live20Data;
|
||||
struct cereal_Live20Data_LeadData;
|
||||
struct cereal_LiveCalibrationData;
|
||||
struct cereal_LiveTracks;
|
||||
struct cereal_Live100Data;
|
||||
struct cereal_LiveEventData;
|
||||
struct cereal_ModelData;
|
||||
struct cereal_ModelData_PathData;
|
||||
struct cereal_ModelData_LeadData;
|
||||
struct cereal_ModelData_ModelSettings;
|
||||
struct cereal_CalibrationFeatures;
|
||||
struct cereal_EncodeIndex;
|
||||
struct cereal_AndroidLogEntry;
|
||||
struct cereal_LogRotate;
|
||||
struct cereal_Event;
|
||||
|
||||
typedef struct {capn_ptr p;} cereal_InitData_ptr;
|
||||
typedef struct {capn_ptr p;} cereal_FrameData_ptr;
|
||||
typedef struct {capn_ptr p;} cereal_GPSNMEAData_ptr;
|
||||
typedef struct {capn_ptr p;} cereal_SensorEventData_ptr;
|
||||
typedef struct {capn_ptr p;} cereal_SensorEventData_SensorVec_ptr;
|
||||
typedef struct {capn_ptr p;} cereal_CanData_ptr;
|
||||
typedef struct {capn_ptr p;} cereal_ThermalData_ptr;
|
||||
typedef struct {capn_ptr p;} cereal_HealthData_ptr;
|
||||
typedef struct {capn_ptr p;} cereal_LiveUI_ptr;
|
||||
typedef struct {capn_ptr p;} cereal_Live20Data_ptr;
|
||||
typedef struct {capn_ptr p;} cereal_Live20Data_LeadData_ptr;
|
||||
typedef struct {capn_ptr p;} cereal_LiveCalibrationData_ptr;
|
||||
typedef struct {capn_ptr p;} cereal_LiveTracks_ptr;
|
||||
typedef struct {capn_ptr p;} cereal_Live100Data_ptr;
|
||||
typedef struct {capn_ptr p;} cereal_LiveEventData_ptr;
|
||||
typedef struct {capn_ptr p;} cereal_ModelData_ptr;
|
||||
typedef struct {capn_ptr p;} cereal_ModelData_PathData_ptr;
|
||||
typedef struct {capn_ptr p;} cereal_ModelData_LeadData_ptr;
|
||||
typedef struct {capn_ptr p;} cereal_ModelData_ModelSettings_ptr;
|
||||
typedef struct {capn_ptr p;} cereal_CalibrationFeatures_ptr;
|
||||
typedef struct {capn_ptr p;} cereal_EncodeIndex_ptr;
|
||||
typedef struct {capn_ptr p;} cereal_AndroidLogEntry_ptr;
|
||||
typedef struct {capn_ptr p;} cereal_LogRotate_ptr;
|
||||
typedef struct {capn_ptr p;} cereal_Event_ptr;
|
||||
|
||||
typedef struct {capn_ptr p;} cereal_InitData_list;
|
||||
typedef struct {capn_ptr p;} cereal_FrameData_list;
|
||||
typedef struct {capn_ptr p;} cereal_GPSNMEAData_list;
|
||||
typedef struct {capn_ptr p;} cereal_SensorEventData_list;
|
||||
typedef struct {capn_ptr p;} cereal_SensorEventData_SensorVec_list;
|
||||
typedef struct {capn_ptr p;} cereal_CanData_list;
|
||||
typedef struct {capn_ptr p;} cereal_ThermalData_list;
|
||||
typedef struct {capn_ptr p;} cereal_HealthData_list;
|
||||
typedef struct {capn_ptr p;} cereal_LiveUI_list;
|
||||
typedef struct {capn_ptr p;} cereal_Live20Data_list;
|
||||
typedef struct {capn_ptr p;} cereal_Live20Data_LeadData_list;
|
||||
typedef struct {capn_ptr p;} cereal_LiveCalibrationData_list;
|
||||
typedef struct {capn_ptr p;} cereal_LiveTracks_list;
|
||||
typedef struct {capn_ptr p;} cereal_Live100Data_list;
|
||||
typedef struct {capn_ptr p;} cereal_LiveEventData_list;
|
||||
typedef struct {capn_ptr p;} cereal_ModelData_list;
|
||||
typedef struct {capn_ptr p;} cereal_ModelData_PathData_list;
|
||||
typedef struct {capn_ptr p;} cereal_ModelData_LeadData_list;
|
||||
typedef struct {capn_ptr p;} cereal_ModelData_ModelSettings_list;
|
||||
typedef struct {capn_ptr p;} cereal_CalibrationFeatures_list;
|
||||
typedef struct {capn_ptr p;} cereal_EncodeIndex_list;
|
||||
typedef struct {capn_ptr p;} cereal_AndroidLogEntry_list;
|
||||
typedef struct {capn_ptr p;} cereal_LogRotate_list;
|
||||
typedef struct {capn_ptr p;} cereal_Event_list;
|
||||
|
||||
enum cereal_EncodeIndex_Type {
|
||||
cereal_EncodeIndex_Type_bigBoxLossless = 0,
|
||||
cereal_EncodeIndex_Type_fullHEVC = 1,
|
||||
cereal_EncodeIndex_Type_bigBoxHEVC = 2
|
||||
};
|
||||
extern int32_t cereal_logVersion;
|
||||
|
||||
struct cereal_InitData {
|
||||
capn_ptr kernelArgs;
|
||||
capn_text gctx;
|
||||
capn_text dongleId;
|
||||
};
|
||||
|
||||
static const size_t cereal_InitData_word_count = 0;
|
||||
|
||||
static const size_t cereal_InitData_pointer_count = 3;
|
||||
|
||||
static const size_t cereal_InitData_struct_bytes_count = 24;
|
||||
|
||||
struct cereal_FrameData {
|
||||
uint32_t frameId;
|
||||
uint32_t encodeId;
|
||||
uint64_t timestampEof;
|
||||
int32_t frameLength;
|
||||
int32_t integLines;
|
||||
int32_t globalGain;
|
||||
capn_data image;
|
||||
};
|
||||
|
||||
static const size_t cereal_FrameData_word_count = 4;
|
||||
|
||||
static const size_t cereal_FrameData_pointer_count = 1;
|
||||
|
||||
static const size_t cereal_FrameData_struct_bytes_count = 40;
|
||||
|
||||
struct cereal_GPSNMEAData {
|
||||
int64_t timestamp;
|
||||
uint64_t localWallTime;
|
||||
capn_text nmea;
|
||||
};
|
||||
|
||||
static const size_t cereal_GPSNMEAData_word_count = 2;
|
||||
|
||||
static const size_t cereal_GPSNMEAData_pointer_count = 1;
|
||||
|
||||
static const size_t cereal_GPSNMEAData_struct_bytes_count = 24;
|
||||
enum cereal_SensorEventData_which {
|
||||
cereal_SensorEventData_acceleration = 0,
|
||||
cereal_SensorEventData_magnetic = 1,
|
||||
cereal_SensorEventData_orientation = 2,
|
||||
cereal_SensorEventData_gyro = 3
|
||||
};
|
||||
|
||||
struct cereal_SensorEventData {
|
||||
int32_t version;
|
||||
int32_t sensor;
|
||||
int32_t type;
|
||||
int64_t timestamp;
|
||||
enum cereal_SensorEventData_which which;
|
||||
union {
|
||||
cereal_SensorEventData_SensorVec_ptr acceleration;
|
||||
cereal_SensorEventData_SensorVec_ptr magnetic;
|
||||
cereal_SensorEventData_SensorVec_ptr orientation;
|
||||
cereal_SensorEventData_SensorVec_ptr gyro;
|
||||
};
|
||||
};
|
||||
|
||||
static const size_t cereal_SensorEventData_word_count = 3;
|
||||
|
||||
static const size_t cereal_SensorEventData_pointer_count = 1;
|
||||
|
||||
static const size_t cereal_SensorEventData_struct_bytes_count = 32;
|
||||
|
||||
struct cereal_SensorEventData_SensorVec {
|
||||
capn_list32 v;
|
||||
int8_t status;
|
||||
};
|
||||
|
||||
static const size_t cereal_SensorEventData_SensorVec_word_count = 1;
|
||||
|
||||
static const size_t cereal_SensorEventData_SensorVec_pointer_count = 1;
|
||||
|
||||
static const size_t cereal_SensorEventData_SensorVec_struct_bytes_count = 16;
|
||||
|
||||
struct cereal_CanData {
|
||||
uint32_t address;
|
||||
uint16_t busTime;
|
||||
capn_data dat;
|
||||
int8_t src;
|
||||
};
|
||||
|
||||
static const size_t cereal_CanData_word_count = 1;
|
||||
|
||||
static const size_t cereal_CanData_pointer_count = 1;
|
||||
|
||||
static const size_t cereal_CanData_struct_bytes_count = 16;
|
||||
|
||||
struct cereal_ThermalData {
|
||||
uint16_t cpu0;
|
||||
uint16_t cpu1;
|
||||
uint16_t cpu2;
|
||||
uint16_t cpu3;
|
||||
uint16_t mem;
|
||||
uint16_t gpu;
|
||||
uint32_t bat;
|
||||
};
|
||||
|
||||
static const size_t cereal_ThermalData_word_count = 2;
|
||||
|
||||
static const size_t cereal_ThermalData_pointer_count = 0;
|
||||
|
||||
static const size_t cereal_ThermalData_struct_bytes_count = 16;
|
||||
|
||||
struct cereal_HealthData {
|
||||
uint32_t voltage;
|
||||
uint32_t current;
|
||||
unsigned started : 1;
|
||||
unsigned controlsAllowed : 1;
|
||||
unsigned gasInterceptorDetected : 1;
|
||||
};
|
||||
|
||||
static const size_t cereal_HealthData_word_count = 2;
|
||||
|
||||
static const size_t cereal_HealthData_pointer_count = 0;
|
||||
|
||||
static const size_t cereal_HealthData_struct_bytes_count = 16;
|
||||
|
||||
struct cereal_LiveUI {
|
||||
unsigned rearViewCam : 1;
|
||||
capn_text alertText1;
|
||||
capn_text alertText2;
|
||||
float awarenessStatus;
|
||||
};
|
||||
|
||||
static const size_t cereal_LiveUI_word_count = 1;
|
||||
|
||||
static const size_t cereal_LiveUI_pointer_count = 2;
|
||||
|
||||
static const size_t cereal_LiveUI_struct_bytes_count = 24;
|
||||
|
||||
struct cereal_Live20Data {
|
||||
capn_list64 canMonoTimes;
|
||||
uint64_t mdMonoTime;
|
||||
uint64_t ftMonoTime;
|
||||
capn_list32 warpMatrix;
|
||||
float angleOffset;
|
||||
int8_t calStatus;
|
||||
int32_t calCycle;
|
||||
int8_t calPerc;
|
||||
cereal_Live20Data_LeadData_ptr leadOne;
|
||||
cereal_Live20Data_LeadData_ptr leadTwo;
|
||||
float cumLagMs;
|
||||
};
|
||||
|
||||
static const size_t cereal_Live20Data_word_count = 4;
|
||||
|
||||
static const size_t cereal_Live20Data_pointer_count = 4;
|
||||
|
||||
static const size_t cereal_Live20Data_struct_bytes_count = 64;
|
||||
|
||||
struct cereal_Live20Data_LeadData {
|
||||
float dRel;
|
||||
float yRel;
|
||||
float vRel;
|
||||
float aRel;
|
||||
float vLead;
|
||||
float aLead;
|
||||
float dPath;
|
||||
float vLat;
|
||||
float vLeadK;
|
||||
float aLeadK;
|
||||
unsigned fcw : 1;
|
||||
unsigned status : 1;
|
||||
};
|
||||
|
||||
static const size_t cereal_Live20Data_LeadData_word_count = 6;
|
||||
|
||||
static const size_t cereal_Live20Data_LeadData_pointer_count = 0;
|
||||
|
||||
static const size_t cereal_Live20Data_LeadData_struct_bytes_count = 48;
|
||||
|
||||
struct cereal_LiveCalibrationData {
|
||||
capn_list32 warpMatrix;
|
||||
int8_t calStatus;
|
||||
int32_t calCycle;
|
||||
int8_t calPerc;
|
||||
};
|
||||
|
||||
static const size_t cereal_LiveCalibrationData_word_count = 1;
|
||||
|
||||
static const size_t cereal_LiveCalibrationData_pointer_count = 1;
|
||||
|
||||
static const size_t cereal_LiveCalibrationData_struct_bytes_count = 16;
|
||||
|
||||
struct cereal_LiveTracks {
|
||||
int32_t trackId;
|
||||
float dRel;
|
||||
float yRel;
|
||||
float vRel;
|
||||
float aRel;
|
||||
float timeStamp;
|
||||
float status;
|
||||
float currentTime;
|
||||
unsigned stationary : 1;
|
||||
unsigned oncoming : 1;
|
||||
};
|
||||
|
||||
static const size_t cereal_LiveTracks_word_count = 5;
|
||||
|
||||
static const size_t cereal_LiveTracks_pointer_count = 0;
|
||||
|
||||
static const size_t cereal_LiveTracks_struct_bytes_count = 40;
|
||||
|
||||
struct cereal_Live100Data {
|
||||
uint64_t canMonoTime;
|
||||
capn_list64 canMonoTimes;
|
||||
uint64_t l20MonoTime;
|
||||
uint64_t mdMonoTime;
|
||||
float vEgo;
|
||||
float aEgo;
|
||||
float vPid;
|
||||
float vTargetLead;
|
||||
float upAccelCmd;
|
||||
float uiAccelCmd;
|
||||
float yActual;
|
||||
float yDes;
|
||||
float upSteer;
|
||||
float uiSteer;
|
||||
float aTargetMin;
|
||||
float aTargetMax;
|
||||
float jerkFactor;
|
||||
float angleSteers;
|
||||
int32_t hudLead;
|
||||
float cumLagMs;
|
||||
unsigned enabled : 1;
|
||||
unsigned steerOverride : 1;
|
||||
float vCruise;
|
||||
unsigned rearViewCam : 1;
|
||||
capn_text alertText1;
|
||||
capn_text alertText2;
|
||||
float awarenessStatus;
|
||||
};
|
||||
|
||||
static const size_t cereal_Live100Data_word_count = 13;
|
||||
|
||||
static const size_t cereal_Live100Data_pointer_count = 3;
|
||||
|
||||
static const size_t cereal_Live100Data_struct_bytes_count = 128;
|
||||
|
||||
struct cereal_LiveEventData {
|
||||
capn_text name;
|
||||
int32_t value;
|
||||
};
|
||||
|
||||
static const size_t cereal_LiveEventData_word_count = 1;
|
||||
|
||||
static const size_t cereal_LiveEventData_pointer_count = 1;
|
||||
|
||||
static const size_t cereal_LiveEventData_struct_bytes_count = 16;
|
||||
|
||||
struct cereal_ModelData {
|
||||
uint32_t frameId;
|
||||
cereal_ModelData_PathData_ptr path;
|
||||
cereal_ModelData_PathData_ptr leftLane;
|
||||
cereal_ModelData_PathData_ptr rightLane;
|
||||
cereal_ModelData_LeadData_ptr lead;
|
||||
cereal_ModelData_ModelSettings_ptr settings;
|
||||
};
|
||||
|
||||
static const size_t cereal_ModelData_word_count = 1;
|
||||
|
||||
static const size_t cereal_ModelData_pointer_count = 5;
|
||||
|
||||
static const size_t cereal_ModelData_struct_bytes_count = 48;
|
||||
|
||||
struct cereal_ModelData_PathData {
|
||||
capn_list32 points;
|
||||
float prob;
|
||||
float std;
|
||||
};
|
||||
|
||||
static const size_t cereal_ModelData_PathData_word_count = 1;
|
||||
|
||||
static const size_t cereal_ModelData_PathData_pointer_count = 1;
|
||||
|
||||
static const size_t cereal_ModelData_PathData_struct_bytes_count = 16;
|
||||
|
||||
struct cereal_ModelData_LeadData {
|
||||
float dist;
|
||||
float prob;
|
||||
float std;
|
||||
};
|
||||
|
||||
static const size_t cereal_ModelData_LeadData_word_count = 2;
|
||||
|
||||
static const size_t cereal_ModelData_LeadData_pointer_count = 0;
|
||||
|
||||
static const size_t cereal_ModelData_LeadData_struct_bytes_count = 16;
|
||||
|
||||
struct cereal_ModelData_ModelSettings {
|
||||
uint16_t bigBoxX;
|
||||
uint16_t bigBoxY;
|
||||
uint16_t bigBoxWidth;
|
||||
uint16_t bigBoxHeight;
|
||||
capn_list32 boxProjection;
|
||||
capn_list32 yuvCorrection;
|
||||
};
|
||||
|
||||
static const size_t cereal_ModelData_ModelSettings_word_count = 1;
|
||||
|
||||
static const size_t cereal_ModelData_ModelSettings_pointer_count = 2;
|
||||
|
||||
static const size_t cereal_ModelData_ModelSettings_struct_bytes_count = 24;
|
||||
|
||||
struct cereal_CalibrationFeatures {
|
||||
uint32_t frameId;
|
||||
capn_list32 p0;
|
||||
capn_list32 p1;
|
||||
capn_list8 status;
|
||||
};
|
||||
|
||||
static const size_t cereal_CalibrationFeatures_word_count = 1;
|
||||
|
||||
static const size_t cereal_CalibrationFeatures_pointer_count = 3;
|
||||
|
||||
static const size_t cereal_CalibrationFeatures_struct_bytes_count = 32;
|
||||
|
||||
struct cereal_EncodeIndex {
|
||||
uint32_t frameId;
|
||||
enum cereal_EncodeIndex_Type type;
|
||||
uint32_t encodeId;
|
||||
int32_t segmentNum;
|
||||
uint32_t segmentId;
|
||||
};
|
||||
|
||||
static const size_t cereal_EncodeIndex_word_count = 3;
|
||||
|
||||
static const size_t cereal_EncodeIndex_pointer_count = 0;
|
||||
|
||||
static const size_t cereal_EncodeIndex_struct_bytes_count = 24;
|
||||
|
||||
struct cereal_AndroidLogEntry {
|
||||
uint8_t id;
|
||||
uint64_t ts;
|
||||
uint8_t priority;
|
||||
int32_t pid;
|
||||
int32_t tid;
|
||||
capn_text tag;
|
||||
capn_text message;
|
||||
};
|
||||
|
||||
static const size_t cereal_AndroidLogEntry_word_count = 3;
|
||||
|
||||
static const size_t cereal_AndroidLogEntry_pointer_count = 2;
|
||||
|
||||
static const size_t cereal_AndroidLogEntry_struct_bytes_count = 40;
|
||||
|
||||
struct cereal_LogRotate {
|
||||
int32_t segmentNum;
|
||||
capn_text path;
|
||||
};
|
||||
|
||||
static const size_t cereal_LogRotate_word_count = 1;
|
||||
|
||||
static const size_t cereal_LogRotate_pointer_count = 1;
|
||||
|
||||
static const size_t cereal_LogRotate_struct_bytes_count = 16;
|
||||
enum cereal_Event_which {
|
||||
cereal_Event_initData = 0,
|
||||
cereal_Event_frame = 1,
|
||||
cereal_Event_gpsNMEA = 2,
|
||||
cereal_Event_sensorEventDEPRECATED = 3,
|
||||
cereal_Event_can = 4,
|
||||
cereal_Event_thermal = 5,
|
||||
cereal_Event_live100 = 6,
|
||||
cereal_Event_liveEventDEPRECATED = 7,
|
||||
cereal_Event_model = 8,
|
||||
cereal_Event_features = 9,
|
||||
cereal_Event_sensorEvents = 10,
|
||||
cereal_Event_health = 11,
|
||||
cereal_Event_live20 = 12,
|
||||
cereal_Event_liveUIDEPRECATED = 13,
|
||||
cereal_Event_encodeIdx = 14,
|
||||
cereal_Event_liveTracks = 15,
|
||||
cereal_Event_sendcan = 16,
|
||||
cereal_Event_logMessage = 17,
|
||||
cereal_Event_liveCalibration = 18,
|
||||
cereal_Event_androidLogEntry = 19
|
||||
};
|
||||
|
||||
struct cereal_Event {
|
||||
uint64_t logMonoTime;
|
||||
enum cereal_Event_which which;
|
||||
union {
|
||||
cereal_InitData_ptr initData;
|
||||
cereal_FrameData_ptr frame;
|
||||
cereal_GPSNMEAData_ptr gpsNMEA;
|
||||
cereal_SensorEventData_ptr sensorEventDEPRECATED;
|
||||
cereal_CanData_list can;
|
||||
cereal_ThermalData_ptr thermal;
|
||||
cereal_Live100Data_ptr live100;
|
||||
cereal_LiveEventData_list liveEventDEPRECATED;
|
||||
cereal_ModelData_ptr model;
|
||||
cereal_CalibrationFeatures_ptr features;
|
||||
cereal_SensorEventData_list sensorEvents;
|
||||
cereal_HealthData_ptr health;
|
||||
cereal_Live20Data_ptr live20;
|
||||
cereal_LiveUI_ptr liveUIDEPRECATED;
|
||||
cereal_EncodeIndex_ptr encodeIdx;
|
||||
cereal_LiveTracks_list liveTracks;
|
||||
cereal_CanData_list sendcan;
|
||||
capn_text logMessage;
|
||||
cereal_LiveCalibrationData_ptr liveCalibration;
|
||||
cereal_AndroidLogEntry_ptr androidLogEntry;
|
||||
};
|
||||
};
|
||||
|
||||
static const size_t cereal_Event_word_count = 2;
|
||||
|
||||
static const size_t cereal_Event_pointer_count = 1;
|
||||
|
||||
static const size_t cereal_Event_struct_bytes_count = 24;
|
||||
|
||||
cereal_InitData_ptr cereal_new_InitData(struct capn_segment*);
|
||||
cereal_FrameData_ptr cereal_new_FrameData(struct capn_segment*);
|
||||
cereal_GPSNMEAData_ptr cereal_new_GPSNMEAData(struct capn_segment*);
|
||||
cereal_SensorEventData_ptr cereal_new_SensorEventData(struct capn_segment*);
|
||||
cereal_SensorEventData_SensorVec_ptr cereal_new_SensorEventData_SensorVec(struct capn_segment*);
|
||||
cereal_CanData_ptr cereal_new_CanData(struct capn_segment*);
|
||||
cereal_ThermalData_ptr cereal_new_ThermalData(struct capn_segment*);
|
||||
cereal_HealthData_ptr cereal_new_HealthData(struct capn_segment*);
|
||||
cereal_LiveUI_ptr cereal_new_LiveUI(struct capn_segment*);
|
||||
cereal_Live20Data_ptr cereal_new_Live20Data(struct capn_segment*);
|
||||
cereal_Live20Data_LeadData_ptr cereal_new_Live20Data_LeadData(struct capn_segment*);
|
||||
cereal_LiveCalibrationData_ptr cereal_new_LiveCalibrationData(struct capn_segment*);
|
||||
cereal_LiveTracks_ptr cereal_new_LiveTracks(struct capn_segment*);
|
||||
cereal_Live100Data_ptr cereal_new_Live100Data(struct capn_segment*);
|
||||
cereal_LiveEventData_ptr cereal_new_LiveEventData(struct capn_segment*);
|
||||
cereal_ModelData_ptr cereal_new_ModelData(struct capn_segment*);
|
||||
cereal_ModelData_PathData_ptr cereal_new_ModelData_PathData(struct capn_segment*);
|
||||
cereal_ModelData_LeadData_ptr cereal_new_ModelData_LeadData(struct capn_segment*);
|
||||
cereal_ModelData_ModelSettings_ptr cereal_new_ModelData_ModelSettings(struct capn_segment*);
|
||||
cereal_CalibrationFeatures_ptr cereal_new_CalibrationFeatures(struct capn_segment*);
|
||||
cereal_EncodeIndex_ptr cereal_new_EncodeIndex(struct capn_segment*);
|
||||
cereal_AndroidLogEntry_ptr cereal_new_AndroidLogEntry(struct capn_segment*);
|
||||
cereal_LogRotate_ptr cereal_new_LogRotate(struct capn_segment*);
|
||||
cereal_Event_ptr cereal_new_Event(struct capn_segment*);
|
||||
|
||||
cereal_InitData_list cereal_new_InitData_list(struct capn_segment*, int len);
|
||||
cereal_FrameData_list cereal_new_FrameData_list(struct capn_segment*, int len);
|
||||
cereal_GPSNMEAData_list cereal_new_GPSNMEAData_list(struct capn_segment*, int len);
|
||||
cereal_SensorEventData_list cereal_new_SensorEventData_list(struct capn_segment*, int len);
|
||||
cereal_SensorEventData_SensorVec_list cereal_new_SensorEventData_SensorVec_list(struct capn_segment*, int len);
|
||||
cereal_CanData_list cereal_new_CanData_list(struct capn_segment*, int len);
|
||||
cereal_ThermalData_list cereal_new_ThermalData_list(struct capn_segment*, int len);
|
||||
cereal_HealthData_list cereal_new_HealthData_list(struct capn_segment*, int len);
|
||||
cereal_LiveUI_list cereal_new_LiveUI_list(struct capn_segment*, int len);
|
||||
cereal_Live20Data_list cereal_new_Live20Data_list(struct capn_segment*, int len);
|
||||
cereal_Live20Data_LeadData_list cereal_new_Live20Data_LeadData_list(struct capn_segment*, int len);
|
||||
cereal_LiveCalibrationData_list cereal_new_LiveCalibrationData_list(struct capn_segment*, int len);
|
||||
cereal_LiveTracks_list cereal_new_LiveTracks_list(struct capn_segment*, int len);
|
||||
cereal_Live100Data_list cereal_new_Live100Data_list(struct capn_segment*, int len);
|
||||
cereal_LiveEventData_list cereal_new_LiveEventData_list(struct capn_segment*, int len);
|
||||
cereal_ModelData_list cereal_new_ModelData_list(struct capn_segment*, int len);
|
||||
cereal_ModelData_PathData_list cereal_new_ModelData_PathData_list(struct capn_segment*, int len);
|
||||
cereal_ModelData_LeadData_list cereal_new_ModelData_LeadData_list(struct capn_segment*, int len);
|
||||
cereal_ModelData_ModelSettings_list cereal_new_ModelData_ModelSettings_list(struct capn_segment*, int len);
|
||||
cereal_CalibrationFeatures_list cereal_new_CalibrationFeatures_list(struct capn_segment*, int len);
|
||||
cereal_EncodeIndex_list cereal_new_EncodeIndex_list(struct capn_segment*, int len);
|
||||
cereal_AndroidLogEntry_list cereal_new_AndroidLogEntry_list(struct capn_segment*, int len);
|
||||
cereal_LogRotate_list cereal_new_LogRotate_list(struct capn_segment*, int len);
|
||||
cereal_Event_list cereal_new_Event_list(struct capn_segment*, int len);
|
||||
|
||||
void cereal_read_InitData(struct cereal_InitData*, cereal_InitData_ptr);
|
||||
void cereal_read_FrameData(struct cereal_FrameData*, cereal_FrameData_ptr);
|
||||
void cereal_read_GPSNMEAData(struct cereal_GPSNMEAData*, cereal_GPSNMEAData_ptr);
|
||||
void cereal_read_SensorEventData(struct cereal_SensorEventData*, cereal_SensorEventData_ptr);
|
||||
void cereal_read_SensorEventData_SensorVec(struct cereal_SensorEventData_SensorVec*, cereal_SensorEventData_SensorVec_ptr);
|
||||
void cereal_read_CanData(struct cereal_CanData*, cereal_CanData_ptr);
|
||||
void cereal_read_ThermalData(struct cereal_ThermalData*, cereal_ThermalData_ptr);
|
||||
void cereal_read_HealthData(struct cereal_HealthData*, cereal_HealthData_ptr);
|
||||
void cereal_read_LiveUI(struct cereal_LiveUI*, cereal_LiveUI_ptr);
|
||||
void cereal_read_Live20Data(struct cereal_Live20Data*, cereal_Live20Data_ptr);
|
||||
void cereal_read_Live20Data_LeadData(struct cereal_Live20Data_LeadData*, cereal_Live20Data_LeadData_ptr);
|
||||
void cereal_read_LiveCalibrationData(struct cereal_LiveCalibrationData*, cereal_LiveCalibrationData_ptr);
|
||||
void cereal_read_LiveTracks(struct cereal_LiveTracks*, cereal_LiveTracks_ptr);
|
||||
void cereal_read_Live100Data(struct cereal_Live100Data*, cereal_Live100Data_ptr);
|
||||
void cereal_read_LiveEventData(struct cereal_LiveEventData*, cereal_LiveEventData_ptr);
|
||||
void cereal_read_ModelData(struct cereal_ModelData*, cereal_ModelData_ptr);
|
||||
void cereal_read_ModelData_PathData(struct cereal_ModelData_PathData*, cereal_ModelData_PathData_ptr);
|
||||
void cereal_read_ModelData_LeadData(struct cereal_ModelData_LeadData*, cereal_ModelData_LeadData_ptr);
|
||||
void cereal_read_ModelData_ModelSettings(struct cereal_ModelData_ModelSettings*, cereal_ModelData_ModelSettings_ptr);
|
||||
void cereal_read_CalibrationFeatures(struct cereal_CalibrationFeatures*, cereal_CalibrationFeatures_ptr);
|
||||
void cereal_read_EncodeIndex(struct cereal_EncodeIndex*, cereal_EncodeIndex_ptr);
|
||||
void cereal_read_AndroidLogEntry(struct cereal_AndroidLogEntry*, cereal_AndroidLogEntry_ptr);
|
||||
void cereal_read_LogRotate(struct cereal_LogRotate*, cereal_LogRotate_ptr);
|
||||
void cereal_read_Event(struct cereal_Event*, cereal_Event_ptr);
|
||||
|
||||
void cereal_write_InitData(const struct cereal_InitData*, cereal_InitData_ptr);
|
||||
void cereal_write_FrameData(const struct cereal_FrameData*, cereal_FrameData_ptr);
|
||||
void cereal_write_GPSNMEAData(const struct cereal_GPSNMEAData*, cereal_GPSNMEAData_ptr);
|
||||
void cereal_write_SensorEventData(const struct cereal_SensorEventData*, cereal_SensorEventData_ptr);
|
||||
void cereal_write_SensorEventData_SensorVec(const struct cereal_SensorEventData_SensorVec*, cereal_SensorEventData_SensorVec_ptr);
|
||||
void cereal_write_CanData(const struct cereal_CanData*, cereal_CanData_ptr);
|
||||
void cereal_write_ThermalData(const struct cereal_ThermalData*, cereal_ThermalData_ptr);
|
||||
void cereal_write_HealthData(const struct cereal_HealthData*, cereal_HealthData_ptr);
|
||||
void cereal_write_LiveUI(const struct cereal_LiveUI*, cereal_LiveUI_ptr);
|
||||
void cereal_write_Live20Data(const struct cereal_Live20Data*, cereal_Live20Data_ptr);
|
||||
void cereal_write_Live20Data_LeadData(const struct cereal_Live20Data_LeadData*, cereal_Live20Data_LeadData_ptr);
|
||||
void cereal_write_LiveCalibrationData(const struct cereal_LiveCalibrationData*, cereal_LiveCalibrationData_ptr);
|
||||
void cereal_write_LiveTracks(const struct cereal_LiveTracks*, cereal_LiveTracks_ptr);
|
||||
void cereal_write_Live100Data(const struct cereal_Live100Data*, cereal_Live100Data_ptr);
|
||||
void cereal_write_LiveEventData(const struct cereal_LiveEventData*, cereal_LiveEventData_ptr);
|
||||
void cereal_write_ModelData(const struct cereal_ModelData*, cereal_ModelData_ptr);
|
||||
void cereal_write_ModelData_PathData(const struct cereal_ModelData_PathData*, cereal_ModelData_PathData_ptr);
|
||||
void cereal_write_ModelData_LeadData(const struct cereal_ModelData_LeadData*, cereal_ModelData_LeadData_ptr);
|
||||
void cereal_write_ModelData_ModelSettings(const struct cereal_ModelData_ModelSettings*, cereal_ModelData_ModelSettings_ptr);
|
||||
void cereal_write_CalibrationFeatures(const struct cereal_CalibrationFeatures*, cereal_CalibrationFeatures_ptr);
|
||||
void cereal_write_EncodeIndex(const struct cereal_EncodeIndex*, cereal_EncodeIndex_ptr);
|
||||
void cereal_write_AndroidLogEntry(const struct cereal_AndroidLogEntry*, cereal_AndroidLogEntry_ptr);
|
||||
void cereal_write_LogRotate(const struct cereal_LogRotate*, cereal_LogRotate_ptr);
|
||||
void cereal_write_Event(const struct cereal_Event*, cereal_Event_ptr);
|
||||
|
||||
void cereal_get_InitData(struct cereal_InitData*, cereal_InitData_list, int i);
|
||||
void cereal_get_FrameData(struct cereal_FrameData*, cereal_FrameData_list, int i);
|
||||
void cereal_get_GPSNMEAData(struct cereal_GPSNMEAData*, cereal_GPSNMEAData_list, int i);
|
||||
void cereal_get_SensorEventData(struct cereal_SensorEventData*, cereal_SensorEventData_list, int i);
|
||||
void cereal_get_SensorEventData_SensorVec(struct cereal_SensorEventData_SensorVec*, cereal_SensorEventData_SensorVec_list, int i);
|
||||
void cereal_get_CanData(struct cereal_CanData*, cereal_CanData_list, int i);
|
||||
void cereal_get_ThermalData(struct cereal_ThermalData*, cereal_ThermalData_list, int i);
|
||||
void cereal_get_HealthData(struct cereal_HealthData*, cereal_HealthData_list, int i);
|
||||
void cereal_get_LiveUI(struct cereal_LiveUI*, cereal_LiveUI_list, int i);
|
||||
void cereal_get_Live20Data(struct cereal_Live20Data*, cereal_Live20Data_list, int i);
|
||||
void cereal_get_Live20Data_LeadData(struct cereal_Live20Data_LeadData*, cereal_Live20Data_LeadData_list, int i);
|
||||
void cereal_get_LiveCalibrationData(struct cereal_LiveCalibrationData*, cereal_LiveCalibrationData_list, int i);
|
||||
void cereal_get_LiveTracks(struct cereal_LiveTracks*, cereal_LiveTracks_list, int i);
|
||||
void cereal_get_Live100Data(struct cereal_Live100Data*, cereal_Live100Data_list, int i);
|
||||
void cereal_get_LiveEventData(struct cereal_LiveEventData*, cereal_LiveEventData_list, int i);
|
||||
void cereal_get_ModelData(struct cereal_ModelData*, cereal_ModelData_list, int i);
|
||||
void cereal_get_ModelData_PathData(struct cereal_ModelData_PathData*, cereal_ModelData_PathData_list, int i);
|
||||
void cereal_get_ModelData_LeadData(struct cereal_ModelData_LeadData*, cereal_ModelData_LeadData_list, int i);
|
||||
void cereal_get_ModelData_ModelSettings(struct cereal_ModelData_ModelSettings*, cereal_ModelData_ModelSettings_list, int i);
|
||||
void cereal_get_CalibrationFeatures(struct cereal_CalibrationFeatures*, cereal_CalibrationFeatures_list, int i);
|
||||
void cereal_get_EncodeIndex(struct cereal_EncodeIndex*, cereal_EncodeIndex_list, int i);
|
||||
void cereal_get_AndroidLogEntry(struct cereal_AndroidLogEntry*, cereal_AndroidLogEntry_list, int i);
|
||||
void cereal_get_LogRotate(struct cereal_LogRotate*, cereal_LogRotate_list, int i);
|
||||
void cereal_get_Event(struct cereal_Event*, cereal_Event_list, int i);
|
||||
|
||||
void cereal_set_InitData(const struct cereal_InitData*, cereal_InitData_list, int i);
|
||||
void cereal_set_FrameData(const struct cereal_FrameData*, cereal_FrameData_list, int i);
|
||||
void cereal_set_GPSNMEAData(const struct cereal_GPSNMEAData*, cereal_GPSNMEAData_list, int i);
|
||||
void cereal_set_SensorEventData(const struct cereal_SensorEventData*, cereal_SensorEventData_list, int i);
|
||||
void cereal_set_SensorEventData_SensorVec(const struct cereal_SensorEventData_SensorVec*, cereal_SensorEventData_SensorVec_list, int i);
|
||||
void cereal_set_CanData(const struct cereal_CanData*, cereal_CanData_list, int i);
|
||||
void cereal_set_ThermalData(const struct cereal_ThermalData*, cereal_ThermalData_list, int i);
|
||||
void cereal_set_HealthData(const struct cereal_HealthData*, cereal_HealthData_list, int i);
|
||||
void cereal_set_LiveUI(const struct cereal_LiveUI*, cereal_LiveUI_list, int i);
|
||||
void cereal_set_Live20Data(const struct cereal_Live20Data*, cereal_Live20Data_list, int i);
|
||||
void cereal_set_Live20Data_LeadData(const struct cereal_Live20Data_LeadData*, cereal_Live20Data_LeadData_list, int i);
|
||||
void cereal_set_LiveCalibrationData(const struct cereal_LiveCalibrationData*, cereal_LiveCalibrationData_list, int i);
|
||||
void cereal_set_LiveTracks(const struct cereal_LiveTracks*, cereal_LiveTracks_list, int i);
|
||||
void cereal_set_Live100Data(const struct cereal_Live100Data*, cereal_Live100Data_list, int i);
|
||||
void cereal_set_LiveEventData(const struct cereal_LiveEventData*, cereal_LiveEventData_list, int i);
|
||||
void cereal_set_ModelData(const struct cereal_ModelData*, cereal_ModelData_list, int i);
|
||||
void cereal_set_ModelData_PathData(const struct cereal_ModelData_PathData*, cereal_ModelData_PathData_list, int i);
|
||||
void cereal_set_ModelData_LeadData(const struct cereal_ModelData_LeadData*, cereal_ModelData_LeadData_list, int i);
|
||||
void cereal_set_ModelData_ModelSettings(const struct cereal_ModelData_ModelSettings*, cereal_ModelData_ModelSettings_list, int i);
|
||||
void cereal_set_CalibrationFeatures(const struct cereal_CalibrationFeatures*, cereal_CalibrationFeatures_list, int i);
|
||||
void cereal_set_EncodeIndex(const struct cereal_EncodeIndex*, cereal_EncodeIndex_list, int i);
|
||||
void cereal_set_AndroidLogEntry(const struct cereal_AndroidLogEntry*, cereal_AndroidLogEntry_list, int i);
|
||||
void cereal_set_LogRotate(const struct cereal_LogRotate*, cereal_LogRotate_list, int i);
|
||||
void cereal_set_Event(const struct cereal_Event*, cereal_Event_list, int i);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
#endif
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
272
cereal/log.capnp
272
cereal/log.capnp
|
@ -1,272 +0,0 @@
|
|||
using Cxx = import "c++.capnp";
|
||||
$Cxx.namespace("cereal");
|
||||
|
||||
@0xf3b1f17e25a4285b;
|
||||
|
||||
const logVersion :Int32 = 1;
|
||||
|
||||
struct InitData {
|
||||
kernelArgs @0 :List(Text);
|
||||
gctx @1 :Text;
|
||||
dongleId @2 :Text;
|
||||
}
|
||||
|
||||
struct FrameData {
|
||||
frameId @0 :UInt32;
|
||||
encodeId @1 :UInt32; # DEPRECATED
|
||||
timestampEof @2 :UInt64;
|
||||
frameLength @3 :Int32;
|
||||
integLines @4 :Int32;
|
||||
globalGain @5 :Int32;
|
||||
image @6 :Data;
|
||||
}
|
||||
|
||||
struct GPSNMEAData {
|
||||
timestamp @0 :Int64;
|
||||
localWallTime @1 :UInt64;
|
||||
nmea @2 :Text;
|
||||
}
|
||||
|
||||
# android sensor_event_t
|
||||
struct SensorEventData {
|
||||
version @0 :Int32;
|
||||
sensor @1 :Int32;
|
||||
type @2 :Int32;
|
||||
timestamp @3 :Int64;
|
||||
union {
|
||||
acceleration @4 :SensorVec;
|
||||
magnetic @5 :SensorVec;
|
||||
orientation @6 :SensorVec;
|
||||
gyro @7 :SensorVec;
|
||||
}
|
||||
|
||||
struct SensorVec {
|
||||
v @0 :List(Float32);
|
||||
status @1 :Int8;
|
||||
}
|
||||
}
|
||||
|
||||
struct CanData {
|
||||
address @0 :UInt32;
|
||||
busTime @1 :UInt16;
|
||||
dat @2 :Data;
|
||||
src @3 :Int8;
|
||||
}
|
||||
|
||||
struct ThermalData {
|
||||
cpu0 @0 :UInt16;
|
||||
cpu1 @1 :UInt16;
|
||||
cpu2 @2 :UInt16;
|
||||
cpu3 @3 :UInt16;
|
||||
mem @4 :UInt16;
|
||||
gpu @5 :UInt16;
|
||||
bat @6 :UInt32;
|
||||
}
|
||||
|
||||
struct HealthData {
|
||||
# from can health
|
||||
voltage @0 :UInt32;
|
||||
current @1 :UInt32;
|
||||
started @2 :Bool;
|
||||
controlsAllowed @3 :Bool;
|
||||
gasInterceptorDetected @4 :Bool;
|
||||
}
|
||||
|
||||
struct LiveUI {
|
||||
rearViewCam @0 :Bool;
|
||||
alertText1 @1 :Text;
|
||||
alertText2 @2 :Text;
|
||||
awarenessStatus @3 :Float32;
|
||||
}
|
||||
|
||||
struct Live20Data {
|
||||
canMonoTimes @10 :List(UInt64);
|
||||
mdMonoTime @6 :UInt64;
|
||||
ftMonoTime @7 :UInt64;
|
||||
|
||||
# all deprecated
|
||||
warpMatrix @0 :List(Float32);
|
||||
angleOffset @1 :Float32;
|
||||
calStatus @2 :Int8;
|
||||
calCycle @8 :Int32;
|
||||
calPerc @9 :Int8;
|
||||
|
||||
leadOne @3 :LeadData;
|
||||
leadTwo @4 :LeadData;
|
||||
cumLagMs @5 :Float32;
|
||||
|
||||
struct LeadData {
|
||||
dRel @0 :Float32;
|
||||
yRel @1 :Float32;
|
||||
vRel @2 :Float32;
|
||||
aRel @3 :Float32;
|
||||
vLead @4 :Float32;
|
||||
aLead @5 :Float32;
|
||||
dPath @6 :Float32;
|
||||
vLat @7 :Float32;
|
||||
vLeadK @8 :Float32;
|
||||
aLeadK @9 :Float32;
|
||||
fcw @10 :Bool;
|
||||
status @11 :Bool;
|
||||
}
|
||||
}
|
||||
|
||||
struct LiveCalibrationData {
|
||||
warpMatrix @0 :List(Float32);
|
||||
calStatus @1 :Int8;
|
||||
calCycle @2 :Int32;
|
||||
calPerc @3 :Int8;
|
||||
}
|
||||
|
||||
struct LiveTracks {
|
||||
trackId @0 :Int32;
|
||||
dRel @1 :Float32;
|
||||
yRel @2 :Float32;
|
||||
vRel @3 :Float32;
|
||||
aRel @4 :Float32;
|
||||
timeStamp @5 :Float32;
|
||||
status @6 :Float32;
|
||||
currentTime @7 :Float32;
|
||||
stationary @8 :Bool;
|
||||
oncoming @9 :Bool;
|
||||
}
|
||||
|
||||
struct Live100Data {
|
||||
canMonoTime @16 :UInt64;
|
||||
canMonoTimes @21 :List(UInt64);
|
||||
l20MonoTime @17 :UInt64;
|
||||
mdMonoTime @18 :UInt64;
|
||||
|
||||
vEgo @0 :Float32;
|
||||
aEgo @1 :Float32;
|
||||
vPid @2 :Float32;
|
||||
vTargetLead @3 :Float32;
|
||||
upAccelCmd @4 :Float32;
|
||||
uiAccelCmd @5 :Float32;
|
||||
yActual @6 :Float32;
|
||||
yDes @7 :Float32;
|
||||
upSteer @8 :Float32;
|
||||
uiSteer @9 :Float32;
|
||||
aTargetMin @10 :Float32;
|
||||
aTargetMax @11 :Float32;
|
||||
jerkFactor @12 :Float32;
|
||||
angleSteers @13 :Float32;
|
||||
hudLead @14 :Int32;
|
||||
cumLagMs @15 :Float32;
|
||||
|
||||
enabled @19: Bool;
|
||||
steerOverride @20: Bool;
|
||||
|
||||
vCruise @22: Float32;
|
||||
|
||||
rearViewCam @23 :Bool;
|
||||
alertText1 @24 :Text;
|
||||
alertText2 @25 :Text;
|
||||
awarenessStatus @26 :Float32;
|
||||
}
|
||||
|
||||
struct LiveEventData {
|
||||
name @0 :Text;
|
||||
value @1 :Int32;
|
||||
}
|
||||
|
||||
struct ModelData {
|
||||
frameId @0 :UInt32;
|
||||
|
||||
path @1 :PathData;
|
||||
leftLane @2 :PathData;
|
||||
rightLane @3 :PathData;
|
||||
lead @4 :LeadData;
|
||||
|
||||
settings @5 :ModelSettings;
|
||||
|
||||
struct PathData {
|
||||
points @0 :List(Float32);
|
||||
prob @1 :Float32;
|
||||
std @2 :Float32;
|
||||
}
|
||||
|
||||
struct LeadData {
|
||||
dist @0 :Float32;
|
||||
prob @1 :Float32;
|
||||
std @2 :Float32;
|
||||
}
|
||||
|
||||
struct ModelSettings {
|
||||
bigBoxX @0 :UInt16;
|
||||
bigBoxY @1 :UInt16;
|
||||
bigBoxWidth @2 :UInt16;
|
||||
bigBoxHeight @3 :UInt16;
|
||||
boxProjection @4 :List(Float32);
|
||||
yuvCorrection @5 :List(Float32);
|
||||
}
|
||||
}
|
||||
|
||||
struct CalibrationFeatures {
|
||||
frameId @0 :UInt32;
|
||||
|
||||
p0 @1 :List(Float32);
|
||||
p1 @2 :List(Float32);
|
||||
status @3 :List(Int8);
|
||||
}
|
||||
|
||||
struct EncodeIndex {
|
||||
# picture from camera
|
||||
frameId @0 :UInt32;
|
||||
type @1 :Type;
|
||||
# index of encoder from start of route
|
||||
encodeId @2 :UInt32;
|
||||
# minute long segment this frame is in
|
||||
segmentNum @3 :Int32;
|
||||
# index into camera file in segment from 0
|
||||
segmentId @4 :UInt32;
|
||||
|
||||
enum Type {
|
||||
bigBoxLossless @0; # rcamera.mkv
|
||||
fullHEVC @1; # fcamera.hevc
|
||||
bigBoxHEVC @2; # bcamera.hevc
|
||||
}
|
||||
}
|
||||
|
||||
struct AndroidLogEntry {
|
||||
id @0 :UInt8;
|
||||
ts @1 :UInt64;
|
||||
priority @2 :UInt8;
|
||||
pid @3 :Int32;
|
||||
tid @4 :Int32;
|
||||
tag @5 :Text;
|
||||
message @6 :Text;
|
||||
}
|
||||
|
||||
struct LogRotate {
|
||||
segmentNum @0 :Int32;
|
||||
path @1 :Text;
|
||||
}
|
||||
|
||||
|
||||
struct Event {
|
||||
logMonoTime @0 :UInt64;
|
||||
|
||||
union {
|
||||
initData @1 :InitData;
|
||||
frame @2 :FrameData;
|
||||
gpsNMEA @3 :GPSNMEAData;
|
||||
sensorEventDEPRECATED @4 :SensorEventData;
|
||||
can @5 :List(CanData);
|
||||
thermal @6 :ThermalData;
|
||||
live100 @7 :Live100Data;
|
||||
liveEventDEPRECATED @8 :List(LiveEventData);
|
||||
model @9 :ModelData;
|
||||
features @10 :CalibrationFeatures;
|
||||
sensorEvents @11 :List(SensorEventData);
|
||||
health @12 : HealthData;
|
||||
live20 @13 :Live20Data;
|
||||
liveUIDEPRECATED @14 :LiveUI;
|
||||
encodeIdx @15 :EncodeIndex;
|
||||
liveTracks @16 :List(LiveTracks);
|
||||
sendcan @17 :List(CanData);
|
||||
logMessage @18 :Text;
|
||||
liveCalibration @19 :LiveCalibrationData;
|
||||
androidLogEntry @20 :AndroidLogEntry;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,8 @@
|
|||
comment: false
|
||||
coverage:
|
||||
status:
|
||||
project:
|
||||
default:
|
||||
informational: true
|
||||
patch: off
|
||||
|
|
@ -0,0 +1 @@
|
|||
*.cpp
|
|
@ -0,0 +1,4 @@
|
|||
Import('envCython', 'common')
|
||||
|
||||
envCython.Program('clock.so', 'clock.pyx')
|
||||
envCython.Program('params_pyx.so', 'params_pyx.pyx', LIBS=envCython['LIBS'] + [common, 'zmq'])
|
|
@ -1,8 +1,45 @@
|
|||
import jwt
|
||||
import requests
|
||||
from datetime import datetime, timedelta
|
||||
from common.basedir import PERSIST
|
||||
from selfdrive.version import version
|
||||
|
||||
def api_get(endpoint, method='GET', timeout=None, **params):
|
||||
class Api():
|
||||
def __init__(self, dongle_id):
|
||||
self.dongle_id = dongle_id
|
||||
with open(PERSIST+'/comma/id_rsa') as f:
|
||||
self.private_key = f.read()
|
||||
|
||||
def get(self, *args, **kwargs):
|
||||
return self.request('GET', *args, **kwargs)
|
||||
|
||||
def post(self, *args, **kwargs):
|
||||
return self.request('POST', *args, **kwargs)
|
||||
|
||||
def request(self, method, endpoint, timeout=None, access_token=None, **params):
|
||||
return api_get(endpoint, method=method, timeout=timeout, access_token=access_token, **params)
|
||||
|
||||
def get_token(self):
|
||||
now = datetime.utcnow()
|
||||
payload = {
|
||||
'identity': self.dongle_id,
|
||||
'nbf': now,
|
||||
'iat': now,
|
||||
'exp': now + timedelta(hours=1)
|
||||
}
|
||||
token = jwt.encode(payload, self.private_key, algorithm='RS256')
|
||||
if isinstance(token, bytes):
|
||||
token = token.decode('utf8')
|
||||
return token
|
||||
|
||||
|
||||
def api_get(endpoint, method='GET', timeout=None, access_token=None, **params):
|
||||
backend = "https://api.commadotai.com/"
|
||||
|
||||
params['_version'] = "OPENPILOTv0.0"
|
||||
headers = {}
|
||||
if access_token is not None:
|
||||
headers['Authorization'] = "JWT "+access_token
|
||||
|
||||
return requests.request(method, backend+endpoint, timeout=timeout, params=params)
|
||||
headers['User-Agent'] = "openpilot-" + version
|
||||
|
||||
return requests.request(method, backend+endpoint, timeout=timeout, headers=headers, params=params)
|
||||
|
|
|
@ -0,0 +1,11 @@
|
|||
import os
|
||||
from pathlib import Path
|
||||
|
||||
from selfdrive.hardware import PC
|
||||
|
||||
BASEDIR = os.path.abspath(os.path.join(os.path.dirname(os.path.realpath(__file__)), "../"))
|
||||
|
||||
if PC:
|
||||
PERSIST = os.path.join(str(Path.home()), ".comma", "persist")
|
||||
else:
|
||||
PERSIST = "/persist"
|
|
@ -0,0 +1,24 @@
|
|||
# distutils: language = c++
|
||||
# cython: language_level = 3
|
||||
from posix.time cimport clock_gettime, timespec, CLOCK_MONOTONIC_RAW, clockid_t
|
||||
|
||||
IF UNAME_SYSNAME == "Darwin":
|
||||
# Darwin doesn't have a CLOCK_BOOTTIME
|
||||
CLOCK_BOOTTIME = CLOCK_MONOTONIC_RAW
|
||||
ELSE:
|
||||
from posix.time cimport CLOCK_BOOTTIME
|
||||
|
||||
cdef double readclock(clockid_t 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)
|
||||
|
|
@ -1,26 +0,0 @@
|
|||
"""Install exception handler for process crash."""
|
||||
import os
|
||||
import sys
|
||||
|
||||
if os.getenv("NOLOG"):
|
||||
def capture_exception(*exc_info):
|
||||
pass
|
||||
def install():
|
||||
pass
|
||||
else:
|
||||
from raven import Client
|
||||
from raven.transport.http import HTTPTransport
|
||||
|
||||
client = Client('https://1994756b5e6f41cf939a4c65de45f4f2:cefebaf3a8aa40d182609785f7189bd7@app.getsentry.com/77924',
|
||||
install_sys_hook=False, transport=HTTPTransport)
|
||||
|
||||
capture_exception = client.captureException
|
||||
|
||||
def install():
|
||||
# installs a sys.excepthook
|
||||
__excepthook__ = sys.excepthook
|
||||
def handle_exception(*exc_info):
|
||||
if exc_info[0] not in (KeyboardInterrupt, SystemExit):
|
||||
client.captureException(exc_info=exc_info)
|
||||
__excepthook__(*exc_info)
|
||||
sys.excepthook = handle_exception
|
|
@ -0,0 +1,23 @@
|
|||
import os
|
||||
import sysconfig
|
||||
from Cython.Distutils import build_ext
|
||||
|
||||
def get_ext_filename_without_platform_suffix(filename):
|
||||
name, ext = os.path.splitext(filename)
|
||||
ext_suffix = sysconfig.get_config_var('EXT_SUFFIX')
|
||||
|
||||
if ext_suffix == ext:
|
||||
return filename
|
||||
|
||||
ext_suffix = ext_suffix.replace(ext, '')
|
||||
idx = name.find(ext_suffix)
|
||||
|
||||
if idx == -1:
|
||||
return filename
|
||||
else:
|
||||
return name[:idx] + ext
|
||||
|
||||
class BuildExtWithoutPlatformSuffix(build_ext):
|
||||
def get_ext_filename(self, ext_name):
|
||||
filename = super().get_ext_filename(ext_name)
|
||||
return get_ext_filename_without_platform_suffix(filename)
|
182
common/dbc.py
182
common/dbc.py
|
@ -1,182 +0,0 @@
|
|||
import re
|
||||
from collections import namedtuple
|
||||
import bitstring
|
||||
|
||||
def int_or_float(s):
|
||||
# return number, trying to maintain int format
|
||||
try:
|
||||
return int(s)
|
||||
except ValueError:
|
||||
return float(s)
|
||||
|
||||
DBCSignal = namedtuple(
|
||||
"DBCSignal", ["name", "start_bit", "size", "is_little_endian", "is_signed",
|
||||
"factor", "offset", "tmin", "tmax", "units"])
|
||||
|
||||
class dbc(object):
|
||||
def __init__(self, fn):
|
||||
self.txt = open(fn).read().split("\n")
|
||||
self._warned_addresses = set()
|
||||
|
||||
# regexps from https://github.com/ebroecker/canmatrix/blob/master/canmatrix/importdbc.py
|
||||
bo_regexp = re.compile("^BO\_ (\w+) (\w+) *: (\w+) (\w+)")
|
||||
sg_regexp = re.compile("^SG\_ (\w+) : (\d+)\|(\d+)@(\d+)([\+|\-]) \(([0-9.+\-eE]+),([0-9.+\-eE]+)\) \[([0-9.+\-eE]+)\|([0-9.+\-eE]+)\] \"(.*)\" (.*)")
|
||||
sgm_regexp = re.compile("^SG\_ (\w+) (\w+) *: (\d+)\|(\d+)@(\d+)([\+|\-]) \(([0-9.+\-eE]+),([0-9.+\-eE]+)\) \[([0-9.+\-eE]+)\|([0-9.+\-eE]+)\] \"(.*)\" (.*)")
|
||||
|
||||
# A dictionary which maps message ids to tuples ((name, size), signals).
|
||||
# name is the ASCII name of the message.
|
||||
# size is the size of the message in bytes.
|
||||
# signals is a list signals contained in the message.
|
||||
# signals is a list of DBCSignal in order of increasing start_bit.
|
||||
self.msgs = {}
|
||||
|
||||
self.bits = []
|
||||
for i in range(0, 64, 8):
|
||||
for j in range(7, -1, -1):
|
||||
self.bits.append(i+j)
|
||||
|
||||
for l in self.txt:
|
||||
l = l.strip()
|
||||
|
||||
if l.startswith("BO_ "):
|
||||
# new group
|
||||
dat = bo_regexp.match(l)
|
||||
|
||||
if dat is None:
|
||||
print "bad BO", l
|
||||
name = dat.group(2)
|
||||
size = int(dat.group(3))
|
||||
ids = int(dat.group(1), 0) # could be hex
|
||||
|
||||
self.msgs[ids] = ((name, size), [])
|
||||
|
||||
if l.startswith("SG_ "):
|
||||
# new signal
|
||||
dat = sg_regexp.match(l)
|
||||
go = 0
|
||||
if dat is None:
|
||||
dat = sgm_regexp.match(l)
|
||||
go = 1
|
||||
if dat is None:
|
||||
print "bad SG", l
|
||||
|
||||
sgname = dat.group(1)
|
||||
start_bit = int(dat.group(go+2))
|
||||
signal_size = int(dat.group(go+3))
|
||||
is_little_endian = int(dat.group(go+4))==1
|
||||
is_signed = dat.group(go+5)=='-'
|
||||
factor = int_or_float(dat.group(go+6))
|
||||
offset = int_or_float(dat.group(go+7))
|
||||
tmin = int_or_float(dat.group(go+8))
|
||||
tmax = int_or_float(dat.group(go+9))
|
||||
units = dat.group(go+10)
|
||||
|
||||
self.msgs[ids][1].append(
|
||||
DBCSignal(sgname, start_bit, signal_size, is_little_endian,
|
||||
is_signed, factor, offset, tmin, tmax, units))
|
||||
|
||||
for msg in self.msgs.viewvalues():
|
||||
msg[1].sort(key=lambda x: x.start_bit)
|
||||
|
||||
def encode(self, msg_id, dd):
|
||||
"""Encode a CAN message using the dbc.
|
||||
|
||||
Inputs:
|
||||
msg_id: The message ID.
|
||||
dd: A dictionary mapping signal name to signal data.
|
||||
"""
|
||||
# TODO: Stop using bitstring, which is super slow.
|
||||
msg_def = self.msgs[msg_id]
|
||||
size = msg_def[0][1]
|
||||
|
||||
bsf = bitstring.Bits(hex="00"*size)
|
||||
for s in msg_def[1]:
|
||||
ival = dd.get(s.name)
|
||||
if ival is not None:
|
||||
ival = (ival / s.factor) - s.offset
|
||||
ival = int(round(ival))
|
||||
|
||||
# should pack this
|
||||
if s.is_little_endian:
|
||||
ss = s.start_bit
|
||||
else:
|
||||
ss = self.bits.index(s.start_bit)
|
||||
|
||||
|
||||
if s.is_signed:
|
||||
tbs = bitstring.Bits(int=ival, length=s.size)
|
||||
else:
|
||||
tbs = bitstring.Bits(uint=ival, length=s.size)
|
||||
|
||||
lpad = bitstring.Bits(bin="0b"+"0"*ss)
|
||||
rpad = bitstring.Bits(bin="0b"+"0"*(8*size-(ss+s.size)))
|
||||
tbs = lpad+tbs+rpad
|
||||
|
||||
bsf |= tbs
|
||||
return bsf.tobytes()
|
||||
|
||||
def decode(self, x, arr=None, debug=False):
|
||||
"""Decode a CAN message using the dbc.
|
||||
|
||||
Inputs:
|
||||
x: A collection with elements (address, time, data), where address is
|
||||
the CAN address, time is the bus time, and data is the CAN data as a
|
||||
hex string.
|
||||
arr: Optional list of signals which should be decoded and returned.
|
||||
debug: True to print debugging statements.
|
||||
|
||||
Returns:
|
||||
A tuple (name, data), where name is the name of the CAN message and data
|
||||
is the decoded result. If arr is None, data is a dict of properties.
|
||||
Otherwise data is a list of the same length as arr.
|
||||
|
||||
Returns (None, None) if the message could not be decoded.
|
||||
"""
|
||||
if arr is None:
|
||||
out = {}
|
||||
else:
|
||||
out = [None]*len(arr)
|
||||
|
||||
msg = self.msgs.get(x[0])
|
||||
if msg is None:
|
||||
if x[0] not in self._warned_addresses:
|
||||
print("WARNING: Unknown message address {}".format(x[0]))
|
||||
self._warned_addresses.add(x[0])
|
||||
return None, None
|
||||
|
||||
name = msg[0][0]
|
||||
if debug:
|
||||
print name
|
||||
|
||||
blen = (len(x[2])/2)*8
|
||||
x2_int = int(x[2], 16)
|
||||
|
||||
for s in msg[1]:
|
||||
if arr is not None and s[0] not in arr:
|
||||
continue
|
||||
|
||||
# big or little endian?
|
||||
# see http://vi-firmware.openxcplatform.com/en/master/config/bit-numbering.html
|
||||
if s[3] is False:
|
||||
ss = self.bits.index(s[1])
|
||||
else:
|
||||
ss = s[1]
|
||||
|
||||
data_bit_pos = (blen - (ss + s[2]))
|
||||
if data_bit_pos < 0:
|
||||
continue
|
||||
ival = (x2_int >> data_bit_pos) & ((1 << (s[2])) - 1)
|
||||
|
||||
if s[4] and (ival & (1<<(s[2]-1))): # signed
|
||||
ival -= (1<<s[2])
|
||||
|
||||
# control the offset
|
||||
ival = (ival + s[6])*s[5]
|
||||
if debug:
|
||||
print "%40s %2d %2d %7.2f %s" % (s[0], s[1], s[2], ival, s[-1])
|
||||
|
||||
if arr is None:
|
||||
out[s[0]] = ival
|
||||
else:
|
||||
out[arr.index(s[0])] = ival
|
||||
return name, out
|
|
@ -0,0 +1,9 @@
|
|||
# remove all keys that end in DEPRECATED
|
||||
def strip_deprecated_keys(d):
|
||||
for k in list(d.keys()):
|
||||
if isinstance(k, str):
|
||||
if k.endswith('DEPRECATED'):
|
||||
d.pop(k)
|
||||
elif isinstance(d[k], dict):
|
||||
strip_deprecated_keys(d[k])
|
||||
return d
|
|
@ -0,0 +1,55 @@
|
|||
import os
|
||||
import sys
|
||||
import fcntl
|
||||
import hashlib
|
||||
import platform
|
||||
from cffi import FFI
|
||||
|
||||
def suffix():
|
||||
if platform.system() == "Darwin":
|
||||
return ".dylib"
|
||||
else:
|
||||
return ".so"
|
||||
|
||||
def ffi_wrap(name, c_code, c_header, tmpdir="/tmp/ccache", cflags="", libraries=None):
|
||||
if libraries is None:
|
||||
libraries = []
|
||||
|
||||
cache = name + "_" + hashlib.sha1(c_code.encode('utf-8')).hexdigest()
|
||||
try:
|
||||
os.mkdir(tmpdir)
|
||||
except OSError:
|
||||
pass
|
||||
|
||||
fd = os.open(tmpdir, 0)
|
||||
fcntl.flock(fd, fcntl.LOCK_EX)
|
||||
try:
|
||||
sys.path.append(tmpdir)
|
||||
try:
|
||||
mod = __import__(cache)
|
||||
except Exception:
|
||||
print("cache miss {0}".format(cache))
|
||||
compile_code(cache, c_code, c_header, tmpdir, cflags, libraries)
|
||||
mod = __import__(cache)
|
||||
finally:
|
||||
os.close(fd)
|
||||
|
||||
return mod.ffi, mod.lib
|
||||
|
||||
|
||||
def compile_code(name, c_code, c_header, directory, cflags="", libraries=None):
|
||||
if libraries is None:
|
||||
libraries = []
|
||||
|
||||
ffibuilder = FFI()
|
||||
ffibuilder.set_source(name, c_code, source_extension='.cpp', libraries=libraries)
|
||||
ffibuilder.cdef(c_header)
|
||||
os.environ['OPT'] = "-fwrapv -O2 -DNDEBUG -std=c++1z"
|
||||
os.environ['CFLAGS'] = cflags
|
||||
ffibuilder.compile(verbose=True, debug=False, tmpdir=directory)
|
||||
|
||||
|
||||
def wrap_compiled(name, directory):
|
||||
sys.path.append(directory)
|
||||
mod = __import__(name)
|
||||
return mod.ffi, mod.lib
|
|
@ -0,0 +1,122 @@
|
|||
import os
|
||||
import shutil
|
||||
import tempfile
|
||||
from atomicwrites import AtomicWriter
|
||||
|
||||
|
||||
def mkdirs_exists_ok(path):
|
||||
if path.startswith('http://') or path.startswith('https://'):
|
||||
raise ValueError('URL 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):
|
||||
normpath = os.path.normpath(path)
|
||||
parts = normpath.split("/")
|
||||
if len(parts) > 1 and parts[1] == "scratch":
|
||||
return "/scratch/tmp"
|
||||
elif len(parts) > 2 and parts[2] == "runner":
|
||||
return "/{}/runner/tmp".format(parts[1])
|
||||
return "/tmp"
|
||||
|
||||
|
||||
class AutoMoveTempdir():
|
||||
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, exc_type, exc_value, traceback):
|
||||
if exc_type is None:
|
||||
self.close()
|
||||
else:
|
||||
shutil.rmtree(self._path)
|
||||
|
||||
|
||||
class NamedTemporaryDir():
|
||||
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, exc_type, exc_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)))
|
||||
|
||||
|
||||
def atomic_write_in_dir_neos(path, contents, mode=None):
|
||||
"""
|
||||
Atomically writes contents to path using a temporary file in the same directory
|
||||
as path. Useful on NEOS, where `os.link` (required by atomic_write_in_dir) is missing.
|
||||
"""
|
||||
|
||||
f = tempfile.NamedTemporaryFile(delete=False, prefix=".tmp", dir=os.path.dirname(path))
|
||||
f.write(contents)
|
||||
f.flush()
|
||||
if mode is not None:
|
||||
os.fchmod(f.fileno(), mode)
|
||||
os.fsync(f.fileno())
|
||||
f.close()
|
||||
|
||||
os.rename(f.name, path)
|
|
@ -0,0 +1,9 @@
|
|||
class FirstOrderFilter():
|
||||
# first order filter
|
||||
def __init__(self, x0, ts, dt):
|
||||
self.k = (dt / ts) / (1. + dt / ts)
|
||||
self.x = x0
|
||||
|
||||
def update(self, x):
|
||||
self.x = (1. - self.k) * self.x + self.k * x
|
||||
return self.x
|
|
@ -1,17 +0,0 @@
|
|||
"""Classes for filtering discrete time signals."""
|
||||
import numpy as np
|
||||
|
||||
|
||||
class FirstOrderLowpassFilter(object):
|
||||
def __init__(self, fc, dt, x1=0):
|
||||
self.kf = 2 * np.pi * fc * dt / (1 + 2 * np.pi * fc * dt)
|
||||
self.x1 = x1
|
||||
|
||||
def __call__(self, x):
|
||||
self.x1 = (1 - self.kf) * self.x1 + self.kf * x
|
||||
|
||||
# If previous or current is NaN, reset filter.
|
||||
if np.isnan(self.x1):
|
||||
self.x1 = x
|
||||
|
||||
return self.x1
|
|
@ -0,0 +1,14 @@
|
|||
def gpio_init(pin, output):
|
||||
try:
|
||||
with open(f"/sys/class/gpio/gpio{pin}/direction", 'wb') as f:
|
||||
f.write(b"out" if output else b"in")
|
||||
except Exception as e:
|
||||
print(f"Failed to set gpio {pin} direction: {e}")
|
||||
|
||||
|
||||
def gpio_set(pin, high):
|
||||
try:
|
||||
with open(f"/sys/class/gpio/gpio{pin}/value", 'wb') as f:
|
||||
f.write(b"1" if high else b"0")
|
||||
except Exception as e:
|
||||
print(f"Failed to set gpio {pin} value: {e}")
|
|
@ -0,0 +1 @@
|
|||
simple_kalman_impl.c
|
|
@ -0,0 +1,3 @@
|
|||
Import('envCython')
|
||||
|
||||
envCython.Program('simple_kalman_impl.so', 'simple_kalman_impl.pyx')
|
|
@ -1,300 +0,0 @@
|
|||
import abc
|
||||
import numpy as np
|
||||
import numpy.matlib
|
||||
|
||||
# The EKF class contains the framework for an Extended Kalman Filter, but must be subclassed to use.
|
||||
# A subclass must implement:
|
||||
# 1) calc_transfer_fun(); see bottom of file for more info.
|
||||
# 2) __init__() to initialize self.state, self.covar, and self.process_noise appropriately
|
||||
|
||||
# Alternatively, the existing implementations of EKF can be used (e.g. EKF2D)
|
||||
|
||||
# Sensor classes are optionally used to pass measurement information into the EKF, to keep
|
||||
# sensor parameters and processing methods for a each sensor together.
|
||||
# Sensor classes have a read() method which takes raw sensor data and returns
|
||||
# a SensorReading object, which can be passed to the EKF update() method.
|
||||
|
||||
# For usage, see run_ekf1d.py in selfdrive/new for a simple example.
|
||||
# ekf.predict(dt) should be called between update cycles with the time since it was last called.
|
||||
# Ideally, predict(dt) should be called at a relatively constant rate.
|
||||
# update() should be called once per sensor, and can be called multiple times between predict steps.
|
||||
# Access and set the state of the filter directly with ekf.state and ekf.covar.
|
||||
|
||||
class SensorReading:
|
||||
# Given a perfect model and no noise, data = obs_model * state
|
||||
def __init__(self, data, covar, obs_model):
|
||||
self.data = data
|
||||
self.obs_model = obs_model
|
||||
self.covar = covar
|
||||
|
||||
def __repr__(self):
|
||||
return "SensorReading(data={}, covar={}, obs_model={})".format(
|
||||
repr(self.data), repr(self.covar), repr(self.obs_model))
|
||||
|
||||
|
||||
# A generic sensor class that does no pre-processing of data
|
||||
class SimpleSensor:
|
||||
# obs_model can be
|
||||
# a full obesrvation model matrix, or
|
||||
# an integer or tuple of indices into ekf.state, indicating which variables are being directly observed
|
||||
# covar can be
|
||||
# a full covariance matrix
|
||||
# a float or tuple of individual covars for each component of the sensor reading
|
||||
# dims is the number of states in the EKF
|
||||
def __init__(self, obs_model, covar, dims):
|
||||
# Allow for integer covar/obs_model
|
||||
if not hasattr(obs_model, "__len__"):
|
||||
obs_model = (obs_model, )
|
||||
if not hasattr(covar, "__len__"):
|
||||
covar = (covar, )
|
||||
|
||||
# Full observation model passed
|
||||
if dims in np.array(obs_model).shape:
|
||||
self.obs_model = np.asmatrix(obs_model)
|
||||
self.covar = np.asmatrix(covar)
|
||||
# Indices of unit observations passed
|
||||
else:
|
||||
self.obs_model = np.matlib.zeros((len(obs_model), dims))
|
||||
self.obs_model[:, list(obs_model)] = np.identity(len(obs_model))
|
||||
if np.asarray(covar).ndim == 2:
|
||||
self.covar = np.asmatrix(covar)
|
||||
elif len(covar) == len(obs_model):
|
||||
self.covar = np.matlib.diag(covar)
|
||||
else:
|
||||
self.covar = np.matlib.identity(len(obs_model)) * covar
|
||||
|
||||
def read(self, data, covar=None):
|
||||
if covar:
|
||||
self.covar = covar
|
||||
return SensorReading(data, self.covar, self.obs_model)
|
||||
|
||||
class GPS:
|
||||
earth_r = 6371e3 # m, average earth radius
|
||||
|
||||
def __init__(self, xy_idx=(0, 1), dims=2, var=1e4):
|
||||
self.obs_model = np.matlib.zeros((2, dims))
|
||||
self.obs_model[:, tuple(xy_idx)] = np.matlib.identity(2)
|
||||
self.covar = np.matlib.identity(2) * var
|
||||
|
||||
# [lat, lon] in decimal degrees
|
||||
def init_pos(self, latlon):
|
||||
self.init_lat, self.init_lon = np.radians(np.asarray(latlon[:2]))
|
||||
|
||||
# Compute straight-line distance, in meters, between two lat/long coordinates
|
||||
# Input in radians
|
||||
def haversine(self, lat1, lon1, lat2, lon2):
|
||||
lat_diff = lat2 - lat1
|
||||
lon_diff = lon2 - lon1
|
||||
d = np.sin(lat_diff * 0.5)**2 + np.cos(lat1) * np.cos(lat2) * np.sin(
|
||||
lon_diff * 0.5)**2
|
||||
h = 2 * GPS.earth_r * np.arcsin(np.sqrt(d))
|
||||
return h
|
||||
|
||||
# Convert decimal degrees into meters
|
||||
def convert_deg2m(self, lat, lon):
|
||||
lat, lon = np.radians([lat, lon])
|
||||
|
||||
xs = (lon - self.init_lon) * np.cos(self.init_lat) * GPS.earth_r
|
||||
ys = (lat - self.init_lat) * GPS.earth_r
|
||||
|
||||
return xs, ys
|
||||
|
||||
# Convert meters into decimal degrees
|
||||
def convert_m2deg(self, xs, ys):
|
||||
lat = ys / GPS.earth_r + self.init_lat
|
||||
lon = xs / (GPS.earth_r * np.cos(self.init_lat)) + self.init_lon
|
||||
|
||||
return np.degrees(lat), np.degrees(lon)
|
||||
|
||||
# latlon is [lat, long,] as decimal degrees
|
||||
# accuracy is as given by Android location service: radius of 68% confidence
|
||||
def read(self, latlon, accuracy=None):
|
||||
x_dist, y_dist = self.convert_deg2m(latlon[0], latlon[1])
|
||||
if not accuracy:
|
||||
covar = self.covar
|
||||
else:
|
||||
covar = np.matlib.identity(2) * accuracy**2
|
||||
|
||||
return SensorReading(
|
||||
np.asmatrix([x_dist, y_dist]).T, covar, self.obs_model)
|
||||
|
||||
class EKF:
|
||||
__metaclass__ = abc.ABCMeta
|
||||
|
||||
def __init__(self, debug=False):
|
||||
self.DEBUG = debug
|
||||
|
||||
|
||||
def __str__(self):
|
||||
return "EKF(state={}, covar={})".format(self.state, self.covar)
|
||||
|
||||
# Measurement update
|
||||
# Reading should be a SensorReading object with data, covar, and obs_model attributes
|
||||
def update(self, reading):
|
||||
# Potential improvements:
|
||||
# deal with negative covars
|
||||
# add noise to really low covars to ensure stability
|
||||
# use mahalanobis distance to reject outliers
|
||||
# wrap angles after state updates and innovation
|
||||
|
||||
# y = z - H*x
|
||||
innovation = reading.data - reading.obs_model * self.state
|
||||
|
||||
if self.DEBUG:
|
||||
print "reading:\n",reading.data
|
||||
print "innovation:\n",innovation
|
||||
|
||||
# S = H*P*H' + R
|
||||
innovation_covar = reading.obs_model * self.covar * reading.obs_model.T + reading.covar
|
||||
|
||||
# K = P*H'*S^-1
|
||||
kalman_gain = self.covar * reading.obs_model.T * np.linalg.inv(
|
||||
innovation_covar)
|
||||
|
||||
if self.DEBUG:
|
||||
print "gain:\n", kalman_gain
|
||||
print "innovation_covar:\n", innovation_covar
|
||||
print "innovation: ", innovation
|
||||
print "test: ", self.covar * reading.obs_model.T * (
|
||||
reading.obs_model * self.covar * reading.obs_model.T + reading.covar *
|
||||
0).I
|
||||
|
||||
# x = x + K*y
|
||||
self.state += kalman_gain*innovation
|
||||
|
||||
# print "covar", np.diag(self.covar)
|
||||
#self.state[(roll_vel, yaw_vel, pitch_vel),:] = reading.data
|
||||
|
||||
# Standard form: P = (I - K*H)*P
|
||||
# self.covar = (self.identity - kalman_gain*reading.obs_model) * self.covar
|
||||
|
||||
# Use the Joseph form for numerical stability: P = (I-K*H)*P*(I - K*H)' + K*R*K'
|
||||
aux_mtrx = (self.identity - kalman_gain * reading.obs_model)
|
||||
self.covar = aux_mtrx * self.covar * aux_mtrx.T + kalman_gain * reading.covar * kalman_gain.T
|
||||
|
||||
if self.DEBUG:
|
||||
print "After update"
|
||||
print "state\n", self.state
|
||||
print "covar:\n",self.covar
|
||||
|
||||
def update_scalar(self, reading):
|
||||
# like update but knowing that measurment is a scalar
|
||||
# this avoids matrix inversions and speeds up (surprisingly) drived.py a lot
|
||||
|
||||
# innovation = reading.data - np.matmul(reading.obs_model, self.state)
|
||||
# innovation_covar = np.matmul(np.matmul(reading.obs_model, self.covar), reading.obs_model.T) + reading.covar
|
||||
# kalman_gain = np.matmul(self.covar, reading.obs_model.T)/innovation_covar
|
||||
# self.state += np.matmul(kalman_gain, innovation)
|
||||
# aux_mtrx = self.identity - np.matmul(kalman_gain, reading.obs_model)
|
||||
# self.covar = np.matmul(aux_mtrx, np.matmul(self.covar, aux_mtrx.T)) + np.matmul(kalman_gain, np.matmul(reading.covar, kalman_gain.T))
|
||||
|
||||
# written without np.matmul
|
||||
es = np.einsum
|
||||
ABC_T = "ij,jk,lk->il"
|
||||
AB_T = "ij,kj->ik"
|
||||
AB = "ij,jk->ik"
|
||||
innovation = reading.data - es(AB, reading.obs_model, self.state)
|
||||
innovation_covar = es(ABC_T, reading.obs_model, self.covar,
|
||||
reading.obs_model) + reading.covar
|
||||
kalman_gain = es(AB_T, self.covar, reading.obs_model) / innovation_covar
|
||||
|
||||
self.state += es(AB, kalman_gain, innovation)
|
||||
aux_mtrx = self.identity - es(AB, kalman_gain, reading.obs_model)
|
||||
self.covar = es(ABC_T, aux_mtrx, self.covar, aux_mtrx) + \
|
||||
es(ABC_T, kalman_gain, reading.covar, kalman_gain)
|
||||
|
||||
# Prediction update
|
||||
def predict(self, dt):
|
||||
es = np.einsum
|
||||
ABC_T = "ij,jk,lk->il"
|
||||
AB = "ij,jk->ik"
|
||||
|
||||
# State update
|
||||
transfer_fun, transfer_fun_jacobian = self.calc_transfer_fun(dt)
|
||||
|
||||
# self.state = np.matmul(transfer_fun, self.state)
|
||||
# self.covar = np.matmul(np.matmul(transfer_fun_jacobian, self.covar), transfer_fun_jacobian.T) + self.process_noise * dt
|
||||
|
||||
# x = f(x, u), written in the form x = A(x, u)*x
|
||||
self.state = es(AB, transfer_fun, self.state)
|
||||
|
||||
# P = J*P*J' + Q
|
||||
self.covar = es(ABC_T, transfer_fun_jacobian, self.covar,
|
||||
transfer_fun_jacobian) + self.process_noise * dt #!dt
|
||||
|
||||
#! Clip covariance to avoid explosions
|
||||
self.covar = np.clip(self.covar,-1e10,1e10)
|
||||
|
||||
@abc.abstractmethod
|
||||
def calc_transfer_fun(self, dt):
|
||||
"""Return a tuple with the transfer function and transfer function jacobian
|
||||
The transfer function and jacobian should both be a numpy matrix of size DIMSxDIMS
|
||||
|
||||
The transfer function matrix A should satisfy the state-update equation
|
||||
x_(k+1) = A * x_k
|
||||
|
||||
The jacobian J is the direct jacobian A*x_k. For linear systems J=A.
|
||||
|
||||
Current implementations calculate A and J as functions of state. Control input
|
||||
can be added trivially by adding a control parameter to predict() and calc_tranfer_update(),
|
||||
and using it during calcualtion of A and J
|
||||
"""
|
||||
|
||||
class FastEKF1D(EKF):
|
||||
"""Fast version of EKF for 1D problems with scalar readings."""
|
||||
|
||||
def __init__(self, dt, var_init, Q):
|
||||
super(FastEKF1D, self).__init__(False)
|
||||
self.state = [0, 0]
|
||||
self.covar = [var_init, var_init, 0]
|
||||
|
||||
# Process Noise
|
||||
self.dtQ0 = dt * Q[0]
|
||||
self.dtQ1 = dt * Q[1]
|
||||
|
||||
def update(self, reading):
|
||||
raise NotImplementedError
|
||||
|
||||
def update_scalar(self, reading):
|
||||
# TODO(mgraczyk): Delete this for speed.
|
||||
# assert np.all(reading.obs_model == [1, 0])
|
||||
|
||||
rcov = reading.covar[0, 0]
|
||||
|
||||
x = self.state
|
||||
S = self.covar
|
||||
|
||||
innovation = reading.data - x[0]
|
||||
innovation_covar = S[0] + rcov
|
||||
|
||||
k0 = S[0] / innovation_covar
|
||||
k1 = S[2] / innovation_covar
|
||||
|
||||
x[0] += k0 * innovation
|
||||
x[1] += k1 * innovation
|
||||
|
||||
mk = 1 - k0
|
||||
S[1] += k1 * (k1 * (S[0] + rcov) - 2 * S[2])
|
||||
S[2] = mk * (S[2] - k1 * S[0]) + rcov * k0 * k1
|
||||
S[0] = mk * mk * S[0] + rcov * k0 * k0
|
||||
|
||||
def predict(self, dt):
|
||||
# State update
|
||||
x = self.state
|
||||
|
||||
x[0] += dt * x[1]
|
||||
|
||||
# P = J*P*J' + Q
|
||||
S = self.covar
|
||||
S[0] += dt * (2 * S[2] + dt * S[1]) + self.dtQ0
|
||||
S[2] += dt * S[1]
|
||||
S[1] += self.dtQ1
|
||||
|
||||
# Clip covariance to avoid explosions
|
||||
S = max(-1e10, min(S, 1e10))
|
||||
|
||||
def calc_transfer_fun(self, dt):
|
||||
tf = np.identity(2)
|
||||
tf[0, 1] = dt
|
||||
tfj = tf
|
||||
return tf, tfj
|
|
@ -0,0 +1,3 @@
|
|||
# pylint: skip-file
|
||||
from common.kalman.simple_kalman_impl import KF1D as KF1D
|
||||
assert KF1D
|
|
@ -0,0 +1,18 @@
|
|||
# cython: language_level = 3
|
||||
|
||||
cdef class KF1D:
|
||||
cdef public:
|
||||
double x0_0
|
||||
double x1_0
|
||||
double K0_0
|
||||
double K1_0
|
||||
double A0_0
|
||||
double A0_1
|
||||
double A1_0
|
||||
double A1_1
|
||||
double C0_0
|
||||
double C0_1
|
||||
double A_K_0
|
||||
double A_K_1
|
||||
double A_K_2
|
||||
double A_K_3
|
|
@ -0,0 +1,37 @@
|
|||
# distutils: language = c++
|
||||
# cython: language_level=3
|
||||
|
||||
cdef class KF1D:
|
||||
def __init__(self, x0, A, C, K):
|
||||
self.x0_0 = x0[0][0]
|
||||
self.x1_0 = x0[1][0]
|
||||
self.A0_0 = A[0][0]
|
||||
self.A0_1 = A[0][1]
|
||||
self.A1_0 = A[1][0]
|
||||
self.A1_1 = A[1][1]
|
||||
self.C0_0 = C[0]
|
||||
self.C0_1 = C[1]
|
||||
self.K0_0 = K[0][0]
|
||||
self.K1_0 = K[1][0]
|
||||
|
||||
self.A_K_0 = self.A0_0 - self.K0_0 * self.C0_0
|
||||
self.A_K_1 = self.A0_1 - self.K0_0 * self.C0_1
|
||||
self.A_K_2 = self.A1_0 - self.K1_0 * self.C0_0
|
||||
self.A_K_3 = self.A1_1 - self.K1_0 * self.C0_1
|
||||
|
||||
def update(self, meas):
|
||||
cdef double x0_0 = self.A_K_0 * self.x0_0 + self.A_K_1 * self.x1_0 + self.K0_0 * meas
|
||||
cdef double x1_0 = self.A_K_2 * self.x0_0 + self.A_K_3 * self.x1_0 + self.K1_0 * meas
|
||||
self.x0_0 = x0_0
|
||||
self.x1_0 = x1_0
|
||||
|
||||
return [self.x0_0, self.x1_0]
|
||||
|
||||
@property
|
||||
def x(self):
|
||||
return [[self.x0_0], [self.x1_0]]
|
||||
|
||||
@x.setter
|
||||
def x(self, x):
|
||||
self.x0_0 = x[0][0]
|
||||
self.x1_0 = x[1][0]
|
|
@ -0,0 +1,23 @@
|
|||
import numpy as np
|
||||
|
||||
|
||||
class KF1D:
|
||||
# this EKF assumes constant covariance matrix, so calculations are much simpler
|
||||
# the Kalman gain also needs to be precomputed using the control module
|
||||
|
||||
def __init__(self, x0, A, C, K):
|
||||
self.x = x0
|
||||
self.A = A
|
||||
self.C = np.atleast_2d(C)
|
||||
self.K = K
|
||||
|
||||
self.A_K = self.A - np.dot(self.K, self.C)
|
||||
|
||||
# K matrix needs to be pre-computed as follow:
|
||||
# import control
|
||||
# (x, l, K) = control.dare(np.transpose(self.A), np.transpose(self.C), Q, R)
|
||||
# self.K = np.transpose(K)
|
||||
|
||||
def update(self, meas):
|
||||
self.x = np.dot(self.A_K, self.x) + np.dot(self.K, meas)
|
||||
return self.x
|
|
@ -0,0 +1,87 @@
|
|||
import unittest
|
||||
import random
|
||||
import timeit
|
||||
import numpy as np
|
||||
|
||||
from common.kalman.simple_kalman import KF1D
|
||||
from common.kalman.simple_kalman_old import KF1D as KF1D_old
|
||||
|
||||
|
||||
class TestSimpleKalman(unittest.TestCase):
|
||||
def setUp(self):
|
||||
dt = 0.01
|
||||
x0_0 = 0.0
|
||||
x1_0 = 0.0
|
||||
A0_0 = 1.0
|
||||
A0_1 = dt
|
||||
A1_0 = 0.0
|
||||
A1_1 = 1.0
|
||||
C0_0 = 1.0
|
||||
C0_1 = 0.0
|
||||
K0_0 = 0.12287673
|
||||
K1_0 = 0.29666309
|
||||
|
||||
self.kf_old = KF1D_old(x0=np.array([[x0_0], [x1_0]]),
|
||||
A=np.array([[A0_0, A0_1], [A1_0, A1_1]]),
|
||||
C=np.array([C0_0, C0_1]),
|
||||
K=np.array([[K0_0], [K1_0]]))
|
||||
|
||||
self.kf = KF1D(x0=[[x0_0], [x1_0]],
|
||||
A=[[A0_0, A0_1], [A1_0, A1_1]],
|
||||
C=[C0_0, C0_1],
|
||||
K=[[K0_0], [K1_0]])
|
||||
|
||||
def test_getter_setter(self):
|
||||
self.kf.x = [[1.0], [1.0]]
|
||||
self.assertEqual(self.kf.x, [[1.0], [1.0]])
|
||||
|
||||
def update_returns_state(self):
|
||||
x = self.kf.update(100)
|
||||
self.assertEqual(x, self.kf.x)
|
||||
|
||||
def test_old_equal_new(self):
|
||||
for _ in range(1000):
|
||||
v_wheel = random.uniform(0, 200)
|
||||
|
||||
x_old = self.kf_old.update(v_wheel)
|
||||
x = self.kf.update(v_wheel)
|
||||
|
||||
# Compare the output x, verify that the error is less than 1e-4
|
||||
np.testing.assert_almost_equal(x_old[0], x[0])
|
||||
np.testing.assert_almost_equal(x_old[1], x[1])
|
||||
|
||||
def test_new_is_faster(self):
|
||||
setup = """
|
||||
import numpy as np
|
||||
|
||||
from common.kalman.simple_kalman import KF1D
|
||||
from common.kalman.simple_kalman_old import KF1D as KF1D_old
|
||||
|
||||
dt = 0.01
|
||||
x0_0 = 0.0
|
||||
x1_0 = 0.0
|
||||
A0_0 = 1.0
|
||||
A0_1 = dt
|
||||
A1_0 = 0.0
|
||||
A1_1 = 1.0
|
||||
C0_0 = 1.0
|
||||
C0_1 = 0.0
|
||||
K0_0 = 0.12287673
|
||||
K1_0 = 0.29666309
|
||||
|
||||
kf_old = KF1D_old(x0=np.array([[x0_0], [x1_0]]),
|
||||
A=np.array([[A0_0, A0_1], [A1_0, A1_1]]),
|
||||
C=np.array([C0_0, C0_1]),
|
||||
K=np.array([[K0_0], [K1_0]]))
|
||||
|
||||
kf = KF1D(x0=[[x0_0], [x1_0]],
|
||||
A=[[A0_0, A0_1], [A1_0, A1_1]],
|
||||
C=[C0_0, C0_1],
|
||||
K=[[K0_0], [K1_0]])
|
||||
"""
|
||||
kf_speed = timeit.timeit("kf.update(1234)", setup=setup, number=10000)
|
||||
kf_old_speed = timeit.timeit("kf_old.update(1234)", setup=setup, number=10000)
|
||||
self.assertTrue(kf_speed < kf_old_speed / 4)
|
||||
|
||||
if __name__ == "__main__":
|
||||
unittest.main()
|
|
@ -0,0 +1,12 @@
|
|||
class lazy_property():
|
||||
"""Defines a property whose value will be computed only once and as needed.
|
||||
|
||||
This can only be used on instance methods.
|
||||
"""
|
||||
def __init__(self, func):
|
||||
self._func = func
|
||||
|
||||
def __get__(self, obj_self, cls):
|
||||
value = self._func(obj_self)
|
||||
setattr(obj_self, self._func.__name__, value)
|
||||
return value
|
|
@ -1,13 +1,28 @@
|
|||
import io
|
||||
import os
|
||||
import sys
|
||||
import copy
|
||||
import json
|
||||
import uuid
|
||||
import socket
|
||||
import logging
|
||||
import traceback
|
||||
from threading import local
|
||||
from collections import OrderedDict
|
||||
from contextlib import contextmanager
|
||||
|
||||
def json_handler(obj):
|
||||
# if isinstance(obj, (datetime.date, datetime.time)):
|
||||
# return obj.isoformat()
|
||||
return repr(obj)
|
||||
|
||||
def json_robust_dumps(obj):
|
||||
return json.dumps(obj, default=json_handler)
|
||||
|
||||
class NiceOrderedDict(OrderedDict):
|
||||
def __str__(self):
|
||||
return json_robust_dumps(self)
|
||||
|
||||
class SwagFormatter(logging.Formatter):
|
||||
def __init__(self, swaglogger):
|
||||
logging.Formatter.__init__(self, None, '%a %b %d %H:%M:%S %Z %Y')
|
||||
|
@ -15,13 +30,8 @@ class SwagFormatter(logging.Formatter):
|
|||
self.swaglogger = swaglogger
|
||||
self.host = socket.gethostname()
|
||||
|
||||
def json_handler(self, obj):
|
||||
# if isinstance(obj, (datetime.date, datetime.time)):
|
||||
# return obj.isoformat()
|
||||
return repr(obj)
|
||||
|
||||
def format(self, record):
|
||||
record_dict = OrderedDict()
|
||||
def format_dict(self, record):
|
||||
record_dict = NiceOrderedDict()
|
||||
|
||||
if isinstance(record.msg, dict):
|
||||
record_dict['msg'] = record.msg
|
||||
|
@ -50,12 +60,60 @@ class SwagFormatter(logging.Formatter):
|
|||
record_dict['threadName'] = record.threadName
|
||||
record_dict['created'] = record.created
|
||||
|
||||
# asctime = self.formatTime(record, self.datefmt)
|
||||
return record_dict
|
||||
|
||||
return json.dumps(record_dict, default=self.json_handler)
|
||||
def format(self, record):
|
||||
if self.swaglogger is None:
|
||||
raise Exception("must set swaglogger before calling format()")
|
||||
return json_robust_dumps(self.format_dict(record))
|
||||
|
||||
_tmpfunc = lambda: 0
|
||||
_srcfile = os.path.normcase(_tmpfunc.__code__.co_filename)
|
||||
class SwagLogFileFormatter(SwagFormatter):
|
||||
def fix_kv(self, k, v):
|
||||
# append type to names to preserve legacy naming in logs
|
||||
# avoids overlapping key namespaces with different types
|
||||
# e.g. log.info() creates 'msg' -> 'msg$s'
|
||||
# log.event() creates 'msg.health.logMonoTime' -> 'msg.health.logMonoTime$i'
|
||||
# because overlapping namespace 'msg' caused problems
|
||||
if isinstance(v, (str, bytes)):
|
||||
k += "$s"
|
||||
elif isinstance(v, float):
|
||||
k += "$f"
|
||||
elif isinstance(v, bool):
|
||||
k += "$b"
|
||||
elif isinstance(v, int):
|
||||
k += "$i"
|
||||
elif isinstance(v, dict):
|
||||
nv = {}
|
||||
for ik, iv in v.items():
|
||||
ik, iv = self.fix_kv(ik, iv)
|
||||
nv[ik] = iv
|
||||
v = nv
|
||||
elif isinstance(v, list):
|
||||
k += "$a"
|
||||
return k, v
|
||||
|
||||
def format(self, record):
|
||||
if isinstance(record, str):
|
||||
v = json.loads(record)
|
||||
else:
|
||||
v = self.format_dict(record)
|
||||
|
||||
mk, mv = self.fix_kv('msg', v['msg'])
|
||||
del v['msg']
|
||||
v[mk] = mv
|
||||
v['id'] = uuid.uuid4().hex
|
||||
|
||||
return json_robust_dumps(v)
|
||||
|
||||
class SwagErrorFilter(logging.Filter):
|
||||
def filter(self, record):
|
||||
return record.levelno < logging.ERROR
|
||||
|
||||
def _tmpfunc():
|
||||
return 0
|
||||
|
||||
def _srcfile():
|
||||
return os.path.normcase(_tmpfunc.__code__.co_filename)
|
||||
|
||||
class SwagLogger(logging.Logger):
|
||||
def __init__(self):
|
||||
|
@ -66,28 +124,6 @@ class SwagLogger(logging.Logger):
|
|||
self.log_local = local()
|
||||
self.log_local.ctx = {}
|
||||
|
||||
def findCaller(self):
|
||||
"""
|
||||
Find the stack frame of the caller so that we can note the source
|
||||
file name, line number and function name.
|
||||
"""
|
||||
# f = currentframe()
|
||||
f = sys._getframe(3)
|
||||
#On some versions of IronPython, currentframe() returns None if
|
||||
#IronPython isn't run with -X:Frames.
|
||||
if f is not None:
|
||||
f = f.f_back
|
||||
rv = "(unknown file)", 0, "(unknown function)"
|
||||
while hasattr(f, "f_code"):
|
||||
co = f.f_code
|
||||
filename = os.path.normcase(co.co_filename)
|
||||
if filename in (logging._srcfile, _srcfile):
|
||||
f = f.f_back
|
||||
continue
|
||||
rv = (co.co_filename, f.f_lineno, co.co_name)
|
||||
break
|
||||
return rv
|
||||
|
||||
def local_ctx(self):
|
||||
try:
|
||||
return self.log_local.ctx
|
||||
|
@ -115,20 +151,85 @@ class SwagLogger(logging.Logger):
|
|||
self.global_ctx.update(kwargs)
|
||||
|
||||
def event(self, event_name, *args, **kwargs):
|
||||
evt = OrderedDict()
|
||||
evt = NiceOrderedDict()
|
||||
evt['event'] = event_name
|
||||
if args:
|
||||
evt['args'] = args
|
||||
evt.update(kwargs)
|
||||
self.info(evt)
|
||||
if 'error' in kwargs:
|
||||
self.error(evt)
|
||||
if 'debug' in kwargs:
|
||||
self.debug(evt)
|
||||
else:
|
||||
self.info(evt)
|
||||
|
||||
def findCaller(self, stack_info=False, stacklevel=1):
|
||||
"""
|
||||
Find the stack frame of the caller so that we can note the source
|
||||
file name, line number and function name.
|
||||
"""
|
||||
f = sys._getframe(3)
|
||||
#On some versions of IronPython, currentframe() returns None if
|
||||
#IronPython isn't run with -X:Frames.
|
||||
if f is not None:
|
||||
f = f.f_back
|
||||
orig_f = f
|
||||
while f and stacklevel > 1:
|
||||
f = f.f_back
|
||||
stacklevel -= 1
|
||||
if not f:
|
||||
f = orig_f
|
||||
rv = "(unknown file)", 0, "(unknown function)", None
|
||||
while hasattr(f, "f_code"):
|
||||
co = f.f_code
|
||||
filename = os.path.normcase(co.co_filename)
|
||||
|
||||
# TODO: is this pylint exception correct?
|
||||
if filename == _srcfile: # pylint: disable=comparison-with-callable
|
||||
f = f.f_back
|
||||
continue
|
||||
sinfo = None
|
||||
if stack_info:
|
||||
sio = io.StringIO()
|
||||
sio.write('Stack (most recent call last):\n')
|
||||
traceback.print_stack(f, file=sio)
|
||||
sinfo = sio.getvalue()
|
||||
if sinfo[-1] == '\n':
|
||||
sinfo = sinfo[:-1]
|
||||
sio.close()
|
||||
rv = (co.co_filename, f.f_lineno, co.co_name, sinfo)
|
||||
break
|
||||
return rv
|
||||
|
||||
if __name__ == "__main__":
|
||||
log = SwagLogger()
|
||||
|
||||
stdout_handler = logging.StreamHandler(sys.stdout)
|
||||
stdout_handler.setLevel(logging.INFO)
|
||||
stdout_handler.addFilter(SwagErrorFilter())
|
||||
log.addHandler(stdout_handler)
|
||||
|
||||
stderr_handler = logging.StreamHandler(sys.stderr)
|
||||
stderr_handler.setLevel(logging.ERROR)
|
||||
log.addHandler(stderr_handler)
|
||||
|
||||
log.info("asdasd %s", "a")
|
||||
log.info({'wut': 1})
|
||||
log.warning("warning")
|
||||
log.error("error")
|
||||
log.critical("critical")
|
||||
log.event("test", x="y")
|
||||
|
||||
with log.ctx():
|
||||
stdout_handler.setFormatter(SwagFormatter(log))
|
||||
stderr_handler.setFormatter(SwagFormatter(log))
|
||||
log.bind(user="some user")
|
||||
log.info("in req")
|
||||
log.event("do_req")
|
||||
print("")
|
||||
log.warning("warning")
|
||||
print("")
|
||||
log.error("error")
|
||||
print("")
|
||||
log.critical("critical")
|
||||
print("")
|
||||
log.event("do_req", a=1, b="c")
|
||||
|
|
|
@ -1,2 +1,22 @@
|
|||
def int_rnd(x):
|
||||
return int(round(x))
|
||||
|
||||
def clip(x, lo, hi):
|
||||
return max(lo, min(hi, x))
|
||||
|
||||
def interp(x, xp, fp):
|
||||
N = len(xp)
|
||||
|
||||
def get_interp(xv):
|
||||
hi = 0
|
||||
while hi < N and xv > xp[hi]:
|
||||
hi += 1
|
||||
low = hi - 1
|
||||
return fp[-1] if hi == N and xv > xp[low] else (
|
||||
fp[0] if hi == 0 else
|
||||
(xv - xp[low]) * (fp[hi] - fp[low]) / (xp[hi] - xp[low]) + fp[low])
|
||||
|
||||
return [get_interp(v) for v in x] if hasattr(x, '__iter__') else get_interp(x)
|
||||
|
||||
def mean(x):
|
||||
return sum(x) / len(x)
|
||||
|
|
|
@ -0,0 +1,22 @@
|
|||
import numpy as np
|
||||
|
||||
|
||||
def deep_interp_np(x, xp, fp, axis=None):
|
||||
if axis is not None:
|
||||
fp = fp.swapaxes(0,axis)
|
||||
x = np.atleast_1d(x)
|
||||
xp = np.array(xp)
|
||||
if len(xp) < 2:
|
||||
return np.repeat(fp, len(x), axis=0)
|
||||
if min(np.diff(xp)) < 0:
|
||||
raise RuntimeError('Bad x array for interpolation')
|
||||
j = np.searchsorted(xp, x) - 1
|
||||
j = np.clip(j, 0, len(xp)-2)
|
||||
d = np.divide(x - xp[j], xp[j + 1] - xp[j], out=np.ones_like(x, dtype=np.float64), where=xp[j + 1] - xp[j] != 0)
|
||||
vals_interp = (fp[j].T*(1 - d)).T + (fp[j + 1].T*d).T
|
||||
if axis is not None:
|
||||
vals_interp = vals_interp.swapaxes(0,axis)
|
||||
if len(vals_interp) == 1:
|
||||
return vals_interp[0]
|
||||
else:
|
||||
return vals_interp
|
|
@ -0,0 +1,24 @@
|
|||
from common.params_pyx import Params, ParamKeyType, UnknownKeyName, put_nonblocking # pylint: disable=no-name-in-module, import-error
|
||||
assert Params
|
||||
assert ParamKeyType
|
||||
assert UnknownKeyName
|
||||
assert put_nonblocking
|
||||
|
||||
if __name__ == "__main__":
|
||||
import sys
|
||||
from common.params_pyx import keys # pylint: disable=no-name-in-module, import-error
|
||||
|
||||
params = Params()
|
||||
if len(sys.argv) == 3:
|
||||
name = sys.argv[1]
|
||||
val = sys.argv[2]
|
||||
assert name.encode("utf-8") in keys.keys(), f"unknown param: {name}"
|
||||
print(f"SET: {name} = {val}")
|
||||
params.put(name, val)
|
||||
elif len(sys.argv) == 2:
|
||||
name = sys.argv[1]
|
||||
assert name.encode("utf-8") in keys.keys(), f"unknown param: {name}"
|
||||
print(f"GET: {name} = {params.get(name)}")
|
||||
else:
|
||||
for k in keys.keys():
|
||||
print(f"GET: {k} = {params.get(k)}")
|
|
@ -0,0 +1,27 @@
|
|||
from libcpp.string cimport string
|
||||
from libcpp cimport bool
|
||||
|
||||
cdef extern from "selfdrive/common/params.cc":
|
||||
pass
|
||||
|
||||
cdef extern from "selfdrive/common/util.cc":
|
||||
pass
|
||||
|
||||
cdef extern from "selfdrive/common/params.h":
|
||||
cpdef enum ParamKeyType:
|
||||
PERSISTENT
|
||||
CLEAR_ON_MANAGER_START
|
||||
CLEAR_ON_PANDA_DISCONNECT
|
||||
CLEAR_ON_IGNITION
|
||||
ALL
|
||||
|
||||
cdef cppclass Params:
|
||||
Params(bool)
|
||||
Params(string)
|
||||
string get(string, bool) nogil
|
||||
bool getBool(string)
|
||||
int remove(string)
|
||||
int put(string, string)
|
||||
int putBool(string, bool)
|
||||
bool checkKey(string)
|
||||
void clearAll(ParamKeyType)
|
|
@ -0,0 +1,108 @@
|
|||
# distutils: language = c++
|
||||
# cython: language_level = 3
|
||||
from libcpp cimport bool
|
||||
from libcpp.string cimport string
|
||||
from common.params_pxd cimport Params as c_Params, ParamKeyType as c_ParamKeyType
|
||||
|
||||
import os
|
||||
import threading
|
||||
from common.basedir import BASEDIR
|
||||
|
||||
|
||||
cdef class ParamKeyType:
|
||||
PERSISTENT = c_ParamKeyType.PERSISTENT
|
||||
CLEAR_ON_MANAGER_START = c_ParamKeyType.CLEAR_ON_MANAGER_START
|
||||
CLEAR_ON_PANDA_DISCONNECT = c_ParamKeyType.CLEAR_ON_PANDA_DISCONNECT
|
||||
CLEAR_ON_IGNITION = c_ParamKeyType.CLEAR_ON_IGNITION
|
||||
ALL = c_ParamKeyType.ALL
|
||||
|
||||
def ensure_bytes(v):
|
||||
if isinstance(v, str):
|
||||
return v.encode()
|
||||
else:
|
||||
return v
|
||||
|
||||
|
||||
class UnknownKeyName(Exception):
|
||||
pass
|
||||
|
||||
cdef class Params:
|
||||
cdef c_Params* p
|
||||
|
||||
def __cinit__(self, d=None, bool persistent_params=False):
|
||||
if d is None:
|
||||
self.p = new c_Params(persistent_params)
|
||||
else:
|
||||
self.p = new c_Params(<string>d.encode())
|
||||
|
||||
def __dealloc__(self):
|
||||
del self.p
|
||||
|
||||
def clear_all(self, tx_type=None):
|
||||
if tx_type is None:
|
||||
tx_type = ParamKeyType.ALL
|
||||
|
||||
self.p.clearAll(tx_type)
|
||||
|
||||
def check_key(self, key):
|
||||
key = ensure_bytes(key)
|
||||
|
||||
if not self.p.checkKey(key):
|
||||
raise UnknownKeyName(key)
|
||||
|
||||
return key
|
||||
|
||||
def get(self, key, block=False, encoding=None):
|
||||
cdef string k = self.check_key(key)
|
||||
cdef bool b = block
|
||||
|
||||
cdef string val
|
||||
with nogil:
|
||||
val = self.p.get(k, b)
|
||||
|
||||
if val == b"":
|
||||
if block:
|
||||
# If we got no value while running in blocked mode
|
||||
# it means we got an interrupt while waiting
|
||||
raise KeyboardInterrupt
|
||||
else:
|
||||
return None
|
||||
|
||||
if encoding is not None:
|
||||
return val.decode(encoding)
|
||||
else:
|
||||
return val
|
||||
|
||||
def get_bool(self, key):
|
||||
cdef string k = self.check_key(key)
|
||||
return self.p.getBool(k)
|
||||
|
||||
def put(self, key, dat):
|
||||
"""
|
||||
Warning: This function blocks until the param is written to disk!
|
||||
In very rare cases this can take over a second, and your code will hang.
|
||||
Use the put_nonblocking helper function in time sensitive code, but
|
||||
in general try to avoid writing params as much as possible.
|
||||
"""
|
||||
cdef string k = self.check_key(key)
|
||||
dat = ensure_bytes(dat)
|
||||
self.p.put(k, dat)
|
||||
|
||||
def put_bool(self, key, val):
|
||||
cdef string k = self.check_key(key)
|
||||
self.p.putBool(k, val)
|
||||
|
||||
def delete(self, key):
|
||||
cdef string k = self.check_key(key)
|
||||
self.p.remove(k)
|
||||
|
||||
|
||||
def put_nonblocking(key, val, d=None):
|
||||
def f(key, val):
|
||||
params = Params(d)
|
||||
cdef string k = ensure_bytes(key)
|
||||
params.put(k, val)
|
||||
|
||||
t = threading.Thread(target=f, args=(key, val))
|
||||
t.start()
|
||||
return t
|
|
@ -0,0 +1,45 @@
|
|||
import time
|
||||
|
||||
class Profiler():
|
||||
def __init__(self, enabled=False):
|
||||
self.enabled = enabled
|
||||
self.cp = {}
|
||||
self.cp_ignored = []
|
||||
self.iter = 0
|
||||
self.start_time = time.time()
|
||||
self.last_time = self.start_time
|
||||
self.tot = 0.
|
||||
|
||||
def reset(self, enabled=False):
|
||||
self.enabled = enabled
|
||||
self.cp = {}
|
||||
self.cp_ignored = []
|
||||
self.iter = 0
|
||||
self.start_time = time.time()
|
||||
self.last_time = self.start_time
|
||||
|
||||
def checkpoint(self, name, ignore=False):
|
||||
# ignore flag needed when benchmarking threads with ratekeeper
|
||||
if not self.enabled:
|
||||
return
|
||||
tt = time.time()
|
||||
if name not in self.cp:
|
||||
self.cp[name] = 0.
|
||||
if ignore:
|
||||
self.cp_ignored.append(name)
|
||||
self.cp[name] += tt - self.last_time
|
||||
if not ignore:
|
||||
self.tot += tt - self.last_time
|
||||
self.last_time = tt
|
||||
|
||||
def display(self):
|
||||
if not self.enabled:
|
||||
return
|
||||
self.iter += 1
|
||||
print("******* Profiling %d *******" % self.iter)
|
||||
for n, ms in sorted(self.cp.items(), key=lambda x: -x[1]):
|
||||
if n in self.cp_ignored:
|
||||
print("%30s: %9.2f avg: %7.2f percent: %3.0f IGNORED" % (n, ms*1000.0, ms*1000.0/self.iter, ms/self.tot*100))
|
||||
else:
|
||||
print("%30s: %9.2f avg: %7.2f percent: %3.0f" % (n, ms*1000.0, ms*1000.0/self.iter, ms/self.tot*100))
|
||||
print("Iter clock: %2.6f TOTAL: %2.2f" % (self.tot/self.iter, self.tot))
|
|
@ -1,66 +1,53 @@
|
|||
"""Utilities for reading real time clocks and keeping soft real time constraints."""
|
||||
import time
|
||||
import ctypes
|
||||
import platform
|
||||
import subprocess
|
||||
import multiprocessing
|
||||
import gc
|
||||
import os
|
||||
import time
|
||||
import multiprocessing
|
||||
|
||||
CLOCK_MONOTONIC_RAW = 4 # see <linux/time.h>
|
||||
CLOCK_BOOTTIME = 7
|
||||
|
||||
class timespec(ctypes.Structure):
|
||||
_fields_ = [
|
||||
('tv_sec', ctypes.c_long),
|
||||
('tv_nsec', ctypes.c_long),
|
||||
]
|
||||
from common.clock import sec_since_boot # pylint: disable=no-name-in-module, import-error
|
||||
from selfdrive.hardware import PC, TICI
|
||||
|
||||
|
||||
try:
|
||||
libc = ctypes.CDLL('libc.so', use_errno=True)
|
||||
except OSError:
|
||||
try:
|
||||
libc = ctypes.CDLL('libc.so.6', use_errno=True)
|
||||
except OSError:
|
||||
libc = None
|
||||
# time step for each process
|
||||
DT_CTRL = 0.01 # controlsd
|
||||
DT_MDL = 0.05 # model
|
||||
DT_TRML = 0.5 # thermald and manager
|
||||
|
||||
if libc is not None:
|
||||
libc.clock_gettime.argtypes = [ctypes.c_int, ctypes.POINTER(timespec)]
|
||||
# driver monitoring
|
||||
if TICI:
|
||||
DT_DMON = 0.05
|
||||
else:
|
||||
DT_DMON = 0.1
|
||||
|
||||
def clock_gettime(clk_id):
|
||||
if platform.system() == "darwin":
|
||||
# TODO: fix this
|
||||
return time.time()
|
||||
else:
|
||||
t = timespec()
|
||||
if libc.clock_gettime(clk_id, ctypes.pointer(t)) != 0:
|
||||
errno_ = ctypes.get_errno()
|
||||
raise OSError(errno_, os.strerror(errno_))
|
||||
return t.tv_sec + t.tv_nsec * 1e-9
|
||||
|
||||
def monotonic_time():
|
||||
return clock_gettime(CLOCK_MONOTONIC_RAW)
|
||||
class Priority:
|
||||
# CORE 2
|
||||
# - modeld = 55
|
||||
# - camerad = 54
|
||||
CTRL_LOW = 51 # plannerd & radard
|
||||
|
||||
def sec_since_boot():
|
||||
return clock_gettime(CLOCK_BOOTTIME)
|
||||
# CORE 3
|
||||
# - boardd = 55
|
||||
CTRL_HIGH = 53
|
||||
|
||||
|
||||
def set_realtime_priority(level):
|
||||
if os.getuid() != 0:
|
||||
print "not setting priority, not root"
|
||||
return
|
||||
if platform.machine() == "x86_64":
|
||||
NR_gettid = 186
|
||||
elif platform.machine() == "aarch64":
|
||||
NR_gettid = 178
|
||||
else:
|
||||
raise NotImplementedError
|
||||
|
||||
tid = libc.syscall(NR_gettid)
|
||||
subprocess.check_call(['chrt', '-f', '-p', str(level), str(tid)])
|
||||
if not PC:
|
||||
os.sched_setscheduler(0, os.SCHED_FIFO, os.sched_param(level))
|
||||
|
||||
|
||||
class Ratekeeper(object):
|
||||
def set_core_affinity(core):
|
||||
if not PC:
|
||||
os.sched_setaffinity(0, [core,])
|
||||
|
||||
|
||||
def config_realtime_process(core, priority):
|
||||
gc.disable()
|
||||
set_realtime_priority(priority)
|
||||
set_core_affinity(core)
|
||||
|
||||
|
||||
class Ratekeeper():
|
||||
def __init__(self, rate, print_delay_threshold=0.):
|
||||
"""Rate in Hz for ratekeeping. print_delay_threshold must be nonnegative."""
|
||||
self._interval = 1. / rate
|
||||
|
@ -80,15 +67,19 @@ class Ratekeeper(object):
|
|||
|
||||
# Maintain loop rate by calling this at the end of each loop
|
||||
def keep_time(self):
|
||||
self.monitor_time()
|
||||
lagged = self.monitor_time()
|
||||
if self._remaining > 0:
|
||||
time.sleep(self._remaining)
|
||||
return lagged
|
||||
|
||||
# this only monitor the cumulative lag, but does not enforce a rate
|
||||
def monitor_time(self):
|
||||
lagged = False
|
||||
remaining = self._next_frame_time - sec_since_boot()
|
||||
self._next_frame_time += self._interval
|
||||
if remaining < -self._print_delay_threshold:
|
||||
print self._process_name, "lagging by", round(-remaining * 1000, 2), "ms"
|
||||
if self._print_delay_threshold is not None and 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
|
||||
|
|
|
@ -1,82 +0,0 @@
|
|||
# TODO: these port numbers are hardcoded in c, fix this
|
||||
|
||||
# LogRotate: 8001 is a PUSH PULL socket between loggerd and visiond
|
||||
|
||||
class Service(object):
|
||||
def __init__(self, port, should_log):
|
||||
self.port = port
|
||||
self.should_log = should_log
|
||||
|
||||
# all ZMQ pub sub
|
||||
service_list = {
|
||||
# frame syncing packet
|
||||
"frame": Service(8002, True),
|
||||
# accel, gyro, and compass
|
||||
"sensorEvents": Service(8003, True),
|
||||
# GPS data, also global timestamp
|
||||
"gpsNMEA": Service(8004, True),
|
||||
# CPU+MEM+GPU+BAT temps
|
||||
"thermal": Service(8005, True),
|
||||
# List(CanData), list of can messages
|
||||
"can": Service(8006, True),
|
||||
"live100": Service(8007, True),
|
||||
# random events we want to log
|
||||
#"liveEvent": Service(8008, True),
|
||||
"model": Service(8009, True),
|
||||
"features": Service(8010, True),
|
||||
"health": Service(8011, True),
|
||||
"live20": Service(8012, True),
|
||||
#"liveUI": Service(8014, True),
|
||||
"encodeIdx": Service(8015, True),
|
||||
"liveTracks": Service(8016, True),
|
||||
"sendcan": Service(8017, True),
|
||||
"logMessage": Service(8018, True),
|
||||
"liveCalibration": Service(8019, True),
|
||||
"androidLog": Service(8020, True),
|
||||
}
|
||||
|
||||
# manager -- base process to manage starting and stopping of all others
|
||||
# subscribes: health
|
||||
# publishes: thermal
|
||||
|
||||
# boardd -- communicates with the car
|
||||
# subscribes: sendcan
|
||||
# publishes: can, health
|
||||
|
||||
# visiond -- talks to the cameras, runs the model, saves the videos
|
||||
# subscribes: liveCalibration, sensorEvents
|
||||
# publishes: frame, encodeIdx, model, features
|
||||
|
||||
# controlsd -- actually drives the car
|
||||
# subscribes: can, thermal, model, live20
|
||||
# publishes: sendcan, live100
|
||||
|
||||
# radard -- processes the radar data
|
||||
# subscribes: can, live100, model
|
||||
# publishes: live20, liveTracks
|
||||
|
||||
# sensord -- publishes the IMU and GPS
|
||||
# publishes: sensorEvents, gpsNMEA
|
||||
|
||||
# calibrationd -- places the camera box
|
||||
# subscribes: features, live100
|
||||
# publishes: liveCalibration
|
||||
|
||||
# **** LOGGING SERVICE ****
|
||||
|
||||
# loggerd
|
||||
# subscribes: EVERYTHING
|
||||
|
||||
# **** NON VITAL SERVICES ****
|
||||
|
||||
# ui
|
||||
# subscribes: live100, live20, liveCalibration, model, (raw frames)
|
||||
|
||||
# uploader
|
||||
# communicates through file system with loggerd
|
||||
|
||||
# logmessaged -- central logging service, can log to cloud
|
||||
# publishes: logMessage
|
||||
|
||||
# logcatd -- fetches logcat info from android
|
||||
# publishes: androidLog
|
|
@ -0,0 +1,52 @@
|
|||
import os
|
||||
import subprocess
|
||||
from common.basedir import BASEDIR
|
||||
|
||||
|
||||
class Spinner():
|
||||
def __init__(self):
|
||||
try:
|
||||
self.spinner_proc = subprocess.Popen(["./spinner"],
|
||||
stdin=subprocess.PIPE,
|
||||
cwd=os.path.join(BASEDIR, "selfdrive", "ui"),
|
||||
close_fds=True)
|
||||
except OSError:
|
||||
self.spinner_proc = None
|
||||
|
||||
def __enter__(self):
|
||||
return self
|
||||
|
||||
def update(self, spinner_text: str):
|
||||
if self.spinner_proc is not None:
|
||||
self.spinner_proc.stdin.write(spinner_text.encode('utf8') + b"\n")
|
||||
try:
|
||||
self.spinner_proc.stdin.flush()
|
||||
except BrokenPipeError:
|
||||
pass
|
||||
|
||||
def update_progress(self, cur: int, total: int):
|
||||
self.update(str(round(100 * cur / total)))
|
||||
|
||||
def close(self):
|
||||
if self.spinner_proc is not None:
|
||||
try:
|
||||
self.spinner_proc.stdin.close()
|
||||
except BrokenPipeError:
|
||||
pass
|
||||
self.spinner_proc.terminate()
|
||||
self.spinner_proc = None
|
||||
|
||||
def __del__(self):
|
||||
self.close()
|
||||
|
||||
def __exit__(self, exc_type, exc_value, traceback):
|
||||
self.close()
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
import time
|
||||
with Spinner() as s:
|
||||
s.update("Spinner text")
|
||||
time.sleep(5.0)
|
||||
print("gone")
|
||||
time.sleep(5.0)
|
|
@ -0,0 +1,73 @@
|
|||
import numpy as np
|
||||
|
||||
class RunningStat():
|
||||
# tracks realtime mean and standard deviation without storing any data
|
||||
def __init__(self, priors=None, max_trackable=-1):
|
||||
self.max_trackable = max_trackable
|
||||
if priors is not None:
|
||||
# initialize from history
|
||||
self.M = priors[0]
|
||||
self.S = priors[1]
|
||||
self.n = priors[2]
|
||||
self.M_last = self.M
|
||||
self.S_last = self.S
|
||||
|
||||
else:
|
||||
self.reset()
|
||||
|
||||
def reset(self):
|
||||
self.M = 0.
|
||||
self.S = 0.
|
||||
self.M_last = 0.
|
||||
self.S_last = 0.
|
||||
self.n = 0
|
||||
|
||||
def push_data(self, new_data):
|
||||
# short term memory hack
|
||||
if self.max_trackable < 0 or self.n < self.max_trackable:
|
||||
self.n += 1
|
||||
if self.n == 0:
|
||||
self.M_last = new_data
|
||||
self.M = self.M_last
|
||||
self.S_last = 0.
|
||||
else:
|
||||
self.M = self.M_last + (new_data - self.M_last) / self.n
|
||||
self.S = self.S_last + (new_data - self.M_last) * (new_data - self.M)
|
||||
self.M_last = self.M
|
||||
self.S_last = self.S
|
||||
|
||||
def mean(self):
|
||||
return self.M
|
||||
|
||||
def variance(self):
|
||||
if self.n >= 2:
|
||||
return self.S / (self.n - 1.)
|
||||
else:
|
||||
return 0
|
||||
|
||||
def std(self):
|
||||
return np.sqrt(self.variance())
|
||||
|
||||
def params_to_save(self):
|
||||
return [self.M, self.S, self.n]
|
||||
|
||||
class RunningStatFilter():
|
||||
def __init__(self, raw_priors=None, filtered_priors=None, max_trackable=-1):
|
||||
self.raw_stat = RunningStat(raw_priors, -1)
|
||||
self.filtered_stat = RunningStat(filtered_priors, max_trackable)
|
||||
|
||||
def reset(self):
|
||||
self.raw_stat.reset()
|
||||
self.filtered_stat.reset()
|
||||
|
||||
def push_and_update(self, new_data):
|
||||
_std_last = self.raw_stat.std()
|
||||
self.raw_stat.push_data(new_data)
|
||||
_delta_std = self.raw_stat.std() - _std_last
|
||||
if _delta_std <= 0:
|
||||
self.filtered_stat.push_data(new_data)
|
||||
else:
|
||||
pass
|
||||
# self.filtered_stat.push_data(self.filtered_stat.mean())
|
||||
|
||||
# class SequentialBayesian():
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue