ADM/GW/RTD/src/Emios_Mcl_Ip.c
2024-08-08 10:00:15 +09:00

398 lines
16 KiB
C

/*==================================================================================================
* Project : RTD AUTOSAR 4.4
* Platform : CORTEXM
* Peripheral : DMA,CACHE,TRGMUX,LCU,EMIOS,FLEXIO
* Dependencies : none
*
* Autosar Version : 4.4.0
* Autosar Revision : ASR_REL_4_4_REV_0000
* Autosar Conf.Variant :
* SW Version : 0.9.0
* Build Version : S32K3_RTD_0_9_0__ASR_REL_4_4_REV_0000_20210326
*
* (c) Copyright 2020 - 2021 NXP Semiconductors
* All Rights Reserved.
*
* NXP Confidential. This software is owned or controlled by NXP and may only be
* used strictly in accordance with the applicable license terms. By expressly
* accepting such terms or by downloading, installing, activating and/or otherwise
* using the software, you are agreeing that you have read, and that you agree to
* comply with and are bound by, such license terms. If you do not agree to be
* bound by the applicable license terms, then you may not retain, install,
* activate or otherwise use the software.
==================================================================================================*/
/**
* @file Emios_Mcl_Ip.c
*
* @version 0.9.0
*
* @brief AUTOSAR Mcl - Emios Common driver source file.
* @details
*
* @addtogroup EMIOS_IP_DRIVER EMIOS IP Driver
* @{
*/
#ifdef __cplusplus
extern "C"{
#endif
/*==================================================================================================
* INCLUDE FILES
* 1) system and project includes
* 2) needed interfaces from external units
* 3) internal and external interfaces from this unit
==================================================================================================*/
#include "Emios_Mcl_Ip.h"
/*==================================================================================================
* SOURCE FILE VERSION INFORMATION
==================================================================================================*/
/*==================================================================================================
* FILE VERSION CHECKS
==================================================================================================*/
/*==================================================================================================
* LOCAL TYPEDEFS (STRUCTURES, UNIONS, ENUMS)
==================================================================================================*/
/*==================================================================================================
* LOCAL CONSTANTS
==================================================================================================*/
/*==================================================================================================
* LOCAL VARIABLES
==================================================================================================*/
#define MCL_START_SEC_VAR_INIT_UNSPECIFIED_NO_CACHEABLE
#include "Mcl_MemMap.h"
eMIOS_Type* emiosBase[eMIOS_INSTANCE_COUNT] = eMIOS_BASE_PTRS;
static Emios_Ip_ChStateType Emios_Ip_ChState[eMIOS_INSTANCE_COUNT][eMIOS_CH_UC_UC_COUNT] =
{
{
{
EMIOS_IP_NO_MASTER_MODE,
(boolean)FALSE
}
}
};
static Emios_Ip_InstStateType Emios_Ip_IpIsInitialized[eMIOS_INSTANCE_COUNT] =
{
{
(boolean)FALSE,
#if (EMIOS_IP_MULTICORE_IS_AVAILABLE == STD_ON)
(uint8)255
#endif
}
};
#define MCL_STOP_SEC_VAR_INIT_UNSPECIFIED_NO_CACHEABLE
#include "Mcl_MemMap.h"
/*==================================================================================================
* GLOBAL CONSTANTS
==================================================================================================*/
/*==================================================================================================
* GLOBAL VARIABLES
==================================================================================================*/
/*==================================================================================================
* LOCAL FUNCTION PROTOTYPES
==================================================================================================*/
/*==================================================================================================
* LOCAL FUNCTIONS
==================================================================================================*/
/*==================================================================================================
* GLOBAL FUNCTIONS PROTOTYPES
==================================================================================================*/
/*==================================================================================================
GLOBAL FUNCTIONS
==================================================================================================*/
#define MCL_START_SEC_CODE
#include "Mcl_MemMap.h"
/** @implements Emios_Mcl_Ip_Init_Activity */
Emios_Ip_CommonStatusType Emios_Mcl_Ip_Init(uint8 instance, const Emios_Mcl_Ip_ConfigType* const pConfig)
{
#if (EMIOS_MCL_IP_DEV_ERROR_DETECT == STD_ON)
DevAssert(instance < eMIOS_INSTANCE_COUNT);
DevAssert(pConfig != NULL_PTR);
#endif
uint8 currentChannel;
eMIOS_Type* base = emiosBase[instance];
Emios_Ip_CommonStatusType status = EMIOS_IP_COMMON_STATUS_SUCCESS;
#if (EMIOS_IP_MULTICORE_IS_AVAILABLE == STD_ON)
uint8 coreID = (uint8)OsIf_GetCoreID();
if ( MULTICORE_INIT_CORE == coreID )
{
#endif /* EMIOS_IP_MULTICORE_IS_AVAILABLE == STD_ON */
if (Emios_Ip_IpIsInitialized[instance].instanceInitState == TRUE)
{
status = EMIOS_IP_COMMON_STATUS_FAIL;
}
else
{
/* Initialization of EMIOS instance specific parameters. */
base->MCR &= ~eMIOS_MCR_GPREN_MASK;
base->MCR = eMIOS_MCR_GPRE(pConfig->emiosGlobalConfig->clkDivVal) | eMIOS_MCR_FRZ(((uint32)pConfig->emiosGlobalConfig->allowDebugMode)) | \
eMIOS_MCR_GTBE(pConfig->emiosGlobalConfig->enableGlobalTimeBase);
/* Initialization of EMIOS channel specific parameters. */
for (currentChannel = 0; currentChannel < pConfig->channelsNumber; currentChannel++)
{
if ((*pConfig->masterBusConfig)[currentChannel].allowDebugMode)
{
base->CH.UC[(*pConfig->masterBusConfig)[currentChannel].hwChannel].C |= eMIOS_C_FREN_MASK;
}
/* Set Cn UCPRE to divider. */
base->CH.UC[(*pConfig->masterBusConfig)[currentChannel].hwChannel].C |= eMIOS_C_UCPRE((*pConfig->masterBusConfig)[currentChannel].masterBusPrescaler);
switch ((*pConfig->masterBusConfig)[currentChannel].masterMode)
{
case EMIOS_IP_MC_UP_COUNTER_START:
base->CH.UC[(*pConfig->masterBusConfig)[currentChannel].hwChannel].A = (*pConfig->masterBusConfig)[currentChannel].defaultPeriod;
break;
case EMIOS_IP_MC_UP_COUNTER_END:
base->CH.UC[(*pConfig->masterBusConfig)[currentChannel].hwChannel].A = (*pConfig->masterBusConfig)[currentChannel].defaultPeriod;
break;
case EMIOS_IP_MC_UP_DOWN_COUNTER:
base->CH.UC[(*pConfig->masterBusConfig)[currentChannel].hwChannel].B = 0;
base->CH.UC[(*pConfig->masterBusConfig)[currentChannel].hwChannel].A = (*pConfig->masterBusConfig)[currentChannel].defaultPeriod;
break;
case EMIOS_IP_MCB_UP_COUNTER:
base->CH.UC[(*pConfig->masterBusConfig)[currentChannel].hwChannel].A = (*pConfig->masterBusConfig)[currentChannel].defaultPeriod;
break;
case EMIOS_IP_MCB_UP_DOWN_COUNTER:
base->CH.UC[(*pConfig->masterBusConfig)[currentChannel].hwChannel].A = (*pConfig->masterBusConfig)[currentChannel].defaultPeriod;
break;
default:
/* Do nothing. */
break;
}
/* Write CNT register with start offset value. */
base->CH.UC[(*pConfig->masterBusConfig)[currentChannel].hwChannel].CNT = (*pConfig->masterBusConfig)[currentChannel].offsetStartValue;
/* Set mode Cn_MODE = mode. */
base->CH.UC[(*pConfig->masterBusConfig)[currentChannel].hwChannel].C |= eMIOS_C_MODE((*pConfig->masterBusConfig)[currentChannel].masterMode);
base->CH.UC[(*pConfig->masterBusConfig)[currentChannel].hwChannel].C |= eMIOS_C_UCPREN(1U);
/* Enable the interrupt flag. */
base->CH.UC[(*pConfig->masterBusConfig)[currentChannel].hwChannel].C |= eMIOS_C_FEN((uint32)(*pConfig->masterBusConfig)[currentChannel].interruptEnable);
/* Save current state of channel. */
Emios_Ip_ChState[instance][(*pConfig->masterBusConfig)[currentChannel].hwChannel].counterMode = (*pConfig->masterBusConfig)[currentChannel].masterMode;
Emios_Ip_ChState[instance][(*pConfig->masterBusConfig)[currentChannel].hwChannel].channelInitState = TRUE;
}
/* Save current state of the instance. */
Emios_Ip_IpIsInitialized[instance].instanceInitState = TRUE;
#if (EMIOS_IP_MULTICORE_IS_AVAILABLE == STD_ON)
Emios_Ip_IpIsInitialized[instance].runCore = pConfig->instanceCoreNumber;
#endif
}
base->MCR |= eMIOS_MCR_GPREN_MASK;
#if (EMIOS_IP_MULTICORE_IS_AVAILABLE == STD_ON)
}
else
{
status = EMIOS_IP_COMMON_STATUS_WRONG_CORE;
}
#endif /* EMIOS_IP_MULTICORE_IS_AVAILABLE == STD_ON */
return status;
}
/** @implements Emios_Mcl_Ip_EnableChannel_Activity */
void Emios_Mcl_Ip_EnableChannel(uint8 instance, uint8 u8HwChannel)
{
#if (EMIOS_MCL_IP_DEV_ERROR_DETECT == STD_ON)
DevAssert(instance < eMIOS_INSTANCE_COUNT);
DevAssert(u8HwChannel < eMIOS_CH_UC_UC_COUNT);
#endif
eMIOS_Type* base = emiosBase[instance];
base->UCDIS &= ~(uint32)((uint32)1 << ((uint32)u8HwChannel));
}
/** @implements Emios_Mcl_Ip_DisableChannel_Activity */
void Emios_Mcl_Ip_DisableChannel(uint8 instance, uint8 u8HwChannel)
{
#if (EMIOS_MCL_IP_DEV_ERROR_DETECT == STD_ON)
DevAssert(instance < eMIOS_INSTANCE_COUNT);
DevAssert(u8HwChannel < eMIOS_CH_UC_UC_COUNT);
#endif
eMIOS_Type* base = emiosBase[instance];
base->UCDIS |= (uint32)((uint32)1 << ((uint32)u8HwChannel));
}
/** @implements Emios_Mcl_Ip_ComparatorTransferEnable_Activity */
void Emios_Mcl_Ip_ComparatorTransferEnable(uint8 instance, uint32 channelMask)
{
#if (EMIOS_MCL_IP_DEV_ERROR_DETECT == STD_ON)
DevAssert(instance < eMIOS_INSTANCE_COUNT);
DevAssert(channelMask < EMIOS_CHANNELMASK_MAXVAL);
#endif
eMIOS_Type* base = emiosBase[instance];
/* Update enable. */
base->OUDIS &= ~(channelMask);
}
/** @implements Emios_Mcl_Ip_ComparatorTransferDisable_Activity */
void Emios_Mcl_Ip_ComparatorTransferDisable(uint8 instance, uint32 channelMask)
{
#if (EMIOS_MCL_IP_DEV_ERROR_DETECT == STD_ON)
DevAssert(instance < eMIOS_INSTANCE_COUNT);
DevAssert(channelMask < EMIOS_CHANNELMASK_MAXVAL);
#endif
eMIOS_Type* base = emiosBase[instance];
/* Disable channel output. */
base->OUDIS |= channelMask;
}
/** @implements Emios_Mcl_Ip_Deinit_Activity */
Emios_Ip_CommonStatusType Emios_Mcl_Ip_Deinit(uint8 instance)
{
#if (EMIOS_MCL_IP_DEV_ERROR_DETECT == STD_ON)
DevAssert(instance < eMIOS_INSTANCE_COUNT);
#endif
uint8 currentChannel;
Emios_Ip_CommonStatusType status = EMIOS_IP_COMMON_STATUS_SUCCESS;
eMIOS_Type* base = emiosBase[instance];
#if (EMIOS_IP_MULTICORE_IS_AVAILABLE == STD_ON)
uint8 coreID = (uint8)OsIf_GetCoreID();
if ( MULTICORE_INIT_CORE == coreID )
{
#endif /* EMIOS_IP_MULTICORE_IS_AVAILABLE == STD_ON */
if (Emios_Ip_IpIsInitialized[instance].instanceInitState == FALSE)
{
status = EMIOS_IP_COMMON_STATUS_FAIL;
}
else
{
base->MCR &= ~eMIOS_MCR_GPREN_MASK;
base->MCR = eMIOS_MCR_GPRE(0U) | eMIOS_MCR_FRZ(0U) | eMIOS_MCR_GTBE(0U);
for (currentChannel = 0; currentChannel < eMIOS_CH_UC_UC_COUNT; currentChannel++)
{
if(Emios_Ip_ChState[instance][currentChannel].channelInitState == TRUE)
{
/* Disable channel pre-scaler (reset default) */
emiosBase[instance]->CH.UC[currentChannel].C = 0U;
/* Reset An and Bn registers */
emiosBase[instance]->CH.UC[currentChannel].A = 0UL;
emiosBase[instance]->CH.UC[currentChannel].B = 0UL;
emiosBase[instance]->UCDIS |= (uint32)((uint32)0 << ((uint32)currentChannel));
Emios_Ip_ChState[instance][currentChannel].channelInitState = FALSE;
}
}
Emios_Ip_IpIsInitialized[instance].instanceInitState = FALSE;
}
#if (EMIOS_IP_MULTICORE_IS_AVAILABLE == STD_ON)
}
else
{
status = EMIOS_IP_COMMON_STATUS_WRONG_CORE;
}
#endif /* EMIOS_IP_MULTICORE_IS_AVAILABLE == STD_ON */
return status;
}
/* Emios_Mcl_Ip_SetReloadInterval_Activity */
void Emios_Mcl_Ip_SetReloadInterval(uint8 hwInstance, uint8 hwChannel, uint8 interval)
{
#if (EMIOS_MCL_IP_DEV_ERROR_DETECT == STD_ON)
DevAssert((uint8)31 > interval);
DevAssert(hwInstance < eMIOS_INSTANCE_COUNT);
DevAssert(hwChannel < eMIOS_CH_UC_UC_COUNT);
#endif
/* Specifies the delay interval, in counter bus reload events, between each assertion
* of AS1-BS1 reload in MC and MCB modes. */
emiosBase[hwInstance]->CH.UC[hwChannel].C2 = eMIOS_C2_UCRELDEL_INT(interval);
}
boolean Emios_Mcl_Ip_ValidateChannel(uint8 hwInstance, uint8 hwChannel)
{
#if (EMIOS_MCL_IP_DEV_ERROR_DETECT == STD_ON)
DevAssert(hwInstance < eMIOS_INSTANCE_COUNT);
DevAssert(hwChannel < eMIOS_CH_UC_UC_COUNT);
#endif
boolean valid = FALSE;
if (TRUE == Emios_Ip_ChState[hwInstance][hwChannel].channelInitState)
{
valid = TRUE;
}
return valid;
}
/** @implements Emios_Mcl_Ip_SetCounterBusPeriod_Activity */
Emios_Ip_CommonStatusType Emios_Mcl_Ip_SetCounterBusPeriod(uint8 hwInstance, uint8 hwChannel, uint16 period)
{
#if (EMIOS_MCL_IP_DEV_ERROR_DETECT == STD_ON)
DevAssert((uint16)65535 > period);
DevAssert(hwInstance < eMIOS_INSTANCE_COUNT);
DevAssert(hwChannel < eMIOS_CH_UC_UC_COUNT);
#endif
Emios_Ip_CommonStatusType status = EMIOS_IP_COMMON_STATUS_FAIL;
if (( (Emios_Ip_ChState[hwInstance][hwChannel].counterMode == EMIOS_IP_MCB_UP_COUNTER) || \
(Emios_Ip_ChState[hwInstance][hwChannel].counterMode == EMIOS_IP_MCB_UP_DOWN_COUNTER) ) && \
(period < 1U) )
{
status = EMIOS_IP_COMMON_STATUS_FAIL;
}
else
{
emiosBase[hwInstance]->CH.UC[hwChannel].A = period;
status = EMIOS_IP_COMMON_STATUS_SUCCESS;
}
return status;
}
#if (EMIOS_IP_MULTICORE_IS_AVAILABLE == STD_ON)
boolean Emios_Ip_ValidateMultiCoreInit(uint8 hwInstance)
{
boolean Valid = FALSE;
uint8 CoreId = (uint8)OsIf_GetCoreID();
if (Emios_Ip_IpIsInitialized[hwInstance].runCore == CoreId)
{
Valid = TRUE;
}
return Valid;
}
#endif
#define MCL_STOP_SEC_CODE
#include "Mcl_MemMap.h"
#ifdef __cplusplus
}
#endif
/** @} */