This commit is contained in:
rusefillc 2022-08-05 12:48:09 -04:00
commit 27cc1d7aa6
414 changed files with 7925 additions and 5821 deletions

7
.github/dependabot.yml vendored Normal file
View File

@ -0,0 +1,7 @@
version: 2
updates:
- package-ecosystem: "github-actions"
directory: "/"
schedule:
interval: "daily"

View File

@ -7,11 +7,12 @@ jobs:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- uses: actions/checkout@v3
with:
submodules: recursive
- uses: actions/setup-java@v1
- uses: actions/setup-java@v3
with:
distribution: 'zulu'
java-version: '8'
- name: Test Compiler
@ -24,7 +25,7 @@ jobs:
- name: Build Native Unit Tests as shared library
working-directory: ./unit_tests/
# we have a unit test of JNI thus we need to build shared library
run: make -j4
run: make -j4 SANITIZE=no build/lib_rusefi_test
- name: Build Android
env:
@ -34,19 +35,19 @@ jobs:
if [ "${{github.event_name}}" == "push" ]; then
bash ./gradlew build
else
bash ./gradlew bundleDebug
bash ./gradlew bundleDebug test
fi
- name: Upload APK - release
if: ${{ github.event_name == 'push' }}
uses: actions/upload-artifact@v2
uses: actions/upload-artifact@v3
with:
name: rusEFI-release
path: ./android/app/build/outputs/apk/release/rusEFI-release.apk
- name: Upload APK - unsigned
if: ${{ github.event_name != 'push' }}
uses: actions/upload-artifact@v2
uses: actions/upload-artifact@v3
with:
name: rusEFI-release-unsigned
path: ./android/app/build/outputs/bundle/debug/rusEFI-debug.aab

View File

@ -23,6 +23,7 @@ jobs:
hellen72,
hellen81,
hellen88bmw,
hellen88bmw_avr,
hellen-nb1,
hellen-gm-e67,
hellenNA8_96,
@ -81,7 +82,10 @@ jobs:
- build-target: hellen88bmw
folder: hellen/hellen88bmw
ini-file: rusefi_hellen88bmw.ini
skip-rate: 90
- build-target: hellen88bmw_avr
folder: hellen/hellen88bmw
ini-file: rusefi_hellen88bmw.ini
- build-target: hellen-nb1
folder: hellen/hellen-nb1
@ -244,14 +248,15 @@ jobs:
if: ${{ matrix.skip-rate && github.event_name != 'workflow_dispatch' }}
run: if (($(($RANDOM % 100)) < ${{ matrix.skip-rate }})); then echo "skip=true" >> $GITHUB_ENV; fi
- uses: actions/checkout@v1
- uses: actions/checkout@v3
if: ${{ env.skip != 'true' }}
with:
submodules: recursive
- uses: actions/setup-java@v1
- uses: actions/setup-java@v3
if: ${{ env.skip != 'true' }}
with:
distribution: 'zulu'
java-version: '8'
- name: Install multilib, mingw, sshpass and mtools
@ -346,37 +351,44 @@ jobs:
if: ${{ github.event_name == 'push' && github.ref == 'refs/heads/master' && env.skip != 'true' }}
run: bash misc/jenkins/compile_other_versions/prepare_bundle.sh ${{matrix.build-target}} ${{matrix.ini-file}}
- name: Upload build elf
if: ${{ github.event_name != 'push' || github.ref != 'refs/heads/master' && env.skip != 'true' }}
uses: actions/upload-artifact@v3
with:
name: rusefi_${{matrix.build-target}}.elf
path: ./firmware/build/rusefi.elf
- name: Upload build bin
if: ${{ github.event_name != 'push' || github.ref != 'refs/heads/master' && env.skip != 'true' }}
uses: actions/upload-artifact@v2
uses: actions/upload-artifact@v3
with:
name: rusefi_${{matrix.build-target}}.bin
path: ./firmware/deliver/rusefi*.bin
- name: Upload build hex
if: ${{ github.event_name != 'push' || github.ref != 'refs/heads/master' && env.skip != 'true' }}
uses: actions/upload-artifact@v2
uses: actions/upload-artifact@v3
with:
name: rusefi_${{matrix.build-target}}.hex
path: ./firmware/deliver/rusefi*.hex
- name: Upload build dfu
if: ${{ github.event_name != 'push' || github.ref != 'refs/heads/master' && env.skip != 'true' }}
uses: actions/upload-artifact@v2
uses: actions/upload-artifact@v3
with:
name: rusefi_${{matrix.build-target}}.dfu
path: ./firmware/deliver/rusefi*.dfu
- name: Upload bundle
if: ${{ github.event_name == 'push' && github.ref == 'refs/heads/master' && env.skip != 'true' }}
uses: actions/upload-artifact@v2
uses: actions/upload-artifact@v3
with:
name: rusefi_bundle_${{matrix.build-target}}.zip
path: ./artifacts/rusefi_bundle*.zip
- name: Upload autoupdate bundle
if: ${{ github.event_name == 'push' && github.ref == 'refs/heads/master' && env.skip != 'true' }}
uses: actions/upload-artifact@v2
uses: actions/upload-artifact@v3
with:
name: rusefi_bundle_${{matrix.build-target}}_autoupdate.zip
path: ./artifacts/rusefi_bundle_${{matrix.build-target}}_autoupdate.zip
@ -385,11 +397,12 @@ jobs:
build-primary-bundle:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v1
- uses: actions/checkout@v3
with:
submodules: recursive
- uses: actions/setup-java@v1
- uses: actions/setup-java@v3
with:
distribution: 'zulu'
java-version: '8'
- name: Install multilib, mingw, and sshpass
@ -442,14 +455,14 @@ jobs:
- name: Attach console junit results
if: always()
uses: actions/upload-artifact@v2
uses: actions/upload-artifact@v3
with:
name: console primary junit
path: ./java_console/build/*.txt
- name: Upload primary bundle
if: ${{ github.event_name == 'push' && github.ref == 'refs/heads/master' }}
uses: actions/upload-artifact@v2
uses: actions/upload-artifact@v3
with:
name: rusefi_bundle.zip
path: ./artifacts/rusefi_bundle.zip

View File

@ -7,12 +7,13 @@ jobs:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- uses: actions/checkout@v3
with:
submodules: recursive
- uses: actions/setup-java@v1
- uses: actions/setup-java@v3
with:
distribution: 'zulu'
java-version: '8'
- name: Test Compiler
@ -22,8 +23,8 @@ jobs:
run: sudo apt-get install sshpass
- name: Generate Java (Antlr)
working-directory: ./java_tools/configuration_definition
run: ant antlr
working-directory: ./android
run: ./gradlew :config_definition:generateGrammarSource
- name: Print GCC version
working-directory: .
@ -31,8 +32,8 @@ jobs:
- name: Build Native Unit Tests as shared library
working-directory: ./unit_tests/
# we have a unit test of JNI thus we need to build shared library
run: make -j4
# we have a unit test of JNI thus we need to build shared library
run: make -j4 SANITIZE=no build/lib_rusefi_test
- name: Test console
# at the moment 'jar' task does not depend on tests?! maybe because tests take some time?
@ -45,7 +46,7 @@ jobs:
- name: Attach console junit results
if: always()
uses: actions/upload-artifact@v2
uses: actions/upload-artifact@v3
with:
name: console junit
path: ./java_console/build/*.txt

View File

@ -8,11 +8,12 @@ jobs:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v1
- uses: actions/checkout@v3
with:
submodules: recursive
- uses: actions/setup-java@v1
- uses: actions/setup-java@v3
with:
distribution: 'zulu'
java-version: '8'
- name: Install multilib
@ -43,11 +44,11 @@ jobs:
run: ./build/rusefi_simulator 10
- name: Upload built simulator
uses: actions/upload-artifact@v2
uses: actions/upload-artifact@v3
with:
name: rusefi_simulator_linux
path: ./simulator/build/rusefi_simulator
- name: Configuration Definition CI, without pushing new .jar
working-directory: ./java_tools/configuration_definition
run: ant
working-directory: ./android
run: ./gradlew :config_definition:shadowJar

View File

@ -7,11 +7,12 @@ jobs:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- uses: actions/checkout@v3
with:
submodules: recursive
- uses: actions/setup-java@v1
- uses: actions/setup-java@v3
with:
distribution: 'zulu'
java-version: '8'
- name: Test Compiler

View File

@ -11,7 +11,7 @@ jobs:
os: [ubuntu-20.04, macos-latest]
steps:
- uses: actions/checkout@v1
- uses: actions/checkout@v3
with:
submodules: recursive
fetch-depth: 0

View File

@ -10,7 +10,7 @@ jobs:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- uses: actions/checkout@v3
with:
submodules: recursive
fetch-depth: 0

View File

@ -10,7 +10,7 @@ jobs:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- uses: actions/checkout@v3
with:
submodules: recursive
fetch-depth: 0

View File

@ -9,7 +9,7 @@ jobs:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- uses: actions/checkout@v3
with:
fetch-depth: 0

View File

@ -9,7 +9,7 @@ jobs:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- uses: actions/checkout@v3
with:
submodules: recursive
fetch-depth: 0

View File

@ -10,7 +10,7 @@ jobs:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- uses: actions/checkout@v3
with:
fetch-depth: 0

View File

@ -28,7 +28,7 @@ jobs:
runs-on: ${{matrix.runs-on}}
steps:
- uses: actions/checkout@v1
- uses: actions/checkout@v3
with:
submodules: recursive
@ -74,8 +74,8 @@ jobs:
run: openocd -f "interface/stlink.cfg" -f "target/stm32f4x.cfg" -c init -c targets -c "reset halt" -c "flash erase_sector 0 0 11" -c "flash write_image "deliver/rusefi.bin" 0x08000000" -c "reset run" -c "shutdown"
- name: Generate Java (Antlr)
working-directory: ./java_tools/configuration_definition
run: ant antlr
working-directory: ./android
run: ./gradlew :config_definition:generateGrammarSource
# This both compiles and runs HW CI tests
- name: Run Hardware CI

View File

@ -17,7 +17,7 @@ jobs:
if: ${{ github.repository == 'rusefi/rusefi' }}
steps:
- uses: actions/checkout@v2
- uses: actions/checkout@v3
with:
fetch-depth: 0

View File

@ -25,7 +25,7 @@ jobs:
steps:
- name: Check out docs repo
uses: actions/checkout@v2
uses: actions/checkout@v3
with:
fetch-depth: 0
repository: rusefi/rusefi_documentation

3
.gitmodules vendored
View File

@ -45,3 +45,6 @@
path = java_console/luaformatter
url = https://github.com/rusefi/luaformatter
branch = prod
[submodule "firmware/libfirmware"]
path = firmware/libfirmware
url = https://github.com/rusefi/libfirmware.git

View File

@ -1,5 +1,6 @@
<div align="center">
<img src="https://raw.githubusercontent.com/wiki/rusefi/rusefi/Images/logo_new.png" alt="rusEFI" width="600" />
<b>GPL open-source DIY ECU</b>

View File

@ -50,7 +50,7 @@ public class DfuUpload {
mResultView.post(() -> mResultView.append("Downloaded! " + "\n"));
uncompressFile(localFullFile, localFolder, localDfuImageFileName, mResultView);
} catch (IOException | KeyManagementException | NoSuchAlgorithmException e) {
} catch (IOException e) {
mResultView.post(() -> mResultView.append("Error downloading " + e + "\n"));
}
}

View File

@ -1,10 +1,10 @@
buildscript {
repositories {
google()
jcenter()
mavenCentral()
}
dependencies {
classpath 'com.android.tools.build:gradle:4.0.0'
classpath 'com.android.tools.build:gradle:4.2.2'
}
}
@ -13,7 +13,7 @@ apply from: 'dependencies.gradle'
allprojects {
repositories {
google()
jcenter()
mavenCentral()
maven { url 'https://jitpack.io' }
}
@ -28,3 +28,8 @@ allprojects {
task clean(type: Delete) {
delete rootProject.buildDir
}
// gradlew allDeps
subprojects {
task allDeps(type: DependencyReportTask) {}
}

View File

@ -1,11 +1,14 @@
ext {
libs = [
junit : "junit:junit:4.13",
mockito : "org.mockito:mockito-all:1.10.19",
annotations : "org.jetbrains:annotations:16.0.1",
javaxJson : "javax.json:javax.json-api:1.1.4",
snakeyaml : "org.yaml:snakeyaml:1.26",
jsr305 : "com.google.code.findbugs:jsr305:3.0.2",
commons_logging: "commons-logging:commons-logging:1.2"
commons_logging: "commons-logging:commons-logging:1.2",
antlr : "org.antlr:antlr4:4.9.3", // use ANTLR version 4
json : "com.googlecode.json-simple:json-simple:1.1.1",
]
ts_plugin_libs = [

Binary file not shown.

View File

@ -1,6 +1,5 @@
#Wed Jun 24 16:34:05 EDT 2020
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-7.5-all.zip
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-6.1.1-all.zip

137
android/gradlew vendored
View File

@ -1,4 +1,20 @@
#!/usr/bin/env bash
#!/usr/bin/env sh
#
# Copyright 2015 the original author or authors.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# https://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
##############################################################################
##
@ -6,42 +22,6 @@
##
##############################################################################
# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
DEFAULT_JVM_OPTS=""
APP_NAME="Gradle"
APP_BASE_NAME=`basename "$0"`
# Use the maximum available, or set MAX_FD != -1 to use that value.
MAX_FD="maximum"
warn ( ) {
echo "$*"
}
die ( ) {
echo
echo "$*"
echo
exit 1
}
# OS specific support (must be 'true' or 'false').
cygwin=false
msys=false
darwin=false
case "`uname`" in
CYGWIN* )
cygwin=true
;;
Darwin* )
darwin=true
;;
MINGW* )
msys=true
;;
esac
# Attempt to set APP_HOME
# Resolve links: $0 may be a link
PRG="$0"
@ -60,6 +40,46 @@ cd "`dirname \"$PRG\"`/" >/dev/null
APP_HOME="`pwd -P`"
cd "$SAVED" >/dev/null
APP_NAME="Gradle"
APP_BASE_NAME=`basename "$0"`
# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"'
# Use the maximum available, or set MAX_FD != -1 to use that value.
MAX_FD="maximum"
warn () {
echo "$*"
}
die () {
echo
echo "$*"
echo
exit 1
}
# OS specific support (must be 'true' or 'false').
cygwin=false
msys=false
darwin=false
nonstop=false
case "`uname`" in
CYGWIN* )
cygwin=true
;;
Darwin* )
darwin=true
;;
MINGW* )
msys=true
;;
NONSTOP* )
nonstop=true
;;
esac
CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
# Determine the Java command to use to start the JVM.
@ -85,7 +105,7 @@ location of your Java installation."
fi
# Increase the maximum file descriptors if we can.
if [ "$cygwin" = "false" -a "$darwin" = "false" ] ; then
if [ "$cygwin" = "false" -a "$darwin" = "false" -a "$nonstop" = "false" ] ; then
MAX_FD_LIMIT=`ulimit -H -n`
if [ $? -eq 0 ] ; then
if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then
@ -105,8 +125,8 @@ if $darwin; then
GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\""
fi
# For Cygwin, switch paths to Windows format before running java
if $cygwin ; then
# For Cygwin or MSYS, switch paths to Windows format before running java
if [ "$cygwin" = "true" -o "$msys" = "true" ] ; then
APP_HOME=`cygpath --path --mixed "$APP_HOME"`
CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
JAVACMD=`cygpath --unix "$JAVACMD"`
@ -134,27 +154,30 @@ if $cygwin ; then
else
eval `echo args$i`="\"$arg\""
fi
i=$((i+1))
i=`expr $i + 1`
done
case $i in
(0) set -- ;;
(1) set -- "$args0" ;;
(2) set -- "$args0" "$args1" ;;
(3) set -- "$args0" "$args1" "$args2" ;;
(4) set -- "$args0" "$args1" "$args2" "$args3" ;;
(5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;;
(6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;;
(7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;;
(8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;;
(9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;;
0) set -- ;;
1) set -- "$args0" ;;
2) set -- "$args0" "$args1" ;;
3) set -- "$args0" "$args1" "$args2" ;;
4) set -- "$args0" "$args1" "$args2" "$args3" ;;
5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;;
6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;;
7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;;
8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;;
9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;;
esac
fi
# Split up the JVM_OPTS And GRADLE_OPTS values into an array, following the shell quoting and substitution rules
function splitJvmOpts() {
JVM_OPTS=("$@")
# Escape application args
save () {
for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done
echo " "
}
eval splitJvmOpts $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS
JVM_OPTS[${#JVM_OPTS[*]}]="-Dorg.gradle.appname=$APP_BASE_NAME"
APP_ARGS=`save "$@"`
exec "$JAVACMD" "${JVM_OPTS[@]}" -classpath "$CLASSPATH" org.gradle.wrapper.GradleWrapperMain "$@"
# Collect all arguments for the java command, following the shell quoting and substitution rules
eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS"
exec "$JAVACMD" "$@"

30
android/gradlew.bat vendored
View File

@ -1,3 +1,19 @@
@rem
@rem Copyright 2015 the original author or authors.
@rem
@rem Licensed under the Apache License, Version 2.0 (the "License");
@rem you may not use this file except in compliance with the License.
@rem You may obtain a copy of the License at
@rem
@rem https://www.apache.org/licenses/LICENSE-2.0
@rem
@rem Unless required by applicable law or agreed to in writing, software
@rem distributed under the License is distributed on an "AS IS" BASIS,
@rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
@rem See the License for the specific language governing permissions and
@rem limitations under the License.
@rem
@if "%DEBUG%" == "" @echo off
@rem ##########################################################################
@rem
@ -8,14 +24,14 @@
@rem Set local scope for the variables with windows NT shell
if "%OS%"=="Windows_NT" setlocal
@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
set DEFAULT_JVM_OPTS=
set DIRNAME=%~dp0
if "%DIRNAME%" == "" set DIRNAME=.
set APP_BASE_NAME=%~n0
set APP_HOME=%DIRNAME%
@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m"
@rem Find java.exe
if defined JAVA_HOME goto findJavaFromJavaHome
@ -46,10 +62,9 @@ echo location of your Java installation.
goto fail
:init
@rem Get command-line arguments, handling Windowz variants
@rem Get command-line arguments, handling Windows variants
if not "%OS%" == "Windows_NT" goto win9xME_args
if "%@eval[2+2]" == "4" goto 4NT_args
:win9xME_args
@rem Slurp the command line arguments.
@ -60,11 +75,6 @@ set _SKIP=2
if "x%~1" == "x" goto execute
set CMD_LINE_ARGS=%*
goto execute
:4NT_args
@rem Get arguments from the 4NT Shell from JP Software
set CMD_LINE_ARGS=%$
:execute
@rem Setup the command line

View File

@ -1,6 +1,8 @@
include ':app'
include ':shared_io'
project(':shared_io').projectDir = new File('../java_console/shared_io')
include ':shared_ui'
project(':shared_ui').projectDir = new File('../java_console/shared_ui')
include ':ecu_io'
project(':ecu_io').projectDir = new File('../java_console/io')
include ':logging'
@ -23,7 +25,9 @@ include ':enum_to_string'
project(':enum_to_string').projectDir = new File('../java_tools/enum_to_string')
include ':bin2header'
project(':bin2header').projectDir = new File('../java_tools/bin2header')
// todo: uncomment me once works include ':config_definition'
// todo: uncomment me once works project(':config_definition').projectDir = new File('../java_tools/configuration_definition')
include ':config_definition'
project(':config_definition').projectDir = new File('../java_tools/configuration_definition')
include ':ts_plugin_launcher'
project(':ts_plugin_launcher').projectDir = new File('../java_tools/ts_plugin_launcher')
include ':ts_plugin'
project(':ts_plugin').projectDir = new File('../java_tools/ts_plugin')

View File

@ -23,9 +23,36 @@ Release template (copy/paste this for new release):
# Changelog
## Unreleased
### Added
- raw voltage gauges for Lua script aux analog inputs #4346
- microRusEFI and Proteus F4 have CAN OpenBLT bootloader #4199 #4230
- counter-noise measure for custom skipped trigger wheels #4375
- Write hard faults to backup ram, print on next boot #4324
- Many more options for Lua CAN rx filters/callbacks #4387
- Password protection against tune access #4243
- Additional CAN messages #4401
### Fixed
- Lua CAN reception fixed for 11-bit IDs where the frame would be received, but a corrupt ID was passed to the handler function. #4321
- Many drop downs menues are now sorted #4339
- rusEFI TS plugin launcher fixed
- Console autoupdate error dialogs #4352
- custom skipped wheel could be located on camshaft #4377
- it's impossible to receive AcceleratorPedal sensor via CAN/Lua #4369
- MRE stepper disables LS2 control #4381
### Removed
- ICU trigger input logic since it is unused in any current ECU #639
- Idle PID "offset" field, as this role is filled more effectively by the various open loop parameters.
## July 2022 Release - "Day 130"
### Added
- verbose trigger sync should reuse engineSnifferRpmThreshold #4259
- Subaru EZ30 variation of 36/2/2/2 trigger
- Linux version of rusEFI simulator SocketCAN integration (#4312)
### Fixed
- Improved logic used to disambiguate trigger sync using cam/VVT information. Engine now runs in wasted spark until cam sync is achieved, at which point it switches to fully sequential. #4099
@ -41,7 +68,6 @@ Release template (copy/paste this for new release):
- Advanced Trigger option: require engine phase synchronization in sequential mode #4151
- Maintainability: frequency sensors need a simple event counter in the logs #4173
- TS bench test commands are now configurable #4192
- microRusEFI and Proteus F4 have CAN OpenBLT bootloader #4199
- microRusEFI can now use more pins for Cam position sensor #3032
- hard requirement for console version match #4187

@ -1 +1 @@
Subproject commit 4a81e00519e4b592176d974c37abc6249ab5294b
Subproject commit cf743886935c39cbf2ca711e54e9e64238da6e57

View File

@ -9,6 +9,10 @@ CHIBIOS = ChibiOS
RULESPATH = $(CHIBIOS)/os/common/startup/ARMCMx/compilers/GCC/mk
RULESFILE = $(RULESPATH)/rules.mk
ifneq ("$(wildcard $(../.git))","")
$(error ../.git not found. We expect source code to be cloned not downloaded as zip file.")
endif
include rusefi_rules.mk
# Define project name here
@ -23,6 +27,10 @@ PCHSUB = firmware
# Imported source files and paths
CHIBIOS_CONTRIB = ChibiOS-Contrib
# Configure libfirmware Paths/Includes
RUSEFI_LIB = $(PROJECT_DIR)/libfirmware
include $(RUSEFI_LIB)/util/util.mk
include rusefi.mk
# by default EXTRA_PARAMS is empty and we create 'debug' version of the firmware with additional assertions and statistics
@ -209,6 +217,7 @@ endif
ifeq ($(USE_OPENBLT),yes)
# Reserve start of flash for OpenBLT
USE_OPT += -Wl,--defsym=BOOTLOADER=1
DDEFS += -DEFI_USE_OPENBLT=TRUE
endif
$(info PROJECT_BOARD: $(PROJECT_BOARD))
@ -241,7 +250,8 @@ CPPSRC = \
$(HW_LAYER_DRIVERS_CORE_CPP) \
$(HW_LAYER_DRIVERS_CPP) \
$(CONSOLE_SRC_CPP) \
rusefi.cpp \
$(RUSEFI_LIB_CPP) \
rusefi.cpp \
main.cpp
# C sources to be compiled in ARM mode regardless of the global setting.
@ -266,7 +276,8 @@ TCPPSRC =
# List ASM source files here
ASMXSRC = $(ALLXASMSRC) \
$(RUSEFIASM)
$(RUSEFIASM) \
main_hardfault_asm.S
#
# WARNING! order of variables is important here - for instance cypress own folders should go before default folders
@ -279,6 +290,7 @@ INCDIR = \
$(BOOTLOADERINC) \
$(CHIBIOS)/os/various \
$(CHIBIOS)/os/hal/lib/peripherals/sensors \
$(RUSEFI_LIB_INC) \
$(CONFDIR) \
ext \
$(PROJECT_DIR)/hw_layer/mass_storage \

View File

@ -130,6 +130,10 @@ CHIBIOS = $(PROJECT_DIR)/ChibiOS
# todo: looks like 'CHIBIOS_CONTRIB' path is universal shall we defined it only once?
CHIBIOS_CONTRIB = $(CHIBIOS)/../ChibiOS-Contrib
# Configure libfirmware Paths/Includes
RUSEFI_LIB = $(PROJECT_DIR)/libfirmware
include $(RUSEFI_LIB)/util/util.mk
RULESPATH = $(CHIBIOS)/os/common/startup/ARMCMx/compilers/GCC/mk
RULESFILE = $(RULESPATH)/rules.mk
@ -187,6 +191,7 @@ CPPSRC = $(ALLCPPSRC) \
$(PROJECT_DIR)/hw_layer/io_pins.cpp \
$(PROJECT_DIR)/util/efilib.cpp \
$(PROJECT_DIR)/hw_layer/pin_repository.cpp \
$(RUSEFI_LIB_CPP) \
src/rusefi_stubs.cpp \
src/dfu.cpp \
src/main.cpp
@ -251,6 +256,7 @@ INCDIR = $(ALLINC) \
$(CONTROLLERS_INC) \
$(PROJECT_DIR)/controllers/sensors \
$(PROJECT_DIR)/init \
$(RUSEFI_LIB_INC) \
config
BUILDDIR=blbuild

View File

@ -39,9 +39,6 @@
#undef EFI_CONSOLE_RX_BRAIN_PIN
#define EFI_CONSOLE_RX_BRAIN_PIN Gpio::A10
#undef EFI_USE_OSC
#define EFI_USE_OSC TRUE
#undef EFI_CAN_SUPPORT
#define EFI_CAN_SUPPORT TRUE

View File

@ -39,9 +39,6 @@
#undef EFI_CONSOLE_RX_BRAIN_PIN
#define EFI_CONSOLE_RX_BRAIN_PIN Gpio::A10
#undef EFI_USE_OSC
#define EFI_USE_OSC TRUE
#undef EFI_CAN_SUPPORT
#define EFI_CAN_SUPPORT TRUE

View File

@ -0,0 +1 @@
https://github.com/rusefi/alphax-2chan/

View File

@ -0,0 +1 @@
https://github.com/rusefi/alphax-4chan/

View File

@ -0,0 +1 @@
https://github.com/rusefi/alphax-8chan/

View File

@ -12,8 +12,6 @@ export EXTRA_PARAMS="-DDUMMY -D__USE_CMSIS\
-DCH_DBG_THREADS_PROFILING=FALSE\
"
TRIGGER_USE_ADC = yes
export BUILDDIR="build"
export USE_FATFS="no"
export USE_BOOTLOADER="no"

View File

@ -12,7 +12,7 @@ DDEFS += -DEFI_MAIN_RELAY_CONTROL=TRUE
DDEFS += -DFIRMWARE_ID=\"hellen81hd\"
DDEFS += -DEFI_SOFTWARE_KNOCK=TRUE -DSTM32_ADC_USE_ADC3=TRUE
DDEFS += -DSTM32_PWM_USE_TIM3=TRUE -DHAL_USE_ICU=FALSE
DDEFS += -DSTM32_PWM_USE_TIM3=TRUE
include $(BOARDS_DIR)/hellen/hellen-common144.mk

View File

@ -11,6 +11,5 @@ DDEFS += -DLED_COMMUNICATION_BRAIN_PIN_MODE=INVERTED_OUTPUT
# We are running on Hellen-One hardware!
DDEFS += -DHW_HELLEN=1
DDEFS += -DEFI_USE_OSC=TRUE
DDEFS += -DTS_NO_SECONDARY=TRUE

View File

@ -94,6 +94,11 @@ void setBoardConfigOverrides() {
setupVbatt();
setHellenSdCardSpi3();
engineConfiguration->etbIo[0].directionPin1 = H144_OUT_PWM7;
engineConfiguration->etbIo[0].directionPin2 = H144_OUT_PWM6;
engineConfiguration->etbIo[0].controlPin = Gpio::D13; // ETB_EN out_pwm1
engineConfiguration->etb_use_two_wires = true;
engineConfiguration->clt.config.bias_resistor = 4700;
engineConfiguration->iat.config.bias_resistor = 4700;
}
@ -126,10 +131,6 @@ void setBoardDefaultConfiguration() {
// "required" hardware is done - set some reasonable defaults
setupDefaultSensorInputs();
engineConfiguration->etbIo[0].directionPin1 = Gpio::D15; // out_pwm7
engineConfiguration->etbIo[0].directionPin2 = Gpio::D14; // out_pwm6
engineConfiguration->etbIo[0].controlPin = Gpio::D13; // ETB_EN out_pwm1
engineConfiguration->etb_use_two_wires = true;
// Some sensible defaults for other options
setCrankOperationMode();

View File

@ -6,9 +6,13 @@
// see comments at declaration in pin_repository.h
const char * getBoardSpecificPinName(brain_pin_e brainPin) {
switch(brainPin) {
case Gpio::A0: return "P36_IN_O2S";
case Gpio::A1: return "P32_IN_O2S2";
case Gpio::A2: return "P40_IN_MAP3";
case Gpio::A3: return "C24 - PPS1";
case Gpio::A4: return "E31 - TPS1";
case Gpio::A6: return "E40 - IN_CAM";
case Gpio::A7: return "P30_IN_AUX4";
case Gpio::A8: return "P18_OUT_PP2";
case Gpio::B0: return "E34 - TPS2";
case Gpio::B1: return "E37 - Crank Input";
@ -17,6 +21,7 @@ const char * getBoardSpecificPinName(brain_pin_e brainPin) {
case Gpio::C2: return "E29 - Coolant Temp";
case Gpio::C3: return "E45 - IAT";
case Gpio::C4: return "C25 - PPS2";
case Gpio::C5: return "P41_IN_AUX3";
case Gpio::C9: return "P33_PWM5";
case Gpio::D10: return "E4 - LS4/VVT";
case Gpio::D11: return "E3 - LS3";

View File

@ -4,30 +4,33 @@ pins:
#extansion pins
#Analog inputs (via Test Points)
- pin: P30
id: EFI_ADC_7
class: analog_inputs
#PA7
id: [A7, EFI_ADC_7]
class: [switch_inputs, analog_inputs]
ts_name: P30_IN_AUX4
- pin: P32
id: EFI_ADC_1
class: analog_inputs
#PA1
id: [A1, EFI_ADC_1]
class: [switch_inputs, analog_inputs]
ts_name: P32_IN_O2S2
- pin: P36
id: EFI_ADC_0
class: analog_inputs
#PA0
id: [A0, EFI_ADC_0]
class: [switch_inputs, analog_inputs]
ts_name: P36_IN_O2S
- pin: P40
# H144_IN_MAP3 AIN15 A15 PA2
id: EFI_ADC_2
class: analog_inputs
id: [A2, EFI_ADC_2]
class: [switch_inputs, analog_inputs]
ts_name: P40_IN_MAP3
- pin: P41
# H144_IN_AUX3 AIN22 PC5
id: EFI_ADC_15
class: analog_inputs
id: [C5, EFI_ADC_15]
class: [switch_inputs, analog_inputs]
ts_name: P41_IN_AUX3
#Outputs (via Test Points)

View File

@ -1 +1 @@
https://rusefi.com/s/hellen121nissan
https://rusefi.com/s/hellen154hyundai

View File

@ -101,9 +101,10 @@ void setBoardConfigOverrides() {
setHellenSdCardSpi2();
}
engineConfiguration->etbIo[0].directionPin1 = Gpio::C7; // out_pwm3
engineConfiguration->etbIo[0].directionPin2 = Gpio::C8; // out_pwm4
engineConfiguration->etbIo[0].controlPin = Gpio::C6; // ETB_EN out_pwm2
// NB2 still uses L6205PD
engineConfiguration->etbIo[0].directionPin1 = H144_OUT_PWM3; // ETB+
engineConfiguration->etbIo[0].directionPin2 = H144_OUT_PWM4; // ETB-
engineConfiguration->etbIo[0].controlPin = H144_OUT_PWM2; // ETB_EN
engineConfiguration->etb_use_two_wires = true;
engineConfiguration->clt.config.bias_resistor = 4700;

View File

@ -9,24 +9,24 @@ DDEFS += -DEFI_MAIN_RELAY_CONTROL=TRUE
# Disable serial ports on this board as UART3 causes a DMA conflict with the SD card
DDEFS += -DTS_NO_PRIMARY
DDEFS += -DEFI_CAN_SERIAL=TRUE
# todo debug:
DDEFS += -DDISABLE_CAN_UPDATE_DASH=TRUE
# Add them all together
DDEFS += -DFIRMWARE_ID=\"hellen81\"
#DDEFS += -DEFI_SOFTWARE_KNOCK=TRUE -DSTM32_ADC_USE_ADC3=TRUE
DDEFS += -DHAL_TRIGGER_USE_ADC=TRUE
TRIGGER_USE_ADC = yes
# we need fast ADC for software trigger detector
#DDEFS += -DEFI_OVERRIDE_FAST_ADC_FOR_STM32H7=TRUE -DADC_FAST_DEVICE=ADCD1 -DADC_SLOW_DEVICE=ADCD3 -DSTM32_ADC_USE_ADC3=TRUE
#DDEFS += -DADC_FAST_DEVICE=ADCD1 -DADC_SLOW_DEVICE=ADCD3 -DSTM32_ADC_USE_ADC3=TRUE
#DDEFS += -DADC_SLOW_DEVICE=ADCD3 -DSTM32_ADC_USE_ADC3=TRUE
DDEFS += -DEFI_OVERRIDE_FAST_ADC_FOR_STM32H7=TRUE -DADC_FAST_DEVICE=ADCD1 -DEFI_USE_ONLY_FAST_ADC=TRUE -DEFI_FASTER_UNIFORM_ADC=TRUE -DADC_MAX_CHANNELS_COUNT=16 -DADC_BUF_DEPTH_FAST=1 -DADC_BUF_NUM_AVG=1
#DDEFS += -DADC_SLOW_DEVICE=ADCD1
# we probably do not need this DDEFS += -DADC_FAST_DEVICE=ADCD1
# implementation not in master as of today DDEFS += -DEFI_FASTER_UNIFORM_ADC=TRUE
# for analog VR we want to access un-averaged most raw data
# DDEFS += -DADC_BUF_DEPTH_FAST=1
# DDEFS += -DADC_BUF_NUM_AVG=1
DDEFS += -DSHORT_BOARD_NAME=hellen81

View File

@ -17,7 +17,6 @@ DDEFS += -DTS_NO_PRIMARY=1
# Add them all together
DDEFS += -DFIRMWARE_ID=\"hellen88bmw\" $(VAR_DEF_ENGINE_TYPE)
DDEFS += -DEFI_SOFTWARE_KNOCK=TRUE -DSTM32_ADC_USE_ADC3=TRUE
DDEFS += -DSHORT_BOARD_NAME=hellen88bmw

View File

@ -89,10 +89,16 @@ void setBoardConfigOverrides() {
setHellen144LedPins();
setupVbatt();
// hellen88bmw uses L6205PD
engineConfiguration->etbIo[0].directionPin1 = H144_OUT_PWM2; // ETB+
engineConfiguration->etbIo[0].directionPin2 = H144_OUT_PWM3; // ETB-
engineConfiguration->etbIo[0].controlPin = H144_OUT_PWM1; // ETB_EN
engineConfiguration->etb_use_two_wires = true;
setHellenSdCardSpi3();
engineConfiguration->clt.config.bias_resistor = 4700;
engineConfiguration->iat.config.bias_resistor = 4700;
engineConfiguration->clt.config.bias_resistor = 2700;
engineConfiguration->iat.config.bias_resistor = 2700;
}
/**
@ -124,10 +130,6 @@ void setBoardDefaultConfiguration() {
// "required" hardware is done - set some reasonable defaults
setupDefaultSensorInputs();
engineConfiguration->etbIo[0].directionPin1 = Gpio::D15; // out_pwm7
engineConfiguration->etbIo[0].directionPin2 = Gpio::D14; // out_pwm6
engineConfiguration->etbIo[0].controlPin = Gpio::D13; // ETB_EN out_pwm1
engineConfiguration->etb_use_two_wires = true;
// Some sensible defaults for other options
setCrankOperationMode();

View File

@ -1,4 +1,9 @@
#!/bin/bash
cd ..
export EXTRA_PARAMS="-DDUMMY \
-DEFI_SOFTWARE_KNOCK=TRUE -DSTM32_ADC_USE_ADC3=TRUE \
"
bash ../common_make.sh hellen/hellen88bmw ARCH_STM32F4

View File

@ -0,0 +1,12 @@
#!/bin/bash
cd ..
export EXTRA_PARAMS="-DDUMMY \
-DEFI_SOFTWARE_KNOCK=FALSE \
-DHAL_TRIGGER_USE_ADC=TRUE \
-DSTM32_ADC_USE_ADC3=TRUE \
"
bash ../common_make.sh hellen/hellen88bmw ARCH_STM32F4

View File

@ -1,6 +1,30 @@
# https://github.com/rusefi/rusefi/blob/master/firmware/config/boards/hellen/hellen_meta.h
pins:
- pin: PPS1
# H144_IN_PPS
id: EFI_ADC_3
class: analog_inputs
ts_name: PPS1
- pin: Aux PPS2
# H144_IN_AUX2
id: EFI_ADC_14
class: analog_inputs
ts_name: Aux PPS2
- pin: Aux TPS2
# H144_IN_AUX1
id: EFI_ADC_8
class: analog_inputs
ts_name: Aux TPS2
- pin: Aux TPS3
# H144_IN_AUX3
id: EFI_ADC_15
class: analog_inputs
ts_name: Aux TPS3
- pin: 1
id: G14
class: outputs
@ -152,6 +176,11 @@ pins:
function: Coil 3
type: ign
- pin: 56
id: EFI_ADC_5
class: analog_inputs
ts_name: 56 - Battery Sense
- pin: 73
id: EFI_ADC_4
class: analog_inputs

View File

@ -1,4 +1,4 @@
#define MAIN_HELP_URL "https://rusefi.com/s/hellen121nissan"
#define MAIN_HELP_URL "https://rusefi.com/s/hellen88bmw"
#define ts_show_hip9011 false
#define ts_show_cj125 false
@ -22,6 +22,7 @@
#define ts_show_sd_pins false
#define ts_show_injectionPinMode false
#define ts_show_ignitionPinMode false
#define ts_show_vbatt false
#define show_test_presets false
#define show_Frankenso_presets false

View File

@ -13,23 +13,28 @@ else
endif
# see also openblt/board.mk STATUS_LED
LED_CRITICAL_ERROR_BRAIN_PIN = -DLED_CRITICAL_ERROR_BRAIN_PIN=Gpio::E3
DDEFS += -DLED_CRITICAL_ERROR_BRAIN_PIN=Gpio::E3
# *TEMPORARY* breaking TTL thus breaking Bluetooth for microRusEFI in order to enable SPI3 for SD card
# *TODO* need to give people the horrible choice between Bluetooth via TTL or SD card via SPI :( horrible choice
EFI_CONSOLE_TTL_PINS = -DEFI_CONSOLE_TX_BRAIN_PIN=Gpio::B10 -DEFI_CONSOLE_RX_BRAIN_PIN=Gpio::B11
# PB10/PB11 uses UART3 peripheral and J12/J13 on MRE
# we also have PC10/PC11 exposed on J4 but that's same UART3
DDEFS += -DEFI_CONSOLE_TX_BRAIN_PIN=Gpio::B10 -DEFI_CONSOLE_RX_BRAIN_PIN=Gpio::B11
# on MRE 0.6.0 we have SD card on SPI2 which shared channel 3 with USART3
# todo: enable serial which would not DMA thus not conflict?
DDEFS += -DSTM32_UART_USE_USART3=FALSE -DHAL_USE_UART=FALSE
DDEFS += -DEFI_USE_UART_DMA=FALSE -DTS_NO_PRIMARY=TRUE
# maybe a way to disable SPI2 privately
#DDEFS += -DSTM32_SPI_USE_SPI2=FALSE
DDEFS += -DEFI_CAN_SERIAL=TRUE
DDEFS += -DEFI_CJ125=FALSE -DBOARD_L9779_COUNT=0 -DEFI_HD44780_LCD=FALSE -DEFI_LCD=FALSE
# Add them all together
DDEFS += -DEFI_USE_OSC=TRUE -DFIRMWARE_ID=\"microRusEFI\" $(LED_CRITICAL_ERROR_BRAIN_PIN) $(EFI_CONSOLE_TTL_PINS) -DEFI_SOFTWARE_KNOCK=TRUE -DSTM32_ADC_USE_ADC3=TRUE
DDEFS += -DFIRMWARE_ID=\"microRusEFI\"
DDEFS += -DEFI_SOFTWARE_KNOCK=TRUE -DSTM32_ADC_USE_ADC3=TRUE
DDEFS += $(VAR_DEF_ENGINE_TYPE)
# We are running on microRusEFI hardware!

View File

@ -1,5 +1,5 @@
#!/bin/bash
# export USE_OPENBLT=yes
export USE_OPENBLT=yes
bash ../common_make.sh microrusefi ARCH_STM32F4

View File

@ -5,8 +5,11 @@
SCRIPT_NAME="compile_nucleo_f767.sh"
echo "Entering $SCRIPT_NAME"
# Nucleo boards use MCO signal from St-Link and NOT oscillator - these need STM32_HSE_BYPASS
export EXTRA_PARAMS="-DDUMMY -DSTM32F767xx \
-DEFI_INJECTOR_PIN3=Gpio::Unassigned \
-DSTM32_HSE_BYPASS=TRUE \
-DFIRMWARE_ID=\\\"nucleo767\\\" \
-DEFI_COMMUNICATION_PIN=Gpio::B7 \
-DLED_CRITICAL_ERROR_BRAIN_PIN=Gpio::B14 \

View File

@ -8,7 +8,6 @@ export EXTRA_PARAMS="-DDUMMY -DSTM32F767xx \
-DEFI_COMMUNICATION_PIN=Gpio::B7 \
-DLED_CRITICAL_ERROR_BRAIN_PIN=Gpio::B14 \
-DEFI_ENABLE_ASSERTS=FALSE \
-DEFI_USE_OSC=TRUE \
-DCH_DBG_ENABLE_CHECKS=FALSE -DCH_DBG_ENABLE_ASSERTS=FALSE -DCH_DBG_ENABLE_STACK_CHECK=FALSE -DCH_DBG_FILL_THREADS=FALSE -DCH_DBG_THREADS_PROFILING=FALSE"
# Do not forget to comment out following line if looking to debug!

View File

@ -5,8 +5,11 @@
SCRIPT_NAME="compile_nucleo_h743.sh"
echo "Entering $SCRIPT_NAME"
# Nucleo boards use MCO signal from St-Link and NOT oscillator - these need STM32_HSE_BYPASS
export EXTRA_PARAMS="-DDUMMY \
-DEFI_INJECTOR_PIN3=Gpio::Unassigned \
-DSTM32_HSE_BYPASS=TRUE \
-DFIRMWARE_ID=\\\"nucleoH743\\\" \
-DEFI_COMMUNICATION_PIN=Gpio::B7 \
-DLED_CRITICAL_ERROR_BRAIN_PIN=Gpio::B14"

View File

@ -8,7 +8,6 @@ ifeq ($(PROJECT_CPU),ARCH_STM32F4)
IS_STM32F429 = yes
endif
DDEFS += -DEFI_USE_OSC=TRUE
# see also openblt/board.mk STATUS_LED
DDEFS += -DLED_CRITICAL_ERROR_BRAIN_PIN=Gpio::E3
DDEFS += -DFIRMWARE_ID=\"proteus\"

View File

@ -1,5 +1,5 @@
#!/bin/bash
# export USE_OPENBLT=yes
export USE_OPENBLT=yes
bash ../common_make.sh proteus ARCH_STM32F4

View File

@ -1,5 +1,6 @@
#!/bin/bash
# does not fit into 512K flash, and we use 512K because of st DFU client bug :(
# export USE_OPENBLT=yes
bash ../common_make.sh proteus ARCH_STM32F7

View File

@ -1,3 +1,5 @@
#!/bin/bash
# export USE_OPENBLT=yes
bash ../common_make.sh proteus ARCH_STM32H7

View File

@ -71,9 +71,6 @@
/* To remove futher possible conflict */
#undef STM32_SPI_SPI6_RX_DMA_STREAM
#undef STM32_ICU_USE_TIM3
#define STM32_ICU_USE_TIM3 TRUE
#undef STM32_CAN_USE_CAN2
#define STM32_CAN_USE_CAN2 FALSE

View File

@ -5,6 +5,8 @@
* @author Andrey Belomutskiy, (c) 2012-2021
*/
#include "pch.h"
#include "bmw_n73.h"
void setEngineProteusBMW_N73_GDI() {
@ -68,6 +70,7 @@ E90_GEAR_SELECTOR = 0x192
E90_DSC_STATUS = 0x19E
E90_DSC_SPEED = 0x1A0
E90_COOLANT = 0x1D0
E90_GEAR_SELECTOR = 0x198
E90_LOCKING = 0x2FC
E90_MSA = 0x308
E90_DASH_ON = 0x332

View File

@ -7,8 +7,6 @@
#pragma once
#include "engine_configuration.h"
void setEngineProteusBMW_N73_GDI();
void setEngineProteusGearboxManInTheMiddle();

View File

@ -788,10 +788,11 @@ void setBoschHDEV_5_injectors() {
engineConfiguration->mc33_i_boost = 13000;
engineConfiguration->mc33_i_peak = 9400;
engineConfiguration->mc33_i_hold = 3700;
engineConfiguration->mc33_t_max_boost = 470;
engineConfiguration->mc33_t_min_boost = 100;
engineConfiguration->mc33_t_max_boost = 400;
engineConfiguration->mc33_t_peak_off = 10;
engineConfiguration->mc33_t_peak_tot = 700;
engineConfiguration->mc33_t_bypass = 15;
engineConfiguration->mc33_t_bypass = 10;
engineConfiguration->mc33_t_hold_off = 60;
engineConfiguration->mc33_t_hold_tot = 10000;

View File

@ -5,8 +5,9 @@
* @author Andrey Belomutskiy, (c) 2012-2021
*/
#include "pch.h"
#include "hyundai.h"
#include "map.h"
static void commonGenesisCoupe() {
strncpy(config->luaScript, R"(

View File

@ -7,8 +7,5 @@
#pragma once
#include "engine_configuration.h"
void setGenesisCoupeBK1();
void setGenesisCoupeBK2();

View File

@ -358,7 +358,6 @@ void setMiataNA6_MAP_MRE() {
engineConfiguration->idle_derivativeFilterLoss = 0.1;
engineConfiguration->idle_antiwindupFreq = 0.1;
engineConfiguration->idleRpmPid.dFactor = 0.002;
engineConfiguration->idleRpmPid.offset = 0;
engineConfiguration->acIdleExtraOffset = 14;
engineConfiguration->idleRpmPid.minValue = -7;
engineConfiguration->idleRpmPid.maxValue = 35;

View File

@ -30,7 +30,6 @@ static void commonNA8() {
engineConfiguration->idle_derivativeFilterLoss = 0.08;
engineConfiguration->idle_antiwindupFreq = 0.03;
engineConfiguration->idleRpmPid.dFactor = 0.002;
engineConfiguration->idleRpmPid.offset = 9;
engineConfiguration->idleRpmPid.minValue = 76;
engineConfiguration->idlerpmpid_iTermMin = -15;
engineConfiguration->idlerpmpid_iTermMax = 30;

View File

@ -343,7 +343,6 @@ static void setCommonMazdaNB() {
engineConfiguration->idle_derivativeFilterLoss = 0.08;
engineConfiguration->idle_antiwindupFreq = 0.03;
engineConfiguration->idleRpmPid.dFactor = 0.002;
engineConfiguration->idleRpmPid.offset = 9;
engineConfiguration->idleRpmPid.minValue = -8;
engineConfiguration->idleRpmPid.minValue = 76;
engineConfiguration->idlerpmpid_iTermMin = -15;

View File

@ -160,9 +160,14 @@ void setProteusVwPassatB6() {
strncpy(config->luaScript, R"(
AIRBAG = 0x050
MOTOR_1 = 0x280
MOTOR_3 = 0x380
GRA = 0x388
TCU_1 = 0x440
TCU_2 = 0x540
BRAKE_2 = 0x5A0
MOTOR_INFO = 0x580
MOTOR_5 = 0x480
MOTOR_6 = 0x488
MOTOR_7 = 0x588
canRxAdd(AIRBAG)
@ -181,8 +186,7 @@ shallSleep = Timer.new()
hadIgnitionEvent = false
function onCanRx(bus, id, dlc, data)
id11 = id % 2048
if id11 == AIRBAG then
if id == AIRBAG then
-- looks like we have ignition key do not sleep!
shallSleep : reset()
hadIgnitionEvent = true
@ -203,8 +207,9 @@ function xorChecksum(data)
return data[1] ~ data[2] ~ data[3] ~ data[4] ~ data[5] ~ data[6] ~ data[7]
end
canMotor1 = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }
canMotor7 = { 0x1A, 0x66, 0x7E, 0x00, 0x00, 0x00, 0x00, 0x00 }
canMotor1 = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }
canMotorInfo = { 0x00, 0x00, 0x00, 0x14, 0x1C, 0x93, 0x48, 0x14 }
canMotor7 = { 0x1A, 0x66, 0x7E, 0x00, 0x00, 0x00, 0x00, 0x00 }
setTickRate(100)

View File

@ -69,10 +69,6 @@
#define EFI_LOGIC_ANALYZER TRUE
#endif
#ifndef EFI_ICU_INPUTS
#define EFI_ICU_INPUTS FALSE
#endif
#ifndef HAL_TRIGGER_USE_PAL
#define HAL_TRIGGER_USE_PAL TRUE
#endif /* HAL_TRIGGER_USE_PAL */
@ -175,6 +171,10 @@
#define BOARD_MC33810_COUNT 0
#endif
#ifndef BOARD_TLE9104_COUNT
#define BOARD_TLE9104_COUNT 0
#endif
#define EFI_ANALOG_SENSORS TRUE
#ifndef EFI_MAX_31855

View File

@ -38,8 +38,5 @@
// H7 runs faster "slow" ADC to make up for reduced oversampling
#define SLOW_ADC_RATE 1000
#undef EFI_ICU_INPUTS
#define EFI_ICU_INPUTS FALSE
#undef LUA_USER_HEAP
#define LUA_USER_HEAP 100000

View File

@ -1,42 +0,0 @@
/*
* FragmentEntry.cpp
*
* Created on: Jan 5, 2022
* @author Andrey Belomutskiy, (c) 2012-2022
*/
#include "pch.h"
#include "FragmentEntry.h"
void copyRange(uint8_t* destination, FragmentList src, size_t skip, size_t size) {
int fragmentIndex = 0;
// Find which fragment to start - skip any full fragments smaller than `skip` parameter
while (skip > src.fragments[fragmentIndex].size && fragmentIndex <= src.count) {
skip -= src.fragments[fragmentIndex].size;
fragmentIndex++;
}
int destinationIndex = 0;
while (size > 0) {
if (fragmentIndex >= src.count) {
// somehow we are past the end of fragments - fill with zeros
memset(destination + destinationIndex, 0, size);
return;
}
int copyNowSize = minI(size, src.fragments[fragmentIndex].size - skip);
const uint8_t* fromBase = src.fragments[fragmentIndex].data;
if (!fromBase) {
// we have no buffer for this fragment - fill with zeroes
memset(destination + destinationIndex, 0, copyNowSize);
} else {
memcpy(destination + destinationIndex, fromBase + skip, copyNowSize);
}
destinationIndex += copyNowSize;
skip = 0;
size -= copyNowSize;
fragmentIndex++;
}
}

View File

@ -1,28 +0,0 @@
/*
* FragmentEntry.h
*
* Created on: Jan 5, 2022
* @author Andrey Belomutskiy, (c) 2012-2022
*/
#pragma once
struct FragmentEntry {
template <typename TData>
FragmentEntry(const TData* data)
: data(reinterpret_cast<const uint8_t*>(data))
, size(sizeof(TData))
{
}
const uint8_t* const data;
const size_t size;
};
struct FragmentList {
const FragmentEntry* fragments;
const size_t count;
};
// copy `size` of fragmented outputs in to destination, skipping the first `skip` bytes
void copyRange(uint8_t* destination, FragmentList src, size_t skip, size_t size);

View File

@ -4,6 +4,8 @@
#include "tunerstudio.h"
#include "wideband_state_generated.h"
#include "electronic_throttle_generated.h"
#include "knock_controller_generated.h"
template<>
const output_channels_s* getLiveDataAddr() {

View File

@ -1,6 +1,6 @@
#pragma once
#include "FragmentEntry.h"
#include <rusefi/fragments.h>
template <typename TStruct>
const TStruct* getLiveDataAddr();

View File

@ -240,7 +240,9 @@ uint16_t rpmAcceleration;dRPM;"RPM/s",1, 0, 0, 5, 0
int8_t[4 iterate] autoscale vvtTargets;;"deg",1, 0, 0, 0, 0
uint16_t turboSpeed;@@GAUGE_NAME_TURBO_SPEED@@;"hz",1, 0, 0, 0, 0
! fun fact: we have a separate pid_state.txt file for a bit of a different structure huh?
struct pid_status_s
float autoscale pTerm;;"", 1, 0, -50000, 50000, 2
int16_t autoscale iTerm;;"", 0.01, 0, -327, 327, 2
int16_t autoscale dTerm;;"", 0.01, 0, -327, 327, 2
int16_t autoscale output;;"", 0.01, 0, -327, 327, 2
@ -334,5 +336,8 @@ uint16_t rpmAcceleration;dRPM;"RPM/s",1, 0, 0, 5, 0
uint16_t autoscale ISSValue;@@GAUGE_NAME_ISS@@;"RPM",1, 0, 0, 8000, 0
uint8_t[78 iterate] unusedAtTheEnd;;"",1, 0, 0, 0, 0
int16_t[AUX_ANALOG_INPUT_COUNT iterate] autoscale rawAnalogInput;;"V",{1/@@PACK_MULT_VOLTAGE@@}, 0, 0, 5, 3
uint8_t[4 iterate] autoscale gppwmOutput;GPPWM Output;"%", 0.5, 0, 0, 100, 2
uint8_t[58] unusedAtTheEnd;;"",1, 0, 0, 0, 0
end_struct

View File

@ -1,4 +1,4 @@
// this section was generated automatically by rusEFI tool ConfigDefinition.jar based on (unknown script) console/binary/output_channels.txt Wed Jun 29 03:16:45 EDT 2022
// this section was generated automatically by rusEFI tool ConfigDefinition.jar based on (unknown script) console/binary/output_channels.txt Wed Jul 27 09:37:52 UTC 2022
// by class com.rusefi.output.CHeaderConsumer
// begin
#pragma once
@ -8,25 +8,29 @@ struct pid_status_s {
/**
* offset 0
*/
scaled_channel<int16_t, 100, 1> iTerm = (int16_t)0;
/**
* offset 2
*/
scaled_channel<int16_t, 100, 1> dTerm = (int16_t)0;
scaled_channel<float, 1, 1> pTerm = (float)0;
/**
* offset 4
*/
scaled_channel<int16_t, 100, 1> output = (int16_t)0;
scaled_channel<int16_t, 100, 1> iTerm = (int16_t)0;
/**
* offset 6
*/
scaled_channel<int16_t, 100, 1> error = (int16_t)0;
scaled_channel<int16_t, 100, 1> dTerm = (int16_t)0;
/**
* offset 8
*/
scaled_channel<int16_t, 100, 1> output = (int16_t)0;
/**
* offset 10
*/
scaled_channel<int16_t, 100, 1> error = (int16_t)0;
/**
* offset 12
*/
uint32_t resetCounter = (uint32_t)0;
};
static_assert(sizeof(pid_status_s) == 12);
static_assert(sizeof(pid_status_s) == 16);
// start of output_channels_s
struct output_channels_s {
@ -1253,41 +1257,52 @@ struct output_channels_s {
*/
pid_status_s alternatorStatus;
/**
* offset 452
* offset 456
*/
pid_status_s idleStatus;
/**
* offset 464
* offset 472
*/
pid_status_s etbStatus;
/**
* offset 476
* offset 488
*/
pid_status_s boostStatus;
/**
* aux speed 1
s
* offset 488
* offset 504
*/
uint16_t auxSpeed1 = (uint16_t)0;
/**
* aux speed 2
s
* offset 490
* offset 506
*/
uint16_t auxSpeed2 = (uint16_t)0;
/**
* @@GAUGE_NAME_ISS@@
RPM
* offset 492
* offset 508
*/
scaled_channel<uint16_t, 1, 1> ISSValue = (uint16_t)0;
/**
* offset 494
V
* offset 510
*/
uint8_t unusedAtTheEnd[78];
scaled_channel<int16_t, 1000, 1> rawAnalogInput[AUX_ANALOG_INPUT_COUNT];
/**
* GPPWM Output
%
* offset 526
*/
scaled_channel<uint8_t, 2, 1> gppwmOutput[4];
/**
* offset 530
*/
uint8_t unusedAtTheEnd[58];
};
static_assert(sizeof(output_channels_s) == 572);
static_assert(sizeof(output_channels_s) == 588);
// end
// this section was generated automatically by rusEFI tool ConfigDefinition.jar based on (unknown script) console/binary/output_channels.txt Wed Jun 29 03:16:45 EDT 2022
// this section was generated automatically by rusEFI tool ConfigDefinition.jar based on (unknown script) console/binary/output_channels.txt Wed Jul 27 09:37:52 UTC 2022

View File

@ -12,7 +12,6 @@
#include "pch.h"
#include "os_access.h"
#include "crc.h"
#if EFI_UNIT_TEST
#define PRINT printf
@ -70,6 +69,9 @@ int CanStreamerState::sendFrame(const IsoTpFrameHeader & header, const uint8_t *
offset = 3;
maxNumBytes = 0; // no data is sent with 'flow control' frame
break;
default:
// bad frame type
return 0;
}
int numBytes = minI(maxNumBytes, num);
@ -119,6 +121,9 @@ int CanStreamerState::receiveFrame(CANRxFrame *rxmsg, uint8_t *buf, int num, can
case ISO_TP_FRAME_FLOW_CONTROL:
// todo: currently we just ignore the FC frame
return 0;
default:
// bad frame type
return 0;
}
#if defined(TS_CAN_DEVICE_SHORT_PACKETS_IN_ONE_FRAME)

View File

@ -31,12 +31,10 @@ typedef struct __attribute__ ((packed)) {
* Engine idles around 20Hz and revs up to 140Hz, at 60/2 and 8 cylinders we have about 20Khz events
* If we can read buffer at 50Hz we want buffer to be about 400 elements.
*/
static composite_logger_s buffer[COMPOSITE_PACKET_COUNT] CCM_OPTIONAL;
static composite_logger_s *ptr_buffer_first = &buffer[0];
static composite_logger_s *ptr_buffer_second = &buffer[(COMPOSITE_PACKET_COUNT/2)-1];
static size_t NextIdx = 0;
static_assert(sizeof(composite_logger_s) == COMPOSITE_PACKET_SIZE, "composite packet size");
static volatile bool ToothLoggerEnabled = false;
static volatile bool firstBuffer = true;
static uint32_t lastEdgeTimestamp = 0;
static bool currentTrigger1 = false;
@ -47,28 +45,54 @@ static bool currentCoilState = false;
// same about injectors
static bool currentInjectorState = false;
int getCompositeRecordCount() {
return NextIdx;
}
#if EFI_UNIT_TEST
#include "logicdata.h"
int copyCompositeEvents(CompositeEvent *events) {
for (size_t i = 0; i < NextIdx; i++) {
CompositeEvent *event = &events[i];
event->timestamp = SWAP_UINT32(buffer[i].timestamp);
event->primaryTrigger = buffer[i].priLevel;
event->secondaryTrigger = buffer[i].secLevel;
event->isTDC = buffer[i].trigger;
event->sync = buffer[i].sync;
event->coil = buffer[i].coil;
event->injector = buffer[i].injector;
}
return NextIdx;
static std::vector<CompositeEvent> events;
const std::vector<CompositeEvent>& getCompositeEvents() {
return events;
}
#endif // EFI_UNIT_TEST
void SetNextCompositeEntry(efitick_t timestamp) {
CompositeEvent event;
event.timestamp = timestamp;
event.primaryTrigger = currentTrigger1;
event.secondaryTrigger = currentTrigger2;
event.isTDC = currentTdc;
event.sync = engine->triggerCentral.triggerState.getShaftSynchronized();
event.coil = currentCoilState;
event.injector = currentInjectorState;
events.push_back(event);
}
void EnableToothLogger() {
ToothLoggerEnabled = true;
events.clear();
}
void DisableToothLogger() {
ToothLoggerEnabled = false;
}
#else // not EFI_UNIT_TEST
static constexpr size_t bufferCount = 4;
static constexpr size_t entriesPerBuffer = COMPOSITE_PACKET_COUNT / bufferCount;
struct CompositeBuffer {
composite_logger_s buffer[entriesPerBuffer];
size_t nextIdx;
Timer startTime;
};
static CompositeBuffer buffers[bufferCount] CCM_OPTIONAL;
static chibios_rt::Mailbox<CompositeBuffer*, bufferCount> freeBuffers CCM_OPTIONAL;
static chibios_rt::Mailbox<CompositeBuffer*, bufferCount> filledBuffers CCM_OPTIONAL;
static CompositeBuffer* currentBuffer = nullptr;
static void setToothLogReady(bool value) {
#if EFI_TUNER_STUDIO && (EFI_PROD_CODE || EFI_SIMULATOR)
@ -76,36 +100,137 @@ static void setToothLogReady(bool value) {
#endif // EFI_TUNER_STUDIO
}
void EnableToothLogger() {
chibios_rt::CriticalSectionLocker csl;
// Reset all buffers
for (size_t i = 0; i < efi::size(buffers); i++) {
buffers[i].nextIdx = 0;
}
// Reset state
currentBuffer = nullptr;
// Empty the filled buffer list
CompositeBuffer* dummy;
while (MSG_TIMEOUT != filledBuffers.fetchI(&dummy)) ;
// Put all buffers in the free list
for (size_t i = 0; i < efi::size(buffers); i++) {
freeBuffers.postI(&buffers[i]);
}
// Reset the last edge to now - this prevents the first edge logged from being bogus
lastEdgeTimestamp = getTimeNowUs();
// Enable logging of edges as they come
ToothLoggerEnabled = true;
setToothLogReady(false);
}
void DisableToothLogger() {
ToothLoggerEnabled = false;
setToothLogReady(false);
}
expected<ToothLoggerBuffer> GetToothLoggerBuffer() {
chibios_rt::CriticalSectionLocker csl;
CompositeBuffer* buffer;
msg_t msg = filledBuffers.fetchI(&buffer);
if (msg == MSG_TIMEOUT) {
setToothLogReady(false);
return unexpected;
}
if (msg != MSG_OK) {
// What even happened if we didn't get timeout, but also didn't get OK?
return unexpected;
}
size_t entryCount = buffer->nextIdx;
buffer->nextIdx = 0;
// Return this buffer to the free list
msg = freeBuffers.postI(buffer);
efiAssert(OBD_PCM_Processor_Fault, msg == MSG_OK, "Composite logger post to free buffer fail", unexpected);
// If the used list is empty, clear the ready flag
if (filledBuffers.getUsedCountI() == 0) {
setToothLogReady(false);
}
return ToothLoggerBuffer{ reinterpret_cast<uint8_t*>(buffer->buffer), entryCount * sizeof(composite_logger_s)};
}
static CompositeBuffer* findBuffer(efitick_t timestamp) {
CompositeBuffer* buffer;
if (!currentBuffer) {
// try and find a buffer, if none available, we can't log
if (MSG_OK != freeBuffers.fetchI(&buffer)) {
return nullptr;
}
// Record the time of the last buffer swap so we can force a swap after a minimum period of time
// This ensures the user sees *something* even if they don't have enough trigger events
// to fill the buffer.
buffer->startTime.reset(timestamp);
currentBuffer = buffer;
}
return currentBuffer;
}
static void SetNextCompositeEntry(efitick_t timestamp) {
// This is called from multiple interrupts/threads, so we need a lock.
chibios_rt::CriticalSectionLocker csl;
CompositeBuffer* buffer = findBuffer(timestamp);
if (!buffer) {
// All buffers are full, nothing to do here.
return;
}
composite_logger_s* entry = &buffer->buffer[buffer->nextIdx];
uint32_t nowUs = NT2US(timestamp);
// TS uses big endian, grumble
buffer[NextIdx].timestamp = SWAP_UINT32(nowUs);
buffer[NextIdx].priLevel = currentTrigger1;
buffer[NextIdx].secLevel = currentTrigger2;
buffer[NextIdx].trigger = currentTdc;
buffer[NextIdx].sync = engine->triggerCentral.triggerState.getShaftSynchronized();
buffer[NextIdx].coil = currentCoilState;
buffer[NextIdx].injector = currentInjectorState;
entry->timestamp = SWAP_UINT32(nowUs);
entry->priLevel = currentTrigger1;
entry->secLevel = currentTrigger2;
entry->trigger = currentTdc;
entry->sync = engine->triggerCentral.triggerState.getShaftSynchronized();
entry->coil = currentCoilState;
entry->injector = currentInjectorState;
NextIdx++;
buffer->nextIdx++;
static_assert(sizeof(composite_logger_s) == COMPOSITE_PACKET_SIZE, "composite packet size");
// if the buffer is full...
bool bufferFull = buffer->nextIdx >= efi::size(buffer->buffer);
// ... or it's been too long since the last flush
bool bufferTimedOut = buffer->startTime.hasElapsedSec(5);
//If we hit the end, loop
if ((firstBuffer) && (NextIdx >= (COMPOSITE_PACKET_COUNT/2))) {
/* first half is full */
// Then cycle buffers and set the ready flag.
if (bufferFull || bufferTimedOut) {
// Post to the output queue
filledBuffers.postI(buffer);
// Null the current buffer so we get a new one next time
currentBuffer = nullptr;
// Flag that we are ready
setToothLogReady(true);
firstBuffer = false;
}
if ((!firstBuffer) && (NextIdx >= sizeof(buffer) / sizeof(buffer[0]))) {
setToothLogReady(true);
NextIdx = 0;
firstBuffer = true;
}
}
#endif // EFI_UNIT_TEST
void LogTriggerTooth(trigger_event_e tooth, efitick_t timestamp) {
// bail if we aren't enabled
if (!ToothLoggerEnabled) {
@ -184,43 +309,10 @@ void LogTriggerInjectorState(efitick_t timestamp, bool state) {
//SetNextCompositeEntry(timestamp, trigger1, trigger2, trigger);
}
void EnableToothLogger() {
// Clear the buffer
memset(buffer, 0, sizeof(buffer));
// Reset the last edge to now - this prevents the first edge logged from being bogus
lastEdgeTimestamp = getTimeNowUs();
// Reset write index
NextIdx = 0;
// Enable logging of edges as they come
ToothLoggerEnabled = true;
setToothLogReady(false);
}
void EnableToothLoggerIfNotEnabled() {
if (!ToothLoggerEnabled) {
EnableToothLogger();
}
}
void DisableToothLogger() {
ToothLoggerEnabled = false;
setToothLogReady(false);
}
ToothLoggerBuffer GetToothLoggerBuffer() {
// tell TS that we do not have data until we have data again
setToothLogReady(false);
if (firstBuffer) {
return { reinterpret_cast<uint8_t*>(ptr_buffer_second), (sizeof(buffer)/2) };
} else {
return { reinterpret_cast<uint8_t*>(ptr_buffer_first), (sizeof(buffer)/2) };
}
}
#endif /* EFI_TOOTH_LOGGER */

View File

@ -11,11 +11,9 @@
#if EFI_UNIT_TEST
#include "logicdata.h"
int copyCompositeEvents(CompositeEvent *events);
const std::vector<CompositeEvent>& getCompositeEvents();
#endif // EFI_UNIT_TEST
int getCompositeRecordCount();
void EnableToothLoggerIfNotEnabled();
// Enable the tooth logger - this clears the buffer starts logging
@ -40,4 +38,5 @@ struct ToothLoggerBuffer
};
// Get a reference to the buffer
ToothLoggerBuffer GetToothLoggerBuffer();
// Returns unexpected if no buffer is available
expected<ToothLoggerBuffer> GetToothLoggerBuffer();

View File

@ -102,7 +102,7 @@ struct CanTsThread : public TunerstudioThread {
static CanTsThread canTsThread;
void startCanConsole() {
canTsThread.Start();
canTsThread.start();
canStreamInit();
}

View File

@ -71,7 +71,6 @@
#include "tunerstudio_io.h"
#include "malfunction_central.h"
#include "console_io.h"
#include "crc.h"
#include "bluetooth.h"
#include "tunerstudio_io.h"
#include "tooth_logger.h"
@ -101,6 +100,8 @@ static void printErrorCounters() {
/* 1S */
#define TS_COMMUNICATION_TIMEOUT TIME_MS2I(1000)
/* 10mS when receiving byte by byte */
#define TS_COMMUNICATION_TIMEOUT_SHORT TIME_MS2I(10)
static efitimems_t previousWriteReportMs = 0;
@ -173,6 +174,10 @@ extern bool rebootForPresetPending;
void TunerStudio::handleWriteChunkCommand(TsChannelBase* tsChannel, ts_response_format_e mode, uint16_t offset, uint16_t count,
void *content) {
tsState.writeChunkCommandCounter++;
if (isLockedFromUser()) {
sendErrorCode(tsChannel, TS_RESPONSE_UNRECOGNIZED_COMMAND);
return;
}
efiPrintf("WRITE CHUNK mode=%d o=%d s=%d", mode, offset, count);
@ -214,6 +219,10 @@ void TunerStudio::handleWriteValueCommand(TsChannelBase* tsChannel, ts_response_
UNUSED(mode);
tsState.writeValueCommandCounter++;
if (isLockedFromUser()) {
sendErrorCode(tsChannel, TS_RESPONSE_UNRECOGNIZED_COMMAND);
return;
}
tunerStudioDebug(tsChannel, "got W (Write)"); // we can get a lot of these
@ -249,7 +258,14 @@ void TunerStudio::handlePageReadCommand(TsChannelBase* tsChannel, ts_response_fo
return;
}
const uint8_t* addr = getWorkingPageAddr() + offset;
uint8_t* addr;
if (isLockedFromUser()) {
// to have rusEFI console happy just send all zeros within a valid packet
addr = (uint8_t*)&tsChannel->scratchBuffer + SCRATCH_BUFFER_PREFIX_SIZE;
memset(addr, 0, count);
} else {
addr = getWorkingPageAddr() + offset;
}
tsChannel->sendResponse(mode, addr, count);
#if EFI_TUNER_STUDIO_VERBOSE
// efiPrintf("Sending %d done", count);
@ -405,7 +421,7 @@ static int tsProcessOne(TsChannelBase* tsChannel) {
tsState.totalCounter++;
uint8_t firstByte;
int received = tsChannel->readTimeout(&firstByte, 1, TS_COMMUNICATION_TIMEOUT);
size_t received = tsChannel->readTimeout(&firstByte, 1, TS_COMMUNICATION_TIMEOUT);
#if EFI_SIMULATOR
logMsg("received %d\r\n", received);
#endif
@ -417,6 +433,7 @@ static int tsProcessOne(TsChannelBase* tsChannel) {
// assume there's connection loss and notify the bluetooth init code
bluetoothSoftwareDisconnectNotify();
#endif /* EFI_BLUETOOTH_SETUP */
tsChannel->in_sync = false;
return -1;
}
@ -425,66 +442,93 @@ static int tsProcessOne(TsChannelBase* tsChannel) {
}
uint8_t secondByte;
received = tsChannel->readTimeout(&secondByte, 1, TS_COMMUNICATION_TIMEOUT);
/* second byte should be received within minimal delay */
received = tsChannel->readTimeout(&secondByte, 1, TS_COMMUNICATION_TIMEOUT_SHORT);
if (received != 1) {
tunerStudioError(tsChannel, "TS: ERROR: no second byte");
tsChannel->in_sync = false;
return -1;
}
uint16_t incomingPacketSize = firstByte << 8 | secondByte;
size_t expectedSize = incomingPacketSize + CRC_VALUE_SIZE;
if (incomingPacketSize == 0 || incomingPacketSize > (sizeof(tsChannel->scratchBuffer) - CRC_WRAPPING_SIZE)) {
efiPrintf("process_ts: channel=%s invalid size: %d", tsChannel->name, incomingPacketSize);
tunerStudioError(tsChannel, "process_ts: ERROR: CRC header size");
sendErrorCode(tsChannel, TS_RESPONSE_UNDERRUN);
if (incomingPacketSize == 0 || expectedSize > sizeof(tsChannel->scratchBuffer)) {
if (tsChannel->in_sync) {
efiPrintf("process_ts: channel=%s invalid size: %d", tsChannel->name, incomingPacketSize);
tunerStudioError(tsChannel, "process_ts: ERROR: CRC header size");
/* send error only if previously we were in sync */
sendErrorCode(tsChannel, TS_RESPONSE_UNDERRUN);
}
tsChannel->in_sync = false;
return -1;
}
received = tsChannel->readTimeout((uint8_t* )tsChannel->scratchBuffer, 1, TS_COMMUNICATION_TIMEOUT);
if (received != 1) {
tunerStudioError(tsChannel, "ERROR: did not receive command");
sendErrorCode(tsChannel, TS_RESPONSE_UNDERRUN);
return -1;
}
char command;
if (tsChannel->in_sync) {
/* we are in sync state, packet size should be correct so lets receive full packet and then check if command is supported
* otherwise (if abort reception in middle of packet) it will break syncronization and cause error on next packet */
received = tsChannel->readTimeout((uint8_t*)(tsChannel->scratchBuffer), expectedSize, TS_COMMUNICATION_TIMEOUT);
command = tsChannel->scratchBuffer[0];
char command = tsChannel->scratchBuffer[0];
if (!isKnownCommand(command)) {
efiPrintf("unexpected command %x", command);
sendErrorCode(tsChannel, TS_RESPONSE_UNRECOGNIZED_COMMAND);
return -1;
if (received != expectedSize) {
/* print and send error as we were in sync */
efiPrintf("Got only %d bytes while expecting %d for command %c", received,
expectedSize, command);
tunerStudioError(tsChannel, "ERROR: not enough bytes in stream");
sendErrorCode(tsChannel, TS_RESPONSE_UNDERRUN);
tsChannel->in_sync = false;
return -1;
}
if (!isKnownCommand(command)) {
/* print and send error as we were in sync */
efiPrintf("unexpected command %x", command);
sendErrorCode(tsChannel, TS_RESPONSE_UNRECOGNIZED_COMMAND);
tsChannel->in_sync = false;
return -1;
}
} else {
/* receive only command byte to check if it is supported */
received = tsChannel->readTimeout((uint8_t*)(tsChannel->scratchBuffer), 1, TS_COMMUNICATION_TIMEOUT_SHORT);
command = tsChannel->scratchBuffer[0];
if (!isKnownCommand(command)) {
/* do not report any error as we are not in sync */
return -1;
}
received = tsChannel->readTimeout((uint8_t*)(tsChannel->scratchBuffer) + 1, expectedSize - 1, TS_COMMUNICATION_TIMEOUT);
if (received != expectedSize - 1) {
/* do not report any error as we are not in sync */
return -1;
}
}
#if EFI_SIMULATOR
logMsg("command %c\r\n", command);
logMsg("command %c\r\n", command);
#endif
int expectedSize = incomingPacketSize + CRC_VALUE_SIZE - 1;
received = tsChannel->readTimeout((uint8_t*)(tsChannel->scratchBuffer + 1), expectedSize, TS_COMMUNICATION_TIMEOUT);
if (received != expectedSize) {
efiPrintf("Got only %d bytes while expecting %d for command %c", received,
expectedSize, command);
tunerStudioError(tsChannel, "ERROR: not enough bytes in stream");
sendErrorCode(tsChannel, TS_RESPONSE_UNDERRUN);
return -1;
}
uint32_t expectedCrc = *(uint32_t*) (tsChannel->scratchBuffer + incomingPacketSize);
expectedCrc = SWAP_UINT32(expectedCrc);
uint32_t actualCrc = crc32(tsChannel->scratchBuffer, incomingPacketSize);
if (actualCrc != expectedCrc) {
efiPrintf("TunerStudio: CRC %x %x %x %x", tsChannel->scratchBuffer[incomingPacketSize + 0],
tsChannel->scratchBuffer[incomingPacketSize + 1], tsChannel->scratchBuffer[incomingPacketSize + 2],
tsChannel->scratchBuffer[incomingPacketSize + 3]);
efiPrintf("TunerStudio: command %c actual CRC %x/expected %x", tsChannel->scratchBuffer[0],
actualCrc, expectedCrc);
tunerStudioError(tsChannel, "ERROR: CRC issue");
sendErrorCode(tsChannel, TS_RESPONSE_CRC_FAILURE);
/* send error only if previously we were in sync */
if (tsChannel->in_sync) {
efiPrintf("TunerStudio: command %c actual CRC %x/expected %x", tsChannel->scratchBuffer[0],
actualCrc, expectedCrc);
tunerStudioError(tsChannel, "ERROR: CRC issue");
sendErrorCode(tsChannel, TS_RESPONSE_CRC_FAILURE);
tsChannel->in_sync = false;
}
return -1;
}
/* we were able to receive known command with correct crc and size! */
tsChannel->in_sync = true;
int success = tsInstance.handleCrcCommand(tsChannel, tsChannel->scratchBuffer, incomingPacketSize);
if (!success) {
@ -565,8 +609,6 @@ void TunerStudio::handleExecuteCommand(TsChannelBase* tsChannel, char *data, int
tsChannel->writeCrcPacket(TS_RESPONSE_COMMAND_OK, nullptr, 0);
}
static int transmitted = 0;
int TunerStudio::handleCrcCommand(TsChannelBase* tsChannel, char *data, int incomingPacketSize) {
ScopePerf perf(PE::TunerStudioHandleCrcCommand);
@ -658,41 +700,19 @@ int TunerStudio::handleCrcCommand(TsChannelBase* tsChannel, char *data, int inco
sendOkResponse(tsChannel, TS_CRC);
break;
case TS_GET_COMPOSITE_BUFFER_DONE_DIFFERENTLY:
{
EnableToothLoggerIfNotEnabled();
const uint8_t* const buffer = GetToothLoggerBuffer().Buffer;
const uint8_t* const start = buffer + COMPOSITE_PACKET_SIZE * transmitted;
int currentEnd = getCompositeRecordCount();
// set debug_mode 40
if (engineConfiguration->debugMode == DBG_COMPOSITE_LOG) {
engine->outputChannels.debugIntField1 = currentEnd;
engine->outputChannels.debugIntField2 = transmitted;
}
if (currentEnd > transmitted) {
// more normal case - tail after head
tsChannel->sendResponse(TS_CRC, start, COMPOSITE_PACKET_SIZE * (currentEnd - transmitted), true);
transmitted = currentEnd;
} else if (currentEnd == transmitted) {
tsChannel->sendResponse(TS_CRC, start, 0);
} else {
// we are here if tail of buffer has reached the end of buffer and re-started from the start of buffer
// sending end of the buffer, next transmission would take care of the rest
tsChannel->sendResponse(TS_CRC, start, COMPOSITE_PACKET_SIZE * (COMPOSITE_PACKET_COUNT - transmitted), true);
transmitted = 0;
}
}
break;
case TS_GET_COMPOSITE_BUFFER_DONE_DIFFERENTLY:
EnableToothLoggerIfNotEnabled();
// falls through
case TS_GET_LOGGER_GET_BUFFER:
{
auto toothBuffer = GetToothLoggerBuffer();
tsChannel->sendResponse(TS_CRC, toothBuffer.Buffer, toothBuffer.Length, true);
if (toothBuffer) {
tsChannel->sendResponse(TS_CRC, toothBuffer.Value.Buffer, toothBuffer.Value.Length, true);
} else {
// TS asked for a tooth logger buffer, but we don't have one to give it.
sendErrorCode(tsChannel, TS_RESPONSE_OUT_OF_RANGE);
}
}
break;

View File

@ -8,9 +8,6 @@
#pragma once
#include "global.h"
#include "tunerstudio_io.h"
#include "electronic_throttle_generated.h"
#include "knock_controller_generated.h"
#include "FragmentEntry.h"
typedef struct {
int queryCommandCounter;
@ -44,18 +41,7 @@ void requestBurn(void);
void startTunerStudioConnectivity(void);
#if defined __GNUC__
// GCC
#define pre_packed
#define post_packed __attribute__((packed))
#else
// IAR
#define pre_packed __packed
#define post_packed
#endif
typedef pre_packed struct
post_packed {
typedef struct {
short int offset;
short int count;
} TunerStudioWriteChunkRequest;

View File

@ -6,7 +6,6 @@ TUNERSTUDIO_SRC_CPP = $(PROJECT_DIR)/console/binary/tunerstudio_io.cpp \
$(PROJECT_DIR)/console/binary/ts_can_channel.cpp \
$(PROJECT_DIR)/console/binary/serial_can.cpp \
$(PROJECT_DIR)/console/binary/tunerstudio.cpp \
$(PROJECT_DIR)/console/binary/FragmentEntry.cpp \
$(PROJECT_DIR)/console/binary/tunerstudio_commands.cpp \
$(PROJECT_DIR)/console/binary/bluetooth.cpp \
$(PROJECT_DIR)/console/binary/signature.cpp

View File

@ -26,8 +26,12 @@ public:
bool handlePlainCommand(TsChannelBase* tsChannel, uint8_t command);
void cmdOutputChannels(TsChannelBase* tsChannel, uint16_t offset, uint16_t count) override;
/**
* this command is part of protocol initialization
*/
void handleQueryCommand(TsChannelBase* tsChannel, ts_response_format_e mode);
void handleExecuteCommand(TsChannelBase* tsChannel, char *data, int incomingPacketSize);
// does more or less nothing, we only handle the command to make frontend application happy
void handlePageSelectCommand(TsChannelBase *tsChannel, ts_response_format_e mode);
void handleWriteChunkCommand(TsChannelBase* tsChannel, ts_response_format_e mode, uint16_t offset, uint16_t count,
void *content);

View File

@ -22,8 +22,6 @@ size_t TsChannelBase::read(uint8_t* buffer, size_t size) {
#define isBigPacket(size) ((size) > BLOCKING_FACTOR + 7)
void TsChannelBase::copyAndWriteSmallCrcPacket(uint8_t responseCode, const uint8_t* buf, size_t size) {
auto scratchBuffer = this->scratchBuffer;
// don't transmit too large a buffer
efiAssertVoid(OBD_PCM_Processor_Fault, !isBigPacket(size), "copyAndWriteSmallCrcPacket tried to transmit too large a packet")
@ -32,7 +30,7 @@ void TsChannelBase::copyAndWriteSmallCrcPacket(uint8_t responseCode, const uint8
// tsOutputChannels) during the CRC computation. Instead compute the CRC on our
// local buffer that nobody else will write.
if (size) {
memcpy(scratchBuffer + 3, buf, size);
memcpy(scratchBuffer + SCRATCH_BUFFER_PREFIX_SIZE, buf, size);
}
crcAndWriteBuffer(responseCode, size);
@ -41,7 +39,6 @@ void TsChannelBase::copyAndWriteSmallCrcPacket(uint8_t responseCode, const uint8
void TsChannelBase::crcAndWriteBuffer(uint8_t responseCode, size_t size) {
efiAssertVoid(OBD_PCM_Processor_Fault, !isBigPacket(size), "crcAndWriteBuffer tried to transmit too large a packet")
auto scratchBuffer = this->scratchBuffer;
// Index 0/1 = packet size (big endian)
*(uint16_t*)scratchBuffer = SWAP_UINT16(size + 1);
// Index 2 = response code
@ -51,7 +48,7 @@ void TsChannelBase::crcAndWriteBuffer(uint8_t responseCode, size_t size) {
uint32_t crc = crc32(&scratchBuffer[2], size + 1); // command part of CRC
// Place the CRC at the end
*reinterpret_cast<uint32_t*>(&scratchBuffer[size + 3]) = SWAP_UINT32(crc);
*reinterpret_cast<uint32_t*>(&scratchBuffer[size + SCRATCH_BUFFER_PREFIX_SIZE]) = SWAP_UINT32(crc);
// Write to the underlying stream
write(reinterpret_cast<uint8_t*>(scratchBuffer), size + 7, true);

View File

@ -30,6 +30,8 @@
#include "pin_repository.h"
#endif
#define SCRATCH_BUFFER_PREFIX_SIZE 3
class TsChannelBase {
public:
TsChannelBase(const char *name);
@ -62,6 +64,18 @@ public:
void crcAndWriteBuffer(uint8_t responseCode, size_t size);
void copyAndWriteSmallCrcPacket(uint8_t responseCode, const uint8_t* buf, size_t size);
/* When TsChannel is in "not in sync" state tsProcessOne will silently try to find
* begining of packet.
* As soon as tsProcessOne was able to receive valid packet with valid size and crc
* TsChannel becomes "in sync". That means it will react on any futher errors: it will
* emit packet with error code and switch back to "not in sync" mode.
* This insures that RE will send only one error message after lost of syncronization
* with TS.
* Also while in "not in sync" state - tsProcessOne will not try to receive whole packet
* by one read. Instead after getting packet size it will try to receive one byte of
* command and check if it is supported. */
bool in_sync = false;
private:
void writeCrcPacketLarge(uint8_t responseCode, const uint8_t* buf, size_t size);
};

View File

@ -93,12 +93,12 @@ void startSerialChannels() {
#if HAS_PRIMARY
// todo: invert setting one day?
if (!engineConfiguration->disablePrimaryUart) {
primaryChannelThread.Start();
primaryChannelThread.start();
}
#endif
#if HAS_SECONDARY
secondaryChannelThread.Start();
secondaryChannelThread.start();
#endif
}

View File

@ -7,7 +7,6 @@
#include "binary_logging.h"
#include "log_field.h"
#include "crc.h"
#include "buffered_writer.h"
#define TIME_PRECISION 1000

View File

@ -110,4 +110,8 @@ static constexpr LogField fields[] = {
{engine->outputChannels.auxLinear2, GAUGE_NAME_AUX_LINEAR_2, "", 2},
{engine->outputChannels.boostControllerOutput, GAUGE_NAME_BOOST_OUTPUT, "%", 1},
{engine->outputChannels.boostControllerOpenLoopPart, GAUGE_NAME_BOOST_OPEN_LOOP, "%", 1},
{engine->outputChannels.gppwmOutput[0], "GPPWM Output 1", "%", 1},
{engine->outputChannels.gppwmOutput[1], "GPPWM Output 2", "%", 1},
{engine->outputChannels.gppwmOutput[2], "GPPWM Output 3", "%", 1},
{engine->outputChannels.gppwmOutput[3], "GPPWM Output 4", "%", 1},
};

View File

@ -98,7 +98,7 @@ void startEthernetConsole() {
efiSetPadMode("ethernet", Gpio::G14, PAL_MODE_ALTERNATE(0xb));
#endif // STM32H7
ethernetConsole.Start();
ethernetConsole.start();
}
#endif // EFI_ETHERNET

View File

@ -67,8 +67,6 @@ extern bool main_loop_started;
#include "max31855.h"
#include "single_timer_executor.h"
#include "periodic_task.h"
extern int icuRisingCallbackCounter;
extern int icuFallingCallbackCounter;
#endif /* EFI_PROD_CODE */
#if EFI_CJ125
@ -114,7 +112,7 @@ static void setWarningEnabled(int value) {
#if EFI_FILE_LOGGING
// this one needs to be in main ram so that SD card SPI DMA works fine
static NO_CACHE char sdLogBuffer[220];
static NO_CACHE char sdLogBuffer[250];
static uint64_t binaryLogCount = 0;
void writeLogLine(Writer& buffer) {
@ -475,33 +473,33 @@ extern HIP9011 instance;
static void updateTempSensors() {
SensorResult clt = Sensor::get(SensorType::Clt);
engine->outputChannels.coolant = clt.Value;
engine->outputChannels.coolant = clt.value_or(0);
engine->outputChannels.isCltError = !clt.Valid;
SensorResult iat = Sensor::get(SensorType::Iat);
engine->outputChannels.intake = iat.Value;
engine->outputChannels.intake = iat.value_or(0);
engine->outputChannels.isIatError = !iat.Valid;
SensorResult auxTemp1 = Sensor::get(SensorType::AuxTemp1);
engine->outputChannels.auxTemp1 = auxTemp1.Value;
engine->outputChannels.auxTemp1 = auxTemp1.value_or(0);
SensorResult auxTemp2 = Sensor::get(SensorType::AuxTemp2);
engine->outputChannels.auxTemp2 = auxTemp2.Value;
engine->outputChannels.auxTemp2 = auxTemp2.value_or(0);
}
static void updateThrottles() {
SensorResult tps1 = Sensor::get(SensorType::Tps1);
engine->outputChannels.TPSValue = tps1.Value;
engine->outputChannels.TPSValue = tps1.value_or(0);
engine->outputChannels.isTpsError = !tps1.Valid;
engine->outputChannels.tpsADC = convertVoltageTo10bitADC(Sensor::getRaw(SensorType::Tps1Primary));
SensorResult tps2 = Sensor::get(SensorType::Tps2);
engine->outputChannels.TPS2Value = tps2.Value;
engine->outputChannels.TPS2Value = tps2.value_or(0);
// If we don't have a TPS2 at all, don't turn on the failure light
engine->outputChannels.isTps2Error = !tps2.Valid && Sensor::hasSensor(SensorType::Tps2Primary);
SensorResult pedal = Sensor::get(SensorType::AcceleratorPedal);
engine->outputChannels.throttlePedalPosition = pedal.Value;
engine->outputChannels.throttlePedalPosition = pedal.value_or(0);
// Only report fail if you have one (many people don't)
engine->outputChannels.isPedalError = !pedal.Valid && Sensor::hasSensor(SensorType::AcceleratorPedalPrimary);
@ -527,11 +525,11 @@ static void updateLambda() {
static void updateFuelSensors() {
// Low pressure is directly in kpa
engine->outputChannels.lowFuelPressure = Sensor::get(SensorType::FuelPressureLow).Value;
engine->outputChannels.lowFuelPressure = Sensor::getOrZero(SensorType::FuelPressureLow);
// High pressure is in bar, aka 100 kpa
engine->outputChannels.highFuelPressure = KPA2BAR(Sensor::get(SensorType::FuelPressureHigh).Value);
engine->outputChannels.highFuelPressure = KPA2BAR(Sensor::getOrZero(SensorType::FuelPressureHigh));
engine->outputChannels.flexPercent = Sensor::get(SensorType::FuelEthanolPercent).Value;
engine->outputChannels.flexPercent = Sensor::getOrZero(SensorType::FuelEthanolPercent);
engine->outputChannels.fuelTankLevel = Sensor::getOrZero(SensorType::FuelLevel);
}
@ -571,16 +569,23 @@ static void updateRawSensors() {
engine->outputChannels.rawWastegatePosition = Sensor::getRaw(SensorType::WastegatePosition);
engine->outputChannels.rawIdlePositionSensor = Sensor::getRaw(SensorType::IdlePosition);
for (int i = 0;i<AUX_ANALOG_INPUT_COUNT;i++) {
adc_channel_e ch = engineConfiguration->auxAnalogInputs[i];
if (ch != EFI_ADC_NONE) {
engine->outputChannels.rawAnalogInput[i] = getVoltageDivided("raw aux", ch);
}
}
// TODO: transition AFR to new sensor model
engine->outputChannels.rawAfr = (engineConfiguration->afr.hwChannel == EFI_ADC_NONE) ? 0 : getVoltageDivided("ego", engineConfiguration->afr.hwChannel);
}
static void updatePressures() {
engine->outputChannels.baroPressure = Sensor::getOrZero(SensorType::BarometricPressure);
engine->outputChannels.MAPValue = Sensor::getOrZero(SensorType::Map);
engine->outputChannels.oilPressure = Sensor::get(SensorType::OilPressure).Value;
engine->outputChannels.oilPressure = Sensor::getOrZero(SensorType::OilPressure);
engine->outputChannels.auxLinear1 = Sensor::get(SensorType::AuxLinear1).Value;
engine->outputChannels.auxLinear2 = Sensor::get(SensorType::AuxLinear2).Value;
engine->outputChannels.auxLinear1 = Sensor::getOrZero(SensorType::AuxLinear1);
engine->outputChannels.auxLinear2 = Sensor::getOrZero(SensorType::AuxLinear2);
}
static void updateMiscSensors() {
@ -710,7 +715,7 @@ static void updateTpsDebug() {
void updateTunerStudioState() {
TunerStudioOutputChannels *tsOutputChannels = &engine->outputChannels;
#if EFI_SHAFT_POSITION_INPUT
int rpm = Sensor::get(SensorType::Rpm).Value;
int rpm = Sensor::get(SensorType::Rpm).value_or(0);
#else /* EFI_SHAFT_POSITION_INPUT */
int rpm = 0;
#endif /* EFI_SHAFT_POSITION_INPUT */
@ -853,9 +858,6 @@ void updateTunerStudioState() {
break;
}
case DBG_TRIGGER_COUNTERS:
#if EFI_PROD_CODE && HAL_USE_ICU == TRUE
tsOutputChannels->debugFloatField3 = icuRisingCallbackCounter + icuFallingCallbackCounter;
#endif /* EFI_PROD_CODE */
#if EFI_SHAFT_POSITION_INPUT
tsOutputChannels->debugIntField4 = engine->triggerCentral.triggerState.currentCycle.eventCount[0];
@ -932,10 +934,10 @@ void startStatusThreads(void) {
// todo: refactoring needed, this file should probably be split into pieces
#if EFI_PROD_CODE
initStatusLeds();
communicationsBlinkingTask.Start();
communicationsBlinkingTask.start();
#endif /* EFI_PROD_CODE */
#if EFI_LCD
lcdInstance.Start();
lcdInstance.start();
#endif /* EFI_LCD */
}

View File

@ -51,7 +51,7 @@ struct UsbThread : public TunerstudioThread {
static UsbThread usbConsole;
void startUsbConsole() {
usbConsole.Start();
usbConsole.start();
}
#endif // EFI_USB_SERIAL

View File

@ -28,6 +28,12 @@ void BoostController::init(IPwm* pwm, const ValueProvider3D* openLoopMap, const
m_closedLoopTargetMap = closedLoopTargetMap;
m_pid.initPidClass(pidParams);
resetLua();
}
void BoostController::resetLua() {
luaTargetAdd = 0;
luaTargetMult = 1;
}
void BoostController::onConfigurationChange(pid_s* previousConfiguration) {
@ -60,7 +66,7 @@ expected<float> BoostController::getSetpoint() {
efiAssert(OBD_PCM_Processor_Fault, m_closedLoopTargetMap != nullptr, "boost closed loop target", unexpected);
return m_closedLoopTargetMap->getValue(rpm, tps.Value);
return m_closedLoopTargetMap->getValue(rpm, tps.Value) * luaTargetMult + luaTargetAdd;
}
expected<percent_t> BoostController::getOpenLoop(float target) {
@ -152,7 +158,16 @@ void BoostController::update() {
m_pid.iTermMin = -50;
m_pid.iTermMax = 50;
ClosedLoopController::update();
bool rpmTooLow = Sensor::getOrZero(SensorType::Rpm) < engineConfiguration->boostControlMinRpm;
bool tpsTooLow = Sensor::getOrZero(SensorType::Tps1) < engineConfiguration->boostControlMinTps;
bool mapTooLow = Sensor::getOrZero(SensorType::Map) < engineConfiguration->boostControlMinMap;
if (rpmTooLow || tpsTooLow || mapTooLow) {
// Passing unexpected will use the safe duty cycle configured by the user
setOutput(unexpected);
} else {
ClosedLoopController::update();
}
}
static bool hasInitBoost = false;

View File

@ -17,6 +17,7 @@ class BoostController : public boost_control_s, public ClosedLoopController<floa
public:
void init(IPwm* pmw, const ValueProvider3D* openLoopMap, const ValueProvider3D* closedLoopTargetMap, pid_s* pidParams);
void update();
void resetLua();
// Called when the configuration may have changed. Controller will
// reset if necessary.

View File

@ -6,8 +6,8 @@ bit isBelowClosedLoopThreshold;
bit isNotClosedLoop;
bit isZeroRpm
float loadTargetAdd
float loadTargetMult
float luaTargetAdd
float luaTargetMult
float openLoopPart;
int8_t autoscale boostControllerClosedLoopPart;@@GAUGE_NAME_BOOST_CLOSED_LOOP@@;"%", 0.5, 0, -50, 50, 1

View File

@ -1,4 +1,4 @@
// this section was generated automatically by rusEFI tool ConfigDefinition.jar based on (unknown script) controllers/actuators/boost_control.txt Wed Jun 29 22:23:02 EDT 2022
// this section was generated automatically by rusEFI tool ConfigDefinition.jar based on (unknown script) controllers/actuators/boost_control.txt Thu Jul 14 13:56:19 UTC 2022
// by class com.rusefi.output.CHeaderConsumer
// begin
#pragma once
@ -104,11 +104,11 @@ struct boost_control_s {
/**
* offset 4
*/
float loadTargetAdd = (float)0;
float luaTargetAdd = (float)0;
/**
* offset 8
*/
float loadTargetMult = (float)0;
float luaTargetMult = (float)0;
/**
* offset 12
*/
@ -135,4 +135,4 @@ struct boost_control_s {
static_assert(sizeof(boost_control_s) == 20);
// end
// this section was generated automatically by rusEFI tool ConfigDefinition.jar based on (unknown script) controllers/actuators/boost_control.txt Wed Jun 29 22:23:02 EDT 2022
// this section was generated automatically by rusEFI tool ConfigDefinition.jar based on (unknown script) controllers/actuators/boost_control.txt Thu Jul 14 13:56:19 UTC 2022

View File

@ -196,7 +196,7 @@ bool EtbController::init(etb_function_e function, DcMotor *motor, pid_s *pidPara
if (!Sensor::isRedundant(m_positionSensor)) {
firmwareError(
OBD_Throttle_Position_Sensor_Circuit_Malfunction,
OBD_TPS_Configuration,
"Use of electronic throttle requires %s to be redundant.",
Sensor::getSensorName(m_positionSensor)
);
@ -206,7 +206,7 @@ bool EtbController::init(etb_function_e function, DcMotor *motor, pid_s *pidPara
if (!Sensor::isRedundant(SensorType::AcceleratorPedal)) {
firmwareError(
OBD_Throttle_Position_Sensor_Circuit_Malfunction,
OBD_TPS_Configuration,
"Use of electronic throttle requires accelerator pedal to be redundant."
);
@ -318,13 +318,16 @@ expected<percent_t> EtbController::getSetpointEtb() {
// 100% target from table -> 100% target position
idlePosition = interpolateClamped(0, etbIdleAddition, 100, 100, etbCurrentTarget);
percent_t targetPosition = idlePosition + luaAdjustment;
percent_t targetPosition = idlePosition + getLuaAdjustment();
// Apply any adjustment that this throttle alone needs
// Clamped to +-10 to prevent anything too wild
trim = clampF(-10, getThrottleTrim(rpm, targetPosition), 10);
targetPosition += trim;
// Clamp before rev limiter to avoid ineffective rev limit due to crazy out of range position target
targetPosition = clampF(0, targetPosition, 100);
// Lastly, apply ETB rev limiter
auto etbRpmLimit = engineConfiguration->etbRevLimitStart;
if (etbRpmLimit != 0) {
@ -361,6 +364,21 @@ expected<percent_t> EtbController::getSetpointEtb() {
return targetPosition;
}
void EtbController::setLuaAdjustment(float adjustment) {
luaAdjustment = adjustment;
m_luaAdjustmentTimer.reset();
}
float EtbController::getLuaAdjustment() const {
// If the lua position hasn't been set in 0.2 second, don't adjust!
// This avoids a stuck throttle due to hung/rogue/etc Lua script
if (m_luaAdjustmentTimer.getElapsedSeconds() > 0.2f) {
return 0;
} else {
return luaAdjustment;
}
}
percent_t EtbController2::getThrottleTrim(float /*rpm*/, percent_t /*targetPosition*/) const {
// TODO: implement me #3680
return 0;
@ -632,7 +650,7 @@ struct EtbImpl final : public TBase {
// Check that the calibrate actually moved the throttle
if (absF(primaryMax - primaryMin) < 0.5f) {
firmwareError(OBD_Throttle_Position_Sensor_Circuit_Malfunction, "Auto calibrate failed, check your wiring!\r\nClosed voltage: %.1fv Open voltage: %.1fv", primaryMin, primaryMax);
firmwareError(OBD_TPS_Configuration, "Auto calibrate failed, check your wiring!\r\nClosed voltage: %.1fv Open voltage: %.1fv", primaryMin, primaryMax);
TBase::m_isAutocal = false;
return;
}
@ -668,7 +686,7 @@ static EtbImpl<EtbController1> etb1;
static EtbImpl<EtbController2> etb2;
static_assert(ETB_COUNT == 2);
EtbController* etbControllers[] = { &etb1, &etb2 };
static EtbController* etbControllers[] = { &etb1, &etb2 };
struct EtbThread final : public PeriodicController<512> {
EtbThread() : PeriodicController("ETB", PRIO_ETB, ETB_LOOP_FREQUENCY) {}
@ -990,7 +1008,7 @@ void doInitElectronicThrottle() {
#endif /* EFI_UNIT_TEST */
#if !EFI_UNIT_TEST
etbThread.Start();
etbThread.start();
#endif
}
@ -1029,6 +1047,14 @@ void setEtbWastegatePosition(percent_t pos) {
}
}
void setEtbLuaAdjustment(percent_t pos) {
for (int i = 0; i < ETB_COUNT; i++) {
if (auto etb = engine->etbControllers[i]) {
etb->setLuaAdjustment(pos);
}
}
}
void set18919_AM810_pedal_position_sensor() {
engineConfiguration->throttlePedalUpVoltage = 0.1;
engineConfiguration->throttlePedalWOTVoltage = 4.5;

View File

@ -15,6 +15,7 @@ void doInitElectronicThrottle();
void setEtbIdlePosition(percent_t pos);
void setEtbWastegatePosition(percent_t pos);
void setEtbLuaAdjustment(percent_t adjustment);
void setHitachiEtbCalibration();
// these two sensors use same plug but have different calibrations and even rotate in different directions
@ -54,4 +55,6 @@ public:
virtual void autoCalibrateTps() = 0;
virtual const pid_state_s* getPidState() const = 0;
virtual void setLuaAdjustment(percent_t adjustment) = 0;
};

View File

@ -66,6 +66,10 @@ public:
return 0;
}
// Lua throttle adjustment
void setLuaAdjustment(percent_t adjustment) override;
float getLuaAdjustment() const;
protected:
// This is set if an automatic TPS calibration should be run
bool m_isAutocal = false;
@ -103,6 +107,8 @@ private:
uint8_t m_autotuneCounter = 0;
uint8_t m_autotuneCurrentParam = 0;
Timer m_luaAdjustmentTimer;
};
class EtbController1 : public EtbController { };

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