Merge pull request #44 from noisymime/master
update from speedy 30092017
|
@ -10,7 +10,11 @@ table.py
|
|||
reference/hardware/v0.2/~$schematic v0.2_bom.xlsx
|
||||
|
||||
reference/hardware/v0.4/gerbers/Archive.zip
|
||||
|
||||
.pioenvs
|
||||
.piolibdeps
|
||||
.clang_complete
|
||||
.gcc-flags.json
|
||||
.project
|
||||
.vscode
|
||||
.build
|
||||
|
|
|
@ -59,8 +59,10 @@ script:
|
|||
- cd /home/travis/build
|
||||
- git clone --depth=20 https://github.com/noisymime/cppcheck.git noisymime/cppcheck
|
||||
- cd noisymime/speeduino
|
||||
- platformio run -e megaatmega2560 -e teensy35
|
||||
- platformio update
|
||||
- platformio run -e megaatmega2560 -e teensy35 -e bluepill_f103c8 -e genericSTM32F103RB
|
||||
- cd ..
|
||||
- chmod +x speeduino/misra/check_misra.sh
|
||||
- speeduino/misra/check_misra.sh
|
||||
|
||||
notifications:
|
||||
|
|
|
@ -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.26 - EFI Analytics, Inc." tuneComment="" writeDate="Wed Jul 05 15:59:26 BST 2017"/>
|
||||
<versionInfo fileFormat="5.0" firmwareInfo="Speeduino+2017.06-dev" nPages="10" signature="speeduino 201706-dev"/>
|
||||
<bibliography author="TunerStudio MS(Beta) 3.0.28 - EFI Analytics, Inc." tuneComment="" writeDate="Sat Sep 09 21:28:59 AEST 2017"/>
|
||||
<versionInfo fileFormat="5.0" firmwareInfo="Speeduino+2017.07" nPages="11" signature="speeduino 201708"/>
|
||||
<page>
|
||||
<pcVariable name="tsCanId">"CAN ID 0"</pcVariable>
|
||||
</page>
|
||||
|
@ -122,9 +122,9 @@
|
|||
<constant name="baroCorr">"Off"</constant>
|
||||
<constant name="injLayout">"Paired"</constant>
|
||||
<constant name="perToothIgn">"No"</constant>
|
||||
<constant name="unused2-38h">"No"</constant>
|
||||
<constant name="dfcoEnabled">"Off"</constant>
|
||||
<constant digits="1" name="primePulse" units="ms">1.0</constant>
|
||||
<constant digits="0" name="dutyLim" units="%">85.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>
|
||||
<constant digits="0" name="boostMaxDuty" units="%">100.0</constant>
|
||||
|
@ -214,15 +214,14 @@
|
|||
<constant name="TrigEdgeSec">"Leading"</constant>
|
||||
<constant name="fuelPumpPin">"Board Default"</constant>
|
||||
<constant name="useResync">"No"</constant>
|
||||
<constant digits="1" name="sparkDur" units="ms">25.5</constant>
|
||||
<constant digits="1" name="sparkDur" units="ms">1.0</constant>
|
||||
<constant digits="0" name="IdleAdvRPM" units="RPM">3200.0</constant>
|
||||
<constant digits="0" name="IdleAdvCLT" units="F">-5.814</constant>
|
||||
<constant digits="1" name="IdleAdvCLT" units="C">-21.0</constant>
|
||||
<constant digits="0" name="IdleDelayTime" units="sec">38.0</constant>
|
||||
<constant digits="0" name="StgCycles" units="cycles">2.0</constant>
|
||||
<constant name="dwellcont">"Dwell control"</constant>
|
||||
<constant name="useDwellLim">"On"</constant>
|
||||
<constant name="sparkMode">"Wasted Spark"</constant>
|
||||
<constant name="dfcoEnabled">"Off"</constant>
|
||||
<constant name="TrigFilter">"Off"</constant>
|
||||
<constant name="ignCranklock">"On"</constant>
|
||||
<constant digits="1" name="dwellcrank" units="ms">4.5</constant>
|
||||
|
@ -247,17 +246,17 @@
|
|||
74.0
|
||||
85.0
|
||||
</constant>
|
||||
<constant cols="1" digits="0" name="wueBins" rows="10" units="F">
|
||||
-40.014
|
||||
-14.814
|
||||
17.586
|
||||
48.186
|
||||
78.786
|
||||
100.386
|
||||
120.186
|
||||
139.986
|
||||
156.186
|
||||
175.986
|
||||
<constant cols="1" digits="0" name="wueBins" rows="10" units="C">
|
||||
-40.0
|
||||
-26.0
|
||||
-8.0
|
||||
9.0
|
||||
26.0
|
||||
38.0
|
||||
49.0
|
||||
60.0
|
||||
69.0
|
||||
80.0
|
||||
</constant>
|
||||
<constant digits="0" name="dwellLim" units="ms">8.0</constant>
|
||||
<constant cols="1" digits="0" name="dwellRates" rows="6" units="%">
|
||||
|
@ -268,13 +267,13 @@
|
|||
91.0
|
||||
85.0
|
||||
</constant>
|
||||
<constant cols="1" digits="0" name="iatRetBins" rows="6" units="F">
|
||||
136.386
|
||||
179.586
|
||||
199.386
|
||||
219.186
|
||||
240.786
|
||||
283.986
|
||||
<constant cols="1" digits="0" name="iatRetBins" rows="6" units="C">
|
||||
58.0
|
||||
82.0
|
||||
93.0
|
||||
104.0
|
||||
116.0
|
||||
140.0
|
||||
</constant>
|
||||
<constant cols="1" digits="0" name="iatRetRates" rows="6" units="deg">
|
||||
0.0
|
||||
|
@ -356,7 +355,7 @@
|
|||
<constant digits="0" name="egoKP" units="%">100.0</constant>
|
||||
<constant digits="0" name="egoKI" units="%">20.0</constant>
|
||||
<constant digits="0" name="egoKD" units="%">0.0</constant>
|
||||
<constant digits="0" name="egoTemp" units="F">157.986</constant>
|
||||
<constant digits="0" name="egoTemp" units="C">70.0</constant>
|
||||
<constant digits="0" name="egoCount">16.0</constant>
|
||||
<constant digits="0" name="egoDelta" units="%">1.0</constant>
|
||||
<constant digits="0" name="egoLimit">15.0</constant>
|
||||
|
@ -366,8 +365,8 @@
|
|||
<constant digits="0" name="egoRPM" units="rpm">1200.0</constant>
|
||||
<constant digits="0" name="egoTPSMax" units="%">70.0</constant>
|
||||
<constant name="vvtPin">"Board Default"</constant>
|
||||
<constant name="unused6-13e">"ONE"</constant>
|
||||
<constant name="unused6-13f">"ONE"</constant>
|
||||
<constant name="useExtBaro">"No"</constant>
|
||||
<constant name="boostMode">"Simple"</constant>
|
||||
<constant name="boostPin">"Board Default"</constant>
|
||||
<constant name="unused6-14e">"ONE"</constant>
|
||||
<constant name="unused6-14f">"ONE"</constant>
|
||||
|
@ -387,16 +386,16 @@
|
|||
100.0
|
||||
98.0
|
||||
</constant>
|
||||
<constant cols="1" digits="0" name="airDenBins" rows="9" units="F">
|
||||
-40.014
|
||||
-4.014
|
||||
31.986
|
||||
67.986
|
||||
94.986
|
||||
121.986
|
||||
139.986
|
||||
193.986
|
||||
247.986
|
||||
<constant cols="1" digits="0" name="airDenBins" rows="9" units="C">
|
||||
-40.0
|
||||
-20.0
|
||||
0.0
|
||||
20.0
|
||||
35.0
|
||||
50.0
|
||||
60.0
|
||||
90.0
|
||||
120.0
|
||||
</constant>
|
||||
<constant cols="1" digits="0" name="airDenRates" rows="9" units="%">
|
||||
126.0
|
||||
|
@ -429,10 +428,7 @@
|
|||
<constant name="lnchPullRes">"Pullup"</constant>
|
||||
<constant name="fuelTrimEnabled">"No"</constant>
|
||||
<constant name="flatSEnable">"No"</constant>
|
||||
<constant name="unused6-60e">"ONE"</constant>
|
||||
<constant name="unused6-60f">"ONE"</constant>
|
||||
<constant name="unused6-60g">"ONE"</constant>
|
||||
<constant name="unused6-60h">"ONE"</constant>
|
||||
<constant name="baroPin">"A0"</constant>
|
||||
<constant digits="0" name="flatSSoftWin" units="rpm">400.0</constant>
|
||||
<constant digits="0" name="flatSRetard" units="deg">5.0</constant>
|
||||
<constant digits="0" name="flatSArm" units="rpm">2000.0</constant>
|
||||
|
@ -474,17 +470,17 @@
|
|||
16.0
|
||||
9.0
|
||||
</constant>
|
||||
<constant cols="1" digits="0" name="iacBins" rows="10" units="F">
|
||||
-36.414
|
||||
-2.214
|
||||
33.786
|
||||
62.586
|
||||
93.186
|
||||
121.986
|
||||
145.386
|
||||
174.186
|
||||
208.386
|
||||
289.386
|
||||
<constant cols="1" digits="0" name="iacBins" rows="10" units="C">
|
||||
-38.0
|
||||
-19.0
|
||||
1.0
|
||||
17.0
|
||||
34.0
|
||||
50.0
|
||||
63.0
|
||||
79.0
|
||||
98.0
|
||||
143.0
|
||||
</constant>
|
||||
<constant cols="1" digits="0" name="iacCrankSteps" rows="4" units="Steps">
|
||||
123.0
|
||||
|
@ -498,30 +494,30 @@
|
|||
44.0
|
||||
60.0
|
||||
</constant>
|
||||
<constant cols="1" digits="0" name="iacCrankBins" rows="4" units="F">
|
||||
-18.414
|
||||
42.786
|
||||
111.186
|
||||
168.786
|
||||
<constant cols="1" digits="0" name="iacCrankBins" rows="4" units="C">
|
||||
-28.0
|
||||
6.0
|
||||
44.0
|
||||
76.0
|
||||
</constant>
|
||||
<constant name="iacAlgorithm">"None"</constant>
|
||||
<constant name="iacStepTime">"3"</constant>
|
||||
<constant name="iacChannels">"1"</constant>
|
||||
<constant name="iacPWMdir">"Normal"</constant>
|
||||
<constant digits="0" name="iacFastTemp" units="F">67.986</constant>
|
||||
<constant digits="0" name="iacFastTemp" units="C">20.0</constant>
|
||||
<constant digits="0" name="iacStepHome" units="Steps">240.0</constant>
|
||||
<constant digits="0" name="iacStepHyster" units="Steps">4.0</constant>
|
||||
<constant name="fanInv">"No"</constant>
|
||||
<constant name="fanEnable">"Off"</constant>
|
||||
<constant name="fanPin">"Board Default"</constant>
|
||||
<constant digits="0" name="fanSP" units="F">166.986</constant>
|
||||
<constant digits="0" name="fanHyster" units="F">36.0</constant>
|
||||
<constant digits="0" name="fanSP" units="C">75.0</constant>
|
||||
<constant digits="0" name="fanHyster" units="C">2.0</constant>
|
||||
<constant digits="0" name="fanFreq" units="Hz">6.0</constant>
|
||||
<constant cols="1" digits="0" name="fanPWMBins" rows="4" units="F">
|
||||
139.986
|
||||
-4.014
|
||||
-40.014
|
||||
316.386
|
||||
<constant cols="1" digits="0" name="fanPWMBins" rows="4" units="C">
|
||||
60.0
|
||||
-20.0
|
||||
-40.0
|
||||
158.0
|
||||
</constant>
|
||||
</page>
|
||||
<page number="7" size="160">
|
||||
|
@ -686,16 +682,16 @@
|
|||
</page>
|
||||
<page number="9" size="128">
|
||||
<constant name="enable_canbus">"Disable"</constant>
|
||||
<constant name="enable_candata_in">"Off"</constant>
|
||||
<constant name="enable_candata_in">"On"</constant>
|
||||
<constant name="caninput_sel0">"Off"</constant>
|
||||
<constant name="caninput_sel1">"Off"</constant>
|
||||
<constant name="caninput_sel2">"Off"</constant>
|
||||
<constant name="caninput_sel3">"Off"</constant>
|
||||
<constant name="caninput_sel4">"Off"</constant>
|
||||
<constant name="caninput_sel5">"Off"</constant>
|
||||
<constant name="caninput_sel6">"Off"</constant>
|
||||
<constant name="caninput_sel7">"Off"</constant>
|
||||
<constant name="caninput_sel8">"Off"</constant>
|
||||
<constant name="caninput_sel1">"On"</constant>
|
||||
<constant name="caninput_sel2">"On"</constant>
|
||||
<constant name="caninput_sel3">"On"</constant>
|
||||
<constant name="caninput_sel4">"On"</constant>
|
||||
<constant name="caninput_sel5">"On"</constant>
|
||||
<constant name="caninput_sel6">"On"</constant>
|
||||
<constant name="caninput_sel7">"On"</constant>
|
||||
<constant name="caninput_sel8">"On"</constant>
|
||||
<constant name="caninput_sel9">"Off"</constant>
|
||||
<constant name="caninput_sel10">"Off"</constant>
|
||||
<constant name="caninput_sel11">"Off"</constant>
|
||||
|
@ -703,22 +699,22 @@
|
|||
<constant name="caninput_sel13">"Off"</constant>
|
||||
<constant name="caninput_sel14">"Off"</constant>
|
||||
<constant name="caninput_sel15">"Off"</constant>
|
||||
<constant name="caninput_param_group0">"0x200"</constant>
|
||||
<constant name="caninput_param_group1">"0x200"</constant>
|
||||
<constant name="caninput_param_group2">"0x200"</constant>
|
||||
<constant name="caninput_param_group3">"0x200"</constant>
|
||||
<constant name="caninput_param_group4">"0x200"</constant>
|
||||
<constant name="caninput_param_group5">"0x200"</constant>
|
||||
<constant name="caninput_param_group6">"0x200"</constant>
|
||||
<constant name="caninput_param_group7">"0x200"</constant>
|
||||
<constant name="caninput_param_group8">"0x200"</constant>
|
||||
<constant name="caninput_param_group9">"0x200"</constant>
|
||||
<constant name="caninput_param_group10">"0x200"</constant>
|
||||
<constant name="caninput_param_group11">"0x200"</constant>
|
||||
<constant name="caninput_param_group12">"0x200"</constant>
|
||||
<constant name="caninput_param_group13">"0x200"</constant>
|
||||
<constant name="caninput_param_group14">"0x200"</constant>
|
||||
<constant name="caninput_param_group15">"0x200"</constant>
|
||||
<constant name="caninput_param_group0">"blank"</constant>
|
||||
<constant name="caninput_param_group1">"blank"</constant>
|
||||
<constant name="caninput_param_group2">"blank"</constant>
|
||||
<constant name="caninput_param_group3">"blank"</constant>
|
||||
<constant name="caninput_param_group4">"blank"</constant>
|
||||
<constant name="caninput_param_group5">"blank"</constant>
|
||||
<constant name="caninput_param_group6">"blank"</constant>
|
||||
<constant name="caninput_param_group7">"blank"</constant>
|
||||
<constant name="caninput_param_group8">"blank"</constant>
|
||||
<constant name="caninput_param_group9">"blank"</constant>
|
||||
<constant name="caninput_param_group10">"blank"</constant>
|
||||
<constant name="caninput_param_group11">"blank"</constant>
|
||||
<constant name="caninput_param_group12">"blank"</constant>
|
||||
<constant name="caninput_param_group13">"blank"</constant>
|
||||
<constant name="caninput_param_group14">"blank"</constant>
|
||||
<constant name="caninput_param_group15">"blank"</constant>
|
||||
<constant name="caninput_param_start_byte0">"7"</constant>
|
||||
<constant name="caninput_param_start_byte1">"0"</constant>
|
||||
<constant name="caninput_param_start_byte2">"0"</constant>
|
||||
|
@ -728,13 +724,13 @@
|
|||
<constant name="caninput_param_start_byte6">"0"</constant>
|
||||
<constant name="caninput_param_start_byte7">"0"</constant>
|
||||
<constant name="caninput_param_start_byte8">"0"</constant>
|
||||
<constant name="caninput_param_start_byte9">"0"</constant>
|
||||
<constant name="caninput_param_start_byte10">"0"</constant>
|
||||
<constant name="caninput_param_start_byte11">"0"</constant>
|
||||
<constant name="caninput_param_start_byte12">"0"</constant>
|
||||
<constant name="caninput_param_start_byte13">"0"</constant>
|
||||
<constant name="caninput_param_start_byte14">"0"</constant>
|
||||
<constant name="caninput_param_start_byte15">"0"</constant>
|
||||
<constant name="caninput_param_start_byte9">"7"</constant>
|
||||
<constant name="caninput_param_start_byte10">"7"</constant>
|
||||
<constant name="caninput_param_start_byte11">"7"</constant>
|
||||
<constant name="caninput_param_start_byte12">"7"</constant>
|
||||
<constant name="caninput_param_start_byte13">"7"</constant>
|
||||
<constant name="caninput_param_start_byte14">"7"</constant>
|
||||
<constant name="caninput_param_start_byte15">"7"</constant>
|
||||
<constant name="caninput_param_num_bytes0">"1"</constant>
|
||||
<constant name="caninput_param_num_bytes1">"1"</constant>
|
||||
<constant name="caninput_param_num_bytes2">"1"</constant>
|
||||
|
@ -785,9 +781,9 @@
|
|||
<constant digits="0" name="unused10_98">255.0</constant>
|
||||
<constant digits="0" name="unused10_99">255.0</constant>
|
||||
<constant name="speeduino_tsCanId">"CAN ID 0"</constant>
|
||||
<constant name="true_address">"0x100"</constant>
|
||||
<constant name="realtime_base_address">"0x150"</constant>
|
||||
<constant name="obd_address">"0x7FF"</constant>
|
||||
<constant name="true_address">"0x101"</constant>
|
||||
<constant name="realtime_base_address">"0x201"</constant>
|
||||
<constant name="obd_address">"0x2FF"</constant>
|
||||
<constant digits="0" name="unused10_107">255.0</constant>
|
||||
<constant digits="0" name="unused10_108">255.0</constant>
|
||||
<constant digits="0" name="unused10_109">255.0</constant>
|
||||
|
@ -808,13 +804,27 @@
|
|||
<constant digits="0" name="unused10_124">255.0</constant>
|
||||
<constant digits="0" name="unused10_125">255.0</constant>
|
||||
<constant digits="0" name="unused10_126">255.0</constant>
|
||||
<constant digits="0" name="unused10_127">255.0</constant>
|
||||
<constant digits="0" name="unused10_127">1.0</constant>
|
||||
</page>
|
||||
<page number="10" size="192">
|
||||
<constant cols="1" digits="0" name="crankingEnrichBins" rows="4" units="C">
|
||||
-40.0
|
||||
0.0
|
||||
30.0
|
||||
70.0
|
||||
</constant>
|
||||
<constant cols="1" digits="0" name="crankingEnrichValues" rows="4" units="%">
|
||||
138.0
|
||||
115.0
|
||||
105.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="FAHRENHEIT" value="FAHRENHEIT"/>
|
||||
<setting name="SPEED_DENSITY" value="SPEED_DENSITY"/>
|
||||
<setting name="CAN_COMMANDS" value="CAN_COMMANDS"/>
|
||||
<setting name="CAN_COMMANDS_OFF" value="CAN_COMMANDS_OFF"/>
|
||||
<setting name="CELSIUS" value="CELSIUS"/>
|
||||
<setting name="AFR" value="AFR"/>
|
||||
</settings>
|
||||
<userComments Comment="These are user comments that can be related to a particular setting or dialog."/>
|
||||
|
|
|
@ -0,0 +1,128 @@
|
|||
$fn = 100;
|
||||
|
||||
// standard board thicknesses (mm)
|
||||
PCB_THICK_06 = 0.6;
|
||||
PCB_THICK_08 = 0.8;
|
||||
PCB_THICK_10 = 1.0;
|
||||
PCB_THICK_12 = 1.2;
|
||||
PCB_THICK_16 = 1.6;
|
||||
|
||||
// standard board hole diameters
|
||||
PCB_HOLE_30 = 3.0;
|
||||
|
||||
HEIGHT = 1.8;
|
||||
|
||||
// standard stand-off heights
|
||||
STANDOFF_4 = 3.0;
|
||||
|
||||
// base dimensions
|
||||
BASE_THICKNESS = 3.0;
|
||||
BASE_DIAMETER = 12.0;
|
||||
|
||||
module pcb_support(coord,hole_dia,pcb_thick,standoff_height)
|
||||
{
|
||||
translate(coord)
|
||||
{
|
||||
standoff(hole_dia,standoff_height);
|
||||
translate([standoff_height,0,0]) clip(hole_dia,pcb_thick,standoff_height);
|
||||
}
|
||||
}
|
||||
|
||||
module baseWedge(hole_dia,base_thickness)
|
||||
{
|
||||
standoff_side = hole_dia*1.2; // width of standoff
|
||||
//standoff_thickness = hole_dia * .75; // thickness of standoff bar
|
||||
standoff_thickness = HEIGHT; // thickness of standoff bar
|
||||
|
||||
translate([0,-base_thickness,0])
|
||||
linear_extrude(height=standoff_thickness)
|
||||
{
|
||||
polygon
|
||||
(
|
||||
points=
|
||||
[
|
||||
[-(standoff_side/2+base_thickness),0],
|
||||
[-standoff_side/2,base_thickness],
|
||||
[standoff_side/2,base_thickness],
|
||||
[standoff_side/2+base_thickness,0]
|
||||
]
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
module standoff(hole_dia,height,base_thickness)
|
||||
{
|
||||
standoff_side = hole_dia*1.2; // width of standoff
|
||||
//standoff_thickness = hole_dia * .75; // thickness of standoff bar
|
||||
standoff_thickness = HEIGHT; // thickness of standoff bar
|
||||
shaft_width = hole_dia * 1.0; // width of clip part that rests inside of the PCB hole
|
||||
slot_length = height/5-2; // length of cut slot
|
||||
slot_width = shaft_width * 0.4; // amount of gap in the slot
|
||||
base_inset = 0.1; // inset of wedge into bottom of base
|
||||
|
||||
// standoff
|
||||
translate([-standoff_side/2,0,0])
|
||||
{
|
||||
difference()
|
||||
{
|
||||
cube([standoff_side,height,standoff_thickness]);
|
||||
translate([standoff_side/2-slot_width/2,height-slot_length,0]) cube([slot_width,slot_length,standoff_thickness]);
|
||||
}
|
||||
}
|
||||
|
||||
difference()
|
||||
{
|
||||
baseWedge(hole_dia,base_thickness);
|
||||
translate([-(standoff_side+base_thickness*2)/2,-base_thickness,0]) cube([standoff_side+base_thickness*2,base_inset,standoff_thickness]);
|
||||
}
|
||||
}
|
||||
|
||||
//pcb_support([0,0,0],3,PCB_THICK_16,8);
|
||||
module clip(hole_dia,pcb_thick)
|
||||
{
|
||||
clip_length = pcb_thick * 3; // total length of clip
|
||||
clip_width = hole_dia * 1.2; // width of clip at its widest
|
||||
//clip_thickness = hole_dia * .75; // thickness of of the entire clip in the Z direction
|
||||
clip_thickness = HEIGHT; // thickness of of the entire clip in the Z direction
|
||||
shaft_length = pcb_thick * 1.1; // length of clip part that rests inside of the PCB hole
|
||||
shaft_width = hole_dia * 0.9; // width of clip part that rests inside of the PCB hole
|
||||
slot_length = clip_length; // length of cut slot
|
||||
slot_width = shaft_width * 0.4; // amount of gap in the slot
|
||||
|
||||
clip_lip = 0.4; // overhange on one side
|
||||
clip_chamfer = hole_dia/3; // side of triangle taken off of clip to produce a chamfer
|
||||
|
||||
translate([-shaft_width/2,0,0])
|
||||
linear_extrude(height=clip_thickness)
|
||||
{
|
||||
polygon
|
||||
(
|
||||
points=
|
||||
[
|
||||
// left clip
|
||||
[0,0],
|
||||
[0,shaft_length],
|
||||
[-clip_lip,shaft_length+clip_chamfer],
|
||||
[-clip_lip,clip_length-clip_chamfer],
|
||||
[0,clip_length],
|
||||
[(shaft_width-slot_width)/2,clip_length],
|
||||
[(shaft_width-slot_width)/2,clip_length-slot_length],
|
||||
|
||||
// right clip
|
||||
[(shaft_width-slot_width)/2+slot_width,clip_length-slot_length],
|
||||
[(shaft_width-slot_width)/2+slot_width,clip_length],
|
||||
[shaft_width,clip_length],
|
||||
[shaft_width+clip_lip,clip_length-clip_chamfer],
|
||||
[shaft_width+clip_lip,shaft_length+clip_chamfer],
|
||||
[shaft_width,shaft_length],
|
||||
[shaft_width,0]
|
||||
]
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
scale([1.8,3.2,2.5])
|
||||
{
|
||||
translate([0,STANDOFF_4,0]) clip(PCB_HOLE_30,PCB_THICK_16);
|
||||
standoff(PCB_HOLE_30,STANDOFF_4,BASE_THICKNESS);
|
||||
}
|
|
@ -1,26 +0,0 @@
|
|||
G04 MADE WITH FRITZING*
|
||||
G04 WWW.FRITZING.ORG*
|
||||
G04 DOUBLE SIDED*
|
||||
G04 HOLES PLATED*
|
||||
G04 CONTOUR ON CENTER OF CONTOUR VECTOR*
|
||||
%ASAXBY*%
|
||||
%FSLAX23Y23*%
|
||||
%MOIN*%
|
||||
%OFA0B0*%
|
||||
%SFA1.0B1.0*%
|
||||
%ADD10R,0.984252X0.984252*%
|
||||
%ADD11C,0.008000*%
|
||||
%ADD10C,0.008*%
|
||||
%LNCONTOUR*%
|
||||
G90*
|
||||
G70*
|
||||
G54D10*
|
||||
G54D11*
|
||||
X4Y980D02*
|
||||
X980Y980D01*
|
||||
X980Y4D01*
|
||||
X4Y4D01*
|
||||
X4Y980D01*
|
||||
D02*
|
||||
G04 End of contour*
|
||||
M02*
|
|
@ -1,39 +0,0 @@
|
|||
; NON-PLATED HOLES START AT T1
|
||||
; THROUGH (PLATED) HOLES START AT T100
|
||||
M48
|
||||
INCH
|
||||
T100C0.039370
|
||||
T101C0.035000
|
||||
T102C0.015748
|
||||
%
|
||||
T100
|
||||
X003694Y006148
|
||||
X003694Y004148
|
||||
X006694Y005148
|
||||
X006694Y003148
|
||||
X003694Y005148
|
||||
X003694Y003148
|
||||
X006694Y006148
|
||||
X006694Y004148
|
||||
T101
|
||||
X008194Y008148
|
||||
X008194Y001398
|
||||
X004194Y008148
|
||||
X004194Y001398
|
||||
T102
|
||||
X002694Y001148
|
||||
X005444Y003148
|
||||
X004944Y004148
|
||||
X002944Y006898
|
||||
X001444Y002648
|
||||
X000444Y009148
|
||||
X002444Y002648
|
||||
X001944Y001398
|
||||
X009444Y007398
|
||||
X005694Y007398
|
||||
X004944Y001148
|
||||
X000694Y007148
|
||||
X005194Y008398
|
||||
X006444Y007398
|
||||
T00
|
||||
M30
|
|
@ -1,136 +0,0 @@
|
|||
G04 MADE WITH FRITZING*
|
||||
G04 WWW.FRITZING.ORG*
|
||||
G04 DOUBLE SIDED*
|
||||
G04 HOLES PLATED*
|
||||
G04 CONTOUR ON CENTER OF CONTOUR VECTOR*
|
||||
%ASAXBY*%
|
||||
%FSLAX23Y23*%
|
||||
%MOIN*%
|
||||
%OFA0B0*%
|
||||
%SFA1.0B1.0*%
|
||||
%ADD10C,0.049370*%
|
||||
%ADD11C,0.085000*%
|
||||
%ADD12C,0.089370*%
|
||||
%ADD13R,0.065118X0.069055*%
|
||||
%ADD14R,0.069055X0.065118*%
|
||||
%ADD15R,0.089370X0.089370*%
|
||||
%ADD16C,0.026000*%
|
||||
%LNMASK0*%
|
||||
G90*
|
||||
G70*
|
||||
G54D10*
|
||||
X569Y740D03*
|
||||
X644Y740D03*
|
||||
X944Y740D03*
|
||||
G54D11*
|
||||
X819Y815D03*
|
||||
X419Y815D03*
|
||||
G54D10*
|
||||
X519Y840D03*
|
||||
X544Y315D03*
|
||||
X194Y140D03*
|
||||
X269Y115D03*
|
||||
X69Y715D03*
|
||||
G54D11*
|
||||
X819Y140D03*
|
||||
X419Y140D03*
|
||||
G54D12*
|
||||
X369Y615D03*
|
||||
X669Y615D03*
|
||||
X369Y515D03*
|
||||
X669Y515D03*
|
||||
X369Y415D03*
|
||||
X669Y415D03*
|
||||
X369Y315D03*
|
||||
X669Y315D03*
|
||||
G54D10*
|
||||
X494Y115D03*
|
||||
X244Y265D03*
|
||||
X144Y265D03*
|
||||
X44Y915D03*
|
||||
X294Y690D03*
|
||||
X494Y415D03*
|
||||
G54D13*
|
||||
X869Y240D03*
|
||||
X789Y240D03*
|
||||
X869Y440D03*
|
||||
X789Y440D03*
|
||||
X119Y640D03*
|
||||
X200Y640D03*
|
||||
X144Y365D03*
|
||||
X225Y365D03*
|
||||
X114Y865D03*
|
||||
X194Y865D03*
|
||||
X569Y915D03*
|
||||
X650Y915D03*
|
||||
G54D14*
|
||||
X544Y615D03*
|
||||
X544Y534D03*
|
||||
X119Y465D03*
|
||||
X119Y546D03*
|
||||
G54D13*
|
||||
X344Y915D03*
|
||||
X425Y915D03*
|
||||
X869Y340D03*
|
||||
X789Y340D03*
|
||||
G54D14*
|
||||
X569Y140D03*
|
||||
X569Y221D03*
|
||||
G54D13*
|
||||
X794Y640D03*
|
||||
X875Y640D03*
|
||||
G54D14*
|
||||
X669Y215D03*
|
||||
X669Y134D03*
|
||||
G54D15*
|
||||
X369Y615D03*
|
||||
G54D16*
|
||||
X330Y240D02*
|
||||
X308Y240D01*
|
||||
D02*
|
||||
X330Y215D02*
|
||||
X308Y215D01*
|
||||
D02*
|
||||
X330Y190D02*
|
||||
X308Y190D01*
|
||||
D02*
|
||||
X330Y165D02*
|
||||
X308Y165D01*
|
||||
D02*
|
||||
X330Y140D02*
|
||||
X308Y140D01*
|
||||
D02*
|
||||
X330Y115D02*
|
||||
X308Y115D01*
|
||||
D02*
|
||||
X330Y90D02*
|
||||
X308Y90D01*
|
||||
D02*
|
||||
X330Y65D02*
|
||||
X308Y65D01*
|
||||
D02*
|
||||
X118Y64D02*
|
||||
X96Y64D01*
|
||||
D02*
|
||||
X118Y89D02*
|
||||
X96Y89D01*
|
||||
D02*
|
||||
X118Y114D02*
|
||||
X96Y114D01*
|
||||
D02*
|
||||
X118Y139D02*
|
||||
X96Y139D01*
|
||||
D02*
|
||||
X118Y164D02*
|
||||
X96Y164D01*
|
||||
D02*
|
||||
X118Y189D02*
|
||||
X96Y189D01*
|
||||
D02*
|
||||
X118Y214D02*
|
||||
X96Y214D01*
|
||||
D02*
|
||||
X118Y239D02*
|
||||
X96Y239D01*
|
||||
G04 End of Mask0*
|
||||
M02*
|
|
@ -1,77 +0,0 @@
|
|||
G04 MADE WITH FRITZING*
|
||||
G04 WWW.FRITZING.ORG*
|
||||
G04 DOUBLE SIDED*
|
||||
G04 HOLES PLATED*
|
||||
G04 CONTOUR ON CENTER OF CONTOUR VECTOR*
|
||||
%ASAXBY*%
|
||||
%FSLAX23Y23*%
|
||||
%MOIN*%
|
||||
%OFA0B0*%
|
||||
%SFA1.0B1.0*%
|
||||
%ADD10C,0.049370*%
|
||||
%ADD11C,0.085000*%
|
||||
%ADD12C,0.089370*%
|
||||
%ADD13R,0.069055X0.065118*%
|
||||
%ADD14R,0.065118X0.069055*%
|
||||
%ADD15R,0.034000X0.097000*%
|
||||
%ADD16R,0.089370X0.089370*%
|
||||
%LNMASK1*%
|
||||
G90*
|
||||
G70*
|
||||
G54D10*
|
||||
X569Y740D03*
|
||||
X644Y740D03*
|
||||
X944Y740D03*
|
||||
G54D11*
|
||||
X819Y815D03*
|
||||
X419Y815D03*
|
||||
G54D10*
|
||||
X519Y840D03*
|
||||
X544Y315D03*
|
||||
X194Y140D03*
|
||||
X269Y115D03*
|
||||
X69Y715D03*
|
||||
G54D11*
|
||||
X819Y140D03*
|
||||
X419Y140D03*
|
||||
G54D12*
|
||||
X369Y615D03*
|
||||
X669Y615D03*
|
||||
X369Y515D03*
|
||||
X669Y515D03*
|
||||
X369Y415D03*
|
||||
X669Y415D03*
|
||||
X369Y315D03*
|
||||
X669Y315D03*
|
||||
G54D10*
|
||||
X494Y115D03*
|
||||
X244Y265D03*
|
||||
X144Y265D03*
|
||||
X44Y915D03*
|
||||
X294Y690D03*
|
||||
X494Y415D03*
|
||||
G54D13*
|
||||
X819Y590D03*
|
||||
X819Y509D03*
|
||||
G54D14*
|
||||
X819Y665D03*
|
||||
X900Y665D03*
|
||||
G54D13*
|
||||
X194Y365D03*
|
||||
X194Y446D03*
|
||||
G54D15*
|
||||
X94Y584D03*
|
||||
X144Y584D03*
|
||||
X194Y584D03*
|
||||
X244Y584D03*
|
||||
X244Y790D03*
|
||||
X194Y790D03*
|
||||
X144Y790D03*
|
||||
X94Y790D03*
|
||||
G54D14*
|
||||
X219Y65D03*
|
||||
X139Y65D03*
|
||||
G54D16*
|
||||
X369Y615D03*
|
||||
G04 End of Mask1*
|
||||
M02*
|
|
@ -1,98 +0,0 @@
|
|||
G04 MADE WITH FRITZING*
|
||||
G04 WWW.FRITZING.ORG*
|
||||
G04 DOUBLE SIDED*
|
||||
G04 HOLES PLATED*
|
||||
G04 CONTOUR ON CENTER OF CONTOUR VECTOR*
|
||||
%ASAXBY*%
|
||||
%FSLAX23Y23*%
|
||||
%MOIN*%
|
||||
%OFA0B0*%
|
||||
%SFA1.0B1.0*%
|
||||
%ADD10R,0.055118X0.059055*%
|
||||
%ADD11R,0.059055X0.055118*%
|
||||
%ADD12C,0.016000*%
|
||||
%LNPASTEMASK0*%
|
||||
G90*
|
||||
G70*
|
||||
G54D10*
|
||||
X869Y240D03*
|
||||
X789Y240D03*
|
||||
X869Y440D03*
|
||||
X789Y440D03*
|
||||
X119Y640D03*
|
||||
X200Y640D03*
|
||||
X144Y365D03*
|
||||
X225Y365D03*
|
||||
X114Y865D03*
|
||||
X194Y865D03*
|
||||
X569Y915D03*
|
||||
X650Y915D03*
|
||||
G54D11*
|
||||
X544Y615D03*
|
||||
X544Y534D03*
|
||||
X119Y465D03*
|
||||
X119Y546D03*
|
||||
G54D10*
|
||||
X344Y915D03*
|
||||
X425Y915D03*
|
||||
X869Y340D03*
|
||||
X789Y340D03*
|
||||
G54D11*
|
||||
X569Y140D03*
|
||||
X569Y221D03*
|
||||
G54D10*
|
||||
X794Y640D03*
|
||||
X875Y640D03*
|
||||
G54D11*
|
||||
X669Y215D03*
|
||||
X669Y134D03*
|
||||
G54D12*
|
||||
X330Y240D02*
|
||||
X308Y240D01*
|
||||
D02*
|
||||
X330Y215D02*
|
||||
X308Y215D01*
|
||||
D02*
|
||||
X330Y190D02*
|
||||
X308Y190D01*
|
||||
D02*
|
||||
X330Y165D02*
|
||||
X308Y165D01*
|
||||
D02*
|
||||
X330Y140D02*
|
||||
X308Y140D01*
|
||||
D02*
|
||||
X330Y115D02*
|
||||
X308Y115D01*
|
||||
D02*
|
||||
X330Y90D02*
|
||||
X308Y90D01*
|
||||
D02*
|
||||
X330Y65D02*
|
||||
X308Y65D01*
|
||||
D02*
|
||||
X118Y64D02*
|
||||
X96Y64D01*
|
||||
D02*
|
||||
X118Y89D02*
|
||||
X96Y89D01*
|
||||
D02*
|
||||
X118Y114D02*
|
||||
X96Y114D01*
|
||||
D02*
|
||||
X118Y139D02*
|
||||
X96Y139D01*
|
||||
D02*
|
||||
X118Y164D02*
|
||||
X96Y164D01*
|
||||
D02*
|
||||
X118Y189D02*
|
||||
X96Y189D01*
|
||||
D02*
|
||||
X118Y214D02*
|
||||
X96Y214D01*
|
||||
D02*
|
||||
X118Y239D02*
|
||||
X96Y239D01*
|
||||
G04 End of PasteMask0*
|
||||
M02*
|
|
@ -1,39 +0,0 @@
|
|||
G04 MADE WITH FRITZING*
|
||||
G04 WWW.FRITZING.ORG*
|
||||
G04 DOUBLE SIDED*
|
||||
G04 HOLES PLATED*
|
||||
G04 CONTOUR ON CENTER OF CONTOUR VECTOR*
|
||||
%ASAXBY*%
|
||||
%FSLAX23Y23*%
|
||||
%MOIN*%
|
||||
%OFA0B0*%
|
||||
%SFA1.0B1.0*%
|
||||
%ADD10R,0.059055X0.055118*%
|
||||
%ADD11R,0.055118X0.059055*%
|
||||
%ADD12R,0.024000X0.087000*%
|
||||
%LNPASTEMASK1*%
|
||||
G90*
|
||||
G70*
|
||||
G54D10*
|
||||
X819Y590D03*
|
||||
X819Y509D03*
|
||||
G54D11*
|
||||
X819Y665D03*
|
||||
X900Y665D03*
|
||||
G54D10*
|
||||
X194Y365D03*
|
||||
X194Y446D03*
|
||||
G54D12*
|
||||
X94Y584D03*
|
||||
X144Y584D03*
|
||||
X194Y584D03*
|
||||
X244Y584D03*
|
||||
X244Y790D03*
|
||||
X194Y790D03*
|
||||
X144Y790D03*
|
||||
X94Y790D03*
|
||||
G54D11*
|
||||
X219Y65D03*
|
||||
X139Y65D03*
|
||||
G04 End of PasteMask1*
|
||||
M02*
|
|
@ -1,121 +0,0 @@
|
|||
*Pick And Place List
|
||||
*Company=
|
||||
*Author=
|
||||
*eMail=
|
||||
*
|
||||
*Project=VR Conditioner v2
|
||||
*Date=23:30:08
|
||||
*CreatedBy=Fritzing 0.9.2b.11.19.8d2d5970658f0bed09c661c9ea9a515b5f40f44c
|
||||
*
|
||||
*
|
||||
*Coordinates in mm, always center of component
|
||||
*Origin 0/0=Lower left corner of PCB
|
||||
*Rotation in degree (0-360, math. pos.)
|
||||
*
|
||||
*No;Value;Package;X;Y;Rotation;Side;Name
|
||||
1;;;22.0472;-14.8654;0;Bottom;Copper Fill43
|
||||
2;;;15.9512;-6.2802;0;Bottom;Copper Fill20
|
||||
3;10k;0805 [SMD];4.0589;-16.2511;180;Bottom;R13
|
||||
4;;;18.9992;-15.602;0;Bottom;Copper Fill42
|
||||
5;;;14.2748;-8.0455;0;Bottom;Copper Fill53
|
||||
6;;;14.4145;-18.3452;0;Bottom;Copper Fill55
|
||||
7;;;2.2098;-18.2055;0;Bottom;Copper Fill29
|
||||
8;;;3.66888;-6.72612;0;Bottom;Via3
|
||||
9;;;20.32;-11.8428;0;Bottom;Copper Fill12
|
||||
10;;;22.6808;-9.35918;90;Bottom;TXT3
|
||||
11;;;13.2842;-8.0455;0;Bottom;Copper Fill30
|
||||
12;;;18.7452;-11.157;0;Bottom;Copper Fill44
|
||||
13;;so08;4.30388;-17.4449;0;Top;IC2
|
||||
14;;;13.1445;-20.8852;0;Bottom;Copper Fill31
|
||||
15;;;8.4582;-6.1151;0;Bottom;Copper Fill34
|
||||
16;;;16.3688;-18.7911;0;Bottom;Via14
|
||||
17;;;12.3698;-4.3244;0;Bottom;Copper Fill23
|
||||
18;;;7.493;-6.8898;0;Bottom;Copper Fill47
|
||||
19;;;6.6802;-1.8606;0;Bottom;Copper Fill26
|
||||
20;;;7.4549;-17.0752;0;Bottom;Copper Fill64
|
||||
21;;DIP (Dual Inline) [THT];13.1939;-11.8061;0;Bottom;IC1
|
||||
22;;;6.84388;-2.91612;0;Bottom;Via12
|
||||
23;;;6.3246;-13.1636;0;Bottom;Copper Fill9
|
||||
24;;;15.4178;-3.1814;0;Bottom;Copper Fill50
|
||||
25;;;2.3368;-3.6386;0;Bottom;Copper Fill48
|
||||
26;;;15.5194;-13.189;0;Bottom;Copper Fill13
|
||||
27;;;12.5589;-2.91612;0;Bottom;Via1
|
||||
28;;;13.0048;-10.5855;0;Bottom;Copper Fill57
|
||||
29;;;14.4145;-19.3358;0;Bottom;Copper Fill33
|
||||
30;1nF;0805 [SMD, multilayer];3.03388;-12.8311;90;Bottom;C5
|
||||
31;;;22.1488;-3.5624;0;Bottom;Copper Fill22
|
||||
32;;;6.477;-20.0851;0;Bottom;Copper Fill61
|
||||
33;;;6.1849;-20.8344;0;Bottom;Copper Fill60
|
||||
34;;;1.12888;-23.2361;0;Bottom;Via4
|
||||
35;220;0805 [SMD];4.5489;-1.6461;180;Top;R2
|
||||
36;;;20.536;-1.021;0;Bottom;TXT5
|
||||
37;;;13.8049;-7.5502;0;Bottom;Copper Fill52
|
||||
38;10k;0805 [SMD];3.91387;-21.9661;180;Bottom;R9
|
||||
39;0.01µF;0805 [SMD, multilayer];21.0588;-8.6311;0;Bottom;C2
|
||||
40;10k;0805 [SMD];17.0039;-4.43111;-90;Bottom;R6
|
||||
41;;;2.5654;-23.476;0;Bottom;Copper Fill1
|
||||
42;;;13.1939;-21.3311;0;Bottom;Via8
|
||||
43;;;1.76388;-18.1561;0;Bottom;Via13
|
||||
44;;;2.7432;-9.9632;0;Bottom;Copper Fill45
|
||||
45;1k;0805 [SMD];13.8289;-14.5911;-90;Bottom;R3
|
||||
46;;;4.93888;-3.55112;0;Bottom;Via10
|
||||
47;;;23.4433;-6.87236;90;Bottom;TXT1
|
||||
48;;;19.736;-0.964559;0;Bottom;TXT4
|
||||
49;10k;0805 [SMD];20.8138;-13.9561;90;Top;R16
|
||||
50;;;3.5052;-19.92;0;Bottom;Copper Fill5
|
||||
51;10k;0805 [SMD];4.6939;-9.2661;180;Bottom;R11
|
||||
52;;;7.4549;-17.0752;0;Bottom;Copper Fill35
|
||||
53;;;18.923;-4.7816;0;Bottom;Copper Fill18
|
||||
54;1µF;0805 [SMD, multilayer];21.0588;-11.1711;0;Bottom;C3
|
||||
55;;;6.477;-14.8527;0;Bottom;Copper Fill59
|
||||
56;4.7k;THT;15.7339;-3.55111;180;Bottom;R12
|
||||
57;;;7.4549;-18.0658;0;Bottom;Copper Fill63
|
||||
58;;;3.2004;-7.6518;0;Bottom;Copper Fill16
|
||||
59;220;0805 [SMD];4.93888;-10.2911;-90;Top;R1
|
||||
60;;;14.6304;-16.6942;0;Bottom;Copper Fill8
|
||||
61;;;7.9248;-17.5451;0;Bottom;Copper Fill65
|
||||
62;;;13.6398;-21.3551;0;Bottom;Copper Fill54
|
||||
63;;;6.2484;-16.0084;0;Bottom;Copper Fill38
|
||||
64;;;22.6568;-21.6726;0;Bottom;Copper Fill2
|
||||
65;;;10.3632;-14.4082;0;Bottom;Copper Fill7
|
||||
66;;;23.9888;-18.7911;0;Bottom;Via15
|
||||
67;;;13.6398;-21.3551;0;Bottom;Copper Fill32
|
||||
68;10k;0805 [SMD];15.4889;-23.2361;180;Bottom;R7
|
||||
69;;;7.47888;-17.5211;0;Bottom;Via5
|
||||
70;;;6.6294;-3.791;0;Bottom;Copper Fill49
|
||||
71;;;3.6449;-20.8344;0;Bottom;Copper Fill62
|
||||
72;;;12.5589;-10.5361;0;Bottom;Via6
|
||||
73;;;2.032;-11.4618;0;Bottom;Copper Fill14
|
||||
74;1nF;0805 [SMD, multilayer];9.77387;-23.2361;180;Bottom;C4
|
||||
75;;;17.018;-9.7854;0;Bottom;Copper Fill46
|
||||
76;;;8.0264;-21.952;0;Bottom;Copper Fill3
|
||||
77;;;18.4404;-15.9576;0;Bottom;Copper Fill10
|
||||
78;;;11.684;-17.9134;0;Bottom;Copper Fill39
|
||||
79;;;17.0434;-21.4186;0;Bottom;Copper Fill40
|
||||
80;;;6.985;-4.6038;0;Bottom;Copper Fill21
|
||||
81;;;4.7244;-20.4026;0;Bottom;Copper Fill6
|
||||
82;;;21.7678;-7.3724;0;Bottom;Copper Fill17
|
||||
83;1k;0805 [SMD];21.2039;-16.2511;180;Bottom;R5
|
||||
84;;;3.8354;-22.1298;0;Bottom;Copper Fill37
|
||||
85;;;6.20888;-6.72612;0;Bottom;Via2
|
||||
86;;;14.4639;-18.7911;0;Bottom;Via16
|
||||
87;;;14.5796;-2.902;0;Bottom;Copper Fill25
|
||||
88;;;1.5494;-14.9924;0;Bottom;Copper Fill11
|
||||
89;;;2.1844;-21.4186;0;Bottom;Copper Fill36
|
||||
90;;;21.8702;-9.95258;90;Bottom;TXT2
|
||||
91;;;4.318;-2.6988;0;Bottom;Copper Fill24
|
||||
92;;;13.8289;-7.99612;0;Bottom;Via9
|
||||
93;0.1µF;0805 [SMD, multilayer];21.0588;-6.0911;0;Bottom;C1
|
||||
94;;QSOP16;5.42149;-4.17341;0;Bottom;MAX9926
|
||||
95;10k;0805 [SMD];21.8389;-16.8861;0;Top;R15
|
||||
96;10k;0805 [SMD];14.4639;-4.5761;90;Bottom;R4
|
||||
97;;;21.7678;-9.9124;0;Bottom;Copper Fill15
|
||||
98;;;15.6972;-20.682;0;Bottom;Copper Fill4
|
||||
99;;;6.1849;-15.602;0;Bottom;Copper Fill58
|
||||
100;;;12.5349;-11.0808;0;Bottom;Copper Fill56
|
||||
101;;;16.0528;-10.5855;0;Bottom;Copper Fill51
|
||||
102;4.7k;THT;15.7339;-20.6961;180;Bottom;R10
|
||||
103;;;11.2776;-7.22;0;Bottom;Copper Fill19
|
||||
104;;;19.3802;-19.3358;0;Bottom;Copper Fill41
|
||||
105;;;1.7145;-18.7008;0;Bottom;Copper Fill27
|
||||
106;;;1.2192;-18.2055;0;Bottom;Copper Fill28
|
|
@ -0,0 +1,31 @@
|
|||
; NON-PLATED HOLES START AT T1
|
||||
; THROUGH (PLATED) HOLES START AT T100
|
||||
M48
|
||||
INCH
|
||||
T100C0.035000
|
||||
T101C0.015748
|
||||
T102C0.039370
|
||||
T103C0.038000
|
||||
%
|
||||
T100
|
||||
X009921Y009135
|
||||
X005921Y009135
|
||||
X009921Y008135
|
||||
X005921Y008135
|
||||
T101
|
||||
X005421Y001885
|
||||
X007671Y003135
|
||||
T102
|
||||
X004171Y006135
|
||||
X007171Y007135
|
||||
X004171Y004135
|
||||
X007171Y005135
|
||||
X004171Y007135
|
||||
X004171Y005135
|
||||
X007171Y006135
|
||||
X007171Y004135
|
||||
T103
|
||||
X007921Y001510
|
||||
X008921Y001510
|
||||
T00
|
||||
M30
|
|
@ -0,0 +1,44 @@
|
|||
G04 MADE WITH FRITZING*
|
||||
G04 WWW.FRITZING.ORG*
|
||||
G04 DOUBLE SIDED*
|
||||
G04 HOLES PLATED*
|
||||
G04 CONTOUR ON CENTER OF CONTOUR VECTOR*
|
||||
%ASAXBY*%
|
||||
%FSLAX23Y23*%
|
||||
%MOIN*%
|
||||
%OFA0B0*%
|
||||
%SFA1.0B1.0*%
|
||||
%ADD10C,0.085000*%
|
||||
%ADD11C,0.089370*%
|
||||
%ADD12C,0.049370*%
|
||||
%ADD13C,0.088000*%
|
||||
%ADD14R,0.089370X0.089370*%
|
||||
%LNMASK0*%
|
||||
G90*
|
||||
G70*
|
||||
G54D10*
|
||||
X592Y814D03*
|
||||
X992Y814D03*
|
||||
G54D11*
|
||||
X417Y714D03*
|
||||
X717Y714D03*
|
||||
X417Y614D03*
|
||||
X717Y614D03*
|
||||
X417Y514D03*
|
||||
X717Y514D03*
|
||||
X417Y414D03*
|
||||
X717Y414D03*
|
||||
G54D10*
|
||||
X992Y914D03*
|
||||
X592Y914D03*
|
||||
G54D12*
|
||||
X767Y314D03*
|
||||
G54D13*
|
||||
X892Y151D03*
|
||||
X792Y151D03*
|
||||
G54D12*
|
||||
X542Y189D03*
|
||||
G54D14*
|
||||
X417Y714D03*
|
||||
G04 End of Mask0*
|
||||
M02*
|
|
@ -0,0 +1,122 @@
|
|||
G04 MADE WITH FRITZING*
|
||||
G04 WWW.FRITZING.ORG*
|
||||
G04 DOUBLE SIDED*
|
||||
G04 HOLES PLATED*
|
||||
G04 CONTOUR ON CENTER OF CONTOUR VECTOR*
|
||||
%ASAXBY*%
|
||||
%FSLAX23Y23*%
|
||||
%MOIN*%
|
||||
%OFA0B0*%
|
||||
%SFA1.0B1.0*%
|
||||
%ADD10C,0.085000*%
|
||||
%ADD11C,0.089370*%
|
||||
%ADD12C,0.049370*%
|
||||
%ADD13C,0.088000*%
|
||||
%ADD14R,0.089370X0.089370*%
|
||||
%ADD15R,0.065118X0.069055*%
|
||||
%ADD16R,0.069055X0.065118*%
|
||||
%ADD17C,0.026000*%
|
||||
%LNMASK1*%
|
||||
G90*
|
||||
G70*
|
||||
G54D10*
|
||||
X592Y814D03*
|
||||
X992Y814D03*
|
||||
G54D11*
|
||||
X417Y714D03*
|
||||
X717Y714D03*
|
||||
X417Y614D03*
|
||||
X717Y614D03*
|
||||
X417Y514D03*
|
||||
X717Y514D03*
|
||||
X417Y414D03*
|
||||
X717Y414D03*
|
||||
G54D10*
|
||||
X992Y914D03*
|
||||
X592Y914D03*
|
||||
G54D12*
|
||||
X767Y314D03*
|
||||
G54D13*
|
||||
X892Y151D03*
|
||||
X792Y151D03*
|
||||
G54D12*
|
||||
X542Y189D03*
|
||||
G54D14*
|
||||
X417Y714D03*
|
||||
G54D15*
|
||||
X830Y714D03*
|
||||
X910Y714D03*
|
||||
X830Y614D03*
|
||||
X910Y614D03*
|
||||
X830Y514D03*
|
||||
X910Y514D03*
|
||||
G54D16*
|
||||
X830Y426D03*
|
||||
X830Y345D03*
|
||||
X930Y426D03*
|
||||
X930Y345D03*
|
||||
G54D15*
|
||||
X317Y914D03*
|
||||
X398Y914D03*
|
||||
X767Y1001D03*
|
||||
X848Y1001D03*
|
||||
G54D16*
|
||||
X242Y914D03*
|
||||
X242Y994D03*
|
||||
G54D15*
|
||||
X242Y664D03*
|
||||
X323Y664D03*
|
||||
X317Y564D03*
|
||||
X236Y564D03*
|
||||
X242Y464D03*
|
||||
X323Y464D03*
|
||||
G54D17*
|
||||
X690Y138D02*
|
||||
X668Y138D01*
|
||||
D02*
|
||||
X690Y163D02*
|
||||
X668Y163D01*
|
||||
D02*
|
||||
X690Y188D02*
|
||||
X668Y188D01*
|
||||
D02*
|
||||
X690Y213D02*
|
||||
X668Y213D01*
|
||||
D02*
|
||||
X690Y238D02*
|
||||
X668Y238D01*
|
||||
D02*
|
||||
X690Y263D02*
|
||||
X668Y263D01*
|
||||
D02*
|
||||
X690Y288D02*
|
||||
X668Y288D01*
|
||||
D02*
|
||||
X690Y313D02*
|
||||
X668Y313D01*
|
||||
D02*
|
||||
X478Y314D02*
|
||||
X456Y314D01*
|
||||
D02*
|
||||
X478Y289D02*
|
||||
X456Y289D01*
|
||||
D02*
|
||||
X478Y264D02*
|
||||
X456Y264D01*
|
||||
D02*
|
||||
X478Y239D02*
|
||||
X456Y239D01*
|
||||
D02*
|
||||
X478Y214D02*
|
||||
X456Y214D01*
|
||||
D02*
|
||||
X478Y189D02*
|
||||
X456Y189D01*
|
||||
D02*
|
||||
X478Y164D02*
|
||||
X456Y164D01*
|
||||
D02*
|
||||
X478Y139D02*
|
||||
X456Y139D01*
|
||||
G04 End of Mask1*
|
||||
M02*
|
|
@ -0,0 +1,93 @@
|
|||
G04 MADE WITH FRITZING*
|
||||
G04 WWW.FRITZING.ORG*
|
||||
G04 DOUBLE SIDED*
|
||||
G04 HOLES PLATED*
|
||||
G04 CONTOUR ON CENTER OF CONTOUR VECTOR*
|
||||
%ASAXBY*%
|
||||
%FSLAX23Y23*%
|
||||
%MOIN*%
|
||||
%OFA0B0*%
|
||||
%SFA1.0B1.0*%
|
||||
%ADD10R,0.055118X0.059055*%
|
||||
%ADD11R,0.059055X0.055118*%
|
||||
%ADD12C,0.016000*%
|
||||
%LNPASTEMASK1*%
|
||||
G90*
|
||||
G70*
|
||||
G54D10*
|
||||
X830Y714D03*
|
||||
X910Y714D03*
|
||||
X830Y614D03*
|
||||
X910Y614D03*
|
||||
X830Y514D03*
|
||||
X910Y514D03*
|
||||
G54D11*
|
||||
X830Y426D03*
|
||||
X830Y345D03*
|
||||
X930Y426D03*
|
||||
X930Y345D03*
|
||||
G54D10*
|
||||
X317Y914D03*
|
||||
X398Y914D03*
|
||||
X767Y1001D03*
|
||||
X848Y1001D03*
|
||||
G54D11*
|
||||
X242Y914D03*
|
||||
X242Y994D03*
|
||||
G54D10*
|
||||
X242Y664D03*
|
||||
X323Y664D03*
|
||||
X317Y564D03*
|
||||
X236Y564D03*
|
||||
X242Y464D03*
|
||||
X323Y464D03*
|
||||
G54D12*
|
||||
X690Y138D02*
|
||||
X668Y138D01*
|
||||
D02*
|
||||
X690Y163D02*
|
||||
X668Y163D01*
|
||||
D02*
|
||||
X690Y188D02*
|
||||
X668Y188D01*
|
||||
D02*
|
||||
X690Y213D02*
|
||||
X668Y213D01*
|
||||
D02*
|
||||
X690Y238D02*
|
||||
X668Y238D01*
|
||||
D02*
|
||||
X690Y263D02*
|
||||
X668Y263D01*
|
||||
D02*
|
||||
X690Y288D02*
|
||||
X668Y288D01*
|
||||
D02*
|
||||
X690Y313D02*
|
||||
X668Y313D01*
|
||||
D02*
|
||||
X478Y314D02*
|
||||
X456Y314D01*
|
||||
D02*
|
||||
X478Y289D02*
|
||||
X456Y289D01*
|
||||
D02*
|
||||
X478Y264D02*
|
||||
X456Y264D01*
|
||||
D02*
|
||||
X478Y239D02*
|
||||
X456Y239D01*
|
||||
D02*
|
||||
X478Y214D02*
|
||||
X456Y214D01*
|
||||
D02*
|
||||
X478Y189D02*
|
||||
X456Y189D01*
|
||||
D02*
|
||||
X478Y164D02*
|
||||
X456Y164D01*
|
||||
D02*
|
||||
X478Y139D02*
|
||||
X456Y139D01*
|
||||
G04 End of PasteMask1*
|
||||
M02*
|
|
@ -0,0 +1,67 @@
|
|||
*Pick And Place List
|
||||
*Company=
|
||||
*Author=
|
||||
*eMail=
|
||||
*
|
||||
*Project=VR Conditioner v3
|
||||
*Date=19:16:10
|
||||
*CreatedBy=Fritzing 0.9.3b.04.19.5c895d327c44a3114e5fcc9d8260daf0cbb52806
|
||||
*
|
||||
*
|
||||
*Coordinates in mm, always center of component
|
||||
*Origin 0/0=Lower left corner of PCB
|
||||
*Rotation in degree (0-360, math. pos.)
|
||||
*
|
||||
*No;Value;Package;X;Y;Rotation;Side;Name
|
||||
1;;DIP (Dual Inline) [THT];14.4059;-14.3144;0;Bottom;IC1
|
||||
2;;;15.9512;-14.2933;0;Bottom;Copper Fill24
|
||||
3;;;22.1742;-8.04494;0;Bottom;Copper Fill20
|
||||
4;4.7k;THT;20.1209;-20.6644;0;Bottom;R12
|
||||
5;;;19.4858;-7.96443;0;Bottom;Via14
|
||||
6;;;6.0564;-7.14176;0;Bottom;TXT5
|
||||
7;;;12.7;-19.3987;0;Bottom;Copper Fill2
|
||||
8;1k;0805 [SMD];23.6134;-9.79692;90;Top;R4
|
||||
9;4.7k;THT;20.1209;-23.2044;180;Bottom;R10
|
||||
10;;;19.2786;-11.7787;0;Bottom;Copper Fill10
|
||||
11;;;11.4554;-6.76224;0;Bottom;Copper Fill25
|
||||
12;1nF;0805 [SMD, multilayer];6.15085;-24.2294;-90;Top;C4
|
||||
13;;;16.9926;-11.4485;0;Bottom;Copper Fill9
|
||||
14;;;13.9954;-14.4965;0;Bottom;Copper Fill1
|
||||
15;10k;0805 [SMD];20.5109;-25.4269;0;Top;R7
|
||||
16;;;19.2786;-14.1663;0;Bottom;Copper Fill8
|
||||
17;;;17.1704;-14.2933;0;Bottom;Copper Fill7
|
||||
18;;;17.5514;-6.76224;0;Bottom;Copper Fill29
|
||||
19;;;18.5928;-4.28574;0;Bottom;Copper Fill23
|
||||
20;;;4.572;-23.9707;0;Bottom;Copper Fill11
|
||||
21;;;25.6196;-12.6698;-90;Bottom;TXT3
|
||||
22;;;7.47786;-7.22642;0;Bottom;TXT4
|
||||
23;;;17.9832;-16.3761;0;Bottom;Copper Fill3
|
||||
24;10k;0805 [SMD];7.17586;-16.8544;0;Top;R13
|
||||
25;0.01µF;0805 [SMD, multilayer];22.0984;-15.5844;0;Top;C2
|
||||
26;;;13.7708;-4.78943;0;Bottom;Via15
|
||||
27;;;21.082;-12.2613;0;Bottom;Copper Fill5
|
||||
28;;;24.2316;-15.3601;0;Bottom;Copper Fill16
|
||||
29;;;9.6012;-13.7091;0;Bottom;Copper Fill12
|
||||
30;1k;0805 [SMD];21.0734;-9.79692;90;Top;R6
|
||||
31;1nF;0805 [SMD, multilayer];7.03084;-14.3144;180;Top;C5
|
||||
32;0.1µF;0805 [SMD, multilayer];22.0984;-13.0444;0;Top;C1
|
||||
33;;THT;21.3909;-3.83692;90;Bottom;J1
|
||||
34;;;17.1704;-16.8333;0;Bottom;Copper Fill6
|
||||
35;;QSOP16;14.5583;-5.41172;180;Top;MAX9926
|
||||
36;;;14.2735;-25.0931;0;Bottom;TXT1
|
||||
37;;;20.701;-15.1061;0;Bottom;Copper Fill15
|
||||
38;10k;0805 [SMD];7.17586;-11.7744;0;Top;R11
|
||||
39;;;17.5514;-4.83184;0;Bottom;Copper Fill27
|
||||
40;;;11.6586;-14.4711;0;Bottom;Copper Fill18
|
||||
41;;;20.2946;-7.13054;0;Bottom;Copper Fill22
|
||||
42;;;11.4554;-5.49224;0;Bottom;Copper Fill28
|
||||
43;;;12.9286;-16.9349;0;Bottom;Copper Fill4
|
||||
44;10k;0805 [SMD];9.08086;-23.2044;0;Top;R9
|
||||
45;;;7.2644;-19.3733;0;Bottom;Copper Fill13
|
||||
46;;;10.287;-19.0685;0;Bottom;Copper Fill14
|
||||
47;;;17.2085;-3.37134;0;Bottom;Copper Fill26
|
||||
48;;;9.9568;-14.2933;0;Bottom;Copper Fill19
|
||||
49;;;22.4815;-12.723;-90;Bottom;IMG1
|
||||
50;1µF;0805 [SMD, multilayer];22.0984;-18.1244;0;Top;C3
|
||||
51;;;8.2804;-14.3187;0;Bottom;Copper Fill17
|
||||
52;;;24.4094;-6.57174;0;Bottom;Copper Fill21
|
|
@ -0,0 +1,10 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<svg version="1.2" baseProfile="tiny" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"
|
||||
x="0px" y="0px" width="120" height="120" viewBox="0 0 120 120" xml:space="preserve">
|
||||
<g id="board">
|
||||
<rect fill="#338040" x="10" y="10" width="100" height="100" rx="15" ry="15"/>
|
||||
</g>
|
||||
<g id="silkscreen">
|
||||
<rect fill="none" stroke="#FFFFFF" stroke-width="0.576" x="10" y="10" width="100" height="100" rx="15" ry="15"/>
|
||||
</g>
|
||||
</svg>
|
After Width: | Height: | Size: 516 B |
|
@ -21,8 +21,8 @@ T1
|
|||
X035411Y031280
|
||||
X037661Y012280
|
||||
T2
|
||||
X001411Y021530
|
||||
X001411Y030530
|
||||
X001437Y021481
|
||||
X001437Y030579
|
||||
T100
|
||||
X036411Y034811
|
||||
X036411Y036780
|
||||
|
@ -37,21 +37,39 @@ X033911Y036983
|
|||
T103
|
||||
X018161Y033045
|
||||
X025911Y023030
|
||||
X026161Y015030
|
||||
X024927Y023030
|
||||
X018161Y034030
|
||||
X025177Y015030
|
||||
X026161Y015030
|
||||
X018161Y034030
|
||||
X018161Y035045
|
||||
X025177Y017030
|
||||
X005421Y033789
|
||||
X005421Y032805
|
||||
X026161Y017030
|
||||
X018161Y036030
|
||||
X025177Y017030
|
||||
X024927Y021030
|
||||
X025911Y021030
|
||||
X005421Y035789
|
||||
X005421Y034805
|
||||
X024927Y021030
|
||||
X024927Y023030
|
||||
T104
|
||||
X010911Y032530
|
||||
X023161Y010780
|
||||
X020911Y010280
|
||||
X037911Y006280
|
||||
X023161Y006780
|
||||
X016411Y014530
|
||||
X031911Y014530
|
||||
X031411Y002280
|
||||
X017411Y006030
|
||||
X017411Y018530
|
||||
X032911Y007280
|
||||
X019661Y030280
|
||||
X024161Y036280
|
||||
X024161Y013780
|
||||
X032911Y010280
|
||||
X016661Y037780
|
||||
X004661Y019030
|
||||
X019661Y026280
|
||||
X016652Y033521
|
||||
X020661Y030280
|
||||
X016661Y035530
|
||||
|
@ -59,31 +77,31 @@ X020661Y026280
|
|||
X031661Y023280
|
||||
X029161Y013280
|
||||
X012911Y011280
|
||||
X029911Y006030
|
||||
X021411Y006030
|
||||
X035911Y017530
|
||||
X029911Y006030
|
||||
X015911Y011030
|
||||
X023661Y030280
|
||||
X016661Y034530
|
||||
X022661Y021030
|
||||
X023661Y030280
|
||||
X020661Y018780
|
||||
X012911Y007280
|
||||
X031661Y022280
|
||||
X015911Y007030
|
||||
X021911Y007280
|
||||
X012411Y006280
|
||||
X021911Y007280
|
||||
X037911Y002280
|
||||
X023661Y025030
|
||||
X023661Y026280
|
||||
X035911Y016530
|
||||
X029911Y005030
|
||||
X030911Y007280
|
||||
X035911Y016530
|
||||
X021911Y010280
|
||||
X017661Y030280
|
||||
X030911Y010280
|
||||
X031661Y021280
|
||||
X021911Y018780
|
||||
X017411Y014530
|
||||
X021911Y018780
|
||||
X017661Y026280
|
||||
X016661Y029530
|
||||
X023161Y017780
|
||||
|
@ -117,20 +135,20 @@ X010911Y036530
|
|||
X025911Y030030
|
||||
X012652Y033521
|
||||
X024661Y025030
|
||||
X035661Y023280
|
||||
X020661Y013780
|
||||
X035661Y023280
|
||||
X016411Y018530
|
||||
X031911Y007280
|
||||
X006911Y033530
|
||||
X018661Y030280
|
||||
X012661Y035530
|
||||
X018661Y030280
|
||||
X016661Y025530
|
||||
X010911Y035530
|
||||
X023161Y013780
|
||||
X031911Y010280
|
||||
X018661Y026280
|
||||
X035661Y022280
|
||||
X025161Y013280
|
||||
X035661Y022280
|
||||
X024161Y017780
|
||||
X016411Y006280
|
||||
X031911Y017530
|
||||
|
@ -140,8 +158,8 @@ X021911Y013780
|
|||
X012661Y034530
|
||||
X010911Y034530
|
||||
X035661Y021280
|
||||
X031911Y016530
|
||||
X019911Y007280
|
||||
X031911Y016530
|
||||
X010911Y033530
|
||||
X014911Y011030
|
||||
X019911Y010280
|
||||
|
@ -154,25 +172,20 @@ X020911Y007280
|
|||
X022661Y025030
|
||||
X022661Y026280
|
||||
X012661Y032530
|
||||
X010911Y032530
|
||||
X023161Y010780
|
||||
X020911Y010280
|
||||
X037911Y006280
|
||||
X023161Y006780
|
||||
X016411Y014530
|
||||
X031911Y014530
|
||||
X031411Y002280
|
||||
X017411Y006030
|
||||
X017411Y018530
|
||||
X032911Y007280
|
||||
X019661Y030280
|
||||
X024161Y036280
|
||||
X024161Y013780
|
||||
X032911Y010280
|
||||
X016661Y037780
|
||||
X004661Y019030
|
||||
X019661Y026280
|
||||
T105
|
||||
X037911Y025280
|
||||
X017911Y012280
|
||||
X036911Y017280
|
||||
X017911Y031280
|
||||
X026911Y012280
|
||||
X026911Y031280
|
||||
X036911Y020280
|
||||
X035911Y012280
|
||||
X037911Y024280
|
||||
X036911Y016280
|
||||
X012311Y031280
|
||||
X029911Y012280
|
||||
X029911Y031280
|
||||
X037911Y023280
|
||||
X012911Y012280
|
||||
X036911Y015280
|
||||
|
@ -191,22 +204,22 @@ X009311Y031280
|
|||
X024911Y031280
|
||||
X036911Y029280
|
||||
X033911Y012280
|
||||
X033911Y031280
|
||||
X037911Y021280
|
||||
X033911Y031280
|
||||
X037911Y017280
|
||||
X010311Y031280
|
||||
X018911Y031280
|
||||
X036911Y028280
|
||||
X027911Y031280
|
||||
X037911Y020280
|
||||
X010911Y012280
|
||||
X036911Y031280
|
||||
X010911Y012280
|
||||
X037911Y016280
|
||||
X036911Y027280
|
||||
X013311Y031280
|
||||
X036911Y030280
|
||||
X013911Y012280
|
||||
X037911Y015280
|
||||
X013911Y012280
|
||||
X022911Y012280
|
||||
X036911Y026280
|
||||
X007311Y031280
|
||||
|
@ -224,15 +237,15 @@ X036911Y024280
|
|||
X019911Y012280
|
||||
X011311Y031280
|
||||
X019911Y031280
|
||||
X028911Y012280
|
||||
X037911Y028280
|
||||
X028911Y012280
|
||||
X028911Y031280
|
||||
X037911Y031280
|
||||
X036911Y023280
|
||||
X011911Y012280
|
||||
X020911Y012280
|
||||
X020911Y031280
|
||||
X037911Y027280
|
||||
X020911Y031280
|
||||
X036911Y019280
|
||||
X014311Y031280
|
||||
X037911Y030280
|
||||
|
@ -240,32 +253,18 @@ X036911Y022280
|
|||
X014911Y012280
|
||||
X037911Y026280
|
||||
X023911Y012280
|
||||
X008311Y031280
|
||||
X036911Y018280
|
||||
X008311Y031280
|
||||
X023911Y031280
|
||||
X032911Y012280
|
||||
X032911Y031280
|
||||
X036911Y021280
|
||||
X037911Y025280
|
||||
X017911Y012280
|
||||
X036911Y017280
|
||||
X017911Y031280
|
||||
X026911Y012280
|
||||
X026911Y031280
|
||||
X036911Y020280
|
||||
X035911Y012280
|
||||
X037911Y024280
|
||||
X036911Y016280
|
||||
X012311Y031280
|
||||
X029911Y012280
|
||||
X029911Y031280
|
||||
T106
|
||||
X008911Y011780
|
||||
X007911Y016780
|
||||
X008911Y003780
|
||||
X007911Y008780
|
||||
X008911Y016780
|
||||
X008911Y008780
|
||||
X006161Y024530
|
||||
X007911Y022780
|
||||
X007911Y014780
|
||||
X008911Y022780
|
||||
|
@ -275,6 +274,7 @@ X007911Y019780
|
|||
X008911Y006780
|
||||
X008911Y019780
|
||||
X007911Y020780
|
||||
X006161Y027530
|
||||
X007911Y012780
|
||||
X008911Y020780
|
||||
X007911Y004780
|
||||
|
@ -284,13 +284,16 @@ X008911Y004780
|
|||
X007911Y009780
|
||||
X008911Y017780
|
||||
X008911Y009780
|
||||
X006161Y025530
|
||||
X007911Y010780
|
||||
X006161Y023529
|
||||
X008911Y010780
|
||||
X007911Y015780
|
||||
X007911Y007780
|
||||
X008911Y015780
|
||||
X008911Y007780
|
||||
X007911Y021780
|
||||
X006161Y028530
|
||||
X007911Y013780
|
||||
X008911Y021780
|
||||
X007911Y005780
|
||||
|
@ -298,124 +301,137 @@ X008911Y013780
|
|||
X007911Y018780
|
||||
X008911Y005780
|
||||
X008911Y018780
|
||||
X006161Y026530
|
||||
X007911Y011780
|
||||
X007911Y003780
|
||||
X008911Y011780
|
||||
X007911Y016780
|
||||
T107
|
||||
X014911Y025030
|
||||
X020661Y024780
|
||||
X021931Y037280
|
||||
X014911Y025030
|
||||
X030661Y036280
|
||||
X003891Y037780
|
||||
X025161Y033280
|
||||
X001411Y033030
|
||||
X003411Y033030
|
||||
X014911Y028280
|
||||
X018661Y022280
|
||||
X021161Y033030
|
||||
X002411Y033030
|
||||
X011911Y010760
|
||||
X019661Y022280
|
||||
X022161Y033030
|
||||
X020161Y033030
|
||||
X014911Y023030
|
||||
X001411Y033030
|
||||
X003411Y033030
|
||||
X018661Y022280
|
||||
X021161Y033030
|
||||
X030661Y033300
|
||||
X028661Y037030
|
||||
X026661Y037030
|
||||
X020661Y022280
|
||||
X027661Y037030
|
||||
X028661Y037030
|
||||
X002421Y035289
|
||||
X000911Y036530
|
||||
X014911Y029280
|
||||
X001421Y035289
|
||||
X003421Y035289
|
||||
X002421Y035289
|
||||
X014911Y024030
|
||||
X000911Y036530
|
||||
X020911Y037280
|
||||
X018661Y024780
|
||||
X019661Y024780
|
||||
X014911Y027280
|
||||
X024911Y037280
|
||||
X020911Y037280
|
||||
X018661Y024780
|
||||
X011911Y007780
|
||||
X000911Y037780
|
||||
X017931Y037280
|
||||
X021161Y035280
|
||||
X003891Y036530
|
||||
X025161Y036260
|
||||
X022161Y035280
|
||||
X020161Y035280
|
||||
X000911Y037780
|
||||
X020661Y024780
|
||||
X021161Y035280
|
||||
T108
|
||||
X014411Y014530
|
||||
X032161Y033780
|
||||
X013911Y013780
|
||||
X015411Y014530
|
||||
X028911Y035280
|
||||
X028661Y010030
|
||||
X029911Y030030
|
||||
X017411Y008280
|
||||
X026911Y033280
|
||||
X028911Y030030
|
||||
X026661Y021030
|
||||
X037911Y011030
|
||||
X031661Y013530
|
||||
X033661Y013530
|
||||
X028911Y033280
|
||||
X004911Y018030
|
||||
X002911Y018030
|
||||
X024411Y003280
|
||||
X007661Y028530
|
||||
X030911Y030030
|
||||
X032911Y030030
|
||||
X034911Y030030
|
||||
X024411Y008280
|
||||
X026411Y003280
|
||||
X031911Y030030
|
||||
X033911Y030030
|
||||
X035911Y030030
|
||||
X029911Y025030
|
||||
X025911Y010280
|
||||
X007661Y026530
|
||||
X028911Y025030
|
||||
X032411Y037280
|
||||
X030411Y037280
|
||||
X017411Y010280
|
||||
X030911Y025030
|
||||
X032911Y025030
|
||||
X034911Y025030
|
||||
X028661Y008030
|
||||
X031911Y025030
|
||||
X033911Y025030
|
||||
X035911Y025030
|
||||
X014661Y003780
|
||||
X016661Y003780
|
||||
X011411Y003780
|
||||
X013411Y003780
|
||||
X037911Y009030
|
||||
X013911Y009780
|
||||
X024411Y010280
|
||||
X025411Y005780
|
||||
X023411Y005780
|
||||
X014411Y016530
|
||||
X032161Y035780
|
||||
X015411Y016530
|
||||
X025911Y008280
|
||||
X013911Y007780
|
||||
X011911Y013780
|
||||
X004911Y016780
|
||||
X002911Y016780
|
||||
X026911Y035280
|
||||
X028911Y035280
|
||||
X028661Y010030
|
||||
X026661Y023030
|
||||
X014411Y014530
|
||||
X032161Y033780
|
||||
X028911Y030030
|
||||
X015411Y014530
|
||||
X029911Y030030
|
||||
X017411Y008280
|
||||
X031661Y013530
|
||||
X033661Y013530
|
||||
X026911Y033280
|
||||
X028911Y033280
|
||||
X026661Y021030
|
||||
X037911Y011030
|
||||
X004911Y018030
|
||||
X002911Y018030
|
||||
X024411Y003280
|
||||
X026411Y003280
|
||||
X007661Y028530
|
||||
X031911Y030030
|
||||
X033911Y030030
|
||||
X035911Y030030
|
||||
X025911Y010280
|
||||
X030911Y030030
|
||||
X032911Y030030
|
||||
X034911Y030030
|
||||
X024411Y008280
|
||||
X028911Y025030
|
||||
X029911Y025030
|
||||
X007661Y026530
|
||||
X028661Y008030
|
||||
X032411Y037280
|
||||
X030411Y037280
|
||||
X031911Y025030
|
||||
X033911Y025030
|
||||
X035911Y025030
|
||||
X017411Y010280
|
||||
X030911Y025030
|
||||
X032911Y025030
|
||||
X034911Y025030
|
||||
X011411Y003780
|
||||
X013411Y003780
|
||||
X013911Y009780
|
||||
X023411Y005780
|
||||
X014661Y003780
|
||||
X016661Y003780
|
||||
X037911Y009030
|
||||
X024411Y010280
|
||||
X025911Y008280
|
||||
X013911Y007780
|
||||
X025411Y005780
|
||||
X014411Y016530
|
||||
X032161Y035780
|
||||
X015411Y016530
|
||||
T109
|
||||
X001911Y009530
|
||||
X001911Y012530
|
||||
X005911Y002530
|
||||
X035661Y008780
|
||||
X004911Y013530
|
||||
X003911Y005530
|
||||
X001911Y008530
|
||||
X004911Y009530
|
||||
X001911Y011530
|
||||
X004911Y012530
|
||||
X003911Y004530
|
||||
X002911Y015530
|
||||
X001911Y007530
|
||||
X035661Y010780
|
||||
X004911Y008530
|
||||
X001911Y010530
|
||||
X006161Y026530
|
||||
X004911Y011530
|
||||
X003911Y003530
|
||||
X002911Y014530
|
||||
X001911Y006530
|
||||
X005911Y015530
|
||||
X004911Y007530
|
||||
X006161Y025530
|
||||
X005911Y015530
|
||||
X004911Y010530
|
||||
X003911Y002530
|
||||
X002911Y013530
|
||||
|
@ -423,27 +439,25 @@ X001911Y005530
|
|||
X005911Y014530
|
||||
X004911Y006530
|
||||
X002911Y009530
|
||||
X006161Y024530
|
||||
X027911Y028280
|
||||
X002911Y012530
|
||||
X001911Y004530
|
||||
X005911Y013530
|
||||
X029911Y004030
|
||||
X005911Y013530
|
||||
X004911Y005530
|
||||
X035661Y007280
|
||||
X002911Y008530
|
||||
X006161Y023530
|
||||
X027911Y027280
|
||||
X005911Y009530
|
||||
X002911Y011530
|
||||
X001911Y003530
|
||||
X032661Y004030
|
||||
X005911Y012530
|
||||
X030911Y004030
|
||||
X005911Y012530
|
||||
X004911Y004530
|
||||
X035661Y006280
|
||||
X003911Y015530
|
||||
X002911Y007530
|
||||
X003911Y015530
|
||||
X027911Y026280
|
||||
X005911Y008530
|
||||
X002911Y010530
|
||||
|
@ -462,16 +476,16 @@ X005911Y006530
|
|||
X003911Y009530
|
||||
X003911Y012530
|
||||
X002911Y004530
|
||||
X005911Y005530
|
||||
X001911Y015530
|
||||
X005911Y005530
|
||||
X003911Y008530
|
||||
X003911Y011530
|
||||
X002911Y003530
|
||||
X033661Y004030
|
||||
X005911Y004530
|
||||
X001911Y014530
|
||||
X003911Y007530
|
||||
X005911Y004530
|
||||
X004911Y015530
|
||||
X003911Y007530
|
||||
X003911Y010530
|
||||
X002911Y002530
|
||||
X001911Y013530
|
||||
|
@ -479,25 +493,7 @@ X005911Y003530
|
|||
X035661Y009780
|
||||
X004911Y014530
|
||||
X003911Y006530
|
||||
X001911Y009530
|
||||
X001911Y012530
|
||||
X005911Y002530
|
||||
X006161Y028530
|
||||
X035661Y008780
|
||||
X004911Y013530
|
||||
X003911Y005530
|
||||
X001911Y008530
|
||||
X004911Y009530
|
||||
X001911Y011530
|
||||
X006161Y027530
|
||||
X004911Y012530
|
||||
X003911Y004530
|
||||
X002911Y015530
|
||||
T110
|
||||
X027661Y023530
|
||||
X030661Y022530
|
||||
X027661Y014530
|
||||
X030661Y023530
|
||||
X027661Y015530
|
||||
X030661Y014530
|
||||
X027661Y016530
|
||||
|
@ -510,49 +506,54 @@ X030661Y020530
|
|||
X030661Y017530
|
||||
X027661Y022530
|
||||
X030661Y021530
|
||||
X027661Y023530
|
||||
X030661Y022530
|
||||
X027661Y014530
|
||||
X030661Y023530
|
||||
T111
|
||||
X012411Y016280
|
||||
X021411Y016780
|
||||
X018911Y012280
|
||||
X035661Y004280
|
||||
X030661Y006030
|
||||
X038161Y013030
|
||||
X013411Y016280
|
||||
X006411Y017530
|
||||
X034911Y025780
|
||||
X036911Y013030
|
||||
X012411Y016280
|
||||
X028661Y015030
|
||||
X031661Y004030
|
||||
X034911Y025780
|
||||
X027661Y018280
|
||||
X015911Y036030
|
||||
X013661Y036780
|
||||
X033161Y016030
|
||||
X015411Y008030
|
||||
X015911Y036030
|
||||
X001661Y026530
|
||||
X033911Y023780
|
||||
X034911Y028780
|
||||
X027911Y018780
|
||||
X003911Y019530
|
||||
X013161Y014780
|
||||
X035911Y028780
|
||||
X001661Y026530
|
||||
X038161Y007780
|
||||
X034911Y028780
|
||||
X027911Y018780
|
||||
X034911Y027030
|
||||
X009661Y026530
|
||||
X038161Y007780
|
||||
X007161Y025530
|
||||
X025411Y029030
|
||||
X037161Y004280
|
||||
X006161Y022030
|
||||
X016911Y016280
|
||||
X028661Y017530
|
||||
X038661Y020780
|
||||
X020161Y029530
|
||||
X022161Y029530
|
||||
X006161Y022030
|
||||
X028661Y017530
|
||||
X012411Y003780
|
||||
X038661Y020780
|
||||
X029661Y023530
|
||||
X015023Y006280
|
||||
X030661Y002780
|
||||
X029661Y023530
|
||||
X010661Y003530
|
||||
X035161Y018280
|
||||
X030661Y006030
|
||||
X030661Y002780
|
||||
X031161Y008530
|
||||
X008911Y032780
|
||||
X036911Y013030
|
||||
X021411Y016780
|
||||
X018911Y012280
|
||||
X035161Y018280
|
||||
X035661Y004280
|
||||
T00
|
||||
M30
|
||||
|
|
|
@ -8,23 +8,23 @@ G04 CONTOUR ON CENTER OF CONTOUR VECTOR*
|
|||
%MOIN*%
|
||||
%OFA0B0*%
|
||||
%SFA1.0B1.0*%
|
||||
%ADD10C,0.049370*%
|
||||
%ADD11C,0.085000*%
|
||||
%ADD12C,0.080000*%
|
||||
%ADD13C,0.088000*%
|
||||
%ADD14C,0.140000*%
|
||||
%ADD15C,0.084000*%
|
||||
%ADD16C,0.082917*%
|
||||
%ADD17C,0.135984*%
|
||||
%ADD18C,0.175354*%
|
||||
%ADD10C,0.084000*%
|
||||
%ADD11C,0.175354*%
|
||||
%ADD12C,0.049370*%
|
||||
%ADD13C,0.085000*%
|
||||
%ADD14C,0.080000*%
|
||||
%ADD15C,0.088000*%
|
||||
%ADD16C,0.140000*%
|
||||
%ADD17C,0.082917*%
|
||||
%ADD18C,0.135984*%
|
||||
%ADD19C,0.092000*%
|
||||
%ADD20C,0.061496*%
|
||||
%ADD21C,0.089370*%
|
||||
%ADD22C,0.072992*%
|
||||
%ADD23C,0.109055*%
|
||||
%ADD24R,0.080000X0.080000*%
|
||||
%ADD25R,0.085000X0.085000*%
|
||||
%ADD26R,0.084000X0.084000*%
|
||||
%ADD24R,0.084000X0.084000*%
|
||||
%ADD25R,0.080000X0.080000*%
|
||||
%ADD26R,0.085000X0.085000*%
|
||||
%ADD27R,0.092000X0.092000*%
|
||||
%ADD28R,0.089370X0.089370*%
|
||||
%ADD29R,0.072992X0.072992*%
|
||||
|
@ -33,12 +33,33 @@ G04 CONTOUR ON CENTER OF CONTOUR VECTOR*
|
|||
G90*
|
||||
G70*
|
||||
G54D10*
|
||||
X616Y2853D03*
|
||||
X616Y2753D03*
|
||||
X616Y2653D03*
|
||||
X616Y2553D03*
|
||||
X616Y2453D03*
|
||||
X616Y2353D03*
|
||||
G54D11*
|
||||
X144Y3058D03*
|
||||
X144Y2148D03*
|
||||
G54D10*
|
||||
X616Y2853D03*
|
||||
X616Y2753D03*
|
||||
X616Y2653D03*
|
||||
X616Y2553D03*
|
||||
X616Y2453D03*
|
||||
X616Y2353D03*
|
||||
G54D11*
|
||||
X144Y3058D03*
|
||||
X144Y2148D03*
|
||||
G54D12*
|
||||
X1366Y3678D03*
|
||||
X3691Y1303D03*
|
||||
X3816Y1303D03*
|
||||
G54D11*
|
||||
G54D13*
|
||||
X2416Y3628D03*
|
||||
X2416Y3228D03*
|
||||
G54D10*
|
||||
G54D12*
|
||||
X3491Y2878D03*
|
||||
X3491Y2703D03*
|
||||
X3491Y2578D03*
|
||||
|
@ -56,7 +77,7 @@ X2866Y1753D03*
|
|||
X2966Y2353D03*
|
||||
X3391Y2378D03*
|
||||
X1502Y628D03*
|
||||
G54D12*
|
||||
G54D14*
|
||||
X3591Y3003D03*
|
||||
X3591Y2503D03*
|
||||
X3491Y3003D03*
|
||||
|
@ -73,7 +94,7 @@ X2991Y3003D03*
|
|||
X2991Y2503D03*
|
||||
X2891Y3003D03*
|
||||
X2891Y2503D03*
|
||||
G54D10*
|
||||
G54D12*
|
||||
X3866Y2078D03*
|
||||
X1591Y3603D03*
|
||||
X3166Y403D03*
|
||||
|
@ -82,12 +103,12 @@ X3816Y778D03*
|
|||
X891Y3278D03*
|
||||
X1541Y803D03*
|
||||
X1891Y1228D03*
|
||||
G54D11*
|
||||
G54D13*
|
||||
X3791Y228D03*
|
||||
X3791Y628D03*
|
||||
X3141Y228D03*
|
||||
X3541Y228D03*
|
||||
G54D13*
|
||||
G54D15*
|
||||
X191Y1553D03*
|
||||
X291Y1553D03*
|
||||
X391Y1553D03*
|
||||
|
@ -158,7 +179,7 @@ X591Y1153D03*
|
|||
X591Y1253D03*
|
||||
X591Y1353D03*
|
||||
X591Y1453D03*
|
||||
G54D11*
|
||||
G54D13*
|
||||
X1891Y728D03*
|
||||
X1891Y1028D03*
|
||||
X1991Y728D03*
|
||||
|
@ -167,12 +188,12 @@ X2091Y728D03*
|
|||
X2091Y1028D03*
|
||||
X2191Y728D03*
|
||||
X2191Y1028D03*
|
||||
G54D14*
|
||||
G54D16*
|
||||
X1241Y2628D03*
|
||||
X1241Y2828D03*
|
||||
X1241Y2428D03*
|
||||
X1241Y2228D03*
|
||||
G54D10*
|
||||
G54D12*
|
||||
X1316Y1478D03*
|
||||
X3316Y1603D03*
|
||||
X2866Y1503D03*
|
||||
|
@ -189,7 +210,7 @@ X2766Y1828D03*
|
|||
X1241Y1628D03*
|
||||
X1341Y1628D03*
|
||||
X3516Y1828D03*
|
||||
G54D11*
|
||||
G54D13*
|
||||
X3091Y728D03*
|
||||
X3091Y1028D03*
|
||||
X3191Y728D03*
|
||||
|
@ -198,7 +219,7 @@ X3291Y728D03*
|
|||
X3291Y1028D03*
|
||||
X3391Y728D03*
|
||||
X3391Y1028D03*
|
||||
G54D15*
|
||||
G54D10*
|
||||
X891Y2278D03*
|
||||
X891Y2178D03*
|
||||
X891Y2078D03*
|
||||
|
@ -239,7 +260,7 @@ X791Y678D03*
|
|||
X791Y578D03*
|
||||
X791Y478D03*
|
||||
X791Y378D03*
|
||||
G54D16*
|
||||
G54D17*
|
||||
X2991Y1228D03*
|
||||
X1391Y1228D03*
|
||||
X3091Y1228D03*
|
||||
|
@ -326,11 +347,9 @@ X3791Y1628D03*
|
|||
X3791Y1528D03*
|
||||
X3791Y1428D03*
|
||||
X2891Y1228D03*
|
||||
G54D17*
|
||||
G54D18*
|
||||
X3766Y1228D03*
|
||||
X3541Y3128D03*
|
||||
G54D18*
|
||||
X141Y3053D03*
|
||||
G54D19*
|
||||
X1491Y2503D03*
|
||||
X1491Y2403D03*
|
||||
|
@ -344,27 +363,19 @@ X1491Y2728D03*
|
|||
X2066Y2228D03*
|
||||
X1966Y2228D03*
|
||||
X1866Y2228D03*
|
||||
G54D12*
|
||||
G54D14*
|
||||
X1191Y1378D03*
|
||||
X1391Y1378D03*
|
||||
G54D11*
|
||||
G54D13*
|
||||
X1291Y728D03*
|
||||
X1291Y1128D03*
|
||||
G54D19*
|
||||
X2516Y3328D03*
|
||||
X2516Y3626D03*
|
||||
G54D11*
|
||||
G54D13*
|
||||
X466Y1903D03*
|
||||
X66Y1903D03*
|
||||
G54D18*
|
||||
X141Y2153D03*
|
||||
G54D13*
|
||||
X616Y2853D03*
|
||||
X616Y2753D03*
|
||||
X616Y2653D03*
|
||||
X616Y2553D03*
|
||||
X616Y2453D03*
|
||||
X616Y2353D03*
|
||||
G54D15*
|
||||
X3566Y528D03*
|
||||
X3566Y628D03*
|
||||
X3566Y728D03*
|
||||
|
@ -374,17 +385,17 @@ X3566Y878D03*
|
|||
X2791Y2828D03*
|
||||
X2791Y2728D03*
|
||||
X2791Y2628D03*
|
||||
G54D11*
|
||||
G54D13*
|
||||
X2991Y603D03*
|
||||
X3391Y603D03*
|
||||
X2991Y503D03*
|
||||
X3391Y503D03*
|
||||
G54D13*
|
||||
G54D15*
|
||||
X2991Y403D03*
|
||||
X3091Y403D03*
|
||||
X3266Y403D03*
|
||||
X3366Y403D03*
|
||||
G54D11*
|
||||
G54D13*
|
||||
X3591Y1453D03*
|
||||
X3191Y1453D03*
|
||||
X2366Y3028D03*
|
||||
|
@ -405,7 +416,7 @@ G54D19*
|
|||
X2666Y3703D03*
|
||||
X2766Y3703D03*
|
||||
X2866Y3703D03*
|
||||
G54D12*
|
||||
G54D14*
|
||||
X3041Y3728D03*
|
||||
X3241Y3728D03*
|
||||
X2891Y3528D03*
|
||||
|
@ -437,7 +448,7 @@ X3066Y2253D03*
|
|||
X2766Y2253D03*
|
||||
X3066Y2353D03*
|
||||
X2766Y2353D03*
|
||||
G54D11*
|
||||
G54D13*
|
||||
X3591Y1553D03*
|
||||
X3191Y1553D03*
|
||||
X1866Y3028D03*
|
||||
|
@ -454,16 +465,16 @@ X1766Y3028D03*
|
|||
X1766Y2628D03*
|
||||
X3566Y2228D03*
|
||||
X3166Y2228D03*
|
||||
G54D12*
|
||||
G54D14*
|
||||
X3366Y1353D03*
|
||||
X3166Y1353D03*
|
||||
G54D11*
|
||||
G54D13*
|
||||
X2066Y1378D03*
|
||||
X2066Y1878D03*
|
||||
G54D12*
|
||||
G54D14*
|
||||
X2666Y2103D03*
|
||||
X2666Y2303D03*
|
||||
G54D11*
|
||||
G54D13*
|
||||
X2591Y2503D03*
|
||||
X2591Y3003D03*
|
||||
X2191Y1878D03*
|
||||
|
@ -487,14 +498,14 @@ X2518Y1503D03*
|
|||
X2616Y1503D03*
|
||||
X2493Y2103D03*
|
||||
X2591Y2103D03*
|
||||
G54D11*
|
||||
G54D13*
|
||||
X1741Y1853D03*
|
||||
X1741Y1453D03*
|
||||
X2141Y603D03*
|
||||
X1741Y603D03*
|
||||
X1641Y628D03*
|
||||
X1241Y628D03*
|
||||
G54D12*
|
||||
G54D14*
|
||||
X1741Y828D03*
|
||||
X1741Y1028D03*
|
||||
X1666Y378D03*
|
||||
|
@ -503,7 +514,7 @@ X1391Y778D03*
|
|||
X1391Y978D03*
|
||||
X1341Y378D03*
|
||||
X1141Y378D03*
|
||||
G54D11*
|
||||
G54D13*
|
||||
X1591Y703D03*
|
||||
X1591Y1103D03*
|
||||
X1491Y703D03*
|
||||
|
@ -511,7 +522,7 @@ X1491Y1103D03*
|
|||
G54D19*
|
||||
X1191Y778D03*
|
||||
X1191Y1076D03*
|
||||
G54D12*
|
||||
G54D14*
|
||||
X2866Y803D03*
|
||||
X2866Y1003D03*
|
||||
X291Y1678D03*
|
||||
|
@ -526,14 +537,14 @@ X2341Y578D03*
|
|||
X2541Y578D03*
|
||||
X2641Y328D03*
|
||||
X2441Y328D03*
|
||||
G54D11*
|
||||
G54D13*
|
||||
X2766Y678D03*
|
||||
X2766Y1078D03*
|
||||
X2316Y678D03*
|
||||
X2316Y1078D03*
|
||||
X2916Y1328D03*
|
||||
X2516Y1328D03*
|
||||
G54D12*
|
||||
G54D14*
|
||||
X1441Y1453D03*
|
||||
X1441Y1653D03*
|
||||
X2591Y828D03*
|
||||
|
@ -542,7 +553,7 @@ X3791Y1103D03*
|
|||
X3791Y903D03*
|
||||
X1541Y1653D03*
|
||||
X1541Y1453D03*
|
||||
G54D11*
|
||||
G54D13*
|
||||
X1641Y1853D03*
|
||||
X1641Y1453D03*
|
||||
X1091Y3253D03*
|
||||
|
@ -583,7 +594,7 @@ X142Y3529D03*
|
|||
X2016Y3528D03*
|
||||
X2116Y3528D03*
|
||||
X2216Y3528D03*
|
||||
G54D11*
|
||||
G54D13*
|
||||
X1091Y3353D03*
|
||||
X691Y3353D03*
|
||||
X1265Y3352D03*
|
||||
|
@ -604,12 +615,15 @@ G54D23*
|
|||
X3641Y3678D03*
|
||||
X3641Y3481D03*
|
||||
G54D24*
|
||||
X616Y2853D03*
|
||||
X616Y2853D03*
|
||||
G54D25*
|
||||
X2891Y2503D03*
|
||||
X3491Y2503D03*
|
||||
G54D25*
|
||||
G54D26*
|
||||
X1891Y728D03*
|
||||
X3091Y728D03*
|
||||
G54D26*
|
||||
G54D24*
|
||||
X791Y2278D03*
|
||||
G54D27*
|
||||
X1491Y2503D03*
|
||||
|
|
|
@ -8,23 +8,23 @@ G04 CONTOUR ON CENTER OF CONTOUR VECTOR*
|
|||
%MOIN*%
|
||||
%OFA0B0*%
|
||||
%SFA1.0B1.0*%
|
||||
%ADD10C,0.049370*%
|
||||
%ADD11C,0.085000*%
|
||||
%ADD12C,0.080000*%
|
||||
%ADD13C,0.088000*%
|
||||
%ADD14C,0.140000*%
|
||||
%ADD15C,0.084000*%
|
||||
%ADD16C,0.082917*%
|
||||
%ADD17C,0.135984*%
|
||||
%ADD18C,0.175354*%
|
||||
%ADD10C,0.084000*%
|
||||
%ADD11C,0.175354*%
|
||||
%ADD12C,0.049370*%
|
||||
%ADD13C,0.085000*%
|
||||
%ADD14C,0.080000*%
|
||||
%ADD15C,0.088000*%
|
||||
%ADD16C,0.140000*%
|
||||
%ADD17C,0.082917*%
|
||||
%ADD18C,0.135984*%
|
||||
%ADD19C,0.092000*%
|
||||
%ADD20C,0.061496*%
|
||||
%ADD21C,0.089370*%
|
||||
%ADD22C,0.072992*%
|
||||
%ADD23C,0.109055*%
|
||||
%ADD24R,0.080000X0.080000*%
|
||||
%ADD25R,0.085000X0.085000*%
|
||||
%ADD26R,0.084000X0.084000*%
|
||||
%ADD24R,0.084000X0.084000*%
|
||||
%ADD25R,0.080000X0.080000*%
|
||||
%ADD26R,0.085000X0.085000*%
|
||||
%ADD27R,0.092000X0.092000*%
|
||||
%ADD28R,0.089370X0.089370*%
|
||||
%ADD29R,0.072992X0.072992*%
|
||||
|
@ -33,12 +33,23 @@ G04 CONTOUR ON CENTER OF CONTOUR VECTOR*
|
|||
G90*
|
||||
G70*
|
||||
G54D10*
|
||||
X616Y2853D03*
|
||||
X616Y2753D03*
|
||||
X616Y2653D03*
|
||||
X616Y2553D03*
|
||||
X616Y2453D03*
|
||||
X616Y2353D03*
|
||||
G54D11*
|
||||
X144Y3058D03*
|
||||
X144Y2148D03*
|
||||
G54D12*
|
||||
X1366Y3678D03*
|
||||
X3691Y1303D03*
|
||||
X3816Y1303D03*
|
||||
G54D11*
|
||||
G54D13*
|
||||
X2416Y3628D03*
|
||||
X2416Y3228D03*
|
||||
G54D10*
|
||||
G54D12*
|
||||
X3491Y2878D03*
|
||||
X3491Y2703D03*
|
||||
X3491Y2578D03*
|
||||
|
@ -56,7 +67,7 @@ X2866Y1753D03*
|
|||
X2966Y2353D03*
|
||||
X3391Y2378D03*
|
||||
X1502Y628D03*
|
||||
G54D12*
|
||||
G54D14*
|
||||
X3591Y3003D03*
|
||||
X3591Y2503D03*
|
||||
X3491Y3003D03*
|
||||
|
@ -73,7 +84,7 @@ X2991Y3003D03*
|
|||
X2991Y2503D03*
|
||||
X2891Y3003D03*
|
||||
X2891Y2503D03*
|
||||
G54D10*
|
||||
G54D12*
|
||||
X3866Y2078D03*
|
||||
X1591Y3603D03*
|
||||
X3166Y403D03*
|
||||
|
@ -82,12 +93,12 @@ X3816Y778D03*
|
|||
X891Y3278D03*
|
||||
X1541Y803D03*
|
||||
X1891Y1228D03*
|
||||
G54D11*
|
||||
G54D13*
|
||||
X3791Y228D03*
|
||||
X3791Y628D03*
|
||||
X3141Y228D03*
|
||||
X3541Y228D03*
|
||||
G54D13*
|
||||
G54D15*
|
||||
X191Y1553D03*
|
||||
X291Y1553D03*
|
||||
X391Y1553D03*
|
||||
|
@ -158,7 +169,7 @@ X591Y1153D03*
|
|||
X591Y1253D03*
|
||||
X591Y1353D03*
|
||||
X591Y1453D03*
|
||||
G54D11*
|
||||
G54D13*
|
||||
X1891Y728D03*
|
||||
X1891Y1028D03*
|
||||
X1991Y728D03*
|
||||
|
@ -167,7 +178,7 @@ X2091Y728D03*
|
|||
X2091Y1028D03*
|
||||
X2191Y728D03*
|
||||
X2191Y1028D03*
|
||||
G54D14*
|
||||
G54D16*
|
||||
X1241Y2628D03*
|
||||
X1241Y2828D03*
|
||||
X1241Y2428D03*
|
||||
|
@ -176,7 +187,7 @@ X1241Y2628D03*
|
|||
X1241Y2828D03*
|
||||
X1241Y2428D03*
|
||||
X1241Y2228D03*
|
||||
G54D10*
|
||||
G54D12*
|
||||
X1316Y1478D03*
|
||||
X3316Y1603D03*
|
||||
X2866Y1503D03*
|
||||
|
@ -193,7 +204,7 @@ X2766Y1828D03*
|
|||
X1241Y1628D03*
|
||||
X1341Y1628D03*
|
||||
X3516Y1828D03*
|
||||
G54D11*
|
||||
G54D13*
|
||||
X3091Y728D03*
|
||||
X3091Y1028D03*
|
||||
X3191Y728D03*
|
||||
|
@ -202,7 +213,7 @@ X3291Y728D03*
|
|||
X3291Y1028D03*
|
||||
X3391Y728D03*
|
||||
X3391Y1028D03*
|
||||
G54D15*
|
||||
G54D10*
|
||||
X891Y2278D03*
|
||||
X891Y2178D03*
|
||||
X891Y2078D03*
|
||||
|
@ -243,7 +254,7 @@ X791Y678D03*
|
|||
X791Y578D03*
|
||||
X791Y478D03*
|
||||
X791Y378D03*
|
||||
G54D16*
|
||||
G54D17*
|
||||
X2991Y1228D03*
|
||||
X1391Y1228D03*
|
||||
X3091Y1228D03*
|
||||
|
@ -330,11 +341,9 @@ X3791Y1628D03*
|
|||
X3791Y1528D03*
|
||||
X3791Y1428D03*
|
||||
X2891Y1228D03*
|
||||
G54D17*
|
||||
G54D18*
|
||||
X3766Y1228D03*
|
||||
X3541Y3128D03*
|
||||
G54D18*
|
||||
X141Y3053D03*
|
||||
G54D19*
|
||||
X1491Y2503D03*
|
||||
X1491Y2403D03*
|
||||
|
@ -348,27 +357,19 @@ X1491Y2728D03*
|
|||
X2066Y2228D03*
|
||||
X1966Y2228D03*
|
||||
X1866Y2228D03*
|
||||
G54D12*
|
||||
G54D14*
|
||||
X1191Y1378D03*
|
||||
X1391Y1378D03*
|
||||
G54D11*
|
||||
G54D13*
|
||||
X1291Y728D03*
|
||||
X1291Y1128D03*
|
||||
G54D19*
|
||||
X2516Y3328D03*
|
||||
X2516Y3626D03*
|
||||
G54D11*
|
||||
G54D13*
|
||||
X466Y1903D03*
|
||||
X66Y1903D03*
|
||||
G54D18*
|
||||
X141Y2153D03*
|
||||
G54D13*
|
||||
X616Y2853D03*
|
||||
X616Y2753D03*
|
||||
X616Y2653D03*
|
||||
X616Y2553D03*
|
||||
X616Y2453D03*
|
||||
X616Y2353D03*
|
||||
G54D15*
|
||||
X3566Y528D03*
|
||||
X3566Y628D03*
|
||||
X3566Y728D03*
|
||||
|
@ -378,17 +379,17 @@ X3566Y878D03*
|
|||
X2791Y2828D03*
|
||||
X2791Y2728D03*
|
||||
X2791Y2628D03*
|
||||
G54D11*
|
||||
G54D13*
|
||||
X2991Y603D03*
|
||||
X3391Y603D03*
|
||||
X2991Y503D03*
|
||||
X3391Y503D03*
|
||||
G54D13*
|
||||
G54D15*
|
||||
X2991Y403D03*
|
||||
X3091Y403D03*
|
||||
X3266Y403D03*
|
||||
X3366Y403D03*
|
||||
G54D11*
|
||||
G54D13*
|
||||
X3591Y1453D03*
|
||||
X3191Y1453D03*
|
||||
X2366Y3028D03*
|
||||
|
@ -409,7 +410,7 @@ G54D19*
|
|||
X2666Y3703D03*
|
||||
X2766Y3703D03*
|
||||
X2866Y3703D03*
|
||||
G54D12*
|
||||
G54D14*
|
||||
X3041Y3728D03*
|
||||
X3241Y3728D03*
|
||||
X2891Y3528D03*
|
||||
|
@ -443,7 +444,7 @@ X3066Y2253D03*
|
|||
X2766Y2253D03*
|
||||
X3066Y2353D03*
|
||||
X2766Y2353D03*
|
||||
G54D11*
|
||||
G54D13*
|
||||
X3591Y1553D03*
|
||||
X3191Y1553D03*
|
||||
X1866Y3028D03*
|
||||
|
@ -460,16 +461,16 @@ X1766Y3028D03*
|
|||
X1766Y2628D03*
|
||||
X3566Y2228D03*
|
||||
X3166Y2228D03*
|
||||
G54D12*
|
||||
G54D14*
|
||||
X3366Y1353D03*
|
||||
X3166Y1353D03*
|
||||
G54D11*
|
||||
G54D13*
|
||||
X2066Y1378D03*
|
||||
X2066Y1878D03*
|
||||
G54D12*
|
||||
G54D14*
|
||||
X2666Y2103D03*
|
||||
X2666Y2303D03*
|
||||
G54D11*
|
||||
G54D13*
|
||||
X2591Y2503D03*
|
||||
X2591Y3003D03*
|
||||
X2191Y1878D03*
|
||||
|
@ -493,14 +494,14 @@ X2518Y1503D03*
|
|||
X2616Y1503D03*
|
||||
X2493Y2103D03*
|
||||
X2591Y2103D03*
|
||||
G54D11*
|
||||
G54D13*
|
||||
X1741Y1853D03*
|
||||
X1741Y1453D03*
|
||||
X2141Y603D03*
|
||||
X1741Y603D03*
|
||||
X1641Y628D03*
|
||||
X1241Y628D03*
|
||||
G54D12*
|
||||
G54D14*
|
||||
X1741Y828D03*
|
||||
X1741Y1028D03*
|
||||
X1666Y378D03*
|
||||
|
@ -509,7 +510,7 @@ X1391Y778D03*
|
|||
X1391Y978D03*
|
||||
X1341Y378D03*
|
||||
X1141Y378D03*
|
||||
G54D11*
|
||||
G54D13*
|
||||
X1591Y703D03*
|
||||
X1591Y1103D03*
|
||||
X1491Y703D03*
|
||||
|
@ -517,7 +518,7 @@ X1491Y1103D03*
|
|||
G54D19*
|
||||
X1191Y778D03*
|
||||
X1191Y1076D03*
|
||||
G54D12*
|
||||
G54D14*
|
||||
X2866Y803D03*
|
||||
X2866Y1003D03*
|
||||
X291Y1678D03*
|
||||
|
@ -532,14 +533,14 @@ X2341Y578D03*
|
|||
X2541Y578D03*
|
||||
X2641Y328D03*
|
||||
X2441Y328D03*
|
||||
G54D11*
|
||||
G54D13*
|
||||
X2766Y678D03*
|
||||
X2766Y1078D03*
|
||||
X2316Y678D03*
|
||||
X2316Y1078D03*
|
||||
X2916Y1328D03*
|
||||
X2516Y1328D03*
|
||||
G54D12*
|
||||
G54D14*
|
||||
X1441Y1453D03*
|
||||
X1441Y1653D03*
|
||||
X2591Y828D03*
|
||||
|
@ -548,7 +549,7 @@ X3791Y1103D03*
|
|||
X3791Y903D03*
|
||||
X1541Y1653D03*
|
||||
X1541Y1453D03*
|
||||
G54D11*
|
||||
G54D13*
|
||||
X1641Y1853D03*
|
||||
X1641Y1453D03*
|
||||
X1091Y3253D03*
|
||||
|
@ -589,7 +590,7 @@ X142Y3529D03*
|
|||
X2016Y3528D03*
|
||||
X2116Y3528D03*
|
||||
X2216Y3528D03*
|
||||
G54D11*
|
||||
G54D13*
|
||||
X1091Y3353D03*
|
||||
X691Y3353D03*
|
||||
X1265Y3352D03*
|
||||
|
@ -610,12 +611,14 @@ G54D23*
|
|||
X3641Y3678D03*
|
||||
X3641Y3481D03*
|
||||
G54D24*
|
||||
X616Y2853D03*
|
||||
G54D25*
|
||||
X2891Y2503D03*
|
||||
X3491Y2503D03*
|
||||
G54D25*
|
||||
G54D26*
|
||||
X1891Y728D03*
|
||||
X3091Y728D03*
|
||||
G54D26*
|
||||
G54D24*
|
||||
X791Y2278D03*
|
||||
G54D27*
|
||||
X1491Y2503D03*
|
||||
|
|
Before Width: | Height: | Size: 1.6 MiB After Width: | Height: | Size: 1.6 MiB |
|
@ -7,11 +7,11 @@
|
|||
|
||||
queryCommand = "Q"
|
||||
;signature = 20
|
||||
signature = "speeduino 201706-dev"
|
||||
signature = "speeduino 201709-dev"
|
||||
versionInfo = "S" ; Put this in the title bar.
|
||||
|
||||
;[TunerStudio]
|
||||
; iniSpecVersion = 3.24
|
||||
[TunerStudio]
|
||||
iniSpecVersion = 3.46
|
||||
|
||||
;-------------------------------------------------------------------------------
|
||||
|
||||
|
@ -98,23 +98,35 @@
|
|||
|
||||
endianness = little
|
||||
nPages = 10
|
||||
burnCommand = "B"
|
||||
pageSize = 288, 64, 288, 64, 288, 64, 64, 160, 192, 128
|
||||
; pageIdentifier = "\$tsCanId\x01", "\$tsCanId\x02", "\$tsCanId\x03", "\$tsCanId\x04", "\$tsCanId\x05", "\$tsCanId\x06", "\$tsCanId\x07", "\$tsCanId\x08", "\$tsCanId\x09", "\$tsCanId\x0A"
|
||||
pageActivationDelay = 10
|
||||
pageActivate = "P\001", "P\002", "P\003", "P\004", "P\005", "P\006", "P\007", "P\010", "P\011", "P\012"
|
||||
pageReadCommand = "V", "V", "V", "V", "V", "V", "V", "V", "V", "V"
|
||||
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"
|
||||
; pageChunkWrite = "" ; No chunk write for standard MS
|
||||
;pageSize = 288, 64, 288, 64, 288, 64, 64, 160, 192, 128, 192
|
||||
pageSize = 288, 128, 288, 128, 288, 128, 160, 192, 128, 192
|
||||
|
||||
;burnCommand = "B"
|
||||
;pageActivate = "P\001", "P\002", "P\003", "P\004", "P\005", "P\006", "P\007", "P\010", "P\011", "P\012", "P\013"
|
||||
;pageReadCommand = "V", "V", "V", "V", "V", "V", "V", "V", "V", "V", "V"
|
||||
;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"
|
||||
|
||||
|
||||
;pageChunkWrite = "w%2o%2c%v", "w%2o%2c%v", "w%2o%2c%v", "w%2o%2c%v", "w%2o%2c%v", "w%2o%2c%v", "w%2o%2c%v", "w%2o%2c%v", "w%2o%2c%v", "w%2o%2c%v", "w%2o%2c%v"
|
||||
;pageChunkWrite = "X%o%c%v", "X%o%c%v", "X%o%c%v", "X%o%c%v", "X%o%c%v", "X%o%c%v", "X%o%c%v", "X%o%c%v", "X%o%c%v", "X%o%c%v", "X%o%c%v"
|
||||
|
||||
; New commands
|
||||
;pageSize = 288, 128, 288, 128, 288, 128, 128, 160, 192, 128, 192
|
||||
pageIdentifier = "\$tsCanId\x01", "\$tsCanId\x02", "\$tsCanId\x03", "\$tsCanId\x04", "\$tsCanId\x05", "\$tsCanId\x06", "\$tsCanId\x07", "\$tsCanId\x08", "\$tsCanId\x09", "\$tsCanId\x0A"
|
||||
burnCommand = "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%v", "p%2i%2o%2c%v", "p%2i%2o%2c%v", "p%2i%2o%2c%v", "p%2i%2o%2c%v", "p%2i%2o%2c%v", "p%2i%2o%2c%v", "p%2i%2o%2c%v", "p%2i%2o%2c%v", "p%2i%2o%2c%v"
|
||||
pageValueWrite = "w%2i%2o%2c%v", "w%2i%2o%2c%v", "w%2i%2o%2c%v", "w%2i%2o%2c%v", "w%2i%2o%2c%v", "w%2i%2o%2c%v", "w%2i%2o%2c%v", "w%2i%2o%2c%v", "w%2i%2o%2c%v", "w%2i%2o%2c%v"
|
||||
pageChunkWrite = "w%2i%2o%2c%v", "w%2i%2o%2c%v", "w%2i%2o%2c%v", "w%2i%2o%2c%v", "w%2i%2o%2c%v", "w%2i%2o%2c%v", "w%2i%2o%2c%v", "w%2i%2o%2c%v", "w%2i%2o%2c%v", "w%2i%2o%2c%v"
|
||||
;pageChunkWrite = "w%2i%2o%2c%v", "", "w%2i%2o%2c%v", "", "w%2i%2o%2c%v", "", "", "w%2i%2o%2c%v", "w%2i%2o%2c%v", "w%2i%2o%2c%v", "w%2i%2o%2c%v"
|
||||
|
||||
blockingFactor = 2048
|
||||
tableBlockingFactor = 2048
|
||||
delayAfterPortOpen=1000
|
||||
;validateArrayBounds = true
|
||||
blockReadTimeout = 2000
|
||||
;tsWriteBlocks = off
|
||||
;writeBlocks = off
|
||||
interWriteDelay = 10
|
||||
;tsWriteBlocks = on
|
||||
interWriteDelay = 5 ;Ignored when tsWriteBlocks is on
|
||||
pageActivationDelay = 10
|
||||
|
||||
;New for TS 3.0.08ish upwards, define lists of standard I/O options
|
||||
|
||||
|
@ -122,7 +134,7 @@
|
|||
#define PIN_OUT16inv = "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID"
|
||||
|
||||
#define tsCanId_list = "CAN ID 0", "CAN ID 1", "CAN ID 2", "CAN ID 3", "CAN ID 4", "CAN ID 5", "CAN ID 6", "CAN ID 7", "CAN ID 8", "CAN ID 9", "CAN ID 10","CAN ID 11","CAN ID 12","CAN ID 13","CAN ID 14","INVALID"
|
||||
#define CAN_ADDRESS_HEX_inv255 = $PIN_OUT16inv, $PIN_OUT16inv, $PIN_OUT16inv, $PIN_OUT16inv, $PIN_OUT16inv, $PIN_OUT16inv, $PIN_OUT16inv, $PIN_OUT16inv, $PIN_OUT16inv, $PIN_OUT16inv, $PIN_OUT16inv, $PIN_OUT16inv, $PIN_OUT16inv, $PIN_OUT16inv, $PIN_OUT16inv, $PIN_OUT10inv, "INVALID", "INVALID", "INVALID", "INVALID", "blank"
|
||||
#define CAN_ADDRESS_HEX_inv255 = $PIN_OUT16inv, $PIN_OUT16inv, $PIN_OUT16inv, $PIN_OUT16inv, $PIN_OUT16inv, $PIN_OUT16inv, $PIN_OUT16inv, $PIN_OUT16inv, $PIN_OUT16inv, $PIN_OUT16inv, $PIN_OUT16inv, $PIN_OUT16inv, $PIN_OUT16inv, $PIN_OUT16inv, $PIN_OUT16inv, $PIN_OUT10inv, "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "blank"
|
||||
#define CAN_ADDRESS_HEX_00XX = "INVALID", "0x001", "0x002", "0x003", "0x004", "0x005", "0x006", "0x007", "0x008", "0x009", "0x00A", "0x00B", "0x00C", "0x00D", "0x00E", "0x00F", "0x010", "0x011", "0x012", "0x013", "0x014", "0x015", "0x016", "0x017", "0x018", "0x019", "0x01A", "0x01B", "0x01C", "0x01D", "0x01E", "0x01F", "0x020", "0x021", "0x022", "0x023", "0x024", "0x025", "0x026", "0x027", "0x028", "0x029", "0x02A", "0x02B", "0x02C", "0x02D", "0x02E", "0x02F", "0x030", "0x031", "0x032", "0x033", "0x034", "0x035", "0x036", "0x037", "0x038", "0x039", "0x03A", "0x03B", "0x03C", "0x03D", "0x03E", "0x03F", "0x040", "0x041", "0x042", "0x043", "0x044", "0x045", "0x046", "0x047", "0x048", "0x049", "0x04A", "0x04B", "0x04C", "0x04D", "0x04E", "0x04F", "0x050", "0x051", "0x052", "0x053", "0x054", "0x055", "0x056", "0x057", "0x058", "0x059", "0x05A", "0x05B", "0x05C", "0x05D", "0x05E", "0x05F" ,"0x060", "0x061", "0x062", "0x063", "0x064", "0x065", "0x066", "0x067", "0x068", "0x069", "0x06A", "0x06B", "0x06C", "0x06D", "0x06E", "0x06F", "0x070", "0x071", "0x072", "0x073", "0x074", "0x075", "0x076", "0x077", "0x078", "0x079", "0x07A", "0x07B", "0x07C", "0x07D", "0x07E", "0x07F", "0x080", "0x081", "0x082", "0x083", "0x084", "0x085", "0x086", "0x087", "0x088", "0x089", "0x08A", "0x08B", "0x08C", "0x08D", "0x08E", "0x08F" ,"0x090", "0x091", "0x092", "0x093", "0x094", "0x095", "0x096", "0x097", "0x098", "0x099", "0x09A", "0x09B", "0x09C", "0x09D", "0x09E", "0x09F", "0x0A0", "0x0A1", "0x0A2", "0x0A3", "0x0A4", "0x0A5", "0x0A6", "0x0A7", "0x0A8", "0x0A9", "0x0AA", "0x0AB", "0x0AC", "0x0AD", "0x0AE", "0x0AF", "0x0B0", "0x0B1", "0x0B2", "0x0B3", "0x0B4", "0x0B5", "0x0B6", "0x0B7", "0x0B8", "0x0B9", "0x0BA", "0x0BB", "0x0BC", "0x0BD", "0x0BE", "0x0BF" ,"0x0C0", "0x0C1", "0x0C2", "0x0C3", "0x0C4", "0x0C5", "0x0C6", "0x0C7", "0x0C8", "0x0C9", "0x0CA", "0x0CB", "0x0CC", "0x0CD", "0x0CE", "0x0CF", "0x0D0", "0x0D1", "0x0D2", "0x0D3", "0x0D4", "0x0D5", "0x0D6", "0x0D7", "0x0D8", "0x0D9", "0x0DA", "0x0DB", "0x0DC", "0x0DD", "0x0DE", "0x0DF", "0x0E0", "0x0E1", "0x0E2", "0x0E3", "0x0E4", "0x0E5", "0x0E6", "0x0E7", "0x0E8", "0x0E9", "0x0EA", "0x0EB", "0x0EC", "0x0ED", "0x0EE", "0x0EF" ,"0x0F0", "0x0F1", "0x0F2", "0x0F3", "0x0F4", "0x0F5", "0x0F6", "0x0F7", "0x0F8", "0x0F9", "0x0FA", "0x0FB", "0x0FC", "0x0FD", "0x0FE", "0x0FF"
|
||||
#define CAN_ADDRESS_HEX_01XX = "0x100", "0x101", "0x102", "0x103", "0x104", "0x105", "0x106", "0x107", "0x108", "0x109", "0x10A", "0x10B", "0x10C", "0x10D", "0x10E", "0x10F", "0x110", "0x111", "0x112", "0x113", "0x114", "0x115", "0x116", "0x117", "0x118", "0x119", "0x11A", "0x11B", "0x11C", "0x11D", "0x11E", "0x11F", "0x120", "0x121", "0x122", "0x123", "0x124", "0x125", "0x126", "0x127", "0x128", "0x129", "0x12A", "0x12B", "0x12C", "0x12D", "0x12E", "0x12F", "0x130", "0x131", "0x132", "0x133", "0x134", "0x135", "0x136", "0x137", "0x138", "0x139", "0x13A", "0x13B", "0x13C", "0x13D", "0x13E", "0x13F", "0x140", "0x141", "0x142", "0x143", "0x144", "0x145", "0x146", "0x147", "0x148", "0x149", "0x14A", "0x14B", "0x14C", "0x14D", "0x14E", "0x14F", "0x150", "0x151", "0x152", "0x153", "0x154", "0x155", "0x156", "0x157", "0x158", "0x159", "0x15A", "0x15B", "0x15C", "0x15D", "0x15E", "0x15F" ,"0x160", "0x161", "0x162", "0x163", "0x164", "0x165", "0x166", "0x167", "0x168", "0x169", "0x16A", "0x16B", "0x16C", "0x16D", "0x16E", "0x16F", "0x170", "0x171", "0x172", "0x173", "0x174", "0x175", "0x176", "0x177", "0x178", "0x179", "0x17A", "0x17B", "0x17C", "0x17D", "0x17E", "0x17F", "0x180", "0x181", "0x182", "0x183", "0x184", "0x185", "0x186", "0x187", "0x188", "0x189", "0x18A", "0x18B", "0x18C", "0x18D", "0x18E", "0x18F" ,"0x190", "0x191", "0x192", "0x193", "0x194", "0x195", "0x196", "0x197", "0x198", "0x199", "0x19A", "0x19B", "0x19C", "0x19D", "0x19E", "0x19F", "0x1A0", "0x1A1", "0x1A2", "0x1A3", "0x1A4", "0x1A5", "0x1A6", "0x1A7", "0x1A8", "0x1A9", "0x1AA", "0x1AB", "0x1AC", "0x1AD", "0x1AE", "0x1AF", "0x1B0", "0x1B1", "0x1B2", "0x1B3", "0x1B4", "0x1B5", "0x1B6", "0x1B7", "0x1B8", "0x1B9", "0x1BA", "0x1BB", "0x1BC", "0x1BD", "0x1BE", "0x1BF" ,"0x1C0", "0x1C1", "0x1C2", "0x1C3", "0x1C4", "0x1C5", "0x1C6", "0x1C7", "0x1C8", "0x1C9", "0x1CA", "0x1CB", "0x1CC", "0x1CD", "0x1CE", "0x1CF", "0x1D0", "0x1D1", "0x1D2", "0x1D3", "0x1D4", "0x1D5", "0x1D6", "0x1D7", "0x1D8", "0x1D9", "0x1DA", "0x1DB", "0x1DC", "0x1DD", "0x1DE", "0x1DF", "0x1E0", "0x1E1", "0x1E2", "0x1E3", "0x1E4", "0x1E5", "0x1E6", "0x1E7", "0x1E8", "0x1E9", "0x1EA", "0x1EB", "0x1EC", "0x1ED", "0x1EE", "0x1EF" ,"0x1F0", "0x1F1", "0x1F2", "0x1F3", "0x1F4", "0x1F5", "0x1F6", "0x1F7", "0x1F8", "0x1F9", "0x1FA", "0x1FB", "0x1FC", "0x1FD", "0x1FE", "0x1FF"
|
||||
#define CAN_ADDRESS_HEX_02XX = "0x200", "0x201", "0x202", "0x203", "0x204", "0x205", "0x206", "0x207", "0x208", "0x209", "0x20A", "0x20B", "0x20C", "0x20D", "0x20E", "0x20F", "0x210", "0x211", "0x212", "0x213", "0x214", "0x215", "0x216", "0x217", "0x218", "0x219", "0x21A", "0x21B", "0x21C", "0x21D", "0x21E", "0x21F", "0x220", "0x221", "0x222", "0x223", "0x224", "0x225", "0x226", "0x227", "0x228", "0x229", "0x22A", "0x22B", "0x22C", "0x22D", "0x22E", "0x22F", "0x230", "0x231", "0x232", "0x233", "0x234", "0x235", "0x236", "0x237", "0x238", "0x239", "0x23A", "0x23B", "0x23C", "0x23D", "0x23E", "0x23F", "0x240", "0x241", "0x242", "0x243", "0x244", "0x245", "0x246", "0x247", "0x248", "0x249", "0x24A", "0x24B", "0x24C", "0x24D", "0x24E", "0x24F", "0x250", "0x251", "0x252", "0x253", "0x254", "0x255", "0x256", "0x257", "0x258", "0x259", "0x25A", "0x25B", "0x25C", "0x25D", "0x25E", "0x25F" ,"0x260", "0x261", "0x262", "0x263", "0x264", "0x265", "0x266", "0x267", "0x268", "0x269", "0x26A", "0x26B", "0x26C", "0x26D", "0x26E", "0x26F", "0x270", "0x271", "0x272", "0x273", "0x274", "0x275", "0x276", "0x277", "0x278", "0x279", "0x27A", "0x27B", "0x27C", "0x27D", "0x27E", "0x27F", "0x280", "0x281", "0x282", "0x283", "0x284", "0x285", "0x286", "0x287", "0x288", "0x289", "0x28A", "0x28B", "0x28C", "0x28D", "0x28E", "0x28F" ,"0x290", "0x291", "0x292", "0x293", "0x294", "0x295", "0x296", "0x297", "0x298", "0x299", "0x29A", "0x29B", "0x29C", "0x29D", "0x29E", "0x29F", "0x2A0", "0x2A1", "0x2A2", "0x2A3", "0x2A4", "0x2A5", "0x2A6", "0x2A7", "0x2A8", "0x2A9", "0x2AA", "0x2AB", "0x2AC", "0x2AD", "0x2AE", "0x2AF", "0x2B0", "0x2B1", "0x2B2", "0x2B3", "0x2B4", "0x2B5", "0x2B6", "0x2B7", "0x2B8", "0x2B9", "0x2BA", "0x2BB", "0x2BC", "0x2BD", "0x2BE", "0x2BF" ,"0x2C0", "0x2C1", "0x2C2", "0x2C3", "0x2C4", "0x2C5", "0x2C6", "0x2C7", "0x2C8", "0x2C9", "0x2CA", "0x2CB", "0x2CC", "0x2CD", "0x2CE", "0x2CF", "0x2D0", "0x2D1", "0x2D2", "0x2D3", "0x2D4", "0x2D5", "0x2D6", "0x2D7", "0x2D8", "0x2D9", "0x2DA", "0x2DB", "0x2DC", "0x2DD", "0x2DE", "0x2DF", "0x2E0", "0x2E1", "0x2E2", "0x2E3", "0x2E4", "0x2E5", "0x2E6", "0x2E7", "0x2E8", "0x2E9", "0x2EA", "0x2EB", "0x2EC", "0x2ED", "0x2EE", "0x2EF" ,"0x2F0", "0x2F1", "0x2F2", "0x2F3", "0x2F4", "0x2F5", "0x2F6", "0x2F7", "0x2F8", "0x2F9", "0x2FA", "0x2FB", "0x2FC", "0x2FD", "0x2FE", "0x2FF"
|
||||
|
@ -216,7 +228,7 @@ page = 2
|
|||
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"
|
||||
unused2-38h= bits, U08, 38, [7:7], "No", "Yes"
|
||||
dfcoEnabled= bits, U08, 38, [7:7], "Off", "On"
|
||||
|
||||
primePulse = scalar, U08, 39, "ms", 0.1, 0.0, 0.0, 25.5, 1
|
||||
dutyLim = scalar, U08, 40, "%", 1.0, 0.0, 0.0, 100.0, 0
|
||||
|
@ -226,7 +238,7 @@ page = 2
|
|||
boostMaxDuty = scalar, U08, 43, "%", 1.0, 0.0, 0.0, 100.0, 0
|
||||
tpsMin = scalar, U08, 44, "ADC", 1.0, 0.0, 0.0, 255.0, 0
|
||||
tpsMax = scalar, U08, 45, "ADC", 1.0, 0.0, 0.0, 255.0, 0
|
||||
mapMin = scalar, U08, 46, "kpa", 1.0, 0.0, 0.0, 255.0, 0
|
||||
mapMin = scalar, S08, 46, "kpa", 1.0, 0.0, -100, 127.0, 0
|
||||
mapMax = scalar, U16, 47, "kpa", 1.0, 0.0, 0.0, 25500, 0
|
||||
fpPrime = scalar, U08, 49, "s", 1.0, 0.0, 0.0, 255.0, 0
|
||||
stoich = scalar, U08, 50, ":1", 0.1, 0.0, 0.0, 25.5, 1
|
||||
|
@ -243,6 +255,7 @@ page = 2
|
|||
iacCLmaxDuty = scalar, U08, 62, "%", 1.0, 0.0, 0.0, 100.0, 0
|
||||
boostMinDuty = scalar, U08, 63, "%", 1.0, 0.0, 0.0, 100.0, 0 ; Minimum and maximum duty cycles for boost control
|
||||
|
||||
unused2-64 = array, U08, 64, [63], "%", 1.0, 0.0, 0.0, 255, 0
|
||||
|
||||
|
||||
;--------------------------------------------------
|
||||
|
@ -273,8 +286,8 @@ page = 4
|
|||
TrigEdge = bits, U08, 5,[0:0], "Leading", "Trailing"
|
||||
TrigSpeed = bits, U08, 5,[1:1], "Crank Speed", "Cam Speed"
|
||||
IgInv = bits, U08, 5,[2:2], "Going Low", "Going High"
|
||||
oddfire = bits, U08, 5,[3:3], "No", "Yes"
|
||||
TrigPattern= bits, U08, 5,[4:7], "Missing Tooth", "Basic Distributor", "Dual Wheel", "GM 7X", "4G63 / Miata / 3000GT", "GM 24X", "Jeep 2000", "Audi 135", "Honda D17", "Miata 99-05", "Mazda AU", "Non-360 Dual", "Nissan 360", "Subaru 6/7", "Daihatsu +1", "INVALID"
|
||||
unused4-5d = bits, U08, 5,[3:3], "No", "Yes"
|
||||
TrigPattern= bits, U08, 5,[4:7], "Missing Tooth", "Basic Distributor", "Dual Wheel", "GM 7X", "4G63 / Miata / 3000GT", "GM 24X", "Jeep 2000", "Audi 135", "Honda D17", "Miata 99-05", "Mazda AU", "Non-360 Dual", "Nissan 360", "Subaru 6/7", "Daihatsu +1", "Harley EVO"
|
||||
TrigEdgeSec= bits, U08, 6,[0:0], "Leading", "Trailing"
|
||||
fuelPumpPin= bits , U08, 6,[1:6], "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", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID"
|
||||
useResync = bits, U08, 6,[7:7], "No", "Yes"
|
||||
|
@ -293,8 +306,7 @@ page = 4
|
|||
;Dwell control
|
||||
dwellcont = bits, U08, 12, [0:0], "INVALID", "Dwell control"
|
||||
useDwellLim= bits, U08, 12, [1:1], "Off", "On"
|
||||
sparkMode = bits, U08, 12, [2:3], "Wasted Spark", "Single Channel", "Wasted COP", "Sequential"
|
||||
dfcoEnabled= bits, U08, 12, [4:4], "Off", "On"
|
||||
sparkMode = bits, U08, 12, [2:4], "Wasted Spark", "Single Channel", "Wasted COP", "Sequential", "Rotary", "INVALID", "INVALID", "INVALID"
|
||||
TrigFilter = bits, U08, 12, [5:6], "Off", "Weak", "Medium", "Aggressive"
|
||||
ignCranklock=bits, U08, 12, [7:7], "Off", "On"
|
||||
dwellcrank = scalar, U08, 13, "ms", 0.1, 0, 0, 25, 1
|
||||
|
@ -340,7 +352,7 @@ page = 4
|
|||
ignBypassPin = bits , U08, 63, [1:6], "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", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID"
|
||||
ignBypassHiLo = bits, U08, 63, [7:7], "LOW", "HIGH"
|
||||
|
||||
|
||||
unused4-64 = array, U08, 64, [63], "%", 1.0, 0.0, 0.0, 255, 0
|
||||
;--------------------------------------------------
|
||||
;Start AFR page
|
||||
;--------------------------------------------------
|
||||
|
@ -389,8 +401,8 @@ page = 6
|
|||
egoRPM = scalar, U08, 11, "rpm", 100, 0.0, 100, 25500, 0
|
||||
egoTPSMax = scalar, U08, 12, "%", 1, 0, 0, 120, 0
|
||||
vvtPin = bits , U08, 13, [0:5], "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", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID"
|
||||
unused6-13e = bits, U08, 13, [6:6], "ONE", "INVALID"
|
||||
unused6-13f = bits, U08, 13, [7:7], "ONE", "INVALID"
|
||||
useExtBaro = bits, U08, 13, [6:6], "No", "Yes"
|
||||
boostMode = bits, U08, 13, [7:7], "Simple", "Full"
|
||||
boostPin = bits, U08, 14, [0:5], "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", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID"
|
||||
unused6-14e = bits, U08, 14, [6:6], "ONE", "INVALID"
|
||||
unused6-14f = bits, U08, 14, [7:7], "ONE", "INVALID"
|
||||
|
@ -429,72 +441,66 @@ page = 6
|
|||
lnchPullRes = bits, U08, 60, [0:1], "Float" , "Pullup", "INVALID", "INVALID"
|
||||
fuelTrimEnabled= bits, U08, 60, [2:2], "No", "Yes"
|
||||
flatSEnable = bits, U08, 60, [3:3], "No", "Yes"
|
||||
unused6-60e = bits, U08, 60, [4:4], "ONE", "INVALID"
|
||||
unused6-60f = bits, U08, 60, [5:5], "ONE", "INVALID"
|
||||
unused6-60g = bits, U08, 60, [6:6], "ONE", "INVALID"
|
||||
unused6-60h = bits, U08, 60, [7:7], "ONE", "INVALID"
|
||||
; Baro Sensor pin
|
||||
baroPin = bits, U08, 60, [4:7], "A0", "A1", "A2", "A3", "A4", "A5", "A6", "A7", "A8", "A8", "A10", "A11", "A12", "A13", "A14", "A15"
|
||||
|
||||
; Flat shift
|
||||
flatSSoftWin = scalar, U08, 61, "rpm", 100, 0.0, 100, 25500, 0
|
||||
flatSRetard = scalar, U08, 62, "deg", 1.0, 0.0, 0.0, 80, 0
|
||||
flatSArm = scalar, U08, 63, "rpm", 100, 0.0, 100, 25500, 0
|
||||
|
||||
;--------------------------------------------------
|
||||
;Start idle and fan controls (Page 7)
|
||||
;--------------------------------------------------
|
||||
page = 7
|
||||
iacCLValues = array, U08, 0, [10], "RPM", 10.0, 0.0, 0, 2550, 0
|
||||
iacOLStepVal = array, U08, 10, [10], "Steps", 3, 0, 0, 765, 0
|
||||
iacOLPWMVal = array, U08, 20, [10], "Duty %", 1.0, 0, 0, 100, 0
|
||||
iacCLValues = array, U08, 64, [10], "RPM", 10.0, 0.0, 0, 2550, 0
|
||||
iacOLStepVal = array, U08, 74, [10], "Steps", 3, 0, 0, 765, 0
|
||||
iacOLPWMVal = array, U08, 84, [10], "Duty %", 1.0, 0, 0, 100, 0
|
||||
#if CELSIUS
|
||||
iacBins = array, U08, 30, [10], "C", 1.0, -40, -40, 215, 0
|
||||
iacBins = array, U08, 94, [10], "C", 1.0, -40, -40, 215, 0
|
||||
#else
|
||||
iacBins = array, U08, 30, [10], "F", 1.8, -22.23, -40, 215, 0
|
||||
iacBins = array, U08, 94, [10], "F", 1.8, -22.23, -40, 215, 0
|
||||
#endif
|
||||
iacCrankSteps= array, U08, 40, [4], "Steps", 3, 0, 0, 765, 0
|
||||
iacCrankDuty = array, U08, 44, [4], "Duty %", 1.0, 0, 0, 100, 0
|
||||
iacCrankSteps= array, U08, 104, [4], "Steps", 3, 0, 0, 765, 0
|
||||
iacCrankDuty = array, U08, 108, [4], "Duty %", 1.0, 0, 0, 100, 0
|
||||
#if CELSIUS
|
||||
iacCrankBins = array, U08, 48, [4], "C", 1.0, -40, -40, 215, 0
|
||||
iacCrankBins = array, U08, 112, [4], "C", 1.0, -40, -40, 215, 0
|
||||
#else
|
||||
iacCrankBins = array, U08, 48, [4], "F", 1.8, -22.23, -40, 215, 0
|
||||
iacCrankBins = array, U08, 112, [4], "F", 1.8, -22.23, -40, 215, 0
|
||||
#endif
|
||||
|
||||
iacAlgorithm = bits , U08, 52, [0:2], "None", "On/Off", "PWM Open loop", "PWM Closed loop", "Stepper Open Loop", "Stepper Closed Loop", "INVALID", "INVALID"
|
||||
iacStepTime = bits , U08, 52, [3:5], "INVALID","1", "2", "3", "4", "5", "6","INVALID"
|
||||
iacChannels = bits, U08, 52, [6:6], "1", "2"
|
||||
iacPWMdir = bits , U08, 52, [7:7], "Normal", "Reverse"
|
||||
iacAlgorithm = bits , U08, 116, [0:2], "None", "On/Off", "PWM Open loop", "PWM Closed loop", "Stepper Open Loop", "Stepper Closed Loop", "INVALID", "INVALID"
|
||||
iacStepTime = bits , U08, 116, [3:5], "INVALID","1", "2", "3", "4", "5", "6","INVALID"
|
||||
iacChannels = bits, U08, 116, [6:6], "1", "2"
|
||||
iacPWMdir = bits , U08, 116, [7:7], "Normal", "Reverse"
|
||||
|
||||
#if CELSIUS
|
||||
iacFastTemp = scalar, U08, 53, "C", 1.0, -40, -40, 215, 0
|
||||
iacFastTemp = scalar, U08, 117, "C", 1.0, -40, -40, 215, 0
|
||||
#else
|
||||
iacFastTemp = scalar, U08, 53, "F", 1.8, -22.23, -40, 215, 0
|
||||
iacFastTemp = scalar, U08, 117, "F", 1.8, -22.23, -40, 215, 0
|
||||
#endif
|
||||
|
||||
iacStepHome = scalar, U08, 54, "Steps", 3, 0, 0, 765, 0
|
||||
iacStepHyster= scalar, U08, 55, "Steps", 1, 0.0, 0.0, 10, 0
|
||||
iacStepHome = scalar, U08, 118, "Steps", 3, 0, 0, 765, 0
|
||||
iacStepHyster= scalar, U08, 119, "Steps", 1, 0.0, 0.0, 10, 0
|
||||
|
||||
; Begin fan control vairables
|
||||
fanInv = bits, U08, 56, [0:0], "No", "Yes"
|
||||
fanEnable = bits, U08, 56, [1:1], "Off", "On/Off"
|
||||
fanPin = bits , U08, 56, [2:7], "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", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID"
|
||||
fanInv = bits, U08, 120, [0:0], "No", "Yes"
|
||||
fanEnable = bits, U08, 120, [1:1], "Off", "On/Off"
|
||||
fanPin = bits , U08, 120, [2:7], "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", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID"
|
||||
#if CELSIUS
|
||||
fanSP = scalar, U08, 57, "C", 1.0, -40, -40, 215.0, 0
|
||||
fanHyster = scalar, U08, 58, "C", 1.0, 0.0, 0.0, 40, 0
|
||||
fanSP = scalar, U08, 121, "C", 1.0, -40, -40, 215.0, 0
|
||||
fanHyster = scalar, U08, 122, "C", 1.0, 0.0, 0.0, 40, 0
|
||||
#else
|
||||
fanSP = scalar, U08, 57, "F", 1.8, -22.23, -40, 215.0, 0
|
||||
fanHyster = scalar, U08, 58, "F", 1.0, 0.0, 0.0, 40, 0
|
||||
fanSP = scalar, U08, 121, "F", 1.8, -22.23, -40, 215.0, 0
|
||||
fanHyster = scalar, U08, 122, "F", 1.0, 0.0, 0.0, 40, 0
|
||||
#endif
|
||||
fanFreq = scalar, U08 , 59, "Hz", 2.0, 0.0, 10, 511, 0
|
||||
fanFreq = scalar, U08 , 123, "Hz", 2.0, 0.0, 10, 511, 0
|
||||
#if CELSIUS
|
||||
fanPWMBins = array, U08, 60, [4], "C", 1.0, -40, -40, 215, 0
|
||||
fanPWMBins = array, U08, 124, [4], "C", 1.0, -40, -40, 215, 0
|
||||
#else
|
||||
fanPWMBins = array, U08, 60, [4], "F", 1.8, -22.23, -40, 215, 0
|
||||
fanPWMBins = array, U08, 124, [4], "F", 1.8, -22.23, -40, 215, 0
|
||||
#endif
|
||||
|
||||
;--------------------------------------------------
|
||||
;Boost and vvt maps (Page 8)
|
||||
;Boost and vvt maps (Page 7)
|
||||
;--------------------------------------------------
|
||||
page = 8
|
||||
page = 7
|
||||
;notes for boostTable in PSI~~~There are 6.895 psis to a kPa then x 2 like the kPa ver~~~div atmos. pressure in kPa by 2 and make neg so to subtract instead of add
|
||||
; #if BOOSTPSI
|
||||
; boostTable = array, U08, 0,[8x8], "PSI", 0.29007547546041846, -50.6625, 0, 74, 0
|
||||
|
@ -508,11 +514,11 @@ page = 8
|
|||
tpsBinsVVT = array, U08, 152,[ 8], "TPS", 1.0, 0.0, 0.0, 255.0, 0
|
||||
|
||||
;--------------------------------------------------
|
||||
;Sequential fuel trim tables (Page 9)
|
||||
;Sequential fuel trim tables (Page 8)
|
||||
;--------------------------------------------------
|
||||
page = 9
|
||||
page = 8
|
||||
fuelTrim1Table = array, U08, 0,[6x6], "%", 1.0, -128, -50, 50, 0
|
||||
fuelTrim1rpmBins = array, U08, 36,[ 6], "RPM", 100.0, 0.0, 100, 25500, 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
|
||||
|
@ -520,7 +526,7 @@ page = 9
|
|||
#endif
|
||||
|
||||
fuelTrim2Table = array, U08, 48,[6x6], "%", 1.0, -128, -50, 50, 0
|
||||
fuelTrim2rpmBins = array, U08, 84,[ 6], "RPM", 100.0, 0.0, 100, 25500, 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
|
||||
|
@ -528,7 +534,7 @@ page = 9
|
|||
#endif
|
||||
|
||||
fuelTrim3Table = array, U08, 96,[6x6], "%", 1.0, -128, -50, 50, 0
|
||||
fuelTrim3rpmBins = array, U08, 132,[ 6], "RPM", 100.0, 0.0, 100, 25500, 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
|
||||
|
@ -536,7 +542,7 @@ page = 9
|
|||
#endif
|
||||
|
||||
fuelTrim4Table = array, U08, 144,[6x6], "%", 1.0, -128, -50, 50, 0
|
||||
fuelTrim4rpmBins = array, U08, 180,[ 6], "RPM", 100.0, 0.0, 100, 25500, 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
|
||||
|
@ -544,9 +550,9 @@ page = 9
|
|||
#endif
|
||||
|
||||
;--------------------------------------------------
|
||||
;CANBUS control (Page 10)
|
||||
;CANBUS control (Page 9)
|
||||
;--------------------------------------------------
|
||||
page = 10
|
||||
page = 9
|
||||
#if CAN_COMMANDS
|
||||
enable_canbus = bits, U08, 0, [0:1], "Disable", "On Via Secondary Serial", "ON via Internal CAN ", "INVALID"
|
||||
#else
|
||||
|
@ -694,6 +700,32 @@ page = 10
|
|||
unused10_126 = scalar, U08, 126, "", 1, 0, 0, 255, 0
|
||||
unused10_127 = scalar, U08, 127, "", 1, 0, 0, 255, 0
|
||||
|
||||
page = 10
|
||||
#if CELSIUS
|
||||
crankingEnrichBins = array, U08, 0, [4], "C", 1.0, -40, -40, 215, 0
|
||||
#else
|
||||
crankingEnrichBins = array, U08, 0, [4], "F", 1.8, -22.23, -40, 215, 0
|
||||
#endif
|
||||
crankingEnrichValues= array, U08, 4, [4], "%", 1.0, 0.0, 0, 255, 0 ; Values for the cranking enrichment curve
|
||||
|
||||
rotaryType = bits , U08, 8, [0:1], "FC", "FD", "RX8", "INVALID"
|
||||
unused11-8c = bits , U08, 8, [2:2], "Off","On"
|
||||
unused11-8d = bits , U08, 8, [3:3], "Off","On"
|
||||
unused11-8e = bits , U08, 8, [4:4], "Off","On"
|
||||
unused11-8f = bits , U08, 8, [5:5], "Off","On"
|
||||
unused11-8g = bits , U08, 8, [6:6], "Off","On"
|
||||
unused11-8h = bits , U08, 8, [7:7], "Off","On"
|
||||
|
||||
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
|
||||
boostSens = scalar, U16, 25, "", 1, 0, 0, 5000, 0
|
||||
boostIntv = scalar, U08, 27, "ms", 1, 0, 0, 250, 0
|
||||
unused11_28_192 = array, U08, 28,[164], "RPM", 100.0, 0.0, 100, 25500, 0
|
||||
|
||||
;-------------------------------------------------------------------------------
|
||||
|
||||
[ConstantsExtensions]
|
||||
|
@ -722,8 +754,9 @@ page = 10
|
|||
requiresPowerCycle = oddfire4
|
||||
requiresPowerCycle = iacCLminDuty
|
||||
requiresPowerCycle = iacCLmaxDuty
|
||||
requiresPowerCycle = boostMinDuty
|
||||
requiresPowerCycle = boostMaxDuty
|
||||
requiresPowerCycle = useExtBaro
|
||||
requiresPowerCycle = baroPin
|
||||
requiresPowerCycle = rotaryType
|
||||
|
||||
defaultValue = pinLayout, 1
|
||||
defaultValue = TrigPattern, 0
|
||||
|
@ -762,6 +795,8 @@ page = 10
|
|||
defaultValue = iacCLmaxDuty,100
|
||||
defaultValue = boostMinDuty,0
|
||||
defaultValue = boostMaxDuty,100
|
||||
defaultValue = boostSens, 2000
|
||||
defaultValue = boostIntv, 30
|
||||
defaultValue = sparkDur, 1.0
|
||||
defaultValue = speeduino_tsCanId, 0
|
||||
defaultValue = true_address, 256
|
||||
|
@ -833,6 +868,7 @@ menuDialog = main
|
|||
subMenu = dwellSettings, "Dwell settings"
|
||||
subMenu = dwell_correction_curve, "Dwell Compensation"
|
||||
subMenu = iat_retard_curve, "&IAT Retard"
|
||||
subMenu = rotary_ignition, "Rotary Ignition", { sparkMode == 4 }
|
||||
;subMenu = wheelsim, "Stim for wheel"
|
||||
;subMenu = oddwheel, "Oddfire Wheel settings", 7, { wheelon && oddfire }
|
||||
|
||||
|
@ -923,7 +959,7 @@ menuDialog = main
|
|||
TrigFilter = "Tuning of the trigger filter algorithm. The more aggressive the setting, the more noise will be removed, however this increases the chance of some true readings being filtered out (False positive). Medium is safe for most setups. Only select 'Aggressive' if no other options are working"
|
||||
|
||||
sparkMode = "Wasted Spark: Ignition outputs are on the channels <= half the number of cylinders. Eg 4 cylinder outputs on IGN1 and IGN2.\nSingle Channel: All ignition pulses are output on IGN1.\nWasted COP: Ignition pulses are output on all ignition channels up to the number of cylinders. Eg 4 cylinder outputs on all ignition channels. No valid for >4 cylinders"
|
||||
IgInv = "Whether the spark fires when the ignition sign goes high or goes low. Most ignition systems 'Going Low' but please verify this as damage to coils can result from the incorrect selection"
|
||||
IgInv = "Whether the spark fires when the ignition signal goes high or goes low. Nearly all ignition systems use 'Going Low' but please verify this as damage to coils can result from the incorrect selection. (NOTE: THIS IS NOT MEGASQUIRT. THIS SETTING IS USUALLY THE OPPOSITE OF WHAT THEY USE!)"
|
||||
sparkDur = "The duration of the spark at full dwell. Typically around 1ms"
|
||||
|
||||
fanInv = ""
|
||||
|
@ -956,6 +992,7 @@ menuDialog = main
|
|||
|
||||
multiplyMAP = "If enabled, the MAP reading is included directly into the pulsewidth calculation. 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."
|
||||
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."
|
||||
|
||||
flexEnabled = "Turns on readings from the Flex sensor and enables the below adjustments"
|
||||
flexFreqLow = "The frequency of the sensor at 0% ethanol (50Hz for standard GM/Continental sensor)"
|
||||
|
@ -1056,6 +1093,8 @@ menuDialog = main
|
|||
cmdtestspk350dc = "this will cycle the output at 50% Duty cycle"
|
||||
cmdtestspk450dc = "this will cycle the output at 50% Duty cycle"
|
||||
|
||||
boostIntv = "The closed loop control interval will run every this many ms. Generally values between 50% and 100% of the valve frequency work best"
|
||||
|
||||
[UserDefined]
|
||||
|
||||
; Enhanced TunerStudio dialogs can be defined here
|
||||
|
@ -1077,6 +1116,9 @@ menuDialog = main
|
|||
; dialog which will be added.
|
||||
; dialogs can be nested and can be mixed with fields
|
||||
|
||||
dialog = wc_note
|
||||
field = "Final enrichment value must be 100%. Typical maximum is 255% (cold)."
|
||||
|
||||
dialog = engine_constants_southwest, "Speeduino Board"
|
||||
field = "Stoichiometric ratio", stoich
|
||||
field = "Injector Layout", injLayout, { nCylinders <= 4 }
|
||||
|
@ -1265,20 +1307,33 @@ menuDialog = main
|
|||
|
||||
dialog = fuelpump, "Fuel pump"
|
||||
field = "Fuel pump pin", fuelPumpPin
|
||||
field = "Fuel pump prime duration", fpPrime
|
||||
|
||||
dialog = crankPW, "Cranking Pulsewidths (ms)"
|
||||
topicHelp = "http://speeduino.com/wiki/index.php/Cranking"
|
||||
dialog = crankingEnrichDialog, "Cranking Enrichment", yAxis
|
||||
panel = cranking_enrich_curve
|
||||
|
||||
dialog = crankingIgnOptions, "Cranking Timing", yAxis
|
||||
field = "Cranking advance Angle", CrankAng
|
||||
field = "Cranking bypass", ignBypassEnable
|
||||
field = "Bypass output pin", ignBypassPin { ignBypassEnable }
|
||||
field = "Fix cranking timing with trigger", ignCranklock, { TrigPattern == 1 || TrigPattern == 4 || TrigPattern == 10 || TrigPattern == 9 }
|
||||
|
||||
dialog = crankingOptions, "", yAxis
|
||||
field = "Cranking RPM (Max)", crankRPM
|
||||
field = "Flood Clear level", tpsflood
|
||||
field = ""
|
||||
field = "Fuel pump prime duration", fpPrime
|
||||
field = "Priming Pulsewidth", primePulse
|
||||
field = ""
|
||||
field = "Cranking Enrichment %", crankingPct
|
||||
field = ""
|
||||
field = "Cranking bypass", ignBypassEnable
|
||||
field = "Bypass output pin", ignBypassPin { ignBypassEnable }
|
||||
field = "Fix cranking timing with trigger", ignCranklock, { TrigPattern == 1 || TrigPattern == 4 || TrigPattern == 10}
|
||||
|
||||
dialog = crankPW, "Cranking Settings", yAxis
|
||||
topicHelp = "http://speeduino.com/wiki/index.php/Cranking"
|
||||
panel = crankingOptions, North
|
||||
;field = ""
|
||||
;field = "Cranking Enrichment %", crankingPct
|
||||
panel = crankingEnrichDialog, Center
|
||||
;field = ""
|
||||
panel = crankingIgnOptions, South
|
||||
|
||||
|
||||
dialog = aseSettings, "Afterstart Enrichment"
|
||||
field = "Enrichment %", asePct
|
||||
|
@ -1301,12 +1356,12 @@ menuDialog = main
|
|||
field = "Note: This is the number of revolutions that will be skipped during"
|
||||
field = "cranking before the injectors and coils are fired"
|
||||
field = "Trigger edge", TrigEdge
|
||||
field = "Secondary trigger edge", TrigEdgeSec, { TrigPattern == 0 || TrigPattern == 2 } ;Missing tooth and dual wheel
|
||||
field = "Secondary trigger edge", TrigEdgeSec, { TrigPattern == 0 || TrigPattern == 2 || TrigPattern == 9 || TrigPattern == 12 } ;Missing tooth, dual wheel and Miata 9905
|
||||
field = "Trigger Filter", TrigFilter
|
||||
field = "Re-sync every cycle", useResync, { TrigPattern == 2 || TrigPattern == 4 || TrigPattern == 7 } ;Dual wheel, 4G63 and Audi 135
|
||||
field = "Re-sync every cycle", useResync, { TrigPattern == 2 || TrigPattern == 4 || TrigPattern == 7 || TrigPattern == 12 } ;Dual wheel, 4G63, Audi 135, Nissan 360
|
||||
field = ""
|
||||
field = "#The below option is EXPERIMENTAL! If unsure what this is, please set to No"
|
||||
field = "User per tooth ignition calculation", perToothIgn, {TrigPattern == 0} ;Only works for missing tooth
|
||||
field = "User per tooth ignition calculation", perToothIgn, {TrigPattern == 0 || TrigPattern == 1 || TrigPattern == 2 || TrigPattern == 4 || TrigPattern == 12 } ;Only works for missing tooth, distributor, dual wheel, nissan 360
|
||||
|
||||
dialog = sparkSettings,"Spark Settings",4
|
||||
field = "Spark output mode", sparkMode
|
||||
|
@ -1336,6 +1391,10 @@ menuDialog = main
|
|||
field = "Note: Set the maximum dwell time at least 3ms above"
|
||||
field = "your desired dwell time (Including cranking)"
|
||||
|
||||
dialog = rotary_ignition, "Rotary Ignition", 4
|
||||
field = "Ignition Configuration", rotaryType
|
||||
panel = rotaryTrailing_curve
|
||||
|
||||
dialog = RevLimiterS, "Rev Limiter", 4
|
||||
topicHelp = "http://speeduino.com/wiki/index.php/Rev_Limits"
|
||||
field = "Rev Limiter"
|
||||
|
@ -1381,7 +1440,7 @@ menuDialog = main
|
|||
|
||||
dialog = mapCal, "Calibrate MAP"
|
||||
field = "#MAP Sensor"
|
||||
settingSelector = "Common MAP Sensors"
|
||||
settingSelector = "Common Pressure Sensors"
|
||||
settingOption = "MPX4115", mapMin=10, mapMax=122
|
||||
settingOption = "MPX4250", mapMin=10, mapMax=260
|
||||
settingOption = "GM 1-BAR", mapMin=10, mapMax=105
|
||||
|
@ -1396,28 +1455,37 @@ menuDialog = main
|
|||
field = "Value At 0.0 Volts", mapMin
|
||||
field = "Value At 5.0 Volts", mapMax
|
||||
|
||||
field = "#Baro Sensor"
|
||||
field = "Use external Baro sensor", useExtBaro
|
||||
field = "Analog pin to use for ext. Baro sensor", baroPin, { useExtBaro }
|
||||
|
||||
dialog = boostCut, "Boost Cut"
|
||||
field = "Boost Cut", boostCutType, { boostEnabled }
|
||||
field = "Boost Limit", boostLimit, { boostEnabled && boostCutType }
|
||||
|
||||
dialog = boostSettings, "Boost Control"
|
||||
topicHelp = "http://speeduino.com/wiki/index.php/Boost_Control"
|
||||
field = "Boost Control Enabled", boostEnabled
|
||||
field = "Boost output pin", boostPin, { boostEnabled }
|
||||
field = "Boost solenoid freq.", boostFreq, { boostEnabled }
|
||||
field = "Boost Cut", boostCutType, { boostEnabled }
|
||||
field = "Boost Limit", boostLimit, { boostEnabled && boostCutType }
|
||||
field = "Closed Loop settings"
|
||||
field = "P", boostKP, { boostEnabled }
|
||||
field = "I", boostKI, { boostEnabled }
|
||||
field = "D", boostKD, { boostEnabled }
|
||||
|
||||
field = "Valve minimum duty cycle", boostMinDuty, { boostEnabled }
|
||||
field = "Valve maximum duty cycle", boostMaxDuty, { boostEnabled }
|
||||
panel = boostCut
|
||||
field = "Closed Loop settings"
|
||||
field = "Control mode", boostMode, { boostEnabled }
|
||||
slider = "Sensitivity", boostSens, horizontal, { boostEnabled }
|
||||
field = "Control interval", boostIntv, { boostEnabled }
|
||||
field = "P", boostKP, { boostEnabled && boostMode }
|
||||
field = "I", boostKI, { boostEnabled && boostMode}
|
||||
field = "D", boostKD, { boostEnabled && boostMode}
|
||||
|
||||
|
||||
dialog = vvtSettings, "VVT Control"
|
||||
field = "VVT Control Enabled", vvtEnabled
|
||||
field = "VVT output pin", vvtPin, { vvtEnabled }
|
||||
field = "VVT solenoid freq.", vvtFreq, { vvtEnabled }
|
||||
|
||||
dialog = wc_note
|
||||
field = "For 99% of engines, warmup must have 100% in the final row. Typical maximum is 255% (cold)."
|
||||
|
||||
dialog = warmup, "Warmup Enrichment (WUE) - Percent Multiplier"
|
||||
panel = warmup_curve
|
||||
panel = wc_note
|
||||
|
@ -1426,7 +1494,7 @@ menuDialog = main
|
|||
|
||||
;Fuel trim composite dialog
|
||||
dialog = inj_trim1TblTitle, "Channel #1"
|
||||
panel = fuelTrimTable1Tbl, Center, { fuelTrimEnabled }
|
||||
panel = fuelTrimTable1Tbl, { fuelTrimEnabled }
|
||||
dialog = inj_trim2TblTitle, "Channel #2"
|
||||
panel = fuelTrimTable2Tbl, { fuelTrimEnabled }
|
||||
dialog = inj_trim3TblTitle, "Channel #3"
|
||||
|
@ -1441,9 +1509,12 @@ menuDialog = main
|
|||
panel = inj_trim3TblTitle
|
||||
panel = inj_trim4TblTitle
|
||||
|
||||
dialog = inj_trimad,"Injector Cyl 1-4 Trims", yAxis
|
||||
dialog = inj_trim_enable, ""
|
||||
field = "Individual fuel trim enabled", fuelTrimEnabled, { injLayout == 3 }
|
||||
panel = inj_trimadt, North
|
||||
|
||||
dialog = inj_trimad,"Injector Cyl 1-4 Trims", yAxis
|
||||
panel = inj_trim_enable, North
|
||||
panel = inj_trimadt, Center
|
||||
panel = inj_trimadb, South
|
||||
|
||||
dialog = outputtest_warningmessage, ""
|
||||
|
@ -1809,8 +1880,6 @@ cmdtestspk450dc = "E\x03\x0C"
|
|||
xBins = brvBins, batteryVoltage
|
||||
yBins = injBatRates
|
||||
|
||||
|
||||
|
||||
; Correction curve for Air Density vs temperature
|
||||
curve = airdensity_curve, "IAT density correction"
|
||||
columnLabel = "Air Temperature", "Fuel Amount"
|
||||
|
@ -1873,6 +1942,18 @@ cmdtestspk450dc = "E\x03\x0C"
|
|||
xBins = iacBins, coolant
|
||||
yBins = iacCLValues
|
||||
|
||||
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
|
||||
yBins = rotarySplitValues
|
||||
|
||||
; Warmup enrichment curve
|
||||
curve = warmup_curve, "Warmup Enrichment (WUE) Curve"
|
||||
;topicHelp = "file://$getProjectsDirPath()/docs/xxx.pdf#wue"
|
||||
|
@ -1883,6 +1964,16 @@ cmdtestspk450dc = "E\x03\x0C"
|
|||
yBins = wueRates
|
||||
gauge = cltGauge
|
||||
|
||||
; Cranking enrichment curve
|
||||
curve = cranking_enrich_curve, "Cranking Enrichment Curve"
|
||||
;topicHelp = "file://$getProjectsDirPath()/docs/xxx.pdf#wue"
|
||||
columnLabel = "Coolant", "Enrich %"
|
||||
xAxis = -40, 110, 9
|
||||
yAxis = 0, 200, 6
|
||||
xBins = crankingEnrichBins, coolant
|
||||
yBins = crankingEnrichValues
|
||||
;gauge = cltGau25
|
||||
|
||||
; Warmup enrichment VEAL AFR adjustment curve (Not currently working)
|
||||
;curve = warmup_afr_curve, "AFR Target Temperature Adustment"
|
||||
; columnLabel = "Coolant Temp", "AFR Offset %"
|
||||
|
@ -2148,7 +2239,7 @@ cmdtestspk450dc = "E\x03\x0C"
|
|||
indicator = { launchSoft }, "Launch Soft", "Launch Soft", white, black, green, black
|
||||
indicator = { softlimitOn }, "Soft Limit OFF","Soft Limiter", white, black, red, black
|
||||
indicator = { hardLimitOn }, "Hard Limit OFF","Hard Limiter", white, black, red, black
|
||||
indicator = { boostCutOut }, "Boost Cut OFF", "Boost Cut", white, black, red, black
|
||||
indicator = { boostCutOut }, "Ign Cut OFF", "Ign Cut (Boost)", white, black, red, black
|
||||
indicator = { sync }, "No Sync", "Sync", white, black, green, black
|
||||
|
||||
;-------------------------------------------------------------------------------
|
||||
|
@ -2227,7 +2318,7 @@ cmdtestspk450dc = "E\x03\x0C"
|
|||
deadValue = { 0 } ; Convenient unchanging value.
|
||||
|
||||
ochGetCommand = "r\$tsCanId\x30%2o%2c"
|
||||
ochBlockSize = 73
|
||||
ochBlockSize = 74
|
||||
|
||||
secl = scalar, U08, 0, "sec", 1.000, 0.000
|
||||
squirt = scalar, U08, 1, "bits", 1.000, 0.000
|
||||
|
@ -2249,39 +2340,37 @@ cmdtestspk450dc = "E\x03\x0C"
|
|||
mapaccaen = bits, U08, 2, [6:6]
|
||||
mapaccden = bits, U08, 2, [7:7]
|
||||
dwell = scalar, U08, 3, "ms", 0.100, 0.000
|
||||
map = scalar, U08, 4, "kpa", 2.000, 0.000
|
||||
iatRaw = scalar, U08, 5, "°C", 1.000, 0.000
|
||||
coolantRaw = scalar, U08, 6, "°C", 1.000, 0.000
|
||||
tpsADC = scalar, U08, 7, "ADC", 1.000, 0.000
|
||||
batteryVoltage = scalar, U08, 8, "V", 0.100, 0.000
|
||||
afr = scalar, U08, 9, "O2", 0.100, 0.000
|
||||
egoCorrection = scalar, U08, 10, "%", 1.000, 0.000
|
||||
airCorrection = scalar, U08, 11, "%", 1.000, 0.000
|
||||
warmupEnrich = scalar, U08, 12, "%", 1.000, 0.000
|
||||
rpm = scalar, U16, 13, "rpm", 1.000, 0.000
|
||||
accelEnrich = scalar, U08, 15, "%", 1.000, 0.000
|
||||
baro = scalar, U08, 16, "%", 1.000, 0.000
|
||||
map = scalar, U16, 4, "kpa", 1.000, 0.000
|
||||
iatRaw = scalar, U08, 6, "°C", 1.000, 0.000
|
||||
coolantRaw = scalar, U08, 7, "°C", 1.000, 0.000
|
||||
batCorrection = scalar, U08, 8, "%", 1.000, 0.000
|
||||
batteryVoltage = scalar, U08, 9, "V", 0.100, 0.000
|
||||
afr = scalar, U08, 10, "O2", 0.100, 0.000
|
||||
egoCorrection = scalar, U08, 11, "%", 1.000, 0.000
|
||||
airCorrection = scalar, U08, 12, "%", 1.000, 0.000
|
||||
warmupEnrich = scalar, U08, 13, "%", 1.000, 0.000
|
||||
rpm = scalar, U16, 14, "rpm", 1.000, 0.000
|
||||
accelEnrich = scalar, U08, 16, "%", 1.000, 0.000
|
||||
gammaEnrich = scalar, U08, 17, "%", 1.000, 0.000
|
||||
veCurr = scalar, U08, 18, "%", 1.000, 0.000
|
||||
afrTarget = scalar, U08, 19, "O2", 0.100, 0.000
|
||||
pulseWidth = scalar, U08, 20, "ms", 0.1, 0.000
|
||||
TPSdot = scalar, U08, 21, "%/s", 10.00, 0.000
|
||||
;advance = scalar, U08, 22, "deg", 1.000, 0.000
|
||||
advance = scalar, S08, 22, "deg", 1.000, 0.000
|
||||
tps = scalar, U08, 23, "%", 1.000, 0.000
|
||||
loopsPerSecond = scalar, U16, 24, "loops", 1.000, 0.000
|
||||
freeRAM = scalar, S16, 26, "bytes", 1.000, 0.000
|
||||
batCorrection = scalar, U08, 28, "%", 1.000, 0.000
|
||||
spark = scalar, U08, 29, "bits", 1.000, 0.000
|
||||
launchHard = bits, U08, 29, [0:0]
|
||||
launchSoft = bits, U08, 29, [1:1]
|
||||
hardLimitOn = bits, U08, 29, [2:2]
|
||||
softlimitOn = bits, U08, 29, [3:3]
|
||||
boostCutSpark = bits, U08, 29, [4:4]
|
||||
error = bits, U08, 29, [5:5]
|
||||
idle = bits, U08, 29, [6:6]
|
||||
sync = bits, U08, 29, [7:7]
|
||||
afr2 = scalar, U08, 30, "O2", 0.100, 0.000
|
||||
freeRAM = scalar, U16, 26, "bytes", 1.000, 0.000
|
||||
boostTarget = scalar, U08, 28, "kPa", 2.000, 0.000
|
||||
boostDuty = scalar, U08, 29, "%", 1.000, 0.000
|
||||
spark = scalar, U08, 30, "bits", 1.000, 0.000
|
||||
launchHard = bits, U08, 30, [0:0]
|
||||
launchSoft = bits, U08, 30, [1:1]
|
||||
hardLimitOn = bits, U08, 30, [2:2]
|
||||
softlimitOn = bits, U08, 30, [3:3]
|
||||
boostCutSpark = bits, U08, 30, [4:4]
|
||||
error = bits, U08, 30, [5:5]
|
||||
idle = bits, U08, 30, [6:6]
|
||||
sync = bits, U08, 30, [7:7]
|
||||
rpmDOT = scalar, S16, 31, "rpm/s", 1.000, 0.000
|
||||
flex = scalar, U08, 33, "%", 1.000, 0.000
|
||||
flexFuelCor = scalar, U08, 34, "%", 1.000, 0.000
|
||||
|
@ -2289,12 +2378,12 @@ cmdtestspk450dc = "E\x03\x0C"
|
|||
errors = scalar, U08, 36, "bits", 1.000, 0.000
|
||||
errorNum = bits, U08, 36, [0:1]
|
||||
currentError = bits, U08, 36, [2:7]
|
||||
boostTarget = scalar, U08, 37, "kPa", 2.000, 0.000
|
||||
boostDuty = scalar, U08, 38, "%", 1.000, 0.000
|
||||
idleLoad = scalar, U08, 39, { bitStringValue( idleUnits , iacAlgorithm ) }, 2.000, 0.000 ; This is a combined variable covering both PWM and stepper IACs. The units used depend on which idle algorithm is chosen
|
||||
testoutputs = scalar, U08, 40, "bits", 1.000, 0.000
|
||||
testenabled = bits, U08, 40, [0:0]
|
||||
testactive = bits, U08, 40, [1:1]
|
||||
idleLoad = scalar, U08, 37, { bitStringValue( idleUnits , iacAlgorithm ) }, 2.000, 0.000 ; This is a combined variable covering both PWM and stepper IACs. The units used depend on which idle algorithm is chosen
|
||||
testoutputs = scalar, U08, 38, "bits", 1.000, 0.000
|
||||
testenabled = bits, U08, 38, [0:0]
|
||||
testactive = bits, U08, 38, [1:1]
|
||||
afr2 = scalar, U08, 39, "O2", 0.100, 0.000
|
||||
baro = scalar, U08, 40, "kpa", 1.000, 0.000
|
||||
canin_gauge0 = scalar, U16, 41, "", 1.000, 0.000
|
||||
canin_gauge1 = scalar, U16, 43, "", 1.000, 0.000
|
||||
canin_gauge2 = scalar, U16, 45, "", 1.000, 0.000
|
||||
|
@ -2311,6 +2400,7 @@ cmdtestspk450dc = "E\x03\x0C"
|
|||
canin_gauge13 = scalar, U16, 67, "", 1.000, 0.000
|
||||
canin_gauge14 = scalar, U16, 69, "", 1.000, 0.000
|
||||
canin_gauge15 = scalar, U16, 71, "", 1.000, 0.000
|
||||
tpsADC = scalar, U08, 73, "ADC",1.000, 0.000
|
||||
|
||||
; Computed output channels. See "megatuneExamples.ini" for all the
|
||||
; pre-defined variables, search for "???" and you'll see them.
|
||||
|
@ -2391,10 +2481,9 @@ cmdtestspk450dc = "E\x03\x0C"
|
|||
entry = rpm, "RPM", int, "%d"
|
||||
entry = map, "MAP", int, "%d"
|
||||
entry = MAPxRPM, "MAPxRPM", int, "%d"
|
||||
entry = tpsADC, "tpsADC", int, "%d"
|
||||
entry = tps, "TPS", int, "%d"
|
||||
entry = afr, "O2", float, "%.3f"
|
||||
entry = lambda, "%", float, "%.3f"
|
||||
entry = lambda, "Lambda", float, "%.3f"
|
||||
entry = iat, "IAT", int, "%d"
|
||||
entry = coolant, "CLT", int, "%d"
|
||||
entry = engine, "Engine", int, "%d"
|
||||
|
@ -2426,7 +2515,9 @@ cmdtestspk450dc = "E\x03\x0C"
|
|||
entry = boostDuty, "Boost Duty", int, "%d", { boostEnabled }
|
||||
entry = boostCutOut , "Boost cut", int, "%d"
|
||||
entry = idleLoad, "IAC value", int, "%d"
|
||||
entry = baro, "Baro Pressure",int, "%d"
|
||||
|
||||
#if CAN_COMMANDS
|
||||
entry = canin_gauge0, "CanIn CH0", int, "%d"
|
||||
entry = canin_gauge1, "CanIn CH1", int, "%d"
|
||||
entry = canin_gauge2, "CanIn CH2", int, "%d"
|
||||
|
@ -2435,6 +2526,7 @@ cmdtestspk450dc = "E\x03\x0C"
|
|||
entry = canin_gauge5, "CanIn CH5", int, "%d"
|
||||
entry = canin_gauge6, "CanIn CH6", int, "%d"
|
||||
entry = canin_gauge7, "CanIn CH7", int, "%d"
|
||||
#endif
|
||||
|
||||
|
||||
[LoggerDefinition]
|
||||
|
|
After Width: | Height: | Size: 101 KiB |
After Width: | Height: | Size: 240 KiB |
After Width: | Height: | Size: 59 KiB |
After Width: | Height: | Size: 16 KiB |
After Width: | Height: | Size: 24 KiB |
|
@ -6,6 +6,61 @@ void boostControl();
|
|||
void vvtControl();
|
||||
void initialiseFan();
|
||||
|
||||
#if defined(CORE_AVR)
|
||||
#define ENABLE_BOOST_TIMER() TIMSK1 |= (1 << OCIE1A)
|
||||
#define DISABLE_BOOST_TIMER() TIMSK1 &= ~(1 << OCIE1A)
|
||||
#define ENABLE_VVT_TIMER() TIMSK1 |= (1 << OCIE1B)
|
||||
#define DISABLE_VVT_TIMER() TIMSK1 &= ~(1 << OCIE1B)
|
||||
|
||||
#define BOOST_TIMER_COMPARE OCR1A
|
||||
#define BOOST_TIMER_COUNTER TCNT1
|
||||
#define VVT_TIMER_COMPARE OCR1B
|
||||
#define VVT_TIMER_COUNTER TCNT1
|
||||
|
||||
#elif defined(CORE_TEENSY)
|
||||
#define ENABLE_BOOST_TIMER() FTM1_C0SC |= FTM_CSC_CHIE
|
||||
#define DISABLE_BOOST_TIMER() FTM1_C0SC &= ~FTM_CSC_CHIE
|
||||
|
||||
#define ENABLE_VVT_TIMER() FTM1_C1SC |= FTM_CSC_CHIE
|
||||
#define DISABLE_VVT_TIMER() FTM1_C1SC &= ~FTM_CSC_CHIE
|
||||
|
||||
#define BOOST_TIMER_COMPARE FTM1_C0V
|
||||
#define BOOST_TIMER_COUNTER FTM1_CNT
|
||||
#define VVT_TIMER_COMPARE FTM1_C1V
|
||||
#define VVT_TIMER_COUNTER FTM1_CNT
|
||||
|
||||
#elif defined(CORE_STM32)
|
||||
#if defined(ARDUINO_ARCH_STM32) // STM32GENERIC core
|
||||
#define ENABLE_BOOST_TIMER() (TIM1)->CCER |= TIM_CCER_CC2E
|
||||
#define DISABLE_BOOST_TIMER() (TIM1)->CCER &= ~TIM_CCER_CC2E
|
||||
|
||||
#define ENABLE_VVT_TIMER() (TIM1)->CCER |= TIM_CCER_CC3E
|
||||
#define DISABLE_VVT_TIMER() (TIM1)->CCER &= ~TIM_CCER_CC3E
|
||||
|
||||
#define BOOST_TIMER_COMPARE (TIM1)->CCR2
|
||||
#define BOOST_TIMER_COUNTER (TIM1)->CNT
|
||||
#define VVT_TIMER_COMPARE (TIM1)->CCR3
|
||||
#define VVT_TIMER_COUNTER (TIM1)->CNT
|
||||
#else //libmaple core aka STM32DUINO
|
||||
#define ENABLE_BOOST_TIMER() (TIMER1->regs).gen->CCER |= TIMER_CCER_CC2E
|
||||
#define DISABLE_BOOST_TIMER() (TIMER1->regs).gen->CCER &= ~TIMER_CCER_CC2E
|
||||
|
||||
#define ENABLE_VVT_TIMER() (TIMER1->regs).gen->CCER |= TIMER_CCER_CC3E
|
||||
#define DISABLE_VVT_TIMER() (TIMER1->regs).gen->CCER &= ~TIMER_CCER_CC3E
|
||||
|
||||
#define BOOST_TIMER_COMPARE (TIMER1->regs).gen->CCR2
|
||||
#define BOOST_TIMER_COUNTER (TIMER1->regs).gen->CNT
|
||||
#define VVT_TIMER_COMPARE (TIMER1->regs).gen->CCR3
|
||||
#define VVT_TIMER_COUNTER (TIMER1->regs).gen->CNT
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#define BOOST_PIN_LOW() *boost_pin_port &= ~(boost_pin_mask)
|
||||
#define BOOST_PIN_HIGH() *boost_pin_port |= (boost_pin_mask)
|
||||
#define VVT_PIN_LOW() *vvt_pin_port &= ~(vvt_pin_mask)
|
||||
#define VVT_PIN_HIGH() *vvt_pin_port |= (vvt_pin_mask)
|
||||
|
||||
|
||||
volatile byte *boost_pin_port;
|
||||
volatile byte boost_pin_mask;
|
||||
volatile byte *vvt_pin_port;
|
||||
|
@ -17,15 +72,15 @@ volatile unsigned int boost_pwm_cur_value;
|
|||
long boost_pwm_target_value;
|
||||
long boost_cl_target_boost;
|
||||
byte boostCounter;
|
||||
//Boost control uses a scaling factor of 100 on the MAP reading and MAP target in order to have a reasonable response time
|
||||
//These are the values that are passed to the PID controller
|
||||
long MAPx100;
|
||||
long boostTargetx100;
|
||||
|
||||
volatile bool vvt_pwm_state;
|
||||
unsigned int vvt_pwm_max_count; //Used for variable PWM frequency
|
||||
volatile unsigned int vvt_pwm_cur_value;
|
||||
long vvt_pwm_target_value;
|
||||
#if defined (CORE_TEENSY) || defined(CORE_STM32)
|
||||
static inline void boostInterrupt();
|
||||
static inline void vvtInterrupt();
|
||||
#endif
|
||||
|
||||
|
||||
#endif
|
||||
|
|
|
@ -3,14 +3,16 @@ Speeduino - Simple engine management for the Arduino Mega 2560 platform
|
|||
Copyright (C) Josh Stewart
|
||||
A full copy of the license may be found in the projects root directory
|
||||
*/
|
||||
integerPID boostPID(&MAPx100, &boost_pwm_target_value, &boostTargetx100, configPage3.boostKP, configPage3.boostKI, configPage3.boostKD, DIRECT); //This is the PID object if that algorithm is used. Needs to be global as it maintains state outside of each function call
|
||||
//Old PID method. Retained incase the new one has issues
|
||||
//integerPID boostPID(&MAPx100, &boost_pwm_target_value, &boostTargetx100, configPage3.boostKP, configPage3.boostKI, configPage3.boostKD, DIRECT);
|
||||
integerPID_ideal boostPID(¤tStatus.MAP, ¤tStatus.boostDuty , ¤tStatus.boostTarget, &configPage11.boostSens, &configPage11.boostIntv, configPage3.boostKP, configPage3.boostKI, configPage3.boostKD, DIRECT); //This is the PID object if that algorithm is used. Needs to be global as it maintains state outside of each function call
|
||||
|
||||
/*
|
||||
Fan control
|
||||
*/
|
||||
void initialiseFan()
|
||||
{
|
||||
if( configPage4.fanInv == 1 ) { fanHIGH = LOW; fanLOW = HIGH; }
|
||||
if( configPage3.fanInv == 1 ) { fanHIGH = LOW; fanLOW = HIGH; }
|
||||
else { fanHIGH = HIGH; fanLOW = LOW; }
|
||||
digitalWrite(pinFan, fanLOW); //Initiallise program with the fan in the off state
|
||||
currentStatus.fanOn = false;
|
||||
|
@ -18,85 +20,107 @@ void initialiseFan()
|
|||
|
||||
void fanControl()
|
||||
{
|
||||
if( configPage4.fanEnable == 1 )
|
||||
if( configPage3.fanEnable == 1 )
|
||||
{
|
||||
int onTemp = (int)configPage4.fanSP - CALIBRATION_TEMPERATURE_OFFSET;
|
||||
int offTemp = onTemp - configPage4.fanHyster;
|
||||
int onTemp = (int)configPage3.fanSP - CALIBRATION_TEMPERATURE_OFFSET;
|
||||
int offTemp = onTemp - configPage3.fanHyster;
|
||||
|
||||
if ( (!currentStatus.fanOn) && (currentStatus.coolant >= onTemp) ) { digitalWrite(pinFan,fanHIGH); currentStatus.fanOn = true; }
|
||||
if ( (currentStatus.fanOn) && (currentStatus.coolant <= offTemp) ) { digitalWrite(pinFan, fanLOW); currentStatus.fanOn = false; }
|
||||
}
|
||||
}
|
||||
|
||||
#if defined(__AVR_ATmega1280__) || defined(__AVR_ATmega2560__)
|
||||
void initialiseAuxPWM()
|
||||
{
|
||||
#if defined(CORE_AVR)
|
||||
TCCR1B = 0x00; //Disbale Timer1 while we set it up
|
||||
TCNT1 = 0; //Reset Timer Count
|
||||
TIFR1 = 0x00; //Timer1 INT Flag Reg: Clear Timer Overflow Flag
|
||||
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
|
||||
#elif defined(CORE_TEENSY)
|
||||
//REALLY NEED TO DO THIS!
|
||||
#elif defined(CORE_STM32)
|
||||
Timer1.attachInterrupt(2, boostInterrupt);
|
||||
Timer1.attachInterrupt(3, vvtInterrupt);
|
||||
Timer1.resume();
|
||||
#endif
|
||||
|
||||
boost_pin_port = portOutputRegister(digitalPinToPort(pinBoost));
|
||||
boost_pin_mask = digitalPinToBitMask(pinBoost);
|
||||
vvt_pin_port = portOutputRegister(digitalPinToPort(pinVVT_1));
|
||||
vvt_pin_mask = digitalPinToBitMask(pinVVT_1);
|
||||
|
||||
#if defined(CORE_STM32) //2uS resolution Min 8Hz, Max 5KHz
|
||||
boost_pwm_max_count = 1000000L / (configPage3.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 / (configPage3.vvtFreq * 2); //Converts the frequency in Hz to the number of ticks (at 16uS) it takes to complete 1 cycle
|
||||
#else
|
||||
boost_pwm_max_count = 1000000L / (16 * configPage3.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 * configPage3.vvtFreq * 2); //Converts the frequency in Hz to the number of ticks (at 16uS) it takes to complete 1 cycle
|
||||
#endif
|
||||
//TIMSK1 |= (1 << OCIE1A); <---- Not required as compare A is turned on when needed by boost control
|
||||
TIMSK1 |= (1 << OCIE1B); //Turn on the B compare unit (ie turn on the interrupt)
|
||||
ENABLE_VVT_TIMER(); //Turn on the B compare unit (ie turn on the interrupt)
|
||||
|
||||
boostPID.SetOutputLimits(percentage(configPage1.boostMinDuty, boost_pwm_max_count) , percentage(configPage1.boostMaxDuty, boost_pwm_max_count));
|
||||
boostPID.SetTunings(configPage3.boostKP, configPage3.boostKI, configPage3.boostKD);
|
||||
boostPID.SetMode(AUTOMATIC); //Turn PID on
|
||||
boostPID.SetOutputLimits(configPage1.boostMinDuty, configPage1.boostMaxDuty);
|
||||
if(configPage3.boostMode == BOOST_MODE_SIMPLE) { boostPID.SetTunings(100, 100, 100); }
|
||||
else { boostPID.SetTunings(configPage3.boostKP, configPage3.boostKI, configPage3.boostKD); }
|
||||
|
||||
currentStatus.boostDuty = 0;
|
||||
boostCounter = 0;
|
||||
}
|
||||
|
||||
#define BOOST_HYSTER 40
|
||||
void boostControl()
|
||||
{
|
||||
if( configPage3.boostEnabled==1 )
|
||||
{
|
||||
if(currentStatus.MAP >= 100)
|
||||
if( (boostCounter & 7) == 1) { currentStatus.boostTarget = get3DTableValue(&boostTable, currentStatus.TPS, currentStatus.RPM) * 2; } //Boost target table is in kpa and divided by 2
|
||||
if(currentStatus.MAP >= (currentStatus.boostTarget - BOOST_HYSTER) )
|
||||
{
|
||||
MAPx100 = currentStatus.MAP * 100;
|
||||
|
||||
boost_cl_target_boost = get3DTableValue(&boostTable, currentStatus.TPS, currentStatus.RPM) * 2; //Boost target table is in kpa and divided by 2
|
||||
//If flex fuel is enabled, there can be an adder to the boost target based on ethanol content
|
||||
if( configPage1.flexEnabled == 1 )
|
||||
{
|
||||
int16_t boostAdder = (((int16_t)configPage1.flexBoostHigh - (int16_t)configPage1.flexBoostLow) * currentStatus.ethanolPct) / 100;
|
||||
boostAdder = boostAdder + configPage1.flexBoostLow; //Required in case flexBoostLow is less than 0
|
||||
boost_cl_target_boost = boost_cl_target_boost + boostAdder;
|
||||
currentStatus.boostTarget += boostAdder;
|
||||
}
|
||||
|
||||
boostTargetx100 = boost_cl_target_boost * 100;
|
||||
currentStatus.boostTarget = boost_cl_target_boost >> 1; //Boost target is sent as a byte value to TS and so is divided by 2
|
||||
if(currentStatus.boostTarget > 0)
|
||||
{
|
||||
if( (boostCounter & 31) == 1) { boostPID.SetTunings(configPage3.boostKP, configPage3.boostKI, configPage3.boostKD); } //This only needs to be run very infrequently, once every 32 calls to boostControl(). This is approx. once per second
|
||||
//This only needs to be run very infrequently, once every 16 calls to boostControl(). This is approx. once per second
|
||||
if( (boostCounter & 15) == 1)
|
||||
{
|
||||
boostPID.SetOutputLimits(configPage1.boostMinDuty, configPage1.boostMaxDuty);
|
||||
|
||||
if(configPage3.boostMode == BOOST_MODE_SIMPLE) { boostPID.SetTunings(100, 100, 100); }
|
||||
else { boostPID.SetTunings(configPage3.boostKP, configPage3.boostKI, configPage3.boostKD); }
|
||||
}
|
||||
|
||||
bool PIDcomputed = boostPID.Compute(); //Compute() returns false if the required interval has not yet passed.
|
||||
if(currentStatus.boostDuty == 0) { DISABLE_BOOST_TIMER(); BOOST_PIN_LOW(); } //If boost duty is 0, shut everything down
|
||||
else
|
||||
{
|
||||
if(PIDcomputed == true)
|
||||
{
|
||||
boost_pwm_target_value = ((unsigned long)(currentStatus.boostDuty) * boost_pwm_max_count) / 10000; //Convert boost duty (Which is a % multipled by 100) to a pwm count
|
||||
ENABLE_BOOST_TIMER(); //Turn on the compare unit (ie turn on the interrupt) if boost duty >0
|
||||
}
|
||||
}
|
||||
|
||||
boostPID.Compute();
|
||||
currentStatus.boostDuty = (unsigned long)(boost_pwm_target_value * 100UL) / boost_pwm_max_count;
|
||||
TIMSK1 |= (1 << OCIE1A); //Turn on the compare unit (ie turn on the interrupt)
|
||||
}
|
||||
else
|
||||
{
|
||||
//If boost target is 0, turn everything off
|
||||
TIMSK1 &= ~(1 << OCIE1A); //Turn off timer
|
||||
digitalWrite(pinBoost, LOW);
|
||||
boostDisable();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
//Boost control does nothing if kPa below 100
|
||||
TIMSK1 &= ~(1 << OCIE1A); //Turn off timer
|
||||
digitalWrite(pinBoost, LOW); //Make sure solenoid is off (0% duty)
|
||||
//Boost control does nothing if kPa below the hyster point
|
||||
boostDisable();
|
||||
}
|
||||
}
|
||||
else { TIMSK1 &= ~(1 << OCIE1A); } // Disable timer channel
|
||||
else { DISABLE_BOOST_TIMER(); } // Disable timer channel
|
||||
|
||||
boostCounter++;
|
||||
}
|
||||
|
@ -106,53 +130,75 @@ void vvtControl()
|
|||
if( configPage3.vvtEnabled == 1 )
|
||||
{
|
||||
byte vvtDuty = get3DTableValue(&vvtTable, currentStatus.TPS, currentStatus.RPM);
|
||||
vvt_pwm_target_value = percentage(vvtDuty, vvt_pwm_max_count);
|
||||
if(vvtDuty == 0)
|
||||
{
|
||||
//Make sure solenoid is off (0% duty)
|
||||
VVT_PIN_LOW();
|
||||
DISABLE_VVT_TIMER();
|
||||
}
|
||||
#if defined(__AVR_ATmega1280__) || defined(__AVR_ATmega2560__)
|
||||
else { TIMSK1 &= ~(1 << OCIE1B); } // Disable timer channel
|
||||
#endif
|
||||
else if (vvtDuty >= 100)
|
||||
{
|
||||
//Make sure solenoid is on (100% duty)
|
||||
VVT_PIN_HIGH();
|
||||
DISABLE_VVT_TIMER();
|
||||
}
|
||||
else
|
||||
{
|
||||
vvt_pwm_target_value = percentage(vvtDuty, vvt_pwm_max_count);
|
||||
ENABLE_VVT_TIMER();
|
||||
}
|
||||
}
|
||||
else { DISABLE_VVT_TIMER(); } // Disable timer channel
|
||||
}
|
||||
|
||||
void boostDisable()
|
||||
{
|
||||
boostPID.Initialize(); //This resets the ITerm value to prevent rubber banding
|
||||
currentStatus.boostDuty = 0;
|
||||
DISABLE_BOOST_TIMER(); //Turn off timer
|
||||
BOOST_PIN_LOW(); //Make sure solenoid is off (0% duty)
|
||||
}
|
||||
|
||||
//The interrupt to control the Boost PWM
|
||||
ISR(TIMER1_COMPA_vect)
|
||||
#if defined(CORE_AVR)
|
||||
ISR(TIMER1_COMPA_vect)
|
||||
#elif defined (CORE_TEENSY) || defined(CORE_STM32)
|
||||
static inline void boostInterrupt() //Most ARM chips can simply call a function
|
||||
#endif
|
||||
{
|
||||
if (boost_pwm_state)
|
||||
{
|
||||
*boost_pin_port &= ~(boost_pin_mask); // Switch pin to low
|
||||
OCR1A = TCNT1 + (boost_pwm_max_count - boost_pwm_cur_value);
|
||||
BOOST_PIN_LOW(); // Switch pin to low
|
||||
BOOST_TIMER_COMPARE = BOOST_TIMER_COUNTER + (boost_pwm_max_count - boost_pwm_cur_value);
|
||||
boost_pwm_state = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
*boost_pin_port |= (boost_pin_mask); // Switch pin high
|
||||
OCR1A = TCNT1 + boost_pwm_target_value;
|
||||
BOOST_PIN_HIGH(); // Switch pin high
|
||||
BOOST_TIMER_COMPARE = BOOST_TIMER_COUNTER + boost_pwm_target_value;
|
||||
boost_pwm_cur_value = boost_pwm_target_value;
|
||||
boost_pwm_state = true;
|
||||
}
|
||||
}
|
||||
|
||||
//The interrupt to control the VVT PWM
|
||||
ISR(TIMER1_COMPB_vect)
|
||||
#if defined(CORE_AVR)
|
||||
ISR(TIMER1_COMPB_vect)
|
||||
#elif defined (CORE_TEENSY) || defined(CORE_STM32)
|
||||
static inline void vvtInterrupt() //Most ARM chips can simply call a function
|
||||
#endif
|
||||
{
|
||||
if (vvt_pwm_state)
|
||||
{
|
||||
*vvt_pin_port &= ~(vvt_pin_mask); // Switch pin to low
|
||||
OCR1B = TCNT1 + (vvt_pwm_max_count - vvt_pwm_cur_value);
|
||||
VVT_PIN_LOW(); // Switch pin to low
|
||||
VVT_TIMER_COMPARE = VVT_TIMER_COUNTER + (vvt_pwm_max_count - vvt_pwm_cur_value);
|
||||
vvt_pwm_state = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
*vvt_pin_port |= (vvt_pin_mask); // Switch pin high
|
||||
OCR1B = TCNT1 + vvt_pwm_target_value;
|
||||
VVT_PIN_HIGH(); // Switch pin high
|
||||
VVT_TIMER_COMPARE = VVT_TIMER_COUNTER + vvt_pwm_target_value;
|
||||
vvt_pwm_cur_value = vvt_pwm_target_value;
|
||||
vvt_pwm_state = true;
|
||||
}
|
||||
}
|
||||
|
||||
#elif defined (CORE_TEENSY) || defined(CORE_STM32)
|
||||
//YET TO BE IMPLEMENTED ON TEENSY
|
||||
void initialiseAuxPWM() { }
|
||||
void boostControl() { }
|
||||
void vvtControl() { }
|
||||
|
||||
#endif
|
||||
|
|
|
@ -15,7 +15,11 @@ uint8_t Glow, Ghigh;
|
|||
#if defined(__AVR_ATmega1280__) || defined(__AVR_ATmega2560__)
|
||||
HardwareSerial &CANSerial = Serial3;
|
||||
#elif defined(CORE_STM32)
|
||||
#if defined(ARDUINO_ARCH_STM32) // STM32GENERIC core
|
||||
SerialUART &CANSerial = Serial2;
|
||||
#else //libmaple core aka STM32DUINO
|
||||
HardwareSerial &CANSerial = Serial2;
|
||||
#endif
|
||||
#elif defined(CORE_TEENSY)
|
||||
HardwareSerial &CANSerial = Serial2;
|
||||
#endif
|
||||
|
|
|
@ -7,18 +7,21 @@
|
|||
#define ignSetPage 4//Config Page 2
|
||||
#define afrMapPage 5
|
||||
#define afrSetPage 6//Config Page 3
|
||||
#define iacPage 7//Config Page 4
|
||||
#define boostvvtPage 8
|
||||
#define seqFuelPage 9
|
||||
#define canbusPage 10//Config Page 10
|
||||
#define boostvvtPage 7
|
||||
#define seqFuelPage 8
|
||||
#define canbusPage 9//Config Page 9
|
||||
#define warmupPage 10 //Config Page 10
|
||||
|
||||
#define packetSize 73
|
||||
#define packetSize 74
|
||||
|
||||
byte currentPage = 1;//Not the same as the speeduino config page numbers
|
||||
bool isMap = true;
|
||||
unsigned long requestCount = 0; //The number of times the A command has been issued
|
||||
byte currentCommand;
|
||||
bool cmdPending = false;
|
||||
bool chunkPending = false;
|
||||
uint16_t chunkComplete = 0;
|
||||
int16_t chunkSize = 0;
|
||||
byte cmdGroup = 0;
|
||||
byte cmdValue = 0;
|
||||
int cmdCombined = 0; //the cmdgroup as high byte and cmdvalue as low byte
|
||||
|
|
|
@ -15,7 +15,9 @@ A detailed description of each call can be found at: http://www.msextra.com/doc/
|
|||
|
||||
void command()
|
||||
{
|
||||
if (!cmdPending) { currentCommand = Serial.read(); }
|
||||
int valueOffset; //cannot use offset as a variable name, it is a reserved word for several teensy libraries
|
||||
|
||||
if (cmdPending == false) { currentCommand = Serial.read(); }
|
||||
|
||||
switch (currentCommand)
|
||||
{
|
||||
|
@ -26,13 +28,31 @@ void command()
|
|||
|
||||
|
||||
case 'B': // Burn current values to eeprom
|
||||
writeConfig();
|
||||
writeAllConfig();
|
||||
break;
|
||||
|
||||
case 'b': // New EEPROM burn command to only burn a single page at a time
|
||||
cmdPending = true;
|
||||
|
||||
if (Serial.available() >= 2)
|
||||
{
|
||||
Serial.read(); //Ignore the first table value, it's always 0
|
||||
writeConfig(Serial.read());
|
||||
cmdPending = false;
|
||||
}
|
||||
break;
|
||||
|
||||
case 'C': // test communications. This is used by Tunerstudio to see whether there is an ECU on a given serial port
|
||||
testComm();
|
||||
break;
|
||||
|
||||
case 'c': //Send the current loops/sec value
|
||||
Serial.write(lowByte(currentStatus.loopsPerSecond));
|
||||
Serial.write(highByte(currentStatus.loopsPerSecond));
|
||||
break;
|
||||
|
||||
//The following can be used to show the amount of free memory
|
||||
|
||||
case 'E': // receive command button commands
|
||||
cmdPending = true;
|
||||
|
||||
|
@ -47,10 +67,20 @@ void command()
|
|||
}
|
||||
break;
|
||||
|
||||
case 'F': // send serial protocol version
|
||||
Serial.print("001");
|
||||
break;
|
||||
|
||||
case 'L': // List the contents of current page in human readable form
|
||||
sendPage(true);
|
||||
break;
|
||||
|
||||
case 'm': //Send the current free memory
|
||||
currentStatus.freeRAM = freeRam();
|
||||
Serial.write(lowByte(currentStatus.freeRAM));
|
||||
Serial.write(highByte(currentStatus.freeRAM));
|
||||
break;
|
||||
|
||||
case 'N': // Displays a new line. Like pushing enter in a text editor
|
||||
Serial.println();
|
||||
break;
|
||||
|
@ -62,30 +92,99 @@ void command()
|
|||
if (Serial.available() > 0)
|
||||
{
|
||||
currentPage = Serial.read();
|
||||
if (currentPage >= '0') {//This converts the ascii number char into binary
|
||||
currentPage -= '0';
|
||||
//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'; }
|
||||
// Detecting if the current page is a table/map
|
||||
if ( (currentPage == veMapPage) || (currentPage == ignMapPage) || (currentPage == afrMapPage) ) { isMap = true; }
|
||||
else { isMap = false; }
|
||||
cmdPending = false;
|
||||
}
|
||||
if ( (currentPage == veMapPage) || (currentPage == ignMapPage) || (currentPage == afrMapPage) ) { // Detecting if the current page is a table/map
|
||||
isMap = true;
|
||||
break;
|
||||
|
||||
/*
|
||||
* New method for sending page values
|
||||
*/
|
||||
case 'p':
|
||||
cmdPending = true;
|
||||
|
||||
//6 bytes required:
|
||||
//2 - Page identifier
|
||||
//2 - offset
|
||||
//2 - Length
|
||||
if(Serial.available() >= 6)
|
||||
{
|
||||
byte offset1, offset2, length1, length2;
|
||||
int length;
|
||||
byte tempPage;
|
||||
|
||||
Serial.read(); // First byte of the page identifier can be ignored. It's always 0
|
||||
tempPage = Serial.read();
|
||||
//currentPage = 1;
|
||||
offset1 = Serial.read();
|
||||
offset2 = Serial.read();
|
||||
valueOffset = word(offset2, offset1);
|
||||
length1 = Serial.read();
|
||||
length2 = Serial.read();
|
||||
length = word(length2, length1);
|
||||
for(int i = 0; i < length; i++)
|
||||
{
|
||||
Serial.write( getPageValue(tempPage, valueOffset + i) );
|
||||
}
|
||||
else {
|
||||
isMap = false;
|
||||
|
||||
cmdPending = false;
|
||||
}
|
||||
break;
|
||||
|
||||
case 'Q': // send code version
|
||||
Serial.print("speeduino 201709-dev");
|
||||
break;
|
||||
|
||||
case 'r': //New format for the optimised OutputChannels
|
||||
cmdPending = true;
|
||||
byte cmd;
|
||||
if (Serial.available() >= 6)
|
||||
{
|
||||
tsCanId = Serial.read(); //Read the $tsCanId
|
||||
cmd = Serial.read(); // read the command
|
||||
|
||||
uint16_t offset, length;
|
||||
if(cmd == 0x30) //Send output channels command 0x30 is 48dec
|
||||
{
|
||||
byte tmp;
|
||||
tmp = Serial.read();
|
||||
offset = word(Serial.read(), tmp);
|
||||
tmp = Serial.read();
|
||||
length = word(Serial.read(), tmp);
|
||||
sendValues(offset, length,cmd, 0);
|
||||
}
|
||||
else
|
||||
{
|
||||
//No other r/ commands should be called
|
||||
}
|
||||
cmdPending = false;
|
||||
}
|
||||
break;
|
||||
|
||||
case 'F': // send serial protocol version
|
||||
Serial.print("001");
|
||||
break;
|
||||
|
||||
case 'S': // send code version
|
||||
Serial.print("Speeduino 2017.06-dev");
|
||||
Serial.print("Speeduino 2017.09-dev");
|
||||
currentStatus.secl = 0; //This is required in TS3 due to its stricter timings
|
||||
break;
|
||||
|
||||
case 'Q': // send code version
|
||||
Serial.print("speeduino 201706-dev");
|
||||
case 'T': //Send 256 tooth log entries to Tuner Studios tooth logger
|
||||
sendToothLog(false); //Sends tooth log values as ints
|
||||
break;
|
||||
|
||||
case 't': // receive new Calibration info. Command structure: "t", <tble_idx> <data array>. This is an MS2/Extra command, NOT part of MS1 spec
|
||||
byte tableID;
|
||||
//byte canID;
|
||||
|
||||
//The first 2 bytes sent represent the canID and tableID
|
||||
while (Serial.available() == 0) { }
|
||||
tableID = Serial.read(); //Not currently used for anything
|
||||
|
||||
receiveCalibration(tableID); //Receive new values and store in memory
|
||||
writeCalibration(); //Store received values in EEPROM
|
||||
|
||||
break;
|
||||
|
||||
case 'V': // send VE table and constants in binary
|
||||
|
@ -95,8 +194,6 @@ void command()
|
|||
case 'W': // receive new VE obr constant at 'W'+<offset>+<newbyte>
|
||||
cmdPending = true;
|
||||
|
||||
int valueOffset; //cannot use offset as a variable name, it is a reserved word for several teensy libraries
|
||||
|
||||
if (isMap)
|
||||
{
|
||||
if(Serial.available() >= 3) // 1 additional byte is required on the MAP pages which are larger than 255 bytes
|
||||
|
@ -121,17 +218,40 @@ void command()
|
|||
|
||||
break;
|
||||
|
||||
case 't': // receive new Calibration info. Command structure: "t", <tble_idx> <data array>. This is an MS2/Extra command, NOT part of MS1 spec
|
||||
byte tableID;
|
||||
//byte canID;
|
||||
case 'w':
|
||||
cmdPending = true;
|
||||
|
||||
//The first 2 bytes sent represent the canID and tableID
|
||||
while (Serial.available() == 0) { }
|
||||
tableID = Serial.read(); //Not currently used for anything
|
||||
if(chunkPending == false)
|
||||
{
|
||||
//This means it's a new request
|
||||
//7 bytes required:
|
||||
//2 - Page identifier
|
||||
//2 - offset
|
||||
//2 - Length (Should always be 1 until chunk write is setup)
|
||||
//1 - New value
|
||||
if(Serial.available() >= 7)
|
||||
{
|
||||
byte offset1, offset2, length1, length2;
|
||||
|
||||
receiveCalibration(tableID); //Receive new values and store in memory
|
||||
writeCalibration(); //Store received values in EEPROM
|
||||
Serial.read(); // First byte of the page identifier can be ignored. It's always 0
|
||||
currentPage = Serial.read();
|
||||
//currentPage = 1;
|
||||
offset1 = Serial.read();
|
||||
offset2 = Serial.read();
|
||||
valueOffset = word(offset2, offset1);
|
||||
length1 = Serial.read(); // Length to be written (Should always be 1)
|
||||
length2 = Serial.read(); // Length to be written (Should always be 1)
|
||||
chunkSize = word(length2, length1);
|
||||
|
||||
//chunkPending = true;
|
||||
for(int i = 0; i < chunkSize; i++)
|
||||
{
|
||||
while(Serial.available() == 0) { } //For chunk writes, we can safely loop here
|
||||
receiveValue( (valueOffset + i), Serial.read());
|
||||
}
|
||||
cmdPending = false;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case 'Z': //Totally non-standard testing function. Will be removed once calibration testing is completed. This function takes 1.5kb of program space! :S
|
||||
|
@ -166,41 +286,10 @@ void command()
|
|||
Serial.flush();
|
||||
break;
|
||||
|
||||
case 'T': //Send 256 tooth log entries to Tuner Studios tooth logger
|
||||
sendToothLog(false); //Sends tooth log values as ints
|
||||
break;
|
||||
|
||||
case 'z': //Send 256 tooth log entries to a terminal emulator
|
||||
sendToothLog(true); //Sends tooth log values as chars
|
||||
break;
|
||||
|
||||
case 'r': //New format for the optimised OutputChannels
|
||||
cmdPending = true;
|
||||
byte cmd;
|
||||
if (Serial.available() >= 6)
|
||||
{
|
||||
tsCanId = Serial.read(); //Read the $tsCanId
|
||||
cmd = Serial.read(); // read the command
|
||||
|
||||
uint16_t offset, length;
|
||||
if(cmd == 0x30) //Send output channels command 0x30 is 48dec
|
||||
{
|
||||
byte tmp;
|
||||
tmp = Serial.read();
|
||||
offset = word(Serial.read(), tmp);
|
||||
tmp = Serial.read();
|
||||
length = word(Serial.read(), tmp);
|
||||
sendValues(offset, length,cmd, 0);
|
||||
}
|
||||
else
|
||||
{
|
||||
//No other r/ commands should be called
|
||||
}
|
||||
cmdPending = false;
|
||||
}
|
||||
break;
|
||||
|
||||
|
||||
case '?':
|
||||
Serial.println
|
||||
(F(
|
||||
|
@ -275,19 +364,19 @@ void sendValues(uint16_t offset, uint16_t packetLength, byte cmd, byte portNum)
|
|||
fullStatus[1] = currentStatus.squirt; //Squirt Bitfield
|
||||
fullStatus[2] = currentStatus.engine; //Engine Status Bitfield
|
||||
fullStatus[3] = (byte)(divu100(currentStatus.dwell)); //Dwell in ms * 10
|
||||
fullStatus[4] = (byte)(currentStatus.MAP >> 1); //map value is divided by 2
|
||||
fullStatus[5] = (byte)(currentStatus.IAT + CALIBRATION_TEMPERATURE_OFFSET); //mat
|
||||
fullStatus[6] = (byte)(currentStatus.coolant + CALIBRATION_TEMPERATURE_OFFSET); //Coolant ADC
|
||||
fullStatus[7] = currentStatus.tpsADC; //TPS (Raw 0-255)
|
||||
fullStatus[8] = currentStatus.battery10; //battery voltage
|
||||
fullStatus[9] = currentStatus.O2; //O2
|
||||
fullStatus[10] = currentStatus.egoCorrection; //Exhaust gas correction (%)
|
||||
fullStatus[11] = currentStatus.iatCorrection; //Air temperature Correction (%)
|
||||
fullStatus[12] = currentStatus.wueCorrection; //Warmup enrichment (%)
|
||||
fullStatus[13] = lowByte(currentStatus.RPM); //rpm HB
|
||||
fullStatus[14] = highByte(currentStatus.RPM); //rpm LB
|
||||
fullStatus[15] = currentStatus.TAEamount; //acceleration enrichment (%)
|
||||
fullStatus[16] = currentStatus.baro; //Barometer value
|
||||
fullStatus[4] = lowByte(currentStatus.MAP); //2 bytes for MAP
|
||||
fullStatus[5] = highByte(currentStatus.MAP);
|
||||
fullStatus[6] = (byte)(currentStatus.IAT + CALIBRATION_TEMPERATURE_OFFSET); //mat
|
||||
fullStatus[7] = (byte)(currentStatus.coolant + CALIBRATION_TEMPERATURE_OFFSET); //Coolant ADC
|
||||
fullStatus[8] = currentStatus.batCorrection; //Battery voltage correction (%)
|
||||
fullStatus[9] = currentStatus.battery10; //battery voltage
|
||||
fullStatus[10] = currentStatus.O2; //O2
|
||||
fullStatus[11] = currentStatus.egoCorrection; //Exhaust gas correction (%)
|
||||
fullStatus[12] = currentStatus.iatCorrection; //Air temperature Correction (%)
|
||||
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[17] = currentStatus.corrections; //Total GammaE (%)
|
||||
fullStatus[18] = currentStatus.VE; //Current VE 1 (%)
|
||||
fullStatus[19] = currentStatus.afrTarget;
|
||||
|
@ -304,9 +393,9 @@ void sendValues(uint16_t offset, uint16_t packetLength, byte cmd, byte portNum)
|
|||
fullStatus[26] = lowByte(currentStatus.freeRAM); //(byte)((currentStatus.loopsPerSecond >> 8) & 0xFF);
|
||||
fullStatus[27] = highByte(currentStatus.freeRAM);
|
||||
|
||||
fullStatus[28] = currentStatus.batCorrection; //Battery voltage correction (%)
|
||||
fullStatus[29] = currentStatus.spark; //Spark related bitfield
|
||||
fullStatus[30] = currentStatus.O2_2; //O2
|
||||
fullStatus[28] = (byte)(currentStatus.boostTarget >> 1); //Divide boost target by 2 to fit in a byte
|
||||
fullStatus[29] = (byte)(currentStatus.boostDuty / 100);
|
||||
fullStatus[30] = currentStatus.spark; //Spark related bitfield
|
||||
|
||||
//rpmDOT must be sent as a signed integer
|
||||
fullStatus[31] = lowByte(currentStatus.rpmDOT);
|
||||
|
@ -316,10 +405,13 @@ void sendValues(uint16_t offset, uint16_t packetLength, byte cmd, byte portNum)
|
|||
fullStatus[34] = currentStatus.flexCorrection; //Flex fuel correction (% above or below 100)
|
||||
fullStatus[35] = currentStatus.flexIgnCorrection; //Ignition correction (Increased degrees of advance) for flex fuel
|
||||
fullStatus[36] = getNextError();
|
||||
fullStatus[37] = currentStatus.boostTarget;
|
||||
fullStatus[38] = currentStatus.boostDuty;
|
||||
fullStatus[39] = currentStatus.idleLoad;
|
||||
fullStatus[40] = currentStatus.testOutputs;
|
||||
|
||||
fullStatus[37] = currentStatus.idleLoad;
|
||||
fullStatus[38] = currentStatus.testOutputs;
|
||||
|
||||
fullStatus[39] = currentStatus.O2_2; //O2
|
||||
fullStatus[40] = currentStatus.baro; //Barometer value
|
||||
|
||||
fullStatus[41] = lowByte(currentStatus.canin[0]);
|
||||
fullStatus[42] = highByte(currentStatus.canin[0]);
|
||||
fullStatus[43] = lowByte(currentStatus.canin[1]);
|
||||
|
@ -353,6 +445,8 @@ void sendValues(uint16_t offset, uint16_t packetLength, byte cmd, byte portNum)
|
|||
fullStatus[71] = lowByte(currentStatus.canin[15]);
|
||||
fullStatus[72] = highByte(currentStatus.canin[15]);
|
||||
|
||||
fullStatus[73] = currentStatus.tpsADC;
|
||||
|
||||
for(byte x=0; x<packetLength; x++)
|
||||
{
|
||||
if (portNum == 0) { Serial.write(fullStatus[offset+x]); }
|
||||
|
@ -365,6 +459,7 @@ void receiveValue(int valueOffset, byte newValue)
|
|||
{
|
||||
|
||||
void* pnt_configPage;//This only stores the address of the value that it's pointing to and not the max size
|
||||
int tempOffset;
|
||||
|
||||
switch (currentPage)
|
||||
{
|
||||
|
@ -381,19 +476,23 @@ void receiveValue(int valueOffset, byte newValue)
|
|||
//X Axis
|
||||
fuelTable.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
|
||||
else if(valueOffset < 288)
|
||||
{
|
||||
//Y Axis
|
||||
int 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
|
||||
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
|
||||
fuelTable.axisY[tempOffset] = (int)(newValue) * TABLE_LOAD_MULTIPLIER;
|
||||
}
|
||||
else
|
||||
{
|
||||
//This should never happen. It means there's an invalid offset value coming through
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case veSetPage:
|
||||
pnt_configPage = &configPage1; //Setup a pointer to the relevant config page
|
||||
//For some reason, TunerStudio is sending offsets greater than the maximum page size. I'm not sure if it's their bug or mine, but the fix is to only update the config page if the offset is less than the maximum size
|
||||
if (valueOffset < page_size)
|
||||
if (valueOffset < npage_size[veSetPage])
|
||||
{
|
||||
*((byte *)pnt_configPage + (byte)valueOffset) = newValue;
|
||||
}
|
||||
|
@ -412,10 +511,10 @@ void receiveValue(int valueOffset, byte newValue)
|
|||
//X Axis
|
||||
ignitionTable.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
|
||||
}
|
||||
else
|
||||
else if(valueOffset < 288)
|
||||
{
|
||||
//Y Axis
|
||||
int tempOffset = 15 - (valueOffset - 272); //Need to do a translation to flip the order
|
||||
tempOffset = 15 - (valueOffset - 272); //Need to do a translation to flip the order
|
||||
ignitionTable.axisY[tempOffset] = (int)(newValue) * TABLE_LOAD_MULTIPLIER;
|
||||
}
|
||||
}
|
||||
|
@ -424,7 +523,7 @@ void receiveValue(int valueOffset, byte newValue)
|
|||
case ignSetPage:
|
||||
pnt_configPage = &configPage2;
|
||||
//For some reason, TunerStudio is sending offsets greater than the maximum page size. I'm not sure if it's their bug or mine, but the fix is to only update the config page if the offset is less than the maximum size
|
||||
if (valueOffset < page_size)
|
||||
if (valueOffset < npage_size[ignSetPage])
|
||||
{
|
||||
*((byte *)pnt_configPage + (byte)valueOffset) = newValue;
|
||||
}
|
||||
|
@ -446,7 +545,7 @@ void receiveValue(int valueOffset, byte newValue)
|
|||
else
|
||||
{
|
||||
//Y Axis
|
||||
int tempOffset = 15 - (valueOffset - 272); //Need to do a translation to flip the order
|
||||
tempOffset = 15 - (valueOffset - 272); //Need to do a translation to flip the order
|
||||
afrTable.axisY[tempOffset] = int(newValue) * TABLE_LOAD_MULTIPLIER;
|
||||
|
||||
}
|
||||
|
@ -456,16 +555,7 @@ void receiveValue(int valueOffset, byte newValue)
|
|||
case afrSetPage:
|
||||
pnt_configPage = &configPage3;
|
||||
//For some reason, TunerStudio is sending offsets greater than the maximum page size. I'm not sure if it's their bug or mine, but the fix is to only update the config page if the offset is less than the maximum size
|
||||
if (valueOffset < page_size)
|
||||
{
|
||||
*((byte *)pnt_configPage + (byte)valueOffset) = newValue;
|
||||
}
|
||||
break;
|
||||
|
||||
case iacPage: //Idle Air Control settings page (Page 4)
|
||||
pnt_configPage = &configPage4;
|
||||
//For some reason, TunerStudio is sending offsets greater than the maximum page size. I'm not sure if it's their bug or mine, but the fix is to only update the config page if the offset is less than the maximum size
|
||||
if (valueOffset < page_size)
|
||||
if (valueOffset < npage_size[afrSetPage])
|
||||
{
|
||||
*((byte *)pnt_configPage + (byte)valueOffset) = newValue;
|
||||
}
|
||||
|
@ -486,24 +576,22 @@ void receiveValue(int valueOffset, byte newValue)
|
|||
}
|
||||
else if (valueOffset < 144) //New value is part of the vvt map
|
||||
{
|
||||
int tempOffset = valueOffset - 80;
|
||||
tempOffset = valueOffset - 80;
|
||||
vvtTable.values[7 - (tempOffset / 8)][tempOffset % 8] = newValue;
|
||||
}
|
||||
else if (valueOffset < 152) //New value is on the X (RPM) axis of the vvt table
|
||||
{
|
||||
int tempOffset = valueOffset - 144;
|
||||
tempOffset = valueOffset - 144;
|
||||
vvtTable.axisX[tempOffset] = int(newValue) * TABLE_RPM_MULTIPLIER; //The RPM values sent by TunerStudio are divided by 100, need to multiply it back by 100 to make it correct (TABLE_RPM_MULTIPLIER)
|
||||
}
|
||||
else //New value is on the Y (Load) axis of the vvt table
|
||||
else if (valueOffset < 161) //New value is on the Y (Load) axis of the vvt table
|
||||
{
|
||||
int tempOffset = valueOffset - 152;
|
||||
tempOffset = valueOffset - 152;
|
||||
vvtTable.axisY[(7 - tempOffset)] = int(newValue); //TABLE_LOAD_MULTIPLIER is NOT used for vvt as it is TPS based (0-100)
|
||||
}
|
||||
break;
|
||||
|
||||
case seqFuelPage:
|
||||
{
|
||||
int tempOffset;
|
||||
if (valueOffset < 36) { trim1Table.values[5 - (valueOffset / 6)][valueOffset % 6] = newValue; } //Trim1 values
|
||||
else if (valueOffset < 42) { trim1Table.axisX[(valueOffset - 36)] = int(newValue) * TABLE_RPM_MULTIPLIER; } //New value is on the X (RPM) axis of the trim1 table. The RPM values sent by TunerStudio are divided by 100, need to multiply it back by 100 to make it correct (TABLE_RPM_MULTIPLIER)
|
||||
else if (valueOffset < 48) { trim1Table.axisY[(5 - (valueOffset - 42))] = int(newValue) * TABLE_LOAD_MULTIPLIER; } //New value is on the Y (TPS) axis of the boost table
|
||||
|
@ -519,7 +607,7 @@ void receiveValue(int valueOffset, byte newValue)
|
|||
else if (valueOffset < 180) { tempOffset = valueOffset - 144; trim4Table.values[5 - (tempOffset / 6)][tempOffset % 6] = newValue; } //New value is part of the trim2 map
|
||||
else if (valueOffset < 186) { tempOffset = valueOffset - 180; trim4Table.axisX[tempOffset] = int(newValue) * TABLE_RPM_MULTIPLIER; } //New value is on the X (RPM) axis of the table. The RPM values sent by TunerStudio are divided by 100, need to multiply it back by 100 to make it correct (TABLE_RPM_MULTIPLIER)
|
||||
else if (valueOffset < 192) { tempOffset = valueOffset - 186; trim4Table.axisY[(5 - tempOffset)] = int(newValue) * TABLE_LOAD_MULTIPLIER; } //New value is on the Y (Load) axis of the table
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
case canbusPage:
|
||||
|
@ -531,9 +619,19 @@ void receiveValue(int valueOffset, byte newValue)
|
|||
}
|
||||
break;
|
||||
|
||||
case warmupPage:
|
||||
pnt_configPage = &configPage11;
|
||||
//For some reason, TunerStudio is sending offsets greater than the maximum page size. I'm not sure if it's their bug or mine, but the fix is to only update the config page if the offset is less than the maximum size
|
||||
if (valueOffset < npage_size[currentPage])
|
||||
{
|
||||
*((byte *)pnt_configPage + (byte)valueOffset) = newValue;
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
//if(Serial.available() > 16) { command(); }
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -544,22 +642,19 @@ useChar - If true, all values are send as chars, this is for the serial command
|
|||
*/
|
||||
void sendPage(bool useChar)
|
||||
{
|
||||
void* pnt_configPage;
|
||||
struct table3D currentTable;
|
||||
void* pnt_configPage = &configPage1; //Default value is for safety only. Will be changed below if needed.
|
||||
struct table3D currentTable = fuelTable; //Default value is for safety only. Will be changed below if needed.
|
||||
byte currentTitleIndex = 0;// This corresponds to the count up to the first char of a string in pageTitles
|
||||
bool sendComplete = false; //Used to track whether all send operations are complete
|
||||
|
||||
switch (currentPage)
|
||||
{
|
||||
case veMapPage:
|
||||
{
|
||||
currentTitleIndex = 0;
|
||||
currentTable = fuelTable;
|
||||
break;
|
||||
}
|
||||
|
||||
case veSetPage:
|
||||
{
|
||||
// currentTitleIndex = 27;
|
||||
if (useChar)
|
||||
{
|
||||
|
@ -586,22 +681,18 @@ void sendPage(bool useChar)
|
|||
for (pnt_configPage = (uint16_t *)&configPage1.inj4Ang + 1; pnt_configPage < &configPage1.mapMax; pnt_configPage = (byte *)pnt_configPage + 1) { Serial.println(*((byte *)pnt_configPage)); }
|
||||
Serial.println(configPage1.mapMax);
|
||||
// Following loop displays remaining byte values of the page
|
||||
for (pnt_configPage = (uint16_t *)&configPage1.mapMax + 1; pnt_configPage < (byte *)&configPage1 + page_size; pnt_configPage = (byte *)pnt_configPage + 1) { Serial.println(*((byte *)pnt_configPage)); }
|
||||
for (pnt_configPage = (uint16_t *)&configPage1.mapMax + 1; pnt_configPage < (byte *)&configPage1 + npage_size[veSetPage]; pnt_configPage = (byte *)pnt_configPage + 1) { Serial.println(*((byte *)pnt_configPage)); }
|
||||
sendComplete = true;
|
||||
}
|
||||
else { pnt_configPage = &configPage1; } //Create a pointer to Page 1 in memory
|
||||
break;
|
||||
}
|
||||
|
||||
case ignMapPage:
|
||||
{
|
||||
currentTitleIndex = 42;// the index to the first char of the third string in pageTitles
|
||||
currentTable = ignitionTable;
|
||||
break;
|
||||
}
|
||||
|
||||
case ignSetPage:
|
||||
{
|
||||
//currentTitleIndex = 56;
|
||||
if (useChar)
|
||||
{
|
||||
|
@ -640,7 +731,7 @@ void sendPage(bool useChar)
|
|||
Serial.print(' ');
|
||||
}
|
||||
Serial.println();
|
||||
for (pnt_configPage = (byte *)&configPage2.dwellCorrectionValues[5] + 1; pnt_configPage < (byte *)&configPage2 + page_size; pnt_configPage = (byte *)pnt_configPage + 1)
|
||||
for (pnt_configPage = (byte *)&configPage2.dwellCorrectionValues[5] + 1; pnt_configPage < (byte *)&configPage2 + npage_size[ignSetPage]; pnt_configPage = (byte *)pnt_configPage + 1)
|
||||
{
|
||||
Serial.println(*((byte *)pnt_configPage));// Displaying remaining byte values of the page
|
||||
}
|
||||
|
@ -648,17 +739,13 @@ void sendPage(bool useChar)
|
|||
}
|
||||
else { pnt_configPage = &configPage2; } //Create a pointer to Page 2 in memory
|
||||
break;
|
||||
}
|
||||
|
||||
case afrMapPage:
|
||||
{
|
||||
currentTitleIndex = 71;//Array index to next string
|
||||
currentTable = afrTable;
|
||||
break;
|
||||
}
|
||||
|
||||
case afrSetPage:
|
||||
{
|
||||
//currentTitleIndex = 91;
|
||||
if (useChar)
|
||||
{
|
||||
|
@ -695,18 +782,15 @@ void sendPage(bool useChar)
|
|||
Serial.println();
|
||||
}
|
||||
// Following loop displays the remaining byte values of the page
|
||||
for (pnt_configPage = (byte *)&configPage3.airDenRates[8] + 1; pnt_configPage < (byte *)&configPage3 + page_size; pnt_configPage = (byte *)pnt_configPage + 1)
|
||||
for (pnt_configPage = (byte *)&configPage3.airDenRates[8] + 1; pnt_configPage < (byte *)&configPage3 + npage_size[afrSetPage]; pnt_configPage = (byte *)pnt_configPage + 1)
|
||||
{
|
||||
Serial.println(*((byte *)pnt_configPage));
|
||||
}
|
||||
sendComplete = true;
|
||||
}
|
||||
else { pnt_configPage = &configPage3; } //Create a pointer to Page 3 in memory
|
||||
break;
|
||||
}
|
||||
|
||||
case iacPage:
|
||||
{
|
||||
//Old configPage4 STARTED HERE!
|
||||
//currentTitleIndex = 106;
|
||||
//To Display Values from Config Page 4
|
||||
if (useChar)
|
||||
|
@ -717,10 +801,10 @@ void sendPage(bool useChar)
|
|||
byte * currentVar;
|
||||
switch (y)
|
||||
{
|
||||
case 1: currentVar = configPage4.iacBins; break;
|
||||
case 2: currentVar = configPage4.iacOLPWMVal; break;
|
||||
case 3: currentVar = configPage4.iacOLStepVal; break;
|
||||
case 4: currentVar = configPage4.iacCLValues; break;
|
||||
case 1: currentVar = configPage3.iacBins; break;
|
||||
case 2: currentVar = configPage3.iacOLPWMVal; break;
|
||||
case 3: currentVar = configPage3.iacOLStepVal; break;
|
||||
case 4: currentVar = configPage3.iacCLValues; break;
|
||||
default: break;
|
||||
}
|
||||
for (byte x = 10; x; x--)
|
||||
|
@ -735,9 +819,9 @@ void sendPage(bool useChar)
|
|||
byte * currentVar;
|
||||
switch (y)
|
||||
{
|
||||
case 1: currentVar = configPage4.iacCrankBins; break;
|
||||
case 2: currentVar = configPage4.iacCrankDuty; break;
|
||||
case 3: currentVar = configPage4.iacCrankSteps; break;
|
||||
case 1: currentVar = configPage3.iacCrankBins; break;
|
||||
case 2: currentVar = configPage3.iacCrankDuty; break;
|
||||
case 3: currentVar = configPage3.iacCrankSteps; break;
|
||||
default: break;
|
||||
}
|
||||
for (byte x = 4; x; x--)
|
||||
|
@ -748,15 +832,13 @@ void sendPage(bool useChar)
|
|||
Serial.println();
|
||||
}
|
||||
// Following loop is for remaining byte value of page
|
||||
for (pnt_configPage = (byte *)&configPage4.iacCrankBins[3] + 1; pnt_configPage < (byte *)&configPage4 + page_size; pnt_configPage = (byte *)pnt_configPage + 1) { Serial.println(*((byte *)pnt_configPage)); }
|
||||
for (pnt_configPage = (byte *)&configPage3.iacCrankBins[3] + 1; pnt_configPage < (byte *)&configPage3 + npage_size[afrSetPage]; pnt_configPage = (byte *)pnt_configPage + 1) { Serial.println(*((byte *)pnt_configPage)); }
|
||||
sendComplete = true;
|
||||
}
|
||||
else { pnt_configPage = &configPage4; } //Create a pointer to Page 4 in memory
|
||||
else { pnt_configPage = &configPage3; } //Create a pointer to Page 4 in memory
|
||||
break;
|
||||
}
|
||||
|
||||
case boostvvtPage:
|
||||
{
|
||||
if(useChar)
|
||||
{
|
||||
currentTable = boostTable;
|
||||
|
@ -779,9 +861,8 @@ void sendPage(bool useChar)
|
|||
sendComplete = true;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case seqFuelPage:
|
||||
{
|
||||
if(useChar)
|
||||
{
|
||||
currentTable = trim1Table;
|
||||
|
@ -842,10 +923,8 @@ void sendPage(bool useChar)
|
|||
sendComplete = true;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case canbusPage:
|
||||
{
|
||||
//currentTitleIndex = 141;
|
||||
if (useChar)
|
||||
{
|
||||
|
@ -859,15 +938,23 @@ void sendPage(bool useChar)
|
|||
}
|
||||
else { pnt_configPage = &configPage10; } //Create a pointer to Page 10 in memory
|
||||
break;
|
||||
|
||||
case warmupPage:
|
||||
if (useChar)
|
||||
{
|
||||
sendComplete = true;
|
||||
}
|
||||
else { pnt_configPage = &configPage11; } //Create a pointer to Page 11 in memory
|
||||
break;
|
||||
|
||||
default:
|
||||
{
|
||||
Serial.println(F("\nPage has not been implemented yet. Change to another page."));
|
||||
//Just set default Values to avoid warnings
|
||||
pnt_configPage = &configPage11;
|
||||
currentTable = fuelTable;
|
||||
sendComplete = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if(!sendComplete)
|
||||
{
|
||||
if (isMap)
|
||||
|
@ -936,7 +1023,7 @@ void sendPage(bool useChar)
|
|||
}
|
||||
else currentTitleIndex = 0;
|
||||
}while(currentTitleIndex == 132); //Should never loop unless going to display vvtTable
|
||||
}
|
||||
} //use char
|
||||
else
|
||||
{
|
||||
//Need to perform a translation of the values[yaxis][xaxis] into the MS expected format
|
||||
|
@ -951,7 +1038,7 @@ void sendPage(bool useChar)
|
|||
//loop();
|
||||
Serial.write((byte *)&response, sizeof(response));
|
||||
}
|
||||
}
|
||||
} //is map
|
||||
else
|
||||
{
|
||||
/*if(useChar)
|
||||
|
@ -980,6 +1067,126 @@ void sendPage(bool useChar)
|
|||
} //sendComplete
|
||||
}
|
||||
|
||||
byte getPageValue(byte page, uint16_t valueAddress)
|
||||
{
|
||||
void* pnt_configPage = &configPage1; //Default value is for safety only. Will be changed below if needed.
|
||||
uint16_t tempAddress;
|
||||
byte returnValue = 0;
|
||||
|
||||
switch (page)
|
||||
{
|
||||
case veMapPage:
|
||||
if( valueAddress < 256) { returnValue = fuelTable.values[15 - (valueAddress / 16)][valueAddress % 16]; } //This is slightly non-intuitive, but essentially just flips the table vertically (IE top line becomes the bottom line etc). Columns are unchanged. Every 16 loops, manually call loop() to avoid potential misses
|
||||
else if(valueAddress < 272) { returnValue = byte(fuelTable.axisX[(valueAddress - 256)] / TABLE_RPM_MULTIPLIER); } //RPM Bins for VE table (Need to be dvidied by 100)
|
||||
else if (valueAddress < 288) { returnValue = byte(fuelTable.axisY[15 - (valueAddress - 272)] / TABLE_LOAD_MULTIPLIER); } //MAP or TPS bins for VE table
|
||||
break;
|
||||
|
||||
case veSetPage:
|
||||
pnt_configPage = &configPage1; //Create a pointer to Page 1 in memory
|
||||
returnValue = *((byte *)pnt_configPage + valueAddress);
|
||||
break;
|
||||
|
||||
case ignMapPage:
|
||||
if( valueAddress < 256) { returnValue = ignitionTable.values[15 - (valueAddress / 16)][valueAddress % 16]; } //This is slightly non-intuitive, but essentially just flips the table vertically (IE top line becomes the bottom line etc). Columns are unchanged. Every 16 loops, manually call loop() to avoid potential misses
|
||||
else if(valueAddress < 272) { returnValue = byte(ignitionTable.axisX[(valueAddress - 256)] / TABLE_RPM_MULTIPLIER); } //RPM Bins for VE table (Need to be dvidied by 100)
|
||||
else if (valueAddress < 288) { returnValue = byte(ignitionTable.axisY[15 - (valueAddress - 272)] / TABLE_LOAD_MULTIPLIER); } //MAP or TPS bins for VE table
|
||||
break;
|
||||
|
||||
case ignSetPage:
|
||||
pnt_configPage = &configPage2; //Create a pointer to Page 2 in memory
|
||||
returnValue = *((byte *)pnt_configPage + valueAddress);
|
||||
break;
|
||||
|
||||
case afrMapPage:
|
||||
if( valueAddress < 256) { returnValue = afrTable.values[15 - (valueAddress / 16)][valueAddress % 16]; } //This is slightly non-intuitive, but essentially just flips the table vertically (IE top line becomes the bottom line etc). Columns are unchanged. Every 16 loops, manually call loop() to avoid potential misses
|
||||
else if(valueAddress < 272) { returnValue = byte(afrTable.axisX[(valueAddress - 256)] / TABLE_RPM_MULTIPLIER); } //RPM Bins for VE table (Need to be dvidied by 100)
|
||||
else if (valueAddress < 288) { returnValue = byte(afrTable.axisY[15 - (valueAddress - 272)] / TABLE_LOAD_MULTIPLIER); } //MAP or TPS bins for VE table
|
||||
break;
|
||||
|
||||
case afrSetPage:
|
||||
pnt_configPage = &configPage3; //Create a pointer to Page 3 in memory
|
||||
returnValue = *((byte *)pnt_configPage + valueAddress);
|
||||
break;
|
||||
|
||||
case boostvvtPage:
|
||||
|
||||
{
|
||||
//Need to perform a translation of the values[MAP/TPS][RPM] into the MS expected format
|
||||
if(valueAddress < 80)
|
||||
{
|
||||
//Boost table
|
||||
if(valueAddress < 64) { returnValue = boostTable.values[7 - (valueAddress / 8)][valueAddress % 8]; }
|
||||
else if(valueAddress < 72) { returnValue = byte(boostTable.axisX[(valueAddress - 64)] / TABLE_RPM_MULTIPLIER); }
|
||||
else if(valueAddress < 80) { returnValue = byte(boostTable.axisY[7 - (valueAddress - 72)]); }
|
||||
}
|
||||
else
|
||||
{
|
||||
tempAddress = valueAddress - 80;
|
||||
//VVT table
|
||||
if(tempAddress < 64) { returnValue = vvtTable.values[7 - (tempAddress / 8)][tempAddress % 8]; }
|
||||
else if(tempAddress < 72) { returnValue = byte(vvtTable.axisX[(tempAddress - 64)] / TABLE_RPM_MULTIPLIER); }
|
||||
else if(tempAddress < 80) { returnValue = byte(vvtTable.axisY[7 - (tempAddress - 72)]); }
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case seqFuelPage:
|
||||
|
||||
{
|
||||
//Need to perform a translation of the values[MAP/TPS][RPM] into the TS expected format
|
||||
if(valueAddress < 48)
|
||||
{
|
||||
//trim1 table
|
||||
if(valueAddress < 36) { returnValue = trim1Table.values[5 - (valueAddress / 6)][valueAddress % 6]; }
|
||||
else if(valueAddress < 42) { returnValue = byte(trim1Table.axisX[(valueAddress - 36)] / TABLE_RPM_MULTIPLIER); }
|
||||
else if(valueAddress < 48) { returnValue = byte(trim1Table.axisY[5 - (valueAddress - 42)] / TABLE_LOAD_MULTIPLIER); }
|
||||
}
|
||||
else if(valueAddress < 96)
|
||||
{
|
||||
tempAddress = valueAddress - 48;
|
||||
//trim2 table
|
||||
if(tempAddress < 36) { returnValue = trim2Table.values[5 - (tempAddress / 6)][tempAddress % 6]; }
|
||||
else if(tempAddress < 42) { returnValue = byte(trim2Table.axisX[(tempAddress - 36)] / TABLE_RPM_MULTIPLIER); }
|
||||
else if(tempAddress < 48) { returnValue = byte(trim2Table.axisY[5 - (tempAddress - 42)] / TABLE_LOAD_MULTIPLIER); }
|
||||
}
|
||||
else if(valueAddress < 144)
|
||||
{
|
||||
tempAddress = valueAddress - 96;
|
||||
//trim3 table
|
||||
if(tempAddress < 36) { returnValue = trim3Table.values[5 - (tempAddress / 6)][tempAddress % 6]; }
|
||||
else if(tempAddress < 42) { returnValue = byte(trim3Table.axisX[(tempAddress - 36)] / TABLE_RPM_MULTIPLIER); }
|
||||
else if(tempAddress < 48) { returnValue = byte(trim3Table.axisY[5 - (tempAddress - 42)] / TABLE_LOAD_MULTIPLIER); }
|
||||
}
|
||||
else if(valueAddress < 192)
|
||||
{
|
||||
tempAddress = valueAddress - 144;
|
||||
//trim4 table
|
||||
if(tempAddress < 36) { returnValue = trim4Table.values[5 - (tempAddress / 6)][tempAddress % 6]; }
|
||||
else if(tempAddress < 42) { returnValue = byte(trim4Table.axisX[(tempAddress - 36)] / TABLE_RPM_MULTIPLIER); }
|
||||
else if(tempAddress < 48) { returnValue = byte(trim4Table.axisY[5 - (tempAddress - 42)] / TABLE_LOAD_MULTIPLIER); }
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case canbusPage:
|
||||
pnt_configPage = &configPage10; //Create a pointer to Page 10 in memory
|
||||
returnValue = *((byte *)pnt_configPage + valueAddress);
|
||||
break;
|
||||
|
||||
case warmupPage:
|
||||
pnt_configPage = &configPage11; //Create a pointer to Page 11 in memory
|
||||
returnValue = *((byte *)pnt_configPage + valueAddress);
|
||||
break;
|
||||
|
||||
default:
|
||||
Serial.println(F("\nPage has not been implemented yet. Change to another page."));
|
||||
//Just set default Values to avoid warnings
|
||||
pnt_configPage = &configPage11;
|
||||
break;
|
||||
}
|
||||
return returnValue;
|
||||
}
|
||||
|
||||
/*
|
||||
This function is used to store calibration data sent by Tuner Studio.
|
||||
*/
|
||||
|
@ -1016,6 +1223,11 @@ void receiveCalibration(byte tableID)
|
|||
break;
|
||||
|
||||
default:
|
||||
OFFSET = 0;
|
||||
pnt_TargetTable = (byte *)&o2CalibrationTable;
|
||||
DIVISION_FACTOR = 1;
|
||||
BYTES_PER_VALUE = 1;
|
||||
EEPROM_START = EEPROM_CALIBRATION_O2;
|
||||
break; //Should never get here, but if we do, just fail back to main loop
|
||||
}
|
||||
|
||||
|
|
|
@ -112,7 +112,11 @@ Additional fuel % to be added when the engine is cranking
|
|||
static inline byte correctionCranking()
|
||||
{
|
||||
byte crankingValue = 100;
|
||||
if ( BIT_CHECK(currentStatus.engine, BIT_ENGINE_CRANK) ) { crankingValue = 100 + configPage1.crankingPct; }
|
||||
//if ( BIT_CHECK(currentStatus.engine, BIT_ENGINE_CRANK) ) { crankingValue = 100 + configPage1.crankingPct; }
|
||||
if ( BIT_CHECK(currentStatus.engine, BIT_ENGINE_CRANK) )
|
||||
{
|
||||
crankingValue = table2D_getValue(&crankingEnrichTable, currentStatus.coolant + CALIBRATION_TEMPERATURE_OFFSET);
|
||||
}
|
||||
return crankingValue;
|
||||
}
|
||||
|
||||
|
@ -152,12 +156,13 @@ static inline byte 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( currentLoopTime >= currentStatus.TAEEndTime )
|
||||
if( micros() >= currentStatus.TAEEndTime )
|
||||
{
|
||||
//Time to turn enrichment off
|
||||
BIT_CLEAR(currentStatus.engine, BIT_ENGINE_ACC);
|
||||
currentStatus.TAEamount = 0;
|
||||
accelValue = 100;
|
||||
currentStatus.tpsDOT = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -173,6 +178,7 @@ static inline byte correctionAccel()
|
|||
if (TPS_change <= 2)
|
||||
{
|
||||
accelValue = 100;
|
||||
currentStatus.tpsDOT = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -256,7 +262,7 @@ static inline byte correctionLaunch()
|
|||
static inline bool correctionDFCO()
|
||||
{
|
||||
bool DFCOValue = false;
|
||||
if ( configPage2.dfcoEnabled == 1 )
|
||||
if ( configPage1.dfcoEnabled == 1 )
|
||||
{
|
||||
if ( bitRead(currentStatus.squirt, BIT_SQUIRT_DFCO) == 1 ) { DFCOValue = ( currentStatus.RPM > ( configPage2.dfcoRPM * 10) ) && ( currentStatus.TPS < configPage2.dfcoTPSThresh ); }
|
||||
else { DFCOValue = ( currentStatus.RPM > (unsigned int)( (configPage2.dfcoRPM * 10) + configPage2.dfcoHyster) ) && ( currentStatus.TPS < configPage2.dfcoTPSThresh ); }
|
||||
|
@ -472,7 +478,7 @@ uint16_t correctionsDwell(uint16_t dwell)
|
|||
uint16_t dwellPerRevolution = tempDwell + (uint16_t)(configPage2.sparkDur * 100); //Spark duration is in mS*10. Multiple it by 100 to get spark duration in uS
|
||||
int8_t pulsesPerRevolution = 1;
|
||||
//Single channel spark mode is the only time there will be more than 1 pulse per revolution on any given output
|
||||
if( (configPage2.sparkMode == IGN_MODE_SINGLE) && (configPage1.nCylinders > 1) ) //No point in running this for 1 cylinder engines
|
||||
if( ( (configPage2.sparkMode == IGN_MODE_SINGLE) || (configPage2.sparkMode == IGN_MODE_ROTARY) ) && (configPage1.nCylinders > 1) ) //No point in running this for 1 cylinder engines
|
||||
{
|
||||
pulsesPerRevolution = (configPage1.nCylinders >> 1);
|
||||
dwellPerRevolution = dwellPerRevolution * pulsesPerRevolution;
|
||||
|
|
|
@ -15,6 +15,8 @@ static inline void addToothLogEntry(unsigned long);
|
|||
static inline uint16_t stdGetRPM();
|
||||
static inline void setFilter(unsigned long);
|
||||
static inline int crankingGetRPM(byte);
|
||||
static inline void doPerToothTiming(uint16_t crankAngle);
|
||||
|
||||
void triggerSetup_missingTooth();
|
||||
void triggerPri_missingTooth();
|
||||
void triggerSec_missingTooth();
|
||||
|
@ -59,6 +61,7 @@ unsigned int triggerSecFilterTime_duration; // The shortest valid time (in uS) p
|
|||
volatile int triggerToothAngle; //The number of crank degrees that elapse per tooth
|
||||
bool secondDerivEnabled; //The use of the 2nd derivative calculation is limited to certain decoders. This is set to either true or false in each decoders setup routine
|
||||
bool decoderIsSequential; //Whether or not the decoder supports sequential operation
|
||||
bool decoderIsLowRes = false; //Is set true, certain extra calculations are performed for better timing accuracy
|
||||
byte checkSyncToothCount; //How many teeth must've been seen on this revolution before we try to confirm sync (Useful for missing tooth type decoders)
|
||||
|
||||
int16_t ignition1EndTooth = 0;
|
||||
|
|
|
@ -9,13 +9,25 @@
|
|||
#define CORE_AVR
|
||||
#elif defined(CORE_TEENSY)
|
||||
#define BOARD_NR_GPIO_PINS 34
|
||||
#elif defined(STM32_MCU_SERIES) || defined(_VARIANT_ARDUINO_STM32_)
|
||||
#elif defined(STM32_MCU_SERIES) || defined(ARDUINO_ARCH_STM32) || defined(__STM32F1__) || defined(STM32F4) || defined(STM32)
|
||||
#define CORE_STM32
|
||||
#if defined (STM32F1) || defined(__STM32F1__)
|
||||
#define BOARD_NR_GPIO_PINS 34
|
||||
#define LED_BUILTIN 33
|
||||
#elif defined(ARDUINO_BLACK_F407VE) || defined(STM32F4)
|
||||
#define BOARD_NR_GPIO_PINS 80
|
||||
#define LED_BUILTIN PA7
|
||||
#endif
|
||||
|
||||
extern "C" char* sbrk(int incr); //Used to freeRam
|
||||
inline unsigned char digitalPinToInterrupt(unsigned char Interrupt_pin) { return Interrupt_pin; } //This isn't included in the stm32duino libs (yet)
|
||||
#if defined(ARDUINO_ARCH_STM32) // STM32GENERIC core
|
||||
#define portOutputRegister(port) (volatile byte *)( &(port->ODR) )
|
||||
#define portInputRegister(port) (volatile byte *)( &(port->IDR) )
|
||||
#else //libmaple core aka STM32DUINO
|
||||
#define portOutputRegister(port) (volatile byte *)( &(port->regs->ODR) ) //These are defined in STM32F1/variants/generic_stm32f103c/variant.h but return a non byte* value
|
||||
#define portInputRegister(port) (volatile byte *)( &(port->regs->IDR) ) //These are defined in STM32F1/variants/generic_stm32f103c/variant.h but return a non byte* value
|
||||
#endif
|
||||
#else
|
||||
#error Incorrect board selected. Please select the correct board (Usually Mega 2560) and upload again
|
||||
#endif
|
||||
|
@ -28,6 +40,10 @@
|
|||
#define MS_IN_MINUTE 60000
|
||||
#define US_IN_MINUTE 60000000
|
||||
|
||||
//Define the load algorithm
|
||||
#define LOAD_SOURCE_MAP 0
|
||||
#define LOAD_SOURCE_TPS 1
|
||||
|
||||
//Define bit positions within engine virable
|
||||
#define BIT_ENGINE_RUN 0 // Engine running
|
||||
#define BIT_ENGINE_CRANK 1 // Engine cranking
|
||||
|
@ -67,6 +83,12 @@
|
|||
#define BIT_SPARK2_UNUSED7 6
|
||||
#define BIT_SPARK2_UNUSED8 7
|
||||
|
||||
#define BIT_TIMER_1HZ 0
|
||||
#define BIT_TIMER_4HZ 1
|
||||
#define BIT_TIMER_10HZ 2
|
||||
#define BIT_TIMER_15HZ 3
|
||||
#define BIT_TIMER_30HZ 4
|
||||
|
||||
#define VALID_MAP_MAX 1022 //The largest ADC value that is valid for the MAP sensor
|
||||
#define VALID_MAP_MIN 2 //The smallest ADC value that is valid for the MAP sensor
|
||||
|
||||
|
@ -82,6 +104,14 @@
|
|||
#define IGN_MODE_SINGLE 1
|
||||
#define IGN_MODE_WASTEDCOP 2
|
||||
#define IGN_MODE_SEQUENTIAL 3
|
||||
#define IGN_MODE_ROTARY 4
|
||||
|
||||
#define ROTARY_IGN_FC 0
|
||||
#define ROTARY_IGN_FD 1
|
||||
#define ROTARY_IGN_RX8 2
|
||||
|
||||
#define BOOST_MODE_SIMPLE 0
|
||||
#define BOOST_MODE_FULL 1
|
||||
|
||||
#define SIZE_BYTE 8
|
||||
#define SIZE_INT 16
|
||||
|
@ -99,6 +129,9 @@
|
|||
|
||||
#define SERIAL_BUFFER_THRESHOLD 32 // When the serial buffer is filled to greater than this threshold value, the serial processing operations will be performed more urgently in order to avoid it overflowing. Serial buffer is 64 bytes long, so the threshold is set at half this as a reasonable figure
|
||||
|
||||
#define FUEL_PUMP_ON() *pump_pin_port |= (pump_pin_mask)
|
||||
#define FUEL_PUMP_OFF() *pump_pin_port &= ~(pump_pin_mask)
|
||||
|
||||
const byte signature = 20;
|
||||
|
||||
//const char signature[] = "speeduino";
|
||||
|
@ -106,9 +139,9 @@ const char displaySignature[] = "speeduino 201609-dev";
|
|||
const char TSfirmwareVersion[] = "Speeduino 2016.09";
|
||||
|
||||
const byte data_structure_version = 2; //This identifies the data structure when reading / writing.
|
||||
const byte page_size = 64;
|
||||
const int npage_size[11] = {0,288,64,288,64,288,64,64,160,192,128};
|
||||
//const byte page10_size = 128;
|
||||
//const byte page_size = 64;
|
||||
const int npage_size[11] = {0,288,128,288,128,288,128,160,192,128,192};
|
||||
//const byte page11_size = 128;
|
||||
#define MAP_PAGE_SIZE 288
|
||||
|
||||
struct table3D fuelTable; //16x16 fuel map
|
||||
|
@ -122,10 +155,12 @@ 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 WUETable; //10 bin Warm Up Enrichment map (2D)
|
||||
struct table2D crankingEnrichTable; //4 bin cranking Enrichment map (2D)
|
||||
struct table2D dwellVCorrectionTable; //6 bin dwell voltage correction (2D)
|
||||
struct table2D injectorVCorrectionTable; //6 bin injector voltage correction (2D)
|
||||
struct table2D IATDensityCorrectionTable; //9 bin inlet air temperature density correction (2D)
|
||||
struct table2D IATRetardTable; //6 bin ignition adjustment based on inlet air temperature (2D)
|
||||
struct table2D rotarySplitTable; //8 bin ignition split curve for rotary leading/trailing (2D)
|
||||
|
||||
//These are for the direct port manipulation of the injectors and coils
|
||||
volatile byte *inj1_pin_port;
|
||||
|
@ -152,6 +187,8 @@ volatile byte ign5_pin_mask;
|
|||
|
||||
volatile byte *tach_pin_port;
|
||||
volatile byte tach_pin_mask;
|
||||
volatile byte *pump_pin_port;
|
||||
volatile byte pump_pin_mask;
|
||||
|
||||
volatile byte *triggerPri_pin_port;
|
||||
volatile byte triggerPri_pin_mask;
|
||||
|
@ -173,6 +210,9 @@ int ignition4EndAngle = 0;
|
|||
//This is used across multiple files
|
||||
unsigned long revolutionTime; //The time in uS that one revolution would take at current speed (The time tooth 1 was last seen, minus the time it was seen prior to that)
|
||||
|
||||
volatile byte TIMER_mask;
|
||||
volatile byte LOOP_TIMER;
|
||||
|
||||
//The status struct contains the current values for all 'live' variables
|
||||
//In current version this is 64 bytes
|
||||
struct statuses {
|
||||
|
@ -180,8 +220,9 @@ struct statuses {
|
|||
uint16_t RPM;
|
||||
long longRPM;
|
||||
int mapADC;
|
||||
int baroADC;
|
||||
long MAP; //Has to be a long for PID calcs (Boost control)
|
||||
byte baro; //Barometric pressure is simply the inital MAP reading, taken before the engine is running
|
||||
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%)
|
||||
byte TPSlast; //The previous TPS reading
|
||||
unsigned long TPS_time; //The time the TPS sample was taken
|
||||
|
@ -230,17 +271,18 @@ struct statuses {
|
|||
volatile unsigned int loopsPerSecond;
|
||||
boolean launchingSoft; //True when in launch control soft limit mode
|
||||
boolean launchingHard; //True when in launch control hard limit mode
|
||||
int freeRAM;
|
||||
uint16_t freeRAM;
|
||||
unsigned int clutchEngagedRPM;
|
||||
bool flatShiftingHard;
|
||||
volatile byte startRevolutions; //A counter for how many revolutions have been completed since sync was achieved.
|
||||
byte boostTarget;
|
||||
volatile uint16_t startRevolutions; //A counter for how many revolutions have been completed since sync was achieved.
|
||||
uint16_t boostTarget;
|
||||
byte testOutputs;
|
||||
bool testActive;
|
||||
byte boostDuty;
|
||||
uint16_t boostDuty; //Percentage value * 100 to give 2 points of precision
|
||||
byte idleLoad; //Either the current steps or current duty cycle for the idle control.
|
||||
uint16_t canin[16]; //16bit raw value of selected canin data for channel 0-15
|
||||
uint8_t current_caninchannel = 0; //start off at channel 0
|
||||
uint16_t crankRPM = 400; //The actual cranking RPM limit. Saves us multiplying it everytime from the config page
|
||||
|
||||
//Helpful bitwise operations:
|
||||
//Useful reference: http://playground.arduino.cc/Code/BitMath
|
||||
|
@ -313,7 +355,7 @@ struct config1 {
|
|||
byte baroCorr : 1;
|
||||
byte injLayout : 2;
|
||||
byte perToothIgn : 1;
|
||||
byte unused2_38h : 1;
|
||||
byte dfcoEnabled : 1; //Whether or not DFCO is turned on
|
||||
|
||||
byte primePulse;
|
||||
byte dutyLim;
|
||||
|
@ -323,7 +365,7 @@ struct config1 {
|
|||
byte boostMaxDuty;
|
||||
byte tpsMin;
|
||||
byte tpsMax;
|
||||
byte mapMin;
|
||||
int8_t mapMin; //Must be signed
|
||||
uint16_t mapMax;
|
||||
byte fpPrime; //Time (In seconds) that the fuel pump should be primed for on power up
|
||||
byte stoich;
|
||||
|
@ -339,6 +381,8 @@ struct config1 {
|
|||
byte iacCLmaxDuty;
|
||||
byte boostMinDuty;
|
||||
|
||||
byte unused1_64[63];
|
||||
|
||||
#if defined(CORE_AVR)
|
||||
};
|
||||
#else
|
||||
|
@ -357,7 +401,7 @@ struct config2 {
|
|||
byte TrigEdge : 1;
|
||||
byte TrigSpeed : 1;
|
||||
byte IgInv : 1;
|
||||
byte oddfire : 1;
|
||||
byte unused4_5d : 1;
|
||||
byte TrigPattern : 4;
|
||||
|
||||
byte TrigEdgeSec : 1;
|
||||
|
@ -372,8 +416,7 @@ struct config2 {
|
|||
|
||||
byte dwellCont : 1; //Fixed duty dwell control
|
||||
byte useDwellLim : 1; //Whether the dwell limiter is off or on
|
||||
byte sparkMode : 2; //Spark output mode (Eg Wasted spark, single channel or Wasted COP)
|
||||
byte dfcoEnabled : 1; //Whether or not DFCO is turned on
|
||||
byte sparkMode : 3; //Spark output mode (Eg Wasted spark, single channel or Wasted COP)
|
||||
byte triggerFilter : 2; //The mode of trigger filter being used (0=Off, 1=Light (Not currently used), 2=Normal, 3=Aggressive)
|
||||
byte ignCranklock : 1; //Whether or not the ignition timing during cranking is locked to a CAS pulse. Only currently valid for Basic distributor and 4G63.
|
||||
|
||||
|
@ -402,6 +445,8 @@ struct config2 {
|
|||
byte ignBypassPin : 6; //Pin the ignition bypass is activated on
|
||||
byte ignBypassHiLo : 1; //Whether this should be active high or low.
|
||||
|
||||
byte unused2_64[63];
|
||||
|
||||
#if defined(CORE_AVR)
|
||||
};
|
||||
#else
|
||||
|
@ -431,7 +476,8 @@ struct config3 {
|
|||
byte egoRPM; //RPM must be above this for closed loop to function
|
||||
byte egoTPSMax; //TPS must be below this for closed loop to function
|
||||
byte vvtPin : 6;
|
||||
byte unused6_13 : 2;
|
||||
byte useExtBaro : 1;
|
||||
byte boostMode : 1; //Simple of full boost contrl
|
||||
byte boostPin : 6;
|
||||
byte unused6_14 : 2;
|
||||
byte voltageCorrectionBins[6]; //X axis bins for voltage correction tables
|
||||
|
@ -464,21 +510,11 @@ struct config3 {
|
|||
byte lnchPullRes : 2;
|
||||
byte fuelTrimEnabled : 1;
|
||||
byte flatSEnable : 1;
|
||||
byte unused60 : 4;
|
||||
byte baroPin : 4;
|
||||
byte flatSSoftWin;
|
||||
byte flatSRetard;
|
||||
byte flatSArm;
|
||||
|
||||
#if defined(CORE_AVR)
|
||||
};
|
||||
#else
|
||||
} __attribute__((__packed__)); //The 32 bit systems require all structs to be fully packed
|
||||
#endif
|
||||
|
||||
|
||||
//Page 4 of the config mostly deals with idle control
|
||||
//See ini file for further info (Config Page 7 in the ini)
|
||||
struct config4 {
|
||||
byte iacCLValues[10]; //Closed loop target RPM value
|
||||
byte iacOLStepVal[10]; //Open loop step values for stepper motors
|
||||
byte iacOLPWMVal[10]; //Open loop duty values for PMWM valves
|
||||
|
@ -561,6 +597,31 @@ struct config10 {
|
|||
} __attribute__((__packed__)); //The 32 bit systems require all structs to be fully packed
|
||||
#endif
|
||||
|
||||
/*
|
||||
Page 11 - No specific purpose. Created initially for the cranking enrich curve
|
||||
192 bytes long
|
||||
See ini file for further info (Config Page 11 in the ini)
|
||||
*/
|
||||
struct config11 {
|
||||
byte crankingEnrichBins[4];
|
||||
byte crankingEnrichValues[4];
|
||||
|
||||
byte rotaryType : 2;
|
||||
byte unused11_8c : 6;
|
||||
|
||||
byte rotarySplitValues[8];
|
||||
byte rotarySplitBins[8];
|
||||
|
||||
uint16_t boostSens;
|
||||
byte boostIntv;
|
||||
byte unused11_28_192[164];
|
||||
|
||||
#if defined(CORE_AVR)
|
||||
};
|
||||
#else
|
||||
} __attribute__((__packed__)); //The 32 bit systems require all structs to be fully packed
|
||||
#endif
|
||||
|
||||
|
||||
byte pinInjector1; //Output pin injector 1
|
||||
byte pinInjector2; //Output pin injector 2
|
||||
|
@ -619,6 +680,7 @@ byte pinStepperEnable; //Turning the DRV8825 driver on/off
|
|||
byte pinLaunch;
|
||||
byte pinIgnBypass; //The pin used for an ignition bypass (Optional)
|
||||
byte pinFlex; //Pin with the flex sensor attached
|
||||
byte pinBaro; //Pin that an external barometric pressure sensor is attached to (If used)
|
||||
|
||||
// global variables // from speeduino.ino
|
||||
extern struct statuses currentStatus; // from speeduino.ino
|
||||
|
@ -627,10 +689,12 @@ extern struct table3D ignitionTable; //16x16 ignition map
|
|||
extern struct table3D afrTable; //16x16 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 config1 configPage1;
|
||||
extern struct config2 configPage2;
|
||||
extern struct config3 configPage3;
|
||||
extern struct config10 configPage10;
|
||||
extern struct config11 configPage11;
|
||||
extern unsigned long currentLoopTime; //The time the current loop started (uS)
|
||||
extern unsigned long previousLoopTime; //The time the previous loop started (uS)
|
||||
extern byte ignitionCount;
|
||||
|
|
|
@ -40,14 +40,19 @@ struct StepperIdle
|
|||
#define IDLE_TIMER_DISABLE() FTM2_C0SC &= ~FTM_CSC_CHIE
|
||||
|
||||
#elif defined(CORE_STM32)
|
||||
#if defined(ARDUINO_ARCH_STM32) // STM32GENERIC core
|
||||
#define IDLE_COUNTER (TIM1)->CNT
|
||||
#define IDLE_COMPARE (TIM1)->CCR4
|
||||
|
||||
//Placeholders only
|
||||
#define IDLE_COUNTER 0
|
||||
#define IDLE_COMPARE 0
|
||||
|
||||
#define IDLE_TIMER_ENABLE()
|
||||
#define IDLE_TIMER_DISABLE()
|
||||
#define IDLE_TIMER_ENABLE() (TIM1)->CCER |= TIM_CCER_CC4E
|
||||
#define IDLE_TIMER_DISABLE() (TIM1)->CCER &= ~TIM_CCER_CC4E
|
||||
#else //libmaple core aka STM32DUINO
|
||||
#define IDLE_COUNTER (TIMER1->regs).gen->CNT
|
||||
#define IDLE_COMPARE (TIMER1->regs).gen->CCR4
|
||||
|
||||
#define IDLE_TIMER_ENABLE() (TIMER1->regs).gen->CCER |= TIMER_CCER_CC4E
|
||||
#define IDLE_TIMER_DISABLE() (TIMER1->regs).gen->CCER &= ~TIMER_CCER_CC4E
|
||||
#endif
|
||||
#endif
|
||||
|
||||
struct table2D iacClosedLoopTable;
|
||||
|
@ -81,5 +86,8 @@ static inline void enableIdle();
|
|||
static inline byte isStepperHomed();
|
||||
static inline byte checkForStepping();
|
||||
static inline void doStep();
|
||||
#if defined (CORE_TEENSY) || defined(CORE_STM32)
|
||||
static inline void idleInterrupt();
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
|
|
@ -24,7 +24,7 @@ void initialiseIdle()
|
|||
|
||||
#elif defined (CORE_TEENSY)
|
||||
|
||||
if( (configPage4.iacAlgorithm == IAC_ALGORITHM_PWM_OL) || (configPage4.iacAlgorithm == IAC_ALGORITHM_PWM_CL) )
|
||||
if( (configPage3.iacAlgorithm == IAC_ALGORITHM_PWM_OL) || (configPage3.iacAlgorithm == IAC_ALGORITHM_PWM_CL) )
|
||||
{
|
||||
//FlexTimer 2 is used for idle
|
||||
FTM2_MODE |= FTM_MODE_WPDIS; // Write Protection Disable
|
||||
|
@ -78,19 +78,20 @@ void initialiseIdle()
|
|||
NVIC_ENABLE_IRQ(IRQ_FTM2);
|
||||
}
|
||||
|
||||
#elif defined(MCU_STM32F103RB)
|
||||
|
||||
#elif defined(CORE_STM32)
|
||||
Timer1.attachInterrupt(4, idleInterrupt);
|
||||
Timer1.resume();
|
||||
#endif
|
||||
|
||||
//Initialising comprises of setting the 2D tables with the relevant values from the config pages
|
||||
switch(configPage4.iacAlgorithm)
|
||||
switch(configPage3.iacAlgorithm)
|
||||
{
|
||||
case IAC_ALGORITHM_NONE: //Case 0 is no idle control ('None')
|
||||
break;
|
||||
|
||||
case IAC_ALGORITHM_ONOFF:
|
||||
//Case 1 is on/off idle control
|
||||
if ((currentStatus.coolant + CALIBRATION_TEMPERATURE_OFFSET) < configPage4.iacFastTemp)
|
||||
if ((currentStatus.coolant + CALIBRATION_TEMPERATURE_OFFSET) < configPage3.iacFastTemp)
|
||||
{
|
||||
digitalWrite(pinIdle1, HIGH);
|
||||
idleOn = true;
|
||||
|
@ -101,20 +102,24 @@ void initialiseIdle()
|
|||
//Case 2 is PWM open loop
|
||||
iacPWMTable.xSize = 10;
|
||||
iacPWMTable.valueSize = SIZE_BYTE;
|
||||
iacPWMTable.values = configPage4.iacOLPWMVal;
|
||||
iacPWMTable.axisX = configPage4.iacBins;
|
||||
iacPWMTable.values = configPage3.iacOLPWMVal;
|
||||
iacPWMTable.axisX = configPage3.iacBins;
|
||||
|
||||
|
||||
iacCrankDutyTable.xSize = 4;
|
||||
iacCrankDutyTable.valueSize = SIZE_BYTE;
|
||||
iacCrankDutyTable.values = configPage4.iacCrankDuty;
|
||||
iacCrankDutyTable.axisX = configPage4.iacCrankBins;
|
||||
iacCrankDutyTable.values = configPage3.iacCrankDuty;
|
||||
iacCrankDutyTable.axisX = configPage3.iacCrankBins;
|
||||
|
||||
idle_pin_port = portOutputRegister(digitalPinToPort(pinIdle1));
|
||||
idle_pin_mask = digitalPinToBitMask(pinIdle1);
|
||||
idle2_pin_port = portOutputRegister(digitalPinToPort(pinIdle2));
|
||||
idle2_pin_mask = digitalPinToBitMask(pinIdle2);
|
||||
#if defined(CORE_STM32)
|
||||
idle_pwm_max_count = 1000000L / (configPage3.idleFreq * 2); //Converts the frequency in Hz to the number of ticks (at 2uS) it takes to complete 1 cycle. Note that the frequency is divided by 2 coming from TS to allow for up to 5KHz
|
||||
#else
|
||||
idle_pwm_max_count = 1000000L / (16 * configPage3.idleFreq * 2); //Converts the frequency in Hz to the number of ticks (at 16uS) it takes to complete 1 cycle. Note that the frequency is divided by 2 coming from TS to allow for up to 512hz
|
||||
#endif
|
||||
enableIdle();
|
||||
break;
|
||||
|
||||
|
@ -122,19 +127,23 @@ void initialiseIdle()
|
|||
//Case 3 is PWM closed loop
|
||||
iacClosedLoopTable.xSize = 10;
|
||||
iacClosedLoopTable.valueSize = SIZE_BYTE;
|
||||
iacClosedLoopTable.values = configPage4.iacCLValues;
|
||||
iacClosedLoopTable.axisX = configPage4.iacBins;
|
||||
iacClosedLoopTable.values = configPage3.iacCLValues;
|
||||
iacClosedLoopTable.axisX = configPage3.iacBins;
|
||||
|
||||
iacCrankDutyTable.xSize = 4;
|
||||
iacCrankDutyTable.valueSize = SIZE_BYTE;
|
||||
iacCrankDutyTable.values = configPage4.iacCrankDuty;
|
||||
iacCrankDutyTable.axisX = configPage4.iacCrankBins;
|
||||
iacCrankDutyTable.values = configPage3.iacCrankDuty;
|
||||
iacCrankDutyTable.axisX = configPage3.iacCrankBins;
|
||||
|
||||
idle_pin_port = portOutputRegister(digitalPinToPort(pinIdle1));
|
||||
idle_pin_mask = digitalPinToBitMask(pinIdle1);
|
||||
idle2_pin_port = portOutputRegister(digitalPinToPort(pinIdle2));
|
||||
idle2_pin_mask = digitalPinToBitMask(pinIdle2);
|
||||
#if defined(CORE_STM32)
|
||||
idle_pwm_max_count = 1000000L / (configPage3.idleFreq * 2); //Converts the frequency in Hz to the number of ticks (at 2uS) it takes to complete 1 cycle. Note that the frequency is divided by 2 coming from TS to allow for up to 5KHz
|
||||
#else
|
||||
idle_pwm_max_count = 1000000L / (16 * configPage3.idleFreq * 2); //Converts the frequency in Hz to the number of ticks (at 16uS) it takes to complete 1 cycle. Note that the frequency is divided by 2 coming from TS to allow for up to 512hz
|
||||
#endif
|
||||
idlePID.SetOutputLimits(percentage(configPage1.iacCLminDuty, idle_pwm_max_count), percentage(configPage1.iacCLmaxDuty, idle_pwm_max_count));
|
||||
idlePID.SetTunings(configPage3.idleKP, configPage3.idleKI, configPage3.idleKD);
|
||||
idlePID.SetMode(AUTOMATIC); //Turn PID on
|
||||
|
@ -146,13 +155,13 @@ void initialiseIdle()
|
|||
//Case 2 is Stepper open loop
|
||||
iacStepTable.xSize = 10;
|
||||
iacStepTable.valueSize = SIZE_BYTE;
|
||||
iacStepTable.values = configPage4.iacOLStepVal;
|
||||
iacStepTable.axisX = configPage4.iacBins;
|
||||
iacStepTable.values = configPage3.iacOLStepVal;
|
||||
iacStepTable.axisX = configPage3.iacBins;
|
||||
|
||||
iacCrankStepsTable.xSize = 4;
|
||||
iacCrankStepsTable.values = configPage4.iacCrankSteps;
|
||||
iacCrankStepsTable.axisX = configPage4.iacCrankBins;
|
||||
iacStepTime = configPage4.iacStepTime * 1000;
|
||||
iacCrankStepsTable.values = configPage3.iacCrankSteps;
|
||||
iacCrankStepsTable.axisX = configPage3.iacCrankBins;
|
||||
iacStepTime = configPage3.iacStepTime * 1000;
|
||||
|
||||
completedHomeSteps = 0;
|
||||
idleStepper.curIdleStep = 0;
|
||||
|
@ -163,20 +172,20 @@ void initialiseIdle()
|
|||
//Case 5 is Stepper closed loop
|
||||
iacClosedLoopTable.xSize = 10;
|
||||
iacClosedLoopTable.valueSize = SIZE_BYTE;
|
||||
iacClosedLoopTable.values = configPage4.iacCLValues;
|
||||
iacClosedLoopTable.axisX = configPage4.iacBins;
|
||||
iacClosedLoopTable.values = configPage3.iacCLValues;
|
||||
iacClosedLoopTable.axisX = configPage3.iacBins;
|
||||
|
||||
iacCrankStepsTable.xSize = 4;
|
||||
iacCrankStepsTable.values = configPage4.iacCrankSteps;
|
||||
iacCrankStepsTable.axisX = configPage4.iacCrankBins;
|
||||
iacStepTime = configPage4.iacStepTime * 1000;
|
||||
iacCrankStepsTable.values = configPage3.iacCrankSteps;
|
||||
iacCrankStepsTable.axisX = configPage3.iacCrankBins;
|
||||
iacStepTime = configPage3.iacStepTime * 1000;
|
||||
|
||||
completedHomeSteps = 0;
|
||||
idleCounter = 0;
|
||||
idleStepper.curIdleStep = 0;
|
||||
idleStepper.stepperStatus = SOFF;
|
||||
|
||||
idlePID.SetOutputLimits(0, (configPage4.iacStepHome * 3)); //Maximum number of steps probably needs its own setting
|
||||
idlePID.SetOutputLimits(0, (configPage3.iacStepHome * 3)); //Maximum number of steps probably needs its own setting
|
||||
idlePID.SetTunings(configPage3.idleKP, configPage3.idleKI, configPage3.idleKD);
|
||||
idlePID.SetMode(AUTOMATIC); //Turn PID on
|
||||
break;
|
||||
|
@ -185,21 +194,21 @@ void initialiseIdle()
|
|||
//Well this just shouldn't happen
|
||||
break;
|
||||
}
|
||||
idleInitComplete = configPage4.iacAlgorithm; //Sets which idle method was initialised
|
||||
idleInitComplete = configPage3.iacAlgorithm; //Sets which idle method was initialised
|
||||
currentStatus.idleLoad = 0;
|
||||
}
|
||||
|
||||
void idleControl()
|
||||
{
|
||||
if(idleInitComplete != configPage4.iacAlgorithm) { initialiseIdle(); }
|
||||
if(idleInitComplete != configPage3.iacAlgorithm) { initialiseIdle(); }
|
||||
|
||||
switch(configPage4.iacAlgorithm)
|
||||
switch(configPage3.iacAlgorithm)
|
||||
{
|
||||
case IAC_ALGORITHM_NONE: //Case 0 is no idle control ('None')
|
||||
break;
|
||||
|
||||
case IAC_ALGORITHM_ONOFF: //Case 1 is on/off idle control
|
||||
if ( (currentStatus.coolant + CALIBRATION_TEMPERATURE_OFFSET) < configPage4.iacFastTemp) //All temps are offset by 40 degrees
|
||||
if ( (currentStatus.coolant + CALIBRATION_TEMPERATURE_OFFSET) < configPage3.iacFastTemp) //All temps are offset by 40 degrees
|
||||
{
|
||||
digitalWrite(pinIdle1, HIGH);
|
||||
idleOn = true;
|
||||
|
@ -261,7 +270,7 @@ void idleControl()
|
|||
{
|
||||
//Only do a lookup of the required value around 4 times per second. Any more than this can create too much jitter and require a hyster value that is too high
|
||||
idleStepper.targetIdleStep = table2D_getValue(&iacStepTable, (currentStatus.coolant + CALIBRATION_TEMPERATURE_OFFSET)) * 3; //All temps are offset by 40 degrees. Step counts are divided by 3 in TS. Multiply back out here
|
||||
iacStepTime = configPage4.iacStepTime * 1000;
|
||||
iacStepTime = configPage3.iacStepTime * 1000;
|
||||
}
|
||||
doStep();
|
||||
}
|
||||
|
@ -277,7 +286,7 @@ void idleControl()
|
|||
{
|
||||
//This only needs to be run very infrequently, once every 32 calls to idleControl(). This is approx. once per second
|
||||
idlePID.SetTunings(configPage3.idleKP, configPage3.idleKI, configPage3.idleKD);
|
||||
iacStepTime = configPage4.iacStepTime * 1000;
|
||||
iacStepTime = configPage3.iacStepTime * 1000;
|
||||
}
|
||||
|
||||
idle_cl_target_rpm = table2D_getValue(&iacClosedLoopTable, currentStatus.coolant + CALIBRATION_TEMPERATURE_OFFSET) * 10; //All temps are offset by 40 degrees
|
||||
|
@ -305,7 +314,7 @@ False: If the motor has not yet been homed. Will also perform another homing ste
|
|||
static inline byte isStepperHomed()
|
||||
{
|
||||
bool isHomed = true; //As it's the most common scenario, default value is true
|
||||
if( completedHomeSteps < (configPage4.iacStepHome * 3) ) //Home steps are divided by 3 from TS
|
||||
if( completedHomeSteps < (configPage3.iacStepHome * 3) ) //Home steps are divided by 3 from TS
|
||||
{
|
||||
digitalWrite(pinStepperDir, STEPPER_BACKWARD); //Sets stepper direction to backwards
|
||||
digitalWrite(pinStepperStep, HIGH);
|
||||
|
@ -360,7 +369,7 @@ Performs a step
|
|||
*/
|
||||
static inline void doStep()
|
||||
{
|
||||
if ( (idleStepper.targetIdleStep <= (idleStepper.curIdleStep - configPage4.iacStepHyster)) || (idleStepper.targetIdleStep >= (idleStepper.curIdleStep + configPage4.iacStepHyster)) ) //Hysteris check
|
||||
if ( (idleStepper.targetIdleStep <= (idleStepper.curIdleStep - configPage3.iacStepHyster)) || (idleStepper.targetIdleStep >= (idleStepper.curIdleStep + configPage3.iacStepHyster)) ) //Hysteris check
|
||||
{
|
||||
if(idleStepper.targetIdleStep < idleStepper.curIdleStep) { digitalWrite(pinStepperDir, STEPPER_BACKWARD); idleStepper.curIdleStep--; }//Sets stepper direction to backwards
|
||||
else if (idleStepper.targetIdleStep > idleStepper.curIdleStep) { digitalWrite(pinStepperDir, STEPPER_FORWARD); idleStepper.curIdleStep++; }//Sets stepper direction to forwards
|
||||
|
@ -376,12 +385,12 @@ static inline void doStep()
|
|||
//This function simply turns off the idle PWM and sets the pin low
|
||||
static inline void disableIdle()
|
||||
{
|
||||
if( (configPage4.iacAlgorithm == IAC_ALGORITHM_PWM_CL) || (configPage4.iacAlgorithm == IAC_ALGORITHM_PWM_OL) )
|
||||
if( (configPage3.iacAlgorithm == IAC_ALGORITHM_PWM_CL) || (configPage3.iacAlgorithm == IAC_ALGORITHM_PWM_OL) )
|
||||
{
|
||||
IDLE_TIMER_DISABLE();
|
||||
digitalWrite(pinIdle1, LOW);
|
||||
}
|
||||
else if ( (configPage4.iacAlgorithm == IAC_ALGORITHM_STEP_CL) || (configPage4.iacAlgorithm == IAC_ALGORITHM_STEP_OL) )
|
||||
else if ( (configPage3.iacAlgorithm == IAC_ALGORITHM_STEP_CL) || (configPage3.iacAlgorithm == IAC_ALGORITHM_STEP_OL) )
|
||||
{
|
||||
digitalWrite(pinStepperEnable, HIGH); //Disable the DRV8825
|
||||
idleStepper.targetIdleStep = idleStepper.curIdleStep; //Don't try to move anymore
|
||||
|
@ -392,11 +401,11 @@ static inline void disableIdle()
|
|||
//Typically this is enabling the PWM interrupt
|
||||
static inline void enableIdle()
|
||||
{
|
||||
if( (configPage4.iacAlgorithm == IAC_ALGORITHM_PWM_CL) || (configPage4.iacAlgorithm == IAC_ALGORITHM_PWM_OL) )
|
||||
if( (configPage3.iacAlgorithm == IAC_ALGORITHM_PWM_CL) || (configPage3.iacAlgorithm == IAC_ALGORITHM_PWM_OL) )
|
||||
{
|
||||
IDLE_TIMER_ENABLE();
|
||||
}
|
||||
else if ( (configPage4.iacAlgorithm == IAC_ALGORITHM_STEP_CL) || (configPage4.iacAlgorithm == IAC_ALGORITHM_STEP_OL) )
|
||||
else if ( (configPage3.iacAlgorithm == IAC_ALGORITHM_STEP_CL) || (configPage3.iacAlgorithm == IAC_ALGORITHM_STEP_OL) )
|
||||
{
|
||||
|
||||
}
|
||||
|
@ -407,38 +416,37 @@ ISR(TIMER4_COMPC_vect)
|
|||
#elif defined (CORE_TEENSY) || defined (CORE_STM32)
|
||||
static inline void idleInterrupt() //Most ARM chips can simply call a function
|
||||
#endif
|
||||
#if defined(CORE_AVR) || defined (CORE_TEENSY)
|
||||
{
|
||||
if (idle_pwm_state)
|
||||
{
|
||||
if (configPage4.iacPWMdir == 0)
|
||||
if (configPage3.iacPWMdir == 0)
|
||||
{
|
||||
//Normal direction
|
||||
*idle_pin_port &= ~(idle_pin_mask); // Switch pin to low (1 pin mode)
|
||||
if(configPage4.iacChannels == 1) { *idle2_pin_port |= (idle2_pin_mask); } //If 2 idle channels are in use, flip idle2 to be the opposite of idle1
|
||||
if(configPage3.iacChannels == 1) { *idle2_pin_port |= (idle2_pin_mask); } //If 2 idle channels are in use, flip idle2 to be the opposite of idle1
|
||||
}
|
||||
else
|
||||
{
|
||||
//Reversed direction
|
||||
*idle_pin_port |= (idle_pin_mask); // Switch pin high
|
||||
if(configPage4.iacChannels == 1) { *idle2_pin_port &= ~(idle2_pin_mask); } //If 2 idle channels are in use, flip idle2 to be the opposite of idle1
|
||||
if(configPage3.iacChannels == 1) { *idle2_pin_port &= ~(idle2_pin_mask); } //If 2 idle channels are in use, flip idle2 to be the opposite of idle1
|
||||
}
|
||||
IDLE_COMPARE = IDLE_COUNTER + (idle_pwm_max_count - idle_pwm_cur_value);
|
||||
idle_pwm_state = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (configPage4.iacPWMdir == 0)
|
||||
if (configPage3.iacPWMdir == 0)
|
||||
{
|
||||
//Normal direction
|
||||
*idle_pin_port |= (idle_pin_mask); // Switch pin high
|
||||
if(configPage4.iacChannels == 1) { *idle2_pin_port &= ~(idle2_pin_mask); } //If 2 idle channels are in use, flip idle2 to be the opposite of idle1
|
||||
if(configPage3.iacChannels == 1) { *idle2_pin_port &= ~(idle2_pin_mask); } //If 2 idle channels are in use, flip idle2 to be the opposite of idle1
|
||||
}
|
||||
else
|
||||
{
|
||||
//Reversed direction
|
||||
*idle_pin_port &= ~(idle_pin_mask); // Switch pin to low (1 pin mode)
|
||||
if(configPage4.iacChannels == 1) { *idle2_pin_port |= (idle2_pin_mask); } //If 2 idle channels are in use, flip idle2 to be the opposite of idle1
|
||||
if(configPage3.iacChannels == 1) { *idle2_pin_port |= (idle2_pin_mask); } //If 2 idle channels are in use, flip idle2 to be the opposite of idle1
|
||||
}
|
||||
IDLE_COMPARE = IDLE_COUNTER + idle_pwm_target_value;
|
||||
idle_pwm_cur_value = idle_pwm_target_value;
|
||||
|
@ -446,8 +454,3 @@ static inline void idleInterrupt() //Most ARM chips can simply call a function
|
|||
}
|
||||
|
||||
}
|
||||
#elif defined (CORE_STM32)
|
||||
{
|
||||
//No PWM idle for STM32 yet
|
||||
}
|
||||
#endif
|
||||
|
|
|
@ -4,4 +4,14 @@
|
|||
int fastMap1023toX(int, int);
|
||||
unsigned long percentage(byte, unsigned long);
|
||||
|
||||
#define degreesToUS(degrees) (decoderIsLowRes == true ) ? ((degrees * 166666UL) / currentStatus.RPM) : degrees * (unsigned long)timePerDegree
|
||||
#define uSToDegrees(time) (((unsigned long)time * currentStatus.RPM) / 166666)
|
||||
#define DIV_ROUND_CLOSEST(n, d) ((((n) < 0) ^ ((d) < 0)) ? (((n) - (d)/2)/(d)) : (((n) + (d)/2)/(d)))
|
||||
|
||||
//This is a dedicated function that specifically handles the case of mapping 0-1023 values into a 0 to X range
|
||||
//This is a common case because it means converting from a standard 10-bit analog input to a byte or 10-bit analog into 0-511 (Eg the temperature readings)
|
||||
#define fastMap1023toX(x, out_max) ( ((unsigned long)x * out_max) >> 10)
|
||||
//This is a new version that allows for out_min
|
||||
#define fastMap10Bit(x, out_min, out_max) ( ( ((unsigned long)x * (out_max-out_min)) >> 10 ) + out_min)
|
||||
|
||||
#endif
|
||||
|
|
|
@ -1,7 +1,5 @@
|
|||
#include "maths.h"
|
||||
|
||||
#define DIV_ROUND_CLOSEST(n, d) ((((n) < 0) ^ ((d) < 0)) ? (((n) - (d)/2)/(d)) : (((n) + (d)/2)/(d)))
|
||||
|
||||
//Replace the standard arduino map() function to use the div function instead
|
||||
int fastMap(unsigned long x, int in_min, int in_max, int out_min, int out_max)
|
||||
{
|
||||
|
@ -14,12 +12,6 @@ int fastMap(unsigned long x, int in_min, int in_max, int out_min, int out_max)
|
|||
//return (x - in_min) * (out_max - out_min) / (in_max - in_min) + out_min;
|
||||
}
|
||||
|
||||
//This is a dedicated function that specifically handles the case of mapping 0-1023 values into a 0 to X range
|
||||
//This is a common case because it means converting from a standard 10-bit analog input to a byte or 10-bit analog into 0-511 (Eg the temperature readings)
|
||||
//int fastMap1023toX(unsigned long x, int in_min, int in_max, int out_min, int out_max)
|
||||
//removed ununsed variables, in_min and out_min is aways 0, in_max is aways 1023
|
||||
#define fastMap1023toX(x, out_max) ( ((unsigned long)x * out_max) >> 10)
|
||||
|
||||
/*
|
||||
The following are all fast versions of specific divisions
|
||||
Ref: http://www.hackersdelight.org/divcMore.pdf
|
||||
|
|
|
@ -16,6 +16,12 @@ inline void endCoil4Charge();
|
|||
inline void beginCoil5Charge();
|
||||
inline void endCoil5Charge();
|
||||
|
||||
//The following functions are used specifically for the trailing coil on rotary engines. They are separate as they also control the switching of the trailing select pin
|
||||
inline void beginTrailingCoilCharge();
|
||||
inline void endTrailingCoilCharge1();
|
||||
inline void endTrailingCoilCharge2();
|
||||
|
||||
|
||||
#define openInjector1() *inj1_pin_port |= (inj1_pin_mask); BIT_SET(currentStatus.squirt, BIT_SQUIRT_INJ1)
|
||||
#define closeInjector1() *inj1_pin_port &= ~(inj1_pin_mask); BIT_CLEAR(currentStatus.squirt, BIT_SQUIRT_INJ1)
|
||||
#define openInjector2() *inj2_pin_port |= (inj2_pin_mask); BIT_SET(currentStatus.squirt, BIT_SQUIRT_INJ2)
|
||||
|
|
|
@ -18,12 +18,14 @@ volatile bool tachoAlt = true;
|
|||
inline void beginCoil5Charge() { digitalWrite(pinCoil5, coilHIGH); TACH_PULSE_LOW(); }
|
||||
inline void endCoil5Charge() { digitalWrite(pinCoil5, coilLOW); TACH_PULSE_HIGH(); }
|
||||
|
||||
|
||||
inline void beginTrailingCoilCharge() { digitalWrite(pinCoil2, coilHIGH); }
|
||||
inline void endTrailingCoilCharge1() { digitalWrite(pinCoil2, coilLOW); *ign3_pin_port |= ign3_pin_mask; } //Sets ign3 (Trailing select) high
|
||||
inline void endTrailingCoilCharge2() { digitalWrite(pinCoil2, coilLOW); *ign3_pin_port &= ~(ign3_pin_mask); } //sets ign3 (Trailing select) low
|
||||
|
||||
//As above but for ignition (Wasted COP mode)
|
||||
void beginCoil1and3Charge() { digitalWrite(pinCoil1, coilHIGH); digitalWrite(pinCoil3, coilHIGH); digitalWrite(pinTachOut, LOW); }
|
||||
void endCoil1and3Charge() { digitalWrite(pinCoil1, coilLOW); digitalWrite(pinCoil3, coilLOW); }
|
||||
void beginCoil2and4Charge() { digitalWrite(pinCoil2, coilHIGH); digitalWrite(pinCoil4, coilHIGH); digitalWrite(pinTachOut, LOW); }
|
||||
void endCoil2and4Charge() { digitalWrite(pinCoil2, coilLOW); digitalWrite(pinCoil4, coilLOW); }
|
||||
void beginCoil1and3Charge() { digitalWrite(pinCoil1, coilHIGH); digitalWrite(pinCoil3, coilHIGH); TACH_PULSE_LOW(); }
|
||||
void endCoil1and3Charge() { digitalWrite(pinCoil1, coilLOW); digitalWrite(pinCoil3, coilLOW); TACH_PULSE_HIGH(); }
|
||||
void beginCoil2and4Charge() { digitalWrite(pinCoil2, coilHIGH); digitalWrite(pinCoil4, coilHIGH); TACH_PULSE_LOW(); }
|
||||
void endCoil2and4Charge() { digitalWrite(pinCoil2, coilLOW); digitalWrite(pinCoil4, coilLOW); TACH_PULSE_HIGH(); }
|
||||
|
||||
void nullCallback() { return; }
|
||||
|
|
|
@ -162,13 +162,57 @@ See page 136 of the processors datasheet: http://www.atmel.com/Images/doc2549.pd
|
|||
#define uS_TO_TIMER_COMPARE_SLOW(uS) ((uS * 15) >> 5)
|
||||
|
||||
#elif defined(CORE_STM32)
|
||||
//Placeholders ONLY!
|
||||
|
||||
//https://github.com/rogerclarkmelbourne/Arduino_STM32/blob/master/STM32F4/cores/maple/libmaple/timer.h#L51
|
||||
#define MAX_TIMER_PERIOD 131070 //The longest period of time (in uS) that the timer can permit (IN this case it is 65535 * 2, as each timer tick is 2uS)
|
||||
#define uS_TO_TIMER_COMPARE(uS) (uS >> 1) //Converts a given number of uS into the required number of timer ticks until that time has passed.
|
||||
#define uS_TO_TIMER_COMPARE_SLOW(uS) (uS >> 1) //Converts a given number of uS into the required number of timer ticks until that time has passed.
|
||||
#if defined(ARDUINO_ARCH_STM32) // STM32GENERIC core
|
||||
#include "HardwareTimer.h"
|
||||
#define FUEL1_COUNTER (TIM2)->CNT
|
||||
#define FUEL2_COUNTER (TIM2)->CNT
|
||||
#define FUEL3_COUNTER (TIM2)->CNT
|
||||
#define FUEL4_COUNTER (TIM2)->CNT
|
||||
#define FUEL5_COUNTER (TIM2)->CNT
|
||||
|
||||
#define IGN1_COUNTER (TIM3)->CNT
|
||||
#define IGN2_COUNTER (TIM3)->CNT
|
||||
#define IGN3_COUNTER (TIM3)->CNT
|
||||
#define IGN4_COUNTER (TIM3)->CNT
|
||||
#define IGN5_COUNTER (TIM3)->CNT
|
||||
|
||||
#define FUEL1_COMPARE (TIM2)->CCR1
|
||||
#define FUEL2_COMPARE (TIM2)->CCR2
|
||||
#define FUEL3_COMPARE (TIM2)->CCR3
|
||||
#define FUEL4_COMPARE (TIM2)->CCR4
|
||||
|
||||
#define IGN1_COMPARE (TIM3)->CCR1
|
||||
#define IGN2_COMPARE (TIM3)->CCR2
|
||||
#define IGN3_COMPARE (TIM3)->CCR3
|
||||
#define IGN4_COMPARE (TIM3)->CCR4
|
||||
#define IGN5_COMPARE (TIM3)->CCR1
|
||||
|
||||
//https://github.com/rogerclarkmelbourne/Arduino_STM32/blob/754bc2969921f1ef262bd69e7faca80b19db7524/STM32F1/system/libmaple/include/libmaple/timer.h#L444
|
||||
#define FUEL1_TIMER_ENABLE() (TIM2)->CCER |= TIM_CCER_CC1E
|
||||
#define FUEL2_TIMER_ENABLE() (TIM2)->CCER |= TIM_CCER_CC2E
|
||||
#define FUEL3_TIMER_ENABLE() (TIM2)->CCER |= TIM_CCER_CC3E
|
||||
#define FUEL4_TIMER_ENABLE() (TIM2)->CCER |= TIM_CCER_CC4E
|
||||
|
||||
#define IGN1_TIMER_ENABLE() (TIM3)->CCER |= TIM_CCER_CC1E
|
||||
#define IGN2_TIMER_ENABLE() (TIM3)->CCER |= TIM_CCER_CC2E
|
||||
#define IGN3_TIMER_ENABLE() (TIM3)->CCER |= TIM_CCER_CC3E
|
||||
#define IGN4_TIMER_ENABLE() (TIM3)->CCER |= TIM_CCER_CC4E
|
||||
#define IGN5_TIMER_ENABLE() (TIM1)->CCER |= TIM_CCER_CC1E
|
||||
|
||||
#define FUEL1_TIMER_DISABLE() (TIM2)->CCER &= ~TIM_CCER_CC1E
|
||||
#define FUEL2_TIMER_DISABLE() (TIM2)->CCER &= ~TIM_CCER_CC2E
|
||||
#define FUEL3_TIMER_DISABLE() (TIM2)->CCER &= ~TIM_CCER_CC3E
|
||||
#define FUEL4_TIMER_DISABLE() (TIM2)->CCER &= ~TIM_CCER_CC4E
|
||||
|
||||
#define IGN1_TIMER_DISABLE() (TIM3)->CCER &= ~TIM_CCER_CC1E
|
||||
#define IGN2_TIMER_DISABLE() (TIM3)->CCER &= ~TIM_CCER_CC2E
|
||||
#define IGN3_TIMER_DISABLE() (TIM3)->CCER &= ~TIM_CCER_CC3E
|
||||
#define IGN4_TIMER_DISABLE() (TIM3)->CCER &= ~TIM_CCER_CC4E
|
||||
#define IGN5_TIMER_DISABLE() (TIM1)->CCER &= ~TIM_CCER_CC1E
|
||||
#else //libmaple core aka STM32DUINO
|
||||
#define FUEL1_COUNTER (TIMER2->regs).gen->CNT
|
||||
#define FUEL2_COUNTER (TIMER2->regs).gen->CNT
|
||||
#define FUEL3_COUNTER (TIMER2->regs).gen->CNT
|
||||
|
@ -214,7 +258,7 @@ See page 136 of the processors datasheet: http://www.atmel.com/Images/doc2549.pd
|
|||
#define IGN3_TIMER_DISABLE() (TIMER3->regs).gen->CCER &= ~TIMER_CCER_CC3E
|
||||
#define IGN4_TIMER_DISABLE() (TIMER3->regs).gen->CCER &= ~TIMER_CCER_CC4E
|
||||
#define IGN5_TIMER_DISABLE() (TIMER1->regs).gen->CCER &= ~TIMER_CCER_CC1E
|
||||
|
||||
#endif
|
||||
#endif
|
||||
|
||||
void initialiseSchedulers();
|
||||
|
|
|
@ -161,13 +161,29 @@ void initialiseSchedulers()
|
|||
NVIC_ENABLE_IRQ(IRQ_FTM1);
|
||||
|
||||
#elif defined(CORE_STM32)
|
||||
#if defined(ARDUINO_ARCH_STM32) // STM32GENERIC core
|
||||
//see https://github.com/rogerclarkmelbourne/Arduino_STM32/blob/754bc2969921f1ef262bd69e7faca80b19db7524/STM32F1/system/libmaple/include/libmaple/timer.h#L444
|
||||
(TIMER1->regs).bas->PSC = (CYCLES_PER_MICROSECOND << 1) - 1; //2us resolution
|
||||
(TIMER2->regs).bas->PSC = (CYCLES_PER_MICROSECOND << 1) - 1; //2us resolution
|
||||
(TIMER3->regs).bas->PSC = (CYCLES_PER_MICROSECOND << 1) - 1; //2us resolution
|
||||
// Alternative 2us resolution:
|
||||
//TimerX.setPrescaleFactor(CYCLES_PER_MICROSECOND * 2U);
|
||||
Timer1.setPrescaleFactor((HAL_RCC_GetHCLKFreq() * 2U)-1); //2us resolution
|
||||
Timer2.setPrescaleFactor((HAL_RCC_GetHCLKFreq() * 2U)-1); //2us resolution
|
||||
Timer3.setPrescaleFactor((HAL_RCC_GetHCLKFreq() * 2U)-1); //2us resolution
|
||||
Timer2.setMode(1, TIMER_OUTPUT_COMPARE);
|
||||
Timer2.setMode(2, TIMER_OUTPUT_COMPARE);
|
||||
Timer2.setMode(3, TIMER_OUTPUT_COMPARE);
|
||||
Timer2.setMode(4, TIMER_OUTPUT_COMPARE);
|
||||
|
||||
Timer3.setMode(1, TIMER_OUTPUT_COMPARE);
|
||||
Timer3.setMode(2, TIMER_OUTPUT_COMPARE);
|
||||
Timer3.setMode(3, TIMER_OUTPUT_COMPARE);
|
||||
Timer3.setMode(4, TIMER_OUTPUT_COMPARE);
|
||||
Timer1.setMode(1, TIMER_OUTPUT_COMPARE);
|
||||
|
||||
#else //libmaple core aka STM32DUINO
|
||||
//see https://github.com/rogerclarkmelbourne/Arduino_STM32/blob/754bc2969921f1ef262bd69e7faca80b19db7524/STM32F1/system/libmaple/include/libmaple/timer.h#L444
|
||||
//(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
|
||||
Timer1.setPrescaleFactor((72 * 2U)-1); //2us resolution
|
||||
Timer2.setPrescaleFactor((36 * 2U)-1); //2us resolution
|
||||
Timer3.setPrescaleFactor((36 * 2U)-1); //2us resolution
|
||||
Timer2.setMode(TIMER_CH1, TIMER_OUTPUT_COMPARE);
|
||||
Timer2.setMode(TIMER_CH2, TIMER_OUTPUT_COMPARE);
|
||||
Timer2.setMode(TIMER_CH3, TIMER_OUTPUT_COMPARE);
|
||||
|
@ -178,6 +194,7 @@ void initialiseSchedulers()
|
|||
Timer3.setMode(TIMER_CH3, TIMER_OUTPUT_COMPARE);
|
||||
Timer3.setMode(TIMER_CH4, TIMER_OUTPUT_COMPARE);
|
||||
|
||||
#endif
|
||||
Timer2.attachInterrupt(1, fuelSchedule1Interrupt);
|
||||
Timer2.attachInterrupt(2, fuelSchedule2Interrupt);
|
||||
Timer2.attachInterrupt(3, fuelSchedule3Interrupt);
|
||||
|
@ -187,7 +204,11 @@ void initialiseSchedulers()
|
|||
Timer3.attachInterrupt(2, ignitionSchedule2Interrupt);
|
||||
Timer3.attachInterrupt(3, ignitionSchedule3Interrupt);
|
||||
Timer3.attachInterrupt(4, ignitionSchedule4Interrupt);
|
||||
Timer1.attachInterrupt(1, ignitionSchedule5Interrupt);
|
||||
|
||||
Timer1.resume();
|
||||
Timer2.resume();
|
||||
Timer3.resume();
|
||||
#endif
|
||||
|
||||
fuelSchedule1.Status = OFF;
|
||||
|
@ -445,6 +466,14 @@ void setIgnitionSchedule3(void (*startCallback)(), unsigned long timeout, unsign
|
|||
interrupts();
|
||||
IGN3_TIMER_ENABLE();
|
||||
}
|
||||
else
|
||||
{
|
||||
//If the schedule is already running, we can set the next schedule so it is ready to go
|
||||
//This is required in cases of high rpm and high DC where there otherwise would not be enough time to set the schedule
|
||||
ignitionSchedule3.nextStartCompare = IGN3_COUNTER + uS_TO_TIMER_COMPARE(timeout);
|
||||
ignitionSchedule3.nextEndCompare = ignitionSchedule3.nextStartCompare + uS_TO_TIMER_COMPARE(duration);
|
||||
ignitionSchedule3.hasNextSchedule = true;
|
||||
}
|
||||
}
|
||||
void setIgnitionSchedule4(void (*startCallback)(), unsigned long timeout, unsigned long duration, void(*endCallback)())
|
||||
{
|
||||
|
@ -469,6 +498,14 @@ void setIgnitionSchedule4(void (*startCallback)(), unsigned long timeout, unsign
|
|||
interrupts();
|
||||
IGN4_TIMER_ENABLE();
|
||||
}
|
||||
else
|
||||
{
|
||||
//If the schedule is already running, we can set the next schedule so it is ready to go
|
||||
//This is required in cases of high rpm and high DC where there otherwise would not be enough time to set the schedule
|
||||
ignitionSchedule4.nextStartCompare = IGN4_COUNTER + uS_TO_TIMER_COMPARE_SLOW(timeout);
|
||||
ignitionSchedule4.nextEndCompare = ignitionSchedule4.nextStartCompare + uS_TO_TIMER_COMPARE_SLOW(duration);
|
||||
ignitionSchedule4.hasNextSchedule = true;
|
||||
}
|
||||
}
|
||||
void setIgnitionSchedule5(void (*startCallback)(), unsigned long timeout, unsigned long duration, void(*endCallback)())
|
||||
{
|
||||
|
@ -653,7 +690,6 @@ static inline void ignitionSchedule1Interrupt() //Most ARM chips can simply call
|
|||
ignitionSchedule1.StartCallback();
|
||||
ignitionSchedule1.Status = RUNNING; //Set the status to be in progress (ie The start callback has been called, but not the end callback)
|
||||
ignitionSchedule1.startTime = micros();
|
||||
ign1LastRev = currentStatus.startRevolutions;
|
||||
IGN1_COMPARE = ignitionSchedule1.endCompare;
|
||||
}
|
||||
else if (ignitionSchedule1.Status == RUNNING)
|
||||
|
@ -677,7 +713,6 @@ static inline void ignitionSchedule2Interrupt() //Most ARM chips can simply call
|
|||
ignitionSchedule2.StartCallback();
|
||||
ignitionSchedule2.Status = RUNNING; //Set the status to be in progress (ie The start callback has been called, but not the end callback)
|
||||
ignitionSchedule2.startTime = micros();
|
||||
ign2LastRev = currentStatus.startRevolutions;
|
||||
IGN2_COMPARE = ignitionSchedule2.endCompare; //OCR5B = TCNT5 + (ignitionSchedule2.duration >> 2);
|
||||
}
|
||||
else if (ignitionSchedule2.Status == RUNNING)
|
||||
|
@ -701,7 +736,6 @@ static inline void ignitionSchedule3Interrupt() //Most ARM chips can simply call
|
|||
ignitionSchedule3.StartCallback();
|
||||
ignitionSchedule3.Status = RUNNING; //Set the status to be in progress (ie The start callback has been called, but not the end callback)
|
||||
ignitionSchedule3.startTime = micros();
|
||||
ign3LastRev = currentStatus.startRevolutions;
|
||||
IGN3_COMPARE = ignitionSchedule3.endCompare; //OCR5C = TCNT5 + (ignitionSchedule3.duration >> 2);
|
||||
}
|
||||
else if (ignitionSchedule3.Status == RUNNING)
|
||||
|
@ -710,7 +744,17 @@ static inline void ignitionSchedule3Interrupt() //Most ARM chips can simply call
|
|||
ignitionSchedule3.EndCallback();
|
||||
ignitionSchedule3.schedulesSet = 0;
|
||||
ignitionCount += 1; //Increment the igintion counter
|
||||
IGN3_TIMER_DISABLE();
|
||||
|
||||
//If there is a next schedule queued up, activate it
|
||||
if(ignitionSchedule3.hasNextSchedule == true)
|
||||
{
|
||||
IGN3_COMPARE = ignitionSchedule3.nextStartCompare;
|
||||
ignitionSchedule3.endCompare = ignitionSchedule3.nextEndCompare;
|
||||
ignitionSchedule3.Status = PENDING;
|
||||
ignitionSchedule3.schedulesSet = 1;
|
||||
ignitionSchedule3.hasNextSchedule = false;
|
||||
}
|
||||
else { IGN3_TIMER_DISABLE(); }
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -725,7 +769,6 @@ static inline void ignitionSchedule4Interrupt() //Most ARM chips can simply call
|
|||
ignitionSchedule4.StartCallback();
|
||||
ignitionSchedule4.Status = RUNNING; //Set the status to be in progress (ie The start callback has been called, but not the end callback)
|
||||
ignitionSchedule4.startTime = micros();
|
||||
ign4LastRev = currentStatus.startRevolutions;
|
||||
IGN4_COMPARE = ignitionSchedule4.endCompare;
|
||||
}
|
||||
else if (ignitionSchedule4.Status == RUNNING)
|
||||
|
@ -734,7 +777,17 @@ static inline void ignitionSchedule4Interrupt() //Most ARM chips can simply call
|
|||
ignitionSchedule4.EndCallback();
|
||||
ignitionSchedule4.schedulesSet = 0;
|
||||
ignitionCount += 1; //Increment the igintion counter
|
||||
IGN4_TIMER_DISABLE();
|
||||
|
||||
//If there is a next schedule queued up, activate it
|
||||
if(ignitionSchedule4.hasNextSchedule == true)
|
||||
{
|
||||
IGN4_COMPARE = ignitionSchedule4.nextStartCompare;
|
||||
ignitionSchedule4.endCompare = ignitionSchedule4.nextEndCompare;
|
||||
ignitionSchedule4.Status = PENDING;
|
||||
ignitionSchedule4.schedulesSet = 1;
|
||||
ignitionSchedule4.hasNextSchedule = false;
|
||||
}
|
||||
else { IGN4_TIMER_DISABLE(); }
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -749,7 +802,6 @@ static inline void ignitionSchedule5Interrupt() //Most ARM chips can simply call
|
|||
ignitionSchedule5.StartCallback();
|
||||
ignitionSchedule5.Status = RUNNING; //Set the status to be in progress (ie The start callback has been called, but not the end callback)
|
||||
ignitionSchedule5.startTime = micros();
|
||||
ign5LastRev = currentStatus.startRevolutions;
|
||||
IGN5_COMPARE = ignitionSchedule5.endCompare;
|
||||
}
|
||||
else if (ignitionSchedule5.Status == RUNNING)
|
||||
|
|
|
@ -12,6 +12,7 @@
|
|||
#define ADCFILTER_O2 128
|
||||
#define ADCFILTER_BAT 128
|
||||
#define ADCFILTER_MAP 20 //This is only used on Instantaneous MAP readings and is intentionally very weak to allow for faster response
|
||||
#define ADCFILTER_BARO 64
|
||||
|
||||
#define BARO_MIN 87
|
||||
#define BARO_MAX 108
|
||||
|
|
|
@ -61,10 +61,12 @@ void instanteneousMAPReading()
|
|||
if( (tempReading >= VALID_MAP_MAX) || (tempReading <= VALID_MAP_MIN) ) { mapErrorCount += 1; }
|
||||
else { mapErrorCount = 0; }
|
||||
|
||||
currentStatus.mapADC = ADC_FILTER(tempReading, ADCFILTER_MAP, currentStatus.mapADC); //Very weak filter
|
||||
|
||||
currentStatus.MAP = fastMap1023toX(currentStatus.mapADC, configPage1.mapMax); //Get the current MAP value
|
||||
//During startup a call is made here to get the baro reading. In this case, we can't apply the ADC filter
|
||||
if(initialisationComplete == true) { currentStatus.mapADC = ADC_FILTER(tempReading, ADCFILTER_MAP, currentStatus.mapADC); } //Very weak filter
|
||||
else { currentStatus.mapADC = tempReading; } //Baro reading (No filter)
|
||||
|
||||
currentStatus.MAP = fastMap10Bit(currentStatus.mapADC, configPage1.mapMin, configPage1.mapMax); //Get the current MAP value
|
||||
if(currentStatus.MAP < 0) { currentStatus.MAP = 0; } //Sanity check
|
||||
|
||||
}
|
||||
|
||||
|
@ -96,7 +98,10 @@ void readMAP()
|
|||
//Error check
|
||||
if( (tempReading < VALID_MAP_MAX) && (tempReading > VALID_MAP_MIN) )
|
||||
{
|
||||
MAPrunningValue = MAPrunningValue + (unsigned long)tempReading; //Add the current reading onto the total
|
||||
currentStatus.mapADC = ADC_FILTER(tempReading, ADCFILTER_MAP, currentStatus.mapADC);
|
||||
MAPrunningValue += currentStatus.mapADC; //Add the current reading onto the total
|
||||
//Old method (No filter)
|
||||
//MAPrunningValue = MAPrunningValue + (unsigned long)tempReading;
|
||||
MAPcount++;
|
||||
}
|
||||
else { mapErrorCount += 1; }
|
||||
|
@ -108,7 +113,9 @@ void readMAP()
|
|||
if( (MAPrunningValue != 0) && (MAPcount != 0) )
|
||||
{
|
||||
currentStatus.mapADC = ldiv(MAPrunningValue, MAPcount).quot;
|
||||
currentStatus.MAP = fastMap1023toX(currentStatus.mapADC, configPage1.mapMax); //Get the current MAP value
|
||||
currentStatus.MAP = fastMap10Bit(currentStatus.mapADC, configPage1.mapMin, configPage1.mapMax); //Get the current MAP value
|
||||
//currentStatus.MAP = fastMap1023toX(currentStatus.mapADC, configPage1.mapMax);
|
||||
if(currentStatus.MAP < 0) { currentStatus.MAP = 0; } //Sanity check
|
||||
MAPcurRev = currentStatus.startRevolutions; //Reset the current rev count
|
||||
MAPrunningValue = 0;
|
||||
MAPcount = 0;
|
||||
|
@ -142,7 +149,8 @@ void readMAP()
|
|||
{
|
||||
//Reaching here means that the last cylce has completed and the MAP value should be calculated
|
||||
currentStatus.mapADC = MAPrunningValue;
|
||||
currentStatus.MAP = fastMap1023toX(currentStatus.mapADC, configPage1.mapMax); //Get the current MAP value
|
||||
currentStatus.MAP = fastMap10Bit(currentStatus.mapADC, configPage1.mapMin, configPage1.mapMax); //Get the current MAP value
|
||||
if(currentStatus.MAP < 0) { currentStatus.MAP = 0; } //Sanity check
|
||||
MAPcurRev = currentStatus.startRevolutions; //Reset the current rev count
|
||||
MAPrunningValue = 1023; //Reset the latest value so the next reading will always be lower
|
||||
}
|
||||
|
@ -202,6 +210,25 @@ void readIAT()
|
|||
currentStatus.IAT = iatCalibrationTable[currentStatus.iatADC] - CALIBRATION_TEMPERATURE_OFFSET;
|
||||
}
|
||||
|
||||
void readBaro()
|
||||
{
|
||||
if ( configPage3.useExtBaro != 0 )
|
||||
{
|
||||
int tempReading;
|
||||
// readings
|
||||
#if defined(ANALOG_ISR_MAP)
|
||||
tempReading = AnChannel[pinBaro-A0];
|
||||
#else
|
||||
tempReading = analogRead(pinBaro);
|
||||
tempReading = analogRead(pinBaro);
|
||||
#endif
|
||||
|
||||
currentStatus.baroADC = ADC_FILTER(tempReading, ADCFILTER_BARO, currentStatus.baroADC); //Very weak filter
|
||||
|
||||
currentStatus.baro = fastMap10Bit(currentStatus.baroADC, configPage1.mapMin, configPage1.mapMax); //Get the current MAP value
|
||||
}
|
||||
}
|
||||
|
||||
void readO2()
|
||||
{
|
||||
unsigned int tempReading;
|
||||
|
|
|
@ -52,16 +52,11 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
|||
struct config1 configPage1;
|
||||
struct config2 configPage2;
|
||||
struct config3 configPage3;
|
||||
struct config4 configPage4;
|
||||
struct config10 configPage10;
|
||||
struct config11 configPage11;
|
||||
|
||||
int req_fuel_uS, inj_opentime_uS;
|
||||
|
||||
volatile byte ign1LastRev;
|
||||
volatile byte ign2LastRev;
|
||||
volatile byte ign3LastRev;
|
||||
volatile byte ign4LastRev;
|
||||
volatile byte ign5LastRev;
|
||||
bool ignitionOn = false; //The current state of the ignition system
|
||||
bool fuelOn = false; //The current state of the ignition system
|
||||
bool fuelPumpOn = false; //The current status of the fuel pump
|
||||
|
@ -94,7 +89,7 @@ static byte coilLOW = LOW;
|
|||
static byte fanHIGH = HIGH; // Used to invert the cooling fan output
|
||||
static byte fanLOW = LOW; // Used to invert the cooling fan output
|
||||
|
||||
volatile int mainLoopCount;
|
||||
volatile uint16_t mainLoopCount;
|
||||
byte deltaToothCount = 0; //The last tooth that was used with the deltaV calc
|
||||
int rpmDelta;
|
||||
byte ignitionCount;
|
||||
|
@ -127,14 +122,15 @@ void (*ign4EndFunction)();
|
|||
void (*ign5StartFunction)();
|
||||
void (*ign5EndFunction)();
|
||||
|
||||
int timePerDegree;
|
||||
volatile int timePerDegree;
|
||||
byte degreesPerLoop; //The number of crank degrees that pass for each mainloop of the program
|
||||
volatile bool fpPrimed = false; //Tracks whether or not the fuel pump priming has been completed yet
|
||||
bool initialisationComplete = false; //Tracks whether the setup() functino has run completely
|
||||
|
||||
void setup()
|
||||
{
|
||||
|
||||
initialiseTimers();
|
||||
digitalWrite(LED_BUILTIN, LOW);
|
||||
//Setup the dummy fuel and ignition tables
|
||||
//dummyFuelTable(&fuelTable);
|
||||
//dummyIgnitionTable(&ignitionTable);
|
||||
|
@ -148,20 +144,23 @@ void setup()
|
|||
table3D_setSize(&trim3Table, 6);
|
||||
table3D_setSize(&trim4Table, 6);
|
||||
|
||||
#if defined(CORE_STM32)
|
||||
EEPROM.init();
|
||||
#endif
|
||||
loadConfig();
|
||||
doUpdates(); //Check if any data items need updating (Occurs ith firmware updates)
|
||||
|
||||
Serial.begin(115200);
|
||||
#if defined(__AVR_ATmega1280__) || defined(__AVR_ATmega2560__) //ATmega2561 does not have Serial3
|
||||
if (configPage10.enable_canbus == 1) { Serial3.begin(115200); }
|
||||
if (configPage10.enable_canbus == 1) { CANSerial.begin(115200); }
|
||||
#elif defined(CORE_STM32)
|
||||
if (configPage10.enable_canbus == 1) { Serial2.begin(115200); }
|
||||
if (configPage10.enable_canbus == 1) { CANSerial.begin(115200); }
|
||||
else if (configPage10.enable_canbus == 2)
|
||||
{
|
||||
//enable local can interface
|
||||
}
|
||||
#elif defined(CORE_TEENSY)
|
||||
if (configPage10.enable_canbus == 1) { Serial2.begin(115200); }
|
||||
if (configPage10.enable_canbus == 1) { CANSerial.begin(115200); }
|
||||
else if (configPage10.enable_canbus == 2)
|
||||
{
|
||||
//Teensy onboard CAN not used currently
|
||||
|
@ -182,6 +181,10 @@ void setup()
|
|||
WUETable.xSize = 10;
|
||||
WUETable.values = configPage1.wueValues;
|
||||
WUETable.axisX = configPage2.wueBins;
|
||||
crankingEnrichTable.valueSize = SIZE_BYTE;
|
||||
crankingEnrichTable.xSize = 4;
|
||||
crankingEnrichTable.values = configPage11.crankingEnrichValues;
|
||||
crankingEnrichTable.axisX = configPage11.crankingEnrichBins;
|
||||
|
||||
dwellVCorrectionTable.valueSize = SIZE_BYTE;
|
||||
dwellVCorrectionTable.xSize = 6;
|
||||
|
@ -199,12 +202,21 @@ void setup()
|
|||
IATRetardTable.xSize = 6;
|
||||
IATRetardTable.values = configPage2.iatRetValues;
|
||||
IATRetardTable.axisX = configPage2.iatRetBins;
|
||||
rotarySplitTable.valueSize = SIZE_BYTE;
|
||||
rotarySplitTable.xSize = 8;
|
||||
rotarySplitTable.values = configPage11.rotarySplitValues;
|
||||
rotarySplitTable.axisX = configPage11.rotarySplitBins;
|
||||
|
||||
//Setup the calibration tables
|
||||
loadCalibration();
|
||||
|
||||
//Set the pin mappings
|
||||
if(configPage1.pinMapping > BOARD_NR_GPIO_PINS) { setPinMapping(3); } //First time running? set to v0.4
|
||||
if(configPage1.pinMapping > BOARD_NR_GPIO_PINS)
|
||||
{
|
||||
//First time running on this board
|
||||
setPinMapping(3); //Force board to v0.4
|
||||
configPage1.flexEnabled = false; //Have to disable flex. If this isn't done and the wrong flex pin is interrupt attached below, system can hang.
|
||||
}
|
||||
else { setPinMapping(configPage1.pinMapping); }
|
||||
|
||||
//Need to check early on whether the coil charging is inverted. If this is not set straight away it can cause an unwanted spark at bootup
|
||||
|
@ -225,9 +237,25 @@ void setup()
|
|||
|
||||
//Set the tacho output default state
|
||||
digitalWrite(pinTachOut, HIGH);
|
||||
//Perform all initialisations
|
||||
initialiseSchedulers();
|
||||
//initialiseDisplay();
|
||||
initialiseIdle();
|
||||
initialiseFan();
|
||||
initialiseAuxPWM();
|
||||
initialiseCorrections();
|
||||
initialiseADC();
|
||||
|
||||
//Lookup the current MAP reading for barometric pressure
|
||||
readMAP();
|
||||
instanteneousMAPReading();
|
||||
//barometric reading can be taken from either an external sensor if enabled, or simply by using the initial MAP value
|
||||
if ( configPage3.useExtBaro != 0 )
|
||||
{
|
||||
readBaro();
|
||||
EEPROM.update(EEPROM_LAST_BARO, currentStatus.baro);
|
||||
}
|
||||
else
|
||||
{
|
||||
/*
|
||||
* The highest sea-level pressure on Earth occurs in Siberia, where the Siberian High often attains a sea-level pressure above 105 kPa;
|
||||
* with record highs close to 108.5 kPa.
|
||||
|
@ -245,16 +273,7 @@ void setup()
|
|||
{ currentStatus.baro = EEPROM.read(EEPROM_LAST_BARO); } //last baro correction
|
||||
else { currentStatus.baro = 100; } //Final fall back position.
|
||||
}
|
||||
|
||||
//Perform all initialisations
|
||||
initialiseSchedulers();
|
||||
initialiseTimers();
|
||||
//initialiseDisplay();
|
||||
initialiseIdle();
|
||||
initialiseFan();
|
||||
initialiseAuxPWM();
|
||||
initialiseCorrections();
|
||||
initialiseADC();
|
||||
}
|
||||
|
||||
//Check whether the flex sensor is enabled and if so, attach an interupt for it
|
||||
if(configPage1.flexEnabled)
|
||||
|
@ -270,8 +289,6 @@ void setup()
|
|||
//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
|
||||
//These assignments are based on the Arduino Mega AND VARY BETWEEN BOARDS. Please confirm the board you are using and update acordingly.
|
||||
byte triggerInterrupt = 0; // By default, use the first interrupt
|
||||
byte triggerInterrupt2 = 1;
|
||||
currentStatus.RPM = 0;
|
||||
currentStatus.hasSync = false;
|
||||
currentStatus.runSecs = 0;
|
||||
|
@ -279,271 +296,14 @@ void setup()
|
|||
currentStatus.startRevolutions = 0;
|
||||
currentStatus.flatShiftingHard = false;
|
||||
currentStatus.launchingHard = false;
|
||||
currentStatus.crankRPM = ((unsigned int)configPage2.crankRPM * 100); //Crank RPM limit (Saves us calculating this over and over again. It's updated once per second in timers.ino)
|
||||
triggerFilterTime = 0; //Trigger filter time is the shortest possible time (in uS) that there can be between crank teeth (ie at max RPM). Any pulses that occur faster than this time will be disgarded as noise. This is simply a default value, the actual values are set in the setup() functinos of each decoder
|
||||
dwellLimit_uS = (1000 * configPage2.dwellLimit);
|
||||
|
||||
#if defined(CORE_AVR)
|
||||
switch (pinTrigger) {
|
||||
//Arduino Mega 2560 mapping
|
||||
case 2:
|
||||
triggerInterrupt = 0; break;
|
||||
case 3:
|
||||
triggerInterrupt = 1; break;
|
||||
case 18:
|
||||
triggerInterrupt = 5; break;
|
||||
case 19:
|
||||
triggerInterrupt = 4; break;
|
||||
case 20:
|
||||
triggerInterrupt = 3; break;
|
||||
case 21:
|
||||
triggerInterrupt = 2; break;
|
||||
default:
|
||||
triggerInterrupt = 0; break; //This should NEVER happen
|
||||
}
|
||||
#else
|
||||
triggerInterrupt = pinTrigger;
|
||||
#endif
|
||||
|
||||
#if defined(CORE_AVR)
|
||||
switch (pinTrigger2) {
|
||||
//Arduino Mega 2560 mapping
|
||||
case 2:
|
||||
triggerInterrupt2 = 0; break;
|
||||
case 3:
|
||||
triggerInterrupt2 = 1; break;
|
||||
case 18:
|
||||
triggerInterrupt2 = 5; break;
|
||||
case 19:
|
||||
triggerInterrupt2 = 4; break;
|
||||
case 20:
|
||||
triggerInterrupt2 = 3; break;
|
||||
case 21:
|
||||
triggerInterrupt2 = 2; break;
|
||||
default:
|
||||
triggerInterrupt2 = 0; break; //This should NEVER happen
|
||||
}
|
||||
#else
|
||||
triggerInterrupt2 = pinTrigger2;
|
||||
#endif
|
||||
pinMode(pinTrigger, INPUT);
|
||||
pinMode(pinTrigger2, INPUT);
|
||||
pinMode(pinTrigger3, INPUT);
|
||||
//digitalWrite(pinTrigger, HIGH);
|
||||
|
||||
|
||||
//Set the trigger function based on the decoder in the config
|
||||
switch (configPage2.TrigPattern)
|
||||
{
|
||||
case 0:
|
||||
//Missing tooth decoder
|
||||
triggerSetup_missingTooth();
|
||||
trigger = triggerPri_missingTooth;
|
||||
triggerSecondary = triggerSec_missingTooth;
|
||||
getRPM = getRPM_missingTooth;
|
||||
getCrankAngle = getCrankAngle_missingTooth;
|
||||
triggerSetEndTeeth = triggerSetEndTeeth_missingTooth;
|
||||
|
||||
if(configPage2.TrigEdge == 0) { attachInterrupt(triggerInterrupt, trigger, RISING); } // Attach the crank trigger wheel interrupt (Hall sensor drags to ground when triggering)
|
||||
else { attachInterrupt(triggerInterrupt, trigger, FALLING); }
|
||||
if(configPage2.TrigEdgeSec == 0) { attachInterrupt(triggerInterrupt2, triggerSec_missingTooth, RISING); }
|
||||
else { attachInterrupt(triggerInterrupt2, triggerSec_missingTooth, FALLING); }
|
||||
break;
|
||||
|
||||
case 1:
|
||||
// Basic distributor
|
||||
triggerSetup_BasicDistributor();
|
||||
trigger = triggerPri_BasicDistributor;
|
||||
getRPM = getRPM_BasicDistributor;
|
||||
getCrankAngle = getCrankAngle_BasicDistributor;
|
||||
triggerSetEndTeeth = triggerSetEndTeeth_BasicDistributor;
|
||||
|
||||
if(configPage2.TrigEdge == 0) { attachInterrupt(triggerInterrupt, trigger, RISING); } // Attach the crank trigger wheel interrupt (Hall sensor drags to ground when triggering)
|
||||
else { attachInterrupt(triggerInterrupt, trigger, FALLING); }
|
||||
break;
|
||||
|
||||
case 2:
|
||||
triggerSetup_DualWheel();
|
||||
trigger = triggerPri_DualWheel;
|
||||
getRPM = getRPM_DualWheel;
|
||||
getCrankAngle = getCrankAngle_DualWheel;
|
||||
triggerSetEndTeeth = triggerSetEndTeeth_DualWheel;
|
||||
|
||||
if(configPage2.TrigEdge == 0) { attachInterrupt(triggerInterrupt, trigger, RISING); } // Attach the crank trigger wheel interrupt (Hall sensor drags to ground when triggering)
|
||||
else { attachInterrupt(triggerInterrupt, trigger, FALLING); }
|
||||
if(configPage2.TrigEdgeSec == 0) { attachInterrupt(triggerInterrupt2, triggerSec_DualWheel, RISING); }
|
||||
else { attachInterrupt(triggerInterrupt2, triggerSec_DualWheel, FALLING); }
|
||||
break;
|
||||
|
||||
case 3:
|
||||
triggerSetup_GM7X();
|
||||
trigger = triggerPri_GM7X;
|
||||
getRPM = getRPM_GM7X;
|
||||
getCrankAngle = getCrankAngle_GM7X;
|
||||
triggerSetEndTeeth = triggerSetEndTeeth_GM7X;
|
||||
|
||||
if(configPage2.TrigEdge == 0) { attachInterrupt(triggerInterrupt, trigger, RISING); } // Attach the crank trigger wheel interrupt (Hall sensor drags to ground when triggering)
|
||||
else { attachInterrupt(triggerInterrupt, trigger, FALLING); }
|
||||
break;
|
||||
|
||||
case 4:
|
||||
triggerSetup_4G63();
|
||||
trigger = triggerPri_4G63;
|
||||
getRPM = getRPM_4G63;
|
||||
getCrankAngle = getCrankAngle_4G63;
|
||||
triggerSetEndTeeth = triggerSetEndTeeth_4G63;
|
||||
|
||||
//These may both need to change, not sure
|
||||
if(configPage2.TrigEdge == 0)
|
||||
{
|
||||
attachInterrupt(triggerInterrupt, trigger, CHANGE); // Attach the crank trigger wheel interrupt (Hall sensor drags to ground when triggering)
|
||||
attachInterrupt(triggerInterrupt2, triggerSec_4G63, FALLING); //changed
|
||||
}
|
||||
else
|
||||
{
|
||||
attachInterrupt(triggerInterrupt, trigger, CHANGE); // Primary trigger connects to
|
||||
attachInterrupt(triggerInterrupt2, triggerSec_4G63, FALLING);
|
||||
}
|
||||
break;
|
||||
|
||||
case 5:
|
||||
triggerSetup_24X();
|
||||
trigger = triggerPri_24X;
|
||||
getRPM = getRPM_24X;
|
||||
getCrankAngle = getCrankAngle_24X;
|
||||
triggerSetEndTeeth = triggerSetEndTeeth_24X;
|
||||
|
||||
if(configPage2.TrigEdge == 0) { attachInterrupt(triggerInterrupt, trigger, RISING); } // Attach the crank trigger wheel interrupt (Hall sensor drags to ground when triggering)
|
||||
else { attachInterrupt(triggerInterrupt, trigger, FALLING); } // Primary trigger connects to
|
||||
attachInterrupt(triggerInterrupt2, triggerSec_24X, CHANGE);
|
||||
break;
|
||||
|
||||
case 6:
|
||||
triggerSetup_Jeep2000();
|
||||
trigger = triggerPri_Jeep2000;
|
||||
getRPM = getRPM_Jeep2000;
|
||||
getCrankAngle = getCrankAngle_Jeep2000;
|
||||
triggerSetEndTeeth = triggerSetEndTeeth_Jeep2000;
|
||||
|
||||
if(configPage2.TrigEdge == 0) { attachInterrupt(triggerInterrupt, trigger, RISING); } // Attach the crank trigger wheel interrupt (Hall sensor drags to ground when triggering)
|
||||
else { attachInterrupt(triggerInterrupt, trigger, FALLING); } // Primary trigger connects to
|
||||
attachInterrupt(triggerInterrupt2, triggerSec_Jeep2000, CHANGE);
|
||||
break;
|
||||
|
||||
case 7:
|
||||
triggerSetup_Audi135();
|
||||
trigger = triggerPri_Audi135;
|
||||
getRPM = getRPM_Audi135;
|
||||
getCrankAngle = getCrankAngle_Audi135;
|
||||
triggerSetEndTeeth = triggerSetEndTeeth_Audi135;
|
||||
|
||||
if(configPage2.TrigEdge == 0) { attachInterrupt(triggerInterrupt, trigger, RISING); } // Attach the crank trigger wheel interrupt (Hall sensor drags to ground when triggering)
|
||||
else { attachInterrupt(triggerInterrupt, trigger, FALLING); }
|
||||
attachInterrupt(triggerInterrupt2, triggerSec_Audi135, RISING);
|
||||
break;
|
||||
|
||||
case 8:
|
||||
triggerSetup_HondaD17();
|
||||
trigger = triggerPri_HondaD17;
|
||||
getRPM = getRPM_HondaD17;
|
||||
getCrankAngle = getCrankAngle_HondaD17;
|
||||
triggerSetEndTeeth = triggerSetEndTeeth_HondaD17;
|
||||
|
||||
if(configPage2.TrigEdge == 0) { attachInterrupt(triggerInterrupt, trigger, RISING); } // Attach the crank trigger wheel interrupt (Hall sensor drags to ground when triggering)
|
||||
else { attachInterrupt(triggerInterrupt, trigger, FALLING); } // Primary trigger connects to
|
||||
attachInterrupt(triggerInterrupt2, triggerSec_HondaD17, CHANGE);
|
||||
break;
|
||||
|
||||
case 9:
|
||||
triggerSetup_Miata9905();
|
||||
trigger = triggerPri_Miata9905;
|
||||
getRPM = getRPM_Miata9905;
|
||||
getCrankAngle = getCrankAngle_Miata9905;
|
||||
triggerSetEndTeeth = triggerSetEndTeeth_Miata9905;
|
||||
|
||||
//These may both need to change, not sure
|
||||
if(configPage2.TrigEdge == 0)
|
||||
{
|
||||
attachInterrupt(triggerInterrupt, trigger, RISING); // Attach the crank trigger wheel interrupt (Hall sensor drags to ground when triggering)
|
||||
attachInterrupt(triggerInterrupt2, triggerSec_Miata9905, FALLING); //changed
|
||||
}
|
||||
else
|
||||
{
|
||||
attachInterrupt(triggerInterrupt, trigger, FALLING); // Primary trigger connects to
|
||||
attachInterrupt(triggerInterrupt2, triggerSec_Miata9905, RISING);
|
||||
}
|
||||
break;
|
||||
|
||||
case 10:
|
||||
triggerSetup_MazdaAU();
|
||||
trigger = triggerPri_MazdaAU;
|
||||
getRPM = getRPM_MazdaAU;
|
||||
getCrankAngle = getCrankAngle_MazdaAU;
|
||||
triggerSetEndTeeth = triggerSetEndTeeth_MazdaAU;
|
||||
|
||||
if(configPage2.TrigEdge == 0) { attachInterrupt(triggerInterrupt, trigger, RISING); } // Attach the crank trigger wheel interrupt (Hall sensor drags to ground when triggering)
|
||||
else { attachInterrupt(triggerInterrupt, trigger, FALLING); } // Primary trigger connects to
|
||||
attachInterrupt(triggerInterrupt2, triggerSec_MazdaAU, FALLING);
|
||||
break;
|
||||
|
||||
case 11:
|
||||
triggerSetup_non360();
|
||||
trigger = triggerPri_DualWheel; //Is identical to the dual wheel decoder, so that is used. Same goes for the secondary below
|
||||
getRPM = getRPM_non360;
|
||||
getCrankAngle = getCrankAngle_non360;
|
||||
triggerSetEndTeeth = triggerSetEndTeeth_Non360;
|
||||
|
||||
if(configPage2.TrigEdge == 0) { attachInterrupt(triggerInterrupt, trigger, RISING); } // Attach the crank trigger wheel interrupt (Hall sensor drags to ground when triggering)
|
||||
else { attachInterrupt(triggerInterrupt, trigger, FALLING); }
|
||||
attachInterrupt(triggerInterrupt2, triggerSec_DualWheel, FALLING); //Note the use of the Dual Wheel trigger function here. No point in having the same code in twice.
|
||||
break;
|
||||
|
||||
case 12:
|
||||
triggerSetup_Nissan360();
|
||||
trigger = triggerPri_Nissan360;
|
||||
getRPM = getRPM_Nissan360;
|
||||
getCrankAngle = getCrankAngle_Nissan360;
|
||||
triggerSetEndTeeth = triggerSetEndTeeth_Nissan360;
|
||||
|
||||
if(configPage2.TrigEdge == 0) { attachInterrupt(triggerInterrupt, trigger, RISING); } // Attach the crank trigger wheel interrupt (Hall sensor drags to ground when triggering)
|
||||
else { attachInterrupt(triggerInterrupt, trigger, FALLING); }
|
||||
attachInterrupt(triggerInterrupt2, triggerSec_Nissan360, CHANGE);
|
||||
break;
|
||||
|
||||
case 13:
|
||||
triggerSetup_Subaru67();
|
||||
trigger = triggerPri_Subaru67;
|
||||
getRPM = getRPM_Subaru67;
|
||||
getCrankAngle = getCrankAngle_Subaru67;
|
||||
triggerSetEndTeeth = triggerSetEndTeeth_Subaru67;
|
||||
|
||||
if(configPage2.TrigEdge == 0) { attachInterrupt(triggerInterrupt, trigger, RISING); } // Attach the crank trigger wheel interrupt (Hall sensor drags to ground when triggering)
|
||||
else { attachInterrupt(triggerInterrupt, trigger, FALLING); }
|
||||
attachInterrupt(triggerInterrupt2, triggerSec_Subaru67, FALLING);
|
||||
break;
|
||||
|
||||
case 14:
|
||||
triggerSetup_Daihatsu();
|
||||
trigger = triggerPri_Daihatsu;
|
||||
getRPM = getRPM_Daihatsu;
|
||||
getCrankAngle = getCrankAngle_Daihatsu;
|
||||
triggerSetEndTeeth = triggerSetEndTeeth_Daihatsu;
|
||||
|
||||
if(configPage2.TrigEdge == 0) { attachInterrupt(triggerInterrupt, trigger, RISING); } // Attach the crank trigger wheel interrupt (Hall sensor drags to ground when triggering)
|
||||
else { attachInterrupt(triggerInterrupt, trigger, FALLING); }
|
||||
//No secondary input required for this pattern
|
||||
break;
|
||||
|
||||
default:
|
||||
trigger = triggerPri_missingTooth;
|
||||
getRPM = getRPM_missingTooth;
|
||||
getCrankAngle = getCrankAngle_missingTooth;
|
||||
|
||||
if(configPage2.TrigEdge == 0) { attachInterrupt(triggerInterrupt, trigger, RISING); } // Attach the crank trigger wheel interrupt (Hall sensor drags to ground when triggering)
|
||||
else { attachInterrupt(triggerInterrupt, trigger, FALLING); }
|
||||
break;
|
||||
}
|
||||
noInterrupts();
|
||||
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)
|
||||
|
||||
//Initial values for loop times
|
||||
|
@ -642,6 +402,12 @@ void setup()
|
|||
|
||||
CRANK_ANGLE_MAX_IGN = 720;
|
||||
}
|
||||
else if(configPage2.sparkMode == IGN_MODE_ROTARY)
|
||||
{
|
||||
//Rotary uses the ign 3 and 4 schedules for the trailing spark. They are offset from the ign 1 and 2 channels respectively and so use the same degrees as them
|
||||
channel3IgnDegrees = 0;
|
||||
channel4IgnDegrees = 180;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -829,6 +595,23 @@ void setup()
|
|||
ign5EndFunction = endCoil5Charge;
|
||||
break;
|
||||
|
||||
case IGN_MODE_ROTARY:
|
||||
if(configPage11.rotaryType == ROTARY_IGN_FC)
|
||||
{
|
||||
ign1StartFunction = beginCoil1Charge;
|
||||
ign1EndFunction = endCoil1Charge;
|
||||
ign2StartFunction = beginCoil1Charge;
|
||||
ign2EndFunction = endCoil1Charge;
|
||||
|
||||
ign3StartFunction = beginTrailingCoilCharge;
|
||||
ign3EndFunction = endTrailingCoilCharge1;
|
||||
ign4StartFunction = beginTrailingCoilCharge;
|
||||
ign4EndFunction = endTrailingCoilCharge2;
|
||||
}
|
||||
break;
|
||||
|
||||
|
||||
|
||||
default:
|
||||
//Wasted spark (Shouldn't ever happen anyway)
|
||||
ign1StartFunction = beginCoil1Charge;
|
||||
|
@ -847,74 +630,55 @@ void setup()
|
|||
//Begin priming the fuel pump. This is turned off in the low resolution, 1s interrupt in timers.ino
|
||||
digitalWrite(pinFuelPump, HIGH);
|
||||
fuelPumpOn = true;
|
||||
interrupts();
|
||||
//Perform the priming pulses. Set these to run at an arbitrary time in the future (100us). The prime pulse value is in ms*10, so need to multiple by 100 to get to uS
|
||||
setFuelSchedule1(100, (unsigned long)(configPage1.primePulse * 100));
|
||||
setFuelSchedule2(100, (unsigned long)(configPage1.primePulse * 100));
|
||||
setFuelSchedule3(100, (unsigned long)(configPage1.primePulse * 100));
|
||||
setFuelSchedule4(100, (unsigned long)(configPage1.primePulse * 100));
|
||||
|
||||
initialisationComplete = true;
|
||||
digitalWrite(LED_BUILTIN, HIGH);
|
||||
}
|
||||
|
||||
void loop()
|
||||
{
|
||||
mainLoopCount++;
|
||||
LOOP_TIMER = TIMER_mask;
|
||||
//Check for any requets from serial. Serial operations are checked under 2 scenarios:
|
||||
// 1) Every 64 loops (64 Is more than fast enough for TunerStudio). This function is equivalent to ((loopCount % 64) == 1) but is considerably faster due to not using the mod or division operations
|
||||
// 2) If the amount of data in the serial buffer is greater than a set threhold (See globals.h). This is to avoid serial buffer overflow when large amounts of data is being sent
|
||||
//if ( (BIT_CHECK(TIMER_mask, BIT_TIMER_15HZ)) || (Serial.available() > SERIAL_BUFFER_THRESHOLD) )
|
||||
//if ( (timer15Hz == true) )
|
||||
if ( ((mainLoopCount & 31) == 1) or (Serial.available() > SERIAL_BUFFER_THRESHOLD) )
|
||||
{
|
||||
if (Serial.available() > 0)
|
||||
{
|
||||
command();
|
||||
}
|
||||
if (Serial.available() > 0) { command(); }
|
||||
}
|
||||
|
||||
|
||||
|
||||
#if defined(__AVR_ATmega1280__) || defined(__AVR_ATmega2560__) //ATmega2561 does not have Serial3
|
||||
//if serial3 interface is enabled then check for serial3 requests.
|
||||
if (configPage10.enable_canbus == 1)
|
||||
{
|
||||
if ( ((mainLoopCount & 31) == 1) or (CANSerial.available() > SERIAL_BUFFER_THRESHOLD) )
|
||||
if ( (BIT_CHECK(LOOP_TIMER, BIT_TIMER_15HZ)) || (CANSerial.available() > SERIAL_BUFFER_THRESHOLD) )
|
||||
{
|
||||
if (CANSerial.available() > 0)
|
||||
{
|
||||
canCommand();
|
||||
}
|
||||
if (CANSerial.available() > 0) { canCommand(); }
|
||||
}
|
||||
}
|
||||
|
||||
#elif defined(CORE_STM32)
|
||||
#elif defined(CORE_TEENSY) || defined(CORE_STM32)
|
||||
//if can or secondary serial interface is enabled then check for requests.
|
||||
if (configPage10.enable_canbus == 1) //secondary serial interface enabled
|
||||
{
|
||||
if ( ((mainLoopCount & 31) == 1) or (Serial2.available() > SERIAL_BUFFER_THRESHOLD) )
|
||||
if ( (BIT_CHECK(LOOP_TIMER, BIT_TIMER_15HZ)) || (CANSerial.available() > SERIAL_BUFFER_THRESHOLD) )
|
||||
{
|
||||
if (Serial2.available() > 0)
|
||||
{
|
||||
canCommand();
|
||||
}
|
||||
if (CANSerial.available() > 0) { canCommand(); }
|
||||
}
|
||||
}
|
||||
else if (configPage10.enable_canbus == 2) // can module enabled
|
||||
{
|
||||
//check local can module
|
||||
}
|
||||
#elif defined(CORE_TEENSY)
|
||||
//if can or secondary serial interface is enabled then check for requests.
|
||||
if (configPage10.enable_canbus == 1) //secondary serial interface enabled
|
||||
{
|
||||
if ( ((mainLoopCount & 31) == 1) or (Serial2.available() > SERIAL_BUFFER_THRESHOLD) )
|
||||
{
|
||||
if (Serial2.available() > 0)
|
||||
{
|
||||
canCommand();
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (configPage10.enable_canbus == 2) // can module enabled
|
||||
{
|
||||
//check local can module
|
||||
// if ( ((mainLoopCount & 31) == 1) or (CANbus0.available())
|
||||
// if ( (BIT_CHECK(LOOP_TIMER, BIT_TIMER_15HZ)) or (CANbus0.available())
|
||||
// {
|
||||
// CANbus0.read(rx_msg);
|
||||
// }
|
||||
|
@ -930,7 +694,8 @@ void loop()
|
|||
if ( (timeToLastTooth < MAX_STALL_TIME) || (toothLastToothTime > currentLoopTime) ) //Check how long ago the last tooth was seen compared to now. If it was more than half a second ago then the engine is probably stopped. toothLastToothTime can be greater than currentLoopTime if a pulse occurs between getting the lastest time and doing the comparison
|
||||
{
|
||||
currentStatus.RPM = currentStatus.longRPM = getRPM(); //Long RPM is included here
|
||||
if(fuelPumpOn == false) { digitalWrite(pinFuelPump, HIGH); fuelPumpOn = true; } //Check if the fuel pump is on and turn it on if it isn't.
|
||||
FUEL_PUMP_ON();
|
||||
fuelPumpOn = true; //Not sure if this is needed.
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -939,21 +704,30 @@ void loop()
|
|||
currentStatus.PW1 = 0;
|
||||
currentStatus.VE = 0;
|
||||
toothLastToothTime = 0;
|
||||
toothLastSecToothTime = 0;
|
||||
//toothLastMinusOneToothTime = 0;
|
||||
currentStatus.hasSync = false;
|
||||
currentStatus.runSecs = 0; //Reset the counter for number of seconds running.
|
||||
secCounter = 0; //Reset our seconds counter.
|
||||
currentStatus.startRevolutions = 0;
|
||||
toothSystemCount = 0;
|
||||
secondaryToothCount = 0;
|
||||
MAPcurRev = 0;
|
||||
MAPcount = 0;
|
||||
currentStatus.rpmDOT = 0;
|
||||
ignitionOn = false;
|
||||
fuelOn = false;
|
||||
if (fpPrimed) { digitalWrite(pinFuelPump, LOW); } //Turn off the fuel pump, but only if the priming is complete
|
||||
fuelPumpOn = false;
|
||||
if (fpPrimed == true) { digitalWrite(pinFuelPump, LOW); fuelPumpOn = false; } //Turn off the fuel pump, but only if the priming is complete
|
||||
disableIdle(); //Turn off the idle PWM
|
||||
BIT_CLEAR(currentStatus.engine, BIT_ENGINE_CRANK); //Clear cranking bit (Can otherwise get stuck 'on' even with 0 rpm)
|
||||
BIT_CLEAR(currentStatus.engine, BIT_ENGINE_WARMUP); //Same as above except for WUE
|
||||
//This is a safety check. If for some reason the interrupts have got screwed up (Leading to 0rpm), this resets them.
|
||||
//It can possibly be run much less frequently.
|
||||
initialiseTriggers();
|
||||
|
||||
VVT_PIN_LOW();
|
||||
DISABLE_VVT_TIMER();
|
||||
boostDisable();
|
||||
}
|
||||
|
||||
//Uncomment the following for testing
|
||||
|
@ -966,8 +740,9 @@ void loop()
|
|||
//-----------------------------------------------------------------------------------------------------
|
||||
readMAP();
|
||||
|
||||
if ((mainLoopCount & 31) == 1) //Every 32 loops
|
||||
if (BIT_CHECK(LOOP_TIMER, BIT_TIMER_15HZ)) //Every 32 loops
|
||||
{
|
||||
BIT_CLEAR(TIMER_mask, BIT_TIMER_15HZ);
|
||||
readTPS(); //TPS reading to be performed every 32 loops (any faster and it can upset the TPSdot sampling time)
|
||||
|
||||
//Check for launching/flat shift (clutch) can be done around here too
|
||||
|
@ -1010,18 +785,29 @@ void loop()
|
|||
|
||||
//And check whether the tooth log buffer is ready
|
||||
if(toothHistoryIndex > TOOTH_LOG_SIZE) { BIT_SET(currentStatus.squirt, BIT_SQUIRT_TOOTHLOG1READY); }
|
||||
|
||||
|
||||
}
|
||||
if( (mainLoopCount & 63) == 1) //Every 64 loops
|
||||
if(BIT_CHECK(LOOP_TIMER, BIT_TIMER_30HZ)) //30 hertz
|
||||
{
|
||||
boostControl(); //Most boost tends to run at about 30Hz, so placing it here ensures a new target time is fetched frequently enough
|
||||
//Nothing here currently
|
||||
BIT_CLEAR(TIMER_mask, BIT_TIMER_30HZ);
|
||||
//Most boost tends to run at about 30Hz, so placing it here ensures a new target time is fetched frequently enough
|
||||
//currentStatus.RPM = 3000;
|
||||
boostControl();
|
||||
|
||||
}
|
||||
//The IAT and CLT readings can be done less frequently. This still runs about 4 times per second
|
||||
if ((mainLoopCount & 255) == 1) //Every 256 loops
|
||||
//The IAT and CLT readings can be done less frequently (4 times per second)
|
||||
if (BIT_CHECK(LOOP_TIMER, BIT_TIMER_4HZ))
|
||||
{
|
||||
BIT_CLEAR(TIMER_mask, BIT_TIMER_4HZ);
|
||||
readCLT();
|
||||
readIAT();
|
||||
readO2();
|
||||
readBat();
|
||||
|
||||
if(eepromWritesPending == true) { writeAllConfig(); } //Check for any outstanding EEPROM writes.
|
||||
|
||||
#if defined(__AVR_ATmega1280__) || defined(__AVR_ATmega2560__) //ATmega2561 does not have Serial3
|
||||
//if Can interface is enabled then check for serial3 requests.
|
||||
if (configPage10.enable_canbus == 1) // megas only support can via secondary serial
|
||||
|
@ -1077,15 +863,21 @@ void loop()
|
|||
vvtControl();
|
||||
idleControl(); //Perform any idle related actions. Even at higher frequencies, running 4x per second is sufficient.
|
||||
}
|
||||
if(configPage4.iacAlgorithm == IAC_ALGORITHM_STEP_OL || configPage4.iacAlgorithm == IAC_ALGORITHM_STEP_CL) { idleControl(); } //Run idlecontrol every loop for stepper idle.
|
||||
if (BIT_CHECK(LOOP_TIMER, BIT_TIMER_1HZ)) //Once per second)
|
||||
{
|
||||
BIT_CLEAR(TIMER_mask, BIT_TIMER_1HZ);
|
||||
readBaro(); //Infrequent baro readings are not an issue.
|
||||
}
|
||||
|
||||
if(configPage3.iacAlgorithm == IAC_ALGORITHM_STEP_OL || configPage3.iacAlgorithm == IAC_ALGORITHM_STEP_CL) { idleControl(); } //Run idlecontrol every loop for stepper idle.
|
||||
|
||||
//Always check for sync
|
||||
//Main loop runs within this clause
|
||||
if (currentStatus.hasSync && (currentStatus.RPM > 0))
|
||||
{
|
||||
if(currentStatus.startRevolutions >= configPage2.StgCycles) { ignitionOn = true; fuelOn = true;} //Enable the fuel and ignition, assuming staging revolutions are complete
|
||||
if(currentStatus.startRevolutions >= configPage2.StgCycles) { ignitionOn = true; fuelOn = true; } //Enable the fuel and ignition, assuming staging revolutions are complete
|
||||
//If it is, check is we're running or cranking
|
||||
if(currentStatus.RPM > ((unsigned int)configPage2.crankRPM * 100)) //Crank RPM stored in byte as RPM / 100
|
||||
if(currentStatus.RPM > currentStatus.crankRPM) //Crank RPM stored in byte as RPM / 100
|
||||
{
|
||||
BIT_SET(currentStatus.engine, BIT_ENGINE_RUN); //Sets the engine running bit
|
||||
//Only need to do anything if we're transitioning from cranking to running
|
||||
|
@ -1109,7 +901,7 @@ void loop()
|
|||
//Calculate an injector pulsewidth from the VE
|
||||
currentStatus.corrections = correctionsFuel();
|
||||
lastAdvance = currentStatus.advance; //Store the previous advance value
|
||||
if (configPage1.algorithm == 0) //Check which fuelling algorithm is being used
|
||||
if (configPage1.algorithm == LOAD_SOURCE_MAP) //Check which fuelling algorithm is being used
|
||||
{
|
||||
//Speed Density
|
||||
currentStatus.VE = get3DTableValue(&fuelTable, currentStatus.MAP, currentStatus.RPM); //Perform lookup into fuel map for RPM vs MAP value
|
||||
|
@ -1133,9 +925,9 @@ void loop()
|
|||
int injector5StartAngle = 0; //For 5 cylinder testing
|
||||
int ignition1StartAngle = 0;
|
||||
int ignition2StartAngle = 0;
|
||||
int ignition3StartAngle = 0; //Currently used for 3 cylinder only
|
||||
int ignition4StartAngle = 0; //Not used until sequential or 4+ cylinders support gets written
|
||||
int ignition5StartAngle = 0; //Not used until sequential or 4+ cylinders support gets written
|
||||
int ignition3StartAngle = 0;
|
||||
int ignition4StartAngle = 0;
|
||||
int ignition5StartAngle = 0;
|
||||
//These are used for comparisons on channels above 1 where the starting angle (for injectors or ignition) can be less than a single loop time
|
||||
//(Don't ask why this is needed, it will break your head)
|
||||
int tempCrankAngle;
|
||||
|
@ -1204,6 +996,7 @@ void loop()
|
|||
int PWdivTimerPerDegree = div(currentStatus.PW1, timePerDegree).quot; //How many crank degrees the calculated PW will take at the current speed
|
||||
injector1StartAngle = configPage1.inj1Ang - ( PWdivTimerPerDegree ); //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
|
||||
if(injector1StartAngle < 0) {injector1StartAngle += CRANK_ANGLE_MAX_INJ;}
|
||||
if(injector1StartAngle > CRANK_ANGLE_MAX_INJ) {injector1StartAngle -= CRANK_ANGLE_MAX_INJ;}
|
||||
|
||||
//Repeat the above for each cylinder
|
||||
switch (configPage1.nCylinders)
|
||||
|
@ -1212,25 +1005,33 @@ void loop()
|
|||
case 2:
|
||||
injector2StartAngle = (configPage1.inj2Ang + channel2InjDegrees - ( PWdivTimerPerDegree ));
|
||||
if(injector2StartAngle > CRANK_ANGLE_MAX_INJ) {injector2StartAngle -= CRANK_ANGLE_MAX_INJ;}
|
||||
if(injector2StartAngle < 0) {injector2StartAngle += CRANK_ANGLE_MAX_INJ;}
|
||||
break;
|
||||
//3 cylinders
|
||||
case 3:
|
||||
injector2StartAngle = (configPage1.inj2Ang + channel2InjDegrees - ( PWdivTimerPerDegree ));
|
||||
if(injector2StartAngle > CRANK_ANGLE_MAX_INJ) {injector2StartAngle -= CRANK_ANGLE_MAX_INJ;}
|
||||
if(injector2StartAngle < 0) {injector2StartAngle += CRANK_ANGLE_MAX_INJ;}
|
||||
|
||||
injector3StartAngle = (configPage1.inj3Ang + channel3InjDegrees - ( PWdivTimerPerDegree ));
|
||||
if(injector3StartAngle > CRANK_ANGLE_MAX_INJ) {injector3StartAngle -= CRANK_ANGLE_MAX_INJ;}
|
||||
if(injector3StartAngle < 0) {injector3StartAngle += CRANK_ANGLE_MAX_INJ;}
|
||||
break;
|
||||
//4 cylinders
|
||||
case 4:
|
||||
injector2StartAngle = (configPage1.inj2Ang + channel2InjDegrees - ( PWdivTimerPerDegree ));
|
||||
if(injector2StartAngle > CRANK_ANGLE_MAX_INJ) {injector2StartAngle -= CRANK_ANGLE_MAX_INJ;}
|
||||
if(injector2StartAngle < 0) {injector2StartAngle += CRANK_ANGLE_MAX_INJ;}
|
||||
|
||||
if(configPage1.injLayout == INJ_SEQUENTIAL)
|
||||
{
|
||||
injector3StartAngle = (configPage1.inj3Ang + channel3InjDegrees - ( PWdivTimerPerDegree ));
|
||||
if(injector3StartAngle > CRANK_ANGLE_MAX_INJ) {injector3StartAngle -= CRANK_ANGLE_MAX_INJ;}
|
||||
if(injector3StartAngle < 0) {injector3StartAngle += CRANK_ANGLE_MAX_INJ;}
|
||||
|
||||
injector4StartAngle = (configPage1.inj4Ang + channel4InjDegrees - ( PWdivTimerPerDegree ));
|
||||
if(injector4StartAngle > CRANK_ANGLE_MAX_INJ) {injector4StartAngle -= CRANK_ANGLE_MAX_INJ;}
|
||||
if(injector4StartAngle < 0) {injector4StartAngle += CRANK_ANGLE_MAX_INJ;}
|
||||
|
||||
if(configPage3.fuelTrimEnabled)
|
||||
{
|
||||
|
@ -1290,7 +1091,7 @@ void loop()
|
|||
else { currentStatus.dwell = (configPage2.dwellRun * 100); }
|
||||
currentStatus.dwell = correctionsDwell(currentStatus.dwell);
|
||||
|
||||
int dwellAngle = (div(currentStatus.dwell, timePerDegree).quot ); //Convert the dwell time to dwell angle based on the current engine speed
|
||||
int dwellAngle = uSToDegrees(currentStatus.dwell); //Convert the dwell time to dwell angle based on the current engine speed
|
||||
|
||||
//Calculate start angle for each channel
|
||||
//1 cylinder (Everyone gets this)
|
||||
|
@ -1333,6 +1134,26 @@ void loop()
|
|||
ignition4StartAngle = ignition4EndAngle - dwellAngle;
|
||||
if(ignition4StartAngle > CRANK_ANGLE_MAX_IGN) {ignition4StartAngle -= CRANK_ANGLE_MAX_IGN;}
|
||||
}
|
||||
else if(configPage2.sparkMode == IGN_MODE_ROTARY)
|
||||
{
|
||||
if(configPage11.rotaryType == ROTARY_IGN_FC)
|
||||
{
|
||||
byte splitDegrees = 0;
|
||||
if (configPage1.algorithm == LOAD_SOURCE_MAP) { splitDegrees = table2D_getValue(&rotarySplitTable, currentStatus.MAP/2); }
|
||||
else { splitDegrees = table2D_getValue(&rotarySplitTable, currentStatus.TPS/2); }
|
||||
|
||||
//The trailing angles are set relative to the leading ones
|
||||
ignition3EndAngle = ignition1EndAngle + splitDegrees;
|
||||
ignition3StartAngle = ignition3EndAngle - dwellAngle;
|
||||
if(ignition3StartAngle > CRANK_ANGLE_MAX_IGN) {ignition3StartAngle -= CRANK_ANGLE_MAX_IGN;}
|
||||
if(ignition3StartAngle < 0) {ignition3StartAngle += CRANK_ANGLE_MAX_IGN;}
|
||||
|
||||
ignition4EndAngle = ignition2EndAngle + splitDegrees;
|
||||
ignition4StartAngle = ignition4EndAngle - dwellAngle;
|
||||
if(ignition4StartAngle > CRANK_ANGLE_MAX_IGN) {ignition4StartAngle -= CRANK_ANGLE_MAX_IGN;}
|
||||
if(ignition4StartAngle < 0) {ignition4StartAngle += CRANK_ANGLE_MAX_IGN;}
|
||||
}
|
||||
}
|
||||
break;
|
||||
//5 cylinders
|
||||
case 5:
|
||||
|
@ -1494,7 +1315,7 @@ void loop()
|
|||
//Likewise for the ignition
|
||||
|
||||
//fixedCrankingOverride is used to extend the dwell during cranking so that the decoder can trigger the spark upon seeing a certain tooth. Currently only available on the basic distributor and 4g63 decoders.
|
||||
if ( configPage2.ignCranklock && BIT_CHECK(currentStatus.engine, BIT_ENGINE_CRANK)) { fixedCrankingOverride = currentStatus.dwell * 2; }
|
||||
if ( configPage2.ignCranklock && BIT_CHECK(currentStatus.engine, BIT_ENGINE_CRANK)) { fixedCrankingOverride = currentStatus.dwell * 3; }
|
||||
else { fixedCrankingOverride = 0; }
|
||||
|
||||
//Perform an initial check to see if the ignition is turned on (Ignition only turns on after a preset number of cranking revolutions and:
|
||||
|
@ -1507,7 +1328,6 @@ void loop()
|
|||
crankAngle = getCrankAngle(timePerDegree); //Refresh with the latest crank angle
|
||||
if (crankAngle > CRANK_ANGLE_MAX_IGN ) { crankAngle -= 360; }
|
||||
|
||||
//if (ignition1StartAngle <= crankAngle && ignition1.schedulesSet == 0) { ignition1StartAngle += CRANK_ANGLE_MAX_IGN; }
|
||||
if (ignition1StartAngle > crankAngle)
|
||||
{
|
||||
/*
|
||||
|
@ -1518,7 +1338,8 @@ void loop()
|
|||
unsigned long timeout = (unsigned long)(ignition1StartAngle - crankAngle) * 282UL;
|
||||
*/
|
||||
setIgnitionSchedule1(ign1StartFunction,
|
||||
((unsigned long)(ignition1StartAngle - crankAngle) * (unsigned long)timePerDegree), //(timeout/10),
|
||||
//((unsigned long)(ignition1StartAngle - crankAngle) * (unsigned long)timePerDegree),
|
||||
degreesToUS((ignition1StartAngle - crankAngle)),
|
||||
currentStatus.dwell + fixedCrankingOverride, //((unsigned long)((unsigned long)currentStatus.dwell* currentStatus.RPM) / newRPM) + fixedCrankingOverride,
|
||||
ign1EndFunction
|
||||
);
|
||||
|
@ -1528,11 +1349,9 @@ void loop()
|
|||
if( tempCrankAngle < 0) { tempCrankAngle += CRANK_ANGLE_MAX_IGN; }
|
||||
tempStartAngle = ignition2StartAngle - channel2IgnDegrees;
|
||||
if ( tempStartAngle < 0) { tempStartAngle += CRANK_ANGLE_MAX_IGN; }
|
||||
//if ( (tempStartAngle > tempCrankAngle) && ign2LastRev != startRevolutions)
|
||||
//if ( ign2LastRev != startRevolutions )
|
||||
{
|
||||
unsigned long ignition2StartTime = 0;
|
||||
if(tempStartAngle > tempCrankAngle) { ignition2StartTime = ((unsigned long)(tempStartAngle - tempCrankAngle) * (unsigned long)timePerDegree); }
|
||||
if(tempStartAngle > tempCrankAngle) { ignition2StartTime = degreesToUS((tempStartAngle - tempCrankAngle)); }
|
||||
//else if (tempStartAngle < tempCrankAngle) { ignition2StartTime = ((long)(360 - tempCrankAngle + tempStartAngle) * (long)timePerDegree); }
|
||||
else { ignition2StartTime = 0; }
|
||||
|
||||
|
@ -1552,7 +1371,7 @@ void loop()
|
|||
//if (tempStartAngle > tempCrankAngle)
|
||||
{
|
||||
long ignition3StartTime = 0;
|
||||
if(tempStartAngle > tempCrankAngle) { ignition3StartTime = ((unsigned long)(tempStartAngle - tempCrankAngle) * (unsigned long)timePerDegree); }
|
||||
if(tempStartAngle > tempCrankAngle) { ignition3StartTime = degreesToUS((tempStartAngle - tempCrankAngle)); }
|
||||
//else if (tempStartAngle < tempCrankAngle) { ignition4StartTime = ((long)(360 - tempCrankAngle + tempStartAngle) * (long)timePerDegree); }
|
||||
else { ignition3StartTime = 0; }
|
||||
|
||||
|
@ -1573,7 +1392,7 @@ void loop()
|
|||
{
|
||||
|
||||
long ignition4StartTime = 0;
|
||||
if(tempStartAngle > tempCrankAngle) { ignition4StartTime = ((unsigned long)(tempStartAngle - tempCrankAngle) * (unsigned long)timePerDegree); }
|
||||
if(tempStartAngle > tempCrankAngle) { ignition4StartTime = degreesToUS((tempStartAngle - tempCrankAngle)); }
|
||||
//else if (tempStartAngle < tempCrankAngle) { ignition4StartTime = ((long)(360 - tempCrankAngle + tempStartAngle) * (long)timePerDegree); }
|
||||
else { ignition4StartTime = 0; }
|
||||
|
||||
|
@ -1594,7 +1413,7 @@ void loop()
|
|||
{
|
||||
|
||||
long ignition5StartTime = 0;
|
||||
if(tempStartAngle > tempCrankAngle) { ignition5StartTime = ((unsigned long)(tempStartAngle - tempCrankAngle) * (unsigned long)timePerDegree); }
|
||||
if(tempStartAngle > tempCrankAngle) { ignition5StartTime = degreesToUS((tempStartAngle - tempCrankAngle)); }
|
||||
//else if (tempStartAngle < tempCrankAngle) { ignition4StartTime = ((long)(360 - tempCrankAngle + tempStartAngle) * (long)timePerDegree); }
|
||||
else { ignition5StartTime = 0; }
|
||||
|
||||
|
|
|
@ -31,7 +31,7 @@
|
|||
#define FastCRC_tables
|
||||
#include "inttypes.h"
|
||||
|
||||
#if defined(__AVR__) || defined(STM32_MCU_SERIES) || defined(_VARIANT_ARDUINO_STM32_)
|
||||
#if defined(__AVR__) || defined(STM32_MCU_SERIES) || defined(ARDUINO_ARCH_STM32) || defined(_VARIANT_ARDUINO_STM32_)
|
||||
#include <avr/pgmspace.h>
|
||||
#else
|
||||
#include <pgmspace.h>
|
||||
|
|
|
@ -302,9 +302,9 @@ void integerPID::SetSampleTime(int NewSampleTime)
|
|||
if (NewSampleTime > 0)
|
||||
{
|
||||
unsigned long ratioX1000 = (unsigned long)(NewSampleTime * 1000) / (unsigned long)SampleTime;
|
||||
ki = (ki * ratioX1000) / 1000;
|
||||
ki = ((unsigned long)ki * ratioX1000) / 1000;
|
||||
//kd /= ratio;
|
||||
kd = (kd * 1000) / ratioX1000;
|
||||
kd = ((unsigned long)kd * 1000) / ratioX1000;
|
||||
SampleTime = (unsigned long)NewSampleTime;
|
||||
}
|
||||
}
|
||||
|
@ -387,3 +387,175 @@ byte integerPID::GetKi(){ return dispKi;}
|
|||
byte integerPID::GetKd(){ return dispKd;}
|
||||
int integerPID::GetMode(){ return inAuto ? AUTOMATIC : MANUAL;}
|
||||
int integerPID::GetDirection(){ return controllerDirection;}
|
||||
|
||||
//************************************************************************************************************************
|
||||
#define limitMultiplier 100 //How much outMin and OutMax must be multiplied by to get them in the same scale as the output
|
||||
|
||||
/*Constructor (...)*********************************************************
|
||||
* The parameters specified here are those for for which we can't set up
|
||||
* reliable defaults, so we need to have the user set them.
|
||||
***************************************************************************/
|
||||
integerPID_ideal::integerPID_ideal(long* Input, uint16_t* Output, uint16_t* Setpoint, uint16_t* Sensitivity, byte* SampleTime,
|
||||
byte Kp, byte Ki, byte Kd, byte ControllerDirection)
|
||||
{
|
||||
|
||||
myOutput = Output;
|
||||
myInput = (long*)Input;
|
||||
mySetpoint = Setpoint;
|
||||
mySensitivity = Sensitivity;
|
||||
mySampleTime = SampleTime;
|
||||
|
||||
integerPID_ideal::SetOutputLimits(20, 80); //default output limits
|
||||
|
||||
integerPID_ideal::SetControllerDirection(ControllerDirection);
|
||||
integerPID_ideal::SetTunings(Kp, Ki, Kd);
|
||||
|
||||
lastTime = millis()- *mySampleTime;
|
||||
lastError = 0;
|
||||
}
|
||||
|
||||
/* Compute() **********************************************************************
|
||||
* This, as they say, is where the magic happens. this function should be called
|
||||
* every time "void loop()" executes. the function will decide for itself whether a new
|
||||
* pid Output needs to be computed. returns true when the output is computed,
|
||||
* false when nothing has been done.
|
||||
**********************************************************************************/
|
||||
bool integerPID_ideal::Compute()
|
||||
{
|
||||
unsigned long now = millis();
|
||||
//SampleTime = (now - lastTime);
|
||||
unsigned long timeChange = (now - lastTime);
|
||||
if(timeChange >= *mySampleTime)
|
||||
{
|
||||
/*Compute all the working error variables*/
|
||||
uint16_t sensitivity = 10001 - (*mySensitivity * 2);
|
||||
long unitless_setpoint = (((long)*mySetpoint - 0) * 10000L) / (sensitivity - 0);
|
||||
long unitless_input = (((long)*myInput - 0) * 10000L) / (sensitivity - 0);
|
||||
long error = unitless_setpoint - unitless_input;
|
||||
|
||||
ITerm += error;
|
||||
|
||||
uint16_t bias = 50; //Base target DC%
|
||||
long output = 0;
|
||||
|
||||
if(ki != 0)
|
||||
{
|
||||
output = ((outMax - bias) * limitMultiplier * 100) / (long)ki;
|
||||
if (output < 0) { output = 0; }
|
||||
}
|
||||
if (ITerm > output) { ITerm = output; }
|
||||
|
||||
if(ki != 0)
|
||||
{
|
||||
output = ((bias - outMin) * limitMultiplier * 100) / (long)ki;
|
||||
if (output < 0) { output = 0; }
|
||||
}
|
||||
else { output = 0; }
|
||||
if (ITerm < -output) { ITerm = -output; }
|
||||
|
||||
/*Compute PID Output*/
|
||||
output = (kp * error) + (ki * ITerm) + (kd * (error - lastError));
|
||||
output = (bias * limitMultiplier) + (output / 10); //output is % multipled by 1000. To get % with 2 decimal places, divide it by 10. Likewise, bias is % in whole numbers. Multiply it by 100 to get it with 2 places.
|
||||
|
||||
if(output > (outMax * limitMultiplier)) { output = (outMax * limitMultiplier); }
|
||||
if(output < (outMin * limitMultiplier)) { output = (outMin * limitMultiplier); }
|
||||
|
||||
*myOutput = output;
|
||||
|
||||
/*Remember some variables for next time*/
|
||||
lastTime = now;
|
||||
lastError = error;
|
||||
|
||||
return true;
|
||||
}
|
||||
else return false;
|
||||
}
|
||||
|
||||
|
||||
/* SetTunings(...)*************************************************************
|
||||
* This function allows the controller's dynamic performance to be adjusted.
|
||||
* it's called automatically from the constructor, but tunings can also
|
||||
* be adjusted on the fly during normal operation
|
||||
******************************************************************************/
|
||||
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;
|
||||
|
||||
kp = Kp;
|
||||
ki = Ki;
|
||||
kd = Kd;
|
||||
|
||||
if(controllerDirection == REVERSE)
|
||||
{
|
||||
kp = (0 - kp);
|
||||
ki = (0 - ki);
|
||||
kd = (0 - kd);
|
||||
}
|
||||
}
|
||||
|
||||
/* SetOutputLimits(...)****************************************************
|
||||
* This function will be used far more often than SetInputLimits. while
|
||||
* the input to the controller will generally be in the 0-1023 range (which is
|
||||
* the default already,) the output will be a little different. maybe they'll
|
||||
* be doing a time window and will need 0-8000 or something. or maybe they'll
|
||||
* want to clamp it from 0-125. who knows. at any rate, that can all be done
|
||||
* here.
|
||||
**************************************************************************/
|
||||
void integerPID_ideal::SetOutputLimits(long Min, long Max)
|
||||
{
|
||||
if(Min < Max)
|
||||
{
|
||||
outMin = Min;
|
||||
outMax = Max;
|
||||
}
|
||||
/*
|
||||
long outMax_resized = outMax * limitMultiplier;
|
||||
long outMin_resized = outMin * limitMultiplier;
|
||||
|
||||
if(*myOutput > outMax_resized) { *myOutput = outMax_resized; }
|
||||
else if(*myOutput < outMin_resized) { *myOutput = outMin_resized; }
|
||||
|
||||
if(ITerm > outMax_resized) ITerm = outMax_resized;
|
||||
else if(ITerm < outMin_resized) ITerm = outMin_resized;
|
||||
*/
|
||||
}
|
||||
|
||||
/* Initialize()****************************************************************
|
||||
* does all the things that need to happen to ensure a bumpless transfer
|
||||
* from manual to automatic mode.
|
||||
******************************************************************************/
|
||||
void integerPID_ideal::Initialize()
|
||||
{
|
||||
ITerm = 0;
|
||||
lastInput = *myInput;
|
||||
lastError = 0;
|
||||
}
|
||||
|
||||
/* SetControllerDirection(...)*************************************************
|
||||
* The PID will either be connected to a DIRECT acting process (+Output leads
|
||||
* to +Input) or a REVERSE acting process(+Output leads to -Input.) we need to
|
||||
* know which one, because otherwise we may increase the output when we should
|
||||
* be decreasing. This is called from the constructor.
|
||||
******************************************************************************/
|
||||
void integerPID_ideal::SetControllerDirection(byte Direction)
|
||||
{
|
||||
if(Direction != controllerDirection)
|
||||
{
|
||||
kp = (0 - kp);
|
||||
ki = (0 - ki);
|
||||
kd = (0 - kd);
|
||||
}
|
||||
controllerDirection = Direction;
|
||||
}
|
||||
|
||||
/* Status Funcions*************************************************************
|
||||
* Just because you set the Kp=-1 doesn't mean it actually happened. these
|
||||
* functions query the internal state of the PID. they're here for display
|
||||
* purposes. this are the functions the PID Front-end uses for example
|
||||
******************************************************************************/
|
||||
byte integerPID_ideal::GetKp(){ return dispKp; }
|
||||
byte integerPID_ideal::GetKi(){ return dispKi;}
|
||||
byte integerPID_ideal::GetKd(){ return dispKd;}
|
||||
int integerPID_ideal::GetDirection(){ return controllerDirection;}
|
||||
|
|
|
@ -133,9 +133,9 @@ class integerPID
|
|||
byte dispKi; // format for display purposes
|
||||
byte dispKd; //
|
||||
|
||||
int kp; // * (P)roportional Tuning Parameter
|
||||
int ki; // * (I)ntegral Tuning Parameter
|
||||
int kd; // * (D)erivative Tuning Parameter
|
||||
uint16_t kp; // * (P)roportional Tuning Parameter
|
||||
uint16_t ki; // * (I)ntegral Tuning Parameter
|
||||
uint16_t kd; // * (D)erivative Tuning Parameter
|
||||
|
||||
int controllerDirection;
|
||||
|
||||
|
@ -151,5 +151,77 @@ class integerPID
|
|||
long outMin, outMax;
|
||||
bool inAuto;
|
||||
};
|
||||
#endif
|
||||
|
||||
class integerPID_ideal
|
||||
{
|
||||
|
||||
|
||||
public:
|
||||
|
||||
//Constants used in some of the functions below
|
||||
#define AUTOMATIC 1
|
||||
#define MANUAL 0
|
||||
#define DIRECT 0
|
||||
#define REVERSE 1
|
||||
|
||||
//commonly used functions **************************************************************************
|
||||
integerPID_ideal(long*, uint16_t*, uint16_t*, uint16_t*, byte*, // * constructor. links the PID to the Input, Output, and
|
||||
byte, byte, byte, byte); // Setpoint. Initial tuning parameters are also set here
|
||||
|
||||
bool Compute(); // * performs the PID calculation. it should be
|
||||
// called every time loop() cycles. ON/OFF and
|
||||
// calculation frequency can be set using SetMode
|
||||
// SetSampleTime respectively
|
||||
|
||||
void SetOutputLimits(long, long); //clamps the output to a specific range. 0-255 by default, but
|
||||
//it's likely the user will want to change this depending on
|
||||
//the application
|
||||
|
||||
|
||||
|
||||
//available but not commonly used functions ********************************************************
|
||||
void SetTunings(byte, byte, // * While most users will set the tunings once in the
|
||||
byte); // constructor, this function gives the user the option
|
||||
// of changing tunings during runtime for Adaptive control
|
||||
void SetControllerDirection(byte); // * Sets the Direction, or "Action" of the controller. DIRECT
|
||||
// means the output will increase when error is positive. REVERSE
|
||||
// means the opposite. it's very unlikely that this will be needed
|
||||
// once it is set in the constructor.
|
||||
|
||||
|
||||
|
||||
//Display functions ****************************************************************
|
||||
byte GetKp(); // These functions query the pid for interal values.
|
||||
byte GetKi(); // they were created mainly for the pid front-end,
|
||||
byte GetKd(); // where it's important to know what is actually
|
||||
int GetMode(); // inside the PID.
|
||||
int GetDirection(); //
|
||||
void Initialize();
|
||||
|
||||
private:
|
||||
|
||||
|
||||
byte dispKp; // * we'll hold on to the tuning parameters in user-entered
|
||||
byte dispKi; // format for display purposes
|
||||
byte dispKd; //
|
||||
|
||||
uint16_t kp; // * (P)roportional Tuning Parameter
|
||||
uint16_t ki; // * (I)ntegral Tuning Parameter
|
||||
uint16_t kd; // * (D)erivative Tuning Parameter
|
||||
|
||||
int controllerDirection;
|
||||
|
||||
long *myInput; //
|
||||
uint16_t *myOutput; // This is a percentage figure multipled by 100 (To give 2 points of precision)
|
||||
uint16_t *mySetpoint; //
|
||||
uint16_t *mySensitivity;
|
||||
byte *mySampleTime;
|
||||
|
||||
|
||||
unsigned long lastTime;
|
||||
long lastError;
|
||||
long ITerm, lastInput;
|
||||
|
||||
long outMin, outMax;
|
||||
};
|
||||
#endif
|
||||
|
|
|
@ -1,11 +1,15 @@
|
|||
#ifndef STORAGE_H
|
||||
#define STORAGE_H
|
||||
|
||||
void writeAllConfig();
|
||||
void writeConfig();
|
||||
void loadConfig();
|
||||
void loadCalibration();
|
||||
void writeCalibration();
|
||||
|
||||
#define EEPROM_MAX_WRITE_BLOCK 30 //The maximum number of write operations that will be performed in one go. If we try to write to the EEPROM too fast (Each write takes ~3ms) then the rest of the system can hang)
|
||||
bool eepromWritesPending = false;
|
||||
|
||||
/*
|
||||
Current layout of EEPROM data (Version 3) is as follows (All sizes are in bytes):
|
||||
|---------------------------------------------------|
|
||||
|
@ -48,7 +52,8 @@ Current layout of EEPROM data (Version 3) is as follows (All sizes are in bytes)
|
|||
| 1441 |2 | X and Y size4 |
|
||||
| 1443 |36 | PAGE 9 MAP4 |
|
||||
| 1479 |6 | X and Y Bins4 |
|
||||
| 1500 |128 | CANBUS config and data |
|
||||
| 1500 |128 | CANBUS config and data (Table 10_) |
|
||||
| 1628 |192 | Table 11 - General settings |
|
||||
| |
|
||||
| 2559 |512 | Calibration data (O2) |
|
||||
| 3071 |512 | Calibration data (IAT) |
|
||||
|
@ -64,57 +69,57 @@ Current layout of EEPROM data (Version 3) is as follows (All sizes are in bytes)
|
|||
#define EEPROM_CONFIG1_XBINS 259
|
||||
#define EEPROM_CONFIG1_YBINS 275
|
||||
#define EEPROM_CONFIG2_START 291
|
||||
#define EEPROM_CONFIG2_END 355 // +64 131
|
||||
#define EEPROM_CONFIG3_XSIZE 355
|
||||
#define EEPROM_CONFIG3_YSIZE 356
|
||||
#define EEPROM_CONFIG3_MAP 357
|
||||
#define EEPROM_CONFIG3_XBINS 613
|
||||
#define EEPROM_CONFIG3_YBINS 629
|
||||
#define EEPROM_CONFIG4_START 645
|
||||
#define EEPROM_CONFIG4_END 709
|
||||
#define EEPROM_CONFIG5_XSIZE 709
|
||||
#define EEPROM_CONFIG5_YSIZE 710
|
||||
#define EEPROM_CONFIG5_MAP 711
|
||||
#define EEPROM_CONFIG5_XBINS 967
|
||||
#define EEPROM_CONFIG5_YBINS 983
|
||||
#define EEPROM_CONFIG6_START 999
|
||||
#define EEPROM_CONFIG6_END 1063
|
||||
#define EEPROM_CONFIG7_START 1063
|
||||
#define EEPROM_CONFIG7_END 1127
|
||||
#define EEPROM_CONFIG8_XSIZE1 1127
|
||||
#define EEPROM_CONFIG8_YSIZE1 1128
|
||||
#define EEPROM_CONFIG8_MAP1 1129
|
||||
#define EEPROM_CONFIG8_XBINS1 1193
|
||||
#define EEPROM_CONFIG8_YBINS1 1201
|
||||
#define EEPROM_CONFIG8_XSIZE2 1209
|
||||
#define EEPROM_CONFIG8_YSIZE2 1210
|
||||
#define EEPROM_CONFIG8_MAP2 1211
|
||||
#define EEPROM_CONFIG8_XBINS2 1275
|
||||
#define EEPROM_CONFIG8_YBINS2 1283
|
||||
#define EEPROM_CONFIG8_END 1291
|
||||
#define EEPROM_CONFIG2_END 419
|
||||
#define EEPROM_CONFIG3_XSIZE 419
|
||||
#define EEPROM_CONFIG3_YSIZE 420
|
||||
#define EEPROM_CONFIG3_MAP 421
|
||||
#define EEPROM_CONFIG3_XBINS 677
|
||||
#define EEPROM_CONFIG3_YBINS 693
|
||||
#define EEPROM_CONFIG4_START 709
|
||||
#define EEPROM_CONFIG4_END 837
|
||||
#define EEPROM_CONFIG5_XSIZE 837
|
||||
#define EEPROM_CONFIG5_YSIZE 838
|
||||
#define EEPROM_CONFIG5_MAP 839
|
||||
#define EEPROM_CONFIG5_XBINS 1095
|
||||
#define EEPROM_CONFIG5_YBINS 1111
|
||||
#define EEPROM_CONFIG6_START 1127
|
||||
#define EEPROM_CONFIG6_END 1255
|
||||
#define EEPROM_CONFIG8_XSIZE1 1255
|
||||
#define EEPROM_CONFIG8_YSIZE1 1256
|
||||
#define EEPROM_CONFIG8_MAP1 1257
|
||||
#define EEPROM_CONFIG8_XBINS1 1321
|
||||
#define EEPROM_CONFIG8_YBINS1 1329
|
||||
#define EEPROM_CONFIG8_XSIZE2 1337
|
||||
#define EEPROM_CONFIG8_YSIZE2 1338
|
||||
#define EEPROM_CONFIG8_MAP2 1339
|
||||
#define EEPROM_CONFIG8_XBINS2 1403
|
||||
#define EEPROM_CONFIG8_YBINS2 1411
|
||||
#define EEPROM_CONFIG8_END 1419
|
||||
|
||||
#define EEPROM_CONFIG9_XSIZE1 1291
|
||||
#define EEPROM_CONFIG9_YSIZE1 1292
|
||||
#define EEPROM_CONFIG9_MAP1 1293
|
||||
#define EEPROM_CONFIG9_XBINS1 1329
|
||||
#define EEPROM_CONFIG9_YBINS1 1335
|
||||
#define EEPROM_CONFIG9_XSIZE2 1341
|
||||
#define EEPROM_CONFIG9_YSIZE2 1342
|
||||
#define EEPROM_CONFIG9_MAP2 1343
|
||||
#define EEPROM_CONFIG9_XBINS2 1379
|
||||
#define EEPROM_CONFIG9_YBINS2 1385
|
||||
#define EEPROM_CONFIG9_XSIZE3 1391
|
||||
#define EEPROM_CONFIG9_YSIZE3 1392
|
||||
#define EEPROM_CONFIG9_MAP3 1393
|
||||
#define EEPROM_CONFIG9_XBINS3 1429
|
||||
#define EEPROM_CONFIG9_YBINS3 1435
|
||||
#define EEPROM_CONFIG9_XSIZE4 1441
|
||||
#define EEPROM_CONFIG9_YSIZE4 1442
|
||||
#define EEPROM_CONFIG9_MAP4 1443
|
||||
#define EEPROM_CONFIG9_XBINS4 1479
|
||||
#define EEPROM_CONFIG9_YBINS4 1485
|
||||
#define EEPROM_CONFIG10_START 1500
|
||||
#define EEPROM_CONFIG10_END 1628
|
||||
#define EEPROM_CONFIG9_XSIZE1 1419
|
||||
#define EEPROM_CONFIG9_YSIZE1 1420
|
||||
#define EEPROM_CONFIG9_MAP1 1421
|
||||
#define EEPROM_CONFIG9_XBINS1 1457
|
||||
#define EEPROM_CONFIG9_YBINS1 1463
|
||||
#define EEPROM_CONFIG9_XSIZE2 1469
|
||||
#define EEPROM_CONFIG9_YSIZE2 1470
|
||||
#define EEPROM_CONFIG9_MAP2 1471
|
||||
#define EEPROM_CONFIG9_XBINS2 1507
|
||||
#define EEPROM_CONFIG9_YBINS2 1513
|
||||
#define EEPROM_CONFIG9_XSIZE3 1519
|
||||
#define EEPROM_CONFIG9_YSIZE3 1520
|
||||
#define EEPROM_CONFIG9_MAP3 1521
|
||||
#define EEPROM_CONFIG9_XBINS3 1557
|
||||
#define EEPROM_CONFIG9_YBINS3 1563
|
||||
#define EEPROM_CONFIG9_XSIZE4 1569
|
||||
#define EEPROM_CONFIG9_YSIZE4 1570
|
||||
#define EEPROM_CONFIG9_MAP4 1571
|
||||
#define EEPROM_CONFIG9_XBINS4 1607
|
||||
#define EEPROM_CONFIG9_YBINS4 1613
|
||||
#define EEPROM_CONFIG10_START 1628
|
||||
#define EEPROM_CONFIG10_END 1756
|
||||
#define EEPROM_CONFIG11_START 1756
|
||||
#define EEPROM_CONFIG11_END 1948
|
||||
|
||||
//Calibration data is stored at the end of the EEPROM (This is in case any further calibration tables are needed as they are large blocks)
|
||||
#define EEPROM_LAST_BARO 2558
|
||||
|
|
|
@ -7,13 +7,29 @@ A full copy of the license may be found in the projects root directory
|
|||
#include "storage.h"
|
||||
#include "globals.h"
|
||||
#include "table.h"
|
||||
#include "comms.h"
|
||||
#include <EEPROM.h>
|
||||
|
||||
void writeAllConfig()
|
||||
{
|
||||
writeConfig(1);
|
||||
if (eepromWritesPending == false) { writeConfig(2); }
|
||||
if (eepromWritesPending == false) { writeConfig(3); }
|
||||
if (eepromWritesPending == false) { writeConfig(4); }
|
||||
if (eepromWritesPending == false) { writeConfig(5); }
|
||||
if (eepromWritesPending == false) { writeConfig(6); }
|
||||
if (eepromWritesPending == false) { writeConfig(7); }
|
||||
if (eepromWritesPending == false) { writeConfig(8); }
|
||||
if (eepromWritesPending == false) { writeConfig(9); }
|
||||
if (eepromWritesPending == false) { writeConfig(10); }
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
Takes the current configuration (config pages and maps)
|
||||
and writes them to EEPROM as per the layout defined in storage.h
|
||||
*/
|
||||
void writeConfig()
|
||||
void writeConfig(byte tableNum)
|
||||
{
|
||||
/*
|
||||
We only ever write to the EEPROM where the new value is different from the currently stored byte
|
||||
|
@ -21,36 +37,47 @@ void writeConfig()
|
|||
*/
|
||||
|
||||
int offset;
|
||||
int i, z, y;
|
||||
int writeCounter = 0;
|
||||
byte newVal; //Used for tempoerarily storing the new intended value
|
||||
//Create a pointer to the config page
|
||||
byte* pnt_configPage;
|
||||
|
||||
switch(tableNum)
|
||||
{
|
||||
case veMapPage:
|
||||
/*---------------------------------------------------
|
||||
| Fuel table (See storage.h for data layout) - Page 1
|
||||
| 16x16 table itself + the 16 values along each of the axis
|
||||
-----------------------------------------------------*/
|
||||
if(EEPROM.read(EEPROM_CONFIG1_XSIZE) != fuelTable.xSize) { EEPROM.write(EEPROM_CONFIG1_XSIZE, fuelTable.xSize); } //Write the VE Tables RPM dimension size
|
||||
if(EEPROM.read(EEPROM_CONFIG1_YSIZE) != fuelTable.ySize) { EEPROM.write(EEPROM_CONFIG1_YSIZE, fuelTable.ySize); } //Write the VE Tables MAP/TPS dimension size
|
||||
if(EEPROM.read(EEPROM_CONFIG1_XSIZE) != fuelTable.xSize) { EEPROM.write(EEPROM_CONFIG1_XSIZE, fuelTable.xSize); writeCounter++; } //Write the VE Tables RPM dimension size
|
||||
if(EEPROM.read(EEPROM_CONFIG1_YSIZE) != fuelTable.ySize) { EEPROM.write(EEPROM_CONFIG1_YSIZE, fuelTable.ySize); writeCounter++; } //Write the VE Tables MAP/TPS dimension size
|
||||
for(int x=EEPROM_CONFIG1_MAP; x<EEPROM_CONFIG1_XBINS; 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_MAP;
|
||||
if( EEPROM.read(x) != (fuelTable.values[15-(offset/16)][offset%16]) ) { EEPROM.write(x, fuelTable.values[15-(offset/16)][offset%16]); } //Write the 16x16 map
|
||||
if( EEPROM.read(x) != (fuelTable.values[15-(offset/16)][offset%16]) ) { EEPROM.write(x, fuelTable.values[15-(offset/16)][offset%16]); writeCounter++; } //Write the 16x16 map
|
||||
}
|
||||
|
||||
//RPM bins
|
||||
for(int x=EEPROM_CONFIG1_XBINS; x<EEPROM_CONFIG1_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;
|
||||
if( EEPROM.read(x) != (byte(fuelTable.axisX[offset]/TABLE_RPM_MULTIPLIER)) ) { EEPROM.write(x, byte(fuelTable.axisX[offset]/TABLE_RPM_MULTIPLIER)); } //RPM bins are divided by 100 and converted to a byte
|
||||
if( EEPROM.read(x) != (byte(fuelTable.axisX[offset]/TABLE_RPM_MULTIPLIER)) ) { EEPROM.write(x, byte(fuelTable.axisX[offset]/TABLE_RPM_MULTIPLIER)); writeCounter++; } //RPM bins are divided by 100 and converted to a byte
|
||||
}
|
||||
//TPS/MAP bins
|
||||
for(int x=EEPROM_CONFIG1_YBINS; x<EEPROM_CONFIG2_START; 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_YBINS;
|
||||
EEPROM.update(x, fuelTable.axisY[offset] / TABLE_LOAD_MULTIPLIER); //Table load is divided by 2 (Allows for MAP up to 511)
|
||||
}
|
||||
if(writeCounter > EEPROM_MAX_WRITE_BLOCK) { eepromWritesPending = true; }
|
||||
else { eepromWritesPending = false; }
|
||||
break;
|
||||
//That concludes the writing of the VE table
|
||||
//*********************************************************************************************************************************************************************************
|
||||
|
||||
case veSetPage:
|
||||
/*---------------------------------------------------
|
||||
| Config page 2 (See storage.h for data layout)
|
||||
| 64 byte long config table
|
||||
|
@ -58,39 +85,54 @@ void writeConfig()
|
|||
pnt_configPage = (byte *)&configPage1; //Create a pointer to Page 2 in memory
|
||||
for(int x=EEPROM_CONFIG2_START; x<EEPROM_CONFIG2_END; x++)
|
||||
{
|
||||
if(EEPROM.read(x) != *(pnt_configPage + byte(x - EEPROM_CONFIG2_START))) { EEPROM.write(x, *(pnt_configPage + byte(x - EEPROM_CONFIG2_START))); }
|
||||
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.
|
||||
if(EEPROM.read(x) != *(pnt_configPage + byte(x - EEPROM_CONFIG2_START))) { EEPROM.write(x, *(pnt_configPage + byte(x - EEPROM_CONFIG2_START))); writeCounter++; }
|
||||
}
|
||||
//*********************************************************************************************************************************************************************************
|
||||
|
||||
if(writeCounter > EEPROM_MAX_WRITE_BLOCK) { eepromWritesPending = true; }
|
||||
else { eepromWritesPending = false; }
|
||||
|
||||
break;
|
||||
|
||||
case ignMapPage:
|
||||
/*---------------------------------------------------
|
||||
| Ignition table (See storage.h for data layout) - Page 1
|
||||
| 16x16 table itself + the 16 values along each of the axis
|
||||
-----------------------------------------------------*/
|
||||
//Begin writing the Ignition table, basically the same thing as above
|
||||
if(EEPROM.read(EEPROM_CONFIG3_XSIZE) != ignitionTable.xSize) { EEPROM.write(EEPROM_CONFIG3_XSIZE,ignitionTable.xSize); } //Write the ignition Table RPM dimension size
|
||||
if(EEPROM.read(EEPROM_CONFIG3_YSIZE) != ignitionTable.ySize) { EEPROM.write(EEPROM_CONFIG3_YSIZE,ignitionTable.ySize); } //Write the ignition Table MAP/TPS dimension size
|
||||
if(EEPROM.read(EEPROM_CONFIG3_XSIZE) != ignitionTable.xSize) { EEPROM.write(EEPROM_CONFIG3_XSIZE,ignitionTable.xSize); writeCounter++; } //Write the ignition Table RPM dimension size
|
||||
if(EEPROM.read(EEPROM_CONFIG3_YSIZE) != ignitionTable.ySize) { EEPROM.write(EEPROM_CONFIG3_YSIZE,ignitionTable.ySize); writeCounter++; } //Write the ignition Table MAP/TPS dimension size
|
||||
|
||||
for(int x=EEPROM_CONFIG3_MAP; x<EEPROM_CONFIG3_XBINS; 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_CONFIG3_MAP;
|
||||
if(EEPROM.read(x) != (ignitionTable.values[15-(offset/16)][offset%16]) ) { EEPROM.write(x, ignitionTable.values[15-(offset/16)][offset%16]); } //Write the 16x16 map with translation
|
||||
newVal = ignitionTable.values[15-(offset/16)][offset%16];
|
||||
if(EEPROM.read(x) != newVal) { EEPROM.write(x, newVal); writeCounter++; } //Write the 16x16 map with translation
|
||||
}
|
||||
//RPM bins
|
||||
for(int x=EEPROM_CONFIG3_XBINS; x<EEPROM_CONFIG3_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_CONFIG3_XBINS;
|
||||
if(EEPROM.read(x) != byte(ignitionTable.axisX[offset]/TABLE_RPM_MULTIPLIER)) { EEPROM.write(x, byte(ignitionTable.axisX[offset]/TABLE_RPM_MULTIPLIER)); } //RPM bins are divided by 100 and converted to a byte
|
||||
newVal = ignitionTable.axisX[offset]/TABLE_RPM_MULTIPLIER;
|
||||
if(EEPROM.read(x) != newVal) { EEPROM.write(x, newVal); writeCounter++; } //RPM bins are divided by 100 and converted to a byte
|
||||
}
|
||||
//TPS/MAP bins
|
||||
for(int x=EEPROM_CONFIG3_YBINS; x<EEPROM_CONFIG4_START; 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_CONFIG3_YBINS;
|
||||
EEPROM.update(x, ignitionTable.axisY[offset]/TABLE_LOAD_MULTIPLIER); //Table load is divided by 2 (Allows for MAP up to 511)
|
||||
newVal = ignitionTable.axisY[offset]/TABLE_LOAD_MULTIPLIER;
|
||||
if(EEPROM.read(x) != newVal) { EEPROM.write(x, newVal); writeCounter++; } //Table load is divided by 2 (Allows for MAP up to 511)
|
||||
}
|
||||
//That concludes the writing of the IGN table
|
||||
//*********************************************************************************************************************************************************************************
|
||||
|
||||
if(writeCounter > EEPROM_MAX_WRITE_BLOCK) { eepromWritesPending = true; }
|
||||
else { eepromWritesPending = false; }
|
||||
|
||||
break;
|
||||
|
||||
case ignSetPage:
|
||||
/*---------------------------------------------------
|
||||
| Config page 2 (See storage.h for data layout)
|
||||
| 64 byte long config table
|
||||
|
@ -98,39 +140,51 @@ void writeConfig()
|
|||
pnt_configPage = (byte *)&configPage2; //Create a pointer to Page 2 in memory
|
||||
for(int x=EEPROM_CONFIG4_START; x<EEPROM_CONFIG4_END; x++)
|
||||
{
|
||||
if(EEPROM.read(x) != *(pnt_configPage + byte(x - EEPROM_CONFIG4_START))) { EEPROM.write(x, *(pnt_configPage + byte(x - EEPROM_CONFIG4_START))); }
|
||||
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.
|
||||
if(EEPROM.read(x) != *(pnt_configPage + byte(x - EEPROM_CONFIG4_START))) { EEPROM.write(x, *(pnt_configPage + byte(x - EEPROM_CONFIG4_START))); writeCounter++; }
|
||||
}
|
||||
//*********************************************************************************************************************************************************************************
|
||||
|
||||
if(writeCounter > EEPROM_MAX_WRITE_BLOCK) { eepromWritesPending = true; }
|
||||
else { eepromWritesPending = false; }
|
||||
|
||||
break;
|
||||
|
||||
case afrMapPage:
|
||||
/*---------------------------------------------------
|
||||
| AFR table (See storage.h for data layout) - Page 5
|
||||
| 16x16 table itself + the 16 values along each of the axis
|
||||
-----------------------------------------------------*/
|
||||
//Begin writing the Ignition table, basically the same thing as above
|
||||
if(EEPROM.read(EEPROM_CONFIG5_XSIZE) != afrTable.xSize) { EEPROM.write(EEPROM_CONFIG5_XSIZE,afrTable.xSize); } //Write the ignition Table RPM dimension size
|
||||
if(EEPROM.read(EEPROM_CONFIG5_YSIZE) != afrTable.ySize) { EEPROM.write(EEPROM_CONFIG5_YSIZE,afrTable.ySize); } //Write the ignition Table MAP/TPS dimension size
|
||||
if(EEPROM.read(EEPROM_CONFIG5_XSIZE) != afrTable.xSize) { EEPROM.write(EEPROM_CONFIG5_XSIZE,afrTable.xSize); writeCounter++; } //Write the ignition Table RPM dimension size
|
||||
if(EEPROM.read(EEPROM_CONFIG5_YSIZE) != afrTable.ySize) { EEPROM.write(EEPROM_CONFIG5_YSIZE,afrTable.ySize); writeCounter++; } //Write the ignition Table MAP/TPS dimension size
|
||||
|
||||
for(int x=EEPROM_CONFIG5_MAP; x<EEPROM_CONFIG5_XBINS; 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_CONFIG5_MAP;
|
||||
if(EEPROM.read(x) != (afrTable.values[15-(offset/16)][offset%16]) ) { EEPROM.write(x, afrTable.values[15-(offset/16)][offset%16]); } //Write the 16x16 map
|
||||
if(EEPROM.read(x) != (afrTable.values[15-(offset/16)][offset%16]) ) { EEPROM.write(x, afrTable.values[15-(offset/16)][offset%16]); writeCounter++; } //Write the 16x16 map
|
||||
}
|
||||
//RPM bins
|
||||
for(int x=EEPROM_CONFIG5_XBINS; x<EEPROM_CONFIG5_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_CONFIG5_XBINS;
|
||||
if(EEPROM.read(x) != byte(afrTable.axisX[offset]/TABLE_RPM_MULTIPLIER)) { EEPROM.write(x, byte(afrTable.axisX[offset]/TABLE_RPM_MULTIPLIER)); } //RPM bins are divided by 100 and converted to a byte
|
||||
if(EEPROM.read(x) != byte(afrTable.axisX[offset]/TABLE_RPM_MULTIPLIER)) { EEPROM.write(x, byte(afrTable.axisX[offset]/TABLE_RPM_MULTIPLIER)); writeCounter++; } //RPM bins are divided by 100 and converted to a byte
|
||||
}
|
||||
//TPS/MAP bins
|
||||
for(int x=EEPROM_CONFIG5_YBINS; x<EEPROM_CONFIG6_START; 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_CONFIG5_YBINS;
|
||||
EEPROM.update(x, afrTable.axisY[offset]/TABLE_LOAD_MULTIPLIER); //Table load is divided by 2 (Allows for MAP up to 511)
|
||||
}
|
||||
//That concludes the writing of the AFR table
|
||||
//*********************************************************************************************************************************************************************************
|
||||
|
||||
if(writeCounter > EEPROM_MAX_WRITE_BLOCK) { eepromWritesPending = true; }
|
||||
else { eepromWritesPending = false; }
|
||||
|
||||
break;
|
||||
|
||||
case afrSetPage:
|
||||
/*---------------------------------------------------
|
||||
| Config page 3 (See storage.h for data layout)
|
||||
| 64 byte long config table
|
||||
|
@ -138,88 +192,102 @@ void writeConfig()
|
|||
pnt_configPage = (byte *)&configPage3; //Create a pointer to Page 3 in memory
|
||||
for(int x=EEPROM_CONFIG6_START; x<EEPROM_CONFIG6_END; x++)
|
||||
{
|
||||
if(EEPROM.read(x) != *(pnt_configPage + byte(x - EEPROM_CONFIG6_START))) { EEPROM.write(x, *(pnt_configPage + byte(x - EEPROM_CONFIG6_START))); }
|
||||
}
|
||||
//*********************************************************************************************************************************************************************************
|
||||
|
||||
/*---------------------------------------------------
|
||||
| Config page 4 (See storage.h for data layout)
|
||||
| 64 byte long config table
|
||||
-----------------------------------------------------*/
|
||||
pnt_configPage = (byte *)&configPage4; //Create a pointer to Page 4 in memory
|
||||
//The next 128 bytes can simply be pulled straight from the configTable
|
||||
for(int x=EEPROM_CONFIG7_START; x<EEPROM_CONFIG7_END; x++)
|
||||
{
|
||||
if(EEPROM.read(x) != *(pnt_configPage + byte(x - EEPROM_CONFIG7_START))) { EEPROM.write(x, *(pnt_configPage + byte(x - EEPROM_CONFIG7_START))); }
|
||||
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.
|
||||
if(EEPROM.read(x) != *(pnt_configPage + byte(x - EEPROM_CONFIG6_START))) { EEPROM.write(x, *(pnt_configPage + byte(x - EEPROM_CONFIG6_START))); writeCounter++; }
|
||||
}
|
||||
|
||||
if(writeCounter > EEPROM_MAX_WRITE_BLOCK) { eepromWritesPending = true; }
|
||||
else { eepromWritesPending = false; }
|
||||
|
||||
break;
|
||||
|
||||
case boostvvtPage:
|
||||
/*---------------------------------------------------
|
||||
| Boost and vvt tables (See storage.h for data layout) - Page 8
|
||||
| 8x8 table itself + the 8 values along each of the axis
|
||||
-----------------------------------------------------*/
|
||||
//Begin writing the 2 tables, basically the same thing as above but we're doing these 2 together (2 tables per page instead of 1)
|
||||
if(EEPROM.read(EEPROM_CONFIG8_XSIZE1) != boostTable.xSize) { EEPROM.write(EEPROM_CONFIG8_XSIZE1,boostTable.xSize); } //Write the boost Table RPM dimension size
|
||||
if(EEPROM.read(EEPROM_CONFIG8_YSIZE1) != boostTable.ySize) { EEPROM.write(EEPROM_CONFIG8_YSIZE1,boostTable.ySize); } //Write the boost Table MAP/TPS dimension size
|
||||
if(EEPROM.read(EEPROM_CONFIG8_XSIZE2) != vvtTable.xSize) { EEPROM.write(EEPROM_CONFIG8_XSIZE2,vvtTable.xSize); } //Write the vvt Table RPM dimension size
|
||||
if(EEPROM.read(EEPROM_CONFIG8_YSIZE2) != vvtTable.ySize) { EEPROM.write(EEPROM_CONFIG8_YSIZE2,vvtTable.ySize); } //Write the vvt Table MAP/TPS dimension size
|
||||
if(EEPROM.read(EEPROM_CONFIG8_XSIZE1) != boostTable.xSize) { EEPROM.write(EEPROM_CONFIG8_XSIZE1,boostTable.xSize); writeCounter++; } //Write the boost Table RPM dimension size
|
||||
if(EEPROM.read(EEPROM_CONFIG8_YSIZE1) != boostTable.ySize) { EEPROM.write(EEPROM_CONFIG8_YSIZE1,boostTable.ySize); writeCounter++; } //Write the boost Table MAP/TPS dimension size
|
||||
if(EEPROM.read(EEPROM_CONFIG8_XSIZE2) != vvtTable.xSize) { EEPROM.write(EEPROM_CONFIG8_XSIZE2,vvtTable.xSize); writeCounter++; } //Write the vvt Table RPM dimension size
|
||||
if(EEPROM.read(EEPROM_CONFIG8_YSIZE2) != vvtTable.ySize) { EEPROM.write(EEPROM_CONFIG8_YSIZE2,vvtTable.ySize); writeCounter++; } //Write the vvt Table MAP/TPS dimension size
|
||||
|
||||
int y = EEPROM_CONFIG8_MAP2; //We do the 2 maps together in the same loop
|
||||
y = EEPROM_CONFIG8_MAP2; //We do the 2 maps together in the same loop
|
||||
for(int x=EEPROM_CONFIG8_MAP1; x<EEPROM_CONFIG8_XBINS1; 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_CONFIG8_MAP1;
|
||||
if(EEPROM.read(x) != (boostTable.values[7-(offset/8)][offset%8]) ) { EEPROM.write(x, boostTable.values[7-(offset/8)][offset%8]); } //Write the 8x8 map
|
||||
if(EEPROM.read(x) != (boostTable.values[7-(offset/8)][offset%8]) ) { EEPROM.write(x, boostTable.values[7-(offset/8)][offset%8]); writeCounter++; } //Write the 8x8 map
|
||||
offset = y - EEPROM_CONFIG8_MAP2;
|
||||
if(EEPROM.read(y) != (vvtTable.values[7-(offset/8)][offset%8]) ) { EEPROM.write(y, vvtTable.values[7-(offset/8)][offset%8]); } //Write the 8x8 map
|
||||
if(EEPROM.read(y) != (vvtTable.values[7-(offset/8)][offset%8]) ) { EEPROM.write(y, vvtTable.values[7-(offset/8)][offset%8]); writeCounter++; } //Write the 8x8 map
|
||||
y++;
|
||||
}
|
||||
//RPM bins
|
||||
y = EEPROM_CONFIG8_XBINS2;
|
||||
for(int x=EEPROM_CONFIG8_XBINS1; x<EEPROM_CONFIG8_YBINS1; 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_CONFIG8_XBINS1;
|
||||
if(EEPROM.read(x) != byte(boostTable.axisX[offset]/TABLE_RPM_MULTIPLIER)) { EEPROM.write(x, byte(boostTable.axisX[offset]/TABLE_RPM_MULTIPLIER)); } //RPM bins are divided by 100 and converted to a byte
|
||||
if(EEPROM.read(x) != byte(boostTable.axisX[offset]/TABLE_RPM_MULTIPLIER)) { EEPROM.write(x, byte(boostTable.axisX[offset]/TABLE_RPM_MULTIPLIER)); writeCounter++; } //RPM bins are divided by 100 and converted to a byte
|
||||
offset = y - EEPROM_CONFIG8_XBINS2;
|
||||
if(EEPROM.read(y) != byte(vvtTable.axisX[offset]/TABLE_RPM_MULTIPLIER)) { EEPROM.write(y, byte(vvtTable.axisX[offset]/TABLE_RPM_MULTIPLIER)); } //RPM bins are divided by 100 and converted to a byte
|
||||
if(EEPROM.read(y) != byte(vvtTable.axisX[offset]/TABLE_RPM_MULTIPLIER)) { EEPROM.write(y, byte(vvtTable.axisX[offset]/TABLE_RPM_MULTIPLIER)); writeCounter++; } //RPM bins are divided by 100 and converted to a byte
|
||||
y++;
|
||||
}
|
||||
//TPS/MAP bins
|
||||
y=EEPROM_CONFIG8_YBINS2;
|
||||
for(int x=EEPROM_CONFIG8_YBINS1; x<EEPROM_CONFIG8_XSIZE2; 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_CONFIG8_YBINS1;
|
||||
EEPROM.update(x, boostTable.axisY[offset]); //TABLE_LOAD_MULTIPLIER is NOT used for boost as it is TPS based (0-100)
|
||||
if(EEPROM.read(x) != boostTable.axisY[offset]) { EEPROM.write(x, boostTable.axisY[offset]); writeCounter++; } //TABLE_LOAD_MULTIPLIER is NOT used for boost as it is TPS based (0-100)
|
||||
offset = y - EEPROM_CONFIG8_YBINS2;
|
||||
EEPROM.update(y, vvtTable.axisY[offset]); //TABLE_LOAD_MULTIPLIER is NOT used for VVT as it is TPS based (0-100)
|
||||
if(EEPROM.read(y) != vvtTable.axisY[offset]) { EEPROM.write(y, vvtTable.axisY[offset]); writeCounter++; } //TABLE_LOAD_MULTIPLIER is NOT used for VVT as it is TPS based (0-100)
|
||||
y++;
|
||||
}
|
||||
|
||||
if(writeCounter > EEPROM_MAX_WRITE_BLOCK) { eepromWritesPending = true; }
|
||||
else { eepromWritesPending = false; }
|
||||
|
||||
break;
|
||||
|
||||
case seqFuelPage:
|
||||
/*---------------------------------------------------
|
||||
| Fuel trim tables (See storage.h for data layout) - Page 9
|
||||
| 6x6 tables itself + the 6 values along each of the axis
|
||||
-----------------------------------------------------*/
|
||||
//Begin writing the 2 tables, basically the same thing as above but we're doing these 2 together (2 tables per page instead of 1)
|
||||
EEPROM.update(EEPROM_CONFIG9_XSIZE1,trim1Table.xSize); //Write the boost Table RPM dimension size
|
||||
EEPROM.update(EEPROM_CONFIG9_YSIZE1,trim1Table.ySize); //Write the boost Table MAP/TPS dimension size
|
||||
EEPROM.update(EEPROM_CONFIG9_XSIZE2,trim2Table.xSize); //Write the boost Table RPM dimension size
|
||||
EEPROM.update(EEPROM_CONFIG9_YSIZE2,trim2Table.ySize); //Write the boost Table MAP/TPS dimension size
|
||||
EEPROM.update(EEPROM_CONFIG9_XSIZE3,trim3Table.xSize); //Write the boost Table RPM dimension size
|
||||
EEPROM.update(EEPROM_CONFIG9_YSIZE3,trim3Table.ySize); //Write the boost Table MAP/TPS dimension size
|
||||
EEPROM.update(EEPROM_CONFIG9_XSIZE4,trim4Table.xSize); //Write the boost Table RPM dimension size
|
||||
EEPROM.update(EEPROM_CONFIG9_YSIZE4,trim4Table.ySize); //Write the boost Table MAP/TPS dimension size
|
||||
if(EEPROM.read(EEPROM_CONFIG9_XSIZE1) != trim1Table.xSize) { EEPROM.write(EEPROM_CONFIG9_XSIZE1,trim1Table.xSize); writeCounter++; } //Write the boost Table RPM dimension size
|
||||
if(EEPROM.read(EEPROM_CONFIG9_YSIZE1) != trim1Table.ySize) { EEPROM.write(EEPROM_CONFIG9_YSIZE1,trim1Table.ySize); writeCounter++; } //Write the boost Table MAP/TPS dimension size
|
||||
if(EEPROM.read(EEPROM_CONFIG9_XSIZE2) != trim2Table.xSize) { EEPROM.write(EEPROM_CONFIG9_XSIZE2,trim2Table.xSize); writeCounter++; } //Write the boost Table RPM dimension size
|
||||
if(EEPROM.read(EEPROM_CONFIG9_YSIZE2) != trim2Table.ySize) { EEPROM.write(EEPROM_CONFIG9_YSIZE2,trim2Table.ySize); writeCounter++; } //Write the boost Table MAP/TPS dimension size
|
||||
if(EEPROM.read(EEPROM_CONFIG9_XSIZE3) != trim3Table.xSize) { EEPROM.write(EEPROM_CONFIG9_XSIZE3,trim3Table.xSize); writeCounter++; } //Write the boost Table RPM dimension size
|
||||
if(EEPROM.read(EEPROM_CONFIG9_YSIZE3) != trim3Table.ySize) { EEPROM.write(EEPROM_CONFIG9_YSIZE3,trim3Table.ySize); writeCounter++; } //Write the boost Table MAP/TPS dimension size
|
||||
if(EEPROM.read(EEPROM_CONFIG9_XSIZE4) != trim4Table.xSize) { EEPROM.write(EEPROM_CONFIG9_XSIZE4,trim4Table.xSize); writeCounter++; } //Write the boost Table RPM dimension size
|
||||
if(EEPROM.read(EEPROM_CONFIG9_YSIZE4) != trim4Table.ySize) { EEPROM.write(EEPROM_CONFIG9_YSIZE4,trim4Table.ySize); writeCounter++; } //Write the boost Table MAP/TPS dimension size
|
||||
|
||||
y = EEPROM_CONFIG9_MAP2; //We do the 4 maps together in the same loop
|
||||
int z = EEPROM_CONFIG9_MAP3; //We do the 4 maps together in the same loop
|
||||
int i = EEPROM_CONFIG9_MAP4; //We do the 4 maps together in the same loop
|
||||
z = EEPROM_CONFIG9_MAP3; //We do the 4 maps together in the same loop
|
||||
i = EEPROM_CONFIG9_MAP4; //We do the 4 maps together in the same loop
|
||||
|
||||
for(int x=EEPROM_CONFIG9_MAP1; x<EEPROM_CONFIG9_XBINS1; 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_CONFIG9_MAP1;
|
||||
EEPROM.update(x, (trim1Table.values[5-(offset/6)][offset%6]) ); //Write the 6x6 map
|
||||
newVal = trim1Table.values[5-(offset/6)][offset%6];
|
||||
if (EEPROM.read(x) != newVal ) { EEPROM.update(x, newVal ); writeCounter++; } //Write the 6x6 map
|
||||
|
||||
offset = y - EEPROM_CONFIG9_MAP2;
|
||||
EEPROM.update(y, trim2Table.values[5-(offset/6)][offset%6]); //Write the 6x6 map
|
||||
newVal = trim2Table.values[5-(offset/6)][offset%6];
|
||||
if (EEPROM.read(y) != newVal ) { EEPROM.update(y, newVal); writeCounter++; } //Write the 6x6 map
|
||||
|
||||
offset = z - EEPROM_CONFIG9_MAP3;
|
||||
EEPROM.update(z, trim3Table.values[5-(offset/6)][offset%6]); //Write the 6x6 map
|
||||
newVal = trim3Table.values[5-(offset/6)][offset%6];
|
||||
if (EEPROM.read(z) != newVal ) { EEPROM.update(z, newVal); writeCounter++; } //Write the 6x6 map
|
||||
|
||||
offset = i - EEPROM_CONFIG9_MAP4;
|
||||
EEPROM.update(i, trim4Table.values[5-(offset/6)][offset%6]); //Write the 6x6 map
|
||||
newVal = trim4Table.values[5-(offset/6)][offset%6];
|
||||
if (EEPROM.read(i) != newVal ) { EEPROM.update(i, newVal); writeCounter++; } //Write the 6x6 map
|
||||
|
||||
y++;
|
||||
z++;
|
||||
i++;
|
||||
|
@ -230,6 +298,7 @@ void writeConfig()
|
|||
i = EEPROM_CONFIG9_XBINS4;
|
||||
for(int x=EEPROM_CONFIG9_XBINS1; x<EEPROM_CONFIG9_YBINS1; x++)
|
||||
{
|
||||
if( (writeCounter > EEPROM_MAX_WRITE_BLOCK) ) { eepromWritesPending = true; 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_CONFIG9_XBINS1;
|
||||
EEPROM.update(x, byte(trim1Table.axisX[offset]/TABLE_RPM_MULTIPLIER)); //RPM bins are divided by 100 and converted to a byte
|
||||
offset = y - EEPROM_CONFIG9_XBINS2;
|
||||
|
@ -248,6 +317,7 @@ void writeConfig()
|
|||
i=EEPROM_CONFIG9_YBINS4;
|
||||
for(int x=EEPROM_CONFIG9_YBINS1; x<EEPROM_CONFIG9_XSIZE2; x++)
|
||||
{
|
||||
if( (writeCounter > EEPROM_MAX_WRITE_BLOCK) ) { eepromWritesPending = true; 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_CONFIG9_YBINS1;
|
||||
EEPROM.update(x, trim1Table.axisY[offset]/TABLE_LOAD_MULTIPLIER); //Table load is divided by 2 (Allows for MAP up to 511)
|
||||
offset = y - EEPROM_CONFIG9_YBINS2;
|
||||
|
@ -260,8 +330,12 @@ void writeConfig()
|
|||
z++;
|
||||
i++;
|
||||
}
|
||||
//*********************************************************************************************************************************************************************************
|
||||
if(writeCounter > EEPROM_MAX_WRITE_BLOCK) { eepromWritesPending = true; }
|
||||
else { eepromWritesPending = false; }
|
||||
|
||||
break;
|
||||
|
||||
case canbusPage:
|
||||
/*---------------------------------------------------
|
||||
| Config page 10 (See storage.h for data layout)
|
||||
| 128 byte long config table
|
||||
|
@ -269,10 +343,36 @@ void writeConfig()
|
|||
pnt_configPage = (byte *)&configPage10; //Create a pointer to Page 10 in memory
|
||||
for(int x=EEPROM_CONFIG10_START; x<EEPROM_CONFIG10_END; x++)
|
||||
{
|
||||
if(EEPROM.read(x) != *(pnt_configPage + byte(x - EEPROM_CONFIG10_START))) { EEPROM.write(x, *(pnt_configPage + byte(x - EEPROM_CONFIG10_START))); }
|
||||
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.
|
||||
if(EEPROM.read(x) != *(pnt_configPage + byte(x - EEPROM_CONFIG10_START))) { EEPROM.write(x, *(pnt_configPage + byte(x - EEPROM_CONFIG10_START))); writeCounter++; }
|
||||
}
|
||||
//*********************************************************************************************************************************************************************************
|
||||
|
||||
if(writeCounter > EEPROM_MAX_WRITE_BLOCK) { eepromWritesPending = true; }
|
||||
else { eepromWritesPending = false; }
|
||||
|
||||
break;
|
||||
|
||||
case warmupPage:
|
||||
/*---------------------------------------------------
|
||||
| Config page 11 (See storage.h for data layout)
|
||||
| 192 byte long config table
|
||||
-----------------------------------------------------*/
|
||||
pnt_configPage = (byte *)&configPage11; //Create a pointer to Page 11 in memory
|
||||
//As there are no 3d tables in this page, all 192 bytes can simply be read in
|
||||
for(int x=EEPROM_CONFIG11_START; x<EEPROM_CONFIG11_END; 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.
|
||||
if(EEPROM.read(x) != *(pnt_configPage + byte(x - EEPROM_CONFIG11_START))) { EEPROM.write(x, *(pnt_configPage + byte(x - EEPROM_CONFIG11_START))); writeCounter++; }
|
||||
}
|
||||
|
||||
if(writeCounter > EEPROM_MAX_WRITE_BLOCK) { eepromWritesPending = true; }
|
||||
else { eepromWritesPending = false; }
|
||||
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void loadConfig()
|
||||
|
@ -364,17 +464,6 @@ void loadConfig()
|
|||
*(pnt_configPage + byte(x - EEPROM_CONFIG6_START)) = EEPROM.read(x);
|
||||
}
|
||||
|
||||
//*********************************************************************************************************************************************************************************
|
||||
|
||||
//CONFIG PAGE (4)
|
||||
pnt_configPage = (byte *)&configPage4; //Create a pointer to Page 3 in memory
|
||||
//Begin writing the Ignition table, basically the same thing as above
|
||||
//The first 64 bytes can simply be pulled straight from the configTable
|
||||
for(int x=EEPROM_CONFIG7_START; x<EEPROM_CONFIG7_END; x++)
|
||||
{
|
||||
*(pnt_configPage + byte(x - EEPROM_CONFIG7_START)) = EEPROM.read(x);
|
||||
}
|
||||
|
||||
//*********************************************************************************************************************************************************************************
|
||||
// Boost and vvt tables load
|
||||
int y = EEPROM_CONFIG8_MAP2;
|
||||
|
@ -476,6 +565,14 @@ void loadConfig()
|
|||
|
||||
//*********************************************************************************************************************************************************************************
|
||||
|
||||
//CONFIG PAGE (11)
|
||||
pnt_configPage = (byte *)&configPage11; //Create a pointer to Page 11 in memory
|
||||
//All 192 bytes can simply be pulled straight from the configTable
|
||||
for(int x=EEPROM_CONFIG11_START; x<EEPROM_CONFIG11_END; x++)
|
||||
{
|
||||
*(pnt_configPage + byte(x - EEPROM_CONFIG11_START)) = EEPROM.read(x);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
|
@ -103,6 +103,7 @@ int table2D_getValue(struct table2D *fromTable, int X_in)
|
|||
{
|
||||
returnValue = fromTable->values[x]; //Simply return the coresponding value
|
||||
valueFound = true;
|
||||
break;
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -143,6 +144,7 @@ int table2D_getValue(struct table2D *fromTable, int X_in)
|
|||
{
|
||||
returnValue = fromTable->values16[x]; //Simply return the coresponding value
|
||||
valueFound = true;
|
||||
break;
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -374,13 +376,29 @@ 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;
|
||||
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 = (long)Y - yMinValue;
|
||||
if (yMaxValue == yMinValue) { q = (q << 8); }
|
||||
else { q = 256 - ( (q << 8) / (yMinValue - yMaxValue) ); }
|
||||
long q;
|
||||
if (yMaxValue == yMinValue)
|
||||
{
|
||||
q = (long)Y - yMinValue;
|
||||
q = (q << 8);
|
||||
}
|
||||
//Standard case
|
||||
else
|
||||
{
|
||||
q = long(Y) - yMaxValue;
|
||||
q = 256 - ( (q << 8) / (yMinValue - yMaxValue) );
|
||||
}
|
||||
|
||||
/*
|
||||
long q;
|
||||
if (yMaxValue == yMinValue) { q = ((long)(Y - yMinValue) << 8); }
|
||||
else { q = 256 - (((long)(Y - yMaxValue) << 8) / (yMinValue - yMaxValue)); }
|
||||
*/
|
||||
|
||||
int m = ((256-p) * (256-q)) >> 8;
|
||||
int n = (p * (256-q)) >> 8;
|
||||
|
@ -390,152 +408,3 @@ int get3DTableValue(struct table3D *fromTable, int Y_in, int X_in)
|
|||
}
|
||||
return tableResult;
|
||||
}
|
||||
/* Executed a benchmark on all options and this is the results
|
||||
* Stadard:226224 91 |FP Math:32240 91.89 |Clean code:34056 91, Number of loops:2500
|
||||
*
|
||||
//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
|
||||
float get3DTableValueF(struct table3D *fromTable, int Y, int X)
|
||||
{
|
||||
float m, n, o ,p, q, r;
|
||||
byte xMin, xMax;
|
||||
byte yMin, yMax;
|
||||
int yMaxValue, yMinValue;
|
||||
int xMaxValue, xMinValue;
|
||||
|
||||
if(fromTable->lastXMin==0) {fromTable->lastXMin = fromTable->xSize-1;}
|
||||
else {xMin = fromTable->lastXMin;}
|
||||
if(fromTable->lastYMin==0) {fromTable->lastYMin = fromTable->ySize-1;}
|
||||
else {yMin = fromTable->lastYMin;}
|
||||
//yMin = fromTable->lastYMin;
|
||||
|
||||
if(xMin>fromTable->xSize-1)
|
||||
{
|
||||
fromTable->lastXMin = fromTable->xSize-1;
|
||||
xMin = fromTable->xSize-1;
|
||||
}
|
||||
if(yMin>fromTable->ySize-1)
|
||||
{
|
||||
fromTable->lastYMin = fromTable->ySize-1;
|
||||
yMin = fromTable->ySize-1;
|
||||
}
|
||||
|
||||
do //RPM axis
|
||||
{
|
||||
if(X>=fromTable->axisX[xMin]) {break;}
|
||||
xMin--;
|
||||
}while(1);
|
||||
fromTable->lastXMin = xMin + 1;
|
||||
do //MAP axis
|
||||
{
|
||||
if(Y<=fromTable->axisY[yMin]) {break;}
|
||||
yMin--;
|
||||
}while(1);
|
||||
fromTable->lastYMin = yMin + 1;
|
||||
|
||||
xMax = xMin + 1;
|
||||
yMax = yMin + 1;
|
||||
if (xMax>fromTable->xSize-1) //Overflow protection
|
||||
{
|
||||
xMax = fromTable->xSize-1;
|
||||
xMin = xMax - 1;
|
||||
}
|
||||
if (yMax>fromTable->ySize-1) //Overflow protection
|
||||
{
|
||||
yMax = fromTable->ySize-1;
|
||||
yMin = yMax - 1;
|
||||
}
|
||||
|
||||
yMaxValue = fromTable->axisY[yMax];
|
||||
yMinValue = fromTable->axisY[yMin];
|
||||
xMaxValue = fromTable->axisX[xMax];
|
||||
xMinValue = fromTable->axisX[xMin];
|
||||
|
||||
int A = fromTable->values[yMin][xMin];
|
||||
int B = fromTable->values[yMin][xMax];
|
||||
int C = fromTable->values[yMax][xMin];
|
||||
int D = fromTable->values[yMax][xMax];
|
||||
|
||||
p = float(X - xMinValue) / (xMaxValue - xMinValue); //(RPM - RPM[1])/(RPM[2]- RPM[1])
|
||||
q = float(Y - yMinValue) / (yMaxValue - yMinValue); //(MAP - MAP[1])/(MAP[2]- MAP[1])
|
||||
|
||||
m = (1.0-p) * (1.0-q);
|
||||
n = p * (1-q);
|
||||
o = (1-p) * q;
|
||||
r = p * q;
|
||||
|
||||
return ( (A * m) + (B * n) + (C * o) + (D * r) );
|
||||
}
|
||||
|
||||
//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
|
||||
int get3DTableValueS(struct table3D *fromTable, int Y, int X)
|
||||
{
|
||||
byte xMin, xMax;
|
||||
byte yMin, yMax;
|
||||
long p, q;
|
||||
int yMaxValue, yMinValue;
|
||||
int xMaxValue, xMinValue;
|
||||
|
||||
if(fromTable->lastXMin==0) {fromTable->lastXMin=fromTable->xSize-1;}
|
||||
else {xMin = fromTable->lastXMin;}
|
||||
if(fromTable->lastYMin==0) {fromTable->lastYMin=fromTable->ySize-1;}
|
||||
else {yMin = fromTable->lastYMin;}
|
||||
|
||||
if(xMin>fromTable->xSize-1)
|
||||
{
|
||||
fromTable->lastXMin = fromTable->xSize-1;
|
||||
xMin = fromTable->xSize-1;
|
||||
}
|
||||
if(yMin>fromTable->ySize-1)
|
||||
{
|
||||
fromTable->lastYMin = fromTable->ySize-1;
|
||||
yMin = fromTable->ySize-1;
|
||||
}
|
||||
|
||||
do //RPM axis
|
||||
{
|
||||
if(X>=fromTable->axisX[xMin]) {break;}
|
||||
xMin--;
|
||||
}while(1);
|
||||
fromTable->lastXMin = xMin + 1;
|
||||
do //MAP axis
|
||||
{
|
||||
if(Y<=fromTable->axisY[yMin]) {break;}
|
||||
yMin--;
|
||||
}while(1);
|
||||
fromTable->lastYMin = yMin + 1;
|
||||
|
||||
xMax = xMin + 1;
|
||||
yMax = yMin + 1;
|
||||
if (xMax>fromTable->xSize-1) //Overflow protection
|
||||
{
|
||||
xMax = fromTable->xSize-1;
|
||||
xMin = xMax - 1;
|
||||
}
|
||||
if (yMax>fromTable->ySize-1) //Overflow protection
|
||||
{
|
||||
yMax = fromTable->ySize-1;
|
||||
yMin = yMax - 1;
|
||||
}
|
||||
|
||||
yMaxValue = fromTable->axisY[yMax];
|
||||
yMinValue = fromTable->axisY[yMin];
|
||||
xMaxValue = fromTable->axisX[xMax];
|
||||
xMinValue = fromTable->axisX[xMin];
|
||||
|
||||
int A = fromTable->values[yMin][xMin];
|
||||
int B = fromTable->values[yMin][xMax];
|
||||
int C = fromTable->values[yMax][xMin];
|
||||
int D = fromTable->values[yMax][xMax];
|
||||
|
||||
p = ((long)(X - xMinValue) << 8) / (xMaxValue - xMinValue); //(RPM - RPM[1])/(RPM[2]- RPM[1])
|
||||
q = 256 - (((long)(Y - yMaxValue) << 8) / (yMinValue - yMaxValue)); //(MAP - MAP[2])/(MAP[2]- MAP[1])
|
||||
|
||||
int m = ((256-p) * (256-q)) >> 8;
|
||||
int n = (p * (256-q)) >> 8;
|
||||
int o = ((256-p) * q) >> 8;
|
||||
int r = (p * q) >> 8;
|
||||
return ( (A * m) + (B * n) + (C * o) + (D * r) ) >> 8;
|
||||
}
|
||||
*/
|
||||
|
|
|
@ -19,12 +19,15 @@ Hence we will preload the timer with 131 cycles to leave 125 until overflow (1ms
|
|||
#ifndef TIMERS_H
|
||||
#define TIMERS_H
|
||||
|
||||
volatile int loop100ms;
|
||||
volatile int loop250ms;
|
||||
volatile byte loop33ms;
|
||||
volatile byte loop66ms;
|
||||
volatile byte loop100ms;
|
||||
volatile byte loop250ms;
|
||||
volatile int loopSec;
|
||||
|
||||
volatile unsigned int dwellLimit_uS;
|
||||
volatile uint16_t lastRPM_100ms; //Need to record this for rpmDOT calculation
|
||||
volatile uint16_t last250msLoopCount = 1000; //Set to effectively random number on startup. Just need this to be different to what mainLoopCount equals initially (Probably 0)
|
||||
|
||||
#if defined (CORE_TEENSY)
|
||||
IntervalTimer lowResTimer;
|
||||
|
|
|
@ -42,18 +42,27 @@ void initialiseTimers()
|
|||
#elif defined(CORE_STM32)
|
||||
Timer4.setPeriod(1000); // Set up period
|
||||
// Set up an interrupt
|
||||
Timer4.setMode(TIMER_CH1, TIMER_OUTPUT_COMPARE);
|
||||
Timer4.setMode(1, TIMER_OUTPUT_COMPARE);
|
||||
Timer4.attachInterrupt(1, oneMSInterval);
|
||||
Timer4.resume(); //Start Timer
|
||||
#endif
|
||||
|
||||
dwellLimit_uS = (1000 * configPage2.dwellLimit);
|
||||
#if defined(CORE_STM32)
|
||||
pinMode(LED_BUILTIN, OUTPUT);
|
||||
#endif
|
||||
|
||||
lastRPM_100ms = 0;
|
||||
loop33ms = 0;
|
||||
loop66ms = 0;
|
||||
loop100ms = 0;
|
||||
loop250ms = 0;
|
||||
loopSec = 0;
|
||||
}
|
||||
|
||||
|
||||
//Timer2 Overflow Interrupt Vector, called when the timer overflows.
|
||||
//Executes every ~1ms.
|
||||
#if defined(__AVR_ATmega1280__) || defined(__AVR_ATmega2560__) //AVR chips use the ISR for this
|
||||
#if defined(CORE_AVR) //AVR chips use the ISR for this
|
||||
ISR(TIMER2_OVF_vect, ISR_NOBLOCK)
|
||||
#elif defined (CORE_TEENSY) || defined(CORE_STM32)
|
||||
void oneMSInterval() //Most ARM chips can simply call a function
|
||||
|
@ -61,6 +70,8 @@ void oneMSInterval() //Most ARM chips can simply call a function
|
|||
{
|
||||
|
||||
//Increment Loop Counters
|
||||
loop33ms++;
|
||||
loop66ms++;
|
||||
loop100ms++;
|
||||
loop250ms++;
|
||||
loopSec++;
|
||||
|
@ -69,19 +80,40 @@ void oneMSInterval() //Most ARM chips can simply call a function
|
|||
|
||||
//Overdwell check
|
||||
targetOverdwellTime = micros() - dwellLimit_uS; //Set a target time in the past that all coil charging must have begun after. If the coil charge began before this time, it's been running too long
|
||||
bool isCrankLocked = configPage2.ignCranklock && (currentStatus.RPM < currentStatus.crankRPM); //Dwell limiter is disabled during cranking on setups using the locked cranking timing. WE HAVE to do the RPM check here as relying on the engine cranking bit can be potentially too slow in updating
|
||||
//Check first whether each spark output is currently on. Only check it's dwell time if it is
|
||||
|
||||
if(ignitionSchedule1.Status == RUNNING) { if( (ignitionSchedule1.startTime < targetOverdwellTime) && (configPage2.useDwellLim) ) { endCoil1Charge(); } }
|
||||
if(ignitionSchedule2.Status == RUNNING) { if( (ignitionSchedule2.startTime < targetOverdwellTime) && (configPage2.useDwellLim) ) { endCoil2Charge(); } }
|
||||
if(ignitionSchedule3.Status == RUNNING) { if( (ignitionSchedule3.startTime < targetOverdwellTime) && (configPage2.useDwellLim) ) { endCoil3Charge(); } }
|
||||
if(ignitionSchedule4.Status == RUNNING) { if( (ignitionSchedule4.startTime < targetOverdwellTime) && (configPage2.useDwellLim) ) { endCoil4Charge(); } }
|
||||
if(ignitionSchedule5.Status == RUNNING) { if( (ignitionSchedule5.startTime < targetOverdwellTime) && (configPage2.useDwellLim) ) { endCoil5Charge(); } }
|
||||
if(ignitionSchedule1.Status == RUNNING) { if( (ignitionSchedule1.startTime < targetOverdwellTime) && (configPage2.useDwellLim) && (isCrankLocked != true) ) { endCoil1Charge(); } }
|
||||
if(ignitionSchedule2.Status == RUNNING) { if( (ignitionSchedule2.startTime < targetOverdwellTime) && (configPage2.useDwellLim) && (isCrankLocked != true) ) { endCoil2Charge(); } }
|
||||
if(ignitionSchedule3.Status == RUNNING) { if( (ignitionSchedule3.startTime < targetOverdwellTime) && (configPage2.useDwellLim) && (isCrankLocked != true) ) { endCoil3Charge(); } }
|
||||
if(ignitionSchedule4.Status == RUNNING) { if( (ignitionSchedule4.startTime < targetOverdwellTime) && (configPage2.useDwellLim) && (isCrankLocked != true) ) { endCoil4Charge(); } }
|
||||
if(ignitionSchedule5.Status == RUNNING) { if( (ignitionSchedule5.startTime < targetOverdwellTime) && (configPage2.useDwellLim) && (isCrankLocked != true) ) { endCoil5Charge(); } }
|
||||
|
||||
|
||||
|
||||
//30Hz loop
|
||||
if (loop33ms == 33)
|
||||
{
|
||||
loop33ms = 0;
|
||||
BIT_SET(TIMER_mask, BIT_TIMER_30HZ);
|
||||
}
|
||||
|
||||
//15Hz loop
|
||||
if (loop66ms == 66)
|
||||
{
|
||||
loop66ms = 0;
|
||||
BIT_SET(TIMER_mask, BIT_TIMER_15HZ);
|
||||
}
|
||||
|
||||
//Loop executed every 100ms loop
|
||||
//Anything inside this if statement will run every 100ms.
|
||||
if (loop100ms == 100)
|
||||
{
|
||||
loop100ms = 0; //Reset counter
|
||||
BIT_SET(TIMER_mask, BIT_TIMER_10HZ);
|
||||
#if defined(CORE_STM32) //debug purpose, only visal for running code
|
||||
digitalWrite(LED_BUILTIN, !digitalRead(LED_BUILTIN));
|
||||
#endif
|
||||
|
||||
currentStatus.rpmDOT = (currentStatus.RPM - lastRPM_100ms) * 10; //This is the RPM per second that the engine has accelerated/decelleratedin the last loop
|
||||
lastRPM_100ms = currentStatus.RPM; //Record the current RPM for next calc
|
||||
|
@ -91,10 +123,16 @@ void oneMSInterval() //Most ARM chips can simply call a function
|
|||
//Anything inside this if statement will run every 250ms.
|
||||
if (loop250ms == 250)
|
||||
{
|
||||
loop250ms = 0; //Reset Counter.
|
||||
loop250ms = 0; //Reset Counter
|
||||
BIT_SET(TIMER_mask, BIT_TIMER_4HZ);
|
||||
|
||||
#if defined(CORE_AVR)
|
||||
//Reset watchdog timer (Not active currently)
|
||||
//wdt_reset();
|
||||
//DIY watchdog
|
||||
//This is a sign of a crash:
|
||||
//if( (initialisationComplete == true) && (last250msLoopCount == mainLoopCount) ) { setup(); }
|
||||
//else { last250msLoopCount = mainLoopCount; }
|
||||
#endif
|
||||
}
|
||||
|
||||
|
@ -102,9 +140,10 @@ void oneMSInterval() //Most ARM chips can simply call a function
|
|||
if (loopSec == 1000)
|
||||
{
|
||||
loopSec = 0; //Reset counter.
|
||||
BIT_SET(TIMER_mask, BIT_TIMER_1HZ);
|
||||
|
||||
dwellLimit_uS = (1000 * configPage2.dwellLimit); //Update uS value incase setting has changed
|
||||
if ( configPage2.ignCranklock && BIT_CHECK(currentStatus.engine, BIT_ENGINE_CRANK)) { dwellLimit_uS = dwellLimit_uS * 3; } //Make sure the overdwell doesn't clobber the fixed ignition cranking if enabled.
|
||||
currentStatus.crankRPM = ((unsigned int)configPage2.crankRPM * 100);
|
||||
|
||||
//**************************************************************************************************************************************************
|
||||
//This updates the runSecs variable
|
||||
|
@ -123,18 +162,23 @@ void oneMSInterval() //Most ARM chips can simply call a function
|
|||
currentStatus.secl++;
|
||||
//**************************************************************************************************************************************************
|
||||
//Check the fan output status
|
||||
if (configPage4.fanEnable == 1)
|
||||
if (configPage3.fanEnable == 1)
|
||||
{
|
||||
fanControl(); // Fucntion to turn the cooling fan on/off
|
||||
}
|
||||
|
||||
//Check whether fuel pump priming is complete
|
||||
if(!fpPrimed)
|
||||
if(fpPrimed == false)
|
||||
{
|
||||
if(currentStatus.secl >= configPage1.fpPrime)
|
||||
{
|
||||
fpPrimed = true; //Mark the priming as being completed
|
||||
if(currentStatus.RPM == 0) { digitalWrite(pinFuelPump, LOW); fuelPumpOn = false; } //If we reach here then the priming is complete, however only turn off the fuel pump if the engine isn't running
|
||||
if(currentStatus.RPM == 0)
|
||||
{
|
||||
//If we reach here then the priming is complete, however only turn off the fuel pump if the engine isn't running
|
||||
digitalWrite(pinFuelPump, LOW);
|
||||
fuelPumpOn = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
//**************************************************************************************************************************************************
|
||||
|
@ -173,7 +217,7 @@ void oneMSInterval() //Most ARM chips can simply call a function
|
|||
}
|
||||
|
||||
}
|
||||
#if defined(__AVR_ATmega1280__) || defined(__AVR_ATmega2560__) //AVR chips use the ISR for this
|
||||
#if defined(CORE_AVR) //AVR chips use the ISR for this
|
||||
//Reset Timer2 to trigger in another ~1ms
|
||||
TCNT2 = 131; //Preload timer2 with 100 cycles, leaving 156 till overflow.
|
||||
TIFR2 = 0x00; //Timer2 INT Flag Reg: Clear Timer Overflow Flag
|
||||
|
|
|
@ -8,7 +8,7 @@
|
|||
|
||||
void doUpdates()
|
||||
{
|
||||
#define CURRENT_DATA_VERSION 3
|
||||
#define CURRENT_DATA_VERSION 6
|
||||
|
||||
//May 2017 firmware introduced a -40 offset on the ignition table. Update that table to +40
|
||||
if(EEPROM.read(EEPROM_DATA_VERSION) == 2)
|
||||
|
@ -20,15 +20,70 @@ void doUpdates()
|
|||
ignitionTable.values[x][y] = ignitionTable.values[x][y] + 40;
|
||||
}
|
||||
}
|
||||
writeConfig();
|
||||
writeAllConfig();
|
||||
EEPROM.write(EEPROM_DATA_VERSION, 3);
|
||||
}
|
||||
//June 2017 required the forced addition of some CAN values to avoid weird errors
|
||||
if(EEPROM.read(EEPROM_DATA_VERSION) == 3)
|
||||
{
|
||||
configPage10.speeduino_tsCanId = 0;
|
||||
configPage10.true_address = 256;
|
||||
configPage10.realtime_base_address = 336;
|
||||
|
||||
//There was a bad value in the May base tune for the spark duration setting, fix it here if it's a problem
|
||||
if(configPage2.sparkDur == 255) { configPage2.sparkDur = 10; }
|
||||
|
||||
writeAllConfig();
|
||||
EEPROM.write(EEPROM_DATA_VERSION, 4);
|
||||
}
|
||||
//July 2017 adds a cranking enrichment curve in place of the single value. This converts that single value to the curve
|
||||
if(EEPROM.read(EEPROM_DATA_VERSION) == 4)
|
||||
{
|
||||
//Some default values for the bins (Doesn't matter too much here as the values against them will all be identical)
|
||||
configPage11.crankingEnrichBins[0] = 0;
|
||||
configPage11.crankingEnrichBins[1] = 40;
|
||||
configPage11.crankingEnrichBins[2] = 70;
|
||||
configPage11.crankingEnrichBins[3] = 100;
|
||||
|
||||
configPage11.crankingEnrichValues[0] = 100 + configPage1.crankingPct;
|
||||
configPage11.crankingEnrichValues[1] = 100 + configPage1.crankingPct;
|
||||
configPage11.crankingEnrichValues[2] = 100 + configPage1.crankingPct;
|
||||
configPage11.crankingEnrichValues[3] = 100 + configPage1.crankingPct;
|
||||
|
||||
writeAllConfig();
|
||||
EEPROM.write(EEPROM_DATA_VERSION, 5);
|
||||
}
|
||||
//September 2017 had a major change to increase the minimum table size to 128. This required multiple pieces of data being moved around
|
||||
if(EEPROM.read(EEPROM_DATA_VERSION) == 5)
|
||||
{
|
||||
//Data after page 4 has to move back 128 bytes
|
||||
for(int x=0; x < 1152; x++)
|
||||
{
|
||||
int endMem = EEPROM_CONFIG11_END - x;
|
||||
int startMem = endMem - 128; //
|
||||
byte currentVal = EEPROM.read(startMem);
|
||||
EEPROM.update(endMem, currentVal);
|
||||
}
|
||||
//The remaining data only has to move back 64 bytes
|
||||
for(int x=0; x < 352; x++)
|
||||
{
|
||||
int endMem = EEPROM_CONFIG11_END - 1152 - x;
|
||||
int startMem = endMem - 64; //
|
||||
byte currentVal = EEPROM.read(startMem);
|
||||
EEPROM.update(endMem, currentVal);
|
||||
}
|
||||
|
||||
EEPROM.write(EEPROM_DATA_VERSION, 6);
|
||||
loadConfig(); //Reload the config after changing everything in EEPROM
|
||||
}
|
||||
|
||||
//Final check is always for 255 and 0 (Brand new arduino)
|
||||
if( (EEPROM.read(EEPROM_DATA_VERSION) == 0) || (EEPROM.read(EEPROM_DATA_VERSION) == 255) )
|
||||
{
|
||||
configPage10.true_address = 0x200;
|
||||
EEPROM.write(EEPROM_DATA_VERSION, CURRENT_DATA_VERSION);
|
||||
|
||||
}
|
||||
|
||||
//Check to see if someone has downgraded versions:
|
||||
if( EEPROM.read(EEPROM_DATA_VERSION) > CURRENT_DATA_VERSION ) { EEPROM.write(EEPROM_DATA_VERSION, CURRENT_DATA_VERSION); }
|
||||
}
|
||||
|
|
|
@ -6,10 +6,51 @@ These are some utility functions and variables used through the main code
|
|||
|
||||
#include <Arduino.h>
|
||||
|
||||
int freeRam ();
|
||||
uint16_t freeRam ();
|
||||
void setPinMapping(byte boardID);
|
||||
unsigned int PW();
|
||||
unsigned int PW_SD();
|
||||
unsigned int PW_AN();
|
||||
|
||||
//This is dumb, but it'll do for now to get things compiling
|
||||
#if defined(CORE_STM32)
|
||||
//STM32F1/variants/.../board.cpp
|
||||
#if defined (STM32F4)
|
||||
#define A0 PA0
|
||||
#define A1 PA1
|
||||
#define A2 PA2
|
||||
#define A3 PA3
|
||||
#define A4 PA4
|
||||
#define A5 PA5
|
||||
#define A6 PA6
|
||||
#define A7 PA7
|
||||
#define A8 PB0
|
||||
#define A9 PB1
|
||||
#define A10 PC0
|
||||
#define A11 PC1
|
||||
#define A12 PC2
|
||||
#define A13 PC3
|
||||
#define A14 PC4
|
||||
#define A15 PC5
|
||||
#else
|
||||
#define A0 PB0
|
||||
#define A1 PA7
|
||||
#define A2 PA6
|
||||
#define A3 PA5
|
||||
#define A4 PA4
|
||||
#define A5 PA3
|
||||
#define A6 PA2
|
||||
#define A7 PA1
|
||||
#define A8 PA0
|
||||
//STM32F1 have only 9 12bit adc
|
||||
#define A9 PB0
|
||||
#define A10 PA7
|
||||
#define A11 PA6
|
||||
#define A12 PA5
|
||||
#define A13 PA4
|
||||
#define A14 PA3
|
||||
#define A15 PA2
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#endif // UTILS_H
|
||||
|
|
|
@ -7,15 +7,18 @@
|
|||
|
||||
/*
|
||||
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 "utils.h"
|
||||
|
||||
int freeRam ()
|
||||
uint16_t freeRam ()
|
||||
{
|
||||
#if defined(__AVR_ATmega1280__) || defined(__AVR_ATmega2560__)
|
||||
extern int __heap_start, *__brkval;
|
||||
int v;
|
||||
return (int) &v - (__brkval == 0 ? (int) &__heap_start : (int) __brkval);
|
||||
uint16_t v;
|
||||
|
||||
return (uint16_t) &v - (__brkval == 0 ? (int) &__heap_start : (int) __brkval);
|
||||
|
||||
#elif defined(CORE_TEENSY)
|
||||
uint32_t stackTop;
|
||||
uint32_t heapTop;
|
||||
|
@ -31,35 +34,14 @@ int freeRam ()
|
|||
// The difference is the free, available ram.
|
||||
return (uint16_t)stackTop - heapTop;
|
||||
#elif defined(CORE_STM32)
|
||||
//Figure this out some_time
|
||||
return 0;
|
||||
char top = 't';
|
||||
return &top - reinterpret_cast<char*>(sbrk(0));
|
||||
|
||||
#endif
|
||||
}
|
||||
|
||||
void setPinMapping(byte boardID)
|
||||
{
|
||||
//This is dumb, but it'll do for now to get things compiling
|
||||
#if defined(CORE_STM32)
|
||||
//STM32F1/variants/.../board.cpp
|
||||
#define A0 boardADCPins[0]
|
||||
#define A1 boardADCPins[1]
|
||||
#define A2 boardADCPins[2]
|
||||
#define A3 boardADCPins[3]
|
||||
#define A4 boardADCPins[4]
|
||||
#define A5 boardADCPins[5]
|
||||
#define A6 boardADCPins[6]
|
||||
#define A7 boardADCPins[7]
|
||||
#define A8 boardADCPins[8]
|
||||
#define A9 boardADCPins[9]
|
||||
//STM32F1 have only 9 12bit adc
|
||||
#define A10 boardADCPins[0]
|
||||
#define A11 boardADCPins[1]
|
||||
#define A12 boardADCPins[2]
|
||||
#define A13 boardADCPins[3]
|
||||
#define A14 boardADCPins[4]
|
||||
#define A15 boardADCPins[5]
|
||||
#endif
|
||||
|
||||
switch (boardID)
|
||||
{
|
||||
case 0:
|
||||
|
@ -164,35 +146,6 @@ void setPinMapping(byte boardID)
|
|||
pinCoil4 = 21;
|
||||
pinCoil3 = 30;
|
||||
pinO2 = A22;
|
||||
#elif defined(CORE_STM32)
|
||||
//http://docs.leaflabs.com/static.leaflabs.com/pub/leaflabs/maple-docs/0.0.12/hardware/maple-mini.html#master-pin-map
|
||||
//pins 23, 24 and 33 couldn't be used
|
||||
pinInjector1 = 15; //Output pin injector 1 is on
|
||||
pinInjector2 = 16; //Output pin injector 2 is on
|
||||
pinInjector3 = 17; //Output pin injector 3 is on
|
||||
pinInjector4 = 18; //Output pin injector 4 is on
|
||||
pinCoil1 = 19; //Pin for coil 1
|
||||
pinCoil2 = 20; //Pin for coil 2
|
||||
pinCoil3 = 21; //Pin for coil 3
|
||||
pinCoil4 = 26; //Pin for coil 4
|
||||
pinCoil5 = 27; //Pin for coil 5
|
||||
pinTPS = A0; //TPS input pin
|
||||
pinMAP = A1; //MAP sensor pin
|
||||
pinIAT = A2; //IAT sensor pin
|
||||
pinCLT = A3; //CLS sensor pin
|
||||
pinO2 = A4; //O2 Sensor pin
|
||||
pinBat = A5; //Battery reference voltage pin
|
||||
pinStepperDir = 12; //Direction pin for DRV8825 driver
|
||||
pinStepperStep = 13; //Step pin for DRV8825 driver
|
||||
pinStepperEnable = 14; //Enable pin for DRV8825
|
||||
pinDisplayReset = 2; // OLED reset pin
|
||||
pinFan = 1; //Pin for the fan output
|
||||
pinFuelPump = 0; //Fuel pump output
|
||||
pinTachOut = 31; //Tacho output pin
|
||||
//external interrupt enabled pins
|
||||
pinFlex = 32; // Flex sensor (Must be external interrupt enabled)
|
||||
pinTrigger = 25; //The CAS pin
|
||||
pinTrigger2 = 22; //The Cam Sensor pin
|
||||
#endif
|
||||
break;
|
||||
|
||||
|
@ -241,6 +194,37 @@ void setPinMapping(byte boardID)
|
|||
pinCoil4 = 29;
|
||||
pinCoil3 = 30;
|
||||
pinO2 = A22;
|
||||
#elif defined(STM32F4)
|
||||
pinInjector1 = PE7; //Output pin injector 1 is on
|
||||
pinInjector2 = PE8; //Output pin injector 2 is on
|
||||
pinInjector3 = PE9; //Output pin injector 3 is on
|
||||
pinInjector4 = PE10; //Output pin injector 4 is on
|
||||
pinInjector5 = PE11; //Output pin injector 5 is on
|
||||
pinCoil1 = PB10; //Pin for coil 1
|
||||
pinCoil2 = PB11; //Pin for coil 2
|
||||
pinCoil3 = PB12; //Pin for coil 3
|
||||
pinCoil4 = PB13; //Pin for coil 4
|
||||
pinCoil5 = PB14; //Pin for coil 5
|
||||
pinTPS = A0; //TPS input pin
|
||||
pinMAP = A1; //MAP sensor pin
|
||||
pinIAT = A2; //IAT sensor pin
|
||||
pinCLT = A3; //CLS sensor pin
|
||||
pinO2 = A4; //O2 Sensor pin
|
||||
pinBat = A5; //Battery reference voltage pin
|
||||
pinBaro = A6;
|
||||
pinStepperDir = PD8; //Direction pin for DRV8825 driver
|
||||
pinStepperStep = PB15; //Step pin for DRV8825 driver
|
||||
pinStepperEnable = PD9; //Enable pin for DRV8825
|
||||
pinDisplayReset = PE1; // OLED reset pin
|
||||
pinFan = PE2; //Pin for the fan output
|
||||
pinFuelPump = PA6; //Fuel pump output
|
||||
pinTachOut = PA7; //Tacho output pin
|
||||
//external interrupt enabled pins
|
||||
pinFlex = PC4; // Flex sensor (Must be external interrupt enabled)
|
||||
pinTrigger = PC5; //The CAS pin
|
||||
pinTrigger2 = PC6; //The Cam Sensor pin
|
||||
pinBoost = PE0; //Boost control
|
||||
pinVVT_1 = PE1; //Default VVT output
|
||||
#elif defined(CORE_STM32)
|
||||
//http://docs.leaflabs.com/static.leaflabs.com/pub/leaflabs/maple-docs/0.0.12/hardware/maple-mini.html#master-pin-map
|
||||
//pins 23, 24 and 33 couldn't be used
|
||||
|
@ -270,6 +254,9 @@ void setPinMapping(byte boardID)
|
|||
pinFlex = 32; // Flex sensor (Must be external interrupt enabled)
|
||||
pinTrigger = 25; //The CAS pin
|
||||
pinTrigger2 = 22; //The Cam Sensor pin
|
||||
pinBaro = pinMAP;
|
||||
pinBoost = 1; //Boost control
|
||||
pinVVT_1 = 0; //Default VVT output
|
||||
#endif
|
||||
break;
|
||||
|
||||
|
@ -277,13 +264,13 @@ void setPinMapping(byte boardID)
|
|||
//Pin mappings as per the 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
|
||||
pinInjector3 = 8; //Output pin injector 3 is on
|
||||
pinInjector4 = 9; //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 = 35; //Pin for coil 3
|
||||
pinCoil4 = 37; //Pin for coil 4
|
||||
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
|
||||
|
@ -296,13 +283,14 @@ void setPinMapping(byte boardID)
|
|||
pinDisplayReset = 48; // OLED reset pin
|
||||
pinTachOut = 49; //Tacho output pin (Goes to ULN2803)
|
||||
pinIdle1 = 2; //Single wire idle control
|
||||
pinIdle2 = 3; //2 wire idle control (Note this is shared with boost!!!)
|
||||
pinFuelPump = 37; //Fuel pump output (Goes to ULN2803)
|
||||
pinBoost = 4;
|
||||
pinIdle2 = 4; //2 wire idle control (Note this is shared with boost!!!)
|
||||
pinFuelPump = 37; //Fuel pump output
|
||||
pinStepperDir = 16; //Direction pin for DRV8825 driver
|
||||
pinStepperStep = 17; //Step pin for DRV8825 driver
|
||||
pinFan = 47; //Pin for the fan output (Goes to ULN2803)
|
||||
pinLaunch = 12; //Can be overwritten below
|
||||
pinFlex = 2; // Flex sensor (Must be external interrupt enabled)
|
||||
pinFlex = 3; // Flex sensor (Must be external interrupt enabled)
|
||||
break;
|
||||
|
||||
case 10:
|
||||
|
@ -370,6 +358,7 @@ void setPinMapping(byte boardID)
|
|||
pinFan = 47; //Pin for the fan output
|
||||
pinFuelPump = 4; //Fuel pump output
|
||||
pinTachOut = 49; //Tacho output pin
|
||||
break;
|
||||
|
||||
case 30:
|
||||
//Pin mappings as per the dazv6 shield
|
||||
|
@ -436,21 +425,22 @@ void setPinMapping(byte boardID)
|
|||
pinFan = 47; //Pin for the fan output
|
||||
pinFuelPump = 4; //Fuel pump output
|
||||
pinTachOut = 49; //Tacho output pin
|
||||
pinFlex = 3; // Flex sensor (Must be external interrupt enabled)
|
||||
pinBoost = 5;
|
||||
pinIdle1 = 6;
|
||||
break;
|
||||
}
|
||||
|
||||
//First time running?
|
||||
if (configPage3.launchPin < BOARD_NR_GPIO_PINS)
|
||||
{
|
||||
//Setup any devices that are using selectable pins
|
||||
if (configPage3.launchPin != 0) { pinLaunch = configPage3.launchPin; }
|
||||
if (configPage2.ignBypassPin != 0) { pinIgnBypass = configPage2.ignBypassPin; }
|
||||
if (configPage1.tachoPin != 0) { pinTachOut = configPage1.tachoPin; }
|
||||
if (configPage2.fuelPumpPin != 0) { pinFuelPump = configPage2.fuelPumpPin; }
|
||||
if (configPage4.fanPin != 0) { pinFan = configPage4.fanPin; }
|
||||
if (configPage3.boostPin != 0) { pinBoost = configPage3.boostPin; }
|
||||
if (configPage3.vvtPin != 0) { pinVVT_1 = configPage3.vvtPin; }
|
||||
}
|
||||
|
||||
if ( (configPage3.launchPin != 0) && (configPage3.launchPin < BOARD_NR_GPIO_PINS) ) { pinLaunch = configPage3.launchPin; }
|
||||
if ( (configPage2.ignBypassPin != 0) && (configPage2.ignBypassPin < BOARD_NR_GPIO_PINS) ) { pinIgnBypass = configPage2.ignBypassPin; }
|
||||
if ( (configPage1.tachoPin != 0) && (configPage1.tachoPin < BOARD_NR_GPIO_PINS) ) { pinTachOut = configPage1.tachoPin; }
|
||||
if ( (configPage2.fuelPumpPin != 0) && (configPage2.fuelPumpPin < BOARD_NR_GPIO_PINS) ) { pinFuelPump = configPage2.fuelPumpPin; }
|
||||
if ( (configPage3.fanPin != 0) && (configPage3.fanPin < BOARD_NR_GPIO_PINS) ) { pinFan = configPage3.fanPin; }
|
||||
if ( (configPage3.boostPin != 0) && (configPage3.boostPin < BOARD_NR_GPIO_PINS) ) { pinBoost = configPage3.boostPin; }
|
||||
if ( (configPage3.vvtPin != 0) && (configPage3.vvtPin < BOARD_NR_GPIO_PINS) ) { pinVVT_1 = configPage3.vvtPin; }
|
||||
if ( (configPage3.useExtBaro != 0) && (configPage3.baroPin < BOARD_NR_GPIO_PINS) ) { pinBaro = configPage3.baroPin + A0; }
|
||||
|
||||
//Finally, set the relevant pin modes for outputs
|
||||
pinMode(pinCoil1, OUTPUT);
|
||||
|
@ -499,9 +489,13 @@ void setPinMapping(byte boardID)
|
|||
|
||||
tach_pin_port = portOutputRegister(digitalPinToPort(pinTachOut));
|
||||
tach_pin_mask = digitalPinToBitMask(pinTachOut);
|
||||
pump_pin_port = portOutputRegister(digitalPinToPort(pinFuelPump));
|
||||
pump_pin_mask = digitalPinToBitMask(pinFuelPump);
|
||||
|
||||
//And for inputs
|
||||
//And for inputs
|
||||
#if defined(CORE_STM32)
|
||||
#ifndef ARDUINO_ARCH_STM32 //libmaple core aka STM32DUINO
|
||||
pinMode(pinMAP, INPUT_ANALOG);
|
||||
pinMode(pinO2, INPUT_ANALOG);
|
||||
pinMode(pinO2_2, INPUT_ANALOG);
|
||||
|
@ -509,6 +503,7 @@ void setPinMapping(byte boardID)
|
|||
pinMode(pinIAT, INPUT_ANALOG);
|
||||
pinMode(pinCLT, INPUT_ANALOG);
|
||||
pinMode(pinBat, INPUT_ANALOG);
|
||||
pinMode(pinBaro, INPUT_ANALOG);
|
||||
#else
|
||||
pinMode(pinMAP, INPUT);
|
||||
pinMode(pinO2, INPUT);
|
||||
|
@ -517,13 +512,14 @@ void setPinMapping(byte boardID)
|
|||
pinMode(pinIAT, INPUT);
|
||||
pinMode(pinCLT, INPUT);
|
||||
pinMode(pinBat, INPUT);
|
||||
pinMode(pinBaro, INPUT);
|
||||
#endif
|
||||
#endif
|
||||
pinMode(pinTrigger, INPUT);
|
||||
pinMode(pinTrigger2, INPUT);
|
||||
pinMode(pinTrigger3, INPUT);
|
||||
pinMode(pinFlex, INPUT_PULLUP); //Standard GM / Continental flex sensor requires pullup
|
||||
// pinMode(pinLaunch, INPUT_PULLUP); //This should work for both NO and NC grounding switches
|
||||
if (configPage3.lnchPullRes) {
|
||||
if (configPage3.lnchPullRes == true) {
|
||||
pinMode(pinLaunch, INPUT_PULLUP);
|
||||
}
|
||||
else {
|
||||
|
@ -545,6 +541,281 @@ void setPinMapping(byte boardID)
|
|||
#endif
|
||||
}
|
||||
|
||||
void initialiseTriggers()
|
||||
{
|
||||
byte triggerInterrupt = 0; // By default, use the first interrupt
|
||||
byte triggerInterrupt2 = 1;
|
||||
|
||||
#if defined(CORE_AVR)
|
||||
switch (pinTrigger) {
|
||||
//Arduino Mega 2560 mapping
|
||||
case 2:
|
||||
triggerInterrupt = 0; break;
|
||||
case 3:
|
||||
triggerInterrupt = 1; break;
|
||||
case 18:
|
||||
triggerInterrupt = 5; break;
|
||||
case 19:
|
||||
triggerInterrupt = 4; break;
|
||||
case 20:
|
||||
triggerInterrupt = 3; break;
|
||||
case 21:
|
||||
triggerInterrupt = 2; break;
|
||||
default:
|
||||
triggerInterrupt = 0; break; //This should NEVER happen
|
||||
}
|
||||
#else
|
||||
triggerInterrupt = pinTrigger;
|
||||
#endif
|
||||
|
||||
#if defined(CORE_AVR)
|
||||
switch (pinTrigger2) {
|
||||
//Arduino Mega 2560 mapping
|
||||
case 2:
|
||||
triggerInterrupt2 = 0; break;
|
||||
case 3:
|
||||
triggerInterrupt2 = 1; break;
|
||||
case 18:
|
||||
triggerInterrupt2 = 5; break;
|
||||
case 19:
|
||||
triggerInterrupt2 = 4; break;
|
||||
case 20:
|
||||
triggerInterrupt2 = 3; break;
|
||||
case 21:
|
||||
triggerInterrupt2 = 2; break;
|
||||
default:
|
||||
triggerInterrupt2 = 0; break; //This should NEVER happen
|
||||
}
|
||||
#else
|
||||
triggerInterrupt2 = pinTrigger2;
|
||||
#endif
|
||||
|
||||
pinMode(pinTrigger, INPUT);
|
||||
pinMode(pinTrigger2, INPUT);
|
||||
pinMode(pinTrigger3, INPUT);
|
||||
//digitalWrite(pinTrigger, HIGH);
|
||||
detachInterrupt(triggerInterrupt);
|
||||
detachInterrupt(triggerInterrupt2);
|
||||
|
||||
//Set the trigger function based on the decoder in the config
|
||||
switch (configPage2.TrigPattern)
|
||||
{
|
||||
case 0:
|
||||
//Missing tooth decoder
|
||||
triggerSetup_missingTooth();
|
||||
trigger = triggerPri_missingTooth;
|
||||
triggerSecondary = triggerSec_missingTooth;
|
||||
getRPM = getRPM_missingTooth;
|
||||
getCrankAngle = getCrankAngle_missingTooth;
|
||||
triggerSetEndTeeth = triggerSetEndTeeth_missingTooth;
|
||||
|
||||
if(configPage2.TrigEdge == 0) { attachInterrupt(triggerInterrupt, trigger, RISING); } // Attach the crank trigger wheel interrupt (Hall sensor drags to ground when triggering)
|
||||
else { attachInterrupt(triggerInterrupt, trigger, FALLING); }
|
||||
if(configPage2.TrigEdgeSec == 0) { attachInterrupt(triggerInterrupt2, triggerSec_missingTooth, RISING); }
|
||||
else { attachInterrupt(triggerInterrupt2, triggerSec_missingTooth, FALLING); }
|
||||
break;
|
||||
|
||||
case 1:
|
||||
// Basic distributor
|
||||
triggerSetup_BasicDistributor();
|
||||
trigger = triggerPri_BasicDistributor;
|
||||
getRPM = getRPM_BasicDistributor;
|
||||
getCrankAngle = getCrankAngle_BasicDistributor;
|
||||
triggerSetEndTeeth = triggerSetEndTeeth_BasicDistributor;
|
||||
|
||||
if(configPage2.TrigEdge == 0) { attachInterrupt(triggerInterrupt, trigger, RISING); } // Attach the crank trigger wheel interrupt (Hall sensor drags to ground when triggering)
|
||||
else { attachInterrupt(triggerInterrupt, trigger, FALLING); }
|
||||
break;
|
||||
|
||||
case 2:
|
||||
triggerSetup_DualWheel();
|
||||
trigger = triggerPri_DualWheel;
|
||||
getRPM = getRPM_DualWheel;
|
||||
getCrankAngle = getCrankAngle_DualWheel;
|
||||
triggerSetEndTeeth = triggerSetEndTeeth_DualWheel;
|
||||
|
||||
if(configPage2.TrigEdge == 0) { attachInterrupt(triggerInterrupt, trigger, RISING); } // Attach the crank trigger wheel interrupt (Hall sensor drags to ground when triggering)
|
||||
else { attachInterrupt(triggerInterrupt, trigger, FALLING); }
|
||||
if(configPage2.TrigEdgeSec == 0) { attachInterrupt(triggerInterrupt2, triggerSec_DualWheel, RISING); }
|
||||
else { attachInterrupt(triggerInterrupt2, triggerSec_DualWheel, FALLING); }
|
||||
break;
|
||||
|
||||
case 3:
|
||||
triggerSetup_GM7X();
|
||||
trigger = triggerPri_GM7X;
|
||||
getRPM = getRPM_GM7X;
|
||||
getCrankAngle = getCrankAngle_GM7X;
|
||||
triggerSetEndTeeth = triggerSetEndTeeth_GM7X;
|
||||
|
||||
if(configPage2.TrigEdge == 0) { attachInterrupt(triggerInterrupt, trigger, RISING); } // Attach the crank trigger wheel interrupt (Hall sensor drags to ground when triggering)
|
||||
else { attachInterrupt(triggerInterrupt, trigger, FALLING); }
|
||||
break;
|
||||
|
||||
case 4:
|
||||
triggerSetup_4G63();
|
||||
trigger = triggerPri_4G63;
|
||||
getRPM = getRPM_4G63;
|
||||
getCrankAngle = getCrankAngle_4G63;
|
||||
triggerSetEndTeeth = triggerSetEndTeeth_4G63;
|
||||
|
||||
//These may both need to change, not sure
|
||||
if(configPage2.TrigEdge == 0)
|
||||
{
|
||||
attachInterrupt(triggerInterrupt, trigger, CHANGE); // Attach the crank trigger wheel interrupt (Hall sensor drags to ground when triggering)
|
||||
attachInterrupt(triggerInterrupt2, triggerSec_4G63, FALLING); //changed
|
||||
}
|
||||
else
|
||||
{
|
||||
attachInterrupt(triggerInterrupt, trigger, CHANGE); // Primary trigger connects to
|
||||
attachInterrupt(triggerInterrupt2, triggerSec_4G63, FALLING);
|
||||
}
|
||||
break;
|
||||
|
||||
case 5:
|
||||
triggerSetup_24X();
|
||||
trigger = triggerPri_24X;
|
||||
getRPM = getRPM_24X;
|
||||
getCrankAngle = getCrankAngle_24X;
|
||||
triggerSetEndTeeth = triggerSetEndTeeth_24X;
|
||||
|
||||
if(configPage2.TrigEdge == 0) { attachInterrupt(triggerInterrupt, trigger, RISING); } // Attach the crank trigger wheel interrupt (Hall sensor drags to ground when triggering)
|
||||
else { attachInterrupt(triggerInterrupt, trigger, FALLING); } // Primary trigger connects to
|
||||
attachInterrupt(triggerInterrupt2, triggerSec_24X, CHANGE);
|
||||
break;
|
||||
|
||||
case 6:
|
||||
triggerSetup_Jeep2000();
|
||||
trigger = triggerPri_Jeep2000;
|
||||
getRPM = getRPM_Jeep2000;
|
||||
getCrankAngle = getCrankAngle_Jeep2000;
|
||||
triggerSetEndTeeth = triggerSetEndTeeth_Jeep2000;
|
||||
|
||||
if(configPage2.TrigEdge == 0) { attachInterrupt(triggerInterrupt, trigger, RISING); } // Attach the crank trigger wheel interrupt (Hall sensor drags to ground when triggering)
|
||||
else { attachInterrupt(triggerInterrupt, trigger, FALLING); } // Primary trigger connects to
|
||||
attachInterrupt(triggerInterrupt2, triggerSec_Jeep2000, CHANGE);
|
||||
break;
|
||||
|
||||
case 7:
|
||||
triggerSetup_Audi135();
|
||||
trigger = triggerPri_Audi135;
|
||||
getRPM = getRPM_Audi135;
|
||||
getCrankAngle = getCrankAngle_Audi135;
|
||||
triggerSetEndTeeth = triggerSetEndTeeth_Audi135;
|
||||
|
||||
if(configPage2.TrigEdge == 0) { attachInterrupt(triggerInterrupt, trigger, RISING); } // Attach the crank trigger wheel interrupt (Hall sensor drags to ground when triggering)
|
||||
else { attachInterrupt(triggerInterrupt, trigger, FALLING); }
|
||||
attachInterrupt(triggerInterrupt2, triggerSec_Audi135, RISING);
|
||||
break;
|
||||
|
||||
case 8:
|
||||
triggerSetup_HondaD17();
|
||||
trigger = triggerPri_HondaD17;
|
||||
getRPM = getRPM_HondaD17;
|
||||
getCrankAngle = getCrankAngle_HondaD17;
|
||||
triggerSetEndTeeth = triggerSetEndTeeth_HondaD17;
|
||||
|
||||
if(configPage2.TrigEdge == 0) { attachInterrupt(triggerInterrupt, trigger, RISING); } // Attach the crank trigger wheel interrupt (Hall sensor drags to ground when triggering)
|
||||
else { attachInterrupt(triggerInterrupt, trigger, FALLING); } // Primary trigger connects to
|
||||
attachInterrupt(triggerInterrupt2, triggerSec_HondaD17, CHANGE);
|
||||
break;
|
||||
|
||||
case 9:
|
||||
triggerSetup_Miata9905();
|
||||
trigger = triggerPri_Miata9905;
|
||||
getRPM = getRPM_Miata9905;
|
||||
getCrankAngle = getCrankAngle_Miata9905;
|
||||
triggerSetEndTeeth = triggerSetEndTeeth_Miata9905;
|
||||
|
||||
//These may both need to change, not sure
|
||||
// Attach the crank trigger wheel interrupt (Hall sensor drags to ground when triggering)
|
||||
if(configPage2.TrigEdge == 0) { attachInterrupt(triggerInterrupt, trigger, RISING); }
|
||||
else { attachInterrupt(triggerInterrupt, trigger, FALLING); }
|
||||
|
||||
if(configPage2.TrigEdgeSec == 0) { attachInterrupt(triggerInterrupt2, triggerSec_Miata9905, RISING); }
|
||||
else { attachInterrupt(triggerInterrupt2, triggerSec_Miata9905, FALLING); }
|
||||
break;
|
||||
|
||||
case 10:
|
||||
triggerSetup_MazdaAU();
|
||||
trigger = triggerPri_MazdaAU;
|
||||
getRPM = getRPM_MazdaAU;
|
||||
getCrankAngle = getCrankAngle_MazdaAU;
|
||||
triggerSetEndTeeth = triggerSetEndTeeth_MazdaAU;
|
||||
|
||||
if(configPage2.TrigEdge == 0) { attachInterrupt(triggerInterrupt, trigger, RISING); } // Attach the crank trigger wheel interrupt (Hall sensor drags to ground when triggering)
|
||||
else { attachInterrupt(triggerInterrupt, trigger, FALLING); } // Primary trigger connects to
|
||||
attachInterrupt(triggerInterrupt2, triggerSec_MazdaAU, FALLING);
|
||||
break;
|
||||
|
||||
case 11:
|
||||
triggerSetup_non360();
|
||||
trigger = triggerPri_DualWheel; //Is identical to the dual wheel decoder, so that is used. Same goes for the secondary below
|
||||
getRPM = getRPM_non360;
|
||||
getCrankAngle = getCrankAngle_non360;
|
||||
triggerSetEndTeeth = triggerSetEndTeeth_Non360;
|
||||
|
||||
if(configPage2.TrigEdge == 0) { attachInterrupt(triggerInterrupt, trigger, RISING); } // Attach the crank trigger wheel interrupt (Hall sensor drags to ground when triggering)
|
||||
else { attachInterrupt(triggerInterrupt, trigger, FALLING); }
|
||||
attachInterrupt(triggerInterrupt2, triggerSec_DualWheel, FALLING); //Note the use of the Dual Wheel trigger function here. No point in having the same code in twice.
|
||||
break;
|
||||
|
||||
case 12:
|
||||
triggerSetup_Nissan360();
|
||||
trigger = triggerPri_Nissan360;
|
||||
getRPM = getRPM_Nissan360;
|
||||
getCrankAngle = getCrankAngle_Nissan360;
|
||||
triggerSetEndTeeth = triggerSetEndTeeth_Nissan360;
|
||||
|
||||
if(configPage2.TrigEdge == 0) { attachInterrupt(triggerInterrupt, trigger, RISING); } // Attach the crank trigger wheel interrupt (Hall sensor drags to ground when triggering)
|
||||
else { attachInterrupt(triggerInterrupt, trigger, FALLING); }
|
||||
attachInterrupt(triggerInterrupt2, triggerSec_Nissan360, CHANGE);
|
||||
break;
|
||||
|
||||
case 13:
|
||||
triggerSetup_Subaru67();
|
||||
trigger = triggerPri_Subaru67;
|
||||
getRPM = getRPM_Subaru67;
|
||||
getCrankAngle = getCrankAngle_Subaru67;
|
||||
triggerSetEndTeeth = triggerSetEndTeeth_Subaru67;
|
||||
|
||||
if(configPage2.TrigEdge == 0) { attachInterrupt(triggerInterrupt, trigger, RISING); } // Attach the crank trigger wheel interrupt (Hall sensor drags to ground when triggering)
|
||||
else { attachInterrupt(triggerInterrupt, trigger, FALLING); }
|
||||
attachInterrupt(triggerInterrupt2, triggerSec_Subaru67, FALLING);
|
||||
break;
|
||||
|
||||
case 14:
|
||||
triggerSetup_Daihatsu();
|
||||
trigger = triggerPri_Daihatsu;
|
||||
getRPM = getRPM_Daihatsu;
|
||||
getCrankAngle = getCrankAngle_Daihatsu;
|
||||
triggerSetEndTeeth = triggerSetEndTeeth_Daihatsu;
|
||||
|
||||
if(configPage2.TrigEdge == 0) { attachInterrupt(triggerInterrupt, trigger, RISING); } // Attach the crank trigger wheel interrupt (Hall sensor drags to ground when triggering)
|
||||
else { attachInterrupt(triggerInterrupt, trigger, FALLING); }
|
||||
//No secondary input required for this pattern
|
||||
break;
|
||||
|
||||
case 15:
|
||||
triggerSetup_Harley();
|
||||
trigger = triggerPri_Harley;
|
||||
//triggerSecondary = triggerSec_Harley;
|
||||
getRPM = getRPM_Harley;
|
||||
getCrankAngle = getCrankAngle_Harley;
|
||||
triggerSetEndTeeth = triggerSetEndTeeth_Harley;
|
||||
attachInterrupt(triggerInterrupt, trigger, RISING);
|
||||
// attachInterrupt(triggerInterrupt2, triggerSec_Harley, FALLING);
|
||||
break;
|
||||
|
||||
default:
|
||||
trigger = triggerPri_missingTooth;
|
||||
getRPM = getRPM_missingTooth;
|
||||
getCrankAngle = getCrankAngle_missingTooth;
|
||||
|
||||
if(configPage2.TrigEdge == 0) { attachInterrupt(triggerInterrupt, trigger, RISING); } // Attach the crank trigger wheel interrupt (Hall sensor drags to ground when triggering)
|
||||
else { attachInterrupt(triggerInterrupt, trigger, FALLING); }
|
||||
break;
|
||||
}
|
||||
}
|
||||
/*
|
||||
This function retuns a pulsewidth time (in us) using a either Alpha-N or Speed Density algorithms, given the following:
|
||||
REQ_FUEL
|
||||
|
@ -556,46 +827,49 @@ void setPinMapping(byte boardID)
|
|||
|
||||
This function is called by PW_SD and PW_AN for speed0density and pure Alpha-N calculations respectively.
|
||||
*/
|
||||
unsigned int PW(int REQ_FUEL, byte VE, byte MAP, int corrections, int injOpen)
|
||||
unsigned int PW(int REQ_FUEL, byte VE, long MAP, int corrections, int injOpen)
|
||||
{
|
||||
//Standard float version of the calculation
|
||||
//return (REQ_FUEL * (float)(VE/100.0) * (float)(MAP/100.0) * (float)(TPS/100.0) * (float)(corrections/100.0) + injOpen);
|
||||
//Note: The MAP and TPS portions are currently disabled, we use VE and corrections only
|
||||
unsigned int iVE, iMAP, iAFR, iCorrections;
|
||||
uint16_t iVE, iCorrections;
|
||||
uint16_t iMAP = 100;
|
||||
uint16_t iAFR = 147;
|
||||
|
||||
//100% float free version, does sacrifice a little bit of accuracy, but not much.
|
||||
iVE = ((unsigned int)VE << 7) / 100;
|
||||
if ( configPage1.multiplyMAP ) {
|
||||
if ( configPage1.multiplyMAP == true ) {
|
||||
iMAP = ((unsigned int)MAP << 7) / currentStatus.baro; //Include multiply MAP (vs baro) if enabled
|
||||
}
|
||||
if ( configPage1.includeAFR && (configPage3.egoType == 2)) {
|
||||
if ( (configPage1.includeAFR == true) && (configPage3.egoType == 2)) {
|
||||
iAFR = ((unsigned int)currentStatus.O2 << 7) / currentStatus.afrTarget; //Include AFR (vs target) if enabled
|
||||
}
|
||||
iCorrections = (corrections << 7) / 100;
|
||||
|
||||
|
||||
unsigned long intermediate = ((long)REQ_FUEL * (long)iVE) >> 7; //Need to use an intermediate value to avoid overflowing the long
|
||||
if ( configPage1.multiplyMAP ) {
|
||||
intermediate = (intermediate * iMAP) >> 7;
|
||||
if ( configPage1.multiplyMAP == true ) {
|
||||
intermediate = (intermediate * (unsigned long)iMAP) >> 7;
|
||||
}
|
||||
if ( configPage1.includeAFR && (configPage3.egoType == 2)) {
|
||||
intermediate = (intermediate * iAFR) >> 7; //EGO type must be set to wideband for this to be used
|
||||
if ( (configPage1.includeAFR == true) && (configPage3.egoType == 2) ) {
|
||||
intermediate = (intermediate * (unsigned long)iAFR) >> 7; //EGO type must be set to wideband for this to be used
|
||||
}
|
||||
intermediate = (intermediate * iCorrections) >> 7;
|
||||
if (intermediate == 0) {
|
||||
return 0; //If the pulsewidth is 0, we return here before the opening time gets added
|
||||
}
|
||||
|
||||
intermediate = (intermediate * (unsigned long)iCorrections) >> 7;
|
||||
if (intermediate != 0)
|
||||
{
|
||||
//If intermeditate is not 0, we need to add the opening time (0 typically indicates that one of the full fuel cuts is active)
|
||||
intermediate += injOpen; //Add the injector opening time
|
||||
if ( intermediate > 65535) {
|
||||
if ( intermediate > 65535)
|
||||
{
|
||||
intermediate = 65535; //Make sure this won't overflow when we convert to uInt. This means the maximum pulsewidth possible is 65.535mS
|
||||
}
|
||||
}
|
||||
return (unsigned int)(intermediate);
|
||||
|
||||
}
|
||||
|
||||
//Convenience functions for Speed Density and Alpha-N
|
||||
unsigned int PW_SD(int REQ_FUEL, byte VE, byte MAP, int corrections, int injOpen)
|
||||
unsigned int PW_SD(int REQ_FUEL, byte VE, long MAP, int corrections, int injOpen)
|
||||
{
|
||||
return PW(REQ_FUEL, VE, MAP, corrections, injOpen);
|
||||
//return PW(REQ_FUEL, VE, 100, corrections, injOpen);
|
||||
|
@ -603,9 +877,5 @@ unsigned int PW_SD(int REQ_FUEL, byte VE, byte MAP, int corrections, int injOpen
|
|||
|
||||
unsigned int PW_AN(int REQ_FUEL, byte VE, byte TPS, int corrections, int injOpen)
|
||||
{
|
||||
//Sanity check
|
||||
if (TPS > 100) {
|
||||
TPS = 100;
|
||||
}
|
||||
return PW(REQ_FUEL, VE, currentStatus.MAP, corrections, injOpen);
|
||||
}
|
||||
|
|