RabbitECUTeensyMCUXpresso/source/UserServices/CTRL.c

185 lines
4.8 KiB
C

/******************************************************************************/
/* CTRL c file */
/******************************************************************************/
/* */
/* Copyright (c) 2013 MD Automotive Controls. All rights reserved. */
/* This file provides port access functions */
/* */
/* */
/******************************************************************************/
#include <CTRLAPI.h>
#include <DECLARATIONS.h>
#include <string.h>
#include "mk64f12.h"
#include "OS.h"
#include "MATH.h"
#include "CTRL.h"
CTRLAPI_tstPIDCB CTRLAPI_astPIDCB[CTRL_nPIDCTRLCount];
CTRLAPI_tstPIDCB* CTRLAPI_apstPIDCB[CTRL_nPIDCTRLCount + CTRL_nPIDUserCount];
uint32 CTRLAPI_au32Counter[CTRL_nPIDCTRLCount + CTRL_nPIDUserCount];
void CTRL_vStart(puint32 const pu32Stat)
{
uint32 u32IDX;
for (u32IDX = 0; u32IDX < (CTRL_nPIDCTRLCount + CTRL_nPIDUserCount); u32IDX++)
{
CTRLAPI_apstPIDCB[u32IDX] = NULL;
}
}
void CTRL_vRun(puint32 const pu32Stat)
{
CTRLAPI_tstPIDCB* pstPIDCB = NULL;
uint32 u32PIDIDX;
uint32 u32CountTerminal;
for (u32PIDIDX = 0; u32PIDIDX < (CTRL_nPIDCTRLCount + CTRL_nPIDUserCount); u32PIDIDX++)
{
pstPIDCB = CTRLAPI_apstPIDCB[u32PIDIDX];
if ((NULL != pstPIDCB) && (TRUE == pstPIDCB->boRun))
{
u32CountTerminal = MATH_u32IDXToMask(pstPIDCB->enPIDRate);
if (1024u >= u32CountTerminal)
/* If terminal count is > 1024 then must be a call iterate controller */
{
if (u32CountTerminal <= ++CTRLAPI_au32Counter[u32PIDIDX])
{
CTRLAPI_au32Counter[u32PIDIDX] = 0;
CTRL_vIteratePIDCB(pstPIDCB);
}
}
}
}
}
void CTRL_vTerminate(puint32 const pu32Stat)
{
}
CTRLAPI_ttPIDIDX CTRL_tRequestKernelPIDController(CTRLAPI_tstPIDCB* pstPIDCBReq)
{
CTRLAPI_tstPIDCB* pstPIDCB;
uint32 u32PIDIDX;
CTRLAPI_ttPIDIDX tPIDIDX = -1;
/* Request a Kernel managed PID controller */
for (u32PIDIDX = 0; CTRL_nPIDCTRLCount > u32PIDIDX; u32PIDIDX++)
{
if (NULL == CTRLAPI_apstPIDCB[u32PIDIDX])
{
pstPIDCB = &CTRLAPI_astPIDCB[u32PIDIDX];
CTRLAPI_apstPIDCB[u32PIDIDX] = pstPIDCB;
memcpy((void*)pstPIDCB, (void*)pstPIDCBReq, sizeof(CTRLAPI_tstPIDCB));
pstPIDCB->i32Error = 0;
pstPIDCB->i32Integral = 0;
pstPIDCB->i32IntegralInput = 0;
tPIDIDX = u32PIDIDX;
break;
}
}
return tPIDIDX;
}
void CTRL_vIteratePIDCB(CTRLAPI_tstPIDCB* pstPIDCB)
{
sint32 i32ErrorDerivative;
sint32 i32Result = 0;
sint32 i32ResultTerm;
sint32 i32Temp;
pstPIDCB->i32Error = *(pstPIDCB->pi32Target) - *(pstPIDCB->pi32Feedback);
/* Calculate the integral */
if (FALSE == pstPIDCB->boResetIntegrator)
{
CTRL_xAddSigned32(pstPIDCB->i32Integral, pstPIDCB->i32Error);
}
else
{
pstPIDCB->i32Integral = 0;
pstPIDCB->boResetIntegrator = FALSE;
}
/* Calculate the error derivative */
i32ErrorDerivative = pstPIDCB->i32Error - pstPIDCB->i32OldError;
/* Calculate the proportional output */
CTRL_xCalcTermResult(pstPIDCB->i32Error, pstPIDCB->u8PTerm);
/* Accumulate the output */
CTRL_xAddSigned32(i32Result, i32ResultTerm);
/* Calculate the derivative output */
CTRL_xCalcTermResult(i32ErrorDerivative, pstPIDCB->u8DTerm);
/* Accumulate the output */
CTRL_xAddSigned32(i32Result, i32ResultTerm);
/* Calculate the integral output */
CTRL_xCalcTermResult(pstPIDCB->i32Integral, pstPIDCB->u8ITerm);
/* Accumulate the output */
CTRL_xAddSigned32(i32Result, i32ResultTerm);
/* Check for out of range and wind-up */
if (pstPIDCB->i32OutputMax < i32Result)
{
i32Temp = i32Result - pstPIDCB->i32OutputMax;
i32Result = pstPIDCB->i32OutputMax;
if (pstPIDCB->boNoWindUp)
{
/* Remove the P component */
i32Temp -= (pstPIDCB->i32Error * pstPIDCB->u8PTerm);
i32Temp = (0 < i32Temp) ? i32Temp : 0;
i32Temp = (0 < pstPIDCB->i32Integral) ? (i32Temp / pstPIDCB->u8ITerm) : 0;
pstPIDCB->i32Integral -= i32Temp;
}
}
else if (pstPIDCB->i32OutputMin > i32Result)
{
i32Temp = pstPIDCB->i32OutputMin - i32Result;
i32Result = pstPIDCB->i32OutputMin;
if (pstPIDCB->boNoWindUp)
{
/* Remove the P component */
i32Temp += (pstPIDCB->i32Error * pstPIDCB->u8PTerm);
i32Temp = (0 < i32Temp) ? i32Temp : 0;
i32Temp = (0 > pstPIDCB->i32Integral) ? (i32Temp / pstPIDCB->u8ITerm) : 0;
pstPIDCB->i32Integral += i32Temp;
}
}
/* Buffer the output result */
*(pstPIDCB->pi32Output) = i32Result;
/* Copy old variables */
pstPIDCB->i32OldError = pstPIDCB->i32Error;
}
void CTRL_vIteratePID(CTRLAPI_ttPIDIDX tPIDIDX)
{
CTRLAPI_tstPIDCB* pstPIDCB;
pstPIDCB = CTRLAPI_apstPIDCB[tPIDIDX];
CTRL_vIteratePIDCB(pstPIDCB);
}