forked from noisymime/speeduino
/
globals.h
1608 lines (1389 loc) · 71.4 KB
/
globals.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
/** @file
* Global defines, macros, struct definitions (@ref statuses, @ref config2, @ref config4, config*), extern-definitions (for globally accessible vars).
*
* ### Note on configuration struct layouts
*
* Once the struct members have been assigned to certain "role" (in certain SW version), they should not be "moved around"
* as the structs are stored onto EEPROM as-is and the offset and size of member needs to remain constant. Also removing existing struct members
* would disturb layouts. Because of this a certain amount unused old members will be left into the structs. For the storage related reasons also the
* bit fields are defined in byte-size (or multiple of ...) chunks.
*
* ### Config Structs and 2D, 3D Tables
*
* The config* structures contain information coming from tuning SW (e.g. TS) for 2D and 3D tables, where looked up value is not a result of direct
* array lookup, but from interpolation algorithm. Because of standard, reusable interpolation routines associated with structs table2D and table3D,
* the values from config are copied from config* structs to table2D (table3D destined configurations are not stored in config* structures).
*
* ### Board choice
* There's a C-preprocessor based "#if defined" logic present in this header file based on the Arduino IDE compiler set CPU
* (+board?) type, e.g. `__AVR_ATmega2560__`. This respectively drives (withi it's "#if defined ..." block):
* - The setting of various BOARD_* C-preprocessor variables (e.g. BOARD_MAX_ADC_PINS)
* - Setting of BOARD_H (Board header) file (e.g. "board_avr2560.h"), which is later used to include the header file
* - Seems Arduino ide implicitly compiles and links respective .ino file (by it's internal build/compilation rules) (?)
* - Setting of CPU (?) CORE_* variables (e.g. CORE_AVR), that is used across codebase to distinguish CPU.
*/
#ifndef GLOBALS_H
#define GLOBALS_H
#include <Arduino.h>
#include "table2d.h"
#include "table3d.h"
#include <assert.h>
#include "logger.h"
#include "src/FastCRC/FastCRC.h"
#if defined(__AVR_ATmega1280__) || defined(__AVR_ATmega2560__) || defined(__AVR_ATmega2561__)
#define BOARD_MAX_DIGITAL_PINS 54 //digital pins +1
#define BOARD_MAX_IO_PINS 70 //digital pins + analog channels + 1
#define BOARD_MAX_ADC_PINS 15 //Number of analog pins
#ifndef LED_BUILTIN
#define LED_BUILTIN 13
#endif
#define CORE_AVR
#define BOARD_H "board_avr2560.h"
#define INJ_CHANNELS 4
#define IGN_CHANNELS 5
#if defined(__AVR_ATmega2561__)
//This is a workaround to avoid having to change all the references to higher ADC channels. We simply define the channels (Which don't exist on the 2561) as being the same as A0-A7
//These Analog inputs should never be used on any 2561 board definition (Because they don't exist on the MCU), so it will not cause any issues
#define A8 A0
#define A9 A1
#define A10 A2
#define A11 A3
#define A12 A4
#define A13 A5
#define A14 A6
#define A15 A7
#endif
//#define TIMER5_MICROS
#elif defined(CORE_TEENSY)
#if defined(__MK64FX512__) || defined(__MK66FX1M0__)
#define CORE_TEENSY35
#define BOARD_H "board_teensy35.h"
#define BOARD_MAX_ADC_PINS 22 //Number of analog pins
#elif defined(__IMXRT1062__)
#define CORE_TEENSY41
#define BOARD_H "board_teensy41.h"
#define BOARD_MAX_ADC_PINS 17 //Number of analog pins
#endif
#define INJ_CHANNELS 8
#define IGN_CHANNELS 8
#elif defined(STM32_MCU_SERIES) || defined(ARDUINO_ARCH_STM32) || defined(STM32)
#define CORE_STM32
#define BOARD_MAX_ADC_PINS NUM_ANALOG_INPUTS-1 //Number of analog pins from core.
#if defined(STM32F407xx) //F407 can do 8x8 STM32F401/STM32F411 not
#define INJ_CHANNELS 8
#define IGN_CHANNELS 8
#else
#define INJ_CHANNELS 4
#define IGN_CHANNELS 5
#endif
//Select one for EEPROM,the default is EEPROM emulation on internal flash.
//#define SRAM_AS_EEPROM /*Use 4K battery backed SRAM, requires a 3V continuous source (like battery) connected to Vbat pin */
//#define USE_SPI_EEPROM PB0 /*Use M25Qxx SPI flash */
//#define FRAM_AS_EEPROM /*Use FRAM like FM25xxx, MB85RSxxx or any SPI compatible */
#ifndef word
#define word(h, l) ((h << 8) | l) //word() function not defined for this platform in the main library
#endif
#if defined(ARDUINO_BLUEPILL_F103C8) || defined(ARDUINO_BLUEPILL_F103CB) \
|| defined(ARDUINO_BLACKPILL_F401CC) || defined(ARDUINO_BLACKPILL_F411CE)
//STM32 Pill boards
#ifndef NUM_DIGITAL_PINS
#define NUM_DIGITAL_PINS 35
#endif
#ifndef LED_BUILTIN
#define LED_BUILTIN PB1 //Maple Mini
#endif
#elif defined(STM32F407xx)
#ifndef NUM_DIGITAL_PINS
#define NUM_DIGITAL_PINS 75
#endif
#endif
#if defined(STM32_CORE_VERSION)
#define BOARD_H "board_stm32_official.h"
#else
#define CORE_STM32_GENERIC
#define BOARD_H "board_stm32_generic.h"
#endif
//Specific mode for Bluepill due to its small flash size. This disables a number of strings from being compiled into the flash
#if defined(MCU_STM32F103C8) || defined(MCU_STM32F103CB)
#define SMALL_FLASH_MODE
#endif
#define BOARD_MAX_DIGITAL_PINS NUM_DIGITAL_PINS
#define BOARD_MAX_IO_PINS NUM_DIGITAL_PINS
#if __GNUC__ < 7 //Already included on GCC 7
extern "C" char* sbrk(int incr); //Used to freeRam
#endif
#ifndef digitalPinToInterrupt
inline uint32_t digitalPinToInterrupt(uint32_t Interrupt_pin) { return Interrupt_pin; } //This isn't included in the stm32duino libs (yet)
#endif
#elif defined(__SAMD21G18A__)
#define BOARD_H "board_samd21.h"
#define CORE_SAMD21
#define CORE_SAM
#define INJ_CHANNELS 4
#define IGN_CHANNELS 4
#elif defined(__SAMC21J18A__)
#define BOARD_H "board_samc21.h"
#define CORE_SAMC21
#define CORE_SAM
#elif defined(__SAME51J19A__)
#define BOARD_H "board_same51.h"
#define CORE_SAME51
#define CORE_SAM
#define INJ_CHANNELS 8
#define IGN_CHANNELS 8
#else
#error Incorrect board selected. Please select the correct board (Usually Mega 2560) and upload again
#endif
//This can only be included after the above section
#include BOARD_H //Note that this is not a real file, it is defined in globals.h.
//Handy bitsetting macros
#define BIT_SET(a,b) ((a) |= (1U<<(b)))
#define BIT_CLEAR(a,b) ((a) &= ~(1U<<(b)))
#define BIT_CHECK(var,pos) !!((var) & (1U<<(pos)))
#define BIT_TOGGLE(var,pos) ((var)^= 1UL << (pos))
#define BIT_WRITE(var, pos, bitvalue) ((bitvalue) ? BIT_SET((var), (pos)) : bitClear((var), (pos)))
#define interruptSafe(c) (noInterrupts(); {c} interrupts();) //Wraps any code between nointerrupt and interrupt calls
#define MS_IN_MINUTE 60000
#define US_IN_MINUTE 60000000
//Define the load algorithm
#define LOAD_SOURCE_MAP 0
#define LOAD_SOURCE_TPS 1
#define LOAD_SOURCE_IMAPEMAP 2
//Define bit positions within engine variable
#define BIT_ENGINE_RUN 0 // Engine running
#define BIT_ENGINE_CRANK 1 // Engine cranking
#define BIT_ENGINE_ASE 2 // after start enrichment (ASE)
#define BIT_ENGINE_WARMUP 3 // Engine in warmup
#define BIT_ENGINE_ACC 4 // in acceleration mode (TPS accel)
#define BIT_ENGINE_DCC 5 // in deceleration mode
#define BIT_ENGINE_MAPACC 6 // MAP acceleration mode
#define BIT_ENGINE_MAPDCC 7 // MAP deceleration mode
//Define masks for Status1
#define BIT_STATUS1_INJ1 0 //inj1
#define BIT_STATUS1_INJ2 1 //inj2
#define BIT_STATUS1_INJ3 2 //inj3
#define BIT_STATUS1_INJ4 3 //inj4
#define BIT_STATUS1_DFCO 4 //Deceleration fuel cutoff
#define BIT_STATUS1_BOOSTCUT 5 //Fuel component of MAP based boost cut out
#define BIT_STATUS1_TOOTHLOG1READY 6 //Used to flag if tooth log 1 is ready
#define BIT_STATUS1_TOOTHLOG2READY 7 //Used to flag if tooth log 2 is ready (Log is not currently used)
//Define masks for spark variable
#define BIT_SPARK_HLAUNCH 0 //Hard Launch indicator
#define BIT_SPARK_SLAUNCH 1 //Soft Launch indicator
#define BIT_SPARK_HRDLIM 2 //Hard limiter indicator
#define BIT_SPARK_SFTLIM 3 //Soft limiter indicator
#define BIT_SPARK_BOOSTCUT 4 //Spark component of MAP based boost cut out
#define BIT_SPARK_ERROR 5 // Error is detected
#define BIT_SPARK_IDLE 6 // idle on
#define BIT_SPARK_SYNC 7 // Whether engine has sync or not
#define BIT_SPARK2_FLATSH 0 //Flat shift hard cut
#define BIT_SPARK2_FLATSS 1 //Flat shift soft cut
#define BIT_SPARK2_SPARK2_ACTIVE 2
#define BIT_SPARK2_UNUSED4 3
#define BIT_SPARK2_UNUSED5 4
#define BIT_SPARK2_UNUSED6 5
#define BIT_SPARK2_UNUSED7 6
#define BIT_SPARK2_UNUSED8 7
#define BIT_TIMER_1HZ 0
#define BIT_TIMER_4HZ 1
#define BIT_TIMER_10HZ 2
#define BIT_TIMER_15HZ 3
#define BIT_TIMER_30HZ 4
#define BIT_STATUS3_RESET_PREVENT 0 //Indicates whether reset prevention is enabled
#define BIT_STATUS3_NITROUS 1
#define BIT_STATUS3_FUEL2_ACTIVE 2
#define BIT_STATUS3_VSS_REFRESH 3
#define BIT_STATUS3_HALFSYNC 4 //shows if there is only sync from primary trigger, but not from secondary.
#define BIT_STATUS3_NSQUIRTS1 5
#define BIT_STATUS3_NSQUIRTS2 6
#define BIT_STATUS3_NSQUIRTS3 7
#define BIT_STATUS4_WMI_EMPTY 0 //Indicates whether the WMI tank is empty
#define BIT_STATUS4_VVT1_ERROR 1 //VVT1 cam angle within limits or not
#define BIT_STATUS4_VVT2_ERROR 2 //VVT2 cam angle within limits or not
#define BIT_STATUS4_FAN 3 //Fan Status
#define BIT_STATUS4_BURNPENDING 4
#define BIT_STATUS4_UNUSED6 5
#define BIT_STATUS4_UNUSED7 6
#define BIT_STATUS4_UNUSED8 7
#define BIT_AIRCON_REQUEST 0 //Indicates whether the A/C button is pressed
#define BIT_AIRCON_COMPRESSOR 1 //Indicates whether the A/C compressor is running
#define BIT_AIRCON_RPM_LOCKOUT 2 //Indicates the A/C is locked out due to the RPM being too high/low, or the post-high/post-low-RPM "stand-down" lockout period
#define BIT_AIRCON_TPS_LOCKOUT 3 //Indicates the A/C is locked out due to high TPS, or the post-high-TPS "stand-down" lockout period
#define BIT_AIRCON_TURNING_ON 4 //Indicates the A/C request is on (i.e. A/C button pressed), the lockouts are off, however the start delay has not yet elapsed. This gives the idle up time to kick in before the compressor.
#define BIT_AIRCON_CLT_LOCKOUT 5 //Indicates the A/C is locked out either due to high coolant temp.
#define BIT_AIRCON_FAN 6 //Indicates whether the A/C fan is running
#define BIT_AIRCON_UNUSED8 7
#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
#ifndef UNIT_TEST
#define TOOTH_LOG_SIZE 127
#else
#define TOOTH_LOG_SIZE 1
#endif
#define O2_CALIBRATION_PAGE 2
#define IAT_CALIBRATION_PAGE 1
#define CLT_CALIBRATION_PAGE 0
#define COMPOSITE_LOG_PRI 0
#define COMPOSITE_LOG_SEC 1
#define COMPOSITE_LOG_TRIG 2
#define COMPOSITE_LOG_SYNC 3
#define EGO_TYPE_OFF 0
#define EGO_TYPE_NARROW 1
#define EGO_TYPE_WIDE 2
#define INJ_TYPE_PORT 0
#define INJ_TYPE_TBODY 1
#define INJ_PAIRED 0
#define INJ_SEMISEQUENTIAL 1
#define INJ_BANKED 2
#define INJ_SEQUENTIAL 3
#define INJ_PAIR_13_24 0
#define INJ_PAIR_14_23 1
#define OUTPUT_CONTROL_DIRECT 0
#define OUTPUT_CONTROL_MC33810 10
#define IGN_MODE_WASTED 0
#define IGN_MODE_SINGLE 1
#define IGN_MODE_WASTEDCOP 2
#define IGN_MODE_SEQUENTIAL 3
#define IGN_MODE_ROTARY 4
#define SEC_TRIGGER_SINGLE 0
#define SEC_TRIGGER_4_1 1
#define SEC_TRIGGER_POLL 2
#define ROTARY_IGN_FC 0
#define ROTARY_IGN_FD 1
#define ROTARY_IGN_RX8 2
#define BOOST_MODE_SIMPLE 0
#define BOOST_MODE_FULL 1
#define EN_BOOST_CONTROL_BARO 0
#define EN_BOOST_CONTROL_FIXED 1
#define WMI_MODE_SIMPLE 0
#define WMI_MODE_PROPORTIONAL 1
#define WMI_MODE_OPENLOOP 2
#define WMI_MODE_CLOSEDLOOP 3
#define HARD_CUT_FULL 0
#define HARD_CUT_ROLLING 1
#define EVEN_FIRE 0
#define ODD_FIRE 1
#define EGO_ALGORITHM_SIMPLE 0
#define EGO_ALGORITHM_PID 2
#define STAGING_MODE_TABLE 0
#define STAGING_MODE_AUTO 1
#define NITROUS_OFF 0
#define NITROUS_STAGE1 1
#define NITROUS_STAGE2 2
#define NITROUS_BOTH 3
#define PROTECT_CUT_OFF 0
#define PROTECT_CUT_IGN 1
#define PROTECT_CUT_FUEL 2
#define PROTECT_CUT_BOTH 3
#define PROTECT_IO_ERROR 7
#define AE_MODE_TPS 0
#define AE_MODE_MAP 1
#define AE_MODE_MULTIPLIER 0
#define AE_MODE_ADDER 1
#define KNOCK_MODE_OFF 0
#define KNOCK_MODE_DIGITAL 1
#define KNOCK_MODE_ANALOG 2
#define FUEL2_MODE_OFF 0
#define FUEL2_MODE_MULTIPLY 1
#define FUEL2_MODE_ADD 2
#define FUEL2_MODE_CONDITIONAL_SWITCH 3
#define FUEL2_MODE_INPUT_SWITCH 4
#define SPARK2_MODE_OFF 0
#define SPARK2_MODE_MULTIPLY 1
#define SPARK2_MODE_ADD 2
#define SPARK2_MODE_CONDITIONAL_SWITCH 3
#define SPARK2_MODE_INPUT_SWITCH 4
#define FUEL2_CONDITION_RPM 0
#define FUEL2_CONDITION_MAP 1
#define FUEL2_CONDITION_TPS 2
#define FUEL2_CONDITION_ETH 3
#define SPARK2_CONDITION_RPM 0
#define SPARK2_CONDITION_MAP 1
#define SPARK2_CONDITION_TPS 2
#define SPARK2_CONDITION_ETH 3
#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 OPEN_LOOP_BOOST 0
#define CLOSED_LOOP_BOOST 1
#define SOFT_LIMIT_FIXED 0
#define SOFT_LIMIT_RELATIVE 1
#define VVT_MODE_ONOFF 0
#define VVT_MODE_OPEN_LOOP 1
#define VVT_MODE_CLOSED_LOOP 2
#define VVT_LOAD_MAP 0
#define VVT_LOAD_TPS 1
#define MULTIPLY_MAP_MODE_OFF 0
#define MULTIPLY_MAP_MODE_BARO 1
#define MULTIPLY_MAP_MODE_100 2
#define FOUR_STROKE 0
#define TWO_STROKE 1
#define GOING_LOW 0
#define GOING_HIGH 1
#define MAX_RPM 18000 /**< 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 BATTV_COR_MODE_WHOLE 0
#define BATTV_COR_MODE_OPENTIME 1
#define INJ1_CMD_BIT 0
#define INJ2_CMD_BIT 1
#define INJ3_CMD_BIT 2
#define INJ4_CMD_BIT 3
#define INJ5_CMD_BIT 4
#define INJ6_CMD_BIT 5
#define INJ7_CMD_BIT 6
#define INJ8_CMD_BIT 7
#define IGN1_CMD_BIT 0
#define IGN2_CMD_BIT 1
#define IGN3_CMD_BIT 2
#define IGN4_CMD_BIT 3
#define IGN5_CMD_BIT 4
#define IGN6_CMD_BIT 5
#define IGN7_CMD_BIT 6
#define IGN8_CMD_BIT 7
#define ENGINE_PROTECT_BIT_RPM 0
#define ENGINE_PROTECT_BIT_MAP 1
#define ENGINE_PROTECT_BIT_OIL 2
#define ENGINE_PROTECT_BIT_AFR 3
#define ENGINE_PROTECT_BIT_COOLANT 4
#define CALIBRATION_TABLE_SIZE 512 ///< Calibration table size for CLT, IAT, O2
#define CALIBRATION_TEMPERATURE_OFFSET 40 /**< All temperature measurements are stored offset by 40 degrees.
This is so we can use an unsigned byte (0-255) to represent temperature ranges from -40 to 215 */
#define OFFSET_FUELTRIM 127 ///< The fuel trim tables are offset by 128 to allow for -128 to +128 values
#define OFFSET_IGNITION 40 ///< Ignition values from the main spark table are offset 40 degrees downwards to allow for negative spark timing
#define SERIAL_BUFFER_THRESHOLD 32 ///< When the serial buffer is filled to greater than this threshold value, the serial processing operations will be performed more urgently in order to avoid it overflowing. Serial buffer is 64 bytes long, so the threshold is set at half this as a reasonable figure
#ifndef CORE_TEENSY41
#define FUEL_PUMP_ON() *pump_pin_port |= (pump_pin_mask)
#define FUEL_PUMP_OFF() *pump_pin_port &= ~(pump_pin_mask)
#else
//Special compatibility case for TEENSY 41 (for now)
#define FUEL_PUMP_ON() digitalWrite(pinFuelPump, HIGH);
#define FUEL_PUMP_OFF() digitalWrite(pinFuelPump, LOW);
#endif
#define LOGGER_CSV_SEPARATOR_SEMICOLON 0
#define LOGGER_CSV_SEPARATOR_COMMA 1
#define LOGGER_CSV_SEPARATOR_TAB 2
#define LOGGER_CSV_SEPARATOR_SPACE 3
#define LOGGER_DISABLED 0
#define LOGGER_CSV 1
#define LOGGER_BINARY 2
#define LOGGER_RATE_1HZ 0
#define LOGGER_RATE_4HZ 1
#define LOGGER_RATE_10HZ 2
#define LOGGER_RATE_30HZ 3
#define LOGGER_FILENAMING_OVERWRITE 0
#define LOGGER_FILENAMING_DATETIME 1
#define LOGGER_FILENAMING_SEQENTIAL 2
extern const char TSfirmwareVersion[] PROGMEM;
extern const byte data_structure_version; //This identifies the data structure when reading / writing. Now in use: CURRENT_DATA_VERSION (migration on-the fly) ?
extern FastCRC32 CRC32; //Generic CRC32 instance for general use in pages etc. Note that the serial comms has its own CRC32 instance
extern struct table3d16RpmLoad fuelTable; //16x16 fuel map
extern struct table3d16RpmLoad fuelTable2; //16x16 fuel map
extern struct table3d16RpmLoad ignitionTable; //16x16 ignition map
extern struct table3d16RpmLoad ignitionTable2; //16x16 ignition map
extern struct table3d16RpmLoad afrTable; //16x16 afr target map
extern struct table3d8RpmLoad stagingTable; //8x8 fuel staging table
extern struct table3d8RpmLoad boostTable; //8x8 boost map
extern struct table3d8RpmLoad boostTableLookupDuty; //8x8 boost map
extern struct table3d8RpmLoad vvtTable; //8x8 vvt map
extern struct table3d8RpmLoad vvt2Table; //8x8 vvt map
extern struct table3d8RpmLoad wmiTable; //8x8 wmi map
typedef table3d6RpmLoad trimTable3d;
extern trimTable3d trim1Table; //6x6 Fuel trim 1 map
extern trimTable3d trim2Table; //6x6 Fuel trim 2 map
extern trimTable3d trim3Table; //6x6 Fuel trim 3 map
extern trimTable3d trim4Table; //6x6 Fuel trim 4 map
extern trimTable3d trim5Table; //6x6 Fuel trim 5 map
extern trimTable3d trim6Table; //6x6 Fuel trim 6 map
extern trimTable3d trim7Table; //6x6 Fuel trim 7 map
extern trimTable3d trim8Table; //6x6 Fuel trim 8 map
extern struct table3d4RpmLoad dwellTable; //4x4 Dwell map
extern struct table2D taeTable; //4 bin TPS Acceleration Enrichment map (2D)
extern struct table2D maeTable;
extern struct table2D WUETable; //10 bin Warm Up Enrichment map (2D)
extern struct table2D ASETable; //4 bin After Start Enrichment map (2D)
extern struct table2D ASECountTable; //4 bin After Start duration map (2D)
extern struct table2D PrimingPulseTable; //4 bin Priming pulsewidth map (2D)
extern struct table2D crankingEnrichTable; //4 bin cranking Enrichment map (2D)
extern struct table2D dwellVCorrectionTable; //6 bin dwell voltage correction (2D)
extern struct table2D injectorVCorrectionTable; //6 bin injector voltage correction (2D)
extern struct table2D injectorAngleTable; //4 bin injector timing curve (2D)
extern struct table2D IATDensityCorrectionTable; //9 bin inlet air temperature density correction (2D)
extern struct table2D baroFuelTable; //8 bin baro correction curve (2D)
extern struct table2D IATRetardTable; //6 bin ignition adjustment based on inlet air temperature (2D)
extern struct table2D idleTargetTable; //10 bin idle target table for idle timing (2D)
extern struct table2D idleAdvanceTable; //6 bin idle advance adjustment table based on RPM difference (2D)
extern struct table2D CLTAdvanceTable; //6 bin ignition adjustment based on coolant temperature (2D)
extern struct table2D rotarySplitTable; //8 bin ignition split curve for rotary leading/trailing (2D)
extern struct table2D flexFuelTable; //6 bin flex fuel correction table for fuel adjustments (2D)
extern struct table2D flexAdvTable; //6 bin flex fuel correction table for timing advance (2D)
extern struct table2D flexBoostTable; //6 bin flex fuel correction table for boost adjustments (2D)
extern struct table2D fuelTempTable; //6 bin fuel temperature correction table for fuel adjustments (2D)
extern struct table2D knockWindowStartTable;
extern struct table2D knockWindowDurationTable;
extern struct table2D oilPressureProtectTable;
extern struct table2D wmiAdvTable; //6 bin wmi correction table for timing advance (2D)
extern struct table2D coolantProtectTable; //6 bin coolant temperature protection table for engine protection (2D)
extern struct table2D fanPWMTable;
//These are for the direct port manipulation of the injectors, coils and aux outputs
extern volatile PORT_TYPE *inj1_pin_port;
extern volatile PINMASK_TYPE inj1_pin_mask;
extern volatile PORT_TYPE *inj2_pin_port;
extern volatile PINMASK_TYPE inj2_pin_mask;
extern volatile PORT_TYPE *inj3_pin_port;
extern volatile PINMASK_TYPE inj3_pin_mask;
extern volatile PORT_TYPE *inj4_pin_port;
extern volatile PINMASK_TYPE inj4_pin_mask;
extern volatile PORT_TYPE *inj5_pin_port;
extern volatile PINMASK_TYPE inj5_pin_mask;
extern volatile PORT_TYPE *inj6_pin_port;
extern volatile PINMASK_TYPE inj6_pin_mask;
extern volatile PORT_TYPE *inj7_pin_port;
extern volatile PINMASK_TYPE inj7_pin_mask;
extern volatile PORT_TYPE *inj8_pin_port;
extern volatile PINMASK_TYPE inj8_pin_mask;
extern volatile PORT_TYPE *ign1_pin_port;
extern volatile PINMASK_TYPE ign1_pin_mask;
extern volatile PORT_TYPE *ign2_pin_port;
extern volatile PINMASK_TYPE ign2_pin_mask;
extern volatile PORT_TYPE *ign3_pin_port;
extern volatile PINMASK_TYPE ign3_pin_mask;
extern volatile PORT_TYPE *ign4_pin_port;
extern volatile PINMASK_TYPE ign4_pin_mask;
extern volatile PORT_TYPE *ign5_pin_port;
extern volatile PINMASK_TYPE ign5_pin_mask;
extern volatile PORT_TYPE *ign6_pin_port;
extern volatile PINMASK_TYPE ign6_pin_mask;
extern volatile PORT_TYPE *ign7_pin_port;
extern volatile PINMASK_TYPE ign7_pin_mask;
extern volatile PORT_TYPE *ign8_pin_port;
extern volatile PINMASK_TYPE ign8_pin_mask;
extern volatile PORT_TYPE *tach_pin_port;
extern volatile PINMASK_TYPE tach_pin_mask;
extern volatile PORT_TYPE *pump_pin_port;
extern volatile PINMASK_TYPE pump_pin_mask;
extern volatile PORT_TYPE *flex_pin_port;
extern volatile PINMASK_TYPE flex_pin_mask;
extern volatile PORT_TYPE *triggerPri_pin_port;
extern volatile PINMASK_TYPE triggerPri_pin_mask;
extern volatile PORT_TYPE *triggerSec_pin_port;
extern volatile PINMASK_TYPE triggerSec_pin_mask;
extern byte triggerInterrupt;
extern byte triggerInterrupt2;
extern byte triggerInterrupt3;
//These need to be here as they are used in both speeduino.ino and scheduler.ino
extern bool channel1InjEnabled;
extern bool channel2InjEnabled;
extern bool channel3InjEnabled;
extern bool channel4InjEnabled;
extern bool channel5InjEnabled;
extern bool channel6InjEnabled;
extern bool channel7InjEnabled;
extern bool channel8InjEnabled;
extern int ignition1EndAngle;
extern int ignition2EndAngle;
extern int ignition3EndAngle;
extern int ignition4EndAngle;
extern int ignition5EndAngle;
extern int ignition6EndAngle;
extern int ignition7EndAngle;
extern int ignition8EndAngle;
extern int ignition1StartAngle;
extern int ignition2StartAngle;
extern int ignition3StartAngle;
extern int ignition4StartAngle;
extern int ignition5StartAngle;
extern int ignition6StartAngle;
extern int ignition7StartAngle;
extern int ignition8StartAngle;
extern bool initialisationComplete; //Tracks whether the setup() function has run completely
extern byte fpPrimeTime; //The time (in seconds, based on currentStatus.secl) that the fuel pump started priming
extern uint8_t softLimitTime; //The time (in 0.1 seconds, based on seclx10) that the soft limiter started
extern volatile uint16_t mainLoopCount;
extern 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)
extern volatile unsigned long timer5_overflow_count; //Increments every time counter 5 overflows. Used for the fast version of micros()
extern volatile unsigned long ms_counter; //A counter that increments once per ms
extern uint16_t fixedCrankingOverride;
extern bool clutchTrigger;
extern bool previousClutchTrigger;
extern volatile uint32_t toothHistory[TOOTH_LOG_SIZE];
extern volatile uint8_t compositeLogHistory[TOOTH_LOG_SIZE];
extern volatile bool fpPrimed; //Tracks whether or not the fuel pump priming has been completed yet
extern volatile bool injPrimed; //Tracks whether or not the injector priming has been completed yet
extern volatile unsigned int toothHistoryIndex;
extern unsigned long currentLoopTime; /**< The time (in uS) that the current mainloop started */
extern volatile uint16_t ignitionCount; /**< The count of ignition events that have taken place since the engine started */
//The below shouldn't be needed and probably should be cleaned up, but the Atmel SAM (ARM) boards use a specific type for the trigger edge values rather than a simple byte/int
#if defined(CORE_SAMD21)
extern PinStatus primaryTriggerEdge;
extern PinStatus secondaryTriggerEdge;
extern PinStatus tertiaryTriggerEdge;
#else
extern byte primaryTriggerEdge;
extern byte secondaryTriggerEdge;
extern byte tertiaryTriggerEdge;
#endif
extern int CRANK_ANGLE_MAX;
extern int CRANK_ANGLE_MAX_IGN;
extern int CRANK_ANGLE_MAX_INJ; ///< The number of crank degrees that the system track over. 360 for wasted / timed batch and 720 for sequential
extern volatile uint32_t runSecsX10; /**< Counter of seconds since cranking commenced (similar to runSecs) but in increments of 0.1 seconds */
extern volatile uint32_t seclx10; /**< Counter of seconds since powered commenced (similar to secl) but in increments of 0.1 seconds */
extern volatile byte HWTest_INJ; /**< Each bit in this variable represents one of the injector channels and it's HW test status */
extern volatile byte HWTest_INJ_50pc; /**< Each bit in this variable represents one of the injector channels and it's 50% HW test status */
extern volatile byte HWTest_IGN; /**< Each bit in this variable represents one of the ignition channels and it's HW test status */
extern volatile byte HWTest_IGN_50pc; /**< Each bit in this variable represents one of the ignition channels and it's 50% HW test status */
extern byte maxIgnOutputs; /**< Used for rolling rev limiter to indicate how many total ignition channels should currently be firing */
extern byte resetControl; ///< resetControl needs to be here (as global) because using the config page (4) directly can prevent burning the setting
extern volatile byte TIMER_mask;
extern volatile byte LOOP_TIMER;
//These functions all do checks on a pin to determine if it is already in use by another (higher importance) function
#define pinIsInjector(pin) ( ((pin) == pinInjector1) || ((pin) == pinInjector2) || ((pin) == pinInjector3) || ((pin) == pinInjector4) || ((pin) == pinInjector5) || ((pin) == pinInjector6) || ((pin) == pinInjector7) || ((pin) == pinInjector8) )
#define pinIsIgnition(pin) ( ((pin) == pinCoil1) || ((pin) == pinCoil2) || ((pin) == pinCoil3) || ((pin) == pinCoil4) || ((pin) == pinCoil5) || ((pin) == pinCoil6) || ((pin) == pinCoil7) || ((pin) == pinCoil8) )
//#define pinIsOutput(pin) ( pinIsInjector((pin)) || pinIsIgnition((pin)) || ((pin) == pinFuelPump) || ((pin) == pinFan) || ((pin) == pinAirConComp) || ((pin) == pinAirConFan)|| ((pin) == pinVVT_1) || ((pin) == pinVVT_2) || ( ((pin) == pinBoost) && configPage6.boostEnabled) || ((pin) == pinIdle1) || ((pin) == pinIdle2) || ((pin) == pinTachOut) || ((pin) == pinStepperEnable) || ((pin) == pinStepperStep) )
#define pinIsSensor(pin) ( ((pin) == pinCLT) || ((pin) == pinIAT) || ((pin) == pinMAP) || ((pin) == pinTPS) || ((pin) == pinO2) || ((pin) == pinBat) || (((pin) == pinFlex) && (configPage2.flexEnabled != 0)) )
//#define pinIsUsed(pin) ( pinIsSensor((pin)) || pinIsOutput((pin)) || pinIsReserved((pin)) )
/** The status struct with current values for all 'live' variables.
* In current version this is 64 bytes. Instantiated as global currentStatus.
* int *ADC (Analog-to-digital value / count) values contain the "raw" value from AD conversion, which get converted to
* unit based values in similar variable(s) without ADC part in name (see sensors.ino for reading of sensors).
*/
struct statuses {
volatile bool hasSync; /**< Flag for crank/cam position being known by decoders (See decoders.ino).
This is used for sanity checking e.g. before logging tooth history or reading some sensors and computing readings. */
uint16_t RPM; ///< RPM - Current Revs per minute
byte RPMdiv100; ///< RPM value scaled (divided by 100) to fit a byte (0-255, e.g. 12000 => 120)
long longRPM; ///< RPM as long int (gets assigned to / maintained in statuses.RPM as well)
int mapADC;
int baroADC;
long MAP; ///< Manifold absolute pressure. Has to be a long for PID calcs (Boost control)
int16_t EMAP; ///< EMAP ... (See @ref config6.useEMAP for EMAP enablement)
int16_t EMAPADC;
byte baro; ///< Barometric pressure is simply the initial MAP reading, taken before the engine is running. Alternatively, can be taken from an external sensor
byte TPS; /**< The current TPS reading (0% - 100%). Is the tpsADC value after the calibration is applied */
byte tpsADC; /**< byte (valued: 0-255) representation of the TPS. Downsampled from the original 10-bit (0-1023) reading, but before any calibration is applied */
byte tpsDOT; /**< TPS delta over time. Measures the % per second that the TPS is changing. Value is divided by 10 to be stored in a byte */
byte TPSlast; /**< The previous TPS reading */
byte mapDOT; /**< MAP delta over time. Measures the kpa per second that the MAP is changing. Value is divided by 10 to be stored in a byte */
volatile int rpmDOT; /**< RPM delta over time (RPM increase / s ?) */
byte VE; /**< The current VE value being used in the fuel calculation. Can be the same as VE1 or VE2, or a calculated value of both. */
byte VE1; /**< The VE value from fuel table 1 */
byte VE2; /**< The VE value from fuel table 2, if in use (and required conditions are met) */
byte O2; /**< Primary O2 sensor reading */
byte O2_2; /**< Secondary O2 sensor reading */
int coolant; /**< Coolant temperature reading */
int cltADC;
int IAT; /**< Inlet air temperature reading */
int iatADC;
int batADC;
int O2ADC;
int O2_2ADC;
int dwell; ///< dwell (coil primary winding/circuit on) time (in ms * 10 ? See @ref correctionsDwell)
byte dwellCorrection; /**< The amount of correction being applied to the dwell time (in unit ...). */
byte battery10; /**< The current BRV in volts (multiplied by 10. Eg 12.5V = 125) */
int8_t advance; /**< The current advance value being used in the spark calculation. Can be the same as advance1 or advance2, or a calculated value of both */
int8_t advance1; /**< The advance value from ignition table 1 */
int8_t advance2; /**< The advance value from ignition table 2 */
uint16_t corrections; /**< The total current corrections % amount */
uint16_t AEamount; /**< The amount of acceleration enrichment currently being applied. 100=No change. Varies above 255 */
byte egoCorrection; /**< The amount of closed loop AFR enrichment currently being applied */
byte wueCorrection; /**< The amount of warmup enrichment currently being applied */
byte batCorrection; /**< The amount of battery voltage enrichment currently being applied */
byte iatCorrection; /**< The amount of inlet air temperature adjustment currently being applied */
byte baroCorrection; /**< The amount of correction being applied for the current baro reading */
byte launchCorrection; /**< The amount of correction being applied if launch control is active */
byte flexCorrection; /**< Amount of correction being applied to compensate for ethanol content */
byte fuelTempCorrection; /**< Amount of correction being applied to compensate for fuel temperature */
int8_t flexIgnCorrection;/**< Amount of additional advance being applied based on flex. Note the type as this allows for negative values */
byte afrTarget; /**< Current AFR Target looked up from AFR target table (x10 ? See @ref afrTable)*/
byte CLIdleTarget; /**< The target idle RPM (when closed loop idle control is active) */
bool idleUpActive; /**< Whether the externally controlled idle up is currently active */
bool CTPSActive; /**< Whether the externally controlled closed throttle position sensor is currently active */
volatile byte ethanolPct; /**< Ethanol reading (if enabled). 0 = No ethanol, 100 = pure ethanol. Eg E85 = 85. */
volatile int8_t fuelTemp;
unsigned long AEEndTime; /**< The target end time used whenever AE (acceleration enrichment) is turned on */
volatile byte status1; ///< Status bits (See BIT_STATUS1_* defines on top of this file)
volatile byte spark; ///< Spark status/control indicator bits (launch control, boost cut, spark errors, See BIT_SPARK_* defines)
volatile byte spark2; ///< Spark 2 ... (See also @ref config10 spark2* members and BIT_SPARK2_* defines)
uint8_t engine; ///< Engine status bits (See BIT_ENGINE_* defines on top of this file)
unsigned int PW1; ///< In uS
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 (Maxes out at 255 to prevent overflow) */
volatile byte secl; /**< Counter incrementing once per second. Will overflow after 255 and begin again. This is used by TunerStudio to maintain comms sync */
volatile uint32_t loopsPerSecond; /**< A performance indicator showing the number of main loops that are being executed each second */
bool launchingSoft; /**< Indicator showing whether soft launch control adjustments are active */
bool launchingHard; /**< Indicator showing whether hard launch control adjustments are active */
uint16_t freeRAM;
unsigned int clutchEngagedRPM; /**< The RPM at which the clutch was last depressed. Used for distinguishing between launch control and flat shift */
bool flatShiftingHard;
volatile uint32_t startRevolutions; /**< A counter for how many revolutions have been completed since sync was achieved. */
uint16_t boostTarget;
byte testOutputs; ///< Test Output bits (only first bit used/tested ?)
bool testActive; // Not in use ? Replaced by testOutputs ?
uint16_t boostDuty; ///< Boost Duty percentage value * 100 to give 2 points of precision
byte idleLoad; ///< Either the current steps or current duty cycle for the idle control
uint16_t canin[16]; ///< 16bit raw value of selected canin data for channels 0-15
uint8_t current_caninchannel = 0; /**< Current CAN channel, defaults to 0 */
uint16_t crankRPM = 400; /**< The actual cranking RPM limit. This is derived from the value in the config page, but saves us multiplying it every time it's used (Config page value is stored divided by 10) */
volatile byte status3; ///< Status bits (See BIT_STATUS3_* defines on top of this file)
int16_t flexBoostCorrection; /**< Amount of boost added based on flex */
byte nitrous_status;
byte nSquirts; ///< Number of injector squirts per cycle (per injector)
byte nChannels; /**< Number of fuel and ignition channels. */
int16_t fuelLoad;
int16_t fuelLoad2;
int16_t ignLoad;
int16_t ignLoad2;
bool fuelPumpOn; /**< Indicator showing the current status of the fuel pump */
volatile byte syncLossCounter;
byte knockRetard;
bool knockActive;
bool toothLogEnabled;
bool compositeLogEnabled;
int16_t vvt1Angle; //Has to be a long for PID calcs (CL VVT control)
byte vvt1TargetAngle;
long vvt1Duty; //Has to be a long for PID calcs (CL VVT control)
uint16_t injAngle;
byte ASEValue;
uint16_t vss; /**< Current speed reading. Natively stored in kph and converted to mph in TS if required */
bool idleUpOutputActive; /**< Whether the idle up output is currently active */
byte gear; /**< Current gear (Calculated from vss) */
byte fuelPressure; /**< Fuel pressure in PSI */
byte oilPressure; /**< Oil pressure in PSI */
byte engineProtectStatus;
byte fanDuty;
byte wmiPW;
volatile byte status4; ///< Status bits (See BIT_STATUS4_* defines on top of this file)
int16_t vvt2Angle; //Has to be a long for PID calcs (CL VVT control)
byte vvt2TargetAngle;
long vvt2Duty; //Has to be a long for PID calcs (CL VVT control)
byte outputsStatus;
byte TS_SD_Status; //TunerStudios SD card status
byte airConStatus;
};
/** Page 2 of the config - mostly variables that are required for fuel.
* These are "non-live" EFI setting, engine and "system" variables that remain fixed once sent
* (and stored to e.g. EEPROM) from configuration/tuning SW (from outside by USBserial/bluetooth).
* Contains a lots of *Min, *Max (named) variables to constrain values to sane ranges.
* See the ini file for further reference.
*
*/
struct config2 {
byte aseTaperTime;
byte aeColdPct; //AE cold clt modifier %
byte aeColdTaperMin; //AE cold modifier, taper start temp (full modifier, was ASE in early versions)
byte aeMode : 2; /**< Acceleration Enrichment mode. 0 = TPS, 1 = MAP. Values 2 and 3 reserved for potential future use (ie blended TPS / MAP) */
byte battVCorMode : 1;
byte SoftLimitMode : 1;
byte useTachoSweep : 1;
byte aeApplyMode : 1; ///< Acceleration enrichment calc mode: 0 = Multiply | 1 = Add (AE_MODE_ADDER)
byte multiplyMAP : 2; ///< MAP value processing: 0 = off, 1 = div by currentStatus.baro, 2 = div by 100 (to gain usable value)
byte wueValues[10]; ///< Warm up enrichment array (10 bytes, transferred to @ref WUETable)
byte crankingPct; ///< Cranking enrichment (See @ref config10, updates.ino)
byte pinMapping; ///< The board / ping mapping number / id to be used (See: @ref setPinMapping in init.ino)
byte tachoPin : 6; ///< Custom pin setting for tacho output (if != 0, override copied to pinTachOut, which defaults to board assigned tach pin)
byte tachoDiv : 2; ///< Whether to change the tacho speed ("half speed tacho" ?)
byte tachoDuration; //The duration of the tacho pulse in mS
byte maeThresh; /**< The MAPdot threshold that must be exceeded before AE is engaged */
byte taeThresh; /**< The TPSdot threshold that must be exceeded before AE is engaged */
byte aeTime;
byte taeMinChange; /**< The minimum change in TPS that must be made before AE is engaged */
byte maeMinChange; /**< The minimum change in MAP that must be made before AE is engaged */
//Display config bits
byte displayB1 : 4; //23
byte displayB2 : 4;
byte reqFuel; //24
byte divider;
byte injTiming : 1; ///< Injector timing (aka. injector staging) 0=simultaneous, 1=alternating
byte multiplyMAP_old : 1;
byte includeAFR : 1; //< Enable AFR compensation ? (See also @ref config2.incorporateAFR)
byte hardCutType : 1;
byte ignAlgorithm : 3;
byte indInjAng : 1;
byte injOpen; ///< Injector opening time (ms * 10)
uint16_t injAng[4];
//config1 in ini
byte mapSample : 2; ///< MAP sampling method (0=Instantaneous, 1=Cycle Average, 2=Cycle Minimum, 4=Ign. event average, See sensors.ino)
byte strokes : 1; ///< Engine cycle type: four-stroke (0) / two-stroke (1)
byte injType : 1; ///< Injector type 0=Port (INJ_TYPE_PORT), 1=Throttle Body / TBI (INJ_TYPE_TBODY)
byte nCylinders : 4; ///< Number of cylinders
//config2 in ini
byte fuelAlgorithm : 3;///< Fuel algorithm - 0=Manifold pressure/MAP (LOAD_SOURCE_MAP, default, proven), 1=Throttle/TPS (LOAD_SOURCE_TPS), 2=IMAP/EMAP (LOAD_SOURCE_IMAPEMAP)
byte fixAngEnable : 1; ///< Whether fixed/locked timing is enabled (0=disable, 1=enable, See @ref configPage4.FixAng)
byte nInjectors : 4; ///< Number of injectors
//config3 in ini
byte engineType : 1; ///< Engine crank/ign phasing type: 0=even fire, 1=odd fire
byte flexEnabled : 1; ///< Enable Flex fuel sensing (pin / interrupt)
byte legacyMAP : 1; ///< Legacy MAP reading behaviour
byte baroCorr : 1; // Unused ?
byte injLayout : 2; /**< Injector Layout - 0=INJ_PAIRED (number outputs == number cyls/2, timed over 1 crank rev), 1=INJ_SEMISEQUENTIAL (like paired, but number outputs == number cyls, only for 4 cyl),
2=INJ_BANKED (2 outputs are used), 3=INJ_SEQUENTIAL (number outputs == number cyls, timed over full cycle, 2 crank revs) */
byte perToothIgn : 1; ///< Experimental / New ignition mode ... (?) (See decoders.ino)
byte dfcoEnabled : 1; ///< Whether or not DFCO (deceleration fuel cut-off) is turned on
byte aeColdTaperMax; ///< AE cold modifier, taper end temp (no modifier applied, was primePulse in early versions)
byte dutyLim;
byte flexFreqLow; //Lowest valid frequency reading from the flex sensor
byte flexFreqHigh; //Highest valid frequency reading from the flex sensor
byte boostMaxDuty;
byte tpsMin;
byte tpsMax;
int8_t mapMin; //Must be signed
uint16_t mapMax;
byte fpPrime; ///< Time (In seconds) that the fuel pump should be primed for on power up
byte stoich; ///< Stoichiometric ratio (x10, so e.g. 14.7 => 147)
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 idleUpPin : 6;
byte idleUpPolarity : 1;
byte idleUpEnabled : 1;
byte idleUpAdder;
byte aeTaperMin;
byte aeTaperMax;
byte iacCLminDuty;
byte iacCLmaxDuty;
byte boostMinDuty;
int8_t baroMin; //Must be signed
uint16_t baroMax;
int8_t EMAPMin; //Must be signed
uint16_t EMAPMax;
byte fanWhenOff : 1; ///< Allow running fan with engine off: 0 = Only run fan when engine is running, 1 = Allow even with engine off
byte fanWhenCranking : 1; ///< Set whether the fan output will stay on when the engine is cranking (0=force off, 1=allow on)
byte useDwellMap : 1; ///< Setting to change between fixed dwell value and dwell map (0=Fixed value from @ref configPage4.dwellRun, 1=Use @ref dwellTable)
byte fanEnable : 2; ///< Fan mode. 0=Off, 1=On/Off, 2=PWM
byte rtc_mode : 2; // Unused ?
byte incorporateAFR : 1; ///< Enable AFR target (stoich/afrtgt) compensation in PW calculation
byte asePct[4]; ///< Afterstart enrichment values (%)
byte aseCount[4]; ///< Afterstart enrichment cycles. This is the number of ignition cycles that the afterstart enrichment % lasts for
byte aseBins[4]; ///< Afterstart enrichment temperatures (x-axis) for (target) enrichment values
byte primePulse[4];//Priming pulsewidth values (mS, copied to @ref PrimingPulseTable)
byte primeBins[4]; //Priming temperatures (source,x-axis)
byte CTPSPin : 6;
byte CTPSPolarity : 1;
byte CTPSEnabled : 1;
byte idleAdvEnabled : 2;
byte idleAdvAlgorithm : 1;
byte idleAdvDelay : 5;
byte idleAdvRPM;
byte idleAdvTPS;
byte injAngRPM[4];
byte idleTaperTime;
byte dfcoDelay;
byte dfcoMinCLT;
//VSS Stuff
byte vssMode : 2; ///< VSS (Vehicle speed sensor) mode (0=none, 1=CANbus, 2,3=Interrupt driven)
byte vssPin : 6; ///< VSS (Vehicle speed sensor) pin number
uint16_t vssPulsesPerKm; ///< VSS (Vehicle speed sensor) pulses per Km
byte vssSmoothing;
uint16_t vssRatio1;
uint16_t vssRatio2;
uint16_t vssRatio3;
uint16_t vssRatio4;
uint16_t vssRatio5;
uint16_t vssRatio6;
byte idleUpOutputEnabled : 1;
byte idleUpOutputInv : 1;
byte idleUpOutputPin : 6;
byte tachoSweepMaxRPM;
byte primingDelay;
byte iacTPSlimit;
byte iacRPMlimitHysteresis;
int8_t rtc_trim;
byte idleAdvVss;
byte mapSwitchPoint;
byte canBMWCluster : 1;
byte canVAGCluster : 1;
byte enableCluster1 : 1;
byte enableCluster2 : 1;
byte unusedClusterBits : 4;
byte unused2_95;
#if defined(CORE_AVR)
};
#else
} __attribute__((__packed__)); //The 32 bit systems require all structs to be fully packed
#endif
/** Page 4 of the config - variables required for ignition and rpm/crank phase /cam phase decoding.
* See the ini file for further reference.
*/
struct config4 {
int16_t triggerAngle; ///< Angle (ATDC) when tooth No:1 on the primary wheel sends signal (-360 to +360 deg.)
int8_t FixAng; ///< Fixed Ignition angle value (enabled by @ref configPage2.fixAngEnable, copied to ignFixValue, Negative values allowed, See corrections.ino)
int8_t CrankAng; ///< Fixed start-up/cranking ignition angle (See: corrections.ino)
byte TrigAngMul; ///< Multiplier for non evenly divisible tooth counts.
byte TrigEdge : 1; ///< Primary (RPM1) Trigger Edge - 0 - RISING, 1 = FALLING (Copied from this config to primaryTriggerEdge)
byte TrigSpeed : 1; ///< Primary (RPM1) Trigger speed - 0 = crank speed (CRANK_SPEED), 1 = cam speed (CAM_SPEED), See decoders.ino
byte IgInv : 1; ///< Ignition signal invert (?) (GOING_LOW=0 (default by init.ino) / GOING_HIGH=1 )
byte TrigPattern : 5; ///< Decoder configured (DECODER_MISSING_TOOTH, DECODER_BASIC_DISTRIBUTOR, DECODER_GM7X, ... See init.ino)
byte TrigEdgeSec : 1; ///< Secondary (RPM2) Trigger Edge (See RPM1)
byte fuelPumpPin : 6; ///< Fuel pump pin (copied as override to pinFuelPump, defaults to board default, See: init.ino)
byte useResync : 1;
byte sparkDur; ///< Spark duration in ms * 10
byte trigPatternSec : 7; ///< Mode for Missing tooth secondary trigger - 0=single tooth cam wheel (SEC_TRIGGER_SINGLE), 1=4-1 (SEC_TRIGGER_4_1) or 2=poll level mode (SEC_TRIGGER_POLL)
byte PollLevelPolarity : 1; //for poll level cam trigger. Sets if the cam trigger is supposed to be high or low for revolution one.
uint8_t bootloaderCaps; //Capabilities of the bootloader over stock. e.g., 0=Stock, 1=Reset protection, etc.
byte resetControlConfig : 2; /** Which method of reset control to use - 0=Disabled (RESET_CONTROL_DISABLED), 1=Prevent When Running (RESET_CONTROL_PREVENT_WHEN_RUNNING),
2=Prevent Always (RESET_CONTROL_PREVENT_ALWAYS), 3=Serial Command (RESET_CONTROL_SERIAL_COMMAND) - Copied to resetControl (See init.ino, utilities.ino) */
byte resetControlPin : 6;
byte StgCycles; //The number of initial cycles before the ignition should fire when first cranking
byte boostType : 1; ///< Boost Control type: 0=Open loop (OPEN_LOOP_BOOST), 1=closed loop (CLOSED_LOOP_BOOST)
byte useDwellLim : 1; //Whether the dwell limiter is off or on
byte sparkMode : 3; /** Ignition/Spark output mode - 0=Wasted spark (IGN_MODE_WASTED), 1=single channel (IGN_MODE_SINGLE),
2=Wasted COP (IGN_MODE_WASTEDCOP), 3=Sequential (IGN_MODE_SEQUENTIAL), 4=Rotary (IGN_MODE_ROTARY) */
byte triggerFilter : 2; //The mode of trigger filter being used (0=Off, 1=Light (Not currently used), 2=Normal, 3=Aggressive)
byte ignCranklock : 1; //Whether or not the ignition timing during cranking is locked to a CAS (crank) pulse. Only currently valid for Basic distributor and 4G63.
byte dwellCrank; ///< Dwell time whilst cranking
byte dwellRun; ///< Dwell time whilst running
byte triggerTeeth; ///< The full count of teeth on the trigger wheel if there were no gaps
byte triggerMissingTeeth; ///< The size of the tooth gap (ie number of missing teeth)
byte crankRPM; ///< RPM below which the engine is considered to be cranking
byte floodClear; ///< TPS (raw adc count? % ?) value that triggers flood clear mode (No fuel whilst cranking, See @ref correctionFloodClear())
byte SoftRevLim; ///< Soft rev limit (RPM/100)
byte SoftLimRetard; ///< Amount soft limit (ignition) retard (degrees)
byte SoftLimMax; ///< Time the soft limit can run (units 0.1S)
byte HardRevLim; ///< Hard rev limit (RPM/100)
byte taeBins[4]; ///< TPS based acceleration enrichment bins (Unit: %/s)
byte taeValues[4]; ///< TPS based acceleration enrichment rates (Unit: % to add), values matched to thresholds of taeBins
byte wueBins[10]; ///< Warmup Enrichment bins (Values are in @ref configPage2.wueValues OLD:configTable1)
byte dwellLimit;
byte dwellCorrectionValues[6]; ///< Correction table for dwell vs battery voltage
byte iatRetBins[6]; ///< Inlet Air Temp timing retard curve bins (Unit: ...)
byte iatRetValues[6]; ///< Inlet Air Temp timing retard curve values (Unit: ...)
byte dfcoRPM; ///< RPM at which DFCO turns off/on at
byte dfcoHyster; //Hysteris RPM for DFCO
byte dfcoTPSThresh; //TPS must be below this figure for DFCO to engage (Unit: ...)
byte ignBypassEnabled : 1; //Whether or not the ignition bypass is enabled
byte ignBypassPin : 6; //Pin the ignition bypass is activated on
byte ignBypassHiLo : 1; //Whether this should be active high or low.
byte ADCFILTER_TPS;
byte ADCFILTER_CLT;
byte ADCFILTER_IAT;
byte ADCFILTER_O2;