This commit is contained in:
John Plusje 2019-08-17 16:21:31 +02:00
commit 4823d54b2d
40 changed files with 2223 additions and 1746 deletions

1
.gitignore vendored
View File

@ -12,6 +12,7 @@ reference/hardware/v0.2/~$schematic v0.2_bom.xlsx
reference/hardware/v0.4/gerbers/Archive.zip
.pioenvs
.pio
.piolibdeps
.clang_complete
.gcc-flags.json

View File

@ -46,11 +46,12 @@ before_install:
- sudo apt-get update -qq
# - sudo apt-get install -t trusty-backports cppcheck
- sudo apt-get build-dep -qq cppcheck
- wget https://github.com/danmar/cppcheck/archive/1.79.zip
- unzip 1.79.zip
- cd cppcheck-1.79
# - make SRCDIR=build CFGDIR=/usr/share/cppcheck/ HAVE_RULES=yes
- sudo make install CFGDIR=/usr/share/cppcheck/ HAVE_RULES=yes
# - wget https://github.com/danmar/cppcheck/archive/1.79.zip
# - unzip 1.79.zip
# - cd cppcheck-1.79
# - git clone --depth=10 https://github.com/noisymime/cppcheck.git
# - cd cppcheck
# - sudo make install CFGDIR=/usr/share/cppcheck/ HAVE_RULES=yes
# Requirements for doxygen
- sudo apt-get install doxygen graphviz
@ -59,19 +60,20 @@ install:
script:
- cd /home/travis/build
- git clone --depth=20 https://github.com/noisymime/cppcheck.git noisymime/cppcheck
- cd noisymime/speeduino
- git clone --depth=10 https://github.com/noisymime/cppcheck.git noisymime/cppcheck_github
- cd noisymime/cppcheck_github
- make
- cd ../speeduino
- platformio update
# - platformio run -e megaatmega2560 -e teensy35 -e bluepill_f103c8 -e genericSTM32F103RB
# Run the builds
- platformio run -e megaatmega2560 -e teensy35 -e genericSTM32F103RB
- platformio run -e megaatmega2560 -e teensy35
# Upload ini and hex files to speeduino.com server
- curl --user "speeduino_firmware@speeduino.com:$WEB_PWD" --basic -T "./.pioenvs/megaatmega2560/firmware.hex" "https://speeduino.com:2078/bin/master.hex"
- curl --user "speeduino_firmware@speeduino.com:$WEB_PWD" --basic -T "./reference/speeduino.ini" "https://speeduino.com:2078/master.ini"
# Begin MISRA scan
- cd ..
- chmod +x speeduino/misra/check_misra.sh
- speeduino/misra/check_misra.sh
- chmod +x speeduino/misra/check_misra_github.sh
- speeduino/misra/check_misra_github.sh
# Do doxygen run and upload to gh-pages server.
- cd speeduino
- doxygen
@ -88,5 +90,5 @@ notifications:
env:
global:
secure: "L6pyVQKCkOJNPBEbx6pEln+QnGyntouZW1tGSqOysgRFmUOdXH8l+DKq0YwW+civ0yWrF91G5YkWmyAE1jkoDLy7TBOt8Iqq/xAmf+BHIqDl/+uNsVxgvZ6+gqwMeoWBfmo0vmRj3/wY7ZmepNe2jKop/DX2olhBgmRdCKp8nA+SX8/pc2tO7DZeSsbCP0+JozvVhFtQMNwzkVp4llmER2yGr+u5pTTOz4eXCEkEKUCZMZ6JhvPKCDm+7tUQSS4NvShizj7QZIjqxvINQPi9i1TGJRoPTlQqYNGfTHufU3/W7nsUWFdtrZRapLZuKN/ktOr5T0ydQriNlDpBoIWXJvHzZrBjyT2arzz7jw57QZ8Yhyhetdw+zIfBepLEp7nKZGjR3eeWGtRzj8RRIgw19MT+8g2l7a1gKte+L01o4y8RKfQCqt/2PcVelIUv3X08JVOE6q7PumBEUSAkk1ITE80Y8SYoQda62gehH06xloSWJvU79tIC0drWMO+hGvj4LTpoe9ujMYTxkwGjiIfx9I9jButAN0vI2MtcDyVR+9XuKwZc9nFf4z4HR8xav1NmrzEAy0OVsOdjpM3OxAnVzTUo4M0c11dt9sDP7xR3TgwgSs2ptNOamujRFqrONHnn6VglOnWuypfvJfBxfovuRP1+UZoHIH7sbiMXmX/3nyA="
secure: "LKvIikE69mmD2yroQ84KFfrCw9sCU6o4zDqdGQM3mFKVi/Tuiyskvk3KMbf5Rxwt6Fy2OhdvitxG1ckbpccdTNlEbef7DtBdjNd5Oh72GseBCwToNTinFCVpJbj2AWceDykSDsaxzZMg3ienXwZ5XB3ClyUi6N+8MLwpsX4kJuGNfOY3z6yC+JQSvuVhIb1zDRYDKAHDuabzo38sk8q/WhBEVvL95lzPHoxMEpaQfwyjZ4lLhDbqe9/y7s7M9bjz1K9AXHS6h5fIWGVKVzL8YKoOVi6Na6vcnS8w7YNr71AMr0d7H0nM9gG6Fy4DDyUsfa9SBhLVxMWbEPe9+eJNZ0MkuwI/6eaxiqnqAcMfFyvw1bwBGCi4+x0+9riwpOYE21q3Mq/XbTKdvI7YG4RPfd2X4Xe6hOVPW/5iEICZdxrpLdyDN7suZX7Y8POcBeJgi6HkdKXfDO6NlCV+Fnmwx/FltHILX2GNASob/o2/dVkPNh3NjxVqgwN9OxyzNQefWC3z1W3YgBwTWc3VkuiuE0eTEkBX5aSGTGZWqysz4U42/7M+MiSC80VpMbsFNd1FEGZR75Y644q+aUHLGNWIK01dslxZUiUEh5CkdOHTqpeHVszJyCblTtIBAXyBhZfnbdOBxpPsZGg2U+iSUSOzXW2W11e52ARhpi0QlnvhdkI="
- secure: "L6pyVQKCkOJNPBEbx6pEln+QnGyntouZW1tGSqOysgRFmUOdXH8l+DKq0YwW+civ0yWrF91G5YkWmyAE1jkoDLy7TBOt8Iqq/xAmf+BHIqDl/+uNsVxgvZ6+gqwMeoWBfmo0vmRj3/wY7ZmepNe2jKop/DX2olhBgmRdCKp8nA+SX8/pc2tO7DZeSsbCP0+JozvVhFtQMNwzkVp4llmER2yGr+u5pTTOz4eXCEkEKUCZMZ6JhvPKCDm+7tUQSS4NvShizj7QZIjqxvINQPi9i1TGJRoPTlQqYNGfTHufU3/W7nsUWFdtrZRapLZuKN/ktOr5T0ydQriNlDpBoIWXJvHzZrBjyT2arzz7jw57QZ8Yhyhetdw+zIfBepLEp7nKZGjR3eeWGtRzj8RRIgw19MT+8g2l7a1gKte+L01o4y8RKfQCqt/2PcVelIUv3X08JVOE6q7PumBEUSAkk1ITE80Y8SYoQda62gehH06xloSWJvU79tIC0drWMO+hGvj4LTpoe9ujMYTxkwGjiIfx9I9jButAN0vI2MtcDyVR+9XuKwZc9nFf4z4HR8xav1NmrzEAy0OVsOdjpM3OxAnVzTUo4M0c11dt9sDP7xR3TgwgSs2ptNOamujRFqrONHnn6VglOnWuypfvJfBxfovuRP1+UZoHIH7sbiMXmX/3nyA="
- secure: "LKvIikE69mmD2yroQ84KFfrCw9sCU6o4zDqdGQM3mFKVi/Tuiyskvk3KMbf5Rxwt6Fy2OhdvitxG1ckbpccdTNlEbef7DtBdjNd5Oh72GseBCwToNTinFCVpJbj2AWceDykSDsaxzZMg3ienXwZ5XB3ClyUi6N+8MLwpsX4kJuGNfOY3z6yC+JQSvuVhIb1zDRYDKAHDuabzo38sk8q/WhBEVvL95lzPHoxMEpaQfwyjZ4lLhDbqe9/y7s7M9bjz1K9AXHS6h5fIWGVKVzL8YKoOVi6Na6vcnS8w7YNr71AMr0d7H0nM9gG6Fy4DDyUsfa9SBhLVxMWbEPe9+eJNZ0MkuwI/6eaxiqnqAcMfFyvw1bwBGCi4+x0+9riwpOYE21q3Mq/XbTKdvI7YG4RPfd2X4Xe6hOVPW/5iEICZdxrpLdyDN7suZX7Y8POcBeJgi6HkdKXfDO6NlCV+Fnmwx/FltHILX2GNASob/o2/dVkPNh3NjxVqgwN9OxyzNQefWC3z1W3YgBwTWc3VkuiuE0eTEkBX5aSGTGZWqysz4U42/7M+MiSC80VpMbsFNd1FEGZR75Y644q+aUHLGNWIK01dslxZUiUEh5CkdOHTqpeHVszJyCblTtIBAXyBhZfnbdOBxpPsZGg2U+iSUSOzXW2W11e52ARhpi0QlnvhdkI="

View File

@ -746,7 +746,7 @@ CITE_BIB_FILES =
# messages are off.
# The default value is: NO.
QUIET = NO
QUIET = YES
# The WARNINGS tag can be used to turn on/off the warning messages that are
# generated to standard error (stderr) by doxygen. If WARNINGS is set to YES

View File

@ -2,7 +2,7 @@
| | |
| --- | --- |
| **Dev Status** | ![Stable](https://img.shields.io/badge/Status-Stable-green.svg) |
| **Latest Release** | [![GitHub release](https://img.shields.io/github/release/noisymime/speeduino.svg)](https://github.com/noisymime/speeduino/releases/tag/201903) |
| **Latest Release** | [![GitHub release](https://img.shields.io/github/release/noisymime/speeduino.svg)](https://github.com/noisymime/speeduino/releases/latest) |
| **MISRA Status** | [![MISRA](https://img.shields.io/travis/noisymime/speeduino.svg)](https://travis-ci.org/noisymime/speeduino/) |
| **Feature Bounties** | [![Bountysource](https://img.shields.io/bountysource/team/speeduino/activity.svg)](https://www.bountysource.com/teams/speeduino)

32
misra/check_misra_github.sh Executable file
View File

@ -0,0 +1,32 @@
#!/bin/bash
cppcheck_path=cppcheck_github/
cppcheck_bin="${cppcheck_path}cppcheck"
#cppcheck_bin="cppcheck"
cppcheck_misra="${cppcheck_path}addons/misra.py"
if [ -f ./results.txt ]; then
rm results.txt
fi
for i in speeduino/speeduino/*.ino; do
$cppcheck_bin --dump --max-configs=1 --suppressions-list=speeduino/misra/suppressions.txt --suppress=syntaxError:speeduino/speeduino/src/PID_v1/PID_v1.h --include=${i%.*}.h -DCORE_AVR=1 -D__AVR_ATmega2560__=1 $i > /dev/null
done
mv speeduino/speeduino/*.dump ./
rm ./utils.*.dump
python $cppcheck_misra --rule-texts=speeduino/misra/misra_2012_text.txt *.dump 2> results.txt
#rm *.dump
cat results.txt
# wc -l results.txt
errors=`wc -l < results.txt | tr -d ' '`
echo $errors MISRA violations
if [ $errors -gt 0 ]; then
exit 1
else
exit 0
fi

View File

@ -1,26 +0,0 @@
if [ -f ./results.txt ]; then
rm results.txt
fi
cd speeduino/speeduino
#cppcheck --dump --inline-suppr --suppress=syntaxError:src/PID_v1/PID_v1.h --suppressions-list=../misra/suppressions.txt --include=./*.h -DCORE_AVR=1 -D__AVR_ATmega2560__ -U__STM32F1__ -USTM32F4 ./*.ino > /dev/null
cppcheck --dump --inline-suppr --suppress=syntaxError:src/PID_v1/PID_v1.h --suppressions-list=../misra/suppressions.txt --include=./*.h -DCORE_AVR=1 -D__AVR_ATmega2560__ -U__STM32F1__ -USTM32F4 -UCORE_STM32 -UCORE_TEENSY ./storage.ino > /dev/null
cd ../..
mv speeduino/speeduino/*.dump ./
rm ./utils.*.dump
python cppcheck/addons/misra.py --rule-texts=speeduino/misra/misra_2012_text.txt *.dump 2> results.txt
#python cppcheck/addons/misra.py --rule-texts=speeduino/misra/misra_2012_text.txt board_avr2560.ino.dump 2> results.txt
#rm *.dump
cat results.txt
# wc -l results.txt
errors=`wc -l < results.txt | tr -d ' '`
echo $errors MISRA violations
if [ $errors -gt 0 ]; then
exit 1
else
exit 0
fi

View File

@ -94,17 +94,17 @@ No text specified
Rule 9.5
No text specified
Rule 10.1
No text specified
Arguments of a conditional operation must be of an essentially boolean type
Rule 10.2
No text specified
Rule 10.3
No text specified
Rule 10.4
No text specified
The target of an operation must be of an appropriate type
Rule 10.5
No text specified
Rule 10.6
No text Specified
An expression should not assign a value to a variable of a narrower or essentially different type
Rule 10.7
No text specified
Rule 10.8
@ -126,7 +126,7 @@ No text specified
Rule 11.8
No text specified
Rule 11.9
No text specified
An integer null pointer shall have no value assigned other than NULL macro
Rule 12.1
Advisory - Order of operations within an expression must be explicit. Multiple conditions in a logical operation should have brackets around them.
Rule 12.2
@ -166,9 +166,9 @@ No text specified
Rule 15.5
Advisory - A function should only have a single return point
Rule 15.6
No text specified
Loops, switch and if/else statements must have brackets around their body
Rule 15.7
No text specified
'else if' statements must terminate with a final 'else'
Rule 16.1
No text specified
Rule 16.2
@ -232,7 +232,7 @@ Advisory - Use of #undef is not permitted
Rule 20.6
No text specified
Rule 20.7
No text specified
Macro expressions must be enclosed in parentheses
Rule 20.8
No text specified
Rule 20.9
@ -252,7 +252,7 @@ No text specified
Rule 21.2
No text specified
Rule 21.3
No text specified
Memory allocation functions (Eg malloc(), talloc() etc) shall not be used
Rule 21.4
No text specified
Rule 21.5

View File

@ -0,0 +1,2 @@
5.4 - cppcheck currently doesn't appear to handle the scope of #defines within header files and so is counting all instances as duplicates.
10.4 - Currently suppressing this as the work required to go through and add I, U, UL, L etc to all the contstants is not worth it.

View File

@ -1,7 +1,6 @@
misra_12.1:board_avr2560.ino:7
misra_14_4
misra.5.2
misra_10.4
misra_5.4
MISRA_16_4:misra-suppressions1-test.c
MISRA.16.6:misra-suppressions1-test.c
MISRA_4_1:misra-suppressions2-test.c
MISRA.19_2:misra-suppressions2-test.c
MISRA.19_2:misra-suppressions2-test.c

View File

@ -13,7 +13,7 @@ platform=atmelavr
board=megaatmega2560
framework=arduino
build_unflags = -Os
build_flags = -O3 -ffast-math
build_flags = -O3 -ffast-math -Wall -Wextra
lib_deps = EEPROM
[env:teensy35]
@ -55,9 +55,8 @@ board = black_f407ve
lib_deps = EEPROM
board_build.core = stm32
;build_flags = -fpermissive -std=gnu++11 -UBOARD_NR_GPIO_PINS -DCORE_STM32_OFFICIAL -DSRAM_AS_EEPROM
build_flags = -fpermissive -std=gnu++11 -UBOARD_NR_GPIO_PINS -DCORE_STM32_OFFICIAL -DSPI_AS_EEPROM
build_flags = -fpermissive -std=gnu++11 -UBOARD_NR_GPIO_PINS -DCORE_STM32_OFFICIAL -DSPI_AS_EEPROM -DMENU_USB_SERIAL
upload_protocol = serial
[env:bluepill_f103c8]
platform = ststm32
@ -88,7 +87,7 @@ upload_protocol = sam-ba
[platformio]
src_dir=speeduino
env_default = megaatmega2560
default_envs = megaatmega2560
;The following lines are for testing / experimentation only. Comment the line above to try them out
;env_default = teensy35
;env_default = LaunchPad_tm4c1294ncpdt

View File

@ -1,7 +1,7 @@
<?xml version="1.0" encoding="ISO-8859-1"?>
<msq xmlns="http://www.msefi.com/:msq">
<bibliography author="TunerStudio MS(Beta) 3.0.60.54 - EFI Analytics, Inc." tuneComment="" writeDate="Thu Apr 04 12:10:43 AEDT 2019"/>
<versionInfo fileFormat="5.0" firmwareInfo="Speeduino+2019.03" nPages="10" signature="speeduino 201903"/>
<bibliography author="TunerStudio MS(Beta) 3.0.60.55 - EFI Analytics, Inc." tuneComment="" writeDate="Thu Jun 06 23:25:47 AEST 2019"/>
<versionInfo fileFormat="5.0" firmwareInfo="Speeduino+2019.03" nPages="11" signature="speeduino 201905"/>
<page>
<pcVariable name="tsCanId">"CAN ID 0"</pcVariable>
<pcVariable cols="1" digits="0" name="algorithmLimits" rows="8">
@ -19,10 +19,8 @@
<pcVariable name="AUXin00Alias">Aux0</pcVariable>
</page>
<page number="0" size="128">
<constant digits="0" name="unused2-1" units="kPa">50.0</constant>
<constant digits="0" name="unused2-2" units="kPa">50.0</constant>
<constant digits="0" name="asePct" units="%">15.0</constant>
<constant digits="0" name="aseCount" units="s">5.0</constant>
<constant name="aeMode">"MAP"</constant>
<constant name="unused1-3c">"MAP"</constant>
<constant cols="1" digits="0" name="wueRates" rows="10" units="%">
179.0
179.0
@ -40,9 +38,9 @@
<constant name="tachoPin">"Board Default"</constant>
<constant name="tachoDiv">"Normal"</constant>
<constant digits="0" name="tachoDuration" units="ms">3.0</constant>
<constant digits="1" name="unused2-18" units="ms">0.0</constant>
<constant digits="0" name="tpsThresh" units="%/s">30.0</constant>
<constant digits="0" name="taeTime" units="ms">400.0</constant>
<constant digits="0" name="maeThresh" units="kPa/s">70.0</constant>
<constant digits="0" name="taeThresh" units="%/s">70.0</constant>
<constant digits="0" name="aeTime" units="ms">200.0</constant>
<constant name="display">"Unused"</constant>
<constant name="display1">"VE"</constant>
<constant name="display2">"CPU"</constant>
@ -78,7 +76,6 @@
<constant name="injLayout">"Paired"</constant>
<constant name="perToothIgn">"Yes"</constant>
<constant name="dfcoEnabled">"Off"</constant>
<constant digits="1" name="primePulse" units="ms">2.0</constant>
<constant digits="0" name="dutyLim" units="%">95.0</constant>
<constant digits="0" name="flexFreqLow" units="Hz">42.0</constant>
<constant digits="0" name="flexFreqHigh" units="Hz">0.0</constant>
@ -96,8 +93,7 @@
<constant name="idleUpPolarity">"Normal"</constant>
<constant name="idleUpEnabled">"Off"</constant>
<constant digits="0" name="idleUpAdder" units="% / Steps">20.0</constant>
<constant digits="0" name="taeTaperMin" units="RPM">1500.0</constant>
<constant digits="0" name="taeTaperMax" units="RPM">6000.0</constant>
<constant digits="0" name="aeTaperMin" units="RPM">1000.0</constant>
<constant digits="0" name="iacCLminDuty" units="%">40.0</constant>
<constant digits="0" name="iacCLmaxDuty" units="%">80.0</constant>
<constant digits="0" name="boostMinDuty" units="%">12.0</constant>
@ -107,66 +103,35 @@
<constant digits="0" name="EMAPMax" units="kpa">65535.0</constant>
<constant name="fanWhenOff">"Yes"</constant>
<constant name="unused_fan_bits">"30"</constant>
<constant cols="1" digits="0" name="unused2-67" rows="56" units="%">
60.0
60.0
64.0
65.0
69.0
72.0
73.0
74.0
75.0
76.0
78.0
78.0
79.0
76.0
62.0
59.0
61.0
64.0
66.0
69.0
72.0
73.0
74.0
75.0
76.0
77.0
78.0
79.0
73.0
63.0
60.0
62.0
64.0
66.0
69.0
72.0
74.0
75.0
76.0
77.0
78.0
78.0
79.0
74.0
61.0
60.0
62.0
65.0
67.0
70.0
72.0
74.0
74.0
76.0
77.0
77.0
<constant cols="1" digits="0" name="asePct" rows="4" units="%">
50.0
29.0
15.0
8.0
</constant>
<constant digits="0" name="UNALLOCATED_TOP_0" units="RAW">
<constant cols="1" digits="0" name="aseCount" rows="4" units="s">
15.0
10.0
10.0
5.0
</constant>
<constant cols="1" digits="0" name="aseBins" rows="4" units="C">
0.0
27.0
60.0
101.0
</constant>
<constant cols="1" digits="1" name="primePulse" rows="4" units="ms">
2.0
1.0
1.0
1.0
</constant>
<constant cols="1" digits="0" name="primeBins" rows="4" units="C">
-8.0
40.0
65.0
100.0
</constant>
</page>
<page number="1" size="288">
@ -286,7 +251,7 @@
<constant digits="0" name="FixAng" units="Deg">0.0</constant>
<constant digits="0" name="CrankAng" units="Deg">5.0</constant>
<constant digits="0" name="TrigAngMul">10.0</constant>
<constant name="TrigEdge">"RISING"</constant>
<constant name="TrigEdge">"FALLING"</constant>
<constant name="TrigSpeed">"Crank Speed"</constant>
<constant name="IgInv">"Going Low"</constant>
<constant name="TrigPattern">"4G63 / Miata / 3000GT"</constant>
@ -372,71 +337,77 @@
<constant digits="0" name="ADCFILTER_TPS" units="%">50.0</constant>
<constant digits="0" name="ADCFILTER_CLT" units="%">180.0</constant>
<constant digits="0" name="ADCFILTER_IAT" units="%">180.0</constant>
<constant digits="0" name="ADCFILTER_O2" units="%">128.0</constant>
<constant digits="0" name="ADCFILTER_O2" units="%">100.0</constant>
<constant digits="0" name="ADCFILTER_BAT" units="%">128.0</constant>
<constant digits="0" name="ADCFILTER_MAP" units="%">20.0</constant>
<constant digits="0" name="ADCFILTER_BARO" units="%">64.0</constant>
<constant cols="1" digits="0" name="unused4-64" rows="56" units="%">
<constant cols="1" digits="0" name="cltAdvBins" rows="6" units="C">
0.0
20.0
50.0
70.0
85.0
100.0
</constant>
<constant cols="1" digits="1" name="cltAdvValues" rows="6" units="deg">
0.0
0.0
0.0
0.0
0.0
0.0
</constant>
<constant cols="1" digits="0" name="maeBins" rows="4" units="kpa/s">
10.0
260.0
670.0
1000.0
</constant>
<constant cols="1" digits="0" name="maeRates" rows="4" units="%">
97.0
102.0
104.0
113.0
</constant>
<constant cols="1" digits="0" name="unused4-64" rows="37" units="%">
16.0
33.0
142.0
128.0
129.0
131.0
147.0
150.0
147.0
147.0
147.0
147.0
147.0
147.0
147.0
147.0
146.0
128.0
91.0
128.0
130.0
142.0
68.0
57.0
95.0
70.0
93.0
147.0
148.0
147.0
147.0
147.0
147.0
147.0
131.0
129.0
140.0
64.0
92.0
80.0
110.0
68.0
5.0
14.0
24.0
35.0
54.0
76.0
94.0
111.0
56.0
79.0
105.0
100.0
99.0
90.0
56.0
9.0
26.0
37.0
57.0
14.0
30.0
56.0
87.0
103.0
71.0
104.0
99.0
82.0
19.0
29.0
54.0
63.0
0.0
0.0
0.0
0.0
0.0
112.0
150.0
130.0
1.0
</constant>
<constant digits="0" name="UNALLOCATED_TOP_3" units="RAW">
0.0
</constant>
</page>
<page number="4" size="288">
<constant cols="16" digits="1" name="afrTable" rows="16" units="AFR">
@ -1063,44 +1034,48 @@
<constant name="Auxin15pinb">"8"</constant>
<constant name="iacStepperInv">"Yes"</constant>
<constant name="iacCoolTime">"0"</constant>
<constant digits="0" name="unused10_154">7.0</constant>
<constant digits="0" name="unused10_155">20.0</constant>
<constant digits="0" name="unused10_156">44.0</constant>
<constant digits="0" name="unused10_157">1.0</constant>
<constant digits="0" name="unused10_158">188.0</constant>
<constant digits="0" name="unused10_159">2.0</constant>
<constant digits="0" name="unused10_160">7.0</constant>
<constant digits="0" name="unused10_161">0.0</constant>
<constant digits="0" name="unused10_162">20.0</constant>
<constant digits="0" name="unused10_163">40.0</constant>
<constant digits="0" name="unused10_164">60.0</constant>
<constant digits="0" name="unused10_165">80.0</constant>
<constant digits="0" name="unused10_166">100.0</constant>
<constant digits="0" name="unused10_167">0.0</constant>
<constant digits="0" name="unused10_168">0.0</constant>
<constant digits="0" name="unused10_169">10.0</constant>
<constant digits="0" name="unused10_170">0.0</constant>
<constant digits="0" name="unused10_171">20.0</constant>
<constant digits="0" name="unused10_172">0.0</constant>
<constant digits="0" name="unused10_173">30.0</constant>
<constant digits="0" name="unused10_174">0.0</constant>
<constant digits="0" name="unused10_175">40.0</constant>
<constant digits="0" name="unused10_176">0.0</constant>
<constant digits="0" name="unused10_177">50.0</constant>
<constant digits="0" name="unused10_178">0.0</constant>
<constant digits="0" name="unused10_179">0.0</constant>
<constant digits="0" name="unused10_180">20.0</constant>
<constant digits="0" name="unused10_181">40.0</constant>
<constant digits="0" name="unused10_182">60.0</constant>
<constant digits="0" name="unused10_183">80.0</constant>
<constant digits="0" name="unused10_184">100.0</constant>
<constant digits="0" name="unused10_185">100.0</constant>
<constant digits="0" name="unused10_186">112.0</constant>
<constant digits="0" name="unused10_187">125.0</constant>
<constant digits="0" name="unused10_188">137.0</constant>
<constant digits="0" name="unused10_189">150.0</constant>
<constant digits="0" name="unused10_190">163.0</constant>
<constant name="blankfield">""</constant>
<constant name="unused10_153">""</constant>
<constant cols="1" digits="0" name="unused10_154" rows="38">
7.0
7.0
7.0
7.0
7.0
7.0
7.0
7.0
7.0
7.0
7.0
7.0
7.0
7.0
7.0
7.0
7.0
7.0
7.0
7.0
7.0
7.0
7.0
7.0
7.0
7.0
7.0
7.0
7.0
7.0
7.0
7.0
7.0
7.0
7.0
7.0
7.0
7.0
</constant>
</page>
<page number="9" size="192">
<constant cols="1" digits="0" name="crankingEnrichBins" rows="4" units="C">
@ -1254,14 +1229,13 @@
<constant digits="1" name="knock_duration" units="Sec">0.1</constant>
<constant digits="1" name="knock_recoveryStepTime" units="Sec">0.0</constant>
<constant digits="0" name="knock_recoveryStep" units="Deg">0.0</constant>
<constant cols="1" digits="0" name="unused11_122_191" rows="70" units="RPM">
<constant cols="1" digits="0" name="unused11_122_191" rows="69" units="RPM">
0.0
0.0
0.0
0.0
18800.0
1400.0
0.0
800.0
17800.0
1300.0
0.0
0.0
0.0
@ -1327,6 +1301,62 @@
9800.0
</constant>
</page>
<page number="10" size="288">
<constant cols="16" digits="0" name="veTable2" rows="16" units="%">
39.0 39.0 39.0 39.0 39.0 38.0 37.0 36.0 35.0 34.0 33.0 33.0 33.0 33.0 33.0 33.0
40.0 40.0 41.0 42.0 42.0 41.0 40.0 39.0 39.0 39.0 39.0 39.0 40.0 40.0 40.0 40.0
40.0 42.0 43.0 46.0 46.0 45.0 44.0 43.0 42.0 42.0 43.0 43.0 43.0 44.0 44.0 44.0
42.0 45.0 47.0 51.0 51.0 49.0 48.0 47.0 46.0 46.0 46.0 47.0 47.0 47.0 48.0 48.0
44.0 49.0 52.0 56.0 55.0 54.0 52.0 51.0 50.0 50.0 50.0 50.0 51.0 51.0 51.0 52.0
48.0 54.0 58.0 61.0 59.0 58.0 56.0 55.0 54.0 53.0 54.0 54.0 54.0 55.0 55.0 55.0
54.0 61.0 64.0 66.0 64.0 62.0 61.0 59.0 58.0 57.0 57.0 58.0 58.0 59.0 59.0 59.0
60.0 67.0 70.0 70.0 68.0 67.0 65.0 63.0 62.0 61.0 61.0 61.0 62.0 63.0 63.0 63.0
67.0 74.0 76.0 75.0 73.0 71.0 69.0 68.0 66.0 64.0 65.0 65.0 66.0 66.0 67.0 67.0
74.0 80.0 81.0 79.0 77.0 75.0 73.0 72.0 70.0 68.0 68.0 69.0 69.0 70.0 70.0 71.0
81.0 85.0 86.0 84.0 82.0 80.0 78.0 76.0 74.0 72.0 72.0 72.0 73.0 74.0 74.0 74.0
87.0 91.0 91.0 88.0 86.0 84.0 82.0 80.0 78.0 76.0 76.0 76.0 77.0 78.0 78.0 78.0
93.0 93.0 93.0 93.0 93.0 90.0 88.0 86.0 84.0 83.0 83.0 83.0 84.0 85.0 85.0 86.0
93.0 93.0 93.0 93.0 93.0 92.0 90.0 88.0 86.0 86.0 86.0 87.0 88.0 89.0 89.0 90.0
93.0 93.0 93.0 93.0 93.0 93.0 93.0 90.0 90.0 90.0 90.0 91.0 92.0 93.0 93.0 93.0
93.0 93.0 93.0 93.0 93.0 93.0 93.0 93.0 93.0 93.0 93.0 93.0 93.0 93.0 93.0 95.0
</constant>
<constant cols="1" digits="0" name="fuelRPM2Bins" rows="16" units="RPM">
500.0
700.0
900.0
1400.0
2000.0
2800.0
3600.0
4500.0
5200.0
5500.0
5800.0
6200.0
6500.0
6800.0
6900.0
7000.0
</constant>
<constant cols="1" digits="0" name="fuelLoad2Bins" rows="16" units="kPa">
16.0
26.0
30.0
36.0
40.0
46.0
50.0
56.0
60.0
66.0
70.0
76.0
86.0
90.0
96.0
100.0
</constant>
</page>
<settings Comment="These setting are only used if this msq is opened without a project.">
<setting name="SPEED_DENSITY" value="SPEED_DENSITY"/>
<setting name="enablehardware_test" value="enablehardware_test"/>

View File

@ -1,7 +1,7 @@
<?xml version="1.0" encoding="ISO-8859-1"?>
<msq xmlns="http://www.msefi.com/:msq">
<bibliography author="TunerStudio MS(Beta) 3.0.60.54 - EFI Analytics, Inc." tuneComment="" writeDate="Thu Apr 04 12:07:20 AEDT 2019"/>
<versionInfo fileFormat="5.0" firmwareInfo="Speeduino+2019.03" nPages="10" signature="speeduino 201903"/>
<bibliography author="TunerStudio MS(Beta) 3.0.60.55 - EFI Analytics, Inc." tuneComment="" writeDate="Thu Jun 06 23:28:41 AEST 2019"/>
<versionInfo fileFormat="5.0" firmwareInfo="Speeduino+2019.03" nPages="11" signature="speeduino 201905"/>
<page>
<pcVariable name="tsCanId">"CAN ID 0"</pcVariable>
<pcVariable cols="1" digits="0" name="algorithmLimits" rows="8">
@ -19,10 +19,8 @@
<pcVariable name="AUXin00Alias">Aux0</pcVariable>
</page>
<page number="0" size="128">
<constant digits="0" name="unused2-1" units="kPa">-1.0</constant>
<constant digits="0" name="unused2-2" units="kPa">255.0</constant>
<constant digits="0" name="asePct" units="%">25.0</constant>
<constant digits="0" name="aseCount" units="s">8.0</constant>
<constant name="aeMode">"TPS"</constant>
<constant name="unused1-3c">"MAP"</constant>
<constant cols="1" digits="0" name="wueRates" rows="10" units="%">
180.0
175.0
@ -40,9 +38,9 @@
<constant name="tachoPin">"Board Default"</constant>
<constant name="tachoDiv">"Normal"</constant>
<constant digits="0" name="tachoDuration" units="ms">3.0</constant>
<constant digits="1" name="unused2-18" units="ms">25.5</constant>
<constant digits="0" name="tpsThresh" units="%/s">70.0</constant>
<constant digits="0" name="taeTime" units="ms">200.0</constant>
<constant digits="0" name="maeThresh" units="kPa/s">70.0</constant>
<constant digits="0" name="taeThresh" units="%/s">70.0</constant>
<constant digits="0" name="aeTime" units="ms">200.0</constant>
<constant name="display">"Unused"</constant>
<constant name="display1">"VE"</constant>
<constant name="display2">"CPU"</constant>
@ -78,7 +76,6 @@
<constant name="injLayout">"Paired"</constant>
<constant name="perToothIgn">"Yes"</constant>
<constant name="dfcoEnabled">"Off"</constant>
<constant digits="1" name="primePulse" units="ms">1.0</constant>
<constant digits="0" name="dutyLim" units="%">90.0</constant>
<constant digits="0" name="flexFreqLow" units="Hz">50.0</constant>
<constant digits="0" name="flexFreqHigh" units="Hz">150.0</constant>
@ -96,8 +93,7 @@
<constant name="idleUpPolarity">"Normal"</constant>
<constant name="idleUpEnabled">"Off"</constant>
<constant digits="0" name="idleUpAdder" units="% / Steps">20.0</constant>
<constant digits="0" name="taeTaperMin" units="RPM">1000.0</constant>
<constant digits="0" name="taeTaperMax" units="RPM">4500.0</constant>
<constant digits="0" name="aeTaperMin" units="RPM">1000.0</constant>
<constant digits="0" name="iacCLminDuty" units="%">0.0</constant>
<constant digits="0" name="iacCLmaxDuty" units="%">0.0</constant>
<constant digits="0" name="boostMinDuty" units="%">20.0</constant>
@ -107,66 +103,35 @@
<constant digits="0" name="EMAPMax" units="kpa">260.0</constant>
<constant name="fanWhenOff">"Yes"</constant>
<constant name="unused_fan_bits">"30"</constant>
<constant cols="1" digits="0" name="unused2-67" rows="56" units="%">
62.0
62.0
60.0
61.0
64.0
65.0
67.0
68.0
69.0
<constant cols="1" digits="0" name="asePct" rows="4" units="%">
70.0
71.0
71.0
70.0
66.0
61.0
60.0
60.0
62.0
63.0
65.0
66.0
67.0
68.0
69.0
70.0
72.0
73.0
69.0
62.0
60.0
61.0
62.0
63.0
65.0
67.0
68.0
70.0
71.0
72.0
72.0
73.0
72.0
64.0
60.0
61.0
60.0
63.0
65.0
66.0
68.0
68.0
70.0
71.0
71.0
71.0
71.0
50.0
35.0
35.0
</constant>
<constant digits="0" name="UNALLOCATED_TOP_0" units="RAW">
<constant cols="1" digits="0" name="aseCount" rows="4" units="s">
15.0
8.0
8.0
3.0
</constant>
<constant cols="1" digits="0" name="aseBins" rows="4" units="C">
0.0
40.0
80.0
100.0
</constant>
<constant cols="1" digits="1" name="primePulse" rows="4" units="ms">
1.0
1.0
1.0
1.0
</constant>
<constant cols="1" digits="0" name="primeBins" rows="4" units="C">
0.0
40.0
60.0
100.0
</constant>
</page>
<page number="1" size="288">
@ -286,7 +251,7 @@
<constant digits="0" name="FixAng" units="Deg">0.0</constant>
<constant digits="0" name="CrankAng" units="Deg">5.0</constant>
<constant digits="0" name="TrigAngMul">0.0</constant>
<constant name="TrigEdge">"RISING"</constant>
<constant name="TrigEdge">"FALLING"</constant>
<constant name="TrigSpeed">"Crank Speed"</constant>
<constant name="IgInv">"Going Low"</constant>
<constant name="TrigPattern">"Missing Tooth"</constant>
@ -372,70 +337,76 @@
<constant digits="0" name="ADCFILTER_TPS" units="%">50.0</constant>
<constant digits="0" name="ADCFILTER_CLT" units="%">180.0</constant>
<constant digits="0" name="ADCFILTER_IAT" units="%">180.0</constant>
<constant digits="0" name="ADCFILTER_O2" units="%">128.0</constant>
<constant digits="0" name="ADCFILTER_O2" units="%">100.0</constant>
<constant digits="0" name="ADCFILTER_BAT" units="%">128.0</constant>
<constant digits="0" name="ADCFILTER_MAP" units="%">20.0</constant>
<constant digits="0" name="ADCFILTER_BARO" units="%">64.0</constant>
<constant cols="1" digits="0" name="unused4-64" rows="56" units="%">
16.0
33.0
147.0
147.0
147.0
149.0
151.0
151.0
148.0
147.0
147.0
147.0
147.0
147.0
147.0
147.0
147.0
147.0
147.0
148.0
151.0
151.0
149.0
147.0
147.0
147.0
147.0
147.0
147.0
147.0
147.0
147.0
147.0
148.0
150.0
151.0
149.0
147.0
147.0
147.0
147.0
147.0
147.0
147.0
147.0
147.0
147.0
147.0
149.0
150.0
149.0
148.0
147.0
147.0
146.0
145.0
</constant>
<constant digits="0" name="UNALLOCATED_TOP_3" units="RAW">
<constant cols="1" digits="0" name="cltAdvBins" rows="6" units="C">
0.0
20.0
40.0
60.0
80.0
100.0
</constant>
<constant cols="1" digits="1" name="cltAdvValues" rows="6" units="deg">
0.0
0.0
0.0
0.0
0.0
0.0
</constant>
<constant cols="1" digits="0" name="maeBins" rows="4" units="kpa/s">
80.0
220.0
500.0
860.0
</constant>
<constant cols="1" digits="0" name="maeRates" rows="4" units="%">
50.0
73.0
92.0
94.0
</constant>
<constant cols="1" digits="0" name="unused4-64" rows="37" units="%">
16.0
93.0
147.0
148.0
151.0
149.0
147.0
147.0
147.0
147.0
147.0
147.0
147.0
151.0
150.0
147.0
147.0
147.0
147.0
147.0
147.0
147.0
149.0
151.0
148.0
147.0
147.0
147.0
147.0
147.0
147.0
148.0
150.0
149.0
147.0
147.0
145.0
</constant>
</page>
<page number="4" size="288">
@ -1063,44 +1034,48 @@
<constant name="Auxin15pinb">"8"</constant>
<constant name="iacStepperInv">"No"</constant>
<constant name="iacCoolTime">"1"</constant>
<constant digits="0" name="unused10_154">7.0</constant>
<constant digits="0" name="unused10_155">20.0</constant>
<constant digits="0" name="unused10_156">44.0</constant>
<constant digits="0" name="unused10_157">1.0</constant>
<constant digits="0" name="unused10_158">188.0</constant>
<constant digits="0" name="unused10_159">2.0</constant>
<constant digits="0" name="unused10_160">7.0</constant>
<constant digits="0" name="unused10_161">0.0</constant>
<constant digits="0" name="unused10_162">20.0</constant>
<constant digits="0" name="unused10_163">40.0</constant>
<constant digits="0" name="unused10_164">60.0</constant>
<constant digits="0" name="unused10_165">80.0</constant>
<constant digits="0" name="unused10_166">100.0</constant>
<constant digits="0" name="unused10_167">0.0</constant>
<constant digits="0" name="unused10_168">0.0</constant>
<constant digits="0" name="unused10_169">10.0</constant>
<constant digits="0" name="unused10_170">0.0</constant>
<constant digits="0" name="unused10_171">20.0</constant>
<constant digits="0" name="unused10_172">0.0</constant>
<constant digits="0" name="unused10_173">30.0</constant>
<constant digits="0" name="unused10_174">0.0</constant>
<constant digits="0" name="unused10_175">40.0</constant>
<constant digits="0" name="unused10_176">0.0</constant>
<constant digits="0" name="unused10_177">50.0</constant>
<constant digits="0" name="unused10_178">0.0</constant>
<constant digits="0" name="unused10_179">0.0</constant>
<constant digits="0" name="unused10_180">20.0</constant>
<constant digits="0" name="unused10_181">40.0</constant>
<constant digits="0" name="unused10_182">60.0</constant>
<constant digits="0" name="unused10_183">80.0</constant>
<constant digits="0" name="unused10_184">100.0</constant>
<constant digits="0" name="unused10_185">100.0</constant>
<constant digits="0" name="unused10_186">112.0</constant>
<constant digits="0" name="unused10_187">125.0</constant>
<constant digits="0" name="unused10_188">137.0</constant>
<constant digits="0" name="unused10_189">150.0</constant>
<constant digits="0" name="unused10_190">163.0</constant>
<constant name="blankfield">""</constant>
<constant name="unused10_153">""</constant>
<constant cols="1" digits="0" name="unused10_154" rows="38">
7.0
7.0
7.0
7.0
7.0
7.0
7.0
7.0
7.0
7.0
7.0
7.0
7.0
7.0
7.0
7.0
7.0
7.0
7.0
7.0
7.0
7.0
7.0
7.0
7.0
7.0
7.0
7.0
7.0
7.0
7.0
7.0
7.0
7.0
7.0
7.0
7.0
7.0
</constant>
</page>
<page number="9" size="192">
<constant cols="1" digits="0" name="crankingEnrichBins" rows="4" units="C">
@ -1254,15 +1229,14 @@
<constant digits="1" name="knock_duration" units="Sec">0.2</constant>
<constant digits="1" name="knock_recoveryStepTime" units="Sec">0.1</constant>
<constant digits="0" name="knock_recoveryStep" units="Deg">0.0</constant>
<constant cols="1" digits="0" name="unused11_122_191" rows="70" units="RPM">
<constant cols="1" digits="0" name="unused11_122_191" rows="69" units="RPM">
0.0
0.0
0.0
0.0
0.0
18600.0
1700.0
0.0
1100.0
17400.0
1500.0
0.0
0.0
0.0
@ -1327,6 +1301,62 @@
0.0
</constant>
</page>
<page number="10" size="288">
<constant cols="16" digits="0" name="veTable2" rows="16" units="%">
39.0 39.0 39.0 39.0 39.0 38.0 37.0 36.0 35.0 34.0 33.0 33.0 33.0 33.0 33.0 33.0
40.0 40.0 41.0 42.0 42.0 41.0 40.0 39.0 39.0 39.0 39.0 39.0 40.0 40.0 40.0 40.0
40.0 42.0 43.0 46.0 46.0 45.0 44.0 43.0 42.0 42.0 43.0 43.0 43.0 44.0 44.0 44.0
42.0 45.0 47.0 51.0 51.0 49.0 48.0 47.0 46.0 46.0 46.0 47.0 47.0 47.0 48.0 48.0
44.0 49.0 52.0 56.0 55.0 54.0 52.0 51.0 50.0 50.0 50.0 50.0 51.0 51.0 51.0 52.0
48.0 54.0 58.0 61.0 59.0 58.0 56.0 55.0 54.0 53.0 54.0 54.0 54.0 55.0 55.0 55.0
54.0 61.0 64.0 66.0 64.0 62.0 61.0 59.0 58.0 57.0 57.0 58.0 58.0 59.0 59.0 59.0
60.0 67.0 70.0 70.0 68.0 67.0 65.0 63.0 62.0 61.0 61.0 61.0 62.0 63.0 63.0 63.0
67.0 74.0 76.0 75.0 73.0 71.0 69.0 68.0 66.0 64.0 65.0 65.0 66.0 66.0 67.0 67.0
74.0 80.0 81.0 79.0 77.0 75.0 73.0 72.0 70.0 68.0 68.0 69.0 69.0 70.0 70.0 71.0
81.0 85.0 86.0 84.0 82.0 80.0 78.0 76.0 74.0 72.0 72.0 72.0 73.0 74.0 74.0 74.0
87.0 91.0 91.0 88.0 86.0 84.0 82.0 80.0 78.0 76.0 76.0 76.0 77.0 78.0 78.0 78.0
93.0 93.0 93.0 93.0 93.0 90.0 88.0 86.0 84.0 83.0 83.0 83.0 84.0 85.0 85.0 86.0
93.0 93.0 93.0 93.0 93.0 92.0 90.0 88.0 86.0 86.0 86.0 87.0 88.0 89.0 89.0 90.0
93.0 93.0 93.0 93.0 93.0 93.0 93.0 90.0 90.0 90.0 90.0 91.0 92.0 93.0 93.0 93.0
93.0 93.0 93.0 93.0 93.0 93.0 93.0 93.0 93.0 93.0 93.0 93.0 93.0 93.0 93.0 95.0
</constant>
<constant cols="1" digits="0" name="fuelRPM2Bins" rows="16" units="RPM">
500.0
700.0
900.0
1400.0
2000.0
2800.0
3600.0
4500.0
5200.0
5500.0
5800.0
6200.0
6500.0
6800.0
6900.0
7000.0
</constant>
<constant cols="1" digits="0" name="fuelLoad2Bins" rows="16" units="kPa">
16.0
26.0
30.0
36.0
40.0
46.0
50.0
56.0
60.0
66.0
70.0
76.0
86.0
90.0
96.0
100.0
</constant>
</page>
<settings Comment="These setting are only used if this msq is opened without a project.">
<setting name="enablehardware_test_OFF" value="enablehardware_test_OFF"/>
<setting name="SPEED_DENSITY" value="SPEED_DENSITY"/>

File diff suppressed because one or more lines are too long

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.6 MiB

After

Width:  |  Height:  |  Size: 1.6 MiB

View File

@ -6,11 +6,11 @@
MTversion = 2.25
queryCommand = "Q"
signature = "speeduino 201904-dev"
signature = "speeduino 201906-dev"
versionInfo = "S" ;This info is what is displayed to user
[TunerStudio]
iniSpecVersion = 3.51
iniSpecVersion = 3.64
;-------------------------------------------------------------------------------
@ -54,6 +54,7 @@
;algorithmUnits = bits, U08, [0:2], $loadSourceUnits
algorithmUnits = bits, U08, [0:2], "kPa", "% TPS", "%", "% TPS", "INVALID", "INVALID", "INVALID", "INVALID"
algorithmLimits= array, U16, [8], "", 1.0, 0, 0, 511, 0, noMsqSave
fuel2SwitchUnits = bits, U08, [0:2], "rpm", "kPa", "% TPS", "%", "% TPS", "INVALID", "INVALID", "INVALID"
#define all_IO_Pins = "Board Default", "INVALID", "INVALID", "3", "4", "5", "6", "7", "8", "9", "10", "11", "12", "13", "14", "15", "16", "17", "18", "19", "20", "21", "22", "23", "24", "25", "26", "27", "28", "29", "30", "31", "32", "33", "34", "35", "36", "37", "38", "39", "40", "41", "42", "43", "44", "45", "46", "47", "48", "49", "50", "51", "52", "53", "54", "A8", "A9", "A10", "A11", "A12", "A13", "A14", "A15", "INVALID"
#define IO_Pins_no_def = "INVALID", "INVALID", "INVALID", "3", "4", "5", "6", "7", "8", "9", "10", "11", "12", "13", "14", "15", "16", "17", "18", "19", "20", "21", "22", "23", "24", "25", "26", "27", "28", "29", "30", "31", "32", "33", "34", "35", "36", "37", "38", "39", "40", "41", "42", "43", "44", "45", "46", "47", "48", "49", "50", "51", "52", "53", "54", "A8", "A9", "A10", "A11", "A12", "A13", "A14", "A15", "INVALID"
@ -159,7 +160,6 @@
;pageValueWrite = "W%2o%v", "W%o%v", "W%2o%v", "W%o%v", "W%2o%v", "W%o%v", "W%o%v", "W%o%v", "W%o%v", "W%o%v", "W%o%v"
; New commands
;pageSize = 288, 128, 288, 128, 288, 128, 128, 160, 192, 192, 192
pageIdentifier = "\$tsCanId\x01", "\$tsCanId\x02", "\$tsCanId\x03", "\$tsCanId\x04", "\$tsCanId\x05", "\$tsCanId\x06", "\$tsCanId\x07", "\$tsCanId\x08", "\$tsCanId\x09", "\$tsCanId\x0A", "\$tsCanId\x0B"
burnCommand = "b%2i", "b%2i", "b%2i", "b%2i", "b%2i", "b%2i", "b%2i", "b%2i", "b%2i", "b%2i", "b%2i"
pageReadCommand = "p%2i%2o%2c", "p%2i%2o%2c", "p%2i%2o%2c", "p%2i%2o%2c", "p%2i%2o%2c", "p%2i%2o%2c", "p%2i%2o%2c", "p%2i%2o%2c", "p%2i%2o%2c", "p%2i%2o%2c", "p%2i%2o%2c"
@ -175,6 +175,7 @@
;tsWriteBlocks = on
interWriteDelay = 5 ;Ignored when tsWriteBlocks is on
pageActivationDelay = 10
restrictSquirtRelationship = false
;New for TS 3.0.08ish upwards, define lists of standard I/O options
@ -204,19 +205,20 @@
;Page 1 is all general settings. Note that some of these (algorithm and ignAlgorithm) MUST come before their use in the bitStringValue() calls in the fuel and ignition tables
;--------------------------------------------------
page = 1
unused2-1 = scalar, S08, 0, "kPa", 1.0, 0.0, -127, 127, 0
unused2-2 = scalar, U08, 1, "kPa", 1.0, 0.0, 0.0, 255, 0
unused2-3 = scalar, U08, 2, "%", 1.0, 0.0, 0.0, 95.0, 0 ;This used to be asePct
unused2-4 = scalar, U08, 3, "s", 1.0, 0.0, 0.0, 255, 0 ;This used to be aseCount
unused1-0 = scalar, S08, 0, "kPa", 1.0, 0.0, -127, 127, 0
unused1-1 = scalar, U08, 1, "kPa", 1.0, 0.0, 0.0, 255, 0
unused1-2 = scalar, U08, 2, "%", 1.0, 0.0, 0.0, 95.0, 0 ;This used to be asePct
aeMode = bits, U08, 3, [0:1], "TPS", "MAP", "INVALID", "INVALID"
unused1-3c = bits, U08, 3, [2:7], "MAP", "TPS", "INVALID", "INVALID"
wueRates = array, U08, 4, [10], "%", 1.0, 0.0, 0.0, 255, 0
crankingPct = scalar, U08, 14, "%", 1.0, 0.0, 0.0, 255, 0
pinLayout = bits, U08, 15, [0:7], "Speeduino v0.1", "Speeduino v0.2", "Speeduino v0.3", "Speeduino v0.4", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "NA6 MX5 PNP", "Turtana PCB", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "Plazomat I/O 0.1", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "Daz V6 Shield 0.1", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "NO2C", "UA4C", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "dvjcodec Teensy RevA", "dvjcodec Teensy RevB", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID"
pinLayout = bits, U08, 15, [0:7], "Speeduino v0.1", "Speeduino v0.2", "Speeduino v0.3", "Speeduino v0.4", "INVALID", "INVALID", "01-05 MX5 PNP", "INVALID", "96-97 MX5 PNP", "NA6 MX5 PNP", "Turtana PCB", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "Plazomat I/O 0.1", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "Daz V6 Shield 0.1", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "NO2C", "UA4C", "INVALID", "INVALID", "INVALID", "DIY-EFI CORE4 v1.0", "INVALID", "INVALID", "INVALID", "INVALID", "dvjcodec Teensy RevA", "dvjcodec Teensy RevB", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID"
tachoPin = bits, U08, 16, [0:5], "Board Default", "1", "2", "3", "4", "5", "6", "7", "8", "9", "10", "11", "12", "13", "14", "15", "16", "17", "18", "19", "20", "21", "22", "23", "24", "25", "26", "27", "28", "29", "30", "31", "32", "33", "34", "35", "36", "37", "38", "39", "40", "41", "42", "43", "44", "45", "46", "47", "48", "49", "50", "51", "52", "53", "54", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID"
tachoDiv = bits, U08, 16, [6:7], "Normal", "Half", "INVALID", "INVALID"
tachoDuration = scalar, U08, 17, "ms", 1.0, 0.0, 1.0, 6.0, 0
unused2-18 = scalar, U08, 18, "ms", 0.1, 0.0, 0.0, 25.5, 1
tpsThresh = scalar, U08, 19, "%/s", 1.0, 0.0, 0.0, 255, 0
taeTime = scalar, U08, 20, "ms", 10, 0.0, 0.0, 2550, 0
maeThresh = scalar, U08, 18, "kPa/s", 1.0, 0.0, 0.0, 255, 0 ;MAP threshold for triggering AE
taeThresh = scalar, U08, 19, "%/s", 1.0, 0.0, 0.0, 255, 0 ;TPS threshold for triggering AE
aeTime = scalar, U08, 20, "ms", 10, 0.0, 0.0, 2550, 0
; Display (Options for what the display is showing)
display = bits, U08, 21, [0:2], "Unused", "Adafruit 128x32", "Generic 128x32", "Adafruit 128x64", "Generic 128x64", "INVALID", "INVALID", "INVALID"
@ -258,7 +260,7 @@ page = 1
; Config3
engineType = bits, U08, 38, [0:0], "Even fire", "Odd fire"
flexEnabled = bits, U08, 38, [1:1], "Off", "On"
unused2_38c = bits, U08, 38, [2:2], "Speed Density", "Alpha-N"
legacyMAP = bits, U08, 38, [2:2], "No", "Yes" ;Whether to use the older legacy MAP reading that had the pullup enabled
baroCorr = bits, U08, 38, [3:3], "Off", "On"
injLayout = bits, U08, 38, [4:5], "Paired", "Semi-Sequential", "INVALID", "Sequential"
perToothIgn = bits, U08, 38, [6:6], "No", "Yes"
@ -284,8 +286,8 @@ page = 1
idleUpPolarity= bits, U08, 57, [6:6], "Normal", "Inverted"
idleUpEnabled = bits, U08, 57, [7:7], "Off", "On"
idleUpAdder = scalar, U08, 58, "% / Steps" 1.0, 0.0, 0.0, 250.0, 0
taeTaperMin = scalar, U08, 59, "RPM", 100, 0.0, 1000, 10000, 0
taeTaperMax = scalar, U08, 60, "RPM", 100, 0.0, 2000, 10000, 0
aeTaperMin = scalar, U08, 59, "RPM", 100, 0.0, 1000, 10000, 0
aeTaperMax = scalar, U08, 60, "RPM", 100, 0.0, 2000, 10000, 0
iacCLminDuty = scalar, U08, 61, "%", 1.0, 0.0, 0.0, 100.0, 0 ; Minimum and maximum duty cycles when using closed loop idle
iacCLmaxDuty = scalar, U08, 62, "%", 1.0, 0.0, 0.0, 100.0, 0
@ -428,9 +430,14 @@ page = 4
#else
cltAdvBins = array, U08, 71, [ 6], "F", 1.8, -22.23, -40, 215.0, 0 ; No -40 degree offset here
#endif
cltAdvValues = array, S08, 77, [ 6], "deg", 0.1, 0.0, -12.7, 12.7, 1
cltAdvValues = array, S08, 77, [ 6], "deg", 1.0, -15, -15, 15, 0
unused4-64 = array, U08, 83, [45], "%", 1.0, 0.0, 0.0, 255, 0
;MAP based acceleration enrichment
maeBins = array, U08, 83, [ 4], "kpa/s", 10.0, 0.0, 0.00, 2550.0, 0
maeRates = array, U08, 87, [ 4], "%", 1.0, 0.0, 0.00, 255.0, 0 ; 4 bytes
batVoltCorrect = scalar, S08, 91, "v", 0.1, 0.0, -2, 2, 1 ;Battery reading calibration value. Note: Signed value
unused4-92 = array, U08, 92, [36], "%", 1.0, 0.0, 0.0, 255, 0
;--------------------------------------------------
;Start AFR page
@ -443,36 +450,37 @@ page = 5
#endif
rpmBinsAFR = array, U08, 256,[ 16], "RPM", 100.0, 0.0, 100, 25500, 0
#if SPEED_DENSITY
mapBinsAFR = array, U08, 272,[ 16], "kPa", 2.0, 0.0, 0.0, 511.0, 0
#elif ALPHA_N
tpsBinsAFR = array, U08, 272,[ 16], "TPS", 2.0, 0.0, 0.0, 100.0, 0
#endif
loadBinsAFR = array, U08, 272,[ 16], { bitStringValue(algorithmUnits , algorithm) }, 2.0, 0.0, 0.0, {fuelLoadMax}, 0
;--------------------------------------------------
;Start page 6
; Page 6 is all settings associated with O2/AFR
;--------------------------------------------------
page = 6
egoAlgorithm= bits , U08, 0, [0:1], "Simple", "INVALID", "PID", "No correction" ; * ( 1 byte)
egoType = bits , U08, 0, [2:3], "Disabled", "Narrow Band", "Wide Band", "INVALID" ; egoOption
boostEnabled= bits, U08, 0, [4:4], "Off", "On"
vvtEnabled = bits, U08, 0, [5:5], "Off", "On"
boostCutType= bits, U08, 0, [6:7], "Off", "Spark Only", "Fuel Only","Both"
egoAlgorithm = bits , U08, 0, [0:1], "Simple", "INVALID", "PID", "No correction" ; * ( 1 byte)
egoType = bits , U08, 0, [2:3], "Disabled", "Narrow Band", "Wide Band", "INVALID" ; egoOption
boostEnabled = bits, U08, 0, [4:4], "Off", "On"
vvtEnabled = bits, U08, 0, [5:5], "Off", "On"
boostCutType = bits, U08, 0, [6:7], "Off", "Spark Only", "Fuel Only","Both"
egoKP = scalar, U08, 1, "%", 1.0, 0.0, 0.0, 200.0, 0 ; * ( 1 byte)
egoKI = scalar, U08, 2, "%", 1.0, 0.0, 0.0, 200.0, 0 ; * ( 1 byte)
egoKD = scalar, U08, 3, "%", 1.0, 0.0, 0.0, 200.0, 0 ; * ( 1 byte)
egoKP = scalar, U08, 1, "%", 1.0, 0.0, 0.0, 200.0, 0 ; * ( 1 byte)
egoKI = scalar, U08, 2, "%", 1.0, 0.0, 0.0, 200.0, 0 ; * ( 1 byte)
egoKD = scalar, U08, 3, "%", 1.0, 0.0, 0.0, 200.0, 0 ; * ( 1 byte)
#if CELSIUS
egoTemp = scalar, U08, 4, "C", 1.0, -40, -40, 102.0, 0
egoTemp = scalar, U08, 4, "C", 1.0, -40, -40, 102.0, 0
#else
egoTemp = scalar, U08, 4, "F", 1.8, -22.23, -40, 215.0, 0
egoTemp = scalar, U08, 4, "F", 1.8, -22.23, -40, 215.0, 0
#endif
egoCount = scalar, U08, 5, "", 4.0, 0.0, 4.0, 255.0, 0 ; * ( 1 byte)
unused6-6 = scalar, U08, 6, "%", 1.0, 0.0, 0.0, 255.0, 0
egoLimit = scalar, U08, 7, "", 1, 0, 0, 16, 0
ego_min = scalar, U08, 8, "AFR", 0.1, 0.0, 7, 25, 1
ego_max = scalar, U08, 9, "AFR", 0.1, 0.0, 7, 25, 1
egoCount = scalar, U08, 5, "", 4.0, 0.0, 4.0, 255.0, 0 ; * ( 1 byte)
vvtMode = bits, U08, 6, [0:1], "On/Off", "Open Loop", "Closed loop", "INVALID"
vvtLoadSource = bits, U08, 6, [2:3], "MAP", "TPS", "INVALID", "INVALID"
vvtCLDir = bits, U08, 6, [4:4], "Advance", "Retard"
vvtCLUseHold = bits, U08, 6, [5:5], "No", "Yes"
vvtCLAlterFuelTiming = bits, U08, 6, [6:6], "No", "Yes"
unused6-6 = bits, U08, 6, [7:7], "TPS", "MAP"
egoLimit = scalar, U08, 7, "", 1, 0, 0, 16, 0
ego_min = scalar, U08, 8, "AFR", 0.1, 0.0, 7, 25, 1
ego_max = scalar, U08, 9, "AFR", 0.1, 0.0, 7, 25, 1
ego_sdelay = scalar, U08, 10, "sec", 1, 0, 0, 120, 0
egoRPM = scalar, U08, 11, "rpm", 100, 0.0, 100, 25500, 0
egoTPSMax = scalar, U08, 12, "%", 1, 0, 0, 120, 0
@ -587,15 +595,11 @@ page = 7
tpsBinsBoost = array, U08, 72,[ 8], "TPS", 1.0, 0.0, 0.0, 255.0, 0
vvtTable = array, U08, 80,[8x8], "%", 1.0, 0.0, 0, 100, 0
rpmBinsVVT = array, U08, 144,[ 8], "RPM", 100.0, 0.0, 100, 25500, 0
tpsBinsVVT = array, U08, 152,[ 8], "TPS", 1.0, 0.0, 0.0, 255.0, 0
loadBinsVVT = array, U08, 152,[ 8], { bitStringValue(algorithmUnits , vvtLoadSource) }, 1.0, 0.0, 0.0, 255.0, 0
;Fuel staging Table
stagingTable = array, U08, 160, [8x8], "%", 1.0, 0.0, 0.0, 100.0, 0
rpmBinsStaging= array, U08, 224, [ 8], "RPM", 100.0, 0.0, 100.0, 25500.0, 0
#if SPEED_DENSITY
mapBinsStaging= array, U08, 232, [ 8], "kPa", 2.0, 0.0, 0.0, 511.0, 0
#elif ALPHA_N
tpsBinsStaging= array, U08, 232, [ 8], "TPS", 2.0, 0.0, 0.0, 100.0, 0
#endif
loadBinsStaging= array, U08, 232, [ 8], { bitStringValue(algorithmUnits , algorithm) }, 2.0, 0.0, 0.0, {fuelLoadMax}, 0
;--------------------------------------------------
;Sequential fuel trim tables (Page 8)
@ -603,35 +607,19 @@ page = 7
page = 8
fuelTrim1Table = array, U08, 0,[6x6], "%", 1.0, -128, -50, 50, 0
fuelTrim1rpmBins = array, U08, 36,[ 6], "RPM", 100.0, 0.0, 0, 25500, 0
#if SPEED_DENSITY
fuelTrim1loadBins = array, U08, 42,[ 6], "kPa", 2.0, 0.0, 0.0, 511.0, 0
#elif ALPHA_N
fuelTrim1loadBins = array, U08, 42,[ 6], "TPS", 2.0, 0.0, 0.0, 100.0, 0
#endif
fuelTrim1loadBins = array, U08, 42,[ 6], { bitStringValue(algorithmUnits , algorithm) }, 2.0, 0.0, 0.0, {fuelLoadMax}, 0
fuelTrim2Table = array, U08, 48,[6x6], "%", 1.0, -128, -50, 50, 0
fuelTrim2rpmBins = array, U08, 84,[ 6], "RPM", 100.0, 0.0, 0, 25500, 0
#if SPEED_DENSITY
fuelTrim2loadBins = array, U08, 90,[ 6], "kPa", 2.0, 0.0, 0.0, 511.0, 0
#elif ALPHA_N
fuelTrim2loadBins = array, U08, 90,[ 6], "TPS", 2.0, 0.0, 0.0, 100.0, 0
#endif
fuelTrim2loadBins = array, U08, 90,[ 6], { bitStringValue(algorithmUnits , algorithm) }, 2.0, 0.0, 0.0, {fuelLoadMax}, 0
fuelTrim3Table = array, U08, 96,[6x6], "%", 1.0, -128, -50, 50, 0
fuelTrim3rpmBins = array, U08, 132,[ 6], "RPM", 100.0, 0.0, 0, 25500, 0
#if SPEED_DENSITY
fuelTrim3loadBins = array, U08, 138,[ 6], "kPa", 2.0, 0.0, 0.0, 511.0, 0
#elif ALPHA_N
fuelTrim3loadBins = array, U08, 138,[ 6], "TPS", 2.0, 0.0, 0.0, 100.0, 0
#endif
fuelTrim3loadBins = array, U08, 138,[ 6], { bitStringValue(algorithmUnits , algorithm) }, 2.0, 0.0, 0.0, {fuelLoadMax}, 0
fuelTrim4Table = array, U08, 144,[6x6], "%", 1.0, -128, -50, 50, 0
fuelTrim4rpmBins = array, U08, 180,[ 6], "RPM", 100.0, 0.0, 0, 25500, 0
#if SPEED_DENSITY
fuelTrim4loadBins = array, U08, 186,[ 6], "kPa", 2.0, 0.0, 0.0, 511.0, 0
#elif ALPHA_N
fuelTrim4loadBins = array, U08, 186,[ 6], "TPS", 2.0, 0.0, 0.0, 100.0, 0
#endif
fuelTrim4loadBins = array, U08, 186,[ 6], { bitStringValue(algorithmUnits , algorithm) }, 2.0, 0.0, 0.0, {fuelLoadMax}, 0
;--------------------------------------------------
;CANBUS control and Auxillary io(Page 9)
@ -884,11 +872,8 @@ page = 10
EMAPPin = bits, U08, 8, [4:7], "A0", "A1", "A2", "A3", "A4", "A5", "A6", "A7", "A8", "A8", "A10", "A11", "A12", "A13", "A14", "A15"
rotarySplitValues = array, U08, 9, [8], "degrees", 1.0, 0.0, 0.0, 40, 0
#if SPEED_DENSITY
rotarySplitBins = array, U08, 17, [8], "kPa", 2.0, 0.0, 0.0, 511.0, 0
#elif ALPHA_N
rotarySplitBins = array, U08, 17, [8], "TPS", 2.0, 0.0, 0.0, 100.0, 0
#endif
rotarySplitBins = array, U08, 17, [8], { bitStringValue(algorithmUnits , algorithm) }, 2.0, 0.0, 0.0, {fuelLoadMax}, 0
boostSens = scalar, U16, 25, "", 1, 0, 0, 5000, 0
boostIntv = scalar, U08, 27, "ms", 1, 0, 0, 250, 0
stagedInjSizePri = scalar, U16, 28, "cc/min", 1, 0, 0, 1500, 0
@ -961,19 +946,28 @@ page = 10
;Things for the 2nd fuel table
fuel2Algorithm = bits, U08, 122, [0:2], $loadSourceNames
fuel2Mode = bits, U08, 122, [3:4], "Off", "Multiplied", "Added", "Switched"
unused10_212 = bits, U08, 122, [5:7], "INVALID","1","2","3","4","5","6","INVALID"
fuel2Mode = bits, U08, 122, [3:5], "Off", "Multiplied %", "Added", "Switched - Conditional", "Switched - Input based","INVALID","INVALID","INVALID"
fuel2SwitchVariable = bits, U08, 122, [6:7], "RPM", "MAP", "TPS", "ETH%"
fuel2SwitchValue = scalar, U16, 123, { bitStringValue(algorithmUnits, fuel2SwitchVariable) }, 1.0, 0.0, 0.0, 9000, 0
unused11_122_191 = array, U08, 123, [69], "RPM", 100.0, 0.0, 100, 25500, 0
;All related to the closed loop VVT control
vvtCLholdDuty = scalar, U08, 125, "%", 1.0, 0.0, 0.0, 100.0, 0
vvtCLKP = scalar, U08, 126, "%", 1.0, 0.0, 0.0, 200.0, 0 ; * ( 1 byte)
vvtCLKI = scalar, U08, 127, "%", 1.0, 0.0, 0.0, 200.0, 0 ; * ( 1 byte)
vvtCLKD = scalar, U08, 128, "%", 1.0, 0.0, 0.0, 200.0, 0 ; * ( 1 byte)
vvtCLMinAng = scalar, U16, 129, "deg", 1.0, 0.0, 0.0, 360.0, 0 ; * ( 1 bytes)
vvtCLMaxAng = scalar, U16, 131, "deg", 1.0, 0.0, 0.0, 360.0, 0 ; * ( 1 bytes)
unused11_122_191 = array, U08, 126, [58], "RPM", 100.0, 0.0, 100, 25500, 0
;Page 11 is the fuel map and axis bins only
page = 11
; name = bits, type, offset, bits
; name = array, type, offset, shape, units, scale, translate, lo, hi, digits
; name = scalar, type, offset, units, scale, translate, lo, hi, digits
veTable2 = array, U08, 0, [16x16],"%", 1.0, 0.0, 0.0, 255.0, 0
fuelRPM2Bins = array, U08, 256, [ 16], "RPM", 100.0, 0.0, 100.0, 25500.0, 0
fuelLoad2Bins = array, U08, 272, [ 16], { bitStringValue(algorithmUnits , fuel2Algorithm) }, 2.0, 0.0, 0.0, {fuelLoadMax}, 0
; name = bits, type, offset, bits
; name = array, type, offset, shape, units, scale, translate, lo, hi, digits
; name = scalar, type, offset, units, scale, translate, lo, hi, digits
veTable2 = array, U08, 0, [16x16],"%", 1.0, 0.0, 0.0, 255.0, 0
fuelRPM2Bins = array, U08, 256, [ 16], "RPM", 100.0, 0.0, 0.0, 25500.0, 0
fuelLoad2Bins = array, U08, 272, [ 16], { bitStringValue(algorithmUnits , fuel2Algorithm) }, 2.0, 0.0, 0.0, {fuelLoadMax}, 0
;-------------------------------------------------------------------------------
@ -1021,12 +1015,13 @@ page = 11
requiresPowerCycle = knock_trigger
requiresPowerCycle = knock_pullup
requiresPowerCycle = idleUpEnabled
requiresPowerCycle = legacyMAP
requiresPowerCycle = caninput_sel0a
requiresPowerCycle = caninput_sel0b
requiresPowerCycle = caninput_sel1a
requiresPowerCycle = caninput_sel1b
requiresPowerCycle = caninput_sel2a
requiresPowerCycle = caninput_sel2a
requiresPowerCycle = caninput_sel2b
requiresPowerCycle = caninput_sel3a
requiresPowerCycle = caninput_sel3b
@ -1105,9 +1100,11 @@ page = 11
defaultValue = lnchCtrlTPS, 0
defaultValue = resetControl, 0
defaultValue = bootloaderCaps, 0
defaultValue = taeTaperMin, 1000
defaultValue = taeTaperMax, 5000
; defaultValue = obd_address, 0
defaultValue = aeTaperMin, 1000
defaultValue = aeTaperMax, 5000
defaultValue = aeMode, 0 ;Set aeMode to TPS
defaultValue = batVoltCorrect, 0
defaultValue = legacyMAP, 0
;Default pins
defaultValue = fanPin, 0
@ -1143,13 +1140,10 @@ page = 11
;These are the limits for each of the load algorithms (Refer to the PC Variables section)
;Order is: MAP TPS IMAP/EMAP ITB UNUSED UNUSED UNUSED UNUSED
defaultValue = algorithmLimits, 511 100 511 511 100 100 100 100
#if SPEED_DENSITY
defaultValue = fuelLoadMax, 511
defaultValue = ignLoadMax, 511
#else
defaultValue = fuelLoadMax, 511
defaultValue = ignLoadMax, 511
#endif
controllerPriority = bootloaderCaps
@ -1231,12 +1225,11 @@ menuDialog = main
;subMenu = knockSettings, "Knock Settings"
subMenu = rotary_ignition, "Rotary Ignition", { sparkMode == 4 }
menu = "&Starting/Idle"
menu = "&Startup/Idle"
subMenu = crankPW, "Cranking Settings"
subMenu = primePW, "Priming Pulsewidth"
subMenu = warmup, "Warmup Enrichment"
subMenu = ASE, "Afterstart Enrichment - Percentage"
subMenu = ASE_time, "Afterstart Enrichment - Duration"
subMenu = ASE, "Afterstart Enrichment (ASE)"
subMenu = std_separator
subMenu = idleSettings, "Idle Control"
subMenu = iacClosedLoop_curve, "Idle - Closed loop targets", 7, { iacAlgorithm == 3 || iacAlgorithm == 5 }
@ -1280,8 +1273,9 @@ menuDialog = main
menuDialog = main
menu = "Tools"
subMenu = mapCal, "Calibrate Pressure Sensors"
subMenu = batCal, "Calibrate Voltage Reading"
subMenu = std_ms2gentherm, "Calibrate Temperature Sensors", 0
subMenu = std_ms2geno2, "Calibrate AFR Sensor", 0
subMenu = std_ms2geno2, "Calibrate AFR Sensor", { egoType > 0 }
subMenu = sensorFilters, "Set analog sensor filters"
menuDialog = main
@ -1336,7 +1330,7 @@ menuDialog = main
fanInv = ""
fanHyster = "The number of degrees of hysteresis to be used in controlling the fan. Recommended values are between 2 and 5"
taeTime = "The duration of the acceleration enrichment"
aeTime = "The duration of the acceleration enrichment"
iacChannels = "The number of output channels used for PWM valves. Select 1 for 2-wire valves or 2 for 3-wire valves."
iacStepTime = "Pause time between each step. Values that are too low can cause the motor to behave erratically or not at all"
@ -1368,6 +1362,7 @@ menuDialog = main
ignCranklock = "On certain low resolution ignition patterns, the cranking timing can be locked to occur when a pulse is recieved."
multiplyMAP = "If enabled, the MAP reading is included directly into the pulsewidth calculation by multiplying the VE lookup value by the MAP:Baro ratio. This results in a flatter VE table that can be easier to tune in some instances. VE table must be retuned when this value is changed."
legacyMAP = "Use the legacy method of reading the MAP sensor that was used prior to the 201905 firmware. This should ONLY be enabled if you are upgrading from a firmware earlier than this"
includeAFR = "When enabled, the current AFR reading is incorporated directly in the pulsewidth calculation as a percentage of the current target ratio. VE table must be retuned when this value is changed. "
useExtBaro = "By Default, Speeduino will measure barometric pressure upon startup. Optionally however, a 2nd pressure sensor can be used to perform live barometric readings whilst the system is on."
@ -1388,9 +1383,7 @@ menuDialog = main
enable_secondarySerial = "This Enables the secondary serial port . Secondary serial is serial3 on mega2560 processor, and Serial2 on STM32 and Teensy processor "
cltAdvValues = "This curve can be used to advance ignition timing when engine is warming up. This can also be used to warm up the catalytic converters in cold start by retarding timing. Or even as safety feature to retard timign when engine is too hot to prevent knock."
asePct = "Defines the fuel enrichment percentage after start. This is needed to keep engine running after start and it's usually about 5% when engine is hot to 50% when engine is cold."
aseCount = "Will set how long time the After Start Enrichment is applied in seconds. Usually this is second or two when engine is hot up to 10 or twenty on really cold engine."
cltAdvValues = "This curve can be used to advance ignition timing when engine is warming up. This can also be used to warm up the catalytic converters in cold start by retarding timing. Or even as safety feature to retard timing when engine is too hot to prevent knock."
;speeduino_tsCanId = "This is the TsCanId that the Speeduino ECU will respond to. This should match the main controller CAN ID in project properties if it is connected directy to TunerStudio, Otherwise the device ID if connected via CAN passthrough"
true_address = "This is the 11bit Can address of the Speeduino ECU "
@ -1641,11 +1634,13 @@ menuDialog = main
field = "Output speed", tachoDiv
field = "Pulse duration", tachoDuration
dialog = accelEnrichments_center, ""
field = "TPSdot Threshold", tpsThresh
field = "Accel Time", taeTime
field = "Taper Start RPM", taeTaperMin
field = "Taper End RPM", taeTaperMax
dialog = accelEnrichments_center, "Acceleration Enrichment"
field = "Enrichment mode", aeMode
field = "TPSdot Threshold", taeThresh, { aeMode == 0 }
field = "MAPdot Threshold", maeThresh, { aeMode == 1 }
field = "Accel Time", aeTime
field = "Taper Start RPM", aeTaperMin
field = "Taper End RPM", aeTaperMax
dialog = accelEnrichments_south, "Decelleration Fuel Cutoff (DFCO)"
field = "Enabled", dfcoEnabled
@ -1657,9 +1652,11 @@ menuDialog = main
liveGraph = pump_ae_Graph, "AE Graph"
graphLine = afr
graphLine = TPSdot, "%", -2000, 2000, auto, auto
graphLine = MAPdot, "%", -2000, 2000, auto, auto
dialog = accelEnrichments_north, "", xAxis
panel = time_accel_tpsdot_curve
panel = time_accel_tpsdot_curve, { aeMode == 0 }
panel = time_accel_mapdot_curve, { aeMode == 1 }
dialog = accelEnrichments, "Acceleration Enrichment"
topicHelp = "http://speeduino.com/wiki/index.php/Acceleration_Wizard"
@ -1705,6 +1702,7 @@ menuDialog = main
dialog = egoControl, ""
topicHelp = "http://speeduino.com/wiki/index.php/AFR/O2"
field = "Sensor Type", egoType
field = "#Please ensure you calibrate your O2 sensor in the Tools menu", { egoType }
field = "Algorithm", egoAlgorithm, { egoType }
field = "Ignition Events per Step", egoCount, { egoType && (egoAlgorithm < 3) }
field = "Controller Auth +/-", egoLimit, { egoType && (egoAlgorithm < 3) }
@ -1790,16 +1788,22 @@ menuDialog = main
panel = crankingEnrichDialog, Center
panel = crankingIgnOptions, South
dialog = ASE, "Afterstart Enrichment(ASE) - Percent Multiplier"
field = "Coolant axis is shared with ASE duration"
field = ""
dialog = ASE_amount, "Enrichment amount (%)", yAxis
field = "Defines the fuel enrichment percentage after start."
field = "This is needed to keep engine running after start"
field = "Common values are 5% when engine is hot to 50% when engine is cold."
panel = afterstart_enrichment_curve
dialog = ASE_time, "Afterstart Enrichment(ASE) - Number of seconds to run"
field = "Coolant axis is shared with ASE percentage"
field = ""
dialog = ASE_time, "Duration (s)", yAxis
field = "How long time the After Start Enrichment is applied in seconds."
field = "Usually this is varies from 1-2s when engine is hot up to 20s on a cold engine."
panel = afterstart_enrichment_time
dialog = ASE, "Afterstart Enrichment(ASE)", yAxis
field = "#Time and duration curves share common coolant values"
panel = ASE_amount
panel = ASE_time
dialog = triggerSettings,"Trigger Settings",4
topicHelp = "http://speeduino.com/wiki/index.php/Decoders"
field = "Trigger Pattern", TrigPattern
@ -1940,6 +1944,9 @@ menuDialog = main
;field = "Bar 1", displayB1, { display }
;field = "Bar 2", displayB2, { display > 2 }
dialog = batCal, "Calibrate voltage reading"
slider = "Battery Voltage reading offset", batVoltCorrect, horizontal
dialog = mapCal, "Calibrate MAP"
field = "#MAP Sensor"
settingSelector = "Common Pressure Sensors"
@ -1957,6 +1964,7 @@ menuDialog = main
field = "kPa At 0.0 Volts", mapMin
field = "kPa At 5.0 Volts", mapMax
field = "Use legacy MAP reading",legacyMAP
field = "#Baro Sensor"
field = "Use external Baro sensor", useExtBaro
@ -2013,7 +2021,7 @@ menuDialog = main
dialog = boostSettings, "Boost Control"
topicHelp = "http://speeduino.com/wiki/index.php/Boost_Control"
field = "Boost Control Enabled", boostEnabled
field = "Boost control type", boostType
field = "Boost control type", boostType, { boostEnabled }
field = "Boost output pin", boostPin, { boostEnabled }
field = "Boost solenoid freq.", boostFreq, { boostEnabled }
@ -2028,12 +2036,26 @@ menuDialog = main
field = "I", boostKI, { boostEnabled && boostMode && boostType == 1 }
field = "D", boostKD, { boostEnabled && boostMode && boostType == 1 }
dialog = vvtClosedLoop, "Closed loop"
field = "Increased duty direction", vvtCLDir
field = "Hold duty used", vvtCLUseHold
field = "Hold duty", vvtCLholdDuty, { vvtCLUseHold }
field = "Adjust fuel timing", vvtCLAlterFuelTiming
field = "Cam angle @ 0% duty", vvtCLMinAng
field = ""
field = "Proportional Gain", vvtCLKP
field = "Integral Gain", vvtCLKI
field = "Differential Gain", vvtCLKD
dialog = vvtSettings, "VVT Control"
field = "VVT Control Enabled", vvtEnabled
field = "Use VVT map as On / Off only", VVTasOnOff, { vvtEnabled }
field = "VVT Mode", vvtMode, { vvtEnabled }
field = "Load source", vvtLoadSource, { vvtEnabled }
field = "Use VVT map as On / Off only", VVTasOnOff, { vvtEnabled && vvtMode != 2 }
field = "VVT output pin", vvtPin, { vvtEnabled }
field = "VVT solenoid freq.", vvtFreq, { vvtEnabled }
panel = vvtClosedLoop, { vvtEnabled && vvtMode == 2 }
dialog = warmup, "Warmup Enrichment (WUE) - Percent Multiplier"
@ -2104,19 +2126,19 @@ menuDialog = main
dialog = outputtestinj1, "Injector CH1", yAxis
commandButton = "Off", cmdtestinj1off,{testactive}
commandButton = "50% DC", cmdtestinj150dc,{!testenabled & testactive}
commandButton = "50% DC", cmdtestinj150dc,{!testenabled & testactive & 0}
commandButton = "On", cmdtestinj1on,{!testenabled & testactive}
dialog = outputtestinj2, "Injector CH2", yAxis
commandButton = "Off", cmdtestinj2off,{testactive}
commandButton = "50% DC", cmdtestinj250dc,{!testenabled &testactive}
commandButton = "50% DC", cmdtestinj250dc,{!testenabled &testactive & 0}
commandButton = "On", cmdtestinj2on,{!testenabled & testactive}
dialog = outputtestinj3, "Injector CH3", yAxis
commandButton = "Off", cmdtestinj3off,{testactive}
commandButton = "50% DC", cmdtestinj350dc,{!testenabled & testactive}
commandButton = "50% DC", cmdtestinj350dc,{!testenabled & testactive & 0}
commandButton = "On", cmdtestinj3on,{!testenabled & testactive}
dialog = outputtestinj4, "Injector CH4", yAxis
commandButton = "Off", cmdtestinj4off,{testactive}
commandButton = "50% DC", cmdtestinj450dc,{!testenabled & testactive}
commandButton = "50% DC", cmdtestinj450dc,{!testenabled & testactive & 0}
commandButton = "On", cmdtestinj4on ,{!testenabled & testactive}
dialog = outputtest_injectors, "Injector Driver Output Test", xAxis
@ -2127,19 +2149,19 @@ menuDialog = main
dialog = outputtestspk1, "Spark CH1 ", yAxis
commandButton = "Off", cmdtestspk1off,{testactive}
commandButton = "50% DC", cmdtestspk150dc,{!testenabled & testactive}
commandButton = "50% DC", cmdtestspk150dc,{!testenabled & testactive & 0}
commandButton = "On", cmdtestspk1on,{!testenabled & testactive}
dialog = outputtestspk2, "Spark CH2", yAxis
commandButton = "Off", cmdtestspk2off,{testactive}
commandButton = "50% DC", cmdtestspk250dc,{!testenabled & testactive}
commandButton = "50% DC", cmdtestspk250dc,{!testenabled & testactive & 0}
commandButton = "On", cmdtestspk2on,{!testenabled & testactive}
dialog = outputtestspk3, "Spark CH3", yAxis
commandButton = "Off", cmdtestspk3off,{testactive}
commandButton = "50% DC", cmdtestspk350dc,{!testenabled & testactive}
commandButton = "50% DC", cmdtestspk350dc,{!testenabled & testactive & 0}
commandButton = "On", cmdtestspk3on,{!testenabled & testactive}
dialog = outputtestspk4, "Spark CH4", yAxis
commandButton = "Off", cmdtestspk4off,{testactive}
commandButton = "50% DC", cmdtestspk450dc,{!testenabled & testactive}
commandButton = "50% DC", cmdtestspk450dc,{!testenabled & testactive & 0}
commandButton = "On", cmdtestspk4on,{!testenabled & testactive}
dialog = outputtest_spark, "Spark Driver Output Test", xAxis
@ -2712,14 +2734,21 @@ cmdtestspk450dc = "E\x03\x0C"
[CurveEditor]
;time-based accel enrichment
;tps-based accel enrichment
curve = time_accel_tpsdot_curve, "TPS based AE"
columnLabel = "TPSdot", "Added"
xAxis = 0, 1200, 6
yAxis = 0, 250, 4
xBins = taeBins, TPSdot
yBins = taeRates
;gauge = cltGauge
;map-based accel enrichment
curve = time_accel_mapdot_curve, "MAP based AE"
columnLabel = "MAPdot", "Added"
xAxis = 0, 1200, 6
yAxis = 0, 250, 4
xBins = maeBins, MAPdot
yBins = maeRates
; Correction curve for dwell vs battery voltage
curve = dwell_correction_curve, "Dwell voltage correction"
@ -2810,13 +2839,8 @@ cmdtestspk450dc = "E\x03\x0C"
curve = rotaryTrailing_curve, "Rotary Trailing Split"
columnLabel = "Engine load", "Split"
yAxis = 0, 40, 4
#if SPEED_DENSITY
xBins = rotarySplitBins, map
xAxis = 0, 250, 5
#else
xBins = rotarySplitBins, throttle
xAxis = 0, 100, 5
#endif
xBins = rotarySplitBins, fuelLoad
xAxis = 0, { fuelLoadMax }, 5
yBins = rotarySplitValues
; Warmup enrichment curve
@ -2841,7 +2865,7 @@ cmdtestspk450dc = "E\x03\x0C"
curve = priming_pw_curve, "Priming Pulsewidth"
columnLabel = "Coolant", "PW"
xAxis = -40, 110, 4
yAxis = 0, 25.5, 4
yAxis = 0, 10, 4
xBins = primeBins, coolant
yBins = primePulse
gauge = cltGauge
@ -2854,6 +2878,7 @@ cmdtestspk450dc = "E\x03\x0C"
xBins = aseBins, coolant
yBins = asePct
gauge = cltGauge
size = 50, 250
; Afterstart Enrichment time
curve = afterstart_enrichment_time, "ASE - Duration"
@ -2863,6 +2888,7 @@ cmdtestspk450dc = "E\x03\x0C"
xBins = aseBins, coolant
yBins = aseCount
gauge = cltGauge
size = 50, 250
; Warmup enrichment VEAL AFR adjustment curve (Not currently working)
;curve = warmup_afr_curve, "AFR Target Temperature Adustment"
@ -2916,7 +2942,7 @@ cmdtestspk450dc = "E\x03\x0C"
[TableEditor]
; table_id, map3d_id, "title", page
table = veTable1Tbl, veTable1Map, "VE Table", 1
table = veTable1Tbl, veTable1Map, "VE Table", 2
topicHelp = "http://speeduino.com/wiki/index.php/Tuning"
; constant, variable
xBins = rpmBins, rpm
@ -2928,10 +2954,10 @@ cmdtestspk450dc = "E\x03\x0C"
gridOrient = 250, 0, 340
upDownLabel = "(RICHER)", "(LEANER)"
table = fuelTable2Tbl, fuel2Map, "Fuel Table 2", 1
table = fuelTable2Tbl, fuel2Map, "Fuel Table 2", 11
topicHelp = "http://speeduino.com/wiki/index.php/Tuning"
xBins = fuelRPM2Bins, rpm
yBins = fuelLoad2Bins, fuelLoad
yBins = fuelLoad2Bins, fuelLoad2
xyLabels = "RPM", "Fuel Load: "
zBins = veTable2
@ -2951,11 +2977,7 @@ cmdtestspk450dc = "E\x03\x0C"
;table = afrTbl, afrTableMap, "AFR Table", 5
table = afrTable1Tbl, afrTable1Map, "AFR Table", 5
xBins = rpmBinsAFR, rpm
#if SPEED_DENSITY
yBins = mapBinsAFR, map
#else ALPHA_N
yBins = tpsBinsAFR, throttle
#endif
yBins = loadBinsAFR, fuelLoad
zBins = afrTable
gridHeight = 1.0
upDownLabel = "RICHER", "LEANER"
@ -2975,18 +2997,16 @@ cmdtestspk450dc = "E\x03\x0C"
table = vvtTbl, vvtMap, "VVT control Table", 8
xBins = rpmBinsVVT, rpm
yBins = tpsBinsVVT, throttle
;yBins = tpsBinsVVT, throttle
yBins = loadBinsVVT, vvtLoad
zBins = vvtTable
xyLabels = "RPM", "VVT Load: "
gridHeight = 3.0
upDownLabel = "HIGHER", "LOWER"
table = stagingTbl, stagingMap, "Fuel Staging Table", 10
xBins = rpmBinsStaging, rpm
#if SPEED_DENSITY
yBins = mapBinsStaging, map
#else ALPHA_N
yBins = tpsBinsStaging, throttle
#endif
yBins = loadBinsStaging, fuelLoad
zBins = stagingTable
gridHeight = 3.0
upDownLabel = "HIGHER", "LOWER"
@ -2995,40 +3015,28 @@ cmdtestspk450dc = "E\x03\x0C"
table = fuelTrimTable1Tbl, fuelTrimTable1Map, "Fuel trim Table 1", 9
topicHelp = "http://speeduino.com/wiki/index.php/Tuning"
xBins = fuelTrim1rpmBins, rpm
#if SPEED_DENSITY
yBins = fuelTrim1loadBins, map
#else
yBins = fuelTrim1loadBins, throttle
#endif
zBins = fuelTrim1Table
yBins = fuelTrim1loadBins, fuelLoad
zBins = fuelTrim1Table
gridHeight = 2.0
gridOrient = 250, 0, 340
upDownLabel = "(RICHER)", "(LEANER)"
gridHeight = 2.0
gridOrient = 250, 0, 340
upDownLabel = "(RICHER)", "(LEANER)"
table = fuelTrimTable2Tbl, fuelTrimTable2Map, "Fuel trim Table 2", 9
topicHelp = "http://speeduino.com/wiki/index.php/Tuning"
xBins = fuelTrim2rpmBins, rpm
#if SPEED_DENSITY
yBins = fuelTrim2loadBins, map
#else
yBins = fuelTrim2loadBins, throttle
#endif
zBins = fuelTrim2Table
yBins = fuelTrim2loadBins, fuelLoad
zBins = fuelTrim2Table
gridHeight = 2.0
gridOrient = 250, 0, 340
upDownLabel = "(RICHER)", "(LEANER)"
gridHeight = 2.0
gridOrient = 250, 0, 340
upDownLabel = "(RICHER)", "(LEANER)"
table = fuelTrimTable3Tbl, fuelTrimTable3Map, "Fuel trim Table 3", 9
topicHelp = "http://speeduino.com/wiki/index.php/Tuning"
xBins = fuelTrim3rpmBins, rpm
#if SPEED_DENSITY
yBins = fuelTrim3loadBins, map
#else
yBins = fuelTrim3loadBins, throttle
#endif
zBins = fuelTrim3Table
yBins = fuelTrim3loadBins, fuelLoad
zBins = fuelTrim3Table
gridHeight = 2.0
gridOrient = 250, 0, 340
@ -3037,12 +3045,8 @@ cmdtestspk450dc = "E\x03\x0C"
table = fuelTrimTable4Tbl, fuelTrimTable4Map, "Fuel trim Table 4", 9
topicHelp = "http://speeduino.com/wiki/index.php/Tuning"
xBins = fuelTrim4rpmBins, rpm
#if SPEED_DENSITY
yBins = fuelTrim4loadBins, map
#else
yBins = fuelTrim4loadBins, throttle
#endif
zBins = fuelTrim4Table
yBins = fuelTrim4loadBins, fuelLoad
zBins = fuelTrim4Table
gridHeight = 2.0
gridOrient = 250, 0, 340
@ -3082,7 +3086,7 @@ cmdtestspk450dc = "E\x03\x0C"
gammaEnrichGauge = gammaEnrich, "Gamma Enrichment", "%", 50, 150, -1, -1, 151, 151, 0, 0
pulseWidthGauge = pulseWidth, "Pulse Width", "mSec", 0, 35.0, 1.0, 1.2, 20, 25, 3, 3
tachometer = rpm, "Engine Speed", "RPM", 0, 8000, 300, 600, 3000, 5000, 0, 0
veGauge = veCurr, "VE Current", "%", 0, 120, -1, -1, 999, 999, 0, 0
veGauge = veCurr, "VE 1 Current", "%", 0, 120, -1, -1, 999, 999, 0, 0
warmupEnrichGauge = warmupEnrich, "Warmup Enrichment", "%", 100, 200, 130, 140, 140, 150, 0, 0
aseEnrichGauge = ase_enrich, "Afterstart Enrichment","%", 0, 200, 130, 140, 140, 150, 0, 0
batCorrectGauge = batCorrection, "Voltage Correction", "%", 0, 200, 130, 140, 140, 150, 0, 0
@ -3096,6 +3100,7 @@ cmdtestspk450dc = "E\x03\x0C"
mapGauge_psi = map_psi, "Engine MAP (PSI)", "PSI", -15, 100, 0, 20, 200, 245, 0, 0
mapGauge_bar = map_bar, "Engine MAP (BAR)", "Bar", -1, 3, -1, -1, 5, 5, 2, 2
mapGauge_vacBoost = map_vacboost, "Engine MAP (in-Hg/PSI)", "in-Hg/PSI", -30, 30, -30, -30, 30, 30, 1, 1
baroGauge = baro, "Baro Pressure", "kPa", 0, 255, 0, 20, 200, 245, 0, 0
batteryVoltage = batteryVoltage,"Battery Voltage", "volts", 0, 25, 8, 9, 15, 16, 2, 2
tpsADCGauge = tpsADC, "TPS ADC", "", 0, 255, -1, -1, 256, 256, 0, 0
@ -3192,7 +3197,7 @@ cmdtestspk450dc = "E\x03\x0C"
; you change it.
ochGetCommand = "r\$tsCanId\x30%2o%2c"
ochBlockSize = 92
ochBlockSize = 94
secl = scalar, U08, 0, "sec", 1.000, 0.000
status1 = scalar, U08, 1, "bits", 1.000, 0.000
@ -3292,7 +3297,8 @@ cmdtestspk450dc = "E\x03\x0C"
ignLoad = scalar, S16, 87, { bitStringValue( algorithmUnits , ignAlgorithm ) }, 1.000, 0.000
dwell = scalar, U16, 89, "ms", 0.001, 0.000
CLIdleTarget = scalar, U08, 91, "RPM", 10.00, 0.000
MAPdot = scalar, U08, 92, "kPa/s", 10.00, 0.000
vvtAngle = scalar, U08, 93, "deg", 1.00, 0.000
#if CELSIUS
coolant = { coolantRaw - 40 } ; Temperature readings are offset by 40 to allow for negatives
@ -3306,11 +3312,14 @@ cmdtestspk450dc = "E\x03\x0C"
throttle = { tps }, "%"
cycleTime = { rpm ? ( 60000.0 / rpm ) : 0 }
cycleMultiplier = { injLayout == 3 ? 2 : 1 }
strokeMultipler = { twoStroke == 1 ? 2 : 1 }
dutyCycle = { rpm ? ( 100.0*pulseWidth/(cycleTime * cycleMultiplier) * strokeMultipler ) : 0 }
stgDutyCycle = { rpm && stagingEnabled ? ( 100.0*pulseWidth3/(cycleTime * cycleMultiplier) * strokeMultipler ) : 0 }
revolutionTime = { rpm ? ( 60000.0 / rpm) : 0 }
strokeMultipler = { twoStroke == 1 ? 1 : 2 }
cycleTime = { revolutionTime * strokeMultipler }
pulseLimit = { cycleTime / nSquirts }
dutyCycle = { rpm ? ( 100.0*pulseWidth/pulseLimit ) : 0 }
stgDutyCycle = { rpm && stagingEnabled ? ( 100.0*pulseWidth3/pulseLimit ) : 0 }
boostCutOut = { boostCutFuel || boostCutSpark }
lambda = { afr / stoich }
@ -3332,6 +3341,9 @@ cmdtestspk450dc = "E\x03\x0C"
fuelLoadMax = { (algorithm == 0 || algorithm == 2) ? 511 : 100 }
ignLoadMax = { (ignAlgorithm == 0 || ignAlgorithm == 2) ? 511 : 100 }
fuelLoad2 = { fuel2Algorithm == 0 ? map : fuel2Algorithm == 1 ? tps : fuel2Algorithm == 2 ? 0 : 0 }
vvtLoad = { (vvtLoadSource == 0) ? map : tps }
boostTableLimit = { boostType == 0 ? 100 : 511 } ;The maximum value allowed in the boost table. 100 is used for duty cycle, 511 for kpa
CLIdleDelta = { CLIdleTarget - rpm }
@ -3374,7 +3386,7 @@ cmdtestspk450dc = "E\x03\x0C"
;entry = baroCorrection, "Gbaro", int, "%d"
entry = gammaEnrich, "Gammae", int, "%d"
entry = accelEnrich, "Accel Enrich", int, "%d"
entry = veCurr, "VE", int, "%d"
entry = veCurr, "VE1", int, "%d"
entry = pulseWidth, "PW", float, "%.1f"
entry = afrTarget, "AFR Target", float, "%.3f"
entry = pulseWidth, "PW2", float, "%.1f"
@ -3401,6 +3413,7 @@ cmdtestspk450dc = "E\x03\x0C"
entry = baro, "Baro Pressure",int, "%d"
entry = nitrousOn, "Nitrous", int, "onOff", { n2o_enable > 0 }
entry = syncLossCounter, "Sync Loss #", int, "%d"
entry = vvtAngle, "VVT Angle", int, "%d", { vvtMode == 2 } ;;Only show when using close loop vvt
entry = auxin_gauge0, "AuxIn CH0", int, "%d"
entry = auxin_gauge1, "AuxIn CH1", int, "%d"

View File

@ -37,7 +37,7 @@
#define FUEL2_COUNTER TCNT3
#define FUEL3_COUNTER TCNT3
#define FUEL4_COUNTER TCNT4
#define FUEL5_COUNTER TCNT1
#define FUEL5_COUNTER TCNT4
#define FUEL6_COUNTER TCNT4 //Replaces ignition 4
#define FUEL7_COUNTER TCNT5 //Replaces ignition 3
#define FUEL8_COUNTER TCNT5 //Replaces ignition 2
@ -46,7 +46,7 @@
#define IGN2_COUNTER TCNT5
#define IGN3_COUNTER TCNT5
#define IGN4_COUNTER TCNT4
#define IGN5_COUNTER TCNT1
#define IGN5_COUNTER TCNT4
#define IGN6_COUNTER TCNT4 //Replaces injector 4
#define IGN7_COUNTER TCNT3 //Replaces injector 3
#define IGN8_COUNTER TCNT3 //Replaces injector 2
@ -55,7 +55,7 @@
#define FUEL2_COMPARE OCR3B
#define FUEL3_COMPARE OCR3C
#define FUEL4_COMPARE OCR4B
#define FUEL5_COMPARE OCR1C //Shared with FUEL1
#define FUEL5_COMPARE OCR4C //Shared with FUEL1
#define FUEL6_COMPARE OCR4A //Replaces ignition4
#define FUEL7_COMPARE OCR5C //Replaces ignition3
#define FUEL8_COMPARE OCR5B //Replaces ignition2
@ -64,7 +64,7 @@
#define IGN2_COMPARE OCR5B
#define IGN3_COMPARE OCR5C
#define IGN4_COMPARE OCR4A
#define IGN5_COMPARE OCR1C
#define IGN5_COMPARE OCR4C
#define IGN6_COMPARE OCR4B //Replaces injector 4
#define IGN7_COMPARE OCR3C //Replaces injector 3
#define IGN8_COMPARE OCR3B //Replaces injector 2
@ -73,7 +73,7 @@
#define FUEL2_TIMER_ENABLE() TIMSK3 |= (1 << OCIE3B) //Turn on the B compare unit (ie turn on the interrupt)
#define FUEL3_TIMER_ENABLE() TIMSK3 |= (1 << OCIE3C) //Turn on the C compare unit (ie turn on the interrupt)
#define FUEL4_TIMER_ENABLE() TIMSK4 |= (1 << OCIE4B) //Turn on the B compare unit (ie turn on the interrupt)
#define FUEL5_TIMER_ENABLE() TIMSK1 |= (1 << OCIE1C) //
#define FUEL5_TIMER_ENABLE() TIMSK4 |= (1 << OCIE4C) //
#define FUEL6_TIMER_ENABLE() TIMSK4 |= (1 << OCIE4A) //
#define FUEL7_TIMER_ENABLE() TIMSK5 |= (1 << OCIE5C) //
#define FUEL8_TIMER_ENABLE() TIMSK5 |= (1 << OCIE5B) //
@ -82,7 +82,7 @@
#define FUEL2_TIMER_DISABLE() TIMSK3 &= ~(1 << OCIE3B); //Turn off this output compare unit
#define FUEL3_TIMER_DISABLE() TIMSK3 &= ~(1 << OCIE3C); //Turn off this output compare unit
#define FUEL4_TIMER_DISABLE() TIMSK4 &= ~(1 << OCIE4B); //Turn off this output compare unit
#define FUEL5_TIMER_DISABLE() TIMSK1 &= ~(1 << OCIE1C); //
#define FUEL5_TIMER_DISABLE() TIMSK4 &= ~(1 << OCIE4C); //
#define FUEL6_TIMER_DISABLE() TIMSK4 &= ~(1 << OCIE4A); //
#define FUEL7_TIMER_DISABLE() TIMSK5 &= ~(1 << OCIE5C); //
#define FUEL8_TIMER_DISABLE() TIMSK5 &= ~(1 << OCIE5B); //
@ -96,7 +96,7 @@
//#define IGN2_TIMER_ENABLE() TIMSK5 |= (1 << OCIE5B) //Turn on the B compare unit (ie turn on the interrupt)
//#define IGN3_TIMER_ENABLE() TIMSK5 |= (1 << OCIE5C) //Turn on the C compare unit (ie turn on the interrupt)
#define IGN4_TIMER_ENABLE() TIMSK4 |= (1 << OCIE4A) //Turn on the A compare unit (ie turn on the interrupt)
#define IGN5_TIMER_ENABLE() TIMSK1 |= (1 << OCIE1C) //Turn on the A compare unit (ie turn on the interrupt)
#define IGN5_TIMER_ENABLE() TIMSK4 |= (1 << OCIE4C) //Turn on the A compare unit (ie turn on the interrupt)
#define IGN6_TIMER_ENABLE() TIMSK4 |= (1 << OCIE4B) //Replaces injector 4
#define IGN7_TIMER_ENABLE() TIMSK3 |= (1 << OCIE3C) //Replaces injector 3
#define IGN8_TIMER_ENABLE() TIMSK3 |= (1 << OCIE3B) //Replaces injector 2
@ -105,16 +105,16 @@
#define IGN2_TIMER_DISABLE() TIMSK5 &= ~(1 << OCIE5B) //Turn off this output compare unit
#define IGN3_TIMER_DISABLE() TIMSK5 &= ~(1 << OCIE5C) //Turn off this output compare unit
#define IGN4_TIMER_DISABLE() TIMSK4 &= ~(1 << OCIE4A) //Turn off this output compare unit
#define IGN5_TIMER_DISABLE() TIMSK1 &= ~(1 << OCIE1C) //Turn off this output compare unit
#define IGN5_TIMER_DISABLE() TIMSK4 &= ~(1 << OCIE4C) //Turn off this output compare unit
#define IGN6_TIMER_DISABLE() TIMSK4 &= ~(1 << OCIE4B) //Replaces injector 4
#define IGN7_TIMER_DISABLE() TIMSK3 &= ~(1 << OCIE3C) //Replaces injector 3
#define IGN8_TIMER_DISABLE() TIMSK3 &= ~(1 << OCIE3B) //Replaces injector 2
#define MAX_TIMER_PERIOD 262140UL //The longest period of time (in uS) that the timer can permit (IN this case it is 65535 * 4, as each timer tick is 4uS)
#define MAX_TIMER_PERIOD_SLOW 1048560UL //The longest period of time (in uS) that the timer can permit (IN this case it is 65535 * 16, as each timer tick is 16uS)
#define uS_TO_TIMER_COMPARE(uS1) (uS1 >> 2) //Converts a given number of uS into the required number of timer ticks until that time has passed
#define MAX_TIMER_PERIOD_SLOW 262140UL //The longest period of time (in uS) that the timer can permit (IN this case it is 65535 * 16, as each timer tick is 16uS)
#define uS_TO_TIMER_COMPARE(uS1) ((uS1) >> 2) //Converts a given number of uS into the required number of timer ticks until that time has passed
//This is a hack until I make all the AVR timers run at the same speed
#define uS_TO_TIMER_COMPARE_SLOW(uS1) (uS1 >> 4)
#define uS_TO_TIMER_COMPARE_SLOW(uS1) ((uS1) >> 2)
/*
***********************************************************************************************************
@ -134,11 +134,11 @@
***********************************************************************************************************
* Idle
*/
#define IDLE_COUNTER TCNT4
#define IDLE_COMPARE OCR4C
#define IDLE_COUNTER TCNT1
#define IDLE_COMPARE OCR1C
#define IDLE_TIMER_ENABLE() TIMSK4 |= (1 << OCIE4C)
#define IDLE_TIMER_DISABLE() TIMSK4 &= ~(1 << OCIE4C)
#define IDLE_TIMER_ENABLE() TIMSK1 |= (1 << OCIE1C)
#define IDLE_TIMER_DISABLE() TIMSK1 &= ~(1 << OCIE1C)
/*
***********************************************************************************************************

View File

@ -3,6 +3,18 @@
#include "globals.h"
#include "auxiliaries.h"
// Prescaler values for timers 1-3-4-5. Refer to www.instructables.com/files/orig/F3T/TIKL/H3WSA4V7/F3TTIKLH3WSA4V7.jpg
#define TIMER_PRESCALER_OFF ((0<<CS12)|(0<<CS11)|(0<<CS10))
#define TIMER_PRESCALER_1 ((0<<CS12)|(0<<CS11)|(1<<CS10))
#define TIMER_PRESCALER_8 ((0<<CS12)|(1<<CS11)|(0<<CS10))
#define TIMER_PRESCALER_64 ((0<<CS12)|(1<<CS11)|(1<<CS10))
#define TIMER_PRESCALER_256 ((1<<CS12)|(0<<CS11)|(0<<CS10))
#define TIMER_PRESCALER_1024 ((1<<CS12)|(0<<CS11)|(1<<CS10))
#define TIMER_MODE_NORMAL ((0<<WGM01)|(0<<WGM00))
#define TIMER_MODE_PWM ((0<<WGM01)|(1<<WGM00))
#define TIMER_MODE_CTC ((1<<WGM01)|(0<<WGM00))
#define TIMER_MODE_FASTPWM ((1<<WGM01)|(1<<WGM00))
void initBoard()
{
@ -17,30 +29,30 @@ void initBoard()
* Auxilliaries
*/
//PWM used by the Boost and VVT outputs. C Channel is used by ign5
TCCR1B = 0x00; //Disbale Timer1 while we set it up
TCNT1 = 0; //Reset Timer Count
TCCR1A = 0x00; //Timer1 Control Reg A: Wave Gen Mode normal (Simply counts up from 0 to 65535 (16-bit int)
TCCR1B = (1 << CS12); //Timer1 Control Reg B: Timer Prescaler set to 256. 1 tick = 16uS. Refer to http://www.instructables.com/files/orig/F3T/TIKL/H3WSA4V7/F3TTIKLH3WSA4V7.jpg
TCCR1B = TIMER_PRESCALER_OFF; //Disbale Timer1 while we set it up
TCNT1 = 0; //Reset Timer Count
TCCR1A = TIMER_MODE_NORMAL; //Timer1 Control Reg A: Wave Gen Mode normal (Simply counts up from 0 to 65535 (16-bit int)
TCCR1B = TIMER_PRESCALER_256; //Timer1 Control Reg B: Timer Prescaler set to 256. 1 tick = 16uS.
TIFR1 = (1 << OCF1A) | (1<<OCF1B) | (1<<OCF1C) | (1<<TOV1) | (1<<ICF1); //Clear the compare flags, overflow flag and external input flag bits
boost_pwm_max_count = 1000000L / (16 * configPage6.boostFreq * 2); //Converts the frequency in Hz to the number of ticks (at 16uS) it takes to complete 1 cycle. The x2 is there because the frequency is stored at half value (in a byte) to allow freqneucies up to 511Hz
vvt_pwm_max_count = 1000000L / (16 * configPage6.vvtFreq * 2); //Converts the frequency in Hz to the number of ticks (at 16uS) it takes to complete 1 cycle
// put idle_pwm_max_count calculation here?
/*
***********************************************************************************************************
* Timers
*/
//Configure Timer2 for our low-freq interrupt code.
TCCR2B = 0x00; //Disbale Timer2 while we set it up
TCNT2 = 131; //Preload timer2 with 131 cycles, leaving 125 till overflow. As the timer runs at 125Khz, this causes overflow to occur at 1Khz = 1ms
TIMSK2 = 0x01; //Timer2 Set Overflow Interrupt enabled.
TCCR2A = 0x00; //Timer2 Control Reg A: Wave Gen Mode normal
TCCR2B = TIMER_PRESCALER_OFF; //Disbale Timer2 while we set it up
TCNT2 = 131; //Preload timer2 with 131 cycles, leaving 125 till overflow. As the timer runs at 125Khz, this causes overflow to occur at 1Khz = 1ms
TIMSK2 = (1<<TOIE2); //Timer2 Set Overflow Interrupt enabled.
TCCR2A = TIMER_MODE_NORMAL; //Timer2 Control Reg A: Wave Gen Mode normal
/* Now configure the prescaler to CPU clock divided by 128 = 125Khz */
TCCR2B |= (1<<CS22) | (1<<CS20); // Set bits
TCCR2B &= ~(1<<CS21); // Clear bit. Shouldn't be needed as initial value is 0 anyway, but best to play it safe
TCCR2B = (1<<CS22) | (1<<CS20); // Set bits. This timer uses different prescaler values, thus we cannot use the defines above.
TIFR2 = (1 << OCF2A) | (1<<OCF2B) | (1<<TOV2); //Clear the compare flag bits and overflow flag bit
//Enable the watchdog timer for 2 second resets (Good reference: https://tushev.org/articles/arduino/5/arduino-and-watchdog-timer)
//Enable the watchdog timer for 2 second resets (Good reference: www.tushev.org/articles/arduino/5/arduino-and-watchdog-timer)
//Boooooooooo WDT is currently broken on Mega 2560 bootloaders :(
//wdt_enable(WDTO_2S);
@ -48,19 +60,19 @@ void initBoard()
***********************************************************************************************************
* Schedules
* */
//Much help in this from http://arduinomega.blogspot.com.au/2011/05/timer2-and-overflow-interrupt-lets-get.html
//Much help in this from www.arduinomega.blogspot.com.au/2011/05/timer2-and-overflow-interrupt-lets-get.html
//Fuel Schedules, which uses timer 3
TCCR3B = 0x00; //Disable Timer3 while we set it up
TCNT3 = 0; //Reset Timer Count
TCCR3A = 0x00; //Timer3 Control Reg A: Wave Gen Mode normal
TCCR3B = (1 << CS12); //Same as: 0x03. Timer3 Control Reg B: Timer Prescaler set to 256. Refer to http://www.instructables.com/files/orig/F3T/TIKL/H3WSA4V7/F3TTIKLH3WSA4V7.jpg
TCCR3B = TIMER_PRESCALER_OFF; //Disable Timer3 while we set it up
TCNT3 = 0; //Reset Timer Count
TCCR3A = TIMER_MODE_NORMAL; //Timer3 Control Reg A: Wave Gen Mode normal
TCCR3B = TIMER_PRESCALER_64; //Timer3 Control Reg B: Timer Prescaler set to 64.
TIFR3 = (1 << OCF3A) | (1<<OCF3B) | (1<<OCF3C) | (1<<TOV3) | (1<<ICF3); //Clear the compare flags, overflow flag and external input flag bits
//Ignition Schedules, which uses timer 5. This is also used by the fast version of micros(). If the speed of this timer is changed from 4uS ticks, that MUST be changed as well. See globals.h and timers.ino
TCCR5B = 0x00; //Disable Timer5 while we set it up
TCNT5 = 0; //Reset Timer Count
TCCR5A = 0x00; //Timer5 Control Reg A: Wave Gen Mode normal
TCCR5B = (1 << CS11) | (1 << CS10); //Timer5 Control Reg B: Timer Prescaler set to 64. Refer to http://www.instructables.com/files/orig/F3T/TIKL/H3WSA4V7/F3TTIKLH3WSA4V7.jpg
TCCR5B = TIMER_PRESCALER_OFF; //Disable Timer5 while we set it up
TCNT5 = 0; //Reset Timer Count
TCCR5A = TIMER_MODE_NORMAL; //Timer5 Control Reg A: Wave Gen Mode normal
TCCR5B = TIMER_PRESCALER_64; //Timer5 Control Reg B: Timer Prescaler set to 64.
TIFR5 = (1 << OCF5A) | (1<<OCF5B) | (1<<OCF5C) | (1<<TOV5) | (1<<ICF5); //Clear the compare flags, overflow flag and external input flag bits
#if defined(TIMER5_MICROS)
@ -68,15 +80,19 @@ void initBoard()
TIMSK0 &= ~_BV(TOIE0); // disable timer0 overflow interrupt
#endif
//The remaining Schedules (Schedules 4 for fuel and ignition) use Timer4
TCCR4B = 0x00; //Disable Timer4 while we set it up
TCNT4 = 0; //Reset Timer Count
TCCR4A = 0x00; //Timer4 Control Reg A: Wave Gen Mode normal
TCCR4B = (1 << CS12); //Timer4 Control Reg B: aka Divisor = 256 = 122.5HzTimer Prescaler set to 256. Refer to http://www.instructables.com/files/orig/F3T/TIKL/H3WSA4V7/F3TTIKLH3WSA4V7.jpg
//The remaining Schedules (Fuel schedule 4 and ignition schedules 4 and 5) use Timer4
TCCR4B = TIMER_PRESCALER_OFF; //Disable Timer4 while we set it up
TCNT4 = 0; //Reset Timer Count
TCCR4A = TIMER_MODE_NORMAL; //Timer4 Control Reg A: Wave Gen Mode normal
TCCR4B = TIMER_PRESCALER_64; //Timer4 Control Reg B: Timer Prescaler set to 64.
TIFR4 = (1 << OCF4A) | (1<<OCF4B) | (1<<OCF4C) | (1<<TOV4) | (1<<ICF4); //Clear the compare flags, overflow flag and external input flag bits
}
/*
Returns how much free dynamic memory exists (between heap and stack)
This function is one big MISRA violation. MISRA advisories forbid directly poking at memory addresses, however there is no other way of determining heap size on embedded systems.
*/
uint16_t freeRam()
{
extern int __heap_start, *__brkval;

View File

@ -74,13 +74,13 @@ void initBoard()
*/
#if defined (STM32F1) || defined(__STM32F1__)
//(CYCLES_PER_MICROSECOND == 72, APB2 at 72MHz, APB1 at 36MHz).
//Timer2 to 4 is on APB1, Timer1 on APB2. http://www.st.com/resource/en/datasheet/stm32f103cb.pdf sheet 12
//Timer2 to 4 is on APB1, Timer1 on APB2. www.st.com/resource/en/datasheet/stm32f103cb.pdf sheet 12
Timer1.setPrescaleFactor((72 * 2)-1); //2us resolution
Timer2.setPrescaleFactor((36 * 2)-1); //2us resolution
Timer3.setPrescaleFactor((36 * 2)-1); //2us resolution
#elif defined(STM32F4)
//(CYCLES_PER_MICROSECOND == 168, APB2 at 84MHz, APB1 at 42MHz).
//Timer2 to 14 is on APB1, Timers 1, 8, 9 and 10 on APB2. http://www.st.com/resource/en/datasheet/stm32f407vg.pdf sheet 120
//Timer2 to 14 is on APB1, Timers 1, 8, 9 and 10 on APB2. www.st.com/resource/en/datasheet/stm32f407vg.pdf sheet 120
Timer1.setPrescaleFactor((168 * 2)-1); //2us resolution
Timer2.setPrescaleFactor((84 * 2)-1); //2us resolution
Timer3.setPrescaleFactor((84 * 2)-1); //2us resolution

View File

@ -165,7 +165,7 @@ void sendcanValues(uint16_t offset, uint16_t packetLength, byte cmd, byte portTy
fullStatus[13] = currentStatus.wueCorrection; //Warmup enrichment (%)
fullStatus[14] = lowByte(currentStatus.RPM); //rpm HB
fullStatus[15] = highByte(currentStatus.RPM); //rpm LB
fullStatus[16] = currentStatus.TAEamount; //acceleration enrichment (%)
fullStatus[16] = currentStatus.AEamount; //acceleration enrichment (%)
fullStatus[17] = currentStatus.corrections; //Total GammaE (%)
fullStatus[18] = currentStatus.VE; //Current VE 1 (%)
fullStatus[19] = currentStatus.afrTarget;

View File

@ -22,7 +22,7 @@
#define warmupPage 10 //Config Page 10
#define fuelMap2Page 11
#define SERIAL_PACKET_SIZE 93 /**< The size of the live data packet. This MUST match ochBlockSize setting in the ini file */
#define SERIAL_PACKET_SIZE 94 /**< The size of the live data packet. This MUST match ochBlockSize setting in the ini file */
byte currentPage = 1;//Not the same as the speeduino config page numbers
bool isMap = true; /**< Whether or not the currentPage contains only a 3D map that would require translation */
@ -46,7 +46,8 @@ const char pageTitles[] PROGMEM //This is being stored in the avr flash instead
"\nPg 4 Config\0" //82
"\nBoost Map\0" //93
"\nVVT Map\0"//102-No need to put a trailing null because it's the last string and the compliler does it for you.
"\nPg 10 Config"
"\nPg 10 Config\0"
"\n2nd Fuel Map"
};
void command();//This is the heart of the Command Line Interpeter. All that needed to be done was to make it human readable.
@ -57,7 +58,7 @@ void saveConfig();
void sendPage();
void sendPageASCII();
void receiveCalibration(byte);
void sendToothLog(bool);
void sendToothLog();
void testComm();
void commandButtons();
byte getPageValue(byte, uint16_t);

View File

@ -92,7 +92,9 @@ void command()
if(Serial.available() >= 2)
{
int cmdCombined = word(Serial.read(), Serial.read());
byte cmdGroup = Serial.read();
byte cmdValue = Serial.read();
int cmdCombined = word(cmdGroup, cmdValue);
if (currentStatus.RPM == 0) { commandButtons(cmdCombined); }
cmdPending = false;
@ -173,6 +175,7 @@ void command()
break;
case 'P': // set the current page
//This is a legacy function and is no longer used by TunerStudio. It is maintained for compatibility with other systems
//A 2nd byte of data is required after the 'P' specifying the new page number.
cmdPending = true;
@ -180,9 +183,21 @@ void command()
{
currentPage = Serial.read();
//This converts the ascii number char into binary. Note that this will break everyything if there are ever more than 48 pages (48 = asci code for '0')
if (currentPage >= '0') { currentPage -= '0'; }
if ((currentPage >= '0') && (currentPage <= '9')) // 0 - 9
{
currentPage -= 48;
}
else if ((currentPage >= 'a') && (currentPage <= 'f')) // 10 - 15
{
currentPage -= 87;
}
else if ((currentPage >= 'A') && (currentPage <= 'F'))
{
currentPage -= 55;
}
// Detecting if the current page is a table/map
if ( (currentPage == veMapPage) || (currentPage == ignMapPage) || (currentPage == afrMapPage) ) { isMap = true; }
if ( (currentPage == veMapPage) || (currentPage == ignMapPage) || (currentPage == afrMapPage) || (currentPage == fuelMap2Page) ) { isMap = true; }
else { isMap = false; }
cmdPending = false;
}
@ -223,7 +238,7 @@ void command()
break;
case 'Q': // send code version
Serial.print(F("speeduino 201904-dev"));
Serial.print(F("speeduino 201906-dev"));
break;
case 'r': //New format for the optimised OutputChannels
@ -253,12 +268,12 @@ void command()
break;
case 'S': // send code version
Serial.print(F("Speeduino 2019.04-dev"));
Serial.print(F("Speeduino 2019.06-dev"));
currentStatus.secl = 0; //This is required in TS3 due to its stricter timings
break;
case 'T': //Send 256 tooth log entries to Tuner Studios tooth logger
if(currentStatus.toothLogEnabled == true) { sendToothLog(false); } //Sends tooth log values as ints
if(currentStatus.toothLogEnabled == true) { sendToothLog(); } //Sends tooth log values as ints
else if (currentStatus.compositeLogEnabled == true) { sendCompositeLog(); }
break;
@ -401,7 +416,7 @@ void command()
break;
case 'z': //Send 256 tooth log entries to a terminal emulator
sendToothLog(true); //Sends tooth log values as chars
sendToothLog(); //Sends tooth log values as chars
break;
case '`': //Custom 16u2 firmware is making its presence known
@ -482,7 +497,7 @@ void sendValues(uint16_t offset, uint16_t packetLength, byte cmd, byte portNum)
requestCount++;
}
currentStatus.spark ^= (-currentStatus.hasSync ^ currentStatus.spark) & (1 << BIT_SPARK_SYNC); //Set the sync bit of the Spark variable to match the hasSync variable
currentStatus.spark ^= (-currentStatus.hasSync ^ currentStatus.spark) & (1U << BIT_SPARK_SYNC); //Set the sync bit of the Spark variable to match the hasSync variable
fullStatus[0] = currentStatus.secl; //secl is simply a counter that increments each second. Used to track unexpected resets (Which will reset this count to 0)
fullStatus[1] = currentStatus.status1; //status1 Bitfield
@ -500,7 +515,7 @@ void sendValues(uint16_t offset, uint16_t packetLength, byte cmd, byte portNum)
fullStatus[13] = currentStatus.wueCorrection; //Warmup enrichment (%)
fullStatus[14] = lowByte(currentStatus.RPM); //rpm HB
fullStatus[15] = highByte(currentStatus.RPM); //rpm LB
fullStatus[16] = (byte)(currentStatus.TAEamount >> 1); //TPS acceleration enrichment (%) divided by 2 (Can exceed 255)
fullStatus[16] = (byte)(currentStatus.AEamount >> 1); //TPS acceleration enrichment (%) divided by 2 (Can exceed 255)
fullStatus[17] = currentStatus.corrections; //Total GammaE (%)
fullStatus[18] = currentStatus.VE; //Current VE 1 (%)
fullStatus[19] = currentStatus.afrTarget;
@ -593,6 +608,7 @@ void sendValues(uint16_t offset, uint16_t packetLength, byte cmd, byte portNum)
fullStatus[90] = highByte(currentStatus.dwell);
fullStatus[91] = currentStatus.CLIdleTarget;
fullStatus[92] = currentStatus.mapDOT;
fullStatus[93] = currentStatus.vvtAngle;
for(byte x=0; x<packetLength; x++)
{
@ -910,6 +926,32 @@ void receiveValue(uint16_t valueOffset, byte newValue)
}
break;
case fuelMap2Page:
if (valueOffset < 256) //New value is part of the fuel map
{
fuelTable2.values[15 - (valueOffset / 16)][valueOffset % 16] = newValue;
}
else
{
//Check whether this is on the X (RPM) or Y (MAP/TPS) axis
if (valueOffset < 272)
{
//X Axis
fuelTable2.axisX[(valueOffset - 256)] = ((int)(newValue) * TABLE_RPM_MULTIPLIER); //The RPM values sent by megasquirt are divided by 100, need to multiple it back by 100 to make it correct (TABLE_RPM_MULTIPLIER)
}
else if(valueOffset < 288)
{
//Y Axis
tempOffset = 15 - (valueOffset - 272); //Need to do a translation to flip the order (Due to us using (0,0) in the top left rather than bottom right
fuelTable2.axisY[tempOffset] = (int)(newValue) * TABLE_LOAD_MULTIPLIER;
}
else
{
//This should never happen. It means there's an invalid offset value coming through
}
}
break;
default:
break;
}
@ -1003,11 +1045,15 @@ void sendPage()
break;
}
case canbusPage:
pnt_configPage = &configPage9; //Create a pointer to Page 10 in memory
pnt_configPage = &configPage9; //Create a pointer to Page 9 in memory
break;
case warmupPage:
pnt_configPage = &configPage10; //Create a pointer to Page 11 in memory
pnt_configPage = &configPage10; //Create a pointer to Page 10 in memory
break;
case fuelMap2Page:
currentTable = fuelTable2;
break;
default:
@ -1164,9 +1210,9 @@ void sendPageASCII()
if (y == 2) { currentVar = configPage6.voltageCorrectionBins; }
else { currentVar = configPage6.injVoltageCorrectionValues; }
for (byte x = 6; x; x--)
for (byte i = 6; i; i--)
{
Serial.print(currentVar[6 - x]);
Serial.print(currentVar[6 - i]);
Serial.print(' ');
}
Serial.println();
@ -1177,9 +1223,9 @@ void sendPageASCII()
if (y == 2) { currentVar = configPage6.airDenBins; }
else { currentVar = configPage6.airDenRates; }
for (byte x = 9; x; x--)
for (byte i = 9; i; i--)
{
Serial.print(currentVar[9 - x]);
Serial.print(currentVar[9 - i]);
Serial.print(' ');
}
Serial.println();
@ -1205,9 +1251,9 @@ void sendPageASCII()
case 4: currentVar = configPage6.iacCLValues; break;
default: break;
}
for (byte x = 10; x; x--)
for (byte i = 10; i; i--)
{
Serial.print(currentVar[10 - x]);
Serial.print(currentVar[10 - i]);
Serial.print(' ');
}
Serial.println();
@ -1222,9 +1268,9 @@ void sendPageASCII()
case 3: currentVar = configPage6.iacCrankSteps; break;
default: break;
}
for (byte x = 4; x; x--)
for (byte i = 4; i; i--)
{
Serial.print(currentVar[4 - x]);
Serial.print(currentVar[4 - i]);
Serial.print(' ');
}
Serial.println();
@ -1254,9 +1300,9 @@ void sendPageASCII()
}
Serial.print(axisY);// Vertical Bins
Serial.write(" ");
for (int x = 0; x < currentTable.xSize; x++)
for (int i = 0; i < currentTable.xSize; i++)
{
byte value = currentTable.values[y][x];
byte value = currentTable.values[y][i];
if (value < 100)
{
Serial.write(" ");
@ -1292,6 +1338,11 @@ void sendPageASCII()
sendComplete = true;
break;
case fuelMap2Page:
currentTitleIndex = 117;// the index to the first char of the third string in pageTitles
currentTable = fuelTable2;
break;
default:
#ifndef SMALL_FLASH_MODE
Serial.println(F("\nPage has not been implemented yet"));
@ -1306,8 +1357,8 @@ void sendPageASCII()
{
if (isMap)
{
do //This is a do while loop that kicks in for the boostvvtPage
{
//This is a do while loop that kicks in for the boostvvtPage
do {
const char spaceChar = ' ';
Serial.println((const __FlashStringHelper *)&pageTitles[currentTitleIndex]);// F macro hack
@ -1362,8 +1413,8 @@ void sendPageASCII()
currentTitleIndex = 132; //Change over to vvtTable mid display
currentTable = vvtTable;
}
else currentTitleIndex = 0;
}while(currentTitleIndex == 132); //Should never loop unless going to display vvtTable
else { currentTitleIndex = 0; }
} while(currentTitleIndex == 132); //Should never loop unless going to display vvtTable
} //is map
else
{
@ -1645,7 +1696,7 @@ Send 256 tooth log entries
* if useChar is true, the values are sent as chars to be printed out by a terminal emulator
* if useChar is false, the values are sent as a 2 byte integer which is readable by TunerStudios tooth logger
*/
void sendToothLog(bool useChar)
void sendToothLog()
{
//We need TOOTH_LOG_SIZE number of records to send to TunerStudio. If there aren't that many in the buffer then we just return and wait for the next call
if (BIT_CHECK(currentStatus.status1, BIT_STATUS1_TOOTHLOG1READY)) //Sanity check. Flagging system means this should always be true
@ -1728,11 +1779,11 @@ void commandButtons(int buttonCommand)
break;
case 513: // cmd group is for injector1 on actions
if( BIT_CHECK(currentStatus.testOutputs, 1) ){ openInjector1(); }
if( BIT_CHECK(currentStatus.testOutputs, 1) ){ openInjector1(); }
break;
case 514: // cmd group is for injector1 off actions
if( BIT_CHECK(currentStatus.testOutputs, 1) ){ closeInjector1(); }
if( BIT_CHECK(currentStatus.testOutputs, 1) ){ closeInjector1(); }
break;
case 515: // cmd group is for injector1 50% dc actions

View File

@ -53,8 +53,8 @@ static inline byte correctionsFuel()
if (result != 100) { sumCorrections = (sumCorrections * result); activeCorrections++; }
if (activeCorrections == 3) { sumCorrections = sumCorrections / powint(100,activeCorrections); activeCorrections = 0; } // Need to check this to ensure that sumCorrections doesn't overflow. Can occur when the number of corrections is greater than 3 (Which is 100^4) as 100^5 can overflow
currentStatus.TAEamount = correctionAccel();
if (currentStatus.TAEamount != 100) { sumCorrections = (sumCorrections * currentStatus.TAEamount); activeCorrections++; }
currentStatus.AEamount = correctionAccel();
if (currentStatus.AEamount != 100) { sumCorrections = (sumCorrections * currentStatus.AEamount); activeCorrections++; }
if (activeCorrections == 3) { sumCorrections = sumCorrections / powint(100,activeCorrections); activeCorrections = 0; }
result = correctionFloodClear();
@ -151,12 +151,15 @@ static inline byte correctionASE()
return ASEValue;
}
/*
TPS based acceleration enrichment
Calculates the % change of the throttle over time (%/second) and performs a lookup based on this
When the enrichment is turned on, it runs at that amount for a fixed period of time (taeTime)
Note that as the maximum enrichment amount is +255%, the overall return value from this function can be 100+255=355. Hence this function returns a int16_t rather than byte
*/
/**
* @brief Acceleration enrichment correction calculation
*
* Calculates the % change of the throttle over time (%/second) and performs a lookup based on this
* When the enrichment is turned on, it runs at that amount for a fixed period of time (taeTime)
*
* @return int16_t The Acceleration enrichment modifier as a %. 100% = No modification.
* As the maximum enrichment amount is +255%, the overall return value from this function can be 100+255=355. Hence this function returns a int16_t rather than byte
*/
static inline int16_t correctionAccel()
{
int16_t accelValue = 100;
@ -164,60 +167,106 @@ static inline int16_t correctionAccel()
if( BIT_CHECK(currentStatus.engine, BIT_ENGINE_ACC) )
{
//If it is currently running, check whether it should still be running or whether it's reached it's end time
if( micros_safe() >= currentStatus.TAEEndTime )
if( micros_safe() >= currentStatus.AEEndTime )
{
//Time to turn enrichment off
BIT_CLEAR(currentStatus.engine, BIT_ENGINE_ACC);
currentStatus.TAEamount = 0;
currentStatus.AEamount = 0;
accelValue = 100;
currentStatus.tpsDOT = 0;
//Reset the relevant DOT value to 0
if(configPage2.aeMode == AE_MODE_MAP) { currentStatus.mapDOT = 0; }
else if(configPage2.aeMode == AE_MODE_TPS) { currentStatus.tpsDOT = 0; }
}
else
{
//Enrichment still needs to keep running. Simply return the total TAE amount
accelValue = currentStatus.TAEamount;
accelValue = currentStatus.AEamount;
}
}
else
{
int8_t TPS_change = (currentStatus.TPS - currentStatus.TPSlast);
//Check for deceleration (Deceleration adjustment not yet supported)
//Also check for only very small movement (Movement less than or equal to 2% is ignored). This not only means we can skip the lookup, but helps reduce false triggering around 0-2% throttle openings
if (TPS_change <= 2)
if(configPage2.aeMode == AE_MODE_MAP)
{
accelValue = 100;
currentStatus.tpsDOT = 0;
}
else
{
//If TAE isn't currently turned on, need to check whether it needs to be turned on
int rateOfChange = ldiv(1000000, (currentStatus.TPS_time - currentStatus.TPSlast_time)).quot * TPS_change; //This is the % per second that the TPS has moved
currentStatus.tpsDOT = rateOfChange / 10; //The TAE bins are divided by 10 in order to allow them to be stored in a byte. Faster as this than divu10
int16_t MAP_change = (currentStatus.MAP - MAPlast);
if (rateOfChange > configPage2.tpsThresh)
if (MAP_change <= 2)
{
BIT_SET(currentStatus.engine, BIT_ENGINE_ACC); //Mark accleration enrichment as active.
currentStatus.TAEEndTime = micros_safe() + ((unsigned long)configPage2.aeTime * 10000); //Set the time in the future where the enrichment will be turned off. taeTime is stored as mS / 10, so multiply it by 100 to get it in uS
accelValue = table2D_getValue(&taeTable, currentStatus.tpsDOT);
accelValue = 100;
currentStatus.mapDOT = 0;
}
else
{
//If MAE isn't currently turned on, need to check whether it needs to be turned on
int rateOfChange = ldiv(1000000, (MAP_time - MAPlast_time)).quot * MAP_change; //This is the % per second that the TPS has moved
currentStatus.mapDOT = rateOfChange / 10; //The MAE bins are divided by 10 in order to allow them to be stored in a byte. Faster as this than divu10
//Apply the taper to the above
//The RPM settings are stored divided by 100:
uint16_t trueTaperMin = configPage2.taeTaperMin * 100;
uint16_t trueTaperMax = configPage2.taeTaperMax * 100;
if (currentStatus.RPM > trueTaperMin)
if (rateOfChange > configPage2.maeThresh)
{
if(currentStatus.RPM > trueTaperMax) { accelValue = 0; } //RPM is beyond taper max limit, so accel enrich is turned off
else
BIT_SET(currentStatus.engine, BIT_ENGINE_ACC); //Mark accleration enrichment as active.
currentStatus.AEEndTime = micros_safe() + ((unsigned long)configPage2.aeTime * 10000); //Set the time in the future where the enrichment will be turned off. taeTime is stored as mS / 10, so multiply it by 100 to get it in uS
accelValue = table2D_getValue(&maeTable, currentStatus.mapDOT);
//Apply the taper to the above
//The RPM settings are stored divided by 100:
uint16_t trueTaperMin = configPage2.aeTaperMin * 100;
uint16_t trueTaperMax = configPage2.aeTaperMax * 100;
if (currentStatus.RPM > trueTaperMin)
{
int16_t taperRange = trueTaperMax - trueTaperMin;
int16_t taperPercent = ((currentStatus.RPM - trueTaperMin) * 100) / taperRange; //The percentage of the way through the RPM taper range
accelValue = percentage((100-taperPercent), accelValue); //Calculate the above percentage of the calculated accel amount.
if(currentStatus.RPM > trueTaperMax) { accelValue = 0; } //RPM is beyond taper max limit, so accel enrich is turned off
else
{
int16_t taperRange = trueTaperMax - trueTaperMin;
int16_t taperPercent = ((currentStatus.RPM - trueTaperMin) * 100) / taperRange; //The percentage of the way through the RPM taper range
accelValue = percentage((100-taperPercent), accelValue); //Calculate the above percentage of the calculated accel amount.
}
}
}
accelValue = 100 + accelValue; //Add the 100 normalisation to the calculated amount
accelValue = 100 + accelValue; //Add the 100 normalisation to the calculated amount
} //MAE Threshold
}
}
}
else if(configPage2.aeMode == AE_MODE_TPS)
{
int8_t TPS_change = (currentStatus.TPS - TPSlast);
//Check for deceleration (Deceleration adjustment not yet supported)
//Also check for only very small movement (Movement less than or equal to 2% is ignored). This not only means we can skip the lookup, but helps reduce false triggering around 0-2% throttle openings
if (TPS_change <= 2)
{
accelValue = 100;
currentStatus.tpsDOT = 0;
}
else
{
//If TAE isn't currently turned on, need to check whether it needs to be turned on
int rateOfChange = ldiv(1000000, (TPS_time - TPSlast_time)).quot * TPS_change; //This is the % per second that the TPS has moved
currentStatus.tpsDOT = rateOfChange / 10; //The TAE bins are divided by 10 in order to allow them to be stored in a byte. Faster as this than divu10
if (rateOfChange > configPage2.taeThresh)
{
BIT_SET(currentStatus.engine, BIT_ENGINE_ACC); //Mark accleration enrichment as active.
currentStatus.AEEndTime = micros_safe() + ((unsigned long)configPage2.aeTime * 10000); //Set the time in the future where the enrichment will be turned off. taeTime is stored as mS / 10, so multiply it by 100 to get it in uS
accelValue = table2D_getValue(&taeTable, currentStatus.tpsDOT);
//Apply the taper to the above
//The RPM settings are stored divided by 100:
uint16_t trueTaperMin = configPage2.aeTaperMin * 100;
uint16_t trueTaperMax = configPage2.aeTaperMax * 100;
if (currentStatus.RPM > trueTaperMin)
{
if(currentStatus.RPM > trueTaperMax) { accelValue = 0; } //RPM is beyond taper max limit, so accel enrich is turned off
else
{
int16_t taperRange = trueTaperMax - trueTaperMin;
int16_t taperPercent = ((currentStatus.RPM - trueTaperMin) * 100) / taperRange; //The percentage of the way through the RPM taper range
accelValue = percentage((100-taperPercent), accelValue); //Calculate the above percentage of the calculated accel amount.
}
}
accelValue = 100 + accelValue; //Add the 100 normalisation to the calculated amount
} //TAE Threshold
} //TPS change > 2
} //AE Mode
} //AE active
return accelValue;
}
@ -450,11 +499,11 @@ static inline int8_t correctionIATretard(int8_t advance)
static inline int8_t correctionCLTadvance(int8_t advance)
{
byte ignCLTValue = advance;
int8_t ignCLTValue = advance;
//Adjust the advance based on CLT.
int8_t advanceCLTadjust = table2D_getValue(&CLTAdvanceTable, currentStatus.coolant + CALIBRATION_TEMPERATURE_OFFSET);
ignCLTValue = (advance + advanceCLTadjust/10);
int8_t advanceCLTadjust = (int16_t)(table2D_getValue(&CLTAdvanceTable, currentStatus.coolant + CALIBRATION_TEMPERATURE_OFFSET)) - 15;
ignCLTValue = (advance + advanceCLTadjust);
return ignCLTValue;
}

View File

@ -10,9 +10,9 @@
//#define fastDegreesToUS(targetDegrees) ((targetDegrees) * (unsigned long)timePerDegree)
#define fastDegreesToUS(targetDegrees) (((targetDegrees) * (unsigned long)timePerDegreex16) >> 4)
//#define fastTimeToAngle(time) (((unsigned long)time * degreesPeruSx2048) / 2048) //Divide by 2048 will be converted at compile time to bitshift
#define fastTimeToAngle(time) (((unsigned long)time * degreesPeruSx32768) / 32768) //Divide by 32768 will be converted at compile time to bitshift
#define fastTimeToAngle(time) (((unsigned long)(time) * degreesPeruSx32768) / 32768) //Divide by 32768 will be converted at compile time to bitshift
#define ignitionLimits(angle) ( (((int16_t)angle) >= CRANK_ANGLE_MAX_IGN) ? (angle - CRANK_ANGLE_MAX_IGN) : ( (angle < 0) ? (angle + CRANK_ANGLE_MAX_IGN) : angle) )
#define ignitionLimits(angle) ( (((int16_t)(angle)) >= CRANK_ANGLE_MAX_IGN) ? ((angle) - CRANK_ANGLE_MAX_IGN) : ( ((int16_t)(angle) < 0) ? ((angle) + CRANK_ANGLE_MAX_IGN) : (angle)) )
unsigned long angleToTime(int16_t, byte);

View File

@ -187,6 +187,7 @@ byte checkSyncToothCount; //How many teeth must've been seen on this revolution
unsigned long elapsedTime;
unsigned long lastCrankAngleCalc;
int16_t lastToothCalcAdvance = 99; //Invalid value here forces calculation of this on first main loop
unsigned long lastVVTtime; //The time between the vvt reference pulse and the last crank pulse
int16_t ignition1EndTooth = 0;
int16_t ignition2EndTooth = 0;

View File

@ -634,7 +634,7 @@ void triggerSetEndTeeth_DualWheel()
/* -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
Name: Basic Distributor
Desc: Tooth equal to the number of cylinders are evenly spaced on the cam. No position sensing (Distributor is retained) so crank angle is a made up figure based purely on the first teeth to be seen
Note: This is a very simple decoder. See http://www.megamanual.com/ms2/GM_7pinHEI.htm
Note: This is a very simple decoder. See www.megamanual.com/ms2/GM_7pinHEI.htm
*/
void triggerSetup_BasicDistributor()
{
@ -662,11 +662,11 @@ void triggerPri_BasicDistributor()
{
if( (toothCurrentCount == triggerActualTeeth) || (currentStatus.hasSync == false) ) //Check if we're back to the beginning of a revolution
{
toothCurrentCount = 1; //Reset the counter
toothOneMinusOneTime = toothOneTime;
toothOneTime = curTime;
currentStatus.hasSync = true;
currentStatus.startRevolutions++; //Counter
toothCurrentCount = 1; //Reset the counter
toothOneMinusOneTime = toothOneTime;
toothOneTime = curTime;
currentStatus.hasSync = true;
currentStatus.startRevolutions++; //Counter
}
else
{
@ -779,7 +779,7 @@ void triggerSetEndTeeth_BasicDistributor()
Name: GM7X
Desc: GM 7X trigger wheel. It has six equally spaced teeth and a seventh tooth for cylinder identification.
Note: Within the code below, the sync tooth is referred to as tooth #3 rather than tooth #7. This makes for simpler angle calculations
https://speeduino.com/forum/download/file.php?id=4743
www.speeduino.com/forum/download/file.php?id=4743
*/
void triggerSetup_GM7X()
{
@ -914,7 +914,7 @@ void triggerSetEndTeeth_GM7X()
/* -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
Name: Mitsubishi 4G63 / NA/NB Miata + MX-5 / 4/2
Desc: TBA
Note: https://raw.githubusercontent.com/noisymime/speeduino/master/reference/wiki/decoders/4g63_trace.png
Note: raw.githubusercontent.com/noisymime/speeduino/master/reference/wiki/decoders/4g63_trace.png
Tooth #1 is defined as the next crank tooth after the crank signal is HIGH when the cam signal is falling.
Tooth number one is at 355* ATDC
*/
@ -965,21 +965,6 @@ void triggerSetup_4G63()
triggerActualTeeth = 8;
}
/*
* https://forums.libreems.org/attachment.php?aid=34
toothAngles[0] = 715; //Falling edge of tooth #1
toothAngles[1] = 49; //Falling edge of wide cam
toothAngles[2] = 105; //Rising edge of tooth #2
toothAngles[3] = 175; //Falling edge of tooth #2
toothAngles[4] = 229; //Rising edge of narrow cam tooth (??)
toothAngles[5] = 285; //Rising edge of tooth #3
toothAngles[6] = 319; //Falling edge of narrow cam tooth
toothAngles[7] = 355; //falling edge of tooth #3
toothAngles[8] = 465; //Rising edge of tooth #4
toothAngles[9] = 535; //Falling edge of tooth #4
toothAngles[10] = 535; //Rising edge of wide cam tooth
toothAngles[11] = 645; //Rising edge of tooth #1
*/
triggerFilterTime = 1500; //10000 rpm, assuming we're triggering on both edges off the crank tooth.
triggerSecFilterTime = (int)(1000000 / (MAX_RPM / 60 * 2)) / 2; //Same as above, but fixed at 2 teeth on the secondary input and divided by 2 (for cam speed)
@ -1365,7 +1350,7 @@ void triggerSetEndTeeth_4G63()
Name: GM
Desc: TBA
Note: Useful references:
http://www.vems.hu/wiki/index.php?page=MembersPage%2FJorgenKarlsson%2FTwentyFourX
www.vems.hu/wiki/index.php?page=MembersPage%2FJorgenKarlsson%2FTwentyFourX
Provided that the cam signal is used, this decoder simply counts the teeth and then looks their angles up against a lookup table. The cam signal is used to determine tooth #1
*/
void triggerSetup_24X()
@ -1488,7 +1473,7 @@ Name: Jeep 2000
Desc: For '91 to 2000 6 cylinder Jeep engines
Note: Quite similar to the 24X setup. 24 crank teeth over 720 degrees, in groups of 4. Crank wheel is high for 360 crank degrees. AS we only need timing within 360 degrees, only 12 tooth angles are defined.
Tooth number 1 represents the first tooth seen after the cam signal goes high
http://speeduino.com/forum/download/file.php?id=205
www.speeduino.com/forum/download/file.php?id=205
*/
void triggerSetup_Jeep2000()
{
@ -1808,7 +1793,7 @@ void triggerSetEndTeeth_HondaD17()
/* -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
Name: Miata '99 to '05
Desc: TBA (See: http://forum.diyefi.org/viewtopic.php?f=56&t=1077)
Desc: TBA (See: www.forum.diyefi.org/viewtopic.php?f=56&t=1077)
Note: 4x 70 degree duration teeth running at cam speed. Believed to be at the same angles as the 4g63 decoder
Tooth #1 is defined as the next crank tooth after the crank signal is HIGH when the cam signal is falling.
Tooth number one is at 355* ATDC
@ -1956,6 +1941,12 @@ void triggerSec_Miata9905()
secondaryToothCount++;
//TODO Add some secondary filtering here
//Record the VVT tooth time
if( (toothCurrentCount == 1) && (curTime2 > toothLastToothTime) )
{
lastVVTtime = curTime2 - toothLastToothTime;
}
}
}
@ -2290,7 +2281,7 @@ void triggerSetEndTeeth_non360()
/* -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
Name: Nissan 360 tooth with cam
Desc:
Note: https://wiki.r31skylineclub.com/index.php/Crank_Angle_Sensor
Note: wiki.r31skylineclub.com/index.php/Crank_Angle_Sensor
*/
void triggerSetup_Nissan360()
{
@ -2767,7 +2758,7 @@ void triggerSetEndTeeth_Subaru67()
/* -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
Name: Daihatsu +1 trigger for 3 and 4 cylinder engines
Desc: Tooth equal to the number of cylinders are evenly spaced on the cam. No position sensing (Distributor is retained) so crank angle is a made up figure based purely on the first teeth to be seen
Note: This is a very simple decoder. See http://www.megamanual.com/ms2/GM_7pinHEI.htm
Note: This is a very simple decoder. See www.megamanual.com/ms2/GM_7pinHEI.htm
*/
void triggerSetup_Daihatsu()
{
@ -3070,7 +3061,7 @@ void triggerSetEndTeeth_Harley()
/*
Name: 36-2-2-2 trigger wheel wheel
Desc: A crank based trigger with a nominal 36 teeth, but 6 of these removed in 3 groups of 2. 2 of these groups are located concurrently.
Note: http://thefactoryfiveforum.com/attachment.php?attachmentid=34279&d=1412431418
Note: www.thefactoryfiveforum.com/attachment.php?attachmentid=34279&d=1412431418
*/
void triggerSetup_ThirtySixMinus222()
{

View File

@ -61,8 +61,8 @@
#else //libmaple core aka STM32DUINO
//These are defined in STM32F1/variants/generic_stm32f103c/variant.h but return a non byte* value
#ifndef portOutputRegister
#define portOutputRegister(port) (volatile byte *)( &(port->regs->ODR) )
#define portInputRegister(port) (volatile byte *)( &(port->regs->IDR) )
#define portOutputRegister(port) ((volatile byte *)( &((port)->regs->ODR) ))
#define portInputRegister(port) ((volatile byte *)( &((port)->regs->IDR) ))
#endif
#endif
#elif defined(__SAMD21G18A__)
@ -76,11 +76,11 @@
#include BOARD_H //Note that this is not a real file, it is defined in globals.h.
//Handy bitsetting macros
#define BIT_SET(a,b) ((a) |= (1<<(b)))
#define BIT_CLEAR(a,b) ((a) &= ~(1<<(b)))
#define BIT_CHECK(var,pos) !!((var) & (1<<(pos)))
#define BIT_SET(a,b) ((a) |= (1U<<(b)))
#define BIT_CLEAR(a,b) ((a) &= ~(1U<<(b)))
#define BIT_CHECK(var,pos) !!((var) & (1U<<(pos)))
#define interruptSafe(c) noInterrupts(); c interrupts(); //Wraps any code between nointerrupt and interrupt calls
#define interruptSafe(c) (noInterrupts(); {c} interrupts();) //Wraps any code between nointerrupt and interrupt calls
#define MS_IN_MINUTE 60000
#define US_IN_MINUTE 60000000
@ -137,7 +137,7 @@
#define BIT_STATUS3_RESET_PREVENT 0 //Indicates whether reset prevention is enabled
#define BIT_STATUS3_NITROUS 1
#define BIT_STATUS3_UNUSED2 2
#define BIT_STATUS3_FUEL2_ACTIVE 2
#define BIT_STATUS3_UNUSED3 3
#define BIT_STATUS3_UNUSED4 4
#define BIT_STATUS3_NSQUIRTS1 5
@ -195,6 +195,9 @@
#define NITROUS_STAGE1 1
#define NITROUS_STAGE2 2
#define AE_MODE_TPS 0
#define AE_MODE_MAP 1
#define KNOCK_MODE_OFF 0
#define KNOCK_MODE_DIGITAL 1
#define KNOCK_MODE_ANALOG 2
@ -202,7 +205,13 @@
#define FUEL2_MODE_OFF 0
#define FUEL2_MODE_MULTIPLY 1
#define FUEL2_MODE_ADD 2
#define FUEL2_MODE_SWITCH 3
#define FUEL2_MODE_CONDITIONAL_SWITCH 3
#define FUEL2_MODE_INPUT_SWITCH 4
#define FUEL2_CONDITION_RPM 0
#define FUEL2_CONDITION_MAP 1
#define FUEL2_CONDITION_TPS 2
#define FUEL2_CONDITION_ETH 3
#define RESET_CONTROL_DISABLED 0
#define RESET_CONTROL_PREVENT_WHEN_RUNNING 1
@ -212,11 +221,17 @@
#define OPEN_LOOP_BOOST 0
#define CLOSED_LOOP_BOOST 1
#define VVT_MODE_ONOFF 0
#define VVT_MODE_OPEN_LOOP 1
#define VVT_MODE_CLOSED_LOOP 2
#define VVTCL_LOAD_MAP 0
#define VVTCL_LOAD_TPS 1
#define FOUR_STROKE 0
#define TWO_STROKE 1
#define MAX_RPM 18000 //This is the maximum rpm that the ECU will attempt to run at. It is NOT related to the rev limiter, but is instead dictates how fast certain operations will be allowed to run. Lower number gives better performance
#define engineSquirtsPerCycle 2 //Would be 1 for a 2 stroke
//Table sizes
#define CALIBRATION_TABLE_SIZE 512
@ -233,7 +248,7 @@ const char TSfirmwareVersion[] PROGMEM = "Speeduino";
const byte data_structure_version = 2; //This identifies the data structure when reading / writing.
#define NUM_PAGES 12
const uint16_t npage_size[NUM_PAGES] = {0,128,288,288,128,288,128,240,192,192,192,288};
const uint16_t npage_size[NUM_PAGES] = {0,128,288,288,128,288,128,240,192,192,192,288}; /**< This array stores the size (in bytes) of each configuration page */
#define MAP_PAGE_SIZE 288
struct table3D fuelTable; //16x16 fuel map
@ -248,6 +263,7 @@ struct table3D trim2Table; //6x6 Fuel trim 2 map
struct table3D trim3Table; //6x6 Fuel trim 3 map
struct table3D trim4Table; //6x6 Fuel trim 4 map
struct table2D taeTable; //4 bin TPS Acceleration Enrichment map (2D)
struct table2D maeTable;
struct table2D WUETable; //10 bin Warm Up Enrichment map (2D)
struct table2D ASETable; //4 bin After Start Enrichment map (2D)
struct table2D ASECountTable; //4 bin After Start duration map (2D)
@ -370,9 +386,6 @@ struct statuses {
int16_t EMAPADC;
byte baro; //Barometric pressure is simply the inital MAP reading, taken before the engine is running. Alternatively, can be taken from an external sensor
byte TPS; /**< The current TPS reading (0% - 100%). Is the tpsADC value after the calibration is applied */
byte TPSlast; /**< The previous TPS reading */
unsigned long TPS_time; //The time the TPS sample was taken
unsigned long TPSlast_time; //The time the previous TPS sample was taken
byte tpsADC; /**< 0-255 byte representation of the TPS. Downsampled from the original 10-bit reading, but before any calibration is applied */
byte tpsDOT; /**< TPS delta over time. Measures the % per second that the TPS is changing. Value is divided by 10 to be stored in a byte */
byte mapDOT; /**< MAP delta over time. Measures the kpa per second that the MAP is changing. Value is divided by 10 to be stored in a byte */
@ -393,7 +406,7 @@ struct statuses {
byte battery10; /**< The current BRV in volts (multiplied by 10. Eg 12.5V = 125) */
int8_t advance; /**< Signed 8 bit as advance can now go negative (ATDC) */
byte corrections; /**< The total current corrections % amount */
int16_t TAEamount; /**< The amount of accleration enrichment currently being applied */
int16_t AEamount; /**< The amount of accleration enrichment currently being applied */
byte egoCorrection; /**< The amount of closed loop AFR enrichment currently being applied */
byte wueCorrection; /**< The amount of warmup enrichment currently being applied */
byte batCorrection; /**< The amount of battery voltage enrichment currently being applied */
@ -407,11 +420,11 @@ struct statuses {
bool idleUpActive; /**< Whether the externally controlled idle up is currently active */
bool fanOn; /**< Whether or not the fan is turned on */
volatile byte ethanolPct; /**< Ethanol reading (if enabled). 0 = No ethanol, 100 = pure ethanol. Eg E85 = 85. */
unsigned long TAEEndTime; /**< The target end time used whenever TAE is turned on */
unsigned long AEEndTime; /**< The target end time used whenever AE is turned on */
volatile byte status1;
volatile byte spark;
volatile byte spark2;
byte engine;
uint8_t engine;
unsigned int PW1; //In uS
unsigned int PW2; //In uS
unsigned int PW3; //In uS
@ -451,6 +464,8 @@ struct statuses {
bool knockActive;
bool toothLogEnabled;
bool compositeLogEnabled;
byte vvtAngle;
byte targetVVTAngle;
};
struct statuses currentStatus; //The global status object
@ -463,10 +478,11 @@ struct statuses currentStatus; //The global status object
*/
struct config2 {
byte unused2_0;
byte unused2_1;
byte unused2_2;
byte unused2_3; //Was ASE
byte unused2_4; //Was ASECount
byte unused2_2; //Was ASE
byte aeMode : 2; /**< Acceleration Enrichment mode. 0 = TPS, 1 = MAP. Values 2 and 3 reserved for potential future use (ie blended TPS / MAP) */
byte unused1_3c : 6;
byte wueValues[10]; //Warm up enrichment array (10 bytes)
byte crankingPct; //Cranking enrichment
byte pinMapping; // The board / ping mapping to be used
@ -474,7 +490,7 @@ struct config2 {
byte tachoDiv : 2; //Whether to change the tacho speed
byte tachoDuration; //The duration of the tacho pulse in mS
byte maeThresh; /**< The MAPdot threshold that must be exceeded before AE is engaged */
byte tpsThresh; /**< The TPSdot threshold that must be exceeded before AE is engaged */
byte taeThresh; /**< The TPSdot threshold that must be exceeded before AE is engaged */
byte aeTime;
//Display config bits
@ -518,7 +534,7 @@ struct config2 {
//config3 in ini
byte engineType : 1;
byte flexEnabled : 1;
byte unused2_38c : 1; //"Speed Density", "Alpha-N"
byte legacyMAP : 1;
byte baroCorr : 1;
byte injLayout : 2;
byte perToothIgn : 1;
@ -545,8 +561,8 @@ struct config2 {
byte idleUpEnabled : 1;
byte idleUpAdder;
byte taeTaperMin;
byte taeTaperMax;
byte aeTaperMin;
byte aeTaperMax;
byte iacCLminDuty;
byte iacCLmaxDuty;
@ -640,12 +656,13 @@ struct config4 {
byte ADCFILTER_BARO;
byte cltAdvBins[6]; /**< Coolant Temp timing advance curve bins */
byte cltAdvValues[6]; /**< Coolant timing advance curve values */
byte cltAdvValues[6]; /**< Coolant timing advance curve values. These are translated by 15 to allow for negative values */
byte maeBins[4]; /**< MAP based AE MAPdot bins */
byte maeRates[4]; /**< MAP based AE values */
byte unused2_91[37];
int8_t batVoltCorrect; /**< Battery voltage calibration offset */
byte unused2_91[36];
#if defined(CORE_AVR)
};
@ -668,7 +685,12 @@ struct config6 {
byte egoKD;
byte egoTemp; //The temperature above which closed loop functions
byte egoCount; //The number of ignition cylces per step
byte unused6_6;
byte vvtMode : 2; //Valid VVT modes are 'on/off', 'open loop' and 'closed loop'
byte vvtLoadSource : 2; //Load source for VVT (TPS or MAP)
byte vvtCLDir : 1; //VVT direction (advance or retard)
byte vvtCLUseHold : 1; //Whether or not to use a hold duty cycle (Most cases are Yes)
byte vvtCLAlterFuelTiming : 1;
byte unused6_6 : 1;
byte egoLimit; //Maximum amount the closed loop will vary the fueling
byte ego_min; //AFR must be above this for closed loop to function
byte ego_max; //AFR must be below this for closed loop to function
@ -831,85 +853,101 @@ Page 10 - No specific purpose. Created initially for the cranking enrich curve
See ini file for further info (Config Page 11 in the ini)
*/
struct config10 {
byte crankingEnrichBins[4];
byte crankingEnrichValues[4];
byte crankingEnrichBins[4]; //Bytes 0-4
byte crankingEnrichValues[4]; //Bytes 4-7
//Byte 8
byte rotaryType : 2;
byte stagingEnabled : 1;
byte stagingMode : 1;
byte EMAPPin : 4;
byte rotarySplitValues[8];
byte rotarySplitBins[8];
byte rotarySplitValues[8]; //Bytes 9-16
byte rotarySplitBins[8]; //Bytes 17-24
uint16_t boostSens;
byte boostIntv;
uint16_t stagedInjSizePri;
uint16_t stagedInjSizeSec;
byte lnchCtrlTPS;
uint16_t boostSens; //Bytes 25-26
byte boostIntv; //Byte 27
uint16_t stagedInjSizePri; //Bytes 28-29
uint16_t stagedInjSizeSec; //Bytes 30-31
byte lnchCtrlTPS; //Byte 32
uint8_t flexBoostBins[6];
int16_t flexBoostAdj[6]; //kPa to be added to the boost target @ current ethanol (negative values allowed)
uint8_t flexFuelBins[6];
uint8_t flexFuelAdj[6]; //Fuel % @ current ethanol (typically 100% @ 0%, 163% @ 100%)
uint8_t flexAdvBins[6];
uint8_t flexAdvAdj[6]; //Additional advance (in degrees) @ current ethanol (typically 0 @ 0%, 10-20 @ 100%). NOTE: THIS IS A SIGNED VALUE!
uint8_t flexBoostBins[6]; //Byets 33-38
int16_t flexBoostAdj[6]; //kPa to be added to the boost target @ current ethanol (negative values allowed). Bytes 39-50
uint8_t flexFuelBins[6]; //Bytes 51-56
uint8_t flexFuelAdj[6]; //Fuel % @ current ethanol (typically 100% @ 0%, 163% @ 100%). Bytes 57-62
uint8_t flexAdvBins[6]; //Bytes 63-68
uint8_t flexAdvAdj[6]; //Additional advance (in degrees) @ current ethanol (typically 0 @ 0%, 10-20 @ 100%). NOTE: THIS SHOULD BE A SIGNED VALUE BUT 2d TABLE LOOKUP NOT WORKING WITH IT CURRENTLY!
//And another three corn rows die.
//Bytes 69-74
//Byte 75
byte n2o_enable : 2;
byte n2o_arming_pin : 6;
byte n2o_minCLT;
byte n2o_maxMAP;
byte n2o_minTPS;
byte n2o_maxAFR;
byte n2o_minCLT; //Byte 76
byte n2o_maxMAP; //Byte 77
byte n2o_minTPS; //Byte 78
byte n2o_maxAFR; //Byte 79
//Byte 80
byte n2o_stage1_pin : 6;
byte n2o_pin_polarity : 1;
byte n2o_stage1_unused : 1;
byte n2o_stage1_minRPM;
byte n2o_stage1_maxRPM;
byte n2o_stage1_adderMin;
byte n2o_stage1_adderMax;
byte n2o_stage1_retard;
byte n2o_stage1_minRPM; //Byte 81
byte n2o_stage1_maxRPM; //Byte 82
byte n2o_stage1_adderMin; //Byte 83
byte n2o_stage1_adderMax; //Byte 84
byte n2o_stage1_retard; //Byte 85
//Byte 86
byte n2o_stage2_pin : 6;
byte n2o_stage2_unused : 2;
byte n2o_stage2_minRPM;
byte n2o_stage2_maxRPM;
byte n2o_stage2_adderMin;
byte n2o_stage2_adderMax;
byte n2o_stage2_retard;
byte n2o_stage2_minRPM; //Byte 87
byte n2o_stage2_maxRPM; //Byte 88
byte n2o_stage2_adderMin; //Byte 89
byte n2o_stage2_adderMax; //Byte 90
byte n2o_stage2_retard; //Byte 91
//Byte 92
byte knock_mode : 2;
byte knock_pin : 6;
//Byte 93
byte knock_trigger : 1;
byte knock_pullup : 1;
byte knock_limiterDisable : 1;
byte knock_unused : 2;
byte knock_count : 3;
byte knock_threshold;
byte knock_maxMAP;
byte knock_maxRPM;
byte knock_window_rpms[6];
byte knock_window_angle[6];
byte knock_window_dur[6];
byte knock_threshold; //Byte 94
byte knock_maxMAP; //Byte 95
byte knock_maxRPM; //Byte 96
byte knock_window_rpms[6]; //Bytes 97-102
byte knock_window_angle[6]; //Bytes 103-108
byte knock_window_dur[6]; //Bytes 109-114
byte knock_maxRetard;
byte knock_firstStep;
byte knock_stepSize;
byte knock_stepTime;
byte knock_maxRetard; //Byte 115
byte knock_firstStep; //Byte 116
byte knock_stepSize; //Byte 117
byte knock_stepTime; //Byte 118
byte knock_duration; //Time after knock retard starts that it should start recovering
byte knock_recoveryStepTime;
byte knock_recoveryStep;
byte knock_duration; //Time after knock retard starts that it should start recovering. Byte 119
byte knock_recoveryStepTime; //Byte 120
byte knock_recoveryStep; //Byte 121
//Byte 122
byte fuel2Algorithm : 3;
byte fuel2Mode : 2;
byte unused10_122 : 3;
byte fuel2Mode : 3;
byte fuel2SwitchVariable : 2;
uint16_t fuel2SwitchValue;
byte unused11_123_191[69];
byte vvtCLholdDuty;
byte vvtCLKP;
byte vvtCLKI;
byte vvtCLKD;
uint16_t vvtCLMinAng;
uint16_t vvtCLMaxAng;
byte unused11_123_191[59];
#if defined(CORE_AVR)
};
@ -982,20 +1020,22 @@ byte pinResetControl; // Output pin used control resetting the Arduino
// global variables // from speeduino.ino
extern struct statuses currentStatus; // from speeduino.ino
extern struct table3D fuelTable; //16x16 fuel map
extern struct table3D fuelTable2; //16x16 fuel map
extern struct table3D ignitionTable; //16x16 ignition map
extern struct table3D afrTable; //16x16 afr target map
extern struct table3D stagingTable; //8x8 afr target map
extern struct table2D taeTable; //4 bin TPS Acceleration Enrichment map (2D)
extern struct table2D WUETable; //10 bin Warm Up Enrichment map (2D)
extern struct table2D crankingEnrichTable; //4 bin cranking Enrichment map (2D)
extern struct table2D taeTable; /**< 4 bin TPS Acceleration Enrichment curve (2D) */
extern struct table2D maeTable; /**< 4 bin MAP based Acceleration Enrichment curve (2D) */
extern struct table2D WUETable; /**< 10 bin Warm Up Enrichment curve (2D) */
extern struct table2D crankingEnrichTable; /**< 4 bin cranking Enrichment curve (2D) */
extern struct config2 configPage2;
extern struct config4 configPage4;
extern struct config6 configPage6;
extern struct config9 configPage9;
extern struct config10 configPage10;
extern unsigned long currentLoopTime; //The time the current loop started (uS)
extern unsigned long previousLoopTime; //The time the previous loop started (uS)
volatile uint16_t ignitionCount; //The count of ignition events that have taken place since the engine started
extern unsigned long currentLoopTime; /**< The time (in uS) that the current mainloop started */
extern unsigned long previousLoopTime; /**< The time (in uS) that the previous mainloop started */
volatile uint16_t ignitionCount; /**< The count of ignition events that have taken place since the engine started */
extern byte cltCalibrationTable[CALIBRATION_TABLE_SIZE];
extern byte iatCalibrationTable[CALIBRATION_TABLE_SIZE];
extern byte o2CalibrationTable[CALIBRATION_TABLE_SIZE];

View File

@ -463,7 +463,7 @@ static inline void enableIdle()
}
#if defined(CORE_AVR) //AVR chips use the ISR for this
ISR(TIMER4_COMPC_vect)
ISR(TIMER1_COMPC_vect)
#else
static inline void idleInterrupt() //Most ARM chips can simply call a function
#endif

View File

@ -44,7 +44,7 @@ void initialiseAll()
Serial.begin(115200);
if (configPage9.enable_secondarySerial == 1) { CANSerial.begin(115200); }
#if defined(CORE_STM32) || defined(CORE_TEENSY)
configPage9.intcan_available = 1; // device has internal canbus
//Teensy onboard CAN not used currently
@ -60,6 +60,10 @@ void initialiseAll()
taeTable.xSize = 4;
taeTable.values = configPage4.taeValues;
taeTable.axisX = configPage4.taeBins;
maeTable.valueSize = SIZE_BYTE; //Set this table to use byte values
maeTable.xSize = 4;
maeTable.values = configPage4.maeRates;
maeTable.axisX = configPage4.maeBins;
WUETable.valueSize = SIZE_BYTE; //Set this table to use byte values
WUETable.xSize = 10;
WUETable.values = configPage2.wueValues;
@ -100,7 +104,7 @@ void initialiseAll()
IATRetardTable.axisX = configPage4.iatRetBins;
CLTAdvanceTable.valueSize = SIZE_BYTE;
CLTAdvanceTable.xSize = 6;
CLTAdvanceTable.values = configPage4.cltAdvValues;
CLTAdvanceTable.values = (byte*)configPage4.cltAdvValues;
CLTAdvanceTable.axisX = configPage4.cltAdvBins;
rotarySplitTable.valueSize = SIZE_BYTE;
rotarySplitTable.xSize = 8;
@ -246,7 +250,7 @@ void initialiseAll()
}
//Begin the main crank trigger interrupt pin setup
//The interrupt numbering is a bit odd - See here for reference: http://arduino.cc/en/Reference/AttachInterrupt
//The interrupt numbering is a bit odd - See here for reference: arduino.cc/en/Reference/AttachInterrupt
//These assignments are based on the Arduino Mega AND VARY BETWEEN BOARDS. Please confirm the board you are using and update acordingly.
currentStatus.RPM = 0;
currentStatus.hasSync = false;
@ -267,7 +271,11 @@ void initialiseAll()
initialiseTriggers();
//End crank triger interrupt attachment
req_fuel_uS = req_fuel_uS / engineSquirtsPerCycle; //The req_fuel calculation above gives the total required fuel (At VE 100%) in the full cycle. If we're doing more than 1 squirt per cycle then we need to split the amount accordingly. (Note that in a non-sequential 4-stroke setup you cannot have less than 2 squirts as you cannot determine the stroke to make the single squirt on)
if(configPage2.strokes == FOUR_STROKE)
{
//Default is 1 squirt per revolution, so we halve the given req-fuel figure (Which would be over 2 revolutions)
req_fuel_uS = req_fuel_uS / 2; //The req_fuel calculation above gives the total required fuel (At VE 100%) in the full cycle. If we're doing more than 1 squirt per cycle then we need to split the amount accordingly. (Note that in a non-sequential 4-stroke setup you cannot have less than 2 squirts as you cannot determine the stroke to make the single squirt on)
}
//Initial values for loop times
previousLoopTime = 0;
@ -280,7 +288,6 @@ void initialiseAll()
if(configPage2.strokes == FOUR_STROKE) { CRANK_ANGLE_MAX_INJ = 720 / currentStatus.nSquirts; }
else { CRANK_ANGLE_MAX_INJ = 360 / currentStatus.nSquirts; }
//Calculate the number of degrees between cylinders
switch (configPage2.nCylinders) {
case 1:
@ -420,7 +427,7 @@ void initialiseAll()
//Adjust the injection angles based on the number of squirts
if (currentStatus.nSquirts > 2)
{
channel2InjDegrees = channel2InjDegrees / (currentStatus.nSquirts / 2);
channel2InjDegrees = (channel2InjDegrees * 2) / currentStatus.nSquirts;
}
if( (configPage4.sparkMode == IGN_MODE_SEQUENTIAL) && (configPage2.strokes == FOUR_STROKE) )
@ -551,8 +558,8 @@ void initialiseAll()
//Adjust the injection angles based on the number of squirts
if (currentStatus.nSquirts > 2)
{
channel2InjDegrees = channel2InjDegrees / (currentStatus.nSquirts / 2);
channel3InjDegrees = channel3InjDegrees / (currentStatus.nSquirts / 2);
channel2InjDegrees = (channel2InjDegrees * 2) / currentStatus.nSquirts;
channel3InjDegrees = (channel3InjDegrees * 2) / currentStatus.nSquirts;
}
#if INJ_CHANNELS >= 6
@ -598,9 +605,9 @@ void initialiseAll()
//Adjust the injection angles based on the number of squirts
if (currentStatus.nSquirts > 2)
{
channel2InjDegrees = channel2InjDegrees / (currentStatus.nSquirts / 2);
channel3InjDegrees = channel3InjDegrees / (currentStatus.nSquirts / 2);
channel4InjDegrees = channel4InjDegrees / (currentStatus.nSquirts / 2);
channel2InjDegrees = (channel2InjDegrees * 2) / currentStatus.nSquirts;
channel3InjDegrees = (channel3InjDegrees * 2) / currentStatus.nSquirts;
channel4InjDegrees = (channel4InjDegrees * 2) / currentStatus.nSquirts;
}
#if INJ_CHANNELS >= 8
@ -654,6 +661,15 @@ void initialiseAll()
else if (CRANK_ANGLE_MAX_IGN > CRANK_ANGLE_MAX_INJ) { CRANK_ANGLE_MAX = CRANK_ANGLE_MAX_IGN; }
else { CRANK_ANGLE_MAX = CRANK_ANGLE_MAX_INJ; }
currentStatus.status3 = currentStatus.nSquirts << BIT_STATUS3_NSQUIRTS1; //Top 3 bits of the status3 variable are the number of squirts. This must be done after the above section due to nSquirts being forced to 1 for sequential
//Special case:
//3 or 5 squirts per cycle MUST be tracked over 720 degrees. This is because the angles for them (Eg 720/3=240) are not evenly divisible into 360
//This is ONLY the case on 4 stroke systems
if( (currentStatus.nSquirts == 3) || (currentStatus.nSquirts == 5) )
{
if(configPage2.strokes == FOUR_STROKE) { CRANK_ANGLE_MAX = 720; }
}
switch(configPage4.sparkMode)
{
@ -998,7 +1014,7 @@ void setPinMapping(byte boardID)
pinCoil3 = 30;
pinO2 = A22;
#elif defined(STM32F4)
//Black F407VE http://wiki.stm32duino.com/index.php?title=STM32F407
//Black F407VE wiki.stm32duino.com/index.php?title=STM32F407
//PC8~PC12 SDio
//PA13~PA15 & PB4 SWD(debug) pins
//PB0 EEPROM CS pin
@ -1039,8 +1055,8 @@ void setPinMapping(byte boardID)
pinTrigger = PE3; //The CAS pin
pinTrigger2 = PE4; //The Cam Sensor pin
#elif defined(CORE_STM32)
//blue pill http://wiki.stm32duino.com/index.php?title=Blue_Pill
//Maple mini http://wiki.stm32duino.com/index.php?title=Maple_Mini
//blue pill wiki.stm32duino.com/index.php?title=Blue_Pill
//Maple mini wiki.stm32duino.com/index.php?title=Maple_Mini
//pins PA12, PA11 are used for USB or CAN couldn't be used for GPIO
pinInjector1 = PB7; //Output pin injector 1 is on
pinInjector2 = PB6; //Output pin injector 2 is on
@ -1076,8 +1092,109 @@ void setPinMapping(byte boardID)
#endif
break;
case 6:
//Pin mappings as per the 2001-05 MX5 PNP shield
pinInjector1 = 44; //Output pin injector 1 is on
pinInjector2 = 46; //Output pin injector 2 is on
pinInjector3 = 47; //Output pin injector 3 is on
pinInjector4 = 45; //Output pin injector 4 is on
pinInjector5 = 14; //Output pin injector 5 is on
pinCoil1 = 42; //Pin for coil 1
pinCoil2 = 43; //Pin for coil 2
pinCoil3 = 32; //Pin for coil 3
pinCoil4 = 33; //Pin for coil 4
pinCoil5 = 34; //Pin for coil 5 PLACEHOLDER value for now
pinTrigger = 19; //The CAS pin
pinTrigger2 = 18; //The Cam Sensor pin
pinTPS = A2;//TPS input pin
pinMAP = A5; //MAP sensor pin
pinIAT = A0; //IAT sensor pin
pinCLT = A1; //CLS sensor pin
pinO2 = A3; //O2 Sensor pin
pinBat = A4; //Battery reference voltage pin
pinDisplayReset = 48; // OLED reset pin
pinTachOut = 23; //Tacho output pin (Goes to ULN2803)
pinIdle1 = 5; //Single wire idle control
pinBoost = 4;
pinVVT_1 = 11; //Default VVT output
pinIdle2 = 4; //2 wire idle control (Note this is shared with boost!!!)
pinFuelPump = 40; //Fuel pump output
pinStepperDir = 16; //Direction pin for DRV8825 driver
pinStepperStep = 17; //Step pin for DRV8825 driver
pinStepperEnable = 24;
pinFan = 41; //Pin for the fan output
pinLaunch = 12; //Can be overwritten below
pinFlex = 3; // Flex sensor (Must be external interrupt enabled)
pinResetControl = 39; //Reset control output
//This is NOT correct. It has not yet been tested with this board
#if defined(CORE_TEENSY)
pinTrigger = 23;
pinTrigger2 = 36;
pinStepperDir = 34;
pinStepperStep = 35;
pinCoil1 = 33; //Done
pinCoil2 = 24; //Done
pinCoil3 = 51; //Won't work (No mapping for pin 32)
pinCoil4 = 52; //Won't work (No mapping for pin 33)
pinFuelPump = 26; //Requires PVT4 adapter or above
pinFan = 50; //Won't work (No mapping for pin 35)
pinTachOut = 28; //Done
#endif
break;
case 8:
//Pin mappings as per the 1996-97 MX5 PNP shield
pinInjector1 = 11; //Output pin injector 1 is on
pinInjector2 = 10; //Output pin injector 2 is on
pinInjector3 = 9; //Output pin injector 3 is on
pinInjector4 = 8; //Output pin injector 4 is on
pinInjector5 = 14; //Output pin injector 5 is on
pinCoil1 = 39; //Pin for coil 1
pinCoil2 = 41; //Pin for coil 2
pinCoil3 = 32; //Pin for coil 3
pinCoil4 = 33; //Pin for coil 4
pinCoil5 = 34; //Pin for coil 5 PLACEHOLDER value for now
pinTrigger = 19; //The CAS pin
pinTrigger2 = 18; //The Cam Sensor pin
pinTPS = A2;//TPS input pin
pinMAP = A5; //MAP sensor pin
pinIAT = A0; //IAT sensor pin
pinCLT = A1; //CLS sensor pin
pinO2 = A3; //O2 Sensor pin
pinBat = A4; //Battery reference voltage pin
pinDisplayReset = 48; // OLED reset pin
pinTachOut = A9; //Tacho output pin (Goes to ULN2803)
pinIdle1 = 2; //Single wire idle control
pinBoost = 4;
pinIdle2 = 4; //2 wire idle control (Note this is shared with boost!!!)
pinFuelPump = 49; //Fuel pump output
pinStepperDir = 16; //Direction pin for DRV8825 driver
pinStepperStep = 17; //Step pin for DRV8825 driver
pinStepperEnable = 24;
pinFan = 35; //Pin for the fan output
pinLaunch = 37; //Can be overwritten below
pinFlex = 3; // Flex sensor (Must be external interrupt enabled)
pinResetControl = 44; //Reset control output
//This is NOT correct. It has not yet been tested with this board
#if defined(CORE_TEENSY)
pinTrigger = 23;
pinTrigger2 = 36;
pinStepperDir = 34;
pinStepperStep = 35;
pinCoil1 = 33; //Done
pinCoil2 = 24; //Done
pinCoil3 = 51; //Won't work (No mapping for pin 32)
pinCoil4 = 52; //Won't work (No mapping for pin 33)
pinFuelPump = 26; //Requires PVT4 adapter or above
pinFan = 50; //Won't work (No mapping for pin 35)
pinTachOut = 28; //Done
#endif
break;
case 9:
//Pin mappings as per the MX5 PNP shield
//Pin mappings as per the 89-95 MX5 PNP shield
pinInjector1 = 11; //Output pin injector 1 is on
pinInjector2 = 10; //Output pin injector 2 is on
pinInjector3 = 9; //Output pin injector 3 is on
@ -1325,6 +1442,51 @@ void setPinMapping(byte boardID)
#endif
break;
case 45:
#ifndef SMALL_FLASH_MODE //No support for bluepill here anyway
//Pin mappings for the DIY-EFI CORE4 Module
pinInjector1 = 10; //Output pin injector 1 is on
pinInjector2 = 11; //Output pin injector 2 is on
pinInjector3 = 12; //Output pin injector 3 is on
pinInjector4 = 9; //Output pin injector 4 is on
pinCoil1 = 39; //Pin for coil 1
pinCoil2 = 29; //Pin for coil 2
pinCoil3 = 28; //Pin for coil 3
pinCoil4 = 27; //Pin for coil 4
pinCoil4 = 26; //Placeholder for coil 5
pinTrigger = 19; //The CAS pin
pinTrigger2 = 18; //The Cam Sensor pin
pinFlex = 20; // Flex sensor
pinTPS = A3; //TPS input pin
pinMAP = A2; //MAP sensor pin
pinBaro = A15; //Baro sensor pin
pinIAT = A11; //IAT sensor pin
pinCLT = A4; //CLS sensor pin
pinO2 = A12; //O2 Sensor pin
pinO2_2 = A13; //O2 sensor pin (second sensor)
pinBat = A1; //Battery reference voltage pin
pinSpareTemp1 = A14; //spare Analog input 1
pinLaunch = 24; //Can be overwritten below
pinDisplayReset = 48; // OLED reset pin PLACEHOLDER value for now
pinTachOut = 38; //Tacho output pin
pinIdle1 = 42; //Single wire idle control
pinIdle2 = 43; //2 wire idle control
pinFuelPump = 41; //Fuel pump output
pinVVT_1 = 44; //Default VVT output
pinStepperDir = 32; //Direction pin for DRV8825 driver
pinStepperStep = 31; //Step pin for DRV8825 driver
pinStepperEnable = 30; //Enable pin for DRV8825 driver
pinBoost = 45; //Boost control
pinSpareLOut1 = 37; //low current output spare1
pinSpareLOut2 = 36; //low current output spare2
pinSpareLOut3 = 35; //low current output spare3
pinSpareLOut4 = 34; //low current output spare4
pinSpareLOut5 = 33; //low current output spare4
pinFan = 40; //Pin for the fan output
pinResetControl = 46; //Reset control output PLACEHOLDER value for now
#endif
break;
#if defined(CORE_TEENSY)
case 50:
//Pin mappings as per the teensy rev A shield
@ -1399,7 +1561,7 @@ void setPinMapping(byte boardID)
default:
#if defined(STM32F4)
//Black F407VE http://wiki.stm32duino.com/index.php?title=STM32F407
//Black F407VE wiki.stm32duino.com/index.php?title=STM32F407
//PC8~PC12 SDio
//PA13~PA15 & PB4 SWD(debug) pins
//PB0 EEPROM CS pin
@ -1524,6 +1686,9 @@ void setPinMapping(byte boardID)
pinMode(pinBoost, OUTPUT);
pinMode(pinVVT_1, OUTPUT);
//This is a legacy mode option to revert the MAP reading behaviour to match what was in place prior to the 201905 firmware
if(configPage2.legacyMAP > 0) { digitalWrite(pinMAP, HIGH); }
inj1_pin_port = portOutputRegister(digitalPinToPort(pinInjector1));
inj1_pin_mask = digitalPinToBitMask(pinInjector1);
inj2_pin_port = portOutputRegister(digitalPinToPort(pinInjector2));
@ -1612,13 +1777,6 @@ void setPinMapping(byte boardID)
triggerSec_pin_port = portInputRegister(digitalPinToPort(pinTrigger2));
triggerSec_pin_mask = digitalPinToBitMask(pinTrigger2);
#if defined(CORE_STM32)
#else
//Set default values
digitalWrite(pinMAP, HIGH);
//digitalWrite(pinO2, LOW);
digitalWrite(pinTPS, LOW);
#endif
}
void initialiseTriggers()

View File

@ -15,7 +15,7 @@ int fastMap(unsigned long x, int in_min, int in_max, int out_min, int out_max)
/*
The following are all fast versions of specific divisions
Ref: http://www.hackersdelight.org/divcMore.pdf
Ref: www.hackersdelight.org/divcMore.pdf
*/
//Unsigned divide by 10
@ -31,20 +31,6 @@ unsigned int divu10(unsigned int n)
return q + ((r + 6) >> 4);
}
//Signed divide by 10
int divs10(long n)
{
long q, r, p;
p = n + ( (n>>31) & 9);
q = (p >> 1) + (p >> 2);
q = q + (q >> 4);
q = q + (q >> 8);
q = q + (q >> 16);
q = q >> 3;
r = p - (q * 10);
return q + ((r + 6) >> 4);
}
//Signed divide by 100
int divs100(long n)
{

View File

@ -854,7 +854,7 @@ static inline void fuelSchedule4Interrupt() //Most ARM chips can simply call a f
#if (INJ_CHANNELS >= 5)
#if defined(CORE_AVR) //AVR chips use the ISR for this
ISR(TIMER1_COMPC_vect) //fuelSchedule5
ISR(TIMER4_COMPC_vect) //fuelSchedule5
#else
static inline void fuelSchedule5Interrupt() //Most ARM chips can simply call a function
#endif
@ -1139,7 +1139,7 @@ static inline void ignitionSchedule4Interrupt() //Most ARM chips can simply call
#if IGN_CHANNELS >= 5
#if defined(CORE_AVR) //AVR chips use the ISR for this
ISR(TIMER1_COMPC_vect) //ignitionSchedule5
ISR(TIMER4_COMPC_vect) //ignitionSchedule5
#else
static inline void ignitionSchedule5Interrupt() //Most ARM chips can simply call a function
#endif
@ -1165,7 +1165,7 @@ static inline void ignitionSchedule5Interrupt() //Most ARM chips can simply call
#if IGN_CHANNELS >= 6
#if defined(CORE_AVR) //AVR chips use the ISR for this
ISR(TIMER1_COMPC_vect) //ignitionSchedule6 NOT CORRECT!!!
ISR(TIMER4_COMPC_vect) //ignitionSchedule6 NOT CORRECT!!!
#else
static inline void ignitionSchedule6Interrupt() //Most ARM chips can simply call a function
#endif
@ -1191,7 +1191,7 @@ static inline void ignitionSchedule6Interrupt() //Most ARM chips can simply call
#if IGN_CHANNELS >= 7
#if defined(CORE_AVR) //AVR chips use the ISR for this
ISR(TIMER1_COMPC_vect) //ignitionSchedule6 NOT CORRECT!!!
ISR(TIMER4_COMPC_vect) //ignitionSchedule6 NOT CORRECT!!!
#else
static inline void ignitionSchedule7Interrupt() //Most ARM chips can simply call a function
#endif
@ -1217,7 +1217,7 @@ static inline void ignitionSchedule7Interrupt() //Most ARM chips can simply call
#if IGN_CHANNELS >= 8
#if defined(CORE_AVR) //AVR chips use the ISR for this
ISR(TIMER1_COMPC_vect) //ignitionSchedule8 NOT CORRECT!!!
ISR(TIMER4_COMPC_vect) //ignitionSchedule8 NOT CORRECT!!!
#else
static inline void ignitionSchedule8Interrupt() //Most ARM chips can simply call a function
#endif

View File

@ -36,6 +36,12 @@ unsigned long EMAPrunningValue; //As above but for EMAP
unsigned int MAPcount; //Number of samples taken in the current MAP cycle
uint32_t MAPcurRev; //Tracks which revolution we're sampling on
bool auxIsEnabled;
byte TPSlast; /**< The previous TPS reading */
unsigned long TPS_time; //The time the TPS sample was taken
unsigned long TPSlast_time; //The time the previous TPS sample was taken
byte MAPlast; /**< The previous MAP reading */
unsigned long MAP_time; //The time the MAP sample was taken
unsigned long MAPlast_time; //The time the previous MAP sample was taken
//These variables are used for tracking the number of running sensors values that appear to be errors. Once a threshold is reached, the sensor reading will go to default value and assume the sensor is faulty
byte mapErrorCount = 0;
@ -49,10 +55,10 @@ byte cltErrorCount = 0;
*/
#define ADC_FILTER(input, alpha, prior) (((long)input * (256 - alpha) + ((long)prior * alpha))) >> 8
//These functions all do checks on a pin to determine if it is already in use by another (higher importance) function
#define pinIsInjector(pin) ( (pin == pinInjector1) || (pin == pinInjector2) || (pin == pinInjector3) || (pin == pinInjector4) )
#define pinIsIgnition(pin) ( (pin == pinCoil1) || (pin == pinCoil2) || (pin == pinCoil3) || (pin == pinCoil4) )
#define pinIsSensor(pin) ( (pin == pinCLT) || (pin == pinIAT) || (pin == pinMAP) || (pin == pinTPS) || (pin == pinO2) || (pin == pinBat) )
#define pinIsUsed(pin) ( pinIsInjector(pin) || pinIsIgnition(pin) || pinIsSensor(pin) )
#define pinIsInjector(pin) ( ((pin) == pinInjector1) || ((pin) == pinInjector2) || ((pin) == pinInjector3) || ((pin) == pinInjector4) )
#define pinIsIgnition(pin) ( ((pin) == pinCoil1) || ((pin) == pinCoil2) || ((pin) == pinCoil3) || ((pin) == pinCoil4) )
#define pinIsSensor(pin) ( ((pin) == pinCLT) || ((pin) == pinIAT) || ((pin) == pinMAP) || ((pin) == pinTPS) || ((pin) == pinO2) || ((pin) == pinBat) )
#define pinIsUsed(pin) ( pinIsInjector((pin)) || pinIsIgnition((pin)) || pinIsSensor((pin)) )
static inline void instanteneousMAPReading() __attribute__((always_inline));
static inline void readMAP() __attribute__((always_inline));

View File

@ -43,7 +43,7 @@ void initialiseADC()
#else
//This sets the ADC (Analog to Digitial Converter) to run at 1Mhz, greatly reducing analog read times (MAP/TPS) when using the standard analogRead() function
//1Mhz is the fastest speed permitted by the CPU without affecting accuracy
//Please see chapter 11 of 'Practical Arduino' (http://books.google.com.au/books?id=HsTxON1L6D4C&printsec=frontcover#v=onepage&q&f=false) for more detail
//Please see chapter 11 of 'Practical Arduino' (books.google.com.au/books?id=HsTxON1L6D4C&printsec=frontcover#v=onepage&q&f=false) for more detail
BIT_SET(ADCSRA,ADPS2);
BIT_CLEAR(ADCSRA,ADPS1);
BIT_CLEAR(ADCSRA,ADPS0);
@ -120,6 +120,11 @@ void initialiseADC()
static inline void instanteneousMAPReading()
{
//Update the calculation times and last value. These are used by the MAP based Accel enrich
MAPlast = currentStatus.MAP;
MAPlast_time = MAP_time;
MAP_time = micros();
unsigned int tempReading;
//Instantaneous MAP readings
#if defined(ANALOG_ISR_MAP)
@ -196,6 +201,11 @@ static inline void readMAP()
//Sanity check
if( (MAPrunningValue != 0) && (MAPcount != 0) )
{
//Update the calculation times and last value. These are used by the MAP based Accel enrich
MAPlast = currentStatus.MAP;
MAPlast_time = MAP_time;
MAP_time = micros();
currentStatus.mapADC = ldiv(MAPrunningValue, MAPcount).quot;
currentStatus.MAP = fastMap10Bit(currentStatus.mapADC, configPage2.mapMin, configPage2.mapMax); //Get the current MAP value
if(currentStatus.MAP < 0) { currentStatus.MAP = 0; } //Sanity check
@ -240,6 +250,12 @@ static inline void readMAP()
else
{
//Reaching here means that the last cylce has completed and the MAP value should be calculated
//Update the calculation times and last value. These are used by the MAP based Accel enrich
MAPlast = currentStatus.MAP;
MAPlast_time = MAP_time;
MAP_time = micros();
currentStatus.mapADC = MAPrunningValue;
currentStatus.MAP = fastMap10Bit(currentStatus.mapADC, configPage2.mapMin, configPage2.mapMax); //Get the current MAP value
if(currentStatus.MAP < 0) { currentStatus.MAP = 0; } //Sanity check
@ -259,8 +275,8 @@ static inline void readMAP()
void readTPS()
{
currentStatus.TPSlast = currentStatus.TPS;
currentStatus.TPSlast_time = currentStatus.TPS_time;
TPSlast = currentStatus.TPS;
TPSlast_time = TPS_time;
#if defined(ANALOG_ISR)
byte tempTPS = fastMap1023toX(AnChannel[pinTPS-A0], 255); //Get the current raw TPS ADC value and map it into a byte
#else
@ -291,7 +307,7 @@ void readTPS()
currentStatus.TPS = map(tempADC, configPage2.tpsMax, configPage2.tpsMin, 0, 100);
}
currentStatus.TPS_time = micros();
TPS_time = micros();
}
void readCLT(bool useFilter)
@ -344,15 +360,25 @@ void readBaro()
void readO2()
{
unsigned int tempReading;
#if defined(ANALOG_ISR)
tempReading = fastMap1023toX(AnChannel[pinO2-A0], 511); //Get the current O2 value.
#else
tempReading = analogRead(pinO2);
tempReading = fastMap1023toX(analogRead(pinO2), 511); //Get the current O2 value.
#endif
currentStatus.O2ADC = ADC_FILTER(tempReading, configPage4.ADCFILTER_O2, currentStatus.O2ADC);
currentStatus.O2 = o2CalibrationTable[currentStatus.O2ADC];
//An O2 read is only performed if an O2 sensor type is selected. This is to prevent potentially dangerous use of the O2 readings prior to proper setup/calibration
if(configPage6.egoType > 0)
{
unsigned int tempReading;
#if defined(ANALOG_ISR)
tempReading = fastMap1023toX(AnChannel[pinO2-A0], 511); //Get the current O2 value.
#else
tempReading = analogRead(pinO2);
tempReading = fastMap1023toX(analogRead(pinO2), 511); //Get the current O2 value.
#endif
currentStatus.O2ADC = ADC_FILTER(tempReading, configPage4.ADCFILTER_O2, currentStatus.O2ADC);
currentStatus.O2 = o2CalibrationTable[currentStatus.O2ADC];
}
else
{
currentStatus.O2ADC = 0;
currentStatus.O2 = 0;
}
}
void readO2_2()
@ -380,6 +406,9 @@ void readBat()
tempReading = fastMap1023toX(analogRead(pinBat), 245); //Get the current raw Battery value. Permissible values are from 0v to 24.5v (245)
#endif
//Apply the offset calibration value to the reading
tempReading += configPage4.batVoltCorrect;
//The following is a check for if the voltage has jumped up from under 5.5v to over 7v.
//If this occurs, it's very likely that the system has gone from being powered by USB to being powered from the 12v power source.
//Should that happen, we retrigger the fuel pump priming and idle homing (If using a stepper)

View File

@ -19,7 +19,7 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
#ifndef UNIT_TEST // Scope guard for unit testing
#include <stdint.h> //https://developer.mbed.org/handbook/C-Data-Types
#include <stdint.h> //developer.mbed.org/handbook/C-Data-Types
//************************************************
#include "globals.h"
#include "speeduino.h"
@ -132,6 +132,7 @@ void loop()
VVT_PIN_LOW();
DISABLE_VVT_TIMER();
boostDisable();
if(configPage4.ignBypassEnabled > 0) { digitalWrite(pinIgnBypass, LOW); } //Reset the ignition bypass ready for next crank attempt
}
//***Perform sensor reads***
@ -286,6 +287,7 @@ void loop()
currentStatus.VE = getVE();
//If the secondary fuel table is in use, also get the VE value from there
BIT_CLEAR(currentStatus.status3, BIT_STATUS3_FUEL2_ACTIVE); //Clear the bit indicating that the 2nd fuel table is in use.
if(configPage10.fuel2Mode > 0)
{
currentStatus.VE2 = getVE2();
@ -293,7 +295,9 @@ void loop()
if(configPage10.fuel2Mode == FUEL2_MODE_MULTIPLY)
{
//Fuel 2 table is treated as a % value. Table 1 and 2 are multiplied together and divded by 100
totalVE = ((uint16_t)currentStatus.VE * (uint16_t)currentStatus.VE2) / 100;
uint16_t combinedVE = ((uint16_t)currentStatus.VE * (uint16_t)currentStatus.VE2) / 100;
if(combinedVE <= 255) { totalVE = combinedVE; }
else { totalVE = 255; }
}
else if(configPage10.fuel2Mode == FUEL2_MODE_ADD)
{
@ -302,7 +306,14 @@ void loop()
if(combinedVE <= 255) { totalVE = combinedVE; }
else { totalVE = 255; }
}
else if(configPage10.fuel2Mode == FUEL2_MODE_SWITCH)
else if(configPage10.fuel2Mode == FUEL2_MODE_CONDITIONAL_SWITCH )
{
if(configPage10.fuel2SwitchVariable == FUEL2_CONDITION_RPM)
{
}
}
else if(configPage10.fuel2Mode == FUEL2_MODE_INPUT_SWITCH)
{
}
@ -399,8 +410,9 @@ void loop()
//Check that the duty cycle of the chosen pulsewidth isn't too high.
unsigned long pwLimit = percentage(configPage2.dutyLim, revolutionTime); //The pulsewidth limit is determined to be the duty cycle limit (Eg 85%) by the total time it takes to perform 1 revolution
if (CRANK_ANGLE_MAX_INJ == 720) { pwLimit = pwLimit * 2; } //For sequential, the maximum pulse time is double (2 revolutions). Wouldn't work for 2 stroke...
else if (CRANK_ANGLE_MAX_INJ < 360) { pwLimit = pwLimit / currentStatus.nSquirts; } //Handle cases where there are multiple squirts per rev
//Handle multiple squirts per rev
if (configPage2.strokes == FOUR_STROKE) { pwLimit = pwLimit * 2 / currentStatus.nSquirts; }
else { pwLimit = pwLimit / currentStatus.nSquirts; }
//Apply the pwLimit if staging is dsiabled and engine is not cranking
if( (!BIT_CHECK(currentStatus.engine, BIT_ENGINE_CRANK)) && (configPage10.stagingEnabled == false) ) { if (currentStatus.PW1 > pwLimit) { currentStatus.PW1 = pwLimit; } }
@ -462,10 +474,10 @@ void loop()
configPage2.inj4Ang = configPage2.inj1Ang;
}
unsigned int PWdivTimerPerDegree = div(currentStatus.PW1, timePerDegree).quot; //How many crank degrees the calculated PW will take at the current speed
//This is a little primitive, but is based on the idea that all fuel needs to be delivered before the inlet valve opens. See http://www.extraefi.co.uk/sequential_fuel.html for more detail
//This is a little primitive, but is based on the idea that all fuel needs to be delivered before the inlet valve opens. See www.extraefi.co.uk/sequential_fuel.html for more detail
if(configPage2.inj1Ang > PWdivTimerPerDegree) { injector1StartAngle = configPage2.inj1Ang - ( PWdivTimerPerDegree ); }
else { injector1StartAngle = configPage2.inj1Ang + CRANK_ANGLE_MAX_INJ - PWdivTimerPerDegree; } //Just incase
if(injector1StartAngle > CRANK_ANGLE_MAX_INJ) {injector1StartAngle -= CRANK_ANGLE_MAX_INJ;}
while(injector1StartAngle > CRANK_ANGLE_MAX_INJ) { injector1StartAngle -= CRANK_ANGLE_MAX_INJ; }
//Repeat the above for each cylinder
switch (configPage2.nCylinders)
@ -488,7 +500,6 @@ void loop()
injector3StartAngle = calculateInjector3StartAngle(PWdivTimerPerDegree);
injector4StartAngle = injector3StartAngle + (CRANK_ANGLE_MAX_INJ / 2); //Phase this either 180 or 360 degrees out from inj3 (In reality this will always be 180 as you can't have sequential and staged currently)
if(injector4StartAngle < 0) {injector4StartAngle += CRANK_ANGLE_MAX_INJ;}
if(injector4StartAngle > (uint16_t)CRANK_ANGLE_MAX_INJ) { injector4StartAngle -= CRANK_ANGLE_MAX_INJ; }
}
break;
@ -525,7 +536,6 @@ void loop()
injector3StartAngle = calculateInjector3StartAngle(PWdivTimerPerDegree);
injector4StartAngle = injector3StartAngle + (CRANK_ANGLE_MAX_INJ / 2); //Phase this either 180 or 360 degrees out from inj3 (In reality this will always be 180 as you can't have sequential and staged currently)
if(injector4StartAngle < 0) {injector4StartAngle += CRANK_ANGLE_MAX_INJ;}
if(injector4StartAngle > (uint16_t)CRANK_ANGLE_MAX_INJ) { injector4StartAngle -= CRANK_ANGLE_MAX_INJ; }
}
break;

View File

@ -82,8 +82,6 @@ bool PID::Compute()
******************************************************************************/
void PID::SetTunings(byte Kp, byte Ki, byte Kd)
{
if (Kp<0 || Ki<0 || Kd<0) return;
dispKp = Kp; dispKi = Ki; dispKd = Kd;
/*
@ -270,7 +268,6 @@ bool integerPID::Compute()
******************************************************************************/
void integerPID::SetTunings(byte Kp, byte Ki, byte Kd)
{
if (Kp<0 || Ki<0 || Kd<0) return;
if ( dispKp == Kp && dispKi == Ki && dispKd == Kd ) return; //Only do anything if one of the values has changed
dispKp = Kp; dispKi = Ki; dispKd = Kd;
@ -479,7 +476,6 @@ bool integerPID_ideal::Compute()
******************************************************************************/
void integerPID_ideal::SetTunings(byte Kp, byte Ki, byte Kd)
{
if (Kp<0 || Ki<0 || Kd<0) return;
if ( dispKp == Kp && dispKi == Ki && dispKd == Kd ) return; //Only do anything if one of the values has changed
dispKp = Kp; dispKi = Ki; dispKd = Kd;

View File

@ -23,6 +23,7 @@ void writeAllConfig()
if (eepromWritesPending == false) { writeConfig(seqFuelPage); }
if (eepromWritesPending == false) { writeConfig(canbusPage); }
if (eepromWritesPending == false) { writeConfig(warmupPage); }
if (eepromWritesPending == false) { writeConfig(fuelMap2Page); }
}
@ -397,15 +398,15 @@ void writeConfig(byte tableNum)
{
if( (writeCounter > EEPROM_MAX_WRITE_BLOCK) ) { break; } //This is a safety check to make sure we don't attempt to write too much to the EEPROM at a time.
offset = x - EEPROM_CONFIG11_MAP;
EEPROM.update(x, fuelTable2.values[15-(offset/16)][offset%16]); writeCounter++; //Write the 16x16 map
if( EEPROM.read(x) != (fuelTable2.values[15-(offset/16)][offset%16]) ) { EEPROM.write(x, fuelTable2.values[15-(offset/16)][offset%16]); writeCounter++; } //Write the 16x16 map
}
//RPM bins
for(int x=EEPROM_CONFIG11_XBINS; x<EEPROM_CONFIG11_YBINS; x++)
{
if( (writeCounter > EEPROM_MAX_WRITE_BLOCK) ) { break; } //This is a safety check to make sure we don't attempt to write too much to the EEPROM at a time.
offset = x - EEPROM_CONFIG1_XBINS;
EEPROM.update(x, byte(fuelTable2.axisX[offset]/TABLE_RPM_MULTIPLIER)); writeCounter++; //RPM bins are divided by 100 and converted to a byte
offset = x - EEPROM_CONFIG11_XBINS;
if( EEPROM.read(x) != (byte(fuelTable2.axisX[offset]/TABLE_RPM_MULTIPLIER)) ) { EEPROM.write(x, byte(fuelTable2.axisX[offset]/TABLE_RPM_MULTIPLIER)); writeCounter++; } //RPM bins are divided by 100 and converted to a byte
}
//TPS/MAP bins
for(int x=EEPROM_CONFIG11_YBINS; x<EEPROM_CONFIG11_END; x++)
@ -422,6 +423,7 @@ void writeConfig(byte tableNum)
default:
break;
}
}
void loadConfig()

View File

@ -19,7 +19,9 @@ void table2D_setSize(struct table2D* targetTable, byte newSize)
//2D tables can contain either bytes or ints, depending on the value of the valueSize field
if(targetTable->valueSize == SIZE_BYTE)
{
targetTable->values = (byte *)realloc(targetTable->values, newSize * sizeof(byte));
//The following lines have MISRA suppressions as realloc is otherwise forbidden. These calls have been verified as unable to be executed from anywhere but controlled areas.
//cppcheck-suppress misra-21.3
targetTable->values = (byte *)realloc(targetTable->values, newSize * sizeof(byte)); //cppcheck-suppress misra_21.3
targetTable->axisX = (byte *)realloc(targetTable->axisX, newSize * sizeof(byte));
targetTable->xSize = newSize;
}
@ -187,7 +189,7 @@ int table2D_getValue(struct table2D *fromTable, int X_in)
*/
//Non-Float version
int yVal;
uint16_t yVal;
if (fromTable->valueSize == SIZE_BYTE)
{
//Byte version
@ -217,7 +219,7 @@ int table2D_getValue(struct table2D *fromTable, int X_in)
//This function pulls a value from a 3D table given a target for X and Y coordinates.
//It performs a 2D linear interpolation as descibred in: http://www.megamanual.com/v22manual/ve_tuner.pdf
//It performs a 2D linear interpolation as descibred in: www.megamanual.com/v22manual/ve_tuner.pdf
int get3DTableValue(struct table3D *fromTable, int Y_in, int X_in)
{
int X = X_in;
@ -267,7 +269,7 @@ int get3DTableValue(struct table3D *fromTable, int Y_in, int X_in)
else
//If it's not caught by one of the above scenarios, give up and just run the loop
{
for (byte x = fromTable->xSize-1; x >= 0; x--)
for (int8_t x = fromTable->xSize-1; x >= 0; x--)
{
//Checks the case where the X value is exactly what was requested
if ( (X == fromTable->axisX[x]) || (x == 0) )
@ -336,7 +338,7 @@ int get3DTableValue(struct table3D *fromTable, int Y_in, int X_in)
//If it's not caught by one of the above scenarios, give up and just run the loop
{
for (byte y = fromTable->ySize-1; y >= 0; y--)
for (int8_t y = fromTable->ySize-1; y >= 0; y--)
{
//Checks the case where the Y value is exactly what was requested
if ( (Y == fromTable->axisY[y]) || (y==0) )
@ -391,11 +393,11 @@ int get3DTableValue(struct table3D *fromTable, int Y_in, int X_in)
//Initial check incase the values were hit straight on
long p = (long)X - xMinValue;
unsigned long p = (long)X - xMinValue;
if (xMaxValue == xMinValue) { p = (p << 8); } //This only occurs if the requested X value was equal to one of the X axis bins
else { p = ( (p << 8) / (xMaxValue - xMinValue) ); } //This is the standard case
long q;
unsigned long q;
if (yMaxValue == yMinValue)
{
q = (long)Y - yMinValue;

View File

@ -84,7 +84,7 @@ void oneMSInterval() //Most ARM chips can simply call a function
else if(tachoOutputFlag == ACTIVE)
{
//If the tacho output is already active, check whether it's reached it's end time
if((uint8_t)ms_counter >= tachoEndTime)
if((uint8_t)ms_counter == tachoEndTime)
{
TACHO_PULSE_HIGH();
tachoOutputFlag = DEACTIVE;

View File

@ -10,7 +10,7 @@
void doUpdates()
{
#define CURRENT_DATA_VERSION 11
#define CURRENT_DATA_VERSION 12
//May 2017 firmware introduced a -40 offset on the ignition table. Update that table to +40
if(EEPROM.read(EEPROM_DATA_VERSION) == 2)
@ -107,7 +107,7 @@ void doUpdates()
configPage10.flexFuelAdj[0] = configPage2.idleUpPin;
configPage10.flexAdvBins[0] = 0;
configPage10.flexAdvAdj[0] = configPage2.taeTaperMin;
configPage10.flexAdvAdj[0] = configPage2.aeTaperMin;
for (uint8_t x = 1; x < 6; x++)
{
@ -122,7 +122,7 @@ void doUpdates()
uint8_t fuelAdder = (((configPage2.idleUpAdder - configPage2.idleUpPin) * pct) / 100) + configPage2.idleUpPin;
configPage10.flexFuelAdj[x] = fuelAdder;
uint8_t advanceAdder = (((configPage2.taeTaperMax - configPage2.taeTaperMin) * pct) / 100) + configPage2.taeTaperMin;
uint8_t advanceAdder = (((configPage2.aeTaperMax - configPage2.aeTaperMin) * pct) / 100) + configPage2.aeTaperMin;
configPage10.flexAdvAdj[x] = advanceAdder;
}
@ -133,8 +133,8 @@ void doUpdates()
if (EEPROM.read(EEPROM_DATA_VERSION) == 8)
{
//May 2018 adds separate load sources for fuel and ignition. Copy the existing load alogirthm into Both
configPage2.fuelAlgorithm = configPage2.unused2_38c;
configPage2.ignAlgorithm = configPage2.unused2_38c;
configPage2.fuelAlgorithm = configPage2.legacyMAP; //Was configPage2.unused2_38c
configPage2.ignAlgorithm = configPage2.legacyMAP; //Was configPage2.unused2_38c
//Add option back in for open or closed loop boost. For all current configs to use closed
configPage4.boostType = 1;
@ -167,7 +167,7 @@ void doUpdates()
if(EEPROM.read(EEPROM_DATA_VERSION) == 10)
{
//April 2019 version adds the use of a 2D table for the priming pulse rather than a single value.
//May 2019 version adds the use of a 2D table for the priming pulse rather than a single value.
//This sets all the values in the 2D table to be the same as the previous single value
configPage2.primePulse[0] = configPage2.unused2_39 / 5; //New priming pulse values are in the range 0-127.5 rather than 0-25.5 so they must be divided by 5
configPage2.primePulse[1] = configPage2.unused2_39 / 5; //New priming pulse values are in the range 0-127.5 rather than 0-25.5 so they must be divided by 5
@ -179,13 +179,75 @@ void doUpdates()
configPage2.primeBins[2] = 70;
configPage2.primeBins[3] = 100;
//Also added is coolant based ASE for both duration and amount
//All the adder amounts are set to what the single value was previously
configPage2.asePct[0] = configPage2.unused2_2;
configPage2.asePct[1] = configPage2.unused2_2;
configPage2.asePct[2] = configPage2.unused2_2;
configPage2.asePct[3] = configPage2.unused2_2;
//ASE duration is set to 10s for all coolant values
configPage2.aseCount[0] = 10;
configPage2.aseCount[1] = 10;
configPage2.aseCount[2] = 10;
configPage2.aseCount[3] = 10;
//Finally the coolant bins for the above are set to sane values (Rememerbing these are offset values)
configPage2.aseBins[0] = 0;
configPage2.aseBins[1] = 20;
configPage2.aseBins[2] = 60;
configPage2.aseBins[3] = 80;
//Coolant based ignition advance was added also. Set sane values
configPage4.cltAdvBins[0] = 0;
configPage4.cltAdvBins[1] = 30;
configPage4.cltAdvBins[2] = 60;
configPage4.cltAdvBins[3] = 70;
configPage4.cltAdvBins[4] = 85;
configPage4.cltAdvBins[5] = 100;
configPage4.cltAdvValues[0] = 0;
configPage4.cltAdvValues[1] = 0;
configPage4.cltAdvValues[2] = 0;
configPage4.cltAdvValues[3] = 0;
configPage4.cltAdvValues[4] = 0;
configPage4.cltAdvValues[5] = 0;
//March 19 added a tacho pulse duration that could default to stupidly high values. Check if this is the case and fix it if found. 6ms is tha maximum allowed value
if(configPage2.tachoDuration > 6) { configPage2.tachoDuration = 3; }
//MAP based AE was introduced, force the AE mode to be TPS for all existing tunes
configPage2.aeMode = AE_MODE_TPS;
configPage2.maeThresh = configPage2.taeThresh;
//Set some sane values for the MAP AE curve
configPage4.maeRates[0] = 75;
configPage4.maeRates[1] = 75;
configPage4.maeRates[2] = 75;
configPage4.maeRates[3] = 75;
configPage4.maeBins[0] = 7;
configPage4.maeBins[1] = 12;
configPage4.maeBins[2] = 20;
configPage4.maeBins[3] = 40;
//The 2nd fuel table was added. To prevent issues, force it to be disabled.
configPage10.fuel2Mode = 0;
writeAllConfig();
EEPROM.write(EEPROM_DATA_VERSION, 11);
}
if(EEPROM.read(EEPROM_DATA_VERSION) == 11)
{
//July 2019
//A battery calibration offset value was introduced. Set default value to 0
configPage4.batVoltCorrect = 0;
//An option was added to select the older method of performing MAP reads with the pullup resistor active
configPage2.legacyMAP = 0;
writeAllConfig();
EEPROM.write(EEPROM_DATA_VERSION, 12);
}
//Final check is always for 255 and 0 (Brand new arduino)
if( (EEPROM.read(EEPROM_DATA_VERSION) == 0) || (EEPROM.read(EEPROM_DATA_VERSION) == 255) )
{

View File

@ -4,11 +4,6 @@
A full copy of the license may be found in the projects root directory
*/
/*
Returns how much free dynamic memory exists (between heap and stack)
This function is one big MISRA violation. MISRA advisories forbid directly poking at memory addresses, however there is no other way of determining heap size on embedded systems.
*/
#include <avr/pgmspace.h>
#include "globals.h"
#include "utils.h"