RabbitECUTeensyMCUXpresso/source/Client/CLO2.c

342 lines
10 KiB
C

/******************************************************************************/
/* Copyright (c) 2016 MD Automotive Controls. Original Work. */
/* License: http://www.gnu.org/licenses/gpl.html GPL version 2 or higher */
/******************************************************************************/
/* CONTEXT:USER_APP */
/* PACKAGE TITLE: CLO2 */
/* DESCRIPTION: This code module provides closed loop fuel functions */
/* FILE NAME: CLO2.c */
/* REVISION HISTORY: 28-03-2016 | 1.0 | Initial revision */
/* */
/******************************************************************************/
#define _CLO2_C
/******************************************************************************/
/* HEADER FILES */
/******************************************************************************/
#include "build.h"
#ifdef BUILD_USER
#include "CLO2.h"
#include "FUEL.h"
/* LOCAL MACRO DEFINITIONS ****************************************************/
/* LOCAL VARIABLE DEFINITIONS (STATIC) ****************************************/
uint32 CLO2_u32SensorStateBank[2];
bool CLO2_boSensorState[2];
uint32 CLO2_u32ReadyCount[2];
/* LOCAL FUNCTION PROTOTYPES (STATIC) *****************************************/
/* LOCAL CONSTANT DEFINITIONS (STATIC) ****************************************/
/* GLOBAL FUNCTION DEFINITIONS ************************************************/
void CLO2_vInit(void)
{
CLO2_u32STT[0] = 1000;
CLO2_u32STT[1] = 1000;
CLO2_s32ISCESTTrim[0] = 0;
CLO2_s32ISCESTTrim[1] = 0;
CLO2_au16AFRMeasured[0] = ~0;
CLO2_au16AFRMeasured[1] = ~0;
#if 0
IOAPI_tenEHIOResource enEHIOResource;
IOAPI_tenEHIOType enEHIOType;
IOAPI_tenDriveStrength enDriveStrength;
uint32 u32Arg;
/* Enable the Oxygen sensor bank 1 discrete input sensor type */
enEHIOResource = CLO2_nOxBank1Pin;
enEHIOType = IOAPI_enDIOInput;
enDriveStrength = IOAPI_enStrong;
SETUP_vSetupDigitalIO(enEHIOResource, enEHIOType, enDriveStrength, &u32Arg);
/* Enable the Oxygen sensor bank 2 discrete input sensor type */
enEHIOResource = CLO2_nOxBank2Pin;
SETUP_vSetupDigitalIO(enEHIOResource, enEHIOType, enDriveStrength, &u32Arg);
#endif
}
void CLO2_vFilterSensors(void)
{
#if 0
CLO2_boSensorState[0] = SETUP_vGetDigitalIO(CLO2_nOxBank1Pin);
if (TRUE == CLO2_boSensorState[0])
{
CLO2_u32SensorStateBank[0] = (7 * CLO2_u32SensorStateBank[0]) / 8;
}
else
{
CLO2_u32SensorStateBank[0] = (7 * CLO2_u32SensorStateBank[0] + 1000) / 8;
}
CLO2_boSensorState[1] = SETUP_vGetDigitalIO(CLO2_nOxBank2Pin);
if (TRUE == CLO2_boSensorState[1])
{
CLO2_u32SensorStateBank[1] = (7 * CLO2_u32SensorStateBank[1]) / 8;
}
else
{
CLO2_u32SensorStateBank[1] = (7 * CLO2_u32SensorStateBank[1] + 1000) / 8;
}
#endif
}
void CLO2_vRun(void)
{
static bool aboSTTRichening[2];
uint32 u32Temp;
uint32 u32SeqIDX;
bool boFuelCutActive = FALSE;
uint32 u32CLStep = TRUE == TPS_boThrottleClosed ? USERCAL_stRAMCAL.u32CLStepClosed : USERCAL_stRAMCAL.u32CLStepOpen;
uint32 u32CLInc = TRUE == TPS_boThrottleClosed ? USERCAL_stRAMCAL.u32CLIncClosed : USERCAL_stRAMCAL.u32CLIncOpen;
/* Buffer the auto-tune diag variable */
CLO2_u32AutoTuneVE = CLO2_au16AFRMeasured[0] + (FUEL_u16TAFR << 16);
if ((0 != USERCAL_stRAMCAL.boUEGOCANPrimary) &&
(EH_IO_Invalid == USERCAL_stRAMCAL.u16AFRADResource) &&
(TRUE == SENSORS_aboCANUEGONewSample[0]))
{
CLO2_au16AFRMeasured[0] = SENSORS_au16CANAFR[0];
SENSORS_aboCANUEGONewSample[0] = FALSE;
}
if ((FALSE == USERCAL_stRAMCAL.u8CLO2Leftenable) && (FALSE == USERCAL_stRAMCAL.u8CLO2Leftenable))
{
CLO2_u32STT[0] = 1000;
CLO2_u32STT[1] = 1000;
return;
}
CLO2_u32ReadyCount[0] = (100000 > CLO2_u32ReadyCount[0]) && (0 < CAM_u32RPMRaw) ?
CLO2_u32ReadyCount[0] + 1 : CLO2_u32ReadyCount[0];
CLO2_u32ReadyCount[1] = (100000 > CLO2_u32ReadyCount[1]) && (0 < CAM_u32RPMRaw) ?
CLO2_u32ReadyCount[1] + 1 : CLO2_u32ReadyCount[1];
for (u32SeqIDX = 0; u32SeqIDX < 8; u32SeqIDX++)
{
boFuelCutActive |= FUEL_aboSeqOverrunCutFlag[u32SeqIDX];
}
if (200 < CLO2_u32ReadyCount[0])
{
if (((FUEL_u16TAFR < 1475) && (FUEL_u16TAFR > 1465)) &&
(FALSE == boFuelCutActive))
{
if (800 < CLO2_u32SensorStateBank[0])
{
if ((TRUE == aboSTTRichening[0]) && (USERCAL_stRAMCAL.u32STTNegLimit < CLO2_u32STT[0])) CLO2_u32STT[0] -= u32CLStep;
CLO2_u32STT[0] = USERCAL_stRAMCAL.u32STTNegLimit < CLO2_u32STT[0] ? CLO2_u32STT[0] - u32CLInc : CLO2_u32STT[0];
aboSTTRichening[0] = FALSE;
}
else if (200 > CLO2_u32SensorStateBank[0])
{
if ((FALSE == aboSTTRichening[0]) && (USERCAL_stRAMCAL.u32STTPosLimit > CLO2_u32STT[0])) CLO2_u32STT[0] += u32CLStep;
CLO2_u32STT[0] = USERCAL_stRAMCAL.u32STTPosLimit > CLO2_u32STT[0] ? CLO2_u32STT[0] + u32CLInc : CLO2_u32STT[0];
aboSTTRichening[0] = TRUE;
}
}
else
{
CLO2_u32STT[0] = 1000;
}
/* If no CAN data yet then just set to neutral */
SENSORS_u8CANSTT[0] = 0xff != SENSORS_u8CANSTT[0] ? SENSORS_u8CANSTT[0] : 0x80;
SENSORS_u8CANLTT[0] = 0xff != SENSORS_u8CANLTT[0] ? SENSORS_u8CANLTT[0] : 0x80;
}
if (200 < CLO2_u32ReadyCount[1])
{
if (((FUEL_u16TAFR < 1475) && (FUEL_u16TAFR > 1465)) &&
(FALSE == boFuelCutActive))
{
if (800 < CLO2_u32SensorStateBank[1])
{
if ((TRUE == aboSTTRichening[1]) && (USERCAL_stRAMCAL.u32STTNegLimit < CLO2_u32STT[1])) CLO2_u32STT[1] -= u32CLStep;
CLO2_u32STT[1] = USERCAL_stRAMCAL.u32STTNegLimit < CLO2_u32STT[1] ? CLO2_u32STT[1] - u32CLInc : CLO2_u32STT[1];
aboSTTRichening[1] = FALSE;
}
else if (200 > CLO2_u32SensorStateBank[1])
{
if ((FALSE == aboSTTRichening[1]) && (USERCAL_stRAMCAL.u32STTPosLimit > CLO2_u32STT[1])) CLO2_u32STT[1] += u32CLStep;
CLO2_u32STT[1] = USERCAL_stRAMCAL.u32STTPosLimit > CLO2_u32STT[1] ? CLO2_u32STT[1] + u32CLInc : CLO2_u32STT[1];
aboSTTRichening[1] = TRUE;
}
}
else
{
CLO2_u32STT[1] = 1000;
}
/* If no CAN data yet then just set to neutral */
SENSORS_u8CANSTT[1] = 0xff != SENSORS_u8CANSTT[1] ? SENSORS_u8CANSTT[1] : 0x80;
SENSORS_u8CANLTT[1] = 0xff != SENSORS_u8CANLTT[1] ? SENSORS_u8CANLTT[1] : 0x80;
}
#ifdef BUILD_BSP_STT_CAN
const uint8_t au8BiasTable[256] = CLO2_nBiasTableData;
static bool aboSimRichening[2];
volatile static uint8 au8STTLTT[2];
volatile static uint8 au8Count[2];
volatile static uint8 au8CountRichLimit[2];
volatile static uint8 au8CountLeanLimit[2];
static bool aboOutRich[2];
static bool aboOutConfigured[2];
IOAPI_tenEHIOResource enEHIOResource;
IOAPI_tenEHIOType enEHIOType;
IOAPI_tenDriveStrength enDriveStrength;
uint32 u32Arg;
if ((0xff != SENSORS_u8CANSTT[0]) && (0xff != SENSORS_u8CANLTT[0]))
{
au8STTLTT[0] = 2 * SENSORS_u8CANSTT[0] + SENSORS_u8CANLTT[0];
au8CountRichLimit[0] = (au8BiasTable[au8STTLTT[0]]) / 15;
au8CountLeanLimit[0] = (256 - au8BiasTable[au8STTLTT[0]]) / 15;
if (TRUE == aboSimRichening[0])
{
if (++au8Count[0] > au8CountRichLimit[0])
{
if ((TRUE == aboOutConfigured[0]) &&
(FUEL_u16TAFR > 1465))
{
SETUP_vSetDigitalIOLow(CLO2_nSwitchBank1Pin);
}
au8Count[0] = 0;
aboSimRichening[0] = FALSE;
}
}
else
{
if (++au8Count[0] > au8CountLeanLimit[0])
{
if (TRUE == aboOutConfigured[0])
{
SETUP_vSetDigitalIOHigh(CLO2_nSwitchBank1Pin);
}
au8Count[0] = 0;
aboSimRichening[0] = TRUE;
}
}
}
if ((0xff != SENSORS_u8CANSTT[1]) && (0xff != SENSORS_u8CANLTT[1]))
{
au8STTLTT[1] = 2 * SENSORS_u8CANSTT[1] + SENSORS_u8CANLTT[1];
au8CountRichLimit[1] = (au8BiasTable[au8STTLTT[1]]) / 15;
au8CountLeanLimit[1] = (256 - au8BiasTable[au8STTLTT[1]]) / 15;
if (TRUE == aboSimRichening[1])
{
if (++au8Count[1] > au8CountRichLimit[1])
{
if ((TRUE == aboOutConfigured[1]) &&
(FUEL_u16TAFR > 1465))
{
SETUP_vSetDigitalIOLow(CLO2_nSwitchBank2Pin);
}
au8Count[1] = 0;
aboSimRichening[1] = FALSE;
}
}
else
{
if (++au8Count[1] > au8CountLeanLimit[1])
{
if (TRUE == aboOutConfigured[1])
{
SETUP_vSetDigitalIOHigh(CLO2_nSwitchBank2Pin);
}
au8Count[1] = 0;
aboSimRichening[1] = TRUE;
}
}
}
CLO2_u32STTAvg[0] = ((3 * CLO2_u32STTAvg[0]) / 4) + CLO2_u32STT[0] / 4;
CLO2_u32STTAvg[1] = ((3 * CLO2_u32STTAvg[1]) / 4) + CLO2_u32STT[1] / 4;
CLO2_u32STTAvg[0] = CLO2_u32STT[0] > CLO2_u32STTAvg[0] ? CLO2_u32STTAvg[0] + 1 : CLO2_u32STTAvg[0];
CLO2_u32STTAvg[1] = CLO2_u32STT[1] > CLO2_u32STTAvg[1] ? CLO2_u32STTAvg[1] + 1 : CLO2_u32STTAvg[1];
if ((FALSE == aboOutConfigured[0]) && (TRUE == aboOutReady[0]))
{
enEHIOResource = CLO2_nSwitchBank1Pin;
SETUP_vSetupDigitalIO(enEHIOResource, enEHIOType, enDriveStrength, &u32Arg);
aboOutConfigured[0] = TRUE;
}
if ((FALSE == aboOutConfigured[1]) && (TRUE == aboOutReady[1]))
{
enEHIOResource = CLO2_nSwitchBank2Pin;
SETUP_vSetupDigitalIO(enEHIOResource, enEHIOType, enDriveStrength, &u32Arg);
aboOutConfigured[1] = TRUE;
}
#endif
if (TRUE == TPS_boThrottleClosed)
{
if (1000 < CLO2_u32STT[0])
{
CLO2_s32ISCESTTrim[0] =
~(((CLO2_u32STT[0] - 1000) * USERCAL_stRAMCAL.u32CLO2ESTTrimPos) / (1000 - USERCAL_stRAMCAL.u32STTPosLimit));
}
else
{
CLO2_s32ISCESTTrim[0] =
(((1000 - CLO2_u32STT[0]) * USERCAL_stRAMCAL.u32CLO2ESTTrimNeg) / (1000 - USERCAL_stRAMCAL.u32STTNegLimit));
}
}
else
{
CLO2_s32ISCESTTrim[0] = 0;
}
if ((TRUE == TPS_boThrottleClosed) && (IAC_enClosedLoop == IAC_enControlState))
{
if (CLO2_u32STTAvg[1] < CLO2_u32STT[1])
{
u32Temp = (((CLO2_u32STT[1] - CLO2_u32STTAvg[1]) * USERCAL_stRAMCAL.u32CLO2ESTTrimPos) / 5);
u32Temp = USERCAL_stRAMCAL.u32CLO2ESTTrimPos < u32Temp ? USERCAL_stRAMCAL.u32CLO2ESTTrimPos : u32Temp;
CLO2_s32ISCESTTrim[1] = ~u32Temp;
}
else
{
u32Temp = (((CLO2_u32STTAvg[1] - CLO2_u32STT[1]) * USERCAL_stRAMCAL.u32CLO2ESTTrimNeg) / 5);
u32Temp = USERCAL_stRAMCAL.u32CLO2ESTTrimNeg < u32Temp ? USERCAL_stRAMCAL.u32CLO2ESTTrimNeg : u32Temp;
CLO2_s32ISCESTTrim[1] = u32Temp;
}
}
else
{
CLO2_s32ISCESTTrim[1] = 0;
}
}
#endif //BUILD_USER