Merge branch 'master' of git://github.com/noisymime/speeduino
This commit is contained in:
commit
27e22eef1b
|
@ -19,3 +19,5 @@ reference/hardware/v0.4/gerbers/Archive.zip
|
|||
.vscode
|
||||
.build
|
||||
.kicad_pcb-bak
|
||||
.vscode/c_cpp_properties.json
|
||||
.vscode/launch.json
|
||||
|
|
|
@ -46,6 +46,13 @@ lib_deps = EEPROM
|
|||
;build_flags = -fpermissive -std=gnu++11 -Os -ffunction-sections -fdata-sections -Wl,--gc-sections -Wl,-Map,output.map
|
||||
build_flags = -fpermissive -std=gnu++11 -Os
|
||||
|
||||
;Support for the stm32f407 doesn't look ready in platformio yet
|
||||
;[env:genericSTM32F407VE]
|
||||
;platform = https://github.com/maichaell/platform-ststm32
|
||||
;framework = arduino
|
||||
;board = disco_f407vg
|
||||
;lib_deps = EEPROM
|
||||
;build_flags = -fpermissive -std=gnu++11 -DUSE_STM32GENERIC -DMENU_USB_SERIAL
|
||||
|
||||
[platformio]
|
||||
src_dir=speeduino
|
||||
|
|
|
@ -0,0 +1,251 @@
|
|||
:1000000092C00000ABC00000A9C00000A7C0000063
|
||||
:10001000A5C00000A3C00000A1C000009FC0000058
|
||||
:100020009DC000009BC0000099C0000014C40000E7
|
||||
:10003000B9C4000093C0000091C000008FC0000050
|
||||
:100040008DC000008BC0000089C0000087C0000088
|
||||
:1000500085C0000083C0000081C00000E7C100002F
|
||||
:100060007DC000007BC0000079C0000077C00000A8
|
||||
:1000700075C000002803530070006500650064002F
|
||||
:10008000750069006E006F0020004D00650067007C
|
||||
:1000900061002000320035003600300000003203DD
|
||||
:1000A000410072006400750069006E006F0020005E
|
||||
:1000B00028007700770077002E006100720064004E
|
||||
:1000C000750069006E006F002E0063006300290058
|
||||
:1000D00000000403090409023E00020100C03209C5
|
||||
:1000E00004000001020201000524000110042402A2
|
||||
:1000F000060524060001070582030800FF09040124
|
||||
:1001000000020A0000000705040240000107058301
|
||||
:10011000024000011201100102000008EB034B2015
|
||||
:1001200001000102DC0111241FBECFEFD2E0DEBFCF
|
||||
:10013000CDBF11E0A0E0B1E0ECE7FFE002C0059028
|
||||
:100140000D92A831B107D9F722E0A8E1B1E001C0D2
|
||||
:100150001D92A133B207E1F74CD00EC751CFFC017D
|
||||
:10016000E058FF4FA081B1816C93A081B1819D01C6
|
||||
:100170002F5F3F4F2E173F0761F0318320832FB74A
|
||||
:10018000F894FC01EC57FF4F80818F5F80832FBF75
|
||||
:10019000089512969C938E931197F1CF84B7877F21
|
||||
:1001A00084BF0FB6F894A895809160008861809311
|
||||
:1001B0006000109260000FBE87E690E09093CD0043
|
||||
:1001C0008093CC0086E08093CA001092C80088E13A
|
||||
:1001D0008093C900539A5A9A8AB180638AB98BB1C5
|
||||
:1001E00080638BB92DD384E085BD5F9A579A279899
|
||||
:1001F0000895D4DF2FB7F89480EA91E0909321021C
|
||||
:100200008093200290932302809322022FBF2FB766
|
||||
:10021000F8948BE191E090939C0180939B019093E3
|
||||
:100220009E0180939D012FBF78948C0183E0F82E6E
|
||||
:100230009FB7F894809124029FBF8038D1F080E06E
|
||||
:1002400091E048D6EC0197FD14C0909116019923D6
|
||||
:1002500051F0863441F460E680EA91E080DF61E0AD
|
||||
:1002600080EA91E07CDF6C2F80EA91E078DF1092E9
|
||||
:1002700016018FB7F894C0919F018FBFA89902C053
|
||||
:10028000C13618F1A89A80919F01882319F05D98D2
|
||||
:10029000F0921801C15008F042C0809118018823E3
|
||||
:1002A00041F080911801815080931801811101C0A3
|
||||
:1002B0005D9A80911901882341F080911901815044
|
||||
:1002C00080931901811101C05C9A9FB7F8948091C5
|
||||
:1002D00024029FBF8823F1F0E0912202F0912302D3
|
||||
:1002E000919182E0E032F807C1F1F0932302E093AC
|
||||
:1002F00022022FB7F8948091240281508093240227
|
||||
:100300002FBF8091C80085FFFCCF9093CE005C98F2
|
||||
:10031000F092190180E091E0CFD5C5D489CFE0916A
|
||||
:100320009D01F0919E01619181E0EB39F80781F028
|
||||
:10033000F0939E01E0939D019FB7F89480919F01F7
|
||||
:10034000815080939F019FBF80E091E067D5A2CF4D
|
||||
:1003500010939E0100939D01EFCF20EA31E030938E
|
||||
:10036000230220932202C5CF80E091E013C580E0F4
|
||||
:1003700091E0ABC40F931F93CF938C01FC01848950
|
||||
:10038000C0E3813021F0C0E2823009F0C0E0F80122
|
||||
:100390008389823009F4C860F80185898730E9F1E2
|
||||
:1003A0008830E9F1863009F4C2601092C9001092D9
|
||||
:1003B000C8001092CA00F801278530894189528906
|
||||
:1003C0002115F1EE3F074105510559F1CA01B90167
|
||||
:1003D000969587957795679560587B47814E9F4F97
|
||||
:1003E000A3D5215031093093CD002093CC00C09388
|
||||
:1003F000CA00F80187859089A189B2898115914E3B
|
||||
:10040000A105B10589F082E08093C80088E9809356
|
||||
:10041000C900CF911F910F910895C460C6CFC660E7
|
||||
:10042000C4CF20E130E0DFCF80E0EECF1F920F920B
|
||||
:100430000FB60F9211242F933F934F935F936F93B7
|
||||
:100440007F938F939F93AF93BF93EF93FF936091AD
|
||||
:10045000CE008EB3843019F48BE191E080DEFF9101
|
||||
:10046000EF91BF91AF919F918F917F916F915F912C
|
||||
:100470004F913F912F910F900FBE0F901F901895A5
|
||||
:1004800023B1FC01858580FF07C027FD05C081E001
|
||||
:10049000809316015F9808955F9A0895292F332756
|
||||
:1004A0002230310571F02330310581F021303105E2
|
||||
:1004B000A1F482E190E024E131E0FA01318320836C
|
||||
:1004C00008958EE390E026ED30E0F7CF9927813054
|
||||
:1004D000910571F038F0029771F090E080E030E023
|
||||
:1004E00020E0EBCFE2EDF0E0849190E09F01E5CFDA
|
||||
:1004F000EEE9F0E0F9CFE4E7F0E0F6CFAC0128E078
|
||||
:1005000030E080E02417350718F08295807F089549
|
||||
:100510008F5F220F331FF6CF8093E900EBEEF0E000
|
||||
:10052000808181608083EDEEF0E010826093EC00CA
|
||||
:1005300040838091EE00881F8827881F08951092BD
|
||||
:10054000F40080E08093E9001092F0001092E8003F
|
||||
:100550001092ED009091EB009E7F9093EB008F5FE7
|
||||
:10056000853081F708958091290287FF11C080911D
|
||||
:10057000E80082FF06C08091E8008B778093E80056
|
||||
:1005800003C08EB38111F3CF08958EB38823E1F3B6
|
||||
:100590008091E80080FFF9CF8091E8008E77EECF60
|
||||
:1005A00085E69091EC0090FF06C09091E80090FFE6
|
||||
:1005B00006C080E008959091E80092FDFACF9EB3C6
|
||||
:1005C0009923A1F09EB3953099F09091EB0095FDA1
|
||||
:1005D00011C09091E10092FFE4CF9091E1009B7FE8
|
||||
:1005E0009093E1008150E9F684E0089582E0089557
|
||||
:1005F00083E0089581E0089520912F023091300228
|
||||
:1006000026173707A0F06115710529F42091E8003D
|
||||
:100610002E772093E80030E06115710551F4311117
|
||||
:1006200008C08091E80082FF30C080E00895B901E1
|
||||
:10063000F2CF2091E80023FD30C02091E80022FD98
|
||||
:10064000F0CF2EB3222359F12EB3253021F1209182
|
||||
:10065000E80020FFE1CF2091F200FC01CF016115FD
|
||||
:10066000710511F0283050F031E0283009F030E009
|
||||
:100670002091E8002E772093E800CECF81918093DF
|
||||
:10068000F100615071092F5FE9CF8EB3882339F0F3
|
||||
:100690008EB3853031F683E0089581E0089582E0DD
|
||||
:1006A000089520912F023091300226173707A0F0CD
|
||||
:1006B0006115710529F42091E8002E772093E80058
|
||||
:1006C00030E06115710551F4311108C08091E800E6
|
||||
:1006D00082FF31C080E00895B901F2CF2091E80097
|
||||
:1006E00023FD31C02091E80022FDF0CF2EB322235C
|
||||
:1006F00061F12EB3253029F12091E80020FFE1CFF0
|
||||
:100700002091F200FC01CF016115710511F0283034
|
||||
:1007100050F031E0283009F030E02091E8002E77E9
|
||||
:100720002093E800CECF84918093F100615071094D
|
||||
:100730002F5F3196E8CF8EB3882339F08EB38530A2
|
||||
:1007400029F683E0089581E0089582E00895611517
|
||||
:10075000710529F42091E8002B772093E8006115BA
|
||||
:10076000710531F48091E80080FF20C080E0089599
|
||||
:100770002091E80023FD22C02EB3222309F12EB3DD
|
||||
:100780002530D1F02091E80022FFE9CF2091F2003E
|
||||
:10079000222301F39C012F5F3F4F4091F100FC01A8
|
||||
:1007A000408361507109C90189F7D4CF8EB3882382
|
||||
:1007B00039F08EB38530B1F683E0089581E0089575
|
||||
:1007C00082E0089542D044D01EBA109227021092BF
|
||||
:1007D00026021092250284E089BD89B5826089BD18
|
||||
:1007E00009B400FEFDCF8091D800982F9F77909399
|
||||
:1007F000D80080688093D800809163008E7F8093BA
|
||||
:1008000063008091D8008F7D8093D8008091E000B4
|
||||
:100810008E7F8093E0008091E1008E7F8093E100E5
|
||||
:100820008091E20081608093E2008091E100877F07
|
||||
:100830008093E1008091E20088608093E200089557
|
||||
:10084000C1DF81E08093280208951092E2000895AC
|
||||
:100850001092E10008951F920F920FB60F9211248B
|
||||
:100860002F933F934F935F936F937F938F939F93B8
|
||||
:10087000AF93BF93EF93FF938091E10080FF1BC084
|
||||
:100880008091E20080FF17C08091E1008E7F80930D
|
||||
:10089000E1008091E2008E7F8093E2008091E2008F
|
||||
:1008A00080618093E2008091D80080628093D800BC
|
||||
:1008B00019BC1EBAF7D18091E10084FF27C0809156
|
||||
:1008C000E20084FF23C084E089BD89B5826089BDD0
|
||||
:1008D00009B400FEFDCF8091D8008F7D8093D800B1
|
||||
:1008E0008091E1008F7E8093E1008091E2008F7E15
|
||||
:1008F0008093E2008091E20081608093E200809129
|
||||
:10090000270281114DC081E08EBBCCD18091E100E6
|
||||
:1009100083FF27C08091E20083FF23C08091E10024
|
||||
:10092000877F8093E10082E08EBB10922702809146
|
||||
:10093000E1008E7F8093E1008091E2008E7F8093C2
|
||||
:10094000E2008091E20080618093E200F8DD42E005
|
||||
:1009500060E080E0E1DD8091F00088608093F0004D
|
||||
:10096000A1D18091E10082FF0AC08091E20082FF64
|
||||
:1009700006C08091E1008B7F8093E10093D1FF91CD
|
||||
:10098000EF91BF91AF919F918F917F916F915F9107
|
||||
:100990004F913F912F910F900FBE0F901F90189580
|
||||
:1009A00084E0B2CF1F920F920FB60F921124FF92E4
|
||||
:1009B0000F931F932F933F934F935F936F937F9367
|
||||
:1009C0008F939F93AF93BF93CF93DF93EF93FF9357
|
||||
:1009D000C9EED0E088818770F82E188200EF10E011
|
||||
:1009E000F8018081877F808378941DD0F8941882E5
|
||||
:1009F000F801808188608083F882FF91EF91DF9118
|
||||
:100A0000CF91BF91AF919F918F917F916F915F91A6
|
||||
:100A10004F913F912F911F910F91FF900F900FBE1B
|
||||
:100A20000F901F9018951F93CF93DF93CDB7DEB72C
|
||||
:100A3000AA970FB6F894DEBF0FBECDBFE9E2F2E091
|
||||
:100A40008091F100819322E0E133F207C9F78091B0
|
||||
:100A5000290290912A029A3008F022C1E92FF0E091
|
||||
:100A6000ED5CFA4F83C23D056205500662055006F3
|
||||
:100A7000BD05D90550062B063706803881F082382F
|
||||
:100A800009F00EC180912D0287708093E90080915A
|
||||
:100A9000EB0085FB882780F91092E90006C0809161
|
||||
:100AA000250290912602911182609091E800977F33
|
||||
:100AB0009093E8008093F1001092F1008091E8009B
|
||||
:100AC0008E772EC0282F2D7F09F0EAC08823D1F021
|
||||
:100AD000823051F18091E80083FF0AC08091EB00E1
|
||||
:100AE00080628093EB008091E800877F8093E8002C
|
||||
:100AF000AA960FB6F894DEBF0FBECDBFDF91CF919F
|
||||
:100B00001F91089580912B02813021F7933009F0D5
|
||||
:100B100080E0809326021092E9008091E800877FB0
|
||||
:100B20008093E80020DDD6CF80912B028111F3CF96
|
||||
:100B300080912D02877071F28093E9002091EB0083
|
||||
:100B400020FFC8CF933031F48091EB008062809316
|
||||
:100B5000EB00E1CF9091EB0090619093EB0021E0EE
|
||||
:100B600030E001C0220F8A95EAF72093EA00109244
|
||||
:100B7000EA008091EB008860EACF811191C010916A
|
||||
:100B80002B028091E800877F8093E800ECDC809165
|
||||
:100B9000E80080FF0AC0812F8F7792E009F093E090
|
||||
:100BA0009EBB80688093E30095CF8EB38111EFCF19
|
||||
:100BB00091CF8058823008F073C080912B029091C1
|
||||
:100BC0002C028C3D23E0920799F583E08A838AE228
|
||||
:100BD00089834FB7F894DE01139620E03EE051E29E
|
||||
:100BE000E32FF0E050935700E49120FF03C0E2951B
|
||||
:100BF000EF703F5FEF7080E38E0F8A3310F087E372
|
||||
:100C00008E0F90E08D939D932F5F243149F74FBF56
|
||||
:100C10008091E800877F8093E8006AE270E0CE016F
|
||||
:100C20000196EADC8091E8008B778093E80052CF50
|
||||
:100C3000AE014F5F5F4F60912D0230DCBC01892B0C
|
||||
:100C400009F448CF9091E800977F9093E80089815C
|
||||
:100C50009A8127DDE7CF803819F58091E800877FFA
|
||||
:100C60008093E800809127028093F10027CF8111C3
|
||||
:100C700017C090912B02923008F02CCF8091E800A1
|
||||
:100C8000877F8093E800909327026DDC8091270294
|
||||
:100C9000811104C083E08EBB67DB1CCF84E0FBCFF7
|
||||
:100CA00066DB18CF0895CF938EB3882359F0C09197
|
||||
:100CB000E900C7701092E9008091E80083FDB3DE7F
|
||||
:100CC000C093E900CF9108950895CF93DF93EC018D
|
||||
:100CD0008091E80083FF0FC0288180912D029091C0
|
||||
:100CE0002E022817190639F480912A028132C1F0A8
|
||||
:100CF00028F4803249F1DF91CF9108958232C1F119
|
||||
:100D00008332C9F7809129028132A9F78091E800E6
|
||||
:100D1000877F8093E80060912B02CE01D5DF37C03A
|
||||
:100D200080912902813A39F78091E800877F80938A
|
||||
:100D3000E80067E070E0CE010F965EDC8091E8008D
|
||||
:100D40008B778093E800D7CF80912902813299F682
|
||||
:100D50008091E800877F8093E80067E070E0CE0133
|
||||
:100D60000F96F5DCCE0106DB8091E8008E77E9CFA7
|
||||
:100D700080912902813209F0BECF8091E800877FFF
|
||||
:100D80008093E80080912B028D87CE0179DBDF9183
|
||||
:100D9000CF91E9CB0F931F93CF93DF93EC01FC012D
|
||||
:100DA0003D9689E0DF011D928A95E9F78A819B8152
|
||||
:100DB0002C8110E0211114E00981A0DB812B482F48
|
||||
:100DC000426061E8802FA8DB882311F18E819F812A
|
||||
:100DD000288510E0211114E00D8190DB812B482F34
|
||||
:100DE000426060E8802F98DB882391F08A859B859C
|
||||
:100DF0002C8510E0211114E0C98580DB812B482F60
|
||||
:100E0000426061EC8C2FDF91CF911F910F9184CBC9
|
||||
:100E100080E0DF91CF911F910F910895CF93C62F5E
|
||||
:100E20002EB32430F1F4FC01478550896189728921
|
||||
:100E3000452B462B472BA9F081818093E9008091B7
|
||||
:100E4000E80085FF05C0C093F10080E0CF910895D0
|
||||
:100E50008091E8008E778093E800A2DB882399F3E5
|
||||
:100E6000F5CF82E0F3CF2EB3243021F5FC01478586
|
||||
:100E7000508961897289452B462B472BD9F0818196
|
||||
:100E80008093E9008091F200811102C080E0089512
|
||||
:100E90009091E8008091E8008E778093E80095FDBE
|
||||
:100EA000F5CF7EDB811107C09091E8009E7790938B
|
||||
:100EB000E800089582E008952EB3243051F4FC0137
|
||||
:100EC0004785508961897289452B462B472B09F04C
|
||||
:100ED000CACF08952EB3243019F08FEF9FEF0895F5
|
||||
:100EE000FC014785508961897289452B462B472B28
|
||||
:100EF000A1F385818093E9008091E80082FFEDCF26
|
||||
:100F00008091F200882369F08091F10090E02091B7
|
||||
:100F1000F200211105C02091E8002B772093E80012
|
||||
:100F200008958FEF9FEFF3CFA1E21A2EAA1BBB1BF0
|
||||
:100F3000FD010DC0AA1FBB1FEE1FFF1FA217B307A5
|
||||
:100F4000E407F50720F0A21BB30BE40BF50B661FBB
|
||||
:100F5000771F881F991F1A9469F76095709580957F
|
||||
:100F600090959B01AC01BD01CF010895EE0FFF1FCD
|
||||
:0C0F70000590F491E02D0994F894FFCF57
|
||||
:100F7C0000034000000440000002080000000000D4
|
||||
:080F8C0000000000000001005C
|
||||
:00000001FF
|
|
@ -1,4 +1,4 @@
|
|||
;-------------------------------------------------------------------------------
|
||||
;-------------------------------------------------------------------------------
|
||||
#unset CAN_COMMANDS
|
||||
#unset enablehardware_test
|
||||
|
||||
|
@ -10,7 +10,7 @@
|
|||
versionInfo = "S" ;This info is what is displayed to user
|
||||
|
||||
[TunerStudio]
|
||||
iniSpecVersion = 3.46
|
||||
iniSpecVersion = 3.51
|
||||
|
||||
;-------------------------------------------------------------------------------
|
||||
|
||||
|
@ -158,8 +158,8 @@ page = 1
|
|||
;Page 2 is all general settings (Previously part of page 1)
|
||||
;--------------------------------------------------
|
||||
page = 2
|
||||
flexBoostLow = scalar, S08, 0, "kPa", 1.0, 0.0, -127, 127, 0
|
||||
flexBoostHigh = scalar, U08, 1, "kPa", 1.0, 0.0, 0.0, 255, 0
|
||||
unused2-1 = scalar, S08, 0, "kPa", 1.0, 0.0, -127, 127, 0
|
||||
unused2-2 = scalar, U08, 1, "kPa", 1.0, 0.0, 0.0, 255, 0
|
||||
asePct = scalar, U08, 2, "%", 1.0, 0.0, 0.0, 95.0, 0
|
||||
aseCount = scalar, U08, 3, "s", 1.0, 0.0, 0.0, 255, 0
|
||||
wueRates = array, U08, 4, [10], "%", 1.0, 0.0, 0.0, 255, 0
|
||||
|
@ -236,10 +236,10 @@ page = 2
|
|||
oddfire3 = scalar, U16, 53, "deg", 1.0, 0.0, 0.0, 720, 0 ; * ( 2 byte)
|
||||
oddfire4 = scalar, U16, 55, "deg", 1.0, 0.0, 0.0, 720, 0 ; * ( 2 byte)
|
||||
|
||||
flexFuelLow = scalar, U08, 57, "%", 1.0, 0.0, 0.0, 250.0, 0
|
||||
flexFuelHigh = scalar, U08, 58, "%", 1.0, 0.0, 0.0, 250.0, 0
|
||||
flexAdvLow = scalar, U08, 59, "Deg", 1.0, 0.0, 0.0, 250.0, 0
|
||||
flexAdvHigh = scalar, U08, 60, "Deg", 1.0, 0.0, 0.0, 250.0, 0
|
||||
unused2-57 = scalar, U08, 57, "%", 1.0, 0.0, 0.0, 250.0, 0
|
||||
unused2-58 = scalar, U08, 58, "%", 1.0, 0.0, 0.0, 250.0, 0
|
||||
unused2-59 = scalar, U08, 59, "Deg", 1.0, 0.0, 0.0, 250.0, 0
|
||||
unused2-60 = scalar, U08, 60, "Deg", 1.0, 0.0, 0.0, 250.0, 0
|
||||
|
||||
iacCLminDuty = scalar, U08, 61, "%", 1.0, 0.0, 0.0, 100.0, 0 ; Minimum and maximum duty cycles when using closed loop idle
|
||||
iacCLmaxDuty = scalar, U08, 62, "%", 1.0, 0.0, 0.0, 100.0, 0
|
||||
|
@ -281,8 +281,10 @@ page = 4
|
|||
useResync = bits, U08, 6,[7:7], "No", "Yes"
|
||||
sparkDur = scalar, U08, 7, "ms", 0.1, 0, 0, 25.5, 1 ; Spark duration
|
||||
trigPatternSec = bits, U08, 8,[0:7], "Single tooth cam", "4-1 cam", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID"
|
||||
unused4-9 = scalar, U08, 9, "ms", 0.1, 0.0, 0.0, 25.5, 1
|
||||
unused4-10 = scalar, U08, 10, "ms", 0.1, 0.0, 0.0, 25.5, 1
|
||||
bootloaderCaps = scalar, U08, 9, "level", 1, 0, 0, 255, 0
|
||||
resetControl_custom = bits, U08, 10,[0:1], "Disabled", "Prevent When Running", "Prevent Always", "Serial Command"
|
||||
resetControl_standard = bits, U08, 10,[0:1], "Disabled", "INVALID", "INVALID", "Enabled"
|
||||
resetControlPin = bits, U08, 10,[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", "A8", "A9", "A10", "A11", "A12", "A13", "A14", "A15", "INVALID"
|
||||
SkipCycles = scalar, U08, 11, "cycles", 1, 0, 0, 255, 0
|
||||
|
||||
; name = array, type, offset, shape, units, scale, translate, lo, hi, digits
|
||||
|
@ -716,8 +718,17 @@ page = 10
|
|||
boostIntv = scalar, U08, 27, "ms", 1, 0, 0, 250, 0
|
||||
stagedInjSizePri = scalar, U16, 28, "cc/min", 1, 0, 0, 1500, 0
|
||||
stagedInjSizeSec = scalar, U16, 30, "cc/min", 1, 0, 0, 1500, 0
|
||||
lnchCtrlTPS = scalar, U08, 32, "%TPS", 1, 0, 0, 100, 0
|
||||
|
||||
unused11_32_192 = array, U08, 32, [159], "RPM", 100.0, 0.0, 100, 25500, 0
|
||||
flexBoostBins = array, U08, 33, [6], "%", 1.0, 0.0, 0.0, 250.0, 0
|
||||
; The boost range is obviously arbitrary since int16_t has ~32k in both directions
|
||||
flexBoostAdj = array, S16, 39, [6], "kPa", 1.0, 0.0, -500.0, 500.0, 0
|
||||
flexFuelBins = array, U08, 51, [6], "%", 1.0, 0.0, 0.0, 250.0, 0
|
||||
flexFuelAdj = array, U08, 57, [6], "%", 1.0, 0.0, 0.0, 250.0, 0
|
||||
flexAdvBins = array, U08, 63, [6], "%", 1.0, 0.0, 0.0, 250.0, 0
|
||||
flexAdvAdj = array, U08, 69, [6], "Deg", 1.0, 0.0, 0.0, 250.0, 0
|
||||
|
||||
unused11_75_192 = array, U08, 75,[117],"RPM", 100.0, 0.0, 100, 25500, 0
|
||||
|
||||
;-------------------------------------------------------------------------------
|
||||
|
||||
|
@ -754,6 +765,9 @@ page = 10
|
|||
requiresPowerCycle = stagedInjSizePri
|
||||
requiresPowerCycle = stagedInjSizeSec
|
||||
requiresPowerCycle = stagingEnabled
|
||||
requiresPowerCycle = resetControl_custom
|
||||
requiresPowerCycle = resetControl_standard
|
||||
requiresPowerCycle = resetControlPin
|
||||
|
||||
defaultValue = pinLayout, 1
|
||||
defaultValue = TrigPattern, 0
|
||||
|
@ -803,6 +817,10 @@ page = 10
|
|||
defaultValue = realtime_base_address, 336
|
||||
defaultValue = VVTasOnOff, 0
|
||||
defaultValue = stagingEnabled, 0
|
||||
defaultValue = lnchCtrlTPS, 0
|
||||
defaultValue = resetControl_custom, 0
|
||||
defaultValue = resetControl_standard, 0
|
||||
defaultValue = bootloaderCaps, 0
|
||||
; defaultValue = obd_address, 0
|
||||
|
||||
;Default pins
|
||||
|
@ -813,6 +831,10 @@ page = 10
|
|||
defaultValue = fuelPumpPin, 0
|
||||
defaultValue = tachoPin, 0
|
||||
defaultValue = perToothIgn, 0
|
||||
defaultValue = resetControlPin, 0
|
||||
|
||||
controllerPriority = bootloaderCaps
|
||||
|
||||
[Menu]
|
||||
|
||||
;----------------------------------------------------------------------------
|
||||
|
@ -847,6 +869,7 @@ menuDialog = main
|
|||
subMenu = triggerSettings, "Trigger Setup"
|
||||
;subMenu = OLED, "OLED Setup"
|
||||
subMenu = airdensity_curve, "IAT Density"
|
||||
subMenu = reset_control, "Reset Control"
|
||||
|
||||
|
||||
menu = "&Tuning"
|
||||
|
@ -989,15 +1012,12 @@ menuDialog = main
|
|||
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)"
|
||||
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)"
|
||||
flexFreqHigh = "The frequency of the sensor at 100% ethanol (150Hz for standard GM/Continental sensor)"
|
||||
flexFuelLow = "Fuel % to be used for the lowest ethanol reading (Typically 100%. ie No adjustment)"
|
||||
flexFuelHigh = "Fuel % to be used for the highest ethanol reading (Typically 163% for 100% ethanol)"
|
||||
flexAdvLow = "Additional advance (in degrees) at lowest ethanol reading (Typically 0)"
|
||||
flexAdvHigh = "Additional advance (in degrees) at highest ethanol reading (Typically 10-20 degrees)"
|
||||
flexBoostHigh = "This amount that will be added to the boost target at E100. Between E0 and E100, the amount added to the boost target will be scaled from 0 to this value"
|
||||
flexBoostLow = "Typically should be set to 0, but can be used to lower boost at E0 if the bast tune is setup with some ethanol"
|
||||
flexFuelAdj = "Fuel % to be used for the current ethanol % (Typically 100% @ 0%, 163% @ 100%)"
|
||||
flexAdvAdj = "Additional advance (in degrees) for the current ethanol % (Typically 0 @ 0%, 10-20 @ 100%)"
|
||||
flexBoostAdj = "Adjustment, in kPa, to the boost target for the current ethanol %. Negative values are allowed to lower boost at lower ethanol % if necessary."
|
||||
|
||||
flatSArm = "The RPM switch point that determines whether an eganged clutch is for launch control or flat shift. Below this figure, an engaged clutch is considered to be for launch, above this figure an active clutch input will be considered a flat shift. This should be set at least several hundred RPM above idle"
|
||||
flatSSoftWin= "The number of RPM below the flat shift point where the softlimit will be applied (aka Soft limit window). Recommended values are 200-1000"
|
||||
|
@ -1095,6 +1115,10 @@ menuDialog = main
|
|||
stagedInjSizePri= "Size of the primary injectors. The sum of the Pri and Sec injectors values MUST match the value used in the req_fuel calculation"
|
||||
stagedInjSizeSec= "Size of the secondary injectors. The sum of the Pri and Sec injectors values MUST match the value used in the req_fuel calculation"
|
||||
|
||||
resetControl_standard = "Whether to enable reset control of the Arduino's automatic reset feature. If this feature is enabled, the selected control pin will be held high at all times. In order to update your Speeduino's firmware, you will first need to open a serial terminal and send a 'U' command so that the Arduino resets when the upload starts. The control pin should be connected to the Arduino's reset pin."
|
||||
resetControl_custom = "How to control the Arduino's automatic reset feature. NOTE: Some of these settings require modifying your hardware and replacing the Arduino bootloader. See the Wiki for more details.\n\nDisabled: Allow the Arduino to reset when a new serial connection is made.\n\nPrevent When Running: Hold the control pin high while the engine is running.\n\nPrevent Always: Always hold the control pin high.\n\nSerial Command: Normally hold the control pin high, but pull it low when the 'U' serial command is issued and reset upon receiving more data."
|
||||
resetControlPin = "The Arduino pin used to control resets."
|
||||
|
||||
[UserDefined]
|
||||
|
||||
; Enhanced TunerStudio dialogs can be defined here
|
||||
|
@ -1140,42 +1164,23 @@ menuDialog = main
|
|||
panel = engine_constants_east, East
|
||||
|
||||
# Flex fuel stuff
|
||||
dialog = flexFueling, "Flex Fuel"
|
||||
field = "Flex sensor", flexEnabled
|
||||
dialog = flexFuelSettings, "", yAxis
|
||||
field = "Flex Fuel Sensor ", flexEnabled
|
||||
field = "Low (E0) ", flexFreqLow, { flexEnabled }
|
||||
field = "High (E100) ", flexFreqHigh, { flexEnabled }
|
||||
|
||||
dialog = flexLeft, ""
|
||||
field = "Component"
|
||||
field = "Sensor Frequency"
|
||||
field = "Fuel Adjustment"
|
||||
field = "Additional advance"
|
||||
field = "Additional boost", { boostEnabled }
|
||||
dialog = flexFuelWest, "", border
|
||||
panel = flexFuelSettings, North
|
||||
|
||||
dialog = flexMiddle, ""
|
||||
field = "Low (E0)"
|
||||
field = "", flexFreqLow, { flexEnabled }
|
||||
field = "", flexFuelLow, { flexEnabled }
|
||||
field = "", flexAdvLow, { flexEnabled }
|
||||
field = "", flexBoostLow, { boostEnabled }
|
||||
dialog = flexCurves, "", indexCard
|
||||
panel = flex_fuel_curve, { flexEnabled }
|
||||
panel = flex_adv_curve, { flexEnabled }
|
||||
panel = flex_boost_curve, { flexEnabled && boostEnabled }
|
||||
|
||||
dialog = flexRight, ""
|
||||
field = "High (E100)"
|
||||
field = "", flexFreqHigh, { flexEnabled }
|
||||
field = "", flexFuelHigh, { flexEnabled }
|
||||
field = "", flexAdvHigh, { flexEnabled }
|
||||
field = "", flexBoostHigh, { flexEnabled && boostEnabled }
|
||||
|
||||
dialog = flexMain, "Flex Fuel Calibration", xAxis
|
||||
panel = flexLeft
|
||||
panel = flexMiddle
|
||||
panel = flexRight
|
||||
|
||||
dialog = flexFuelTop, ""
|
||||
field = "Flex Fuel Sensor", flexEnabled
|
||||
|
||||
dialog = flexFueling, "Fuel Sensor Settings", yAxis
|
||||
dialog = flexFueling, "Fuel Sensor Settings", border
|
||||
topicHelp = "http://speeduino.com/wiki/index.php/Flex_Fuel"
|
||||
panel = flexFuelTop
|
||||
panel = flexMain
|
||||
panel = flexFuelWest, West
|
||||
panel = flexCurves, Center
|
||||
|
||||
dialog = tacho, "Tacho"
|
||||
field = "Output pin", tachoPin
|
||||
|
@ -1389,6 +1394,7 @@ menuDialog = main
|
|||
; Launch control
|
||||
field = "Launch Control"
|
||||
field = "Enable Launch", launchEnable
|
||||
field = "TPS threshold", lnchCtrlTPS, { launchEnable }
|
||||
field = "Soft rev limit", lnchSoftLim, { launchEnable }
|
||||
field = "Soft limit absolute timing", lnchRetard, { launchEnable }
|
||||
field = "Hard rev limit", lnchHardLim, { launchEnable }
|
||||
|
@ -1801,6 +1807,13 @@ menuDialog = main
|
|||
topicHelp = "http://speeduino.com/wiki/index.php/Serial3_IO_interface"
|
||||
field = "Enable Second Serial", enable_canbus
|
||||
|
||||
dialog = reset_control, "Reset Control"
|
||||
; Control type options for custom firmware
|
||||
field = "Control Type", resetControl_custom, { bootloaderCaps > 0 }, { bootloaderCaps > 0 }
|
||||
; Control type options for standard / unmodifyable firmware
|
||||
field = "Control Type", resetControl_standard, { bootloaderCaps == 0 }, { bootloaderCaps == 0 }
|
||||
field = "Control Pin", resetControlPin
|
||||
|
||||
;-------------------------------------------------------------------------------
|
||||
; General help text
|
||||
|
||||
|
@ -1982,6 +1995,30 @@ cmdtestspk450dc = "E\x03\x0C"
|
|||
; xBins = wueAFRBins, coolant
|
||||
; yBins = wueAFRRates
|
||||
|
||||
; Flex fuel correction curves
|
||||
curve = flex_fuel_curve, "Flex Fuel Adjustments"
|
||||
columnLabel = "Ethanol", "Fuel"
|
||||
xAxis = 0, 100, 5
|
||||
yAxis = 0, 255, 10
|
||||
xBins = flexFuelBins, flex
|
||||
yBins = flexFuelAdj
|
||||
size = 400, 200
|
||||
|
||||
curve = flex_adv_curve, "Flex Timing Advance"
|
||||
columnLabel = "Ethanol", "Advance"
|
||||
xAxis = 0, 100, 5
|
||||
yAxis = 0, 100, 5
|
||||
xBins = flexAdvBins, flex
|
||||
yBins = flexAdvAdj
|
||||
size = 400, 200
|
||||
|
||||
curve = flex_boost_curve, "Flex Boost Adjustments"
|
||||
columnLabel = "Ethanol", "Boost"
|
||||
xAxis = 0, 100, 5
|
||||
yAxis = -100, 200, 5
|
||||
xBins = flexBoostBins, flex
|
||||
yBins = flexBoostAdj
|
||||
size = 400, 200
|
||||
|
||||
[TableEditor]
|
||||
; table_id, map3d_id, "title", page
|
||||
|
@ -2234,6 +2271,8 @@ cmdtestspk450dc = "E\x03\x0C"
|
|||
indicator = { hardLimitOn }, "Hard Limit OFF","Hard Limiter", 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
|
||||
indicator = { resetLockOn }, "Reset Lock OFF","Reset Lock ON", red, black, green, black
|
||||
indicator = { bootloaderCaps > 0 }, "Std. Boot", "Custom Boot", white, black, white, black
|
||||
|
||||
;-------------------------------------------------------------------------------
|
||||
|
||||
|
@ -2244,7 +2283,7 @@ cmdtestspk450dc = "E\x03\x0C"
|
|||
; you change it.
|
||||
|
||||
ochGetCommand = "r\$tsCanId\x30%2o%2c"
|
||||
ochBlockSize = 81
|
||||
ochBlockSize = 84
|
||||
|
||||
secl = scalar, U08, 0, "sec", 1.000, 0.000
|
||||
status1 = scalar, U08, 1, "bits", 1.000, 0.000
|
||||
|
@ -2331,7 +2370,10 @@ cmdtestspk450dc = "E\x03\x0C"
|
|||
pulseWidth2 = scalar, U16, 75, "ms", 0.001, 0.000
|
||||
pulseWidth3 = scalar, U16, 77, "ms", 0.001, 0.000
|
||||
pulseWidth4 = scalar, U16, 79, "ms", 0.001, 0.000
|
||||
|
||||
status3 = scalar, U08, 81, "bits", 1.000, 0.000
|
||||
resetLockOn = bits, U08, 81, [0:0]
|
||||
unused81_1-7 = bits, U08, 81, [1:7]
|
||||
flexBoostCor = scalar, S16, 81, "kPa", 1.000, 0.000
|
||||
#if CELSIUS
|
||||
coolant = { coolantRaw - 40 } ; Temperature readings are offset by 40 to allow for negatives
|
||||
iat = { iatRaw - 40 } ; Temperature readings are offset by 40 to allow for negatives
|
||||
|
|
|
@ -4,15 +4,15 @@ Copyright (C) Josh Stewart
|
|||
A full copy of the license may be found in the projects root directory
|
||||
*/
|
||||
//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
|
||||
//integerPID boostPID(&MAPx100, &boost_pwm_target_value, &boostTargetx100, configPage6.boostKP, configPage6.boostKI, configPage6.boostKD, DIRECT);
|
||||
integerPID_ideal boostPID(¤tStatus.MAP, ¤tStatus.boostDuty , ¤tStatus.boostTarget, &configPage10.boostSens, &configPage10.boostIntv, configPage6.boostKP, configPage6.boostKI, configPage6.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( configPage3.fanInv == 1 ) { fanHIGH = LOW; fanLOW = HIGH; }
|
||||
if( configPage6.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;
|
||||
|
@ -20,10 +20,10 @@ void initialiseFan()
|
|||
|
||||
void fanControl()
|
||||
{
|
||||
if( configPage3.fanEnable == 1 )
|
||||
if( configPage6.fanEnable == 1 )
|
||||
{
|
||||
int onTemp = (int)configPage3.fanSP - CALIBRATION_TEMPERATURE_OFFSET;
|
||||
int offTemp = onTemp - configPage3.fanHyster;
|
||||
int onTemp = (int)configPage6.fanSP - CALIBRATION_TEMPERATURE_OFFSET;
|
||||
int offTemp = onTemp - configPage6.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; }
|
||||
|
@ -48,18 +48,18 @@ void initialiseAuxPWM()
|
|||
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
|
||||
boost_pwm_max_count = 1000000L / (configPage6.boostFreq * 2); //Converts the frequency in Hz to the number of ticks (at 16uS) it takes to complete 1 cycle. The x2 is there because the frequency is stored at half value (in a byte) to allow freqneucies up to 511Hz
|
||||
vvt_pwm_max_count = 1000000L / (configPage6.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
|
||||
boost_pwm_max_count = 1000000L / (16 * configPage6.boostFreq * 2); //Converts the frequency in Hz to the number of ticks (at 16uS) it takes to complete 1 cycle. The x2 is there because the frequency is stored at half value (in a byte) to allow freqneucies up to 511Hz
|
||||
vvt_pwm_max_count = 1000000L / (16 * configPage6.vvtFreq * 2); //Converts the frequency in Hz to the number of ticks (at 16uS) it takes to complete 1 cycle
|
||||
#endif
|
||||
//TIMSK1 |= (1 << OCIE1A); <---- Not required as compare A is turned on when needed by boost control
|
||||
ENABLE_VVT_TIMER(); //Turn on the B compare unit (ie turn on the interrupt)
|
||||
|
||||
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); }
|
||||
boostPID.SetOutputLimits(configPage2.boostMinDuty, configPage2.boostMaxDuty);
|
||||
if(configPage6.boostMode == BOOST_MODE_SIMPLE) { boostPID.SetTunings(100, 100, 100); }
|
||||
else { boostPID.SetTunings(configPage6.boostKP, configPage6.boostKI, configPage6.boostKD); }
|
||||
|
||||
currentStatus.boostDuty = 0;
|
||||
boostCounter = 0;
|
||||
|
@ -75,17 +75,19 @@ void initialiseAuxPWM()
|
|||
#define BOOST_HYSTER 40
|
||||
void boostControl()
|
||||
{
|
||||
if( configPage3.boostEnabled==1 )
|
||||
if( configPage6.boostEnabled==1 )
|
||||
{
|
||||
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) )
|
||||
{
|
||||
//If flex fuel is enabled, there can be an adder to the boost target based on ethanol content
|
||||
if( configPage1.flexEnabled == 1 )
|
||||
if( configPage2.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
|
||||
currentStatus.boostTarget += boostAdder;
|
||||
currentStatus.boostTarget += table2D_getValue(&flexBoostTable, currentStatus.ethanolPct);;
|
||||
}
|
||||
else
|
||||
{
|
||||
currentStatus.flexBoostCorrection = 0;
|
||||
}
|
||||
|
||||
if(currentStatus.boostTarget > 0)
|
||||
|
@ -93,10 +95,10 @@ void boostControl()
|
|||
//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);
|
||||
boostPID.SetOutputLimits(configPage2.boostMinDuty, configPage2.boostMaxDuty);
|
||||
|
||||
if(configPage3.boostMode == BOOST_MODE_SIMPLE) { boostPID.SetTunings(100, 100, 100); }
|
||||
else { boostPID.SetTunings(configPage3.boostKP, configPage3.boostKI, configPage3.boostKD); }
|
||||
if(configPage6.boostMode == BOOST_MODE_SIMPLE) { boostPID.SetTunings(100, 100, 100); }
|
||||
else { boostPID.SetTunings(configPage6.boostKP, configPage6.boostKI, configPage6.boostKD); }
|
||||
}
|
||||
|
||||
bool PIDcomputed = boostPID.Compute(); //Compute() returns false if the required interval has not yet passed.
|
||||
|
@ -123,19 +125,22 @@ void boostControl()
|
|||
boostDisable();
|
||||
}
|
||||
}
|
||||
else { DISABLE_BOOST_TIMER(); } // Disable timer channel
|
||||
else { // Disable timer channel and zero the flex boost correction status
|
||||
DISABLE_BOOST_TIMER();
|
||||
currentStatus.flexBoostCorrection = 0;
|
||||
}
|
||||
|
||||
boostCounter++;
|
||||
}
|
||||
|
||||
void vvtControl()
|
||||
{
|
||||
if( configPage3.vvtEnabled == 1 )
|
||||
if( configPage6.vvtEnabled == 1 )
|
||||
{
|
||||
byte vvtDuty = get3DTableValue(&vvtTable, currentStatus.TPS, currentStatus.RPM);
|
||||
|
||||
//VVT table can be used for controlling on/off switching. If this is turned on, then disregard any interpolation or non-binary values
|
||||
if( (configPage3.VVTasOnOff == true) && (vvtDuty < 100) ) { vvtDuty = 0; }
|
||||
if( (configPage6.VVTasOnOff == true) && (vvtDuty < 100) ) { vvtDuty = 0; }
|
||||
|
||||
if(vvtDuty == 0)
|
||||
{
|
||||
|
|
|
@ -33,12 +33,12 @@ void canCommand()
|
|||
{
|
||||
Gdata[Gx] = CANSerial.read();
|
||||
}
|
||||
Glow = Gdata[(configPage10.caninput_source_start_byte[destcaninchannel]&7)];
|
||||
if ((BIT_CHECK(configPage10.caninput_source_num_bytes,destcaninchannel))) //if true then num bytes is 2
|
||||
Glow = Gdata[(configPage9.caninput_source_start_byte[destcaninchannel]&7)];
|
||||
if ((BIT_CHECK(configPage9.caninput_source_num_bytes,destcaninchannel))) //if true then num bytes is 2
|
||||
{
|
||||
if ((configPage10.caninput_source_start_byte[destcaninchannel]&7) < 8) //you cant have a 2 byte value starting at byte 7(8 on the list)
|
||||
if ((configPage9.caninput_source_start_byte[destcaninchannel]&7) < 8) //you cant have a 2 byte value starting at byte 7(8 on the list)
|
||||
{
|
||||
Ghigh = Gdata[((configPage10.caninput_source_start_byte[destcaninchannel]&7)+1)];
|
||||
Ghigh = Gdata[((configPage9.caninput_source_start_byte[destcaninchannel]&7)+1)];
|
||||
}
|
||||
else{Ghigh = 0;}
|
||||
}
|
||||
|
|
|
@ -12,7 +12,7 @@
|
|||
#define canbusPage 9//Config Page 9
|
||||
#define warmupPage 10 //Config Page 10
|
||||
|
||||
#define SERIAL_PACKET_SIZE 81
|
||||
#define SERIAL_PACKET_SIZE 84
|
||||
|
||||
byte currentPage = 1;//Not the same as the speeduino config page numbers
|
||||
bool isMap = true;
|
||||
|
@ -32,14 +32,14 @@ byte tsCanId = 0; // current tscanid requested
|
|||
const char pageTitles[] PROGMEM //This is being stored in the avr flash instead of SRAM which there is not very much of
|
||||
{
|
||||
"\nVE Map\0"//This is an alternative to using a 2D array which would waste space because of the different lengths of the strings
|
||||
"\nPg 1 Config\0"//The configuration page titles' indexes are found by counting the chars
|
||||
"\nIgnition Map\0"//The map page titles' indexes are put into a var called currentTitleIndex. That represents the first char of each string.
|
||||
"\nPg 2 Config\0"
|
||||
"\nAFR Map\0"
|
||||
"\nPg 3 Config\0"
|
||||
"\nPg 4 Config\0"
|
||||
"\nBoost Map\0"
|
||||
"\nVVT Map\0"//No need to put a trailing null because it's the last string and the compliler does it for you.
|
||||
"\nPg 1 Config\0"// 21-The configuration page titles' indexes are found by counting the chars
|
||||
"\nIgnition Map\0"//35-The map page titles' indexes are put into a var called currentTitleIndex. That represents the first char of each string.
|
||||
"\nPg 2 Config\0" //48
|
||||
"\nAFR Map\0" //56
|
||||
"\nPg 3 Config\0" //69
|
||||
"\nPg 4 Config\0" //82
|
||||
"\nBoost Map\0" //93
|
||||
"\nVVT Map\0"//102-No need to put a trailing null because it's the last string and the compliler does it for you.
|
||||
"\nPg 10 Config"
|
||||
};
|
||||
|
||||
|
|
|
@ -183,6 +183,24 @@ void command()
|
|||
|
||||
break;
|
||||
|
||||
case 'U': //User wants to reset the Arduino (probably for FW update)
|
||||
if (resetControl != RESET_CONTROL_DISABLED)
|
||||
{
|
||||
#ifndef SMALL_FLASH_MODE
|
||||
if (!cmdPending) { Serial.println(F("Comms halted. Next byte will reset the Arduino.")); }
|
||||
#endif
|
||||
|
||||
while (Serial.available() == 0) { }
|
||||
digitalWrite(pinResetControl, LOW);
|
||||
}
|
||||
else
|
||||
{
|
||||
#ifndef SMALL_FLASH_MODE
|
||||
if (!cmdPending) { Serial.println(F("Reset control is currently disabled.")); }
|
||||
#endif
|
||||
}
|
||||
break;
|
||||
|
||||
case 'V': // send VE table and constants in binary
|
||||
sendPage(false);
|
||||
break;
|
||||
|
@ -282,9 +300,9 @@ void command()
|
|||
Serial.println(F("WUE"));
|
||||
for (int x = 0; x < 10; x++)
|
||||
{
|
||||
Serial.print(configPage2.wueBins[x]);
|
||||
Serial.print(configPage4.wueBins[x]);
|
||||
Serial.print(", ");
|
||||
Serial.println(configPage1.wueValues[x]);
|
||||
Serial.println(configPage2.wueValues[x]);
|
||||
}
|
||||
Serial.flush();
|
||||
#endif
|
||||
|
@ -294,6 +312,16 @@ void command()
|
|||
sendToothLog(true); //Sends tooth log values as chars
|
||||
break;
|
||||
|
||||
case '`': //Custom 16u2 firmware is making its presence known
|
||||
cmdPending = true;
|
||||
|
||||
if (Serial.available() >= 1) {
|
||||
configPage4.bootloaderCaps = Serial.read();
|
||||
cmdPending = false;
|
||||
}
|
||||
break;
|
||||
|
||||
|
||||
case '?':
|
||||
#ifndef SMALL_FLASH_MODE
|
||||
Serial.println
|
||||
|
@ -321,6 +349,7 @@ void command()
|
|||
"Z - Display calibration values\n"
|
||||
"T - Displays 256 tooth log entries in binary\n"
|
||||
"r - Displays 256 tooth log entries\n"
|
||||
"U - Prepare for firmware update. The next byte received will cause the Arduino to reset.\n"
|
||||
"? - Displays this help page"
|
||||
));
|
||||
#endif
|
||||
|
@ -458,6 +487,10 @@ void sendValues(uint16_t offset, uint16_t packetLength, byte cmd, byte portNum)
|
|||
fullStatus[79] = lowByte(currentStatus.PW4); //Pulsewidth 4 multiplied by 10 in ms. Have to convert from uS to mS.
|
||||
fullStatus[80] = highByte(currentStatus.PW4); //Pulsewidth 4 multiplied by 10 in ms. Have to convert from uS to mS.
|
||||
|
||||
fullStatus[81] = currentStatus.status3;
|
||||
fullStatus[82] = lowByte(currentStatus.flexBoostCorrection);
|
||||
fullStatus[83] = highByte(currentStatus.flexBoostCorrection);
|
||||
|
||||
for(byte x=0; x<packetLength; x++)
|
||||
{
|
||||
if (portNum == 0) { Serial.write(fullStatus[offset+x]); }
|
||||
|
@ -501,7 +534,7 @@ void receiveValue(int valueOffset, byte newValue)
|
|||
break;
|
||||
|
||||
case veSetPage:
|
||||
pnt_configPage = &configPage1; //Setup a pointer to the relevant config page
|
||||
pnt_configPage = &configPage2; //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 < npage_size[veSetPage])
|
||||
{
|
||||
|
@ -532,7 +565,7 @@ void receiveValue(int valueOffset, byte newValue)
|
|||
break;
|
||||
|
||||
case ignSetPage:
|
||||
pnt_configPage = &configPage2;
|
||||
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 < npage_size[ignSetPage])
|
||||
{
|
||||
|
@ -564,7 +597,7 @@ void receiveValue(int valueOffset, byte newValue)
|
|||
break;
|
||||
|
||||
case afrSetPage:
|
||||
pnt_configPage = &configPage3;
|
||||
pnt_configPage = &configPage6;
|
||||
//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[afrSetPage])
|
||||
{
|
||||
|
@ -639,7 +672,7 @@ void receiveValue(int valueOffset, byte newValue)
|
|||
break;
|
||||
|
||||
case canbusPage:
|
||||
pnt_configPage = &configPage10;
|
||||
pnt_configPage = &configPage9;
|
||||
//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])
|
||||
{
|
||||
|
@ -648,7 +681,7 @@ void receiveValue(int valueOffset, byte newValue)
|
|||
break;
|
||||
|
||||
case warmupPage:
|
||||
pnt_configPage = &configPage11;
|
||||
pnt_configPage = &configPage10;
|
||||
//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])
|
||||
{
|
||||
|
@ -670,7 +703,7 @@ useChar - If true, all values are send as chars, this is for the serial command
|
|||
*/
|
||||
void sendPage(bool useChar)
|
||||
{
|
||||
void* pnt_configPage = &configPage1; //Default value is for safety only. Will be changed below if needed.
|
||||
void* pnt_configPage = &configPage2; //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
|
||||
|
@ -692,27 +725,27 @@ void sendPage(bool useChar)
|
|||
Serial.println((const __FlashStringHelper *)&pageTitles[27]);//27 is the index to the first char in the second sting in pageTitles
|
||||
// The following loop displays in human readable form of all byte values in config page 1 up to but not including the first array.
|
||||
// incrementing void pointers is cumbersome. Thus we have "pnt_configPage = (byte *)pnt_configPage + 1"
|
||||
for (pnt_configPage = &configPage1; pnt_configPage < &configPage1.wueValues[0]; pnt_configPage = (byte *)pnt_configPage + 1) { Serial.println(*((byte *)pnt_configPage)); }
|
||||
for (pnt_configPage = &configPage2; pnt_configPage < &configPage2.wueValues[0]; pnt_configPage = (byte *)pnt_configPage + 1) { Serial.println(*((byte *)pnt_configPage)); }
|
||||
for (byte x = 10; x; x--)// The x between the ';' has the same representation as the "x != 0" test or comparision
|
||||
{
|
||||
Serial.print(configPage1.wueValues[10 - x]);// This displays the values horizantially on the screen
|
||||
Serial.print(configPage2.wueValues[10 - x]);// This displays the values horizantially on the screen
|
||||
Serial.print(' ');
|
||||
}
|
||||
Serial.println();
|
||||
for (pnt_configPage = (byte *)&configPage1.wueValues[9] + 1; pnt_configPage < &configPage1.inj1Ang; pnt_configPage = (byte *)pnt_configPage + 1) {
|
||||
for (pnt_configPage = (byte *)&configPage2.wueValues[9] + 1; pnt_configPage < &configPage2.inj1Ang; pnt_configPage = (byte *)pnt_configPage + 1) {
|
||||
Serial.println(*((byte *)pnt_configPage));// This displays all the byte values between the last array up to but not including the first unsigned int on config page 1
|
||||
}
|
||||
// The following loop displays four unsigned ints
|
||||
for (pnt16_configPage = (uint16_t *)&configPage1.inj1Ang; pnt16_configPage < (uint16_t*)&configPage1.inj4Ang + 1; pnt16_configPage = (uint16_t*)pnt16_configPage + 1)
|
||||
for (pnt16_configPage = (uint16_t *)&configPage2.inj1Ang; pnt16_configPage < (uint16_t*)&configPage2.inj4Ang + 1; pnt16_configPage = (uint16_t*)pnt16_configPage + 1)
|
||||
{ Serial.println(*((uint16_t *)pnt16_configPage)); }
|
||||
// Following loop displays byte values between the unsigned ints
|
||||
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);
|
||||
for (pnt_configPage = (uint16_t *)&configPage2.inj4Ang + 1; pnt_configPage < &configPage2.mapMax; pnt_configPage = (byte *)pnt_configPage + 1) { Serial.println(*((byte *)pnt_configPage)); }
|
||||
Serial.println(configPage2.mapMax);
|
||||
// Following loop displays remaining byte values of the page
|
||||
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)); }
|
||||
for (pnt_configPage = (uint16_t *)&configPage2.mapMax + 1; pnt_configPage < (byte *)&configPage2 + 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
|
||||
else { pnt_configPage = &configPage2; } //Create a pointer to Page 1 in memory
|
||||
break;
|
||||
|
||||
case ignMapPage:
|
||||
|
@ -726,17 +759,17 @@ void sendPage(bool useChar)
|
|||
{
|
||||
//To Display Values from Config Page 2
|
||||
Serial.println((const __FlashStringHelper *)&pageTitles[56]);
|
||||
Serial.println(configPage2.triggerAngle);// configPsge2.triggerAngle is an int so just display it without complication
|
||||
Serial.println(configPage4.triggerAngle);// configPsge2.triggerAngle is an int so just display it without complication
|
||||
// Following loop displays byte values after that first int up to but not including the first array in config page 2
|
||||
for (pnt_configPage = (int *)&configPage2 + 1; pnt_configPage < &configPage2.taeBins[0]; pnt_configPage = (byte *)pnt_configPage + 1) { Serial.println(*((byte *)pnt_configPage)); }
|
||||
for (pnt_configPage = (int *)&configPage4 + 1; pnt_configPage < &configPage4.taeBins[0]; pnt_configPage = (byte *)pnt_configPage + 1) { Serial.println(*((byte *)pnt_configPage)); }
|
||||
for (byte y = 2; y; y--)// Displaying two equal sized arrays
|
||||
{
|
||||
byte * currentVar;// A placeholder for each array
|
||||
if (y == 2) {
|
||||
currentVar = configPage2.taeBins;
|
||||
currentVar = configPage4.taeBins;
|
||||
}
|
||||
else {
|
||||
currentVar = configPage2.taeValues;
|
||||
currentVar = configPage4.taeValues;
|
||||
}
|
||||
|
||||
for (byte j = 4; j; j--)
|
||||
|
@ -748,24 +781,24 @@ void sendPage(bool useChar)
|
|||
}
|
||||
for (byte x = 10; x ; x--)
|
||||
{
|
||||
Serial.print(configPage2.wueBins[10 - x]);//Displaying array horizontally across screen
|
||||
Serial.print(configPage4.wueBins[10 - x]);//Displaying array horizontally across screen
|
||||
Serial.print(' ');
|
||||
}
|
||||
Serial.println();
|
||||
Serial.println(configPage2.dwellLimit);// Little lonely byte stuck between two arrays. No complications just display it.
|
||||
Serial.println(configPage4.dwellLimit);// Little lonely byte stuck between two arrays. No complications just display it.
|
||||
for (byte x = 6; x; x--)
|
||||
{
|
||||
Serial.print(configPage2.dwellCorrectionValues[6 - x]);
|
||||
Serial.print(configPage4.dwellCorrectionValues[6 - x]);
|
||||
Serial.print(' ');
|
||||
}
|
||||
Serial.println();
|
||||
for (pnt_configPage = (byte *)&configPage2.dwellCorrectionValues[5] + 1; pnt_configPage < (byte *)&configPage2 + npage_size[ignSetPage]; pnt_configPage = (byte *)pnt_configPage + 1)
|
||||
for (pnt_configPage = (byte *)&configPage4.dwellCorrectionValues[5] + 1; pnt_configPage < (byte *)&configPage4 + npage_size[ignSetPage]; pnt_configPage = (byte *)pnt_configPage + 1)
|
||||
{
|
||||
Serial.println(*((byte *)pnt_configPage));// Displaying remaining byte values of the page
|
||||
}
|
||||
sendComplete = true;
|
||||
}
|
||||
else { pnt_configPage = &configPage2; } //Create a pointer to Page 2 in memory
|
||||
else { pnt_configPage = &configPage4; } //Create a pointer to Page 2 in memory
|
||||
break;
|
||||
|
||||
case afrMapPage:
|
||||
|
@ -779,15 +812,15 @@ void sendPage(bool useChar)
|
|||
{
|
||||
//To Display Values from Config Page 3
|
||||
Serial.println((const __FlashStringHelper *)&pageTitles[91]);//special typecasting to enable suroutine that the F macro uses
|
||||
for (pnt_configPage = &configPage3; pnt_configPage < &configPage3.voltageCorrectionBins[0]; pnt_configPage = (byte *)pnt_configPage + 1)
|
||||
for (pnt_configPage = &configPage6; pnt_configPage < &configPage6.voltageCorrectionBins[0]; pnt_configPage = (byte *)pnt_configPage + 1)
|
||||
{
|
||||
Serial.println(*((byte *)pnt_configPage));// Displaying byte values of config page 3 up to but not including the first array
|
||||
}
|
||||
for (byte y = 2; y; y--)// Displaying two equally sized arrays that are next to each other
|
||||
{
|
||||
byte * currentVar;
|
||||
if (y == 2) { currentVar = configPage3.voltageCorrectionBins; }
|
||||
else { currentVar = configPage3.injVoltageCorrectionValues; }
|
||||
if (y == 2) { currentVar = configPage6.voltageCorrectionBins; }
|
||||
else { currentVar = configPage6.injVoltageCorrectionValues; }
|
||||
|
||||
for (byte x = 6; x; x--)
|
||||
{
|
||||
|
@ -799,8 +832,8 @@ void sendPage(bool useChar)
|
|||
for (byte y = 2; y; y--)// and again
|
||||
{
|
||||
byte* currentVar;
|
||||
if (y == 2) { currentVar = configPage3.airDenBins; }
|
||||
else { currentVar = configPage3.airDenRates; }
|
||||
if (y == 2) { currentVar = configPage6.airDenBins; }
|
||||
else { currentVar = configPage6.airDenRates; }
|
||||
|
||||
for (byte x = 9; x; x--)
|
||||
{
|
||||
|
@ -810,13 +843,13 @@ 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 + npage_size[afrSetPage]; pnt_configPage = (byte *)pnt_configPage + 1)
|
||||
for (pnt_configPage = (byte *)&configPage6.airDenRates[8] + 1; pnt_configPage < (byte *)&configPage6 + 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
|
||||
else { pnt_configPage = &configPage6; } //Create a pointer to Page 3 in memory
|
||||
|
||||
//Old configPage4 STARTED HERE!
|
||||
//currentTitleIndex = 106;
|
||||
|
@ -829,10 +862,10 @@ void sendPage(bool useChar)
|
|||
byte * currentVar;
|
||||
switch (y)
|
||||
{
|
||||
case 1: currentVar = configPage3.iacBins; break;
|
||||
case 2: currentVar = configPage3.iacOLPWMVal; break;
|
||||
case 3: currentVar = configPage3.iacOLStepVal; break;
|
||||
case 4: currentVar = configPage3.iacCLValues; break;
|
||||
case 1: currentVar = configPage6.iacBins; break;
|
||||
case 2: currentVar = configPage6.iacOLPWMVal; break;
|
||||
case 3: currentVar = configPage6.iacOLStepVal; break;
|
||||
case 4: currentVar = configPage6.iacCLValues; break;
|
||||
default: break;
|
||||
}
|
||||
for (byte x = 10; x; x--)
|
||||
|
@ -847,9 +880,9 @@ void sendPage(bool useChar)
|
|||
byte * currentVar;
|
||||
switch (y)
|
||||
{
|
||||
case 1: currentVar = configPage3.iacCrankBins; break;
|
||||
case 2: currentVar = configPage3.iacCrankDuty; break;
|
||||
case 3: currentVar = configPage3.iacCrankSteps; break;
|
||||
case 1: currentVar = configPage6.iacCrankBins; break;
|
||||
case 2: currentVar = configPage6.iacCrankDuty; break;
|
||||
case 3: currentVar = configPage6.iacCrankSteps; break;
|
||||
default: break;
|
||||
}
|
||||
for (byte x = 4; x; x--)
|
||||
|
@ -860,10 +893,10 @@ void sendPage(bool useChar)
|
|||
Serial.println();
|
||||
}
|
||||
// Following loop is for remaining byte value of page
|
||||
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)); }
|
||||
for (pnt_configPage = (byte *)&configPage6.iacCrankBins[3] + 1; pnt_configPage < (byte *)&configPage6 + 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 4 in memory
|
||||
else { pnt_configPage = &configPage6; } //Create a pointer to Page 4 in memory
|
||||
break;
|
||||
|
||||
case boostvvtPage:
|
||||
|
@ -963,14 +996,14 @@ void sendPage(bool useChar)
|
|||
if (useChar)
|
||||
{
|
||||
//To Display Values from Config Page 10
|
||||
Serial.println((const __FlashStringHelper *)&pageTitles[141]);//special typecasting to enable suroutine that the F macro uses
|
||||
for (pnt_configPage = &configPage10; pnt_configPage < ((byte *)pnt_configPage + 128); pnt_configPage = (byte *)pnt_configPage + 1)
|
||||
Serial.println((const __FlashStringHelper *)&pageTitles[103]);//special typecasting to enable suroutine that the F macro uses
|
||||
for (pnt_configPage = &configPage9; pnt_configPage < ((byte *)pnt_configPage + 128); pnt_configPage = (byte *)pnt_configPage + 1)
|
||||
{
|
||||
Serial.println(*((byte *)pnt_configPage));// Displaying byte values of config page 3 up to but not including the first array
|
||||
}
|
||||
sendComplete = true;
|
||||
}
|
||||
else { pnt_configPage = &configPage10; } //Create a pointer to Page 10 in memory
|
||||
else { pnt_configPage = &configPage9; } //Create a pointer to Page 10 in memory
|
||||
break;
|
||||
|
||||
case warmupPage:
|
||||
|
@ -978,7 +1011,7 @@ void sendPage(bool useChar)
|
|||
{
|
||||
sendComplete = true;
|
||||
}
|
||||
else { pnt_configPage = &configPage11; } //Create a pointer to Page 11 in memory
|
||||
else { pnt_configPage = &configPage10; } //Create a pointer to Page 11 in memory
|
||||
break;
|
||||
|
||||
default:
|
||||
|
@ -986,7 +1019,7 @@ void sendPage(bool useChar)
|
|||
Serial.println(F("\nPage has not been implemented yet"));
|
||||
#endif
|
||||
//Just set default Values to avoid warnings
|
||||
pnt_configPage = &configPage11;
|
||||
pnt_configPage = &configPage10;
|
||||
currentTable = fuelTable;
|
||||
sendComplete = true;
|
||||
break;
|
||||
|
@ -1105,7 +1138,7 @@ void sendPage(bool useChar)
|
|||
|
||||
byte getPageValue(byte page, uint16_t valueAddress)
|
||||
{
|
||||
void* pnt_configPage = &configPage1; //Default value is for safety only. Will be changed below if needed.
|
||||
void* pnt_configPage = &configPage2; //Default value is for safety only. Will be changed below if needed.
|
||||
uint16_t tempAddress;
|
||||
byte returnValue = 0;
|
||||
|
||||
|
@ -1118,7 +1151,7 @@ byte getPageValue(byte page, uint16_t valueAddress)
|
|||
break;
|
||||
|
||||
case veSetPage:
|
||||
pnt_configPage = &configPage1; //Create a pointer to Page 1 in memory
|
||||
pnt_configPage = &configPage2; //Create a pointer to Page 1 in memory
|
||||
returnValue = *((byte *)pnt_configPage + valueAddress);
|
||||
break;
|
||||
|
||||
|
@ -1129,7 +1162,7 @@ byte getPageValue(byte page, uint16_t valueAddress)
|
|||
break;
|
||||
|
||||
case ignSetPage:
|
||||
pnt_configPage = &configPage2; //Create a pointer to Page 2 in memory
|
||||
pnt_configPage = &configPage4; //Create a pointer to Page 2 in memory
|
||||
returnValue = *((byte *)pnt_configPage + valueAddress);
|
||||
break;
|
||||
|
||||
|
@ -1140,7 +1173,7 @@ byte getPageValue(byte page, uint16_t valueAddress)
|
|||
break;
|
||||
|
||||
case afrSetPage:
|
||||
pnt_configPage = &configPage3; //Create a pointer to Page 3 in memory
|
||||
pnt_configPage = &configPage6; //Create a pointer to Page 3 in memory
|
||||
returnValue = *((byte *)pnt_configPage + valueAddress);
|
||||
break;
|
||||
|
||||
|
@ -1213,12 +1246,12 @@ byte getPageValue(byte page, uint16_t valueAddress)
|
|||
break;
|
||||
|
||||
case canbusPage:
|
||||
pnt_configPage = &configPage10; //Create a pointer to Page 10 in memory
|
||||
pnt_configPage = &configPage9; //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
|
||||
pnt_configPage = &configPage10; //Create a pointer to Page 11 in memory
|
||||
returnValue = *((byte *)pnt_configPage + valueAddress);
|
||||
break;
|
||||
|
||||
|
@ -1227,7 +1260,7 @@ byte getPageValue(byte page, uint16_t valueAddress)
|
|||
Serial.println(F("\nPage has not been implemented yet"));
|
||||
#endif
|
||||
//Just set default Values to avoid warnings
|
||||
pnt_configPage = &configPage11;
|
||||
pnt_configPage = &configPage10;
|
||||
break;
|
||||
}
|
||||
return returnValue;
|
||||
|
|
|
@ -17,7 +17,7 @@ Flood clear mode etc.
|
|||
#include "globals.h"
|
||||
|
||||
long PID_O2, PID_output, PID_AFRTarget;
|
||||
PID egoPID(&PID_O2, &PID_output, &PID_AFRTarget, configPage3.egoKP, configPage3.egoKI, configPage3.egoKD, REVERSE); //This is the PID object if that algorithm is used. Needs to be global as it maintains state outside of each function call
|
||||
PID egoPID(&PID_O2, &PID_output, &PID_AFRTarget, configPage6.egoKP, configPage6.egoKI, configPage6.egoKD, REVERSE); //This is the PID object if that algorithm is used. Needs to be global as it maintains state outside of each function call
|
||||
|
||||
void initialiseCorrections()
|
||||
{
|
||||
|
@ -114,7 +114,7 @@ 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 + configPage2.crankingPct; }
|
||||
if ( BIT_CHECK(currentStatus.engine, BIT_ENGINE_CRANK) )
|
||||
{
|
||||
crankingValue = table2D_getValue(&crankingEnrichTable, currentStatus.coolant + CALIBRATION_TEMPERATURE_OFFSET);
|
||||
|
@ -133,10 +133,10 @@ static inline byte correctionASE()
|
|||
//Two checks are requiredL:
|
||||
//1) Is the negine run time less than the configured ase time
|
||||
//2) Make sure we're not still cranking
|
||||
if ( (currentStatus.runSecs < configPage1.aseCount) && !(BIT_CHECK(currentStatus.engine, BIT_ENGINE_CRANK)) )
|
||||
if ( (currentStatus.runSecs < configPage2.aseCount) && !(BIT_CHECK(currentStatus.engine, BIT_ENGINE_CRANK)) )
|
||||
{
|
||||
BIT_SET(currentStatus.engine, BIT_ENGINE_ASE); //Mark ASE as active.
|
||||
ASEValue = 100 + configPage1.asePct;
|
||||
ASEValue = 100 + configPage2.asePct;
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -189,10 +189,10 @@ static inline int16_t correctionAccel()
|
|||
int rateOfChange = ldiv(1000000, (currentStatus.TPS_time - currentStatus.TPSlast_time)).quot * TPS_change; //This is the % per second that the TPS has moved
|
||||
currentStatus.tpsDOT = rateOfChange / 10; //The TAE bins are divided by 10 in order to allow them to be stored in a byte. Faster as this than divu10
|
||||
|
||||
if (rateOfChange > configPage1.tpsThresh)
|
||||
if (rateOfChange > configPage2.tpsThresh)
|
||||
{
|
||||
BIT_SET(currentStatus.engine, BIT_ENGINE_ACC); //Mark accleration enrichment as active.
|
||||
currentStatus.TAEEndTime = micros() + ((unsigned long)configPage1.taeTime * 10000); //Set the time in the future where the enrichment will be turned off. taeTime is stored as mS / 10, so multiply it by 100 to get it in uS
|
||||
currentStatus.TAEEndTime = micros() + ((unsigned long)configPage2.taeTime * 10000); //Set the time in the future where the enrichment will be turned off. taeTime is stored as mS / 10, so multiply it by 100 to get it in uS
|
||||
accelValue = 100 + table2D_getValue(&taeTable, currentStatus.tpsDOT);
|
||||
}
|
||||
}
|
||||
|
@ -212,7 +212,7 @@ static inline byte correctionFloodClear()
|
|||
if( BIT_CHECK(currentStatus.engine, BIT_ENGINE_CRANK) )
|
||||
{
|
||||
//Engine is currently cranking, check what the TPS is
|
||||
if(currentStatus.TPS >= configPage2.floodClear)
|
||||
if(currentStatus.TPS >= configPage4.floodClear)
|
||||
{
|
||||
//Engine is cranking and TPS is above threshold. Cut all fuel
|
||||
floodValue = 0;
|
||||
|
@ -254,7 +254,7 @@ This simple check applies the extra fuel if we're currently launching
|
|||
static inline byte correctionLaunch()
|
||||
{
|
||||
byte launchValue = 100;
|
||||
if(currentStatus.launchingHard || currentStatus.launchingSoft) { launchValue = (100 + configPage3.lnchFuelAdd); }
|
||||
if(currentStatus.launchingHard || currentStatus.launchingSoft) { launchValue = (100 + configPage6.lnchFuelAdd); }
|
||||
|
||||
return launchValue;
|
||||
}
|
||||
|
@ -265,10 +265,10 @@ static inline byte correctionLaunch()
|
|||
static inline bool correctionDFCO()
|
||||
{
|
||||
bool DFCOValue = false;
|
||||
if ( configPage1.dfcoEnabled == 1 )
|
||||
if ( configPage2.dfcoEnabled == 1 )
|
||||
{
|
||||
if ( bitRead(currentStatus.status1, BIT_STATUS1_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 ); }
|
||||
if ( bitRead(currentStatus.status1, BIT_STATUS1_DFCO) == 1 ) { DFCOValue = ( currentStatus.RPM > ( configPage4.dfcoRPM * 10) ) && ( currentStatus.TPS < configPage4.dfcoTPSThresh ); }
|
||||
else { DFCOValue = ( currentStatus.RPM > (unsigned int)( (configPage4.dfcoRPM * 10) + configPage4.dfcoHyster) ) && ( currentStatus.TPS < configPage4.dfcoTPSThresh ); }
|
||||
}
|
||||
return DFCOValue;
|
||||
}
|
||||
|
@ -280,10 +280,10 @@ static inline bool correctionDFCO()
|
|||
static inline byte correctionFlex()
|
||||
{
|
||||
byte flexValue = 100;
|
||||
if(configPage1.flexEnabled == 1)
|
||||
|
||||
if (configPage2.flexEnabled == 1)
|
||||
{
|
||||
byte flexRange = configPage1.flexFuelHigh - configPage1.flexFuelLow;
|
||||
flexValue = percentage(currentStatus.ethanolPct, flexRange) + 100;
|
||||
flexValue = table2D_getValue(&flexFuelTable, currentStatus.ethanolPct);
|
||||
}
|
||||
return flexValue;
|
||||
}
|
||||
|
@ -305,34 +305,34 @@ PID (Best suited to wideband sensors):
|
|||
static inline byte correctionAFRClosedLoop()
|
||||
{
|
||||
byte AFRValue = 100;
|
||||
if( configPage3.egoType > 0 ) //egoType of 0 means no O2 sensor
|
||||
if( configPage6.egoType > 0 ) //egoType of 0 means no O2 sensor
|
||||
{
|
||||
currentStatus.afrTarget = currentStatus.O2; //Catch all incase the below doesn't run. This prevents the Include AFR option from doing crazy things if the AFR target conditions aren't met. This value is changed again below if all conditions are met.
|
||||
|
||||
//Determine whether the Y axis of the AFR target table tshould be MAP (Speed-Density) or TPS (Alpha-N)
|
||||
byte yValue;
|
||||
if (configPage1.algorithm == 0) { yValue = currentStatus.MAP; }
|
||||
if (configPage2.algorithm == 0) { yValue = currentStatus.MAP; }
|
||||
else { yValue = currentStatus.TPS; }
|
||||
currentStatus.afrTarget = get3DTableValue(&afrTable, yValue, currentStatus.RPM); //Perform the target lookup
|
||||
|
||||
//Check all other requirements for closed loop adjustments
|
||||
if( (currentStatus.coolant > (int)(configPage3.egoTemp - CALIBRATION_TEMPERATURE_OFFSET)) && (currentStatus.RPM > (unsigned int)(configPage3.egoRPM * 100)) && (currentStatus.TPS < configPage3.egoTPSMax) && (currentStatus.O2 < configPage3.ego_max) && (currentStatus.O2 > configPage3.ego_min) && (currentStatus.runSecs > configPage3.ego_sdelay) )
|
||||
if( (currentStatus.coolant > (int)(configPage6.egoTemp - CALIBRATION_TEMPERATURE_OFFSET)) && (currentStatus.RPM > (unsigned int)(configPage6.egoRPM * 100)) && (currentStatus.TPS < configPage6.egoTPSMax) && (currentStatus.O2 < configPage6.ego_max) && (currentStatus.O2 > configPage6.ego_min) && (currentStatus.runSecs > configPage6.ego_sdelay) )
|
||||
{
|
||||
AFRValue = currentStatus.egoCorrection; //Need to record this here, just to make sure the correction stays 'on' even if the nextCycle count isn't ready
|
||||
|
||||
if(ignitionCount >= AFRnextCycle)
|
||||
{
|
||||
AFRnextCycle = ignitionCount + configPage3.egoCount; //Set the target ignition event for the next calculation
|
||||
AFRnextCycle = ignitionCount + configPage6.egoCount; //Set the target ignition event for the next calculation
|
||||
|
||||
//Check which algorithm is used, simple or PID
|
||||
if (configPage3.egoAlgorithm == EGO_ALGORITHM_SIMPLE)
|
||||
if (configPage6.egoAlgorithm == EGO_ALGORITHM_SIMPLE)
|
||||
{
|
||||
//*************************************************************************************************************************************
|
||||
//Simple algorithm
|
||||
if(currentStatus.O2 > currentStatus.afrTarget)
|
||||
{
|
||||
//Running lean
|
||||
if(currentStatus.egoCorrection < (100 + configPage3.egoLimit) ) //Fueling adjustment must be at most the egoLimit amount (up or down)
|
||||
if(currentStatus.egoCorrection < (100 + configPage6.egoLimit) ) //Fueling adjustment must be at most the egoLimit amount (up or down)
|
||||
{
|
||||
if(currentStatus.egoCorrection >= 100) { AFRValue = (currentStatus.egoCorrection + 1); } //Increase the fueling by 1%
|
||||
else { AFRValue += 1; } //This means that the last reading had been rich, so start counting back towards 100%
|
||||
|
@ -341,19 +341,19 @@ static inline byte correctionAFRClosedLoop()
|
|||
}
|
||||
else
|
||||
//Running Rich
|
||||
if(currentStatus.egoCorrection > (100 - configPage3.egoLimit) ) //Fueling adjustment must be at most the egoLimit amount (up or down)
|
||||
if(currentStatus.egoCorrection > (100 - configPage6.egoLimit) ) //Fueling adjustment must be at most the egoLimit amount (up or down)
|
||||
{
|
||||
if(currentStatus.egoCorrection <= 100) { AFRValue = (currentStatus.egoCorrection - 1); } //Increase the fueling by 1%
|
||||
else { AFRValue -= 1; } //This means that the last reading had been lean, so start count back towards 100%
|
||||
}
|
||||
else { AFRValue = currentStatus.egoCorrection; } //Means we're at the maximum adjustment amount, so simply return then again
|
||||
}
|
||||
else if(configPage3.egoAlgorithm == EGO_ALGORITHM_PID)
|
||||
else if(configPage6.egoAlgorithm == EGO_ALGORITHM_PID)
|
||||
{
|
||||
//*************************************************************************************************************************************
|
||||
//PID algorithm
|
||||
egoPID.SetOutputLimits((long)(-configPage3.egoLimit), (long)(configPage3.egoLimit)); //Set the limits again, just incase the user has changed them since the last loop. Note that these are sent to the PID library as (Eg:) -15 and +15
|
||||
egoPID.SetTunings(configPage3.egoKP, configPage3.egoKI, configPage3.egoKD); //Set the PID values again, just incase the user has changed them since the last loop
|
||||
egoPID.SetOutputLimits((long)(-configPage6.egoLimit), (long)(configPage6.egoLimit)); //Set the limits again, just incase the user has changed them since the last loop. Note that these are sent to the PID library as (Eg:) -15 and +15
|
||||
egoPID.SetTunings(configPage6.egoKP, configPage6.egoKI, configPage6.egoKD); //Set the PID values again, just incase the user has changed them since the last loop
|
||||
PID_O2 = (long)(currentStatus.O2);
|
||||
PID_AFRTarget = (long)(currentStatus.afrTarget);
|
||||
|
||||
|
@ -390,27 +390,23 @@ int8_t correctionsIgn(int8_t base_advance)
|
|||
static inline int8_t correctionFixedTiming(int8_t advance)
|
||||
{
|
||||
byte ignFixValue = advance;
|
||||
if (configPage2.FixAng != 0) { ignFixValue = configPage2.FixAng; } //Check whether the user has set a fixed timing angle
|
||||
if (configPage4.FixAng != 0) { ignFixValue = configPage4.FixAng; } //Check whether the user has set a fixed timing angle
|
||||
return ignFixValue;
|
||||
}
|
||||
|
||||
static inline int8_t correctionCrankingFixedTiming(int8_t advance)
|
||||
{
|
||||
byte ignCrankFixValue = advance;
|
||||
if ( BIT_CHECK(currentStatus.engine, BIT_ENGINE_CRANK) ) { ignCrankFixValue = configPage2.CrankAng; } //Use the fixed cranking ignition angle
|
||||
if ( BIT_CHECK(currentStatus.engine, BIT_ENGINE_CRANK) ) { ignCrankFixValue = configPage4.CrankAng; } //Use the fixed cranking ignition angle
|
||||
return ignCrankFixValue;
|
||||
}
|
||||
|
||||
static inline int8_t correctionFlexTiming(int8_t advance)
|
||||
{
|
||||
byte ignFlexValue = advance;
|
||||
if( configPage1.flexEnabled == 1 ) //Check for flex being enabled
|
||||
if( configPage2.flexEnabled == 1 ) //Check for flex being enabled
|
||||
{
|
||||
byte flexRange = configPage1.flexAdvHigh - configPage1.flexAdvLow;
|
||||
|
||||
if (currentStatus.ethanolPct != 0) { currentStatus.flexIgnCorrection = percentage(currentStatus.ethanolPct, flexRange); }
|
||||
else { currentStatus.flexIgnCorrection = 0; }
|
||||
|
||||
currentStatus.flexIgnCorrection = table2D_getValue(&flexAdvTable, currentStatus.ethanolPct);
|
||||
ignFlexValue = advance + currentStatus.flexIgnCorrection;
|
||||
}
|
||||
return ignFlexValue;
|
||||
|
@ -432,7 +428,7 @@ static inline int8_t correctionSoftRevLimit(int8_t advance)
|
|||
{
|
||||
byte ignSoftRevValue = advance;
|
||||
BIT_CLEAR(currentStatus.spark, BIT_SPARK_SFTLIM);
|
||||
if (currentStatus.RPM > ((unsigned int)(configPage2.SoftRevLim) * 100) ) { BIT_SET(currentStatus.spark, BIT_SPARK_SFTLIM); ignSoftRevValue = configPage2.SoftLimRetard; } //Softcut RPM limit (If we're above softcut limit, delay timing by configured number of degrees)
|
||||
if (currentStatus.RPM > ((unsigned int)(configPage4.SoftRevLim) * 100) ) { BIT_SET(currentStatus.spark, BIT_SPARK_SFTLIM); ignSoftRevValue = configPage4.SoftLimRetard; } //Softcut RPM limit (If we're above softcut limit, delay timing by configured number of degrees)
|
||||
|
||||
return ignSoftRevValue;
|
||||
}
|
||||
|
@ -441,11 +437,11 @@ static inline int8_t correctionSoftLaunch(int8_t advance)
|
|||
{
|
||||
byte ignSoftLaunchValue = advance;
|
||||
//SoftCut rev limit for 2-step launch control.
|
||||
if (configPage3.launchEnabled && clutchTrigger && (currentStatus.clutchEngagedRPM < ((unsigned int)(configPage3.flatSArm) * 100)) && (currentStatus.RPM > ((unsigned int)(configPage3.lnchSoftLim) * 100)) )
|
||||
if (configPage6.launchEnabled && clutchTrigger && (currentStatus.clutchEngagedRPM < ((unsigned int)(configPage6.flatSArm) * 100)) && (currentStatus.RPM > ((unsigned int)(configPage6.lnchSoftLim) * 100)) && (currentStatus.TPS >= configPage10.lnchCtrlTPS) )
|
||||
{
|
||||
currentStatus.launchingSoft = true;
|
||||
BIT_SET(currentStatus.spark, BIT_SPARK_SLAUNCH);
|
||||
ignSoftLaunchValue = configPage3.lnchRetard;
|
||||
ignSoftLaunchValue = configPage6.lnchRetard;
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -460,10 +456,10 @@ static inline int8_t correctionSoftFlatShift(int8_t advance)
|
|||
{
|
||||
byte ignSoftFlatValue = advance;
|
||||
|
||||
if(configPage3.flatSEnable && clutchTrigger && (currentStatus.clutchEngagedRPM > ((unsigned int)(configPage3.flatSArm) * 100)) && (currentStatus.RPM > (currentStatus.clutchEngagedRPM-configPage3.flatSSoftWin) ) )
|
||||
if(configPage6.flatSEnable && clutchTrigger && (currentStatus.clutchEngagedRPM > ((unsigned int)(configPage6.flatSArm) * 100)) && (currentStatus.RPM > (currentStatus.clutchEngagedRPM-configPage6.flatSSoftWin) ) )
|
||||
{
|
||||
BIT_SET(currentStatus.spark2, BIT_SPARK2_FLATSS);
|
||||
ignSoftFlatValue = configPage3.flatSRetard;
|
||||
ignSoftFlatValue = configPage6.flatSRetard;
|
||||
}
|
||||
else { BIT_CLEAR(currentStatus.spark2, BIT_SPARK2_FLATSS); }
|
||||
|
||||
|
@ -479,19 +475,19 @@ uint16_t correctionsDwell(uint16_t dwell)
|
|||
if (currentStatus.dwellCorrection != 100) { tempDwell = divs100(dwell) * currentStatus.dwellCorrection; }
|
||||
|
||||
//Dwell limiter
|
||||
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
|
||||
uint16_t dwellPerRevolution = tempDwell + (uint16_t)(configPage4.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) || (configPage2.sparkMode == IGN_MODE_ROTARY) ) && (configPage1.nCylinders > 1) ) //No point in running this for 1 cylinder engines
|
||||
if( ( (configPage4.sparkMode == IGN_MODE_SINGLE) || (configPage4.sparkMode == IGN_MODE_ROTARY) ) && (configPage2.nCylinders > 1) ) //No point in running this for 1 cylinder engines
|
||||
{
|
||||
pulsesPerRevolution = (configPage1.nCylinders >> 1);
|
||||
pulsesPerRevolution = (configPage2.nCylinders >> 1);
|
||||
dwellPerRevolution = dwellPerRevolution * pulsesPerRevolution;
|
||||
}
|
||||
|
||||
if(dwellPerRevolution > revolutionTime)
|
||||
{
|
||||
//Possibly need some method of reducing spark duration here as well, but this is a start
|
||||
tempDwell = (revolutionTime / pulsesPerRevolution) - (configPage2.sparkDur * 100);
|
||||
tempDwell = (revolutionTime / pulsesPerRevolution) - (configPage4.sparkDur * 100);
|
||||
}
|
||||
return tempDwell;
|
||||
}
|
||||
|
|
|
@ -74,9 +74,9 @@ static inline uint16_t stdGetRPM()
|
|||
*/
|
||||
static inline void setFilter(unsigned long curGap)
|
||||
{
|
||||
if(configPage2.triggerFilter == 1) { triggerFilterTime = curGap >> 2; } //Lite filter level is 25% of previous gap
|
||||
else if(configPage2.triggerFilter == 2) { triggerFilterTime = curGap >> 1; } //Medium filter level is 50% of previous gap
|
||||
else if (configPage2.triggerFilter == 3) { triggerFilterTime = (curGap * 3) >> 2; } //Aggressive filter level is 75% of previous gap
|
||||
if(configPage4.triggerFilter == 1) { triggerFilterTime = curGap >> 2; } //Lite filter level is 25% of previous gap
|
||||
else if(configPage4.triggerFilter == 2) { triggerFilterTime = curGap >> 1; } //Medium filter level is 50% of previous gap
|
||||
else if (configPage4.triggerFilter == 3) { triggerFilterTime = (curGap * 3) >> 2; } //Aggressive filter level is 75% of previous gap
|
||||
else { triggerFilterTime = 0; } //trigger filter is turned off.
|
||||
}
|
||||
|
||||
|
@ -89,7 +89,7 @@ It takes an argument of the full (COMPLETE) number of teeth per revolution. For
|
|||
static inline int crankingGetRPM(byte totalTeeth)
|
||||
{
|
||||
uint16_t tempRPM = 0;
|
||||
if( (currentStatus.startRevolutions >= configPage2.StgCycles) && (currentStatus.hasSync == true) )
|
||||
if( (currentStatus.startRevolutions >= configPage4.StgCycles) && (currentStatus.hasSync == true) )
|
||||
{
|
||||
if( (toothLastToothTime > 0) && (toothLastMinusOneToothTime > 0) && (toothLastToothTime > toothLastMinusOneToothTime) )
|
||||
{
|
||||
|
@ -124,19 +124,19 @@ Note: This does not currently support dual wheel (ie missing tooth + single toot
|
|||
*/
|
||||
void triggerSetup_missingTooth()
|
||||
{
|
||||
triggerToothAngle = 360 / configPage2.triggerTeeth; //The number of degrees that passes from tooth to tooth
|
||||
if(configPage2.TrigSpeed == 1) { triggerToothAngle = 720 / configPage2.triggerTeeth; } //Account for cam speed missing tooth
|
||||
triggerActualTeeth = configPage2.triggerTeeth - configPage2.triggerMissingTeeth; //The number of physical teeth on the wheel. Doing this here saves us a calculation each time in the interrupt
|
||||
triggerFilterTime = (int)(1000000 / (MAX_RPM / 60 * configPage2.triggerTeeth)); //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
|
||||
triggerSecFilterTime = (int)((trigPatternSec == true) ? 1000000 * 60 / MAX_RPM / 4 / 2 : 1000000 * 60 / MAX_RPM / 2 / 2); //Same as above, but fixed at 2 teeth on the secondary input and divided by 2 (for cam speed)
|
||||
triggerToothAngle = 360 / configPage4.triggerTeeth; //The number of degrees that passes from tooth to tooth
|
||||
if(configPage4.TrigSpeed == 1) { triggerToothAngle = 720 / configPage4.triggerTeeth; } //Account for cam speed missing tooth
|
||||
triggerActualTeeth = configPage4.triggerTeeth - configPage4.triggerMissingTeeth; //The number of physical teeth on the wheel. Doing this here saves us a calculation each time in the interrupt
|
||||
triggerFilterTime = (int)(1000000 / (MAX_RPM / 60 * configPage4.triggerTeeth)); //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
|
||||
triggerSecFilterTime = (int)((configPage4.trigPatternSec == SEC_TRIGGER_4_1 ) ? 1000000 * 60 / MAX_RPM / 4 / 2 : 1000000 * 60 / MAX_RPM / 2 / 2); //For 4-1 came wheel. Same as above, but fixed at 2 teeth on the secondary input and divided by 2 (for cam speed)
|
||||
secondDerivEnabled = false;
|
||||
decoderIsSequential = false;
|
||||
checkSyncToothCount = (configPage2.triggerTeeth) >> 1; //50% of the total teeth.
|
||||
checkSyncToothCount = (configPage4.triggerTeeth) >> 1; //50% of the total teeth.
|
||||
toothLastMinusOneToothTime = 0;
|
||||
toothCurrentCount = 0;
|
||||
toothOneTime = 0;
|
||||
toothOneMinusOneTime = 0;
|
||||
MAX_STALL_TIME = (3333UL * triggerToothAngle * (configPage2.triggerMissingTeeth + 1)); //Minimum 50rpm. (3333uS is the time per degree at 50rpm)
|
||||
MAX_STALL_TIME = (3333UL * triggerToothAngle * (configPage4.triggerMissingTeeth + 1)); //Minimum 50rpm. (3333uS is the time per degree at 50rpm)
|
||||
}
|
||||
|
||||
void triggerPri_missingTooth()
|
||||
|
@ -153,7 +153,7 @@ void triggerPri_missingTooth()
|
|||
{
|
||||
//Begin the missing tooth detection
|
||||
//If the time between the current tooth and the last is greater than 1.5x the time between the last tooth and the tooth before that, we make the assertion that we must be at the first tooth after the gap
|
||||
if(configPage2.triggerMissingTeeth == 1) { targetGap = (3 * (toothLastToothTime - toothLastMinusOneToothTime)) >> 1; } //Multiply by 1.5 (Checks for a gap 1.5x greater than the last one) (Uses bitshift to multiply by 3 then divide by 2. Much faster than multiplying by 1.5)
|
||||
if(configPage4.triggerMissingTeeth == 1) { targetGap = (3 * (toothLastToothTime - toothLastMinusOneToothTime)) >> 1; } //Multiply by 1.5 (Checks for a gap 1.5x greater than the last one) (Uses bitshift to multiply by 3 then divide by 2. Much faster than multiplying by 1.5)
|
||||
else { targetGap = ((toothLastToothTime - toothLastMinusOneToothTime)) * 2; } //Multiply by 2 (Checks for a gap 2x greater than the last one)
|
||||
|
||||
if( (toothLastToothTime == 0) || (toothLastMinusOneToothTime == 0) ) { curGap = 0; }
|
||||
|
@ -188,9 +188,9 @@ void triggerPri_missingTooth()
|
|||
}
|
||||
|
||||
//EXPERIMENTAL!
|
||||
if(configPage1.perToothIgn == true)
|
||||
if(configPage2.perToothIgn == true)
|
||||
{
|
||||
uint16_t crankAngle = ( (toothCurrentCount-1) * triggerToothAngle ) + configPage2.triggerAngle;
|
||||
uint16_t crankAngle = ( (toothCurrentCount-1) * triggerToothAngle ) + configPage4.triggerAngle;
|
||||
doPerToothTiming(crankAngle);
|
||||
}
|
||||
}
|
||||
|
@ -207,8 +207,7 @@ void triggerSec_missingTooth()
|
|||
) { curGap2 = 0; }
|
||||
if ( curGap2 >= triggerSecFilterTime )
|
||||
{
|
||||
#ifndef SMALL_FLASH_MODE
|
||||
if ( trigPatternSec == true )
|
||||
if ( configPage4.trigPatternSec == SEC_TRIGGER_4_1 )
|
||||
{
|
||||
targetGap2 = (3 * (toothLastSecToothTime - toothLastMinusOneSecToothTime)) >> 1; //If the time between the current tooth and the last is greater than 1.5x the time between the last tooth and the tooth before that, we make the assertion that we must be at the first tooth after the gap
|
||||
toothLastMinusOneSecToothTime = toothLastSecToothTime;
|
||||
|
@ -225,11 +224,10 @@ void triggerSec_missingTooth()
|
|||
}
|
||||
}
|
||||
else
|
||||
#endif
|
||||
{
|
||||
revolutionOne = 1; //Sequential revolution reset
|
||||
}
|
||||
toothLastSecToothTime = curTime2;
|
||||
}
|
||||
toothLastSecToothTime = curTime2;
|
||||
} //Trigger filter
|
||||
}
|
||||
|
||||
|
@ -240,14 +238,14 @@ uint16_t getRPM_missingTooth()
|
|||
{
|
||||
if(toothCurrentCount != 1)
|
||||
{
|
||||
if(configPage2.TrigSpeed == 1) { tempRPM = crankingGetRPM(configPage2.triggerTeeth/2); } //Account for cam speed
|
||||
else { tempRPM = crankingGetRPM(configPage2.triggerTeeth); }
|
||||
if(configPage4.TrigSpeed == 1) { tempRPM = crankingGetRPM(configPage4.triggerTeeth/2); } //Account for cam speed
|
||||
else { tempRPM = crankingGetRPM(configPage4.triggerTeeth); }
|
||||
}
|
||||
else { tempRPM = currentStatus.RPM; } //Can't do per tooth RPM if we're at tooth #1 as the missing tooth messes the calculation
|
||||
}
|
||||
else
|
||||
{
|
||||
if(configPage2.TrigSpeed == 1) { tempRPM = (stdGetRPM() * 2); } //Account for cam speed
|
||||
if(configPage4.TrigSpeed == 1) { tempRPM = (stdGetRPM() * 2); } //Account for cam speed
|
||||
else { tempRPM = stdGetRPM(); }
|
||||
}
|
||||
return tempRPM;
|
||||
|
@ -266,7 +264,7 @@ int getCrankAngle_missingTooth(int timePerDegree)
|
|||
tempRevolutionOne = revolutionOne;
|
||||
interrupts();
|
||||
|
||||
int crankAngle = ((tempToothCurrentCount - 1) * triggerToothAngle) + configPage2.triggerAngle; //Number of teeth that have passed since tooth 1, multiplied by the angle each tooth represents, plus the angle that tooth 1 is ATDC. This gives accuracy only to the nearest tooth.
|
||||
int crankAngle = ((tempToothCurrentCount - 1) * triggerToothAngle) + configPage4.triggerAngle; //Number of teeth that have passed since tooth 1, multiplied by the angle each tooth represents, plus the angle that tooth 1 is ATDC. This gives accuracy only to the nearest tooth.
|
||||
//Estimate the number of degrees travelled since the last tooth}
|
||||
long elapsedTime = (micros() - tempToothLastToothTime);
|
||||
//crankAngle += DIV_ROUND_CLOSEST(elapsedTime, timePerDegree);
|
||||
|
@ -287,24 +285,24 @@ int getCrankAngle_missingTooth(int timePerDegree)
|
|||
void triggerSetEndTeeth_missingTooth()
|
||||
{
|
||||
|
||||
ignition1EndTooth = ( (ignition1EndAngle - configPage2.triggerAngle) / triggerToothAngle ) - 1;
|
||||
if(ignition1EndTooth > configPage2.triggerTeeth) { ignition1EndTooth -= configPage2.triggerTeeth; }
|
||||
if(ignition1EndTooth <= 0) { ignition1EndTooth -= configPage2.triggerTeeth; }
|
||||
ignition1EndTooth = ( (ignition1EndAngle - configPage4.triggerAngle) / triggerToothAngle ) - 1;
|
||||
if(ignition1EndTooth > configPage4.triggerTeeth) { ignition1EndTooth -= configPage4.triggerTeeth; }
|
||||
if(ignition1EndTooth <= 0) { ignition1EndTooth -= configPage4.triggerTeeth; }
|
||||
if(ignition1EndTooth > triggerActualTeeth) { ignition1EndTooth = triggerActualTeeth; }
|
||||
|
||||
ignition2EndTooth = ( (ignition2EndAngle - configPage2.triggerAngle) / triggerToothAngle ) - 1;
|
||||
if(ignition2EndTooth > configPage2.triggerTeeth) { ignition2EndTooth -= configPage2.triggerTeeth; }
|
||||
if(ignition2EndTooth <= 0) { ignition2EndTooth -= configPage2.triggerTeeth; }
|
||||
ignition2EndTooth = ( (ignition2EndAngle - configPage4.triggerAngle) / triggerToothAngle ) - 1;
|
||||
if(ignition2EndTooth > configPage4.triggerTeeth) { ignition2EndTooth -= configPage4.triggerTeeth; }
|
||||
if(ignition2EndTooth <= 0) { ignition2EndTooth -= configPage4.triggerTeeth; }
|
||||
if(ignition2EndTooth > triggerActualTeeth) { ignition2EndTooth = triggerActualTeeth; }
|
||||
|
||||
ignition3EndTooth = ( (ignition3EndAngle - configPage2.triggerAngle) / triggerToothAngle ) - 1;
|
||||
if(ignition3EndTooth > configPage2.triggerTeeth) { ignition3EndTooth -= configPage2.triggerTeeth; }
|
||||
if(ignition3EndTooth <= 0) { ignition3EndTooth -= configPage2.triggerTeeth; }
|
||||
ignition3EndTooth = ( (ignition3EndAngle - configPage4.triggerAngle) / triggerToothAngle ) - 1;
|
||||
if(ignition3EndTooth > configPage4.triggerTeeth) { ignition3EndTooth -= configPage4.triggerTeeth; }
|
||||
if(ignition3EndTooth <= 0) { ignition3EndTooth -= configPage4.triggerTeeth; }
|
||||
if(ignition3EndTooth > triggerActualTeeth) { ignition3EndTooth = triggerActualTeeth; }
|
||||
|
||||
ignition4EndTooth = ( (ignition4EndAngle - configPage2.triggerAngle) / triggerToothAngle ) - 1;
|
||||
if(ignition4EndTooth > configPage2.triggerTeeth) { ignition4EndTooth -= configPage2.triggerTeeth; }
|
||||
if(ignition4EndTooth <= 0) { ignition4EndTooth -= configPage2.triggerTeeth; }
|
||||
ignition4EndTooth = ( (ignition4EndAngle - configPage4.triggerAngle) / triggerToothAngle ) - 1;
|
||||
if(ignition4EndTooth > configPage4.triggerTeeth) { ignition4EndTooth -= configPage4.triggerTeeth; }
|
||||
if(ignition4EndTooth <= 0) { ignition4EndTooth -= configPage4.triggerTeeth; }
|
||||
if(ignition4EndTooth > triggerActualTeeth) { ignition4EndTooth = triggerActualTeeth; }
|
||||
|
||||
|
||||
|
@ -317,10 +315,10 @@ Note: There can be no missing teeth on the primary wheel
|
|||
*/
|
||||
void triggerSetup_DualWheel()
|
||||
{
|
||||
triggerToothAngle = 360 / configPage2.triggerTeeth; //The number of degrees that passes from tooth to tooth
|
||||
if(configPage2.TrigSpeed == 1) { triggerToothAngle = 720 / configPage2.triggerTeeth; } //Account for cam speed missing tooth
|
||||
triggerToothAngle = 360 / configPage4.triggerTeeth; //The number of degrees that passes from tooth to tooth
|
||||
if(configPage4.TrigSpeed == 1) { triggerToothAngle = 720 / configPage4.triggerTeeth; } //Account for cam speed missing tooth
|
||||
toothCurrentCount = 255; //Default value
|
||||
triggerFilterTime = (int)(1000000 / (MAX_RPM / 60 * configPage2.triggerTeeth)); //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
|
||||
triggerFilterTime = (int)(1000000 / (MAX_RPM / 60 * configPage4.triggerTeeth)); //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
|
||||
triggerSecFilterTime = (int)(1000000 / (MAX_RPM / 60 * 2)) / 2; //Same as above, but fixed at 2 teeth on the secondary input and divided by 2 (for cam speed)
|
||||
secondDerivEnabled = false;
|
||||
decoderIsSequential = true;
|
||||
|
@ -343,7 +341,7 @@ void triggerPri_DualWheel()
|
|||
|
||||
if ( currentStatus.hasSync == true )
|
||||
{
|
||||
if ( (toothCurrentCount == 1) || (toothCurrentCount > configPage2.triggerTeeth) )
|
||||
if ( (toothCurrentCount == 1) || (toothCurrentCount > configPage4.triggerTeeth) )
|
||||
{
|
||||
toothCurrentCount = 1;
|
||||
revolutionOne = !revolutionOne; //Flip sequential revolution tracker
|
||||
|
@ -356,9 +354,9 @@ void triggerPri_DualWheel()
|
|||
}
|
||||
|
||||
//EXPERIMENTAL!
|
||||
if(configPage1.perToothIgn == true)
|
||||
if(configPage2.perToothIgn == true)
|
||||
{
|
||||
uint16_t crankAngle = ( (toothCurrentCount-1) * triggerToothAngle ) + configPage2.triggerAngle;
|
||||
uint16_t crankAngle = ( (toothCurrentCount-1) * triggerToothAngle ) + configPage4.triggerAngle;
|
||||
doPerToothTiming(crankAngle);
|
||||
}
|
||||
} //TRigger filter
|
||||
|
@ -378,12 +376,13 @@ void triggerSec_DualWheel()
|
|||
if(currentStatus.hasSync == false)
|
||||
{
|
||||
toothLastToothTime = micros();
|
||||
toothLastMinusOneToothTime = (toothOneTime - 6000000) / configPage2.triggerTeeth; //Fixes RPM at 10rpm until a full revolution has taken place
|
||||
toothCurrentCount = configPage2.triggerTeeth;
|
||||
//CONFIRM THE BELOW! IT DOESN'T LOOK RIGHT (toothOneTime??)
|
||||
toothLastMinusOneToothTime = (toothOneTime - 6000000) / configPage4.triggerTeeth; //Fixes RPM at 10rpm until a full revolution has taken place
|
||||
toothCurrentCount = configPage4.triggerTeeth;
|
||||
|
||||
currentStatus.hasSync = true;
|
||||
}
|
||||
else if (configPage2.useResync == 1) { toothCurrentCount = configPage2.triggerTeeth; }
|
||||
else if (configPage4.useResync == 1) { toothCurrentCount = configPage4.triggerTeeth; }
|
||||
|
||||
revolutionOne = 1; //Sequential revolution reset
|
||||
} //Trigger filter
|
||||
|
@ -394,7 +393,7 @@ uint16_t getRPM_DualWheel()
|
|||
uint16_t tempRPM = 0;
|
||||
if( currentStatus.hasSync == true )
|
||||
{
|
||||
if(currentStatus.RPM < currentStatus.crankRPM) { tempRPM = crankingGetRPM(configPage2.triggerTeeth); }
|
||||
if(currentStatus.RPM < currentStatus.crankRPM) { tempRPM = crankingGetRPM(configPage4.triggerTeeth); }
|
||||
else { tempRPM = stdGetRPM(); }
|
||||
}
|
||||
return tempRPM;
|
||||
|
@ -414,9 +413,9 @@ int getCrankAngle_DualWheel(int timePerDegree)
|
|||
interrupts();
|
||||
|
||||
//Handle case where the secondary tooth was the last one seen
|
||||
if(tempToothCurrentCount == 0) { tempToothCurrentCount = configPage2.triggerTeeth; }
|
||||
if(tempToothCurrentCount == 0) { tempToothCurrentCount = configPage4.triggerTeeth; }
|
||||
|
||||
int crankAngle = ((tempToothCurrentCount - 1) * triggerToothAngle) + configPage2.triggerAngle; //Number of teeth that have passed since tooth 1, multiplied by the angle each tooth represents, plus the angle that tooth 1 is ATDC. This gives accuracy only to the nearest tooth.
|
||||
int crankAngle = ((tempToothCurrentCount - 1) * triggerToothAngle) + configPage4.triggerAngle; //Number of teeth that have passed since tooth 1, multiplied by the angle each tooth represents, plus the angle that tooth 1 is ATDC. This gives accuracy only to the nearest tooth.
|
||||
//Estimate the number of degrees travelled since the last tooth}
|
||||
long elapsedTime = micros() - tempToothLastToothTime;
|
||||
if(elapsedTime < SHRT_MAX ) { crankAngle += div((int)elapsedTime, timePerDegree).quot; } //This option is much faster, but only available for smaller values of elapsedTime
|
||||
|
@ -434,24 +433,24 @@ int getCrankAngle_DualWheel(int timePerDegree)
|
|||
|
||||
void triggerSetEndTeeth_DualWheel()
|
||||
{
|
||||
ignition1EndTooth = ( (ignition1EndAngle - configPage2.triggerAngle) / triggerToothAngle ) - 1;
|
||||
if(ignition1EndTooth > configPage2.triggerTeeth) { ignition1EndTooth -= configPage2.triggerTeeth; }
|
||||
if(ignition1EndTooth <= 0) { ignition1EndTooth -= configPage2.triggerTeeth; }
|
||||
ignition1EndTooth = ( (ignition1EndAngle - configPage4.triggerAngle) / triggerToothAngle ) - 1;
|
||||
if(ignition1EndTooth > configPage4.triggerTeeth) { ignition1EndTooth -= configPage4.triggerTeeth; }
|
||||
if(ignition1EndTooth <= 0) { ignition1EndTooth -= configPage4.triggerTeeth; }
|
||||
if(ignition1EndTooth > triggerActualTeeth) { ignition1EndTooth = triggerActualTeeth; }
|
||||
|
||||
ignition2EndTooth = ( (ignition2EndAngle - configPage2.triggerAngle) / triggerToothAngle ) - 1;
|
||||
if(ignition2EndTooth > configPage2.triggerTeeth) { ignition2EndTooth -= configPage2.triggerTeeth; }
|
||||
if(ignition2EndTooth <= 0) { ignition2EndTooth -= configPage2.triggerTeeth; }
|
||||
ignition2EndTooth = ( (ignition2EndAngle - configPage4.triggerAngle) / triggerToothAngle ) - 1;
|
||||
if(ignition2EndTooth > configPage4.triggerTeeth) { ignition2EndTooth -= configPage4.triggerTeeth; }
|
||||
if(ignition2EndTooth <= 0) { ignition2EndTooth -= configPage4.triggerTeeth; }
|
||||
if(ignition2EndTooth > triggerActualTeeth) { ignition2EndTooth = triggerActualTeeth; }
|
||||
|
||||
ignition3EndTooth = ( (ignition3EndAngle - configPage2.triggerAngle) / triggerToothAngle ) - 1;
|
||||
if(ignition3EndTooth > configPage2.triggerTeeth) { ignition3EndTooth -= configPage2.triggerTeeth; }
|
||||
if(ignition3EndTooth <= 0) { ignition3EndTooth -= configPage2.triggerTeeth; }
|
||||
ignition3EndTooth = ( (ignition3EndAngle - configPage4.triggerAngle) / triggerToothAngle ) - 1;
|
||||
if(ignition3EndTooth > configPage4.triggerTeeth) { ignition3EndTooth -= configPage4.triggerTeeth; }
|
||||
if(ignition3EndTooth <= 0) { ignition3EndTooth -= configPage4.triggerTeeth; }
|
||||
if(ignition3EndTooth > triggerActualTeeth) { ignition3EndTooth = triggerActualTeeth; }
|
||||
|
||||
ignition4EndTooth = ( (ignition4EndAngle - configPage2.triggerAngle) / triggerToothAngle ) - 1;
|
||||
if(ignition4EndTooth > configPage2.triggerTeeth) { ignition4EndTooth -= configPage2.triggerTeeth; }
|
||||
if(ignition4EndTooth <= 0) { ignition4EndTooth -= configPage2.triggerTeeth; }
|
||||
ignition4EndTooth = ( (ignition4EndAngle - configPage4.triggerAngle) / triggerToothAngle ) - 1;
|
||||
if(ignition4EndTooth > configPage4.triggerTeeth) { ignition4EndTooth -= configPage4.triggerTeeth; }
|
||||
if(ignition4EndTooth <= 0) { ignition4EndTooth -= configPage4.triggerTeeth; }
|
||||
if(ignition4EndTooth > triggerActualTeeth) { ignition4EndTooth = triggerActualTeeth; }
|
||||
}
|
||||
|
||||
|
@ -463,10 +462,10 @@ Note: This is a very simple decoder. See http://www.megamanual.com/ms2/GM_7pinHE
|
|||
*/
|
||||
void triggerSetup_BasicDistributor()
|
||||
{
|
||||
triggerActualTeeth = configPage1.nCylinders;
|
||||
triggerActualTeeth = configPage2.nCylinders;
|
||||
if(triggerActualTeeth == 0) { triggerActualTeeth = 1; }
|
||||
triggerToothAngle = 720 / triggerActualTeeth; //The number of degrees that passes from tooth to tooth
|
||||
triggerFilterTime = 60000000L / MAX_RPM / configPage1.nCylinders; // Minimum time required between teeth
|
||||
triggerFilterTime = 60000000L / MAX_RPM / configPage2.nCylinders; // Minimum time required between teeth
|
||||
triggerFilterTime = triggerFilterTime / 2; //Safety margin
|
||||
triggerFilterTime = 0;
|
||||
secondDerivEnabled = false;
|
||||
|
@ -474,7 +473,7 @@ void triggerSetup_BasicDistributor()
|
|||
toothCurrentCount = 0; //Default value
|
||||
decoderHasFixedCrankingTiming = true;
|
||||
triggerToothAngleIsCorrect = true;
|
||||
if(configPage1.nCylinders <= 4) { MAX_STALL_TIME = (1851UL * triggerToothAngle); }//Minimum 90rpm. (1851uS is the time per degree at 90rpm). This uses 90rpm rather than 50rpm due to the potentially very high stall time on a 4 cylinder if we wait that long.
|
||||
if(configPage2.nCylinders <= 4) { MAX_STALL_TIME = (1851UL * triggerToothAngle); }//Minimum 90rpm. (1851uS is the time per degree at 90rpm). This uses 90rpm rather than 50rpm due to the potentially very high stall time on a 4 cylinder if we wait that long.
|
||||
else { MAX_STALL_TIME = (3200UL * triggerToothAngle); } //Minimum 50rpm. (3200uS is the time per degree at 50rpm).
|
||||
|
||||
}
|
||||
|
@ -501,7 +500,7 @@ void triggerPri_BasicDistributor()
|
|||
setFilter(curGap); //Recalc the new filter value
|
||||
addToothLogEntry(curGap);
|
||||
|
||||
if ( configPage2.ignCranklock && BIT_CHECK(currentStatus.engine, BIT_ENGINE_CRANK) )
|
||||
if ( configPage4.ignCranklock && BIT_CHECK(currentStatus.engine, BIT_ENGINE_CRANK) )
|
||||
{
|
||||
endCoil1Charge();
|
||||
endCoil2Charge();
|
||||
|
@ -509,9 +508,9 @@ void triggerPri_BasicDistributor()
|
|||
endCoil4Charge();
|
||||
}
|
||||
|
||||
if(configPage1.perToothIgn == true)
|
||||
if(configPage2.perToothIgn == true)
|
||||
{
|
||||
uint16_t crankAngle = ( (toothCurrentCount-1) * triggerToothAngle ) + configPage2.triggerAngle;
|
||||
uint16_t crankAngle = ( (toothCurrentCount-1) * triggerToothAngle ) + configPage4.triggerAngle;
|
||||
if ( (toothCurrentCount == ignition1EndTooth) && (ignitionSchedule1.Status == RUNNING) )
|
||||
{
|
||||
IGN1_COMPARE = IGN1_COUNTER + uS_TO_TIMER_COMPARE( (ignition1EndAngle - crankAngle) * timePerDegree );
|
||||
|
@ -554,7 +553,7 @@ int getCrankAngle_BasicDistributor(int timePerDegree)
|
|||
tempToothLastToothTime = toothLastToothTime;
|
||||
interrupts();
|
||||
|
||||
int crankAngle = ((tempToothCurrentCount - 1) * triggerToothAngle) + configPage2.triggerAngle; //Number of teeth that have passed since tooth 1, multiplied by the angle each tooth represents, plus the angle that tooth 1 is ATDC. This gives accuracy only to the nearest tooth.
|
||||
int crankAngle = ((tempToothCurrentCount - 1) * triggerToothAngle) + configPage4.triggerAngle; //Number of teeth that have passed since tooth 1, multiplied by the angle each tooth represents, plus the angle that tooth 1 is ATDC. This gives accuracy only to the nearest tooth.
|
||||
//Estimate the number of degrees travelled since the last tooth}
|
||||
long elapsedTime = micros() - tempToothLastToothTime;
|
||||
if(elapsedTime < SHRT_MAX ) { crankAngle += div((int)elapsedTime, timePerDegree).quot; } //This option is much faster, but only available for smaller values of elapsedTime
|
||||
|
@ -569,9 +568,9 @@ int getCrankAngle_BasicDistributor(int timePerDegree)
|
|||
|
||||
void triggerSetEndTeeth_BasicDistributor()
|
||||
{
|
||||
ignition1EndTooth = ( (ignition1EndAngle - configPage2.triggerAngle) / triggerToothAngle ) - 1;
|
||||
if(ignition1EndTooth > configPage2.triggerTeeth) { ignition1EndTooth -= configPage2.triggerTeeth; }
|
||||
if(ignition1EndTooth <= 0) { ignition1EndTooth -= configPage2.triggerTeeth; }
|
||||
ignition1EndTooth = ( (ignition1EndAngle - configPage4.triggerAngle) / triggerToothAngle ) - 1;
|
||||
if(ignition1EndTooth > configPage4.triggerTeeth) { ignition1EndTooth -= configPage4.triggerTeeth; }
|
||||
if(ignition1EndTooth <= 0) { ignition1EndTooth -= configPage4.triggerTeeth; }
|
||||
if(ignition1EndTooth > triggerActualTeeth) { ignition1EndTooth = triggerActualTeeth; }
|
||||
}
|
||||
|
||||
|
@ -692,7 +691,7 @@ void triggerSetup_4G63()
|
|||
//decoderIsLowRes = true;
|
||||
|
||||
//Note that these angles are for every rising and falling edge
|
||||
if(configPage1.nCylinders == 6)
|
||||
if(configPage2.nCylinders == 6)
|
||||
{
|
||||
// 70 / 50 for 6 cylinder applications
|
||||
toothAngles[0] = 185; //
|
||||
|
@ -766,15 +765,15 @@ void triggerPri_4G63()
|
|||
|
||||
if (currentStatus.hasSync == true)
|
||||
{
|
||||
if ( BIT_CHECK(currentStatus.engine, BIT_ENGINE_CRANK) && configPage2.ignCranklock && (currentStatus.startRevolutions >= configPage2.StgCycles))
|
||||
if ( BIT_CHECK(currentStatus.engine, BIT_ENGINE_CRANK) && configPage4.ignCranklock && (currentStatus.startRevolutions >= configPage4.StgCycles))
|
||||
{
|
||||
if(configPage1.nCylinders == 4)
|
||||
if(configPage2.nCylinders == 4)
|
||||
{
|
||||
//This operates in forced wasted spark mode during cranking to align with crank teeth
|
||||
if( (toothCurrentCount == 1) || (toothCurrentCount == 5) ) { endCoil1Charge(); endCoil3Charge(); }
|
||||
else if( (toothCurrentCount == 3) || (toothCurrentCount == 7) ) { endCoil2Charge(); endCoil4Charge(); }
|
||||
}
|
||||
else if(configPage1.nCylinders == 6)
|
||||
else if(configPage2.nCylinders == 6)
|
||||
{
|
||||
if( toothCurrentCount == 1 ) { endCoil1Charge(); }
|
||||
else if( toothCurrentCount == 3 ) { endCoil2Charge(); }
|
||||
|
@ -783,14 +782,14 @@ void triggerPri_4G63()
|
|||
}
|
||||
|
||||
//Whilst this is an uneven tooth pattern, if the specific angle between the last 2 teeth is specified, 1st deriv prediction can be used
|
||||
if( (configPage2.triggerFilter == 1) || (currentStatus.RPM < 1400) )
|
||||
if( (configPage4.triggerFilter == 1) || (currentStatus.RPM < 1400) )
|
||||
{
|
||||
//Lite filter
|
||||
if( (toothCurrentCount == 1) || (toothCurrentCount == 3) || (toothCurrentCount == 5) || (toothCurrentCount == 7) )
|
||||
{
|
||||
triggerToothAngle = 70;
|
||||
triggerFilterTime = curGap; //Trigger filter is set to whatever time it took to do 70 degrees (Next trigger is 110 degrees away)
|
||||
if(configPage1.nCylinders == 6)
|
||||
if(configPage2.nCylinders == 6)
|
||||
{
|
||||
triggerFilterTime = (curGap >> 2); //Trigger filter is set to (70/4)=17.5=17 degrees (Next trigger is 50 degrees away).
|
||||
}
|
||||
|
@ -799,20 +798,20 @@ void triggerPri_4G63()
|
|||
{
|
||||
triggerToothAngle = 110;
|
||||
triggerFilterTime = (curGap * 3) >> 3; //Trigger filter is set to (110*3)/8=41.25=41 degrees (Next trigger is 70 degrees away).
|
||||
if(configPage1.nCylinders == 6)
|
||||
if(configPage2.nCylinders == 6)
|
||||
{
|
||||
triggerToothAngle = 50;
|
||||
triggerFilterTime = (curGap * 3) >> 2; //Trigger filter is set to (50*3)/4=37.5=37 degrees (Next trigger is 70 degrees away).
|
||||
}
|
||||
}
|
||||
}
|
||||
else if(configPage2.triggerFilter == 2)
|
||||
else if(configPage4.triggerFilter == 2)
|
||||
{
|
||||
//Medium filter level
|
||||
if( (toothCurrentCount == 1) || (toothCurrentCount == 3) || (toothCurrentCount == 5) || (toothCurrentCount == 7) ) { triggerToothAngle = 70; triggerFilterTime = (curGap * 5) >> 2 ; } //87.5 degrees with a target of 110
|
||||
else { triggerToothAngle = 110; triggerFilterTime = (curGap >> 1); } //55 degrees with a target of 70
|
||||
}
|
||||
else if (configPage2.triggerFilter == 3)
|
||||
else if (configPage4.triggerFilter == 3)
|
||||
{
|
||||
//Aggressive filter level
|
||||
if( (toothCurrentCount == 1) || (toothCurrentCount == 3) || (toothCurrentCount == 5) || (toothCurrentCount == 7) ) { triggerToothAngle = 70; triggerFilterTime = (curGap * 11) >> 3 ; } //96.26 degrees with a target of 110
|
||||
|
@ -827,7 +826,7 @@ void triggerPri_4G63()
|
|||
}
|
||||
|
||||
//EXPERIMENTAL!
|
||||
if(configPage1.perToothIgn == true)
|
||||
if(configPage2.perToothIgn == true)
|
||||
{
|
||||
uint16_t crankAngle = toothAngles[(toothCurrentCount-1)];
|
||||
doPerToothTiming(crankAngle);
|
||||
|
@ -895,7 +894,7 @@ void triggerSec_4G63()
|
|||
}
|
||||
|
||||
//if ( (micros() - secondaryLastToothTime1) < triggerSecFilterTime_duration && configPage2.useResync )
|
||||
if ( (configPage2.useResync == 1) && (currentStatus.hasSync == true) )
|
||||
if ( (configPage4.useResync == 1) && (currentStatus.hasSync == true) )
|
||||
{
|
||||
triggerSecFilterTime_duration = (micros() - secondaryLastToothTime1) >> 1;
|
||||
if(READ_PRI_TRIGGER() == true)// && (crankState == digitalRead(pinTrigger)))
|
||||
|
@ -921,7 +920,7 @@ uint16_t getRPM_4G63()
|
|||
//Because these signals aren't even (Alternating 110 and 70 degrees), this needs a special function
|
||||
if(currentStatus.hasSync == true)
|
||||
{
|
||||
if( (currentStatus.RPM < currentStatus.crankRPM) || (configPage1.perToothIgn == true) )
|
||||
if( (currentStatus.RPM < currentStatus.crankRPM) || (configPage2.perToothIgn == true) )
|
||||
{
|
||||
int tempToothAngle;
|
||||
unsigned long toothTime;
|
||||
|
@ -966,7 +965,7 @@ int getCrankAngle_4G63(int timePerDegree)
|
|||
tempToothLastMinusOneToothTime = toothLastMinusOneToothTime;
|
||||
interrupts();
|
||||
|
||||
crankAngle = toothAngles[(tempToothCurrentCount - 1)] + configPage2.triggerAngle; //Perform a lookup of the fixed toothAngles array to find what the angle of the last tooth passed was.
|
||||
crankAngle = toothAngles[(tempToothCurrentCount - 1)] + configPage4.triggerAngle; //Perform a lookup of the fixed toothAngles array to find what the angle of the last tooth passed was.
|
||||
//Estimate the number of degrees travelled since the last tooth}
|
||||
|
||||
unsigned long elapsedTime = micros() - tempToothLastToothTime;
|
||||
|
@ -984,10 +983,10 @@ int getCrankAngle_4G63(int timePerDegree)
|
|||
|
||||
void triggerSetEndTeeth_4G63()
|
||||
{
|
||||
if((ignition1EndAngle - configPage2.triggerAngle) > 355) { ignition1EndTooth = 1; }
|
||||
if((ignition1EndAngle - configPage4.triggerAngle) > 355) { ignition1EndTooth = 1; }
|
||||
else { ignition1EndTooth = 4; }
|
||||
//ignition1EndTooth = 1;
|
||||
//ignition1EndTooth = ( (ignition1EndAngle - configPage2.triggerAngle) /
|
||||
//ignition1EndTooth = ( (ignition1EndAngle - configPage4.triggerAngle) /
|
||||
}
|
||||
|
||||
/* -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||
|
@ -1080,8 +1079,8 @@ int getCrankAngle_24X(int timePerDegree)
|
|||
interrupts();
|
||||
|
||||
int crankAngle;
|
||||
if (toothCurrentCount == 0) { crankAngle = 0 + configPage2.triggerAngle; } //This is the special case to handle when the 'last tooth' seen was the cam tooth. 0 is the angle at which the crank tooth goes high (Within 360 degrees).
|
||||
else { crankAngle = toothAngles[(tempToothCurrentCount - 1)] + configPage2.triggerAngle;} //Perform a lookup of the fixed toothAngles array to find what the angle of the last tooth passed was.
|
||||
if (toothCurrentCount == 0) { crankAngle = 0 + configPage4.triggerAngle; } //This is the special case to handle when the 'last tooth' seen was the cam tooth. 0 is the angle at which the crank tooth goes high (Within 360 degrees).
|
||||
else { crankAngle = toothAngles[(tempToothCurrentCount - 1)] + configPage4.triggerAngle;} //Perform a lookup of the fixed toothAngles array to find what the angle of the last tooth passed was.
|
||||
|
||||
//Estimate the number of degrees travelled since the last tooth}
|
||||
long elapsedTime = micros() - tempToothLastToothTime;
|
||||
|
@ -1182,8 +1181,8 @@ int getCrankAngle_Jeep2000(int timePerDegree)
|
|||
interrupts();
|
||||
|
||||
int crankAngle;
|
||||
if (toothCurrentCount == 0) { crankAngle = 146 + configPage2.triggerAngle; } //This is the special case to handle when the 'last tooth' seen was the cam tooth. 146 is the angle at which the crank tooth goes high.
|
||||
else { crankAngle = toothAngles[(tempToothCurrentCount - 1)] + configPage2.triggerAngle;} //Perform a lookup of the fixed toothAngles array to find what the angle of the last tooth passed was.
|
||||
if (toothCurrentCount == 0) { crankAngle = 146 + configPage4.triggerAngle; } //This is the special case to handle when the 'last tooth' seen was the cam tooth. 146 is the angle at which the crank tooth goes high.
|
||||
else { crankAngle = toothAngles[(tempToothCurrentCount - 1)] + configPage4.triggerAngle;} //Perform a lookup of the fixed toothAngles array to find what the angle of the last tooth passed was.
|
||||
//Estimate the number of degrees travelled since the last tooth}
|
||||
long elapsedTime = micros() - tempToothLastToothTime;
|
||||
if(elapsedTime < SHRT_MAX ) { crankAngle += div((int)elapsedTime, timePerDegree).quot; } //This option is much faster, but only available for smaller values of elapsedTime
|
||||
|
@ -1272,7 +1271,7 @@ void triggerSec_Audi135()
|
|||
currentStatus.hasSync = true;
|
||||
toothSystemCount = 3; //Need to set this to 3 so that the next primary tooth is counted
|
||||
}
|
||||
else if (configPage2.useResync == 1) { toothCurrentCount = 0; toothSystemCount = 3; }
|
||||
else if (configPage4.useResync == 1) { toothCurrentCount = 0; toothSystemCount = 3; }
|
||||
else if ( (currentStatus.startRevolutions < 100) && (toothCurrentCount != 45) ) { toothCurrentCount = 0; }
|
||||
revolutionOne = 1; //Sequential revolution reset
|
||||
}
|
||||
|
@ -1298,7 +1297,7 @@ int getCrankAngle_Audi135(int timePerDegree)
|
|||
//Handle case where the secondary tooth was the last one seen
|
||||
if(tempToothCurrentCount == 0) { tempToothCurrentCount = 45; }
|
||||
|
||||
int crankAngle = ((tempToothCurrentCount - 1) * triggerToothAngle) + configPage2.triggerAngle; //Number of teeth that have passed since tooth 1, multiplied by the angle each tooth represents, plus the angle that tooth 1 is ATDC. This gives accuracy only to the nearest tooth.
|
||||
int crankAngle = ((tempToothCurrentCount - 1) * triggerToothAngle) + configPage4.triggerAngle; //Number of teeth that have passed since tooth 1, multiplied by the angle each tooth represents, plus the angle that tooth 1 is ATDC. This gives accuracy only to the nearest tooth.
|
||||
//Estimate the number of degrees travelled since the last tooth}
|
||||
long elapsedTime = micros() - tempToothLastToothTime;
|
||||
if(elapsedTime < SHRT_MAX ) { crankAngle += div((int)elapsedTime, timePerDegree).quot; } //This option is much faster, but only available for smaller values of elapsedTime
|
||||
|
@ -1393,11 +1392,11 @@ int getCrankAngle_HondaD17(int timePerDegree)
|
|||
int crankAngle;
|
||||
if( tempToothCurrentCount == 0 )
|
||||
{
|
||||
crankAngle = (11 * triggerToothAngle) + configPage2.triggerAngle; //if temptoothCurrentCount is 0, the last tooth seen was the 13th one. Based on this, ignore the 13th tooth and use the 12th one as the last reference.
|
||||
crankAngle = (11 * triggerToothAngle) + configPage4.triggerAngle; //if temptoothCurrentCount is 0, the last tooth seen was the 13th one. Based on this, ignore the 13th tooth and use the 12th one as the last reference.
|
||||
}
|
||||
else
|
||||
{
|
||||
crankAngle = ((tempToothCurrentCount - 1) * triggerToothAngle) + configPage2.triggerAngle; //Number of teeth that have passed since tooth 1, multiplied by the angle each tooth represents, plus the angle that tooth 1 is ATDC. This gives accuracy only to the nearest tooth.
|
||||
crankAngle = ((tempToothCurrentCount - 1) * triggerToothAngle) + configPage4.triggerAngle; //Number of teeth that have passed since tooth 1, multiplied by the angle each tooth represents, plus the angle that tooth 1 is ATDC. This gives accuracy only to the nearest tooth.
|
||||
}
|
||||
|
||||
//Estimate the number of degrees travelled since the last tooth}
|
||||
|
@ -1478,7 +1477,7 @@ void triggerPri_Miata9905()
|
|||
}
|
||||
else
|
||||
{
|
||||
if( (currentStatus.hasSync == false) || (configPage2.useResync == true) )
|
||||
if( (currentStatus.hasSync == false) || (configPage4.useResync == true) )
|
||||
{
|
||||
if(secondaryToothCount == 2)
|
||||
{
|
||||
|
@ -1493,25 +1492,25 @@ void triggerPri_Miata9905()
|
|||
addToothLogEntry(curGap);
|
||||
|
||||
//Whilst this is an uneven tooth pattern, if the specific angle between the last 2 teeth is specified, 1st deriv prediction can be used
|
||||
if( (configPage2.triggerFilter == 1) )
|
||||
if( (configPage4.triggerFilter == 1) )
|
||||
{
|
||||
//Lite filter
|
||||
if( (toothCurrentCount == 1) || (toothCurrentCount == 3) || (toothCurrentCount == 5) || (toothCurrentCount == 7) ) { triggerToothAngle = 70; triggerFilterTime = curGap; } //Trigger filter is set to whatever time it took to do 70 degrees (Next trigger is 110 degrees away)
|
||||
else { triggerToothAngle = 110; triggerFilterTime = (curGap * 3) >> 3; } //Trigger filter is set to (110*3)/8=41.25=41 degrees (Next trigger is 70 degrees away).
|
||||
}
|
||||
else if(configPage2.triggerFilter == 2)
|
||||
else if(configPage4.triggerFilter == 2)
|
||||
{
|
||||
//Medium filter level
|
||||
if( (toothCurrentCount == 1) || (toothCurrentCount == 3) || (toothCurrentCount == 5) || (toothCurrentCount == 7) ) { triggerToothAngle = 70; triggerFilterTime = (curGap * 5) >> 2 ; } //87.5 degrees with a target of 110
|
||||
else { triggerToothAngle = 110; triggerFilterTime = (curGap >> 1); } //55 degrees with a target of 70
|
||||
}
|
||||
else if (configPage2.triggerFilter == 3)
|
||||
else if (configPage4.triggerFilter == 3)
|
||||
{
|
||||
//Aggressive filter level
|
||||
if( (toothCurrentCount == 1) || (toothCurrentCount == 3) || (toothCurrentCount == 5) || (toothCurrentCount == 7) ) { triggerToothAngle = 70; triggerFilterTime = (curGap * 11) >> 3 ; } //96.26 degrees with a target of 110
|
||||
else { triggerToothAngle = 110; triggerFilterTime = (curGap * 9) >> 5; } //61.87 degrees with a target of 70
|
||||
}
|
||||
else if (configPage2.triggerFilter == 0)
|
||||
else if (configPage4.triggerFilter == 0)
|
||||
{
|
||||
//trigger filter is turned off.
|
||||
triggerFilterTime = 0;
|
||||
|
@ -1525,7 +1524,7 @@ void triggerPri_Miata9905()
|
|||
toothLastMinusOneToothTime = toothLastToothTime;
|
||||
toothLastToothTime = curTime;
|
||||
|
||||
if ( BIT_CHECK(currentStatus.engine, BIT_ENGINE_CRANK) && configPage2.ignCranklock)
|
||||
if ( BIT_CHECK(currentStatus.engine, BIT_ENGINE_CRANK) && configPage4.ignCranklock)
|
||||
{
|
||||
//This operates in waasted spark mode during cranking to align with crank teeth
|
||||
if( (toothCurrentCount == 1) || (toothCurrentCount == 5) ) { endCoil1Charge(); endCoil3Charge(); }
|
||||
|
@ -1602,7 +1601,7 @@ int getCrankAngle_Miata9905(int timePerDegree)
|
|||
tempToothLastToothTime = toothLastToothTime;
|
||||
interrupts();
|
||||
|
||||
crankAngle = toothAngles[(tempToothCurrentCount - 1)] + configPage2.triggerAngle; //Perform a lookup of the fixed toothAngles array to find what the angle of the last tooth passed was.
|
||||
crankAngle = toothAngles[(tempToothCurrentCount - 1)] + configPage4.triggerAngle; //Perform a lookup of the fixed toothAngles array to find what the angle of the last tooth passed was.
|
||||
//Estimate the number of degrees travelled since the last tooth}
|
||||
|
||||
unsigned long elapsedTime = micros() - tempToothLastToothTime;
|
||||
|
@ -1668,7 +1667,7 @@ void triggerPri_MazdaAU()
|
|||
if (currentStatus.hasSync == true)
|
||||
{
|
||||
// Locked cranking timing is available, fixed at 12* BTDC
|
||||
if ( BIT_CHECK(currentStatus.engine, BIT_ENGINE_CRANK) && configPage2.ignCranklock )
|
||||
if ( BIT_CHECK(currentStatus.engine, BIT_ENGINE_CRANK) && configPage4.ignCranklock )
|
||||
{
|
||||
if( toothCurrentCount == 1 ) { endCoil1Charge(); }
|
||||
else if( toothCurrentCount == 3 ) { endCoil2Charge(); }
|
||||
|
@ -1755,7 +1754,7 @@ int getCrankAngle_MazdaAU(int timePerDegree)
|
|||
tempToothLastToothTime = toothLastToothTime;
|
||||
interrupts();
|
||||
|
||||
crankAngle = toothAngles[(tempToothCurrentCount - 1)] + configPage2.triggerAngle; //Perform a lookup of the fixed toothAngles array to find what the angle of the last tooth passed was.
|
||||
crankAngle = toothAngles[(tempToothCurrentCount - 1)] + configPage4.triggerAngle; //Perform a lookup of the fixed toothAngles array to find what the angle of the last tooth passed was.
|
||||
//Estimate the number of degrees travelled since the last tooth}
|
||||
|
||||
long elapsedTime = micros() - tempToothLastToothTime;
|
||||
|
@ -1782,9 +1781,9 @@ Note: There can be no missing teeth on the primary wheel
|
|||
*/
|
||||
void triggerSetup_non360()
|
||||
{
|
||||
triggerToothAngle = (360 * configPage2.TrigAngMul) / configPage2.triggerTeeth; //The number of degrees that passes from tooth to tooth multiplied by the additional multiplier
|
||||
triggerToothAngle = (360 * configPage4.TrigAngMul) / configPage4.triggerTeeth; //The number of degrees that passes from tooth to tooth multiplied by the additional multiplier
|
||||
toothCurrentCount = 255; //Default value
|
||||
triggerFilterTime = (int)(1000000 / (MAX_RPM / 60 * configPage2.triggerTeeth)); //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
|
||||
triggerFilterTime = (int)(1000000 / (MAX_RPM / 60 * configPage4.triggerTeeth)); //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
|
||||
triggerSecFilterTime = (int)(1000000 / (MAX_RPM / 60 * 2)) / 2; //Same as above, but fixed at 2 teeth on the secondary input and divided by 2 (for cam speed)
|
||||
secondDerivEnabled = false;
|
||||
decoderIsSequential = true;
|
||||
|
@ -1807,7 +1806,7 @@ uint16_t getRPM_non360()
|
|||
uint16_t tempRPM = 0;
|
||||
if( (currentStatus.hasSync == true) && (toothCurrentCount != 0) )
|
||||
{
|
||||
if(currentStatus.RPM < currentStatus.crankRPM) { tempRPM = crankingGetRPM(configPage2.triggerTeeth); }
|
||||
if(currentStatus.RPM < currentStatus.crankRPM) { tempRPM = crankingGetRPM(configPage4.triggerTeeth); }
|
||||
else { tempRPM = stdGetRPM(); }
|
||||
}
|
||||
return tempRPM;
|
||||
|
@ -1825,11 +1824,11 @@ int getCrankAngle_non360(int timePerDegree)
|
|||
interrupts();
|
||||
|
||||
//Handle case where the secondary tooth was the last one seen
|
||||
if(tempToothCurrentCount == 0) { tempToothCurrentCount = configPage2.triggerTeeth; }
|
||||
if(tempToothCurrentCount == 0) { tempToothCurrentCount = configPage4.triggerTeeth; }
|
||||
|
||||
//Number of teeth that have passed since tooth 1, multiplied by the angle each tooth represents, plus the angle that tooth 1 is ATDC. This gives accuracy only to the nearest tooth.
|
||||
int crankAngle = (tempToothCurrentCount - 1) * triggerToothAngle;
|
||||
crankAngle = (crankAngle / configPage2.TrigAngMul) + configPage2.triggerAngle; //Have to divide by the multiplier to get back to actual crank angle.
|
||||
crankAngle = (crankAngle / configPage4.TrigAngMul) + configPage4.triggerAngle; //Have to divide by the multiplier to get back to actual crank angle.
|
||||
|
||||
//Estimate the number of degrees travelled since the last tooth}
|
||||
long elapsedTime = micros() - tempToothLastToothTime;
|
||||
|
@ -1890,9 +1889,9 @@ void triggerPri_Nissan360()
|
|||
//setFilter(curGap);
|
||||
|
||||
//EXPERIMENTAL!
|
||||
if(configPage1.perToothIgn == true)
|
||||
if(configPage2.perToothIgn == true)
|
||||
{
|
||||
int16_t crankAngle = ( (toothCurrentCount-1) * 2 ) + configPage2.triggerAngle;
|
||||
int16_t crankAngle = ( (toothCurrentCount-1) * 2 ) + configPage4.triggerAngle;
|
||||
//if(crankAngle > CRANK_ANGLE_MAX_IGN) { crankAngle -= CRANK_ANGLE_MAX_IGN; }
|
||||
//if(crankAngle < CRANK_ANGLE_MAX_IGN) {
|
||||
doPerToothTiming(crankAngle);
|
||||
|
@ -1914,7 +1913,7 @@ void triggerSec_Nissan360()
|
|||
|
||||
//Calculate number of primary teeth that this window has been active for
|
||||
byte trigEdge;
|
||||
if(configPage2.TrigEdgeSec == 0) { trigEdge = LOW; }
|
||||
if(configPage4.TrigEdgeSec == 0) { trigEdge = LOW; }
|
||||
else { trigEdge = HIGH; }
|
||||
|
||||
if( (secondaryToothCount == 0) || (READ_SEC_TRIGGER() == trigEdge) ) { secondaryToothCount = toothCurrentCount; } //This occurs on the first rotation upon powerup OR the start of a secondary window
|
||||
|
@ -1925,7 +1924,7 @@ void triggerSec_Nissan360()
|
|||
|
||||
if(currentStatus.hasSync == false)
|
||||
{
|
||||
if(configPage1.nCylinders == 4)
|
||||
if(configPage2.nCylinders == 4)
|
||||
{
|
||||
if( (secondaryDuration >= 15) && (secondaryDuration <= 17) ) //Duration of window = 16 primary teeth
|
||||
{
|
||||
|
@ -1949,7 +1948,7 @@ void triggerSec_Nissan360()
|
|||
}
|
||||
else { currentStatus.hasSync = false; } //This should really never happen
|
||||
}
|
||||
else if(configPage1.nCylinders == 6)
|
||||
else if(configPage2.nCylinders == 6)
|
||||
{
|
||||
//Pattern on the 6 cylinders is 4-8-12-16-12-8
|
||||
//We can therefore only get sync on the 4 and 16 pulses as they are the only unique ones
|
||||
|
@ -1968,17 +1967,17 @@ void triggerSec_Nissan360()
|
|||
}
|
||||
else
|
||||
{
|
||||
if (configPage2.useResync == true)
|
||||
if (configPage4.useResync == true)
|
||||
{
|
||||
//Already have sync, but do a verify every 720 degrees.
|
||||
if(configPage1.nCylinders == 4)
|
||||
if(configPage2.nCylinders == 4)
|
||||
{
|
||||
if( (secondaryDuration >= 15) && (secondaryDuration <= 17) ) //Duration of window = 16 primary teeth
|
||||
{
|
||||
toothCurrentCount = 16; //End of first window (The longest) occurs 16 teeth after TDC
|
||||
}
|
||||
}
|
||||
else if(configPage1.nCylinders == 6)
|
||||
else if(configPage2.nCylinders == 6)
|
||||
{
|
||||
if(secondaryDuration == 4)
|
||||
{
|
||||
|
@ -2031,7 +2030,7 @@ int getCrankAngle_Nissan360(int timePerDegree)
|
|||
tempToothCurrentCount = toothCurrentCount;
|
||||
interrupts();
|
||||
|
||||
crankAngle = ( (tempToothCurrentCount - 1) * 2) + configPage2.triggerAngle;
|
||||
crankAngle = ( (tempToothCurrentCount - 1) * 2) + configPage4.triggerAngle;
|
||||
unsigned long halfTooth = (tempToothLastToothTime - tempToothLastMinusOneToothTime) >> 1;
|
||||
if ( (micros() - tempToothLastToothTime) > halfTooth)
|
||||
{
|
||||
|
@ -2049,10 +2048,10 @@ int getCrankAngle_Nissan360(int timePerDegree)
|
|||
void triggerSetEndTeeth_Nissan360()
|
||||
{
|
||||
//This uses 4 prior teeth, just to ensure there is sufficient time to set the schedule etc
|
||||
ignition1EndTooth = ( (ignition1EndAngle - configPage2.triggerAngle) / 2 ) - 4;
|
||||
ignition2EndTooth = ( (ignition2EndAngle - configPage2.triggerAngle) / 2 ) - 4;
|
||||
ignition3EndTooth = ( (ignition3EndAngle - configPage2.triggerAngle) / 2 ) - 4;
|
||||
ignition4EndTooth = ( (ignition4EndAngle - configPage2.triggerAngle) / 2 ) - 4;
|
||||
ignition1EndTooth = ( (ignition1EndAngle - configPage4.triggerAngle) / 2 ) - 4;
|
||||
ignition2EndTooth = ( (ignition2EndAngle - configPage4.triggerAngle) / 2 ) - 4;
|
||||
ignition3EndTooth = ( (ignition3EndAngle - configPage4.triggerAngle) / 2 ) - 4;
|
||||
ignition4EndTooth = ( (ignition4EndAngle - configPage4.triggerAngle) / 2 ) - 4;
|
||||
}
|
||||
|
||||
/* -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||
|
@ -2097,7 +2096,7 @@ void triggerPri_Subaru67()
|
|||
toothLastMinusOneToothTime = toothLastToothTime;
|
||||
toothLastToothTime = curTime;
|
||||
|
||||
if ( (currentStatus.hasSync == false) || configPage2.useResync || (currentStatus.startRevolutions == 0) )
|
||||
if ( (currentStatus.hasSync == false) || configPage4.useResync || (currentStatus.startRevolutions == 0) )
|
||||
{
|
||||
//Sync is determined by counting the number of cam teeth that have passed between the crank teeth
|
||||
switch(secondaryToothCount)
|
||||
|
@ -2136,7 +2135,7 @@ void triggerPri_Subaru67()
|
|||
if ( currentStatus.hasSync == true )
|
||||
{
|
||||
//Locked timing during cranking. This is fixed at 10* BTDC.
|
||||
if ( BIT_CHECK(currentStatus.engine, BIT_ENGINE_CRANK) && configPage2.ignCranklock)
|
||||
if ( BIT_CHECK(currentStatus.engine, BIT_ENGINE_CRANK) && configPage4.ignCranklock)
|
||||
{
|
||||
if( (toothCurrentCount == 1) || (toothCurrentCount == 7) ) { endCoil1Charge(); endCoil3Charge(); }
|
||||
else if( (toothCurrentCount == 4) || (toothCurrentCount == 10) ) { endCoil2Charge(); endCoil4Charge(); }
|
||||
|
@ -2153,7 +2152,7 @@ void triggerPri_Subaru67()
|
|||
|
||||
//Recalc the new filter value
|
||||
//setFilter(curGap);
|
||||
}
|
||||
}
|
||||
|
||||
void triggerSec_Subaru67()
|
||||
{
|
||||
|
@ -2168,7 +2167,7 @@ void triggerSec_Subaru67()
|
|||
|
||||
uint16_t getRPM_Subaru67()
|
||||
{
|
||||
//if(currentStatus.RPM < currentStatus.crankRPM) { return crankingGetRPM(configPage2.triggerTeeth); }
|
||||
//if(currentStatus.RPM < currentStatus.crankRPM) { return crankingGetRPM(configPage4.triggerTeeth); }
|
||||
|
||||
uint16_t tempRPM = 0;
|
||||
if(currentStatus.startRevolutions > 0)
|
||||
|
@ -2194,7 +2193,7 @@ int getCrankAngle_Subaru67(int timePerDegree)
|
|||
tempToothLastToothTime = toothLastToothTime;
|
||||
interrupts();
|
||||
|
||||
crankAngle = toothAngles[(tempToothCurrentCount - 1)] + configPage2.triggerAngle; //Perform a lookup of the fixed toothAngles array to find what the angle of the last tooth passed was.
|
||||
crankAngle = toothAngles[(tempToothCurrentCount - 1)] + configPage4.triggerAngle; //Perform a lookup of the fixed toothAngles array to find what the angle of the last tooth passed was.
|
||||
//Estimate the number of degrees travelled since the last tooth}
|
||||
|
||||
unsigned long elapsedTime = micros() - tempToothLastToothTime;
|
||||
|
@ -2221,16 +2220,16 @@ Note: This is a very simple decoder. See http://www.megamanual.com/ms2/GM_7pinHE
|
|||
*/
|
||||
void triggerSetup_Daihatsu()
|
||||
{
|
||||
triggerActualTeeth = configPage1.nCylinders + 1;
|
||||
triggerActualTeeth = configPage2.nCylinders + 1;
|
||||
triggerToothAngle = 720 / triggerActualTeeth; //The number of degrees that passes from tooth to tooth
|
||||
triggerFilterTime = 60000000L / MAX_RPM / configPage1.nCylinders; // Minimum time required between teeth
|
||||
triggerFilterTime = 60000000L / MAX_RPM / configPage2.nCylinders; // Minimum time required between teeth
|
||||
triggerFilterTime = triggerFilterTime / 2; //Safety margin
|
||||
secondDerivEnabled = false;
|
||||
decoderIsSequential = false;
|
||||
|
||||
MAX_STALL_TIME = (1851UL * triggerToothAngle)*4;//Minimum 90rpm. (1851uS is the time per degree at 90rpm). This uses 90rpm rather than 50rpm due to the potentially very high stall time on a 4 cylinder if we wait that long.
|
||||
|
||||
if(configPage1.nCylinders == 3)
|
||||
if(configPage2.nCylinders == 3)
|
||||
{
|
||||
toothAngles[0] = 0; //tooth #1
|
||||
toothAngles[1] = 30; //tooth #2 (Extra tooth)
|
||||
|
@ -2278,7 +2277,7 @@ void triggerPri_Daihatsu()
|
|||
|
||||
//addToothLogEntry(curGap);
|
||||
|
||||
if ( configPage2.ignCranklock && BIT_CHECK(currentStatus.engine, BIT_ENGINE_CRANK) )
|
||||
if ( configPage4.ignCranklock && BIT_CHECK(currentStatus.engine, BIT_ENGINE_CRANK) )
|
||||
{
|
||||
//This locks the cranking timing to 0 degrees BTDC (All the triggers allow for)
|
||||
if(toothCurrentCount == 1) { endCoil1Charge(); }
|
||||
|
@ -2295,7 +2294,7 @@ void triggerPri_Daihatsu()
|
|||
unsigned long targetTime;
|
||||
//We need to try and find the extra tooth (#2) which is located 30 degrees after tooth #1
|
||||
//Aim for tooth times less than about 60 degrees
|
||||
if(configPage1.nCylinders == 3)
|
||||
if(configPage2.nCylinders == 3)
|
||||
{
|
||||
targetTime = (toothLastToothTime - toothLastMinusOneToothTime) >> 2; //Teeth are 240 degrees apart for 3 cylinder. 240/3 = 60
|
||||
}
|
||||
|
@ -2358,7 +2357,7 @@ int getCrankAngle_Daihatsu(int timePerDegree)
|
|||
tempToothLastToothTime = toothLastToothTime;
|
||||
interrupts();
|
||||
|
||||
crankAngle = toothAngles[tempToothCurrentCount-1] + configPage2.triggerAngle; //Crank angle of the last tooth seen
|
||||
crankAngle = toothAngles[tempToothCurrentCount-1] + configPage4.triggerAngle; //Crank angle of the last tooth seen
|
||||
//Estimate the number of degrees travelled since the last tooth}
|
||||
long elapsedTime = micros() - tempToothLastToothTime;
|
||||
if(elapsedTime < SHRT_MAX ) { crankAngle += div((int)elapsedTime, timePerDegree).quot; } //This option is much faster, but only available for smaller values of elapsedTime
|
||||
|
@ -2447,7 +2446,7 @@ uint16_t getRPM_Harley()
|
|||
uint16_t tempRPM = 0;
|
||||
if (currentStatus.hasSync == true)
|
||||
{
|
||||
if ( currentStatus.RPM < (unsigned int)(configPage2.crankRPM * 100) )
|
||||
if ( currentStatus.RPM < (unsigned int)(configPage4.crankRPM * 100) )
|
||||
{
|
||||
// Kein Unterschied mit dieser Option
|
||||
int tempToothAngle;
|
||||
|
@ -2491,10 +2490,10 @@ int getCrankAngle_Harley(int timePerDegree)
|
|||
int crankAngle;
|
||||
if ( (tempToothCurrentCount == 1) || (tempToothCurrentCount == 3) )
|
||||
{
|
||||
crankAngle = 0 + configPage2.triggerAngle; //Number of teeth that have passed since tooth 1, multiplied by the angle each tooth represents, plus the angle that tooth 1 is ATDC. This gives accuracy only to the nearest tooth.
|
||||
crankAngle = 0 + configPage4.triggerAngle; //Number of teeth that have passed since tooth 1, multiplied by the angle each tooth represents, plus the angle that tooth 1 is ATDC. This gives accuracy only to the nearest tooth.
|
||||
}
|
||||
else {
|
||||
crankAngle = 157 + configPage2.triggerAngle;
|
||||
crankAngle = 157 + configPage4.triggerAngle;
|
||||
}
|
||||
|
||||
//Estimate the number of degrees travelled since the last tooth}
|
||||
|
@ -2527,10 +2526,10 @@ void triggerSetup_ThirtySixMinus222()
|
|||
{
|
||||
triggerToothAngle = 10; //The number of degrees that passes from tooth to tooth
|
||||
triggerActualTeeth = 30; //The number of physical teeth on the wheel. Doing this here saves us a calculation each time in the interrupt
|
||||
triggerFilterTime = (int)(1000000 / (MAX_RPM / 60 * configPage2.triggerTeeth)); //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
|
||||
triggerFilterTime = (int)(1000000 / (MAX_RPM / 60 * configPage4.triggerTeeth)); //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
|
||||
secondDerivEnabled = false;
|
||||
decoderIsSequential = false;
|
||||
checkSyncToothCount = (configPage2.triggerTeeth) >> 1; //50% of the total teeth.
|
||||
checkSyncToothCount = (configPage4.triggerTeeth) >> 1; //50% of the total teeth.
|
||||
toothLastMinusOneToothTime = 0;
|
||||
toothCurrentCount = 0;
|
||||
toothOneTime = 0;
|
||||
|
@ -2607,9 +2606,9 @@ void triggerPri_ThirtySixMinus222()
|
|||
toothLastToothTime = curTime;
|
||||
|
||||
//EXPERIMENTAL!
|
||||
if(configPage1.perToothIgn == true)
|
||||
if(configPage2.perToothIgn == true)
|
||||
{
|
||||
uint16_t crankAngle = ( (toothCurrentCount-1) * triggerToothAngle ) + configPage2.triggerAngle;
|
||||
uint16_t crankAngle = ( (toothCurrentCount-1) * triggerToothAngle ) + configPage4.triggerAngle;
|
||||
doPerToothTiming(crankAngle);
|
||||
}
|
||||
|
||||
|
|
|
@ -3,6 +3,10 @@
|
|||
#include <Arduino.h>
|
||||
#include "table.h"
|
||||
|
||||
//These are configuration options for changing around the outputs that are used
|
||||
#define INJ_CHANNELS 4
|
||||
#define IGN_CHANNELS 5
|
||||
|
||||
#if defined(__AVR_ATmega1280__) || defined(__AVR_ATmega2560__) || defined(__AVR_ATmega2561__)
|
||||
#define BOARD_DIGITAL_GPIO_PINS 54
|
||||
#define BOARD_NR_GPIO_PINS 62
|
||||
|
@ -13,8 +17,10 @@
|
|||
#define BOARD_NR_GPIO_PINS 34
|
||||
#elif defined(STM32_MCU_SERIES) || defined(ARDUINO_ARCH_STM32) || defined(__STM32F1__) || defined(STM32F4) || defined(STM32)
|
||||
#define CORE_STM32
|
||||
#define word(h, l) ((h << 8) | l) //word() function not defined for this platform in the main library
|
||||
#if defined (STM32F1) || defined(__STM32F1__)
|
||||
#define BOARD_DIGITAL_GPIO_PINS 34
|
||||
#undef BOARD_NR_GPIO_PINS //This is declared as 49 in .../framework-arduinoststm32/STM32F1/variants/generic_stm32f103r8/board/board.h
|
||||
#define BOARD_NR_GPIO_PINS 34
|
||||
#ifndef LED_BUILTIN
|
||||
#define LED_BUILTIN PB1 //Maple Mini
|
||||
|
@ -36,8 +42,11 @@
|
|||
#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
|
||||
//These are defined in STM32F1/variants/generic_stm32f103c/variant.h but return a non byte* value
|
||||
#undef portOutputRegister
|
||||
#undef portInputRegister
|
||||
#define portOutputRegister(port) (volatile byte *)( &(port->regs->ODR) )
|
||||
#define portInputRegister(port) (volatile byte *)( &(port->regs->IDR) )
|
||||
#endif
|
||||
#else
|
||||
#error Incorrect board selected. Please select the correct board (Usually Mega 2560) and upload again
|
||||
|
@ -100,6 +109,14 @@
|
|||
#define BIT_TIMER_15HZ 3
|
||||
#define BIT_TIMER_30HZ 4
|
||||
|
||||
#define BIT_STATUS3_RESET_PREVENT 0 //Indicates whether reset prevention is enabled
|
||||
#define BIT_STATUS3_UNUSED2 1
|
||||
#define BIT_STATUS3_UNUSED3 2
|
||||
#define BIT_STATUS3_UNUSED4 3
|
||||
#define BIT_STATUS3_UNUSED5 4
|
||||
#define BIT_STATUS3_UNUSED6 5
|
||||
#define BIT_STATUS3_UNUSED7 6
|
||||
|
||||
#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
|
||||
|
||||
|
@ -117,6 +134,9 @@
|
|||
#define IGN_MODE_SEQUENTIAL 3
|
||||
#define IGN_MODE_ROTARY 4
|
||||
|
||||
#define SEC_TRIGGER_SINGLE 0
|
||||
#define SEC_TRIGGER_4_1 1
|
||||
|
||||
#define ROTARY_IGN_FC 0
|
||||
#define ROTARY_IGN_FD 1
|
||||
#define ROTARY_IGN_RX8 2
|
||||
|
@ -139,6 +159,11 @@
|
|||
#define STAGING_MODE_TABLE 0
|
||||
#define STAGING_MODE_AUTO 1
|
||||
|
||||
#define RESET_CONTROL_DISABLED 0
|
||||
#define RESET_CONTROL_PREVENT_WHEN_RUNNING 1
|
||||
#define RESET_CONTROL_PREVENT_ALWAYS 2
|
||||
#define RESET_CONTROL_SERIAL_COMMAND 3
|
||||
|
||||
#define MAX_RPM 18000 //This is the maximum rpm that the ECU will attempt to run at. It is NOT related to the rev limiter, but is instead dictates how fast certain operations will be allowed to run. Lower number gives better performance
|
||||
#define engineSquirtsPerCycle 2 //Would be 1 for a 2 stroke
|
||||
|
||||
|
@ -179,6 +204,9 @@ 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)
|
||||
struct table2D flexFuelTable; //6 bin flex fuel correction table for fuel adjustments (2D)
|
||||
struct table2D flexAdvTable; //6 bin flex fuel correction table for timing advance (2D)
|
||||
struct table2D flexBoostTable; //6 bin flex fuel correction table for boost adjustments (2D)
|
||||
|
||||
//These are for the direct port manipulation of the injectors and coils
|
||||
volatile byte *inj1_pin_port;
|
||||
|
@ -219,6 +247,9 @@ bool channel2InjEnabled = false;
|
|||
bool channel3InjEnabled = false;
|
||||
bool channel4InjEnabled = false;
|
||||
bool channel5InjEnabled = false;
|
||||
bool channel6InjEnabled = false;
|
||||
bool channel7InjEnabled = false;
|
||||
bool channel8InjEnabled = false;
|
||||
|
||||
int ignition1EndAngle = 0;
|
||||
int ignition2EndAngle = 0;
|
||||
|
@ -228,6 +259,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)
|
||||
|
||||
//This needs to be here because using the config page directly can prevent burning the setting
|
||||
byte resetControl = RESET_CONTROL_DISABLED;
|
||||
|
||||
volatile byte TIMER_mask;
|
||||
volatile byte LOOP_TIMER;
|
||||
|
||||
|
@ -284,6 +318,10 @@ struct statuses {
|
|||
unsigned int PW2; //In uS
|
||||
unsigned int PW3; //In uS
|
||||
unsigned int PW4; //In uS
|
||||
unsigned int PW5; //In uS
|
||||
unsigned int PW6; //In uS
|
||||
unsigned int PW7; //In uS
|
||||
unsigned int PW8; //In uS
|
||||
volatile byte runSecs; //Counter of seconds since cranking commenced (overflows at 255 obviously)
|
||||
volatile byte secl; //Continous
|
||||
volatile unsigned int loopsPerSecond;
|
||||
|
@ -301,6 +339,8 @@ struct statuses {
|
|||
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
|
||||
volatile byte status3;
|
||||
int16_t flexBoostCorrection; //Amount of boost added based on flex
|
||||
|
||||
//Helpful bitwise operations:
|
||||
//Useful reference: http://playground.arduino.cc/Code/BitMath
|
||||
|
@ -313,10 +353,10 @@ struct statuses currentStatus; //The global status object
|
|||
|
||||
//Page 1 of the config - See the ini file for further reference
|
||||
//This mostly covers off variables that are required for fuel
|
||||
struct config1 {
|
||||
struct config2 {
|
||||
|
||||
int8_t flexBoostLow; //Must be signed to allow for negatives
|
||||
byte flexBoostHigh;
|
||||
byte unused2_1;
|
||||
byte unused2_2;
|
||||
byte asePct; //Afterstart enrichment (%)
|
||||
byte aseCount; //Afterstart enrichment cycles. This is the number of ignition cycles that the afterstart enrichment % lasts for
|
||||
byte wueValues[10]; //Warm up enrichment array (10 bytes)
|
||||
|
@ -391,10 +431,10 @@ struct config1 {
|
|||
uint16_t oddfire2; //The ATDC angle of channel 2 for oddfire
|
||||
uint16_t oddfire3; //The ATDC angle of channel 3 for oddfire
|
||||
uint16_t oddfire4; //The ATDC angle of channel 4 for oddfire
|
||||
byte flexFuelLow; //Fuel % to be used for the lowest ethanol reading (Typically 100%)
|
||||
byte flexFuelHigh; //Fuel % to be used for the highest ethanol reading (Typically 163%)
|
||||
byte flexAdvLow; //Additional advance (in degrees) at lowest ethanol reading (Typically 0)
|
||||
byte flexAdvHigh; //Additional advance (in degrees) at highest ethanol reading (Varies, usually 10-20)
|
||||
byte unused2_57;
|
||||
byte unused2_58;
|
||||
byte unused2_59;
|
||||
byte unused2_60;
|
||||
|
||||
byte iacCLminDuty;
|
||||
byte iacCLmaxDuty;
|
||||
|
@ -413,7 +453,7 @@ struct config1 {
|
|||
|
||||
//Page 2 of the config - See the ini file for further reference
|
||||
//This mostly covers off variables that are required for ignition
|
||||
struct config2 {
|
||||
struct config4 {
|
||||
|
||||
int16_t triggerAngle;
|
||||
byte FixAng;
|
||||
|
@ -430,9 +470,12 @@ struct config2 {
|
|||
byte useResync : 1;
|
||||
|
||||
byte sparkDur; //Spark duration in ms * 10
|
||||
bool trigPatternSec; //Mode for Missing tooth secondary trigger. Either single tooth cam wheel or 4-1
|
||||
byte unused4_9;
|
||||
byte unused4_10;
|
||||
byte trigPatternSec; //Mode for Missing tooth secondary trigger. Either single tooth cam wheel or 4-1
|
||||
uint8_t bootloaderCaps; //Capabilities of the bootloader over stock. e.g., 0=Stock, 1=Reset protection, etc.
|
||||
|
||||
byte resetControl : 2; //Which method of reset control to use (0=None, 1=Prevent When Running, 2=Prevent Always, 3=Serial Command)
|
||||
byte resetControlPin : 6;
|
||||
|
||||
byte StgCycles; //The number of initial cycles before the ignition should fire when first cranking
|
||||
|
||||
byte dwellCont : 1; //Fixed duty dwell control
|
||||
|
@ -474,9 +517,9 @@ struct config2 {
|
|||
} __attribute__((__packed__)); //The 32 bi systems require all structs to be fully packed
|
||||
#endif
|
||||
|
||||
//Page 3 of the config - See the ini file for further reference
|
||||
//Page 6 of the config - See the ini file for further reference
|
||||
//This mostly covers off variables that are required for AFR targets and closed loop
|
||||
struct config3 {
|
||||
struct config6 {
|
||||
|
||||
byte egoAlgorithm : 2;
|
||||
byte egoType : 2;
|
||||
|
@ -568,9 +611,9 @@ struct config3 {
|
|||
} __attribute__((__packed__)); //The 32 bit systems require all structs to be fully packed
|
||||
#endif
|
||||
|
||||
//Page 10 of the config mostly deals with CANBUS control
|
||||
//Page 9 of the config mostly deals with CANBUS control
|
||||
//See ini file for further info (Config Page 10 in the ini)
|
||||
struct config10 {
|
||||
struct config9 {
|
||||
byte enable_canbus:2;
|
||||
byte enable_candata_in:1;
|
||||
uint16_t caninput_sel; //bit status on/off if input is enabled
|
||||
|
@ -620,11 +663,11 @@ struct config10 {
|
|||
#endif
|
||||
|
||||
/*
|
||||
Page 11 - No specific purpose. Created initially for the cranking enrich curve
|
||||
Page 10 - 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 {
|
||||
struct config10 {
|
||||
byte crankingEnrichBins[4];
|
||||
byte crankingEnrichValues[4];
|
||||
|
||||
|
@ -640,7 +683,17 @@ struct config11 {
|
|||
byte boostIntv;
|
||||
uint16_t stagedInjSizePri;
|
||||
uint16_t stagedInjSizeSec;
|
||||
byte unused11_28_192[160];
|
||||
byte lnchCtrlTPS;
|
||||
|
||||
uint8_t flexBoostBins[6];
|
||||
int16_t flexBoostAdj[6]; //kPa to be added to the boost target @ current ethanol (negative values allowed)
|
||||
uint8_t flexFuelBins[6];
|
||||
uint8_t flexFuelAdj[6]; //Fuel % @ current ethanol (typically 100% @ 0%, 163% @ 100%)
|
||||
uint8_t flexAdvBins[6];
|
||||
uint8_t flexAdvAdj[6]; //Additional advance (in degrees) @ current ethanol (typically 0 @ 0%, 10-20 @ 100%)
|
||||
//And another three corn rows die.
|
||||
|
||||
byte unused11_75_192[117];
|
||||
|
||||
#if defined(CORE_AVR)
|
||||
};
|
||||
|
@ -648,7 +701,6 @@ struct config11 {
|
|||
} __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
|
||||
byte pinInjector3; //Output pin injector 3 is on
|
||||
|
@ -707,6 +759,7 @@ 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)
|
||||
byte pinResetControl; // Output pin used control resetting the Arduino
|
||||
|
||||
// global variables // from speeduino.ino
|
||||
extern struct statuses currentStatus; // from speeduino.ino
|
||||
|
@ -717,11 +770,11 @@ extern struct table3D stagingTable; //8x8 afr target map
|
|||
extern struct table2D taeTable; //4 bin TPS Acceleration Enrichment map (2D)
|
||||
extern struct table2D WUETable; //10 bin Warm Up Enrichment map (2D)
|
||||
extern struct table2D crankingEnrichTable; //4 bin cranking Enrichment map (2D)
|
||||
extern struct config1 configPage1;
|
||||
extern struct config2 configPage2;
|
||||
extern struct config3 configPage3;
|
||||
extern struct config4 configPage4;
|
||||
extern struct config6 configPage6;
|
||||
extern struct config9 configPage9;
|
||||
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)
|
||||
volatile uint16_t ignitionCount; //The count of ignition events that have taken place since the engine started
|
||||
|
@ -729,7 +782,4 @@ extern byte cltCalibrationTable[CALIBRATION_TABLE_SIZE];
|
|||
extern byte iatCalibrationTable[CALIBRATION_TABLE_SIZE];
|
||||
extern byte o2CalibrationTable[CALIBRATION_TABLE_SIZE];
|
||||
|
||||
// alias(es) for ease of code reading!!
|
||||
bool& trigPatternSec = configPage2.trigPatternSec;
|
||||
|
||||
#endif // GLOBALS_H
|
||||
|
|
|
@ -13,7 +13,7 @@ These functions cover the PWM and stepper idle control
|
|||
Idle Control
|
||||
Currently limited to on/off control and open loop PWM and stepper drive
|
||||
*/
|
||||
integerPID idlePID(¤tStatus.longRPM, &idle_pid_target_value, &idle_cl_target_rpm, configPage3.idleKP, configPage3.idleKI, configPage3.idleKD, DIRECT); //This is the PID object if that algorithm is used. Needs to be global as it maintains state outside of each function call
|
||||
integerPID idlePID(¤tStatus.longRPM, &idle_pid_target_value, &idle_cl_target_rpm, configPage6.idleKP, configPage6.idleKI, configPage6.idleKD, DIRECT); //This is the PID object if that algorithm is used. Needs to be global as it maintains state outside of each function call
|
||||
|
||||
void initialiseIdle()
|
||||
{
|
||||
|
@ -24,7 +24,7 @@ void initialiseIdle()
|
|||
|
||||
#elif defined (CORE_TEENSY)
|
||||
|
||||
if( (configPage3.iacAlgorithm == IAC_ALGORITHM_PWM_OL) || (configPage3.iacAlgorithm == IAC_ALGORITHM_PWM_CL) )
|
||||
if( (configPage6.iacAlgorithm == IAC_ALGORITHM_PWM_OL) || (configPage6.iacAlgorithm == IAC_ALGORITHM_PWM_CL) )
|
||||
{
|
||||
//FlexTimer 2 is used for idle
|
||||
FTM2_MODE |= FTM_MODE_WPDIS; // Write Protection Disable
|
||||
|
@ -81,14 +81,14 @@ void initialiseIdle()
|
|||
#endif
|
||||
|
||||
//Initialising comprises of setting the 2D tables with the relevant values from the config pages
|
||||
switch(configPage3.iacAlgorithm)
|
||||
switch(configPage6.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) < configPage3.iacFastTemp)
|
||||
if ((currentStatus.coolant + CALIBRATION_TEMPERATURE_OFFSET) < configPage6.iacFastTemp)
|
||||
{
|
||||
digitalWrite(pinIdle1, HIGH);
|
||||
idleOn = true;
|
||||
|
@ -99,23 +99,23 @@ void initialiseIdle()
|
|||
//Case 2 is PWM open loop
|
||||
iacPWMTable.xSize = 10;
|
||||
iacPWMTable.valueSize = SIZE_BYTE;
|
||||
iacPWMTable.values = configPage3.iacOLPWMVal;
|
||||
iacPWMTable.axisX = configPage3.iacBins;
|
||||
iacPWMTable.values = configPage6.iacOLPWMVal;
|
||||
iacPWMTable.axisX = configPage6.iacBins;
|
||||
|
||||
|
||||
iacCrankDutyTable.xSize = 4;
|
||||
iacCrankDutyTable.valueSize = SIZE_BYTE;
|
||||
iacCrankDutyTable.values = configPage3.iacCrankDuty;
|
||||
iacCrankDutyTable.axisX = configPage3.iacCrankBins;
|
||||
iacCrankDutyTable.values = configPage6.iacCrankDuty;
|
||||
iacCrankDutyTable.axisX = configPage6.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
|
||||
idle_pwm_max_count = 1000000L / (configPage6.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
|
||||
idle_pwm_max_count = 1000000L / (16 * configPage6.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;
|
||||
|
@ -124,25 +124,25 @@ void initialiseIdle()
|
|||
//Case 3 is PWM closed loop
|
||||
iacClosedLoopTable.xSize = 10;
|
||||
iacClosedLoopTable.valueSize = SIZE_BYTE;
|
||||
iacClosedLoopTable.values = configPage3.iacCLValues;
|
||||
iacClosedLoopTable.axisX = configPage3.iacBins;
|
||||
iacClosedLoopTable.values = configPage6.iacCLValues;
|
||||
iacClosedLoopTable.axisX = configPage6.iacBins;
|
||||
|
||||
iacCrankDutyTable.xSize = 4;
|
||||
iacCrankDutyTable.valueSize = SIZE_BYTE;
|
||||
iacCrankDutyTable.values = configPage3.iacCrankDuty;
|
||||
iacCrankDutyTable.axisX = configPage3.iacCrankBins;
|
||||
iacCrankDutyTable.values = configPage6.iacCrankDuty;
|
||||
iacCrankDutyTable.axisX = configPage6.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
|
||||
idle_pwm_max_count = 1000000L / (configPage6.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
|
||||
idle_pwm_max_count = 1000000L / (16 * configPage6.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.SetOutputLimits(percentage(configPage2.iacCLminDuty, idle_pwm_max_count), percentage(configPage2.iacCLmaxDuty, idle_pwm_max_count));
|
||||
idlePID.SetTunings(configPage6.idleKP, configPage6.idleKI, configPage6.idleKD);
|
||||
idlePID.SetMode(AUTOMATIC); //Turn PID on
|
||||
|
||||
idleCounter = 0;
|
||||
|
@ -152,13 +152,13 @@ void initialiseIdle()
|
|||
//Case 2 is Stepper open loop
|
||||
iacStepTable.xSize = 10;
|
||||
iacStepTable.valueSize = SIZE_BYTE;
|
||||
iacStepTable.values = configPage3.iacOLStepVal;
|
||||
iacStepTable.axisX = configPage3.iacBins;
|
||||
iacStepTable.values = configPage6.iacOLStepVal;
|
||||
iacStepTable.axisX = configPage6.iacBins;
|
||||
|
||||
iacCrankStepsTable.xSize = 4;
|
||||
iacCrankStepsTable.values = configPage3.iacCrankSteps;
|
||||
iacCrankStepsTable.axisX = configPage3.iacCrankBins;
|
||||
iacStepTime = configPage3.iacStepTime * 1000;
|
||||
iacCrankStepsTable.values = configPage6.iacCrankSteps;
|
||||
iacCrankStepsTable.axisX = configPage6.iacCrankBins;
|
||||
iacStepTime = configPage6.iacStepTime * 1000;
|
||||
|
||||
completedHomeSteps = 0;
|
||||
idleStepper.curIdleStep = 0;
|
||||
|
@ -169,21 +169,21 @@ void initialiseIdle()
|
|||
//Case 5 is Stepper closed loop
|
||||
iacClosedLoopTable.xSize = 10;
|
||||
iacClosedLoopTable.valueSize = SIZE_BYTE;
|
||||
iacClosedLoopTable.values = configPage3.iacCLValues;
|
||||
iacClosedLoopTable.axisX = configPage3.iacBins;
|
||||
iacClosedLoopTable.values = configPage6.iacCLValues;
|
||||
iacClosedLoopTable.axisX = configPage6.iacBins;
|
||||
|
||||
iacCrankStepsTable.xSize = 4;
|
||||
iacCrankStepsTable.values = configPage3.iacCrankSteps;
|
||||
iacCrankStepsTable.axisX = configPage3.iacCrankBins;
|
||||
iacStepTime = configPage3.iacStepTime * 1000;
|
||||
iacCrankStepsTable.values = configPage6.iacCrankSteps;
|
||||
iacCrankStepsTable.axisX = configPage6.iacCrankBins;
|
||||
iacStepTime = configPage6.iacStepTime * 1000;
|
||||
|
||||
completedHomeSteps = 0;
|
||||
idleCounter = 0;
|
||||
idleStepper.curIdleStep = 0;
|
||||
idleStepper.stepperStatus = SOFF;
|
||||
|
||||
idlePID.SetOutputLimits(0, (configPage3.iacStepHome * 3)); //Maximum number of steps probably needs its own setting
|
||||
idlePID.SetTunings(configPage3.idleKP, configPage3.idleKI, configPage3.idleKD);
|
||||
idlePID.SetOutputLimits(0, (configPage6.iacStepHome * 3)); //Maximum number of steps probably needs its own setting
|
||||
idlePID.SetTunings(configPage6.idleKP, configPage6.idleKI, configPage6.idleKD);
|
||||
idlePID.SetMode(AUTOMATIC); //Turn PID on
|
||||
break;
|
||||
|
||||
|
@ -191,7 +191,7 @@ void initialiseIdle()
|
|||
//Well this just shouldn't happen
|
||||
break;
|
||||
}
|
||||
idleInitComplete = configPage3.iacAlgorithm; //Sets which idle method was initialised
|
||||
idleInitComplete = configPage6.iacAlgorithm; //Sets which idle method was initialised
|
||||
currentStatus.idleLoad = 0;
|
||||
#if defined(CORE_STM32) //Need to be initialised last due to instant interrupt
|
||||
Timer1.setMode(4, TIMER_OUTPUT_COMPARE);
|
||||
|
@ -202,15 +202,15 @@ void initialiseIdle()
|
|||
|
||||
void idleControl()
|
||||
{
|
||||
if(idleInitComplete != configPage3.iacAlgorithm) { initialiseIdle(); }
|
||||
if(idleInitComplete != configPage6.iacAlgorithm) { initialiseIdle(); }
|
||||
|
||||
switch(configPage3.iacAlgorithm)
|
||||
switch(configPage6.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) < configPage3.iacFastTemp) //All temps are offset by 40 degrees
|
||||
if ( (currentStatus.coolant + CALIBRATION_TEMPERATURE_OFFSET) < configPage6.iacFastTemp) //All temps are offset by 40 degrees
|
||||
{
|
||||
digitalWrite(pinIdle1, HIGH);
|
||||
idleOn = true;
|
||||
|
@ -242,7 +242,7 @@ void idleControl()
|
|||
case IAC_ALGORITHM_PWM_CL: //Case 3 is PWM closed loop
|
||||
//No cranking specific value for closed loop (yet?)
|
||||
idle_cl_target_rpm = table2D_getValue(&iacClosedLoopTable, currentStatus.coolant + CALIBRATION_TEMPERATURE_OFFSET) * 10; //All temps are offset by 40 degrees
|
||||
if( (idleCounter & 31) == 1) { idlePID.SetTunings(configPage3.idleKP, configPage3.idleKI, configPage3.idleKD); } //This only needs to be run very infrequently, once every 32 calls to idleControl(). This is approx. once per second
|
||||
if( (idleCounter & 31) == 1) { idlePID.SetTunings(configPage6.idleKP, configPage6.idleKI, configPage6.idleKD); } //This only needs to be run very infrequently, once every 32 calls to idleControl(). This is approx. once per second
|
||||
|
||||
idlePID.Compute();
|
||||
idle_pwm_target_value = idle_pid_target_value;
|
||||
|
@ -272,7 +272,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 = configPage3.iacStepTime * 1000;
|
||||
iacStepTime = configPage6.iacStepTime * 1000;
|
||||
}
|
||||
doStep();
|
||||
}
|
||||
|
@ -287,8 +287,8 @@ void idleControl()
|
|||
if( (idleCounter & 31) == 1)
|
||||
{
|
||||
//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 = configPage3.iacStepTime * 1000;
|
||||
idlePID.SetTunings(configPage6.idleKP, configPage6.idleKI, configPage6.idleKD);
|
||||
iacStepTime = configPage6.iacStepTime * 1000;
|
||||
}
|
||||
|
||||
idle_cl_target_rpm = table2D_getValue(&iacClosedLoopTable, currentStatus.coolant + CALIBRATION_TEMPERATURE_OFFSET) * 10; //All temps are offset by 40 degrees
|
||||
|
@ -316,7 +316,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 < (configPage3.iacStepHome * 3) ) //Home steps are divided by 3 from TS
|
||||
if( completedHomeSteps < (configPage6.iacStepHome * 3) ) //Home steps are divided by 3 from TS
|
||||
{
|
||||
digitalWrite(pinStepperDir, STEPPER_BACKWARD); //Sets stepper direction to backwards
|
||||
digitalWrite(pinStepperEnable, LOW); //Enable the DRV8825
|
||||
|
@ -372,7 +372,7 @@ Performs a step
|
|||
*/
|
||||
static inline void doStep()
|
||||
{
|
||||
if ( (idleStepper.targetIdleStep <= (idleStepper.curIdleStep - configPage3.iacStepHyster)) || (idleStepper.targetIdleStep >= (idleStepper.curIdleStep + configPage3.iacStepHyster)) ) //Hysteris check
|
||||
if ( (idleStepper.targetIdleStep <= (idleStepper.curIdleStep - configPage6.iacStepHyster)) || (idleStepper.targetIdleStep >= (idleStepper.curIdleStep + configPage6.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
|
||||
|
@ -388,12 +388,12 @@ static inline void doStep()
|
|||
//This function simply turns off the idle PWM and sets the pin low
|
||||
static inline void disableIdle()
|
||||
{
|
||||
if( (configPage3.iacAlgorithm == IAC_ALGORITHM_PWM_CL) || (configPage3.iacAlgorithm == IAC_ALGORITHM_PWM_OL) )
|
||||
if( (configPage6.iacAlgorithm == IAC_ALGORITHM_PWM_CL) || (configPage6.iacAlgorithm == IAC_ALGORITHM_PWM_OL) )
|
||||
{
|
||||
IDLE_TIMER_DISABLE();
|
||||
digitalWrite(pinIdle1, LOW);
|
||||
}
|
||||
else if ( (configPage3.iacAlgorithm == IAC_ALGORITHM_STEP_CL) || (configPage3.iacAlgorithm == IAC_ALGORITHM_STEP_OL) )
|
||||
else if ( (configPage6.iacAlgorithm == IAC_ALGORITHM_STEP_CL) || (configPage6.iacAlgorithm == IAC_ALGORITHM_STEP_OL) )
|
||||
{
|
||||
//Only disable the stepper motor if homing is completed
|
||||
if( isStepperHomed() == true )
|
||||
|
@ -408,11 +408,11 @@ static inline void disableIdle()
|
|||
//Typically this is enabling the PWM interrupt
|
||||
static inline void enableIdle()
|
||||
{
|
||||
if( (configPage3.iacAlgorithm == IAC_ALGORITHM_PWM_CL) || (configPage3.iacAlgorithm == IAC_ALGORITHM_PWM_OL) )
|
||||
if( (configPage6.iacAlgorithm == IAC_ALGORITHM_PWM_CL) || (configPage6.iacAlgorithm == IAC_ALGORITHM_PWM_OL) )
|
||||
{
|
||||
IDLE_TIMER_ENABLE();
|
||||
}
|
||||
else if ( (configPage3.iacAlgorithm == IAC_ALGORITHM_STEP_CL) || (configPage3.iacAlgorithm == IAC_ALGORITHM_STEP_OL) )
|
||||
else if ( (configPage6.iacAlgorithm == IAC_ALGORITHM_STEP_CL) || (configPage6.iacAlgorithm == IAC_ALGORITHM_STEP_OL) )
|
||||
{
|
||||
|
||||
}
|
||||
|
@ -426,34 +426,34 @@ static inline void idleInterrupt() //Most ARM chips can simply call a function
|
|||
{
|
||||
if (idle_pwm_state)
|
||||
{
|
||||
if (configPage3.iacPWMdir == 0)
|
||||
if (configPage6.iacPWMdir == 0)
|
||||
{
|
||||
//Normal direction
|
||||
*idle_pin_port &= ~(idle_pin_mask); // Switch pin to low (1 pin mode)
|
||||
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
|
||||
if(configPage6.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(configPage3.iacChannels == 1) { *idle2_pin_port &= ~(idle2_pin_mask); } //If 2 idle channels are in use, flip idle2 to be the opposite of idle1
|
||||
if(configPage6.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 (configPage3.iacPWMdir == 0)
|
||||
if (configPage6.iacPWMdir == 0)
|
||||
{
|
||||
//Normal direction
|
||||
*idle_pin_port |= (idle_pin_mask); // Switch pin high
|
||||
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
|
||||
if(configPage6.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(configPage3.iacChannels == 1) { *idle2_pin_port |= (idle2_pin_mask); } //If 2 idle channels are in use, flip idle2 to be the opposite of idle1
|
||||
if(configPage6.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;
|
||||
|
|
|
@ -32,6 +32,13 @@ inline void endTrailingCoilCharge2();
|
|||
#define closeInjector4() *inj4_pin_port &= ~(inj4_pin_mask); BIT_CLEAR(currentStatus.status1, BIT_STATUS1_INJ4)
|
||||
#define openInjector5() *inj5_pin_port |= (inj5_pin_mask)
|
||||
#define closeInjector5() *inj5_pin_port &= ~(inj5_pin_mask)
|
||||
//Dynamic functions below
|
||||
#define openInjector6() *inj6_pin_port |= (inj6_pin_mask);
|
||||
#define closeInjector6() *inj6_pin_port &= ~(inj6_pin_mask);
|
||||
#define openInjector7() *inj7_pin_port |= (inj7_pin_mask);
|
||||
#define closeInjector7() *inj7_pin_port &= ~(inj7_pin_mask);
|
||||
#define openInjector8() *inj8_pin_port |= (inj8_pin_mask);
|
||||
#define closeInjector8() *inj8_pin_port &= ~(inj8_pin_mask);
|
||||
|
||||
#define openInjector1and4() openInjector1(); openInjector4()
|
||||
#define closeInjector1and4() closeInjector1(); closeInjector4()
|
||||
|
|
|
@ -1,7 +1,9 @@
|
|||
|
||||
volatile bool tachoAlt = true;
|
||||
#define TACH_PULSE_HIGH() *tach_pin_port |= (tach_pin_mask)
|
||||
#define TACH_PULSE_LOW() if( (configPage1.tachoDiv == 0) || tachoAlt ) { *tach_pin_port &= ~(tach_pin_mask); tachoAlt = !tachoAlt; }
|
||||
#define TACH_PULSE_LOW() if( (configPage2.tachoDiv == 0) || tachoAlt ) { *tach_pin_port &= ~(tach_pin_mask); tachoAlt = !tachoAlt; }
|
||||
|
||||
|
||||
|
||||
inline void beginCoil1Charge() { digitalWrite(pinCoil1, coilHIGH); TACH_PULSE_LOW(); }
|
||||
inline void endCoil1Charge() { digitalWrite(pinCoil1, coilLOW); TACH_PULSE_HIGH(); }
|
||||
|
|
|
@ -36,46 +36,76 @@ See page 136 of the processors datasheet: http://www.atmel.com/Images/doc2549.pd
|
|||
#define FUEL3_COUNTER TCNT3
|
||||
#define FUEL4_COUNTER TCNT4
|
||||
#define FUEL5_COUNTER TCNT3
|
||||
//The following are for the additional dynamic modes and share the counter and compares with the ignition
|
||||
#define FUEL6_COUNTER TCNT4 //Takes off ignition 4
|
||||
#define FUEL7_COUNTER TCNT5
|
||||
#define FUEL8_COUNTER TCNT5
|
||||
|
||||
#define IGN1_COUNTER TCNT5
|
||||
#define IGN2_COUNTER TCNT5
|
||||
#define IGN3_COUNTER TCNT5
|
||||
#define IGN4_COUNTER TCNT4
|
||||
#define IGN5_COUNTER TCNT1
|
||||
//The following are for the additional dynamic modes and share the counter and compares with the injectors
|
||||
#define IGN6_COUNTER TCNT4 //Replaces injector 4
|
||||
#define IGN7_COUNTER TCNT3 //Replaces injector 3
|
||||
#define IGN8_COUNTER TCNT3 //Replaces injector 2
|
||||
|
||||
#define FUEL1_COMPARE OCR3A
|
||||
#define FUEL2_COMPARE OCR3B
|
||||
#define FUEL3_COMPARE OCR3C
|
||||
#define FUEL4_COMPARE OCR4B
|
||||
#define FUEL5_COMPARE OCR3A //Shared with FUEL1
|
||||
//The following are for the additional dynamic modes and share the counter and compares with the ignition
|
||||
#define FUEL6_COMPARE OCR4A //Replaces ignition4
|
||||
#define FUEL7_COMPARE OCR5C //Replaces ignition3
|
||||
#define FUEL8_COMPARE OCR5B //Replaces ignition2
|
||||
|
||||
#define IGN1_COMPARE OCR5A
|
||||
#define IGN2_COMPARE OCR5B
|
||||
#define IGN3_COMPARE OCR5C
|
||||
#define IGN4_COMPARE OCR4A
|
||||
#define IGN5_COMPARE OCR1C
|
||||
//The following are for the additional dynamic modes and share the counter and compares with the injectors
|
||||
#define IGN6_COMPARE OCR4B //Replaces injector 4
|
||||
#define IGN7_COMPARE OCR3C //Replaces injector 3
|
||||
#define IGN8_COMPARE OCR3B //Replaces injector 2
|
||||
|
||||
#define FUEL1_TIMER_ENABLE() TIMSK3 |= (1 << OCIE3A) //Turn on the A compare unit (ie turn on the interrupt)
|
||||
#define FUEL2_TIMER_ENABLE() TIMSK3 |= (1 << OCIE3B) //Turn on the B compare unit (ie turn on the interrupt)
|
||||
#define FUEL3_TIMER_ENABLE() TIMSK3 |= (1 << OCIE3C) //Turn on the C compare unit (ie turn on the interrupt)
|
||||
#define FUEL4_TIMER_ENABLE() TIMSK4 |= (1 << OCIE4B) //Turn on the B compare unit (ie turn on the interrupt)
|
||||
#define FUEL5_TIMER_ENABLE() TIMSK3 |= (1 << OCIE3B) //
|
||||
#define FUEL6_TIMER_ENABLE() TIMSK3 |= (1 << OCIE3B) //
|
||||
#define FUEL7_TIMER_ENABLE() TIMSK3 |= (1 << OCIE3C) //
|
||||
#define FUEL8_TIMER_ENABLE() TIMSK4 |= (1 << OCIE4B) //
|
||||
|
||||
#define FUEL1_TIMER_DISABLE() TIMSK3 &= ~(1 << OCIE3A); //Turn off this output compare unit
|
||||
#define FUEL2_TIMER_DISABLE() TIMSK3 &= ~(1 << OCIE3B); //Turn off this output compare unit
|
||||
#define FUEL3_TIMER_DISABLE() TIMSK3 &= ~(1 << OCIE3C); //Turn off this output compare unit
|
||||
#define FUEL4_TIMER_DISABLE() TIMSK4 &= ~(1 << OCIE4B); //Turn off this output compare unit
|
||||
#define FUEL5_TIMER_DISABLE() TIMSK3 &= ~(1 << OCIE3A); //
|
||||
#define FUEL6_TIMER_DISABLE() TIMSK3 &= ~(1 << OCIE3B); //
|
||||
#define FUEL7_TIMER_DISABLE() TIMSK3 &= ~(1 << OCIE3C); //
|
||||
#define FUEL8_TIMER_DISABLE() TIMSK4 &= ~(1 << OCIE4B); //
|
||||
|
||||
#define IGN1_TIMER_ENABLE() TIMSK5 |= (1 << OCIE5A) //Turn on the A compare unit (ie turn on the interrupt)
|
||||
#define IGN2_TIMER_ENABLE() TIMSK5 |= (1 << OCIE5B) //Turn on the B compare unit (ie turn on the interrupt)
|
||||
#define IGN3_TIMER_ENABLE() TIMSK5 |= (1 << OCIE5C) //Turn on the C compare unit (ie turn on the interrupt)
|
||||
#define IGN4_TIMER_ENABLE() TIMSK4 |= (1 << OCIE4A) //Turn on the A compare unit (ie turn on the interrupt)
|
||||
#define IGN5_TIMER_ENABLE() TIMSK1 |= (1 << OCIE1C) //Turn on the A compare unit (ie turn on the interrupt)
|
||||
#define IGN6_TIMER_ENABLE() TIMSK4 |= (1 << OCIE4B) //Replaces injector 4
|
||||
#define IGN7_TIMER_ENABLE() TIMSK3 |= (1 << OCIE3C) //Replaces injector 3
|
||||
#define IGN8_TIMER_ENABLE() TIMSK3 |= (1 << OCIE3B) //Replaces injector 2
|
||||
|
||||
#define IGN1_TIMER_DISABLE() TIMSK5 &= ~(1 << OCIE5A) //Turn off this output compare unit
|
||||
#define IGN2_TIMER_DISABLE() TIMSK5 &= ~(1 << OCIE5B) //Turn off this output compare unit
|
||||
#define IGN3_TIMER_DISABLE() TIMSK5 &= ~(1 << OCIE5C) //Turn off this output compare unit
|
||||
#define IGN4_TIMER_DISABLE() TIMSK4 &= ~(1 << OCIE4A) //Turn off this output compare unit
|
||||
#define IGN5_TIMER_DISABLE() TIMSK1 &= ~(1 << OCIE1C) //Turn off this output compare unit
|
||||
#define IGN6_TIMER_DISABLE() TIMSK4 &= ~(1 << OCIE4B) //Replaces injector 4
|
||||
#define IGN7_TIMER_DISABLE() TIMSK3 &= ~(1 << OCIE3C) //Replaces injector 3
|
||||
#define IGN8_TIMER_DISABLE() TIMSK3 &= ~(1 << OCIE3B) //Replaces injector 2
|
||||
|
||||
#define MAX_TIMER_PERIOD 262140UL //The longest period of time (in uS) that the timer can permit (IN this case it is 65535 * 4, as each timer tick is 4uS)
|
||||
#define MAX_TIMER_PERIOD_SLOW 1048560UL //The longest period of time (in uS) that the timer can permit (IN this case it is 65535 * 16, as each timer tick is 16uS)
|
||||
|
@ -174,30 +204,47 @@ See page 136 of the processors datasheet: http://www.atmel.com/Images/doc2549.pd
|
|||
#define FUEL2_COUNTER (TIM2)->CNT
|
||||
#define FUEL3_COUNTER (TIM2)->CNT
|
||||
#define FUEL4_COUNTER (TIM2)->CNT
|
||||
#define FUEL5_COUNTER (TIM2)->CNT
|
||||
#define FUEL5_COUNTER (TIM4)->CNT
|
||||
#define FUEL6_COUNTER (TIM4)->CNT
|
||||
#define FUEL7_COUNTER (TIM4)->CNT
|
||||
#define FUEL8_COUNTER (TIM4)->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 IGN5_COUNTER (TIM4)->CNT
|
||||
#define IGN6_COUNTER (TIM4)->CNT
|
||||
#define IGN7_COUNTER (TIM4)->CNT
|
||||
#define IGN8_COUNTER (TIM4)->CNT
|
||||
|
||||
#define FUEL1_COMPARE (TIM2)->CCR1
|
||||
#define FUEL2_COMPARE (TIM2)->CCR2
|
||||
#define FUEL3_COMPARE (TIM2)->CCR3
|
||||
#define FUEL4_COMPARE (TIM2)->CCR4
|
||||
#define FUEL5_COMPARE (TIM4)->CCR1
|
||||
#define FUEL6_COMPARE (TIM4)->CCR2
|
||||
#define FUEL7_COMPARE (TIM4)->CCR3
|
||||
#define FUEL8_COMPARE (TIM4)->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
|
||||
#define IGN5_COMPARE (TIM4)->CCR1
|
||||
#define IGN6_COMPARE (TIM4)->CCR2
|
||||
#define IGN7_COMPARE (TIM4)->CCR3
|
||||
#define IGN8_COMPARE (TIM4)->CCR4
|
||||
|
||||
//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 FUEL5_TIMER_ENABLE() (TIM4)->CCER |= TIM_CCER_CC1E
|
||||
#define FUEL6_TIMER_ENABLE() (TIM4)->CCER |= TIM_CCER_CC2E
|
||||
#define FUEL7_TIMER_ENABLE() (TIM4)->CCER |= TIM_CCER_CC3E
|
||||
#define FUEL8_TIMER_ENABLE() (TIM4)->CCER |= TIM_CCER_CC4E
|
||||
|
||||
#define IGN1_TIMER_ENABLE() (TIM3)->CCER |= TIM_CCER_CC1E
|
||||
#define IGN2_TIMER_ENABLE() (TIM3)->CCER |= TIM_CCER_CC2E
|
||||
|
@ -220,47 +267,75 @@ See page 136 of the processors datasheet: http://www.atmel.com/Images/doc2549.pd
|
|||
#define FUEL2_COUNTER (TIMER2->regs).gen->CNT
|
||||
#define FUEL3_COUNTER (TIMER2->regs).gen->CNT
|
||||
#define FUEL4_COUNTER (TIMER2->regs).gen->CNT
|
||||
#define FUEL5_COUNTER (TIMER1->regs).gen->CNT
|
||||
#define FUEL5_COUNTER (TIMER4->regs).gen->CNT
|
||||
#define FUEL6_COUNTER (TIMER4->regs).gen->CNT
|
||||
#define FUEL7_COUNTER (TIMER4->regs).gen->CNT
|
||||
#define FUEL8_COUNTER (TIMER4->regs).gen->CNT
|
||||
|
||||
#define IGN1_COUNTER (TIMER3->regs).gen->CNT
|
||||
#define IGN2_COUNTER (TIMER3->regs).gen->CNT
|
||||
#define IGN3_COUNTER (TIMER3->regs).gen->CNT
|
||||
#define IGN4_COUNTER (TIMER3->regs).gen->CNT
|
||||
#define IGN5_COUNTER (TIMER1->regs).gen->CNT
|
||||
#define IGN5_COUNTER (TIMER4->regs).gen->CNT
|
||||
#define IGN6_COUNTER (TIMER4->regs).gen->CNT
|
||||
#define IGN7_COUNTER (TIMER4->regs).gen->CNT
|
||||
#define IGN8_COUNTER (TIMER4->regs).gen->CNT
|
||||
|
||||
#define FUEL1_COMPARE (TIMER2->regs).gen->CCR1
|
||||
#define FUEL2_COMPARE (TIMER2->regs).gen->CCR2
|
||||
#define FUEL3_COMPARE (TIMER2->regs).gen->CCR3
|
||||
#define FUEL4_COMPARE (TIMER2->regs).gen->CCR4
|
||||
#define FUEL5_COMPARE (TIMER4->regs).gen->CCR1
|
||||
#define FUEL6_COMPARE (TIMER4->regs).gen->CCR2
|
||||
#define FUEL7_COMPARE (TIMER4->regs).gen->CCR3
|
||||
#define FUEL8_COMPARE (TIMER4->regs).gen->CCR4
|
||||
|
||||
#define IGN1_COMPARE (TIMER3->regs).gen->CCR1
|
||||
#define IGN2_COMPARE (TIMER3->regs).gen->CCR2
|
||||
#define IGN3_COMPARE (TIMER3->regs).gen->CCR3
|
||||
#define IGN4_COMPARE (TIMER3->regs).gen->CCR4
|
||||
#define IGN5_COMPARE (TIMER1->regs).gen->CCR1
|
||||
#define IGN5_COMPARE (TIMER4->regs).gen->CCR1
|
||||
#define IGN6_COMPARE (TIMER4->regs).gen->CCR2
|
||||
#define IGN7_COMPARE (TIMER4->regs).gen->CCR3
|
||||
#define IGN8_COMPARE (TIMER4->regs).gen->CCR4
|
||||
|
||||
//https://github.com/rogerclarkmelbourne/Arduino_STM32/blob/754bc2969921f1ef262bd69e7faca80b19db7524/STM32F1/system/libmaple/include/libmaple/timer.h#L444
|
||||
#define FUEL1_TIMER_ENABLE() (TIMER2->regs).gen->CCER |= TIMER_CCER_CC1E
|
||||
#define FUEL2_TIMER_ENABLE() (TIMER2->regs).gen->CCER |= TIMER_CCER_CC2E
|
||||
#define FUEL3_TIMER_ENABLE() (TIMER2->regs).gen->CCER |= TIMER_CCER_CC3E
|
||||
#define FUEL4_TIMER_ENABLE() (TIMER2->regs).gen->CCER |= TIMER_CCER_CC4E
|
||||
#define FUEL5_TIMER_ENABLE() (TIMER4->regs).gen->CCER |= TIMER_CCER_CC1E
|
||||
#define FUEL6_TIMER_ENABLE() (TIMER4->regs).gen->CCER |= TIMER_CCER_CC2E
|
||||
#define FUEL7_TIMER_ENABLE() (TIMER4->regs).gen->CCER |= TIMER_CCER_CC3E
|
||||
#define FUEL8_TIMER_ENABLE() (TIMER4->regs).gen->CCER |= TIMER_CCER_CC4E
|
||||
|
||||
#define IGN1_TIMER_ENABLE() (TIMER3->regs).gen->CCER |= TIMER_CCER_CC1E
|
||||
#define IGN2_TIMER_ENABLE() (TIMER3->regs).gen->CCER |= TIMER_CCER_CC2E
|
||||
#define IGN3_TIMER_ENABLE() (TIMER3->regs).gen->CCER |= TIMER_CCER_CC3E
|
||||
#define IGN4_TIMER_ENABLE() (TIMER3->regs).gen->CCER |= TIMER_CCER_CC4E
|
||||
#define IGN5_TIMER_ENABLE() (TIMER1->regs).gen->CCER |= TIMER_CCER_CC1E
|
||||
#define IGN5_TIMER_ENABLE() (TIMER4->regs).gen->CCER |= TIMER_CCER_CC1E
|
||||
#define IGN6_TIMER_ENABLE() (TIMER4->regs).gen->CCER |= TIMER_CCER_CC2E
|
||||
#define IGN7_TIMER_ENABLE() (TIMER4->regs).gen->CCER |= TIMER_CCER_CC3E
|
||||
#define IGN8_TIMER_ENABLE() (TIMER4->regs).gen->CCER |= TIMER_CCER_CC4E
|
||||
|
||||
#define FUEL1_TIMER_DISABLE() (TIMER2->regs).gen->CCER &= ~TIMER_CCER_CC1E
|
||||
#define FUEL2_TIMER_DISABLE() (TIMER2->regs).gen->CCER &= ~TIMER_CCER_CC2E
|
||||
#define FUEL3_TIMER_DISABLE() (TIMER2->regs).gen->CCER &= ~TIMER_CCER_CC3E
|
||||
#define FUEL4_TIMER_DISABLE() (TIMER2->regs).gen->CCER &= ~TIMER_CCER_CC4E
|
||||
#define FUEL5_TIMER_DISABLE() (TIMER4->regs).gen->CCER &= ~TIMER_CCER_CC1E
|
||||
#define FUEL6_TIMER_DISABLE() (TIMER4->regs).gen->CCER &= ~TIMER_CCER_CC2E
|
||||
#define FUEL7_TIMER_DISABLE() (TIMER4->regs).gen->CCER &= ~TIMER_CCER_CC3E
|
||||
#define FUEL8_TIMER_DISABLE() (TIMER4->regs).gen->CCER &= ~TIMER_CCER_CC4E
|
||||
|
||||
#define IGN1_TIMER_DISABLE() (TIMER3->regs).gen->CCER &= ~TIMER_CCER_CC1E
|
||||
#define IGN2_TIMER_DISABLE() (TIMER3->regs).gen->CCER &= ~TIMER_CCER_CC2E
|
||||
#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
|
||||
#define IGN5_TIMER_DISABLE() (TIMER4->regs).gen->CCER &= ~TIMER_CCER_CC1E
|
||||
#define IGN6_TIMER_DISABLE() (TIMER4->regs).gen->CCER &= ~TIMER_CCER_CC2E
|
||||
#define IGN7_TIMER_DISABLE() (TIMER4->regs).gen->CCER &= ~TIMER_CCER_CC3E
|
||||
#define IGN8_TIMER_DISABLE() (TIMER4->regs).gen->CCER &= ~TIMER_CCER_CC4E
|
||||
|
||||
#endif
|
||||
#endif
|
||||
|
||||
|
@ -284,19 +359,49 @@ void setIgnitionSchedule8(void (*startCallback)(), unsigned long timeout, unsign
|
|||
|
||||
static inline void refreshIgnitionSchedule1(unsigned long timeToEnd) __attribute__((always_inline));
|
||||
|
||||
//Needed for STM32 interrupt handlers
|
||||
#if defined(CORE_STM32)
|
||||
//The ARM cores use seprate functions for their ISRs
|
||||
#if defined(CORE_STM32) || defined(CORE_TEENSY)
|
||||
static inline void fuelSchedule1Interrupt();
|
||||
static inline void fuelSchedule2Interrupt();
|
||||
static inline void fuelSchedule3Interrupt();
|
||||
static inline void fuelSchedule4Interrupt();
|
||||
#if (INJ_CHANNELS >= 5)
|
||||
static inline void fuelSchedule5Interrupt();
|
||||
#endif
|
||||
#if (INJ_CHANNELS >= 6)
|
||||
static inline void fuelSchedule6Interrupt();
|
||||
#endif
|
||||
#if (INJ_CHANNELS >= 7)
|
||||
static inline void fuelSchedule7Interrupt();
|
||||
#endif
|
||||
#if (INJ_CHANNELS >= 8)
|
||||
static inline void fuelSchedule8Interrupt();
|
||||
#endif
|
||||
#if (IGN_CHANNELS >= 1)
|
||||
static inline void ignitionSchedule1Interrupt();
|
||||
#endif
|
||||
#if (IGN_CHANNELS >= 2)
|
||||
static inline void ignitionSchedule2Interrupt();
|
||||
#endif
|
||||
#if (IGN_CHANNELS >= 3)
|
||||
static inline void ignitionSchedule3Interrupt();
|
||||
#endif
|
||||
#if (IGN_CHANNELS >= 4)
|
||||
static inline void ignitionSchedule4Interrupt();
|
||||
#endif
|
||||
#if (IGN_CHANNELS >= 5)
|
||||
static inline void ignitionSchedule5Interrupt();
|
||||
#endif
|
||||
#if (IGN_CHANNELS >= 6)
|
||||
static inline void ignitionSchedule6Interrupt();
|
||||
#endif
|
||||
#if (IGN_CHANNELS >= 7)
|
||||
static inline void ignitionSchedule7Interrupt();
|
||||
#endif
|
||||
#if (IGN_CHANNELS >= 8)
|
||||
static inline void ignitionSchedule8Interrupt();
|
||||
#endif
|
||||
#endif
|
||||
|
||||
enum ScheduleStatus {OFF, PENDING, STAGED, RUNNING}; //The 3 statuses that a schedule can have
|
||||
|
||||
|
@ -313,6 +418,13 @@ struct Schedule {
|
|||
unsigned int nextStartCompare;
|
||||
unsigned int nextEndCompare;
|
||||
volatile bool hasNextSchedule = false;
|
||||
#if defined(CORE_AVR)
|
||||
volatile uint16_t * counter;
|
||||
volatile uint16_t * compare;
|
||||
#elif defined(CORE_STM32) || defined(CORE_TEENSY)
|
||||
volatile uint32_t * counter;
|
||||
volatile uint32_t * compare;
|
||||
#endif
|
||||
};
|
||||
|
||||
volatile Schedule *timer3Aqueue[4];
|
||||
|
@ -327,6 +439,7 @@ Schedule fuelSchedule5;
|
|||
Schedule fuelSchedule6;
|
||||
Schedule fuelSchedule7;
|
||||
Schedule fuelSchedule8;
|
||||
|
||||
Schedule ignitionSchedule1;
|
||||
Schedule ignitionSchedule2;
|
||||
Schedule ignitionSchedule3;
|
||||
|
|
|
@ -198,11 +198,21 @@ void initialiseSchedulers()
|
|||
Timer2.attachInterrupt(3, fuelSchedule3Interrupt);
|
||||
Timer2.attachInterrupt(4, fuelSchedule4Interrupt);
|
||||
|
||||
#if (IGN_CHANNELS >= 1)
|
||||
Timer3.attachInterrupt(1, ignitionSchedule1Interrupt);
|
||||
#endif
|
||||
#if (IGN_CHANNELS >= 2)
|
||||
Timer3.attachInterrupt(2, ignitionSchedule2Interrupt);
|
||||
#endif
|
||||
#if (IGN_CHANNELS >= 3)
|
||||
Timer3.attachInterrupt(3, ignitionSchedule3Interrupt);
|
||||
#endif
|
||||
#if (IGN_CHANNELS >= 4)
|
||||
Timer3.attachInterrupt(4, ignitionSchedule4Interrupt);
|
||||
#endif
|
||||
#if (IGN_CHANNELS >= 5)
|
||||
Timer1.attachInterrupt(1, ignitionSchedule5Interrupt);
|
||||
#endif
|
||||
|
||||
Timer1.resume();
|
||||
Timer2.resume();
|
||||
|
@ -214,24 +224,45 @@ void initialiseSchedulers()
|
|||
fuelSchedule3.Status = OFF;
|
||||
fuelSchedule4.Status = OFF;
|
||||
fuelSchedule5.Status = OFF;
|
||||
fuelSchedule6.Status = OFF;
|
||||
fuelSchedule7.Status = OFF;
|
||||
fuelSchedule8.Status = OFF;
|
||||
|
||||
fuelSchedule1.schedulesSet = 0;
|
||||
fuelSchedule2.schedulesSet = 0;
|
||||
fuelSchedule3.schedulesSet = 0;
|
||||
fuelSchedule4.schedulesSet = 0;
|
||||
fuelSchedule5.schedulesSet = 0;
|
||||
fuelSchedule6.schedulesSet = 0;
|
||||
fuelSchedule7.schedulesSet = 0;
|
||||
fuelSchedule8.schedulesSet = 0;
|
||||
|
||||
fuelSchedule1.counter = &FUEL1_COUNTER;
|
||||
fuelSchedule2.counter = &FUEL2_COUNTER;
|
||||
fuelSchedule3.counter = &FUEL3_COUNTER;
|
||||
fuelSchedule4.counter = &FUEL4_COUNTER;
|
||||
fuelSchedule5.counter = &FUEL5_COUNTER;
|
||||
fuelSchedule6.counter = &FUEL6_COUNTER;
|
||||
fuelSchedule7.counter = &FUEL7_COUNTER;
|
||||
fuelSchedule8.counter = &FUEL8_COUNTER;
|
||||
|
||||
ignitionSchedule1.Status = OFF;
|
||||
ignitionSchedule2.Status = OFF;
|
||||
ignitionSchedule3.Status = OFF;
|
||||
ignitionSchedule4.Status = OFF;
|
||||
ignitionSchedule5.Status = OFF;
|
||||
ignitionSchedule6.Status = OFF;
|
||||
ignitionSchedule7.Status = OFF;
|
||||
ignitionSchedule8.Status = OFF;
|
||||
|
||||
ignitionSchedule1.schedulesSet = 0;
|
||||
ignitionSchedule2.schedulesSet = 0;
|
||||
ignitionSchedule3.schedulesSet = 0;
|
||||
ignitionSchedule4.schedulesSet = 0;
|
||||
ignitionSchedule5.schedulesSet = 0;
|
||||
ignitionSchedule6.schedulesSet = 0;
|
||||
ignitionSchedule7.schedulesSet = 0;
|
||||
ignitionSchedule8.schedulesSet = 0;
|
||||
|
||||
}
|
||||
|
||||
|
@ -244,6 +275,44 @@ timeout: The number of uS in the future that the startCallback should be trigger
|
|||
duration: The number of uS after startCallback is called before endCallback is called
|
||||
endCallback: This function is called once the duration time has been reached
|
||||
*/
|
||||
|
||||
//Experimental new generic function
|
||||
void setFuelSchedule(struct Schedule *targetSchedule, unsigned long timeout, unsigned long duration)
|
||||
{
|
||||
if(targetSchedule->Status != RUNNING) //Check that we're not already part way through a schedule
|
||||
{
|
||||
//Callbacks no longer used, but retained for now:
|
||||
//fuelSchedule1.StartCallback = startCallback;
|
||||
//fuelSchedule1.EndCallback = endCallback;
|
||||
targetSchedule->duration = duration;
|
||||
|
||||
//Need to check that the timeout doesn't exceed the overflow
|
||||
uint16_t timeout_timer_compare;
|
||||
if (timeout > MAX_TIMER_PERIOD_SLOW) { timeout_timer_compare = uS_TO_TIMER_COMPARE_SLOW( (MAX_TIMER_PERIOD_SLOW - 1) ); } // If the timeout is >16x (Each tick represents 16uS) the maximum allowed value of unsigned int (65535), the timer compare value will overflow when appliedcausing erratic behaviour such as erroneous sparking.
|
||||
else { timeout_timer_compare = uS_TO_TIMER_COMPARE_SLOW(timeout); } //Normal case
|
||||
|
||||
//The following must be enclosed in the noInterupts block to avoid contention caused if the relevant interrupt fires before the state is fully set
|
||||
noInterrupts();
|
||||
targetSchedule->startCompare = *targetSchedule->counter + timeout_timer_compare;
|
||||
targetSchedule->endCompare = targetSchedule->startCompare + uS_TO_TIMER_COMPARE_SLOW(duration);
|
||||
targetSchedule->Status = PENDING; //Turn this schedule on
|
||||
targetSchedule->schedulesSet++; //Increment the number of times this schedule has been set
|
||||
|
||||
*targetSchedule->compare = targetSchedule->startCompare;
|
||||
interrupts();
|
||||
FUEL1_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
|
||||
targetSchedule->nextStartCompare = *targetSchedule->counter + uS_TO_TIMER_COMPARE_SLOW(timeout);
|
||||
targetSchedule->nextEndCompare = targetSchedule->nextStartCompare + uS_TO_TIMER_COMPARE_SLOW(duration);
|
||||
targetSchedule->hasNextSchedule = true;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//void setFuelSchedule1(void (*startCallback)(), unsigned long timeout, unsigned long duration, void(*endCallback)())
|
||||
void setFuelSchedule1(unsigned long timeout, unsigned long duration)
|
||||
{
|
||||
|
@ -282,6 +351,7 @@ void setFuelSchedule1(unsigned long timeout, unsigned long duration)
|
|||
fuelSchedule1.hasNextSchedule = true;
|
||||
}
|
||||
}
|
||||
|
||||
void setFuelSchedule2(unsigned long timeout, unsigned long duration)
|
||||
{
|
||||
if(fuelSchedule2.Status != RUNNING) //Check that we're not already part way through a schedule
|
||||
|
@ -383,37 +453,150 @@ void setFuelSchedule4(unsigned long timeout, unsigned long duration) //Uses time
|
|||
fuelSchedule4.hasNextSchedule = true;
|
||||
}
|
||||
}
|
||||
void setFuelSchedule5(void (*startCallback)(), unsigned long timeout, unsigned long duration, void(*endCallback)())
|
||||
{
|
||||
if(fuelSchedule5.Status != RUNNING) //Check that we're not already part way through a schedule
|
||||
{
|
||||
fuelSchedule5.StartCallback = startCallback; //Name the start callback function
|
||||
fuelSchedule5.EndCallback = endCallback; //Name the end callback function
|
||||
fuelSchedule5.duration = duration;
|
||||
|
||||
/*
|
||||
* The following must be enclosed in the noIntterupts block to avoid contention caused if the relevant interrupts fires before the state is fully set
|
||||
*/
|
||||
#if defined(__AVR_ATmega1280__) || defined(__AVR_ATmega2560__) || defined(__AVR_ATmega2561__)
|
||||
noInterrupts();
|
||||
fuelSchedule5.startCompare = TCNT3 + (timeout >> 4); //As above, but with bit shift instead of / 16
|
||||
fuelSchedule5.endCompare = fuelSchedule5.startCompare + (duration >> 4);
|
||||
fuelSchedule5.Status = PENDING; //Turn this schedule on
|
||||
fuelSchedule5.schedulesSet++; //Increment the number of times this schedule has been set
|
||||
OCR3A = setQueue(timer3Aqueue, &fuelSchedule1, &fuelSchedule5, TCNT3); //Schedule 1 shares a timer with schedule 5
|
||||
interrupts();
|
||||
TIMSK3 |= (1 << OCIE3A); //Turn on the A compare unit (ie turn on the interrupt)
|
||||
#endif
|
||||
}
|
||||
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
|
||||
fuelSchedule5.nextStartCompare = FUEL5_COUNTER + uS_TO_TIMER_COMPARE_SLOW(timeout);
|
||||
fuelSchedule5.nextEndCompare = fuelSchedule5.nextStartCompare + uS_TO_TIMER_COMPARE_SLOW(duration);
|
||||
fuelSchedule5.hasNextSchedule = true;
|
||||
}
|
||||
void setFuelSchedule5(void (*startCallback)(), unsigned long timeout, unsigned long duration, void(*endCallback)())
|
||||
{
|
||||
if(fuelSchedule5.Status != RUNNING) //Check that we're not already part way through a schedule
|
||||
{
|
||||
fuelSchedule5.StartCallback = startCallback; //Name the start callback function
|
||||
fuelSchedule5.EndCallback = endCallback; //Name the end callback function
|
||||
fuelSchedule5.duration = duration;
|
||||
|
||||
/*
|
||||
* The following must be enclosed in the noIntterupts block to avoid contention caused if the relevant interrupts fires before the state is fully set
|
||||
*/
|
||||
#if defined(__AVR_ATmega1280__) || defined(__AVR_ATmega2560__) || defined(__AVR_ATmega2561__)
|
||||
noInterrupts();
|
||||
fuelSchedule5.startCompare = TCNT3 + (timeout >> 4); //As above, but with bit shift instead of / 16
|
||||
fuelSchedule5.endCompare = fuelSchedule5.startCompare + (duration >> 4);
|
||||
fuelSchedule5.Status = PENDING; //Turn this schedule on
|
||||
fuelSchedule5.schedulesSet++; //Increment the number of times this schedule has been set
|
||||
OCR3A = setQueue(timer3Aqueue, &fuelSchedule1, &fuelSchedule5, TCNT3); //Schedule 1 shares a timer with schedule 5
|
||||
interrupts();
|
||||
TIMSK3 |= (1 << OCIE3A); //Turn on the A compare unit (ie turn on the interrupt)
|
||||
#endif
|
||||
}
|
||||
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
|
||||
fuelSchedule5.nextStartCompare = FUEL5_COUNTER + uS_TO_TIMER_COMPARE_SLOW(timeout);
|
||||
fuelSchedule5.nextEndCompare = fuelSchedule5.nextStartCompare + uS_TO_TIMER_COMPARE_SLOW(duration);
|
||||
fuelSchedule5.hasNextSchedule = true;
|
||||
}
|
||||
}
|
||||
|
||||
#if INJ_CHANNELS >= 6
|
||||
//This uses timer
|
||||
void setFuelSchedule6(unsigned long timeout, unsigned long duration)
|
||||
{
|
||||
if(fuelSchedule6.Status != RUNNING) //Check that we're not already part way through a schedule
|
||||
{
|
||||
//Callbacks no longer used, but retained for now:
|
||||
//fuelSchedule4.StartCallback = startCallback;
|
||||
//fuelSchedule4.EndCallback = endCallback;
|
||||
fuelSchedule6.duration = duration;
|
||||
|
||||
//Need to check that the timeout doesn't exceed the overflow
|
||||
uint16_t timeout_timer_compare;
|
||||
if (timeout > MAX_TIMER_PERIOD_SLOW) { timeout_timer_compare = uS_TO_TIMER_COMPARE_SLOW( (MAX_TIMER_PERIOD - 1) ); } // If the timeout is >4x (Each tick represents 4uS) the maximum allowed value of unsigned int (65535), the timer compare value will overflow when appliedcausing erratic behaviour such as erroneous sparking.
|
||||
else { timeout_timer_compare = uS_TO_TIMER_COMPARE_SLOW(timeout); } //Normal case
|
||||
|
||||
//The following must be enclosed in the noInterupts block to avoid contention caused if the relevant interrupt fires before the state is fully set
|
||||
noInterrupts();
|
||||
fuelSchedule6.startCompare = FUEL6_COUNTER + timeout_timer_compare;
|
||||
fuelSchedule6.endCompare = fuelSchedule6.startCompare + uS_TO_TIMER_COMPARE_SLOW(duration);
|
||||
FUEL6_COMPARE = fuelSchedule6.startCompare; //Use the C copmare unit of timer 3
|
||||
fuelSchedule6.Status = PENDING; //Turn this schedule on
|
||||
fuelSchedule6.schedulesSet++; //Increment the number of times this schedule has been set
|
||||
interrupts();
|
||||
FUEL6_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
|
||||
fuelSchedule6.nextStartCompare = FUEL6_COUNTER + uS_TO_TIMER_COMPARE_SLOW(timeout);
|
||||
fuelSchedule6.nextEndCompare = fuelSchedule6.nextStartCompare + uS_TO_TIMER_COMPARE_SLOW(duration);
|
||||
fuelSchedule6.hasNextSchedule = true;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
#if INJ_CHANNELS >= 7
|
||||
//This uses timer
|
||||
void setFuelSchedule7(unsigned long timeout, unsigned long duration)
|
||||
{
|
||||
if(fuelSchedule7.Status != RUNNING) //Check that we're not already part way through a schedule
|
||||
{
|
||||
//Callbacks no longer used, but retained for now:
|
||||
//fuelSchedule4.StartCallback = startCallback;
|
||||
//fuelSchedule4.EndCallback = endCallback;
|
||||
fuelSchedule7.duration = duration;
|
||||
|
||||
//Need to check that the timeout doesn't exceed the overflow
|
||||
uint16_t timeout_timer_compare;
|
||||
if (timeout > MAX_TIMER_PERIOD) { timeout_timer_compare = uS_TO_TIMER_COMPARE( (MAX_TIMER_PERIOD - 1) ); } // If the timeout is >4x (Each tick represents 4uS) the maximum allowed value of unsigned int (65535), the timer compare value will overflow when appliedcausing erratic behaviour such as erroneous sparking.
|
||||
else { timeout_timer_compare = uS_TO_TIMER_COMPARE(timeout); } //Normal case
|
||||
|
||||
//The following must be enclosed in the noInterupts block to avoid contention caused if the relevant interrupt fires before the state is fully set
|
||||
noInterrupts();
|
||||
fuelSchedule7.startCompare = FUEL7_COUNTER + timeout_timer_compare;
|
||||
fuelSchedule7.endCompare = fuelSchedule6.startCompare + uS_TO_TIMER_COMPARE(duration);
|
||||
FUEL7_COMPARE = fuelSchedule7.startCompare; //Use the C copmare unit of timer 3
|
||||
fuelSchedule7.Status = PENDING; //Turn this schedule on
|
||||
fuelSchedule7.schedulesSet++; //Increment the number of times this schedule has been set
|
||||
interrupts();
|
||||
FUEL7_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
|
||||
fuelSchedule7.nextStartCompare = FUEL7_COUNTER + uS_TO_TIMER_COMPARE(timeout);
|
||||
fuelSchedule7.nextEndCompare = fuelSchedule7.nextStartCompare + uS_TO_TIMER_COMPARE(duration);
|
||||
fuelSchedule7.hasNextSchedule = true;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
#if INJ_CHANNELS >= 8
|
||||
//This uses timer
|
||||
void setFuelSchedule8(unsigned long timeout, unsigned long duration)
|
||||
{
|
||||
if(fuelSchedule8.Status != RUNNING) //Check that we're not already part way through a schedule
|
||||
{
|
||||
//Callbacks no longer used, but retained for now:
|
||||
//fuelSchedule4.StartCallback = startCallback;
|
||||
//fuelSchedule4.EndCallback = endCallback;
|
||||
fuelSchedule8.duration = duration;
|
||||
|
||||
//Need to check that the timeout doesn't exceed the overflow
|
||||
uint16_t timeout_timer_compare;
|
||||
if (timeout > MAX_TIMER_PERIOD) { timeout_timer_compare = uS_TO_TIMER_COMPARE( (MAX_TIMER_PERIOD - 1) ); } // If the timeout is >4x (Each tick represents 4uS) the maximum allowed value of unsigned int (65535), the timer compare value will overflow when appliedcausing erratic behaviour such as erroneous sparking.
|
||||
else { timeout_timer_compare = uS_TO_TIMER_COMPARE(timeout); } //Normal case
|
||||
|
||||
//The following must be enclosed in the noInterupts block to avoid contention caused if the relevant interrupt fires before the state is fully set
|
||||
noInterrupts();
|
||||
fuelSchedule8.startCompare = FUEL8_COUNTER + timeout_timer_compare;
|
||||
fuelSchedule8.endCompare = fuelSchedule8.startCompare + uS_TO_TIMER_COMPARE(duration);
|
||||
FUEL8_COMPARE = fuelSchedule8.startCompare; //Use the C copmare unit of timer 3
|
||||
fuelSchedule8.Status = PENDING; //Turn this schedule on
|
||||
fuelSchedule8.schedulesSet++; //Increment the number of times this schedule has been set
|
||||
interrupts();
|
||||
FUEL8_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
|
||||
fuelSchedule8.nextStartCompare = FUEL8_COUNTER + uS_TO_TIMER_COMPARE(timeout);
|
||||
fuelSchedule8.nextEndCompare = fuelSchedule8.nextStartCompare + uS_TO_TIMER_COMPARE(duration);
|
||||
fuelSchedule8.hasNextSchedule = true;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
//Ignition schedulers use Timer 5
|
||||
void setIgnitionSchedule1(void (*startCallback)(), unsigned long timeout, unsigned long duration, void(*endCallback)())
|
||||
{
|
||||
|
@ -578,7 +761,7 @@ static inline void fuelSchedule1Interrupt() //Most ARM chips can simply call a f
|
|||
if (fuelSchedule1.Status == PENDING) //Check to see if this schedule is turn on
|
||||
{
|
||||
//To use timer queue, change fuelShedule1 to timer3Aqueue[0];
|
||||
if (configPage1.injLayout == INJ_SEMISEQUENTIAL) { openInjector1and4(); }
|
||||
if (configPage2.injLayout == INJ_SEMISEQUENTIAL) { openInjector1and4(); }
|
||||
else { openInjector1(); }
|
||||
fuelSchedule1.Status = RUNNING; //Set the status to be in progress (ie The start callback has been called, but not the end callback)
|
||||
FUEL1_COMPARE = fuelSchedule1.endCompare;
|
||||
|
@ -586,7 +769,7 @@ static inline void fuelSchedule1Interrupt() //Most ARM chips can simply call a f
|
|||
else if (fuelSchedule1.Status == RUNNING)
|
||||
{
|
||||
//timer3Aqueue[0]->EndCallback();
|
||||
if (configPage1.injLayout == INJ_SEMISEQUENTIAL) { closeInjector1and4(); }
|
||||
if (configPage2.injLayout == INJ_SEMISEQUENTIAL) { closeInjector1and4(); }
|
||||
else { closeInjector1(); }
|
||||
fuelSchedule1.Status = OFF; //Turn off the schedule
|
||||
fuelSchedule1.schedulesSet = 0;
|
||||
|
@ -615,7 +798,7 @@ static inline void fuelSchedule2Interrupt() //Most ARM chips can simply call a f
|
|||
if (fuelSchedule2.Status == PENDING) //Check to see if this schedule is turn on
|
||||
{
|
||||
//fuelSchedule2.StartCallback();
|
||||
if (configPage1.injLayout == INJ_SEMISEQUENTIAL) { openInjector2and3(); }
|
||||
if (configPage2.injLayout == INJ_SEMISEQUENTIAL) { openInjector2and3(); }
|
||||
else { openInjector2(); }
|
||||
fuelSchedule2.Status = RUNNING; //Set the status to be in progress (ie The start callback has been called, but not the end callback)
|
||||
FUEL2_COMPARE = fuelSchedule2.endCompare;
|
||||
|
@ -623,7 +806,7 @@ static inline void fuelSchedule2Interrupt() //Most ARM chips can simply call a f
|
|||
else if (fuelSchedule2.Status == RUNNING)
|
||||
{
|
||||
//fuelSchedule2.EndCallback();
|
||||
if (configPage1.injLayout == INJ_SEMISEQUENTIAL) { closeInjector2and3(); }
|
||||
if (configPage2.injLayout == INJ_SEMISEQUENTIAL) { closeInjector2and3(); }
|
||||
else { closeInjector2(); }
|
||||
fuelSchedule2.Status = OFF; //Turn off the schedule
|
||||
fuelSchedule2.schedulesSet = 0;
|
||||
|
@ -711,6 +894,41 @@ static inline void fuelSchedule4Interrupt() //Most ARM chips can simply call a f
|
|||
}
|
||||
}
|
||||
|
||||
#if (INJ_CHANNELS >= 6)
|
||||
#if defined(CORE_AVR) //AVR chips use the ISR for this
|
||||
ISR(TIMER4_COMPA_vect) //fuelSchedule6
|
||||
#elif defined (CORE_TEENSY) || defined(CORE_STM32)
|
||||
static inline void fuelSchedule6Interrupt() //Most ARM chips can simply call a function
|
||||
#endif
|
||||
{
|
||||
if (fuelSchedule6.Status == PENDING) //Check to see if this schedule is turn on
|
||||
{
|
||||
//fuelSchedule4.StartCallback();
|
||||
openInjector6();
|
||||
fuelSchedule6.Status = RUNNING; //Set the status to be in progress (ie The start callback has been called, but not the end callback)
|
||||
FUEL6_COMPARE = fuelSchedule6.endCompare;
|
||||
}
|
||||
else if (fuelSchedule6.Status == RUNNING)
|
||||
{
|
||||
//fuelSchedule4.EndCallback();
|
||||
closeInjector6();
|
||||
fuelSchedule6.Status = OFF; //Turn off the schedule
|
||||
fuelSchedule6.schedulesSet = 0;
|
||||
|
||||
//If there is a next schedule queued up, activate it
|
||||
if(fuelSchedule6.hasNextSchedule == true)
|
||||
{
|
||||
FUEL6_COMPARE = fuelSchedule6.nextStartCompare;
|
||||
fuelSchedule6.endCompare = fuelSchedule6.nextEndCompare;
|
||||
fuelSchedule6.Status = PENDING;
|
||||
fuelSchedule6.schedulesSet = 1;
|
||||
fuelSchedule6.hasNextSchedule = false;
|
||||
}
|
||||
else { FUEL6_TIMER_DISABLE(); }
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
#if defined(__AVR_ATmega1280__) || defined(__AVR_ATmega2560__) || defined(__AVR_ATmega2561__) //AVR chips use the ISR for this
|
||||
ISR(TIMER5_COMPA_vect) //ignitionSchedule1
|
||||
#elif defined (CORE_TEENSY) || defined(CORE_STM32)
|
||||
|
@ -805,7 +1023,7 @@ static inline void ignitionSchedule3Interrupt() //Most ARM chips can simply call
|
|||
}
|
||||
}
|
||||
|
||||
#if defined(__AVR_ATmega1280__) || defined(__AVR_ATmega2560__) || defined(__AVR_ATmega2561__) //AVR chips use the ISR for this
|
||||
#if defined(CORE_AVR) //AVR chips use the ISR for this
|
||||
ISR(TIMER4_COMPA_vect) //ignitionSchedule4
|
||||
#elif defined (CORE_TEENSY) || defined(CORE_STM32)
|
||||
static inline void ignitionSchedule4Interrupt() //Most ARM chips can simply call a function
|
||||
|
|
|
@ -68,7 +68,7 @@ static inline void instanteneousMAPReading()
|
|||
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
|
||||
currentStatus.MAP = fastMap10Bit(currentStatus.mapADC, configPage2.mapMin, configPage2.mapMax); //Get the current MAP value
|
||||
if(currentStatus.MAP < 0) { currentStatus.MAP = 0; } //Sanity check
|
||||
|
||||
}
|
||||
|
@ -77,7 +77,7 @@ static inline void readMAP()
|
|||
{
|
||||
unsigned int tempReading;
|
||||
//MAP Sampling system
|
||||
switch(configPage1.mapSample)
|
||||
switch(configPage2.mapSample)
|
||||
{
|
||||
case 0:
|
||||
//Instantaneous MAP readings
|
||||
|
@ -116,8 +116,8 @@ static inline void readMAP()
|
|||
if( (MAPrunningValue != 0) && (MAPcount != 0) )
|
||||
{
|
||||
currentStatus.mapADC = ldiv(MAPrunningValue, MAPcount).quot;
|
||||
currentStatus.MAP = fastMap10Bit(currentStatus.mapADC, configPage1.mapMin, configPage1.mapMax); //Get the current MAP value
|
||||
//currentStatus.MAP = fastMap1023toX(currentStatus.mapADC, configPage1.mapMax);
|
||||
currentStatus.MAP = fastMap10Bit(currentStatus.mapADC, configPage2.mapMin, configPage2.mapMax); //Get the current MAP value
|
||||
//currentStatus.MAP = fastMap1023toX(currentStatus.mapADC, configPage2.mapMax);
|
||||
if(currentStatus.MAP < 0) { currentStatus.MAP = 0; } //Sanity check
|
||||
}
|
||||
else { instanteneousMAPReading(); }
|
||||
|
@ -152,7 +152,7 @@ static inline void readMAP()
|
|||
{
|
||||
//Reaching here means that the last cylce has completed and the MAP value should be calculated
|
||||
currentStatus.mapADC = MAPrunningValue;
|
||||
currentStatus.MAP = fastMap10Bit(currentStatus.mapADC, configPage1.mapMin, configPage1.mapMax); //Get the current MAP value
|
||||
currentStatus.MAP = fastMap10Bit(currentStatus.mapADC, configPage2.mapMin, configPage2.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
|
||||
|
@ -181,9 +181,9 @@ void readTPS()
|
|||
currentStatus.tpsADC = ADC_FILTER(tempTPS, ADCFILTER_TPS, currentStatus.tpsADC);
|
||||
//Check that the ADC values fall within the min and max ranges (Should always be the case, but noise can cause these to fluctuate outside the defined range).
|
||||
byte tempADC = currentStatus.tpsADC; //The tempADC value is used in order to allow TunerStudio to recover and redo the TPS calibration if this somehow gets corrupted
|
||||
if (currentStatus.tpsADC < configPage1.tpsMin) { tempADC = configPage1.tpsMin; }
|
||||
else if(currentStatus.tpsADC > configPage1.tpsMax) { tempADC = configPage1.tpsMax; }
|
||||
currentStatus.TPS = map(tempADC, configPage1.tpsMin, configPage1.tpsMax, 0, 100); //Take the raw TPS ADC value and convert it into a TPS% based on the calibrated values
|
||||
if (currentStatus.tpsADC < configPage2.tpsMin) { tempADC = configPage2.tpsMin; }
|
||||
else if(currentStatus.tpsADC > configPage2.tpsMax) { tempADC = configPage2.tpsMax; }
|
||||
currentStatus.TPS = map(tempADC, configPage2.tpsMin, configPage2.tpsMax, 0, 100); //Take the raw TPS ADC value and convert it into a TPS% based on the calibrated values
|
||||
currentStatus.TPS_time = currentLoopTime;
|
||||
}
|
||||
|
||||
|
@ -215,7 +215,7 @@ void readIAT()
|
|||
|
||||
void readBaro()
|
||||
{
|
||||
if ( configPage3.useExtBaro != 0 )
|
||||
if ( configPage6.useExtBaro != 0 )
|
||||
{
|
||||
int tempReading;
|
||||
// readings
|
||||
|
@ -228,7 +228,7 @@ void readBaro()
|
|||
|
||||
currentStatus.baroADC = ADC_FILTER(tempReading, ADCFILTER_BARO, currentStatus.baroADC); //Very weak filter
|
||||
|
||||
currentStatus.baro = fastMap10Bit(currentStatus.baroADC, configPage1.baroMin, configPage1.baroMax); //Get the current MAP value
|
||||
currentStatus.baro = fastMap10Bit(currentStatus.baroADC, configPage2.baroMin, configPage2.baroMax); //Get the current MAP value
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -17,6 +17,8 @@ along with this program; if not, write to the Free Software
|
|||
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*/
|
||||
|
||||
#ifndef UNIT_TEST // Scope guard for unit testing
|
||||
|
||||
#include <stdint.h> //https://developer.mbed.org/handbook/C-Data-Types
|
||||
//************************************************
|
||||
#include "speeduino.h"
|
||||
|
@ -44,11 +46,17 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
|||
#include <FlexCAN.h>
|
||||
#endif
|
||||
|
||||
struct config1 configPage1;
|
||||
struct config2 configPage2;
|
||||
struct config3 configPage3;
|
||||
struct config4 configPage4; //Done
|
||||
struct config6 configPage6;
|
||||
struct config9 configPage9;
|
||||
struct config10 configPage10;
|
||||
struct config11 configPage11;
|
||||
/*
|
||||
struct config2 configPage1;
|
||||
struct config6 configPage3;
|
||||
struct config9 configPage9;
|
||||
struct config10 configPage11;
|
||||
*/
|
||||
|
||||
uint16_t req_fuel_uS, inj_opentime_uS;
|
||||
uint16_t staged_req_fuel_mult_pri;
|
||||
|
@ -102,11 +110,17 @@ int channel2IgnDegrees; //The number of crank degrees until cylinder 2 (and 5/6/
|
|||
int channel3IgnDegrees; //The number of crank degrees until cylinder 3 (and 5/6/7/8) is at TDC
|
||||
int channel4IgnDegrees; //The number of crank degrees until cylinder 4 (and 5/6/7/8) is at TDC
|
||||
int channel5IgnDegrees; //The number of crank degrees until cylinder 5 is at TDC
|
||||
int channel6IgnDegrees; //The number of crank degrees until cylinder 6 is at TDC
|
||||
int channel7IgnDegrees; //The number of crank degrees until cylinder 7 is at TDC
|
||||
int channel8IgnDegrees; //The number of crank degrees until cylinder 8 is at TDC
|
||||
int channel1InjDegrees; //The number of crank degrees until cylinder 1 is at TDC (This is obviously 0 for virtually ALL engines, but there's some weird ones)
|
||||
int channel2InjDegrees; //The number of crank degrees until cylinder 2 (and 5/6/7/8) is at TDC
|
||||
int channel3InjDegrees; //The number of crank degrees until cylinder 3 (and 5/6/7/8) is at TDC
|
||||
int channel4InjDegrees; //The number of crank degrees until cylinder 4 (and 5/6/7/8) is at TDC
|
||||
int channel5InjDegrees; //The number of crank degrees until cylinder 5 is at TDC
|
||||
int channel6InjDegrees; //The number of crank degrees until cylinder 6 is at TDC
|
||||
int channel7InjDegrees; //The number of crank degrees until cylinder 7 is at TDC
|
||||
int channel8InjDegrees; //The number of crank degrees until cylinder 8 is at TDC
|
||||
|
||||
//These are the functions the get called to begin and end the ignition coil charging. They are required for the various spark output modes
|
||||
void (*ign1StartFunction)();
|
||||
|
@ -147,6 +161,10 @@ void setup()
|
|||
loadConfig();
|
||||
doUpdates(); //Check if any data items need updating (Occurs ith firmware updates)
|
||||
|
||||
//Always start with a clean slate on the bootloader capabilities level
|
||||
//This should be 0 until we hear otherwise from the 16u2
|
||||
configPage4.bootloaderCaps = 0;
|
||||
|
||||
Serial.begin(115200);
|
||||
if (configPage10.enable_canbus == 1) { CANSerial.begin(115200); }
|
||||
|
||||
|
@ -165,52 +183,65 @@ void setup()
|
|||
//Repoint the 2D table structs to the config pages that were just loaded
|
||||
taeTable.valueSize = SIZE_BYTE; //Set this table to use byte values
|
||||
taeTable.xSize = 4;
|
||||
taeTable.values = configPage2.taeValues;
|
||||
taeTable.axisX = configPage2.taeBins;
|
||||
taeTable.values = configPage4.taeValues;
|
||||
taeTable.axisX = configPage4.taeBins;
|
||||
WUETable.valueSize = SIZE_BYTE; //Set this table to use byte values
|
||||
WUETable.xSize = 10;
|
||||
WUETable.values = configPage1.wueValues;
|
||||
WUETable.axisX = configPage2.wueBins;
|
||||
WUETable.values = configPage2.wueValues;
|
||||
WUETable.axisX = configPage4.wueBins;
|
||||
crankingEnrichTable.valueSize = SIZE_BYTE;
|
||||
crankingEnrichTable.xSize = 4;
|
||||
crankingEnrichTable.values = configPage11.crankingEnrichValues;
|
||||
crankingEnrichTable.axisX = configPage11.crankingEnrichBins;
|
||||
crankingEnrichTable.values = configPage10.crankingEnrichValues;
|
||||
crankingEnrichTable.axisX = configPage10.crankingEnrichBins;
|
||||
|
||||
dwellVCorrectionTable.valueSize = SIZE_BYTE;
|
||||
dwellVCorrectionTable.xSize = 6;
|
||||
dwellVCorrectionTable.values = configPage2.dwellCorrectionValues;
|
||||
dwellVCorrectionTable.axisX = configPage3.voltageCorrectionBins;
|
||||
dwellVCorrectionTable.values = configPage4.dwellCorrectionValues;
|
||||
dwellVCorrectionTable.axisX = configPage6.voltageCorrectionBins;
|
||||
injectorVCorrectionTable.valueSize = SIZE_BYTE;
|
||||
injectorVCorrectionTable.xSize = 6;
|
||||
injectorVCorrectionTable.values = configPage3.injVoltageCorrectionValues;
|
||||
injectorVCorrectionTable.axisX = configPage3.voltageCorrectionBins;
|
||||
injectorVCorrectionTable.values = configPage6.injVoltageCorrectionValues;
|
||||
injectorVCorrectionTable.axisX = configPage6.voltageCorrectionBins;
|
||||
IATDensityCorrectionTable.valueSize = SIZE_BYTE;
|
||||
IATDensityCorrectionTable.xSize = 9;
|
||||
IATDensityCorrectionTable.values = configPage3.airDenRates;
|
||||
IATDensityCorrectionTable.axisX = configPage3.airDenBins;
|
||||
IATDensityCorrectionTable.values = configPage6.airDenRates;
|
||||
IATDensityCorrectionTable.axisX = configPage6.airDenBins;
|
||||
IATRetardTable.valueSize = SIZE_BYTE;
|
||||
IATRetardTable.xSize = 6;
|
||||
IATRetardTable.values = configPage2.iatRetValues;
|
||||
IATRetardTable.axisX = configPage2.iatRetBins;
|
||||
IATRetardTable.values = configPage4.iatRetValues;
|
||||
IATRetardTable.axisX = configPage4.iatRetBins;
|
||||
rotarySplitTable.valueSize = SIZE_BYTE;
|
||||
rotarySplitTable.xSize = 8;
|
||||
rotarySplitTable.values = configPage11.rotarySplitValues;
|
||||
rotarySplitTable.axisX = configPage11.rotarySplitBins;
|
||||
rotarySplitTable.values = configPage10.rotarySplitValues;
|
||||
rotarySplitTable.axisX = configPage10.rotarySplitBins;
|
||||
|
||||
flexFuelTable.valueSize = SIZE_BYTE;
|
||||
flexFuelTable.xSize = 6;
|
||||
flexFuelTable.values = configPage10.flexFuelAdj;
|
||||
flexFuelTable.axisX = configPage10.flexFuelBins;
|
||||
flexAdvTable.valueSize = SIZE_BYTE;
|
||||
flexAdvTable.xSize = 6;
|
||||
flexAdvTable.values = configPage10.flexAdvAdj;
|
||||
flexAdvTable.axisX = configPage10.flexAdvBins;
|
||||
flexBoostTable.valueSize = SIZE_INT;
|
||||
flexBoostTable.xSize = 6;
|
||||
flexBoostTable.values16 = configPage10.flexBoostAdj;
|
||||
flexBoostTable.axisX = configPage10.flexBoostBins;
|
||||
|
||||
//Setup the calibration tables
|
||||
loadCalibration();
|
||||
|
||||
//Set the pin mappings
|
||||
if((configPage1.pinMapping == 0) || (configPage1.pinMapping > BOARD_NR_GPIO_PINS))
|
||||
if(configPage2.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.
|
||||
configPage2.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); }
|
||||
else { setPinMapping(configPage2.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
|
||||
if(configPage2.IgInv == 1) { coilHIGH = LOW, coilLOW = HIGH; }
|
||||
if(configPage4.IgInv == 1) { coilHIGH = LOW, coilLOW = HIGH; }
|
||||
else { coilHIGH = HIGH, coilLOW = LOW; }
|
||||
endCoil1Charge();
|
||||
endCoil2Charge();
|
||||
|
@ -239,7 +270,7 @@ void setup()
|
|||
//Lookup the current MAP reading for barometric pressure
|
||||
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 )
|
||||
if ( configPage6.useExtBaro != 0 )
|
||||
{
|
||||
readBaro();
|
||||
EEPROM.update(EEPROM_LAST_BARO, currentStatus.baro);
|
||||
|
@ -266,19 +297,19 @@ void setup()
|
|||
}
|
||||
|
||||
//Check whether the flex sensor is enabled and if so, attach an interupt for it
|
||||
if(configPage1.flexEnabled)
|
||||
if(configPage2.flexEnabled)
|
||||
{
|
||||
attachInterrupt(digitalPinToInterrupt(pinFlex), flexPulse, RISING);
|
||||
currentStatus.ethanolPct = 0;
|
||||
}
|
||||
|
||||
//Once the configs have been loaded, a number of one time calculations can be completed
|
||||
req_fuel_uS = configPage1.reqFuel * 100; //Convert to uS and an int. This is the only variable to be used in calculations
|
||||
inj_opentime_uS = configPage1.injOpen * 100; //Injector open time. Comes through as ms*10 (Eg 15.5ms = 155).
|
||||
req_fuel_uS = configPage2.reqFuel * 100; //Convert to uS and an int. This is the only variable to be used in calculations
|
||||
inj_opentime_uS = configPage2.injOpen * 100; //Injector open time. Comes through as ms*10 (Eg 15.5ms = 155).
|
||||
|
||||
if(configPage11.stagingEnabled == true)
|
||||
if(configPage10.stagingEnabled == true)
|
||||
{
|
||||
uint32_t totalInjector = configPage11.stagedInjSizePri + configPage11.stagedInjSizeSec;
|
||||
uint32_t totalInjector = configPage10.stagedInjSizePri + configPage10.stagedInjSizeSec;
|
||||
/*
|
||||
These values are a percentage of the req_fuel value that would be required for each injector channel to deliver that much fuel.
|
||||
Eg:
|
||||
|
@ -289,8 +320,8 @@ void setup()
|
|||
staged_req_fuel_mult_pri = 300% (The primary injectors would have to run 3x the overall PW in order to be the equivalent of the full 750cc capacity
|
||||
staged_req_fuel_mult_sec = 150% (The secondary injectors would have to run 1.5x the overall PW in order to be the equivalent of the full 750cc capacity
|
||||
*/
|
||||
staged_req_fuel_mult_pri = (100 * totalInjector) / configPage11.stagedInjSizePri;
|
||||
staged_req_fuel_mult_sec = (100 * totalInjector) / configPage11.stagedInjSizeSec;
|
||||
staged_req_fuel_mult_pri = (100 * totalInjector) / configPage10.stagedInjSizePri;
|
||||
staged_req_fuel_mult_sec = (100 * totalInjector) / configPage10.stagedInjSizeSec;
|
||||
}
|
||||
|
||||
//Begin the main crank trigger interrupt pin setup
|
||||
|
@ -303,9 +334,9 @@ 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)
|
||||
currentStatus.crankRPM = ((unsigned int)configPage4.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);
|
||||
dwellLimit_uS = (1000 * configPage4.dwellLimit);
|
||||
|
||||
noInterrupts();
|
||||
initialiseTriggers();
|
||||
|
@ -320,7 +351,7 @@ void setup()
|
|||
mainLoopCount = 0;
|
||||
|
||||
//Calculate the number of degrees between cylinders
|
||||
switch (configPage1.nCylinders) {
|
||||
switch (configPage2.nCylinders) {
|
||||
case 1:
|
||||
channel1IgnDegrees = 0;
|
||||
channel1InjDegrees = 0;
|
||||
|
@ -331,21 +362,21 @@ void setup()
|
|||
case 2:
|
||||
channel1IgnDegrees = 0;
|
||||
maxIgnOutputs = 2;
|
||||
if (configPage1.engineType == EVEN_FIRE )
|
||||
if (configPage2.engineType == EVEN_FIRE )
|
||||
{
|
||||
channel2IgnDegrees = 180;
|
||||
}
|
||||
else { channel2IgnDegrees = configPage1.oddfire2; }
|
||||
else { channel2IgnDegrees = configPage2.oddfire2; }
|
||||
|
||||
//For alternating injection, the squirt occurs at different times for each channel
|
||||
if(configPage1.injLayout == INJ_SEMISEQUENTIAL || configPage1.injLayout == INJ_PAIRED)
|
||||
if(configPage2.injLayout == INJ_SEMISEQUENTIAL || configPage2.injLayout == INJ_PAIRED)
|
||||
{
|
||||
channel1InjDegrees = 0;
|
||||
channel2InjDegrees = channel2IgnDegrees; //Set to the same as the ignition degrees (Means there's no need for another if to check for oddfire)
|
||||
|
||||
if (!configPage1.injTiming) { channel1InjDegrees = channel2InjDegrees = 0; } //For simultaneous, all squirts happen at the same time
|
||||
if (!configPage2.injTiming) { channel1InjDegrees = channel2InjDegrees = 0; } //For simultaneous, all squirts happen at the same time
|
||||
}
|
||||
else if (configPage1.injLayout == INJ_SEQUENTIAL)
|
||||
else if (configPage2.injLayout == INJ_SEQUENTIAL)
|
||||
{
|
||||
channel1InjDegrees = 0;
|
||||
channel2InjDegrees = channel2IgnDegrees;
|
||||
|
@ -361,9 +392,9 @@ void setup()
|
|||
case 3:
|
||||
channel1IgnDegrees = 0;
|
||||
maxIgnOutputs = 3;
|
||||
if (configPage1.engineType == EVEN_FIRE )
|
||||
if (configPage2.engineType == EVEN_FIRE )
|
||||
{
|
||||
if(configPage2.sparkMode == IGN_MODE_SEQUENTIAL)
|
||||
if(configPage4.sparkMode == IGN_MODE_SEQUENTIAL)
|
||||
{
|
||||
channel2IgnDegrees = 240;
|
||||
channel3IgnDegrees = 480;
|
||||
|
@ -378,20 +409,20 @@ void setup()
|
|||
}
|
||||
else
|
||||
{
|
||||
channel2IgnDegrees = configPage1.oddfire2;
|
||||
channel3IgnDegrees = configPage1.oddfire3;
|
||||
channel2IgnDegrees = configPage2.oddfire2;
|
||||
channel3IgnDegrees = configPage2.oddfire3;
|
||||
}
|
||||
|
||||
//For alternatiing injection, the squirt occurs at different times for each channel
|
||||
if(configPage1.injLayout == INJ_SEMISEQUENTIAL || configPage1.injLayout == INJ_PAIRED)
|
||||
if(configPage2.injLayout == INJ_SEMISEQUENTIAL || configPage2.injLayout == INJ_PAIRED)
|
||||
{
|
||||
channel1InjDegrees = 0;
|
||||
channel2InjDegrees = 120;
|
||||
channel3InjDegrees = 240;
|
||||
|
||||
if (!configPage1.injTiming) { channel1InjDegrees = channel2InjDegrees = channel3InjDegrees = 0; } //For simultaneous, all squirts happen at the same time
|
||||
if (!configPage2.injTiming) { channel1InjDegrees = channel2InjDegrees = channel3InjDegrees = 0; } //For simultaneous, all squirts happen at the same time
|
||||
}
|
||||
else if (configPage1.injLayout == INJ_SEQUENTIAL)
|
||||
else if (configPage2.injLayout == INJ_SEQUENTIAL)
|
||||
{
|
||||
channel1InjDegrees = 0;
|
||||
channel2InjDegrees = 240;
|
||||
|
@ -407,11 +438,11 @@ void setup()
|
|||
case 4:
|
||||
channel1IgnDegrees = 0;
|
||||
maxIgnOutputs = 2; //Default value for 4 cylinder, may be changed below
|
||||
if (configPage1.engineType == EVEN_FIRE )
|
||||
if (configPage2.engineType == EVEN_FIRE )
|
||||
{
|
||||
channel2IgnDegrees = 180;
|
||||
|
||||
if(configPage2.sparkMode == IGN_MODE_SEQUENTIAL)
|
||||
if(configPage4.sparkMode == IGN_MODE_SEQUENTIAL)
|
||||
{
|
||||
channel3IgnDegrees = 360;
|
||||
channel4IgnDegrees = 540;
|
||||
|
@ -419,7 +450,7 @@ void setup()
|
|||
CRANK_ANGLE_MAX_IGN = 720;
|
||||
maxIgnOutputs = 4;
|
||||
}
|
||||
else if(configPage2.sparkMode == IGN_MODE_ROTARY)
|
||||
else if(configPage4.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;
|
||||
|
@ -428,20 +459,21 @@ void setup()
|
|||
}
|
||||
else
|
||||
{
|
||||
channel2IgnDegrees = configPage1.oddfire2;
|
||||
channel3IgnDegrees = configPage1.oddfire3;
|
||||
channel4IgnDegrees = configPage1.oddfire4;
|
||||
channel2IgnDegrees = configPage2.oddfire2;
|
||||
channel3IgnDegrees = configPage2.oddfire3;
|
||||
channel4IgnDegrees = configPage2.oddfire4;
|
||||
maxIgnOutputs = 4;
|
||||
}
|
||||
|
||||
//For alternatiing injection, the squirt occurs at different times for each channel
|
||||
if(configPage1.injLayout == INJ_SEMISEQUENTIAL || configPage1.injLayout == INJ_PAIRED)
|
||||
if(configPage2.injLayout == INJ_SEMISEQUENTIAL || configPage2.injLayout == INJ_PAIRED)
|
||||
{
|
||||
channel1InjDegrees = 0;
|
||||
channel2InjDegrees = 180;
|
||||
|
||||
if (!configPage1.injTiming) { channel1InjDegrees = channel2InjDegrees = 0; } //For simultaneous, all squirts happen at the same time
|
||||
if (!configPage2.injTiming) { channel1InjDegrees = channel2InjDegrees = 0; } //For simultaneous, all squirts happen at the same time
|
||||
}
|
||||
else if (configPage1.injLayout == INJ_SEQUENTIAL)
|
||||
else if (configPage2.injLayout == INJ_SEQUENTIAL)
|
||||
{
|
||||
channel1InjDegrees = 0;
|
||||
channel2InjDegrees = 180;
|
||||
|
@ -456,7 +488,7 @@ void setup()
|
|||
}
|
||||
|
||||
//Check if injector staging is enabled
|
||||
if(configPage11.stagingEnabled == true)
|
||||
if(configPage10.stagingEnabled == true)
|
||||
{
|
||||
channel3InjEnabled = true;
|
||||
channel4InjEnabled = true;
|
||||
|
@ -476,7 +508,7 @@ void setup()
|
|||
channel5IgnDegrees = 288;
|
||||
maxIgnOutputs = 4; //Only 4 actual outputs, so that's all that can be cut
|
||||
|
||||
if(configPage2.sparkMode == IGN_MODE_SEQUENTIAL)
|
||||
if(configPage4.sparkMode == IGN_MODE_SEQUENTIAL)
|
||||
{
|
||||
channel2IgnDegrees = 144;
|
||||
channel3IgnDegrees = 288;
|
||||
|
@ -487,7 +519,7 @@ void setup()
|
|||
}
|
||||
|
||||
//For alternatiing injection, the squirt occurs at different times for each channel
|
||||
if(configPage1.injLayout == INJ_SEMISEQUENTIAL || configPage1.injLayout == INJ_PAIRED)
|
||||
if(configPage2.injLayout == INJ_SEMISEQUENTIAL || configPage2.injLayout == INJ_PAIRED)
|
||||
{
|
||||
channel1InjDegrees = 0;
|
||||
channel2InjDegrees = 72;
|
||||
|
@ -495,7 +527,7 @@ void setup()
|
|||
channel4InjDegrees = 216;
|
||||
channel5InjDegrees = 288;
|
||||
}
|
||||
else if (configPage1.injLayout == INJ_SEQUENTIAL)
|
||||
else if (configPage2.injLayout == INJ_SEQUENTIAL)
|
||||
{
|
||||
channel1InjDegrees = 0;
|
||||
channel2InjDegrees = 144;
|
||||
|
@ -505,7 +537,7 @@ void setup()
|
|||
|
||||
CRANK_ANGLE_MAX_INJ = 720;
|
||||
}
|
||||
if (!configPage1.injTiming) { channel1InjDegrees = channel2InjDegrees = channel3InjDegrees = channel4InjDegrees = channel5InjDegrees = 0; } //For simultaneous, all squirts happen at the same time
|
||||
if (!configPage2.injTiming) { channel1InjDegrees = channel2InjDegrees = channel3InjDegrees = channel4InjDegrees = channel5InjDegrees = 0; } //For simultaneous, all squirts happen at the same time
|
||||
|
||||
channel1InjEnabled = true;
|
||||
channel2InjEnabled = true;
|
||||
|
@ -522,9 +554,9 @@ void setup()
|
|||
channel3InjDegrees = 240;
|
||||
maxIgnOutputs = 3;
|
||||
|
||||
if (!configPage1.injTiming) { channel1InjDegrees = channel2InjDegrees = channel3InjDegrees = 0; } //For simultaneous, all squirts happen at the same time
|
||||
if (!configPage2.injTiming) { channel1InjDegrees = channel2InjDegrees = channel3InjDegrees = 0; } //For simultaneous, all squirts happen at the same time
|
||||
|
||||
configPage1.injLayout = 0; //This is a failsafe. We can never run semi-sequential with more than 4 cylinders
|
||||
configPage2.injLayout = 0; //This is a failsafe. We can never run semi-sequential with more than 4 cylinders
|
||||
|
||||
channel1InjEnabled = true;
|
||||
channel2InjEnabled = true;
|
||||
|
@ -537,9 +569,9 @@ void setup()
|
|||
channel4IgnDegrees = channel4InjDegrees = 270;
|
||||
maxIgnOutputs = 4;
|
||||
|
||||
if (!configPage1.injTiming) { channel1InjDegrees = channel2InjDegrees = channel3InjDegrees = channel4InjDegrees = 0; } //For simultaneous, all squirts happen at the same time
|
||||
if (!configPage2.injTiming) { channel1InjDegrees = channel2InjDegrees = channel3InjDegrees = channel4InjDegrees = 0; } //For simultaneous, all squirts happen at the same time
|
||||
|
||||
configPage1.injLayout = 0; //This is a failsafe. We can never run semi-sequential with more than 4 cylinders
|
||||
configPage2.injLayout = 0; //This is a failsafe. We can never run semi-sequential with more than 4 cylinders
|
||||
|
||||
channel1InjEnabled = true;
|
||||
channel2InjEnabled = true;
|
||||
|
@ -554,7 +586,7 @@ void setup()
|
|||
|
||||
if(CRANK_ANGLE_MAX_IGN == CRANK_ANGLE_MAX_INJ) { CRANK_ANGLE_MAX = CRANK_ANGLE_MAX_IGN; } //If both the injector max and ignition max angles are the same, make the overall system max this value
|
||||
|
||||
switch(configPage2.sparkMode)
|
||||
switch(configPage4.sparkMode)
|
||||
{
|
||||
case IGN_MODE_WASTED:
|
||||
//Wasted Spark (Normal mode)
|
||||
|
@ -587,7 +619,7 @@ void setup()
|
|||
case IGN_MODE_WASTEDCOP:
|
||||
//Wasted COP mode. Ignition channels 1&3 and 2&4 are paired together
|
||||
//This is not a valid mode for >4 cylinders
|
||||
if( configPage1.nCylinders <= 4 )
|
||||
if( configPage2.nCylinders <= 4 )
|
||||
{
|
||||
ign1StartFunction = beginCoil1and3Charge;
|
||||
ign1EndFunction = endCoil1and3Charge;
|
||||
|
@ -629,7 +661,7 @@ void setup()
|
|||
break;
|
||||
|
||||
case IGN_MODE_ROTARY:
|
||||
if(configPage11.rotaryType == ROTARY_IGN_FC)
|
||||
if(configPage10.rotaryType == ROTARY_IGN_FC)
|
||||
{
|
||||
ign1StartFunction = beginCoil1Charge;
|
||||
ign1EndFunction = endCoil1Charge;
|
||||
|
@ -665,10 +697,11 @@ void setup()
|
|||
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));
|
||||
setFuelSchedule1(100, (unsigned long)(configPage2.primePulse * 100));
|
||||
setFuelSchedule2(100, (unsigned long)(configPage2.primePulse * 100));
|
||||
setFuelSchedule3(100, (unsigned long)(configPage2.primePulse * 100));
|
||||
setFuelSchedule4(100, (unsigned long)(configPage2.primePulse * 100));
|
||||
|
||||
initialisationComplete = true;
|
||||
digitalWrite(LED_BUILTIN, HIGH);
|
||||
}
|
||||
|
@ -705,7 +738,7 @@ void loop()
|
|||
#endif
|
||||
|
||||
//Displays currently disabled
|
||||
// if (configPage1.displayType && (mainLoopCount & 255) == 1) { updateDisplay();}
|
||||
// if (configPage2.displayType && (mainLoopCount & 255) == 1) { updateDisplay();}
|
||||
|
||||
previousLoopTime = currentLoopTime;
|
||||
currentLoopTime = micros();
|
||||
|
@ -770,21 +803,21 @@ void loop()
|
|||
|
||||
//Check for launching/flat shift (clutch) can be done around here too
|
||||
previousClutchTrigger = clutchTrigger;
|
||||
if(configPage3.launchHiLo) { clutchTrigger = digitalRead(pinLaunch); }
|
||||
if(configPage6.launchHiLo) { clutchTrigger = digitalRead(pinLaunch); }
|
||||
else { clutchTrigger = !digitalRead(pinLaunch); }
|
||||
|
||||
if(previousClutchTrigger != clutchTrigger) { currentStatus.clutchEngagedRPM = currentStatus.RPM; }
|
||||
|
||||
if (configPage3.launchEnabled && clutchTrigger && (currentStatus.clutchEngagedRPM < ((unsigned int)(configPage3.flatSArm) * 100)) && (currentStatus.RPM > ((unsigned int)(configPage3.lnchHardLim) * 100)) ) { currentStatus.launchingHard = true; BIT_SET(currentStatus.spark, BIT_SPARK_HLAUNCH); } //HardCut rev limit for 2-step launch control.
|
||||
if (configPage6.launchEnabled && clutchTrigger && (currentStatus.clutchEngagedRPM < ((unsigned int)(configPage6.flatSArm) * 100)) && (currentStatus.RPM > ((unsigned int)(configPage6.lnchHardLim) * 100)) && (currentStatus.TPS >= configPage10.lnchCtrlTPS) ) { currentStatus.launchingHard = true; BIT_SET(currentStatus.spark, BIT_SPARK_HLAUNCH); } //HardCut rev limit for 2-step launch control.
|
||||
else { currentStatus.launchingHard = false; BIT_CLEAR(currentStatus.spark, BIT_SPARK_HLAUNCH); }
|
||||
|
||||
if(configPage3.flatSEnable && clutchTrigger && (currentStatus.RPM > ((unsigned int)(configPage3.flatSArm) * 100)) && (currentStatus.RPM > currentStatus.clutchEngagedRPM) ) { currentStatus.flatShiftingHard = true; }
|
||||
if(configPage6.flatSEnable && clutchTrigger && (currentStatus.RPM > ((unsigned int)(configPage6.flatSArm) * 100)) && (currentStatus.RPM > currentStatus.clutchEngagedRPM) ) { currentStatus.flatShiftingHard = true; }
|
||||
else { currentStatus.flatShiftingHard = false; }
|
||||
|
||||
//Boost cutoff is very similar to launchControl, but with a check against MAP rather than a switch
|
||||
if(configPage3.boostCutType && currentStatus.MAP > (configPage3.boostLimit * 2) ) //The boost limit is divided by 2 to allow a limit up to 511kPa
|
||||
if(configPage6.boostCutType && currentStatus.MAP > (configPage6.boostLimit * 2) ) //The boost limit is divided by 2 to allow a limit up to 511kPa
|
||||
{
|
||||
switch(configPage3.boostCutType)
|
||||
switch(configPage6.boostCutType)
|
||||
{
|
||||
case 1:
|
||||
BIT_SET(currentStatus.spark, BIT_SPARK_BOOSTCUT);
|
||||
|
@ -833,18 +866,18 @@ void loop()
|
|||
|
||||
#if defined(__AVR_ATmega1280__) || defined(__AVR_ATmega2560__) //ATmega2561 does not have Serial3
|
||||
//if Can interface is enabled then check for external data requests.
|
||||
if (configPage10.enable_candata_in) //if external data input is enabled
|
||||
if (configPage9.enable_candata_in) //if external data input is enabled
|
||||
{
|
||||
if (configPage10.enable_canbus == 1) // megas only support can via secondary serial
|
||||
if (configPage9.enable_canbus == 1) // megas only support can via secondary serial
|
||||
{
|
||||
for (byte caninChan = 0; caninChan <16 ; caninChan++)
|
||||
{
|
||||
currentStatus.current_caninchannel = caninChan;
|
||||
//currentStatus.canin[14] = currentStatus.current_caninchannel;
|
||||
currentStatus.canin[13] = ((configPage10.caninput_source_can_address[currentStatus.current_caninchannel]&2047)+0x100);
|
||||
if (BIT_CHECK(configPage10.caninput_sel,currentStatus.current_caninchannel)) //if current input channel bit is enabled
|
||||
currentStatus.canin[13] = ((configPage9.caninput_source_can_address[currentStatus.current_caninchannel]&2047)+0x100);
|
||||
if (BIT_CHECK(configPage9.caninput_sel,currentStatus.current_caninchannel)) //if current input channel bit is enabled
|
||||
{
|
||||
sendCancommand(2,0,currentStatus.current_caninchannel,0,((configPage10.caninput_source_can_address[currentStatus.current_caninchannel]&2047)+0x100));
|
||||
sendCancommand(2,0,currentStatus.current_caninchannel,0,((configPage9.caninput_source_can_address[currentStatus.current_caninchannel]&2047)+0x100));
|
||||
//send an R command for data from caninput_source_address[currentStatus.current_caninchannel]
|
||||
}
|
||||
}
|
||||
|
@ -853,20 +886,20 @@ void loop()
|
|||
|
||||
#elif defined(CORE_STM32) || defined(CORE_TEENSY)
|
||||
//if serial3io is enabled then check for serial3 requests.
|
||||
if (configPage10.enable_candata_in)
|
||||
if (configPage9.enable_candata_in)
|
||||
{
|
||||
for (byte caninChan = 0; caninChan <16 ; caninChan++)
|
||||
{
|
||||
currentStatus.current_caninchannel == caninChan;
|
||||
if (BIT_CHECK(configPage10.caninput_sel,currentStatus.current_caninchannel)) //if current input channel is enabled
|
||||
currentStatus.current_caninchannel = caninChan;
|
||||
if (BIT_CHECK(configPage9.caninput_sel,currentStatus.current_caninchannel)) //if current input channel is enabled
|
||||
{
|
||||
if (configPage10.enable_canbus == 1) //can via secondary serial
|
||||
if (configPage9.enable_canbus == 1) //can via secondary serial
|
||||
{
|
||||
sendCancommand(2,0,currentStatus.current_caninchannel,0,((configPage10.caninput_source_can_address[currentStatus.current_caninchannel]&2047)+256)); //send an R command for data from paramgroup[currentStatus.current_caninchannel]
|
||||
sendCancommand(2,0,currentStatus.current_caninchannel,0,((configPage9.caninput_source_can_address[currentStatus.current_caninchannel]&2047)+256)); //send an R command for data from paramgroup[currentStatus.current_caninchannel]
|
||||
}
|
||||
else if (configPage10.enable_canbus == 2) // can via internal can module
|
||||
else if (configPage9.enable_canbus == 2) // can via internal can module
|
||||
{
|
||||
sendCancommand(3,configPage10.speeduino_tsCanId,currentStatus.current_caninchannel,0,configPage10.caninput_source_can_address[currentStatus.current_caninchannel]); //send via localcanbus the command for data from paramgroup[currentStatus.current_caninchannel]
|
||||
sendCancommand(3,configPage9.speeduino_tsCanId,currentStatus.current_caninchannel,0,configPage9.caninput_source_can_address[currentStatus.current_caninchannel]); //send via localcanbus the command for data from paramgroup[currentStatus.current_caninchannel]
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -881,13 +914,13 @@ void loop()
|
|||
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.
|
||||
if(configPage6.iacAlgorithm == IAC_ALGORITHM_STEP_OL || configPage6.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 >= configPage4.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 > currentStatus.crankRPM) //Crank RPM stored in byte as RPM / 100
|
||||
{
|
||||
|
@ -896,7 +929,7 @@ void loop()
|
|||
if( BIT_CHECK(currentStatus.engine, BIT_ENGINE_CRANK) )
|
||||
{
|
||||
BIT_CLEAR(currentStatus.engine, BIT_ENGINE_CRANK); //clears the engine cranking bit
|
||||
if(configPage2.ignBypassEnabled) { digitalWrite(pinIgnBypass, HIGH); }
|
||||
if(configPage4.ignBypassEnabled) { digitalWrite(pinIgnBypass, HIGH); }
|
||||
}
|
||||
}
|
||||
else
|
||||
|
@ -904,7 +937,7 @@ void loop()
|
|||
BIT_SET(currentStatus.engine, BIT_ENGINE_CRANK);
|
||||
BIT_CLEAR(currentStatus.engine, BIT_ENGINE_RUN);
|
||||
currentStatus.runSecs = 0; //We're cranking (hopefully), so reset the engine run time to prompt ASE.
|
||||
if(configPage2.ignBypassEnabled) { digitalWrite(pinIgnBypass, LOW); }
|
||||
if(configPage4.ignBypassEnabled) { digitalWrite(pinIgnBypass, LOW); }
|
||||
}
|
||||
//END SETTING STATUSES
|
||||
//-----------------------------------------------------------------------------------------------------
|
||||
|
@ -913,7 +946,7 @@ void loop()
|
|||
//Calculate an injector pulsewidth from the VE
|
||||
currentStatus.corrections = correctionsFuel();
|
||||
lastAdvance = currentStatus.advance; //Store the previous advance value
|
||||
if (configPage1.algorithm == LOAD_SOURCE_MAP) //Check which fuelling algorithm is being used
|
||||
if (configPage2.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
|
||||
|
@ -931,14 +964,32 @@ void loop()
|
|||
|
||||
int injector1StartAngle = 0;
|
||||
int injector2StartAngle = 0;
|
||||
int injector3StartAngle = 0; //Currently used for 3 cylinder only
|
||||
int injector4StartAngle = 0; //Not used until sequential gets written
|
||||
int injector3StartAngle = 0;
|
||||
int injector4StartAngle = 0;
|
||||
int injector5StartAngle = 0; //For 5 cylinder testing
|
||||
#if INJ_CHANNELS >= 6
|
||||
int injector6StartAngle = 0;
|
||||
#endif
|
||||
#if INJ_CHANNELS >= 7
|
||||
int injector7StartAngle = 0;
|
||||
#endif
|
||||
#if INJ_CHANNELS >= 8
|
||||
int injector8StartAngle = 0;
|
||||
#endif
|
||||
int ignition1StartAngle = 0;
|
||||
int ignition2StartAngle = 0;
|
||||
int ignition3StartAngle = 0;
|
||||
int ignition4StartAngle = 0;
|
||||
int ignition5StartAngle = 0;
|
||||
#if IGN_CHANNELS >= 6
|
||||
int ignition6StartAngle = 0;
|
||||
#endif
|
||||
#if IGN_CHANNELS >= 7
|
||||
int ignition7StartAngle = 0;
|
||||
#endif
|
||||
#if IGN_CHANNELS >= 8
|
||||
int ignition8StartAngle = 0;
|
||||
#endif
|
||||
//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;
|
||||
|
@ -956,14 +1007,14 @@ void loop()
|
|||
{
|
||||
deltaToothCount = toothCurrentCount;
|
||||
int angle1, angle2; //These represent the crank angles that are travelled for the last 2 pulses
|
||||
if(configPage2.TrigPattern == 4)
|
||||
if(configPage4.TrigPattern == 4)
|
||||
{
|
||||
//Special case for 70/110 pattern on 4g63
|
||||
angle2 = triggerToothAngle; //Angle 2 is the most recent
|
||||
if (angle2 == 70) { angle1 = 110; }
|
||||
else { angle1 = 70; }
|
||||
}
|
||||
else if(configPage2.TrigPattern == 0)
|
||||
else if(configPage4.TrigPattern == 0)
|
||||
{
|
||||
//Special case for missing tooth decoder where the missing tooth was one of the last 2 seen
|
||||
if(toothCurrentCount == 1) { angle2 = 2*triggerToothAngle; angle1 = triggerToothAngle; }
|
||||
|
@ -1004,18 +1055,18 @@ void loop()
|
|||
}
|
||||
|
||||
//Check that the duty cycle of the chosen pulsewidth isn't too high.
|
||||
unsigned long pwLimit = percentage(configPage1.dutyLim, revolutionTime); //The pulsewidth limit is determined to be the duty cycle limit (Eg 85%) by the total time it takes to perform 1 revolution
|
||||
unsigned long pwLimit = percentage(configPage2.dutyLim, revolutionTime); //The pulsewidth limit is determined to be the duty cycle limit (Eg 85%) by the total time it takes to perform 1 revolution
|
||||
if (CRANK_ANGLE_MAX_INJ == 720) { pwLimit = pwLimit * 2; } //For sequential, the maximum pulse time is double (2 revolutions). Wouldn't work for 2 stroke...
|
||||
//Apply the pwLimit if staging is dsiabled and engine is not cranking
|
||||
if( (!BIT_CHECK(currentStatus.engine, BIT_ENGINE_CRANK)) && configPage11.stagingEnabled == false) { if (currentStatus.PW1 > pwLimit) { currentStatus.PW1 = pwLimit; } }
|
||||
if( (!BIT_CHECK(currentStatus.engine, BIT_ENGINE_CRANK)) && configPage10.stagingEnabled == false) { if (currentStatus.PW1 > pwLimit) { currentStatus.PW1 = pwLimit; } }
|
||||
|
||||
//Calculate staging pulsewidths if used
|
||||
if(configPage11.stagingEnabled == true)
|
||||
if(configPage10.stagingEnabled == true)
|
||||
{
|
||||
//Scale the 'full' pulsewidth by each of the injector capacities
|
||||
uint32_t tempPW1 = ((unsigned long)currentStatus.PW1 * staged_req_fuel_mult_pri) / 100;
|
||||
|
||||
if(configPage11.stagingMode == STAGING_MODE_TABLE)
|
||||
if(configPage10.stagingMode == STAGING_MODE_TABLE)
|
||||
{
|
||||
uint32_t tempPW3 = ((unsigned long)currentStatus.PW1 * staged_req_fuel_mult_sec) / 100; //This is ONLY needed in in table mode. Auto mode only calculates the difference.
|
||||
|
||||
|
@ -1025,7 +1076,7 @@ void loop()
|
|||
if(stagingSplit > 0) { currentStatus.PW3 = (stagingSplit * tempPW3) / 100; }
|
||||
else { currentStatus.PW3 = 0; }
|
||||
}
|
||||
else if(configPage11.stagingMode == STAGING_MODE_AUTO)
|
||||
else if(configPage10.stagingMode == STAGING_MODE_AUTO)
|
||||
{
|
||||
currentStatus.PW1 = tempPW1;
|
||||
//If automatic mode, the primary injectors are used all the way up to their limit (COnfigured by the pulsewidth limit setting)
|
||||
|
@ -1045,53 +1096,53 @@ void loop()
|
|||
currentStatus.PW4 = currentStatus.PW3;
|
||||
}
|
||||
//If staging is off, all the pulse widths are set the same (Sequential adjustments will be made below)
|
||||
else { currentStatus.PW2 = currentStatus.PW3 = currentStatus.PW4 = currentStatus.PW1; } // Initial state is for all pulsewidths to be the same (This gets changed below)
|
||||
else { currentStatus.PW2 = currentStatus.PW3 = currentStatus.PW4 = currentStatus.PW5 = currentStatus.PW6 = currentStatus.PW7 = currentStatus.PW1; } // Initial state is for all pulsewidths to be the same (This gets changed below)
|
||||
|
||||
//***********************************************************************************************
|
||||
//BEGIN INJECTION TIMING
|
||||
//Determine next firing angles
|
||||
if(!configPage1.indInjAng) {configPage1.inj4Ang = configPage1.inj3Ang = configPage1.inj2Ang = configPage1.inj1Ang;} //Forcing all injector close angles to be the same.
|
||||
if(!configPage2.indInjAng) {configPage2.inj4Ang = configPage2.inj3Ang = configPage2.inj2Ang = configPage2.inj1Ang;} //Forcing all injector close angles to be the same.
|
||||
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
|
||||
injector1StartAngle = configPage2.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)
|
||||
switch (configPage2.nCylinders)
|
||||
{
|
||||
//2 cylinders
|
||||
case 2:
|
||||
injector2StartAngle = (configPage1.inj2Ang + channel2InjDegrees - ( PWdivTimerPerDegree ));
|
||||
injector2StartAngle = (configPage2.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 ));
|
||||
injector2StartAngle = (configPage2.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 ));
|
||||
injector3StartAngle = (configPage2.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 ));
|
||||
injector2StartAngle = (configPage2.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)
|
||||
if(configPage2.injLayout == INJ_SEQUENTIAL)
|
||||
{
|
||||
injector3StartAngle = (configPage1.inj3Ang + channel3InjDegrees - ( PWdivTimerPerDegree ));
|
||||
injector3StartAngle = (configPage2.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 ));
|
||||
injector4StartAngle = (configPage2.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)
|
||||
if(configPage6.fuelTrimEnabled)
|
||||
{
|
||||
unsigned long pw1percent = 100 + (byte)get3DTableValue(&trim1Table, currentStatus.MAP, currentStatus.RPM) - OFFSET_FUELTRIM;
|
||||
unsigned long pw2percent = 100 + (byte)get3DTableValue(&trim2Table, currentStatus.MAP, currentStatus.RPM) - OFFSET_FUELTRIM;
|
||||
|
@ -1104,10 +1155,10 @@ void loop()
|
|||
if (pw4percent != 100) { currentStatus.PW4 = (pw4percent * currentStatus.PW4) / 100; }
|
||||
}
|
||||
}
|
||||
else if(configPage11.stagingEnabled == true)
|
||||
else if(configPage10.stagingEnabled == true)
|
||||
{
|
||||
PWdivTimerPerDegree = div(currentStatus.PW3, timePerDegree).quot; //Need to redo this for PW3 as it will be dramatically different to PW1 when staging
|
||||
injector3StartAngle = configPage1.inj3Ang - ( 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
|
||||
injector3StartAngle = configPage2.inj3Ang - ( 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(injector3StartAngle < 0) {injector3StartAngle += CRANK_ANGLE_MAX_INJ;}
|
||||
if(injector3StartAngle > CRANK_ANGLE_MAX_INJ) {injector3StartAngle -= CRANK_ANGLE_MAX_INJ;}
|
||||
|
||||
|
@ -1118,29 +1169,40 @@ void loop()
|
|||
break;
|
||||
//5 cylinders
|
||||
case 5:
|
||||
injector2StartAngle = (configPage1.inj2Ang + channel2InjDegrees - ( PWdivTimerPerDegree ));
|
||||
injector2StartAngle = (configPage2.inj2Ang + channel2InjDegrees - ( PWdivTimerPerDegree ));
|
||||
if(injector2StartAngle > CRANK_ANGLE_MAX_INJ) {injector2StartAngle -= CRANK_ANGLE_MAX_INJ;}
|
||||
injector3StartAngle = (configPage1.inj3Ang + channel3InjDegrees - ( PWdivTimerPerDegree ));
|
||||
injector3StartAngle = (configPage2.inj3Ang + channel3InjDegrees - ( PWdivTimerPerDegree ));
|
||||
if(injector3StartAngle > CRANK_ANGLE_MAX_INJ) {injector3StartAngle -= CRANK_ANGLE_MAX_INJ;}
|
||||
injector4StartAngle = (configPage1.inj4Ang + channel4InjDegrees - ( PWdivTimerPerDegree ));
|
||||
injector4StartAngle = (configPage2.inj4Ang + channel4InjDegrees - ( PWdivTimerPerDegree ));
|
||||
if(injector4StartAngle > CRANK_ANGLE_MAX_INJ) {injector4StartAngle -= CRANK_ANGLE_MAX_INJ;}
|
||||
injector5StartAngle = (configPage1.inj1Ang + channel5InjDegrees - ( PWdivTimerPerDegree ));
|
||||
injector5StartAngle = (configPage2.inj1Ang + channel5InjDegrees - ( PWdivTimerPerDegree ));
|
||||
if(injector5StartAngle > CRANK_ANGLE_MAX_INJ) {injector5StartAngle -= CRANK_ANGLE_MAX_INJ;}
|
||||
break;
|
||||
//6 cylinders
|
||||
case 6:
|
||||
injector2StartAngle = (configPage1.inj2Ang + channel2InjDegrees - ( PWdivTimerPerDegree ));
|
||||
injector2StartAngle = (configPage2.inj2Ang + channel2InjDegrees - ( PWdivTimerPerDegree ));
|
||||
if(injector2StartAngle > CRANK_ANGLE_MAX_INJ) {injector2StartAngle -= CRANK_ANGLE_MAX_INJ;}
|
||||
injector3StartAngle = (configPage1.inj3Ang + channel3InjDegrees - ( PWdivTimerPerDegree ));
|
||||
injector3StartAngle = (configPage2.inj3Ang + channel3InjDegrees - ( PWdivTimerPerDegree ));
|
||||
if(injector3StartAngle > CRANK_ANGLE_MAX_INJ) {injector3StartAngle -= CRANK_ANGLE_MAX_INJ;}
|
||||
#if INJ_CHANNELS >= 6
|
||||
if(configPage2.injLayout == INJ_SEQUENTIAL)
|
||||
{
|
||||
injector4StartAngle = (configPage2.inj1Ang + channel4InjDegrees - ( PWdivTimerPerDegree ));
|
||||
if(injector4StartAngle > CRANK_ANGLE_MAX_INJ) {injector4StartAngle -= CRANK_ANGLE_MAX_INJ;}
|
||||
injector5StartAngle = (configPage2.inj2Ang + channel5InjDegrees - ( PWdivTimerPerDegree ));
|
||||
if(injector5StartAngle > CRANK_ANGLE_MAX_INJ) {injector5StartAngle -= CRANK_ANGLE_MAX_INJ;}
|
||||
injector6StartAngle = (configPage2.inj3Ang + channel6InjDegrees - ( PWdivTimerPerDegree ));
|
||||
if(injector6StartAngle > CRANK_ANGLE_MAX_INJ) {injector6StartAngle -= CRANK_ANGLE_MAX_INJ;}
|
||||
}
|
||||
#endif
|
||||
break;
|
||||
//8 cylinders
|
||||
case 8:
|
||||
injector2StartAngle = (configPage1.inj2Ang + channel2InjDegrees - ( PWdivTimerPerDegree ));
|
||||
injector2StartAngle = (configPage2.inj2Ang + channel2InjDegrees - ( PWdivTimerPerDegree ));
|
||||
if(injector2StartAngle > CRANK_ANGLE_MAX_INJ) {injector2StartAngle -= CRANK_ANGLE_MAX_INJ;}
|
||||
injector3StartAngle = (configPage1.inj3Ang + channel3InjDegrees - ( PWdivTimerPerDegree ));
|
||||
injector3StartAngle = (configPage2.inj3Ang + channel3InjDegrees - ( PWdivTimerPerDegree ));
|
||||
if(injector3StartAngle > CRANK_ANGLE_MAX_INJ) {injector3StartAngle -= CRANK_ANGLE_MAX_INJ;}
|
||||
injector4StartAngle = (configPage1.inj4Ang + channel4InjDegrees - ( PWdivTimerPerDegree ));
|
||||
injector4StartAngle = (configPage2.inj4Ang + channel4InjDegrees - ( PWdivTimerPerDegree ));
|
||||
if(injector4StartAngle > CRANK_ANGLE_MAX_INJ) {injector4StartAngle -= CRANK_ANGLE_MAX_INJ;}
|
||||
break;
|
||||
//Will hit the default case on 1 cylinder or >8 cylinders. Do nothing in these cases
|
||||
|
@ -1150,14 +1212,14 @@ void loop()
|
|||
|
||||
//***********************************************************************************************
|
||||
//| BEGIN IGNITION CALCULATIONS
|
||||
if (currentStatus.RPM > ((unsigned int)(configPage2.HardRevLim) * 100) ) { BIT_SET(currentStatus.spark, BIT_SPARK_HRDLIM); } //Hardcut RPM limit
|
||||
if (currentStatus.RPM > ((unsigned int)(configPage4.HardRevLim) * 100) ) { BIT_SET(currentStatus.spark, BIT_SPARK_HRDLIM); } //Hardcut RPM limit
|
||||
else { BIT_CLEAR(currentStatus.spark, BIT_SPARK_HRDLIM); }
|
||||
|
||||
|
||||
//Set dwell
|
||||
//Dwell is stored as ms * 10. ie Dwell of 4.3ms would be 43 in configPage2. This number therefore needs to be multiplied by 100 to get dwell in uS
|
||||
if ( BIT_CHECK(currentStatus.engine, BIT_ENGINE_CRANK) ) { currentStatus.dwell = (configPage2.dwellCrank * 100); }
|
||||
else { currentStatus.dwell = (configPage2.dwellRun * 100); }
|
||||
//Dwell is stored as ms * 10. ie Dwell of 4.3ms would be 43 in configPage4. This number therefore needs to be multiplied by 100 to get dwell in uS
|
||||
if ( BIT_CHECK(currentStatus.engine, BIT_ENGINE_CRANK) ) { currentStatus.dwell = (configPage4.dwellCrank * 100); }
|
||||
else { currentStatus.dwell = (configPage4.dwellRun * 100); }
|
||||
currentStatus.dwell = correctionsDwell(currentStatus.dwell);
|
||||
|
||||
int dwellAngle = uSToDegrees(currentStatus.dwell); //Convert the dwell time to dwell angle based on the current engine speed
|
||||
|
@ -1169,7 +1231,7 @@ void loop()
|
|||
if(ignition1StartAngle < 0) {ignition1StartAngle += CRANK_ANGLE_MAX_IGN;}
|
||||
|
||||
//This test for more cylinders and do the same thing
|
||||
switch (configPage1.nCylinders)
|
||||
switch (configPage2.nCylinders)
|
||||
{
|
||||
//2 cylinders
|
||||
case 2:
|
||||
|
@ -1193,7 +1255,7 @@ void loop()
|
|||
if(ignition2StartAngle > CRANK_ANGLE_MAX_IGN) {ignition2StartAngle -= CRANK_ANGLE_MAX_IGN;}
|
||||
if(ignition2StartAngle < 0) {ignition2StartAngle += CRANK_ANGLE_MAX_IGN;}
|
||||
|
||||
if(configPage2.sparkMode == IGN_MODE_SEQUENTIAL)
|
||||
if(configPage4.sparkMode == IGN_MODE_SEQUENTIAL)
|
||||
{
|
||||
ignition3EndAngle = channel3IgnDegrees + CRANK_ANGLE_MAX_IGN - currentStatus.advance;
|
||||
ignition3StartAngle = ignition3EndAngle - dwellAngle;
|
||||
|
@ -1203,12 +1265,12 @@ void loop()
|
|||
ignition4StartAngle = ignition4EndAngle - dwellAngle;
|
||||
if(ignition4StartAngle > CRANK_ANGLE_MAX_IGN) {ignition4StartAngle -= CRANK_ANGLE_MAX_IGN;}
|
||||
}
|
||||
else if(configPage2.sparkMode == IGN_MODE_ROTARY)
|
||||
else if(configPage4.sparkMode == IGN_MODE_ROTARY)
|
||||
{
|
||||
if(configPage11.rotaryType == ROTARY_IGN_FC)
|
||||
if(configPage10.rotaryType == ROTARY_IGN_FC)
|
||||
{
|
||||
byte splitDegrees = 0;
|
||||
if (configPage1.algorithm == LOAD_SOURCE_MAP) { splitDegrees = table2D_getValue(&rotarySplitTable, currentStatus.MAP/2); }
|
||||
if (configPage2.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
|
||||
|
@ -1274,7 +1336,7 @@ void loop()
|
|||
}
|
||||
//If ignition timing is being tracked per tooth, perform the calcs to get the end teeth
|
||||
//This only needs to be run if the advance figure has changed, otherwise the end teeth will still be the same
|
||||
if( (configPage1.perToothIgn == true) && (lastAdvance != currentStatus.advance) ) { triggerSetEndTeeth(); }
|
||||
if( (configPage2.perToothIgn == true) && (lastAdvance != currentStatus.advance) ) { triggerSetEndTeeth(); }
|
||||
|
||||
//***********************************************************************************************
|
||||
//| BEGIN FUEL SCHEDULES
|
||||
|
@ -1286,6 +1348,7 @@ void loop()
|
|||
int crankAngle = getCrankAngle(timePerDegree);
|
||||
if (crankAngle > CRANK_ANGLE_MAX_INJ ) { crankAngle -= 360; }
|
||||
|
||||
#if INJ_CHANNELS >= 1
|
||||
if (fuelOn && !BIT_CHECK(currentStatus.status1, BIT_STATUS1_BOOSTCUT))
|
||||
{
|
||||
if(currentStatus.PW1 >= inj_opentime_uS)
|
||||
|
@ -1299,6 +1362,7 @@ void loop()
|
|||
);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
/*-----------------------------------------------------------------------------------------
|
||||
| A Note on tempCrankAngle and tempStartAngle:
|
||||
|
@ -1311,6 +1375,7 @@ void loop()
|
|||
| This will very likely need to be rewritten when sequential is enabled
|
||||
|------------------------------------------------------------------------------------------
|
||||
*/
|
||||
#if INJ_CHANNELS >= 2
|
||||
if( (channel2InjEnabled) && (currentStatus.PW2 >= inj_opentime_uS) )
|
||||
{
|
||||
tempCrankAngle = crankAngle - channel2InjDegrees;
|
||||
|
@ -1326,7 +1391,9 @@ void loop()
|
|||
);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
#if INJ_CHANNELS >= 3
|
||||
if( (channel3InjEnabled) && (currentStatus.PW3 >= inj_opentime_uS) )
|
||||
{
|
||||
tempCrankAngle = crankAngle - channel3InjDegrees;
|
||||
|
@ -1342,7 +1409,9 @@ void loop()
|
|||
);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
#if INJ_CHANNELS >= 4
|
||||
if( (channel4InjEnabled) && (currentStatus.PW4 >= inj_opentime_uS) )
|
||||
{
|
||||
tempCrankAngle = crankAngle - channel4InjDegrees;
|
||||
|
@ -1358,8 +1427,10 @@ void loop()
|
|||
);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
if(channel5InjEnabled)
|
||||
#if INJ_CHANNELS >= 5
|
||||
if( (channel5InjEnabled) && (currentStatus.PW4 >= inj_opentime_uS) )
|
||||
{
|
||||
tempCrankAngle = crankAngle - channel5InjDegrees;
|
||||
if( tempCrankAngle < 0) { tempCrankAngle += CRANK_ANGLE_MAX_INJ; }
|
||||
|
@ -1381,20 +1452,75 @@ void loop()
|
|||
);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
#if INJ_CHANNELS >= 6
|
||||
if( (channel6InjEnabled) && (currentStatus.PW6 >= inj_opentime_uS) )
|
||||
{
|
||||
tempCrankAngle = crankAngle - channel6InjDegrees;
|
||||
if( tempCrankAngle < 0) { tempCrankAngle += CRANK_ANGLE_MAX_INJ; }
|
||||
tempStartAngle = injector6StartAngle - channel6InjDegrees;
|
||||
if ( tempStartAngle < 0) { tempStartAngle += CRANK_ANGLE_MAX_INJ; }
|
||||
if ( (tempStartAngle <= tempCrankAngle) && (fuelSchedule6.Status == RUNNING) ) { tempStartAngle += CRANK_ANGLE_MAX_INJ; }
|
||||
if ( tempStartAngle > tempCrankAngle )
|
||||
{
|
||||
setFuelSchedule6(
|
||||
((unsigned long)(tempStartAngle - tempCrankAngle) * (unsigned long)timePerDegree),
|
||||
(unsigned long)currentStatus.PW6
|
||||
);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
#if INJ_CHANNELS >= 7
|
||||
if( (channel7InjEnabled) && (currentStatus.PW7 >= inj_opentime_uS) )
|
||||
{
|
||||
tempCrankAngle = crankAngle - channel7InjDegrees;
|
||||
if( tempCrankAngle < 0) { tempCrankAngle += CRANK_ANGLE_MAX_INJ; }
|
||||
tempStartAngle = injector7StartAngle - channel7InjDegrees;
|
||||
if ( tempStartAngle < 0) { tempStartAngle += CRANK_ANGLE_MAX_INJ; }
|
||||
if ( (tempStartAngle <= tempCrankAngle) && (fuelSchedule7.Status == RUNNING) ) { tempStartAngle += CRANK_ANGLE_MAX_INJ; }
|
||||
if ( tempStartAngle > tempCrankAngle )
|
||||
{
|
||||
setFuelSchedule7(
|
||||
((unsigned long)(tempStartAngle - tempCrankAngle) * (unsigned long)timePerDegree),
|
||||
(unsigned long)currentStatus.PW7
|
||||
);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
#if INJ_CHANNELS >= 8
|
||||
if( (channel8InjEnabled) && (currentStatus.PW8 >= inj_opentime_uS) )
|
||||
{
|
||||
tempCrankAngle = crankAngle - channel8InjDegrees;
|
||||
if( tempCrankAngle < 0) { tempCrankAngle += CRANK_ANGLE_MAX_INJ; }
|
||||
tempStartAngle = injector8StartAngle - channel8InjDegrees;
|
||||
if ( tempStartAngle < 0) { tempStartAngle += CRANK_ANGLE_MAX_INJ; }
|
||||
if ( (tempStartAngle <= tempCrankAngle) && (fuelSchedule8.Status == RUNNING) ) { tempStartAngle += CRANK_ANGLE_MAX_INJ; }
|
||||
if ( tempStartAngle > tempCrankAngle )
|
||||
{
|
||||
setFuelSchedule8(
|
||||
((unsigned long)(tempStartAngle - tempCrankAngle) * (unsigned long)timePerDegree),
|
||||
(unsigned long)currentStatus.PW8
|
||||
);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
//***********************************************************************************************
|
||||
//| BEGIN IGNITION SCHEDULES
|
||||
//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) && (decoderHasFixedCrankingTiming == true) ) { fixedCrankingOverride = currentStatus.dwell * 3; }
|
||||
if ( configPage4.ignCranklock && BIT_CHECK(currentStatus.engine, BIT_ENGINE_CRANK) && (decoderHasFixedCrankingTiming == true) ) { 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:
|
||||
//Check for any of the hard cut rev limits being on
|
||||
if(currentStatus.launchingHard || BIT_CHECK(currentStatus.spark, BIT_SPARK_BOOSTCUT) || BIT_CHECK(currentStatus.spark, BIT_SPARK_HRDLIM) || currentStatus.flatShiftingHard)
|
||||
{
|
||||
if(configPage1.hardCutType == HARD_CUT_FULL) { ignitionOn = false; }
|
||||
if(configPage2.hardCutType == HARD_CUT_FULL) { ignitionOn = false; }
|
||||
else { curRollingCut = ( (currentStatus.startRevolutions / 2) % maxIgnOutputs) + 1; } //Rolls through each of the active ignition channels based on how many revolutions have taken place
|
||||
}
|
||||
else { curRollingCut = 0; } //Disables the rolling hard cut
|
||||
|
@ -1427,7 +1553,7 @@ void loop()
|
|||
}
|
||||
}
|
||||
/*
|
||||
if( (ignitionSchedule1.Status == RUNNING) && (ignition1EndAngle > crankAngle) && configPage2.StgCycles == 0)
|
||||
if( (ignitionSchedule1.Status == RUNNING) && (ignition1EndAngle > crankAngle) && configPage4.StgCycles == 0)
|
||||
{
|
||||
unsigned long uSToEnd = 0;
|
||||
|
||||
|
@ -1529,7 +1655,17 @@ void loop()
|
|||
}
|
||||
}
|
||||
} //Ignition schedules on
|
||||
|
||||
if (!BIT_CHECK(currentStatus.status3, BIT_STATUS3_RESET_PREVENT) && resetControl == RESET_CONTROL_PREVENT_WHEN_RUNNING) {
|
||||
//Reset prevention is supposed to be on while the engine is running but isn't. Fix that.
|
||||
digitalWrite(pinResetControl, HIGH);
|
||||
BIT_SET(currentStatus.status3, BIT_STATUS3_RESET_PREVENT);
|
||||
}
|
||||
} //Has sync and RPM
|
||||
else if (BIT_CHECK(currentStatus.status3, BIT_STATUS3_RESET_PREVENT) && resetControl == RESET_CONTROL_PREVENT_WHEN_RUNNING) {
|
||||
digitalWrite(pinResetControl, LOW);
|
||||
BIT_CLEAR(currentStatus.status3, BIT_STATUS3_RESET_PREVENT);
|
||||
}
|
||||
} //loop()
|
||||
|
||||
/*
|
||||
|
@ -1551,20 +1687,20 @@ static inline unsigned int PW(int REQ_FUEL, byte VE, long MAP, int corrections,
|
|||
|
||||
//100% float free version, does sacrifice a little bit of accuracy, but not much.
|
||||
iVE = ((unsigned int)VE << 7) / 100;
|
||||
if ( configPage1.multiplyMAP == true ) {
|
||||
if ( configPage2.multiplyMAP == true ) {
|
||||
iMAP = ((unsigned int)MAP << 7) / currentStatus.baro; //Include multiply MAP (vs baro) if enabled
|
||||
}
|
||||
if ( (configPage1.includeAFR == true) && (configPage3.egoType == 2)) {
|
||||
if ( (configPage2.includeAFR == true) && (configPage6.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 == true ) {
|
||||
if ( configPage2.multiplyMAP == true ) {
|
||||
intermediate = (intermediate * (unsigned long)iMAP) >> 7;
|
||||
}
|
||||
if ( (configPage1.includeAFR == true) && (configPage3.egoType == 2) ) {
|
||||
if ( (configPage2.includeAFR == true) && (configPage6.egoType == 2) ) {
|
||||
intermediate = (intermediate * (unsigned long)iAFR) >> 7; //EGO type must be set to wideband for this to be used
|
||||
}
|
||||
intermediate = (intermediate * (unsigned long)iCorrections) >> 7;
|
||||
|
@ -1579,3 +1715,5 @@ static inline unsigned int PW(int REQ_FUEL, byte VE, long MAP, int corrections,
|
|||
}
|
||||
return (unsigned int)(intermediate);
|
||||
}
|
||||
|
||||
#endif //Unit testing scope guard
|
||||
|
|
|
@ -88,48 +88,48 @@ Current layout of EEPROM data (Version 3) is as follows (All sizes are in bytes)
|
|||
#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_CONFIG7_XSIZE1 1255
|
||||
#define EEPROM_CONFIG7_YSIZE1 1256
|
||||
#define EEPROM_CONFIG7_MAP1 1257
|
||||
#define EEPROM_CONFIG7_XBINS1 1321
|
||||
#define EEPROM_CONFIG7_YBINS1 1329
|
||||
#define EEPROM_CONFIG7_XSIZE2 1337
|
||||
#define EEPROM_CONFIG7_YSIZE2 1338
|
||||
#define EEPROM_CONFIG7_MAP2 1339
|
||||
#define EEPROM_CONFIG7_XBINS2 1403
|
||||
#define EEPROM_CONFIG7_YBINS2 1411
|
||||
|
||||
#define EEPROM_CONFIG8_XSIZE3 1419
|
||||
#define EEPROM_CONFIG8_YSIZE3 1420
|
||||
#define EEPROM_CONFIG8_MAP3 1421
|
||||
#define EEPROM_CONFIG7_XSIZE3 1419
|
||||
#define EEPROM_CONFIG7_YSIZE3 1420
|
||||
#define EEPROM_CONFIG7_MAP3 1421
|
||||
|
||||
#define EEPROM_CONFIG8_XBINS3 1485
|
||||
#define EEPROM_CONFIG8_YBINS3 1493
|
||||
#define EEPROM_CONFIG8_END 1501
|
||||
#define EEPROM_CONFIG9_XSIZE1 1501
|
||||
#define EEPROM_CONFIG9_YSIZE1 1502
|
||||
#define EEPROM_CONFIG9_MAP1 1503
|
||||
#define EEPROM_CONFIG9_XBINS1 1539
|
||||
#define EEPROM_CONFIG9_YBINS1 1545
|
||||
#define EEPROM_CONFIG9_XSIZE2 1551
|
||||
#define EEPROM_CONFIG9_YSIZE2 1552
|
||||
#define EEPROM_CONFIG9_MAP2 1553
|
||||
#define EEPROM_CONFIG9_XBINS2 1589
|
||||
#define EEPROM_CONFIG9_YBINS2 1595
|
||||
#define EEPROM_CONFIG9_XSIZE3 1601
|
||||
#define EEPROM_CONFIG9_YSIZE3 1602
|
||||
#define EEPROM_CONFIG9_MAP3 1603
|
||||
#define EEPROM_CONFIG9_XBINS3 1639
|
||||
#define EEPROM_CONFIG9_YBINS3 1645
|
||||
#define EEPROM_CONFIG9_XSIZE4 1651
|
||||
#define EEPROM_CONFIG9_YSIZE4 1652
|
||||
#define EEPROM_CONFIG9_MAP4 1653
|
||||
#define EEPROM_CONFIG9_XBINS4 1689
|
||||
#define EEPROM_CONFIG9_YBINS4 1695
|
||||
#define EEPROM_CONFIG10_START 1710
|
||||
#define EEPROM_CONFIG10_END 1838
|
||||
#define EEPROM_CONFIG11_START 1838
|
||||
#define EEPROM_CONFIG11_END 2030
|
||||
#define EEPROM_CONFIG7_XBINS3 1485
|
||||
#define EEPROM_CONFIG7_YBINS3 1493
|
||||
#define EEPROM_CONFIG7_END 1501
|
||||
#define EEPROM_CONFIG8_XSIZE1 1501
|
||||
#define EEPROM_CONFIG8_YSIZE1 1502
|
||||
#define EEPROM_CONFIG8_MAP1 1503
|
||||
#define EEPROM_CONFIG8_XBINS1 1539
|
||||
#define EEPROM_CONFIG8_YBINS1 1545
|
||||
#define EEPROM_CONFIG8_XSIZE2 1551
|
||||
#define EEPROM_CONFIG8_YSIZE2 1552
|
||||
#define EEPROM_CONFIG8_MAP2 1553
|
||||
#define EEPROM_CONFIG8_XBINS2 1589
|
||||
#define EEPROM_CONFIG8_YBINS2 1595
|
||||
#define EEPROM_CONFIG8_XSIZE3 1601
|
||||
#define EEPROM_CONFIG8_YSIZE3 1602
|
||||
#define EEPROM_CONFIG8_MAP3 1603
|
||||
#define EEPROM_CONFIG8_XBINS3 1639
|
||||
#define EEPROM_CONFIG8_YBINS3 1645
|
||||
#define EEPROM_CONFIG8_XSIZE4 1651
|
||||
#define EEPROM_CONFIG8_YSIZE4 1652
|
||||
#define EEPROM_CONFIG8_MAP4 1653
|
||||
#define EEPROM_CONFIG8_XBINS4 1689
|
||||
#define EEPROM_CONFIG8_YBINS4 1695
|
||||
#define EEPROM_CONFIG9_START 1710
|
||||
#define EEPROM_CONFIG9_END 1838
|
||||
#define EEPROM_CONFIG10_START 1838
|
||||
#define EEPROM_CONFIG10_END 2030
|
||||
|
||||
//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
|
||||
|
|
|
@ -83,7 +83,7 @@ void writeConfig(byte tableNum)
|
|||
| Config page 2 (See storage.h for data layout)
|
||||
| 64 byte long config table
|
||||
-----------------------------------------------------*/
|
||||
pnt_configPage = (byte *)&configPage1; //Create a pointer to Page 2 in memory
|
||||
pnt_configPage = (byte *)&configPage2; //Create a pointer to Page 2 in memory
|
||||
for(int x=EEPROM_CONFIG2_START; x<EEPROM_CONFIG2_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.
|
||||
|
@ -138,7 +138,7 @@ void writeConfig(byte tableNum)
|
|||
| Config page 2 (See storage.h for data layout)
|
||||
| 64 byte long config table
|
||||
-----------------------------------------------------*/
|
||||
pnt_configPage = (byte *)&configPage2; //Create a pointer to Page 2 in memory
|
||||
pnt_configPage = (byte *)&configPage4; //Create a pointer to Page 2 in memory
|
||||
for(int x=EEPROM_CONFIG4_START; x<EEPROM_CONFIG4_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.
|
||||
|
@ -190,7 +190,7 @@ void writeConfig(byte tableNum)
|
|||
| Config page 3 (See storage.h for data layout)
|
||||
| 64 byte long config table
|
||||
-----------------------------------------------------*/
|
||||
pnt_configPage = (byte *)&configPage3; //Create a pointer to Page 3 in memory
|
||||
pnt_configPage = (byte *)&configPage6; //Create a pointer to Page 3 in memory
|
||||
for(int x=EEPROM_CONFIG6_START; x<EEPROM_CONFIG6_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.
|
||||
|
@ -208,53 +208,53 @@ void writeConfig(byte tableNum)
|
|||
| 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); 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
|
||||
if(EEPROM.read(EEPROM_CONFIG8_XSIZE3) != stagingTable.xSize) { EEPROM.write(EEPROM_CONFIG8_XSIZE3,stagingTable.xSize); writeCounter++; } //Write the staging Table RPM dimension size
|
||||
if(EEPROM.read(EEPROM_CONFIG8_YSIZE3) != stagingTable.ySize) { EEPROM.write(EEPROM_CONFIG8_YSIZE3,stagingTable.ySize); writeCounter++; } //Write the staging Table MAP/TPS dimension size
|
||||
if(EEPROM.read(EEPROM_CONFIG7_XSIZE1) != boostTable.xSize) { EEPROM.write(EEPROM_CONFIG7_XSIZE1,boostTable.xSize); writeCounter++; } //Write the boost Table RPM dimension size
|
||||
if(EEPROM.read(EEPROM_CONFIG7_YSIZE1) != boostTable.ySize) { EEPROM.write(EEPROM_CONFIG7_YSIZE1,boostTable.ySize); writeCounter++; } //Write the boost Table MAP/TPS dimension size
|
||||
if(EEPROM.read(EEPROM_CONFIG7_XSIZE2) != vvtTable.xSize) { EEPROM.write(EEPROM_CONFIG7_XSIZE2,vvtTable.xSize); writeCounter++; } //Write the vvt Table RPM dimension size
|
||||
if(EEPROM.read(EEPROM_CONFIG7_YSIZE2) != vvtTable.ySize) { EEPROM.write(EEPROM_CONFIG7_YSIZE2,vvtTable.ySize); writeCounter++; } //Write the vvt Table MAP/TPS dimension size
|
||||
if(EEPROM.read(EEPROM_CONFIG7_XSIZE3) != stagingTable.xSize) { EEPROM.write(EEPROM_CONFIG7_XSIZE3,stagingTable.xSize); writeCounter++; } //Write the staging Table RPM dimension size
|
||||
if(EEPROM.read(EEPROM_CONFIG7_YSIZE3) != stagingTable.ySize) { EEPROM.write(EEPROM_CONFIG7_YSIZE3,stagingTable.ySize); writeCounter++; } //Write the staging Table MAP/TPS dimension size
|
||||
|
||||
y = EEPROM_CONFIG8_MAP2; //We do the 3 maps together in the same loop
|
||||
z = EEPROM_CONFIG8_MAP3;
|
||||
for(int x=EEPROM_CONFIG8_MAP1; x<EEPROM_CONFIG8_XBINS1; x++)
|
||||
y = EEPROM_CONFIG7_MAP2; //We do the 3 maps together in the same loop
|
||||
z = EEPROM_CONFIG7_MAP3;
|
||||
for(int x=EEPROM_CONFIG7_MAP1; x<EEPROM_CONFIG7_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;
|
||||
offset = x - EEPROM_CONFIG7_MAP1;
|
||||
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;
|
||||
offset = y - EEPROM_CONFIG7_MAP2;
|
||||
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
|
||||
offset = z - EEPROM_CONFIG8_MAP3;
|
||||
offset = z - EEPROM_CONFIG7_MAP3;
|
||||
if(EEPROM.read(z) != (stagingTable.values[7-(offset/8)][offset%8]) ) { EEPROM.write(z, stagingTable.values[7-(offset/8)][offset%8]); writeCounter++; } //Write the 8x8 map
|
||||
y++;
|
||||
z++;
|
||||
}
|
||||
//RPM bins
|
||||
y = EEPROM_CONFIG8_XBINS2;
|
||||
z = EEPROM_CONFIG8_XBINS3;
|
||||
for(int x=EEPROM_CONFIG8_XBINS1; x<EEPROM_CONFIG8_YBINS1; x++)
|
||||
y = EEPROM_CONFIG7_XBINS2;
|
||||
z = EEPROM_CONFIG7_XBINS3;
|
||||
for(int x=EEPROM_CONFIG7_XBINS1; x<EEPROM_CONFIG7_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;
|
||||
offset = x - EEPROM_CONFIG7_XBINS1;
|
||||
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;
|
||||
offset = y - EEPROM_CONFIG7_XBINS2;
|
||||
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
|
||||
offset = z - EEPROM_CONFIG8_XBINS3;
|
||||
offset = z - EEPROM_CONFIG7_XBINS3;
|
||||
if(EEPROM.read(z) != byte(stagingTable.axisX[offset]/TABLE_RPM_MULTIPLIER)) { EEPROM.write(z, byte(stagingTable.axisX[offset]/TABLE_RPM_MULTIPLIER)); writeCounter++; } //RPM bins are divided by 100 and converted to a byte
|
||||
y++;
|
||||
z++;
|
||||
}
|
||||
//TPS/MAP bins
|
||||
y=EEPROM_CONFIG8_YBINS2;
|
||||
z=EEPROM_CONFIG8_YBINS3;
|
||||
for(int x=EEPROM_CONFIG8_YBINS1; x<EEPROM_CONFIG8_XSIZE2; x++)
|
||||
y=EEPROM_CONFIG7_YBINS2;
|
||||
z=EEPROM_CONFIG7_YBINS3;
|
||||
for(int x=EEPROM_CONFIG7_YBINS1; x<EEPROM_CONFIG7_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;
|
||||
offset = x - EEPROM_CONFIG7_YBINS1;
|
||||
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;
|
||||
offset = y - EEPROM_CONFIG7_YBINS2;
|
||||
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)
|
||||
offset = z - EEPROM_CONFIG8_YBINS3;
|
||||
offset = z - EEPROM_CONFIG7_YBINS3;
|
||||
if(EEPROM.read(z) != byte(stagingTable.axisY[offset]/TABLE_LOAD_MULTIPLIER)) { EEPROM.write(z, byte(stagingTable.axisY[offset]/TABLE_LOAD_MULTIPLIER)); writeCounter++; } //RPM bins are divided by 100 and converted to a byte
|
||||
y++;
|
||||
z++;
|
||||
|
@ -271,35 +271,35 @@ void writeConfig(byte tableNum)
|
|||
| 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)
|
||||
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
|
||||
if(EEPROM.read(EEPROM_CONFIG8_XSIZE1) != trim1Table.xSize) { EEPROM.write(EEPROM_CONFIG8_XSIZE1,trim1Table.xSize); writeCounter++; } //Write the boost Table RPM dimension size
|
||||
if(EEPROM.read(EEPROM_CONFIG8_YSIZE1) != trim1Table.ySize) { EEPROM.write(EEPROM_CONFIG8_YSIZE1,trim1Table.ySize); writeCounter++; } //Write the boost Table MAP/TPS dimension size
|
||||
if(EEPROM.read(EEPROM_CONFIG8_XSIZE2) != trim2Table.xSize) { EEPROM.write(EEPROM_CONFIG8_XSIZE2,trim2Table.xSize); writeCounter++; } //Write the boost Table RPM dimension size
|
||||
if(EEPROM.read(EEPROM_CONFIG8_YSIZE2) != trim2Table.ySize) { EEPROM.write(EEPROM_CONFIG8_YSIZE2,trim2Table.ySize); writeCounter++; } //Write the boost Table MAP/TPS dimension size
|
||||
if(EEPROM.read(EEPROM_CONFIG8_XSIZE3) != trim3Table.xSize) { EEPROM.write(EEPROM_CONFIG8_XSIZE3,trim3Table.xSize); writeCounter++; } //Write the boost Table RPM dimension size
|
||||
if(EEPROM.read(EEPROM_CONFIG8_YSIZE3) != trim3Table.ySize) { EEPROM.write(EEPROM_CONFIG8_YSIZE3,trim3Table.ySize); writeCounter++; } //Write the boost Table MAP/TPS dimension size
|
||||
if(EEPROM.read(EEPROM_CONFIG8_XSIZE4) != trim4Table.xSize) { EEPROM.write(EEPROM_CONFIG8_XSIZE4,trim4Table.xSize); writeCounter++; } //Write the boost Table RPM dimension size
|
||||
if(EEPROM.read(EEPROM_CONFIG8_YSIZE4) != trim4Table.ySize) { EEPROM.write(EEPROM_CONFIG8_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
|
||||
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
|
||||
y = EEPROM_CONFIG8_MAP2; //We do the 4 maps together in the same loop
|
||||
z = EEPROM_CONFIG8_MAP3; //We do the 4 maps together in the same loop
|
||||
i = EEPROM_CONFIG8_MAP4; //We do the 4 maps together in the same loop
|
||||
|
||||
for(int x=EEPROM_CONFIG9_MAP1; x<EEPROM_CONFIG9_XBINS1; x++)
|
||||
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_CONFIG9_MAP1;
|
||||
offset = x - EEPROM_CONFIG8_MAP1;
|
||||
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;
|
||||
offset = y - EEPROM_CONFIG8_MAP2;
|
||||
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;
|
||||
offset = z - EEPROM_CONFIG8_MAP3;
|
||||
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;
|
||||
offset = i - EEPROM_CONFIG8_MAP4;
|
||||
newVal = trim4Table.values[5-(offset/6)][offset%6];
|
||||
if (EEPROM.read(i) != newVal ) { EEPROM.update(i, newVal); writeCounter++; } //Write the 6x6 map
|
||||
|
||||
|
@ -308,38 +308,38 @@ void writeConfig(byte tableNum)
|
|||
i++;
|
||||
}
|
||||
//RPM bins
|
||||
y = EEPROM_CONFIG9_XBINS2;
|
||||
z = EEPROM_CONFIG9_XBINS3;
|
||||
i = EEPROM_CONFIG9_XBINS4;
|
||||
for(int x=EEPROM_CONFIG9_XBINS1; x<EEPROM_CONFIG9_YBINS1; x++)
|
||||
y = EEPROM_CONFIG8_XBINS2;
|
||||
z = EEPROM_CONFIG8_XBINS3;
|
||||
i = EEPROM_CONFIG8_XBINS4;
|
||||
for(int x=EEPROM_CONFIG8_XBINS1; x<EEPROM_CONFIG8_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;
|
||||
offset = x - EEPROM_CONFIG8_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;
|
||||
offset = y - EEPROM_CONFIG8_XBINS2;
|
||||
EEPROM.update(y, byte(trim2Table.axisX[offset]/TABLE_RPM_MULTIPLIER)); //RPM bins are divided by 100 and converted to a byte
|
||||
offset = z - EEPROM_CONFIG9_XBINS3;
|
||||
offset = z - EEPROM_CONFIG8_XBINS3;
|
||||
EEPROM.update(z, byte(trim3Table.axisX[offset]/TABLE_RPM_MULTIPLIER)); //RPM bins are divided by 100 and converted to a byte
|
||||
offset = i - EEPROM_CONFIG9_XBINS4;
|
||||
offset = i - EEPROM_CONFIG8_XBINS4;
|
||||
EEPROM.update(i, byte(trim4Table.axisX[offset]/TABLE_RPM_MULTIPLIER)); //RPM bins are divided by 100 and converted to a byte
|
||||
y++;
|
||||
z++;
|
||||
i++;
|
||||
}
|
||||
//TPS/MAP bins
|
||||
y=EEPROM_CONFIG9_YBINS2;
|
||||
z=EEPROM_CONFIG9_YBINS3;
|
||||
i=EEPROM_CONFIG9_YBINS4;
|
||||
for(int x=EEPROM_CONFIG9_YBINS1; x<EEPROM_CONFIG9_XSIZE2; x++)
|
||||
y=EEPROM_CONFIG8_YBINS2;
|
||||
z=EEPROM_CONFIG8_YBINS3;
|
||||
i=EEPROM_CONFIG8_YBINS4;
|
||||
for(int x=EEPROM_CONFIG8_YBINS1; x<EEPROM_CONFIG8_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;
|
||||
offset = x - EEPROM_CONFIG8_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;
|
||||
offset = y - EEPROM_CONFIG8_YBINS2;
|
||||
EEPROM.update(y, trim2Table.axisY[offset]/TABLE_LOAD_MULTIPLIER); //Table load is divided by 2 (Allows for MAP up to 511)
|
||||
offset = z - EEPROM_CONFIG9_YBINS3;
|
||||
offset = z - EEPROM_CONFIG8_YBINS3;
|
||||
EEPROM.update(z, trim3Table.axisY[offset]/TABLE_LOAD_MULTIPLIER); //Table load is divided by 2 (Allows for MAP up to 511)
|
||||
offset = i - EEPROM_CONFIG9_YBINS4;
|
||||
offset = i - EEPROM_CONFIG8_YBINS4;
|
||||
EEPROM.update(i, trim4Table.axisY[offset]/TABLE_LOAD_MULTIPLIER); //Table load is divided by 2 (Allows for MAP up to 511)
|
||||
y++;
|
||||
z++;
|
||||
|
@ -355,11 +355,11 @@ void writeConfig(byte tableNum)
|
|||
| Config page 10 (See storage.h for data layout)
|
||||
| 128 byte long config table
|
||||
-----------------------------------------------------*/
|
||||
pnt_configPage = (byte *)&configPage10; //Create a pointer to Page 10 in memory
|
||||
for(int x=EEPROM_CONFIG10_START; x<EEPROM_CONFIG10_END; x++)
|
||||
pnt_configPage = (byte *)&configPage9; //Create a pointer to Page 10 in memory
|
||||
for(int x=EEPROM_CONFIG9_START; x<EEPROM_CONFIG9_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_CONFIG10_START))) { EEPROM.write(x, *(pnt_configPage + byte(x - EEPROM_CONFIG10_START))); writeCounter++; }
|
||||
if(EEPROM.read(x) != *(pnt_configPage + byte(x - EEPROM_CONFIG9_START))) { EEPROM.write(x, *(pnt_configPage + byte(x - EEPROM_CONFIG9_START))); writeCounter++; }
|
||||
}
|
||||
|
||||
if(writeCounter > EEPROM_MAX_WRITE_BLOCK) { eepromWritesPending = true; }
|
||||
|
@ -372,12 +372,12 @@ void writeConfig(byte tableNum)
|
|||
| 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
|
||||
pnt_configPage = (byte *)&configPage10; //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++)
|
||||
for(int x=EEPROM_CONFIG10_START; x<EEPROM_CONFIG10_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(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; }
|
||||
|
@ -416,7 +416,7 @@ void loadConfig()
|
|||
fuelTable.axisY[offset] = EEPROM.read(x) * TABLE_LOAD_MULTIPLIER;
|
||||
}
|
||||
|
||||
pnt_configPage = (byte *)&configPage1; //Create a pointer to Page 1 in memory
|
||||
pnt_configPage = (byte *)&configPage2; //Create a pointer to Page 1 in memory
|
||||
for(int x=EEPROM_CONFIG2_START; x<EEPROM_CONFIG2_END; x++)
|
||||
{
|
||||
*(pnt_configPage + byte(x - EEPROM_CONFIG2_START)) = EEPROM.read(x);
|
||||
|
@ -445,7 +445,7 @@ void loadConfig()
|
|||
ignitionTable.axisY[offset] = EEPROM.read(x) * TABLE_LOAD_MULTIPLIER; //Table load is divided by 2 (Allows for MAP up to 511)
|
||||
}
|
||||
|
||||
pnt_configPage = (byte *)&configPage2; //Create a pointer to Page 2 in memory
|
||||
pnt_configPage = (byte *)&configPage4; //Create a pointer to Page 4 in memory
|
||||
for(int x=EEPROM_CONFIG4_START; x<EEPROM_CONFIG4_END; x++)
|
||||
{
|
||||
*(pnt_configPage + byte(x - EEPROM_CONFIG4_START)) = EEPROM.read(x);
|
||||
|
@ -473,7 +473,7 @@ void loadConfig()
|
|||
afrTable.axisY[offset] = EEPROM.read(x) * TABLE_LOAD_MULTIPLIER; //Table load is divided by 2 (Allows for MAP up to 511)
|
||||
}
|
||||
|
||||
pnt_configPage = (byte *)&configPage3; //Create a pointer to Page 2 in memory
|
||||
pnt_configPage = (byte *)&configPage6; //Create a pointer to Page 6 in memory
|
||||
for(int x=EEPROM_CONFIG6_START; x<EEPROM_CONFIG6_END; x++)
|
||||
{
|
||||
*(pnt_configPage + byte(x - EEPROM_CONFIG6_START)) = EEPROM.read(x);
|
||||
|
@ -481,45 +481,45 @@ void loadConfig()
|
|||
|
||||
//*********************************************************************************************************************************************************************************
|
||||
// Boost and vvt tables load
|
||||
int y = EEPROM_CONFIG8_MAP2;
|
||||
int z = EEPROM_CONFIG8_MAP3;
|
||||
for(int x=EEPROM_CONFIG8_MAP1; x<EEPROM_CONFIG8_XBINS1; x++)
|
||||
int y = EEPROM_CONFIG7_MAP2;
|
||||
int z = EEPROM_CONFIG7_MAP3;
|
||||
for(int x=EEPROM_CONFIG7_MAP1; x<EEPROM_CONFIG7_XBINS1; x++)
|
||||
{
|
||||
offset = x - EEPROM_CONFIG8_MAP1;
|
||||
offset = x - EEPROM_CONFIG7_MAP1;
|
||||
boostTable.values[7-(offset/8)][offset%8] = EEPROM.read(x); //Read the 8x8 map
|
||||
offset = y - EEPROM_CONFIG8_MAP2;
|
||||
offset = y - EEPROM_CONFIG7_MAP2;
|
||||
vvtTable.values[7-(offset/8)][offset%8] = EEPROM.read(y); //Read the 8x8 map
|
||||
offset = z - EEPROM_CONFIG8_MAP3;
|
||||
offset = z - EEPROM_CONFIG7_MAP3;
|
||||
stagingTable.values[7-(offset/8)][offset%8] = EEPROM.read(z); //Read the 8x8 map
|
||||
y++;
|
||||
z++;
|
||||
}
|
||||
|
||||
//RPM bins
|
||||
y = EEPROM_CONFIG8_XBINS2;
|
||||
z = EEPROM_CONFIG8_XBINS3;
|
||||
for(int x=EEPROM_CONFIG8_XBINS1; x<EEPROM_CONFIG8_YBINS1; x++)
|
||||
y = EEPROM_CONFIG7_XBINS2;
|
||||
z = EEPROM_CONFIG7_XBINS3;
|
||||
for(int x=EEPROM_CONFIG7_XBINS1; x<EEPROM_CONFIG7_YBINS1; x++)
|
||||
{
|
||||
offset = x - EEPROM_CONFIG8_XBINS1;
|
||||
offset = x - EEPROM_CONFIG7_XBINS1;
|
||||
boostTable.axisX[offset] = (EEPROM.read(x) * TABLE_RPM_MULTIPLIER); //RPM bins are divided by 100 when stored. Multiply them back now
|
||||
offset = y - EEPROM_CONFIG8_XBINS2;
|
||||
offset = y - EEPROM_CONFIG7_XBINS2;
|
||||
vvtTable.axisX[offset] = (EEPROM.read(y) * TABLE_RPM_MULTIPLIER); //RPM bins are divided by 100 when stored. Multiply them back now
|
||||
offset = z - EEPROM_CONFIG8_XBINS3;
|
||||
offset = z - EEPROM_CONFIG7_XBINS3;
|
||||
stagingTable.axisX[offset] = (EEPROM.read(z) * TABLE_RPM_MULTIPLIER); //RPM bins are divided by 100 when stored. Multiply them back now
|
||||
y++;
|
||||
z++;
|
||||
}
|
||||
|
||||
//TPS/MAP bins
|
||||
y = EEPROM_CONFIG8_YBINS2;
|
||||
z = EEPROM_CONFIG8_YBINS3;
|
||||
for(int x=EEPROM_CONFIG8_YBINS1; x<EEPROM_CONFIG8_XSIZE2; x++)
|
||||
y = EEPROM_CONFIG7_YBINS2;
|
||||
z = EEPROM_CONFIG7_YBINS3;
|
||||
for(int x=EEPROM_CONFIG7_YBINS1; x<EEPROM_CONFIG7_XSIZE2; x++)
|
||||
{
|
||||
offset = x - EEPROM_CONFIG8_YBINS1;
|
||||
offset = x - EEPROM_CONFIG7_YBINS1;
|
||||
boostTable.axisY[offset] = EEPROM.read(x); //TABLE_LOAD_MULTIPLIER is NOT used for boost as it is TPS based (0-100)
|
||||
offset = y - EEPROM_CONFIG8_YBINS2;
|
||||
offset = y - EEPROM_CONFIG7_YBINS2;
|
||||
vvtTable.axisY[offset] = EEPROM.read(y); //TABLE_LOAD_MULTIPLIER is NOT used for VVT as it is TPS based (0-100)
|
||||
offset = z - EEPROM_CONFIG8_YBINS3;
|
||||
offset = z - EEPROM_CONFIG7_YBINS3;
|
||||
stagingTable.axisY[offset] = EEPROM.read(z) * TABLE_LOAD_MULTIPLIER;
|
||||
y++;
|
||||
z++;
|
||||
|
@ -527,18 +527,18 @@ void loadConfig()
|
|||
|
||||
//*********************************************************************************************************************************************************************************
|
||||
// Fuel trim tables load
|
||||
y = EEPROM_CONFIG9_MAP2;
|
||||
z = EEPROM_CONFIG9_MAP3;
|
||||
int i = EEPROM_CONFIG9_MAP4;
|
||||
for(int x=EEPROM_CONFIG9_MAP1; x<EEPROM_CONFIG9_XBINS1; x++)
|
||||
y = EEPROM_CONFIG8_MAP2;
|
||||
z = EEPROM_CONFIG8_MAP3;
|
||||
int i = EEPROM_CONFIG8_MAP4;
|
||||
for(int x=EEPROM_CONFIG8_MAP1; x<EEPROM_CONFIG8_XBINS1; x++)
|
||||
{
|
||||
offset = x - EEPROM_CONFIG9_MAP1;
|
||||
offset = x - EEPROM_CONFIG8_MAP1;
|
||||
trim1Table.values[5-(offset/6)][offset%6] = EEPROM.read(x); //Read the 6x6 map
|
||||
offset = y - EEPROM_CONFIG9_MAP2;
|
||||
offset = y - EEPROM_CONFIG8_MAP2;
|
||||
trim2Table.values[5-(offset/6)][offset%6] = EEPROM.read(y); //Read the 6x6 map
|
||||
offset = z - EEPROM_CONFIG9_MAP3;
|
||||
offset = z - EEPROM_CONFIG8_MAP3;
|
||||
trim3Table.values[5-(offset/6)][offset%6] = EEPROM.read(z); //Read the 6x6 map
|
||||
offset = i - EEPROM_CONFIG9_MAP4;
|
||||
offset = i - EEPROM_CONFIG8_MAP4;
|
||||
trim4Table.values[5-(offset/6)][offset%6] = EEPROM.read(i); //Read the 6x6 map
|
||||
y++;
|
||||
z++;
|
||||
|
@ -546,18 +546,18 @@ void loadConfig()
|
|||
}
|
||||
|
||||
//RPM bins
|
||||
y = EEPROM_CONFIG9_XBINS2;
|
||||
z = EEPROM_CONFIG9_XBINS3;
|
||||
i = EEPROM_CONFIG9_XBINS4;
|
||||
for(int x=EEPROM_CONFIG9_XBINS1; x<EEPROM_CONFIG9_YBINS1; x++)
|
||||
y = EEPROM_CONFIG8_XBINS2;
|
||||
z = EEPROM_CONFIG8_XBINS3;
|
||||
i = EEPROM_CONFIG8_XBINS4;
|
||||
for(int x=EEPROM_CONFIG8_XBINS1; x<EEPROM_CONFIG8_YBINS1; x++)
|
||||
{
|
||||
offset = x - EEPROM_CONFIG9_XBINS1;
|
||||
offset = x - EEPROM_CONFIG8_XBINS1;
|
||||
trim1Table.axisX[offset] = (EEPROM.read(x) * TABLE_RPM_MULTIPLIER); //RPM bins are divided by 100 when stored. Multiply them back now
|
||||
offset = y - EEPROM_CONFIG9_XBINS2;
|
||||
offset = y - EEPROM_CONFIG8_XBINS2;
|
||||
trim2Table.axisX[offset] = (EEPROM.read(y) * TABLE_RPM_MULTIPLIER); //RPM bins are divided by 100 when stored. Multiply them back now
|
||||
offset = z - EEPROM_CONFIG9_XBINS3;
|
||||
offset = z - EEPROM_CONFIG8_XBINS3;
|
||||
trim3Table.axisX[offset] = (EEPROM.read(z) * TABLE_RPM_MULTIPLIER); //RPM bins are divided by 100 when stored. Multiply them back now
|
||||
offset = i - EEPROM_CONFIG9_XBINS4;
|
||||
offset = i - EEPROM_CONFIG8_XBINS4;
|
||||
trim4Table.axisX[offset] = (EEPROM.read(i) * TABLE_RPM_MULTIPLIER); //RPM bins are divided by 100 when stored. Multiply them back now
|
||||
y++;
|
||||
z++;
|
||||
|
@ -565,18 +565,18 @@ void loadConfig()
|
|||
}
|
||||
|
||||
//TPS/MAP bins
|
||||
y = EEPROM_CONFIG9_YBINS2;
|
||||
z = EEPROM_CONFIG9_YBINS3;
|
||||
i = EEPROM_CONFIG9_YBINS4;
|
||||
for(int x=EEPROM_CONFIG9_YBINS1; x<EEPROM_CONFIG9_XSIZE2; x++)
|
||||
y = EEPROM_CONFIG8_YBINS2;
|
||||
z = EEPROM_CONFIG8_YBINS3;
|
||||
i = EEPROM_CONFIG8_YBINS4;
|
||||
for(int x=EEPROM_CONFIG8_YBINS1; x<EEPROM_CONFIG8_XSIZE2; x++)
|
||||
{
|
||||
offset = x - EEPROM_CONFIG9_YBINS1;
|
||||
offset = x - EEPROM_CONFIG8_YBINS1;
|
||||
trim1Table.axisY[offset] = EEPROM.read(x) * TABLE_LOAD_MULTIPLIER; //Table load is divided by 2 (Allows for MAP up to 511)
|
||||
offset = y - EEPROM_CONFIG9_YBINS2;
|
||||
offset = y - EEPROM_CONFIG8_YBINS2;
|
||||
trim2Table.axisY[offset] = EEPROM.read(y) * TABLE_LOAD_MULTIPLIER; //Table load is divided by 2 (Allows for MAP up to 511)
|
||||
offset = z - EEPROM_CONFIG9_YBINS3;
|
||||
offset = z - EEPROM_CONFIG8_YBINS3;
|
||||
trim3Table.axisY[offset] = EEPROM.read(z) * TABLE_LOAD_MULTIPLIER; //Table load is divided by 2 (Allows for MAP up to 511)
|
||||
offset = i - EEPROM_CONFIG9_YBINS4;
|
||||
offset = i - EEPROM_CONFIG8_YBINS4;
|
||||
trim4Table.axisY[offset] = EEPROM.read(i) * TABLE_LOAD_MULTIPLIER; //Table load is divided by 2 (Allows for MAP up to 511)
|
||||
y++;
|
||||
z++;
|
||||
|
@ -584,20 +584,20 @@ void loadConfig()
|
|||
}
|
||||
//*********************************************************************************************************************************************************************************
|
||||
//canbus control page load
|
||||
pnt_configPage = (byte *)&configPage10; //Create a pointer to Page 10 in memory
|
||||
for(int x=EEPROM_CONFIG10_START; x<EEPROM_CONFIG10_END; x++)
|
||||
pnt_configPage = (byte *)&configPage9; //Create a pointer to Page 10 in memory
|
||||
for(int x=EEPROM_CONFIG9_START; x<EEPROM_CONFIG9_END; x++)
|
||||
{
|
||||
*(pnt_configPage + byte(x - EEPROM_CONFIG10_START)) = EEPROM.read(x);
|
||||
*(pnt_configPage + byte(x - EEPROM_CONFIG9_START)) = EEPROM.read(x);
|
||||
}
|
||||
|
||||
//*********************************************************************************************************************************************************************************
|
||||
|
||||
//CONFIG PAGE (11)
|
||||
pnt_configPage = (byte *)&configPage11; //Create a pointer to Page 11 in memory
|
||||
//CONFIG PAGE (10)
|
||||
pnt_configPage = (byte *)&configPage10; //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++)
|
||||
for(int x=EEPROM_CONFIG10_START; x<EEPROM_CONFIG10_END; x++)
|
||||
{
|
||||
*(pnt_configPage + byte(x - EEPROM_CONFIG11_START)) = EEPROM.read(x);
|
||||
*(pnt_configPage + byte(x - EEPROM_CONFIG10_START)) = EEPROM.read(x);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -19,12 +19,16 @@ struct table2D {
|
|||
byte *values;
|
||||
byte *axisX;
|
||||
|
||||
int *values16;
|
||||
int *axisX16;
|
||||
int16_t *values16;
|
||||
int16_t *axisX16;
|
||||
|
||||
//Store the last X and Y coordinates in the table. This is used to make the next check faster
|
||||
int lastXMax;
|
||||
int lastXMin;
|
||||
int16_t lastXMax;
|
||||
int16_t lastXMin;
|
||||
|
||||
//Store the last input and output for caching
|
||||
int16_t lastInput;
|
||||
int16_t lastOutput;
|
||||
};
|
||||
|
||||
void table2D_setSize(struct table2D targetTable, byte newSize);
|
||||
|
@ -37,8 +41,8 @@ struct table3D {
|
|||
byte ySize;
|
||||
|
||||
byte **values;
|
||||
int *axisX;
|
||||
int *axisY;
|
||||
int16_t *axisX;
|
||||
int16_t *axisY;
|
||||
|
||||
//Store the last X and Y coordinates in the table. This is used to make the next check faster
|
||||
byte lastXMax, lastXMin;
|
||||
|
|
|
@ -24,8 +24,8 @@ void table2D_setSize(struct table2D* targetTable, byte newSize)
|
|||
}
|
||||
else
|
||||
{
|
||||
targetTable->values16 = (int *)realloc(targetTable->values16, newSize * sizeof(int));
|
||||
targetTable->axisX16 = (int *)realloc(targetTable->axisX16, newSize * sizeof(int));
|
||||
targetTable->values16 = (int16_t *)realloc(targetTable->values16, newSize * sizeof(int16_t));
|
||||
targetTable->axisX16 = (int16_t *)realloc(targetTable->axisX16, newSize * sizeof(int16_t));
|
||||
targetTable->xSize = newSize;
|
||||
} //Byte or int
|
||||
} //initialisationComplete
|
||||
|
@ -39,8 +39,8 @@ void table3D_setSize(struct table3D *targetTable, byte newSize)
|
|||
targetTable->values = (byte **)malloc(newSize * sizeof(byte*));
|
||||
for(byte i = 0; i < newSize; i++) { targetTable->values[i] = (byte *)malloc(newSize * sizeof(byte)); }
|
||||
|
||||
targetTable->axisX = (int *)malloc(newSize * sizeof(int));
|
||||
targetTable->axisY = (int *)malloc(newSize * sizeof(int));
|
||||
targetTable->axisX = (int16_t *)malloc(newSize * sizeof(int16_t));
|
||||
targetTable->axisY = (int16_t *)malloc(newSize * sizeof(int16_t));
|
||||
targetTable->xSize = newSize;
|
||||
targetTable->ySize = newSize;
|
||||
} //initialisationComplete
|
||||
|
@ -198,6 +198,9 @@ int table2D_getValue(struct table2D *fromTable, int X_in)
|
|||
returnValue = yVal;
|
||||
}
|
||||
|
||||
fromTable->lastInput = X_in;
|
||||
fromTable->lastOutput = returnValue;
|
||||
|
||||
return returnValue;
|
||||
}
|
||||
|
||||
|
|
|
@ -77,14 +77,14 @@ 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
|
||||
bool isCrankLocked = configPage4.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) && (isCrankLocked != true) ) { endCoil1Charge(); ignitionSchedule1.Status = OFF; } }
|
||||
if(ignitionSchedule2.Status == RUNNING) { if( (ignitionSchedule2.startTime < targetOverdwellTime) && (configPage2.useDwellLim) && (isCrankLocked != true) ) { endCoil2Charge(); ignitionSchedule2.Status = OFF; } }
|
||||
if(ignitionSchedule3.Status == RUNNING) { if( (ignitionSchedule3.startTime < targetOverdwellTime) && (configPage2.useDwellLim) && (isCrankLocked != true) ) { endCoil3Charge(); ignitionSchedule3.Status = OFF; } }
|
||||
if(ignitionSchedule4.Status == RUNNING) { if( (ignitionSchedule4.startTime < targetOverdwellTime) && (configPage2.useDwellLim) && (isCrankLocked != true) ) { endCoil4Charge(); ignitionSchedule4.Status = OFF; } }
|
||||
if(ignitionSchedule5.Status == RUNNING) { if( (ignitionSchedule5.startTime < targetOverdwellTime) && (configPage2.useDwellLim) && (isCrankLocked != true) ) { endCoil5Charge(); ignitionSchedule5.Status = OFF; } }
|
||||
if(ignitionSchedule1.Status == RUNNING) { if( (ignitionSchedule1.startTime < targetOverdwellTime) && (configPage4.useDwellLim) && (isCrankLocked != true) ) { endCoil1Charge(); ignitionSchedule1.Status = OFF; } }
|
||||
if(ignitionSchedule2.Status == RUNNING) { if( (ignitionSchedule2.startTime < targetOverdwellTime) && (configPage4.useDwellLim) && (isCrankLocked != true) ) { endCoil2Charge(); ignitionSchedule2.Status = OFF; } }
|
||||
if(ignitionSchedule3.Status == RUNNING) { if( (ignitionSchedule3.startTime < targetOverdwellTime) && (configPage4.useDwellLim) && (isCrankLocked != true) ) { endCoil3Charge(); ignitionSchedule3.Status = OFF; } }
|
||||
if(ignitionSchedule4.Status == RUNNING) { if( (ignitionSchedule4.startTime < targetOverdwellTime) && (configPage4.useDwellLim) && (isCrankLocked != true) ) { endCoil4Charge(); ignitionSchedule4.Status = OFF; } }
|
||||
if(ignitionSchedule5.Status == RUNNING) { if( (ignitionSchedule5.startTime < targetOverdwellTime) && (configPage4.useDwellLim) && (isCrankLocked != true) ) { endCoil5Charge(); ignitionSchedule5.Status = OFF; } }
|
||||
|
||||
|
||||
|
||||
|
@ -139,8 +139,8 @@ void oneMSInterval() //Most ARM chips can simply call a function
|
|||
loopSec = 0; //Reset counter.
|
||||
BIT_SET(TIMER_mask, BIT_TIMER_1HZ);
|
||||
|
||||
dwellLimit_uS = (1000 * configPage2.dwellLimit); //Update uS value incase setting has changed
|
||||
currentStatus.crankRPM = ((unsigned int)configPage2.crankRPM * 100);
|
||||
dwellLimit_uS = (1000 * configPage4.dwellLimit); //Update uS value incase setting has changed
|
||||
currentStatus.crankRPM = ((unsigned int)configPage4.crankRPM * 100);
|
||||
|
||||
//**************************************************************************************************************************************************
|
||||
//This updates the runSecs variable
|
||||
|
@ -159,7 +159,7 @@ void oneMSInterval() //Most ARM chips can simply call a function
|
|||
currentStatus.secl++;
|
||||
//**************************************************************************************************************************************************
|
||||
//Check the fan output status
|
||||
if (configPage3.fanEnable == 1)
|
||||
if (configPage6.fanEnable == 1)
|
||||
{
|
||||
fanControl(); // Fucntion to turn the cooling fan on/off
|
||||
}
|
||||
|
@ -167,7 +167,7 @@ void oneMSInterval() //Most ARM chips can simply call a function
|
|||
//Check whether fuel pump priming is complete
|
||||
if(fpPrimed == false)
|
||||
{
|
||||
if(currentStatus.secl >= configPage1.fpPrime)
|
||||
if(currentStatus.secl >= configPage2.fpPrime)
|
||||
{
|
||||
fpPrimed = true; //Mark the priming as being completed
|
||||
if(currentStatus.RPM == 0)
|
||||
|
@ -180,7 +180,7 @@ void oneMSInterval() //Most ARM chips can simply call a function
|
|||
}
|
||||
//**************************************************************************************************************************************************
|
||||
//Set the flex reading (if enabled). The flexCounter is updated with every pulse from the sensor. If cleared once per second, we get a frequency reading
|
||||
if(configPage1.flexEnabled == true)
|
||||
if(configPage2.flexEnabled == true)
|
||||
{
|
||||
if(flexCounter < 50)
|
||||
{
|
||||
|
|
|
@ -8,7 +8,7 @@
|
|||
|
||||
void doUpdates()
|
||||
{
|
||||
#define CURRENT_DATA_VERSION 7
|
||||
#define CURRENT_DATA_VERSION 8
|
||||
uint8_t currentVersion = EEPROM.read(EEPROM_DATA_VERSION);
|
||||
|
||||
//May 2017 firmware introduced a -40 offset on the ignition table. Update that table to +40
|
||||
|
@ -27,12 +27,12 @@ void doUpdates()
|
|||
//June 2017 required the forced addition of some CAN values to avoid weird errors
|
||||
if(currentVersion == 3)
|
||||
{
|
||||
configPage10.speeduino_tsCanId = 0;
|
||||
configPage10.true_address = 256;
|
||||
configPage10.realtime_base_address = 336;
|
||||
configPage9.speeduino_tsCanId = 0;
|
||||
configPage9.true_address = 256;
|
||||
configPage9.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; }
|
||||
if(configPage4.sparkDur == 255) { configPage4.sparkDur = 10; }
|
||||
|
||||
writeAllConfig();
|
||||
EEPROM.write(EEPROM_DATA_VERSION, 4);
|
||||
|
@ -41,15 +41,15 @@ void doUpdates()
|
|||
if(currentVersion == 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;
|
||||
configPage10.crankingEnrichBins[0] = 0;
|
||||
configPage10.crankingEnrichBins[1] = 40;
|
||||
configPage10.crankingEnrichBins[2] = 70;
|
||||
configPage10.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;
|
||||
configPage10.crankingEnrichValues[0] = 100 + configPage2.crankingPct;
|
||||
configPage10.crankingEnrichValues[1] = 100 + configPage2.crankingPct;
|
||||
configPage10.crankingEnrichValues[2] = 100 + configPage2.crankingPct;
|
||||
configPage10.crankingEnrichValues[3] = 100 + configPage2.crankingPct;
|
||||
|
||||
writeAllConfig();
|
||||
EEPROM.write(EEPROM_DATA_VERSION, 5);
|
||||
|
@ -60,7 +60,7 @@ void doUpdates()
|
|||
//Data after page 4 has to move back 128 bytes
|
||||
for(int x=0; x < 1152; x++)
|
||||
{
|
||||
int endMem = EEPROM_CONFIG11_END - x;
|
||||
int endMem = EEPROM_CONFIG10_END - x;
|
||||
int startMem = endMem - 128; //
|
||||
byte currentVal = EEPROM.read(startMem);
|
||||
EEPROM.update(endMem, currentVal);
|
||||
|
@ -68,7 +68,7 @@ void doUpdates()
|
|||
//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 endMem = EEPROM_CONFIG10_END - 1152 - x;
|
||||
int startMem = endMem - 64; //
|
||||
byte currentVal = EEPROM.read(startMem);
|
||||
EEPROM.update(endMem, currentVal);
|
||||
|
@ -83,7 +83,7 @@ void doUpdates()
|
|||
//Data after page 8 has to move back 82 bytes
|
||||
for(int x=0; x < 529; x++)
|
||||
{
|
||||
int endMem = EEPROM_CONFIG11_END - x;
|
||||
int endMem = EEPROM_CONFIG10_END - x;
|
||||
int startMem = endMem - 82; //
|
||||
byte currentVal = EEPROM.read(startMem);
|
||||
EEPROM.update(endMem, currentVal);
|
||||
|
@ -93,10 +93,36 @@ void doUpdates()
|
|||
loadConfig(); //Reload the config after changing everything in EEPROM
|
||||
}
|
||||
|
||||
if (currentVersion == 7) {
|
||||
//Convert whatever flex fuel settings are there into the new tables
|
||||
|
||||
configPage10.flexBoostAdj[0] = (int8_t)configPage2.unused2_1;
|
||||
configPage10.flexFuelAdj[0] = configPage2.unused2_57;
|
||||
configPage10.flexAdvAdj[0] = configPage2.unused2_59;
|
||||
|
||||
for (uint8_t x = 1; x < 6; x++)
|
||||
{
|
||||
uint8_t pct = x * 20;
|
||||
configPage10.flexBoostBins[x] = configPage10.flexFuelBins[x] = configPage10.flexAdvBins[x] = pct;
|
||||
|
||||
int16_t boostAdder = (((configPage2.unused2_2 - (int8_t)configPage2.unused2_1) * pct) / 100) + (int8_t)configPage2.unused2_1;
|
||||
configPage10.flexBoostAdj[x] = boostAdder;
|
||||
|
||||
uint8_t fuelAdder = (((configPage2.unused2_58 - configPage2.unused2_57) * pct) / 100) + configPage2.unused2_57;
|
||||
configPage10.flexFuelAdj[x] = fuelAdder;
|
||||
|
||||
uint8_t advanceAdder = (((configPage2.unused2_60 - configPage2.unused2_59) * pct) / 100) + configPage2.unused2_59;
|
||||
configPage10.flexAdvAdj[x] = advanceAdder;
|
||||
}
|
||||
|
||||
writeAllConfig();
|
||||
EEPROM.write(EEPROM_DATA_VERSION, 8);
|
||||
}
|
||||
|
||||
//Final check is always for 255 and 0 (Brand new arduino)
|
||||
if( (currentVersion == 0) || (currentVersion == 255) )
|
||||
{
|
||||
configPage10.true_address = 0x200;
|
||||
configPage9.true_address = 0x200;
|
||||
EEPROM.write(EEPROM_DATA_VERSION, CURRENT_DATA_VERSION);
|
||||
}
|
||||
|
||||
|
|
|
@ -48,6 +48,32 @@ byte pinTranslate(byte rawPin)
|
|||
return outputPin;
|
||||
}
|
||||
|
||||
void setResetControlPinState()
|
||||
{
|
||||
BIT_CLEAR(currentStatus.status3, BIT_STATUS3_RESET_PREVENT);
|
||||
|
||||
/* Setup reset control initial state */
|
||||
switch (resetControl)
|
||||
{
|
||||
case RESET_CONTROL_PREVENT_WHEN_RUNNING:
|
||||
/* Set the reset control pin LOW and change it to HIGH later when we get sync. */
|
||||
digitalWrite(pinResetControl, LOW);
|
||||
BIT_CLEAR(currentStatus.status3, BIT_STATUS3_RESET_PREVENT);
|
||||
break;
|
||||
case RESET_CONTROL_PREVENT_ALWAYS:
|
||||
/* Set the reset control pin HIGH and never touch it again. */
|
||||
digitalWrite(pinResetControl, HIGH);
|
||||
BIT_SET(currentStatus.status3, BIT_STATUS3_RESET_PREVENT);
|
||||
break;
|
||||
case RESET_CONTROL_SERIAL_COMMAND:
|
||||
/* Set the reset control pin HIGH. There currently isn't any practical difference
|
||||
between this and PREVENT_ALWAYS but it doesn't hurt anything to have them separate. */
|
||||
digitalWrite(pinResetControl, HIGH);
|
||||
BIT_CLEAR(currentStatus.status3, BIT_STATUS3_RESET_PREVENT);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void setPinMapping(byte boardID)
|
||||
{
|
||||
switch (boardID)
|
||||
|
@ -80,6 +106,7 @@ void setPinMapping(byte boardID)
|
|||
pinFuelPump = 4; //Fuel pump output
|
||||
pinTachOut = 49; //Tacho output pin
|
||||
pinFlex = 19; // Flex sensor (Must be external interrupt enabled)
|
||||
pinResetControl = 43; //Reset control output
|
||||
#endif
|
||||
break;
|
||||
case 1:
|
||||
|
@ -112,6 +139,7 @@ void setPinMapping(byte boardID)
|
|||
pinFan = 47; //Pin for the fan output
|
||||
pinFuelPump = 4; //Fuel pump output
|
||||
pinFlex = 2; // Flex sensor (Must be external interrupt enabled)
|
||||
pinResetControl = 43; //Reset control output
|
||||
break;
|
||||
#endif
|
||||
case 2:
|
||||
|
@ -148,6 +176,7 @@ void setPinMapping(byte boardID)
|
|||
pinFan = A13; //Pin for the fan output
|
||||
pinLaunch = 51; //Can be overwritten below
|
||||
pinFlex = 2; // Flex sensor (Must be external interrupt enabled)
|
||||
pinResetControl = 50; //Reset control output
|
||||
|
||||
#if defined(CORE_TEENSY)
|
||||
pinTrigger = 23;
|
||||
|
@ -196,6 +225,7 @@ void setPinMapping(byte boardID)
|
|||
pinFan = 47; //Pin for the fan output (Goes to ULN2803)
|
||||
pinLaunch = 51; //Can be overwritten below
|
||||
pinFlex = 2; // Flex sensor (Must be external interrupt enabled)
|
||||
pinResetControl = 43; //Reset control output
|
||||
|
||||
#if defined(CORE_TEENSY)
|
||||
pinTrigger = 23;
|
||||
|
@ -316,6 +346,7 @@ void setPinMapping(byte boardID)
|
|||
pinFan = 35; //Pin for the fan output
|
||||
pinLaunch = 12; //Can be overwritten below
|
||||
pinFlex = 3; // Flex sensor (Must be external interrupt enabled)
|
||||
pinResetControl = 44; //Reset control output
|
||||
|
||||
#if defined(CORE_TEENSY)
|
||||
pinTrigger = 23;
|
||||
|
@ -365,6 +396,8 @@ void setPinMapping(byte boardID)
|
|||
pinFan = 47; //Pin for the fan output
|
||||
pinTachOut = 49; //Tacho output pin
|
||||
pinFlex = 2; // Flex sensor (Must be external interrupt enabled)
|
||||
pinResetControl = 26; //Reset control output
|
||||
|
||||
#endif
|
||||
break;
|
||||
|
||||
|
@ -400,6 +433,7 @@ void setPinMapping(byte boardID)
|
|||
pinFan = 47; //Pin for the fan output
|
||||
pinFuelPump = 4; //Fuel pump output
|
||||
pinTachOut = 49; //Tacho output pin
|
||||
pinResetControl = 26; //Reset control output
|
||||
#endif
|
||||
break;
|
||||
|
||||
|
@ -482,6 +516,7 @@ void setPinMapping(byte boardID)
|
|||
pinSpareLOut1 = 32; //low current output spare1 - ONLY WITH DB
|
||||
pinSpareLOut2 = 34; //low current output spare2 - ONLY WITH DB
|
||||
pinSpareLOut3 = 36; //low current output spare3 - ONLY WITH DB
|
||||
pinResetControl = 26; //Reset control output
|
||||
break;
|
||||
|
||||
default:
|
||||
|
@ -514,20 +549,32 @@ void setPinMapping(byte boardID)
|
|||
pinFlex = 3; // Flex sensor (Must be external interrupt enabled)
|
||||
pinBoost = 5;
|
||||
pinIdle1 = 6;
|
||||
pinResetControl = 43; //Reset control output
|
||||
#endif
|
||||
break;
|
||||
}
|
||||
|
||||
//Setup any devices that are using selectable pins
|
||||
|
||||
if ( (configPage3.launchPin != 0) && (configPage3.launchPin < BOARD_NR_GPIO_PINS) ) { pinLaunch = pinTranslate(configPage3.launchPin); }
|
||||
if ( (configPage2.ignBypassPin != 0) && (configPage2.ignBypassPin < BOARD_NR_GPIO_PINS) ) { pinIgnBypass = pinTranslate(configPage2.ignBypassPin); }
|
||||
if ( (configPage1.tachoPin != 0) && (configPage1.tachoPin < BOARD_NR_GPIO_PINS) ) { pinTachOut = pinTranslate(configPage1.tachoPin); }
|
||||
if ( (configPage2.fuelPumpPin != 0) && (configPage2.fuelPumpPin < BOARD_NR_GPIO_PINS) ) { pinFuelPump = pinTranslate(configPage2.fuelPumpPin); }
|
||||
if ( (configPage3.fanPin != 0) && (configPage3.fanPin < BOARD_NR_GPIO_PINS) ) { pinFan = pinTranslate(configPage3.fanPin); }
|
||||
if ( (configPage3.boostPin != 0) && (configPage3.boostPin < BOARD_NR_GPIO_PINS) ) { pinBoost = pinTranslate(configPage3.boostPin); }
|
||||
if ( (configPage3.vvtPin != 0) && (configPage3.vvtPin < BOARD_NR_GPIO_PINS) ) { pinVVT_1 = pinTranslate(configPage3.vvtPin); }
|
||||
if ( (configPage3.useExtBaro != 0) && (configPage3.baroPin < BOARD_NR_GPIO_PINS) ) { pinBaro = configPage3.baroPin + A0; }
|
||||
if ( (configPage6.launchPin != 0) && (configPage6.launchPin < BOARD_NR_GPIO_PINS) ) { pinLaunch = pinTranslate(configPage6.launchPin); }
|
||||
if ( (configPage4.ignBypassPin != 0) && (configPage4.ignBypassPin < BOARD_NR_GPIO_PINS) ) { pinIgnBypass = pinTranslate(configPage4.ignBypassPin); }
|
||||
if ( (configPage2.tachoPin != 0) && (configPage2.tachoPin < BOARD_NR_GPIO_PINS) ) { pinTachOut = pinTranslate(configPage2.tachoPin); }
|
||||
if ( (configPage4.fuelPumpPin != 0) && (configPage4.fuelPumpPin < BOARD_NR_GPIO_PINS) ) { pinFuelPump = pinTranslate(configPage4.fuelPumpPin); }
|
||||
if ( (configPage6.fanPin != 0) && (configPage6.fanPin < BOARD_NR_GPIO_PINS) ) { pinFan = pinTranslate(configPage6.fanPin); }
|
||||
if ( (configPage6.boostPin != 0) && (configPage6.boostPin < BOARD_NR_GPIO_PINS) ) { pinBoost = pinTranslate(configPage6.boostPin); }
|
||||
if ( (configPage6.vvtPin != 0) && (configPage6.vvtPin < BOARD_NR_GPIO_PINS) ) { pinVVT_1 = pinTranslate(configPage6.vvtPin); }
|
||||
if ( (configPage6.useExtBaro != 0) && (configPage6.baroPin < BOARD_NR_GPIO_PINS) ) { pinBaro = configPage6.baroPin + A0; }
|
||||
|
||||
/* Reset control is a special case. If reset control is enabled, it needs its initial state set BEFORE its pinMode.
|
||||
If that doesn't happen and reset control is in "Serial Command" mode, the Arduino will end up in a reset loop
|
||||
because the control pin will go low as soon as the pinMode is set to OUTPUT. */
|
||||
if ( (configPage4.resetControl != 0) && (configPage4.resetControlPin < BOARD_NR_GPIO_PINS) )
|
||||
{
|
||||
resetControl = configPage4.resetControl;
|
||||
pinResetControl = pinTranslate(configPage4.resetControlPin);
|
||||
setResetControlPinState();
|
||||
pinMode(pinResetControl, OUTPUT);
|
||||
}
|
||||
|
||||
//Finally, set the relevant pin modes for outputs
|
||||
pinMode(pinCoil1, OUTPUT);
|
||||
|
@ -605,7 +652,7 @@ void setPinMapping(byte boardID)
|
|||
pinMode(pinTrigger2, INPUT);
|
||||
pinMode(pinTrigger3, INPUT);
|
||||
pinMode(pinFlex, INPUT_PULLUP); //Standard GM / Continental flex sensor requires pullup
|
||||
if (configPage3.lnchPullRes == true) {
|
||||
if (configPage6.lnchPullRes == true) {
|
||||
pinMode(pinLaunch, INPUT_PULLUP);
|
||||
}
|
||||
else {
|
||||
|
@ -684,7 +731,7 @@ void initialiseTriggers()
|
|||
detachInterrupt(triggerInterrupt2);
|
||||
|
||||
//Set the trigger function based on the decoder in the config
|
||||
switch (configPage2.TrigPattern)
|
||||
switch (configPage4.TrigPattern)
|
||||
{
|
||||
case 0:
|
||||
//Missing tooth decoder
|
||||
|
@ -695,9 +742,9 @@ void initialiseTriggers()
|
|||
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)
|
||||
if(configPage4.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); }
|
||||
if(configPage4.TrigEdgeSec == 0) { attachInterrupt(triggerInterrupt2, triggerSec_missingTooth, RISING); }
|
||||
else { attachInterrupt(triggerInterrupt2, triggerSec_missingTooth, FALLING); }
|
||||
break;
|
||||
|
||||
|
@ -709,7 +756,7 @@ void initialiseTriggers()
|
|||
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)
|
||||
if(configPage4.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;
|
||||
|
||||
|
@ -720,9 +767,9 @@ void initialiseTriggers()
|
|||
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)
|
||||
if(configPage4.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); }
|
||||
if(configPage4.TrigEdgeSec == 0) { attachInterrupt(triggerInterrupt2, triggerSec_DualWheel, RISING); }
|
||||
else { attachInterrupt(triggerInterrupt2, triggerSec_DualWheel, FALLING); }
|
||||
break;
|
||||
|
||||
|
@ -733,7 +780,7 @@ void initialiseTriggers()
|
|||
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)
|
||||
if(configPage4.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;
|
||||
|
||||
|
@ -745,7 +792,7 @@ void initialiseTriggers()
|
|||
triggerSetEndTeeth = triggerSetEndTeeth_4G63;
|
||||
|
||||
//These may both need to change, not sure
|
||||
if(configPage2.TrigEdge == 0)
|
||||
if(configPage4.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
|
||||
|
@ -764,7 +811,7 @@ void initialiseTriggers()
|
|||
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)
|
||||
if(configPage4.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;
|
||||
|
@ -776,7 +823,7 @@ void initialiseTriggers()
|
|||
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)
|
||||
if(configPage4.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;
|
||||
|
@ -788,7 +835,7 @@ void initialiseTriggers()
|
|||
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)
|
||||
if(configPage4.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;
|
||||
|
@ -800,7 +847,7 @@ void initialiseTriggers()
|
|||
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)
|
||||
if(configPage4.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;
|
||||
|
@ -814,10 +861,10 @@ void initialiseTriggers()
|
|||
|
||||
//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); }
|
||||
if(configPage4.TrigEdge == 0) { attachInterrupt(triggerInterrupt, trigger, RISING); }
|
||||
else { attachInterrupt(triggerInterrupt, trigger, FALLING); }
|
||||
|
||||
if(configPage2.TrigEdgeSec == 0) { attachInterrupt(triggerInterrupt2, triggerSec_Miata9905, RISING); }
|
||||
if(configPage4.TrigEdgeSec == 0) { attachInterrupt(triggerInterrupt2, triggerSec_Miata9905, RISING); }
|
||||
else { attachInterrupt(triggerInterrupt2, triggerSec_Miata9905, FALLING); }
|
||||
break;
|
||||
|
||||
|
@ -828,7 +875,7 @@ void initialiseTriggers()
|
|||
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)
|
||||
if(configPage4.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;
|
||||
|
@ -840,7 +887,7 @@ void initialiseTriggers()
|
|||
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)
|
||||
if(configPage4.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;
|
||||
|
@ -852,7 +899,7 @@ void initialiseTriggers()
|
|||
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)
|
||||
if(configPage4.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;
|
||||
|
@ -864,7 +911,7 @@ void initialiseTriggers()
|
|||
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)
|
||||
if(configPage4.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;
|
||||
|
@ -876,7 +923,7 @@ void initialiseTriggers()
|
|||
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)
|
||||
if(configPage4.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;
|
||||
|
@ -901,9 +948,9 @@ void initialiseTriggers()
|
|||
getCrankAngle = getCrankAngle_missingTooth; //This uses the same function as the missing tooth decoder, so no need to duplicate code
|
||||
triggerSetEndTeeth = triggerSetEndTeeth_ThirtySixMinus222;
|
||||
|
||||
if(configPage2.TrigEdge == 0) { attachInterrupt(triggerInterrupt, trigger, RISING); } // Attach the crank trigger wheel interrupt (Hall sensor drags to ground when triggering)
|
||||
if(configPage4.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, triggerSecondary, RISING); }
|
||||
if(configPage4.TrigEdgeSec == 0) { attachInterrupt(triggerInterrupt2, triggerSecondary, RISING); }
|
||||
else { attachInterrupt(triggerInterrupt2, triggerSecondary, FALLING); }
|
||||
break;
|
||||
|
||||
|
@ -912,7 +959,7 @@ void initialiseTriggers()
|
|||
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)
|
||||
if(configPage4.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;
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue