/*================================================================================================== * 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 /** @} */