add dvjcodec rev a and b teensy board entry

reactivate second o2 input
This commit is contained in:
darren siepka 2018-04-10 23:17:38 +01:00
parent 2498f53730
commit aa3904b448
5 changed files with 152 additions and 92 deletions

View File

@ -203,6 +203,7 @@ void initialiseIdle()
void idleControl()
{
if(idleInitComplete != configPage6.iacAlgorithm) { initialiseIdle(); }
if(currentStatus.RPM > 0) { enableIdle(); }
switch(configPage6.iacAlgorithm)
{
@ -224,6 +225,7 @@ void idleControl()
{
//Currently cranking. Use the cranking table
currentStatus.idleDuty = table2D_getValue(&iacCrankDutyTable, currentStatus.coolant + CALIBRATION_TEMPERATURE_OFFSET); //All temps are offset by 40 degrees
if( currentStatus.idleDuty == 0 ) { disableIdle(); break; }
idle_pwm_target_value = percentage(currentStatus.idleDuty, idle_pwm_max_count);
idleOn = true;
}
@ -232,7 +234,6 @@ void idleControl()
//Standard running
currentStatus.idleDuty = table2D_getValue(&iacPWMTable, currentStatus.coolant + CALIBRATION_TEMPERATURE_OFFSET); //All temps are offset by 40 degrees
if( currentStatus.idleDuty == 0 ) { disableIdle(); break; }
enableIdle();
idle_pwm_target_value = percentage(currentStatus.idleDuty, idle_pwm_max_count);
currentStatus.idleLoad = currentStatus.idleDuty >> 1;
idleOn = true;
@ -247,7 +248,6 @@ void idleControl()
idlePID.Compute();
idle_pwm_target_value = idle_pid_target_value;
if( idle_pwm_target_value == 0 ) { disableIdle(); }
else{ enableIdle(); } //Turn on the C compare unit (ie turn on the interrupt)
currentStatus.idleLoad = ((unsigned long)(idle_pwm_target_value * 100UL) / idle_pwm_max_count) >> 1;
//idle_pwm_target_value = 104;
@ -459,6 +459,4 @@ static inline void idleInterrupt() //Most ARM chips can simply call a function
idle_pwm_cur_value = idle_pwm_target_value;
idle_pwm_state = true;
}
}

View File

@ -40,8 +40,9 @@ uint16_t MAPcurRev; //Tracks which revolution we're sampling on
static inline void instanteneousMAPReading() __attribute__((always_inline));
static inline void readMAP() __attribute__((always_inline));
void readTPS();
void flexPulse();
void readO2_2();
void flexPulse();
#if defined(ANALOG_ISR)
//Analog ISR interrupt routine

View File

@ -42,6 +42,8 @@ void initialiseADC()
BIT_CLEAR(ADCSRA,ADPS1);
BIT_CLEAR(ADCSRA,ADPS0);
#endif
#elif defined(ARDUINO_ARCH_STM32) //STM32GENERIC lib
analogReadResolution(10); //use 10bits for analog
#endif
MAPcurRev = 0;
MAPcount = 0;
@ -119,7 +121,6 @@ static inline void readMAP()
if(currentStatus.MAP < 0) { currentStatus.MAP = 0; } //Sanity check
}
else { instanteneousMAPReading(); }
MAPcurRev = currentStatus.startRevolutions; //Reset the current rev count
MAPrunningValue = 0;
MAPcount = 0;

View File

@ -133,6 +133,12 @@ void (*ign4StartFunction)();
void (*ign4EndFunction)();
void (*ign5StartFunction)();
void (*ign5EndFunction)();
void (*ign6StartFunction)();
void (*ign6EndFunction)();
void (*ign7StartFunction)();
void (*ign7EndFunction)();
void (*ign8StartFunction)();
void (*ign8EndFunction)();
volatile int timePerDegree;
byte degreesPerLoop; //The number of crank degrees that pass for each mainloop of the program
@ -141,9 +147,11 @@ bool initialisationComplete = false; //Tracks whether the setup() functino has r
void setup()
{
initialiseTimers();
pinMode(LED_BUILTIN, OUTPUT);
digitalWrite(LED_BUILTIN, LOW);
//Setup the dummy fuel and ignition tables
//dummyFuelTable(&fuelTable);
//dummyIgnitionTable(&ignitionTable);
table3D_setSize(&fuelTable, 16);
table3D_setSize(&ignitionTable, 16);
table3D_setSize(&afrTable, 16);
@ -154,10 +162,8 @@ void setup()
table3D_setSize(&trim2Table, 6);
table3D_setSize(&trim3Table, 6);
table3D_setSize(&trim4Table, 6);
initialiseTimers();
#if defined(CORE_STM32)
EEPROM.init();
#endif
loadConfig();
doUpdates(); //Check if any data items need updating (Occurs ith firmware updates)
@ -166,16 +172,9 @@ void setup()
configPage4.bootloaderCaps = 0;
Serial.begin(115200);
#if defined(__AVR_ATmega1280__) || defined(__AVR_ATmega2560__) //ATmega2561 does not have Serial3
if (configPage9.enable_canbus == 1) { CANSerial.begin(115200); }
#elif defined(CORE_STM32)
if (configPage9.enable_canbus == 1) { CANSerial.begin(115200); }
else if (configPage9.enable_canbus == 2)
{
//enable local can interface
}
#elif defined(CORE_TEENSY)
if (configPage9.enable_canbus == 1) { CANSerial.begin(115200); }
#if defined(CORE_STM32) || defined(CORE_TEENSY)
else if (configPage9.enable_canbus == 2)
{
//Teensy onboard CAN not used currently
@ -185,7 +184,8 @@ void setup()
//static CAN_message_t txmsg,rxmsg;
//CANbus0.begin();
}
#endif
#endif
//Repoint the 2D table structs to the config pages that were just loaded
taeTable.valueSize = SIZE_BYTE; //Set this table to use byte values
@ -665,6 +665,12 @@ void setup()
ign4EndFunction = endCoil4Charge;
ign5StartFunction = beginCoil5Charge;
ign5EndFunction = endCoil5Charge;
ign6StartFunction = beginCoil6Charge;
ign6EndFunction = endCoil6Charge;
ign7StartFunction = beginCoil7Charge;
ign7EndFunction = endCoil7Charge;
ign8StartFunction = beginCoil8Charge;
ign8EndFunction = endCoil8Charge;
break;
case IGN_MODE_ROTARY:
@ -721,48 +727,34 @@ void loop()
// 1) Every 64 loops (64 Is more than fast enough for TunerStudio). This function is equivalent to ((loopCount % 64) == 1) but is considerably faster due to not using the mod or division operations
// 2) If the amount of data in the serial buffer is greater than a set threhold (See globals.h). This is to avoid serial buffer overflow when large amounts of data is being sent
//if ( (BIT_CHECK(TIMER_mask, BIT_TIMER_15HZ)) || (Serial.available() > SERIAL_BUFFER_THRESHOLD) )
//if ( (timer15Hz == true) )
if ( ((mainLoopCount & 31) == 1) or (Serial.available() > SERIAL_BUFFER_THRESHOLD) )
{
if (Serial.available() > 0) { command(); }
}
#if defined(__AVR_ATmega1280__) || defined(__AVR_ATmega2560__) //ATmega2561 does not have Serial3
//if serial3 interface is enabled then check for serial3 requests.
if (configPage9.enable_canbus == 1)
{
if ( (BIT_CHECK(LOOP_TIMER, BIT_TIMER_15HZ)) || (CANSerial.available() > SERIAL_BUFFER_THRESHOLD) )
{
if (CANSerial.available() > 0) { canCommand(); }
}
}
#elif defined(CORE_TEENSY) || defined(CORE_STM32)
//if can or secondary serial interface is enabled then check for requests.
if (configPage9.enable_canbus == 1) //secondary serial interface enabled
{
if ( (BIT_CHECK(LOOP_TIMER, BIT_TIMER_15HZ)) || (CANSerial.available() > SERIAL_BUFFER_THRESHOLD) )
{
if (CANSerial.available() > 0) { canCommand(); }
}
}
else if (configPage9.enable_canbus == 2) // can module enabled
{
if ( ((mainLoopCount & 31) == 1) or (CANSerial.available() > SERIAL_BUFFER_THRESHOLD) )
{
if (CANSerial.available() > 0) { canCommand(); }
}
}
#if defined(CORE_TEENSY) || defined(CORE_STM32)
else if (configPage9.enable_canbus == 2) // can module enabled
{
//check local can module
// if ( (BIT_CHECK(LOOP_TIMER, BIT_TIMER_15HZ)) or (CANbus0.available())
// if ( BIT_CHECK(LOOP_TIMER, BIT_TIMER_15HZ) or (CANbus0.available())
// {
// CANbus0.read(rx_msg);
// }
}
#endif
#endif
//Displays currently disabled
// if (configPage2.displayType && (mainLoopCount & 255) == 1) { updateDisplay();}
previousLoopTime = currentLoopTime;
currentLoopTime = micros();
currentLoopTime = micros_safe();
unsigned long timeToLastTooth = (currentLoopTime - toothLastToothTime);
if ( (timeToLastTooth < MAX_STALL_TIME) || (toothLastToothTime > currentLoopTime) ) //Check how long ago the last tooth was seen compared to now. If it was more than half a second ago then the engine is probably stopped. toothLastToothTime can be greater than currentLoopTime if a pulse occurs between getting the lastest time and doing the comparison
{
@ -929,12 +921,12 @@ void loop()
#endif
vvtControl();
idleControl(); //Perform any idle related actions. Even at higher frequencies, running 4x per second is sufficient.
}
} //4Hz timer
if (BIT_CHECK(LOOP_TIMER, BIT_TIMER_1HZ)) //Once per second)
{
BIT_CLEAR(TIMER_mask, BIT_TIMER_1HZ);
readBaro(); //Infrequent baro readings are not an issue.
}
} //1Hz timer
if(configPage6.iacAlgorithm == IAC_ALGORITHM_STEP_OL || configPage6.iacAlgorithm == IAC_ALGORITHM_STEP_CL) { idleControl(); } //Run idlecontrol every loop for stepper idle.
@ -1070,7 +1062,8 @@ void loop()
}
else
{
long rpm_adjust = ((long)(micros() - toothOneTime) * (long)currentStatus.rpmDOT) / 1000000; //Take into account any likely accleration that has occurred since the last full revolution completed
interruptSafe(long elapsedTime = (micros() - toothOneTime);) //micros() is no longer interrupt safe
long rpm_adjust = (elapsedTime * (long)currentStatus.rpmDOT) / 1000000; //Take into account any likely accleration that has occurred since the last full revolution completed
timePerDegree = ldiv( 166666L, currentStatus.RPM + rpm_adjust).quot; //There is a small amount of rounding in this calculation, however it is less than 0.001 of a uS (Faster as ldiv than / )
}
@ -1083,7 +1076,8 @@ void loop()
if( (!BIT_CHECK(currentStatus.engine, BIT_ENGINE_CRANK)) && configPage10.stagingEnabled == false) { if (currentStatus.PW1 > pwLimit) { currentStatus.PW1 = pwLimit; } }
//Calculate staging pulsewidths if used
if(configPage10.stagingEnabled == true)
//To run staged injection, the number of cylinders must be less than or equal to the injector channels (ie Assuming you're running paired injection, you need at least as many injector channels as you have cylinders, half for the primaries and half for the secondaries)
if( (configPage10.stagingEnabled == true) && (configPage2.nCylinders <= INJ_CHANNELS) )
{
//Scale the 'full' pulsewidth by each of the injector capacities
uint32_t tempPW1 = ((unsigned long)currentStatus.PW1 * staged_req_fuel_mult_pri) / 100;
@ -1549,7 +1543,18 @@ void loop()
//Likewise for the ignition
//fixedCrankingOverride is used to extend the dwell during cranking so that the decoder can trigger the spark upon seeing a certain tooth. Currently only available on the basic distributor and 4g63 decoders.
if ( configPage4.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;
//This is a safety step to prevent the ignition start time occuring AFTER the target tooth pulse has already occcured. It simply moves the start time forward a little, which is compensated for by the increase in the dwell time
if(currentStatus.RPM < 250)
{
ignition1StartAngle -= 5;
ignition2StartAngle -= 5;
ignition3StartAngle -= 5;
ignition4StartAngle -= 5;
}
}
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:
@ -1569,6 +1574,7 @@ void loop()
crankAngle = getCrankAngle(timePerDegree); //Refresh with the latest crank angle
if (crankAngle > CRANK_ANGLE_MAX_IGN ) { crankAngle -= 360; }
#if IGN_CHANNELS >= 1
if ( (ignition1StartAngle > crankAngle) && (curRollingCut != 1) )
{
/*
@ -1588,6 +1594,7 @@ void loop()
);
}
}
#endif
/*
if( (ignitionSchedule1.Status == RUNNING) && (ignition1EndAngle > crankAngle) && configPage4.StgCycles == 0)
{
@ -1606,7 +1613,7 @@ void loop()
*/
#if IGN_CHANNELS >= 2
tempCrankAngle = crankAngle - channel2IgnDegrees;
if( tempCrankAngle < 0) { tempCrankAngle += CRANK_ANGLE_MAX_IGN; }
tempStartAngle = ignition2StartAngle - channel2IgnDegrees;
@ -1626,7 +1633,9 @@ void loop()
);
}
}
#endif
#if IGN_CHANNELS >= 3
tempCrankAngle = crankAngle - channel3IgnDegrees;
if( tempCrankAngle < 0) { tempCrankAngle += CRANK_ANGLE_MAX_IGN; }
tempStartAngle = ignition3StartAngle - channel3IgnDegrees;
@ -1647,7 +1656,9 @@ void loop()
);
}
}
#endif
#if IGN_CHANNELS >= 4
tempCrankAngle = crankAngle - channel4IgnDegrees;
if( tempCrankAngle < 0) { tempCrankAngle += CRANK_ANGLE_MAX_IGN; }
tempStartAngle = ignition4StartAngle - channel4IgnDegrees;
@ -1669,7 +1680,9 @@ void loop()
);
}
}
#endif
#if IGN_CHANNELS >= 5
tempCrankAngle = crankAngle - channel5IgnDegrees;
if( tempCrankAngle < 0) { tempCrankAngle += CRANK_ANGLE_MAX_IGN; }
tempStartAngle = ignition5StartAngle - channel5IgnDegrees;
@ -1690,6 +1703,29 @@ void loop()
);
}
}
#endif
#if IGN_CHANNELS >= 6
tempCrankAngle = crankAngle - channel6IgnDegrees;
if( tempCrankAngle < 0) { tempCrankAngle += CRANK_ANGLE_MAX_IGN; }
tempStartAngle = ignition6StartAngle - channel6IgnDegrees;
if ( tempStartAngle < 0) { tempStartAngle += CRANK_ANGLE_MAX_IGN; }
{
unsigned long ignition6StartTime = 0;
if(tempStartAngle > tempCrankAngle) { ignition6StartTime = degreesToUS((tempStartAngle - tempCrankAngle)); }
else { ignition6StartTime = 0; }
if( (ignition6StartTime > 0) && (curRollingCut != 2) )
{
setIgnitionSchedule6(ign6StartFunction,
ignition6StartTime,
currentStatus.dwell + fixedCrankingOverride,
ign6EndFunction
);
}
}
#endif
} //Ignition schedules on
if (!BIT_CHECK(currentStatus.status3, BIT_STATUS3_RESET_PREVENT) && resetControl == RESET_CONTROL_PREVENT_WHEN_RUNNING) {

View File

@ -239,23 +239,32 @@ void setPinMapping(byte boardID)
pinCoil3 = 30;
pinO2 = A22;
#elif defined(STM32F4)
//Black F407VE http://wiki.stm32duino.com/index.php?title=STM32F407
//PC8~PC12 SDio
//PA13~PA15 & PB4 SWD(debug) pins
//PB0 EEPROM CS pin
//PD5 & PD6 Serial2
pinInjector1 = PE7; //Output pin injector 1 is on
pinInjector2 = PE8; //Output pin injector 2 is on
pinInjector3 = PE9; //Output pin injector 3 is on
pinInjector4 = PE10; //Output pin injector 4 is on
pinInjector5 = PE11; //Output pin injector 5 is on
pinCoil1 = PB10; //Pin for coil 1
pinCoil2 = PB11; //Pin for coil 2
pinCoil3 = PB12; //Pin for coil 3
pinCoil4 = PB13; //Pin for coil 4
pinCoil5 = PB14; //Pin for coil 5
pinCoil1 = PB5; //Pin for coil 1
pinCoil2 = PB6; //Pin for coil 2
pinCoil3 = PB7; //Pin for coil 3
pinCoil4 = PB8; //Pin for coil 4
pinCoil5 = PB9; //Pin for coil 5
pinTPS = A0; //TPS input pin
pinMAP = A1; //MAP sensor pin
pinIAT = A2; //IAT sensor pin
pinCLT = A3; //CLS sensor pin
pinCLT = A3; //CLT sensor pin
pinO2 = A4; //O2 Sensor pin
pinBat = A5; //Battery reference voltage pin
pinBaro = A6;
pinBaro = A10;
pinIdle1 = PB8; //Single wire idle control
pinIdle2 = PB9; //2 wire idle control
pinBoost = PE0; //Boost control
pinVVT_1 = PE1; //Default VVT output
pinStepperDir = PD8; //Direction pin for DRV8825 driver
pinStepperStep = PB15; //Step pin for DRV8825 driver
pinStepperEnable = PD9; //Enable pin for DRV8825
@ -264,43 +273,45 @@ void setPinMapping(byte boardID)
pinFuelPump = PA6; //Fuel pump output
pinTachOut = PA7; //Tacho output pin
//external interrupt enabled pins
pinFlex = PC4; // Flex sensor (Must be external interrupt enabled)
pinTrigger = PC5; //The CAS pin
pinTrigger2 = PC6; //The Cam Sensor pin
pinBoost = PE0; //Boost control
pinVVT_1 = PE1; //Default VVT output
//external interrupts could be enalbed in any pin, except same port numbers (PA4,PE4)
pinFlex = PE2; // Flex sensor (Must be external interrupt enabled)
pinTrigger = PE3; //The CAS pin
pinTrigger2 = PE4; //The Cam Sensor pin
#elif defined(CORE_STM32)
//http://docs.leaflabs.com/static.leaflabs.com/pub/leaflabs/maple-docs/0.0.12/hardware/maple-mini.html#master-pin-map
//pins 23, 24 and 33 couldn't be used
pinInjector1 = 15; //Output pin injector 1 is on
pinInjector2 = 16; //Output pin injector 2 is on
pinInjector3 = 17; //Output pin injector 3 is on
pinInjector4 = 18; //Output pin injector 4 is on
pinCoil1 = 19; //Pin for coil 1
pinCoil2 = 20; //Pin for coil 2
pinCoil3 = 21; //Pin for coil 3
pinCoil4 = 26; //Pin for coil 4
pinCoil5 = 27; //Pin for coil 5
//blue pill http://wiki.stm32duino.com/index.php?title=Blue_Pill
//Maple mini http://wiki.stm32duino.com/index.php?title=Maple_Mini
//pins PA12, PA11 are used for USB or CAN couldn't be used for GPIO
pinInjector1 = PB7; //Output pin injector 1 is on
pinInjector2 = PB6; //Output pin injector 2 is on
pinInjector3 = PB5; //Output pin injector 3 is on
pinInjector4 = PB4; //Output pin injector 4 is on
pinCoil1 = PB3; //Pin for coil 1
pinCoil2 = PA15; //Pin for coil 2
pinCoil3 = PA14; //Pin for coil 3
pinCoil4 = PA9; //Pin for coil 4
pinCoil5 = PA8; //Pin for coil 5
pinTPS = A0; //TPS input pin
pinMAP = A1; //MAP sensor pin
pinIAT = A2; //IAT sensor pin
pinCLT = A3; //CLS sensor pin
pinO2 = A4; //O2 Sensor pin
pinBat = A5; //Battery reference voltage pin
pinStepperDir = 12; //Direction pin for DRV8825 driver
pinStepperStep = 13; //Step pin for DRV8825 driver
pinStepperEnable = 14; //Enable pin for DRV8825
pinDisplayReset = 2; // OLED reset pin
pinFan = 1; //Pin for the fan output
pinFuelPump = 0; //Fuel pump output
pinTachOut = 31; //Tacho output pin
//external interrupt enabled pins
pinFlex = 32; // Flex sensor (Must be external interrupt enabled)
pinTrigger = 25; //The CAS pin
pinTrigger2 = 22; //The Cam Sensor pin
pinBaro = pinMAP;
pinBoost = 1; //Boost control
pinVVT_1 = 0; //Default VVT output
pinIdle1 = PB2; //Single wire idle control
pinIdle2 = PA2; //2 wire idle control
pinBoost = PA1; //Boost control
pinVVT_1 = PA0; //Default VVT output
pinStepperDir = PC15; //Direction pin for DRV8825 driver
pinStepperStep = PC14; //Step pin for DRV8825 driver
pinStepperEnable = PC13; //Enable pin for DRV8825
pinDisplayReset = PB2; // OLED reset pin
pinFan = PB1; //Pin for the fan output
pinFuelPump = PB11; //Fuel pump output
pinTachOut = PB10; //Tacho output pin
//external interrupt enabled pins
pinFlex = PB8; // Flex sensor (Must be external interrupt enabled)
pinTrigger = PA10; //The CAS pin
pinTrigger2 = PA13; //The Cam Sensor pin
#endif
break;
@ -507,7 +518,8 @@ void setPinMapping(byte boardID)
pinSpareLOut3 = 36; //low current output spare3 - ONLY WITH DB
pinResetControl = 26; //Reset control output
break;
#if defined(CORE_TEENSY)
#if defined(CORE_TEENSY)
case 50:
//Pin mappings as per the teensy rev A shield
pinInjector1 = 2; //Output pin injector 1 is on
@ -555,7 +567,7 @@ void setPinMapping(byte boardID)
case 51:
//Pin mappings as per the teensy revB board shield
pinInjector1 = 2; //Output pin injector 1 is on
pinInjector1 = 2; //Output pin injector 1 is on
pinInjector2 = 10; //Output pin injector 2 is on
pinInjector3 = 6; //Output pin injector 3 is on - NOT USED
pinInjector4 = 9; //Output pin injector 4 is on - NOT USED
@ -597,7 +609,8 @@ void setPinMapping(byte boardID)
pinSpareHOut2 = 7; // high current output spare2
pinSpareLOut1 = 21; //low current output spare1
break;
#endif
#endif
default:
#ifndef SMALL_FLASH_MODE //No support for bluepill here anyway
//Pin mappings as per the v0.2 shield
@ -688,6 +701,12 @@ void setPinMapping(byte boardID)
inj4_pin_mask = digitalPinToBitMask(pinInjector4);
inj5_pin_port = portOutputRegister(digitalPinToPort(pinInjector5));
inj5_pin_mask = digitalPinToBitMask(pinInjector5);
inj6_pin_port = portOutputRegister(digitalPinToPort(pinInjector6));
inj6_pin_mask = digitalPinToBitMask(pinInjector6);
inj7_pin_port = portOutputRegister(digitalPinToPort(pinInjector7));
inj7_pin_mask = digitalPinToBitMask(pinInjector7);
inj8_pin_port = portOutputRegister(digitalPinToPort(pinInjector8));
inj8_pin_mask = digitalPinToBitMask(pinInjector8);
ign1_pin_port = portOutputRegister(digitalPinToPort(pinCoil1));
ign1_pin_mask = digitalPinToBitMask(pinCoil1);
@ -699,13 +718,18 @@ void setPinMapping(byte boardID)
ign4_pin_mask = digitalPinToBitMask(pinCoil4);
ign5_pin_port = portOutputRegister(digitalPinToPort(pinCoil5));
ign5_pin_mask = digitalPinToBitMask(pinCoil5);
ign6_pin_port = portOutputRegister(digitalPinToPort(pinCoil6));
ign6_pin_mask = digitalPinToBitMask(pinCoil6);
ign7_pin_port = portOutputRegister(digitalPinToPort(pinCoil7));
ign7_pin_mask = digitalPinToBitMask(pinCoil7);
ign8_pin_port = portOutputRegister(digitalPinToPort(pinCoil8));
ign8_pin_mask = digitalPinToBitMask(pinCoil8);
tach_pin_port = portOutputRegister(digitalPinToPort(pinTachOut));
tach_pin_mask = digitalPinToBitMask(pinTachOut);
pump_pin_port = portOutputRegister(digitalPinToPort(pinFuelPump));
pump_pin_mask = digitalPinToBitMask(pinFuelPump);
//And for inputs
//And for inputs
#if defined(CORE_STM32)
#ifndef ARDUINO_ARCH_STM32 //libmaple core aka STM32DUINO