/*================================================================================================== * Project : RTD AUTOSAR 4.4 * Platform : CORTEXM * Peripheral : PORT_CI * Dependencies : none * * Autosar Version : 4.4.0 * Autosar Revision : ASR_REL_4_4_REV_0000 * Autosar Conf.Variant : * SW Version : 1.0.0 * Build Version : S32K1_RTD_1_0_0_HF01_D2109_ASR_REL_4_4_REV_0000_20210907 * * (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 Port.c * * @implements Port.c_Artifact * @brief Autosar Port driver main source file * @details Port driver file that contains the implementation of the interface functions * * @addtogroup Port_HLD * @{ */ #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 "Port.h" #if (STD_ON == PORT_DEV_ERROR_DETECT) #include "Det.h" #endif /*================================================================================================= * SOURCE FILE VERSION INFORMATION =================================================================================================*/ /** * @brief Parameters that shall be published within the Port driver header file and also in the * module's description file */ #define PORT_VENDOR_ID_C 43 #define PORT_AR_RELEASE_MAJOR_VERSION_C 4 #define PORT_AR_RELEASE_MINOR_VERSION_C 4 #define PORT_AR_RELEASE_REVISION_VERSION_C 0 #define PORT_SW_MAJOR_VERSION_C 1 #define PORT_SW_MINOR_VERSION_C 0 #define PORT_SW_PATCH_VERSION_C 0 /*================================================================================================= * FILE VERSION CHECKS =================================================================================================*/ /* Check if source file and Port header file are of the same vendor */ #if (PORT_VENDOR_ID_C != PORT_VENDOR_ID_H) #error "Port.c and Port.h have different vendor ids" #endif /* Check if source file and Port header file are of the same Autosar version */ #if ((PORT_AR_RELEASE_MAJOR_VERSION_C != PORT_AR_RELEASE_MAJOR_VERSION_H) || \ (PORT_AR_RELEASE_MINOR_VERSION_C != PORT_AR_RELEASE_MINOR_VERSION_H) || \ (PORT_AR_RELEASE_REVISION_VERSION_C != PORT_AR_RELEASE_REVISION_VERSION_H) \ ) #error "AutoSar Version Numbers of Port.c and Port.h are different" #endif /* Check if source file and Port header file are of the same Software version */ #if ((PORT_SW_MAJOR_VERSION_C != PORT_SW_MAJOR_VERSION_H) || \ (PORT_SW_MINOR_VERSION_C != PORT_SW_MINOR_VERSION_H) || \ (PORT_SW_PATCH_VERSION_C != PORT_SW_PATCH_VERSION_H) \ ) #error "Software Version Numbers of Port.c and Port.h are different" #endif #if (STD_ON == PORT_DEV_ERROR_DETECT) #ifndef DISABLE_MCAL_INTERMODULE_ASR_CHECK /* Check if the source file and Det.h file are of the same Autosar version */ #if ((PORT_AR_RELEASE_MAJOR_VERSION_C != DET_AR_RELEASE_MAJOR_VERSION) || \ (PORT_AR_RELEASE_MINOR_VERSION_C != DET_AR_RELEASE_MINOR_VERSION) \ ) #error "AutoSar Version Numbers of Port.c and Det.h are different" #endif #endif #endif /*================================================================================================= * LOCAL TYPEDEFS (STRUCTURES, UNIONS, ENUMS) =================================================================================================*/ /*================================================================================================= * LOCAL MACROS =================================================================================================*/ /*================================================================================================= * LOCAL CONSTANTS =================================================================================================*/ #if (STD_ON == PORT_MULTICORE_ENABLED) #define Port_GetCoreID() OsIf_GetCoreID() #else #define Port_GetCoreID() ((uint32)0UL) #endif /*================================================================================================= * LOCAL VARIABLES =================================================================================================*/ /*================================================================================================= * GLOBAL CONSTANTS =================================================================================================*/ /*================================================================================================= * GLOBAL VARIABLES =================================================================================================*/ #define PORT_START_SEC_VAR_CLEARED_UNSPECIFIED_NO_CACHEABLE #include "Port_MemMap.h" static const Port_ConfigType * Port_pConfig; #define PORT_STOP_SEC_VAR_CLEARED_UNSPECIFIED_NO_CACHEABLE #include "Port_MemMap.h" #define PORT_START_SEC_CONFIG_DATA_UNSPECIFIED #include "Port_MemMap.h" #if (STD_ON == PORT_PRECOMPILE_SUPPORT) extern Port_ConfigType Port_Config; #endif #define PORT_STOP_SEC_CONFIG_DATA_UNSPECIFIED #include "Port_MemMap.h" /*================================================================================================= * LOCAL FUNCTION PROTOTYPES =================================================================================================*/ /*================================================================================================= * LOCAL FUNCTIONS =================================================================================================*/ #define PORT_START_SEC_CODE #include "Port_MemMap.h" /*================================================================================================= * GLOBAL FUNCTIONS =================================================================================================*/ /** * @brief Initializes the Port Driver module. * @details The function @p Port_Init() will initialize ALL ports and port pins * with the configuration set pointed to by the parameter @p pConfigPtr. * @post Port_Init() must be called before all other Port Driver module's functions * otherwise no operation can occur on the MCU ports and port pins. * * @param[in] ConfigPtr A pointer to the structure which contains * initialization parameters. * * @implements Port_Init_Activity */ void Port_Init ( const Port_ConfigType * ConfigPtr ) { const Port_ConfigType * pLocalConfigPtr = ConfigPtr; #if (STD_ON == PORT_DEV_ERROR_DETECT) uint8 CoreId; CoreId = (uint8)Port_GetCoreID(); #if (STD_OFF == PORT_PRECOMPILE_SUPPORT) if (NULL_PTR == ConfigPtr) #else /*(STD_OFF == PORT_PRECOMPILE_SUPPORT) */ if (NULL_PTR != ConfigPtr) #endif /* (STD_OFF == PORT_PRECOMPILE_SUPPORT) */ { (void)Det_ReportError((uint16)PORT_MODULE_ID, PORT_INSTANCE_ID, (uint8)PORT_INIT_ID, (uint8)PORT_E_INIT_FAILED); } else #endif /* (STD_ON == PORT_DEV_ERROR_DETECT) */ { #if (STD_ON == PORT_PRECOMPILE_SUPPORT) pLocalConfigPtr = &Port_Config; #endif /* (STD_ON == PORT_PRECOMPILE_SUPPORT) */ #if (STD_ON == PORT_DEV_ERROR_DETECT) if ((uint32)1 != pLocalConfigPtr->pau8Port_PartitionList[CoreId]) { (void)Det_ReportError((uint16)PORT_MODULE_ID, PORT_INSTANCE_ID, (uint8)PORT_INIT_ID, (uint8)PORT_E_PARAM_CONFIG); } else #endif /* (STD_ON == PORT_DEV_ERROR_DETECT) */ { Port_Ipw_Init(pLocalConfigPtr); /* Save configuration pointer in global variable */ Port_pConfig = pLocalConfigPtr; } } } #if (STD_ON == PORT_SET_PIN_DIRECTION_API) /** * @brief Sets the port pin direction. * @details The function @p Port_SetPinDirection() will set the port pin direction * during runtime. * @pre @p Port_Init() must have been called first. In order to change the * pin direction the PortPinDirectionChangeable flag must have been set * to @p TRUE. * * @param[in] Pin Pin ID number. * @param[in] Direction Port Pin direction. * * @implements Port_SetPinDirection_Activity */ void Port_SetPinDirection ( Port_PinType Pin, Port_PinDirectionType Direction ) { #if (STD_ON == PORT_DEV_ERROR_DETECT) /* Variable used to store current error status */ Std_ReturnType ErrStatus; uint8 CoreId; CoreId = (uint8)Port_GetCoreID(); /* Check if Port module is initialized */ if (NULL_PTR == Port_pConfig) { (void)Det_ReportError((uint16)PORT_MODULE_ID, (uint8)PORT_INSTANCE_ID, (uint8)PORT_SETPINDIRECTION_ID, (uint8)PORT_E_UNINIT); } /* Check port pin validity */ else if (Pin >= (Port_PinType)Port_pConfig->u16NumPins) { (void)Det_ReportError((uint16)PORT_MODULE_ID, (uint8)PORT_INSTANCE_ID, (uint8)PORT_SETPINDIRECTION_ID, (uint8)PORT_E_PARAM_PIN); } else if ((uint32)1 != (((Port_pConfig->pau32Port_PinToPartitionMap[Pin])&((uint32)1 << CoreId)) >> CoreId)) { (void)Det_ReportError((uint16)PORT_MODULE_ID, (uint8)PORT_INSTANCE_ID, (uint8)PORT_SETPINDIRECTION_ID, (uint8)PORT_E_PARAM_CONFIG); } else #endif /* PORT_DEV_ERROR_DETECT */ { #if (STD_ON == PORT_DEV_ERROR_DETECT) ErrStatus = Port_Ipw_SetPinDirection(Pin, Direction, Port_pConfig); #else (void)Port_Ipw_SetPinDirection(Pin, Direction, Port_pConfig); #endif #if (STD_ON == PORT_DEV_ERROR_DETECT) if ((Std_ReturnType)E_NOT_OK == ErrStatus) { (void)Det_ReportError((uint16)PORT_MODULE_ID, (uint8)PORT_INSTANCE_ID, (uint8)PORT_SETPINDIRECTION_ID, (uint8)PORT_E_DIRECTION_UNCHANGEABLE); } #endif /* (STD_ON == PORT_DEV_ERROR_DETECT) */ } } #endif /* (STD_ON == PORT_SET_PIN_DIRECTION_API) */ #ifdef PORT_SET_2_PINS_DIRECTION_API #if (STD_ON == PORT_SET_2_PINS_DIRECTION_API) /** * @brief Sets the direction of 2 pins. * @details The function @p Port_Set2PinsDirection() will set the port pins direction * during runtime. * @pre @p Port_Init() must have been called first. In order to change the * pin direction the PortPinDirectionChangeable flag must have been set * to @p TRUE for both pins. * * @param[in] Pin1 Pin 1 ID number. * @param[in] Pin2 Pin 2 ID number. * @param[in] Direction Port Pin direction. * * Port_Set2PinsDirection_Activity * @api */ void Port_Set2PinsDirection ( Port_PinType Pin1, Port_PinType Pin2, Port_PinDirectionType Direction ) { #if (STD_ON == PORT_DEV_ERROR_DETECT) /* Variable used to store current error status */ Std_ReturnType ErrStatus = (Std_ReturnType)E_OK; /* Check if Port module is initialized */ if (NULL_PTR == Port_pConfig) { (void)Det_ReportError((uint16)PORT_MODULE_ID, (uint8)PORT_INSTANCE_ID, (uint8)PORT_SET2PINSDIRECTION_ID, (uint8)PORT_E_UNINIT); } /* Check port pin validity */ else if ((Pin1 >= (Port_PinType)Port_pConfig->u16NumPins) || (Pin2 >= (Port_PinType)Port_pConfig->u16NumPins)) { (void)Det_ReportError((uint16)PORT_MODULE_ID, (uint8)PORT_INSTANCE_ID, (uint8)PORT_SET2PINSDIRECTION_ID, (uint8)PORT_E_PARAM_PIN); } else #endif /* PORT_DEV_ERROR_DETECT */ { #if (STD_ON == PORT_DEV_ERROR_DETECT) ErrStatus = Port_Ipw_Set2PinsDirection(Pin1, Pin2, (Port_PinDirectionType)Direction, Port_pConfig); #else (void)Port_Ipw_Set2PinsDirection(Pin1, Pin2, (Port_PinDirectionType)Direction, Port_pConfig); #endif #if (STD_ON == PORT_DEV_ERROR_DETECT) if ((Std_ReturnType)E_NOT_OK == ErrStatus) { (void)Det_ReportError((uint16)PORT_MODULE_ID, (uint8)PORT_INSTANCE_ID, (uint8)PORT_SET2PINSDIRECTION_ID, (uint8)PORT_E_DIRECTION_UNCHANGEABLE); } #endif /* (STD_ON == PORT_DEV_ERROR_DETECT) */ } } #endif /*(STD_ON == PORT_SET_2_PINS_DIRECTION_API) */ #endif #if (STD_ON == PORT_SET_PIN_MODE_API) /** * @brief Sets the port pin mode. * @details The function @p Port_SetPinMode() will set the port pin mode of the * referenced pin during runtime. * @pre @p Port_Init() must have been called first. * * @param[in] Pin Pin ID number. * @param[in] Mode New Port Pin mode to be set on port pin. * * @implements Port_SetPinMode_Activity */ void Port_SetPinMode ( Port_PinType Pin, Port_PinModeType Mode ) { #if (STD_ON == PORT_DEV_ERROR_DETECT) uint8 u8PinModeError = (uint8)0U; uint8 CoreId; CoreId = (uint8)Port_GetCoreID(); /* Check if port is initialized */ if (NULL_PTR == Port_pConfig) { (void)Det_ReportError((uint16)PORT_MODULE_ID, (uint8)PORT_INSTANCE_ID, (uint8)PORT_SETPINMODE_ID, (uint8)PORT_E_UNINIT); } /* Check port pin validity */ else if (Pin >= (Port_PinType)Port_pConfig->u16NumPins) { (void)Det_ReportError((uint16)PORT_MODULE_ID, (uint8)PORT_INSTANCE_ID, (uint8)PORT_SETPINMODE_ID, (uint8)PORT_E_PARAM_PIN); } else if ((uint32)1 != (((Port_pConfig->pau32Port_PinToPartitionMap[Pin])&((uint32)1 << CoreId)) >> CoreId)) { (void)Det_ReportError((uint16)PORT_MODULE_ID, (uint8)PORT_INSTANCE_ID, (uint8)PORT_SETPINMODE_ID, (uint8)PORT_E_PARAM_CONFIG); } /* Check port pin mode Unchangeable */ else if(FALSE == Port_pConfig->pUsedPadConfig[Pin].bMC) { (void)Det_ReportError((uint16)PORT_MODULE_ID, (uint8)PORT_INSTANCE_ID, (uint8)PORT_SETPINMODE_ID, (uint8)PORT_E_MODE_UNCHANGEABLE); } else #endif /* (STD_ON == PORT_DEV_ERROR_DETECT) */ { /* Sets the port pin direction */ #if (STD_ON == PORT_DEV_ERROR_DETECT) u8PinModeError = (uint8)Port_Ipw_SetPinMode(Pin, Mode, Port_pConfig); #else (void)Port_Ipw_SetPinMode(Pin, Mode, Port_pConfig); #endif #if (STD_ON == PORT_DEV_ERROR_DETECT) if (PORT_E_PARAM_INVALID_MODE == u8PinModeError) { (void)Det_ReportError((uint16)PORT_MODULE_ID, (uint8)PORT_INSTANCE_ID, (uint8)PORT_SETPINMODE_ID, (uint8)PORT_E_PARAM_INVALID_MODE); } #endif /* (STD_ON == PORT_DEV_ERROR_DETECT) */ } } #endif /* (STD_ON == PORT_SET_PIN_MODE_API) */ /** * @brief Refreshes port direction. * @details This function will refresh the direction of all configured ports to * the configured direction. * The PORT driver will exclude from refreshing those port pins that * are configured as "pin direction changeable during runtime". * @pre @p Port_Init() must have been called first. * * @implements Port_RefreshPortDirection_Activity */ void Port_RefreshPortDirection( void ) { #if (STD_ON == PORT_DEV_ERROR_DETECT) uint8 CoreId; CoreId = (uint8)Port_GetCoreID(); /* Check if Port module is initialized */ if (NULL_PTR == Port_pConfig) { (void)Det_ReportError((uint16)PORT_MODULE_ID, (uint8)PORT_INSTANCE_ID, (uint8)PORT_REFRESHPINDIRECTION_ID, (uint8)PORT_E_UNINIT); } else if ((uint32)1 != Port_pConfig->pau8Port_PartitionList[CoreId]) { (void)Det_ReportError((uint16)PORT_MODULE_ID, PORT_INSTANCE_ID, (uint8)PORT_REFRESHPINDIRECTION_ID, (uint8)PORT_E_PARAM_CONFIG); } else #endif /* (STD_ON == PORT_DEV_ERROR_DETECT) */ { Port_Ipw_RefreshPortDirection(Port_pConfig); } } #if (STD_ON == PORT_VERSION_INFO_API) /** * @brief Returns the version information of this module. * @details The function Port_GetVersionInfo() will return the version * information of this module. The version information includes: * - Module Id, * - Vendor Id, * - Vendor specific version numbers. * * @param[in,out] versioninfo Pointer to where to store the version * information of this module. * * * @implements Port_GetVersionInfo_Activity */ void Port_GetVersionInfo ( Std_VersionInfoType * versioninfo ) { #if (STD_ON == PORT_DEV_ERROR_DETECT) if (NULL_PTR == versioninfo) { (void)Det_ReportError((uint16)PORT_MODULE_ID, (uint8)PORT_INSTANCE_ID, (uint8)PORT_GETVERSIONINFO_ID, (uint8)PORT_E_PARAM_POINTER); } else #endif /* (STD_ON == PORT_DEV_ERROR_DETECT) */ { (versioninfo)->vendorID = (uint16)PORT_VENDOR_ID_H; (versioninfo)->moduleID = (uint16)PORT_MODULE_ID; (versioninfo)->sw_major_version = (uint8)PORT_SW_MAJOR_VERSION_H; (versioninfo)->sw_minor_version = (uint8)PORT_SW_MINOR_VERSION_H; (versioninfo)->sw_patch_version = (uint8)PORT_SW_PATCH_VERSION_H; } } #endif /* (STD_ON == PORT_VERSION_INFO_API) */ #ifdef PORT_SET_AS_UNUSED_PIN_API #if (STD_ON == PORT_SET_AS_UNUSED_PIN_API) /** * @brief Set as unused pin. * @details This function shall configure the referenced pin with all * the properties specified in the NotUsedPortPin container. * @pre @p Port_Init() must have been called first. * * @implements Port_SetAsUnusedPin_Activity */ void Port_SetAsUnusedPin ( Port_PinType Pin ) { #if (STD_ON == PORT_DEV_ERROR_DETECT) uint8 CoreId; CoreId = (uint8)Port_GetCoreID(); /* Check if port is initialized */ if (NULL_PTR == Port_pConfig) { (void)Det_ReportError((uint16)PORT_MODULE_ID, (uint8)PORT_INSTANCE_ID, (uint8)PORT_SETASUNUSEDPIN_ID, (uint8)PORT_E_UNINIT); } else if (Pin >= (Port_PinType)Port_pConfig->u16NumPins) { (void)Det_ReportError((uint16)PORT_MODULE_ID, (uint8)PORT_INSTANCE_ID, (uint8)PORT_SETASUNUSEDPIN_ID, (uint8)PORT_E_PARAM_PIN); } /* Check if this function was called with wrong core */ else if ((uint32)1 != (((Port_pConfig->pau32Port_PinToPartitionMap[Pin])&((uint32)1 << CoreId)) >> CoreId)) { (void)Det_ReportError((uint16)PORT_MODULE_ID, (uint8)PORT_INSTANCE_ID, (uint8)PORT_SETASUNUSEDPIN_ID, (uint8)PORT_E_PARAM_CONFIG); } /* Check port pin mode Unchangeable */ else if(FALSE == Port_pConfig->pUsedPadConfig[Pin].bMC) { (void)Det_ReportError((uint16)PORT_MODULE_ID, (uint8)PORT_INSTANCE_ID, (uint8)PORT_SETASUNUSEDPIN_ID, (uint8)PORT_E_MODE_UNCHANGEABLE); } else #endif { Port_Ipw_SetAsUnusedPin(Pin, Port_pConfig); } } /** * @brief Set as used pin. * @details This function shall configure the referenced pin with * all the properties that where set during the Port_Init operation. * @pre @p Port_Init() must have been called first. * * @implements Port_SetAsUsedPin_Activity */ void Port_SetAsUsedPin ( Port_PinType Pin ) { #if (STD_ON == PORT_DEV_ERROR_DETECT) uint8 CoreId; CoreId = (uint8)Port_GetCoreID(); /* Check if port is initialized */ if (NULL_PTR == Port_pConfig) { (void)Det_ReportError((uint16)PORT_MODULE_ID, (uint8)PORT_INSTANCE_ID, (uint8)PORT_SETASUSEDPIN_ID, (uint8)PORT_E_UNINIT); } /* Check port pin validity */ else if (Pin >= (Port_PinType)Port_pConfig->u16NumPins) { (void)Det_ReportError((uint16)PORT_MODULE_ID, (uint8)PORT_INSTANCE_ID, (uint8)PORT_SETASUSEDPIN_ID, (uint8)PORT_E_PARAM_PIN); } else if ((uint32)1 != (((Port_pConfig->pau32Port_PinToPartitionMap[Pin])&((uint32)1 << CoreId)) >> CoreId)) { (void)Det_ReportError((uint16)PORT_MODULE_ID, (uint8)PORT_INSTANCE_ID, (uint8)PORT_SETASUSEDPIN_ID, (uint8)PORT_E_PARAM_CONFIG); } /* Check port pin mode Unchangeable */ else if(FALSE == Port_pConfig->pUsedPadConfig[Pin].bMC) { (void)Det_ReportError((uint16)PORT_MODULE_ID, (uint8)PORT_INSTANCE_ID, (uint8)PORT_SETASUSEDPIN_ID, (uint8)PORT_E_MODE_UNCHANGEABLE); } else #endif { Port_Ipw_SetAsUsedPin(Pin, Port_pConfig); } } #endif /* (STD_ON == PORT_SET_AS_UNUSED_PIN_API) */ #endif #ifdef PORT_RESET_PIN_MODE_API #if (STD_ON == PORT_RESET_PIN_MODE_API) /** * @brief Reset Pin Mode. * @details This function shall revert the port pin mode of the referenced pin * to the value that was set by Port_Init operation. * @pre @p Port_Init() must have been called first. * * @implements Port_ResetPinMode_Activity */ void Port_ResetPinMode ( Port_PinType Pin ) { #if (STD_ON == PORT_DEV_ERROR_DETECT) uint8 CoreId; CoreId = (uint8)Port_GetCoreID(); /* Check if port is initialized */ if (NULL_PTR == Port_pConfig) { (void)Det_ReportError((uint16)PORT_MODULE_ID, (uint8)PORT_INSTANCE_ID, (uint8)PORT_RESETPINMODE_ID, (uint8)PORT_E_UNINIT); } /* Check port pin validity */ else if (Pin >= (Port_PinType)Port_pConfig->u16NumPins) { (void)Det_ReportError((uint16)PORT_MODULE_ID, (uint8)PORT_INSTANCE_ID, (uint8)PORT_RESETPINMODE_ID, (uint8)PORT_E_PARAM_PIN); } /* Check port pin validity */ else if ((uint32)1 != (((Port_pConfig->pau32Port_PinToPartitionMap[Pin])&((uint32)1 << CoreId)) >> CoreId)) { (void)Det_ReportError((uint16)PORT_MODULE_ID, (uint8)PORT_INSTANCE_ID, (uint8)PORT_RESETPINMODE_ID, (uint8)PORT_E_PARAM_CONFIG); } /* Check port pin mode Unchangeable */ else if(FALSE == Port_pConfig->pUsedPadConfig[Pin].bMC) { (void)Det_ReportError((uint16)PORT_MODULE_ID, (uint8)PORT_INSTANCE_ID, (uint8)PORT_RESETPINMODE_ID, (uint8)PORT_E_MODE_UNCHANGEABLE); } else #endif { Port_Ipw_ResetPinMode(Pin, Port_pConfig); } } #endif /* (STD_ON == PORT_RESET_PIN_MODE_API) */ #endif #define PORT_STOP_SEC_CODE #include "Port_MemMap.h" #ifdef __cplusplus } #endif /** @} */ /* End of File */