Created
May 26, 2024 22:33
-
-
Save eliaskanelis/1e9a8f4aad8ec7686a753fc51af64a47 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// ------------------------------------------------------------------------ | |
#include "CddTemplate.h" | |
#include "Std_Types.h" | |
// ------------------------------------------------------------------------ | |
/** Uncomment to enable debugging aid */ | |
//#define CDDTEMPLATE_ENABLE_DEBUG | |
// ------------------------------------------------------------------------ | |
/** \brief States for the FSM. */ | |
typedef enum | |
{ | |
/** \brief Initialisation FSM state. */ | |
CDDTEMPLATE_STATE_INIT = 0u, | |
/** \brief Idle FSM state. */ | |
CDDTEMPLATE_STATE_IDLE, | |
/** \brief Error FSM state. */ | |
CDDTEMPLATE_STATE_ERROR, | |
/** \brief How many FSM states are there? */ | |
CDDTEMPLATE_STATE_HOWMANY | |
} CddTemplate_State; | |
/** \brief Typedef to the runtime data. */ | |
typedef struct CddTemplate_RunTimeData CddTemplate_RunTimeData; | |
/** | |
* \brief A function pointer type for the processing the states. | |
* | |
* \param[in,out]: pRtData The runtime data. | |
* \param[out]: nextState The next state. | |
* | |
* \retval True Success. | |
* \retval False Failure. | |
*/ | |
typedef boolean( *StateFunction )( CddTemplate_RunTimeData *pRtData, | |
CddTemplate_State *nextState ); | |
/** \brief Group of data with protected access. */ | |
typedef struct | |
{ | |
uint32 forcePhyDisabled; | |
} CddTemplate_ProtectedData; | |
/** \brief The runtime data. */ | |
struct CddTemplate_RunTimeData | |
{ | |
/** \brief FSM state. */ | |
CddTemplate_State state; | |
/** \brief Runtime data with protected access. */ | |
CddTemplate_ProtectedData protected; | |
/** \brief Pointer to the FSM state function callback list. */ | |
const StateFunction *pStateFunctionCBList; | |
/** \brief Error counter. */ | |
uint8 errCnt; | |
}; | |
// ------------------------------------------------------------------------ | |
/** | |
* \brief Check whether PHY is enabled. | |
* The check is on shared SRAM with sequencer | |
* | |
* \retval True PHY is enabled. | |
* \retval False PHY is disabled. | |
*/ | |
static boolean HardwareIsPhyEnabled( void ); | |
/** | |
* \brief Enable APIX PHY. | |
* The operation takes place via shared SRAM with sequencer. | |
*/ | |
static void HardwareEnablePhy( void ); | |
/** | |
* \brief Disable APIX PHY. | |
* The operation takes place via shared SRAM with sequencer. | |
*/ | |
static void HardwareDisablePhy( void ); | |
/** | |
* \brief Acquire/Lock shared resources. | |
* | |
* \param[in,out]: pRtData The runtime data. | |
* | |
* \retval True Success. | |
* \retval False Failure. | |
*/ | |
static boolean Lock( CddTemplate_RunTimeData *pRtData ); | |
/** | |
* \brief Release/Unlock shared resources. | |
* \retval True Success. | |
* \retval False Failure. | |
*/ | |
static boolean Unlock( CddTemplate_RunTimeData *pRtData ); | |
/** | |
* \brief Initialise the runtime data to default values. | |
* | |
* \param[out]: pRtData The runtime data. | |
* | |
* \retval True Success. | |
* \retval False Failure. | |
*/ | |
static boolean InitRunTimeData( CddTemplate_RunTimeData *pRtData ); | |
/** | |
* \brief Callback for processing the initialisation state. | |
* | |
* \param[in,out]: pRtData The runtime data. | |
* \param[out]: nextState The next state. | |
* | |
* \retval True Success. | |
* \retval False Failure. | |
*/ | |
static boolean ProcessInitStateCB( CddTemplate_RunTimeData *pRtData, | |
CddTemplate_State *nextState ); | |
/** | |
* \brief Callback for processing the idle state. | |
* | |
* \param[in,out]: pRtData The runtime data. | |
* \param[out]: nextState The next state. | |
* | |
* \retval True Success. | |
* \retval False Failure. | |
*/ | |
static boolean ProcessIdleStateCB( CddTemplate_RunTimeData *pRtData, | |
CddTemplate_State *nextState ); | |
/** | |
* \brief Callback for processing the error state. | |
* | |
* \param[in,out]: pRtData The runtime data. | |
* \param[out]: nextState The next state. | |
* | |
* \retval True Success. | |
* \retval False Failure. | |
*/ | |
static boolean ProcessErrorStateCB( CddTemplate_RunTimeData *pRtData, | |
CddTemplate_State *nextState ); | |
/** | |
* \brief Print information for aiding during debugging. | |
* | |
* \param[in,out]: pRtData The runtime data. | |
* | |
* \retval True Success. | |
* \retval False Failure. | |
*/ | |
#if defined CDDTEMPLATE_ENABLE_DEBUG | |
static boolean PrintDebugInfo( CddTemplate_RunTimeData *pRtData ); | |
#endif /* CDDTEMPLATE_ENABLE_DEBUG */ | |
/** | |
* \brief Process the FSM. | |
* | |
* \param[in,out]: pRtData The runtime data. | |
* | |
* \retval True Success. | |
* \retval False Failure. | |
*/ | |
static boolean ProcessStateMachine( CddTemplate_RunTimeData *pRtData ); | |
// ------------------------------------------------------------------------ | |
/** \brief FSM state function callback list. */ | |
static const StateFunction g_StateFunctionCBList[CDDTEMPLATE_STATE_HOWMANY] = | |
{ | |
ProcessInitStateCB, /**< State function for CDDTEMPLATE_STATE_INIT */ | |
ProcessIdleStateCB, /**< State function for CDDTEMPLATE_STATE_IDLE */ | |
ProcessErrorStateCB /**< State function for CDDTEMPLATE_STATE_ERROR */ | |
}; | |
// ------------------------------------------------------------------------ | |
/** \brief Runtime data. */ | |
static CddTemplate_RunTimeData cddTemplateRtData; | |
/** \brief Is component initialised? */ | |
static boolean isInitialised = FALSE; | |
static boolean SRAM_isPHYTxEnabled = TRUE; // TODO(elias): Delete | |
// ------------------------------------------------------------------------ | |
void CddTemplate_Init( void ) | |
{ | |
CddTemplate_RunTimeData *pRtData = &cddTemplateRtData; | |
boolean success = ( !isInitialised ); | |
if( success ) | |
{ | |
success = InitRunTimeData( pRtData ); | |
} | |
if( success ) | |
{ | |
isInitialised = TRUE; | |
} | |
else | |
{ | |
if( pRtData->errCnt < MAX_UINT8 ) | |
{ | |
pRtData->errCnt++; | |
} | |
} | |
} | |
void CddTemplate_MainFunction( void ) | |
{ | |
CddTemplate_RunTimeData *pRtData = &cddTemplateRtData; | |
boolean success = ( isInitialised ); | |
if( success ) | |
{ | |
success = ProcessStateMachine( pRtData ); | |
} | |
if( !success ) | |
{ | |
if( pRtData->errCnt < MAX_UINT8 ) | |
{ | |
pRtData->errCnt++; | |
} | |
} | |
} | |
void CddTemplate_Deinit( void ) | |
{ | |
CddTemplate_RunTimeData *pRtData = &cddTemplateRtData; | |
boolean success = ( isInitialised ); | |
if( success ) | |
{ | |
success = InitRunTimeData( pRtData ); | |
} | |
if( success ) | |
{ | |
isInitialised = FALSE; | |
} | |
else | |
{ | |
if( pRtData->errCnt < MAX_UINT8 ) | |
{ | |
pRtData->errCnt++; | |
} | |
} | |
} | |
Std_ReturnType CddTemplate_EnablePhy( void ) | |
{ | |
CddTemplate_RunTimeData *pRtData = &cddTemplateRtData; | |
boolean success = isInitialised; | |
if( success ) | |
{ | |
success = Lock( pRtData ); | |
} | |
if( success ) | |
{ | |
pRtData->protected.forcePhyDisabled = FALSE; | |
success = Unlock( pRtData ); | |
} | |
return success; | |
} | |
Std_ReturnType CddTemplate_DisablePhy( void ) | |
{ | |
CddTemplate_RunTimeData *pRtData = &cddTemplateRtData; | |
Std_ReturnType returnCode = E_NOT_OK; | |
if( isInitialised ) | |
{ | |
returnCode = E_OK; | |
} | |
if( returnCode == E_OK ) | |
{ | |
const boolean lockSuccess = Lock( pRtData ); | |
if( !lockSuccess ) | |
{ | |
returnCode = E_NOT_OK; | |
} | |
} | |
if( returnCode == E_OK ) | |
{ | |
pRtData->protected.forcePhyDisabled = TRUE; | |
const boolean unlockSuccess = Unlock( pRtData ); | |
if( !unlockSuccess ) | |
{ | |
returnCode = E_NOT_OK; | |
} | |
} | |
return returnCode; | |
} | |
Std_ReturnType CddTemplate_GetLinkStatus( boolean *isLinkUp ) | |
{ | |
Std_ReturnType returnCode = E_NOT_OK; | |
if( isInitialised && ( isLinkUp != NULL ) ) | |
{ | |
returnCode = E_OK; | |
} | |
if( returnCode == E_OK ) | |
{ | |
*isLinkUp = TRUE; // TODO(elias): Read from memory mapped register | |
} | |
return returnCode; | |
} | |
// ------------------------------------------------------------------------ | |
static boolean HardwareIsPhyEnabled( void ) | |
{ | |
// TODO(elias): Check the TX PHY from SRAM variables. | |
boolean isPhyEnabled = SRAM_isPHYTxEnabled; | |
return isPhyEnabled; | |
} | |
static void HardwareEnablePhy( void ) | |
{ | |
// TODO(elias): Enable the TX PHY from SRAM variables. | |
printf( "Hardware Enable\n" ); | |
SRAM_isPHYTxEnabled = TRUE; | |
} | |
static void HardwareDisablePhy( void ) | |
{ | |
// TODO(elias): Disable the TX PHY from SRAM variables. | |
printf( "Hardware Disable\n" ); | |
SRAM_isPHYTxEnabled = FALSE; | |
} | |
static boolean Lock( CddTemplate_RunTimeData *pRtData ) | |
{ | |
boolean success = ( pRtData != NULL ); | |
if( success ) | |
{ | |
// TODO(): Implement lock mechanism. | |
} | |
return success; | |
} | |
static boolean Unlock( CddTemplate_RunTimeData *pRtData ) | |
{ | |
boolean success = ( pRtData != NULL ); | |
if( success ) | |
{ | |
// TODO(): Implement unlock mechanism. | |
} | |
return success; | |
} | |
static boolean InitRunTimeData( CddTemplate_RunTimeData *pRtData ) | |
{ | |
boolean success = ( pRtData != NULL ); | |
if( success ) | |
{ | |
pRtData->errCnt = 0ul; | |
pRtData->state = CDDTEMPLATE_STATE_INIT; | |
pRtData->pStateFunctionCBList = g_StateFunctionCBList; | |
success = TRUE; // TODO(): Status from mutex init | |
} | |
if( success ) | |
{ | |
success = Lock( pRtData ); | |
} | |
if( success ) | |
{ | |
/* Init the protected part of runtime data */ | |
pRtData->protected.forcePhyDisabled = FALSE; | |
success = Unlock( pRtData ); | |
} | |
return success; | |
} | |
static boolean ProcessInitStateCB( CddTemplate_RunTimeData *pRtData, | |
CddTemplate_State *nextState ) | |
{ | |
boolean success = ( ( pRtData != NULL ) && ( nextState != NULL ) ); | |
if( success ) | |
{ | |
*nextState = CDDTEMPLATE_STATE_IDLE; | |
} | |
return success; | |
} | |
static boolean ProcessIdleStateCB( CddTemplate_RunTimeData *pRtData, | |
CddTemplate_State *nextState ) | |
{ | |
boolean success = ( ( pRtData != NULL ) && ( nextState != NULL ) ); | |
if( success ) | |
{ | |
/* Rule #1: */ | |
const boolean shouldDisablePhy = pRtData->protected.forcePhyDisabled; | |
if( shouldDisablePhy ) | |
{ | |
if( HardwareIsPhyEnabled() ) | |
{ | |
HardwareDisablePhy(); | |
} | |
} | |
else | |
{ | |
if( !HardwareIsPhyEnabled() ) | |
{ | |
HardwareEnablePhy(); | |
} | |
} | |
*nextState = CDDTEMPLATE_STATE_IDLE; | |
} | |
return success; | |
} | |
static boolean ProcessErrorStateCB( CddTemplate_RunTimeData *pRtData, | |
CddTemplate_State *nextState ) | |
{ | |
boolean success = ( ( pRtData != NULL ) && ( nextState != NULL ) ); | |
if( success ) | |
{ | |
/* TODO(elias): No logs here. Should not pollute. */ | |
*nextState = CDDTEMPLATE_STATE_ERROR; | |
} | |
return success; | |
} | |
#if defined CDDTEMPLATE_ENABLE_DEBUG | |
#include <stdio.h> | |
static boolean PrintDebugInfo( CddTemplate_RunTimeData *pRtData ) | |
{ | |
boolean success = ( pRtData != NULL ); | |
if( success ) | |
{ | |
printf( "---------------------------\n" ); | |
printf( "\tState: %d\n", pRtData->state ); | |
printf( "\tforcePhyDisabled: %d\n", pRtData->protected.forcePhyDisabled ); | |
printf( "\terrCnt: %d\n", pRtData->errCnt ); | |
printf( "\tisPHYEnabled SRAM %d\n", HardwareIsPhyEnabled() ); | |
} | |
return success; | |
} | |
#endif /* CDDTEMPLATE_ENABLE_DEBUG */ | |
static boolean ProcessStateMachine( CddTemplate_RunTimeData *pRtData ) | |
{ | |
boolean success = ( pRtData != NULL ); | |
CddTemplate_State nextState = CDDTEMPLATE_STATE_ERROR; | |
if( success ) | |
{ | |
success = Lock( pRtData ); | |
} | |
#if 1 // TODO(elias): Not feeling confident about using a function pointer when system is not stable. | |
StateFunction stateFunc = NULL; | |
if( success ) | |
{ | |
/* We get the state function from a list given the state */ | |
if( pRtData->state < CDDTEMPLATE_STATE_HOWMANY ) | |
{ | |
stateFunc = pRtData->pStateFunctionCBList[pRtData->state]; | |
} | |
/* We need to be extra sure that the function pointer is valid */ | |
if( stateFunc == NULL ) | |
{ | |
success = FALSE; | |
} | |
} | |
if( success ) | |
{ | |
success = stateFunc( pRtData, &nextState ); | |
} | |
#else | |
if( success ) | |
{ | |
switch( pRtData->state ) | |
{ | |
case CDDTEMPLATE_STATE_INIT: | |
{ | |
success = ProcessInitStateCB( pRtData, &nextState ); | |
break; | |
} | |
case CDDTEMPLATE_STATE_IDLE: | |
{ | |
success = ProcessIdleStateCB( pRtData, &nextState ); | |
break; | |
} | |
case CDDTEMPLATE_STATE_ERROR: | |
{ | |
success = ProcessErrorStateCB( pRtData, &nextState ); | |
break; | |
} | |
default: | |
{ | |
success = FALSE; | |
break; | |
} | |
} | |
} | |
#endif | |
#if defined CDDTEMPLATE_ENABLE_DEBUG | |
if( success ) | |
{ | |
success = PrintDebugInfo( pRtData ); | |
} | |
#endif /* CDDTEMPLATE_ENABLE_DEBUG */ | |
if( success ) | |
{ | |
pRtData->state = nextState; | |
success = Unlock( pRtData ); | |
} | |
return success; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment