191 lines
7.5 KiB
C
191 lines
7.5 KiB
C
/******************************************************************************/
|
|
/* Copyright (c) 2016 MD Automotive Controls. Original Work. */
|
|
/******************************************************************************/
|
|
/* CONTEXT:USER_APP */
|
|
/* PACKAGE TITLE: Air Flow Meter */
|
|
/* DESCRIPTION: This code module initialises the required ADC */
|
|
/* resources and functions for air flow measurement */
|
|
/* */
|
|
/* FILE NAME: AFM.c */
|
|
/* REVISION HISTORY: 28-03-2016 | 1.0 | Initial revision */
|
|
/* */
|
|
/******************************************************************************/
|
|
|
|
#define _AFM_C
|
|
|
|
/******************************************************************************/
|
|
/* HEADER FILES */
|
|
/******************************************************************************/
|
|
#include "build.h"
|
|
|
|
#ifdef BUILD_USER
|
|
|
|
#include "AFM.h"
|
|
#include "MAP.h"
|
|
|
|
|
|
/* LOCAL VARIABLE DEFINITIONS (STATIC) ****************************************/
|
|
bool AFM_boNewSample;
|
|
EXTERN GPM6_ttUg AFM_tManChargeMassOldUg;
|
|
|
|
/* LOCAL FUNCTION PROTOTYPES (STATIC) *****************************************/
|
|
/*******************************************************************************
|
|
* Interface : AFM_vADCCallBack
|
|
*
|
|
* Implementation : Callback to receive the measured ADC value
|
|
*
|
|
* Parameter
|
|
* Par1 : enEHIOResource enum of the ADC resource
|
|
* Par2 : u32ADCResult the ADC conversion value
|
|
*
|
|
* Return Value : NIL
|
|
*******************************************************************************/
|
|
static void AFM_vADCCallBack(IOAPI_tenEHIOResource enEHIOResource, uint32 u32ADCResult);
|
|
SPREADAPI_ttSpreadIDX AFM_tSpreadBackupAirflowxIDX;
|
|
SPREADAPI_ttSpreadIDX AFM_tSpreadBackupAirflowyIDX;
|
|
MAPSAPI_ttMapIDX AFM_tMapBackupAirflowIDX;
|
|
|
|
/* GLOBAL FUNCTION DEFINITIONS ************************************************/
|
|
void AFM_vStart(puint32 const pu32Arg)
|
|
{
|
|
AFM_boNewSample = FALSE;
|
|
|
|
#ifdef BUILD_BSP_AFM_ANALOG
|
|
IOAPI_tenEHIOResource enEHIOResource;
|
|
IOAPI_tenEHIOType enEHIOType;
|
|
ADCAPI_tstADCCB stADCCB;
|
|
|
|
enEHIOResource = USERCAL_stRAMCAL.u16AFMADResource;
|
|
enEHIOType = IOAPI_enADSE;
|
|
stADCCB.enSamplesAv = ADCAPI_en32Samples;
|
|
stADCCB.pfResultCB = &AFM_vADCCallBack;
|
|
stADCCB.enTrigger = ADCAPI_enTrigger4;
|
|
USER_vSVC(SYSAPI_enRequestIOResource, (void*)&enEHIOResource, (void*)NULL, (void*)NULL);
|
|
|
|
if (SYSAPI_enOK == pstSVCDataStruct->enSVCResult)
|
|
{
|
|
USER_vSVC(SYSAPI_enInitialiseIOResource, (void*)&enEHIOResource,
|
|
(void*)&enEHIOType, (void*)&stADCCB);
|
|
|
|
if (SYSAPI_enOK != pstSVCDataStruct->enSVCResult)
|
|
{
|
|
*pu32Arg |= (uint32)SYSAPI_enResourceRequestFailed;/*CR1_13*/
|
|
}
|
|
}
|
|
else
|
|
{
|
|
*pu32Arg |= (uint32)SYSAPI_enResourceInitFailed;/*CR1_13*/
|
|
}
|
|
#endif
|
|
|
|
AFM_tSensorHertz = 0;
|
|
|
|
/* Request and initialise required Kernel managed spread for backup airflow x */
|
|
AFM_tSpreadBackupAirflowxIDX = SETUP_tSetupSpread((void*)&CAM_u32RPMRaw, (void*)&USERCAL_stRAMCAL.aUserBackupAirflowxSpread, TYPE_enUInt32, 17, SPREADAPI_enSpread4ms, NULL);
|
|
|
|
/* Request and initialise required Kernel managed spread for backup airflow y */
|
|
AFM_tSpreadBackupAirflowyIDX = SETUP_tSetupSpread((void*)&TPS_tThetaFiltered, (void*)&USERCAL_stRAMCAL.aUserBackupAirflowySpread, TYPE_enUInt32, 11, SPREADAPI_enSpread4ms, NULL);
|
|
|
|
/* Request and initialise required Kernel managed map for backup airflow */
|
|
AFM_tMapBackupAirflowIDX = SETUP_tSetupMap((void*)&USERCAL_stRAMCAL.aUserBackupAirflowMap, (void*)&AFM_tAirFlowBackupRawUg, TYPE_enUInt32, 11, 11, AFM_tSpreadBackupAirflowxIDX, AFM_tSpreadBackupAirflowyIDX, NULL);
|
|
}
|
|
|
|
void AFM_vRun(puint32 const pu32Arg)
|
|
{
|
|
uint32 u32Temp;
|
|
uint8 u8ManifoldTimeConstantFilter;
|
|
SPREADAPI_tstSpreadResult* pstSpreadResultAirflowBackupX;
|
|
SPREADAPI_tstSpreadResult* pstSpreadResultAirflowBackupY;
|
|
uint32 u32TableIDXx = ~0;
|
|
uint32 u32TableIDXy = ~0;
|
|
|
|
if (TRUE == AFM_boNewSample)
|
|
{
|
|
USER_xEnterCritical();/*CR1_16*/
|
|
(void)USERMATH_u16SinglePoleLowPassFilter16((uint16)AFM_u32ADCRaw, AFM_nADFiltVal,
|
|
&AFM_u32ADCFiltered);
|
|
AFM_boNewSample = FALSE;
|
|
USER_xExitCritical();/*CR1_16*/
|
|
|
|
u32Temp = AFM_u32ADCFiltered * SENSORS_nADRefVolts;
|
|
u32Temp /= SENSORS_nADScaleMax;
|
|
u32Temp /= SENSORS_nVDivRatio;
|
|
|
|
AFM_tSensorVolts = u32Temp;
|
|
|
|
(void)BOOSTED_boIndexAndCalculateMap(AFM_tSpreadBackupAirflowxIDX, AFM_tSpreadBackupAirflowyIDX, AFM_tMapBackupAirflowIDX);
|
|
|
|
u8ManifoldTimeConstantFilter = USERMATH_u8GetFilterFromTimeConstant(0x01, TPS_u32ManifoldVolumeTau );
|
|
u8ManifoldTimeConstantFilter = ~u8ManifoldTimeConstantFilter;
|
|
u8ManifoldTimeConstantFilter++;
|
|
|
|
AFM_tAirFlowBackupUg = USERMATH_u32SinglePoleLowPassFilter32(AFM_tAirFlowBackupRawUg, u8ManifoldTimeConstantFilter, &AFM_tAirFlowBackupUg);
|
|
|
|
if (0 == TPS_u32ThrottleMovingCounter)
|
|
{
|
|
/* Get the current x spread for backup airflow */
|
|
pstSpreadResultAirflowBackupX = BOOSTED_pstGetSpread(AFM_tSpreadBackupAirflowxIDX);
|
|
|
|
/* Get the current x spread for backup airflow */
|
|
pstSpreadResultAirflowBackupY = BOOSTED_pstGetSpread(AFM_tSpreadBackupAirflowyIDX);
|
|
|
|
u32TableIDXx = (0x1000u > pstSpreadResultAirflowBackupX->uSpreadData.stSpreadResult.u16SpreadOffset) ? pstSpreadResultAirflowBackupX->uSpreadData.stSpreadResult.u16SpreadIndex : u32TableIDXx;
|
|
u32TableIDXx = (0xf000u < pstSpreadResultAirflowBackupX->uSpreadData.stSpreadResult.u16SpreadOffset) ? pstSpreadResultAirflowBackupX->uSpreadData.stSpreadResult.u16SpreadIndex + 1 : u32TableIDXx;
|
|
u32TableIDXy = (0x1000u > pstSpreadResultAirflowBackupY->uSpreadData.stSpreadResult.u16SpreadOffset) ? pstSpreadResultAirflowBackupY->uSpreadData.stSpreadResult.u16SpreadIndex : u32TableIDXy;
|
|
u32TableIDXy = (0xf000u < pstSpreadResultAirflowBackupY->uSpreadData.stSpreadResult.u16SpreadOffset) ? pstSpreadResultAirflowBackupY->uSpreadData.stSpreadResult.u16SpreadIndex + 1 : u32TableIDXy;
|
|
|
|
/* If the indexes are valid then learn the new airflow */
|
|
if ((0xffffffff != u32TableIDXx) && (0xffffffff != u32TableIDXy))
|
|
{
|
|
u32Temp = AFM_tAirFlowAFMUg / 4 + (3 * USERCAL_stRAMCAL.aUserBackupAirflowMap[u32TableIDXx][u32TableIDXy]) / 4;
|
|
USERCAL_stRAMCAL.aUserBackupAirflowMap[u32TableIDXx][u32TableIDXy] = u32Temp;
|
|
}
|
|
}
|
|
}
|
|
|
|
/* Calculate predicted VE method airflow */
|
|
u32Temp = MAP_u16VE * USERCAL_stRAMCAL.u16CylinderCC * USERCAL_stRAMCAL.u8CylCount / 120;
|
|
u32Temp *= CAM_u32RPMRaw;
|
|
u32Temp /= 10000;
|
|
u32Temp *= MAP_tKiloPaFiltered;
|
|
u32Temp /= 10000;
|
|
|
|
/* Correct for air temperature */
|
|
u32Temp = (u32Temp * 2980 ) / ((ATS_tTempCPort / 100) + 2730);
|
|
AFM_tAirFlowVEUg = 1225 * u32Temp;
|
|
|
|
#ifdef BUILD_BSP_AFM_FREQ
|
|
/* Calculate current running VE */
|
|
u32Temp = USERCAL_stRAMCAL.u16CylinderCC * USERCAL_stRAMCAL.u8CylCount / 120;
|
|
u32Temp *= CAM_u32RPMFiltered;
|
|
u32Temp /= 10;
|
|
u32Temp *= MAP_tKiloPaFiltered;
|
|
u32Temp /= 10000;
|
|
u32Temp *= 1225;
|
|
u32Temp /= 1000;
|
|
AFM_u16LearnVE = AFM_tAirFlowAFMUg / u32Temp;
|
|
#endif
|
|
}
|
|
|
|
void AFM_vTerminate(puint32 const pu32Arg)
|
|
{
|
|
|
|
}
|
|
|
|
|
|
void AFM_vCallBack(puint32 const pu32Arg)
|
|
{
|
|
|
|
}
|
|
|
|
|
|
static void __attribute__((used)) AFM_vADCCallBack(IOAPI_tenEHIOResource enEHIOResource, uint32 u32ADCResult)
|
|
{
|
|
AFM_u32ADCRaw = u32ADCResult;
|
|
AFM_boNewSample = TRUE;
|
|
}
|
|
|
|
|
|
|
|
#endif //BUILD_USER
|