Ensure that output port manipulations are done atomically. Fixes #972

This commit is contained in:
Josh Stewart 2023-04-24 10:30:51 +10:00
parent 90530f65a3
commit d0286fe02d
4 changed files with 43 additions and 31 deletions

View File

@ -3,6 +3,10 @@
#include BOARD_H //Note that this is not a real file, it is defined in globals.h.
#if defined(CORE_AVR)
#include <util/atomic.h>
#endif
void initialiseAuxPWM(void);
void boostControl(void);
void boostDisable(void);
@ -24,7 +28,7 @@ static inline void checkAirConRPMLockout(void);
#define SIMPLE_BOOST_I 1
#define SIMPLE_BOOST_D 1
#if(defined(CORE_TEENSY))
#if(defined(CORE_TEENSY) || defined(CORE_STM32))
#define BOOST_PIN_LOW() (digitalWrite(pinBoost, LOW))
#define BOOST_PIN_HIGH() (digitalWrite(pinBoost, HIGH))
#define VVT1_PIN_LOW() (digitalWrite(pinVVT_1, LOW))
@ -41,32 +45,49 @@ static inline void checkAirConRPMLockout(void);
#define AIRCON_PIN_HIGH() (digitalWrite(pinAirConComp, HIGH))
#define AIRCON_FAN_PIN_LOW() (digitalWrite(pinAirConFan, LOW))
#define AIRCON_FAN_PIN_HIGH() (digitalWrite(pinAirConFan, HIGH))
#define FUEL_PUMP_ON() (digitalWrite(pinFuelPump, HIGH))
#define FUEL_PUMP_OFF() (digitalWrite(pinFuelPump, LOW))
#define AIRCON_ON() { ((((configPage15.airConCompPol&1)==1)) ? AIRCON_PIN_LOW() : AIRCON_PIN_HIGH()); BIT_SET(currentStatus.airConStatus, BIT_AIRCON_COMPRESSOR); }
#define AIRCON_OFF() { ((((configPage15.airConCompPol&1)==1)) ? AIRCON_PIN_HIGH() : AIRCON_PIN_LOW()); BIT_CLEAR(currentStatus.airConStatus, BIT_AIRCON_COMPRESSOR); }
#define AIRCON_FAN_ON() { ((((configPage15.airConFanPol&1)==1)) ? AIRCON_FAN_PIN_LOW() : AIRCON_FAN_PIN_HIGH()); BIT_SET(currentStatus.airConStatus, BIT_AIRCON_FAN); }
#define AIRCON_FAN_OFF() { ((((configPage15.airConFanPol&1)==1)) ? AIRCON_FAN_PIN_HIGH() : AIRCON_FAN_PIN_LOW()); BIT_CLEAR(currentStatus.airConStatus, BIT_AIRCON_FAN); }
#define FAN_ON() { ((configPage6.fanInv) ? FAN_PIN_LOW() : FAN_PIN_HIGH()); }
#define FAN_OFF() { ((configPage6.fanInv) ? FAN_PIN_HIGH() : FAN_PIN_LOW()); }
#else
#define BOOST_PIN_LOW() *boost_pin_port &= ~(boost_pin_mask)
#define BOOST_PIN_HIGH() *boost_pin_port |= (boost_pin_mask)
#define VVT1_PIN_LOW() *vvt1_pin_port &= ~(vvt1_pin_mask)
#define VVT1_PIN_HIGH() *vvt1_pin_port |= (vvt1_pin_mask)
#define VVT2_PIN_LOW() *vvt2_pin_port &= ~(vvt2_pin_mask)
#define VVT2_PIN_HIGH() *vvt2_pin_port |= (vvt2_pin_mask)
#define FAN_PIN_LOW() *fan_pin_port &= ~(fan_pin_mask)
#define FAN_PIN_HIGH() *fan_pin_port |= (fan_pin_mask)
#define N2O_STAGE1_PIN_LOW() *n2o_stage1_pin_port &= ~(n2o_stage1_pin_mask)
#define N2O_STAGE1_PIN_HIGH() *n2o_stage1_pin_port |= (n2o_stage1_pin_mask)
#define N2O_STAGE2_PIN_LOW() *n2o_stage2_pin_port &= ~(n2o_stage2_pin_mask)
#define N2O_STAGE2_PIN_HIGH() *n2o_stage2_pin_port |= (n2o_stage2_pin_mask)
#define AIRCON_PIN_LOW() *aircon_comp_pin_port &= ~(aircon_comp_pin_mask)
#define AIRCON_PIN_HIGH() *aircon_comp_pin_port |= (aircon_comp_pin_mask)
#define BOOST_PIN_LOW() ATOMIC_BLOCK(ATOMIC_RESTORESTATE) { *boost_pin_port &= ~(boost_pin_mask); }
#define BOOST_PIN_HIGH() ATOMIC_BLOCK(ATOMIC_RESTORESTATE) { *boost_pin_port |= (boost_pin_mask); }
#define VVT1_PIN_LOW() ATOMIC_BLOCK(ATOMIC_RESTORESTATE) { *vvt1_pin_port &= ~(vvt1_pin_mask); }
#define VVT1_PIN_HIGH() ATOMIC_BLOCK(ATOMIC_RESTORESTATE) { *vvt1_pin_port |= (vvt1_pin_mask); }
#define VVT2_PIN_LOW() ATOMIC_BLOCK(ATOMIC_RESTORESTATE) { *vvt2_pin_port &= ~(vvt2_pin_mask); }
#define VVT2_PIN_HIGH() ATOMIC_BLOCK(ATOMIC_RESTORESTATE) { *vvt2_pin_port |= (vvt2_pin_mask); }
#define N2O_STAGE1_PIN_LOW() ATOMIC_BLOCK(ATOMIC_RESTORESTATE) { *n2o_stage1_pin_port &= ~(n2o_stage1_pin_mask); }
#define N2O_STAGE1_PIN_HIGH() ATOMIC_BLOCK(ATOMIC_RESTORESTATE) { *n2o_stage1_pin_port |= (n2o_stage1_pin_mask); }
#define N2O_STAGE2_PIN_LOW() ATOMIC_BLOCK(ATOMIC_RESTORESTATE) { *n2o_stage2_pin_port &= ~(n2o_stage2_pin_mask); }
#define N2O_STAGE2_PIN_HIGH() ATOMIC_BLOCK(ATOMIC_RESTORESTATE) { *n2o_stage2_pin_port |= (n2o_stage2_pin_mask); }
#define FUEL_PUMP_ON() ATOMIC_BLOCK(ATOMIC_RESTORESTATE) { *pump_pin_port |= (pump_pin_mask); }
#define FUEL_PUMP_OFF() ATOMIC_BLOCK(ATOMIC_RESTORESTATE) { *pump_pin_port &= ~(pump_pin_mask); }
//Note the below macros cannot use ATOMIC_BLOCK(ATOMIC_RESTORESTATE) as they are called from within ternary operators. The ATOMIC_BLOCK wrapped is instead placed around the ternary call below
#define FAN_PIN_LOW() *fan_pin_port &= ~(fan_pin_mask)
#define FAN_PIN_HIGH() *fan_pin_port |= (fan_pin_mask)
#define AIRCON_PIN_LOW() *aircon_comp_pin_port &= ~(aircon_comp_pin_mask)
#define AIRCON_PIN_HIGH() *aircon_comp_pin_port |= (aircon_comp_pin_mask)
#define AIRCON_FAN_PIN_LOW() *aircon_fan_pin_port &= ~(aircon_fan_pin_mask)
#define AIRCON_FAN_PIN_HIGH() *aircon_fan_pin_port |= (aircon_fan_pin_mask)
#define AIRCON_ON() ATOMIC_BLOCK(ATOMIC_RESTORESTATE) { ((((configPage15.airConCompPol&1)==1)) ? AIRCON_PIN_LOW() : AIRCON_PIN_HIGH()); BIT_SET(currentStatus.airConStatus, BIT_AIRCON_COMPRESSOR); }
#define AIRCON_OFF() ATOMIC_BLOCK(ATOMIC_RESTORESTATE) { ((((configPage15.airConCompPol&1)==1)) ? AIRCON_PIN_HIGH() : AIRCON_PIN_LOW()); BIT_CLEAR(currentStatus.airConStatus, BIT_AIRCON_COMPRESSOR); }
#define AIRCON_FAN_ON() ATOMIC_BLOCK(ATOMIC_RESTORESTATE) { ((((configPage15.airConFanPol&1)==1)) ? AIRCON_FAN_PIN_LOW() : AIRCON_FAN_PIN_HIGH()); BIT_SET(currentStatus.airConStatus, BIT_AIRCON_FAN); }
#define AIRCON_FAN_OFF() ATOMIC_BLOCK(ATOMIC_RESTORESTATE) { ((((configPage15.airConFanPol&1)==1)) ? AIRCON_FAN_PIN_HIGH() : AIRCON_FAN_PIN_LOW()); BIT_CLEAR(currentStatus.airConStatus, BIT_AIRCON_FAN); }
#define FAN_ON() ATOMIC_BLOCK(ATOMIC_RESTORESTATE) { ((configPage6.fanInv) ? FAN_PIN_LOW() : FAN_PIN_HIGH()); }
#define FAN_OFF() ATOMIC_BLOCK(ATOMIC_RESTORESTATE) { ((configPage6.fanInv) ? FAN_PIN_HIGH() : FAN_PIN_LOW()); }
#endif
#define READ_N2O_ARM_PIN() ((*n2o_arming_pin_port & n2o_arming_pin_mask) ? true : false)
#define AIRCON_ON() {((((configPage15.airConCompPol&1)==1)) ? AIRCON_PIN_LOW() : AIRCON_PIN_HIGH()); BIT_SET(currentStatus.airConStatus, BIT_AIRCON_COMPRESSOR);}
#define AIRCON_OFF() {((((configPage15.airConCompPol&1)==1)) ? AIRCON_PIN_HIGH() : AIRCON_PIN_LOW()); BIT_CLEAR(currentStatus.airConStatus, BIT_AIRCON_COMPRESSOR);}
#define AIRCON_FAN_ON() {((((configPage15.airConFanPol&1)==1)) ? AIRCON_FAN_PIN_LOW() : AIRCON_FAN_PIN_HIGH()); BIT_SET(currentStatus.airConStatus, BIT_AIRCON_FAN);}
#define AIRCON_FAN_OFF() {((((configPage15.airConFanPol&1)==1)) ? AIRCON_FAN_PIN_HIGH() : AIRCON_FAN_PIN_LOW()); BIT_CLEAR(currentStatus.airConStatus, BIT_AIRCON_FAN);}
#define VVT1_PIN_ON() VVT1_PIN_HIGH();
#define VVT1_PIN_OFF() VVT1_PIN_LOW();
@ -74,9 +95,6 @@ static inline void checkAirConRPMLockout(void);
#define VVT2_PIN_OFF() VVT2_PIN_LOW();
#define VVT_TIME_DELAY_MULTIPLIER 50
#define FAN_ON() ((configPage6.fanInv) ? FAN_PIN_LOW() : FAN_PIN_HIGH())
#define FAN_OFF() ((configPage6.fanInv) ? FAN_PIN_HIGH() : FAN_PIN_LOW())
#define WMI_TANK_IS_EMPTY() ((configPage10.wmiEmptyEnabled) ? ((configPage10.wmiEmptyPolarity) ? digitalRead(pinWMIEmpty) : !digitalRead(pinWMIEmpty)) : 1)
volatile PORT_TYPE *boost_pin_port;

View File

@ -420,15 +420,6 @@ This is so we can use an unsigned byte (0-255) to represent temperature ranges f
#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

View File

@ -17,6 +17,8 @@ A full copy of the license may be found in the projects root directory
#include "corrections.h"
#include "pages.h"
#include "decoders.h"
#include "auxiliaries.h"
#include "utilities.h"
/** Init all ADC conversions by setting resolutions, etc.
*/

View File

@ -44,6 +44,7 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
#include "canBroadcast.h"
#include "SD_logger.h"
#include "schedule_calcs.h"
#include "auxiliaries.h"
#include RTC_LIB_H //Defined in each boards .h file
#include BOARD_H //Note that this is not a real file, it is defined in globals.h.